#keywords hard: fun not and or;
#keywords soft: name;
unop = '-' | '~' | "not";
binop = '+' | '-' | '*' | '/' | '%' | '|' | '^' | '&' | '>>' | '<<';
logicop = "and" | "or";
name = @ident | '@' "name" (expr);
delimited_expr = (expr);
tuple = (expr ','*~);
reshape = '.' <name tuple | name>;
chainop = reshape | tuple;
block = { <expr ';'> .*~ };
leaf = &[
name: name;
delimited_expr: delimited_expr;
tuple: tuple;
];
term = <leaf | unop term> chainop .*~;
binexpr = term binop+;
expr = binexpr logicop+;
param = name ':' expr;
param_inferrable = name <':' expr>?;
ct_args = [param_inferrable ','*~];
rt_args = (param ','*~);
function_def = &{
kw: "fun";
name: name;
ct_args: ct_args?;
rt_args: rt_args?;
return_type: <'->' expr>?;
expr: <'=' expr | block>;
};
a = b;
b = a^;