Minimal (?) protype-based language.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 

1688 řádky
51 KiB

global then = cputime();
// ----- Utils -----
true = (1 == 1);
false = (1 == 0);
Object.contains(item) {
for (i in self.length()) {
if (self[i] == item) {
return 1;
}
}
return nil;
}
with(namespace) {
//print("--- With ", namespace, " ---\n\n");
if (__namespaces__.length() == 0) {
__namespaces__.push([]);
}
if (!__namespaces__.keys().contains(namespace)) {
newNamespace = [__nsname__: namespace];
__namespaces__[namespace] = newNamespace;
__namespaces__[0][namespace] = newNamespace;
} else {
__namespaces__[0][namespace] = __namespaces__[namespace];
}
__namespaces__.push(__namespaces__[namespace]);
return __namespaces__[namespace];
}
//without(); // latest
//without(#peg); // remove a plate from the middle the pile without smashing everything
//without(all: 1); // ALL
without(namespace, all: nil) {
// Remove all
if (all != nil) {
for (i in (__namespaces__.length() - 1)) {
removedNamespace = __namespaces__.pop().__nsname__;
//print("--- Without ", removedNamespace, " ---\n\n");
__namespaces__[0][removedNamespace] = nil;
}
__namespaces__.pop();
return;
}
// Remove last
if (namespace == nil) {
removedNamespace = __namespaces__.pop().__nsname__;
//print("--- Without ", removedNamespace, " ---\n\n");
__namespaces__[0][removedNamespace] = nil;
if (__namespaces__.length() == 1) {
__namespaces__.pop();
}
return;
}
// Remove a given namespace
// Find its index
namespaceIndex = nil;
for (i from (__namespaces__.length() - 1) to 1) {
if (__namespaces__[i].__nsname__ == namespace) {
namespaceIndex = i;
break;
}
}
// If it's on top of the stack, just pop
if (namespaceIndex == __namespaces__.length() - 1) {
__namespaces__.pop();
//print("--- Without ", namespace, " ---\n\n");
__namespaces__[0][namespace] = nil;
if (__namespaces__.length() == 1) {
__namespaces__.pop();
}
return;
}
// If it's not on top, offset all the namespaces on top of it by one, and then pop
for (i from namespaceIndex to (__namespaces__.length() - 2)) {
__namespaces__[i] = __namespaces__[i + 1];
}
__namespaces__.pop();
//print("--- Without ", namespace, " ---\n\n");
__namespaces__[0][namespace] = nil;
if (__namespaces__.length() == 1) {
__namespaces__.pop();
}
}
get(__identifier) {
eval(GetVar.new(name: __identifier));
}
setInTopNamespace(__identifier, __value) {
__namespaces__.last()[__identifier] = __value;
}
println(x) {
if (!x) {
if (len(__env__().__delegate__) == 0){
print("\n");
} else {
print(nil, "\n");
}
} else {
print(x, "\n", full: 1);
}
}
Object.subtype(name) { self.new(__name__: name) }
Object.last() { self[self.length() - 1] }
// Input stream
Stream.peek() { self.content[self.position] }
// Context
Context = Object.subtype(#Context);
Context.init() { self.variables = []; self; }
Context.declareVariable(var) {
local found = 0;
for (key in self.variables.keys()) {
if (key == var) {
found = 1;
}
}
if (found == 0) {
self.variables[var] = nil;
}
}
// ----- Grammar Constructs -----
// Parser VM op-codes
// opcodes opcode argument arglength next-pc notes
OpCodes = [
PUSH: 0, // PUSH nil 0 ok ok both pcs should be set the same
DROP: 1, // DROP nil 0 ok ok
POP: 2, // POP nil 0 ok ok
DOT: 3, // DOT nil 0 ok ko ok/ko next pc are absolute and are
CLASS: 4, // CLASS bitarray len(bitarray) ok ko instruction indexes (0, 1, 2, ...)
STRING: 5, // STRING string len(string) ok ko and not array indexes (0, 5, 10, ...)
TEST: 6,
RULE2: 7,
RULE: 8, // RULE symbol 0 ok ko
CALL: 9, // CALL nil 0 ok ko do not use this; VM internal use only
SUCCEED: 10, // SUCCEED nil 0 0 0 next pcs are ignored
FAIL: 11, // FAIL nil 0 0 0
ACTION: 12, // ACTION function 0 ok ok both pcs should be the same
BEGIN: 13, // BEGIN nil 0 ok ok
END: 14, // END nil 0 ok ok
UNEND: 15, // UNEND nil 0 ok ok
SET: 16 // SET symbol 0 ok ok
];
OpCodeNames = [
"PUSH",
"DROP",
"POP",
"DOT",
"CLASS",
"STRING",
"TEST",
"RULE2",
"RULE",
"CALL",
"SUCCEED",
"FAIL",
"ACTION",
"BEGIN",
"END",
"UNEND",
"SET"
];
Instruction = Object.subtype(#Instruction);
Instruction.new(op, arg, arglen, ok, ko) {
self = super.new();
self.op = op;
self.arg = arg;
self.arglen = arglen;
self.ok = ok;
self.ko = ko;
self;
}
Instruction.printline() {
print(OpCodeNames[self.op], " ", self.arg, " ", self.arglen, " ", self.ok, " ", self.ko, "\n");
}
// String Literal
StringLiteral = Object.subtype(#StringLiteral);
StringLiteral.getMatchingExpression() {
return `{
((stream.content.compareFrom(stream.position, @self.string) == 0) &&
(stream.position += len(@self.string)) &&
@true)
||
@false
};
}
StringLiteral.emitByteCode(instructions, ok, ko) {
//emit(STRING, (byte *)node->String.string, strlen(node->String.string), ok, ko);
instructions.push(Instruction.new(OpCodes.STRING, self.string, len(self.string), ok, ko));
instructions.length() - 1;
}
// Character Class
CharacterClass = Object.subtype(#CharacterClass);
CharacterClass.getMatchingExpression() {
return `{ !stream.atEnd() && (@self.value.charClass()).bitTest(stream.peek()) && stream.inc() && @true };
}
CharacterClass.emitByteCode(instructions, ok, ko) {
//emit(CLASS, node->Class.bits, 32, ok, ko);
instructions.push(Instruction.new(OpCodes.CLASS, self.value.charClass(), 32, ok, ko));
instructions.length() - 1;
}
// Dot
Dot = Object.subtype(#Dot);
Dot.getMatchingExpression() {
return `{ !stream.atEnd() && stream.inc() && @true };
}
Dot.emitByteCode(instructions, ok, ko) {
//emit(DOT, 0, 0, ok, ko);
instructions.push(Instruction.new(OpCodes.DOT, 0, 0, ok, ko));
instructions.length() - 1;
}
// Capture
Capture = Object.subtype(#Capture);
Capture.getMatchingExpression() {
return `{ stream.setLastBegin()
&& (@self.expression.getMatchingExpression())
&& (context.variables.yytext = stream.content[stream.lastBegin:stream.position].unescaped())
&& @true
};
}
Capture.emitByteCode(instructions, ok, ko) {
//ok = emit(END, 0, 0, ok, ok);
//ko = emit(UNEND, 0, 0, ko, ko);
//ok = generateNode(node->Capture.exp, ok, ko);
//emit(BEGIN, 0, 0, ok, ok);
// FAIS CE QUE LE CODE DIT BORDEL
instructions.push(Instruction.new(OpCodes.END, 0, 0, ok, ok));
ok = instructions.length() - 1;
instructions.push(Instruction.new(OpCodes.UNEND, 0, 0, ko, ko));
ko = instructions.length() - 1;
ok = self.expression.emitByteCode(instructions, ok, ko);
instructions.push(Instruction.new(OpCodes.BEGIN, 0, 0, ok, ok));
instructions.length() - 1;
}
// Optional (? postfix operator)
Optional = Object.subtype(#Optional);
Optional.getMatchingExpression() {
return `{ (@self.expression.getMatchingExpression()); @true };
}
Optional.emitByteCode(instructions, ok, ko) {
self.expression.emitByteCode(instructions, ok, ok);
instructions.length() - 1;
}
// Star
Star = Object.subtype(#Star);
Star.getMatchingExpression() {
return `{ while (@self.expression.getMatchingExpression()) @true; @true };
}
Star.emitByteCode(instructions, ok, ko) {
local last = instructions.length();
self.expression.emitByteCode(instructions, ok, ok);
instructions[last].ok = instructions.length() - 1;
instructions.length() - 1;
}
// Plus
Plus = Object.subtype(#Plus);
Plus.getMatchingExpression() {
return `{
if (@self.expression.getMatchingExpression()) {
while (@self.expression.getMatchingExpression()) {}
@true;
} else {
@false;
}
};
}
Plus.emitByteCode(instructions, ok, ko) {
local last = instructions.length();
local next = self.expression.emitByteCode(instructions, ok, ok);
instructions[last].ok = instructions.length() - 1;
self.expression.emitByteCode(instructions, next, ko);
instructions.length() - 1;
}
// And
And = Object.subtype(#And);
And.getMatchingExpression() {
return `{
local position = stream.position;
if (@self.expression.getMatchingExpression()) {
stream.position = position;
@true;
} else {
@false;
}
};
}
And.emitByteCode(instructions, ok, ko) {
instructions.push(Instruction.new(OpCodes.POP, 0, 0, ok, ok));
ok = instructions.length() - 1;
instructions.push(Instruction.new(OpCodes.DROP, 0, 0, ko, ko));
ko = instructions.length() - 1;
local here = self.expression.emitByteCode(instructions, ok, ko);
instructions.push(Instruction.new(OpCodes.PUSH, 0, 0, here, here));
instructions.length() - 1;
}
// Not
Not = Object.subtype(#Not);
Not.getMatchingExpression() {
return `{
local position = stream.position;
if (@self.expression.getMatchingExpression()) {
stream.position = position;
@false;
} else {
@true;
}
};
}
Not.emitByteCode(instructions, ok, ko) {
instructions.push(Instruction.new(OpCodes.POP, 0, 0, ko, ko));
local nok = instructions.length() - 1;
instructions.push(Instruction.new(OpCodes.DROP, 0, 0, ok, ok));
local nko = instructions.length() - 1;
local here = self.expression.emitByteCode(instructions, nok, nko);
instructions.push(Instruction.new(OpCodes.PUSH, 0, 0, here, here));
instructions.length() - 1;
}
// Sequence
Sequence = Object.subtype(#Sequence);
Sequence._getMatchingExpression(index) {
if (index == self.length() - 1) {
return self[index].getMatchingExpression();
}
return `(@self[index].getMatchingExpression())
&& @self._getMatchingExpression(index + 1);
}
Sequence.getMatchingExpression() {
return `{
local initialActionCount = actions.length();
local startingPosition = stream.position;
({
(@self._getMatchingExpression(0));
} || {
while (actions.length() > initialActionCount)
actions.pop();
stream.position = startingPosition;
@false;
});
}
}
Sequence.emitByteCode(instructions, ok, ko) {
instructions.push(Instruction.new(OpCodes.DROP, 0, 0, ok, ok));
ok = instructions.length() - 1;
instructions.push(Instruction.new(OpCodes.POP, 0, 0, ko, ko));
ko = instructions.length() - 1;
for (i from self.length() - 1 to 0) {
ok = self[i].emitByteCode(instructions, ok, ko);
}
instructions.push(Instruction.new(OpCodes.PUSH, 0, 0, ok, ok));
instructions.length() - 1;
}
// Alternation
Alternation = Object.subtype(#Alternation);
Alternation._getMatchingExpression(index) {
if (index == self.length() - 1) {
return self[index].getMatchingExpression();
}
return `(@self[index].getMatchingExpression())
|| @self._getMatchingExpression(index + 1);
}
Alternation.getMatchingExpression() {
return `{ @self._getMatchingExpression(0) };
}
Alternation.prepend(pegString) {
local stream = newStream(pegString);
local context = Context.new(outerContext: nil).init();
local actions = [];
peg.expression(stream, context, actions);
local expression = { for (actionAndContext in actions) {
actionAndContext.action.execute(actionAndContext.context);
} };
self.push(self[len(self) - 1]);
for (i from len(self) - 2 to 0) {
self[i + 1] = self[i];
}
self[0] = expression;
}
parseDefinition(pegString) {
local stream = newStream(pegString);
local context = Context.new(outerContext: nil).init();
local actions = [];
peg.definition(stream, context, actions);
local definition = { for (actionAndContext in actions) {
actionAndContext.action.execute(actionAndContext.context);
} };
definition;
}
Alternation.emitByteCode(instructions, ok, ko) {
instructions.push(Instruction.new(OpCodes.DROP, 0, 0, ok, ok));
ok = instructions.length() - 1;
instructions.push(Instruction.new(OpCodes.POP, 0, 0, ko, ko));
ko = instructions.length() - 1;
for (i from self.length() - 1 to 0) {
ko = self[i].emitByteCode(instructions, ok, ko);
}
instructions.push(Instruction.new(OpCodes.PUSH, 0, 0, ko, ko));
instructions.length() - 1;
}
// Action
Action = Object.subtype(#Action);
Action.getMatchingExpression() {
return `{ actions.push([action: @self, context: context]); @true; }
}
Action.execute(context) {
// Declare all variables that a value is set to in the context
for (statement in self.parseTree.body) {
if (statement.__name__ == "SetVar") {
context.declareVariable(statement.name);
}
}
// Evaluate the parse tree and return to outer context if needed
local returnValue = eval(self.parseTree, env: context.variables);
if (context.outerContext != nil) {
context.outerContext.variables[context.returnValueName] = returnValue;
}
returnValue;
}
Action.emitByteCode(instructions, ok, ko) {
instructions.push(Instruction.new(
OpCodes.ACTION,
Closure.new(
environment: nil,
function: Lambda.new(
parameters: [],
body: self.parseTree.body
)
),
0,
ok,
ok
));
instructions.length() - 1;
}
// Parse-time Action (&)
ParseTimeAction = Object.subtype(#ParseTimeAction);
ParseTimeAction.getMatchingExpression() {
return `{ (@self.action).execute(context) };
}
ParseTimeAction.emitByteCode(instructions, ok, ko) {
instructions.push(Instruction.new(
OpCodes.TEST,
Closure.new(
environment: nil,
function: Lambda.new(
parameters: [],
body: self.action.parseTree.body
)
),
0,
ok,
ko
));
instructions.length() - 1;
}
// Execute Action (@)
ExecuteAction = Object.subtype(#ExecuteAction);
ExecuteAction.getMatchingExpression() {
return `{ (@self.action).execute(context); @true; };
}
ExecuteAction.emitByteCode(instructions, ok, ko) {
instructions.push(Instruction.new(
OpCodes.TEST,
Closure.new(
environment: nil,
function: Lambda.new(
parameters: [],
body: self.action.parseTree.body
)
),
0,
ok,
ok
));
instructions.length() - 1;
}
// Assignment
Assignment = Object.subtype(#Assignment);
Assignment.getMatchingExpression() {
return `{
context.declareVariable(@self.name);
local context = Context.new(outerContext: context, returnValueName: @self.name).init();
@self.rule.getMatchingExpression();
}
}
Assignment.emitByteCode(instructions, ok, ko) {
instructions.push(Instruction.new(OpCodes.SET, self.name, 0, ok, ok));
ok = instructions.length() - 1;
self.rule.emitByteCode(instructions, ok, ko);
instructions.length() - 1;
}
// RuleCall
RuleCall = Object.subtype(#RuleCall);
RuleCall.getMatchingExpression() {
`{ /*increaseCount(@self.name);*/ Invoke.new(self: self, method: @self.name, arguments: [stream, context, actions]).__eval__() };
}
RuleCall.emitByteCode(instructions, ok, ko) {
instructions.push(Instruction.new(OpCodes.RULE, self.name, 0, ok, ko));
instructions.length() - 1;
}
// NamespacedRuleCall
NamespacedRuleCall = Object.subtype(#NamespacedRuleCall);
NamespacedRuleCall.getMatchingExpression(innerContext) {
`{ Invoke.new(self: @get(self.namespace), method: @self.name, arguments: [stream, context, actions]).__eval__() };
}
NamespacedRuleCall.emitByteCode(instructions, ok, ko) {
instructions.push(Instruction.new(OpCodes.RULE, self.name, self.namespace, ok, ko));
instructions.length() - 1;
}
Definition = Object.subtype(#Definition);
Grammar = Object.subtype(#Grammar);
Grammar.addRulesFromNamespace(namespace) {
for (key in __namespaces__[namespace].keys()) {
if (key == #__nsname__) continue;
self.addRule(key, __namespaces__[namespace][key]);
}
}
Grammar.addRule(ruleName, rule) {
self[ruleName] = Closure.new(
environment: nil,
function: Lambda.new(
parameters: [#stream, #context, #actions],
body: rule.getMatchingExpression().body,
name: ruleName,
parent: self
)
);
}
//global functionCounts = [];
//
//increaseCount(function) {
// if (!functionCounts.keys().contains(function)){
// functionCounts[function] = 1;
// } else {
// functionCounts[function]++;
// }
//}
// ----- Grammar of Meta Language (Minimal) -----
with(#HardCodedMeta);
metaStatement =
Alternation.new()
.push(Sequence.new()
.push(Assignment.new(name: #b, rule: RuleCall.new(name: #block)))
.push(Action.new(parseTree: `{ b; }))
)
.push(Sequence.new()
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression)))
.push(Alternation.new()
.push(RuleCall.new(name: #semi))
.push(And.new(expression: RuleCall.new(name: #rbrace)))
)
.push(Action.new(parseTree: `{ e; }))
);
metaExpression =
Alternation.new(id: 1234)
.push(Sequence.new()
.push(Assignment.new(name: #p, rule: RuleCall.new(name: #metaPrimary)))
.push(Alternation.new()
.push(Sequence.new()
.push(RuleCall.new(name: #dot))
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #metaId)))
.push(RuleCall.new(name: #assign))
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression)))
)
.push(Sequence.new()
.push(RuleCall.new(name: #lbrak))
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #metaExpression)))
.push(RuleCall.new(name: #rbrak))
.push(RuleCall.new(name: #assign))
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression)))
.push(Action.new(parseTree: `{ SetArray.new(object: p, index: i, value: e); }))
)
)
)
.push(Sequence.new()
.push(StringLiteral.new(string: "global"))
.push(RuleCall.new(name: #ws))
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #metaId)))
.push(RuleCall.new(name: #assign))
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression)))
.push(Action.new(parseTree: `{ SetGlobal.new(name: i, value: e); }))
)
.push(Sequence.new()
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #metaId)))
.push(RuleCall.new(name: #assign))
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression)))
.push(Action.new(parseTree: `{ SetVar.new(name: i, value: e); }))
)
.push(Sequence.new()
.push(Assignment.new(name: #pf, rule: RuleCall.new(name: #metaPrefix)))
.push(Action.new(parseTree: `{ pf; }))
);
metaPrefix =
Alternation.new()
.push(Sequence.new()
.push(RuleCall.new(name: #pplus))
.push(Assignment.new(name: #p, rule: RuleCall.new(name: #metaPrefix)))
.push(Action.new(parseTree: `{ $$ = newBinop(opPreAdd, lvalue(p), newInteger(1)) }))
)
.push(RuleCall.new(name: #metaPostfix));
metaPostfix =
Sequence.new()
.push(Assignment.new(name: #p, rule: RuleCall.new(name: #metaPrimary)))
.push(Star.new(expression: Alternation.new()
.push(Sequence.new()
.push(RuleCall.new(name: #lbrak))
.push(Assignment.new(name: #s, rule: RuleCall.new(name: #metaExpression)))
.push(RuleCall.new(name: #rbrak))
.push(Not.new(expression: RuleCall.new(name: #assign)))
.push(Action.new(parseTree: `{ p = newGetArray(p, s) }))
)
.push(Sequence.new()
.push(RuleCall.new(name: #dot))
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #metaId)))
.push(Assignment.new(name: #a, rule: RuleCall.new(name: #args)))
.push(Not.new(expression: RuleCall.new(name: #assign)))
.push(Not.new(expression: RuleCall.new(name: #lbrace)))
.push(Action.new(parseTree: `{ p = Invoke.new(self: p, method: i, arguments: a); }))
)
.push(Sequence.new()
.push(RuleCall.new(name: #dot))
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #metaId)))
.push(Not.new(expression: RuleCall.new(name: #assign)))
.push(Action.new(parseTree: `{ p = GetProp.new(object: p, key: i); }))
)
.push(Sequence.new()
.push(Assignment.new(name: #a, rule: RuleCall.new(name: #args)))
.push(Not.new(expression: RuleCall.new(name: #assign)))
.push(Not.new(expression: RuleCall.new(name: #lbrace)))
.push(Action.new(parseTree: `{ p = Call.new(function: p, arguments: a); }))
// TODO: Voir si c'est toujours bon avec le newApply()
)
))
.push(Action.new(parseTree: `{ p; }));
args =
Sequence.new()
.push(RuleCall.new(name: #lparen))
.push(Assignment.new(name: #a, rule: RuleCall.new(name: #mklist)))
.push(Optional.new(expression: Sequence.new()
.push(Alternation.new()
.push(Sequence.new()
.push(Assignment.new(name: #k, rule: RuleCall.new(name: #metaId)))
.push(RuleCall.new(name: #colon))
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression)))
.push(Action.new(parseTree: `{ a[k] = e; }))
)
.push(Sequence.new()
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression)))
.push(Action.new(parseTree: `{ a.push(e); }))
)
)
.push(Star.new(expression: Sequence.new()
.push(RuleCall.new(name: #comma))
.push(Alternation.new()
.push(Sequence.new()
.push(Assignment.new(name: #k, rule: RuleCall.new(name: #metaId)))
.push(RuleCall.new(name: #colon))
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression)))
.push(Action.new(parseTree: `{ a[k] = e; }))
)
.push(Sequence.new()
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression)))
.push(Action.new(parseTree: `{ a.push(e); }))
)
)
))
))
.push(RuleCall.new(name: #rparen))
.push(Action.new(parseTree: `{ a; }));
mklist = Action.new(parseTree: `{ Object.new(); });
metaPrimary =
Alternation.new()
.push(RuleCall.new(name: #nil))
.push(RuleCall.new(name: #number))
.push(RuleCall.new(name: #string))
.push(RuleCall.new(name: #metaVar))
.push(RuleCall.new(name: #metaSubExpr));
metaSubExpr =
Sequence.new()
.push(RuleCall.new(name: #lparen))
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaExpression)))
.push(RuleCall.new(name: #rparen))
.push(Action.new(parseTree: `{ e; }));
block =
Sequence.new()
.push(RuleCall.new(name: #lbrace))
.push(Assignment.new(name: #b, rule: RuleCall.new(name: #mklist)))
.push(
Star.new(
expression: Sequence.new()
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #metaStatement)))
.push(Action.new(parseTree: `{ b.push(e); }))
)
)
.push(RuleCall.new(name: #rbrace))
.push(Action.new(parseTree: `{ b; }));
string =
Sequence.new()
.push(StringLiteral.new(string: "\""))
.push(Capture.new(expression: Star.new(expression: Sequence.new()
.push(Not.new(expression: StringLiteral.new(string: "\"")))
.push(RuleCall.new(name: #char))
)))
.push(StringLiteral.new(string: "\""))
.push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ $$ = newStringUnescaped(yytext) }));
char =
Alternation.new()
.push(Sequence.new()
.push(StringLiteral.new(string: "\\"))
.push(CharacterClass.new(value: "abefnrtv\'\"[]\\"))
)
.push(Sequence.new()
.push(StringLiteral.new(string: "\\"))
.push(CharacterClass.new(value: "0-3"))
.push(CharacterClass.new(value: "0-7"))
.push(CharacterClass.new(value: "0-7"))
)
.push(Sequence.new()
.push(StringLiteral.new(string: "\\"))
.push(CharacterClass.new(value: "0-7"))
.push(Optional.new(expression: CharacterClass.new(value: "0-7")))
)
.push(Sequence.new()
.push(StringLiteral.new(string: "\\"))
.push(CharacterClass.new(value: "xX"))
.push(Star.new(expression: RuleCall.new(name: #higit)))
)
.push(Sequence.new()
.push(Not.new(expression: StringLiteral.new(string: "\\")))
.push(Dot.new())
);
number =
Alternation.new()
.push(Sequence.new()
.push(StringLiteral.new(string: "-"))
.push(Assignment.new(name: #n, rule: RuleCall.new(name: #unsign)))
.push(Action.new(parseTree: `{ Unyop.new(operation: opNeg).push(n) }))
)
.push(Sequence.new()
.push(StringLiteral.new(string: "+"))
.push(Assignment.new(name: #n, rule: RuleCall.new(name: #number)))
.push(Action.new(parseTree: `{ n }))
)
.push(Sequence.new()
.push(Assignment.new(name: #n, rule: RuleCall.new(name: #unsign)))
.push(Action.new(parseTree: `{ n }))
);
unsign =
Sequence.new()
.push(Capture.new(expression:
Plus.new(expression: RuleCall.new(name: #digit)))
)
.push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ yytext.asInteger(10); }));
metaVar =
Alternation.new()
.push(
Sequence.new()
.push(StringLiteral.new(string: "global"))
.push(RuleCall.new(name: #ws))
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #metaId)))
.push(Action.new(parseTree: `{ GetGlobal.new(name: i); }))
)
.push(
Sequence.new()
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #metaId)))
.push(Action.new(parseTree: `{ GetVar.new(name: i); }))
);
metaId =
Sequence.new()
.push(Capture.new(expression: Sequence.new()
.push(RuleCall.new(name: #letter))
.push(Star.new(expression: RuleCall.new(name: #alnum)))
))
.push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ intern(yytext); }));
digit = CharacterClass.new(value: "0-9");
higit = CharacterClass.new(value: "0-9A-Fa-f");
letter = CharacterClass.new(value: "A-Za-z_$");
alnum =
Alternation.new()
.push(RuleCall.new(name: #letter))
.push(RuleCall.new(name: #digit));
nil =
Sequence.new()
.push(StringLiteral.new(string: "nil"))
.push(Not.new(expression: RuleCall.new(name: #alnum)))
.push(RuleCall.new(name: #ws));
semi = Sequence.new().push(StringLiteral.new(string: ";" )).push(RuleCall.new(name: #ws));
comma = Sequence.new().push(StringLiteral.new(string: "," )).push(RuleCall.new(name: #ws));
lparen = Sequence.new().push(StringLiteral.new(string: "(" )).push(RuleCall.new(name: #ws));
rparen = Sequence.new().push(StringLiteral.new(string: ")" )).push(RuleCall.new(name: #ws));
lbrak = Sequence.new().push(StringLiteral.new(string: "[" )).push(RuleCall.new(name: #ws));
rbrak = Sequence.new().push(StringLiteral.new(string: "]" )).push(RuleCall.new(name: #ws));
lbrace = Sequence.new().push(StringLiteral.new(string: "{" )).push(RuleCall.new(name: #ws));
rbrace = Sequence.new().push(StringLiteral.new(string: "}" )).push(RuleCall.new(name: #ws));
pplus = Sequence.new().push(StringLiteral.new(string: "++")).push(RuleCall.new(name: #ws));
assign =
Sequence.new()
.push(StringLiteral.new(string: "="))
.push(Not.new(expression: CharacterClass.new(value: "=")))
.push(RuleCall.new(name: #ws));
dot =
Sequence.new()
.push(StringLiteral.new(string: "."))
.push(Not.new(expression: CharacterClass.new(value: ".")))
.push(RuleCall.new(name: #ws));
colon =
Sequence.new()
.push(StringLiteral.new(string: ":"))
.push(Not.new(expression: CharacterClass.new(value: ":")))
.push(RuleCall.new(name: #ws));
end_of_file = Not.new(expression: Dot.new());
end_of_line =
Alternation.new()
.push(StringLiteral.new(string: "\r\n"))
.push(StringLiteral.new(string: "\n"))
.push(StringLiteral.new(string: "\r"));
comment =
Sequence.new()
.push(StringLiteral.new(string: "//"))
.push(Star.new(expression:
Sequence.new()
.push(Not.new(expression: RuleCall.new(name: #end_of_line)))
.push(Dot.new())
))
.push(RuleCall.new(name: #end_of_line));
space =
Alternation.new()
.push(StringLiteral.new(string: " "))
.push(StringLiteral.new(string: "\t"))
.push(RuleCall.new(name: #end_of_line));
ws =
Star.new(expression: Alternation.new()
.push(RuleCall.new(name: #space))
.push(RuleCall.new(name: #comment))
);
// ----- Grammar of Grammars -----
with(#HardCodedPeg);
grammar =
Sequence.new()
.push(RuleCall.new(name: #ws))
.push(Alternation.new()
.push(Sequence.new()
.push(Assignment.new(name: #d, rule: RuleCall.new(name: #definition)))
.push(Action.new(parseTree: `{ d; }))
)
.push(Sequence.new()
.push(RuleCall.new(name: #end_of_file))
.push(Action.new(parseTree: `{ nil; }))
)
);
definition =
Sequence.new()
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #identifier)))
.push(RuleCall.new(name: #assign))
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #expression)))
.push(Optional.new(expression: RuleCall.new(name: #semi)))
.push(Action.new(parseTree: `{ Definition.new(name: i, expression: e); }));
expression =
Alternation.new()
.push(Sequence.new()
.push(Assignment.new(name: #s, rule: RuleCall.new(name: #sequence)))
.push(Not.new(expression: RuleCall.new(name: #bar)))
.push(Action.new(parseTree: `{ s; }))
)
.push(Sequence.new()
.push(Assignment.new(name: #s1, rule: RuleCall.new(name: #sequence)))
.push(Action.new(parseTree: `{ s1 = Alternation.new().push(s1); }))
.push(Star.new(expression: Sequence.new()
.push(RuleCall.new(name: #bar))
.push(Assignment.new(name: #s2, rule: RuleCall.new(name: #sequence)))
.push(Action.new(parseTree: `{ s1.push(s2); }))
))
.push(Action.new(parseTree: `{ s1; }))
);
sequence =
Sequence.new()
.push(Assignment.new(name: #p, rule: RuleCall.new(name: #prefix)))
.push(Optional.new(expression: Sequence.new()
.push(Assignment.new(name: #q, rule: RuleCall.new(name: #prefix)))
.push(Action.new(parseTree: `{ p = Sequence.new().push(p).push(q); }))
.push(Star.new(expression: Sequence.new()
.push(Assignment.new(name: #q, rule: RuleCall.new(name: #prefix)))
.push(Action.new(parseTree: `{ p.push(q); }))
))
))
.push(Action.new(parseTree: `{ p; }));
prefix =
Alternation.new()
.push(Sequence.new()
.push(RuleCall.new(name: #and))
.push(RuleCall.new(name: #action))
)
.push(Sequence.new()
.push(RuleCall.new(name: #at))
.push(Assignment.new(name: #a, rule: RuleCall.new(name: #action)))
.push(Action.new(parseTree: `{ ExecuteAction.new(action: a); }))
)
.push(Alternation.new()
.push(Sequence.new()
.push(RuleCall.new(name: #and))
.push(Assignment.new(name: #s, rule: RuleCall.new(name: #suffix)))
.push(Action.new(parseTree: `{ And.new(expression: s); }))
)
.push(Sequence.new()
.push(RuleCall.new(name: #not))
.push(Assignment.new(name: #s, rule: RuleCall.new(name: #suffix)))
.push(Action.new(parseTree: `{ Not.new(expression: s); }))
)
.push(Sequence.new()
.push(Assignment.new(name: #s, rule: RuleCall.new(name: #suffix)))
.push(Action.new(parseTree: `{ s; }))
)
);
suffix =
Sequence.new()
.push(Assignment.new(name: #p, rule: RuleCall.new(name: #primary)))
.push(Optional.new(expression: Alternation.new()
.push(Sequence.new()
.push(RuleCall.new(name: #query))
.push(Action.new(parseTree: `{ p = Optional.new(expression: p); }))
)
.push(Sequence.new()
.push(RuleCall.new(name: #star))
.push(Action.new(parseTree: `{ p = Star.new(expression: p); }))
)
.push(Sequence.new()
.push(RuleCall.new(name: #plus))
.push(Action.new(parseTree: `{ p = Plus.new(expression: p); }))
)
))
.push(Action.new(parseTree: `{ p; }));
primary =
Alternation.new()
.push(Sequence.new()
.push(Assignment.new(name: #i1, rule: RuleCall.new(name: #identifier)))
.push(RuleCall.new(name: #colon))
.push(Assignment.new(name: #i2, rule: RuleCall.new(name: #ruleCall)))
.push(Not.new(expression: RuleCall.new(name: #assign)))
.push(Action.new(parseTree: `{ Assignment.new(name: i1, rule: i2); }))
)
.push(Sequence.new()
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #ruleCall)))
.push(Not.new(expression: RuleCall.new(name: #assign)))
.push(Action.new(parseTree: `{ i; }))
)
.push(Sequence.new()
.push(RuleCall.new(name: #lparen))
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #expression)))
.push(RuleCall.new(name: #rparen))
.push(Action.new(parseTree: `{ e; }))
)
.push(Sequence.new()
.push(Assignment.new(name: #l, rule: RuleCall.new(name: #literal)))
.push(Action.new(parseTree: `{ l; }))
)
.push(Sequence.new()
.push(Assignment.new(name: #c, rule: RuleCall.new(name: #class)))
.push(Action.new(parseTree: `{ c; }))
)
.push(Sequence.new()
.push(RuleCall.new(name: #dot))
.push(Action.new(parseTree: `{ Dot.new(); }))
)
.push(Sequence.new()
.push(Assignment.new(name: #a, rule: RuleCall.new(name: #action)))
.push(Action.new(parseTree: `{ a; }))
)
.push(Sequence.new()
.push(RuleCall.new(name: #begin))
.push(Assignment.new(name: #e, rule: RuleCall.new(name: #expression)))
.push(RuleCall.new(name: #end))
.push(Action.new(parseTree: `{ Capture.new(expression: e); }))
);
identifier =
Sequence.new()
.push(Capture.new(expression: Sequence.new()
.push(CharacterClass.new(value: "-a-zA-Z_"))
.push(Star.new(expression: CharacterClass.new(value: "-a-zA-Z_0-9")))
))
.push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ intern(yytext); }));
ruleCall =
Alternation.new()
.push(Sequence.new()
.push(Assignment.new(name: #n, rule: RuleCall.new(name: #identifier)))
.push(RuleCall.new(name: #ccolon))
.push(Assignment.new(name: #r, rule: RuleCall.new(name: #identifier)))
.push(Action.new(parseTree: `{ NamespacedRuleCall.new(namespace: n, name: r); }))
)
.push(Sequence.new()
.push(Assignment.new(name: #i, rule: RuleCall.new(name: #identifier)))
.push(Action.new(parseTree: `{ RuleCall.new(name: i); }))
);
literal =
Alternation.new()
.push(Sequence.new()
.push(CharacterClass.new(value: "\'"))
.push(Capture.new(expression:
Star.new(expression: Sequence.new()
.push(Not.new(expression: CharacterClass.new(value: "\'")))
.push(RuleCall.new(name: #char)))
))
.push(CharacterClass.new(value: "\'"))
.push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ StringLiteral.new(string: yytext); }))
)
.push(Sequence.new()
.push(CharacterClass.new(value: "\""))
.push(Capture.new(expression:
Star.new(expression: Sequence.new()
.push(Not.new(expression: CharacterClass.new(value: "\"")))
.push(RuleCall.new(name: #char)))
))
.push(CharacterClass.new(value: "\""))
.push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ StringLiteral.new(string: yytext); }))
);
class =
Sequence.new()
.push(StringLiteral.new(string: "["))
.push(Capture.new(expression:
Star.new(expression: Sequence.new()
.push(Not.new(expression: StringLiteral.new(string: "]")))
.push(RuleCall.new(name: #range)))
))
.push(StringLiteral.new(string: "]"))
.push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ CharacterClass.new(value: yytext.unescaped()); }));
range =
Alternation.new()
.push(Sequence.new()
.push(RuleCall.new(name: #char))
.push(StringLiteral.new(string: "-"))
.push(RuleCall.new(name: #char))
)
.push(
RuleCall.new(name: #char)
);
char =
Alternation.new()
.push(Sequence.new()
.push(StringLiteral.new(string: "\\"))
.push(CharacterClass.new(value: "abefnrtv\'\"[]\\"))
)
.push(Sequence.new()
.push(StringLiteral.new(string: "\\"))
.push(CharacterClass.new(value: "0-3"))
.push(CharacterClass.new(value: "0-7"))
.push(CharacterClass.new(value: "0-7"))
)
.push(Sequence.new()
.push(StringLiteral.new(string: "\\"))
.push(CharacterClass.new(value: "0-7"))
.push(Optional.new(expression: CharacterClass.new(value: "0-7")))
)
.push(Sequence.new()
.push(Not.new(expression: StringLiteral.new(string: "\\")))
.push(Dot.new())
);
action =
Sequence.new()
.push(Assignment.new(name: #m, rule: NamespacedRuleCall.new(namespace: #HardCodedMeta, name: #block)))
.push(RuleCall.new(name: #ws))
.push(Action.new(parseTree: `{ Action.new(parseTree: Block.new(body: m)); }));
bar = Sequence.new().push(StringLiteral.new(string: "|")).push(RuleCall.new(name: #ws));
not = Sequence.new().push(StringLiteral.new(string: "!")).push(RuleCall.new(name: #ws));
query = Sequence.new().push(StringLiteral.new(string: "?")).push(RuleCall.new(name: #ws));
begin = Sequence.new().push(StringLiteral.new(string: "<")).push(RuleCall.new(name: #ws));
end = Sequence.new().push(StringLiteral.new(string: ">")).push(RuleCall.new(name: #ws));
tilde = Sequence.new().push(StringLiteral.new(string: "~")).push(RuleCall.new(name: #ws));
at = Sequence.new().push(StringLiteral.new(string: "@")).push(RuleCall.new(name: #ws));
rpercent = Sequence.new().push(StringLiteral.new(string: "%}")).push(RuleCall.new(name: #ws));
ccolon = Sequence.new().push(StringLiteral.new(string: "::")).push(RuleCall.new(name: #ws));
and =
Sequence.new()
.push(StringLiteral.new(string: "&"))
.push(Not.new(expression: CharacterClass.new(value: "&=")))
.push(RuleCall.new(name: #ws));
plus =
Sequence.new()
.push(StringLiteral.new(string: "+"))
.push(Not.new(expression: CharacterClass.new(value: "+=")))
.push(RuleCall.new(name: #ws));
star =
Sequence.new()
.push(StringLiteral.new(string: "*"))
.push(Not.new(expression: CharacterClass.new(value: "=")))
.push(RuleCall.new(name: #ws));
end_of_file = Not.new(expression: Dot.new());
end_of_line =
Alternation.new()
.push(StringLiteral.new(string: "\r\n"))
.push(StringLiteral.new(string: "\n"))
.push(StringLiteral.new(string: "\r"));
comment =
Sequence.new()
.push(StringLiteral.new(string: "#"))
.push(Star.new(expression:
Sequence.new()
.push(Not.new(expression: RuleCall.new(name: #end_of_line)))
.push(Dot.new())
))
.push(RuleCall.new(name: #end_of_line));
space =
Alternation.new()
.push(StringLiteral.new(string: " "))
.push(StringLiteral.new(string: "\t"))
.push(RuleCall.new(name: #end_of_line));
ws =
Star.new(expression: Alternation.new()
.push(RuleCall.new(name: #space))
.push(RuleCall.new(name: #comment))
);
without(all: 1);
// Functions for minproto parser
Object_push(o, v) {
o.push(v);
o;
}
Object_put(o, k, v) {
o[k] = v;
o;
}
global pObject = Object;
new(_) {
[];
}
_get(obj, _, __) {
obj;
}
expected(what, where)
{
error("syntax error: " + what + " expected near: " + where);
}
syntaxError(str) {
error("syntax error: " + str);
}
newWhile(cond, stmt) {
While.new(condition: cond, body: stmt);
}
newIf(c, s, t) {
If.new(condition: c, consequent: s, alternate: t);
}
newContinue() {
Continue.new();
}
newBreak(e) {
Break.new(value: e);
}
newReturn(e) {
Return.new(value: e);
}
newForIn(i, e, s) {
ForIn.new(identifier: i, expression: e, body: s);
}
newForFromTo(i, a, b, s) {
ForFromTo.new(identifier: i, first: a, last: b, body: s);
}
newFor(i, c, u, s) {
For.new(initialise: i, condition: c, update: u, body: s);
}
newTryCatch(t, i, c) {
TryCatch.new(statement: t, identifier: i, handler: c);
}
newTryEnsure(t, e) {
TryEnsure.new(statement: t, handler: e);
}
newRaise(e) {
Raise.new(value: e);
}
newLambda(p, b, par, n) {
Lambda.new(parameters: p, body: b, parent: par, name: n);
}
newGetLocal(i) {
GetLocal.new(name: i);
}
newSetLocal(i, v) {
SetLocal.new(name: i, value: v);
}
newGetGlobal(i) {
GetGlobal.new(name: i);
}
newSetGlobal(i, v) {
SetGlobal.new(name: i, value: v);
}
newGetVar(i) {
GetVar.new(name: i);
}
newSetVar(i, v) {
SetVar.new(name: i, value: v);
}
newGetProp(v, j) {
GetProp.new(object: v, key: j);
}
newSetProp(o, k, v) {
SetProp.new(object: o, key: k, value: v);
}
newBlock(b) {
Block.new(body: b);
}
newUnyop(o, p) {
Unyop.new(operation: o).push(p);
}
neg(n) {
Unyop.new(operation: opNeg).push(n);
}
newSuper(i, a) {
Super.new(method: i, arguments: a);
}
newGetArray(p, e) {
GetArray.new(object: p, index: e);
}
newGetSlice(o, s, e) {
GetSlice.new(object: o, start: s, stop: e);
}
newInvoke(p, i, a) {
Invoke.new(self: p, method: i, arguments: a);
}
newLiteral(o) {
Literal.new(object: o);
}
newFloat(f) {
f;
}
strtod(text, _) {
text.asFloat();
}
newInteger(i) {
i;
}
strtol(text, _, base) {
text.asInteger(base)
}
newStringUnescaped(text) {
text;
}
HardCodedPeg = Grammar.new();
HardCodedMeta = Grammar.new();
HardCodedPeg.addRulesFromNamespace(#HardCodedPeg);
HardCodedMeta.addRulesFromNamespace(#HardCodedMeta);
HardCodedPeg.__delegate__ = HardCodedMeta;
global stream = newStream(readfile("minproto.grammar"));
global context = Context.new(outerContext: nil).init();
global actions = [];
global lineno = 0;
while(!stream.atEnd()) {
HardCodedPeg.grammar(stream, context, actions);
with(#metaLanguage);
local definition = { for (actionAndContext in actions) {
actionAndContext.action.execute(actionAndContext.context);
} };
if (definition == nil) continue; // end of file case
setInTopNamespace(definition.name, definition.expression);
without(#metaLanguage);
global actions = [];
}
//println("\n--------- META ---------\n\n");
//println(__namespaces__.metaLanguage);
global stream = newStream(readfile("rawgrammar.leg"));
global context = Context.new(outerContext: nil).init();
global actions = [];
while(!stream.atEnd()) {
HardCodedPeg.grammar(stream, context, actions);
with(#peg);
local definition = { for (actionAndContext in actions) {
actionAndContext.action.execute(actionAndContext.context);
} };
if (definition == nil) continue; // end of file case
setInTopNamespace(definition.name, definition.expression);
without(#peg);
global actions = [];
}
//println("\n--------- PEG ---------\n\n");
//println(__namespaces__.peg);
global peg = Grammar.new();
global metaLanguage = Grammar.new();
peg.addRulesFromNamespace(#peg);
metaLanguage.addRulesFromNamespace(#metaLanguage);
peg.__delegate__ = metaLanguage;
global now = cputime();
print("Parser Generation Time : ", now - then, "s\n");
// Circularity test
if (nil) {
println("circularity test\n");
global stream2 = newStream(readfile("minproto.grammar"));
global context2 = Context.new(outerContext: nil).init();
global actions2 = [];
while(!stream2.atEnd()) {
peg.grammar(stream2, context2, actions2);
with(#metaLanguageCircular);
local definition = { for (actionAndContext in actions2) {
actionAndContext.action.execute(actionAndContext.context);
} };
if (definition == nil) continue; // end of file case
setInTopNamespace(definition.name, definition.expression);
without(#metaLanguageCircular);
global actions2 = [];
}
//println("\n--------- CIRCULAR META ---------\n\n");
//println(__namespaces__.metaLanguageCircular);
global stream2 = newStream(readfile("rawgrammar.leg"));
global context2 = Context.new(outerContext: nil).init();
global actions2 = [];
while(!stream2.atEnd()) {
peg.grammar(stream2, context2, actions2);
with(#pegCircular);
local definition = { for (actionAndContext in actions2) {
actionAndContext.action.execute(actionAndContext.context);
} };
if (definition == nil) continue; // end of file case
setInTopNamespace(definition.name, definition.expression);
without(#pegCircular);
global actions2 = [];
}
//println("\n--------- CIRCULAR PEG ---------\n\n");
//println(__namespaces__.pegCircular);
compareGrammars(grammar1, grammar2) {
local success = 1;
for (key in __namespaces__[grammar1].keys()) {
if (key == #__nsname__) continue;
if (codeString(__namespaces__[grammar1][key]) != codeString(__namespaces__[grammar2][key])) {
print("Found different objects for rule ", key, ":\n");
println(__namespaces__[grammar1][key]);
println(__namespaces__[grammar2][key]);
success = 0;
}
}
if (success == 1) {
print("Grammars ", grammar1, " and ", grammar2, " are equal\n");
}
}
compareGrammars(#peg, #pegCircular);
compareGrammars(#metaLanguage, #metaLanguageCircular);
}
//global functionCounts = [];
global then = cputime();
global stream3 = newStream(readfile("dowhile.meta"));
global context3 = Context.new(outerContext: nil).init();
global actions3 = [];
while(!stream3.atEnd()) {
metaLanguage.start(stream3, context3, actions3);
local res = { for (actionAndContext in actions3) {
actionAndContext.action.execute(actionAndContext.context);
} };
eval(res, env: nil);
global actions3 = [];
}
global now = cputime();
print("---\nFile Execution time : ", now - then, "s\n---\n");
//println(functionCounts);
global then = cputime();
global streamFString = newStream(readfile("fstring.meta"));
global contextFString = Context.new(outerContext: nil).init();
global actionsFString = [];
while(!streamFString.atEnd()) {
metaLanguage.start(streamFString, contextFString, actionsFString);
local res = { for (actionAndContext in actionsFString) {
actionAndContext.action.execute(actionAndContext.context);
} };
eval(res, env: nil);
global actionsFString = [];
}
global now = cputime();
print("---\nFile Execution time : ", now - then, "s\n---\n");
global stream4 = newStream(readfile("minproto.grammar"));
global context4 = Context.new(outerContext: nil).init();
global actions4 = [];
addRule(grammar, definition) {
local instructions = [];
instructions.push(Instruction.new(OpCodes.FAIL, nil, 0, 0, 0));
local ko = instructions.length() - 1;
instructions.push(Instruction.new(OpCodes.SUCCEED, nil, 0, 0, 0));
local ok = instructions.length() - 1;
definition.expression.emitByteCode(instructions, ok, ko);
for (n from 0 to (instructions.length() - 1 - ((instructions.length() - 1) % 2)) / 2) {
local i = instructions[n];
instructions[n] = instructions[instructions.length() - 1 - n];
instructions[instructions.length() - 1 - n] = i;
}
//println(definition.name);
for (n in instructions.length()) {
i = instructions[n];
i.ok = instructions.length() - 1 - i.ok;
i.ko = instructions.length() - 1 - i.ko;
//print(" 0", { if (n < 10) { "0" } else { "" } }, n, " ");
//i.printline();
}
grammar[definition.name] = [];
for (instruction in instructions) {
grammar[definition.name].push(instruction.op);
grammar[definition.name].push(instruction.arg);
grammar[definition.name].push(instruction.arglen);
grammar[definition.name].push(instruction.ok);
grammar[definition.name].push(instruction.ko);
}
}
minprotoVMGrammar = [];
while(!stream4.atEnd()) {
peg.grammar(stream4, context4, actions4);
local definition = { for (actionAndContext in actions4) {
actionAndContext.action.execute(actionAndContext.context);
} };
if (definition == nil) continue; // end of file case
addRule(minprotoVMGrammar, definition);
global actions4 = [];
}
global then = cputime();
input = readfile("grammar_parser.meta");
cursor = 0;
while (yysval != 0) {
matchedCharacters = __match__(minprotoVMGrammar, #start, input, cursor);
//print(yysval, "\n");
cursor += matchedCharacters;
}
global now = cputime();
print("---\nFile Parsing time : ", now - then, "s\nSpeed: ", 1688/(now-then), " lines per second\n---\n");