diff options
Diffstat (limited to 'src/parser/grammar.pegjs')
-rw-r--r-- | src/parser/grammar.pegjs | 364 |
1 files changed, 364 insertions, 0 deletions
diff --git a/src/parser/grammar.pegjs b/src/parser/grammar.pegjs new file mode 100644 index 0000000..b375608 --- /dev/null +++ b/src/parser/grammar.pegjs @@ -0,0 +1,364 @@ +Program + = exprs:(ContinuationExpression / _)* { + return exprs.filter(x => !Array.isArray(x)); + } + +ContinuationExpression + = RecordExpression + / SelectExpression + / OffsetExpression + / ApplicationExpression + / FixExpression + / SwitchExpression + / PrimitiveOperationExpression + +SelectExpression + = SELECT + _? + LPAREN + _? + select:Integer + _? + COMMA + _? + val:Value + _? + COMMA + _? + bind:Identifier + _? + continuation:ContinuationExpression + _? + RPAREN { return { select, val, bind, continuation }; } + +OffsetExpression + = OFFSET + _? + LPAREN + _? + offset:Integer + _? + COMMA + _? + val:Value + _? + COMMA + _? + bind:Identifier + _? + continuation:ContinuationExpression + _? + RPAREN { return { offset, val, bind, continuation }; } + +IdentifierList + = LBRACKET + _? + identifiers:(ident:Identifier _? COMMA _?)* + _? + lastIdent:Identifier? + _? + RBRACKET { + return identifiers.length || lastIdent + ? [...identifiers.map(x => x.ident), lastIdent] + : []; + } + +ValueList + = LBRACKET + _? + values:(value:Value _? COMMA _?)* + _? + lastValue:Value? + _? + RBRACKET { + return values.length || lastValue + ? [...values.map(x => x.value), lastValue] + : []; + } + +SwitchExpression + = SWITCH + _? + LPAREN + _? + switchIndex:Value + _? + COMMA + _? + continuations:ContinuationList + _? + RPAREN { return { switchIndex, continuations }; } + +ApplicationExpression + = APP _? LPAREN _? fn:Value _? COMMA _? args:ValueList _? RPAREN { + return { fn, args }; + } + +FixBinding + = LPAREN + _? + fn:Identifier + _? + COMMA + _? + args:IdentifierList + _? + COMMA + _? + continuation:ContinuationExpression + _? + RPAREN + +FixBindingList + = LBRACKET + _ + bindings:(binding:FixBinding _? COMMA _?)* + _? + lastBinding:FixBinding? + _? + RBRACKET { + return bindings.length || lastBinding + ? [...bindings.map(x => x.binding), lastBinding] + : []; + } + +FixExpression + = FIX + _? + LPAREN + _? + fixBindings:FixBindingList + _? + COMMA + _? + continuation:ContinuationExpression + _? + RPAREN { return { fixBindings, continuation }; } + +ContinuationList + = LBRACKET + _? + continuations:(continuation:ContinuationExpression _? COMMA _?)* + _? + lastContinuation:ContinuationExpression? + _? + RBRACKET { + return lastContinuation || continuations.length + ? [...continuations.map(x => x.continuation), lastContinuation] + : []; + } + +PrimitiveOperationExpression + = PRIMOP + _? + LPAREN + _? + opr:PrimitiveOperation + _? + COMMA + _? + operands:ValueList + _? + COMMA + _? + resultBindings:IdentifierList + _? + COMMA + _? + continuations:ContinuationList + _? + RPAREN { return { opr, operands, resultBindings, continuations }; } + +RecordExpressionTuple + = LPAREN + _? + variable:VarStatement + _? + COMMA + _? + offset:OffsetStatement + _? + RPAREN { return { variable, offset }; } + +RecordExpressionTupleList + = LBRACKET + _? + records:(record:RecordExpressionTuple _? COMMA _?)* + _? + lastRecord:RecordExpressionTuple? + _? + RBRACKET { + return records.length || lastRecord + ? [...records.map(x => x.record), lastRecord] + : []; + } + +RecordExpression + = RECORD + _? + LPAREN + _? + records:RecordExpressionTupleList + _? + COMMA + _? + address:Literal + _? + COMMA + _? + body:ContinuationExpression + _? + RPAREN { + return { + records, + address, + body, + }; + } + +Value + = VarStatement + / LabelStatement + / IntStatement + / RealStatement + / StringStatement + +VarStatement = VAR _ ident:Identifier { return ident; } + +LabelStatement = LABEL _ ident:Identifier { return ident; } + +IntStatement = INT _ int:Integer { return int; } + +RealStatement = REAL _ real:Real { return real; } + +StringStatement = STRING _ string:QuotedString { return string; } + +AccessStatement + = OffsetStatement + / SelectStatement + +OffsetStatement = OFFP _ offset:Integer { return offset; } + +SelectStatement = SELP _ offset:Integer { return offset; } + +Identifier + = name:([A-Za-z] (LETTER / DIGIT / SAFE_SYMBOL)*) { + return { name: name[0] + name[1].join('') }; + } + +PrimitiveOperation + = ArithmeticOperation + / ComparisonOperation + / BitOperation + / StoreOperation + +StoreOperation + = STORE + / UPDATE + / MAKEREF + / MAKEREFUNBOXED + / UNBOXED_UPDATE + / BOXED + / SUBSCRIPT + +ArithmeticOperation + = "+" + / "-" + / "/" + / "*" + / "**" + +BitOperation + = ">>" + / "<<" + / "~" + / "^" + +ComparisonOperation + = "==" + / "<=" + / ">=" + / "!=" + / "!" + / ">" + / "<" + +Integer = digits:[0-9]+ !"." { return parseInt(digits.join(''), 10); } + +QuotedString + = "'" content:[^']* "'" { return content.join(''); } + / "\"" content:[^"]* "\"" { return content.join(''); } + +Real + = value:("-"? [0-9]+ "." [0-9]+) { + return parseFloat( + value.map(x => (Array.isArray(x) ? x.join('') : x)).join(''), + ); + } + +Literal + = Real + / QuotedString + / Integer + +OFFSET = "OFFSET" + +OFFP = "OFFp" + +SELP = "SELp" + +VAR = "VAR" + +INT = "INT" + +REAL = "REAL" + +STRING = "STRING" + +APP = "APP" + +RECORD = "RECORD" + +SELECT = "SELECT" + +FIX = "FIX" + +SWITCH = "SWITCH" + +PRIMOP = "PRIMOP" + +LABEL = "LABEL" + +STORE = "store" + +UPDATE = "update" + +MAKEREF = "makeref" + +MAKEREFUNBOXED = "makerefunboxed" + +UNBOXED_UPDATE = "unboxedupdate" + +SUBSCRIPT = "subscript" + +BOXED = "boxed" + +LETTER = [A-Za-z] + +SAFE_SYMBOL = "_" + +DIGIT = [0-9] + +LBRACKET = "[" + +RBRACKET = "]" + +COMMA = "," + +EQUALS = "=" + +LPAREN = "(" + +RPAREN = ")" + +_ = (" " / "\n" / "\t" / "\r\n")+ |