add compiler

This commit is contained in:
Lizzy Hunt 2023-11-16 19:06:35 -07:00
parent ec2b924fda
commit 56bf487823
No known key found for this signature in database
GPG Key ID: E835BD4B08CCAF96
7 changed files with 666 additions and 224 deletions

View File

@ -39,10 +39,21 @@ body {
border: 2px solid white;
border-radius: 0.25rem;
padding: 1rem;
flex: 1;
}
.source-container {
display: flex;
flex-direction: row;
gap: 1rem;
height: 100%;
}
textarea {
border-radius: 0.25rem;
}
.CodeMirror {
height: 50vh;
}

View File

@ -1,8 +1,8 @@
Program = instructions: Line* {
return { instructions: instructions };
Program = lines: (Line / (_/[\n]))* {
return { instructions: lines.filter((line) => typeof line !== "string" || line.trim() != "") };
}
Line = instruction: (LabeledInstruction / Instruction) _ {
Line = _? instruction: (LabeledInstruction / Instruction) _? [\n]? {
return instruction;
}
@ -16,9 +16,14 @@ Label = "[" _? label:LABEL_V _? "]" {
Instruction = conditional: Conditional { return { conditional }; }
/ assignment: Assignment { return { assignment }; }
/ goto: Goto { return { goto }; }
Conditional = "IF" _ variable: VAR _ "!=" _ "0" _ "GOTO" _ label: Label {
return { variable, label };
Goto = GOTO _ label: LABEL_V {
return { label };
}
Conditional = "IF" _ variable: VAR _? "!=" _? "0" _ goto: Goto {
return { variable, goto };
}
Assignment = variable: VAR _ "<-" _ expr: Expression {
@ -30,19 +35,25 @@ Assignment = variable: VAR _ "<-" _ expr: Expression {
Expression = left: VAR _ opr: OPERATION _ "1" {
return { left, opr };
} / left: VAR {
return { left };
}
VAR = symbol:"Y" { return symbol } / symbol:("X" / "Z") ind:Integer+ {
return symbol + ind;
}
GOTO = "GOTO"
OPERATION = "+" / "-"
LABEL_V = symbol:[A-E] ind:Integer+ {
LABEL_V = symbol:END_LABEL { return symbol } / symbol:[A-E] ind:Integer+ {
return symbol + ind;
}
Integer "integer"
= _ [0-9]+ { return parseInt(text(), 10); }
END_LABEL = "E"
_ "whitespace" = [ \t\n\r]* { }
Integer "integer"
= [0-9]+ { return parseInt(text(), 10); }
_ "whitespace" = [ \t]+ { }

View File

@ -1,35 +1,46 @@
<!DOCTYPE html>
<!doctype html>
<html>
<head>
<title>L-Program Compiler</title>
<link rel="stylesheet" type="text/css" href="css/styles.css">
<link rel="stylesheet" type="text/css" href=
"codemirror/codemirror.css">
</head>
<body>
<div class="container">
<h1>L-Program Compiler</h1>
<p><i>Developed for Kulyukin's CS5000</i></p>
<hr>
<div class="textarea-container">
<textarea id="instructions">// asdf
q0 B 1 q1
q1 1 R q1
q1 B 1 q2
q2 1 R q2
q2 B 1 f</textarea>
<div>
<button id="compile">Compile</button><span style=
"margin-left: 0.5rem" id="compile_status"></span>
</div>
<div>
<button id="copy_state">Copy State</button>
<head>
<title>Liz's L-Program Compiler</title>
<link rel="stylesheet" type="text/css" href="codemirror/codemirror.css" />
<link rel="stylesheet" type="text/css" href="css/styles.css" />
</head>
<body>
<div class="container">
<h1>Liz's L-Program Compiler</h1>
<p><i>Developed for Kulyukin's CS5000</i></p>
<hr />
<div class="source-container">
<div class="textarea-container">
<h3>L Source</h3>
<textarea id="instructions">
// asdf
[ B1 ] X1 <- X1 + 1
IF X1 != 0 GOTO B1
X1 <- X1
</textarea
>
<div>
<button id="compile">Compile</button
><span style="margin-left: 0.5rem" id="compile_status"></span>
</div>
</div>
<div class="textarea-container">
<h3>Compiled JS</h3>
<textarea id="compiled"></textarea>
<div>
<button id="eval">Eval</button
><span style="margin-left: 0.5rem" id="eval_status"></span>
</div>
</div>
</div>
</div>
</div>
<script src="codemirror/codemirror.js"></script>
<script src="js/observable.js"></script>
<script src="js/parser.js"></script>
<script src="js/main.js"></script>
</body>
<script src="codemirror/codemirror.js"></script>
<script src="js-beautify/js-beautify.js"></script>
<script src="js/observable.js"></script>
<script src="js/parser.js"></script>
<script src="js/compiler.js"></script>
<script src="js/main.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

163
godel/js/compiler.js Normal file
View File

@ -0,0 +1,163 @@
class StringBuilder {
constructor() {
this.stringPieces = [];
}
add(s) {
this.stringPieces.push(s);
}
build() {
return this.stringPieces.join("");
}
}
const compileGoto = (gotoNode, stringBuilder) => {
stringBuilder.add(`this.followGoto("${gotoNode.label}");\nreturn;\n`);
};
const compileConditional = (conditionalNode, stringBuilder) => {
const { variable, goto: gotoNode } = conditionalNode;
stringBuilder.add(`if (this.get("${variable}") != 0) {\n`);
compileGoto(gotoNode, stringBuilder);
stringBuilder.add(`}\n`);
};
const compileAssignment = (assignmentNode, stringBuilder) => {
const { variable, expr } = assignmentNode;
if (expr.opr) {
if (expr.opr == "+") stringBuilder.add(`this.addOne("${variable}");\n`);
else if (expr.opr == "-")
stringBuilder.add(`this.subtractOne("${variable}");\n`);
} else {
stringBuilder.add("// noop \n");
}
};
const compileInstruction = (instruction, stringBuilder) => {
if (instruction.goto) {
compileGoto(instruction.goto, stringBuilder);
return; // ignore unreachable addition to instructionPointer
}
if (instruction.conditional) {
compileConditional(instruction.conditional, stringBuilder);
} else if (instruction.assignment) {
compileAssignment(instruction.assignment, stringBuilder);
}
stringBuilder.add("this.instructionPointer++;\n");
};
const compile = (ast) => {
const stringBuilder = new StringBuilder();
stringBuilder.add(`
class Program {
constructor() {
this.variables = new Map(); // variable -> natural number val
this.labelInstructions = new Map(); // labels to instruction indices
this.instructions = new Map(); // instruction indices to procedures
this.instructions.set(0, () => this.main());
this.instructionPointer = 0;
this.variables.set("Y", 0);
// -- program-specific state init --
this.finalInstruction = ${
ast.instructions.length + 1
}; // instruction of the implied "exit" label
this.labelInstructions.set("E", this.finalInstruction); // "E" is the exit label
}
get(variable) {
if (!this.variables.has(variable)) {
this.variables.set(variable, 0);
}
return this.variables.get(variable);
}
addOne(variable) {
const val = this.get(variable);
this.variables.set(variable, val + 1);
}
subtractOne(variable) {
const val = this.get(variable);
this.variables.set(variable, val - 1);
}
followGoto(label) {
this.instructionPointer = this.labelInstructions.get(label);
}
step() {
if (!this.isCompleted()) {
const procedure = this.instructions.get(this.instructionPointer);
procedure();
}
return this.instructionPointer;
}
isCompleted() {
return this.instructionPointer == this.finalInstruction;
}
getResult() {
return this.variables.get("Y");
}
run(maxIter=50000) {
let iter = 0;
while (!this.isCompleted() && (++iter) < maxIter) this.step();
if (iter < maxIter) {
return this.getResult();
}
throw new Error("Iterations went over maxIter=(" + maxIter + "). To resolve, please ask Turing how we can tell if a program will halt during compilation.");
}
main() {
`);
stringBuilder.add("// -- build label -> instruction map --\n");
for (let i = 0; i < ast.instructions.length; i++) {
const line = ast.instructions[i];
const instructionIdx = i + 1;
if (line.label) {
stringBuilder.add(
`this.instructions.set(${instructionIdx}, () => this.${line.label}());\n`,
);
stringBuilder.add(
`this.labelInstructions.set("${line.label}", ${instructionIdx});\n`,
);
}
}
stringBuilder.add("// -- compiled instructions --\n");
for (let i = 0; i < ast.instructions.length; i++) {
let instruction = ast.instructions[i];
const instructionIdx = i + 1;
if (instruction.label) {
stringBuilder.add(
` this.followGoto("${instruction.label}");\n}\n\n${instruction.label}() {\n`,
);
stringBuilder.add(`this.instructionPointer = ${instructionIdx};\n`);
instruction = instruction.instruction;
}
compileInstruction(instruction, stringBuilder);
}
stringBuilder.add(` }\n}\n`);
stringBuilder.add("// -- \n");
stringBuilder.add("const program = new Program();\n\n");
stringBuilder.add("// set the initial Snapshot here\n");
stringBuilder.add('// program.variables.set("X1", 2);\n\n');
stringBuilder.add(
"program.run(50_000); // 50_000 is the max iterations before throwing an exception\n",
);
return js_beautify(stringBuilder.build(), {
indent_size: 2,
wrap_line_length: 120,
});
};

View File

@ -1,5 +1,121 @@
const MESSAGES = {};
const MESSAGES = {
COMPILE: "COMPILE",
COMPILE_RESULT: "COMPILE_RESULT",
EVAL: "EVAL",
EVAL_STATUS: "EVAL_RESULT",
};
// -- the "real" code
// -- the "real" code --
const state = new Observable();
const prepareSource = (text) => text.replaceAll(/\/\/.*/g, "").trim();
const main = () => {
let program;
state.subscribe((msg) => {
if (msg.type == MESSAGES.COMPILE) {
const { value } = msg;
const source = prepareSource(value);
try {
const ast = parser.parse(source);
const program = compile(ast);
state.notify({
type: MESSAGES.COMPILE_RESULT,
value: program,
});
} catch (e) {
state.notify({
type: MESSAGES.COMPILE_RESULT,
error: e.toString(),
});
}
}
if (msg.type == MESSAGES.EVAL) {
const source = compiledEditorEl.getValue();
try {
const result = eval(source);
state.notify({
type: MESSAGES.EVAL_RESULT,
value: result,
});
} catch (e) {
state.notify({
type: MESSAGES.EVAL_RESULT,
error: e.toString(),
});
}
}
});
};
main();
// -- a bit of some hacky ui code --
const instructionsEl = document.getElementById("instructions");
const instructionsEditorEl = CodeMirror.fromTextArea(instructionsEl, {
lineNumbers: true,
});
const compileButton = document.getElementById("compile");
const evalButton = document.getElementById("eval");
const evalStatusEl = document.getElementById("eval_status");
const compileStatusEl = document.getElementById("compile_status");
const compiledEl = document.getElementById("compiled");
const compiledEditorEl = CodeMirror.fromTextArea(compiledEl, {
lineNumbers: true,
});
state.subscribe((msg) => {
if (msg.type == MESSAGES.COMPILE_RESULT) {
evalStatusEl.classList.remove("error");
evalStatusEl.classList.remove("success");
evalStatusEl.innerHTML = "";
if (typeof msg.value !== "undefined") {
compiledEditorEl.setValue(msg.value);
compileStatusEl.classList.add("success");
compileStatusEl.classList.remove("error");
compileStatusEl.innerHTML = `Successful compile at ${new Date().toLocaleString()}!`;
} else if (msg.error) {
compiledEditorEl.setValue("");
compileStatusEl.classList.remove("success");
compileStatusEl.classList.add("error");
compileStatusEl.innerHTML = msg.error;
}
}
});
state.subscribe((msg) => {
if (msg.type == MESSAGES.EVAL_RESULT) {
if (typeof msg.value !== "undefined") {
evalStatusEl.classList.add("success");
evalStatusEl.classList.remove("error");
evalStatusEl.innerHTML = `Result: ${msg.value}`;
} else if (msg.error) {
evalStatusEl.classList.remove("success");
evalStatusEl.classList.add("error");
evalStatusEl.innerHTML = msg.error;
}
}
});
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get("instructions")) {
editorEl.setValue(atob(urlParams.get("instructions")));
}
compileButton.addEventListener("click", () => {
state.notify({
type: MESSAGES.COMPILE,
value: instructionsEditorEl.getValue(),
});
});
evalButton.addEventListener("click", () => {
state.notify({
type: MESSAGES.EVAL,
});
});

View File

@ -1,4 +1,4 @@
module.exports = /*
parser = /*
* Generated by PEG.js 0.10.0.
*
* http://pegjs.org/
@ -141,72 +141,83 @@ module.exports = /*
peg$startRuleFunctions = { Program: peg$parseProgram },
peg$startRuleFunction = peg$parseProgram,
peg$c0 = function(instructions) {
return { instructions: instructions };
peg$c0 = /^[\n]/,
peg$c1 = peg$classExpectation(["\n"], false, false),
peg$c2 = function(lines) {
return { instructions: lines.filter((line) => typeof line !== "string" || line.trim() != "") };
},
peg$c1 = function(instruction) {
peg$c3 = function(instruction) {
return instruction;
},
peg$c2 = function(label, instruction) {
peg$c4 = function(label, instruction) {
return { label, instruction };
},
peg$c3 = "[",
peg$c4 = peg$literalExpectation("[", false),
peg$c5 = "]",
peg$c6 = peg$literalExpectation("]", false),
peg$c7 = function(label) {
peg$c5 = "[",
peg$c6 = peg$literalExpectation("[", false),
peg$c7 = "]",
peg$c8 = peg$literalExpectation("]", false),
peg$c9 = function(label) {
return label;
},
peg$c8 = function(conditional) { return { conditional }; },
peg$c9 = function(assignment) { return { assignment }; },
peg$c10 = "IF",
peg$c11 = peg$literalExpectation("IF", false),
peg$c12 = "!=",
peg$c13 = peg$literalExpectation("!=", false),
peg$c14 = "0",
peg$c15 = peg$literalExpectation("0", false),
peg$c16 = "GOTO",
peg$c17 = peg$literalExpectation("GOTO", false),
peg$c18 = function(variable, label) {
return { variable, label };
peg$c10 = function(conditional) { return { conditional }; },
peg$c11 = function(assignment) { return { assignment }; },
peg$c12 = function(goto) { return { goto }; },
peg$c13 = function(label) {
return { label };
},
peg$c19 = "<-",
peg$c20 = peg$literalExpectation("<-", false),
peg$c21 = function(variable, expr) {
peg$c14 = "IF",
peg$c15 = peg$literalExpectation("IF", false),
peg$c16 = "!=",
peg$c17 = peg$literalExpectation("!=", false),
peg$c18 = "0",
peg$c19 = peg$literalExpectation("0", false),
peg$c20 = function(variable, goto) {
return { variable, goto };
},
peg$c21 = "<-",
peg$c22 = peg$literalExpectation("<-", false),
peg$c23 = function(variable, expr) {
if (expr.left != variable) {
error("left hand variable must match right hand");
}
return { variable, expr };
},
peg$c22 = "1",
peg$c23 = peg$literalExpectation("1", false),
peg$c24 = function(left, opr) {
peg$c24 = "1",
peg$c25 = peg$literalExpectation("1", false),
peg$c26 = function(left, opr) {
return { left, opr };
},
peg$c25 = "Y",
peg$c26 = peg$literalExpectation("Y", false),
peg$c27 = function(symbol) { return symbol },
peg$c28 = "X",
peg$c29 = peg$literalExpectation("X", false),
peg$c30 = "Z",
peg$c31 = peg$literalExpectation("Z", false),
peg$c32 = function(symbol, ind) {
peg$c27 = function(left) {
return { left };
},
peg$c28 = "Y",
peg$c29 = peg$literalExpectation("Y", false),
peg$c30 = function(symbol) { return symbol },
peg$c31 = "X",
peg$c32 = peg$literalExpectation("X", false),
peg$c33 = "Z",
peg$c34 = peg$literalExpectation("Z", false),
peg$c35 = function(symbol, ind) {
return symbol + ind;
},
peg$c33 = "+",
peg$c34 = peg$literalExpectation("+", false),
peg$c35 = "-",
peg$c36 = peg$literalExpectation("-", false),
peg$c37 = /^[A-E]/,
peg$c38 = peg$classExpectation([["A", "E"]], false, false),
peg$c39 = peg$otherExpectation("integer"),
peg$c40 = /^[0-9]/,
peg$c41 = peg$classExpectation([["0", "9"]], false, false),
peg$c42 = function() { return parseInt(text(), 10); },
peg$c43 = peg$otherExpectation("whitespace"),
peg$c44 = /^[ \t\n\r]/,
peg$c45 = peg$classExpectation([" ", "\t", "\n", "\r"], false, false),
peg$c46 = function() { },
peg$c36 = "GOTO",
peg$c37 = peg$literalExpectation("GOTO", false),
peg$c38 = "+",
peg$c39 = peg$literalExpectation("+", false),
peg$c40 = "-",
peg$c41 = peg$literalExpectation("-", false),
peg$c42 = /^[A-E]/,
peg$c43 = peg$classExpectation([["A", "E"]], false, false),
peg$c44 = "E",
peg$c45 = peg$literalExpectation("E", false),
peg$c46 = peg$otherExpectation("integer"),
peg$c47 = /^[0-9]/,
peg$c48 = peg$classExpectation([["0", "9"]], false, false),
peg$c49 = function() { return parseInt(text(), 10); },
peg$c50 = peg$otherExpectation("whitespace"),
peg$c51 = /^[ \t]/,
peg$c52 = peg$classExpectation([" ", "\t"], false, false),
peg$c53 = function() { },
peg$currPos = 0,
peg$savedPos = 0,
@ -350,13 +361,37 @@ module.exports = /*
s0 = peg$currPos;
s1 = [];
s2 = peg$parseLine();
if (s2 === peg$FAILED) {
s2 = peg$parse_();
if (s2 === peg$FAILED) {
if (peg$c0.test(input.charAt(peg$currPos))) {
s2 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s2 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c1); }
}
}
}
while (s2 !== peg$FAILED) {
s1.push(s2);
s2 = peg$parseLine();
if (s2 === peg$FAILED) {
s2 = peg$parse_();
if (s2 === peg$FAILED) {
if (peg$c0.test(input.charAt(peg$currPos))) {
s2 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s2 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c1); }
}
}
}
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c0(s1);
s1 = peg$c2(s1);
}
s0 = s1;
@ -364,19 +399,46 @@ module.exports = /*
}
function peg$parseLine() {
var s0, s1, s2;
var s0, s1, s2, s3, s4;
s0 = peg$currPos;
s1 = peg$parseLabeledInstruction();
s1 = peg$parse_();
if (s1 === peg$FAILED) {
s1 = peg$parseInstruction();
s1 = null;
}
if (s1 !== peg$FAILED) {
s2 = peg$parse_();
s2 = peg$parseLabeledInstruction();
if (s2 === peg$FAILED) {
s2 = peg$parseInstruction();
}
if (s2 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c1(s1);
s0 = s1;
s3 = peg$parse_();
if (s3 === peg$FAILED) {
s3 = null;
}
if (s3 !== peg$FAILED) {
if (peg$c0.test(input.charAt(peg$currPos))) {
s4 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s4 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c1); }
}
if (s4 === peg$FAILED) {
s4 = null;
}
if (s4 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c3(s2);
s0 = s1;
} else {
peg$currPos = s0;
s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
s0 = peg$FAILED;
@ -400,7 +462,7 @@ module.exports = /*
s3 = peg$parseInstruction();
if (s3 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c2(s1, s3);
s1 = peg$c4(s1, s3);
s0 = s1;
} else {
peg$currPos = s0;
@ -423,11 +485,11 @@ module.exports = /*
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 91) {
s1 = peg$c3;
s1 = peg$c5;
peg$currPos++;
} else {
s1 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c4); }
if (peg$silentFails === 0) { peg$fail(peg$c6); }
}
if (s1 !== peg$FAILED) {
s2 = peg$parse_();
@ -443,15 +505,15 @@ module.exports = /*
}
if (s4 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 93) {
s5 = peg$c5;
s5 = peg$c7;
peg$currPos++;
} else {
s5 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c6); }
if (peg$silentFails === 0) { peg$fail(peg$c8); }
}
if (s5 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c7(s3);
s1 = peg$c9(s3);
s0 = s1;
} else {
peg$currPos = s0;
@ -484,7 +546,7 @@ module.exports = /*
s1 = peg$parseConditional();
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c8(s1);
s1 = peg$c10(s1);
}
s0 = s1;
if (s0 === peg$FAILED) {
@ -492,24 +554,62 @@ module.exports = /*
s1 = peg$parseAssignment();
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c9(s1);
s1 = peg$c11(s1);
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
s1 = peg$parseGoto();
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c12(s1);
}
s0 = s1;
}
}
return s0;
}
function peg$parseGoto() {
var s0, s1, s2, s3;
s0 = peg$currPos;
s1 = peg$parseGOTO();
if (s1 !== peg$FAILED) {
s2 = peg$parse_();
if (s2 !== peg$FAILED) {
s3 = peg$parseLABEL_V();
if (s3 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c13(s3);
s0 = s1;
} else {
peg$currPos = s0;
s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
s0 = peg$FAILED;
}
return s0;
}
function peg$parseConditional() {
var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11;
var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
s0 = peg$currPos;
if (input.substr(peg$currPos, 2) === peg$c10) {
s1 = peg$c10;
if (input.substr(peg$currPos, 2) === peg$c14) {
s1 = peg$c14;
peg$currPos += 2;
} else {
s1 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c11); }
if (peg$silentFails === 0) { peg$fail(peg$c15); }
}
if (s1 !== peg$FAILED) {
s2 = peg$parse_();
@ -517,50 +617,38 @@ module.exports = /*
s3 = peg$parseVAR();
if (s3 !== peg$FAILED) {
s4 = peg$parse_();
if (s4 === peg$FAILED) {
s4 = null;
}
if (s4 !== peg$FAILED) {
if (input.substr(peg$currPos, 2) === peg$c12) {
s5 = peg$c12;
if (input.substr(peg$currPos, 2) === peg$c16) {
s5 = peg$c16;
peg$currPos += 2;
} else {
s5 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c13); }
if (peg$silentFails === 0) { peg$fail(peg$c17); }
}
if (s5 !== peg$FAILED) {
s6 = peg$parse_();
if (s6 === peg$FAILED) {
s6 = null;
}
if (s6 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 48) {
s7 = peg$c14;
s7 = peg$c18;
peg$currPos++;
} else {
s7 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c15); }
if (peg$silentFails === 0) { peg$fail(peg$c19); }
}
if (s7 !== peg$FAILED) {
s8 = peg$parse_();
if (s8 !== peg$FAILED) {
if (input.substr(peg$currPos, 4) === peg$c16) {
s9 = peg$c16;
peg$currPos += 4;
} else {
s9 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c17); }
}
s9 = peg$parseGoto();
if (s9 !== peg$FAILED) {
s10 = peg$parse_();
if (s10 !== peg$FAILED) {
s11 = peg$parseLabel();
if (s11 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c18(s3, s11);
s0 = s1;
} else {
peg$currPos = s0;
s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
s0 = peg$FAILED;
}
peg$savedPos = s0;
s1 = peg$c20(s3, s9);
s0 = s1;
} else {
peg$currPos = s0;
s0 = peg$FAILED;
@ -609,12 +697,12 @@ module.exports = /*
if (s1 !== peg$FAILED) {
s2 = peg$parse_();
if (s2 !== peg$FAILED) {
if (input.substr(peg$currPos, 2) === peg$c19) {
s3 = peg$c19;
if (input.substr(peg$currPos, 2) === peg$c21) {
s3 = peg$c21;
peg$currPos += 2;
} else {
s3 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c20); }
if (peg$silentFails === 0) { peg$fail(peg$c22); }
}
if (s3 !== peg$FAILED) {
s4 = peg$parse_();
@ -622,7 +710,7 @@ module.exports = /*
s5 = peg$parseExpression();
if (s5 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c21(s1, s5);
s1 = peg$c23(s1, s5);
s0 = s1;
} else {
peg$currPos = s0;
@ -661,15 +749,15 @@ module.exports = /*
s4 = peg$parse_();
if (s4 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 49) {
s5 = peg$c22;
s5 = peg$c24;
peg$currPos++;
} else {
s5 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c23); }
if (peg$silentFails === 0) { peg$fail(peg$c25); }
}
if (s5 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c24(s1, s3);
s1 = peg$c26(s1, s3);
s0 = s1;
} else {
peg$currPos = s0;
@ -691,6 +779,15 @@ module.exports = /*
peg$currPos = s0;
s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
s1 = peg$parseVAR();
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c27(s1);
}
s0 = s1;
}
return s0;
}
@ -700,33 +797,33 @@ module.exports = /*
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 89) {
s1 = peg$c25;
s1 = peg$c28;
peg$currPos++;
} else {
s1 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c26); }
if (peg$silentFails === 0) { peg$fail(peg$c29); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c27(s1);
s1 = peg$c30(s1);
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 88) {
s1 = peg$c28;
s1 = peg$c31;
peg$currPos++;
} else {
s1 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c29); }
if (peg$silentFails === 0) { peg$fail(peg$c32); }
}
if (s1 === peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 90) {
s1 = peg$c30;
s1 = peg$c33;
peg$currPos++;
} else {
s1 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c31); }
if (peg$silentFails === 0) { peg$fail(peg$c34); }
}
}
if (s1 !== peg$FAILED) {
@ -742,7 +839,7 @@ module.exports = /*
}
if (s2 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c32(s1, s2);
s1 = peg$c35(s1, s2);
s0 = s1;
} else {
peg$currPos = s0;
@ -757,23 +854,37 @@ module.exports = /*
return s0;
}
function peg$parseGOTO() {
var s0;
if (input.substr(peg$currPos, 4) === peg$c36) {
s0 = peg$c36;
peg$currPos += 4;
} else {
s0 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c37); }
}
return s0;
}
function peg$parseOPERATION() {
var s0;
if (input.charCodeAt(peg$currPos) === 43) {
s0 = peg$c33;
s0 = peg$c38;
peg$currPos++;
} else {
s0 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c34); }
if (peg$silentFails === 0) { peg$fail(peg$c39); }
}
if (s0 === peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 45) {
s0 = peg$c35;
s0 = peg$c40;
peg$currPos++;
} else {
s0 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c36); }
if (peg$silentFails === 0) { peg$fail(peg$c41); }
}
}
@ -784,85 +895,99 @@ module.exports = /*
var s0, s1, s2, s3;
s0 = peg$currPos;
if (peg$c37.test(input.charAt(peg$currPos))) {
s1 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s1 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c38); }
}
s1 = peg$parseEND_LABEL();
if (s1 !== peg$FAILED) {
s2 = [];
s3 = peg$parseInteger();
if (s3 !== peg$FAILED) {
while (s3 !== peg$FAILED) {
s2.push(s3);
s3 = peg$parseInteger();
}
peg$savedPos = s0;
s1 = peg$c30(s1);
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
if (peg$c42.test(input.charAt(peg$currPos))) {
s1 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s2 = peg$FAILED;
s1 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c43); }
}
if (s2 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c32(s1, s2);
s0 = s1;
if (s1 !== peg$FAILED) {
s2 = [];
s3 = peg$parseInteger();
if (s3 !== peg$FAILED) {
while (s3 !== peg$FAILED) {
s2.push(s3);
s3 = peg$parseInteger();
}
} else {
s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c35(s1, s2);
s0 = s1;
} else {
peg$currPos = s0;
s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
s0 = peg$FAILED;
}
}
return s0;
}
function peg$parseEND_LABEL() {
var s0;
if (input.charCodeAt(peg$currPos) === 69) {
s0 = peg$c44;
peg$currPos++;
} else {
peg$currPos = s0;
s0 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c45); }
}
return s0;
}
function peg$parseInteger() {
var s0, s1, s2, s3;
var s0, s1, s2;
peg$silentFails++;
s0 = peg$currPos;
s1 = peg$parse_();
if (s1 !== peg$FAILED) {
s2 = [];
if (peg$c40.test(input.charAt(peg$currPos))) {
s3 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s3 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c41); }
}
if (s3 !== peg$FAILED) {
while (s3 !== peg$FAILED) {
s2.push(s3);
if (peg$c40.test(input.charAt(peg$currPos))) {
s3 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s3 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c41); }
}
s1 = [];
if (peg$c47.test(input.charAt(peg$currPos))) {
s2 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s2 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c48); }
}
if (s2 !== peg$FAILED) {
while (s2 !== peg$FAILED) {
s1.push(s2);
if (peg$c47.test(input.charAt(peg$currPos))) {
s2 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s2 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c48); }
}
} else {
s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c42();
s0 = s1;
} else {
peg$currPos = s0;
s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
s0 = peg$FAILED;
s1 = peg$FAILED;
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c49();
}
s0 = s1;
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c39); }
if (peg$silentFails === 0) { peg$fail(peg$c46); }
}
return s0;
@ -874,32 +999,36 @@ module.exports = /*
peg$silentFails++;
s0 = peg$currPos;
s1 = [];
if (peg$c44.test(input.charAt(peg$currPos))) {
if (peg$c51.test(input.charAt(peg$currPos))) {
s2 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s2 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c45); }
if (peg$silentFails === 0) { peg$fail(peg$c52); }
}
while (s2 !== peg$FAILED) {
s1.push(s2);
if (peg$c44.test(input.charAt(peg$currPos))) {
s2 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s2 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c45); }
if (s2 !== peg$FAILED) {
while (s2 !== peg$FAILED) {
s1.push(s2);
if (peg$c51.test(input.charAt(peg$currPos))) {
s2 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s2 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c52); }
}
}
} else {
s1 = peg$FAILED;
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c46();
s1 = peg$c53();
}
s0 = s1;
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c43); }
if (peg$silentFails === 0) { peg$fail(peg$c50); }
}
return s0;