mirror of
https://github.com/janet-lang/janet
synced 2025-01-24 06:06:52 +00:00
Address #137
Fix compiler bug when compiling desturctured bindings in a top-level def or var. Also introduce janet_table_clone API call to make this easier.
This commit is contained in:
parent
044fc7c461
commit
affcb5b459
@ -116,7 +116,7 @@ static JanetSlot janetc_unquote(JanetFopts opts, int32_t argn, const Janet *argv
|
|||||||
return janetc_cslot(janet_wrap_nil());
|
return janetc_cslot(janet_wrap_nil());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Preform destructuring. Be careful to
|
/* Perform destructuring. Be careful to
|
||||||
* keep the order registers are freed.
|
* keep the order registers are freed.
|
||||||
* Returns if the slot 'right' can be freed. */
|
* Returns if the slot 'right' can be freed. */
|
||||||
static int destructure(JanetCompiler *c,
|
static int destructure(JanetCompiler *c,
|
||||||
@ -282,12 +282,13 @@ static int varleaf(
|
|||||||
if (c->scope->flags & JANET_SCOPE_TOP) {
|
if (c->scope->flags & JANET_SCOPE_TOP) {
|
||||||
/* Global var, generate var */
|
/* Global var, generate var */
|
||||||
JanetSlot refslot;
|
JanetSlot refslot;
|
||||||
|
JanetTable *entry = janet_table_clone(reftab);
|
||||||
JanetArray *ref = janet_array(1);
|
JanetArray *ref = janet_array(1);
|
||||||
janet_array_push(ref, janet_wrap_nil());
|
janet_array_push(ref, janet_wrap_nil());
|
||||||
janet_table_put(reftab, janet_ckeywordv("ref"), janet_wrap_array(ref));
|
janet_table_put(entry, janet_ckeywordv("ref"), janet_wrap_array(ref));
|
||||||
janet_table_put(reftab, janet_ckeywordv("source-map"),
|
janet_table_put(entry, janet_ckeywordv("source-map"),
|
||||||
janet_wrap_tuple(janetc_make_sourcemap(c)));
|
janet_wrap_tuple(janetc_make_sourcemap(c)));
|
||||||
janet_table_put(c->env, janet_wrap_symbol(sym), janet_wrap_table(reftab));
|
janet_table_put(c->env, janet_wrap_symbol(sym), janet_wrap_table(entry));
|
||||||
refslot = janetc_cslot(janet_wrap_array(ref));
|
refslot = janetc_cslot(janet_wrap_array(ref));
|
||||||
janetc_emit_ssu(c, JOP_PUT_INDEX, refslot, s, 0, 0);
|
janetc_emit_ssu(c, JOP_PUT_INDEX, refslot, s, 0, 0);
|
||||||
return 1;
|
return 1;
|
||||||
@ -312,13 +313,14 @@ static int defleaf(
|
|||||||
JanetSlot s,
|
JanetSlot s,
|
||||||
JanetTable *tab) {
|
JanetTable *tab) {
|
||||||
if (c->scope->flags & JANET_SCOPE_TOP) {
|
if (c->scope->flags & JANET_SCOPE_TOP) {
|
||||||
janet_table_put(tab, janet_ckeywordv("source-map"),
|
JanetTable *entry = janet_table_clone(tab);
|
||||||
|
janet_table_put(entry, janet_ckeywordv("source-map"),
|
||||||
janet_wrap_tuple(janetc_make_sourcemap(c)));
|
janet_wrap_tuple(janetc_make_sourcemap(c)));
|
||||||
JanetSlot valsym = janetc_cslot(janet_ckeywordv("value"));
|
JanetSlot valsym = janetc_cslot(janet_ckeywordv("value"));
|
||||||
JanetSlot tabslot = janetc_cslot(janet_wrap_table(tab));
|
JanetSlot tabslot = janetc_cslot(janet_wrap_table(entry));
|
||||||
|
|
||||||
/* Add env entry to env */
|
/* Add env entry to env */
|
||||||
janet_table_put(c->env, janet_wrap_symbol(sym), janet_wrap_table(tab));
|
janet_table_put(c->env, janet_wrap_symbol(sym), janet_wrap_table(entry));
|
||||||
|
|
||||||
/* Put value in table when evaulated */
|
/* Put value in table when evaulated */
|
||||||
janetc_emit_sss(c, JOP_PUT, tabslot, valsym, s, 0);
|
janetc_emit_sss(c, JOP_PUT, tabslot, valsym, s, 0);
|
||||||
|
@ -208,6 +208,18 @@ const JanetKV *janet_table_to_struct(JanetTable *t) {
|
|||||||
return janet_struct_end(st);
|
return janet_struct_end(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clone a table. */
|
||||||
|
JanetTable *janet_table_clone(JanetTable *table) {
|
||||||
|
JanetTable *newTable = janet_gcalloc(JANET_MEMORY_TABLE, sizeof(JanetTable));
|
||||||
|
memcpy(newTable, table, sizeof(JanetTable));
|
||||||
|
newTable->data = malloc(newTable->capacity * sizeof(JanetKV));
|
||||||
|
if (NULL == newTable->data) {
|
||||||
|
JANET_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
memcpy(newTable->data, table->data, table->capacity * sizeof(JanetKV));
|
||||||
|
return newTable;
|
||||||
|
}
|
||||||
|
|
||||||
/* Merge a table or struct into a table */
|
/* Merge a table or struct into a table */
|
||||||
static void janet_table_mergekv(JanetTable *table, const JanetKV *kvs, int32_t cap) {
|
static void janet_table_mergekv(JanetTable *table, const JanetKV *kvs, int32_t cap) {
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
@ -1202,6 +1202,7 @@ JANET_API const JanetKV *janet_table_to_struct(JanetTable *t);
|
|||||||
JANET_API void janet_table_merge_table(JanetTable *table, JanetTable *other);
|
JANET_API void janet_table_merge_table(JanetTable *table, JanetTable *other);
|
||||||
JANET_API void janet_table_merge_struct(JanetTable *table, const JanetKV *other);
|
JANET_API void janet_table_merge_struct(JanetTable *table, const JanetKV *other);
|
||||||
JANET_API JanetKV *janet_table_find(JanetTable *t, Janet key);
|
JANET_API JanetKV *janet_table_find(JanetTable *t, Janet key);
|
||||||
|
JANET_API JanetTable *janet_table_clone(JanetTable *table);
|
||||||
|
|
||||||
/* Fiber */
|
/* Fiber */
|
||||||
JANET_API JanetFiber *janet_fiber(JanetFunction *callee, int32_t capacity, int32_t argc, const Janet *argv);
|
JANET_API JanetFiber *janet_fiber(JanetFunction *callee, int32_t capacity, int32_t argc, const Janet *argv);
|
||||||
|
@ -303,5 +303,16 @@
|
|||||||
# Regression Test
|
# Regression Test
|
||||||
(assert (= 1 (((compile '(fn [] 1) @{})))) "regression test")
|
(assert (= 1 (((compile '(fn [] 1) @{})))) "regression test")
|
||||||
|
|
||||||
|
# Regression Test #137
|
||||||
|
(def [a b c] (range 10))
|
||||||
|
(assert (= a 0) "regression #137 (1)")
|
||||||
|
(assert (= b 1) "regression #137 (2)")
|
||||||
|
(assert (= c 2) "regression #137 (3)")
|
||||||
|
|
||||||
|
(var [x y z] (range 10))
|
||||||
|
(assert (= a 0) "regression #137 (4)")
|
||||||
|
(assert (= b 1) "regression #137 (5)")
|
||||||
|
(assert (= c 2) "regression #137 (6)")
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user