diff options
author | Alexis Lockwood | 2021-06-27 13:31:54 -0400 |
---|---|---|
committer | Alexis Lockwood | 2021-06-27 13:31:54 -0400 |
commit | 77bbb2d9595af3b2738b1a9845eeab63198e15cd (patch) | |
tree | 51359f2b88454f48487bbfc823c1092b392c61fd | |
parent | 4c54b23471f2da27660f86cfeccdb7916949fede (diff) |
Stop tracking line numbers
-rw-r--r-- | README | 3 | ||||
-rw-r--r-- | ls_run.c | 26 | ||||
-rw-r--r-- | src/ls.c | 33 | ||||
-rw-r--r-- | src/ls.h | 18 | ||||
-rw-r--r-- | src/ls_expr.c | 2 | ||||
-rw-r--r-- | src/ls_goto.c | 13 | ||||
-rw-r--r-- | src/ls_internal.c | 1 | ||||
-rw-r--r-- | src/ls_lex.c | 4 | ||||
-rw-r--r-- | src/ls_types.h | 2 |
9 files changed, 65 insertions, 37 deletions
@@ -50,9 +50,6 @@ Originally written by Alexis Lockwood in 2021. Ⓐ - Fetcher (always execute in RAM) - Delete GOFUN, it doesn't exist anymore - Argument and return value support for GOSUB and RETURN -- Stop tracking line number, it's getting too messy (esp with function calls, - etc). It's only needed to report errors. We can just count it out in the - error handler. ╒════════════════════════╕ │ THE SCRIPTING LANGUAGE │ @@ -128,7 +128,6 @@ int main(int argc, char ** argv) if (action == ACT_TOKENIZE) { ls_ctx.pc = 0; - ls_ctx.line = 1; ls_ctx.labels = NULL; _tokenize(&ls_ctx); exit(EXIT_SUCCESS); @@ -137,15 +136,16 @@ int main(int argc, char ** argv) ls_value_t pool[1000]; ls_error_t e = ls_run(&ls_ctx, pool, 1000); + uint16_t line = 0, col = 0; + ls_translate_pc(&ls_ctx, ls_ctx.pc, &line, &col); + if (e == LS_STOPPED) { - fprintf(stderr, ">stopped at line %u\n", - ls_ctx.line); + fprintf(stderr, ">stopped at %u:%u\n", line, col); } else if (e != 0) { - fprintf(stderr, ">error %d at line %u\n", - (int) e, ls_ctx.line); + fprintf(stderr, ">error %d at %u:%u\n", (int) e, line, col); } fclose(f); @@ -159,8 +159,7 @@ int main(int argc, char ** argv) { ls_print_value(stdout, &pool[i], &pool[0]); printf("\n"); - //if (pool[i].ty == LS_TY_PRISTINE) - if (i == 10) + if (pool[i].ty == LS_TY_PRISTINE) break; } } @@ -258,8 +257,10 @@ static void _tokenize(ls_context_t * ctx) if (setjmp(ctx->error_jmp_buf)) { - fprintf(stderr, "error %d at line %"PRIu16"\n", - (int) ctx->error, ctx->line); + uint16_t line = 0, col = 0; + ls_translate_pc(ctx, ctx->pc, &line, &col); + fprintf(stderr, "error %d at %u:%u", + (int) ctx->error, line, col); exit(EXIT_FAILURE); } @@ -343,5 +344,10 @@ static void _tokenize(ls_context_t * ctx) static void _line_trace_hook(ls_context_t * ctx) { - fprintf(stderr, ">line %"PRIu16"\n", ctx->line); + uint16_t line = 0, col = 0; + bool cachedebug_hold = cachedebug; + cachedebug = false; + ls_translate_pc(ctx, ctx->pc, &line, &col); + cachedebug = cachedebug_hold; + fprintf(stderr, ">line %"PRIu16"\n", line); } @@ -138,4 +138,37 @@ void ls_print_value(FILE * stream, ls_value_t * value, ls_value_t * first) } } +bool ls_translate_pc(ls_context_t * ctx, ls_addr_t pc, uint16_t * line, + uint16_t * col) +{ + uint16_t n_line = 1, n_col = 1; + bool last_was_nl = false; + + for (ls_addr_t i = 0; i <= pc; i++) + { + int f = ctx->fetcher(ctx->fetcher_ctx, i); + + if (f <= 0) + return false; + + ls_uchar uch = (ls_uchar) f; + + if (last_was_nl) + { + n_line++; + n_col = 1; + } + else + { + n_col++; + } + + last_was_nl = (uch == (ls_uchar) '\n'); + } + + *line = n_line; + *col = n_col; + return true; +} + // --- PRIVATE FUNCTION DEFINITIONS -------------------------------------------- @@ -75,9 +75,6 @@ typedef struct ls_context_s { /// Program counter ls_addr_t pc; - /// Current line number, 1-indexed - uint16_t line; - /// Top error-handling jmpbuf. When the interpreter encounters an error, /// it should store the error code in .error and jump here. jmp_buf error_jmp_buf; @@ -105,6 +102,21 @@ typedef struct ls_context_s { /// @param szpool - number of elements in @a pool ls_error_t ls_run(ls_context_t * ctx, ls_value_t * pool, size_t szpool); +/// Convert a program counter value to a line and column number. This is +/// expensive and should only be called in rare cases (for example, printing +/// out a line number in an error message). +/// +/// @param ctx - context +/// @param pc - program counter to look up +/// @param[out] line - 1-based line number +/// @param[out] col - 1-based column number +/// @retval true - success +/// @retval false - the PC doesn't exist +/// +/// If the PC doesn't exist, @a line and @a col are unchanged. +bool ls_translate_pc(ls_context_t * ctx, ls_addr_t pc, uint16_t * line, + uint16_t * col); + /// Print out a ls_value_t. For diagnostics. /// /// @param stream - stream to print it into diff --git a/src/ls_expr.c b/src/ls_expr.c index 20eb787..f6bfd2a 100644 --- a/src/ls_expr.c +++ b/src/ls_expr.c @@ -157,7 +157,6 @@ void ls_eval_expr(ls_context_t * ctx, ls_value_t * val, ls_token_t * firsttok) while (!done) { ls_addr_t pc_save = ctx->pc; - uint16_t line_save = ctx->line; ls_lex(ctx, &tok); have_token: @@ -190,7 +189,6 @@ have_token: if (done) { // Don't eat the token that ended the line ctx->pc = pc_save; - ctx->line = line_save; } } diff --git a/src/ls_goto.c b/src/ls_goto.c index ef0c9eb..1c198c3 100644 --- a/src/ls_goto.c +++ b/src/ls_goto.c @@ -30,7 +30,6 @@ static bool _rewind_line(ls_context_t * ctx); void ls_goto_num(ls_context_t * ctx, bool backward, uint16_t num) { ls_addr_t target = LS_ADDR_NULL; - uint16_t tline; for (size_t i = 0; i < LS_LABEL_CACHE_SIZE; i++) { @@ -42,16 +41,14 @@ void ls_goto_num(ls_context_t * ctx, bool backward, uint16_t num) (ctx->label_cache[i].pc <= ctx->pc && backward)) { target = ctx->label_cache[i].pc; - tline = ctx->label_cache[i].line; break; } } } - // In case we can't find the label, save pc/line to "unwind" for a + // In case we can't find the label, save pc to "unwind" for a // more helpful error later ls_addr_t pc = ctx->pc; - uint16_t line = ctx->line; if (target == LS_ADDR_NULL && !backward) { @@ -66,7 +63,6 @@ void ls_goto_num(ls_context_t * ctx, bool backward, uint16_t num) if (tok.body.number_val == num) { target = ctx->pc; - tline = ctx->line; break; } } @@ -87,20 +83,17 @@ void ls_goto_num(ls_context_t * ctx, bool backward, uint16_t num) // Quickly saving and restoring our location avoids // a costly second rewind to undo the ls_lex(). ls_addr_t bw_pc = ctx->pc++; - uint16_t bw_line = ctx->line++; ls_lex(ctx, &tok); if (tok.ty == LS_TOK_NUM_LABEL) { if (tok.body.number_val == num) { target = ctx->pc; - tline = ctx->line; break; } } ctx->pc = bw_pc; - ctx->line = bw_line; } } @@ -108,13 +101,11 @@ void ls_goto_num(ls_context_t * ctx, bool backward, uint16_t num) { throw: ctx->pc = pc; - ctx->line = line; ls_throw_err(ctx, LS_UNDEFINED_LABEL); } else { ctx->pc = target; - ctx->line = tline; } } @@ -161,7 +152,6 @@ void ls_goto_ident(ls_context_t * ctx, char const * ident) ls_throw_err(ctx, LS_UNDEFINED_LABEL); ctx->pc = label->body.label.pc; - ctx->line = (uint16_t) (uintptr_t) label->prev; } // --- PRIVATE FUNCTION DEFINITIONS -------------------------------------------- @@ -180,7 +170,6 @@ static bool _rewind_line(ls_context_t * ctx) if (ch == '\n') { ctx->pc = pc; - --ctx->line; return true; } diff --git a/src/ls_internal.c b/src/ls_internal.c index 87873f2..8d63fa3 100644 --- a/src/ls_internal.c +++ b/src/ls_internal.c @@ -73,7 +73,6 @@ void ls_init_ctx(ls_context_t * ctx, ls_value_t * pool, size_t szpool) ctx->funcs = NULL; ctx->labels = NULL; ctx->pc = 0; - ctx->line = 1; ctx->stop = false; for (size_t i = 0; i < LS_LABEL_CACHE_SIZE; i++) diff --git a/src/ls_lex.c b/src/ls_lex.c index f8ff0d0..186e789 100644 --- a/src/ls_lex.c +++ b/src/ls_lex.c @@ -103,8 +103,6 @@ void ls_lex(ls_context_t * ctx, ls_token_t * tok) break; case CH_KIND_LINESEP: - ctx->line++; - // fall through case CH_KIND_SEP: tok->ty = LS_TOK_STATEMENT_SEP; break; @@ -312,7 +310,6 @@ static void _lex_num(ls_context_t * ctx, ls_token_t * tok, ls_uchar ch[2]) ls_label_cache_t * lc = &ctx->label_cache[ctx->label_cache_i]; lc->pc = (ls_addr_t)(ctx->pc + 1); - lc->line = ctx->line; lc->num = (ls_addr_t)(tok->body.number_val); tok->ty = LS_TOK_NUM_LABEL; } @@ -399,7 +396,6 @@ static void _lex_word(ls_context_t * ctx, ls_token_t * tok, ls_uchar ch[2]) strncpy(label->body.label.ident, tok->body.word_val, LS_IDENT_LEN); label->body.label.pc = ctx->pc; - label->prev = (void *) (uintptr_t) ctx->line; ctx->labels = label; } } diff --git a/src/ls_types.h b/src/ls_types.h index 567b926..9df404e 100644 --- a/src/ls_types.h +++ b/src/ls_types.h @@ -205,7 +205,6 @@ typedef struct ls_value_s { /// Internal types: /// - Stack frames: PREV points at the stack frame above this one. /// NEXT points at the variable scope. - /// - Labels: PREV contains a line number cast to a pointer (sorry) /// - Others: as defined in those types' documentation. struct ls_value_s * prev, * next; union { @@ -231,7 +230,6 @@ typedef struct ls_value_s { /// needing to scan the code. typedef struct { ls_addr_t pc; - uint16_t line; uint16_t num; } ls_label_cache_t; |