nand2tetris/compiler/backend/lib/parser.mly
2024-09-20 14:20:09 -04:00

91 lines
2.9 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 EOF
%start <Ast.expr> prog
%%
prog:
| e = expr; EOF { e }
;
expr:
| e = arithmetic { e }
| e = memoryaccess { e }
| e = programflow { e }
| e = functioncall { 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 }
;
memoryaccess:
| POP; e = pop { e }
| PUSH; e = push { e }
;
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) }
;
programflow:
| LABEL; i = ID { ProgramFlowCommand (Label, i) }
| GOTO; i = ID { ProgramFlowCommand (Goto, i) }
| IFGOTO; i = ID { ProgramFlowCommand (Ifgoto, i) }
;
functioncall:
| FUNCTION; i = ID; a = ADDRESS { FunctionCallCommand (Function, i, a) }
| CALL; i = ID; a = ADDRESS { FunctionCallCommand (Call, i, a) }
| RETURN { Return }
;