nooc

nooc programming language compiler
git clone git://git.nihaljere.xyz/nooc
Log | Files | Refs | LICENSE

commit 2407feb102ed22a3b1dbb47ec814ef066bb09d03
parent ec7dafa82296ddd9c75a487dc7c94e5701f1bd12
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Sun, 26 Dec 2021 16:40:43 -0600

add equals boolean operator

tests can specify expected return values more precisely now

Diffstat:
Mmain.c | 7+++++++
Mnooc.h | 1+
Mparse.c | 4++++
Mtest/exitwrite.pass.nooc | 2+-
Mtest/global.pass.nooc | 2+-
Mtest/syscall_ret.pass.nooc | 2+-
Mx64.c | 17+++++++++++++++++
Mx64.h | 1+
8 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/main.c b/main.c @@ -298,6 +298,9 @@ dumpbinop(enum binop op) case OP_GREATER: fprintf(stderr, "OP_GREATER"); break; + case OP_EQUAL: + fprintf(stderr, "OP_EQUAL"); + break; default: die("invalid binop"); } @@ -510,6 +513,7 @@ genexpr(char *buf, size_t idx, struct place *out) total += sub_r64_r64(buf ? buf + total : buf, regbuf.l.reg, place2.l.reg); break; } + case OP_EQUAL: case OP_GREATER: { total += cmp_r64_r64(buf ? buf + total : buf, regbuf.l.reg, place2.l.reg); break; @@ -553,6 +557,9 @@ genexpr(char *buf, size_t idx, struct place *out) case OP_GREATER: total += jng(buf ? buf + total : NULL, iflen); break; + case OP_EQUAL: + total += jne(buf ? buf + total : NULL, iflen); + break; default: error(expr->start->line, expr->start->col, "unknown binop for conditional"); } diff --git a/nooc.h b/nooc.h @@ -185,6 +185,7 @@ enum binop { OP_PLUS, OP_MINUS, OP_GREATER, + OP_EQUAL, }; struct value { diff --git a/parse.c b/parse.c @@ -233,6 +233,10 @@ parseexpr(struct block *block) expr.d.v.v.i64 = strtol(tok->slice.data, NULL, 10); tok = tok->next; break; + case TOK_EQUAL: + expr.kind = EXPR_BINARY; + expr.d.op = OP_EQUAL; + goto binary_common; case TOK_GREATER: expr.kind = EXPR_BINARY; expr.d.op = OP_GREATER; diff --git a/test/exitwrite.pass.nooc b/test/exitwrite.pass.nooc @@ -11,7 +11,7 @@ let exit proc(i64) = proc(code i64) { let main proc() = proc() { let ret i64 = 0 ret = write(1, "hello\n", 6) - if > ret 0 { + if = ret 6 { exit(0) } else { exit(1) diff --git a/test/global.pass.nooc b/test/global.pass.nooc @@ -1,7 +1,7 @@ let a i32 = 10 let main proc() = proc() { - if > a 5 { + if = a 10 { syscall(60, 0) } else { syscall(60, 1) diff --git a/test/syscall_ret.pass.nooc b/test/syscall_ret.pass.nooc @@ -1,6 +1,6 @@ let main proc() = proc() { let ret i64 = syscall(1, 1, "syscall_ret", 11) - if > ret 0 { + if = ret 11 { syscall(60, 0) } else { syscall(60, 1) diff --git a/x64.c b/x64.c @@ -470,6 +470,23 @@ jg(char *buf, int64_t offset) } size_t +jne(char *buf, int64_t offset) +{ + if (-256 <= offset && offset <= 255) { + int8_t i = offset; + if (buf) { + *(buf++) = 0x75; + *(buf++) = i; + } + return 2; + } else { + die("unimplemented jng offet!"); + } + + return 0; // prevents warning +} + +size_t jmp(char *buf, int64_t offset) { if (-256 <= offset && offset <= 255) { diff --git a/x64.h b/x64.h @@ -51,6 +51,7 @@ size_t sub_r64_imm(char *buf, enum reg reg1, int32_t imm); size_t cmp_r64_r64(char *buf, enum reg reg1, enum reg reg2); size_t jng(char *buf, int64_t offset); size_t jg(char *buf, int64_t offset); +size_t jne(char *buf, int64_t offset); size_t jmp(char *buf, int64_t offset); size_t call(char *buf, enum reg reg); size_t ret(char *buf);