From a1486b4f97e8cf8d457bec936879d70b3b92587f Mon Sep 17 00:00:00 2001 From: Bobby Bingham Date: Sat, 14 Jan 2017 15:55:57 -0600 Subject: nqasm: Handle immediate arguments --- lexer.l | 14 ++++++++++++++ parser.y | 33 +++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/lexer.l b/lexer.l index f3a540c..85021c5 100644 --- a/lexer.l +++ b/lexer.l @@ -1,9 +1,19 @@ %{ +#include +#include + #include "parser.h" #define SETVALUE(v) yylval.arg = (struct argument) { .value = (v) } +static int intlit(const char *s, int base, long *out) +{ + errno = 0; + *out = strtol(s, NULL, base); + return errno == ERANGE ? T_BADINT : T_INT; +} + %} %option outfile="lexer.c" header-file="lexer.h" @@ -16,6 +26,8 @@ COMMENT #[^\n]* SP [ \t] EOI [ \t\n#] REGNUM [0-7] +DEC [0-9] +HEX [0-9a-f] %% @@ -59,6 +71,8 @@ REGNUM [0-7] r{REGNUM} { SETVALUE(yytext[1]-'0'); return T_REG; } @r{REGNUM} { SETVALUE(yytext[2]-'0'); return T_REGPTR; } +[-+]?{DEC}+ { return intlit(yytext, 10, &yylval.lval); } +0x{HEX}+ { return intlit(yytext+2, 16, &yylval.lval); } {SP}*,{SP}* { return T_COMMA; } {SP}*{COMMENT}?\n { BEGIN(INITIAL); return T_EOL; } 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 T_INT +%token T_BADINT + %token T_REG %token T_REGPTR %token T_COMMA "," %type inst +%type imm %type reg2 %type reg3 %type regp %type regp_reg %type reg_regp +%type reg_imm +%type 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 -- cgit v1.2.3