feat: handle punning in a non-ambiguous way
This commit is contained in:
parent
391849bf37
commit
9ebc836b89
|
@ -627,7 +627,7 @@ pub fn expr_parser(
|
|||
|
||||
let record_parser = choice((
|
||||
select! {Token::Name { name } => name}
|
||||
.map_with_span(|module, span| (module, span))
|
||||
.map_with_span(|module, span: Span| (module, span))
|
||||
.then_ignore(just(Token::Dot))
|
||||
.or_not()
|
||||
.then(
|
||||
|
@ -635,35 +635,29 @@ pub fn expr_parser(
|
|||
.map_with_span(|name, span| (name, span)),
|
||||
)
|
||||
.then(
|
||||
select! {Token::Name {name} => name}
|
||||
.then_ignore(just(Token::Colon))
|
||||
.or_not()
|
||||
.then(r.clone())
|
||||
.validate(|(label_opt, value), span, emit| {
|
||||
dbg!(&label_opt);
|
||||
let label = if label_opt.is_some() {
|
||||
label_opt
|
||||
} else if let expr::UntypedExpr::Var { name, .. } = &value {
|
||||
Some(name.clone())
|
||||
} else {
|
||||
emit(ParseError::expected_input_found(
|
||||
value.location(),
|
||||
None,
|
||||
Some(error::Pattern::RecordPunning),
|
||||
));
|
||||
|
||||
None
|
||||
};
|
||||
|
||||
ast::CallArg {
|
||||
choice((
|
||||
select! {Token::Name {name} => name}
|
||||
.then_ignore(just(Token::Colon))
|
||||
.then(r.clone())
|
||||
.map_with_span(|(label, value), span| ast::CallArg {
|
||||
location: span,
|
||||
value,
|
||||
label,
|
||||
label: Some(label),
|
||||
}),
|
||||
select! {Token::Name {name} => name}.map_with_span(|name, span| {
|
||||
ast::CallArg {
|
||||
location: span,
|
||||
value: expr::UntypedExpr::Var {
|
||||
name: name.clone(),
|
||||
location: span,
|
||||
},
|
||||
label: Some(name),
|
||||
}
|
||||
})
|
||||
.separated_by(just(Token::Comma))
|
||||
.allow_trailing()
|
||||
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
|
||||
}),
|
||||
))
|
||||
.separated_by(just(Token::Comma))
|
||||
.allow_trailing()
|
||||
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
|
||||
),
|
||||
select! {Token::Name { name } => name}
|
||||
.map_with_span(|module, span| (module, span))
|
||||
|
@ -918,29 +912,23 @@ pub fn expr_parser(
|
|||
);
|
||||
|
||||
let if_parser = just(Token::If)
|
||||
.ignore_then(
|
||||
r.clone()
|
||||
.then_ignore(just(Token::Then))
|
||||
.then(block_parser.clone())
|
||||
.map_with_span(|(condition, body), span| ast::IfBranch {
|
||||
condition,
|
||||
body,
|
||||
location: span,
|
||||
}),
|
||||
)
|
||||
.ignore_then(r.clone().then(block_parser.clone()).map_with_span(
|
||||
|(condition, body), span| ast::IfBranch {
|
||||
condition,
|
||||
body,
|
||||
location: span,
|
||||
},
|
||||
))
|
||||
.then(
|
||||
just(Token::Else)
|
||||
.ignore_then(just(Token::If))
|
||||
.ignore_then(
|
||||
r.clone()
|
||||
.then_ignore(just(Token::Then))
|
||||
.then(block_parser.clone())
|
||||
.map_with_span(|(condition, body), span| ast::IfBranch {
|
||||
condition,
|
||||
body,
|
||||
location: span,
|
||||
}),
|
||||
)
|
||||
.ignore_then(r.clone().then(block_parser.clone()).map_with_span(
|
||||
|(condition, body), span| ast::IfBranch {
|
||||
condition,
|
||||
body,
|
||||
location: span,
|
||||
},
|
||||
))
|
||||
.repeated(),
|
||||
)
|
||||
.then_ignore(just(Token::Else))
|
||||
|
|
|
@ -69,7 +69,6 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = ParseError> {
|
|||
"fn" => Token::Fn,
|
||||
"if" => Token::If,
|
||||
"else" => Token::Else,
|
||||
"then" => Token::Then,
|
||||
"is" => Token::Is,
|
||||
"let" => Token::Let,
|
||||
"opaque" => Token::Opaque,
|
||||
|
|
|
@ -72,7 +72,6 @@ pub enum Token {
|
|||
Trace,
|
||||
Type,
|
||||
When,
|
||||
Then,
|
||||
}
|
||||
|
||||
impl fmt::Display for Token {
|
||||
|
@ -146,7 +145,6 @@ impl fmt::Display for Token {
|
|||
Token::Todo => "todo",
|
||||
Token::Trace => "try",
|
||||
Token::Type => "type",
|
||||
Token::Then => "then",
|
||||
};
|
||||
write!(f, "\"{}\"", s)
|
||||
}
|
||||
|
|
|
@ -423,11 +423,11 @@ fn pipeline() {
|
|||
fn if_expression() {
|
||||
let code = indoc! {r#"
|
||||
fn ifs() {
|
||||
if True then {
|
||||
if True {
|
||||
1 + 1
|
||||
} else if a < 4 then {
|
||||
} else if a < 4 {
|
||||
5
|
||||
} else if a || b then {
|
||||
} else if a || b {
|
||||
6
|
||||
} else {
|
||||
3
|
||||
|
@ -440,7 +440,7 @@ fn if_expression() {
|
|||
ast::UntypedDefinition::Fn(Function {
|
||||
arguments: vec![],
|
||||
body: expr::UntypedExpr::If {
|
||||
location: Span::new((), 13..121),
|
||||
location: Span::new((), 13..106),
|
||||
branches: vec1::vec1![
|
||||
ast::IfBranch {
|
||||
condition: expr::UntypedExpr::Var {
|
||||
|
@ -448,60 +448,60 @@ fn if_expression() {
|
|||
name: "True".to_string(),
|
||||
},
|
||||
body: expr::UntypedExpr::BinOp {
|
||||
location: Span::new((), 32..37),
|
||||
location: Span::new((), 27..32),
|
||||
name: ast::BinOp::AddInt,
|
||||
left: Box::new(expr::UntypedExpr::Int {
|
||||
location: Span::new((), 32..33),
|
||||
location: Span::new((), 27..28),
|
||||
value: "1".to_string(),
|
||||
}),
|
||||
right: Box::new(expr::UntypedExpr::Int {
|
||||
location: Span::new((), 36..37),
|
||||
location: Span::new((), 31..32),
|
||||
value: "1".to_string(),
|
||||
}),
|
||||
},
|
||||
location: Span::new((), 16..41),
|
||||
location: Span::new((), 16..36),
|
||||
},
|
||||
ast::IfBranch {
|
||||
condition: expr::UntypedExpr::BinOp {
|
||||
location: Span::new((), 50..55),
|
||||
location: Span::new((), 45..50),
|
||||
name: ast::BinOp::LtInt,
|
||||
left: Box::new(expr::UntypedExpr::Var {
|
||||
location: Span::new((), 50..51),
|
||||
location: Span::new((), 45..46),
|
||||
name: "a".to_string(),
|
||||
}),
|
||||
right: Box::new(expr::UntypedExpr::Int {
|
||||
location: Span::new((), 54..55),
|
||||
location: Span::new((), 49..50),
|
||||
value: "4".to_string(),
|
||||
}),
|
||||
},
|
||||
body: expr::UntypedExpr::Int {
|
||||
location: Span::new((), 67..68),
|
||||
location: Span::new((), 57..58),
|
||||
value: "5".to_string(),
|
||||
},
|
||||
location: Span::new((), 50..72),
|
||||
location: Span::new((), 45..62),
|
||||
},
|
||||
ast::IfBranch {
|
||||
condition: expr::UntypedExpr::BinOp {
|
||||
location: Span::new((), 81..87),
|
||||
location: Span::new((), 71..77),
|
||||
name: ast::BinOp::Or,
|
||||
left: Box::new(expr::UntypedExpr::Var {
|
||||
location: Span::new((), 81..82),
|
||||
location: Span::new((), 71..72),
|
||||
name: "a".to_string(),
|
||||
}),
|
||||
right: Box::new(expr::UntypedExpr::Var {
|
||||
location: Span::new((), 86..87),
|
||||
location: Span::new((), 76..77),
|
||||
name: "b".to_string(),
|
||||
}),
|
||||
},
|
||||
body: expr::UntypedExpr::Int {
|
||||
location: Span::new((), 99..100),
|
||||
location: Span::new((), 84..85),
|
||||
value: "6".to_string(),
|
||||
},
|
||||
location: Span::new((), 81..104),
|
||||
location: Span::new((), 71..89),
|
||||
},
|
||||
],
|
||||
final_else: Box::new(expr::UntypedExpr::Int {
|
||||
location: Span::new((), 116..117),
|
||||
location: Span::new((), 101..102),
|
||||
value: "3".to_string(),
|
||||
}),
|
||||
},
|
||||
|
@ -511,7 +511,7 @@ fn if_expression() {
|
|||
public: false,
|
||||
return_annotation: None,
|
||||
return_type: (),
|
||||
end_position: 122,
|
||||
end_position: 107,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ pub fn final_check(z: Int) {
|
|||
}
|
||||
|
||||
pub fn incrementor(counter: Int, target: Int) -> Int {
|
||||
if counter == target then {
|
||||
if counter == target {
|
||||
target
|
||||
} else {
|
||||
incrementor(counter + 1, target)
|
||||
|
|
Loading…
Reference in New Issue