Add block expression parsing

main
trivernis 2 months ago
parent 899c1cebd5
commit 52c7d7234c
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG Key ID: 7E6D18B61C8D2F4B

@ -1,10 +1,12 @@
file = { "hello world" } file = { "hello world" }
statement = { decl } block = { "{" ~ MLF ~ block_line ~ MLF ~ "}" }
block_line = _{ expr | (statement ~ MLF)* }
statement = { (decl | expr) ~ TERMINATE }
decl = { "let" ~ #name = ident ~ #args = (ident)* ~ "=" ~ expr } decl = { "let" ~ #name = ident ~ #args = (ident)* ~ "=" ~ expr }
expr = { infix_expr | call_expr | term } expr = { infix_expr | call_expr | term }
term = _{ ident | literal | "(" ~ expr ~ ")" } term = _{ ident | literal | "(" ~ MLF ~ expr ~ MLF ~ ")" | block }
call_expr = { call_expr = {
#name = ident ~ #args = (term)+ #name = ident ~ #args = (term)+
} }
@ -14,7 +16,7 @@ infix_expr = {
operator = { "+" | "-" | "*" | "/" | "&&" | "||" | "<" | ">" | "==" | "!=" } operator = { "+" | "-" | "*" | "/" | "&&" | "||" | "<" | ">" | "==" | "!=" }
ident = @{ ALPHABETIC ~ (ALPHABETIC | NUMBER | "_")* | quoted_indent } ident = @{ !KEYWORD ~ ALPHABETIC ~ (ALPHABETIC | NUMBER | "_")* | quoted_indent }
quoted_indent = _{ "`" ~ (!"`" ~ ANY)+ ~ "`" } quoted_indent = _{ "`" ~ (!"`" ~ ANY)+ ~ "`" }
literal = { string | number | boolean | char } literal = { string | number | boolean | char }
@ -29,4 +31,8 @@ float = @{
byte = @{ "0x" ~ ASCII_HEX_DIGIT{1, 2} | "0b" ~ ASCII_BIN_DIGIT{0, 8} } byte = @{ "0x" ~ ASCII_HEX_DIGIT{1, 2} | "0b" ~ ASCII_BIN_DIGIT{0, 8} }
boolean = @{ "true" | "false" } boolean = @{ "true" | "false" }
WHITESPACE = _{ " " | "\t" | "\r" | "\n" } WHITESPACE = _{ " " | "\t" }
KEYWORD = _{ "let" }
TERMINATE = _{ LF | EOI | ";" }
MLF = _{ (LF)* }
LF = _{ "\n" | "\r" }

@ -21,6 +21,23 @@ fn it_parses_addition() {
]); ]);
} }
#[test]
fn it_parses_plain_values() {
parses_to!(parser: SnekParser, input: "10", rule: Rule::expr, tokens: [
expr(0, 2, [
literal(0, 2, [
integer(0, 2)
]),
])
]);
parses_to!(parser: SnekParser, input: "test", rule: Rule::expr, tokens: [
expr(0, 4, [
ident(0, 4),
])
]);
}
#[test] #[test]
fn it_parses_addition_with_variables() { fn it_parses_addition_with_variables() {
parses_to!(parser: SnekParser, input: "first + second", rule: Rule::expr, tokens: [ parses_to!(parser: SnekParser, input: "first + second", rule: Rule::expr, tokens: [

@ -13,7 +13,8 @@ fn it_parses_plain_assignments() {
integer(8, 9) integer(8, 9)
]), ]),
]) ])
]) ]),
EOI(9, 9)
]) ])
]); ]);
} }
@ -36,7 +37,76 @@ fn it_parses_assignments_with_args() {
]) ])
]) ])
]) ])
]),
EOI(17, 17)
]),
]);
}
#[test]
fn it_parses_blocks() {
parses_to!(parser: SnekParser, input: "let a = { 1 + 1 }", rule: Rule::statement, tokens: [
statement(0, 17, [
decl(0, 17, [
ident(4, 5),
expr(8, 17, [
block(8, 17, [
expr(10, 15, [
infix_expr(10, 15, [
literal(10, 11, [
integer(10, 11)
]),
operator(12, 13),
expr(14, 15, [
literal(14, 15, [
integer(14, 15)
])
])
])
])
])
])
]),
EOI(17, 17)
])
]);
}
#[test]
fn it_parses_multiline_blocks() {
parses_to!(parser: SnekParser, input: "let a = {\nlet b = 1 + 1\nb\n}", rule: Rule::statement, tokens: [
statement(0, 27, [
decl(0, 27, [
ident(4, 5),
expr(8, 27, [
block(8, 27, [
statement(10, 24, [
decl(10, 23, [
ident(14, 15),
expr(18, 23, [
infix_expr(18, 23, [
literal(18, 19, [
integer(18, 19)
]),
operator(20, 21),
expr(22, 23, [
literal(22, 23, [
integer(22, 23)
])
]) ])
]) ])
])
]),
]),
statement(24, 26, [
expr(24, 25, [
ident(24, 25)
])
])
])
])
]),
EOI(27, 27)
])
]); ]);
} }

Loading…
Cancel
Save