diff --git a/crates/aiken-lang/src/expr.rs b/crates/aiken-lang/src/expr.rs index b5dab82f..36cfb1f0 100644 --- a/crates/aiken-lang/src/expr.rs +++ b/crates/aiken-lang/src/expr.rs @@ -382,6 +382,11 @@ pub enum UntypedExpr { text: Box, }, + TraceIfFalse { + location: Span, + value: Box, + }, + When { location: Span, subjects: Vec, @@ -510,7 +515,8 @@ impl UntypedExpr { match self { Self::PipeLine { expressions, .. } => expressions.last().location(), Self::Trace { then, .. } => then.location(), - Self::Fn { location, .. } + Self::TraceIfFalse { location, .. } + | Self::Fn { location, .. } | Self::Var { location, .. } | Self::Int { location, .. } | Self::ErrorTerm { location, .. } diff --git a/crates/aiken-lang/src/format.rs b/crates/aiken-lang/src/format.rs index a6e71b00..9b8cd0d3 100644 --- a/crates/aiken-lang/src/format.rs +++ b/crates/aiken-lang/src/format.rs @@ -800,6 +800,8 @@ impl<'comments> Formatter<'comments> { } UntypedExpr::ErrorTerm { .. } => "error".to_doc(), + + UntypedExpr::TraceIfFalse { value, .. } => self.trace_if_false(value), }; commented(document, comments) @@ -814,6 +816,10 @@ impl<'comments> Formatter<'comments> { } } + pub fn trace_if_false<'a>(&mut self, value: &'a UntypedExpr) -> Document<'a> { + docvec![self.wrap_unary_op(value), "?"] + } + pub fn trace<'a>( &mut self, kind: &'a TraceKind, diff --git a/crates/aiken-lang/src/tipo/expr.rs b/crates/aiken-lang/src/tipo/expr.rs index ac5686e4..52019b78 100644 --- a/crates/aiken-lang/src/tipo/expr.rs +++ b/crates/aiken-lang/src/tipo/expr.rs @@ -225,6 +225,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { | UntypedExpr::TupleIndex { .. } | UntypedExpr::UnOp { .. } | UntypedExpr::Var { .. } + | UntypedExpr::TraceIfFalse { .. } | UntypedExpr::When { .. } => Ok(()), } } @@ -361,6 +362,10 @@ impl<'a, 'b> ExprTyper<'a, 'b> { value, op, } => self.infer_un_op(location, value, op), + + UntypedExpr::TraceIfFalse { value, location } => { + self.infer_trace_if_false(*value, location) + } } }