simple parser
This commit is contained in:
parent
d0d6aae1e5
commit
e8e9ee18f2
@ -17,7 +17,7 @@ SelectExpression
|
|||||||
_?
|
_?
|
||||||
LPAREN
|
LPAREN
|
||||||
_?
|
_?
|
||||||
select:Integer
|
record:Integer
|
||||||
_?
|
_?
|
||||||
COMMA
|
COMMA
|
||||||
_?
|
_?
|
||||||
@ -27,16 +27,18 @@ SelectExpression
|
|||||||
_?
|
_?
|
||||||
bind:Identifier
|
bind:Identifier
|
||||||
_?
|
_?
|
||||||
|
COMMA
|
||||||
|
_?
|
||||||
continuation:ContinuationExpression
|
continuation:ContinuationExpression
|
||||||
_?
|
_?
|
||||||
RPAREN { return { select, val, bind, continuation }; }
|
RPAREN { return { select: { record, val, bind, continuation } }; }
|
||||||
|
|
||||||
OffsetExpression
|
OffsetExpression
|
||||||
= OFFSET
|
= OFFSET
|
||||||
_?
|
_?
|
||||||
LPAREN
|
LPAREN
|
||||||
_?
|
_?
|
||||||
offset:Integer
|
index:Integer
|
||||||
_?
|
_?
|
||||||
COMMA
|
COMMA
|
||||||
_?
|
_?
|
||||||
@ -48,31 +50,25 @@ OffsetExpression
|
|||||||
_?
|
_?
|
||||||
continuation:ContinuationExpression
|
continuation:ContinuationExpression
|
||||||
_?
|
_?
|
||||||
RPAREN { return { offset, val, bind, continuation }; }
|
RPAREN { return { offset: { index, val, bind, continuation } }; }
|
||||||
|
|
||||||
IdentifierList
|
IdentifierList
|
||||||
= LBRACKET
|
= LBRACKET
|
||||||
_?
|
_?
|
||||||
identifiers:(ident:Identifier _? COMMA _?)*
|
identifiers:(Identifier _? COMMA _?)*
|
||||||
_?
|
_?
|
||||||
lastIdent:Identifier?
|
lastIdent:Identifier?
|
||||||
_?
|
_?
|
||||||
RBRACKET {
|
RBRACKET {
|
||||||
return identifiers.length || lastIdent
|
return identifiers.length || lastIdent
|
||||||
? [...identifiers.map(x => x.ident), lastIdent]
|
? [...identifiers.map(x => x[0]), lastIdent]
|
||||||
: [];
|
: [];
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueList
|
ValueList
|
||||||
= LBRACKET
|
= LBRACKET _? values:(Value _? COMMA _?)* _? lastValue:Value? _? RBRACKET {
|
||||||
_?
|
|
||||||
values:(value:Value _? COMMA _?)*
|
|
||||||
_?
|
|
||||||
lastValue:Value?
|
|
||||||
_?
|
|
||||||
RBRACKET {
|
|
||||||
return values.length || lastValue
|
return values.length || lastValue
|
||||||
? [...values.map(x => x.value), lastValue]
|
? [...values.map(x => x[0]), lastValue]
|
||||||
: [];
|
: [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,11 +83,11 @@ SwitchExpression
|
|||||||
_?
|
_?
|
||||||
continuations:ContinuationList
|
continuations:ContinuationList
|
||||||
_?
|
_?
|
||||||
RPAREN { return { switchIndex, continuations }; }
|
RPAREN { return { switch: { switchIndex, continuations } }; }
|
||||||
|
|
||||||
ApplicationExpression
|
ApplicationExpression
|
||||||
= APP _? LPAREN _? fn:Value _? COMMA _? args:ValueList _? RPAREN {
|
= APP _? LPAREN _? fn:Value _? COMMA _? args:ValueList _? RPAREN {
|
||||||
return { fn, args };
|
return { application: { fn, args } };
|
||||||
}
|
}
|
||||||
|
|
||||||
FixBinding
|
FixBinding
|
||||||
@ -111,14 +107,14 @@ FixBinding
|
|||||||
|
|
||||||
FixBindingList
|
FixBindingList
|
||||||
= LBRACKET
|
= LBRACKET
|
||||||
_
|
_?
|
||||||
bindings:(binding:FixBinding _? COMMA _?)*
|
bindings:(FixBinding _? COMMA _?)*
|
||||||
_?
|
_?
|
||||||
lastBinding:FixBinding?
|
lastBinding:FixBinding?
|
||||||
_?
|
_?
|
||||||
RBRACKET {
|
RBRACKET {
|
||||||
return bindings.length || lastBinding
|
return bindings.length || lastBinding
|
||||||
? [...bindings.map(x => x.binding), lastBinding]
|
? [...bindings.map(x => x[0]), lastBinding]
|
||||||
: [];
|
: [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,18 +129,18 @@ FixExpression
|
|||||||
_?
|
_?
|
||||||
continuation:ContinuationExpression
|
continuation:ContinuationExpression
|
||||||
_?
|
_?
|
||||||
RPAREN { return { fixBindings, continuation }; }
|
RPAREN { return { fix: { fixBindings, continuation } }; }
|
||||||
|
|
||||||
ContinuationList
|
ContinuationList
|
||||||
= LBRACKET
|
= LBRACKET
|
||||||
_?
|
_?
|
||||||
continuations:(continuation:ContinuationExpression _? COMMA _?)*
|
continuations:(ContinuationExpression _? COMMA _?)*
|
||||||
_?
|
_?
|
||||||
lastContinuation:ContinuationExpression?
|
lastContinuation:ContinuationExpression?
|
||||||
_?
|
_?
|
||||||
RBRACKET {
|
RBRACKET {
|
||||||
return lastContinuation || continuations.length
|
return lastContinuation || continuations.length
|
||||||
? [...continuations.map(x => x.continuation), lastContinuation]
|
? [...continuations.map(x => x[0]), lastContinuation]
|
||||||
: [];
|
: [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +163,11 @@ PrimitiveOperationExpression
|
|||||||
_?
|
_?
|
||||||
continuations:ContinuationList
|
continuations:ContinuationList
|
||||||
_?
|
_?
|
||||||
RPAREN { return { opr, operands, resultBindings, continuations }; }
|
RPAREN {
|
||||||
|
return {
|
||||||
|
primitiveOperation: { opr, operands, resultBindings, continuations },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
RecordExpressionTuple
|
RecordExpressionTuple
|
||||||
= LPAREN
|
= LPAREN
|
||||||
@ -183,13 +183,13 @@ RecordExpressionTuple
|
|||||||
RecordExpressionTupleList
|
RecordExpressionTupleList
|
||||||
= LBRACKET
|
= LBRACKET
|
||||||
_?
|
_?
|
||||||
records:(record:RecordExpressionTuple _? COMMA _?)*
|
records:(RecordExpressionTuple _? COMMA _?)*
|
||||||
_?
|
_?
|
||||||
lastRecord:RecordExpressionTuple?
|
lastRecord:RecordExpressionTuple?
|
||||||
_?
|
_?
|
||||||
RBRACKET {
|
RBRACKET {
|
||||||
return records.length || lastRecord
|
return records.length || lastRecord
|
||||||
? [...records.map(x => x.record), lastRecord]
|
? [...records.map(x => x[0]), lastRecord]
|
||||||
: [];
|
: [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,9 +210,11 @@ RecordExpression
|
|||||||
_?
|
_?
|
||||||
RPAREN {
|
RPAREN {
|
||||||
return {
|
return {
|
||||||
|
record: {
|
||||||
records,
|
records,
|
||||||
address,
|
address,
|
||||||
body,
|
body,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,17 +408,17 @@ function peg$parse(input, options) {
|
|||||||
return exprs.filter(x => !Array.isArray(x));
|
return exprs.filter(x => !Array.isArray(x));
|
||||||
};// @ts-ignore
|
};// @ts-ignore
|
||||||
|
|
||||||
var peg$f1 = function(select, val, bind, continuation) {// @ts-ignore
|
var peg$f1 = function(record, val, bind, continuation) {// @ts-ignore
|
||||||
return { select, val, bind, continuation }; };// @ts-ignore
|
return { select: { record, val, bind, continuation } }; };// @ts-ignore
|
||||||
|
|
||||||
var peg$f2 = function(offset, val, bind, continuation) {// @ts-ignore
|
var peg$f2 = function(index, val, bind, continuation) {// @ts-ignore
|
||||||
return { offset, val, bind, continuation }; };// @ts-ignore
|
return { offset: { index, val, bind, continuation } }; };// @ts-ignore
|
||||||
|
|
||||||
var peg$f3 = function(identifiers, lastIdent) {
|
var peg$f3 = function(identifiers, lastIdent) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return identifiers.length || lastIdent
|
return identifiers.length || lastIdent
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
? [...identifiers.map(x => x.ident), lastIdent]
|
? [...identifiers.map(x => x[0]), lastIdent]
|
||||||
: [];
|
: [];
|
||||||
};// @ts-ignore
|
};// @ts-ignore
|
||||||
|
|
||||||
@ -426,39 +426,44 @@ function peg$parse(input, options) {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return values.length || lastValue
|
return values.length || lastValue
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
? [...values.map(x => x.value), lastValue]
|
? [...values.map(x => x[0]), lastValue]
|
||||||
: [];
|
: [];
|
||||||
};// @ts-ignore
|
};// @ts-ignore
|
||||||
|
|
||||||
var peg$f5 = function(switchIndex, continuations) {// @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) {
|
var peg$f6 = function(fn, args) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return { fn, args };
|
return { application: { fn, args } };
|
||||||
};// @ts-ignore
|
};// @ts-ignore
|
||||||
|
|
||||||
var peg$f7 = function(bindings, lastBinding) {
|
var peg$f7 = function(bindings, lastBinding) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return bindings.length || lastBinding
|
return bindings.length || lastBinding
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
? [...bindings.map(x => x.binding), lastBinding]
|
? [...bindings.map(x => x[0]), lastBinding]
|
||||||
: [];
|
: [];
|
||||||
};// @ts-ignore
|
};// @ts-ignore
|
||||||
|
|
||||||
var peg$f8 = function(fixBindings, continuation) {// @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) {
|
var peg$f9 = function(continuations, lastContinuation) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return lastContinuation || continuations.length
|
return lastContinuation || continuations.length
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
? [...continuations.map(x => x.continuation), lastContinuation]
|
? [...continuations.map(x => x[0]), lastContinuation]
|
||||||
: [];
|
: [];
|
||||||
};// @ts-ignore
|
};// @ts-ignore
|
||||||
|
|
||||||
var peg$f10 = function(opr, operands, resultBindings, continuations) {// @ts-ignore
|
var peg$f10 = function(opr, operands, resultBindings, continuations) {
|
||||||
return { opr, operands, resultBindings, continuations }; };// @ts-ignore
|
// @ts-ignore
|
||||||
|
return {
|
||||||
|
// @ts-ignore
|
||||||
|
primitiveOperation: { opr, operands, resultBindings, continuations },
|
||||||
|
};
|
||||||
|
};// @ts-ignore
|
||||||
|
|
||||||
var peg$f11 = function(variable, offset) {// @ts-ignore
|
var peg$f11 = function(variable, offset) {// @ts-ignore
|
||||||
return { variable, offset }; };// @ts-ignore
|
return { variable, offset }; };// @ts-ignore
|
||||||
@ -467,19 +472,22 @@ function peg$parse(input, options) {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return records.length || lastRecord
|
return records.length || lastRecord
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
? [...records.map(x => x.record), lastRecord]
|
? [...records.map(x => x[0]), lastRecord]
|
||||||
: [];
|
: [];
|
||||||
};// @ts-ignore
|
};// @ts-ignore
|
||||||
|
|
||||||
var peg$f13 = function(records, address, body) {
|
var peg$f13 = function(records, address, body) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return {
|
return {
|
||||||
|
// @ts-ignore
|
||||||
|
record: {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
records,
|
records,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
address,
|
address,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
body,
|
body,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};// @ts-ignore
|
};// @ts-ignore
|
||||||
|
|
||||||
@ -874,7 +882,7 @@ peg$parseContinuationExpression() {
|
|||||||
function // @ts-ignore
|
function // @ts-ignore
|
||||||
peg$parseSelectExpression() {
|
peg$parseSelectExpression() {
|
||||||
// @ts-ignore
|
// @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
|
// @ts-ignore
|
||||||
s0 = peg$currPos;
|
s0 = peg$currPos;
|
||||||
@ -956,7 +964,7 @@ peg$parseSelectExpression() {
|
|||||||
s14 = null;
|
s14 = null;
|
||||||
}
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
s15 = peg$parseContinuationExpression();
|
s15 = peg$parseCOMMA();
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (s15 !== peg$FAILED) {
|
if (s15 !== peg$FAILED) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@ -967,13 +975,31 @@ peg$parseSelectExpression() {
|
|||||||
s16 = null;
|
s16 = null;
|
||||||
}
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
s17 = peg$parseRPAREN();
|
s17 = peg$parseContinuationExpression();
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (s17 !== peg$FAILED) {
|
if (s17 !== peg$FAILED) {
|
||||||
|
// @ts-ignore
|
||||||
|
s18 = peg$parse_();
|
||||||
|
// @ts-ignore
|
||||||
|
if (s18 === peg$FAILED) {
|
||||||
|
// @ts-ignore
|
||||||
|
s18 = null;
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
s19 = peg$parseRPAREN();
|
||||||
|
// @ts-ignore
|
||||||
|
if (s19 !== peg$FAILED) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
peg$savedPos = s0;
|
peg$savedPos = s0;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
s0 = peg$f1(s5, s9, s13, s15);
|
s0 = peg$f1(s5, s9, s13, s17);
|
||||||
|
// @ts-ignore
|
||||||
|
} else {
|
||||||
|
// @ts-ignore
|
||||||
|
peg$currPos = s0;
|
||||||
|
// @ts-ignore
|
||||||
|
s0 = peg$FAILED;
|
||||||
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@ -1917,7 +1943,10 @@ peg$parseFixBindingList() {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
s2 = peg$parse_();
|
s2 = peg$parse_();
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (s2 !== peg$FAILED) {
|
if (s2 === peg$FAILED) {
|
||||||
|
// @ts-ignore
|
||||||
|
s2 = null;
|
||||||
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
s3 = [];
|
s3 = [];
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@ -2052,13 +2081,6 @@ peg$parseFixBindingList() {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
s0 = peg$FAILED;
|
s0 = peg$FAILED;
|
||||||
}
|
}
|
||||||
// @ts-ignore
|
|
||||||
} else {
|
|
||||||
// @ts-ignore
|
|
||||||
peg$currPos = s0;
|
|
||||||
// @ts-ignore
|
|
||||||
s0 = peg$FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return s0;
|
return s0;
|
||||||
@ -5112,24 +5134,29 @@ export type ContinuationExpression =
|
|||||||
| SwitchExpression
|
| SwitchExpression
|
||||||
| PrimitiveOperationExpression;
|
| PrimitiveOperationExpression;
|
||||||
export type SelectExpression = {
|
export type SelectExpression = {
|
||||||
select: Integer;
|
select: {
|
||||||
|
record: Integer;
|
||||||
val: Value;
|
val: Value;
|
||||||
bind: Identifier;
|
bind: Identifier;
|
||||||
continuation: ContinuationExpression;
|
continuation: ContinuationExpression;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
export type OffsetExpression = {
|
export type OffsetExpression = {
|
||||||
offset: Integer;
|
offset: {
|
||||||
|
index: Integer;
|
||||||
val: Value;
|
val: Value;
|
||||||
bind: Identifier;
|
bind: Identifier;
|
||||||
continuation: ContinuationExpression;
|
continuation: ContinuationExpression;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
export type IdentifierList = any[];
|
export type IdentifierList = any[];
|
||||||
export type ValueList = any[];
|
export type ValueList = any[];
|
||||||
export type SwitchExpression = {
|
export type SwitchExpression = {
|
||||||
switchIndex: Value;
|
switch: { switchIndex: Value; continuations: ContinuationList };
|
||||||
continuations: ContinuationList;
|
};
|
||||||
|
export type ApplicationExpression = {
|
||||||
|
application: { fn: Value; args: ValueList };
|
||||||
};
|
};
|
||||||
export type ApplicationExpression = { fn: Value; args: ValueList };
|
|
||||||
export type FixBinding = [
|
export type FixBinding = [
|
||||||
LPAREN,
|
LPAREN,
|
||||||
_ | null,
|
_ | null,
|
||||||
@ -5147,15 +5174,16 @@ export type FixBinding = [
|
|||||||
];
|
];
|
||||||
export type FixBindingList = any[];
|
export type FixBindingList = any[];
|
||||||
export type FixExpression = {
|
export type FixExpression = {
|
||||||
fixBindings: FixBindingList;
|
fix: { fixBindings: FixBindingList; continuation: ContinuationExpression };
|
||||||
continuation: ContinuationExpression;
|
|
||||||
};
|
};
|
||||||
export type ContinuationList = any[];
|
export type ContinuationList = any[];
|
||||||
export type PrimitiveOperationExpression = {
|
export type PrimitiveOperationExpression = {
|
||||||
|
primitiveOperation: {
|
||||||
opr: PrimitiveOperation;
|
opr: PrimitiveOperation;
|
||||||
operands: ValueList;
|
operands: ValueList;
|
||||||
resultBindings: IdentifierList;
|
resultBindings: IdentifierList;
|
||||||
continuations: ContinuationList;
|
continuations: ContinuationList;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
export type RecordExpressionTuple = {
|
export type RecordExpressionTuple = {
|
||||||
variable: VarStatement;
|
variable: VarStatement;
|
||||||
@ -5163,9 +5191,11 @@ export type RecordExpressionTuple = {
|
|||||||
};
|
};
|
||||||
export type RecordExpressionTupleList = any[];
|
export type RecordExpressionTupleList = any[];
|
||||||
export type RecordExpression = {
|
export type RecordExpression = {
|
||||||
|
record: {
|
||||||
records: RecordExpressionTupleList;
|
records: RecordExpressionTupleList;
|
||||||
address: Literal;
|
address: Literal;
|
||||||
body: ContinuationExpression;
|
body: ContinuationExpression;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
export type Value =
|
export type Value =
|
||||||
| VarStatement
|
| 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