|
@ -4,7 +4,12 @@ |
|
|
const stmt = (stmt_type, args) => ({ type: "stmt", stmt_type, args }) |
|
|
const stmt = (stmt_type, args) => ({ type: "stmt", stmt_type, args }) |
|
|
const decl = (decl_type, name, attrs, args) => ({ type: "decl", decl_type, name, attrs: attrs || [], args }) |
|
|
const decl = (decl_type, name, attrs, args) => ({ type: "decl", decl_type, name, attrs: attrs || [], args }) |
|
|
const uexpr = (op, arg) => ({ type: "unary", op, arg }) |
|
|
const uexpr = (op, arg) => ({ type: "unary", op, arg }) |
|
|
const bexpr = (op, arg1, arg2) => ({ type: "binary", op, arg1, arg2 }) |
|
|
|
|
|
|
|
|
const bexpr = (op, left, right) => ({ type: "binary", op, left, right }) |
|
|
|
|
|
|
|
|
|
|
|
const assocl = (head, tail) => tail.reduce((left, arg) => { |
|
|
|
|
|
const [op, right] = arg |
|
|
|
|
|
return bexpr(op, left, right) |
|
|
|
|
|
}, head) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Program = WS @(Decl / Stmt)* WS |
|
|
Program = WS @(Decl / Stmt)* WS |
|
@ -18,7 +23,24 @@ Stmt = @AssignStmt SEMI |
|
|
AssignStmt = name:Ident ASSIGN expr:Expr { return stmt("assign", { name, expr }) } |
|
|
AssignStmt = name:Ident ASSIGN expr:Expr { return stmt("assign", { name, expr }) } |
|
|
|
|
|
|
|
|
// Expressions |
|
|
// Expressions |
|
|
Expr = UnaryExpr |
|
|
|
|
|
|
|
|
Expr = BitOrExpr |
|
|
|
|
|
|
|
|
|
|
|
BitOrExpr = head:BitXorExpr tail:(op:BitOrOp e:BitXorExpr)* { return assocl(head, tail || []) } |
|
|
|
|
|
BitOrOp = PIPE { return "bit_or" } |
|
|
|
|
|
|
|
|
|
|
|
BitXorExpr = head:BitAndExpr tail:(op:BitXorOp e:BitAndExpr)* { return assocl(head, tail || []) } |
|
|
|
|
|
BitXorOp = CARET { return "bit_xor" } |
|
|
|
|
|
|
|
|
|
|
|
BitAndExpr = head:ShiftExpr tail:(op:BitAndOp e:ShiftExpr)* { return assocl(head, tail || []) } |
|
|
|
|
|
BitAndOp = AMPERSAND { return "bit_and" } |
|
|
|
|
|
|
|
|
|
|
|
ShiftExpr = head:AddExpr tail:(op:ShiftOp e:AddExpr)* { return assocl(head, tail || []) } |
|
|
|
|
|
ShiftOp = LTLT { return "shift_left" } |
|
|
|
|
|
/ GTGT { return "shift_right" } |
|
|
|
|
|
|
|
|
|
|
|
AddExpr = head:UnaryExpr tail:(op:AddOp e:UnaryExpr)* { return assocl(head, tail || []) } |
|
|
|
|
|
AddOp = PLUS { return "add" } |
|
|
|
|
|
/ MINUS { return "subtract" } |
|
|
|
|
|
|
|
|
UnaryExpr = op:UnaryOp? e:BaseExpr { return op ? uexpr(op, e) : e } |
|
|
UnaryExpr = op:UnaryOp? e:BaseExpr { return op ? uexpr(op, e) : e } |
|
|
UnaryOp = TILDE { return "bit_negate" } |
|
|
UnaryOp = TILDE { return "bit_negate" } |
|
@ -51,6 +73,12 @@ U8 = @'u8' WS |
|
|
U16 = @'u16' WS |
|
|
U16 = @'u16' WS |
|
|
|
|
|
|
|
|
// Terminal symbols |
|
|
// Terminal symbols |
|
|
|
|
|
PIPE = '|' WS |
|
|
|
|
|
CARET = '^' WS |
|
|
|
|
|
AMPERSAND = '&' WS |
|
|
|
|
|
LTLT = '<<' WS |
|
|
|
|
|
GTGT = '>>' WS |
|
|
|
|
|
PLUS = '+' WS |
|
|
TILDE = '~' WS |
|
|
TILDE = '~' WS |
|
|
MINUS = '-' WS |
|
|
MINUS = '-' WS |
|
|
SEMI = ';' WS |
|
|
SEMI = ';' WS |
|
|