summaryrefslogtreecommitdiff
path: root/src/parser/grammar.pegjs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/grammar.pegjs')
-rw-r--r--src/parser/grammar.pegjs364
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")+