feat: allow error to hold a label

This commit is contained in:
rvcas 2022-12-23 15:47:54 -05:00 committed by Lucas
parent 37196a29ee
commit 38a716d94e
5 changed files with 40 additions and 7 deletions

View File

@ -205,6 +205,7 @@ pub enum Air {
ErrorTerm { ErrorTerm {
scope: Vec<u64>, scope: Vec<u64>,
tipo: Arc<Type>, tipo: Arc<Type>,
label: Option<String>,
}, },
Trace { Trace {

View File

@ -151,6 +151,7 @@ pub enum TypedExpr {
ErrorTerm { ErrorTerm {
location: Span, location: Span,
tipo: Arc<Type>, tipo: Arc<Type>,
label: Option<String>,
}, },
RecordUpdate { RecordUpdate {
@ -425,6 +426,7 @@ pub enum UntypedExpr {
ErrorTerm { ErrorTerm {
location: Span, location: Span,
label: Option<String>,
}, },
RecordUpdate { RecordUpdate {

View File

@ -852,8 +852,15 @@ pub fn expr_parser(
}); });
let error_parser = just(Token::ErrorTerm) let error_parser = just(Token::ErrorTerm)
.ignored() .ignore_then(
.map_with_span(|_, span| expr::UntypedExpr::ErrorTerm { location: span }); 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) let tuple = just(Token::Hash)
.ignore_then( .ignore_then(

View File

@ -236,7 +236,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
.. ..
} => Ok(self.infer_todo(location, kind, label)), } => 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), 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<String>) -> TypedExpr {
let tipo = self.new_unbound_var(); let tipo = self.new_unbound_var();
TypedExpr::ErrorTerm { location, tipo } TypedExpr::ErrorTerm {
location,
tipo,
label,
}
} }
fn infer_trace( fn infer_trace(

View File

@ -537,10 +537,11 @@ impl<'a> CodeGenerator<'a> {
todo!("Tuple indexing not implementing yet"); todo!("Tuple indexing not implementing yet");
} }
TypedExpr::ErrorTerm { tipo, .. } => { TypedExpr::ErrorTerm { tipo, label, .. } => {
ir_stack.push(Air::ErrorTerm { ir_stack.push(Air::ErrorTerm {
scope, scope,
tipo: tipo.clone(), tipo: tipo.clone(),
label: label.clone(),
}); });
} }
} }
@ -3739,7 +3740,23 @@ impl<'a> CodeGenerator<'a> {
arg_stack.push(term); 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)
}
}
} }
} }
} }