diff options
author | Bobby Bingham <koorogi@koorogi.info> | 2017-01-18 19:10:20 -0600 |
---|---|---|
committer | Bobby Bingham <koorogi@koorogi.info> | 2017-01-18 19:10:20 -0600 |
commit | 6ee196e6800099d52776bb16f84f26525586958f (patch) | |
tree | 7e48b6b771b8a5edddc7ce2c37b4cc9f728a2a26 | |
parent | 619c5cc4ab4bd94f9b270a9868bb5f08ffd76acb (diff) |
nqasm: lex registers as if they were labels
This makes parsing registers trickier, but allows a label to have a name
'r0'-'r7', which would otherwise conflict with the registers.
-rw-r--r-- | lexer.l | 6 | ||||
-rw-r--r-- | parser.y | 36 |
2 files changed, 29 insertions, 13 deletions
@@ -35,7 +35,7 @@ HEX [0-9a-f] %% <INITIAL>{SP}+ { BEGIN(inst); return T_SPACE; } -<INITIAL>{LABEL} { SETSTR(yytext); return T_LABEL; } +<INITIAL,args>{LABEL} { SETSTR(yytext); return T_LABEL; } <INITIAL>:{SP}* { BEGIN(inst); return T_COLON; } <inst>add/{EOI} { BEGIN(args); return T_ADD; } @@ -74,12 +74,10 @@ HEX [0-9a-f] <inst>addpc/{EOI} { BEGIN(args); return T_ADDPC; } <inst>nop/{EOI} { BEGIN(args); return T_NOP; } -<args>r{REGNUM} { SETVALUE(yytext[1]-'0'); return T_REG; } -<args>@r{REGNUM} { SETVALUE(yytext[2]-'0'); return T_REGPTR; } +<args>@ { return T_DEREF; } <args>[-+]?{DEC}+ { return intlit(yytext, 10, &yylval.lval); } <args>0x{HEX}+ { return intlit(yytext+2, 16, &yylval.lval); } <args>{SP}*,{SP}* { return T_COMMA; } -<args>{LABEL} { SETSTR(yytext); return T_LABEL; } {SP}*{COMMENT}?\n { BEGIN(INITIAL); return T_EOL; } {SP}*{COMMENT} { BEGIN(INITIAL); return T_EOL; } @@ -78,13 +78,13 @@ void yyerror(const char *msg) %token <lval> T_INT %token T_BADINT -%token <arg> T_REG -%token <arg> T_REGPTR - %token T_COMMA "," %token T_COLON ":" +%token T_DEREF "@" %type <inst> inst +%type <arg> reg +%type <arg> regp %type <arg> expr %type <args> a_reg2 %type <args> a_reg3 @@ -150,20 +150,38 @@ inst: ; a_reg2: - T_SPACE T_REG "," T_REG { $$ = MKARGS($2, $4); } + T_SPACE reg "," reg { $$ = MKARGS($2, $4); } a_reg3: - T_SPACE T_REG "," T_REG "," T_REG { $$ = MKARGS($2, $4, $6); } + T_SPACE reg "," reg "," reg { $$ = MKARGS($2, $4, $6); } a_regp: - T_SPACE T_REGPTR { $$ = MKARGS($2); } + T_SPACE regp { $$ = MKARGS($2); } a_regp_reg: - T_SPACE T_REGPTR "," T_REG { $$ = MKARGS($2, $4); } + T_SPACE regp "," reg { $$ = MKARGS($2, $4); } a_reg_regp: - T_SPACE T_REG "," T_REGPTR { $$ = MKARGS($2, $4); } + T_SPACE reg "," regp { $$ = MKARGS($2, $4); } a_reg_expr: - T_SPACE T_REG "," expr { $$ = MKARGS($2, $4); } + T_SPACE reg "," expr { $$ = MKARGS($2, $4); } a_expr: T_SPACE expr { $$ = MKARGS($2); } +regp: "@" reg { $$ = $2; } +reg: T_LABEL { + int bad = 0; + if ($1[0] != 'r' && $1[0] != 'R') + bad = 1; + else if (0 > $1[1] - '0' || $1[1] - '0' > 9) + bad = 1; + else if ($1[2]) + bad = 1; + + if (bad) { + yyerror("invalid register"); + YYERROR; + } else { + $$ = MKARGVALUE($1[1] - '0'); + } + } + expr: intlit { $$ = MKARGVALUE($1); } | T_LABEL { $$ = MKARGLABEL($1); } |