commit 71ff7998381c7bd7718d0b7e1c7e38d4ef613d59
parent 7df0fb70a3b9b8cf9a49ccd9a5dd590590f772e9
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Thu, 21 May 2026 11:59:00 -0700
Improve Toy REPL diagnostic locations
Diffstat:
6 files changed, 38 insertions(+), 13 deletions(-)
diff --git a/lang/toy/compile.c b/lang/toy/compile.c
@@ -162,12 +162,13 @@ static CfreeStatus toy_frontend_compile(
if (st != CFREE_OK) goto done_status;
if (!fe->parser_live) {
- toy_parser_init(&fe->parser, c, cg, source, source_len);
+ toy_parser_init(&fe->parser, c, cg, source, source_len,
+ input->bytes.name);
fe->parser.input_kind = opts->input_kind;
fe->parser_live = 1;
} else {
toy_parser_reinit(&fe->parser, c, cg, source, source_len,
- opts->input_kind);
+ input->bytes.name, opts->input_kind);
}
p = fe->parser;
if (opts->input_kind != CFREE_FRONTEND_INPUT_TRANSLATION_UNIT &&
diff --git a/lang/toy/expr.c b/lang/toy/expr.c
@@ -688,8 +688,8 @@ static CfreeCgTypeId toy_parse_expr_primary(ToyParser* p) {
ToyTypeId callee_toy_type = p->last_type;
const ToyType* source_fn_type = NULL;
if (callee_ty == CFREE_CG_TYPE_NONE) {
- toy_error(p, ident_tok.loc, "undefined function '%s'",
- (const char*)ident_tok.text);
+ toy_error(p, ident_tok.loc, "undefined function '%.*s'",
+ (int)ident_tok.text_len, (const char*)ident_tok.text);
return CFREE_CG_TYPE_NONE;
}
CfreeCgTypeId fn_ty = toy_ptr_pointee_func_type(p, callee_ty);
@@ -754,8 +754,8 @@ static CfreeCgTypeId toy_parse_expr_primary(ToyParser* p) {
CfreeCgTypeId ty = toy_push_named_rvalue(p, name);
if (ty != CFREE_CG_TYPE_NONE) return ty;
}
- toy_error(p, ident_tok.loc, "undefined variable '%s'",
- (const char*)ident_tok.text);
+ toy_error(p, ident_tok.loc, "undefined variable '%.*s'",
+ (int)ident_tok.text_len, (const char*)ident_tok.text);
return CFREE_CG_TYPE_NONE;
}
diff --git a/lang/toy/internal.h b/lang/toy/internal.h
@@ -214,6 +214,8 @@ typedef struct ToyParser {
CfreeCgTypeId cur_fn_ret;
ToyTypeId cur_fn_ret_toy;
CfreeDiagSink* diag;
+ const char* input_name;
+ uint32_t file_id;
int has_error;
uint32_t static_counter;
uint32_t expr_island_mask;
@@ -223,9 +225,11 @@ typedef struct ToyParser {
CfreeCgTypeId toy_builtin_type(ToyParser* p, CfreeCgBuiltinType ty);
void toy_parser_init(ToyParser* p, CfreeCompiler* c, CfreeCg* cg,
- const uint8_t* data, size_t len);
+ const uint8_t* data, size_t len,
+ const char* input_name);
void toy_parser_reinit(ToyParser* p, CfreeCompiler* c, CfreeCg* cg,
const uint8_t* data, size_t len,
+ const char* input_name,
CfreeFrontendInputKind input_kind);
void toy_parser_dispose(ToyParser* p);
void* toy_parser_zalloc(ToyParser* p, size_t count, size_t elem_size,
diff --git a/lang/toy/lexer.c b/lang/toy/lexer.c
@@ -3,10 +3,12 @@
#include <stdlib.h>
#include <string.h>
-void toy_lexer_init(ToyLexer* lex, const uint8_t* data, size_t len) {
+void toy_lexer_init(ToyLexer* lex, const uint8_t* data, size_t len,
+ uint32_t file_id) {
lex->cur = data;
lex->end = data + len;
lex->bol = data;
+ lex->file_id = file_id;
lex->line = 1;
}
@@ -49,7 +51,7 @@ static ToyToken toy_lexer_emit(ToyLexer* lex, ToyTokenKind kind,
const uint8_t* start) {
ToyToken tok;
tok.kind = kind;
- tok.loc.file_id = 0;
+ tok.loc.file_id = lex->file_id;
tok.loc.line = lex->line;
tok.loc.col = (uint32_t)(start - lex->bol) + 1;
tok.text = start;
diff --git a/lang/toy/lexer.h b/lang/toy/lexer.h
@@ -86,10 +86,12 @@ typedef struct ToyLexer {
const uint8_t* cur;
const uint8_t* end;
const uint8_t* bol;
+ uint32_t file_id;
uint32_t line;
} ToyLexer;
-void toy_lexer_init(ToyLexer* lex, const uint8_t* data, size_t len);
+void toy_lexer_init(ToyLexer* lex, const uint8_t* data, size_t len,
+ uint32_t file_id);
ToyToken toy_lexer_next(ToyLexer* lex);
ToyToken toy_lexer_peek(const ToyLexer* lex);
diff --git a/lang/toy/parser_core.c b/lang/toy/parser_core.c
@@ -1,5 +1,6 @@
#include "internal.h"
+#include <cfree/source.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
@@ -33,10 +34,20 @@ void toy_parser_free_mem(ToyParser* p, void* items, size_t size) {
h->free(h, items, size ? size : 1u);
}
+static uint32_t toy_source_file_id(CfreeCompiler* c, const char* name) {
+ uint32_t file_id = 0;
+ if (name && *name)
+ (void)cfree_source_add_memory(c, name, &file_id);
+ return file_id;
+}
+
void toy_parser_init(ToyParser* p, CfreeCompiler* c, CfreeCg* cg,
- const uint8_t* data, size_t len) {
+ const uint8_t* data, size_t len,
+ const char* input_name) {
memset(p, 0, sizeof *p);
- toy_lexer_init(&p->lex, data, len);
+ p->file_id = toy_source_file_id(c, input_name);
+ p->input_name = input_name;
+ toy_lexer_init(&p->lex, data, len, p->file_id);
p->cur = toy_lexer_next(&p->lex);
p->c = c;
p->cg = cg;
@@ -72,6 +83,7 @@ void toy_parser_init(ToyParser* p, CfreeCompiler* c, CfreeCg* cg,
p->cur_fn_ret = toy_builtin_type(p, CFREE_CG_BUILTIN_VOID);
p->cur_fn_ret_toy = toy_type_from_cg(p, p->cur_fn_ret);
p->diag = cfree_compiler_context(c)->diag;
+ p->input_name = input_name;
p->has_error = 0;
p->static_counter = 0;
p->expr_island_mask = 0;
@@ -81,8 +93,11 @@ void toy_parser_init(ToyParser* p, CfreeCompiler* c, CfreeCg* cg,
void toy_parser_reinit(ToyParser* p, CfreeCompiler* c, CfreeCg* cg,
const uint8_t* data, size_t len,
+ const char* input_name,
CfreeFrontendInputKind input_kind) {
- toy_lexer_init(&p->lex, data, len);
+ p->file_id = toy_source_file_id(c, input_name);
+ p->input_name = input_name;
+ toy_lexer_init(&p->lex, data, len, p->file_id);
p->cur = toy_lexer_next(&p->lex);
p->c = c;
p->cg = cg;
@@ -97,6 +112,7 @@ void toy_parser_reinit(ToyParser* p, CfreeCompiler* c, CfreeCg* cg,
p->cur_fn_ret = toy_builtin_type(p, CFREE_CG_BUILTIN_VOID);
p->cur_fn_ret_toy = toy_type_from_cg(p, p->cur_fn_ret);
p->diag = cfree_compiler_context(c)->diag;
+ p->input_name = input_name;
p->has_error = 0;
p->expr_island_mask = 0;
p->last_type = TOY_TYPE_NONE;