//
// Created by intellij-pest on 2019-04-06
// voile grammar
// Author: ice1000
//
WHITESPACE = _{ WHITE_SPACE | ("//" ~ (!NEWLINE ~ ANY)*) }
// Identifier
ident_char =
_{ ASCII_ALPHA
| "_"
}
ident_raw = _{ ident_char ~ ident_following* }
ident_following =
_{ ident_char
| ASCII_DIGIT
| "'"
| "_"
| "\\"
}
///Yellow
ident =
@{ !"or" ~ ident_raw
| "or" ~ ident_following+
}
///Pink
cons = @{ "@" ~ ident_raw }
///Pink
proj_op = @{ "." ~ ident_raw }
///Red
meta = @{ "_" }
///#E0957B
no_cases = @{ "whatever" }
// Keywords
val_keyword = _{ "val" }
let_keyword = _{ "let" }
case_keyword = _{ "case" }
or_keyword = _{ "or" }
rec_keyword = _{ "Rec" }
sum_keyword = _{ "Sum" }
lambda_keyword = _{ "\\" | "\u{03BB}" }
type_level = @{ ASCII_DIGIT* }
///#E0957B
type_keyword = ${ "Type" ~ type_level }
semicolon = _{ ";" }
arrow = _{ "->" }
lift_op = @{ "^" }
dot = _{ "." }
sig_op = _{ "*" }
pipe_op = _{ "|>" }
comma_op = _{ "," }
dollar_op = _{ "$" }
// Parameters
multi_param = { ident+ ~ ":" ~ expr }
implicit = { "{" ~ multi_param ~ "}" }
explicit = { "(" ~ multi_param ~ ")" }
param =
{ implicit
| explicit
| dollar_expr // unnamed parameter
}
// Lambdas
lambda =
{ lambda_keyword
~ ident+
~ dot
~ expr
}
// Row-polymorphic things
record = { rec_keyword ~ row_polymorphic }
variant = { sum_keyword ~ row_polymorphic }
row_polymorphic =
{ "{"
~ labelled*
~ row_rest?
~ "}"
}
record_kind = { rec_keyword ~ label_list }
variant_kind = { sum_keyword ~ label_list }
label_list = { "[" ~ ident+ ~ "]" }
labelled = { ident ~ ":" ~ expr ~ ";" }
rec_field = { ident ~ "=" ~ expr ~ ";" }
row_rest = { "..." ~ "=" ~ expr }
// Record literals
record_literal =
{ "{|"
~ rec_field*
~ row_rest?
~ "|}"
}
// Case expressions
case_expr =
{ case_keyword
~ ident
~ ident
~ ":"
~ expr
~ or_keyword
~ expr
}
expr = { sig_expr }
sig_expr = { (param ~ sig_op)* ~ pi_expr }
pi_expr = { (param ~ arrow)* ~ dollar_expr }
dollar_expr = { comma_expr ~ (dollar_op ~ comma_expr)* }
comma_expr = { pipe_expr ~ (comma_op ~ pipe_expr)* }
pipe_expr = { lift_expr ~ (pipe_op ~ lift_expr)* }
lift_expr = { lift_op* ~ proj_expr }
proj_expr = { app_expr ~ proj_op* }
app_expr = { primary_expr+ }
primary_expr =
{ type_keyword
| cons
| meta
| no_cases
| lambda
| record
| variant
| record_kind
| variant_kind
| case_expr
| record_literal
| ident
| "(" ~ expr ~ ")"
}
// ML-style type signature and definition
signature =
{ val_keyword
~ ident
~ ":"
~ expr
~ semicolon
}
implementation =
{ let_keyword
~ ident
~ "="
~ expr
~ semicolon
}
declaration =
{ signature
| implementation
}
// File
file = { WHITESPACE* ~ declaration* ~ WHITESPACE* }
standalone_expr = { WHITESPACE* ~ sig_expr ~ WHITESPACE* }