mirror of
https://github.com/janet-lang/janet
synced 2025-02-03 18:59:09 +00:00
Support :dynamic-defs dynamic binding
This commit is contained in:
parent
8347439644
commit
ec65f038a8
@ -3581,6 +3581,7 @@
|
|||||||
-e code : Execute a string of janet
|
-e code : Execute a string of janet
|
||||||
-E code arguments... : Evaluate an expression as a short-fn with arguments
|
-E code arguments... : Evaluate an expression as a short-fn with arguments
|
||||||
-d : Set the debug flag in the REPL
|
-d : Set the debug flag in the REPL
|
||||||
|
-D : Use dynamic def bindings
|
||||||
-r : Enter the REPL after running all scripts
|
-r : Enter the REPL after running all scripts
|
||||||
-R : Disables loading profile.janet when JANET_PROFILE is present
|
-R : Disables loading profile.janet when JANET_PROFILE is present
|
||||||
-p : Keep on executing if there is a top-level error (persistent)
|
-p : Keep on executing if there is a top-level error (persistent)
|
||||||
@ -3631,6 +3632,7 @@
|
|||||||
(error (get thunk :error)))
|
(error (get thunk :error)))
|
||||||
math/inf)
|
math/inf)
|
||||||
"d" (fn [&] (set debug-flag true) 1)
|
"d" (fn [&] (set debug-flag true) 1)
|
||||||
|
"D" (fn [&] (setdyn :dynamic-defs true) 1)
|
||||||
"w" (fn [i &] (set warn-level (get-lint-level i)) 2)
|
"w" (fn [i &] (set warn-level (get-lint-level i)) 2)
|
||||||
"x" (fn [i &] (set error-level (get-lint-level i)) 2)
|
"x" (fn [i &] (set error-level (get-lint-level i)) 2)
|
||||||
"R" (fn [&] (setdyn :profilepath nil) 1)})
|
"R" (fn [&] (setdyn :profilepath nil) 1)})
|
||||||
|
@ -238,12 +238,10 @@ JanetSlot janetc_resolve(
|
|||||||
case JANET_BINDING_DEF:
|
case JANET_BINDING_DEF:
|
||||||
case JANET_BINDING_MACRO: /* Macro should function like defs when not in calling pos */
|
case JANET_BINDING_MACRO: /* Macro should function like defs when not in calling pos */
|
||||||
ret = janetc_cslot(binding.value);
|
ret = janetc_cslot(binding.value);
|
||||||
break;
|
if (binding.dynamic) {
|
||||||
case JANET_BINDING_DEF_REF:
|
ret.flags |= JANET_SLOT_REF | JANET_SLOT_NAMED | JANET_SLOTTYPE_ANY;
|
||||||
case JANET_BINDING_MACRO_REF:
|
ret.flags &= ~JANET_SLOT_CONSTANT;
|
||||||
ret = janetc_cslot(binding.value);
|
}
|
||||||
ret.flags |= JANET_SLOT_REF | JANET_SLOT_NAMED | JANET_SLOTTYPE_ANY;
|
|
||||||
ret.flags &= ~JANET_SLOT_CONSTANT;
|
|
||||||
break;
|
break;
|
||||||
case JANET_BINDING_VAR: {
|
case JANET_BINDING_VAR: {
|
||||||
ret = janetc_cslot(binding.value);
|
ret = janetc_cslot(binding.value);
|
||||||
@ -657,7 +655,7 @@ static int macroexpand1(
|
|||||||
}
|
}
|
||||||
Janet macroval;
|
Janet macroval;
|
||||||
JanetBindingType btype = janet_resolve(c->env, name, ¯oval);
|
JanetBindingType btype = janet_resolve(c->env, name, ¯oval);
|
||||||
if (!(btype == JANET_BINDING_MACRO || btype == JANET_BINDING_MACRO_REF) ||
|
if (btype != JANET_BINDING_MACRO ||
|
||||||
!janet_checktype(macroval, JANET_FUNCTION))
|
!janet_checktype(macroval, JANET_FUNCTION))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -331,8 +331,11 @@ static int defleaf(
|
|||||||
JanetTable *entry = janet_table_clone(tab);
|
JanetTable *entry = janet_table_clone(tab);
|
||||||
janet_table_put(entry, 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)));
|
||||||
|
if (janet_truthy(janet_dyn("dynamic-defs"))) {
|
||||||
|
janet_table_put(entry, janet_ckeywordv("dynamic"), janet_wrap_true());
|
||||||
|
}
|
||||||
|
|
||||||
if (!janet_checktype(janet_table_get(entry, janet_ckeywordv("redef")), JANET_NIL)) {
|
if (!janet_checktype(janet_table_get(entry, janet_ckeywordv("dynamic")), JANET_NIL)) {
|
||||||
JanetBinding binding = janet_resolve_ext(c->env, sym);
|
JanetBinding binding = janet_resolve_ext(c->env, sym);
|
||||||
JanetArray *ref;
|
JanetArray *ref;
|
||||||
if (janet_checktype(binding.value, JANET_ARRAY)) {
|
if (janet_checktype(binding.value, JANET_ARRAY)) {
|
||||||
@ -341,7 +344,7 @@ static int defleaf(
|
|||||||
ref = janet_array(1);
|
ref = janet_array(1);
|
||||||
janet_array_push(ref, janet_wrap_nil());
|
janet_array_push(ref, janet_wrap_nil());
|
||||||
}
|
}
|
||||||
janet_table_put(entry, janet_ckeywordv("ref"), janet_wrap_array(ref));
|
janet_table_put(entry, janet_ckeywordv("value"), janet_wrap_array(ref));
|
||||||
JanetSlot refslot = janetc_cslot(janet_wrap_array(ref));
|
JanetSlot 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);
|
||||||
} else {
|
} else {
|
||||||
|
@ -604,7 +604,8 @@ JanetBinding janet_resolve_ext(JanetTable *env, const uint8_t *sym) {
|
|||||||
JanetBinding binding = {
|
JanetBinding binding = {
|
||||||
JANET_BINDING_NONE,
|
JANET_BINDING_NONE,
|
||||||
janet_wrap_nil(),
|
janet_wrap_nil(),
|
||||||
JANET_BINDING_DEP_NONE
|
JANET_BINDING_DEP_NONE,
|
||||||
|
JANET_BINDING_STATIC
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Check environment for entry */
|
/* Check environment for entry */
|
||||||
@ -627,37 +628,39 @@ JanetBinding janet_resolve_ext(JanetTable *env, const uint8_t *sym) {
|
|||||||
binding.deprecation = JANET_BINDING_DEP_NORMAL;
|
binding.deprecation = JANET_BINDING_DEP_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref = janet_table_get(entry_table, janet_ckeywordv("ref"));
|
binding.dynamic = !janet_checktype(janet_table_get(entry_table, janet_ckeywordv("dynamic")), JANET_NIL);
|
||||||
int is_value = !janet_checktype(ref, JANET_ARRAY);
|
|
||||||
int is_macro = !janet_checktype(janet_table_get(entry_table, janet_ckeywordv("macro")), JANET_NIL);
|
|
||||||
int is_redef = !janet_checktype(janet_table_get(entry_table, janet_ckeywordv("redef")), JANET_NIL);
|
|
||||||
|
|
||||||
if (is_redef && is_value) {
|
if (!janet_checktype(
|
||||||
/* invalid, return empty binding */
|
janet_table_get(entry_table, janet_ckeywordv("macro")),
|
||||||
return binding;
|
JANET_NIL)) {
|
||||||
} else if (is_macro && is_redef) {
|
|
||||||
binding.value = ref;
|
|
||||||
binding.type = JANET_BINDING_MACRO_REF;
|
|
||||||
} else if (is_macro) {
|
|
||||||
binding.value = janet_table_get(entry_table, janet_ckeywordv("value"));
|
binding.value = janet_table_get(entry_table, janet_ckeywordv("value"));
|
||||||
binding.type = JANET_BINDING_MACRO;
|
binding.type = JANET_BINDING_MACRO;
|
||||||
} else if (is_redef) {
|
return binding;
|
||||||
binding.value = ref;
|
|
||||||
binding.type = JANET_BINDING_DEF_REF;
|
|
||||||
} else if (is_value) {
|
|
||||||
binding.value = janet_table_get(entry_table, janet_ckeywordv("value"));
|
|
||||||
binding.type = JANET_BINDING_DEF;
|
|
||||||
} else {
|
|
||||||
binding.value = ref;
|
|
||||||
binding.type = JANET_BINDING_VAR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ref = janet_table_get(entry_table, janet_ckeywordv("ref"));
|
||||||
|
if (janet_checktype(ref, JANET_ARRAY)) {
|
||||||
|
binding.value = ref;
|
||||||
|
binding.type = JANET_BINDING_VAR;
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.value = janet_table_get(entry_table, janet_ckeywordv("value"));
|
||||||
|
binding.type = JANET_BINDING_DEF;
|
||||||
return binding;
|
return binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
JanetBindingType janet_resolve(JanetTable *env, const uint8_t *sym, Janet *out) {
|
JanetBindingType janet_resolve(JanetTable *env, const uint8_t *sym, Janet *out) {
|
||||||
JanetBinding binding = janet_resolve_ext(env, sym);
|
JanetBinding binding = janet_resolve_ext(env, sym);
|
||||||
*out = binding.value;
|
if (binding.dynamic) {
|
||||||
|
if (janet_checktype(binding.value, JANET_ARRAY)) {
|
||||||
|
*out = janet_array_peek(janet_unwrap_array(binding.value));
|
||||||
|
} else {
|
||||||
|
*out = janet_wrap_nil();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*out = binding.value;
|
||||||
|
}
|
||||||
return binding.type;
|
return binding.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1779,9 +1779,7 @@ typedef enum {
|
|||||||
JANET_BINDING_NONE,
|
JANET_BINDING_NONE,
|
||||||
JANET_BINDING_DEF,
|
JANET_BINDING_DEF,
|
||||||
JANET_BINDING_VAR,
|
JANET_BINDING_VAR,
|
||||||
JANET_BINDING_MACRO,
|
JANET_BINDING_MACRO
|
||||||
JANET_BINDING_DEF_REF,
|
|
||||||
JANET_BINDING_MACRO_REF
|
|
||||||
} JanetBindingType;
|
} JanetBindingType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -1793,6 +1791,9 @@ typedef struct {
|
|||||||
JANET_BINDING_DEP_NORMAL,
|
JANET_BINDING_DEP_NORMAL,
|
||||||
JANET_BINDING_DEP_STRICT,
|
JANET_BINDING_DEP_STRICT,
|
||||||
} deprecation;
|
} deprecation;
|
||||||
|
enum {
|
||||||
|
JANET_BINDING_STATIC,
|
||||||
|
JANET_BINDING_DYNAMIC } dynamic;
|
||||||
} JanetBinding;
|
} JanetBinding;
|
||||||
|
|
||||||
JANET_API void janet_def(JanetTable *env, const char *name, Janet val, const char *documentation);
|
JANET_API void janet_def(JanetTable *env, const char *name, Janet val, const char *documentation);
|
||||||
|
@ -295,18 +295,25 @@
|
|||||||
(++ i))
|
(++ i))
|
||||||
(assert (= i 6) "when macro"))
|
(assert (= i 6) "when macro"))
|
||||||
|
|
||||||
# Redefs
|
# Dynamic defs
|
||||||
|
|
||||||
(def noredef 0)
|
(def staticdef 0)
|
||||||
(defn noredef-inc [] (+ 1 noredef))
|
(defn staticdef-inc [] (+ 1 staticdef))
|
||||||
(assert (= 1 (noredef-inc)) "result before redef without :redef")
|
(assert (= 1 (staticdef-inc)) "result before redefinition without :dynamic")
|
||||||
(def noredef 1)
|
(def staticdef 1)
|
||||||
(assert (= 1 (noredef-inc)) "result after redef without :redef")
|
(assert (= 1 (staticdef-inc)) "result after redefinition without :dynamic")
|
||||||
(def redef :redef 0)
|
(def dynamicdef :dynamic 0)
|
||||||
(defn redef-inc [] (+ 1 redef))
|
(defn dynamicdef-inc [] (+ 1 dynamicdef))
|
||||||
(assert (= 1 (redef-inc)) "result before redef with :redef")
|
(assert (= 1 (dynamicdef-inc)) "result before redefinition with :dynamic")
|
||||||
(def redef :redef 1)
|
(def dynamicdef :dynamic 1)
|
||||||
(assert (= 2 (redef-inc)) "result before redef with :redef")
|
(assert (= 2 (dynamicdef-inc)) "result after redefinition with :dynamic")
|
||||||
|
(setdyn :dynamic-defs true)
|
||||||
|
(def dynamicdef2 0)
|
||||||
|
(defn dynamicdef2-inc [] (+ 1 dynamicdef2))
|
||||||
|
(assert (= 1 (dynamicdef2-inc)) "result before redefinition with :dynamic-defs")
|
||||||
|
(def dynamicdef2 1)
|
||||||
|
(assert (= 2 (dynamicdef2-inc)) "result after redefinition with :dynamic-defs")
|
||||||
|
(setdyn :dynamic-defs nil)
|
||||||
|
|
||||||
# Denormal tables and structs
|
# Denormal tables and structs
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user