feat: some new features
- tuples `#(Int, Int)` - `trace` and `trace("text")`
This commit is contained in:
parent
6066e3176c
commit
0823b78bf8
|
@ -385,12 +385,18 @@ pub enum Annotation {
|
|||
location: Span,
|
||||
name: String,
|
||||
},
|
||||
|
||||
Tuple {
|
||||
location: Span,
|
||||
elems: Vec<Self>,
|
||||
},
|
||||
}
|
||||
|
||||
impl Annotation {
|
||||
pub fn location(&self) -> Span {
|
||||
match self {
|
||||
Annotation::Fn { location, .. }
|
||||
| Annotation::Tuple { location, .. }
|
||||
| Annotation::Var { location, .. }
|
||||
| Annotation::Hole { location, .. }
|
||||
| Annotation::Constructor { location, .. } => *location,
|
||||
|
@ -421,6 +427,19 @@ impl Annotation {
|
|||
}
|
||||
_ => false,
|
||||
},
|
||||
Annotation::Tuple { elems, location: _ } => match other {
|
||||
Annotation::Tuple {
|
||||
elems: o_elems,
|
||||
location: _,
|
||||
} => {
|
||||
elems.len() == o_elems.len()
|
||||
&& elems
|
||||
.iter()
|
||||
.zip(o_elems)
|
||||
.all(|a| a.0.is_logically_equal(a.1))
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
Annotation::Fn {
|
||||
arguments,
|
||||
ret,
|
||||
|
@ -584,10 +603,11 @@ pub enum Pattern<Constructor, Type> {
|
|||
with_spread: bool,
|
||||
tipo: Type,
|
||||
},
|
||||
// Tuple {
|
||||
// location: Span,
|
||||
// elems: Vec<Self>,
|
||||
// },
|
||||
|
||||
Tuple {
|
||||
location: Span,
|
||||
elems: Vec<Self>,
|
||||
},
|
||||
}
|
||||
|
||||
impl<A, B> Pattern<A, B> {
|
||||
|
@ -600,7 +620,7 @@ impl<A, B> Pattern<A, B> {
|
|||
| Pattern::List { location, .. }
|
||||
| Pattern::Discard { location, .. }
|
||||
| Pattern::String { location, .. }
|
||||
// | Pattern::Tuple { location, .. }
|
||||
| Pattern::Tuple { location, .. }
|
||||
// | Pattern::Concatenate { location, .. }
|
||||
| Pattern::Constructor { location, .. } => *location,
|
||||
}
|
||||
|
|
|
@ -438,6 +438,10 @@ pub fn byte_array() -> Arc<Type> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn tuple(elems: Vec<Arc<Type>>) -> Arc<Type> {
|
||||
Arc::new(Type::Tuple { elems })
|
||||
}
|
||||
|
||||
pub fn bool() -> Arc<Type> {
|
||||
Arc::new(Type::App {
|
||||
args: vec![],
|
||||
|
|
|
@ -91,12 +91,10 @@ pub enum TypedExpr {
|
|||
kind: AssignmentKind,
|
||||
},
|
||||
|
||||
Try {
|
||||
Trace {
|
||||
location: Span,
|
||||
tipo: Arc<Type>,
|
||||
value: Box<Self>,
|
||||
then: Box<Self>,
|
||||
pattern: Pattern<PatternConstructor, Arc<Type>>,
|
||||
},
|
||||
|
||||
When {
|
||||
|
@ -130,11 +128,11 @@ pub enum TypedExpr {
|
|||
constructor: ModuleValueConstructor,
|
||||
},
|
||||
|
||||
// Tuple {
|
||||
// location: Span,
|
||||
// tipo: Arc<Type>,
|
||||
// elems: Vec<Self>,
|
||||
// },
|
||||
Tuple {
|
||||
location: Span,
|
||||
tipo: Arc<Type>,
|
||||
elems: Vec<Self>,
|
||||
},
|
||||
|
||||
// TupleIndex {
|
||||
// location: Span,
|
||||
|
@ -166,7 +164,7 @@ impl TypedExpr {
|
|||
match self {
|
||||
Self::Negate { .. } => bool(),
|
||||
Self::Var { constructor, .. } => constructor.tipo.clone(),
|
||||
Self::Try { then, .. } => then.tipo(),
|
||||
Self::Trace { then, .. } => then.tipo(),
|
||||
Self::Fn { tipo, .. }
|
||||
| Self::Int { tipo, .. }
|
||||
| Self::Todo { tipo, .. }
|
||||
|
@ -175,7 +173,7 @@ impl TypedExpr {
|
|||
| Self::Call { tipo, .. }
|
||||
| Self::If { tipo, .. }
|
||||
| Self::BinOp { tipo, .. }
|
||||
// | Self::Tuple { tipo, .. }
|
||||
| Self::Tuple { tipo, .. }
|
||||
| Self::String { tipo, .. }
|
||||
| Self::ByteArray { tipo, .. }
|
||||
// | Self::TupleIndex { tipo, .. }
|
||||
|
@ -194,7 +192,7 @@ impl TypedExpr {
|
|||
self,
|
||||
Self::Int { .. }
|
||||
| Self::List { .. }
|
||||
// | Self::Tuple { .. }
|
||||
| Self::Tuple { .. }
|
||||
| Self::String { .. }
|
||||
| Self::ByteArray { .. }
|
||||
)
|
||||
|
@ -209,13 +207,13 @@ impl TypedExpr {
|
|||
match self {
|
||||
TypedExpr::Fn { .. }
|
||||
| TypedExpr::Int { .. }
|
||||
| TypedExpr::Try { .. }
|
||||
| TypedExpr::Trace { .. }
|
||||
| TypedExpr::List { .. }
|
||||
| TypedExpr::Call { .. }
|
||||
| TypedExpr::When { .. }
|
||||
| TypedExpr::Todo { .. }
|
||||
| TypedExpr::BinOp { .. }
|
||||
// | TypedExpr::Tuple { .. }
|
||||
| TypedExpr::Tuple { .. }
|
||||
| TypedExpr::Negate { .. }
|
||||
| TypedExpr::String { .. }
|
||||
| TypedExpr::Sequence { .. }
|
||||
|
@ -249,14 +247,14 @@ impl TypedExpr {
|
|||
match self {
|
||||
Self::Fn { location, .. }
|
||||
| Self::Int { location, .. }
|
||||
| Self::Try { location, .. }
|
||||
| Self::Trace { location, .. }
|
||||
| Self::Var { location, .. }
|
||||
| Self::Todo { location, .. }
|
||||
| Self::When { location, .. }
|
||||
| Self::Call { location, .. }
|
||||
| Self::List { location, .. }
|
||||
| Self::BinOp { location, .. }
|
||||
// | Self::Tuple { location, .. }
|
||||
| Self::Tuple { location, .. }
|
||||
| Self::String { location, .. }
|
||||
| Self::Negate { location, .. }
|
||||
| Self::Pipeline { location, .. }
|
||||
|
@ -286,7 +284,7 @@ impl TypedExpr {
|
|||
pub fn location(&self) -> Span {
|
||||
match self {
|
||||
Self::Fn { location, .. }
|
||||
| Self::Try { location, .. }
|
||||
| Self::Trace { location, .. }
|
||||
| Self::Int { location, .. }
|
||||
| Self::Var { location, .. }
|
||||
| Self::Todo { location, .. }
|
||||
|
@ -295,7 +293,7 @@ impl TypedExpr {
|
|||
| Self::If { location, .. }
|
||||
| Self::List { location, .. }
|
||||
| Self::BinOp { location, .. }
|
||||
// | Self::Tuple { location, .. }
|
||||
| Self::Tuple { location, .. }
|
||||
| Self::String { location, .. }
|
||||
| Self::Negate { location, .. }
|
||||
| Self::Sequence { location, .. }
|
||||
|
@ -376,12 +374,10 @@ pub enum UntypedExpr {
|
|||
annotation: Option<Annotation>,
|
||||
},
|
||||
|
||||
Try {
|
||||
Trace {
|
||||
location: Span,
|
||||
value: Box<Self>,
|
||||
pattern: Pattern<(), ()>,
|
||||
then: Box<Self>,
|
||||
annotation: Option<Annotation>,
|
||||
text: Option<String>,
|
||||
},
|
||||
|
||||
When {
|
||||
|
@ -402,10 +398,10 @@ pub enum UntypedExpr {
|
|||
container: Box<Self>,
|
||||
},
|
||||
|
||||
// Tuple {
|
||||
// location: Span,
|
||||
// elems: Vec<Self>,
|
||||
// },
|
||||
Tuple {
|
||||
location: Span,
|
||||
elems: Vec<Self>,
|
||||
},
|
||||
// TupleIndex {
|
||||
// location: Span,
|
||||
// index: u64,
|
||||
|
@ -481,7 +477,7 @@ impl UntypedExpr {
|
|||
|
||||
pub fn location(&self) -> Span {
|
||||
match self {
|
||||
Self::Try { then, .. } => then.location(),
|
||||
Self::Trace { then, .. } => then.location(),
|
||||
Self::PipeLine { expressions, .. } => expressions.last().location(),
|
||||
Self::Fn { location, .. }
|
||||
| Self::Var { location, .. }
|
||||
|
@ -492,7 +488,7 @@ impl UntypedExpr {
|
|||
| Self::List { location, .. }
|
||||
| Self::ByteArray { location, .. }
|
||||
| Self::BinOp { location, .. }
|
||||
// | Self::Tuple { location, .. }
|
||||
| Self::Tuple { location, .. }
|
||||
| Self::String { location, .. }
|
||||
| Self::Assignment { location, .. }
|
||||
// | Self::TupleIndex { location, .. }
|
||||
|
@ -519,7 +515,7 @@ impl UntypedExpr {
|
|||
.map(|e| e.start_byte_index())
|
||||
.unwrap_or(location.start),
|
||||
Self::PipeLine { expressions, .. } => expressions.first().start_byte_index(),
|
||||
Self::Try { location, .. } | Self::Assignment { location, .. } => location.start,
|
||||
Self::Trace { location, .. } | Self::Assignment { location, .. } => location.start,
|
||||
_ => self.location().start,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -276,7 +276,7 @@ impl<'comments> Formatter<'comments> {
|
|||
let head = pub_(*public).append("const ").append(name.as_str());
|
||||
let head = match annotation {
|
||||
None => head,
|
||||
Some(t) => head.append(": ").append(self.type_ast(t)),
|
||||
Some(t) => head.append(": ").append(self.annotation(t)),
|
||||
};
|
||||
head.append(" = ").append(self.const_expr(value))
|
||||
}
|
||||
|
@ -410,7 +410,7 @@ impl<'comments> Formatter<'comments> {
|
|||
}
|
||||
}
|
||||
|
||||
fn type_ast<'a>(&mut self, t: &'a Annotation) -> Document<'a> {
|
||||
fn annotation<'a>(&mut self, t: &'a Annotation) -> Document<'a> {
|
||||
match t {
|
||||
Annotation::Hole { name, .. } => name.to_doc(),
|
||||
|
||||
|
@ -430,15 +430,16 @@ impl<'comments> Formatter<'comments> {
|
|||
.append(self.type_arguments(args))
|
||||
.group()
|
||||
.append(" ->")
|
||||
.append(break_("", " ").append(self.type_ast(retrn)).nest(INDENT)),
|
||||
.append(break_("", " ").append(self.annotation(retrn)).nest(INDENT)),
|
||||
|
||||
Annotation::Var { name, .. } => name.to_doc(),
|
||||
Annotation::Tuple { elems, .. } => "#".to_doc().append(self.type_arguments(elems)),
|
||||
}
|
||||
.group()
|
||||
}
|
||||
|
||||
fn type_arguments<'a>(&mut self, args: &'a [Annotation]) -> Document<'a> {
|
||||
wrap_args(args.iter().map(|t| (self.type_ast(t), false)))
|
||||
wrap_args(args.iter().map(|t| (self.annotation(t), false)))
|
||||
}
|
||||
|
||||
pub fn type_alias<'a>(
|
||||
|
@ -457,7 +458,7 @@ impl<'comments> Formatter<'comments> {
|
|||
};
|
||||
|
||||
head.append(" =")
|
||||
.append(line().append(self.type_ast(typ)).group().nest(INDENT))
|
||||
.append(line().append(self.annotation(typ)).group().nest(INDENT))
|
||||
}
|
||||
|
||||
fn fn_arg<'a, A>(&mut self, arg: &'a Arg<A>) -> Document<'a> {
|
||||
|
@ -465,7 +466,11 @@ impl<'comments> Formatter<'comments> {
|
|||
|
||||
let doc = match &arg.annotation {
|
||||
None => arg.arg_name.to_doc(),
|
||||
Some(a) => arg.arg_name.to_doc().append(": ").append(self.type_ast(a)),
|
||||
Some(a) => arg
|
||||
.arg_name
|
||||
.to_doc()
|
||||
.append(": ")
|
||||
.append(self.annotation(a)),
|
||||
}
|
||||
.group();
|
||||
|
||||
|
@ -489,7 +494,7 @@ impl<'comments> Formatter<'comments> {
|
|||
|
||||
// Add return annotation
|
||||
let head = match return_annotation {
|
||||
Some(anno) => head.append(" -> ").append(self.type_ast(anno)),
|
||||
Some(anno) => head.append(" -> ").append(self.annotation(anno)),
|
||||
None => head,
|
||||
}
|
||||
.group();
|
||||
|
@ -526,7 +531,7 @@ impl<'comments> Formatter<'comments> {
|
|||
|
||||
let header = match return_annotation {
|
||||
None => header,
|
||||
Some(t) => header.append(" -> ").append(self.type_ast(t)),
|
||||
Some(t) => header.append(" -> ").append(self.annotation(t)),
|
||||
};
|
||||
|
||||
header
|
||||
|
@ -576,7 +581,7 @@ impl<'comments> Formatter<'comments> {
|
|||
|
||||
let annotation = annotation
|
||||
.as_ref()
|
||||
.map(|a| ": ".to_doc().append(self.type_ast(a)));
|
||||
.map(|a| ": ".to_doc().append(self.annotation(a)));
|
||||
|
||||
let doc = if then.is_some() {
|
||||
keyword.to_doc().force_break()
|
||||
|
@ -697,13 +702,28 @@ impl<'comments> Formatter<'comments> {
|
|||
..
|
||||
} => self.assignment(pattern, value, None, Some(*kind), annotation),
|
||||
|
||||
UntypedExpr::Try {
|
||||
value,
|
||||
pattern,
|
||||
annotation,
|
||||
UntypedExpr::Trace {
|
||||
text: None, then, ..
|
||||
} => "trace"
|
||||
.to_doc()
|
||||
.append(if self.pop_empty_lines(then.start_byte_index()) {
|
||||
lines(2)
|
||||
} else {
|
||||
line()
|
||||
})
|
||||
.append(self.expr(then)),
|
||||
|
||||
UntypedExpr::Trace {
|
||||
text: Some(l),
|
||||
then,
|
||||
..
|
||||
} => self.assignment(pattern, value, Some(then), None, annotation),
|
||||
} => docvec!["trace(\"", l, "\")"]
|
||||
.append(if self.pop_empty_lines(then.start_byte_index()) {
|
||||
lines(2)
|
||||
} else {
|
||||
line()
|
||||
})
|
||||
.append(self.expr(then)),
|
||||
|
||||
UntypedExpr::When {
|
||||
subjects, clauses, ..
|
||||
|
@ -719,6 +739,11 @@ impl<'comments> Formatter<'comments> {
|
|||
arguments: args,
|
||||
..
|
||||
} => self.record_update(constructor, spread, args),
|
||||
|
||||
UntypedExpr::Tuple { elems, .. } => "#"
|
||||
.to_doc()
|
||||
.append(wrap_args(elems.iter().map(|e| (self.wrap_expr(e), false))))
|
||||
.group(),
|
||||
};
|
||||
commented(document, comments)
|
||||
}
|
||||
|
@ -742,7 +767,7 @@ impl<'comments> Formatter<'comments> {
|
|||
) -> Document<'a> {
|
||||
fn is_breakable(expr: &UntypedPattern) -> bool {
|
||||
match expr {
|
||||
Pattern::List { .. } => true,
|
||||
Pattern::Tuple { .. } | Pattern::List { .. } => true,
|
||||
Pattern::Constructor {
|
||||
arguments: args, ..
|
||||
} => !args.is_empty(),
|
||||
|
@ -982,8 +1007,8 @@ impl<'comments> Formatter<'comments> {
|
|||
let arg_comments = self.pop_comments(location.start);
|
||||
|
||||
let arg = match label {
|
||||
Some(l) => l.to_doc().append(": ").append(self.type_ast(annotation)),
|
||||
None => self.type_ast(annotation),
|
||||
Some(l) => l.to_doc().append(": ").append(self.annotation(annotation)),
|
||||
None => self.annotation(annotation),
|
||||
};
|
||||
|
||||
commented(
|
||||
|
@ -1007,8 +1032,8 @@ impl<'comments> Formatter<'comments> {
|
|||
let arg_comments = self.pop_comments(location.start);
|
||||
|
||||
let arg = match label {
|
||||
Some(l) => l.to_doc().append(": ").append(self.type_ast(annotation)),
|
||||
None => self.type_ast(annotation),
|
||||
Some(l) => l.to_doc().append(": ").append(self.annotation(annotation)),
|
||||
None => self.annotation(annotation),
|
||||
};
|
||||
|
||||
(
|
||||
|
@ -1127,7 +1152,7 @@ impl<'comments> Formatter<'comments> {
|
|||
match expr {
|
||||
UntypedExpr::Sequence { .. }
|
||||
| UntypedExpr::Assignment { .. }
|
||||
| UntypedExpr::Try { .. } => "{"
|
||||
| UntypedExpr::Trace { .. } => "{"
|
||||
.to_doc()
|
||||
.append(line().append(self.expr(expr)).nest(INDENT))
|
||||
.append(line())
|
||||
|
@ -1158,7 +1183,7 @@ impl<'comments> Formatter<'comments> {
|
|||
|
||||
fn case_clause_value<'a>(&mut self, expr: &'a UntypedExpr) -> Document<'a> {
|
||||
match expr {
|
||||
UntypedExpr::Try { .. }
|
||||
UntypedExpr::Trace { .. }
|
||||
| UntypedExpr::Sequence { .. }
|
||||
| UntypedExpr::Assignment { .. } => " {"
|
||||
.to_doc()
|
||||
|
@ -1245,6 +1270,11 @@ impl<'comments> Formatter<'comments> {
|
|||
|
||||
Pattern::Discard { name, .. } => name.to_doc(),
|
||||
|
||||
Pattern::Tuple { elems, .. } => "#"
|
||||
.to_doc()
|
||||
.append(wrap_args(elems.iter().map(|e| (self.pattern(e), false))))
|
||||
.group(),
|
||||
|
||||
Pattern::List { elements, tail, .. } => {
|
||||
let elements_document =
|
||||
join(elements.iter().map(|e| self.pattern(e)), break_(",", ", "));
|
||||
|
|
|
@ -327,20 +327,17 @@ pub fn anon_fn_param_parser() -> impl Parser<Token, ast::UntypedArg, Error = Par
|
|||
pub fn expr_seq_parser() -> impl Parser<Token, expr::UntypedExpr, Error = ParseError> {
|
||||
recursive(|r| {
|
||||
choice((
|
||||
just(Token::Try)
|
||||
.ignore_then(pattern_parser())
|
||||
.then(just(Token::Colon).ignore_then(type_parser()).or_not())
|
||||
.then_ignore(just(Token::Equal))
|
||||
.then(expr_parser(r.clone()))
|
||||
just(Token::Trace)
|
||||
.ignore_then(
|
||||
select! {Token::String {value} => value}
|
||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen))
|
||||
.or_not(),
|
||||
)
|
||||
.then(r.clone())
|
||||
.map_with_span(|(((pattern, annotation), value), then_), span| {
|
||||
expr::UntypedExpr::Try {
|
||||
location: span,
|
||||
value: Box::new(value),
|
||||
pattern,
|
||||
then: Box::new(then_),
|
||||
annotation,
|
||||
}
|
||||
.map_with_span(|(text, then_), span| expr::UntypedExpr::Trace {
|
||||
location: span,
|
||||
then: Box::new(then_),
|
||||
text,
|
||||
}),
|
||||
expr_parser(r.clone())
|
||||
.then(r.repeated())
|
||||
|
@ -389,6 +386,18 @@ pub fn expr_parser(
|
|||
label,
|
||||
});
|
||||
|
||||
let tuple = just(Token::Hash)
|
||||
.ignore_then(
|
||||
r.clone()
|
||||
.separated_by(just(Token::Comma))
|
||||
.allow_trailing()
|
||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen)),
|
||||
)
|
||||
.map_with_span(|elems, span| expr::UntypedExpr::Tuple {
|
||||
location: span,
|
||||
elems,
|
||||
});
|
||||
|
||||
let list_parser = just(Token::LeftSquare)
|
||||
.ignore_then(r.clone().separated_by(just(Token::Comma)))
|
||||
.then(choice((
|
||||
|
@ -562,6 +571,7 @@ pub fn expr_parser(
|
|||
int_parser,
|
||||
var_parser,
|
||||
todo_parser,
|
||||
tuple,
|
||||
list_parser,
|
||||
anon_fn_parser,
|
||||
block_parser,
|
||||
|
@ -835,12 +845,24 @@ pub fn expr_parser(
|
|||
pub fn type_parser() -> impl Parser<Token, ast::Annotation, Error = ParseError> {
|
||||
recursive(|r| {
|
||||
choice((
|
||||
// Type hole
|
||||
select! {Token::DiscardName { name } => name}.map_with_span(|name, span| {
|
||||
ast::Annotation::Hole {
|
||||
location: span,
|
||||
name,
|
||||
}
|
||||
}),
|
||||
just(Token::Hash)
|
||||
.ignore_then(
|
||||
r.clone()
|
||||
.separated_by(just(Token::Comma))
|
||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen)),
|
||||
)
|
||||
.map_with_span(|elems, span| ast::Annotation::Tuple {
|
||||
location: span,
|
||||
elems,
|
||||
}),
|
||||
// Function
|
||||
just(Token::Fn)
|
||||
.ignore_then(
|
||||
r.clone()
|
||||
|
@ -855,6 +877,7 @@ pub fn type_parser() -> impl Parser<Token, ast::Annotation, Error = ParseError>
|
|||
arguments,
|
||||
ret: Box::new(ret),
|
||||
}),
|
||||
// Constructor function
|
||||
select! {Token::UpName { name } => name}
|
||||
.then(
|
||||
r.clone()
|
||||
|
@ -869,6 +892,7 @@ pub fn type_parser() -> impl Parser<Token, ast::Annotation, Error = ParseError>
|
|||
name,
|
||||
arguments: arguments.unwrap_or_default(),
|
||||
}),
|
||||
// Constructor Module or type Variable
|
||||
select! {Token::Name { name } => name}
|
||||
.then(
|
||||
just(Token::Dot)
|
||||
|
@ -890,6 +914,7 @@ pub fn type_parser() -> impl Parser<Token, ast::Annotation, Error = ParseError>
|
|||
arguments: arguments.unwrap_or_default(),
|
||||
}
|
||||
} else {
|
||||
// TODO: parse_error(ParseErrorType::NotConstType, SrcSpan { start, end })
|
||||
ast::Annotation::Var {
|
||||
location: span,
|
||||
name: mod_name,
|
||||
|
@ -1058,6 +1083,16 @@ pub fn pattern_parser() -> impl Parser<Token, ast::UntypedPattern, Error = Parse
|
|||
value,
|
||||
}
|
||||
}),
|
||||
just(Token::Hash)
|
||||
.ignore_then(
|
||||
r.clone()
|
||||
.separated_by(just(Token::Comma))
|
||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen)),
|
||||
)
|
||||
.map_with_span(|elems, span| ast::UntypedPattern::Tuple {
|
||||
location: span,
|
||||
elems,
|
||||
}),
|
||||
just(Token::LeftSquare)
|
||||
.ignore_then(r.clone().separated_by(just(Token::Comma)))
|
||||
.then(choice((
|
||||
|
@ -1066,7 +1101,7 @@ pub fn pattern_parser() -> impl Parser<Token, ast::UntypedPattern, Error = Parse
|
|||
just(Token::Comma).ignored().or_not().map(|_| None),
|
||||
)))
|
||||
.then_ignore(just(Token::RightSquare))
|
||||
.validate(|(elements, tail), span: Span, _emit| {
|
||||
.validate(|(elements, tail), span: Span, emit| {
|
||||
let tail = match tail {
|
||||
// There is a tail and it has a Pattern::Var or Pattern::Discard
|
||||
Some(Some(
|
||||
|
@ -1074,8 +1109,12 @@ pub fn pattern_parser() -> impl Parser<Token, ast::UntypedPattern, Error = Parse
|
|||
| ast::UntypedPattern::Discard { .. }),
|
||||
)) => Some(pat),
|
||||
Some(Some(pat)) => {
|
||||
// use emit
|
||||
// return parse_error(ParseErrorType::InvalidTailPattern, pat.location())
|
||||
emit(ParseError::expected_input_found(
|
||||
pat.location(),
|
||||
None,
|
||||
Some(error::Pattern::Match),
|
||||
));
|
||||
|
||||
Some(pat)
|
||||
}
|
||||
// There is a tail but it has no content, implicit discard
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::{collections::HashSet, fmt};
|
||||
use std::collections::HashSet;
|
||||
|
||||
use miette::Diagnostic;
|
||||
|
||||
|
@ -72,7 +72,7 @@ pub enum ErrorKind {
|
|||
#[error("unexpected end")]
|
||||
UnexpectedEnd,
|
||||
#[error("unexpected {0}")]
|
||||
#[diagnostic(help("try removing it"))]
|
||||
#[diagnostic(help("{}", .0.help().unwrap_or_else(|| Box::new(""))))]
|
||||
Unexpected(Pattern),
|
||||
#[error("unclosed {start}")]
|
||||
Unclosed {
|
||||
|
@ -87,12 +87,22 @@ pub enum ErrorKind {
|
|||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Diagnostic, thiserror::Error)]
|
||||
pub enum Pattern {
|
||||
#[error("{0:?}")]
|
||||
Char(char),
|
||||
#[error("{0}")]
|
||||
#[diagnostic(help("try removing it"))]
|
||||
Token(Token),
|
||||
#[error("literal")]
|
||||
Literal,
|
||||
#[error("type name")]
|
||||
TypeIdent,
|
||||
#[error("indentifier")]
|
||||
TermIdent,
|
||||
#[error("end of input")]
|
||||
End,
|
||||
#[error("pattern")]
|
||||
#[diagnostic(help("list spread in match can only have a discard or var"))]
|
||||
Match,
|
||||
}
|
||||
|
||||
impl From<char> for Pattern {
|
||||
|
@ -105,16 +115,3 @@ impl From<Token> for Pattern {
|
|||
Self::Token(tok)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Pattern {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Pattern::Token(token) => write!(f, "{}", token),
|
||||
Pattern::Char(c) => write!(f, "{:?}", c),
|
||||
Pattern::Literal => write!(f, "literal"),
|
||||
Pattern::TypeIdent => write!(f, "type name"),
|
||||
Pattern::TermIdent => write!(f, "identifier"),
|
||||
Pattern::End => write!(f, "end of input"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = ParseError> {
|
|||
just('|').to(Token::Vbar),
|
||||
just("&&").to(Token::AmperAmper),
|
||||
just("\n\n").to(Token::EmptyLine),
|
||||
just('#').to(Token::Hash),
|
||||
));
|
||||
|
||||
let grouping = choice((
|
||||
|
@ -74,7 +75,7 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = ParseError> {
|
|||
"pub" => Token::Pub,
|
||||
"use" => Token::Use,
|
||||
"todo" => Token::Todo,
|
||||
"try" => Token::Try,
|
||||
"trace" => Token::Trace,
|
||||
"type" => Token::Type,
|
||||
"when" => Token::When,
|
||||
_ => {
|
||||
|
|
|
@ -69,7 +69,7 @@ pub enum Token {
|
|||
Pub,
|
||||
Use,
|
||||
Todo,
|
||||
Try,
|
||||
Trace,
|
||||
Type,
|
||||
When,
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ impl fmt::Display for Token {
|
|||
Token::Opaque => "opaque",
|
||||
Token::Pub => "pub",
|
||||
Token::Todo => "todo",
|
||||
Token::Try => "try",
|
||||
Token::Trace => "try",
|
||||
Token::Type => "type",
|
||||
};
|
||||
write!(f, "\"{}\"", s)
|
||||
|
|
|
@ -45,12 +45,16 @@ pub enum Type {
|
|||
|
||||
/// A type variable. See the contained `TypeVar` enum for more information.
|
||||
///
|
||||
Var { tipo: Arc<RefCell<TypeVar>> },
|
||||
Var {
|
||||
tipo: Arc<RefCell<TypeVar>>,
|
||||
},
|
||||
// /// A tuple is an ordered collection of 0 or more values, each of which
|
||||
// /// can have a different type, so the `tuple` type is the sum of all the
|
||||
// /// contained types.
|
||||
// ///
|
||||
// Tuple { elems: Vec<Arc<Type>> },
|
||||
Tuple {
|
||||
elems: Vec<Arc<Type>>,
|
||||
},
|
||||
}
|
||||
|
||||
impl Type {
|
||||
|
@ -185,7 +189,7 @@ impl Type {
|
|||
|
||||
Self::App { args, .. } => args.iter().find_map(|t| t.find_private_type()),
|
||||
|
||||
// Self::Tuple { elems, .. } => elems.iter().find_map(|t| t.find_private_type()),
|
||||
Self::Tuple { elems, .. } => elems.iter().find_map(|t| t.find_private_type()),
|
||||
Self::Fn { ret, args, .. } => ret
|
||||
.find_private_type()
|
||||
.or_else(|| args.iter().find_map(|t| t.find_private_type())),
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::{
|
|||
RecordConstructor, RecordConstructorArg, Span, TypeAlias, TypedDefinition,
|
||||
UnqualifiedImport, UntypedDefinition, Use, PIPE_VARIABLE,
|
||||
},
|
||||
builtins::{self, function, generic_var, unbound_var},
|
||||
builtins::{self, function, generic_var, tuple, unbound_var},
|
||||
tipo::fields::FieldMap,
|
||||
IdGenerator,
|
||||
};
|
||||
|
@ -564,12 +564,13 @@ impl<'a> Environment<'a> {
|
|||
.collect(),
|
||||
self.instantiate(ret.clone(), ids, hydrator),
|
||||
),
|
||||
// Type::Tuple { elems } => tuple(
|
||||
// elems
|
||||
// .iter()
|
||||
// .map(|t| self.instantiate(t.clone(), ids, hydrator))
|
||||
// .collect(),
|
||||
// ),
|
||||
|
||||
Type::Tuple { elems } => tuple(
|
||||
elems
|
||||
.iter()
|
||||
.map(|t| self.instantiate(t.clone(), ids, hydrator))
|
||||
.collect(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1400,6 +1401,7 @@ fn unify_unbound_type(tipo: Arc<Type>, own_id: u64, location: Span) -> Result<()
|
|||
for arg in args {
|
||||
unify_unbound_type(arg.clone(), own_id, location)?
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1407,9 +1409,18 @@ fn unify_unbound_type(tipo: Arc<Type>, own_id: u64, location: Span) -> Result<()
|
|||
for arg in args {
|
||||
unify_unbound_type(arg.clone(), own_id, location)?;
|
||||
}
|
||||
|
||||
unify_unbound_type(ret.clone(), own_id, location)
|
||||
}
|
||||
|
||||
Type::Tuple { elems, .. } => {
|
||||
for elem in elems {
|
||||
unify_unbound_type(elem.clone(), own_id, location)?
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Type::Var { .. } => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -1591,11 +1602,12 @@ pub(crate) fn generalise(t: Arc<Type>, ctx_level: usize) -> Arc<Type> {
|
|||
.collect(),
|
||||
generalise(ret.clone(), ctx_level),
|
||||
),
|
||||
// Type::Tuple { elems } => tuple(
|
||||
// elems
|
||||
// .iter()
|
||||
// .map(|t| generalise(t.clone(), ctx_level))
|
||||
// .collect(),
|
||||
// ),
|
||||
|
||||
Type::Tuple { elems } => tuple(
|
||||
elems
|
||||
.iter()
|
||||
.map(|t| generalise(t.clone(), ctx_level))
|
||||
.collect(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::{
|
|||
UntypedClause, UntypedClauseGuard, UntypedConstant, UntypedIfBranch, UntypedMultiPattern,
|
||||
UntypedPattern, UntypedRecordUpdateArg,
|
||||
},
|
||||
builtins::{bool, byte_array, function, int, list, result, string},
|
||||
builtins::{bool, byte_array, function, int, list, string, tuple},
|
||||
expr::{TypedExpr, UntypedExpr},
|
||||
tipo::fields::FieldMap,
|
||||
};
|
||||
|
@ -245,9 +245,10 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
location,
|
||||
} => self.infer_seq(location, expressions),
|
||||
|
||||
// UntypedExpr::Tuple {
|
||||
// location, elems, ..
|
||||
// } => self.infer_tuple(elems, location),
|
||||
UntypedExpr::Tuple {
|
||||
location, elems, ..
|
||||
} => self.infer_tuple(elems, location),
|
||||
|
||||
UntypedExpr::String {
|
||||
location, value, ..
|
||||
} => Ok(self.infer_string(value, location)),
|
||||
|
@ -278,14 +279,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
..
|
||||
} => self.infer_assignment(pattern, *value, kind, &annotation, location),
|
||||
|
||||
UntypedExpr::Try {
|
||||
location,
|
||||
pattern,
|
||||
value,
|
||||
then,
|
||||
annotation,
|
||||
..
|
||||
} => self.infer_try(pattern, *value, *then, &annotation, location),
|
||||
UntypedExpr::Trace { location, then, .. } => self.infer_trace(*then, location),
|
||||
|
||||
UntypedExpr::When {
|
||||
location,
|
||||
|
@ -1665,6 +1659,24 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
fn infer_tuple(&mut self, elems: Vec<UntypedExpr>, location: Span) -> Result<TypedExpr, Error> {
|
||||
let mut typed_elems = vec![];
|
||||
|
||||
for elem in elems {
|
||||
let typed_elem = self.infer(elem)?;
|
||||
|
||||
typed_elems.push(typed_elem);
|
||||
}
|
||||
|
||||
let tipo = tuple(typed_elems.iter().map(|e| e.tipo()).collect());
|
||||
|
||||
Ok(TypedExpr::Tuple {
|
||||
location,
|
||||
elems: typed_elems,
|
||||
tipo,
|
||||
})
|
||||
}
|
||||
|
||||
fn infer_todo(&mut self, location: Span, kind: TodoKind, label: Option<String>) -> TypedExpr {
|
||||
let tipo = self.new_unbound_var();
|
||||
|
||||
|
@ -1681,66 +1693,15 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
fn infer_try(
|
||||
&mut self,
|
||||
pattern: UntypedPattern,
|
||||
value: UntypedExpr,
|
||||
then: UntypedExpr,
|
||||
annotation: &Option<Annotation>,
|
||||
location: Span,
|
||||
) -> Result<TypedExpr, Error> {
|
||||
let value = self.in_new_scope(|value_typer| value_typer.infer(value))?;
|
||||
|
||||
let value_type = self.new_unbound_var();
|
||||
let try_error_type = self.new_unbound_var();
|
||||
|
||||
// Ensure that the value is a result
|
||||
{
|
||||
let v = value_type.clone();
|
||||
|
||||
let e = try_error_type.clone();
|
||||
|
||||
self.unify(result(v, e), value.tipo(), value.type_defining_location())?;
|
||||
};
|
||||
|
||||
// Ensure the pattern matches the type of the value
|
||||
let pattern = PatternTyper::new(self.environment, &self.hydrator).unify(
|
||||
pattern,
|
||||
value_type.clone(),
|
||||
None,
|
||||
)?;
|
||||
|
||||
fn infer_trace(&mut self, then: UntypedExpr, location: Span) -> Result<TypedExpr, Error> {
|
||||
// Check the type of the following code
|
||||
let then = self.infer(then)?;
|
||||
|
||||
let tipo = then.tipo();
|
||||
|
||||
// Ensure that a Result with the right error type is returned for `try`
|
||||
{
|
||||
let t = self.new_unbound_var();
|
||||
|
||||
self.unify(
|
||||
result(t, try_error_type),
|
||||
tipo.clone(),
|
||||
then.type_defining_location(),
|
||||
)
|
||||
.map_err(|e| e.inconsistent_try(tipo.is_result()))?;
|
||||
}
|
||||
|
||||
// Check that any type annotation is accurate.
|
||||
if let Some(ann) = annotation {
|
||||
let ann_typ = self
|
||||
.type_from_annotation(ann)
|
||||
.map(|t| self.instantiate(t, &mut HashMap::new()))?;
|
||||
|
||||
self.unify(ann_typ, value_type, value.type_defining_location())?;
|
||||
}
|
||||
|
||||
Ok(TypedExpr::Try {
|
||||
Ok(TypedExpr::Trace {
|
||||
location,
|
||||
tipo,
|
||||
pattern,
|
||||
value: Box::new(value),
|
||||
then: Box::new(then),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use crate::{ast::Annotation, builtins::function};
|
||||
use crate::{
|
||||
ast::Annotation,
|
||||
builtins::{function, tuple},
|
||||
};
|
||||
|
||||
use super::{environment::Environment, error::Error, Type, TypeConstructor};
|
||||
|
||||
|
@ -208,6 +211,18 @@ impl Hydrator {
|
|||
Annotation::Hole { location, .. } => Err(Error::UnexpectedTypeHole {
|
||||
location: *location,
|
||||
}),
|
||||
|
||||
Annotation::Tuple { elems, .. } => {
|
||||
let mut typed_elems = vec![];
|
||||
|
||||
for elem in elems {
|
||||
let typed_elem = self.type_from_annotation(elem, environment)?;
|
||||
|
||||
typed_elems.push(typed_elem)
|
||||
}
|
||||
|
||||
Ok(tuple(typed_elems))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -459,7 +459,7 @@ fn str_to_keyword(word: &str) -> Option<Token> {
|
|||
"opaque" => Some(Token::Opaque),
|
||||
"pub" => Some(Token::Pub),
|
||||
"todo" => Some(Token::Todo),
|
||||
"try" => Some(Token::Try),
|
||||
"try" => Some(Token::Trace),
|
||||
"type" => Some(Token::Type),
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
@ -9,14 +9,14 @@ use std::{
|
|||
use itertools::Itertools;
|
||||
|
||||
use super::{
|
||||
environment::{assert_no_labeled_arguments, EntityKind, Environment},
|
||||
environment::{assert_no_labeled_arguments, collapse_links, EntityKind, Environment},
|
||||
error::Error,
|
||||
hydrator::Hydrator,
|
||||
PatternConstructor, Type, ValueConstructor, ValueConstructorVariant,
|
||||
};
|
||||
use crate::{
|
||||
ast::{CallArg, Pattern, Span, TypedPattern, UntypedMultiPattern, UntypedPattern},
|
||||
builtins::{int, list, string},
|
||||
builtins::{int, list, string, tuple},
|
||||
};
|
||||
|
||||
pub struct PatternTyper<'a, 'b> {
|
||||
|
@ -354,55 +354,68 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
|||
}),
|
||||
},
|
||||
|
||||
// Pattern::Tuple { elems, location } => match collapse_links(tipo.clone()).deref() {
|
||||
// Type::Tuple { elems: type_elems } => {
|
||||
// if elems.len() != type_elems.len() {
|
||||
// return Err(Error::IncorrectArity {
|
||||
// labels: vec![],
|
||||
// location,
|
||||
// expected: type_elems.len(),
|
||||
// given: elems.len(),
|
||||
// });
|
||||
// }
|
||||
Pattern::Tuple { elems, location } => match collapse_links(tipo.clone()).deref() {
|
||||
Type::Tuple { elems: type_elems } => {
|
||||
if elems.len() != type_elems.len() {
|
||||
return Err(Error::IncorrectArity {
|
||||
labels: vec![],
|
||||
location,
|
||||
expected: type_elems.len(),
|
||||
given: elems.len(),
|
||||
});
|
||||
}
|
||||
|
||||
// let elems = elems
|
||||
// .into_iter()
|
||||
// .zip(type_elems)
|
||||
// .map(|(pattern, typ)| self.unify(pattern, typ.clone()))
|
||||
// .try_collect()?;
|
||||
let mut patterns = vec![];
|
||||
|
||||
// Ok(Pattern::Tuple { elems, location })
|
||||
// }
|
||||
for (pattern, typ) in elems.into_iter().zip(type_elems) {
|
||||
let typed_pattern = self.unify(pattern, typ.clone(), None)?;
|
||||
|
||||
// Type::Var { .. } => {
|
||||
// let elems_types: Vec<_> = (0..(elems.len()))
|
||||
// .map(|_| self.environment.new_unbound_var())
|
||||
// .collect();
|
||||
// self.environment
|
||||
// .unify(tuple(elems_types.clone()), type_)
|
||||
// .map_err(|e| convert_unify_error(e, location))?;
|
||||
// let elems = elems
|
||||
// .into_iter()
|
||||
// .zip(elems_types)
|
||||
// .map(|(pattern, type_)| self.unify(pattern, type_))
|
||||
// .try_collect()?;
|
||||
// Ok(Pattern::Tuple { elems, location })
|
||||
// }
|
||||
patterns.push(typed_pattern);
|
||||
}
|
||||
|
||||
// _ => {
|
||||
// let elems_types = (0..(elems.len()))
|
||||
// .map(|_| self.environment.new_unbound_var())
|
||||
// .collect();
|
||||
Ok(Pattern::Tuple {
|
||||
elems: patterns,
|
||||
location,
|
||||
})
|
||||
}
|
||||
|
||||
Type::Var { .. } => {
|
||||
let elems_types: Vec<_> = (0..(elems.len()))
|
||||
.map(|_| self.environment.new_unbound_var())
|
||||
.collect();
|
||||
|
||||
self.environment
|
||||
.unify(tuple(elems_types.clone()), tipo, location)?;
|
||||
|
||||
let mut patterns = vec![];
|
||||
|
||||
for (pattern, type_) in elems.into_iter().zip(elems_types) {
|
||||
let typed_pattern = self.unify(pattern, type_, None)?;
|
||||
|
||||
patterns.push(typed_pattern);
|
||||
}
|
||||
|
||||
Ok(Pattern::Tuple {
|
||||
elems: patterns,
|
||||
location,
|
||||
})
|
||||
}
|
||||
|
||||
_ => {
|
||||
let elems_types = (0..(elems.len()))
|
||||
.map(|_| self.environment.new_unbound_var())
|
||||
.collect();
|
||||
|
||||
Err(Error::CouldNotUnify {
|
||||
given: tuple(elems_types),
|
||||
expected: tipo,
|
||||
situation: None,
|
||||
location,
|
||||
rigid_type_names: HashMap::new(),
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
// Err(Error::CouldNotUnify {
|
||||
// given: tuple(elems_types),
|
||||
// expected: type_,
|
||||
// situation: None,
|
||||
// location,
|
||||
// rigid_type_names: hashmap![],
|
||||
// })
|
||||
// }
|
||||
// },
|
||||
Pattern::Constructor {
|
||||
location,
|
||||
module,
|
||||
|
|
|
@ -74,6 +74,8 @@ impl Printer {
|
|||
.append(break_("", " ").append(self.print(ret)).nest(INDENT).group()),
|
||||
|
||||
Type::Var { tipo: typ, .. } => self.type_var_doc(&typ.borrow()),
|
||||
|
||||
Type::Tuple { elems, .. } => self.args_to_aiken_doc(elems).surround("#(", ")"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -317,7 +317,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
ValueConstructorVariant::Record { .. } => {
|
||||
match &*constructor.tipo {
|
||||
Type::App { .. } => {}
|
||||
Type::Fn { .. } | Type::Var { .. } => {}
|
||||
Type::Fn { .. } | Type::Var { .. } | Type::Tuple { .. } => {}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -351,7 +351,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
scope_level.scope_increment(1),
|
||||
&[],
|
||||
),
|
||||
TypedExpr::Try { .. } => todo!(),
|
||||
TypedExpr::Trace { .. } => todo!(),
|
||||
TypedExpr::When {
|
||||
subjects, clauses, ..
|
||||
} => {
|
||||
|
@ -531,6 +531,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
TypedExpr::Todo { .. } => todo!(),
|
||||
TypedExpr::RecordUpdate { .. } => todo!(),
|
||||
TypedExpr::Negate { .. } => todo!(),
|
||||
TypedExpr::Tuple { .. } => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -763,6 +764,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
_ => todo!(),
|
||||
};
|
||||
}
|
||||
Pattern::Tuple { .. } => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -818,6 +820,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
},
|
||||
Type::Fn { .. } => todo!(),
|
||||
Type::Var { .. } => todo!(),
|
||||
Type::Tuple { .. } => todo!(),
|
||||
};
|
||||
|
||||
if let Some(data_type) = self.data_types.get(&data_type_key) {
|
||||
|
@ -871,6 +874,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
Type::App { args, .. } => (*args[0]).clone(),
|
||||
Type::Fn { .. } => todo!(),
|
||||
Type::Var { .. } => todo!(),
|
||||
Type::Tuple { .. } => todo!(),
|
||||
};
|
||||
while !is_final_type {
|
||||
match current_tipo.clone() {
|
||||
|
@ -891,6 +895,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
}
|
||||
tipo::TypeVar::Generic { .. } => todo!(),
|
||||
},
|
||||
Type::Tuple { .. } => todo!(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1282,6 +1287,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
},
|
||||
Type::Fn { .. } => todo!(),
|
||||
Type::Var { .. } => todo!(),
|
||||
Type::Tuple { .. } => todo!(),
|
||||
},
|
||||
BinOp::And => Term::Force(
|
||||
Term::Apply {
|
||||
|
@ -1411,6 +1417,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
}
|
||||
Type::Fn { .. } => todo!(),
|
||||
Type::Var { .. } => todo!(),
|
||||
Type::Tuple { .. } => todo!(),
|
||||
},
|
||||
BinOp::LtInt => Term::Apply {
|
||||
function: Term::Apply {
|
||||
|
@ -1508,8 +1515,9 @@ impl<'a> CodeGenerator<'a> {
|
|||
Pattern::Discard { .. } => todo!(),
|
||||
Pattern::List { .. } => todo!(),
|
||||
Pattern::Constructor { .. } => todo!(),
|
||||
Pattern::Tuple { .. } => todo!(),
|
||||
},
|
||||
TypedExpr::Try { .. } => todo!(),
|
||||
TypedExpr::Trace { .. } => todo!(),
|
||||
TypedExpr::When {
|
||||
subjects, clauses, ..
|
||||
} => {
|
||||
|
@ -1753,6 +1761,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
Type::App { args, .. } => (*args[0]).clone(),
|
||||
Type::Fn { .. } => todo!(),
|
||||
Type::Var { .. } => todo!(),
|
||||
Type::Tuple { .. } => todo!(),
|
||||
};
|
||||
|
||||
while !is_final_type {
|
||||
|
@ -1774,6 +1783,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
}
|
||||
tipo::TypeVar::Generic { .. } => todo!(),
|
||||
},
|
||||
Type::Tuple { .. } => todo!(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -2356,6 +2366,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
TypedExpr::Todo { .. } => todo!(),
|
||||
TypedExpr::RecordUpdate { .. } => todo!(),
|
||||
TypedExpr::Negate { .. } => todo!(),
|
||||
TypedExpr::Tuple { .. } => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2617,6 +2628,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
Type::App { name, .. } => name,
|
||||
Type::Fn { .. } => todo!(),
|
||||
Type::Var { .. } => todo!(),
|
||||
Type::Tuple { .. } => todo!(),
|
||||
};
|
||||
(index, name.clone())
|
||||
}
|
||||
|
@ -2628,6 +2640,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
Type::App { name, .. } => name,
|
||||
Type::Fn { .. } => todo!(),
|
||||
Type::Var { .. } => todo!(),
|
||||
Type::Tuple { .. } => todo!(),
|
||||
};
|
||||
(index, name.clone())
|
||||
}
|
||||
|
|
|
@ -36,12 +36,17 @@ pub fn incrementor(counter: Int, target: Int) -> Int {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn who(a: #(Int, Int)) -> #(Int, Int) {
|
||||
#(1, 2)
|
||||
}
|
||||
|
||||
pub fn spend(
|
||||
datum: sample.Datum,
|
||||
rdmr: Redeemer,
|
||||
ctx: spend.ScriptContext,
|
||||
) -> Bool {
|
||||
let x = Sell
|
||||
let z = incrementor(0, 4) == 4
|
||||
z
|
||||
when [1, 2, 3] is {
|
||||
[a, b, ..] -> True
|
||||
[] -> False
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue