simponic.xyz/godel/grammar.peg

60 lines
1.3 KiB
Plaintext
Raw Normal View History

2023-11-16 21:06:35 -05:00
Program = lines: (Line / (_/[\n]))* {
return { instructions: lines.filter((line) => typeof line !== "string" || line.trim() != "") };
2023-11-16 16:56:56 -05:00
}
2023-11-16 21:06:35 -05:00
Line = _? instruction: (LabeledInstruction / Instruction) _? [\n]? {
2023-11-16 16:56:56 -05:00
return instruction;
}
LabeledInstruction = label:Label _ instruction:Instruction {
return { label, instruction };
}
Label = "[" _? label:LABEL_V _? "]" {
return label;
}
Instruction = conditional: Conditional { return { conditional }; }
/ assignment: Assignment { return { assignment }; }
2023-11-16 21:06:35 -05:00
/ goto: Goto { return { goto }; }
2023-11-16 16:56:56 -05:00
2023-11-16 21:06:35 -05:00
Goto = GOTO _ label: LABEL_V {
return { label };
}
Conditional = "IF" _ variable: VAR _? "!=" _? "0" _ goto: Goto {
return { variable, goto };
2023-11-16 16:56:56 -05:00
}
Assignment = variable: VAR _ "<-" _ expr: Expression {
if (expr.left != variable) {
error("left hand variable must match right hand");
}
return { variable, expr };
}
Expression = left: VAR _ opr: OPERATION _ "1" {
return { left, opr };
2023-11-16 21:06:35 -05:00
} / left: VAR {
return { left };
2023-11-16 16:56:56 -05:00
}
VAR = symbol:"Y" { return symbol } / symbol:("X" / "Z") ind:Integer+ {
return symbol + ind;
}
2023-11-16 21:06:35 -05:00
GOTO = "GOTO"
2023-11-16 16:56:56 -05:00
OPERATION = "+" / "-"
2023-11-16 21:06:35 -05:00
LABEL_V = symbol:END_LABEL { return symbol } / symbol:[A-E] ind:Integer+ {
2023-11-16 16:56:56 -05:00
return symbol + ind;
}
2023-11-16 21:06:35 -05:00
END_LABEL = "E"
2023-11-16 16:56:56 -05:00
Integer "integer"
2023-11-16 21:06:35 -05:00
= [0-9]+ { return parseInt(text(), 10); }
2023-11-16 16:56:56 -05:00
2023-11-16 21:06:35 -05:00
_ "whitespace" = [ \t]+ { }