diff options
-rw-r--r-- | lexer.l | 4 | ||||
-rw-r--r-- | nqasm.c | 5 | ||||
-rw-r--r-- | nqasm.h | 7 | ||||
-rw-r--r-- | parser.y | 29 |
4 files changed, 36 insertions, 9 deletions
@@ -78,8 +78,12 @@ HEX [0-9a-f] <args>@ { return T_DEREF; } <args>\+ { return T_OPERATOR_ADD; } <args>- { return T_OPERATOR_SUB; } +<args>\* { return T_OPERATOR_MUL; } +<args>\/ { return T_OPERATOR_DIV; } <args>! { return T_OPERATOR_NOT; } <args>~ { return T_OPERATOR_INV; } +<args>\( { return T_LPAREN; } +<args>\) { return T_RPAREN; } <args>{DEC}+ { return intlit(yytext, 10, &yylval.lval); } <args>0x{HEX}+ { return intlit(yytext+2, 16, &yylval.lval); } <args>{SP}*,{SP}* { return T_COMMA; } @@ -78,6 +78,11 @@ static long eval_argument(const struct argument *arg, uint16_t pc) case ARG_UNARY_NOT: return !eval_argument(arg->children[0], pc); case ARG_UNARY_INV: return ~eval_argument(arg->children[0], pc); + case ARG_ADD: return eval_argument(arg->children[0], pc) + eval_argument(arg->children[1], pc); + case ARG_SUB: return eval_argument(arg->children[0], pc) - eval_argument(arg->children[1], pc); + case ARG_MUL: return eval_argument(arg->children[0], pc) * eval_argument(arg->children[1], pc); + case ARG_DIV: return eval_argument(arg->children[0], pc) / eval_argument(arg->children[1], pc); + case ARG_LABEL: l = vector_search(&labels->v, &(struct label) { .name = arg->label }, cmp_label); if (l) return l->addr; @@ -10,6 +10,11 @@ enum { ARG_UNARY_SUB, ARG_UNARY_NOT, ARG_UNARY_INV, + + ARG_ADD, + ARG_SUB, + ARG_MUL, + ARG_DIV, }; struct argument { @@ -17,7 +22,7 @@ struct argument { union { long value; char *label; - const struct argument *children[1]; + const struct argument *children[2]; }; }; @@ -16,7 +16,7 @@ void yyerror(const char *msg) #define MKARGVALUE(v) (struct argument) { .type = ARG_INTEGER, .value = (v) } #define MKARGLABEL(l) (struct argument) { .type = ARG_LABEL, .label = (l) } #define MKARGTYPE(t) (struct argument) { .type = (t) } -#define MKARGEXPR(op,c) (struct argument) { .type = (op), .children = c } +#define MKARGEXPR(op,...) (struct argument) { .type = (op), .children = { __VA_ARGS__ } } %} @@ -87,8 +87,16 @@ void yyerror(const char *msg) %token T_OPERATOR_ADD "+" %token T_OPERATOR_SUB "-" +%token T_OPERATOR_MUL "*" +%token T_OPERATOR_DIV "/" %token T_OPERATOR_NOT "!" %token T_OPERATOR_INV "~" +%token T_LPAREN "(" +%token T_RPAREN ")" + +%left "-" "+" +%left "*" "/" +%precedence NEG %type <inst> inst %type <arg> reg @@ -184,13 +192,18 @@ reg: T_LABEL { } expr: - intlit { $$ = MKARGVALUE($1); } - | T_LABEL { $$ = MKARGLABEL($1); } - | "." { $$ = MKARGTYPE(ARG_PC); } - | "+" expr { $$ = MKARGEXPR(ARG_UNARY_ADD, { argdup(&$2) }); } - | "-" expr { $$ = MKARGEXPR(ARG_UNARY_SUB, { argdup(&$2) }); } - | "!" expr { $$ = MKARGEXPR(ARG_UNARY_NOT, { argdup(&$2) }); } - | "~" expr { $$ = MKARGEXPR(ARG_UNARY_INV, { argdup(&$2) }); } + intlit { $$ = MKARGVALUE($1); } + | T_LABEL { $$ = MKARGLABEL($1); } + | "." { $$ = MKARGTYPE(ARG_PC); } + | "+" expr %prec NEG { $$ = MKARGEXPR(ARG_UNARY_ADD, argdup(&$2)); } + | "-" expr %prec NEG { $$ = MKARGEXPR(ARG_UNARY_SUB, argdup(&$2)); } + | "!" expr %prec NEG { $$ = MKARGEXPR(ARG_UNARY_NOT, argdup(&$2)); } + | "~" expr %prec NEG { $$ = MKARGEXPR(ARG_UNARY_INV, argdup(&$2)); } + | expr "+" expr { $$ = MKARGEXPR(ARG_ADD, argdup(&$1), argdup(&$3)); } + | expr "-" expr { $$ = MKARGEXPR(ARG_SUB, argdup(&$1), argdup(&$3)); } + | expr "*" expr { $$ = MKARGEXPR(ARG_MUL, argdup(&$1), argdup(&$3)); } + | expr "/" expr { $$ = MKARGEXPR(ARG_DIV, argdup(&$1), argdup(&$3)); } + | "(" expr ")" { $$ = $2; } ; intlit: T_INT |