boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

commit ef80474926e643782b6684c10ec7367bd2a1ed01
parent 63959a59c2526161431457084565f13ffa939916
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Sat, 25 Apr 2026 14:42:41 -0700

M1pp: track source line numbers and report them in error messages

Diffstat:
MM1pp/M1pp.c | 49++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 38 insertions(+), 11 deletions(-)

diff --git a/M1pp/M1pp.c b/M1pp/M1pp.c @@ -127,6 +127,7 @@ struct TextSpan { struct Token { int kind; int tight; + int line; struct TextSpan text; }; @@ -178,6 +179,9 @@ static int output_need_space; static int stream_top; static int next_expansion_id; static int scope_depth; +static int current_line; +static int error_line; +static const char *input_path; static struct Token *arg_starts[MAX_PARAMS]; static struct Token *arg_ends[MAX_PARAMS]; @@ -189,6 +193,7 @@ static const char *error_msg; static int fail(const char *msg) { error_msg = msg; + error_line = current_line; return 0; } @@ -213,13 +218,14 @@ static char *append_text_len(const char *s, int len) } static int push_token(struct Token *buf, int *count, int max_count, - int kind, int tight, struct TextSpan text) + int kind, int tight, int line, struct TextSpan text) { if (*count >= max_count) { return fail("token overflow"); } buf[*count].kind = kind; buf[*count].tight = tight; + buf[*count].line = line; buf[*count].text = text; *count += 1; return 1; @@ -255,6 +261,7 @@ static int lex_source(const char *src) * LPAREN's tight bit is consulted, to decide whether %FOO(...) / * !(...) etc. are paren-call forms. */ int i = 0; + int line = 1; int saw_separator = 1; while (src[i] != '\0') { @@ -262,6 +269,8 @@ static int lex_source(const char *src) int len; int tight; + current_line = line; + if (is_space_no_nl((unsigned char)src[i])) { saw_separator = 1; i++; @@ -269,9 +278,10 @@ static int lex_source(const char *src) } if (src[i] == '\n') { if (!push_token(source_tokens, &source_count, MAX_TOKENS, - TOK_NEWLINE, 0, (struct TextSpan){src + i, 1})) { + TOK_NEWLINE, 0, line, (struct TextSpan){src + i, 1})) { return 0; } + line++; saw_separator = 1; i++; continue; @@ -283,6 +293,9 @@ static int lex_source(const char *src) start = i; i++; while (src[i] != '\0' && src[i] != quote) { + if (src[i] == '\n') { + line++; + } i++; } if (src[i] == quote) { @@ -290,7 +303,7 @@ static int lex_source(const char *src) } len = i - start; if (!push_token(source_tokens, &source_count, MAX_TOKENS, - TOK_STRING, tight, (struct TextSpan){src + start, len})) { + TOK_STRING, tight, current_line, (struct TextSpan){src + start, len})) { return 0; } saw_separator = 0; @@ -299,7 +312,7 @@ static int lex_source(const char *src) if (src[i] == '#' && src[i + 1] == '#') { tight = !saw_separator; if (!push_token(source_tokens, &source_count, MAX_TOKENS, - TOK_PASTE, tight, (struct TextSpan){src + i, 2})) { + TOK_PASTE, tight, line, (struct TextSpan){src + i, 2})) { return 0; } i += 2; @@ -316,7 +329,7 @@ static int lex_source(const char *src) if (src[i] == '(') { tight = !saw_separator; if (!push_token(source_tokens, &source_count, MAX_TOKENS, - TOK_LPAREN, tight, (struct TextSpan){src + i, 1})) { + TOK_LPAREN, tight, line, (struct TextSpan){src + i, 1})) { return 0; } i++; @@ -326,7 +339,7 @@ static int lex_source(const char *src) if (src[i] == ')') { tight = !saw_separator; if (!push_token(source_tokens, &source_count, MAX_TOKENS, - TOK_RPAREN, tight, (struct TextSpan){src + i, 1})) { + TOK_RPAREN, tight, line, (struct TextSpan){src + i, 1})) { return 0; } i++; @@ -336,7 +349,7 @@ static int lex_source(const char *src) if (src[i] == ',') { tight = !saw_separator; if (!push_token(source_tokens, &source_count, MAX_TOKENS, - TOK_COMMA, tight, (struct TextSpan){src + i, 1})) { + TOK_COMMA, tight, line, (struct TextSpan){src + i, 1})) { return 0; } i++; @@ -346,7 +359,7 @@ static int lex_source(const char *src) if (src[i] == '{') { tight = !saw_separator; if (!push_token(source_tokens, &source_count, MAX_TOKENS, - TOK_LBRACE, tight, (struct TextSpan){src + i, 1})) { + TOK_LBRACE, tight, line, (struct TextSpan){src + i, 1})) { return 0; } i++; @@ -356,7 +369,7 @@ static int lex_source(const char *src) if (src[i] == '}') { tight = !saw_separator; if (!push_token(source_tokens, &source_count, MAX_TOKENS, - TOK_RBRACE, tight, (struct TextSpan){src + i, 1})) { + TOK_RBRACE, tight, line, (struct TextSpan){src + i, 1})) { return 0; } i++; @@ -381,7 +394,7 @@ static int lex_source(const char *src) } len = i - start; if (!push_token(source_tokens, &source_count, MAX_TOKENS, - TOK_WORD, tight, (struct TextSpan){src + start, len})) { + TOK_WORD, tight, line, (struct TextSpan){src + start, len})) { return 0; } saw_separator = 0; @@ -654,6 +667,7 @@ static int define_fielded_macro(struct TextSpan base, const char *suffix, m->param_count = 0; body_tok.kind = TOK_WORD; body_tok.tight = 0; + body_tok.line = current_line; if (!emit_decimal_text(value, &body_tok.text)) { return 0; } @@ -1071,6 +1085,7 @@ static int push_local_label_token(const struct Token *tok, int expansion_id) out.kind = TOK_WORD; out.tight = 0; + out.line = current_line; out.text.ptr = text_buf + start; out.text.len = total; return push_pool_token(out); @@ -1438,6 +1453,9 @@ static int eval_expr_range(struct TokenSpan span, long long *out) if (pos >= span.end) { break; } + if (pos->line > 0) { + current_line = pos->line; + } if (pos->kind == TOK_LPAREN) { enum ExprOp op; @@ -1541,6 +1559,7 @@ static int emit_hex_value(unsigned long long value, int bytes) } tok.kind = TOK_STRING; tok.tight = 0; + tok.line = current_line; tok.text.ptr = text_ptr; tok.text.len = total_len; return emit_token(&tok); @@ -1643,6 +1662,7 @@ static int expand_builtin_call(struct Stream *s, const struct Token *tok) out_tok.kind = TOK_STRING; out_tok.tight = 0; + out_tok.line = current_line; out_tok.text.ptr = text_ptr; out_tok.text.len = out_len; s->pos = end_pos; @@ -1733,6 +1753,9 @@ static int process_tokens(void) } tok = s->pos; + if (tok->line > 0) { + current_line = tok->line; + } if (tok->kind == TOK_WORD && token_text_eq(tok, "%macro")) { if (!define_macro(s)) { @@ -1834,6 +1857,7 @@ int main(int argc, char **argv) return 1; } + input_path = argv[1]; in = fopen(argv[1], "rb"); if (in == NULL) { perror(argv[1]); @@ -1853,7 +1877,10 @@ int main(int argc, char **argv) input_buf[nread] = '\0'; if (!lex_source(input_buf) || !process_tokens()) { - fprintf(stderr, "m1macro: %s\n", error_msg != NULL ? error_msg : "failed"); + fprintf(stderr, "%s:%d: m1macro: %s\n", + input_path != NULL ? input_path : "?", + error_line, + error_msg != NULL ? error_msg : "failed"); return 1; }