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 {
scope: Vec<u64>,
tipo: Arc<Type>,
label: Option<String>,
},
Trace {

View File

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

View File

@ -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(

View File

@ -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<String>) -> TypedExpr {
let tipo = self.new_unbound_var();
TypedExpr::ErrorTerm { location, tipo }
TypedExpr::ErrorTerm {
location,
tipo,
label,
}
}
fn infer_trace(

View File

@ -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)
}
}
}
}
}