nand2tetris/compiler/backend/lib/parser.mly
Konarak b7dee58454
finish project eight backend compiler
- modify existing implementation to use variant types for a more
  accurate representation of the vm byte code
- switch to fold from recursion for the main translate function
- use separate modules for translating different vm commands
- move static arithmetic command translations to a map
2024-09-13 17:03:52 -04:00

93 lines
3.1 KiB
OCaml

%{
open Ast
%}
(* arithmetic and logical commands *)
%token ADD SUB EQ GT LT AND OR NEG NOT
(* memory commands *)
%token POP PUSH
(* memory segments *)
%token CONSTANT STATIC POINTER TEMP
ARGUMENT LOCAL THIS THAT
(* branching commands *)
%token LABEL GOTO IFGOTO
(* function commands*)
%token FUNCTION CALL RETURN
%token <int> ADDRESS
%token <string> ID
%token <string> COMMENT
%token EOF
%start <Ast.expr> prog
%%
prog:
| e = expr; EOF { e }
;
expr:
| c = COMMENT { Comment c }
| e = arithmetic { e }
| POP; p = pop { p }
| PUSH; p = push { p }
| b = branching { b }
| FUNCTION; f = function_definition { f }
| CALL; c = function_call { c }
| RETURN { Return }
| e = expr; COMMENT { e }
;
arithmetic:
| ADD { ArithmeticCommand Add }
| SUB { ArithmeticCommand Sub }
| EQ { ArithmeticCommand Eq }
| GT { ArithmeticCommand Gt }
| LT { ArithmeticCommand Lt }
| AND { ArithmeticCommand And }
| OR { ArithmeticCommand Or }
| NEG { ArithmeticCommand Neg }
| NOT { ArithmeticCommand Not }
;
pop:
| ARGUMENT; a = ADDRESS { MemoryAccessCommand (Pop, Argument, a) }
| LOCAL; a = ADDRESS { MemoryAccessCommand (Pop, Local, a) }
| STATIC; a = ADDRESS { MemoryAccessCommand (Pop, Static, a) }
| THIS; a = ADDRESS { MemoryAccessCommand (Pop, This, a) }
| THAT; a = ADDRESS { MemoryAccessCommand (Pop, That, a) }
| POINTER; a = ADDRESS { MemoryAccessCommand (Pop, Pointer, a) }
| TEMP; a = ADDRESS { MemoryAccessCommand (Pop, Temp, a) }
;
push:
| ARGUMENT; a = ADDRESS { MemoryAccessCommand (Push, Argument, a) }
| LOCAL; a = ADDRESS { MemoryAccessCommand (Push, Local, a) }
| STATIC; a = ADDRESS { MemoryAccessCommand (Push, Static, a) }
| THIS; a = ADDRESS { MemoryAccessCommand (Push, This, a) }
| THAT; a = ADDRESS { MemoryAccessCommand (Push, That, a) }
| POINTER; a = ADDRESS { MemoryAccessCommand (Push, Pointer, a) }
| TEMP; a = ADDRESS { MemoryAccessCommand (Push, Temp, a) }
| CONSTANT; a = ADDRESS { MemoryAccessCommand (Push, Constant, a) }
;
branching:
| LABEL; i = ID { ProgramFlowCommand (Label, i) }
| GOTO; i = ID { ProgramFlowCommand (Goto, i) }
| IFGOTO; i = ID { ProgramFlowCommand (Ifgoto, i) }
;
function_definition:
| i = ID; a = ADDRESS { FunctionCallCommand (Function, i, a) }
;
function_call:
| i = ID; a = ADDRESS { FunctionCallCommand (Call, i, a) }
;