diff options
Diffstat (limited to 'src/parser/grammar.jison')
-rw-r--r-- | src/parser/grammar.jison | 97 |
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; } ; + + |