Source mapping v4 (line and column instead of byte offsets).

This commit is contained in:
Calvin Rose 2018-06-29 11:12:33 -04:00
parent f93c84c21f
commit 28cf753fa2
8 changed files with 65 additions and 41 deletions

View File

@ -709,8 +709,8 @@ static DstAssembleResult dst_asm1(DstAssembler *parent, Dst source, int flags) {
if (!dst_checktype(tup[1], DST_INTEGER)) {
dst_asm_error(&a, "expected integer");
}
mapping.start = dst_unwrap_integer(tup[0]);
mapping.end = dst_unwrap_integer(tup[1]);
mapping.line = dst_unwrap_integer(tup[0]);
mapping.column = dst_unwrap_integer(tup[1]);
def->sourcemap[i] = mapping;
}
}
@ -868,8 +868,8 @@ Dst dst_disasm(DstFuncDef *def) {
for (i = 0; i < def->bytecode_length; i++) {
Dst *t = dst_tuple_begin(2);
DstSourceMapping mapping = def->sourcemap[i];
t[0] = dst_wrap_integer(mapping.start);
t[1] = dst_wrap_integer(mapping.end);
t[0] = dst_wrap_integer(mapping.line);
t[1] = dst_wrap_integer(mapping.column);
sourcemap->data[i] = dst_wrap_tuple(dst_tuple_end(t));
}
sourcemap->count = def->bytecode_length;

View File

@ -958,7 +958,9 @@ onvalue."
(while going
(switch (parser.status p)
:full (yield (parser.produce p))
:error (onerr where "parse" (string (parser.error p) " at byte index " byteindex))
:error (do
(def (line col) (parser.where p))
(onerr where "parse" (string (parser.error p) " on line " line ", column " col)))
(switch (fiber.status chars)
:new (parser.byte p (resume chars))
:pending (parser.byte p (resume chars))
@ -975,10 +977,10 @@ onvalue."
(res)
(do
(:= good false)
(def {:error err :error-start errs :error-end erre} res)
(def {:error err :error-line errl :error-column errc} res)
(onerr where "compile"
(if (<= 0 errs)
(string err " at (" errs ":" erre ")")
(if (< 0 errl)
(string err " on line " errl ", column " errc)
err)))))
:a))
(def res (resume f))
@ -1013,8 +1015,8 @@ onvalue."
:c c
:name name
:source source
:source-start source-start
:source-end source-end
:source-line source-line
:source-column source-col
} :in st]
(file.write stdout " in")
(when c (file.write stdout " cfunction"))
@ -1024,8 +1026,8 @@ onvalue."
(if source
(do
(file.write stdout " [" source "]")
(if source-start (file.write stdout " at byte range ("
(string source-start) ":" (string source-end) ")")))
(if source-line (file.write stdout " on line "
(string source-line) ", column " (string source-col))))
(if pc (file.write stdout " at (pc=" (string pc) ")")))
(when tail (file.write stdout " (tailcall)"))
(file.write stdout "\n"))))

View File

@ -35,11 +35,11 @@ static void dstc_ast_push(DstCompiler *c, const Dst *tup) {
if (c->result.status == DST_COMPILE_ERROR) {
return;
}
mapping.start = dst_tuple_sm_start(tup);
mapping.end = dst_tuple_sm_end(tup);
if (mapping.start < 0 || mapping.end < 0) {
mapping.line = dst_tuple_sm_line(tup);
mapping.column = dst_tuple_sm_col(tup);
if (!mapping.line) {
/* Reuse previous mapping */
mapping = dst_v_last(c->ast_stack);
mapping = c->current_mapping;
}
dst_v_push(c->ast_stack, mapping);
c->current_mapping = mapping;
@ -53,8 +53,8 @@ static void dstc_ast_pop(DstCompiler *c) {
if (dst_v_count(c->ast_stack)) {
c->current_mapping = dst_v_last(c->ast_stack);
} else {
c->current_mapping.start = -1;
c->current_mapping.end = -1;
c->current_mapping.line = 0;
c->current_mapping.column = 0;
}
}
@ -964,14 +964,14 @@ static void dstc_init(DstCompiler *c, DstTable *env, const uint8_t *where) {
c->env = env;
c->source = where;
c->ast_stack = NULL;
c->current_mapping.start = -1;
c->current_mapping.end = -1;
c->current_mapping.line = 0;
c->current_mapping.column = 0;
/* Init result */
c->result.error = NULL;
c->result.status = DST_COMPILE_OK;
c->result.funcdef = NULL;
c->result.error_mapping.start = -1;
c->result.error_mapping.end = -1;
c->result.error_mapping.line = 0;
c->result.error_mapping.column = 0;
}
/* Deinitialize a compiler struct */
@ -1033,8 +1033,8 @@ int dst_compile_cfun(DstArgs args) {
} else {
t = dst_table(2);
dst_table_put(t, dst_csymbolv(":error"), dst_wrap_string(res.error));
dst_table_put(t, dst_csymbolv(":error-start"), dst_wrap_integer(res.error_mapping.start));
dst_table_put(t, dst_csymbolv(":error-end"), dst_wrap_integer(res.error_mapping.end));
dst_table_put(t, dst_csymbolv(":error-line"), dst_wrap_integer(res.error_mapping.line));
dst_table_put(t, dst_csymbolv(":error-column"), dst_wrap_integer(res.error_mapping.column));
DST_RETURN_TABLE(args, t);
}
}

View File

@ -365,8 +365,8 @@ static Dst doframe(DstStackFrame *frame) {
dst_table_put(t, dst_csymbolv(":pc"), dst_wrap_integer(off));
if (def->sourcemap) {
DstSourceMapping mapping = def->sourcemap[off];
dst_table_put(t, dst_csymbolv(":source-start"), dst_wrap_integer(mapping.start));
dst_table_put(t, dst_csymbolv(":source-end"), dst_wrap_integer(mapping.end));
dst_table_put(t, dst_csymbolv(":source-line"), dst_wrap_integer(mapping.line));
dst_table_put(t, dst_csymbolv(":source-column"), dst_wrap_integer(mapping.column));
}
if (def->source) {
dst_table_put(t, dst_csymbolv(":source"), dst_wrap_string(def->source));

View File

@ -112,7 +112,8 @@ struct DstParseState {
int32_t qcount;
int32_t argn;
int flags;
size_t start;
size_t start_line;
size_t start_col;
Consumer consumer;
};
@ -155,7 +156,8 @@ static void pushstate(DstParser *p, Consumer consumer, int flags) {
s.argn = 0;
s.flags = flags;
s.consumer = consumer;
s.start = p->index;
s.start_line = p->line;
s.start_col = p->col;
_pushstate(p, s);
}
@ -168,8 +170,8 @@ static void popstate(DstParser *p, Dst val) {
/* Quote the returned value qcount times */
for (i = 0; i < len; i++) {
if (dst_checktype(val, DST_TUPLE)) {
dst_tuple_sm_start(dst_unwrap_tuple(val)) = (int32_t) top.start;
dst_tuple_sm_end(dst_unwrap_tuple(val)) = (int32_t) p->index;
dst_tuple_sm_line(dst_unwrap_tuple(val)) = (int32_t) top.start_line;
dst_tuple_sm_col(dst_unwrap_tuple(val)) = (int32_t) top.start_col;
}
val = quote(val);
}
@ -177,8 +179,8 @@ static void popstate(DstParser *p, Dst val) {
/* Ast wrap */
if (dst_checktype(val, DST_TUPLE)) {
dst_tuple_sm_start(dst_unwrap_tuple(val)) = (int32_t) top.start;
dst_tuple_sm_end(dst_unwrap_tuple(val)) = (int32_t) p->index;
dst_tuple_sm_line(dst_unwrap_tuple(val)) = (int32_t) top.start_line;
dst_tuple_sm_col(dst_unwrap_tuple(val)) = (int32_t) top.start_col;
}
newtop->argn++;
@ -518,7 +520,12 @@ static int root(DstParser *p, DstParseState *state, uint8_t c) {
int dst_parser_consume(DstParser *parser, uint8_t c) {
int consumed = 0;
if (parser->error) return 0;
parser->index++;
if (c == '\n') {
parser->line++;
parser->col = 0;
} else if (c != '\r') {
parser->col++;
}
while (!consumed && !parser->error) {
DstParseState *state = parser->states + parser->statecount - 1;
consumed = state->consumer(parser, state, c);
@ -575,7 +582,8 @@ void dst_parser_init(DstParser *parser) {
parser->statecount = 0;
parser->statecap = 0;
parser->error = NULL;
parser->index = 0;
parser->line = 1;
parser->col = 0;
parser->lookback = -1;
pushstate(parser, root, PFLAG_CONTAINER);
@ -722,6 +730,17 @@ static int cfun_flush(DstArgs args) {
DST_RETURN(args, args.v[0]);
}
static int cfun_where(DstArgs args) {
DstParser *p;
DST_FIXARITY(args, 1);
DST_CHECKABSTRACT(args, 0, &dst_parse_parsertype);
p = (DstParser *) dst_unwrap_abstract(args.v[0]);
Dst *tup = dst_tuple_begin(2);
tup[0] = dst_wrap_integer((int32_t)p->line);
tup[1] = dst_wrap_integer((int32_t)p->col);
DST_RETURN_TUPLE(args, dst_tuple_end(tup));
}
static int cfun_state(DstArgs args) {
size_t i;
const uint8_t *str;
@ -762,6 +781,7 @@ static const DstReg cfuns[] = {
{"parser.status", cfun_status},
{"parser.flush", cfun_flush},
{"parser.state", cfun_state},
{"parser.where", cfun_where},
{NULL, NULL}
};

View File

@ -33,8 +33,8 @@ Dst *dst_tuple_begin(int32_t length) {
char *data = dst_gcalloc(DST_MEMORY_TUPLE, 4 * sizeof(int32_t) + length * sizeof(Dst));
Dst *tuple = (Dst *)(data + (4 * sizeof(int32_t)));
dst_tuple_length(tuple) = length;
dst_tuple_sm_start(tuple) = -1;
dst_tuple_sm_end(tuple) = -1;
dst_tuple_sm_line(tuple) = 0;
dst_tuple_sm_col(tuple) = 0;
return tuple;
}

View File

@ -80,8 +80,8 @@ int dst_buffer_push_u64(DstBuffer *buffer, uint64_t x);
#define dst_tuple_raw(t) ((int32_t *)(t) - 4)
#define dst_tuple_length(t) (dst_tuple_raw(t)[0])
#define dst_tuple_hash(t) ((dst_tuple_raw(t)[1]))
#define dst_tuple_sm_start(t) ((dst_tuple_raw(t)[2]))
#define dst_tuple_sm_end(t) ((dst_tuple_raw(t)[3]))
#define dst_tuple_sm_line(t) ((dst_tuple_raw(t)[2]))
#define dst_tuple_sm_col(t) ((dst_tuple_raw(t)[3]))
Dst *dst_tuple_begin(int32_t length);
const Dst *dst_tuple_end(Dst *tuple);
const Dst *dst_tuple_n(Dst *values, int32_t n);

View File

@ -462,9 +462,10 @@ struct DstKV {
#define DST_FUNCDEF_FLAG_VARARG 1
#define DST_FUNCDEF_FLAG_NEEDSENV 4
/* Source mapping structure for a bytecode instruction */
struct DstSourceMapping {
int32_t start;
int32_t end;
int32_t line;
int32_t column;
};
/* A function definition. Contains information needed to instantiate closures. */
@ -529,7 +530,8 @@ struct DstParser {
size_t statecap;
size_t bufcount;
size_t bufcap;
size_t index;
size_t line;
size_t col;
int lookback;
};