nooc

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

commit 695cc9130a08fa77369eef0ec44c260e36c4ef1b
parent 2a8af28e0f1f3dabb248c2f28a089780077cc7c1
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Wed, 29 Dec 2021 17:30:59 -0600

initial reference operator implementation

Diffstat:
Mlex.c | 3+++
Mmain.c | 18++++++++++++++++++
Mnooc.h | 12++++++++++++
Mparse.c | 8++++++++
Atest/pointer_global.pass.nooc | 6++++++
Mutil.c | 3+++
6 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/lex.c b/lex.c @@ -56,6 +56,9 @@ lex(struct slice start) } else if (*start.data == '>') { cur->type = TOK_GREATER; ADVANCE(1); + } else if (*start.data == '$') { + cur->type = TOK_DOLLAR; + ADVANCE(1); } else if (*start.data == ',') { cur->type = TOK_COMMA; ADVANCE(1); diff --git a/main.c b/main.c @@ -446,6 +446,24 @@ genexpr(char *buf, size_t idx, struct place *out) total += place_move(buf ? buf + total : buf, out, &regbuf); freereg(regbuf.l.reg); + } else if (expr->kind == EXPR_UNARY) { + assert(expr->d.uop.kind == UOP_REF); + struct expr *ident = &exprs.data[expr->d.uop.expr]; + assert(ident->kind == EXPR_IDENT); + struct decl *decl = finddecl(ident->d.s); + assert(decl->place.kind == PLACE_ABS); + struct place src = { .kind = PLACE_REG, .l.reg = getreg(), .size = 8 }; + + switch (decl->place.kind) { + case PLACE_ABS: + total += mov_r64_imm(buf ? buf + total : NULL, src.l.reg, decl->place.l.addr); + total += place_move(buf ? buf + total : NULL, out, &src); + break; + default: + die("genexpr: unhandled place kind for EXPR_UNARY"); + } + + freereg(src.l.reg); } else if (expr->kind == EXPR_IDENT) { struct decl *decl = finddecl(expr->d.s); if (decl == NULL) { diff --git a/nooc.h b/nooc.h @@ -16,6 +16,8 @@ enum tokentype { TOK_MINUS, TOK_GREATER, + TOK_DOLLAR, + TOK_COMMA, TOK_EQUAL, @@ -192,6 +194,13 @@ struct binop { size_t right; }; +struct unop { + enum { + UOP_REF, + } kind; + size_t expr; +}; + struct value { union { int64_t i64; @@ -204,6 +213,7 @@ enum exprkind { EXPR_LIT, EXPR_IDENT, EXPR_BINARY, + EXPR_UNARY, EXPR_FCALL, EXPR_COND, EXPR_LOOP, @@ -212,6 +222,7 @@ enum exprkind { enum class { C_INT = 1, + C_REF, C_STR, C_PROC, }; @@ -222,6 +233,7 @@ struct expr { union { struct value v; struct binop bop; + struct unop uop; struct slice s; struct fcall call; struct cond cond; diff --git a/parse.c b/parse.c @@ -263,6 +263,14 @@ binary_common: case TOK_STRING: parsestring(&expr); break; + case TOK_DOLLAR: + expr.start = tok; + expr.kind = EXPR_UNARY; + expr.class = C_REF; + expr.d.uop.kind = UOP_REF; + tok = tok->next; + expr.d.uop.expr = parseexpr(block); + break; default: error(tok->line, tok->col, "invalid token for expression"); } diff --git a/test/pointer_global.pass.nooc b/test/pointer_global.pass.nooc @@ -0,0 +1,6 @@ +let c i8 = 65 + +let main proc() = proc() { + syscall(1, 1, $c, 1) + syscall(60, 0) +} diff --git a/util.c b/util.c @@ -64,6 +64,9 @@ dumpval(struct expr *e) case C_STR: fprintf(stderr, "\"%.*s\"", (int)e->d.v.v.s.len, e->d.v.v.s.data); break; + case C_REF: + fprintf(stderr, "a reference"); + break; case C_PROC: fprintf(stderr, "proc with %lu params", e->d.proc.in.len); break;