better error messages

This commit is contained in:
r4 2021-12-25 12:32:52 +01:00
parent f02dae603d
commit b58810e822
5 changed files with 24 additions and 5 deletions

6
lex.c
View File

@ -2,6 +2,8 @@
#include "util.h" #include "util.h"
#define TAB_WIDTH 4
typedef struct Pos { typedef struct Pos {
size_t ln, col; /* current position */ size_t ln, col; /* current position */
size_t m_ln, m_col; /* marked position */ size_t m_ln, m_col; /* marked position */
@ -17,7 +19,9 @@ static void consume(Pos *p, char c) {
if (c == '\n') { if (c == '\n') {
p->ln++; p->ln++;
p->col = 1; p->col = 1;
} else } else if (c == '\t')
p->col += TAB_WIDTH;
else
p->col++; p->col++;
} }

View File

@ -292,6 +292,7 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
Value *arg_vals = args_len ? xmalloc(sizeof(Value) * args_len) : NULL; Value *arg_vals = args_len ? xmalloc(sizeof(Value) * args_len) : NULL;
for (size_t i = 0; i < args_len; i++) for (size_t i = 0; i < args_len; i++)
arg_vals[i] = args[i].Literal; arg_vals[i] = args[i].Literal;
mark_err(&func_ident->tok);
func_ident->tok = (Tok) { func_ident->tok = (Tok) {
.kind = TokVal, .kind = TokVal,
.Val = func.func(arg_vals), .Val = func.func(arg_vals),
@ -348,6 +349,7 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
if (v->kind == TokVal) { if (v->kind == TokVal) {
/* immediately perform operation */ /* immediately perform operation */
t->tok.kind = TokVal; t->tok.kind = TokVal;
mark_err(&t->tok);
TRY_RET(t->tok.Val = eval_unary(unary_op, &v->Val), (ExprRet){0}); TRY_RET(t->tok.Val = eval_unary(unary_op, &v->Val), (ExprRet){0});
} else { } else {
size_t res_addr = is_last_operation ? 0 : sc.mem_addr++; size_t res_addr = is_last_operation ? 0 : sc.mem_addr++;
@ -472,6 +474,7 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
Value *lhs_val = swap_operands ? &rhs->Val : &lhs->Val; Value *lhs_val = swap_operands ? &rhs->Val : &lhs->Val;
Value *rhs_val = swap_operands ? &lhs->Val : &rhs->Val; Value *rhs_val = swap_operands ? &lhs->Val : &rhs->Val;
lhs->kind = TokVal; lhs->kind = TokVal;
mark_err(l_op);
TRY_RET(lhs->Val = eval_binary(instr, lhs_val, rhs_val), (ExprRet){0}); TRY_RET(lhs->Val = eval_binary(instr, lhs_val, rhs_val), (ExprRet){0});
} else { } else {
bool is_last_operation = t == start && r_op_prec == PREC_DELIM; bool is_last_operation = t == start && r_op_prec == PREC_DELIM;
@ -532,6 +535,8 @@ static void expr_into_addr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *par
IRParam res; IRParam res;
TRY(res = tok_to_irparam(parent_sc, &t->tok)); TRY(res = tok_to_irparam(parent_sc, &t->tok));
irtoks_app(out_ir, (IRTok){ irtoks_app(out_ir, (IRTok){
.ln = t->tok.ln,
.col = t->tok.col,
.instr = IRSet, .instr = IRSet,
.Unary = { .Unary = {
.addr = addr, .addr = addr,

View File

@ -35,7 +35,7 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
.Float = res, .Float = res,
}; };
} else { } else {
set_err("Unsupported types for operation '%s'", irinstr_str[instr]); set_err("Unsupported types for operation '%s': %s and %s", irinstr_str[instr], type_str[lhs->type.kind], type_str[rhs->type.kind]);
return (Value){0}; return (Value){0};
} }
} }
@ -58,7 +58,7 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
default: ASSERT_UNREACHED(); default: ASSERT_UNREACHED();
}; };
} else { } else {
set_err("Unsupported types for operation '%s'", irinstr_str[instr]); set_err("Unsupported types for operation '%s': %s and %s", irinstr_str[instr], type_str[lhs->type.kind], type_str[rhs->type.kind]);
return (Value){0}; return (Value){0};
} }
return (Value){ return (Value){
@ -93,14 +93,14 @@ Value eval_unary(IRInstr instr, const Value *v) {
else if (v->type.kind == TypeFloat) else if (v->type.kind == TypeFloat)
return (Value){ .type.kind = TypeFloat, .Float = -v->Float }; return (Value){ .type.kind = TypeFloat, .Float = -v->Float };
else { else {
set_err("Unsupported type for operation '%s'", irinstr_str[instr]); set_err("Unsupported type for operation '%s': %s", irinstr_str[instr], type_str[v->type.kind]);
return (Value){0}; return (Value){0};
} }
case IRNot: case IRNot:
if (v->type.kind == TypeBool) { if (v->type.kind == TypeBool) {
return (Value){ .type.kind = TypeBool, .Bool = !v->Bool }; return (Value){ .type.kind = TypeBool, .Bool = !v->Bool };
} else { } else {
set_err("Unsupported type for operation '%s'", irinstr_str[instr]); set_err("Unsupported type for operation '%s': %s", irinstr_str[instr], type_str[v->type.kind]);
return (Value){0}; return (Value){0};
} }
default: default:

9
tok.c
View File

@ -14,6 +14,15 @@ size_t type_size[TypeEnumSize] = {
[TypeArr] = sizeof(((Value*)NULL)->Arr), [TypeArr] = sizeof(((Value*)NULL)->Arr),
}; };
const char *type_str[TypeEnumSize] = {
[TypeVoid] = "void",
[TypeFloat] = "float",
[TypeInt] = "int",
[TypeBool] = "bool",
[TypeChar] = "char",
[TypeArr] = "arr",
};
void print_value(const Value *v, bool raw) { void print_value(const Value *v, bool raw) {
switch (v->type.kind) { switch (v->type.kind) {
case TypeVoid: case TypeVoid:

1
tok.h
View File

@ -22,6 +22,7 @@ typedef struct Type {
} Type; } Type;
extern size_t type_size[TypeEnumSize]; extern size_t type_size[TypeEnumSize];
extern const char *type_str[TypeEnumSize];
typedef struct Value { typedef struct Value {
Type type; Type type;