From 1ea9ebf04f6d853b80e4f8c2bbac60d8ad7a2a9f Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Fri, 29 Jun 2018 19:44:33 -0400 Subject: [PATCH] Fix sourcemapping bug with closures, add some library functions to boot.dst --- examples/error.dst | 13 +++++++------ src/compiler/boot.dst | 42 ++++++++++++++++++++++++++---------------- src/compiler/compile.c | 10 ++++------ 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/examples/error.dst b/examples/error.dst index 0aa50cb1..23ffee88 100644 --- a/examples/error.dst +++ b/examples/error.dst @@ -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))) diff --git a/src/compiler/boot.dst b/src/compiler/boot.dst index 5280c737..9e20267d 100644 --- a/src/compiler/boot.dst +++ b/src/compiler/boot.dst @@ -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) diff --git a/src/compiler/compile.c b/src/compiler/compile.c index ccfb42fc..897aeebf 100644 --- a/src/compiler/compile.c +++ b/src/compiler/compile.c @@ -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; } }