From a8afc5b81f46615b451175d081d65664a00cd72f Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 22 Sep 2019 17:18:28 -0500 Subject: [PATCH] Sourcemapping uses line, column instead of offsets. This should be friendlier to most users. It does, however, mean we lose range information. However, range information could be recovered by re-parsing, as janet's grammar is simple enough to do this. --- Makefile | 2 +- src/boot/boot.janet | 30 ++++++++++---- src/core/asm.c | 75 ++++++++++++++++++++-------------- src/core/compile.c | 18 ++++---- src/core/debug.c | 86 ++++++++++++--------------------------- src/core/marsh.c | 11 +++-- src/core/parse.c | 61 +++++++++++++++------------ src/core/specials.c | 4 +- src/core/tuple.c | 24 +++++------ src/core/vm.c | 2 +- src/include/janet.h | 17 ++++---- src/mainclient/init.janet | 4 +- test/suite7.janet | 7 ++++ 13 files changed, 177 insertions(+), 164 deletions(-) diff --git a/Makefile b/Makefile index 54c434a4..7ced00a7 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ MANPATH?=$(PREFIX)/share/man/man1/ PKG_CONFIG_PATH?=$(PREFIX)/lib/pkgconfig DEBUGGER=gdb -CFLAGS=-std=c99 -Wall -Wextra -Isrc/include -Isrc/conf -fpic -O2 -fvisibility=hidden \ +CFLAGS=-std=c99 -Wall -Wextra -Isrc/include -Isrc/conf -fpic -O0 -g -fvisibility=hidden \ -DJANET_BUILD=$(JANET_BUILD) LDFLAGS=-rdynamic diff --git a/src/boot/boot.janet b/src/boot/boot.janet index bd0630f3..f84c80f8 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -1598,19 +1598,33 @@ (defn bad-parse "Default handler for a parse error." [p where] + (def ec (dyn :err-color)) + (def [line col] (parser/where p)) (file/write stderr + (if ec "\e[31m" "") "parse error in " where - " around byte " - (string (parser/where p)) + " around line " + (string line) + ", column " + (string col) ": " (parser/error p) + (if ec "\e[0m" "") "\n")) (defn bad-compile "Default handler for a compile error." [msg macrof where] - (file/write stderr "compile error: " msg " while compiling " where "\n") + (def ec (dyn :err-color)) + (file/write stderr + (if ec "\e[31m" "") + "compile error: " + msg + " while compiling " + where + (if ec "\e[0m" "") + "\n") (when macrof (debug/stacktrace macrof))) (defn run-context @@ -1660,10 +1674,10 @@ (unless compile-only (res)) (do (set good false) - (def {:error err :start start :end end :fiber errf} res) + (def {:error err :line line :column column :fiber errf} res) (def msg - (if (<= 0 start) - (string err " at (" start ":" end ")") + (if (<= 0 line) + (string err " on line " line ", column " column) err)) (on-compile-error msg errf where)))) (or guard :a))) @@ -1946,7 +1960,7 @@ (def level (+ (dyn :debug-level 0) 1)) (default env (make-env)) (default chunks (fn [buf p] (getline (string "repl:" - (parser/where p) + ((parser/where p) 0) ":" (parser/state p :delimiters) "> ") buf))) @@ -1967,7 +1981,7 @@ _fiber is bound to the suspended fiber ```) (repl (fn [buf p] (def status (parser/state p :delimiters)) - (def c (parser/where p)) + (def c ((parser/where p) 0)) (def prompt (string "debug[" level "]:" c ":" status "> ")) (getline prompt buf)) onsignal nextenv)) diff --git a/src/core/asm.c b/src/core/asm.c index ae699b1e..d27aef6f 100644 --- a/src/core/asm.c +++ b/src/core/asm.c @@ -705,8 +705,8 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int if (!janet_checkint(tup[1])) { janet_asm_error(&a, "expected integer"); } - mapping.start = janet_unwrap_integer(tup[0]); - mapping.end = janet_unwrap_integer(tup[1]); + mapping.line = janet_unwrap_integer(tup[0]); + mapping.column = janet_unwrap_integer(tup[1]); def->sourcemap[i] = mapping; } } @@ -749,31 +749,31 @@ static const JanetInstructionDef *janet_asm_reverse_lookup(uint32_t instr) { } /* Create some constant sized tuples */ -static Janet tup1(Janet x) { +static const Janet *tup1(Janet x) { Janet *tup = janet_tuple_begin(1); tup[0] = x; - return janet_wrap_tuple(janet_tuple_end(tup)); + return janet_tuple_end(tup); } -static Janet tup2(Janet x, Janet y) { +static const Janet *tup2(Janet x, Janet y) { Janet *tup = janet_tuple_begin(2); tup[0] = x; tup[1] = y; - return janet_wrap_tuple(janet_tuple_end(tup)); + return janet_tuple_end(tup); } -static Janet tup3(Janet x, Janet y, Janet z) { +static const Janet *tup3(Janet x, Janet y, Janet z) { Janet *tup = janet_tuple_begin(3); tup[0] = x; tup[1] = y; tup[2] = z; - return janet_wrap_tuple(janet_tuple_end(tup)); + return janet_tuple_end(tup); } -static Janet tup4(Janet w, Janet x, Janet y, Janet z) { +static const Janet *tup4(Janet w, Janet x, Janet y, Janet z) { Janet *tup = janet_tuple_begin(4); tup[0] = w; tup[1] = x; tup[2] = y; tup[3] = z; - return janet_wrap_tuple(janet_tuple_end(tup)); + return janet_tuple_end(tup); } /* Given an argument, convert it to the appropriate integer or symbol */ @@ -784,41 +784,56 @@ Janet janet_asm_decode_instruction(uint32_t instr) { return janet_wrap_integer((int32_t)instr); } name = janet_csymbolv(def->name); + const Janet *ret = NULL; #define oparg(shift, mask) ((instr >> ((shift) << 3)) & (mask)) switch (janet_instructions[def->opcode]) { case JINT_0: - return tup1(name); + ret = tup1(name); + break; case JINT_S: - return tup2(name, janet_wrap_integer(oparg(1, 0xFFFFFF))); + ret = tup2(name, janet_wrap_integer(oparg(1, 0xFFFFFF))); + break; case JINT_L: - return tup2(name, janet_wrap_integer((int32_t)instr >> 8)); + ret = tup2(name, janet_wrap_integer((int32_t)instr >> 8)); + break; case JINT_SS: case JINT_ST: case JINT_SC: case JINT_SU: case JINT_SD: - return tup3(name, - janet_wrap_integer(oparg(1, 0xFF)), - janet_wrap_integer(oparg(2, 0xFFFF))); + ret = tup3(name, + janet_wrap_integer(oparg(1, 0xFF)), + janet_wrap_integer(oparg(2, 0xFFFF))); + break; case JINT_SI: case JINT_SL: - return tup3(name, - janet_wrap_integer(oparg(1, 0xFF)), - janet_wrap_integer((int32_t)instr >> 16)); + ret = tup3(name, + janet_wrap_integer(oparg(1, 0xFF)), + janet_wrap_integer((int32_t)instr >> 16)); + break; case JINT_SSS: case JINT_SES: case JINT_SSU: - return tup4(name, - janet_wrap_integer(oparg(1, 0xFF)), - janet_wrap_integer(oparg(2, 0xFF)), - janet_wrap_integer(oparg(3, 0xFF))); + ret = tup4(name, + janet_wrap_integer(oparg(1, 0xFF)), + janet_wrap_integer(oparg(2, 0xFF)), + janet_wrap_integer(oparg(3, 0xFF))); + break; case JINT_SSI: - return tup4(name, - janet_wrap_integer(oparg(1, 0xFF)), - janet_wrap_integer(oparg(2, 0xFF)), - janet_wrap_integer((int32_t)instr >> 24)); + ret = tup4(name, + janet_wrap_integer(oparg(1, 0xFF)), + janet_wrap_integer(oparg(2, 0xFF)), + janet_wrap_integer((int32_t)instr >> 24)); + break; } #undef oparg + if (ret) { + /* Check if break point set */ + if (instr & 0x80) { + janet_tuple_flag(ret) |= JANET_TUPLE_FLAG_BRACKETCTOR; + } + return janet_wrap_tuple(ret); + } return janet_wrap_nil(); } @@ -849,7 +864,7 @@ Janet janet_disasm(JanetFuncDef *def) { Janet src = def->constants[i]; Janet dest; if (janet_checktype(src, JANET_TUPLE)) { - dest = tup2(janet_csymbolv("quote"), src); + dest = janet_wrap_tuple(tup2(janet_csymbolv("quote"), src)); } else { dest = src; } @@ -870,8 +885,8 @@ Janet janet_disasm(JanetFuncDef *def) { for (i = 0; i < def->bytecode_length; i++) { Janet *t = janet_tuple_begin(2); JanetSourceMapping mapping = def->sourcemap[i]; - t[0] = janet_wrap_integer(mapping.start); - t[1] = janet_wrap_integer(mapping.end); + t[0] = janet_wrap_integer(mapping.line); + t[1] = janet_wrap_integer(mapping.column); sourcemap->data[i] = janet_wrap_tuple(janet_tuple_end(t)); } sourcemap->count = def->bytecode_length; diff --git a/src/core/compile.c b/src/core/compile.c index 64dc5bad..cb33293b 100644 --- a/src/core/compile.c +++ b/src/core/compile.c @@ -474,9 +474,9 @@ static int macroexpand1( if (janet_tuple_length(form) == 0) return 0; /* Source map - only set when we get a tuple */ - if (janet_tuple_sm_start(form) >= 0) { - c->current_mapping.start = janet_tuple_sm_start(form); - c->current_mapping.end = janet_tuple_sm_end(form); + if (janet_tuple_sm_line(form) >= 0) { + c->current_mapping.line = janet_tuple_sm_line(form); + c->current_mapping.column = janet_tuple_sm_column(form); } /* Bracketed tuples are not specials or macros! */ if (janet_tuple_flag(form) & JANET_TUPLE_FLAG_BRACKETCTOR) @@ -664,15 +664,15 @@ static void janetc_init(JanetCompiler *c, JanetTable *env, const uint8_t *where) c->recursion_guard = JANET_RECURSION_GUARD; c->env = env; c->source = where; - c->current_mapping.start = -1; - c->current_mapping.end = -1; + c->current_mapping.line = -1; + c->current_mapping.column = -1; /* Init result */ c->result.error = NULL; c->result.status = JANET_COMPILE_OK; c->result.funcdef = NULL; c->result.macrofiber = NULL; - c->result.error_mapping.start = -1; - c->result.error_mapping.end = -1; + c->result.error_mapping.line = -1; + c->result.error_mapping.column = -1; } /* Deinitialize a compiler struct */ @@ -733,8 +733,8 @@ static Janet cfun(int32_t argc, Janet *argv) { } else { JanetTable *t = janet_table(4); janet_table_put(t, janet_ckeywordv("error"), janet_wrap_string(res.error)); - janet_table_put(t, janet_ckeywordv("start"), janet_wrap_integer(res.error_mapping.start)); - janet_table_put(t, janet_ckeywordv("end"), janet_wrap_integer(res.error_mapping.end)); + janet_table_put(t, janet_ckeywordv("line"), janet_wrap_integer(res.error_mapping.line)); + janet_table_put(t, janet_ckeywordv("column"), janet_wrap_integer(res.error_mapping.column)); if (res.macrofiber) { janet_table_put(t, janet_ckeywordv("fiber"), janet_wrap_fiber(res.macrofiber)); } diff --git a/src/core/debug.c b/src/core/debug.c index 04c11b5c..e91c02c6 100644 --- a/src/core/debug.c +++ b/src/core/debug.c @@ -52,31 +52,34 @@ void janet_debug_unbreak(JanetFuncDef *def, int32_t pc) { */ void janet_debug_find( JanetFuncDef **def_out, int32_t *pc_out, - const uint8_t *source, int32_t offset) { + const uint8_t *source, int32_t sourceLine, int32_t sourceColumn) { /* Scan the heap for right func def */ JanetGCObject *current = janet_vm_blocks; /* Keep track of the best source mapping we have seen so far */ int32_t besti = -1; - int32_t best_range = INT32_MAX; + int32_t best_line = -1; + int32_t best_column = -1; JanetFuncDef *best_def = NULL; while (NULL != current) { if ((current->flags & JANET_MEM_TYPEBITS) == JANET_MEMORY_FUNCDEF) { - JanetFuncDef *def = (JanetFuncDef *)(current + 1); + JanetFuncDef *def = (JanetFuncDef *)(current); if (def->sourcemap && def->source && !janet_string_compare(source, def->source)) { /* Correct source file, check mappings. The chosen - * pc index is the first match with the smallest range. */ + * pc index is the instruction closest to the given line column, but + * not after. */ int32_t i; for (i = 0; i < def->bytecode_length; i++) { - int32_t start = def->sourcemap[i].start; - int32_t end = def->sourcemap[i].end; - if (end - start < best_range && - start <= offset && - end >= offset) { - best_range = end - start; - besti = i; - best_def = def; + int32_t line = def->sourcemap[i].line; + int32_t column = def->sourcemap[i].column; + if (line <= sourceLine && line >= best_line) { + if (column <= sourceColumn && column > best_column) { + best_line = line; + best_column = column; + besti = i; + best_def = def; + } } } } @@ -150,44 +153,8 @@ void janet_stacktrace(JanetFiber *fiber, Janet err) { if (frame->func && frame->pc) { int32_t off = (int32_t)(frame->pc - def->bytecode); if (def->sourcemap) { - /* Try to get line and column information */ JanetSourceMapping mapping = def->sourcemap[off]; - char buf[1024]; - size_t nread; - int32_t offset = 0; - int32_t line = 1; - int32_t col = 1; - int notdone = 1; - char last = 0; - FILE *f; - if (def->source && (f = fopen((const char *)def->source, "rb"))) { - while (notdone && (nread = fread(buf, 1, sizeof(buf), f)) > 0) { - for (size_t i = 0; i < nread; i++) { - char c = buf[i]; - if (c == '\r') { - line++; - col = 1; - } else if (c == '\n') { - col = 1; - if (last != '\r') { - line++; - } - } else { - col++; - } - last = c; - if (offset == mapping.start) { - fprintf(out, " on line %d, column %d", line, col); - notdone = 0; - break; - } - offset++; - } - } - fclose(f); - } else { - fprintf(out, " at (%d:%d)", mapping.start, mapping.end); - } + fprintf(out, " on line %d, column %d", mapping.line, mapping.column); } else { fprintf(out, " pc=%d", off); } @@ -208,10 +175,11 @@ void janet_stacktrace(JanetFiber *fiber, Janet err) { /* Helper to find funcdef and bytecode offset to insert or remove breakpoints. * Takes a source file name and byte offset. */ static void helper_find(int32_t argc, Janet *argv, JanetFuncDef **def, int32_t *bytecode_offset) { - janet_fixarity(argc, 2); + janet_fixarity(argc, 3); const uint8_t *source = janet_getstring(argv, 0); - int32_t source_offset = janet_getinteger(argv, 1); - janet_debug_find(def, bytecode_offset, source, source_offset); + int32_t line = janet_getinteger(argv, 1); + int32_t col = janet_getinteger(argv, 2); + janet_debug_find(def, bytecode_offset, source, line, col); } /* Helper to find funcdef and bytecode offset to insert or remove breakpoints. @@ -298,8 +266,8 @@ static Janet doframe(JanetStackFrame *frame) { janet_table_put(t, janet_ckeywordv("pc"), janet_wrap_integer(off)); if (def->sourcemap) { JanetSourceMapping mapping = def->sourcemap[off]; - janet_table_put(t, janet_ckeywordv("source-start"), janet_wrap_integer(mapping.start)); - janet_table_put(t, janet_ckeywordv("source-end"), janet_wrap_integer(mapping.end)); + janet_table_put(t, janet_ckeywordv("source-line"), janet_wrap_integer(mapping.line)); + janet_table_put(t, janet_ckeywordv("source-column"), janet_wrap_integer(mapping.column)); } if (def->source) { janet_table_put(t, janet_ckeywordv("source"), janet_wrap_string(def->source)); @@ -349,17 +317,17 @@ static const JanetReg debug_cfuns[] = { { "debug/break", cfun_debug_break, JDOC("(debug/break source byte-offset)\n\n" - "Sets a breakpoint with source a key at a given byte offset. An offset " - "of 0 is the first byte in a file. Will throw an error if the breakpoint location " + "Sets a breakpoint with source a key at a given line and column. " + "Will throw an error if the breakpoint location " "cannot be found. For example\n\n" "\t(debug/break \"core.janet\" 1000)\n\n" "wil set a breakpoint at the 1000th byte of the file core.janet.") }, { "debug/unbreak", cfun_debug_unbreak, - JDOC("(debug/unbreak source byte-offset)\n\n" - "Remove a breakpoint with a source key at a given byte offset. An offset " - "of 0 is the first byte in a file. Will throw an error if the breakpoint " + JDOC("(debug/unbreak source line column)\n\n" + "Remove a breakpoint with a source key at a given line and column. " + "Will throw an error if the breakpoint " "cannot be found.") }, { diff --git a/src/core/marsh.c b/src/core/marsh.c index 83a37d1a..4f50e118 100644 --- a/src/core/marsh.c +++ b/src/core/marsh.c @@ -258,9 +258,9 @@ static void marshal_one_def(MarshalState *st, JanetFuncDef *def, int flags) { int32_t current = 0; for (int32_t i = 0; i < def->bytecode_length; i++) { JanetSourceMapping map = def->sourcemap[i]; - pushint(st, map.start - current); - pushint(st, map.end - map.start); - current = map.end; + pushint(st, map.line - current); + pushint(st, map.column); + current = map.line; } } } @@ -827,9 +827,8 @@ static const uint8_t *unmarshal_one_def( } for (int32_t i = 0; i < bytecode_length; i++) { current += readint(st, &data); - def->sourcemap[i].start = current; - current += readint(st, &data); - def->sourcemap[i].end = current; + def->sourcemap[i].line = current; + def->sourcemap[i].column = readint(st, &data); } } else { def->sourcemap = NULL; diff --git a/src/core/parse.c b/src/core/parse.c index e19bff42..eb4ad24a 100644 --- a/src/core/parse.c +++ b/src/core/parse.c @@ -106,7 +106,8 @@ struct JanetParseState { int32_t counter; int32_t argn; int flags; - size_t start; + size_t line; + size_t column; Consumer consumer; }; @@ -153,7 +154,8 @@ static void pushstate(JanetParser *p, Consumer consumer, int flags) { s.argn = 0; s.flags = flags; s.consumer = consumer; - s.start = p->offset; + s.line = p->line; + s.column = p->column; _pushstate(p, s); } @@ -164,8 +166,8 @@ static void popstate(JanetParser *p, Janet val) { if (newtop->flags & PFLAG_CONTAINER) { /* Source mapping info */ if (janet_checktype(val, JANET_TUPLE)) { - janet_tuple_sm_start(janet_unwrap_tuple(val)) = (int32_t) top.start; - janet_tuple_sm_end(janet_unwrap_tuple(val)) = (int32_t) p->offset; + janet_tuple_sm_line(janet_unwrap_tuple(val)) = (int32_t) top.line; + janet_tuple_sm_column(janet_unwrap_tuple(val)) = (int32_t) top.column; } newtop->argn++; /* Keep track of number of values in the root state */ @@ -184,8 +186,8 @@ static void popstate(JanetParser *p, Janet val) { t[0] = janet_csymbolv(which); t[1] = val; /* Quote source mapping info */ - janet_tuple_sm_start(t) = (int32_t) newtop->start; - janet_tuple_sm_end(t) = (int32_t) p->offset; + janet_tuple_sm_line(t) = (int32_t) newtop->line; + janet_tuple_sm_column(t) = (int32_t) newtop->column; val = janet_wrap_tuple(janet_tuple_end(t)); } else { return; @@ -562,7 +564,16 @@ static void janet_parser_checkdead(JanetParser *parser) { void janet_parser_consume(JanetParser *parser, uint8_t c) { int consumed = 0; janet_parser_checkdead(parser); - parser->offset++; + if (c == '\r') { + parser->line++; + parser->column = 0; + } else if (c == '\n') { + parser->column = 0; + if (parser->lookback != '\r') + parser->line++; + } else { + parser->column++; + } while (!consumed && !parser->error) { JanetParseState *state = parser->states + parser->statecount - 1; consumed = state->consumer(parser, state, c); @@ -572,11 +583,14 @@ void janet_parser_consume(JanetParser *parser, uint8_t c) { void janet_parser_eof(JanetParser *parser) { janet_parser_checkdead(parser); + size_t oldcolumn = parser->column; + size_t oldline = parser->line; janet_parser_consume(parser, '\n'); if (parser->statecount > 1) { parser->error = "unexpected end of source"; } - parser->offset--; + parser->line = oldline; + parser->column = oldcolumn; parser->flag = 1; } @@ -630,7 +644,8 @@ void janet_parser_init(JanetParser *parser) { parser->statecap = 0; parser->error = NULL; parser->lookback = -1; - parser->offset = 0; + parser->line = 1; + parser->column = 0; parser->pending = 0; parser->flag = 0; @@ -648,7 +663,8 @@ void janet_parser_clone(const JanetParser *src, JanetParser *dest) { dest->flag = src->flag; dest->pending = src->pending; dest->lookback = src->lookback; - dest->offset = src->offset; + dest->line = src->line; + dest->column = src->column; dest->error = src->error; /* Keep counts */ @@ -771,7 +787,7 @@ static Janet cfun_parse_insert(int32_t argc, Janet *argv) { JanetParseState *s = p->states + p->statecount - 1; if (s->consumer == tokenchar) { janet_parser_consume(p, ' '); - p->offset--; + p->column--; s = p->states + p->statecount - 1; } if (s->flags & PFLAG_CONTAINER) { @@ -855,15 +871,12 @@ static Janet cfun_parse_flush(int32_t argc, Janet *argv) { } static Janet cfun_parse_where(int32_t argc, Janet *argv) { - janet_arity(argc, 1, 2); + janet_fixarity(argc, 1); JanetParser *p = janet_getabstract(argv, 0, &janet_parse_parsertype); - if (argc > 1) { - int32_t offset = janet_getinteger(argv, 1); - p->offset = offset; - return argv[0]; - } else { - return janet_wrap_integer(p->offset); - } + Janet *tup = janet_tuple_begin(2); + tup[0] = janet_wrap_integer(p->line); + tup[1] = janet_wrap_integer(p->column); + return janet_wrap_tuple(janet_tuple_end(tup)); } static Janet janet_wrap_parse_state(JanetParseState *s, Janet *args, @@ -928,8 +941,8 @@ static Janet janet_wrap_parse_state(JanetParseState *s, Janet *args, janet_table_put(state, janet_ckeywordv("buffer"), janet_wrap_string(buffer)); } - janet_table_put(state, janet_ckeywordv("start"), - janet_wrap_integer(s->start)); + janet_table_put(state, janet_ckeywordv("line"), janet_wrap_integer(s->line)); + janet_table_put(state, janet_ckeywordv("column"), janet_wrap_integer(s->column)); return janet_wrap_table(state); } @@ -1121,10 +1134,8 @@ static const JanetReg parse_cfuns[] = { }, { "parser/where", cfun_parse_where, - JDOC("(parser/where parser &opt offset)\n\n" - "Returns the current line number and column number of the parser's location " - "in the byte stream as an index, counted from 0. " - "If offset is supplied, then the byte offset is updated to that new value.") + JDOC("(parser/where parser)\n\n" + "Returns the current line number and column of the parser's internal state.") }, { "parser/eof", cfun_parse_eof, diff --git a/src/core/specials.c b/src/core/specials.c index 8be85bdc..8e10594a 100644 --- a/src/core/specials.c +++ b/src/core/specials.c @@ -175,8 +175,8 @@ static int destructure(JanetCompiler *c, static const Janet *janetc_make_sourcemap(JanetCompiler *c) { Janet *tup = janet_tuple_begin(3); tup[0] = c->source ? janet_wrap_string(c->source) : janet_wrap_nil(); - tup[1] = janet_wrap_integer(c->current_mapping.start); - tup[2] = janet_wrap_integer(c->current_mapping.end); + tup[1] = janet_wrap_integer(c->current_mapping.line); + tup[2] = janet_wrap_integer(c->current_mapping.column); return janet_tuple_end(tup); } diff --git a/src/core/tuple.c b/src/core/tuple.c index 9d367155..1e33d5c2 100644 --- a/src/core/tuple.c +++ b/src/core/tuple.c @@ -33,8 +33,8 @@ Janet *janet_tuple_begin(int32_t length) { size_t size = sizeof(JanetTupleHead) + (length * sizeof(Janet)); JanetTupleHead *head = janet_gcalloc(JANET_MEMORY_TUPLE, size); - head->sm_start = -1; - head->sm_end = -1; + head->sm_line = -1; + head->sm_column = -1; head->length = length; return (Janet *)(head->data); } @@ -119,16 +119,16 @@ static Janet cfun_tuple_sourcemap(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); const Janet *tup = janet_gettuple(argv, 0); Janet contents[2]; - contents[0] = janet_wrap_integer(janet_tuple_head(tup)->sm_start); - contents[1] = janet_wrap_integer(janet_tuple_head(tup)->sm_end); + contents[0] = janet_wrap_integer(janet_tuple_head(tup)->sm_line); + contents[1] = janet_wrap_integer(janet_tuple_head(tup)->sm_column); return janet_wrap_tuple(janet_tuple_n(contents, 2)); } static Janet cfun_tuple_setmap(int32_t argc, Janet *argv) { janet_fixarity(argc, 3); const Janet *tup = janet_gettuple(argv, 0); - janet_tuple_head(tup)->sm_start = janet_getinteger(argv, 1); - janet_tuple_head(tup)->sm_end = janet_getinteger(argv, 2); + janet_tuple_head(tup)->sm_line = janet_getinteger(argv, 1); + janet_tuple_head(tup)->sm_column = janet_getinteger(argv, 2); return argv[0]; } @@ -158,16 +158,14 @@ static const JanetReg tuple_cfuns[] = { { "tuple/sourcemap", cfun_tuple_sourcemap, JDOC("(tuple/sourcemap tup)\n\n" - "Returns the sourcemap metadata attached to a tuple. " - "The mapping is represented by a pair of byte offsets into the " - "the source code representing the start and end byte indices where " - "the tuple is. ") + "Returns the sourcemap metadata attached to a tuple, " + " which is another tuple (line, column).") }, { "tuple/setmap", cfun_tuple_setmap, - JDOC("(tuple/setmap tup start end)\n\n" - "Set the sourcemap metadata on a tuple. start and end should " - "be integers representing byte offsets into the file. Returns tup.") + JDOC("(tuple/setmap tup line column)\n\n" + "Set the sourcemap metadata on a tuple. line and column indicate " + "should be integers.") }, {NULL, NULL, NULL} }; diff --git a/src/core/vm.c b/src/core/vm.c index 07802701..082297e5 100644 --- a/src/core/vm.c +++ b/src/core/vm.c @@ -58,7 +58,7 @@ JANET_THREAD_LOCAL jmp_buf *janet_vm_jmp_buf = NULL; * a switch inside an infinite loop. For GCC/clang, we use * computed gotos. */ #if defined(__GNUC__) && !defined(__EMSCRIPTEN__) -#define JANET_USE_COMPUTED_GOTOS +/*#define JANET_USE_COMPUTED_GOTOS*/ #endif #ifdef JANET_USE_COMPUTED_GOTOS diff --git a/src/include/janet.h b/src/include/janet.h index 27aa71eb..4ad7d7e8 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -755,8 +755,8 @@ struct JanetTupleHead { JanetGCObject gc; int32_t length; int32_t hash; - int32_t sm_start; - int32_t sm_end; + int32_t sm_line; + int32_t sm_column; const Janet data[]; }; @@ -798,8 +798,8 @@ struct JanetAbstractHead { /* Source mapping structure for a bytecode instruction */ struct JanetSourceMapping { - int32_t start; - int32_t end; + int32_t line; + int32_t column; }; /* A function definition. Contains information needed to instantiate closures. */ @@ -869,7 +869,8 @@ struct JanetParser { size_t statecap; size_t bufcount; size_t bufcap; - size_t offset; + size_t line; + size_t column; size_t pending; int lookback; int flag; @@ -1100,7 +1101,7 @@ JANET_API void janet_debug_break(JanetFuncDef *def, int32_t pc); JANET_API void janet_debug_unbreak(JanetFuncDef *def, int32_t pc); JANET_API void janet_debug_find( JanetFuncDef **def_out, int32_t *pc_out, - const uint8_t *source, int32_t offset); + const uint8_t *source, int32_t line, int32_t column); /* Array functions */ JANET_API JanetArray *janet_array(int32_t capacity); @@ -1133,8 +1134,8 @@ JANET_API void janet_buffer_push_u64(JanetBuffer *buffer, uint64_t x); #define janet_tuple_head(t) ((JanetTupleHead *)((char *)t - offsetof(JanetTupleHead, data))) #define janet_tuple_length(t) (janet_tuple_head(t)->length) #define janet_tuple_hash(t) (janet_tuple_head(t)->hash) -#define janet_tuple_sm_start(t) (janet_tuple_head(t)->sm_start) -#define janet_tuple_sm_end(t) (janet_tuple_head(t)->sm_end) +#define janet_tuple_sm_line(t) (janet_tuple_head(t)->sm_line) +#define janet_tuple_sm_column(t) (janet_tuple_head(t)->sm_column) #define janet_tuple_flag(t) (janet_tuple_head(t)->gc.flags) JANET_API Janet *janet_tuple_begin(int32_t length); JANET_API const Janet *janet_tuple_end(Janet *tuple); diff --git a/src/mainclient/init.janet b/src/mainclient/init.janet index 9b34bc60..4030ca1e 100644 --- a/src/mainclient/init.janet +++ b/src/mainclient/init.janet @@ -80,8 +80,8 @@ (print "Janet " janet/version "-" janet/build " Copyright (C) 2017-2019 Calvin Rose")) (defn noprompt [_] "") (defn getprompt [p] - (def offset (parser/where p)) - (string "janet:" offset ":" (parser/state p :delimiters) "> ")) + (def [line] (parser/where p)) + (string "janet:" line ":" (parser/state p :delimiters) "> ")) (def prompter (if *quiet* noprompt getprompt)) (defn getstdin [prompt buf] (file/write stdout prompt) diff --git a/test/suite7.janet b/test/suite7.janet index 749d566e..476586e5 100644 --- a/test/suite7.janet +++ b/test/suite7.janet @@ -155,5 +155,12 @@ (assert (= (|(+ $1 $1 $1 $1) 2 4) 16) "function shorthand 8") (assert (= (|(+ $0 $1 $3 $2 $6) 0 1 2 3 4 5 6) 12) "function shorthand 9") +# Simple function break +(debug/fbreak map) +(def f (fiber/new (fn [] (map inc [1 2 3])) :a)) +(resume f) +(assert (= :debug (fiber/status f)) "debug/fbreak") +(debug/unfbreak map) +(map inc [1 2 3]) (end-suite)