diff options
| -rw-r--r-- | lex.c | 33 | ||||
| -rw-r--r-- | lex.h | 1 | ||||
| -rw-r--r-- | main.c | 17 | ||||
| -rw-r--r-- | test.lang | 2 |
4 files changed, 25 insertions, 28 deletions
@@ -48,13 +48,13 @@ void lex_expect_not(Lexer *l, TokMask t) { void lex_expected(Lexer *l, TokMask t) { if (!(TMASK(l->tok) & t)) { - lex_error(l, LE_ERROR, str_fmt(&l->arena, "Expected %S but got %s", lex_mask_str(l, t), lex_tok_str[l->tok])); + lex_error(l, LE_ERROR, str_fmt(&l->arena, "expected %S but got %s", lex_mask_str(l, t), lex_tok_str[l->tok])); } } void lex_expected_not(Lexer *l, TokMask t) { if (TMASK(l->tok) & t) { - lex_error(l, LE_ERROR, str_fmt(&l->arena, "Unexpected %s", lex_tok_str[l->tok])); + lex_error(l, LE_ERROR, str_fmt(&l->arena, "unexpected %s", lex_tok_str[l->tok])); } } @@ -81,14 +81,20 @@ void lex_error(Lexer *l, LexErr e, Str msg) { lex_error_at(l, l->pos, e, msg); } +void lex_err_color(LexErr e) { + fprintf(stderr, "%s", e == LE_NONE ? "\x1b[0m" : (e == LE_ERROR ? "\x1b[1;31m" : "\x1b[1;33m")); +} + void lex_error_at(Lexer *l, LexSpan pos, LexErr e, Str msg) { int line, col; lex_pos(l, pos.ofs, &line, &col); - fprintf(stderr, "%s", e == LE_ERROR ? "\x1b[1;31m" : "\x1b[1;33m"); - fprintf(stderr, "%.*s:%d:%d: %.*s\n\n", - (int)l->filename.n, l->filename.s, line + 1, col + 1, (int)msg.n, msg.s); + fprintf(stderr, "\x1b[1m%.*s:%d:%d:\x1b[0m ", (int)l->filename.n, l->filename.s, line + 1, col + 1); + lex_err_color(e); + if (e != LE_NONE) fprintf(stderr, "%s", e == LE_ERROR ? "error" : "warn"); + lex_err_color(LE_NONE); + fprintf(stderr, ": %.*s\n\n", (int)msg.n, msg.s); { int ofs = pos.ofs; @@ -96,13 +102,16 @@ void lex_error_at(Lexer *l, LexSpan pos, LexErr e, Str msg) { while (line_start > 0 && l->buf.s[line_start - 1] != '\n') line_start--; int line_end = line_start; while (line_end < l->buf.n && l->buf.s[line_end] != '\n') line_end++; + lex_err_color(e); fprintf(stderr, "%.*s\n", line_end - line_start, &l->buf.s[line_start]); for (int i = 0; i < col; i++) fputc(' ', stderr); - for (int i = ofs; i < ofs + pos.n && i < line_end; i++) fputc('^', stderr); - putchar('\n'); + fputc('^', stderr); + for (int i = ofs + 1; i < ofs + pos.n && i < line_end; i++) fputc('~', stderr); + lex_err_color(LE_NONE); + fputc('\n', stderr); } - fprintf(stderr, "\x1b[0m\n"); + fputc('\n', stderr); if (e == LE_ERROR) { exit(1); @@ -170,15 +179,15 @@ recurse: T(TOK_LIT_CHAR); if (i < l->buf.n && l->buf.s[i] == '\\') i += 2; else i++; - if (i >= l->buf.n) lex_error(l, LE_ERROR, S("Unterminated character literal")); - if (l->buf.s[i] != '\'') lex_error(l, LE_ERROR, S("Overlong character literal")); + if (i >= l->buf.n) lex_error(l, LE_ERROR, S("unterminated character literal")); + if (l->buf.s[i] != '\'') lex_error(l, LE_ERROR, S("overlong character literal")); i++; break; case '"': T(TOK_LIT_STR); for (;;) { if (i >= l->buf.n) { - lex_error(l, LE_ERROR, S("Unterminated string literal")); + lex_error(l, LE_ERROR, S("unterminated string literal")); } if (l->buf.s[i] == '\\') { i += 2; @@ -190,7 +199,7 @@ recurse: } } if (l->tok == TOK_MAX) { - lex_error(l, LE_ERROR, S("Invalid token")); + lex_error(l, LE_ERROR, S("parse error")); } l->ident.n = i - start_ofs; l->pos.n = i - start_ofs; @@ -83,6 +83,7 @@ typedef struct { } Lexer; typedef enum { + LE_NONE, LE_WARN, LE_ERROR } LexErr; @@ -227,7 +227,6 @@ static inline int node_op_communative(NodeType t) { /* needs lexer for error reporting */ Node *node_peephole(Node *n, Proc *p, Lexer *l) { - return n; /* * Is there a method to convey these transformations a little more nicely? * @@ -253,7 +252,7 @@ Node *node_peephole(Node *n, Proc *p, Lexer *l) { case N_OP_MUL: r = node_new_lit_i64(p, in[0]->lit.i * in[1]->lit.i); break; case N_OP_DIV: if (in[1]->lit.i == 0) { - lex_error_at(l, n->src_pos, LE_ERROR, S("Division by zero")); + lex_error_at(l, in[1]->src_pos, LE_ERROR, S("divisor always evaluates to zero")); } r = node_new_lit_i64(p, in[0]->lit.i / in[1]->lit.i); break; @@ -364,21 +363,9 @@ Node *parse_term(Lexer *l, Proc *p) { return node_peephole(node, p, l); } +/* TODO: operator precedence would be kinda nice actually, sad to say */ Node *parse_expr(Lexer *l, Proc *p) { Node *lhs = parse_term(l, p); - if (l->tok == TOK_LPAREN) { - lex_next(l); - puts("args_start"); - for (;;) { - parse_expr(l, p); - lex_expected(l, TM_COMMA | TM_RPAREN); - if (l->tok == TOK_RPAREN) break; - lex_next(l); - } - lex_next(l); - puts("args_end"); - puts("func_call"); - } if (TMASK(l->tok) & (TM_PLUS | TM_MINUS | TM_ASTERISK | TM_SLASH | TM_NOT | TM_AND | TM_XOR | TM_OR)) { Token t = l->tok; lex_next(l); @@ -7,5 +7,5 @@ */ proc main { - return ((1 & 3) * 1 + 4 / (81237 & 37)) - 23 + -3 + 4 + return (3 * 5612 * -2) / (1 * (32 ^ 32) + (512 ^ 512) & 3131) } |
