voile 0.2.6

Voile, a dependently-typed row-polymorphic programming language
Documentation
//
// 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* }