summaryrefslogtreecommitdiff
path: root/parser.y
diff options
context:
space:
mode:
authorBobby Bingham <koorogi@koorogi.info>2017-01-14 15:55:57 -0600
committerBobby Bingham <koorogi@koorogi.info>2017-01-15 23:19:11 -0600
commita1486b4f97e8cf8d457bec936879d70b3b92587f (patch)
tree83e2d1fcd2c848b9836ceac63b72b36817c31f94 /parser.y
parent50e67fb3e640a9e6e1260ca984582c9a9b8d5375 (diff)
nqasm: Handle immediate arguments
Diffstat (limited to 'parser.y')
-rw-r--r--parser.y33
1 files changed, 27 insertions, 6 deletions
diff --git a/parser.y b/parser.y
index 2177ae8..c953aa4 100644
--- a/parser.y
+++ b/parser.y
@@ -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