commit df67a9c8f9fc64c7cbcf2250a07fc7a95b1de740
parent f56821f2a3d5b1da0e8acd553c994758b941b2ef
Author: Nihal Jere <nihal@nihaljere.xyz>
Date: Thu, 9 Dec 2021 20:01:14 -0600
make error vararg
Diffstat:
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);