summaryrefslogtreecommitdiff
path: root/src/parser/grammar.jison
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/grammar.jison')
-rw-r--r--src/parser/grammar.jison97
1 files changed, 76 insertions, 21 deletions
diff --git a/src/parser/grammar.jison b/src/parser/grammar.jison
index 4a17d2b..ae8793b 100644
--- a/src/parser/grammar.jison
+++ b/src/parser/grammar.jison
@@ -1,15 +1,18 @@
%lex
+%s comment
+
%%
-";" { this.pushState('comment'); return "COMMENT"; }
+<<EOF>> { return "EOF"; }
<comment>"\n" { this.popState(); return "NEWLINE"; }
<comment>. { /* ignore anything else inside a comment */ }
+";" { this.pushState('comment'); }
-"\n" { return "NEWLINE"; }
-\s+ { /* ignore whitespace */ }
+[\n] { console.log("new!"); return "NEWLINE"; }
+\s { /* ignore whitespace */ }
-"MOV" { return "MOV"; }
+"MOV" { console.log("mov"); return "MOV"; }
"ADD" { return "ADD"; }
"SUB" { return "SUB"; }
"CMP" { return "CMP"; }
@@ -24,6 +27,7 @@
"EQU" { return "EQU"; }
"END" { return "END"; }
":" { return ":"; }
+"," { return ","; }
"#" { return "#"; }
"@" { return "@"; }
@@ -41,28 +45,73 @@
/lex
-%%
+%left '+' '-'
+%left '*' '/'
+%left UMINUS
+%%
program
- : lines { return $lines; }
+ : lines NEWLINE END coda { yy.start = 0; return $lines; }
+ | lines NEWLINE END label coda { yy.start = yy.getLabel($label); return $lines; }
;
+coda
+ : newlines EOF
+ | EOF
+ ;
+
+newlines
+ : newlines NEWLINE
+ | NEWLINE
+ ;
lines
- : lines line { $lines.push($line); $$ = $lines; }
- | line { $$ = [ $line ]; }
+ : lines line
+ {
+ if ($line !== null) {
+ $lines.push($line);
+ }
+ $$ = $lines;
+ }
+ | line
+ {
+ if ($line === null) {
+ $$ = [];
+ } else {
+ $$ = [ $line ];
+ }
+ }
;
line
- : op NEWLINE { $$ = $op; }
- | op EOF { $$ = $op; }
+ : row NEWLINE { $$ = $row; }
+ | NEWLINE { $$ = null; }
+ ;
+
+row
+ : op
+ {
+ yy.pc += 1;
+ $$ = $op;
+ }
+ | label ":" op
+ {
+ yy.setLabel($label, yy.pc);
+ yy.pc += 1;
+ $$ = $op;
+ }
+ | label EQU e
+ {
+ yy.setLabel($label, $e);
+ $$ = null;
+ }
;
op
- : opcode address address
+ : opcode address "," address
{ $$ = { opcode: $opcode, a: $address1, b: $address2 }; }
;
@@ -82,7 +131,7 @@ opcode
;
-address:
+address
: address_mode e { $$ = { mode: $1, value: $2 }; }
| e { $$ = { mode: 'direct', value: $1 }; }
;
@@ -90,22 +139,28 @@ address:
address_mode
: "#" { $$ = 'immediate'; }
- | "@" { $$ = 'indirect'; }
+ | "@" { $$ = 'indirect'; }
| "<" { $$ = 'predecrement'; }
| "$" { $$ = 'direct'; }
;
+
e
- : NUMBER { $$ = Math.floor(Number(yytext)); }
- | LABEL {
- $$ = yy.getLabel(yytext);
- if ($$ === null) {
- YYABORT;
- }
- }
- | e '+' e { $$ = Math.floor($e1 + $e2); }
+ : e '+' e { $$ = Math.floor($e1 + $e2); }
| e '-' e { $$ = Math.floor($e1 - $e2); }
| e '*' e { $$ = Math.floor($e1 * $e2); }
| e '/' e { $$ = Math.floor($e1 / $e2); }
| '(' e ')' { $$ = Math.floor($e); }
+ | '-' e %prec UMINUS { $$ = - $e; }
+ | NUMBER { $$ = Math.floor(Number(yytext)); }
+ | label {
+ $$ = yy.getLabel($label);
+ }
+ ;
+
+
+label
+ : LABEL { $$ = yytext; }
;
+
+