summaryrefslogtreecommitdiff
path: root/nqasm.c
diff options
context:
space:
mode:
authorBobby Bingham <koorogi@koorogi.info>2017-01-18 19:40:18 -0600
committerBobby Bingham <koorogi@koorogi.info>2017-01-18 19:40:18 -0600
commit6c6b91f9a6bc5ae203e99ac7abb3a70215488a6f (patch)
treea60ee21b204363128001cf323e5914745a630afd /nqasm.c
parent1e0d0202e614f398f491624c84ae9a8309fa2f96 (diff)
nqasm: support unary operators in immediate expressions
Diffstat (limited to 'nqasm.c')
-rw-r--r--nqasm.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/nqasm.c b/nqasm.c
index ee3010a..49b4ec6 100644
--- a/nqasm.c
+++ b/nqasm.c
@@ -56,12 +56,27 @@ void add_instruction(const struct instruction *inst)
addr += 2;
}
+struct argument *argdup(const struct argument *arg)
+{
+ struct argument *ret = malloc(sizeof *ret);
+ if (!ret) {
+ fprintf(stderr, "unable to allocate argument\n");
+ exit(1);
+ }
+ *ret = *arg;
+ return ret;
+}
+
static long eval_argument(const struct argument *arg, uint16_t pc)
{
struct label *l;
switch (arg->type) {
- case ARG_INTEGER: return arg->value;
- case ARG_PC: return pc;
+ case ARG_INTEGER: return arg->value;
+ case ARG_PC: return pc;
+ case ARG_UNARY_ADD: return eval_argument(arg->children[0], pc);
+ case ARG_UNARY_SUB: return -eval_argument(arg->children[0], 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_LABEL:
l = vector_search(&labels->v, &(struct label) { .name = arg->label }, cmp_label);