diff --git a/lex.c b/lex.c index 3f3d274..3184650 100644 --- a/lex.c +++ b/lex.c @@ -2,6 +2,8 @@ #include "util.h" +#define TAB_WIDTH 4 + typedef struct Pos { size_t ln, col; /* current position */ size_t m_ln, m_col; /* marked position */ @@ -17,7 +19,9 @@ static void consume(Pos *p, char c) { if (c == '\n') { p->ln++; p->col = 1; - } else + } else if (c == '\t') + p->col += TAB_WIDTH; + else p->col++; } diff --git a/parse.c b/parse.c index a3cb3d6..819e815 100644 --- a/parse.c +++ b/parse.c @@ -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; for (size_t i = 0; i < args_len; i++) arg_vals[i] = args[i].Literal; + mark_err(&func_ident->tok); func_ident->tok = (Tok) { .kind = TokVal, .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) { /* immediately perform operation */ t->tok.kind = TokVal; + mark_err(&t->tok); TRY_RET(t->tok.Val = eval_unary(unary_op, &v->Val), (ExprRet){0}); } else { 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 *rhs_val = swap_operands ? &lhs->Val : &rhs->Val; lhs->kind = TokVal; + mark_err(l_op); TRY_RET(lhs->Val = eval_binary(instr, lhs_val, rhs_val), (ExprRet){0}); } else { 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; TRY(res = tok_to_irparam(parent_sc, &t->tok)); irtoks_app(out_ir, (IRTok){ + .ln = t->tok.ln, + .col = t->tok.col, .instr = IRSet, .Unary = { .addr = addr, diff --git a/runtime.c b/runtime.c index a94b1f4..2cf2d1f 100644 --- a/runtime.c +++ b/runtime.c @@ -35,7 +35,7 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) { .Float = res, }; } 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}; } } @@ -58,7 +58,7 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) { default: ASSERT_UNREACHED(); }; } 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){ @@ -93,14 +93,14 @@ Value eval_unary(IRInstr instr, const Value *v) { else if (v->type.kind == TypeFloat) return (Value){ .type.kind = TypeFloat, .Float = -v->Float }; 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}; } case IRNot: if (v->type.kind == TypeBool) { return (Value){ .type.kind = TypeBool, .Bool = !v->Bool }; } 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}; } default: diff --git a/tok.c b/tok.c index f76d69e..63215ae 100644 --- a/tok.c +++ b/tok.c @@ -14,6 +14,15 @@ size_t type_size[TypeEnumSize] = { [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) { switch (v->type.kind) { case TypeVoid: diff --git a/tok.h b/tok.h index 1380ab6..32fe39d 100644 --- a/tok.h +++ b/tok.h @@ -22,6 +22,7 @@ typedef struct Type { } Type; extern size_t type_size[TypeEnumSize]; +extern const char *type_str[TypeEnumSize]; typedef struct Value { Type type;