parse function application

This commit is contained in:
mehbark 2026-01-02 00:52:57 -05:00
parent a93092e925
commit 255c9f2109
2 changed files with 55 additions and 19 deletions

View file

@ -73,3 +73,23 @@ compose f g x == (((compose f) g) x) == compose {f: f2, g} x == compose {x} f g
```rust
fn id([x]) ()
```
"Maps" should really just be blocks
```rust
foo := 3;
{
x := 42;
^twice_x := x * 2;
^thrice_x := x * 3;
^foo;
}
```
becomes
```json5
{
"twice_x": 84,
"thrice_x": 126,
// ^foo as a statement behaves like ^foo := foo, so we get that nice record field punning
"foo": 3,
}
```

View file

@ -17,6 +17,9 @@ enum Token<'a> {
#[token(":")]
Colon,
#[token(",")]
Comma,
#[token(";")]
Semicolon,
@ -44,9 +47,6 @@ enum Token<'a> {
#[regex(r"[+*/%=-]")]
BinOp(&'a str),
#[token("fn")]
Fn,
#[regex(r"[a-zA-Z_][a-zA-Z_0-9']*")]
Var(&'a str),
@ -60,6 +60,7 @@ impl fmt::Display for Token<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Token::Colon => write!(f, ":"),
Token::Comma => write!(f, ","),
Token::Semicolon => write!(f, ";"),
Token::Set => write!(f, ":="),
Token::OpenParen => write!(f, "("),
@ -69,7 +70,6 @@ impl fmt::Display for Token<'_> {
Token::OpenBrace => write!(f, "{{"),
Token::CloseBrace => write!(f, "}}"),
Token::Return => write!(f, "^"),
Token::Fn => write!(f, "fn"),
Token::BinOp(x) | Token::Var(x) | Token::Num(x) => write!(f, "{x}"),
Token::Error => write!(f, "ERROR"),
}
@ -85,14 +85,24 @@ fn parser<'tokens, 'src: 'tokens, I>()
where
I: ValueInput<'tokens, Token = Token<'src>, Span = SimpleSpan>,
{
let semicolon = just(Token::Semicolon)
.repeated()
.at_least(1)
.labelled("semicolon");
recursive(|expr| {
let expr = expr.labelled("expression");
let ident = choice((
just(Token::Return).ignore_then(select! {
Token::Var(s) => Ident::Return(s.to_owned())
}),
just(Token::Return)
.ignore_then(select! {
Token::Var(s) => Ident::Return(s.to_owned())
})
.labelled("return identifier"),
select! {
Token::Var(s) => Ident::Local(s.to_owned()),
},
}
.labelled("local identifier"),
))
.labelled("identifier");
@ -115,22 +125,28 @@ where
})
.labelled("number");
let semicolon = just(Token::Semicolon)
.repeated()
.at_least(1)
.labelled("semicolon");
let block = just(Token::OpenParen)
.ignore_then(expr.clone().separated_by(semicolon).collect())
.then_ignore(just(Token::CloseParen))
let block = expr
.clone()
.separated_by(semicolon.clone())
.collect()
.map(Ast::Block)
.delimited_by(just(Token::OpenParen), just(Token::CloseParen))
.labelled("block");
choice((set, ident.map(Ast::Var).labelled("variable"), num, block))
let non_app = choice((set, num, ident.map(Ast::Var).labelled("variable"), block));
let app = non_app
.clone()
.foldl(non_app.clone().repeated(), |f, x| {
Ast::App(Box::new(f), Box::new(x))
})
.labelled("function application");
app.or(non_app)
})
.labelled("expression")
.then_ignore(just(Token::Semicolon).repeated().at_least(1))
.repeated()
.separated_by(semicolon)
.allow_trailing()
.collect()
}