From e8e9ee18f29b2557fdc514c4322f5446484c4d58 Mon Sep 17 00:00:00 2001 From: Elizabeth Hunt Date: Fri, 23 Feb 2024 17:27:16 -0700 Subject: [PATCH] simple parser --- src/parser/grammar.pegjs | 58 ++++----- src/parser/parser.ts | 258 +++++++++++++++++++++----------------- test/logger.ts | 8 ++ test/parser.spec.ts | 7 ++ test/programs/add-1-3.cps | 2 + test/programs/index.ts | 7 ++ 6 files changed, 198 insertions(+), 142 deletions(-) create mode 100644 test/logger.ts create mode 100644 test/parser.spec.ts create mode 100644 test/programs/add-1-3.cps create mode 100644 test/programs/index.ts diff --git a/src/parser/grammar.pegjs b/src/parser/grammar.pegjs index b375608..007bc1d 100644 --- a/src/parser/grammar.pegjs +++ b/src/parser/grammar.pegjs @@ -17,7 +17,7 @@ SelectExpression _? LPAREN _? - select:Integer + record:Integer _? COMMA _? @@ -27,16 +27,18 @@ SelectExpression _? bind:Identifier _? + COMMA + _? continuation:ContinuationExpression _? - RPAREN { return { select, val, bind, continuation }; } + RPAREN { return { select: { record, val, bind, continuation } }; } OffsetExpression = OFFSET _? LPAREN _? - offset:Integer + index:Integer _? COMMA _? @@ -48,31 +50,25 @@ OffsetExpression _? continuation:ContinuationExpression _? - RPAREN { return { offset, val, bind, continuation }; } + RPAREN { return { offset: { index, val, bind, continuation } }; } IdentifierList = LBRACKET _? - identifiers:(ident:Identifier _? COMMA _?)* + identifiers:(Identifier _? COMMA _?)* _? lastIdent:Identifier? _? RBRACKET { return identifiers.length || lastIdent - ? [...identifiers.map(x => x.ident), lastIdent] + ? [...identifiers.map(x => x[0]), lastIdent] : []; } ValueList - = LBRACKET - _? - values:(value:Value _? COMMA _?)* - _? - lastValue:Value? - _? - RBRACKET { + = LBRACKET _? values:(Value _? COMMA _?)* _? lastValue:Value? _? RBRACKET { return values.length || lastValue - ? [...values.map(x => x.value), lastValue] + ? [...values.map(x => x[0]), lastValue] : []; } @@ -87,11 +83,11 @@ SwitchExpression _? continuations:ContinuationList _? - RPAREN { return { switchIndex, continuations }; } + RPAREN { return { switch: { switchIndex, continuations } }; } ApplicationExpression = APP _? LPAREN _? fn:Value _? COMMA _? args:ValueList _? RPAREN { - return { fn, args }; + return { application: { fn, args } }; } FixBinding @@ -111,14 +107,14 @@ FixBinding FixBindingList = LBRACKET - _ - bindings:(binding:FixBinding _? COMMA _?)* + _? + bindings:(FixBinding _? COMMA _?)* _? lastBinding:FixBinding? _? RBRACKET { return bindings.length || lastBinding - ? [...bindings.map(x => x.binding), lastBinding] + ? [...bindings.map(x => x[0]), lastBinding] : []; } @@ -133,18 +129,18 @@ FixExpression _? continuation:ContinuationExpression _? - RPAREN { return { fixBindings, continuation }; } + RPAREN { return { fix: { fixBindings, continuation } }; } ContinuationList = LBRACKET _? - continuations:(continuation:ContinuationExpression _? COMMA _?)* + continuations:(ContinuationExpression _? COMMA _?)* _? lastContinuation:ContinuationExpression? _? RBRACKET { return lastContinuation || continuations.length - ? [...continuations.map(x => x.continuation), lastContinuation] + ? [...continuations.map(x => x[0]), lastContinuation] : []; } @@ -167,7 +163,11 @@ PrimitiveOperationExpression _? continuations:ContinuationList _? - RPAREN { return { opr, operands, resultBindings, continuations }; } + RPAREN { + return { + primitiveOperation: { opr, operands, resultBindings, continuations }, + }; + } RecordExpressionTuple = LPAREN @@ -183,13 +183,13 @@ RecordExpressionTuple RecordExpressionTupleList = LBRACKET _? - records:(record:RecordExpressionTuple _? COMMA _?)* + records:(RecordExpressionTuple _? COMMA _?)* _? lastRecord:RecordExpressionTuple? _? RBRACKET { return records.length || lastRecord - ? [...records.map(x => x.record), lastRecord] + ? [...records.map(x => x[0]), lastRecord] : []; } @@ -210,9 +210,11 @@ RecordExpression _? RPAREN { return { - records, - address, - body, + record: { + records, + address, + body, + }, }; } diff --git a/src/parser/parser.ts b/src/parser/parser.ts index 6e09c0d..c3708cf 100644 --- a/src/parser/parser.ts +++ b/src/parser/parser.ts @@ -408,17 +408,17 @@ function peg$parse(input, options) { return exprs.filter(x => !Array.isArray(x)); };// @ts-ignore - var peg$f1 = function(select, val, bind, continuation) {// @ts-ignore - return { select, val, bind, continuation }; };// @ts-ignore + var peg$f1 = function(record, val, bind, continuation) {// @ts-ignore + return { select: { record, val, bind, continuation } }; };// @ts-ignore - var peg$f2 = function(offset, val, bind, continuation) {// @ts-ignore - return { offset, val, bind, continuation }; };// @ts-ignore + var peg$f2 = function(index, val, bind, continuation) {// @ts-ignore + return { offset: { index, val, bind, continuation } }; };// @ts-ignore var peg$f3 = function(identifiers, lastIdent) { // @ts-ignore return identifiers.length || lastIdent // @ts-ignore - ? [...identifiers.map(x => x.ident), lastIdent] + ? [...identifiers.map(x => x[0]), lastIdent] : []; };// @ts-ignore @@ -426,39 +426,44 @@ function peg$parse(input, options) { // @ts-ignore return values.length || lastValue // @ts-ignore - ? [...values.map(x => x.value), lastValue] + ? [...values.map(x => x[0]), lastValue] : []; };// @ts-ignore var peg$f5 = function(switchIndex, continuations) {// @ts-ignore - return { switchIndex, continuations }; };// @ts-ignore + return { switch: { switchIndex, continuations } }; };// @ts-ignore var peg$f6 = function(fn, args) { // @ts-ignore - return { fn, args }; + return { application: { fn, args } }; };// @ts-ignore var peg$f7 = function(bindings, lastBinding) { // @ts-ignore return bindings.length || lastBinding // @ts-ignore - ? [...bindings.map(x => x.binding), lastBinding] + ? [...bindings.map(x => x[0]), lastBinding] : []; };// @ts-ignore var peg$f8 = function(fixBindings, continuation) {// @ts-ignore - return { fixBindings, continuation }; };// @ts-ignore + return { fix: { fixBindings, continuation } }; };// @ts-ignore var peg$f9 = function(continuations, lastContinuation) { // @ts-ignore return lastContinuation || continuations.length // @ts-ignore - ? [...continuations.map(x => x.continuation), lastContinuation] + ? [...continuations.map(x => x[0]), lastContinuation] : []; };// @ts-ignore - var peg$f10 = function(opr, operands, resultBindings, continuations) {// @ts-ignore - return { opr, operands, resultBindings, continuations }; };// @ts-ignore + var peg$f10 = function(opr, operands, resultBindings, continuations) { +// @ts-ignore + return { +// @ts-ignore + primitiveOperation: { opr, operands, resultBindings, continuations }, + }; + };// @ts-ignore var peg$f11 = function(variable, offset) {// @ts-ignore return { variable, offset }; };// @ts-ignore @@ -467,7 +472,7 @@ function peg$parse(input, options) { // @ts-ignore return records.length || lastRecord // @ts-ignore - ? [...records.map(x => x.record), lastRecord] + ? [...records.map(x => x[0]), lastRecord] : []; };// @ts-ignore @@ -475,11 +480,14 @@ function peg$parse(input, options) { // @ts-ignore return { // @ts-ignore - records, + record: { // @ts-ignore - address, + records, // @ts-ignore - body, + address, +// @ts-ignore + body, + }, }; };// @ts-ignore @@ -874,7 +882,7 @@ peg$parseContinuationExpression() { function // @ts-ignore peg$parseSelectExpression() { // @ts-ignore - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17; + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19; // @ts-ignore s0 = peg$currPos; @@ -956,7 +964,7 @@ peg$parseSelectExpression() { s14 = null; } // @ts-ignore - s15 = peg$parseContinuationExpression(); + s15 = peg$parseCOMMA(); // @ts-ignore if (s15 !== peg$FAILED) { // @ts-ignore @@ -967,13 +975,31 @@ peg$parseSelectExpression() { s16 = null; } // @ts-ignore - s17 = peg$parseRPAREN(); + s17 = peg$parseContinuationExpression(); // @ts-ignore if (s17 !== peg$FAILED) { // @ts-ignore - peg$savedPos = s0; + s18 = peg$parse_(); // @ts-ignore - s0 = peg$f1(s5, s9, s13, s15); + if (s18 === peg$FAILED) { +// @ts-ignore + s18 = null; + } +// @ts-ignore + s19 = peg$parseRPAREN(); +// @ts-ignore + if (s19 !== peg$FAILED) { +// @ts-ignore + peg$savedPos = s0; +// @ts-ignore + s0 = peg$f1(s5, s9, s13, s17); +// @ts-ignore + } else { +// @ts-ignore + peg$currPos = s0; +// @ts-ignore + s0 = peg$FAILED; + } // @ts-ignore } else { // @ts-ignore @@ -1917,9 +1943,58 @@ peg$parseFixBindingList() { // @ts-ignore s2 = peg$parse_(); // @ts-ignore - if (s2 !== peg$FAILED) { + if (s2 === peg$FAILED) { // @ts-ignore - s3 = []; + s2 = null; + } +// @ts-ignore + s3 = []; +// @ts-ignore + s4 = peg$currPos; +// @ts-ignore + s5 = peg$parseFixBinding(); +// @ts-ignore + if (s5 !== peg$FAILED) { +// @ts-ignore + s6 = peg$parse_(); +// @ts-ignore + if (s6 === peg$FAILED) { +// @ts-ignore + s6 = null; + } +// @ts-ignore + s7 = peg$parseCOMMA(); +// @ts-ignore + if (s7 !== peg$FAILED) { +// @ts-ignore + s8 = peg$parse_(); +// @ts-ignore + if (s8 === peg$FAILED) { +// @ts-ignore + s8 = null; + } +// @ts-ignore + s5 = [s5, s6, s7, s8]; +// @ts-ignore + s4 = s5; +// @ts-ignore + } else { +// @ts-ignore + peg$currPos = s4; +// @ts-ignore + s4 = peg$FAILED; + } +// @ts-ignore + } else { +// @ts-ignore + peg$currPos = s4; +// @ts-ignore + s4 = peg$FAILED; + } +// @ts-ignore + while (s4 !== peg$FAILED) { +// @ts-ignore + s3.push(s4); // @ts-ignore s4 = peg$currPos; // @ts-ignore @@ -1962,89 +2037,36 @@ peg$parseFixBindingList() { // @ts-ignore s4 = peg$FAILED; } + } // @ts-ignore - while (s4 !== peg$FAILED) { + s4 = peg$parse_(); // @ts-ignore - s3.push(s4); + if (s4 === peg$FAILED) { // @ts-ignore - s4 = peg$currPos; + s4 = null; + } // @ts-ignore - s5 = peg$parseFixBinding(); + s5 = peg$parseFixBinding(); // @ts-ignore - if (s5 !== peg$FAILED) { + if (s5 === peg$FAILED) { // @ts-ignore - s6 = peg$parse_(); + s5 = null; + } // @ts-ignore - if (s6 === peg$FAILED) { + s6 = peg$parse_(); // @ts-ignore - s6 = null; - } + if (s6 === peg$FAILED) { // @ts-ignore - s7 = peg$parseCOMMA(); + s6 = null; + } // @ts-ignore - if (s7 !== peg$FAILED) { + s7 = peg$parseRBRACKET(); // @ts-ignore - s8 = peg$parse_(); + if (s7 !== peg$FAILED) { // @ts-ignore - if (s8 === peg$FAILED) { + peg$savedPos = s0; // @ts-ignore - s8 = null; - } -// @ts-ignore - s5 = [s5, s6, s7, s8]; -// @ts-ignore - s4 = s5; -// @ts-ignore - } else { -// @ts-ignore - peg$currPos = s4; -// @ts-ignore - s4 = peg$FAILED; - } -// @ts-ignore - } else { -// @ts-ignore - peg$currPos = s4; -// @ts-ignore - s4 = peg$FAILED; - } - } -// @ts-ignore - s4 = peg$parse_(); -// @ts-ignore - if (s4 === peg$FAILED) { -// @ts-ignore - s4 = null; - } -// @ts-ignore - s5 = peg$parseFixBinding(); -// @ts-ignore - if (s5 === peg$FAILED) { -// @ts-ignore - s5 = null; - } -// @ts-ignore - s6 = peg$parse_(); -// @ts-ignore - if (s6 === peg$FAILED) { -// @ts-ignore - s6 = null; - } -// @ts-ignore - s7 = peg$parseRBRACKET(); -// @ts-ignore - if (s7 !== peg$FAILED) { -// @ts-ignore - peg$savedPos = s0; -// @ts-ignore - s0 = peg$f7(s3, s5); -// @ts-ignore - } else { -// @ts-ignore - peg$currPos = s0; -// @ts-ignore - s0 = peg$FAILED; - } + s0 = peg$f7(s3, s5); // @ts-ignore } else { // @ts-ignore @@ -5112,24 +5134,29 @@ export type ContinuationExpression = | SwitchExpression | PrimitiveOperationExpression; export type SelectExpression = { - select: Integer; - val: Value; - bind: Identifier; - continuation: ContinuationExpression; + select: { + record: Integer; + val: Value; + bind: Identifier; + continuation: ContinuationExpression; + }; }; export type OffsetExpression = { - offset: Integer; - val: Value; - bind: Identifier; - continuation: ContinuationExpression; + offset: { + index: Integer; + val: Value; + bind: Identifier; + continuation: ContinuationExpression; + }; }; export type IdentifierList = any[]; export type ValueList = any[]; export type SwitchExpression = { - switchIndex: Value; - continuations: ContinuationList; + switch: { switchIndex: Value; continuations: ContinuationList }; +}; +export type ApplicationExpression = { + application: { fn: Value; args: ValueList }; }; -export type ApplicationExpression = { fn: Value; args: ValueList }; export type FixBinding = [ LPAREN, _ | null, @@ -5147,15 +5174,16 @@ export type FixBinding = [ ]; export type FixBindingList = any[]; export type FixExpression = { - fixBindings: FixBindingList; - continuation: ContinuationExpression; + fix: { fixBindings: FixBindingList; continuation: ContinuationExpression }; }; export type ContinuationList = any[]; export type PrimitiveOperationExpression = { - opr: PrimitiveOperation; - operands: ValueList; - resultBindings: IdentifierList; - continuations: ContinuationList; + primitiveOperation: { + opr: PrimitiveOperation; + operands: ValueList; + resultBindings: IdentifierList; + continuations: ContinuationList; + }; }; export type RecordExpressionTuple = { variable: VarStatement; @@ -5163,9 +5191,11 @@ export type RecordExpressionTuple = { }; export type RecordExpressionTupleList = any[]; export type RecordExpression = { - records: RecordExpressionTupleList; - address: Literal; - body: ContinuationExpression; + record: { + records: RecordExpressionTupleList; + address: Literal; + body: ContinuationExpression; + }; }; export type Value = | VarStatement diff --git a/test/logger.ts b/test/logger.ts new file mode 100644 index 0000000..2eb523b --- /dev/null +++ b/test/logger.ts @@ -0,0 +1,8 @@ +import { ConsoleTracingLogger } from '@/utils'; + +export const testingLogger = new ConsoleTracingLogger('test', [ + 'info', + 'warn', + 'error', + 'debug', +]); diff --git a/test/parser.spec.ts b/test/parser.spec.ts new file mode 100644 index 0000000..e174383 --- /dev/null +++ b/test/parser.spec.ts @@ -0,0 +1,7 @@ +import { expect, test } from 'bun:test'; +import { TestPrograms } from './programs'; +import { peggyParse } from '@/parser'; + +test('Primitive Operations', async () => { + const ast = peggyParse(await TestPrograms.AddOneThree); +}); diff --git a/test/programs/add-1-3.cps b/test/programs/add-1-3.cps new file mode 100644 index 0000000..95b9939 --- /dev/null +++ b/test/programs/add-1-3.cps @@ -0,0 +1,2 @@ +PRIMOP(+, [INT 1, INT 2], [u], + [APP(LABEL identity, [VAR u])]) \ No newline at end of file diff --git a/test/programs/index.ts b/test/programs/index.ts new file mode 100644 index 0000000..e0403fd --- /dev/null +++ b/test/programs/index.ts @@ -0,0 +1,7 @@ +import { join } from 'path'; + +export namespace TestPrograms { + export const AddOneThree = Bun.file( + join(import.meta.dir + '/add-1-3.cps'), + ).text(); +}