simple parser
This commit is contained in:
parent
d0d6aae1e5
commit
e8e9ee18f2
@ -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,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
8
test/logger.ts
Normal file
8
test/logger.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { ConsoleTracingLogger } from '@/utils';
|
||||
|
||||
export const testingLogger = new ConsoleTracingLogger('test', [
|
||||
'info',
|
||||
'warn',
|
||||
'error',
|
||||
'debug',
|
||||
]);
|
7
test/parser.spec.ts
Normal file
7
test/parser.spec.ts
Normal file
@ -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);
|
||||
});
|
2
test/programs/add-1-3.cps
Normal file
2
test/programs/add-1-3.cps
Normal file
@ -0,0 +1,2 @@
|
||||
PRIMOP(+, [INT 1, INT 2], [u],
|
||||
[APP(LABEL identity, [VAR u])])
|
7
test/programs/index.ts
Normal file
7
test/programs/index.ts
Normal file
@ -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();
|
||||
}
|
Loading…
Reference in New Issue
Block a user