nooc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/nooc
Log | Files | Refs | LICENSE

commit dcdf77176b840cf4bea9974a51614bfdaf888a87
parent 55c2f96d993d3f08226d66b284fa6cc92b0130ec
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Tue, 23 Nov 2021 18:36:22 -0600

subtraction

Diffstat:
Mmain.c | 23+++++++++++++++++++++++
Mnooc.h | 2++
Mprog.nc | 2+-
Mx64.c | 14++++++++++++++
Mx64.h | 1+
5 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/main.c b/main.c @@ -75,6 +75,10 @@ lex(struct slice start) cur->type = TOK_PLUS; start.ptr++; start.len--; + } else if (*start.ptr == '-') { + cur->type = TOK_MINUS; + start.ptr++; + start.len--; } else if (*start.ptr == '=') { cur->type = TOK_EQUAL; start.ptr++; @@ -184,6 +188,9 @@ dumpbinop(enum binop op) case OP_PLUS: fprintf(stderr, "OP_PLUS"); break; + case OP_MINUS: + fprintf(stderr, "OP_MINUS"); + break; default: error("invalid binop"); } @@ -238,6 +245,13 @@ parseexpr(struct token **tok) expr.left = parseexpr(tok); expr.right = parseexpr(tok); break; + case TOK_MINUS: + expr.kind = EXPR_BINARY; + expr.d.op = OP_MINUS; + *tok = (*tok)->next; + expr.left = parseexpr(tok); + expr.right = parseexpr(tok); + break; case TOK_STRING: expr.kind = EXPR_LIT; expr.d.v.type = P_STR; @@ -330,6 +344,15 @@ genexpr(char *buf, size_t idx, enum reg reg) freereg(rreg); break; } + case OP_MINUS: { + len += genexpr(ptr ? ptr + len : ptr, expr->left, reg); + enum reg rreg = getreg(); + len += genexpr(ptr ? ptr + len : ptr, expr->right, rreg); + + len += sub_r64_r64(ptr ? ptr + len : ptr, reg, rreg); + freereg(rreg); + break; + } default: error("genexpr: unknown binary op!"); } diff --git a/nooc.h b/nooc.h @@ -8,6 +8,7 @@ enum tokentype { TOK_RPAREN, TOK_PLUS, + TOK_MINUS, TOK_COMMA, TOK_EQUAL, @@ -80,6 +81,7 @@ enum primitive { enum binop { OP_PLUS, + OP_MINUS, }; struct value { diff --git a/prog.nc b/prog.nc @@ -3,6 +3,6 @@ stdout = 0 exit = 60 len1 = 11 len2 = 6 -syscall(write, + + 0 1 + 0 1, "hello world", + 1 + 2 + 3 + 4 1) +syscall(write, - 2 1, "hello world", + 1 + 2 + 3 + 4 1) syscall(write, stdout, " world", len2) syscall(exit, 0) diff --git a/x64.c b/x64.c @@ -103,3 +103,17 @@ add_r64_r64(char *buf, enum reg reg1, enum reg reg2) return 3; } + +size_t +sub_r64_r64(char *buf, enum reg reg1, enum reg reg2) +{ + uint8_t mov[] = {0x48, 0x29}; + uint8_t op = (MOD_DIRECT << 6) | (reg1 << 3) | reg2; + if (buf) { + memcpy(buf, mov, 2); + buf += 2; + *(buf++) = op; + } + + return 3; +} diff --git a/x64.h b/x64.h @@ -35,3 +35,4 @@ size_t add_r_imm(char *buf, enum reg reg, uint64_t imm); size_t mov_r_imm(char *buf, enum reg reg, uint64_t imm); size_t mov_r64_m64(char *buf, enum reg reg, uint64_t addr); size_t add_r64_r64(char *buf, enum reg reg1, enum reg reg2); +size_t sub_r64_r64(char *buf, enum reg reg1, enum reg reg2);