Remove 'Todo' from the AST & AIR
Todo is fundamentally just a trace and an error. The only reason we kept it as a separate element in the AST is for the formatter to work out whether it should format something back to a todo or something else. However, this introduces redundancy in the code internally and makes the AIR more complicated than it needs to be. Both todo and errors can actually be represented as trace + errors, and we only need to record their preferred shape when parsing so that we can format them back to what's expected.
This commit is contained in:
parent
7b676643bd
commit
6525f21712
|
@ -235,12 +235,6 @@ pub enum Air {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Misc.
|
// Misc.
|
||||||
Todo {
|
|
||||||
scope: Vec<u64>,
|
|
||||||
label: Option<String>,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
|
|
||||||
ErrorTerm {
|
ErrorTerm {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
|
@ -290,7 +284,6 @@ impl Air {
|
||||||
| Air::ListExpose { scope, .. }
|
| Air::ListExpose { scope, .. }
|
||||||
| Air::TupleAccessor { scope, .. }
|
| Air::TupleAccessor { scope, .. }
|
||||||
| Air::TupleIndex { scope, .. }
|
| Air::TupleIndex { scope, .. }
|
||||||
| Air::Todo { scope, .. }
|
|
||||||
| Air::ErrorTerm { scope, .. }
|
| Air::ErrorTerm { scope, .. }
|
||||||
| Air::Trace { scope, .. } => scope.clone(),
|
| Air::Trace { scope, .. } => scope.clone(),
|
||||||
}
|
}
|
||||||
|
@ -373,7 +366,6 @@ impl Air {
|
||||||
| Air::ListExpose { tipo, .. }
|
| Air::ListExpose { tipo, .. }
|
||||||
| Air::TupleAccessor { tipo, .. }
|
| Air::TupleAccessor { tipo, .. }
|
||||||
| Air::TupleIndex { tipo, .. }
|
| Air::TupleIndex { tipo, .. }
|
||||||
| Air::Todo { tipo, .. }
|
|
||||||
| Air::ErrorTerm { tipo, .. }
|
| Air::ErrorTerm { tipo, .. }
|
||||||
| Air::Trace { tipo, .. } => Some(tipo.clone()),
|
| Air::Trace { tipo, .. } => Some(tipo.clone()),
|
||||||
|
|
||||||
|
|
|
@ -995,9 +995,10 @@ pub struct RecordUpdateSpread {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum TodoKind {
|
pub enum TraceKind {
|
||||||
Keyword,
|
Trace,
|
||||||
EmptyFunction,
|
Todo,
|
||||||
|
Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
|
|
|
@ -1678,15 +1678,6 @@ pub fn monomorphize(
|
||||||
needs_variant = true;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::Todo { scope, label, tipo } => {
|
|
||||||
if tipo.is_generic() {
|
|
||||||
let mut tipo = tipo.clone();
|
|
||||||
find_generics_to_replace(&mut tipo, &generic_types);
|
|
||||||
|
|
||||||
new_air[index] = Air::Todo { scope, tipo, label };
|
|
||||||
needs_variant = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Air::ErrorTerm { scope, tipo } => {
|
Air::ErrorTerm { scope, tipo } => {
|
||||||
if tipo.is_generic() {
|
if tipo.is_generic() {
|
||||||
let mut tipo = tipo.clone();
|
let mut tipo = tipo.clone();
|
||||||
|
|
|
@ -5,8 +5,7 @@ use vec1::Vec1;
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Annotation, Arg, AssignmentKind, BinOp, CallArg, Clause, DefinitionLocation, IfBranch,
|
Annotation, Arg, AssignmentKind, BinOp, CallArg, Clause, DefinitionLocation, IfBranch,
|
||||||
Pattern, RecordUpdateSpread, Span, TodoKind, TypedRecordUpdateArg, UnOp,
|
Pattern, RecordUpdateSpread, Span, TypedRecordUpdateArg, UnOp, UntypedRecordUpdateArg,
|
||||||
UntypedRecordUpdateArg,
|
|
||||||
},
|
},
|
||||||
builtins::void,
|
builtins::void,
|
||||||
tipo::{ModuleValueConstructor, PatternConstructor, Type, ValueConstructor},
|
tipo::{ModuleValueConstructor, PatternConstructor, Type, ValueConstructor},
|
||||||
|
@ -143,12 +142,6 @@ pub enum TypedExpr {
|
||||||
tuple: Box<Self>,
|
tuple: Box<Self>,
|
||||||
},
|
},
|
||||||
|
|
||||||
Todo {
|
|
||||||
location: Span,
|
|
||||||
label: Option<String>,
|
|
||||||
tipo: Arc<Type>,
|
|
||||||
},
|
|
||||||
|
|
||||||
ErrorTerm {
|
ErrorTerm {
|
||||||
location: Span,
|
location: Span,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
|
@ -176,7 +169,6 @@ impl TypedExpr {
|
||||||
Self::Trace { then, .. } => then.tipo(),
|
Self::Trace { then, .. } => then.tipo(),
|
||||||
Self::Fn { tipo, .. }
|
Self::Fn { tipo, .. }
|
||||||
| Self::Int { tipo, .. }
|
| Self::Int { tipo, .. }
|
||||||
| Self::Todo { tipo, .. }
|
|
||||||
| Self::ErrorTerm { tipo, .. }
|
| Self::ErrorTerm { tipo, .. }
|
||||||
| Self::When { tipo, .. }
|
| Self::When { tipo, .. }
|
||||||
| Self::List { tipo, .. }
|
| Self::List { tipo, .. }
|
||||||
|
@ -222,7 +214,6 @@ impl TypedExpr {
|
||||||
| TypedExpr::List { .. }
|
| TypedExpr::List { .. }
|
||||||
| TypedExpr::Call { .. }
|
| TypedExpr::Call { .. }
|
||||||
| TypedExpr::When { .. }
|
| TypedExpr::When { .. }
|
||||||
| TypedExpr::Todo { .. }
|
|
||||||
| TypedExpr::ErrorTerm { .. }
|
| TypedExpr::ErrorTerm { .. }
|
||||||
| TypedExpr::BinOp { .. }
|
| TypedExpr::BinOp { .. }
|
||||||
| TypedExpr::Tuple { .. }
|
| TypedExpr::Tuple { .. }
|
||||||
|
@ -261,7 +252,6 @@ impl TypedExpr {
|
||||||
| Self::Int { location, .. }
|
| Self::Int { location, .. }
|
||||||
| Self::Var { location, .. }
|
| Self::Var { location, .. }
|
||||||
| Self::Trace { location, .. }
|
| Self::Trace { location, .. }
|
||||||
| Self::Todo { location, .. }
|
|
||||||
| Self::ErrorTerm { location, .. }
|
| Self::ErrorTerm { location, .. }
|
||||||
| Self::When { location, .. }
|
| Self::When { location, .. }
|
||||||
| Self::Call { location, .. }
|
| Self::Call { location, .. }
|
||||||
|
@ -297,7 +287,6 @@ impl TypedExpr {
|
||||||
| Self::Int { location, .. }
|
| Self::Int { location, .. }
|
||||||
| Self::Trace { location, .. }
|
| Self::Trace { location, .. }
|
||||||
| Self::Var { location, .. }
|
| Self::Var { location, .. }
|
||||||
| Self::Todo { location, .. }
|
|
||||||
| Self::ErrorTerm { location, .. }
|
| Self::ErrorTerm { location, .. }
|
||||||
| Self::When { location, .. }
|
| Self::When { location, .. }
|
||||||
| Self::Call { location, .. }
|
| Self::Call { location, .. }
|
||||||
|
@ -420,12 +409,6 @@ pub enum UntypedExpr {
|
||||||
tuple: Box<Self>,
|
tuple: Box<Self>,
|
||||||
},
|
},
|
||||||
|
|
||||||
Todo {
|
|
||||||
kind: TodoKind,
|
|
||||||
location: Span,
|
|
||||||
label: Option<String>,
|
|
||||||
},
|
|
||||||
|
|
||||||
ErrorTerm {
|
ErrorTerm {
|
||||||
location: Span,
|
location: Span,
|
||||||
},
|
},
|
||||||
|
@ -444,7 +427,22 @@ pub enum UntypedExpr {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const DEFAULT_TODO_STR: &str = "aiken::todo";
|
||||||
|
|
||||||
|
pub const DEFAULT_ERROR_STR: &str = "aiken::error";
|
||||||
|
|
||||||
impl UntypedExpr {
|
impl UntypedExpr {
|
||||||
|
pub fn todo(location: Span, reason: Option<Self>) -> Self {
|
||||||
|
UntypedExpr::Trace {
|
||||||
|
location,
|
||||||
|
then: Box::new(UntypedExpr::ErrorTerm { location }),
|
||||||
|
text: Box::new(reason.unwrap_or_else(|| UntypedExpr::String {
|
||||||
|
location,
|
||||||
|
value: DEFAULT_TODO_STR.to_string(),
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn append_in_sequence(self, next: Self) -> Self {
|
pub fn append_in_sequence(self, next: Self) -> Self {
|
||||||
let location = Span {
|
let location = Span {
|
||||||
start: self.location().start,
|
start: self.location().start,
|
||||||
|
@ -500,7 +498,6 @@ impl UntypedExpr {
|
||||||
Self::Fn { location, .. }
|
Self::Fn { location, .. }
|
||||||
| Self::Var { location, .. }
|
| Self::Var { location, .. }
|
||||||
| Self::Int { location, .. }
|
| Self::Int { location, .. }
|
||||||
| Self::Todo { location, .. }
|
|
||||||
| Self::ErrorTerm { location, .. }
|
| Self::ErrorTerm { location, .. }
|
||||||
| Self::When { location, .. }
|
| Self::When { location, .. }
|
||||||
| Self::Call { location, .. }
|
| Self::Call { location, .. }
|
||||||
|
|
|
@ -654,9 +654,6 @@ impl<'comments> Formatter<'comments> {
|
||||||
final_else,
|
final_else,
|
||||||
..
|
..
|
||||||
} => self.if_expr(branches, final_else),
|
} => self.if_expr(branches, final_else),
|
||||||
UntypedExpr::Todo { label: None, .. } => "todo".to_doc(),
|
|
||||||
|
|
||||||
UntypedExpr::Todo { label: Some(l), .. } => docvec!["todo(\"", l, "\")"],
|
|
||||||
|
|
||||||
UntypedExpr::PipeLine { expressions, .. } => self.pipeline(expressions),
|
UntypedExpr::PipeLine { expressions, .. } => self.pipeline(expressions),
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub mod lexer;
|
||||||
pub mod token;
|
pub mod token;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{self, BinOp, Span, TodoKind, UnOp, UntypedDefinition, CAPTURE_VARIABLE},
|
ast::{self, BinOp, Span, UnOp, UntypedDefinition, CAPTURE_VARIABLE},
|
||||||
expr,
|
expr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -254,11 +254,7 @@ pub fn fn_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseEr
|
||||||
|((((opt_pub, name), (arguments, args_span)), return_annotation), body), span| {
|
|((((opt_pub, name), (arguments, args_span)), return_annotation), body), span| {
|
||||||
ast::UntypedDefinition::Fn(ast::Function {
|
ast::UntypedDefinition::Fn(ast::Function {
|
||||||
arguments,
|
arguments,
|
||||||
body: body.unwrap_or(expr::UntypedExpr::Todo {
|
body: body.unwrap_or_else(|| expr::UntypedExpr::todo(span, None)),
|
||||||
kind: TodoKind::EmptyFunction,
|
|
||||||
location: span,
|
|
||||||
label: None,
|
|
||||||
}),
|
|
||||||
doc: None,
|
doc: None,
|
||||||
location: Span {
|
location: Span {
|
||||||
start: span.start,
|
start: span.start,
|
||||||
|
@ -291,11 +287,7 @@ pub fn test_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = Parse
|
||||||
.map_with_span(|((name, span_end), body), span| {
|
.map_with_span(|((name, span_end), body), span| {
|
||||||
ast::UntypedDefinition::Test(ast::Function {
|
ast::UntypedDefinition::Test(ast::Function {
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: body.unwrap_or(expr::UntypedExpr::Todo {
|
body: body.unwrap_or_else(|| expr::UntypedExpr::todo(span, None)),
|
||||||
kind: TodoKind::EmptyFunction,
|
|
||||||
location: span,
|
|
||||||
label: None,
|
|
||||||
}),
|
|
||||||
doc: None,
|
doc: None,
|
||||||
location: span_end,
|
location: span_end,
|
||||||
end_position: span.end - 1,
|
end_position: span.end - 1,
|
||||||
|
@ -598,7 +590,8 @@ pub fn expr_seq_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseE
|
||||||
then: Box::new(then_),
|
then: Box::new(then_),
|
||||||
text: Box::new(text),
|
text: Box::new(text),
|
||||||
}),
|
}),
|
||||||
todo_parser(r.clone(), Token::ErrorTerm, "aiken::error"),
|
todo_parser(r.clone(), Token::ErrorTerm),
|
||||||
|
todo_parser(r.clone(), Token::Todo),
|
||||||
expr_parser(r.clone())
|
expr_parser(r.clone())
|
||||||
.then(r.repeated())
|
.then(r.repeated())
|
||||||
.foldl(|current, next| current.append_in_sequence(next)),
|
.foldl(|current, next| current.append_in_sequence(next)),
|
||||||
|
@ -606,33 +599,23 @@ pub fn expr_seq_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseE
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn todo_parser<'a>(
|
pub fn todo_parser(
|
||||||
r: Recursive<'a, Token, expr::UntypedExpr, ParseError>,
|
r: Recursive<'_, Token, expr::UntypedExpr, ParseError>,
|
||||||
keyword: Token,
|
keyword: Token,
|
||||||
default_value: &'a str,
|
) -> impl Parser<Token, expr::UntypedExpr, Error = ParseError> + '_ {
|
||||||
) -> impl Parser<Token, expr::UntypedExpr, Error = ParseError> + 'a {
|
just(keyword.clone())
|
||||||
just(keyword)
|
|
||||||
.ignore_then(expr_parser(r.clone()).or_not())
|
.ignore_then(expr_parser(r.clone()).or_not())
|
||||||
.then(r.clone().or_not())
|
.map_with_span(move |text, span| expr::UntypedExpr::Trace {
|
||||||
.map_with_span(|(text, then_), span| match then_ {
|
|
||||||
None => expr::UntypedExpr::Trace {
|
|
||||||
location: span,
|
location: span,
|
||||||
then: Box::new(expr::UntypedExpr::ErrorTerm { location: span }),
|
then: Box::new(expr::UntypedExpr::ErrorTerm { location: span }),
|
||||||
text: Box::new(text.unwrap_or_else(|| expr::UntypedExpr::String {
|
text: Box::new(text.unwrap_or_else(|| expr::UntypedExpr::String {
|
||||||
location: span,
|
location: span,
|
||||||
value: default_value.to_string(),
|
value: match keyword {
|
||||||
})),
|
Token::ErrorTerm => expr::DEFAULT_ERROR_STR.to_string(),
|
||||||
|
Token::Todo => expr::DEFAULT_TODO_STR.to_string(),
|
||||||
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
Some(e) => expr::UntypedExpr::Trace {
|
|
||||||
location: span,
|
|
||||||
then: Box::new(
|
|
||||||
expr::UntypedExpr::ErrorTerm { location: span }.append_in_sequence(e),
|
|
||||||
),
|
|
||||||
text: Box::new(text.unwrap_or_else(|| expr::UntypedExpr::String {
|
|
||||||
location: span,
|
|
||||||
value: default_value.to_string(),
|
|
||||||
})),
|
})),
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -946,6 +929,7 @@ pub fn expr_parser(
|
||||||
just(Token::RightParen),
|
just(Token::RightParen),
|
||||||
),
|
),
|
||||||
just(Token::ErrorTerm).rewind().ignore_then(seq_r.clone()),
|
just(Token::ErrorTerm).rewind().ignore_then(seq_r.clone()),
|
||||||
|
just(Token::Todo).rewind().ignore_then(seq_r.clone()),
|
||||||
));
|
));
|
||||||
|
|
||||||
let anon_fn_parser = just(Token::Fn)
|
let anon_fn_parser = just(Token::Fn)
|
||||||
|
|
|
@ -308,10 +308,15 @@ fn empty_function() {
|
||||||
code,
|
code,
|
||||||
vec![ast::UntypedDefinition::Fn(Function {
|
vec![ast::UntypedDefinition::Fn(Function {
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: expr::UntypedExpr::Todo {
|
body: expr::UntypedExpr::Trace {
|
||||||
kind: ast::TodoKind::EmptyFunction,
|
|
||||||
location: Span::new((), 0..15),
|
location: Span::new((), 0..15),
|
||||||
label: None,
|
text: Box::new(expr::UntypedExpr::String {
|
||||||
|
value: "aiken::todo".to_string(),
|
||||||
|
location: Span::new((), 0..15),
|
||||||
|
}),
|
||||||
|
then: Box::new(expr::UntypedExpr::ErrorTerm {
|
||||||
|
location: Span::new((), 0..15),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
doc: None,
|
doc: None,
|
||||||
location: Span::new((), 0..12),
|
location: Span::new((), 0..12),
|
||||||
|
@ -1781,10 +1786,15 @@ fn function_def() {
|
||||||
vec![ast::UntypedDefinition::Fn(Function {
|
vec![ast::UntypedDefinition::Fn(Function {
|
||||||
doc: None,
|
doc: None,
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: expr::UntypedExpr::Todo {
|
body: expr::UntypedExpr::Trace {
|
||||||
kind: ast::TodoKind::EmptyFunction,
|
|
||||||
location: Span::new((), 0..11),
|
location: Span::new((), 0..11),
|
||||||
label: None,
|
text: Box::new(expr::UntypedExpr::String {
|
||||||
|
value: "aiken::todo".to_string(),
|
||||||
|
location: Span::new((), 0..11),
|
||||||
|
}),
|
||||||
|
then: Box::new(expr::UntypedExpr::ErrorTerm {
|
||||||
|
location: Span::new((), 0..11),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
location: Span::new((), 0..8),
|
location: Span::new((), 0..8),
|
||||||
name: "foo".to_string(),
|
name: "foo".to_string(),
|
||||||
|
@ -2710,7 +2720,6 @@ fn parse_keyword_error() {
|
||||||
let code = indoc! {r#"
|
let code = indoc! {r#"
|
||||||
fn foo() {
|
fn foo() {
|
||||||
error "not implemented"
|
error "not implemented"
|
||||||
Void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bar() {
|
fn bar() {
|
||||||
|
@ -2726,18 +2735,9 @@ fn parse_keyword_error() {
|
||||||
ast::Definition::Fn(Function {
|
ast::Definition::Fn(Function {
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: expr::UntypedExpr::Trace {
|
body: expr::UntypedExpr::Trace {
|
||||||
location: Span::new((), 13..43),
|
location: Span::new((), 13..36),
|
||||||
then: Box::new(expr::UntypedExpr::Sequence {
|
then: Box::new(expr::UntypedExpr::ErrorTerm {
|
||||||
location: Span::new((), 13..43),
|
location: Span::new((), 13..36),
|
||||||
expressions: vec![
|
|
||||||
expr::UntypedExpr::ErrorTerm {
|
|
||||||
location: Span::new((), 13..43),
|
|
||||||
},
|
|
||||||
expr::UntypedExpr::Var {
|
|
||||||
location: Span::new((), 39..43),
|
|
||||||
name: "Void".to_string(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
text: Box::new(expr::UntypedExpr::String {
|
text: Box::new(expr::UntypedExpr::String {
|
||||||
location: Span::new((), 19..36),
|
location: Span::new((), 19..36),
|
||||||
|
@ -2750,22 +2750,22 @@ fn parse_keyword_error() {
|
||||||
public: false,
|
public: false,
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
end_position: 44,
|
end_position: 37,
|
||||||
}),
|
}),
|
||||||
ast::Definition::Fn(Function {
|
ast::Definition::Fn(Function {
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: expr::UntypedExpr::When {
|
body: expr::UntypedExpr::When {
|
||||||
location: Span::new((), 60..116),
|
location: Span::new((), 53..109),
|
||||||
subjects: vec![expr::UntypedExpr::Var {
|
subjects: vec![expr::UntypedExpr::Var {
|
||||||
location: Span::new((), 65..66),
|
location: Span::new((), 58..59),
|
||||||
name: "x".to_string(),
|
name: "x".to_string(),
|
||||||
}],
|
}],
|
||||||
clauses: vec![
|
clauses: vec![
|
||||||
ast::Clause {
|
ast::Clause {
|
||||||
location: Span::new((), 78..95),
|
location: Span::new((), 71..88),
|
||||||
pattern: vec![ast::Pattern::Constructor {
|
pattern: vec![ast::Pattern::Constructor {
|
||||||
is_record: false,
|
is_record: false,
|
||||||
location: Span::new((), 78..87),
|
location: Span::new((), 71..80),
|
||||||
name: "Something".to_string(),
|
name: "Something".to_string(),
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
module: None,
|
module: None,
|
||||||
|
@ -2776,25 +2776,25 @@ fn parse_keyword_error() {
|
||||||
alternative_patterns: vec![],
|
alternative_patterns: vec![],
|
||||||
guard: None,
|
guard: None,
|
||||||
then: expr::UntypedExpr::Var {
|
then: expr::UntypedExpr::Var {
|
||||||
location: Span::new((), 91..95),
|
location: Span::new((), 84..88),
|
||||||
name: "Void".to_string(),
|
name: "Void".to_string(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ast::Clause {
|
ast::Clause {
|
||||||
location: Span::new((), 102..112),
|
location: Span::new((), 95..105),
|
||||||
pattern: vec![ast::Pattern::Discard {
|
pattern: vec![ast::Pattern::Discard {
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
location: Span::new((), 102..103),
|
location: Span::new((), 95..96),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
alternative_patterns: vec![],
|
||||||
guard: None,
|
guard: None,
|
||||||
then: expr::UntypedExpr::Trace {
|
then: expr::UntypedExpr::Trace {
|
||||||
location: Span::new((), 107..112),
|
location: Span::new((), 100..105),
|
||||||
then: Box::new(expr::UntypedExpr::ErrorTerm {
|
then: Box::new(expr::UntypedExpr::ErrorTerm {
|
||||||
location: Span::new((), 107..112),
|
location: Span::new((), 100..105),
|
||||||
}),
|
}),
|
||||||
text: Box::new(expr::UntypedExpr::String {
|
text: Box::new(expr::UntypedExpr::String {
|
||||||
location: Span::new((), 107..112),
|
location: Span::new((), 100..105),
|
||||||
value: "aiken::error".to_string(),
|
value: "aiken::error".to_string(),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
@ -2802,12 +2802,110 @@ fn parse_keyword_error() {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
doc: None,
|
doc: None,
|
||||||
location: Span::new((), 47..55),
|
location: Span::new((), 40..48),
|
||||||
name: "bar".to_string(),
|
name: "bar".to_string(),
|
||||||
public: false,
|
public: false,
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
end_position: 117,
|
end_position: 110,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_keyword_todo() {
|
||||||
|
let code = indoc! {r#"
|
||||||
|
fn foo() {
|
||||||
|
todo "not implemented"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar() {
|
||||||
|
when x is {
|
||||||
|
Something -> Void
|
||||||
|
_ -> todo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#};
|
||||||
|
assert_definitions(
|
||||||
|
code,
|
||||||
|
vec![
|
||||||
|
ast::Definition::Fn(Function {
|
||||||
|
arguments: vec![],
|
||||||
|
body: expr::UntypedExpr::Trace {
|
||||||
|
location: Span::new((), 13..35),
|
||||||
|
then: Box::new(expr::UntypedExpr::ErrorTerm {
|
||||||
|
location: Span::new((), 13..35),
|
||||||
|
}),
|
||||||
|
text: Box::new(expr::UntypedExpr::String {
|
||||||
|
location: Span::new((), 18..35),
|
||||||
|
value: "not implemented".to_string(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
doc: None,
|
||||||
|
location: Span::new((), 0..8),
|
||||||
|
name: "foo".to_string(),
|
||||||
|
public: false,
|
||||||
|
return_annotation: None,
|
||||||
|
return_type: (),
|
||||||
|
end_position: 36,
|
||||||
|
}),
|
||||||
|
ast::Definition::Fn(Function {
|
||||||
|
arguments: vec![],
|
||||||
|
body: expr::UntypedExpr::When {
|
||||||
|
location: Span::new((), 52..107),
|
||||||
|
subjects: vec![expr::UntypedExpr::Var {
|
||||||
|
location: Span::new((), 57..58),
|
||||||
|
name: "x".to_string(),
|
||||||
|
}],
|
||||||
|
clauses: vec![
|
||||||
|
ast::Clause {
|
||||||
|
location: Span::new((), 70..87),
|
||||||
|
pattern: vec![ast::Pattern::Constructor {
|
||||||
|
is_record: false,
|
||||||
|
location: Span::new((), 70..79),
|
||||||
|
name: "Something".to_string(),
|
||||||
|
arguments: vec![],
|
||||||
|
module: None,
|
||||||
|
constructor: (),
|
||||||
|
with_spread: false,
|
||||||
|
tipo: (),
|
||||||
|
}],
|
||||||
|
alternative_patterns: vec![],
|
||||||
|
guard: None,
|
||||||
|
then: expr::UntypedExpr::Var {
|
||||||
|
location: Span::new((), 83..87),
|
||||||
|
name: "Void".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ast::Clause {
|
||||||
|
location: Span::new((), 94..103),
|
||||||
|
pattern: vec![ast::Pattern::Discard {
|
||||||
|
name: "_".to_string(),
|
||||||
|
location: Span::new((), 94..95),
|
||||||
|
}],
|
||||||
|
alternative_patterns: vec![],
|
||||||
|
guard: None,
|
||||||
|
then: expr::UntypedExpr::Trace {
|
||||||
|
location: Span::new((), 99..103),
|
||||||
|
then: Box::new(expr::UntypedExpr::ErrorTerm {
|
||||||
|
location: Span::new((), 99..103),
|
||||||
|
}),
|
||||||
|
text: Box::new(expr::UntypedExpr::String {
|
||||||
|
location: Span::new((), 99..103),
|
||||||
|
value: "aiken::todo".to_string(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
doc: None,
|
||||||
|
location: Span::new((), 39..47),
|
||||||
|
name: "bar".to_string(),
|
||||||
|
public: false,
|
||||||
|
return_annotation: None,
|
||||||
|
return_type: (),
|
||||||
|
end_position: 108,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::Type;
|
use super::Type;
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Annotation, BinOp, CallArg, Span, TodoKind, UntypedPattern},
|
ast::{Annotation, BinOp, CallArg, Span, UntypedPattern},
|
||||||
expr::{self, UntypedExpr},
|
expr::{self, UntypedExpr},
|
||||||
format::Formatter,
|
format::Formatter,
|
||||||
levenshtein,
|
levenshtein,
|
||||||
|
@ -1118,7 +1118,6 @@ pub enum Warning {
|
||||||
#[diagnostic(help("You probably want to replace that one with real code... eventually."))]
|
#[diagnostic(help("You probably want to replace that one with real code... eventually."))]
|
||||||
#[diagnostic(code("todo"))]
|
#[diagnostic(code("todo"))]
|
||||||
Todo {
|
Todo {
|
||||||
kind: TodoKind,
|
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
|
|
|
@ -5,7 +5,7 @@ use vec1::Vec1;
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Annotation, Arg, ArgName, AssignmentKind, BinOp, CallArg, Clause, ClauseGuard, Constant,
|
Annotation, Arg, ArgName, AssignmentKind, BinOp, CallArg, Clause, ClauseGuard, Constant,
|
||||||
RecordUpdateSpread, Span, TodoKind, TypedArg, TypedCallArg, TypedClause, TypedClauseGuard,
|
RecordUpdateSpread, Span, TypedArg, TypedCallArg, TypedClause, TypedClauseGuard,
|
||||||
TypedConstant, TypedIfBranch, TypedMultiPattern, TypedRecordUpdateArg, UnOp, UntypedArg,
|
TypedConstant, TypedIfBranch, TypedMultiPattern, TypedRecordUpdateArg, UnOp, UntypedArg,
|
||||||
UntypedClause, UntypedClauseGuard, UntypedConstant, UntypedIfBranch, UntypedMultiPattern,
|
UntypedClause, UntypedClauseGuard, UntypedConstant, UntypedIfBranch, UntypedMultiPattern,
|
||||||
UntypedPattern, UntypedRecordUpdateArg,
|
UntypedPattern, UntypedRecordUpdateArg,
|
||||||
|
@ -221,7 +221,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
| UntypedExpr::RecordUpdate { .. }
|
| UntypedExpr::RecordUpdate { .. }
|
||||||
| UntypedExpr::Sequence { .. }
|
| UntypedExpr::Sequence { .. }
|
||||||
| UntypedExpr::String { .. }
|
| UntypedExpr::String { .. }
|
||||||
| UntypedExpr::Todo { .. }
|
|
||||||
| UntypedExpr::Tuple { .. }
|
| UntypedExpr::Tuple { .. }
|
||||||
| UntypedExpr::TupleIndex { .. }
|
| UntypedExpr::TupleIndex { .. }
|
||||||
| UntypedExpr::UnOp { .. }
|
| UntypedExpr::UnOp { .. }
|
||||||
|
@ -249,13 +248,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
/// returning an error.
|
/// returning an error.
|
||||||
pub fn infer(&mut self, expr: UntypedExpr) -> Result<TypedExpr, Error> {
|
pub fn infer(&mut self, expr: UntypedExpr) -> Result<TypedExpr, Error> {
|
||||||
match expr {
|
match expr {
|
||||||
UntypedExpr::Todo {
|
|
||||||
location,
|
|
||||||
label,
|
|
||||||
kind,
|
|
||||||
..
|
|
||||||
} => Ok(self.infer_todo(location, kind, label)),
|
|
||||||
|
|
||||||
UntypedExpr::ErrorTerm { location } => Ok(self.infer_error_term(location)),
|
UntypedExpr::ErrorTerm { location } => Ok(self.infer_error_term(location)),
|
||||||
|
|
||||||
UntypedExpr::Var { location, name, .. } => self.infer_var(name, location),
|
UntypedExpr::Var { location, name, .. } => self.infer_var(name, location),
|
||||||
|
@ -1855,22 +1847,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_todo(&mut self, location: Span, kind: TodoKind, label: Option<String>) -> TypedExpr {
|
|
||||||
let tipo = self.new_unbound_var();
|
|
||||||
|
|
||||||
self.environment.warnings.push(Warning::Todo {
|
|
||||||
kind,
|
|
||||||
location,
|
|
||||||
tipo: tipo.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
TypedExpr::Todo {
|
|
||||||
location,
|
|
||||||
label,
|
|
||||||
tipo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn infer_error_term(&mut self, location: Span) -> TypedExpr {
|
fn infer_error_term(&mut self, location: Span) -> TypedExpr {
|
||||||
let tipo = self.new_unbound_var();
|
let tipo = self.new_unbound_var();
|
||||||
|
|
||||||
|
@ -1889,6 +1865,13 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
let then = self.infer(then)?;
|
let then = self.infer(then)?;
|
||||||
let tipo = then.tipo();
|
let tipo = then.tipo();
|
||||||
|
|
||||||
|
// TODO: reinstate once we can distinguish traces
|
||||||
|
//
|
||||||
|
// self.environment.warnings.push(Warning::Todo {
|
||||||
|
// location,
|
||||||
|
// tipo: tipo.clone(),
|
||||||
|
// })
|
||||||
|
|
||||||
Ok(TypedExpr::Trace {
|
Ok(TypedExpr::Trace {
|
||||||
location,
|
location,
|
||||||
tipo,
|
tipo,
|
||||||
|
|
|
@ -587,13 +587,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
constants_ir(literal, ir_stack, scope);
|
constants_ir(literal, ir_stack, scope);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TypedExpr::Todo { label, tipo, .. } => {
|
|
||||||
ir_stack.push(Air::Todo {
|
|
||||||
scope,
|
|
||||||
label: label.clone(),
|
|
||||||
tipo: tipo.clone(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
TypedExpr::RecordUpdate {
|
TypedExpr::RecordUpdate {
|
||||||
spread, args, tipo, ..
|
spread, args, tipo, ..
|
||||||
} => {
|
} => {
|
||||||
|
@ -3494,16 +3487,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tuple_index,
|
tuple_index,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Air::Todo { tipo, scope, label } => {
|
|
||||||
let mut replaced_type = tipo.clone();
|
|
||||||
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
|
||||||
|
|
||||||
ir_stack[index] = Air::Todo {
|
|
||||||
scope,
|
|
||||||
label,
|
|
||||||
tipo: replaced_type,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Air::ErrorTerm { tipo, scope } => {
|
Air::ErrorTerm { tipo, scope } => {
|
||||||
let mut replaced_type = tipo.clone();
|
let mut replaced_type = tipo.clone();
|
||||||
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
@ -5286,23 +5269,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::Todo { label, .. } => {
|
|
||||||
let term = apply_wrap(
|
|
||||||
apply_wrap(
|
|
||||||
Term::Builtin(DefaultFunction::Trace).force_wrap(),
|
|
||||||
Term::Constant(
|
|
||||||
UplcConstant::String(
|
|
||||||
label.unwrap_or_else(|| "aiken::todo".to_string()),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Term::Delay(Term::Error.into()),
|
|
||||||
)
|
|
||||||
.force_wrap();
|
|
||||||
|
|
||||||
arg_stack.push(term);
|
|
||||||
}
|
|
||||||
Air::RecordUpdate {
|
Air::RecordUpdate {
|
||||||
highest_index,
|
highest_index,
|
||||||
indices,
|
indices,
|
||||||
|
|
Loading…
Reference in New Issue