Merge pull request #459 from aiken-lang/remove-multi-subjects
Cleanup implementation from multi-subjects when/is
This commit is contained in:
commit
3eccc349aa
|
@ -1,5 +1,3 @@
|
||||||
use std::{fmt, ops::Range, sync::Arc};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
builtins::{self, bool},
|
builtins::{self, bool},
|
||||||
expr::{TypedExpr, UntypedExpr},
|
expr::{TypedExpr, UntypedExpr},
|
||||||
|
@ -8,6 +6,8 @@ use crate::{
|
||||||
};
|
};
|
||||||
use miette::Diagnostic;
|
use miette::Diagnostic;
|
||||||
use owo_colors::{OwoColorize, Stream::Stdout};
|
use owo_colors::{OwoColorize, Stream::Stdout};
|
||||||
|
use std::{fmt, ops::Range, sync::Arc};
|
||||||
|
use vec1::Vec1;
|
||||||
|
|
||||||
pub const ASSERT_VARIABLE: &str = "_try";
|
pub const ASSERT_VARIABLE: &str = "_try";
|
||||||
pub const CAPTURE_VARIABLE: &str = "_capture";
|
pub const CAPTURE_VARIABLE: &str = "_capture";
|
||||||
|
@ -909,26 +909,26 @@ pub type MultiPattern<PatternConstructor, Type> = Vec<Pattern<PatternConstructor
|
||||||
pub type UntypedMultiPattern = MultiPattern<(), ()>;
|
pub type UntypedMultiPattern = MultiPattern<(), ()>;
|
||||||
pub type TypedMultiPattern = MultiPattern<PatternConstructor, Arc<Type>>;
|
pub type TypedMultiPattern = MultiPattern<PatternConstructor, Arc<Type>>;
|
||||||
|
|
||||||
pub type TypedClause = Clause<TypedExpr, PatternConstructor, Arc<Type>>;
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub type UntypedClause = Clause<UntypedExpr, (), ()>;
|
pub struct UntypedClause {
|
||||||
|
pub location: Span,
|
||||||
|
pub patterns: Vec1<Pattern<(), ()>>,
|
||||||
|
pub guard: Option<ClauseGuard<()>>,
|
||||||
|
pub then: UntypedExpr,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Clause<Expr, PatternConstructor, Type> {
|
pub struct TypedClause {
|
||||||
pub location: Span,
|
pub location: Span,
|
||||||
pub pattern: MultiPattern<PatternConstructor, Type>,
|
pub pattern: Pattern<PatternConstructor, Arc<Type>>,
|
||||||
pub alternative_patterns: Vec<MultiPattern<PatternConstructor, Type>>,
|
pub guard: Option<ClauseGuard<Arc<Type>>>,
|
||||||
pub guard: Option<ClauseGuard<Type>>,
|
pub then: TypedExpr,
|
||||||
pub then: Expr,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypedClause {
|
impl TypedClause {
|
||||||
pub fn location(&self) -> Span {
|
pub fn location(&self) -> Span {
|
||||||
Span {
|
Span {
|
||||||
start: self
|
start: self.pattern.location().start,
|
||||||
.pattern
|
|
||||||
.get(0)
|
|
||||||
.map(|p| p.location().start)
|
|
||||||
.unwrap_or_default(),
|
|
||||||
end: self.then.location().end,
|
end: self.then.location().end,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -936,29 +936,6 @@ impl TypedClause {
|
||||||
pub fn find_node(&self, byte_index: usize) -> Option<&TypedExpr> {
|
pub fn find_node(&self, byte_index: usize) -> Option<&TypedExpr> {
|
||||||
self.then.find_node(byte_index)
|
self.then.find_node(byte_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn desugarize(self) -> Vec<Self> {
|
|
||||||
let mut alternative_patterns = self
|
|
||||||
.alternative_patterns
|
|
||||||
.into_iter()
|
|
||||||
.map(|pattern| Self {
|
|
||||||
location: self.location,
|
|
||||||
pattern,
|
|
||||||
alternative_patterns: vec![],
|
|
||||||
guard: self.guard.clone(),
|
|
||||||
then: self.then.clone(),
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let mut clauses = vec![Self {
|
|
||||||
alternative_patterns: vec![],
|
|
||||||
..self
|
|
||||||
}];
|
|
||||||
|
|
||||||
clauses.append(&mut alternative_patterns);
|
|
||||||
|
|
||||||
clauses
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type UntypedClauseGuard = ClauseGuard<()>;
|
pub type UntypedClauseGuard = ClauseGuard<()>;
|
||||||
|
|
|
@ -18,8 +18,8 @@ use uplc::{
|
||||||
use crate::{
|
use crate::{
|
||||||
air::Air,
|
air::Air,
|
||||||
ast::{
|
ast::{
|
||||||
AssignmentKind, BinOp, Clause, ClauseGuard, Constant, DataType, Pattern, Span, TypedArg,
|
AssignmentKind, BinOp, ClauseGuard, Constant, DataType, Pattern, Span, TypedArg,
|
||||||
TypedDataType, UnOp,
|
TypedClause, TypedDataType, UnOp,
|
||||||
},
|
},
|
||||||
expr::TypedExpr,
|
expr::TypedExpr,
|
||||||
tipo::{PatternConstructor, Type, TypeVar, ValueConstructor, ValueConstructorVariant},
|
tipo::{PatternConstructor, Type, TypeVar, ValueConstructor, ValueConstructorVariant},
|
||||||
|
@ -396,9 +396,7 @@ pub fn convert_data_to_type(term: Term<Name>, field_type: &Arc<Type>) -> Term<Na
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rearrange_clauses(
|
pub fn rearrange_clauses(clauses: Vec<TypedClause>) -> Vec<TypedClause> {
|
||||||
clauses: Vec<Clause<TypedExpr, PatternConstructor, Arc<Type>>>,
|
|
||||||
) -> Vec<Clause<TypedExpr, PatternConstructor, Arc<Type>>> {
|
|
||||||
let mut sorted_clauses = clauses;
|
let mut sorted_clauses = clauses;
|
||||||
|
|
||||||
// if we have a list sort clauses so we can plug holes for cases not covered by clauses
|
// if we have a list sort clauses so we can plug holes for cases not covered by clauses
|
||||||
|
@ -406,11 +404,11 @@ pub fn rearrange_clauses(
|
||||||
// let's sort clauses by a safer manner
|
// let's sort clauses by a safer manner
|
||||||
// TODO: how shall tails be weighted? Since any clause after will not run
|
// TODO: how shall tails be weighted? Since any clause after will not run
|
||||||
sorted_clauses.sort_by(|clause1, clause2| {
|
sorted_clauses.sort_by(|clause1, clause2| {
|
||||||
let clause1_len = match &clause1.pattern[0] {
|
let clause1_len = match &clause1.pattern {
|
||||||
Pattern::List { elements, tail, .. } => elements.len() + usize::from(tail.is_some()),
|
Pattern::List { elements, tail, .. } => elements.len() + usize::from(tail.is_some()),
|
||||||
_ => 10000000,
|
_ => 10000000,
|
||||||
};
|
};
|
||||||
let clause2_len = match &clause2.pattern[0] {
|
let clause2_len = match &clause2.pattern {
|
||||||
Pattern::List { elements, tail, .. } => elements.len() + usize::from(tail.is_some()),
|
Pattern::List { elements, tail, .. } => elements.len() + usize::from(tail.is_some()),
|
||||||
_ => 10000001,
|
_ => 10000001,
|
||||||
};
|
};
|
||||||
|
@ -427,7 +425,7 @@ pub fn rearrange_clauses(
|
||||||
|
|
||||||
// If we have a catch all, use that. Otherwise use todo which will result in error
|
// If we have a catch all, use that. Otherwise use todo which will result in error
|
||||||
// TODO: fill in todo label with description
|
// TODO: fill in todo label with description
|
||||||
let plug_in_then = match &sorted_clauses[sorted_clauses.len() - 1].pattern[0] {
|
let plug_in_then = match &sorted_clauses[sorted_clauses.len() - 1].pattern {
|
||||||
Pattern::Var { name, .. } => {
|
Pattern::Var { name, .. } => {
|
||||||
assign_plug_in_name = Some(name);
|
assign_plug_in_name = Some(name);
|
||||||
sorted_clauses[sorted_clauses.len() - 1].clone().then
|
sorted_clauses[sorted_clauses.len() - 1].clone().then
|
||||||
|
@ -452,7 +450,7 @@ pub fn rearrange_clauses(
|
||||||
};
|
};
|
||||||
|
|
||||||
for (index, clause) in sorted_clauses.iter().enumerate() {
|
for (index, clause) in sorted_clauses.iter().enumerate() {
|
||||||
if let Pattern::List { elements, .. } = &clause.pattern[0] {
|
if let Pattern::List { elements, .. } = &clause.pattern {
|
||||||
// found a hole and now we plug it
|
// found a hole and now we plug it
|
||||||
while elems_len < elements.len() {
|
while elems_len < elements.len() {
|
||||||
let mut discard_elems = vec![];
|
let mut discard_elems = vec![];
|
||||||
|
@ -466,9 +464,9 @@ pub fn rearrange_clauses(
|
||||||
|
|
||||||
// If we have a named catch all then in scope the name and create list of discards, otherwise list of discards
|
// If we have a named catch all then in scope the name and create list of discards, otherwise list of discards
|
||||||
let clause_to_fill = if let Some(name) = assign_plug_in_name {
|
let clause_to_fill = if let Some(name) = assign_plug_in_name {
|
||||||
Clause {
|
TypedClause {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
pattern: vec![Pattern::Assign {
|
pattern: Pattern::Assign {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
pattern: Pattern::List {
|
pattern: Pattern::List {
|
||||||
|
@ -477,20 +475,18 @@ pub fn rearrange_clauses(
|
||||||
tail: None,
|
tail: None,
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
}],
|
},
|
||||||
alternative_patterns: vec![],
|
|
||||||
guard: None,
|
guard: None,
|
||||||
then: plug_in_then.clone(),
|
then: plug_in_then.clone(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Clause {
|
TypedClause {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
pattern: vec![Pattern::List {
|
pattern: Pattern::List {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
elements: discard_elems,
|
elements: discard_elems,
|
||||||
tail: None,
|
tail: None,
|
||||||
}],
|
},
|
||||||
alternative_patterns: vec![],
|
|
||||||
guard: None,
|
guard: None,
|
||||||
then: plug_in_then.clone(),
|
then: plug_in_then.clone(),
|
||||||
}
|
}
|
||||||
|
@ -502,7 +498,7 @@ pub fn rearrange_clauses(
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we have a pattern with no clause guards and a tail then no lists will get past here to other clauses
|
// if we have a pattern with no clause guards and a tail then no lists will get past here to other clauses
|
||||||
match &clause.pattern[0] {
|
match &clause.pattern {
|
||||||
Pattern::Var { .. } => {
|
Pattern::Var { .. } => {
|
||||||
last_clause_index = index + 1;
|
last_clause_index = index + 1;
|
||||||
last_clause_set = true;
|
last_clause_set = true;
|
||||||
|
@ -533,14 +529,13 @@ pub fn rearrange_clauses(
|
||||||
|
|
||||||
// If the last condition doesn't have a catch all or tail then add a catch all with a todo
|
// If the last condition doesn't have a catch all or tail then add a catch all with a todo
|
||||||
if index == sorted_clauses.len() - 1 {
|
if index == sorted_clauses.len() - 1 {
|
||||||
if let Pattern::List { tail: None, .. } = &clause.pattern[0] {
|
if let Pattern::List { tail: None, .. } = &clause.pattern {
|
||||||
final_clauses.push(Clause {
|
final_clauses.push(TypedClause {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
pattern: vec![Pattern::Discard {
|
pattern: Pattern::Discard {
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
}],
|
},
|
||||||
alternative_patterns: vec![],
|
|
||||||
guard: None,
|
guard: None,
|
||||||
then: plug_in_then.clone(),
|
then: plug_in_then.clone(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,9 +4,9 @@ use vec1::Vec1;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Annotation, Arg, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg, Clause,
|
Annotation, Arg, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg,
|
||||||
DefinitionLocation, IfBranch, Pattern, RecordUpdateSpread, Span, TraceKind,
|
DefinitionLocation, IfBranch, Pattern, RecordUpdateSpread, Span, TraceKind, TypedClause,
|
||||||
TypedRecordUpdateArg, UnOp, UntypedRecordUpdateArg,
|
TypedRecordUpdateArg, UnOp, UntypedClause, UntypedRecordUpdateArg,
|
||||||
},
|
},
|
||||||
builtins::void,
|
builtins::void,
|
||||||
tipo::{ModuleValueConstructor, PatternConstructor, Type, ValueConstructor},
|
tipo::{ModuleValueConstructor, PatternConstructor, Type, ValueConstructor},
|
||||||
|
@ -102,8 +102,8 @@ pub enum TypedExpr {
|
||||||
When {
|
When {
|
||||||
location: Span,
|
location: Span,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
subjects: Vec<Self>,
|
subject: Box<Self>,
|
||||||
clauses: Vec<Clause<Self, PatternConstructor, Arc<Type>>>,
|
clauses: Vec<TypedClause>,
|
||||||
},
|
},
|
||||||
|
|
||||||
If {
|
If {
|
||||||
|
@ -355,10 +355,9 @@ impl TypedExpr {
|
||||||
TypedExpr::Assignment { value, .. } => value.find_node(byte_index),
|
TypedExpr::Assignment { value, .. } => value.find_node(byte_index),
|
||||||
|
|
||||||
TypedExpr::When {
|
TypedExpr::When {
|
||||||
subjects, clauses, ..
|
subject, clauses, ..
|
||||||
} => subjects
|
} => subject
|
||||||
.iter()
|
.find_node(byte_index)
|
||||||
.find_map(|subject| subject.find_node(byte_index))
|
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
clauses
|
clauses
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -481,8 +480,8 @@ pub enum UntypedExpr {
|
||||||
|
|
||||||
When {
|
When {
|
||||||
location: Span,
|
location: Span,
|
||||||
subjects: Vec<Self>,
|
subject: Box<Self>,
|
||||||
clauses: Vec<Clause<Self, (), ()>>,
|
clauses: Vec<UntypedClause>,
|
||||||
},
|
},
|
||||||
|
|
||||||
If {
|
If {
|
||||||
|
|
|
@ -728,8 +728,8 @@ impl<'comments> Formatter<'comments> {
|
||||||
} => self.trace(kind, text, then),
|
} => self.trace(kind, text, then),
|
||||||
|
|
||||||
UntypedExpr::When {
|
UntypedExpr::When {
|
||||||
subjects, clauses, ..
|
subject, clauses, ..
|
||||||
} => self.when(subjects, clauses),
|
} => self.when(subject, clauses),
|
||||||
|
|
||||||
UntypedExpr::FieldAccess {
|
UntypedExpr::FieldAccess {
|
||||||
label, container, ..
|
label, container, ..
|
||||||
|
@ -933,14 +933,11 @@ impl<'comments> Formatter<'comments> {
|
||||||
|
|
||||||
pub fn when<'a>(
|
pub fn when<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
subjects: &'a [UntypedExpr],
|
subject: &'a UntypedExpr,
|
||||||
clauses: &'a [UntypedClause],
|
clauses: &'a [UntypedClause],
|
||||||
) -> Document<'a> {
|
) -> Document<'a> {
|
||||||
let subjects_doc = break_("when", "when ")
|
let subjects_doc = break_("when", "when ")
|
||||||
.append(join(
|
.append(self.wrap_expr(subject))
|
||||||
subjects.iter().map(|s| self.wrap_expr(s)),
|
|
||||||
break_(",", ", "),
|
|
||||||
))
|
|
||||||
.nest(INDENT)
|
.nest(INDENT)
|
||||||
.append(break_("", " "))
|
.append(break_("", " "))
|
||||||
.append("is {")
|
.append("is {")
|
||||||
|
@ -1449,9 +1446,7 @@ impl<'comments> Formatter<'comments> {
|
||||||
let space_before = self.pop_empty_lines(clause.location.start);
|
let space_before = self.pop_empty_lines(clause.location.start);
|
||||||
let after_position = clause.location.end;
|
let after_position = clause.location.end;
|
||||||
let clause_doc = join(
|
let clause_doc = join(
|
||||||
std::iter::once(&clause.pattern)
|
clause.patterns.iter().map(|p| self.pattern(p)),
|
||||||
.chain(&clause.alternative_patterns)
|
|
||||||
.map(|p| join(p.iter().map(|p| self.pattern(p)), ", ".to_doc())),
|
|
||||||
" | ".to_doc(),
|
" | ".to_doc(),
|
||||||
);
|
);
|
||||||
let clause_doc = match &clause.guard {
|
let clause_doc = match &clause.guard {
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
use chumsky::prelude::*;
|
|
||||||
use vec1::Vec1;
|
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod extra;
|
pub mod extra;
|
||||||
pub mod lexer;
|
pub mod lexer;
|
||||||
|
@ -13,10 +10,11 @@ use crate::{
|
||||||
},
|
},
|
||||||
expr,
|
expr,
|
||||||
};
|
};
|
||||||
|
use chumsky::prelude::*;
|
||||||
use error::ParseError;
|
use error::ParseError;
|
||||||
use extra::ModuleExtra;
|
use extra::ModuleExtra;
|
||||||
use token::Token;
|
use token::Token;
|
||||||
|
use vec1::{vec1, Vec1};
|
||||||
|
|
||||||
pub fn module(
|
pub fn module(
|
||||||
src: &str,
|
src: &str,
|
||||||
|
@ -923,7 +921,7 @@ pub fn expr_parser(
|
||||||
let when_clause_parser = pattern_parser()
|
let when_clause_parser = pattern_parser()
|
||||||
.then(
|
.then(
|
||||||
just(Token::Vbar)
|
just(Token::Vbar)
|
||||||
.ignore_then(pattern_parser().map(|pattern| vec![pattern]))
|
.ignore_then(pattern_parser())
|
||||||
.repeated()
|
.repeated()
|
||||||
.or_not(),
|
.or_not(),
|
||||||
)
|
)
|
||||||
|
@ -962,26 +960,29 @@ pub fn expr_parser(
|
||||||
}),
|
}),
|
||||||
)))
|
)))
|
||||||
.map_with_span(
|
.map_with_span(
|
||||||
|(((pattern, alternative_patterns_opt), guard), then), span| ast::UntypedClause {
|
|(((pattern, alternative_patterns_opt), guard), then), span| {
|
||||||
|
let mut patterns = vec1![pattern];
|
||||||
|
patterns.append(&mut alternative_patterns_opt.unwrap_or_default());
|
||||||
|
ast::UntypedClause {
|
||||||
location: span,
|
location: span,
|
||||||
pattern: vec![pattern],
|
patterns,
|
||||||
alternative_patterns: alternative_patterns_opt.unwrap_or_default(),
|
|
||||||
guard,
|
guard,
|
||||||
then,
|
then,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let when_parser = just(Token::When)
|
let when_parser = just(Token::When)
|
||||||
// TODO: If subject is empty we should return ParseErrorType::ExpectedExpr,
|
// TODO: If subject is empty we should return ParseErrorType::ExpectedExpr,
|
||||||
.ignore_then(r.clone().separated_by(just(Token::Comma)))
|
.ignore_then(r.clone().map(Box::new))
|
||||||
.then_ignore(just(Token::Is))
|
.then_ignore(just(Token::Is))
|
||||||
.then_ignore(just(Token::LeftBrace))
|
.then_ignore(just(Token::LeftBrace))
|
||||||
// TODO: If clauses are empty we should return ParseErrorType::NoCaseClause
|
// TODO: If clauses are empty we should return ParseErrorType::NoCaseClause
|
||||||
.then(when_clause_parser.repeated())
|
.then(when_clause_parser.repeated())
|
||||||
.then_ignore(just(Token::RightBrace))
|
.then_ignore(just(Token::RightBrace))
|
||||||
.map_with_span(|(subjects, clauses), span| expr::UntypedExpr::When {
|
.map_with_span(|(subject, clauses), span| expr::UntypedExpr::When {
|
||||||
location: span,
|
location: span,
|
||||||
subjects,
|
subject,
|
||||||
clauses,
|
clauses,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use chumsky::prelude::*;
|
|
||||||
use indoc::indoc;
|
|
||||||
use pretty_assertions::assert_eq;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{self, Constant, DataType, Function, ModuleConstant, Span, TypeAlias, Use},
|
ast::{self, Constant, DataType, Function, ModuleConstant, Span, TypeAlias, Use},
|
||||||
expr, parser,
|
expr, parser,
|
||||||
};
|
};
|
||||||
|
use chumsky::prelude::*;
|
||||||
|
use indoc::indoc;
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
use vec1::vec1;
|
||||||
|
|
||||||
fn assert_definitions(code: &str, definitions: Vec<ast::UntypedDefinition>) {
|
fn assert_definitions(code: &str, definitions: Vec<ast::UntypedDefinition>) {
|
||||||
let (module, _extra) = parser::module(code, ast::ModuleKind::Validator).unwrap();
|
let (module, _extra) = parser::module(code, ast::ModuleKind::Validator).unwrap();
|
||||||
|
@ -933,39 +933,38 @@ fn when() {
|
||||||
}],
|
}],
|
||||||
body: expr::UntypedExpr::When {
|
body: expr::UntypedExpr::When {
|
||||||
location: Span::new((), 23..132),
|
location: Span::new((), 23..132),
|
||||||
subjects: vec![expr::UntypedExpr::Var {
|
subject: Box::new(expr::UntypedExpr::Var {
|
||||||
location: Span::new((), 28..29),
|
location: Span::new((), 28..29),
|
||||||
name: "a".to_string(),
|
name: "a".to_string(),
|
||||||
}],
|
}),
|
||||||
clauses: vec![
|
clauses: vec![
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 39..45),
|
location: Span::new((), 39..45),
|
||||||
pattern: vec![ast::Pattern::Int {
|
patterns: vec1![ast::Pattern::Int {
|
||||||
location: Span::new((), 39..40),
|
location: Span::new((), 39..40),
|
||||||
value: "2".to_string(),
|
value: "2".to_string(),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
|
||||||
guard: None,
|
guard: None,
|
||||||
then: expr::UntypedExpr::Int {
|
then: expr::UntypedExpr::Int {
|
||||||
location: Span::new((), 44..45),
|
location: Span::new((), 44..45),
|
||||||
value: "3".to_string(),
|
value: "3".to_string(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 50..106),
|
location: Span::new((), 50..106),
|
||||||
pattern: vec![ast::Pattern::Int {
|
patterns: vec1![
|
||||||
|
ast::Pattern::Int {
|
||||||
location: Span::new((), 50..51),
|
location: Span::new((), 50..51),
|
||||||
value: "1".to_string(),
|
value: "1".to_string()
|
||||||
}],
|
},
|
||||||
alternative_patterns: vec![
|
ast::Pattern::Int {
|
||||||
vec![ast::Pattern::Int {
|
|
||||||
location: Span::new((), 54..55),
|
location: Span::new((), 54..55),
|
||||||
value: "4".to_string(),
|
value: "4".to_string(),
|
||||||
}],
|
},
|
||||||
vec![ast::Pattern::Int {
|
ast::Pattern::Int {
|
||||||
location: Span::new((), 58..59),
|
location: Span::new((), 58..59),
|
||||||
value: "5".to_string(),
|
value: "5".to_string(),
|
||||||
}],
|
},
|
||||||
],
|
],
|
||||||
guard: None,
|
guard: None,
|
||||||
then: expr::UntypedExpr::Sequence {
|
then: expr::UntypedExpr::Sequence {
|
||||||
|
@ -991,26 +990,24 @@ fn when() {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 111..117),
|
location: Span::new((), 111..117),
|
||||||
pattern: vec![ast::Pattern::Int {
|
patterns: vec1![ast::Pattern::Int {
|
||||||
location: Span::new((), 111..112),
|
location: Span::new((), 111..112),
|
||||||
value: "3".to_string(),
|
value: "3".to_string(),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
|
||||||
guard: None,
|
guard: None,
|
||||||
then: expr::UntypedExpr::Int {
|
then: expr::UntypedExpr::Int {
|
||||||
location: Span::new((), 116..117),
|
location: Span::new((), 116..117),
|
||||||
value: "9".to_string(),
|
value: "9".to_string(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 122..128),
|
location: Span::new((), 122..128),
|
||||||
pattern: vec![ast::Pattern::Discard {
|
patterns: vec1![ast::Pattern::Discard {
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
location: Span::new((), 122..123),
|
location: Span::new((), 122..123),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
|
||||||
guard: None,
|
guard: None,
|
||||||
then: expr::UntypedExpr::Int {
|
then: expr::UntypedExpr::Int {
|
||||||
location: Span::new((), 127..128),
|
location: Span::new((), 127..128),
|
||||||
|
@ -2154,13 +2151,13 @@ fn tuple_pattern() {
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: expr::UntypedExpr::When {
|
body: expr::UntypedExpr::When {
|
||||||
location: Span::new((), 13..49),
|
location: Span::new((), 13..49),
|
||||||
subjects: vec![expr::UntypedExpr::Var {
|
subject: Box::new(expr::UntypedExpr::Var {
|
||||||
location: Span::new((), 18..19),
|
location: Span::new((), 18..19),
|
||||||
name: "a".to_string(),
|
name: "a".to_string(),
|
||||||
}],
|
}),
|
||||||
clauses: vec![ast::Clause {
|
clauses: vec![ast::UntypedClause {
|
||||||
location: Span::new((), 29..45),
|
location: Span::new((), 29..45),
|
||||||
pattern: vec![ast::Pattern::Tuple {
|
patterns: vec1![ast::Pattern::Tuple {
|
||||||
location: Span::new((), 29..37),
|
location: Span::new((), 29..37),
|
||||||
elems: vec![
|
elems: vec![
|
||||||
ast::Pattern::Var {
|
ast::Pattern::Var {
|
||||||
|
@ -2173,7 +2170,6 @@ fn tuple_pattern() {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
|
||||||
guard: None,
|
guard: None,
|
||||||
then: expr::UntypedExpr::Var {
|
then: expr::UntypedExpr::Var {
|
||||||
location: Span::new((), 41..45),
|
location: Span::new((), 41..45),
|
||||||
|
@ -2324,19 +2320,18 @@ fn clause_guards() {
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: expr::UntypedExpr::When {
|
body: expr::UntypedExpr::When {
|
||||||
location: Span::new((), 13..250),
|
location: Span::new((), 13..250),
|
||||||
subjects: vec![expr::UntypedExpr::Var {
|
subject: Box::new(expr::UntypedExpr::Var {
|
||||||
location: Span::new((), 18..19),
|
location: Span::new((), 18..19),
|
||||||
name: "a".to_string(),
|
name: "a".to_string(),
|
||||||
}],
|
}),
|
||||||
clauses: vec![
|
clauses: vec![
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 29..44),
|
location: Span::new((), 29..44),
|
||||||
pattern: vec![ast::Pattern::Discard {
|
patterns: vec1![ast::Pattern::Discard {
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
location: Span::new((), 29..30),
|
location: Span::new((), 29..30),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
guard: Some(ast::UntypedClauseGuard::Constant(ast::Constant::Int {
|
||||||
guard: Some(ast::ClauseGuard::Constant(ast::Constant::Int {
|
|
||||||
location: Span::new((), 34..36),
|
location: Span::new((), 34..36),
|
||||||
value: "42".to_string(),
|
value: "42".to_string(),
|
||||||
})),
|
})),
|
||||||
|
@ -2345,14 +2340,13 @@ fn clause_guards() {
|
||||||
name: "Void".to_string(),
|
name: "Void".to_string(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 49..65),
|
location: Span::new((), 49..65),
|
||||||
pattern: vec![ast::Pattern::Discard {
|
patterns: vec1![ast::Pattern::Discard {
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
location: Span::new((), 49..50),
|
location: Span::new((), 49..50),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
guard: Some(ast::UntypedClauseGuard::Var {
|
||||||
guard: Some(ast::ClauseGuard::Var {
|
|
||||||
location: Span::new((), 54..57),
|
location: Span::new((), 54..57),
|
||||||
name: "bar".to_string(),
|
name: "bar".to_string(),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
|
@ -2362,14 +2356,13 @@ fn clause_guards() {
|
||||||
name: "Void".to_string(),
|
name: "Void".to_string(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 70..87),
|
location: Span::new((), 70..87),
|
||||||
pattern: vec![ast::Pattern::Discard {
|
patterns: vec1![ast::Pattern::Discard {
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
location: Span::new((), 70..71),
|
location: Span::new((), 70..71),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
guard: Some(ast::UntypedClauseGuard::Var {
|
||||||
guard: Some(ast::ClauseGuard::Var {
|
|
||||||
location: Span::new((), 75..79),
|
location: Span::new((), 75..79),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
name: "True".to_string(),
|
name: "True".to_string(),
|
||||||
|
@ -2379,28 +2372,27 @@ fn clause_guards() {
|
||||||
name: "Void".to_string(),
|
name: "Void".to_string(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 92..116),
|
location: Span::new((), 92..116),
|
||||||
pattern: vec![ast::Pattern::Discard {
|
patterns: vec1![ast::Pattern::Discard {
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
location: Span::new((), 92..93),
|
location: Span::new((), 92..93),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
guard: Some(ast::UntypedClauseGuard::Or {
|
||||||
guard: Some(ast::ClauseGuard::Or {
|
|
||||||
location: Span::new((), 97..108),
|
location: Span::new((), 97..108),
|
||||||
left: Box::new(ast::ClauseGuard::Var {
|
left: Box::new(ast::UntypedClauseGuard::Var {
|
||||||
location: Span::new((), 97..98),
|
location: Span::new((), 97..98),
|
||||||
name: "a".to_string(),
|
name: "a".to_string(),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}),
|
}),
|
||||||
right: Box::new(ast::ClauseGuard::And {
|
right: Box::new(ast::UntypedClauseGuard::And {
|
||||||
location: Span::new((), 102..108),
|
location: Span::new((), 102..108),
|
||||||
left: Box::new(ast::ClauseGuard::Var {
|
left: Box::new(ast::UntypedClauseGuard::Var {
|
||||||
location: Span::new((), 102..103),
|
location: Span::new((), 102..103),
|
||||||
name: "b".to_string(),
|
name: "b".to_string(),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}),
|
}),
|
||||||
right: Box::new(ast::ClauseGuard::Var {
|
right: Box::new(ast::UntypedClauseGuard::Var {
|
||||||
location: Span::new((), 107..108),
|
location: Span::new((), 107..108),
|
||||||
name: "c".to_string(),
|
name: "c".to_string(),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
|
@ -2412,29 +2404,28 @@ fn clause_guards() {
|
||||||
name: "Void".to_string(),
|
name: "Void".to_string(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 121..147),
|
location: Span::new((), 121..147),
|
||||||
pattern: vec![ast::Pattern::Discard {
|
patterns: vec1![ast::Pattern::Discard {
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
location: Span::new((), 121..122),
|
location: Span::new((), 121..122),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
guard: Some(ast::UntypedClauseGuard::And {
|
||||||
guard: Some(ast::ClauseGuard::And {
|
|
||||||
location: Span::new((), 127..139),
|
location: Span::new((), 127..139),
|
||||||
left: Box::new(ast::ClauseGuard::Or {
|
left: Box::new(ast::UntypedClauseGuard::Or {
|
||||||
location: Span::new((), 127..133),
|
location: Span::new((), 127..133),
|
||||||
left: Box::new(ast::ClauseGuard::Var {
|
left: Box::new(ast::UntypedClauseGuard::Var {
|
||||||
location: Span::new((), 127..128),
|
location: Span::new((), 127..128),
|
||||||
name: "a".to_string(),
|
name: "a".to_string(),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}),
|
}),
|
||||||
right: Box::new(ast::ClauseGuard::Var {
|
right: Box::new(ast::UntypedClauseGuard::Var {
|
||||||
location: Span::new((), 132..133),
|
location: Span::new((), 132..133),
|
||||||
name: "b".to_string(),
|
name: "b".to_string(),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
right: Box::new(ast::ClauseGuard::Var {
|
right: Box::new(ast::UntypedClauseGuard::Var {
|
||||||
location: Span::new((), 138..139),
|
location: Span::new((), 138..139),
|
||||||
name: "c".to_string(),
|
name: "c".to_string(),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
|
@ -2445,39 +2436,38 @@ fn clause_guards() {
|
||||||
name: "Void".to_string(),
|
name: "Void".to_string(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 152..191),
|
location: Span::new((), 152..191),
|
||||||
pattern: vec![ast::Pattern::Discard {
|
patterns: vec1![ast::Pattern::Discard {
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
location: Span::new((), 152..153),
|
location: Span::new((), 152..153),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
guard: Some(ast::UntypedClauseGuard::Or {
|
||||||
guard: Some(ast::ClauseGuard::Or {
|
|
||||||
location: Span::new((), 157..183),
|
location: Span::new((), 157..183),
|
||||||
left: Box::new(ast::ClauseGuard::Or {
|
left: Box::new(ast::UntypedClauseGuard::Or {
|
||||||
location: Span::new((), 157..174),
|
location: Span::new((), 157..174),
|
||||||
left: Box::new(ast::ClauseGuard::LtEqInt {
|
left: Box::new(ast::UntypedClauseGuard::LtEqInt {
|
||||||
location: Span::new((), 157..164),
|
location: Span::new((), 157..164),
|
||||||
left: Box::new(ast::ClauseGuard::Var {
|
left: Box::new(ast::UntypedClauseGuard::Var {
|
||||||
location: Span::new((), 157..158),
|
location: Span::new((), 157..158),
|
||||||
name: "a".to_string(),
|
name: "a".to_string(),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}),
|
}),
|
||||||
right: Box::new(ast::ClauseGuard::Constant(
|
right: Box::new(ast::UntypedClauseGuard::Constant(
|
||||||
ast::Constant::Int {
|
ast::Constant::Int {
|
||||||
location: Span::new((), 162..164),
|
location: Span::new((), 162..164),
|
||||||
value: "42".to_string(),
|
value: "42".to_string(),
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
}),
|
}),
|
||||||
right: Box::new(ast::ClauseGuard::GtInt {
|
right: Box::new(ast::UntypedClauseGuard::GtInt {
|
||||||
location: Span::new((), 168..174),
|
location: Span::new((), 168..174),
|
||||||
left: Box::new(ast::ClauseGuard::Var {
|
left: Box::new(ast::UntypedClauseGuard::Var {
|
||||||
location: Span::new((), 168..169),
|
location: Span::new((), 168..169),
|
||||||
name: "b".to_string(),
|
name: "b".to_string(),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}),
|
}),
|
||||||
right: Box::new(ast::ClauseGuard::Constant(
|
right: Box::new(ast::UntypedClauseGuard::Constant(
|
||||||
ast::Constant::Int {
|
ast::Constant::Int {
|
||||||
location: Span::new((), 172..174),
|
location: Span::new((), 172..174),
|
||||||
value: "14".to_string(),
|
value: "14".to_string(),
|
||||||
|
@ -2485,41 +2475,44 @@ fn clause_guards() {
|
||||||
)),
|
)),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
right: Box::new(ast::ClauseGuard::Constant(ast::Constant::ByteArray {
|
right: Box::new(ast::UntypedClauseGuard::Constant(
|
||||||
|
ast::Constant::ByteArray {
|
||||||
location: Span::new((), 178..183),
|
location: Span::new((), 178..183),
|
||||||
bytes: String::from("str").into_bytes(),
|
bytes: String::from("str").into_bytes(),
|
||||||
preferred_format: ast::ByteArrayFormatPreference::Utf8String,
|
preferred_format: ast::ByteArrayFormatPreference::Utf8String,
|
||||||
})),
|
},
|
||||||
|
)),
|
||||||
}),
|
}),
|
||||||
then: expr::UntypedExpr::Var {
|
then: expr::UntypedExpr::Var {
|
||||||
location: Span::new((), 187..191),
|
location: Span::new((), 187..191),
|
||||||
name: "Void".to_string(),
|
name: "Void".to_string(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 196..222),
|
location: Span::new((), 196..222),
|
||||||
pattern: vec![ast::Pattern::Discard {
|
patterns: vec1![ast::Pattern::Discard {
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
location: Span::new((), 196..197),
|
location: Span::new((), 196..197),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
guard: Some(ast::UntypedClauseGuard::And {
|
||||||
guard: Some(ast::ClauseGuard::And {
|
|
||||||
location: Span::new((), 201..214),
|
location: Span::new((), 201..214),
|
||||||
left: Box::new(ast::ClauseGuard::Equals {
|
left: Box::new(ast::UntypedClauseGuard::Equals {
|
||||||
location: Span::new((), 201..208),
|
location: Span::new((), 201..208),
|
||||||
left: Box::new(ast::ClauseGuard::Var {
|
left: Box::new(ast::UntypedClauseGuard::Var {
|
||||||
location: Span::new((), 201..202),
|
location: Span::new((), 201..202),
|
||||||
name: "a".to_string(),
|
name: "a".to_string(),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}),
|
}),
|
||||||
right: Box::new(ast::ClauseGuard::Constant(ast::Constant::Int {
|
right: Box::new(ast::UntypedClauseGuard::Constant(
|
||||||
|
ast::Constant::Int {
|
||||||
location: Span::new((), 206..208),
|
location: Span::new((), 206..208),
|
||||||
value: "14".to_string(),
|
value: "14".to_string(),
|
||||||
})),
|
},
|
||||||
|
)),
|
||||||
}),
|
}),
|
||||||
right: Box::new(ast::ClauseGuard::Not {
|
right: Box::new(ast::UntypedClauseGuard::Not {
|
||||||
location: Span::new((), 212..214),
|
location: Span::new((), 212..214),
|
||||||
value: Box::new(ast::ClauseGuard::Var {
|
value: Box::new(ast::UntypedClauseGuard::Var {
|
||||||
location: Span::new((), 213..214),
|
location: Span::new((), 213..214),
|
||||||
name: "b".to_string(),
|
name: "b".to_string(),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
|
@ -2531,18 +2524,17 @@ fn clause_guards() {
|
||||||
name: "Void".to_string(),
|
name: "Void".to_string(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 227..246),
|
location: Span::new((), 227..246),
|
||||||
pattern: vec![ast::Pattern::Discard {
|
patterns: vec1![ast::Pattern::Discard {
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
location: Span::new((), 227..228),
|
location: Span::new((), 227..228),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
guard: Some(ast::UntypedClauseGuard::Not {
|
||||||
guard: Some(ast::ClauseGuard::Not {
|
|
||||||
location: Span::new((), 232..238),
|
location: Span::new((), 232..238),
|
||||||
value: Box::new(ast::ClauseGuard::Not {
|
value: Box::new(ast::UntypedClauseGuard::Not {
|
||||||
location: Span::new((), 233..238),
|
location: Span::new((), 233..238),
|
||||||
value: Box::new(ast::ClauseGuard::Var {
|
value: Box::new(ast::UntypedClauseGuard::Var {
|
||||||
location: Span::new((), 234..238),
|
location: Span::new((), 234..238),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
name: "True".to_string(),
|
name: "True".to_string(),
|
||||||
|
@ -2826,14 +2818,14 @@ fn parse_keyword_error() {
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: expr::UntypedExpr::When {
|
body: expr::UntypedExpr::When {
|
||||||
location: Span::new((), 54..110),
|
location: Span::new((), 54..110),
|
||||||
subjects: vec![expr::UntypedExpr::Var {
|
subject: Box::new(expr::UntypedExpr::Var {
|
||||||
location: Span::new((), 59..60),
|
location: Span::new((), 59..60),
|
||||||
name: "x".to_string(),
|
name: "x".to_string(),
|
||||||
}],
|
}),
|
||||||
clauses: vec![
|
clauses: vec![
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 72..89),
|
location: Span::new((), 72..89),
|
||||||
pattern: vec![ast::Pattern::Constructor {
|
patterns: vec1![ast::Pattern::Constructor {
|
||||||
is_record: false,
|
is_record: false,
|
||||||
location: Span::new((), 72..81),
|
location: Span::new((), 72..81),
|
||||||
name: "Something".to_string(),
|
name: "Something".to_string(),
|
||||||
|
@ -2843,20 +2835,18 @@ fn parse_keyword_error() {
|
||||||
with_spread: false,
|
with_spread: false,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
|
||||||
guard: None,
|
guard: None,
|
||||||
then: expr::UntypedExpr::Var {
|
then: expr::UntypedExpr::Var {
|
||||||
location: Span::new((), 85..89),
|
location: Span::new((), 85..89),
|
||||||
name: "Void".to_string(),
|
name: "Void".to_string(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 96..106),
|
location: Span::new((), 96..106),
|
||||||
pattern: vec![ast::Pattern::Discard {
|
patterns: vec1![ast::Pattern::Discard {
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
location: Span::new((), 96..97),
|
location: Span::new((), 96..97),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
|
||||||
guard: None,
|
guard: None,
|
||||||
then: expr::UntypedExpr::Trace {
|
then: expr::UntypedExpr::Trace {
|
||||||
kind: ast::TraceKind::Error,
|
kind: ast::TraceKind::Error,
|
||||||
|
@ -2927,14 +2917,14 @@ fn parse_keyword_todo() {
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: expr::UntypedExpr::When {
|
body: expr::UntypedExpr::When {
|
||||||
location: Span::new((), 53..121),
|
location: Span::new((), 53..121),
|
||||||
subjects: vec![expr::UntypedExpr::Var {
|
subject: Box::new(expr::UntypedExpr::Var {
|
||||||
location: Span::new((), 58..59),
|
location: Span::new((), 58..59),
|
||||||
name: "x".to_string(),
|
name: "x".to_string(),
|
||||||
}],
|
}),
|
||||||
clauses: vec![
|
clauses: vec![
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 71..82),
|
location: Span::new((), 71..82),
|
||||||
pattern: vec![ast::Pattern::Constructor {
|
patterns: vec1![ast::Pattern::Constructor {
|
||||||
is_record: false,
|
is_record: false,
|
||||||
location: Span::new((), 71..74),
|
location: Span::new((), 71..74),
|
||||||
name: "Foo".to_string(),
|
name: "Foo".to_string(),
|
||||||
|
@ -2944,7 +2934,6 @@ fn parse_keyword_todo() {
|
||||||
with_spread: false,
|
with_spread: false,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
|
||||||
guard: None,
|
guard: None,
|
||||||
then: expr::UntypedExpr::Trace {
|
then: expr::UntypedExpr::Trace {
|
||||||
kind: ast::TraceKind::Todo,
|
kind: ast::TraceKind::Todo,
|
||||||
|
@ -2958,9 +2947,9 @@ fn parse_keyword_todo() {
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 89..100),
|
location: Span::new((), 89..100),
|
||||||
pattern: vec![ast::Pattern::Constructor {
|
patterns: vec1![ast::Pattern::Constructor {
|
||||||
is_record: false,
|
is_record: false,
|
||||||
location: Span::new((), 89..92),
|
location: Span::new((), 89..92),
|
||||||
name: "Bar".to_string(),
|
name: "Bar".to_string(),
|
||||||
|
@ -2970,20 +2959,18 @@ fn parse_keyword_todo() {
|
||||||
with_spread: false,
|
with_spread: false,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
|
||||||
guard: None,
|
guard: None,
|
||||||
then: expr::UntypedExpr::Var {
|
then: expr::UntypedExpr::Var {
|
||||||
location: Span::new((), 96..100),
|
location: Span::new((), 96..100),
|
||||||
name: "True".to_string(),
|
name: "True".to_string(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ast::Clause {
|
ast::UntypedClause {
|
||||||
location: Span::new((), 107..117),
|
location: Span::new((), 107..117),
|
||||||
pattern: vec![ast::Pattern::Discard {
|
patterns: vec1![ast::Pattern::Discard {
|
||||||
name: "_".to_string(),
|
name: "_".to_string(),
|
||||||
location: Span::new((), 107..108),
|
location: Span::new((), 107..108),
|
||||||
}],
|
}],
|
||||||
alternative_patterns: vec![],
|
|
||||||
guard: None,
|
guard: None,
|
||||||
then: expr::UntypedExpr::Var {
|
then: expr::UntypedExpr::Var {
|
||||||
location: Span::new((), 112..117),
|
location: Span::new((), 112..117),
|
||||||
|
|
|
@ -315,22 +315,6 @@ From there, you can define 'increment', a function that takes a single argument
|
||||||
given: usize,
|
given: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO: Since we do not actually support patterns on multiple items, we won't likely ever
|
|
||||||
// encounter that error. We could simplify a bit the type-checker and get rid of that error
|
|
||||||
// eventually.
|
|
||||||
#[error(
|
|
||||||
"I counted {} different clauses in a multi-pattern instead of {}.\n",
|
|
||||||
given.if_supports_color(Stdout, |s| s.purple()),
|
|
||||||
expected.if_supports_color(Stdout, |s| s.purple()),
|
|
||||||
)]
|
|
||||||
#[diagnostic(code("arity::clause"))]
|
|
||||||
IncorrectNumClausePatterns {
|
|
||||||
#[label]
|
|
||||||
location: Span,
|
|
||||||
expected: usize,
|
|
||||||
given: usize,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"I saw a pattern on a constructor that has {} field(s) be matched with {} argument(s).\n",
|
"I saw a pattern on a constructor that has {} field(s) be matched with {} argument(s).\n",
|
||||||
expected.if_supports_color(Stdout, |s| s.purple()),
|
expected.if_supports_color(Stdout, |s| s.purple()),
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::ast::TypedPattern;
|
||||||
use std::{cmp::Ordering, collections::HashMap, sync::Arc};
|
use std::{cmp::Ordering, collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use vec1::Vec1;
|
use vec1::Vec1;
|
||||||
|
@ -5,10 +6,10 @@ use vec1::Vec1;
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Annotation, Arg, ArgName, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg,
|
Annotation, Arg, ArgName, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg,
|
||||||
Clause, ClauseGuard, Constant, IfBranch, RecordUpdateSpread, Span, TraceKind, Tracing,
|
ClauseGuard, Constant, IfBranch, RecordUpdateSpread, Span, TraceKind, Tracing, TypedArg,
|
||||||
TypedArg, TypedCallArg, TypedClause, TypedClauseGuard, TypedIfBranch, TypedMultiPattern,
|
TypedCallArg, TypedClause, TypedClauseGuard, TypedIfBranch, TypedRecordUpdateArg, UnOp,
|
||||||
TypedRecordUpdateArg, UnOp, UntypedArg, UntypedClause, UntypedClauseGuard, UntypedIfBranch,
|
UntypedArg, UntypedClause, UntypedClauseGuard, UntypedIfBranch, UntypedPattern,
|
||||||
UntypedMultiPattern, UntypedPattern, UntypedRecordUpdateArg,
|
UntypedRecordUpdateArg,
|
||||||
},
|
},
|
||||||
builtins::{bool, byte_array, function, int, list, string, tuple},
|
builtins::{bool, byte_array, function, int, list, string, tuple},
|
||||||
expr::{TypedExpr, UntypedExpr},
|
expr::{TypedExpr, UntypedExpr},
|
||||||
|
@ -22,7 +23,7 @@ use super::{
|
||||||
hydrator::Hydrator,
|
hydrator::Hydrator,
|
||||||
pattern::PatternTyper,
|
pattern::PatternTyper,
|
||||||
pipe::PipeTyper,
|
pipe::PipeTyper,
|
||||||
PatternConstructor, RecordAccessor, Type, ValueConstructor, ValueConstructorVariant,
|
RecordAccessor, Type, ValueConstructor, ValueConstructorVariant,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -45,44 +46,24 @@ pub(crate) struct ExprTyper<'a, 'b> {
|
||||||
impl<'a, 'b> ExprTyper<'a, 'b> {
|
impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
fn check_when_exhaustiveness(
|
fn check_when_exhaustiveness(
|
||||||
&mut self,
|
&mut self,
|
||||||
subjects_count: usize,
|
subject: &Type,
|
||||||
subjects: &[Arc<Type>],
|
typed_clauses: &[TypedClause],
|
||||||
typed_clauses: &[Clause<TypedExpr, PatternConstructor, Arc<Type>>],
|
|
||||||
location: Span,
|
location: Span,
|
||||||
) -> Result<(), Vec<String>> {
|
) -> Result<(), Vec<String>> {
|
||||||
// Because exhaustiveness checking in presence of multiple subjects is similar
|
let value_typ = collapse_links(Arc::new(subject.clone()));
|
||||||
// to full exhaustiveness checking of tuples or other nested record patterns,
|
|
||||||
// and we currently only do only limited exhaustiveness checking of custom types
|
|
||||||
// at the top level of patterns, only consider case expressions with one subject.
|
|
||||||
if subjects_count != 1 {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let subject_type = subjects
|
|
||||||
.get(0)
|
|
||||||
.expect("Asserted there's one case subject but found none");
|
|
||||||
|
|
||||||
let value_typ = collapse_links(subject_type.clone());
|
|
||||||
|
|
||||||
// Currently guards in exhaustiveness checking are assumed that they can fail,
|
// Currently guards in exhaustiveness checking are assumed that they can fail,
|
||||||
// so we go through all clauses and pluck out only the patterns
|
// so we go through all clauses and pluck out only the patterns
|
||||||
// for clauses that don't have guards.
|
// for clauses that don't have guards.
|
||||||
let mut patterns = Vec::new();
|
let mut patterns = Vec::new();
|
||||||
for clause in typed_clauses {
|
for clause in typed_clauses {
|
||||||
if let Clause { guard: None, .. } = clause {
|
if let TypedClause {
|
||||||
// clause.pattern is a list of patterns for all subjects
|
guard: None,
|
||||||
if let Some(pattern) = clause.pattern.get(0) {
|
pattern,
|
||||||
patterns.push(pattern.clone());
|
..
|
||||||
}
|
} = clause
|
||||||
|
{
|
||||||
// A clause can be built with alternative patterns as well, e.g. `Audio(_) | Text(_) ->`.
|
patterns.push(pattern.clone())
|
||||||
// We're interested in all patterns so we build a flattened list.
|
|
||||||
for alternative_pattern in &clause.alternative_patterns {
|
|
||||||
// clause.alternative_pattern is a list of patterns for all subjects
|
|
||||||
if let Some(pattern) = alternative_pattern.get(0) {
|
|
||||||
patterns.push(pattern.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,10 +290,10 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
|
|
||||||
UntypedExpr::When {
|
UntypedExpr::When {
|
||||||
location,
|
location,
|
||||||
subjects,
|
subject,
|
||||||
clauses,
|
clauses,
|
||||||
..
|
..
|
||||||
} => self.infer_when(subjects, clauses, location),
|
} => self.infer_when(*subject, clauses, location),
|
||||||
|
|
||||||
UntypedExpr::List {
|
UntypedExpr::List {
|
||||||
location,
|
location,
|
||||||
|
@ -1093,35 +1074,34 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
fn infer_clause(
|
fn infer_clause(
|
||||||
&mut self,
|
&mut self,
|
||||||
clause: UntypedClause,
|
clause: UntypedClause,
|
||||||
subjects: &[Arc<Type>],
|
subject: &Type,
|
||||||
) -> Result<TypedClause, Error> {
|
) -> Result<Vec<TypedClause>, Error> {
|
||||||
let Clause {
|
let UntypedClause {
|
||||||
pattern,
|
patterns,
|
||||||
alternative_patterns,
|
|
||||||
guard,
|
guard,
|
||||||
then,
|
then,
|
||||||
location,
|
location,
|
||||||
} = clause;
|
} = clause;
|
||||||
|
|
||||||
let (guard, then, typed_pattern, typed_alternatives) = self.in_new_scope(|scope| {
|
let (guard, then, typed_patterns) = self.in_new_scope(|scope| {
|
||||||
// Check the types
|
let typed_patterns = scope.infer_clause_pattern(patterns, subject, &location)?;
|
||||||
let (typed_pattern, typed_alternatives) =
|
|
||||||
scope.infer_clause_pattern(pattern, alternative_patterns, subjects, &location)?;
|
|
||||||
|
|
||||||
let guard = scope.infer_optional_clause_guard(guard)?;
|
let guard = scope.infer_optional_clause_guard(guard)?;
|
||||||
|
|
||||||
let then = scope.infer(then)?;
|
let then = scope.infer(then)?;
|
||||||
|
|
||||||
Ok::<_, Error>((guard, then, typed_pattern, typed_alternatives))
|
Ok::<_, Error>((guard, then, typed_patterns))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(Clause {
|
Ok(typed_patterns
|
||||||
|
.into_iter()
|
||||||
|
.map(|pattern| TypedClause {
|
||||||
location,
|
location,
|
||||||
pattern: typed_pattern,
|
pattern,
|
||||||
alternative_patterns: typed_alternatives,
|
guard: guard.clone(),
|
||||||
guard,
|
then: then.clone(),
|
||||||
then,
|
|
||||||
})
|
})
|
||||||
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_clause_guard(&mut self, guard: UntypedClauseGuard) -> Result<TypedClauseGuard, Error> {
|
fn infer_clause_guard(&mut self, guard: UntypedClauseGuard) -> Result<TypedClauseGuard, Error> {
|
||||||
|
@ -1333,26 +1313,23 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
|
|
||||||
fn infer_clause_pattern(
|
fn infer_clause_pattern(
|
||||||
&mut self,
|
&mut self,
|
||||||
pattern: UntypedMultiPattern,
|
patterns: Vec1<UntypedPattern>,
|
||||||
alternatives: Vec<UntypedMultiPattern>,
|
subject: &Type,
|
||||||
subjects: &[Arc<Type>],
|
|
||||||
location: &Span,
|
location: &Span,
|
||||||
) -> Result<(TypedMultiPattern, Vec<TypedMultiPattern>), Error> {
|
) -> Result<Vec<TypedPattern>, Error> {
|
||||||
let mut pattern_typer = PatternTyper::new(self.environment, &self.hydrator);
|
let mut pattern_typer = PatternTyper::new(self.environment, &self.hydrator);
|
||||||
|
|
||||||
let typed_pattern = pattern_typer.infer_multi_pattern(pattern, subjects, location)?;
|
let mut typed_patterns = Vec::with_capacity(patterns.len());
|
||||||
|
for (ix, pattern) in patterns.into_iter().enumerate() {
|
||||||
// Each case clause has one or more patterns that may match the
|
if ix == 0 {
|
||||||
// subject in order for the clause to be selected, so we must type
|
typed_patterns.push(pattern_typer.infer_pattern(pattern, subject)?);
|
||||||
// check every pattern.
|
} else {
|
||||||
let mut typed_alternatives = Vec::with_capacity(alternatives.len());
|
typed_patterns
|
||||||
|
.push(pattern_typer.infer_alternative_pattern(pattern, subject, location)?);
|
||||||
for m in alternatives {
|
}
|
||||||
typed_alternatives
|
|
||||||
.push(pattern_typer.infer_alternative_multi_pattern(m, subjects, location)?);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((typed_pattern, typed_alternatives))
|
Ok(typed_patterns)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: extract the type annotation checking into a infer_module_const
|
// TODO: extract the type annotation checking into a infer_module_const
|
||||||
|
@ -1865,7 +1842,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
|
|
||||||
fn infer_when(
|
fn infer_when(
|
||||||
&mut self,
|
&mut self,
|
||||||
subjects: Vec<UntypedExpr>,
|
subject: UntypedExpr,
|
||||||
clauses: Vec<UntypedClause>,
|
clauses: Vec<UntypedClause>,
|
||||||
location: Span,
|
location: Span,
|
||||||
) -> Result<TypedExpr, Error> {
|
) -> Result<TypedExpr, Error> {
|
||||||
|
@ -1873,36 +1850,24 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
// that suggests that a `let` binding should be used instead.
|
// that suggests that a `let` binding should be used instead.
|
||||||
if clauses.len() == 1 {
|
if clauses.len() == 1 {
|
||||||
self.environment.warnings.push(Warning::SingleWhenClause {
|
self.environment.warnings.push(Warning::SingleWhenClause {
|
||||||
location: clauses[0].pattern[0].location(),
|
location: clauses[0].patterns[0].location(),
|
||||||
sample: UntypedExpr::Assignment {
|
sample: UntypedExpr::Assignment {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
value: Box::new(subjects[0].clone()),
|
value: Box::new(subject.clone()),
|
||||||
pattern: clauses[0].pattern[0].clone(),
|
pattern: clauses[0].patterns[0].clone(),
|
||||||
kind: AssignmentKind::Let,
|
kind: AssignmentKind::Let,
|
||||||
annotation: None,
|
annotation: None,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let subjects_count = subjects.len();
|
let typed_subject = self.infer(subject)?;
|
||||||
|
let subject_type = typed_subject.tipo();
|
||||||
let mut typed_subjects = Vec::with_capacity(subjects_count);
|
|
||||||
let mut subject_types = Vec::with_capacity(subjects_count);
|
|
||||||
let mut typed_clauses = Vec::new();
|
|
||||||
|
|
||||||
let return_type = self.new_unbound_var();
|
let return_type = self.new_unbound_var();
|
||||||
|
|
||||||
for subject in subjects {
|
let mut typed_clauses = Vec::new();
|
||||||
let subject = self.infer(subject)?;
|
|
||||||
|
|
||||||
subject_types.push(subject.tipo());
|
|
||||||
|
|
||||||
typed_subjects.push(subject);
|
|
||||||
}
|
|
||||||
|
|
||||||
for clause in clauses {
|
for clause in clauses {
|
||||||
let typed_clause = self.infer_clause(clause, &subject_types)?;
|
for typed_clause in self.infer_clause(clause, &subject_type)? {
|
||||||
|
|
||||||
self.unify(
|
self.unify(
|
||||||
return_type.clone(),
|
return_type.clone(),
|
||||||
typed_clause.then.tipo(),
|
typed_clause.then.tipo(),
|
||||||
|
@ -1911,11 +1876,12 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
)
|
)
|
||||||
.map_err(|e| e.case_clause_mismatch())?;
|
.map_err(|e| e.case_clause_mismatch())?;
|
||||||
|
|
||||||
typed_clauses.append(&mut typed_clause.desugarize());
|
typed_clauses.push(typed_clause)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(unmatched) =
|
if let Err(unmatched) =
|
||||||
self.check_when_exhaustiveness(subjects_count, &subject_types, &typed_clauses, location)
|
self.check_when_exhaustiveness(&subject_type, &typed_clauses, location)
|
||||||
{
|
{
|
||||||
return Err(Error::NotExhaustivePatternMatch {
|
return Err(Error::NotExhaustivePatternMatch {
|
||||||
location,
|
location,
|
||||||
|
@ -1927,7 +1893,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
Ok(TypedExpr::When {
|
Ok(TypedExpr::When {
|
||||||
location,
|
location,
|
||||||
tipo: return_type,
|
tipo: return_type,
|
||||||
subjects: typed_subjects,
|
subject: Box::new(typed_subject),
|
||||||
clauses: typed_clauses,
|
clauses: typed_clauses,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use super::{
|
||||||
PatternConstructor, Type, ValueConstructorVariant,
|
PatternConstructor, Type, ValueConstructorVariant,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{CallArg, Pattern, Span, TypedPattern, UntypedMultiPattern, UntypedPattern},
|
ast::{CallArg, Pattern, Span, TypedPattern, UntypedPattern},
|
||||||
builtins::{int, list, tuple},
|
builtins::{int, list, tuple},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -96,14 +96,14 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn infer_alternative_multi_pattern(
|
pub fn infer_alternative_pattern(
|
||||||
&mut self,
|
&mut self,
|
||||||
multi_pattern: UntypedMultiPattern,
|
pattern: UntypedPattern,
|
||||||
subjects: &[Arc<Type>],
|
subject: &Type,
|
||||||
location: &Span,
|
location: &Span,
|
||||||
) -> Result<Vec<TypedPattern>, Error> {
|
) -> Result<TypedPattern, Error> {
|
||||||
self.mode = PatternMode::Alternative(vec![]);
|
self.mode = PatternMode::Alternative(vec![]);
|
||||||
let typed_multi = self.infer_multi_pattern(multi_pattern, subjects, location)?;
|
let typed_pattern = self.infer_pattern(pattern, subject)?;
|
||||||
match &self.mode {
|
match &self.mode {
|
||||||
PatternMode::Initial => panic!("Pattern mode switched from Alternative to Initial"),
|
PatternMode::Initial => panic!("Pattern mode switched from Alternative to Initial"),
|
||||||
PatternMode::Alternative(assigned)
|
PatternMode::Alternative(assigned)
|
||||||
|
@ -123,32 +123,16 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
.clone(),
|
.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
PatternMode::Alternative(_) => Ok(typed_multi),
|
PatternMode::Alternative(_) => Ok(typed_pattern),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn infer_multi_pattern(
|
pub fn infer_pattern(
|
||||||
&mut self,
|
&mut self,
|
||||||
multi_pattern: UntypedMultiPattern,
|
pattern: UntypedPattern,
|
||||||
subjects: &[Arc<Type>],
|
subject: &Type,
|
||||||
location: &Span,
|
) -> Result<TypedPattern, Error> {
|
||||||
) -> Result<Vec<TypedPattern>, Error> {
|
self.unify(pattern, Arc::new(subject.clone()), None, false)
|
||||||
// If there are N subjects the multi-pattern is expected to be N patterns
|
|
||||||
if subjects.len() != multi_pattern.len() {
|
|
||||||
return Err(Error::IncorrectNumClausePatterns {
|
|
||||||
location: *location,
|
|
||||||
expected: subjects.len(),
|
|
||||||
given: multi_pattern.len(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unify each pattern in the multi-pattern with the corresponding subject
|
|
||||||
let mut typed_multi = Vec::with_capacity(multi_pattern.len());
|
|
||||||
for (pattern, subject_type) in multi_pattern.into_iter().zip(subjects) {
|
|
||||||
let pattern = self.unify(pattern, subject_type.clone(), None, false)?;
|
|
||||||
typed_multi.push(pattern);
|
|
||||||
}
|
|
||||||
Ok(typed_multi)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When we have an assignment or a case expression we unify the pattern with the
|
/// When we have an assignment or a case expression we unify the pattern with the
|
||||||
|
|
|
@ -20,7 +20,7 @@ use uplc::{
|
||||||
use crate::{
|
use crate::{
|
||||||
air::Air,
|
air::Air,
|
||||||
ast::{
|
ast::{
|
||||||
ArgName, AssignmentKind, BinOp, Clause, Pattern, Span, TypedArg, TypedDataType,
|
ArgName, AssignmentKind, BinOp, Pattern, Span, TypedArg, TypedClause, TypedDataType,
|
||||||
TypedFunction, UnOp,
|
TypedFunction, UnOp,
|
||||||
},
|
},
|
||||||
builder::{
|
builder::{
|
||||||
|
@ -476,13 +476,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
ir_stack.append(&mut pattern_vec);
|
ir_stack.append(&mut pattern_vec);
|
||||||
}
|
}
|
||||||
TypedExpr::When {
|
TypedExpr::When {
|
||||||
subjects, clauses, ..
|
subject, clauses, ..
|
||||||
} => {
|
} => {
|
||||||
let subject_name = format!("__subject_name_{}", self.id_gen.next());
|
let subject_name = format!("__subject_name_{}", self.id_gen.next());
|
||||||
let constr_var = format!("__constr_name_{}", self.id_gen.next());
|
let constr_var = format!("__constr_name_{}", self.id_gen.next());
|
||||||
|
|
||||||
// assuming one subject at the moment
|
|
||||||
let subject = subjects[0].clone();
|
|
||||||
let subject_tipo = subject.tipo();
|
let subject_tipo = subject.tipo();
|
||||||
if clauses.len() <= 1 {
|
if clauses.len() <= 1 {
|
||||||
let mut value_vec: Vec<Air> = vec![];
|
let mut value_vec: Vec<Air> = vec![];
|
||||||
|
@ -491,10 +489,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
self.build_ir(&clauses[0].then, &mut value_vec, scope.clone());
|
self.build_ir(&clauses[0].then, &mut value_vec, scope.clone());
|
||||||
|
|
||||||
self.build_ir(&subject, &mut subject_vec, scope.clone());
|
self.build_ir(subject, &mut subject_vec, scope.clone());
|
||||||
|
|
||||||
self.assignment_ir(
|
self.assignment_ir(
|
||||||
&clauses[0].pattern[0],
|
&clauses[0].pattern,
|
||||||
&mut pattern_vec,
|
&mut pattern_vec,
|
||||||
&mut subject_vec,
|
&mut subject_vec,
|
||||||
&subject_tipo,
|
&subject_tipo,
|
||||||
|
@ -508,12 +506,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
ir_stack.append(&mut pattern_vec);
|
ir_stack.append(&mut pattern_vec);
|
||||||
ir_stack.append(&mut value_vec);
|
ir_stack.append(&mut value_vec);
|
||||||
} else {
|
} else {
|
||||||
|
println!("{clauses:?}");
|
||||||
// HERE TODO
|
// HERE TODO
|
||||||
let clauses = if subject_tipo.is_list() {
|
let clauses = if subject_tipo.is_list() {
|
||||||
rearrange_clauses(clauses.clone())
|
rearrange_clauses(clauses.clone())
|
||||||
} else {
|
} else {
|
||||||
clauses.clone()
|
clauses.clone()
|
||||||
};
|
};
|
||||||
|
println!("{clauses:?}");
|
||||||
|
|
||||||
if let Some((last_clause, clauses)) = clauses.split_last() {
|
if let Some((last_clause, clauses)) = clauses.split_last() {
|
||||||
let mut pattern_vec = vec![];
|
let mut pattern_vec = vec![];
|
||||||
|
@ -532,7 +532,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
scope.clone(),
|
scope.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let last_pattern = &last_clause.pattern[0];
|
let last_pattern = &last_clause.pattern;
|
||||||
|
|
||||||
let mut final_scope = scope.clone();
|
let mut final_scope = scope.clone();
|
||||||
|
|
||||||
|
@ -571,7 +571,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let mut subject_scope = scope.clone();
|
let mut subject_scope = scope.clone();
|
||||||
subject_scope.push(self.id_gen.next());
|
subject_scope.push(self.id_gen.next());
|
||||||
|
|
||||||
self.build_ir(&subject, ir_stack, subject_scope.clone());
|
self.build_ir(subject, ir_stack, subject_scope.clone());
|
||||||
|
|
||||||
let mut scope = scope;
|
let mut scope = scope;
|
||||||
scope.push(self.id_gen.next());
|
scope.push(self.id_gen.next());
|
||||||
|
@ -603,7 +603,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let mut scope = scope;
|
let mut scope = scope;
|
||||||
scope.push(self.id_gen.next());
|
scope.push(self.id_gen.next());
|
||||||
|
|
||||||
self.build_ir(&subject, ir_stack, scope);
|
self.build_ir(subject, ir_stack, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_stack.append(&mut pattern_vec);
|
ir_stack.append(&mut pattern_vec);
|
||||||
|
@ -817,7 +817,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
ir_stack: &mut Vec<Air>,
|
ir_stack: &mut Vec<Air>,
|
||||||
clause_properties: &mut ClauseProperties,
|
clause_properties: &mut ClauseProperties,
|
||||||
clauses: &[Clause<TypedExpr, PatternConstructor, Arc<Type>>],
|
clauses: &[TypedClause],
|
||||||
subject_type: &Arc<Type>,
|
subject_type: &Arc<Type>,
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
) {
|
) {
|
||||||
|
@ -876,7 +876,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
} => {
|
} => {
|
||||||
let subject_name = original_subject_name.clone();
|
let subject_name = original_subject_name.clone();
|
||||||
self.when_ir(
|
self.when_ir(
|
||||||
&clause.pattern[0],
|
&clause.pattern,
|
||||||
&mut clause_subject_vec,
|
&mut clause_subject_vec,
|
||||||
&mut clause_then_vec,
|
&mut clause_then_vec,
|
||||||
subject_type,
|
subject_type,
|
||||||
|
@ -922,16 +922,16 @@ impl<'a> CodeGenerator<'a> {
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let (current_clause_index, has_tail) =
|
let (current_clause_index, has_tail) =
|
||||||
if let Pattern::List { elements, tail, .. } = &clause.pattern[0] {
|
if let Pattern::List { elements, tail, .. } = &clause.pattern {
|
||||||
(elements.len(), tail.is_some())
|
(elements.len(), tail.is_some())
|
||||||
} else if let Pattern::Assign { pattern, .. } = &clause.pattern[0] {
|
} else if let Pattern::Assign { pattern, .. } = &clause.pattern {
|
||||||
if let Pattern::List { elements, tail, .. } = pattern.as_ref() {
|
if let Pattern::List { elements, tail, .. } = pattern.as_ref() {
|
||||||
(elements.len(), tail.is_some())
|
(elements.len(), tail.is_some())
|
||||||
} else {
|
} else {
|
||||||
unreachable!("{:#?}", pattern)
|
unreachable!("{:#?}", pattern)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unreachable!("{:#?}", &clause.pattern[0])
|
unreachable!("{:#?}", &clause.pattern)
|
||||||
};
|
};
|
||||||
|
|
||||||
let prev_index = *current_index;
|
let prev_index = *current_index;
|
||||||
|
@ -943,7 +943,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.when_ir(
|
self.when_ir(
|
||||||
&clause.pattern[0],
|
&clause.pattern,
|
||||||
&mut clause_subject_vec,
|
&mut clause_subject_vec,
|
||||||
&mut clause_then_vec,
|
&mut clause_then_vec,
|
||||||
subject_type,
|
subject_type,
|
||||||
|
@ -955,11 +955,10 @@ impl<'a> CodeGenerator<'a> {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let next_list_size = if let Pattern::List { elements, .. } =
|
let next_list_size = if let Pattern::List { elements, .. } =
|
||||||
&clauses[index + 1].pattern[0]
|
&clauses[index + 1].pattern
|
||||||
{
|
{
|
||||||
elements.len()
|
elements.len()
|
||||||
} else if let Pattern::Assign { pattern, .. } =
|
} else if let Pattern::Assign { pattern, .. } = &clauses[index + 1].pattern
|
||||||
&clauses[index + 1].pattern[0]
|
|
||||||
{
|
{
|
||||||
if let Pattern::List { elements, .. } = pattern.as_ref() {
|
if let Pattern::List { elements, .. } = pattern.as_ref() {
|
||||||
elements.len()
|
elements.len()
|
||||||
|
@ -1008,7 +1007,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let subject_name = original_subject_name.clone();
|
let subject_name = original_subject_name.clone();
|
||||||
|
|
||||||
self.when_ir(
|
self.when_ir(
|
||||||
&clause.pattern[0],
|
&clause.pattern,
|
||||||
&mut clause_subject_vec,
|
&mut clause_subject_vec,
|
||||||
&mut clause_then_vec,
|
&mut clause_then_vec,
|
||||||
subject_type,
|
subject_type,
|
||||||
|
|
Loading…
Reference in New Issue