mighty

The mighty programming language, compiler and tools (WIP)
Log | Files | Refs

old-language.bnf (6207B)


      1 ---------- plan
      2 
      3 5 scalar types: int float bool char str
      4 arrays: T[]
      5 structs
      6 enums
      7 methods
      8 contracts: @pre @post @inv
      9 expression functions with =
     10 block functions with ::
     11 match
     12 conditional expression: x if cond else y
     13 pipes: | f, | f(args), | [pred], | @(mapper)
     14 
     15 drop for now:
     16 
     17 block if/else
     18 fixed-shape arrays
     19 implicit whitespace arrays
     20 bind-pipe
     21 mutating methods
     22 function overloading
     23 standalone attributes
     24 same-line block bodies
     25 complex # shape semantics
     26 
     27 note: pipe rules:
     28 x | f              // f(x)
     29 x | f(a, b)        // f(x, a, b)
     30 x | [pred]         // filter(x, pred)
     31 x | @(mapper)      // map(x, mapper)
     32 
     33 
     34 
     35 
     36 ------------------ ebnf
     37 
     38 
     39 
     40 
     41 :: opens a layout block
     42 indent enters the block
     43 dedent exits the block
     44 newline separates statements
     45 ; only separates statements on one line
     46 
     47 = opens to a single expr line
     48 
     49 note: the following is wrong about this
     50 
     51 
     52 
     53 
     54 program         = { top_decl } EOF ;
     55 
     56 top_decl        = mod_decl
     57                 | use_decl
     58                 | type_decl
     59                 | const_decl
     60                 | func_decl ;
     61 
     62 mod_decl        = "mod" path CLOSE ;
     63 use_decl        = "use" path CLOSE ;
     64 
     65 path            = ident { "." ident } ;
     66 
     67 attr_decl       = attr { NEWLINE attr } ;
     68 attr            = "@" ident expr ;
     69 
     70 const_decl      = "const" type ident "=" expr CLOSE ;
     71 
     72 func_decl       = { attr NEWLINE }
     73                   type ident "(" [ params ] ")" func_body ;
     74 
     75 func_body       = "=" expr CLOSE
     76                 | "::" block ;
     77 
     78 params          = param { "," param } ;
     79 param           = [ "mut" ] type ident
     80                 | [ "mut" ] "self" ;
     81 
     82 type            = base_type { array_suffix } ;
     83 
     84 base_type       = "int"
     85                 | "float"
     86                 | "bool"
     87                 | "char"
     88                 | "str"
     89                 | ident ;
     90 
     91 array_suffix    = "[]" ;
     92 shape           = int_lit { "," int_lit } ;
     93 
     94 
     95 
     96 
     97 
     98 
     99 
    100 
    101 block           = NEWLINE INDENT block_body DEDENT ;
    102 
    103 block_body      = { stmt stmt_sep } final_expr CLOSE ;
    104 
    105 stmt_sep        = NEWLINE | SEP ;
    106 
    107 stmt            = var_decl
    108                 | assign_stmt
    109                 | defer_stmt
    110                 | expr ;
    111 
    112 var_decl        = [ "mut" ] type ident "=" expr ;
    113 
    114 assign_stmt     = lvalue "=" expr ;
    115 
    116 defer_stmt      = "defer" expr ;
    117 
    118 final_expr      = expr ;
    119 
    120 lvalue          = ident
    121                 | postfix_expr "." ident
    122                 | postfix_expr "[" expr "]" ;
    123 
    124 
    125 
    126 
    127 
    128 
    129 
    130 
    131 int main() ::
    132     io.put("hello")
    133     0;
    134 // becomes
    135 func_decl
    136   block
    137     stmt: io.put("hello")
    138     final_expr: 0
    139     CLOSE
    140 
    141 
    142 
    143 
    144 
    145 
    146 
    147 
    148 
    149 
    150 
    151 type_decl       = "type" ident "=" type_body CLOSE ;
    152 
    153 type_body       = struct_type
    154                 | enum_type
    155                 | type ;
    156 
    157 struct_type     = "struct" "::" NEWLINE INDENT
    158                     { struct_item }
    159                   DEDENT ;
    160 
    161 struct_item     = field_decl
    162                 | method_decl
    163                 | attr_decl ;
    164 
    165 field_decl      = type ident stmt_sep ;
    166 
    167 method_decl     = { attr NEWLINE }
    168                   type ident "(" [ params ] ")" func_body ;
    169 
    170 enum_type       = "enum" "::" NEWLINE INDENT
    171                     { enum_item }
    172                   DEDENT ;
    173 
    174 enum_item       = enum_case stmt_sep
    175                 | method_decl
    176                 | attr_decl ;
    177 
    178 enum_case       = ident [ "(" [ fields ] ")" ] ;
    179 
    180 fields          = field { "," field } ;
    181 field           = type ident ;
    182 
    183 
    184 
    185 
    186 
    187 
    188 
    189 
    190 primary
    191 postfix: call, index, field
    192 prefix: -, !, #, +/, */, min/, max/, avg/
    193 power: ^
    194 multiplicative: *, /, %
    195 additive: +, -
    196 range: ..
    197 comparison: == != < <= > >=
    198 logical and
    199 logical or
    200 pipe: |
    201 lambda: =>
    202 
    203 
    204 
    205 
    206 
    207 
    208 ebnf
    209 
    210 
    211 expr            = lambda_expr ;
    212 
    213 lambda_expr     = pipe_expr
    214                 | ident "=>" expr ;
    215 
    216 pipe_expr       = logic_or_expr { "|" pipe_stage } ;
    217 
    218 pipe_stage      = "[" expr "]"                 (* filter: x | [pred] *)
    219                 | "@(" expr ")"                (* map:    x | @(f) *)
    220                 | ident "=>" expr              (* bind:   x | y => expr *)
    221                 | "." ident "(" [ args ] ")"   (* method: x | .len() *)
    222                 | postfix_expr ;               (* call:   x | f or x | f(a) *)
    223 
    224 logic_or_expr   = logic_and_expr { "or" logic_and_expr } ;
    225 
    226 logic_and_expr  = compare_expr { "and" compare_expr } ;
    227 
    228 compare_expr    = range_expr { compare_op range_expr } ;
    229 
    230 compare_op      = "==" | "!=" | "<" | "<=" | ">" | ">=" ;
    231 
    232 range_expr      = add_expr [ ".." add_expr ] ;
    233 
    234 add_expr        = mul_expr { add_op mul_expr } ;
    235 add_op          = "+" | "-" ;
    236 
    237 mul_expr        = power_expr { mul_op power_expr } ;
    238 mul_op          = "*" | "/" | "%" ;
    239 
    240 power_expr      = prefix_expr [ "^" power_expr ] ;
    241 
    242 prefix_expr     = prefix_op prefix_expr
    243                 | postfix_expr ;
    244 
    245 prefix_op       = "-"
    246                 | "!"
    247                 | "#"
    248                 | "+/"
    249                 | "*/"
    250                 | "min/"
    251                 | "max/"
    252                 | "avg/" ;
    253 
    254 postfix_expr    = primary_expr { postfix_suffix } ;
    255 
    256 postfix_suffix  = call_suffix
    257                 | index_suffix
    258                 | field_suffix ;
    259 
    260 call_suffix     = "(" [ args ] ")" ;
    261 args            = expr { "," expr } ;
    262 
    263 index_suffix    = "[" index_expr "]" ;
    264 index_expr      = expr
    265                 | [ expr ] ".." [ expr ] ;
    266 
    267 field_suffix    = "." ident ;
    268 
    269 primary_expr    = literal
    270                 | ident
    271                 | array_lit
    272                 | if_expr
    273                 | match_expr
    274                 | "(" expr ")" ;
    275 
    276 
    277 
    278 
    279 
    280 
    281 
    282 
    283 
    284 expr              = lambda_expr ;
    285 
    286 lambda_expr       = if_expr
    287                   | ident "=>" expr ;
    288 
    289 if_expr  = pipe_expr [ "if" expr "else" if_expr ] ;
    290 
    291 
    292 
    293 
    294 
    295 
    296 
    297 
    298 
    299 
    300 
    301 literal         = int_lit
    302                 | float_lit
    303                 | bool_lit
    304                 | char_lit
    305                 | str_lit ;
    306 
    307 bool_lit        = "true" | "false" ;
    308 
    309 array_lit       = "[" [ expr { "," expr } ] "]"
    310                 | scalar_run ;
    311 
    312 scalar_run      = scalar_atom scalar_atom { scalar_atom } ;
    313 
    314 scalar_atom     = int_lit
    315                 | float_lit
    316                 | bool_lit
    317                 | char_lit
    318                 | str_lit ;
    319 
    320 ident           = letter { letter | digit | "_" } ;
    321 
    322 int_lit         = digit { digit } ;
    323 float_lit       = digit { digit } "." digit { digit } ;
    324 
    325 char_lit        = "'" char_body "'" ;
    326 str_lit         = '"' { str_char } '"' ;
    327 
    328 
    329 
    330 
    331 
    332 
    333 
    334 
    335