mighty

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

language2.bnf (4217B)


      1 # Mighty language2 sketch grammar
      2 
      3 program         ::= { nl | top nl }
      4 nl              ::= NEWLINE { NEWLINE }
      5 
      6 top             ::= namespace | use | decl
      7 namespace       ::= "ns" path
      8 use             ::= "use" path
      9 decl            ::= [ "pub" ] ( struct | function | operator )
     10 
     11 struct          ::= "struct" Type [ generics ] "::" block(member)
     12 member          ::= field | decl
     13 field           ::= type names
     14 names           ::= name { "," name }
     15 
     16 function        ::= { pre nl } signature { where_part } body
     17 pre             ::= "pre" expr
     18 where_part      ::= [ nl ] where
     19 where           ::= "where" constraint      # may mention contextual `result`
     20 signature       ::= type name [ generics ] "(" [ params ] ")"
     21 params          ::= param { "," param }
     22 param           ::= type [ name ]
     23 body            ::= [ nl ] "=" ( expr | nl expr ) | "::" block(stmt)
     24 
     25 operator        ::= "op" op [ generics ] "(" params ")" "->" type body
     26 
     27 stmt            ::= binding | ret | expr
     28 binding         ::= type name "=" expr
     29 ret             ::= "ret" expr
     30 
     31 generics        ::= "[" typevar { "," typevar } "]"
     32 typevar         ::= Type
     33 constraint      ::= expr | type_constraint
     34 type_constraint ::= Type ":" trait { "+" trait }
     35 trait           ::= Type
     36 
     37 type            ::= primary_type { type_suffix }
     38 primary_type    ::= path [ type_args ] | "(" types ")"
     39 type_args       ::= "[" type { "," type } "]"
     40 types           ::= type { "," type }
     41 type_suffix     ::= "[]"                    # slice/dynamic array
     42                   | "[" int_lit "]"         # fixed array
     43                   | "?"                      # option: T?
     44                   | "!" type                 # result: T!E
     45 
     46 path            ::= name { "." name }
     47 
     48 expr            ::= conditional
     49 conditional     ::= pipe [ "if" expr "else" expr ]
     50 pipe            ::= scan { "|" ( map | expr ) }
     51 map             ::= "@" "(" expr ")"        # each: `.` is the current element
     52 scan            ::= [ op "\\" ] reduce       # +\xs, *\xs
     53 reduce          ::= [ op "/" ] logic          # +/xs, */xs, max/xs
     54 
     55 logic           ::= compare { ( "and" | "or" ) compare }
     56 compare         ::= range { cmp range }
     57 range           ::= add [ ".." [ add ] ]
     58 add             ::= mul { ( "+" | "-" ) mul }
     59 mul             ::= pow { ( "*" | "/" ) pow }
     60 pow             ::= unary { "^" unary }
     61 unary           ::= [ "-" | "#" ] postfix    # #xs is length/count
     62 
     63 postfix         ::= atom { call | selector | "." name }
     64 call            ::= "(" [ args ] ")"
     65 args            ::= expr { "," expr }
     66 selector        ::= "[" [ items ] "]"        # index, gather, mask, or filter expr
     67 
     68 atom            ::= literal | path | subject | array | record | "(" expr ")"
     69 subject         ::= "." [ name ]             # current subject/self/element
     70 array           ::= "[" [ items ] "]"
     71 items           ::= expr { "," expr }
     72 record          ::= path "(" [ fields ] ")"
     73 fields          ::= field_value { "," field_value }
     74 field_value     ::= name ":" expr
     75 
     76 literal         ::= int_lit | float_lit | string | "true" | "false" | "nil"
     77 op              ::= "+" | "*" | "&" | "|" | "min" | "max" | name
     78 cmp             ::= "==" | "!=" | "<" | "<=" | ">" | ">="
     79 
     80 block(x)        ::= INDENT { nl | x nl } DEDENT
     81 
     82 # Lexical sketch: name is an identifier, Type is a capitalized identifier.
     83 # Comments run from // to end of line.
     84 
     85 # Selector semantics:
     86 # xs[i]          scalar index
     87 # xs[[0, 2]]     gather by int[] indices
     88 # xs[mask]       compress by bool[] mask
     89 # xs[.valid]     filter by expression evaluated per element
     90 
     91 # Array literals use commas: [1, 2, 3], [true, false, true].
     92 
     93 # Named record literals use Type(field: value): Vec2(x: 1.0, y: 2.0).
     94 
     95 # Ranges are half-open. Negative indices are relative to the end.
     96 # xs[0..-1] selects from the first element up to, not including, the last.
     97 
     98 # Reductions over empty collections are invalid unless the operator has a
     99 # defined identity. max/ and min/ require non-empty collections.
    100 
    101 # Values are passed by copy semantically. An implementation may pass by
    102 # read-only reference when that is observationally identical.
    103 
    104 # `.` semantics:
    105 # In methods, `.` is the receiver. In free functions, `.` is the first argument.
    106 # In selectors and @(...), `.` is the current element.