nooc

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

commit df67a9c8f9fc64c7cbcf2250a07fc7a95b1de740
parent f56821f2a3d5b1da0e8acd553c994758b941b2ef
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Thu,  9 Dec 2021 20:01:14 -0600

make error vararg

Diffstat:
Mlex.c | 2+-
Mmain.c | 48++++++++++++++++++++++++++----------------------
Mparse.c | 16++++++++--------
Mutil.c | 11+++++++++--
Mutil.h | 2+-
5 files changed, 45 insertions(+), 34 deletions(-)

diff --git a/lex.c b/lex.c @@ -108,7 +108,7 @@ lex(struct slice start) cur->slice.len++; } } else { - error("invalid token", line, col); + error(line, col, "invalid token"); } cur->next = calloc(1, sizeof(struct token)); diff --git a/main.c b/main.c @@ -140,45 +140,49 @@ typecheck(struct block items) expr = &exprs.data[decl->val]; // FIXME: we should be able to deal with ident or fcalls if (expr->class != C_INT) - error("expected integer expression for integer declaration", decl->start->line, decl->start->col); + error(decl->start->line, decl->start->col, "expected integer expression for integer declaration"); break; case TYPE_STR: expr = &exprs.data[decl->val]; // FIXME: we should be able to deal with ident or fcalls - if (expr->class != C_STR) error("expected string expression for string declaration", decl->start->line, decl->start->col); + if (expr->class != C_STR) + error(decl->start->line, decl->start->col, "expected string expression for string declaration"); break; case TYPE_PROC: expr = &exprs.data[decl->val]; - if (expr->class != C_PROC) error("expected proc expression for proc declaration", decl->start->line, decl->start->col); + if (expr->class != C_PROC) + error(decl->start->line, decl->start->col, "expected proc expression for proc declaration"); break; default: - error("unknown decl type", decl->start->line, decl->start->col); + error(decl->start->line, decl->start->col, "unknown decl type"); } break; case ITEM_ASSGN: struct assgn *assgn = &assgns.data[item->idx]; decl = finddecl(&items, assgn->s); if (decl == NULL) - error("unknown name", assgn->start->line, assgn->start->col); + error(assgn->start->line, assgn->start->col, "unknown name"); switch (decl->type) { case TYPE_I64: expr = &exprs.data[assgn->val]; // FIXME: we should be able to deal with ident or fcalls - if (expr->class != C_INT) error("expected integer expression for integer variable", assgn->start->line, assgn->start->col); + if (expr->class != C_INT) + error(assgn->start->line, assgn->start->col, "expected integer expression for integer variable"); break; case TYPE_STR: expr = &exprs.data[assgn->val]; // FIXME: we should be able to deal with ident or fcalls - if (expr->class != C_STR) error("expected string expression for string variable", assgn->start->line, assgn->start->col); + if (expr->class != C_STR) + error(assgn->start->line, assgn->start->col, "expected string expression for string variable"); break; default: - error("unknown decl type", assgn->start->line, assgn->start->col); + error(assgn->start->line, assgn->start->col, "unknown decl type"); } break; case ITEM_EXPR: break; default: - error("unknown item type", item->start->line, item->start->col); + error(item->start->line, item->start->col, "unknown item type"); } } } @@ -200,7 +204,7 @@ genexpr(char *buf, size_t idx, enum reg reg) break; } default: - error("genexpr: unknown value type!", expr->start->line, expr->start->col); + error(expr->start->line, expr->start->col, "genexpr: unknown value type!"); } } else if (expr->kind == EXPR_BINARY) { len += genexpr(ptr ? ptr + len : ptr, expr->left, reg); @@ -221,17 +225,17 @@ genexpr(char *buf, size_t idx, enum reg reg) break; } default: - error("genexpr: unknown binary op!", expr->start->line, expr->start->col); + error(expr->start->line, expr->start->col, "genexpr: unknown binary op!"); } freereg(rreg); } else if (expr->kind == EXPR_IDENT) { struct decl *decl = finddecl(curitems, expr->d.s); if (decl == NULL) { - error("unknown name!", expr->start->line, expr->start->col); + error(expr->start->line, expr->start->col, "unknown name!"); } len += mov_r64_m64(ptr ? ptr + len : ptr, reg, decl->addr); } else { - error("genexpr: could not generate code for expression", expr->start->line, expr->start->col); + error(expr->start->line, expr->start->col, "genexpr: could not generate code for expression"); } return len; } @@ -242,7 +246,7 @@ gensyscall(char *buf, struct expr *expr) size_t len = 0; struct fparams *params = &expr->d.call.params; if (params->len > 7) - error("syscall can take at most 7 parameters", expr->start->line, expr->start->col); + error(expr->start->line, expr->start->col, "syscall can take at most 7 parameters"); // encoding for argument registers in ABI order for (int i = 0; i < params->len; i++) { @@ -278,7 +282,7 @@ genblock(char *buf, struct block *block) } else { struct decl *decl = finddecl(block, expr->d.call.name); if (decl == NULL) { - error("unknown function!", expr->start->line, expr->start->col); + error(expr->start->line, expr->start->col, "unknown function!"); } enum reg reg = getreg(); @@ -300,7 +304,7 @@ genblock(char *buf, struct block *block) total += jng(buf ? buf + total : NULL, iflen); break; default: - error("unknown binop for conditional", expr->start->line, expr->start->col); + error(expr->start->line, expr->start->col, "unknown binop for conditional"); } total += genblock(buf ? buf + total : NULL, &expr->d.cond.bif); total += jmp(buf ? buf + total: NULL, elselen); @@ -310,7 +314,7 @@ genblock(char *buf, struct block *block) total += genblock(buf ? buf + total : NULL, &expr->d.loop.block); total += jmp(buf ? buf + total: NULL, -back); } else { - error("unhandled toplevel expression type!", expr->start->line, expr->start->col); + error(expr->start->line, expr->start->col, "unhandled toplevel expression type!"); } } else if (item->kind == ITEM_DECL) { struct expr *expr = &exprs.data[decls.data[item->idx].val]; @@ -339,17 +343,17 @@ genblock(char *buf, struct block *block) total += genblock(buf ? buf + total : NULL, &(expr->d.proc.block)); break; default: - error("cannot generate code for unknown expression class", expr->start->line, expr->start->col); + error(expr->start->line, expr->start->col, "cannot generate code for unknown expression class"); } } else if (item->kind == ITEM_ASSGN) { struct expr *expr = &exprs.data[assgns.data[item->idx].val]; struct assgn *assgn = &assgns.data[item->idx]; struct decl *decl = finddecl(block, assgn->s); if (decl == NULL) - error("unknown name", assgn->start->line, assgn->start->col); + error(assgn->start->line, assgn->start->col, "unknown name"); if (buf && decl->addr == 0) - error("assignment before declaration", assgn->start->line, assgn->start->col); + error(assgn->start->line, assgn->start->col, "assignment before declaration"); switch (expr->class) { case C_INT: @@ -366,12 +370,12 @@ genblock(char *buf, struct block *block) total += mov_m64_r64(buf ? buf + total : NULL, decl->addr, reg); break; default: - error("cannot generate code for unknown expression class", expr->start->line, expr->start->col); + error(expr->start->line, expr->start->col, "cannot generate code for unknown expression class"); } } else if (item->kind == ITEM_RETURN) { total += ret(buf ? buf + total : NULL); } else { - error("cannot generate code for type", item->start->line, item->start->col); + error(item->start->line, item->start->col, "cannot generate code for type"); } } diff --git a/parse.c b/parse.c @@ -32,9 +32,9 @@ static void expect(enum tokentype type) { if (!tok) - error("unexpected null token!", tok->line, tok->col); + error(tok->line, tok->col, "unexpected null token!"); if (tok->type != type) { - error("mismatch", tok->line, tok->col); + error(tok->line, tok->col, "mismatch"); } } @@ -62,10 +62,10 @@ parsestring() array_add((&expr.d.v.v.s), c); break; default: - error("invalid string escape!", tok->line, tok->col); + error(tok->line, tok->col, "invalid string escape!"); } } else { - error("string escape without parameter", tok->line, tok->col); + error(tok->line, tok->col, "string escape without parameter"); } break; default: @@ -162,14 +162,14 @@ binary_common: expr.left = parseexpr(); expr.right = parseexpr(); if (exprs.data[expr.left].class != exprs.data[expr.right].class) - error("expected binary expression operands to be of same class", tok->line, tok->col); + error(tok->line, tok->col, "expected binary expression operands to be of same class"); expr.class = exprs.data[expr.left].class; break; case TOK_STRING: parsestring(); break; default: - error("invalid token for expression", tok->line, tok->col); + error(tok->line, tok->col, "invalid token for expression"); } array_add((&exprs), expr); @@ -210,7 +210,7 @@ parseblock() } else if (strncmp(tok->slice.data, "proc", 3) == 0) { decl.type = TYPE_PROC; } else { - error("unknown type", tok->line, tok->col); + error(tok->line, tok->col, "unknown type"); } tok = tok->next; @@ -219,7 +219,7 @@ parseblock() // FIXME: scoping if (finddecl(&items, decl.s)) { - error("repeat declaration!", tok->line, tok->col); + error(tok->line, tok->col, "repeat declaration!"); } decl.val = parseexpr(); diff --git a/util.c b/util.c @@ -1,3 +1,4 @@ +#include <stdarg.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> @@ -29,9 +30,15 @@ slice_cmplit(struct slice *s1, char *s2) } void -error(char *error, size_t line, size_t col) +error(size_t line, size_t col, const char *error, ...) { - fprintf(stderr, "%s:%u:%u: %s\n", infile, line, col, error); + va_list args; + + fprintf(stderr, "%s:%u:%u: ", infile, line, col); + va_start(args, error); + vfprintf(stderr, error, args); + va_end(args); + fputc('\n', stderr); exit(1); } diff --git a/util.h b/util.h @@ -1,4 +1,4 @@ int slice_cmp(struct slice *s1, struct slice *s2); int slice_cmplit(struct slice *s1, char *s2); -void error(char *error, size_t line, size_t col); +void error(size_t line, size_t col, const char *error, ...); void die(char *error);