From 38a716d94eae49c7c6ec25fb5cea7d78ed629ebc Mon Sep 17 00:00:00 2001 From: rvcas Date: Fri, 23 Dec 2022 15:47:54 -0500 Subject: [PATCH] feat: allow error to hold a label --- crates/aiken-lang/src/air.rs | 1 + crates/aiken-lang/src/expr.rs | 2 ++ crates/aiken-lang/src/parser.rs | 11 +++++++++-- crates/aiken-lang/src/tipo/expr.rs | 12 +++++++++--- crates/aiken-lang/src/uplc.rs | 21 +++++++++++++++++++-- 5 files changed, 40 insertions(+), 7 deletions(-) diff --git a/crates/aiken-lang/src/air.rs b/crates/aiken-lang/src/air.rs index 4ad55444..cb1b67d0 100644 --- a/crates/aiken-lang/src/air.rs +++ b/crates/aiken-lang/src/air.rs @@ -205,6 +205,7 @@ pub enum Air { ErrorTerm { scope: Vec, tipo: Arc, + label: Option, }, Trace { diff --git a/crates/aiken-lang/src/expr.rs b/crates/aiken-lang/src/expr.rs index 530ec438..3b14b287 100644 --- a/crates/aiken-lang/src/expr.rs +++ b/crates/aiken-lang/src/expr.rs @@ -151,6 +151,7 @@ pub enum TypedExpr { ErrorTerm { location: Span, tipo: Arc, + label: Option, }, RecordUpdate { @@ -425,6 +426,7 @@ pub enum UntypedExpr { ErrorTerm { location: Span, + label: Option, }, RecordUpdate { diff --git a/crates/aiken-lang/src/parser.rs b/crates/aiken-lang/src/parser.rs index 68806090..84a1f35a 100644 --- a/crates/aiken-lang/src/parser.rs +++ b/crates/aiken-lang/src/parser.rs @@ -852,8 +852,15 @@ pub fn expr_parser( }); let error_parser = just(Token::ErrorTerm) - .ignored() - .map_with_span(|_, span| expr::UntypedExpr::ErrorTerm { location: span }); + .ignore_then( + select! {Token::String {value} => value} + .delimited_by(just(Token::LeftParen), just(Token::RightParen)) + .or_not(), + ) + .map_with_span(|label, span| expr::UntypedExpr::ErrorTerm { + location: span, + label, + }); let tuple = just(Token::Hash) .ignore_then( diff --git a/crates/aiken-lang/src/tipo/expr.rs b/crates/aiken-lang/src/tipo/expr.rs index 95c47feb..ffafd25f 100644 --- a/crates/aiken-lang/src/tipo/expr.rs +++ b/crates/aiken-lang/src/tipo/expr.rs @@ -236,7 +236,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> { .. } => Ok(self.infer_todo(location, kind, label)), - UntypedExpr::ErrorTerm { location } => Ok(self.infer_error_term(location)), + UntypedExpr::ErrorTerm { location, label } => { + Ok(self.infer_error_term(location, label)) + } UntypedExpr::Var { location, name, .. } => self.infer_var(name, location), @@ -1761,10 +1763,14 @@ impl<'a, 'b> ExprTyper<'a, 'b> { } } - fn infer_error_term(&mut self, location: Span) -> TypedExpr { + fn infer_error_term(&mut self, location: Span, label: Option) -> TypedExpr { let tipo = self.new_unbound_var(); - TypedExpr::ErrorTerm { location, tipo } + TypedExpr::ErrorTerm { + location, + tipo, + label, + } } fn infer_trace( diff --git a/crates/aiken-lang/src/uplc.rs b/crates/aiken-lang/src/uplc.rs index 77ec8941..263e439e 100644 --- a/crates/aiken-lang/src/uplc.rs +++ b/crates/aiken-lang/src/uplc.rs @@ -537,10 +537,11 @@ impl<'a> CodeGenerator<'a> { todo!("Tuple indexing not implementing yet"); } - TypedExpr::ErrorTerm { tipo, .. } => { + TypedExpr::ErrorTerm { tipo, label, .. } => { ir_stack.push(Air::ErrorTerm { scope, tipo: tipo.clone(), + label: label.clone(), }); } } @@ -3739,7 +3740,23 @@ impl<'a> CodeGenerator<'a> { arg_stack.push(term); } - Air::ErrorTerm { .. } => arg_stack.push(Term::Error), + Air::ErrorTerm { label, .. } => { + if let Some(label) = label { + let term = Term::Apply { + function: Term::Apply { + function: Term::Builtin(DefaultFunction::Trace).force_wrap().into(), + argument: Term::Constant(UplcConstant::String(label)).into(), + } + .into(), + argument: Term::Delay(Term::Error.into()).into(), + } + .force_wrap(); + + arg_stack.push(term); + } else { + arg_stack.push(Term::Error) + } + } } } }