Files
vulcan/forge_core/src/forge.pest
T

72 lines
2.9 KiB
Plaintext
Raw Normal View History

2023-07-02 02:10:06 -05:00
WHITESPACE = _{ " " | "\t" | NEWLINE }
COMMENT = _{ "//" ~ (!"\n" ~ ANY)* }
name_char = { ASCII_ALPHA_LOWER | ASCII_ALPHA_UPPER | "_" | "$" }
name = @{ name_char ~ (name_char | ASCII_DIGIT)* }
dec_number = @{ ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* }
neg_number = ${ "-" ~ dec_number }
hex_number = ${ "0x" ~ ASCII_HEX_DIGIT+ }
bin_number = ${ "0b" ~ ASCII_BIN_DIGIT+ }
oct_number = ${ "0o" ~ ASCII_OCT_DIGIT+ }
dec_zero = @{ "0" }
number = { dec_number | hex_number | bin_number | oct_number | dec_zero | neg_number }
2023-07-03 01:35:37 -05:00
escape = @{ "\\" ~ ("t" | "r" | "n" | "0" | "\\" | "\"") }
string_inner = ${ !("\"" | "\\") ~ ANY | escape }
string = ${ "\"" ~ string_inner* ~ "\"" }
2023-07-02 02:10:06 -05:00
assignment = { lvalue ~ "=" ~ rvalue }
lvalue = { arrayref | name }
rvalue = { expr | string }
sign = { "+" | "-" }
term_op = { "*" | "/" | "%" }
expr = { term ~ (sign ~ term)* }
term = { val ~ (term_op ~ val)* }
val = { // These are what get evaluated and left on the stack:
number | // Literal numbers
("(" ~ expr ~ ")") | // Nested parenthesized exprs
// Bare literal ids, fn calls, array references
// (call, or pointer arithmetic, since ids all reference addresses)
// (multiple calls / subscripts aren't allowed; use CALL or collapse to one
// subscript)
2023-07-04 02:49:29 -05:00
call | arrayref | name | address }
2023-07-02 02:10:06 -05:00
2023-07-04 02:49:29 -05:00
address = { "&" ~ name } // The address for a name
2023-07-02 02:10:06 -05:00
arrayref = { name ~ subscript } // Subscripting is only literal IDs. Anything else can be pointer arithmetic
call = { name ~ arglist } // Call syntax is only literal IDs. Calling things dynamically is done with a builtin; CALL(foo[3], 1, 2, 3)
2023-07-08 19:09:32 -05:00
arglist = { "(" ~ (rvalue ~ ("," ~ rvalue)*)? ~ ")" }
2023-07-02 02:10:06 -05:00
subscript = { "[" ~ expr ~ "]" }
2023-07-04 02:49:29 -05:00
statement = { ((return_stmt | assignment | call | var_decl) ~ ";") | conditional | while_loop | repeat_loop }
2023-07-02 02:10:06 -05:00
block = { "{" ~ statement* ~ "}" }
function = { "fn" ~ name ~ annotations? ~ argnames ~ block }
annotations = { "<" ~ (annotation ~ ("," ~ annotation)*) ~ ">" }
2023-07-03 17:19:19 -05:00
annotation = { inline_annotation | org_annotation | type_annotation }
inline_annotation = { "inline" }
org_annotation = { "org=" ~ number }
type_annotation = { "type=" ~ name }
argnames = { "(" ~ (argname ~ ("," ~ argname)*)? ~ ")" }
argname = { name ~ typename? }
2023-07-02 02:10:06 -05:00
2023-07-03 01:35:37 -05:00
declaration = { function | global | struct_decl | const_decl }
program = { (COMMENT | WHITESPACE)? ~ declaration* ~ EOI }
2023-07-02 02:10:06 -05:00
2023-07-08 19:09:32 -05:00
return_stmt = { "return" ~ expr? }
2023-07-02 02:10:06 -05:00
conditional = { "if" ~ "(" ~ expr ~ ")" ~ block ~ ("else" ~ block)? }
2023-07-04 02:49:29 -05:00
while_loop = { "while" ~ "(" ~ expr ~ ")" ~ block }
repeat_loop = { "repeat" ~ "(" ~ expr ~ ")" ~ name ~ block }
2023-07-03 01:35:37 -05:00
var_decl = { "var" ~ name ~ varinfo ~ ("=" ~ expr)? }
global = { "global" ~ name ~ varinfo ~ ";" }
2023-07-02 02:10:06 -05:00
typename = { ":" ~ name }
2023-07-03 01:35:37 -05:00
size = { "[" ~ number ~ "]" }
2023-07-02 02:10:06 -05:00
const_decl = { "const" ~ name ~ "=" ~ (number | string) ~ ";" }
struct_decl = { "struct" ~ name ~ "{" ~ members ~ "}" }
2023-07-03 01:35:37 -05:00
member = { name ~ varinfo }
members = { (member ~ ("," ~ member)*)? }
varinfo = { typename? ~ size? }