Fix sourcemapping bug with closures, add some library functions

to boot.dst
This commit is contained in:
Calvin Rose 2018-06-29 19:44:33 -04:00
parent 11ced5b582
commit 1ea9ebf04f
3 changed files with 37 additions and 28 deletions

View File

@ -1,13 +1,14 @@
# An example file that errors out. Run with ./dst examples/error.dst
# to see stack trace for runtime errors.
(defn bark [x]
(print "Woof!")
(print x)
(error x)
(print "Woof!"))
(defn bork [x]
(defn bark [x]
(print "Woof!")
(print x)
(error x)
(print "Woof!"))
(bark (* 2 x))
(bark (* 3 x)))

View File

@ -248,10 +248,10 @@ value."
(switch
verb
:in-while (do
(def preds @['and (tuple := bindings object)])
(def preds @['and (tuple ':= bindings object)])
(def subloop (doone (+ i 3) preds))
(tuple 'do
(tuple 'var bindings)
(tuple 'var bindings nil)
(tuple 'while (apply1 tuple preds)
subloop)))
:range (do
@ -895,40 +895,50 @@ to call on any table. Does not print table prototype information."
m? (apply1 m (tuple.slice t 1))
(apply1 tuple (map macroexpand-1 t))))
(switch (type x)
(def ret (switch (type x)
:tuple (dotup x)
:array (map macroexpand-1 x)
:struct (table.to-struct (dotable x macroexpand-1))
:table (dotable x macroexpand-1)
x))
ret)
(defn all? [& xs]
(defn all? [xs]
(var good true)
(loop [x :in xs :while good] (if x nil (:= good false)))
good)
(defn some? [& xs]
(defn some? [xs]
(var bad true)
(loop [x :in xs :while bad] (if x (:= bad false)))
(not bad))
(defn deep-not= [x y]
"Like not=, but mutable types (arrays, tables, buffers) are considered
equal if they have identical structure. Much slower than not=."
(def tx (type x))
(or
(not= tx (type y))
(switch tx
:tuple (or (not= (length x) (length y)) (some? (map deep-not= x y)))
:array (or (not= (length x) (length y)) (some? (map deep-not= x y)))
:struct (deep-not= (pairs x) (pairs y))
:table (deep-not= (table.to-struct x) (table.to-struct y))
:buffer (not= (string x) (string y))
(not= x y))))
(defn deep= [x y]
"Like =, but mutable types (arrays, tables, buffers) are considered
equal if they have identical structure. Much slower than =."
(not (deep-not= x y)))
(defn macroexpand
"Expand macros completely."
[x]
(defn deep= [x y]
(def tx (type x))
(and
(= tx (type y))
(switch tx
:tuple (all? (map deep= x y))
:array (all? (map deep= x y))
:struct (deep= (pairs x) (pairs y))
:table (deep= (table.to-struct x) (table.to-struct y))
(= x y))))
(var previous x)
(var current (macroexpand-1 x))
(var counter 0)
(while (not (deep= current previous))
(while (deep-not= current previous)
(if (> (++ counter) 200)
(error "macro expansion too nested"))
(:= previous current)

View File

@ -40,9 +40,10 @@ static void dstc_ast_push(DstCompiler *c, const Dst *tup) {
if (!mapping.line) {
/* Reuse previous mapping */
mapping = c->current_mapping;
} else {
c->current_mapping = mapping;
}
dst_v_push(c->ast_stack, mapping);
c->current_mapping = mapping;
}
static void dstc_ast_pop(DstCompiler *c) {
@ -927,15 +928,12 @@ DstFuncDef *dstc_pop_funcdef(DstCompiler *c) {
memcpy(def->bytecode, c->buffer + scope.bytecode_start, s);
dst_v__cnt(c->buffer) = scope.bytecode_start;
if (NULL != c->mapbuffer) {
int32_t i;
size_t s = sizeof(DstSourceMapping) * dst_v_count(c->mapbuffer);
size_t s = sizeof(DstSourceMapping) * def->bytecode_length;
def->sourcemap = malloc(s);
if (NULL == def->sourcemap) {
DST_OUT_OF_MEMORY;
}
for (i = 0; i < dst_v_count(c->mapbuffer); i++) {
def->sourcemap[i] = c->mapbuffer[i];
}
memcpy(def->sourcemap, c->mapbuffer + scope.bytecode_start, s);
dst_v__cnt(c->mapbuffer) = scope.bytecode_start;
}
}