Change output format for line+col.

This commit is contained in:
Calvin Rose 2021-01-30 11:33:15 -06:00
parent 04805d106e
commit 72ec89dfe9
5 changed files with 69 additions and 32 deletions

View File

@ -1,6 +1,11 @@
# Changelog
All notable changes to this project will be documented in this file.
## Unreleased - ???
- Fix bug where a buffer overflow could be confused with an out of memory error.
- Change error output to `file:line:column: message`. Column is in bytes - tabs
are considered to have width 1 (instead of 8).
## 1.14.2 - 2021-01-23
- Allow `JANET_PROFILE` env variable to load a profile before loading the repl.
- Update `tracev` macro to allow `def` and `var` inside to work as expected.

View File

@ -2054,30 +2054,31 @@
(def [line col] (:where p))
(eprint
(if ec "\e[31m" "")
"parse error in "
where
" around line "
(string line)
", column "
(string col)
": "
":"
line
":"
col
": parse error: "
(:error p)
(if ec "\e[0m" ""))
(eflush))
(defn bad-compile
"Default handler for a compile error."
[msg macrof where]
[msg macrof where line col]
(def ec (dyn :err-color))
(eprin
(if ec "\e[31m" "")
where
":"
line
":"
col
": compile error: ")
(if macrof
(debug/stacktrace macrof (string msg " while compiling " where))
(eprint
(if ec "\e[31m" "")
"compile error: "
msg
" while compiling "
where
(if ec "\e[0m" "")))
(debug/stacktrace macrof msg)
(eprint msg (if ec "\e[0m" "")))
(eflush))
(defn curenv
@ -2130,7 +2131,7 @@
(default guard :ydt)
# Evaluate 1 source form in a protected manner
(defn eval1 [source]
(defn eval1 [source &opt l c]
(def source (if expand (expand source) source))
(var good true)
(var resumeval nil)
@ -2143,11 +2144,7 @@
(do
(set good false)
(def {:error err :line line :column column :fiber errf} res)
(def msg
(if (<= 0 line)
(string err " on line " line ", column " column)
err))
(on-compile-error msg errf where))))
(on-compile-error err errf where (or line l) (or column c)))))
guard))
(fiber/setenv f env)
(while (fiber/can-resume? f)
@ -2175,6 +2172,10 @@
(fiber/setenv f env)
(resume f))
(defn produce []
(def tup (p-produce p true))
[(in tup 0) ;(tuple/sourcemap tup)])
# Loop
(def buf @"")
(var parser-not-done true)
@ -2196,7 +2197,7 @@
(while (> len pindex)
(+= pindex (p-consume p buf pindex))
(while (p-has-more p)
(eval1 (p-produce p))
(eval1 ;(produce))
(if (env :exit) (break)))
(when (= (p-status p) :error)
(parse-err p where)
@ -2205,7 +2206,7 @@
# Check final parser state
(unless (env :exit)
(while (p-has-more p)
(eval1 (p-produce p))
(eval1 ;(produce))
(if (env :exit) (break)))
(when (= (p-status p) :error)
(parse-err p where)))
@ -2450,9 +2451,9 @@
(def [line col] (:where x))
(def pe (string (:error x) " in " y " around line " line ", column " col))
(set exit-error pe))
(defn bc [&opt x y z]
(defn bc [&opt x y z a b]
(when exit
(bad-compile x y z)
(bad-compile x y z a b)
(os/exit 1))
(put env :exit true)
(def ce (string x " while compiling " z))

View File

@ -872,8 +872,12 @@ 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("line"), janet_wrap_integer(res.error_mapping.line));
janet_table_put(t, janet_ckeywordv("column"), janet_wrap_integer(res.error_mapping.column));
if (res.error_mapping.line > 0) {
janet_table_put(t, janet_ckeywordv("line"), janet_wrap_integer(res.error_mapping.line));
}
if (res.error_mapping.column > 0) {
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));
}

View File

@ -175,7 +175,14 @@ static void popstate(JanetParser *p, Janet val) {
if (newtop->flags & PFLAG_CONTAINER) {
newtop->argn++;
/* Keep track of number of values in the root state */
if (p->statecount == 1) p->pending++;
if (p->statecount == 1) {
p->pending++;
/* Root items are always wrapped in a tuple for source map info. */
const Janet *tup = janet_tuple_n(&val, 1);
janet_tuple_sm_line(tup) = (int32_t) top.line;
janet_tuple_sm_column(tup) = (int32_t) top.column;
val = janet_wrap_tuple(tup);
}
push_arg(p, val);
return;
} else if (newtop->flags & PFLAG_READERMAC) {
@ -730,6 +737,19 @@ const char *janet_parser_error(JanetParser *parser) {
}
Janet janet_parser_produce(JanetParser *parser) {
Janet ret;
size_t i;
if (parser->pending == 0) return janet_wrap_nil();
ret = janet_unwrap_tuple(parser->args[0])[0];
for (i = 1; i < parser->argcount; i++) {
parser->args[i - 1] = parser->args[i];
}
parser->pending--;
parser->argcount--;
return ret;
}
Janet janet_parser_produce_wrapped(JanetParser *parser) {
Janet ret;
size_t i;
if (parser->pending == 0) return janet_wrap_nil();
@ -980,9 +1000,13 @@ static Janet cfun_parse_error(int32_t argc, Janet *argv) {
}
static Janet cfun_parse_produce(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1);
janet_arity(argc, 1, 2);
JanetParser *p = janet_getabstract(argv, 0, &janet_parser_type);
return janet_parser_produce(p);
if (argc == 2 && janet_truthy(argv[1])) {
return janet_parser_produce_wrapped(p);
} else {
return janet_parser_produce(p);
}
}
static Janet cfun_parse_flush(int32_t argc, Janet *argv) {
@ -1217,10 +1241,12 @@ static const JanetReg parse_cfuns[] = {
},
{
"parser/produce", cfun_parse_produce,
JDOC("(parser/produce parser)\n\n"
JDOC("(parser/produce parser &opt wrap)\n\n"
"Dequeue the next value in the parse queue. Will return nil if "
"no parsed values are in the queue, otherwise will dequeue the "
"next value.")
"next value. If `wrap` is truthy, will return a 1-element tuple that "
"wraps the result. This tuple can be used for source-mapping "
"purposes.")
},
{
"parser/consume", cfun_parse_consume,

View File

@ -1367,6 +1367,7 @@ JANET_API void janet_parser_deinit(JanetParser *parser);
JANET_API void janet_parser_consume(JanetParser *parser, uint8_t c);
JANET_API enum JanetParserStatus janet_parser_status(JanetParser *parser);
JANET_API Janet janet_parser_produce(JanetParser *parser);
JANET_API Janet janet_parser_produce_wrapped(JanetParser *parser);
JANET_API const char *janet_parser_error(JanetParser *parser);
JANET_API void janet_parser_flush(JanetParser *parser);
JANET_API void janet_parser_eof(JanetParser *parser);