diff options
Diffstat (limited to 'parser.y')
-rw-r--r-- | parser.y | 33 |
1 files changed, 27 insertions, 6 deletions
@@ -13,6 +13,7 @@ void yyerror(const char *msg) #define INSTRUCTION_ARGS(m,a) (struct instruction) { MNEM_ ## m, a } #define INSTRUCTION(m) (struct instruction) { MNEM_ ## m } #define MKARGS(...) (struct arguments) { __VA_ARGS__ } +#define MKARGVALUE(v) (struct argument) { (v) } %} @@ -27,6 +28,7 @@ void yyerror(const char *msg) struct instruction inst; struct arguments args; struct argument arg; + long lval; } %token END 0 "end of file" @@ -70,16 +72,22 @@ void yyerror(const char *msg) %token T_ADDPC %token T_NOP +%token <lval> T_INT +%token T_BADINT + %token <arg> T_REG %token <arg> T_REGPTR %token T_COMMA "," %type <inst> inst +%type <arg> imm %type <args> reg2 %type <args> reg3 %type <args> regp %type <args> regp_reg %type <args> reg_regp +%type <args> reg_imm +%type <lval> intlit %% @@ -115,10 +123,8 @@ inst: T_ADD reg3 { $$ = INSTRUCTION_ARGS(ADD, $2); } | T_LD_BL reg_regp { $$ = INSTRUCTION_ARGS(LD_BL, $2); } | T_LD_BH reg_regp { $$ = INSTRUCTION_ARGS(LD_BH, $2); } | T_LD_W reg_regp { $$ = INSTRUCTION_ARGS(LD_W, $2); } - | T_LDI_BL - { $$ = INSTRUCTION(LDI_BL); } - | T_LDI_BH - { $$ = INSTRUCTION(LDI_BH); } + | T_LDI_BL reg_imm { $$ = INSTRUCTION_ARGS(LDI_BL, $2); } + | T_LDI_BH reg_imm { $$ = INSTRUCTION_ARGS(LDI_BH, $2); } | T_BEQ { $$ = INSTRUCTION(BEQ); } | T_BNE @@ -134,8 +140,7 @@ inst: T_ADD reg3 { $$ = INSTRUCTION_ARGS(ADD, $2); } | T_BRA { $$ = INSTRUCTION(BRA); } | T_JMP regp { $$ = INSTRUCTION_ARGS(JMP, $2); } - | T_ADDPC - { $$ = INSTRUCTION(ADDPC); } + | T_ADDPC reg_imm { $$ = INSTRUCTION_ARGS(ADDPC, $2); } | T_NOP { $$ = INSTRUCTION(NOP); } ; @@ -145,6 +150,22 @@ reg3: T_SPACE T_REG "," T_REG "," T_REG { $$ = MKARGS($2, $4, $6); } regp: T_SPACE T_REGPTR { $$ = MKARGS($2); } regp_reg: T_SPACE T_REGPTR "," T_REG { $$ = MKARGS($2, $4); } reg_regp: T_SPACE T_REG "," T_REGPTR { $$ = MKARGS($2, $4); } +reg_imm: T_SPACE T_REG "," imm { $$ = MKARGS($2, $4); } + +imm: intlit { + if (-0x80 > $1 || $1 > 0xff) { + yyerror("immediate operand out of range"); + YYERROR; + } else { + $$ = MKARGVALUE((uint8_t) $1); + } + } + +intlit: T_INT + | T_BADINT { + yyerror("integer literal out of range"); + YYERROR; + } eol: T_EOL | T_SPACE T_EOL |