summaryrefslogtreecommitdiff
path: root/nqasm.c
diff options
context:
space:
mode:
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);