mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 07:33:01 +00:00 
			
		
		
		
	Support redefinable bindings
This commit is contained in:
		| @@ -239,6 +239,12 @@ JanetSlot janetc_resolve( | ||||
|             case JANET_BINDING_MACRO: /* Macro should function like defs when not in calling pos */ | ||||
|                 ret = janetc_cslot(binding.value); | ||||
|                 break; | ||||
|             case JANET_BINDING_DEF_REF: | ||||
|             case JANET_BINDING_MACRO_REF: | ||||
|                 ret = janetc_cslot(binding.value); | ||||
|                 ret.flags |= JANET_SLOT_REF | JANET_SLOT_NAMED | JANET_SLOTTYPE_ANY; | ||||
|                 ret.flags &= ~JANET_SLOT_CONSTANT; | ||||
|                 break; | ||||
|             case JANET_BINDING_VAR: { | ||||
|                 ret = janetc_cslot(binding.value); | ||||
|                 ret.flags |= JANET_SLOT_REF | JANET_SLOT_NAMED | JANET_SLOT_MUTABLE | JANET_SLOTTYPE_ANY; | ||||
| @@ -651,7 +657,7 @@ static int macroexpand1( | ||||
|     } | ||||
|     Janet macroval; | ||||
|     JanetBindingType btype = janet_resolve(c->env, name, ¯oval); | ||||
|     if (btype != JANET_BINDING_MACRO || | ||||
|     if (!(btype == JANET_BINDING_MACRO || btype == JANET_BINDING_MACRO_REF) || | ||||
|             !janet_checktype(macroval, JANET_FUNCTION)) | ||||
|         return 0; | ||||
|  | ||||
|   | ||||
| @@ -331,14 +331,27 @@ static int defleaf( | ||||
|         JanetTable *entry = janet_table_clone(tab); | ||||
|         janet_table_put(entry, janet_ckeywordv("source-map"), | ||||
|                         janet_wrap_tuple(janetc_make_sourcemap(c))); | ||||
|  | ||||
|         if (!janet_checktype(janet_table_get(entry, janet_ckeywordv("redef")), JANET_NIL)) { | ||||
|             JanetBinding binding = janet_resolve_ext(c->env, sym); | ||||
|             JanetArray *ref; | ||||
|             if (janet_checktype(binding.value, JANET_ARRAY)) { | ||||
|                 ref = janet_unwrap_array(binding.value); | ||||
|             } else { | ||||
|                 ref = janet_array(1); | ||||
|                 janet_array_push(ref, janet_wrap_nil()); | ||||
|             } | ||||
|             janet_table_put(entry, janet_ckeywordv("ref"), janet_wrap_array(ref)); | ||||
|             JanetSlot refslot = janetc_cslot(janet_wrap_array(ref)); | ||||
|             janetc_emit_ssu(c, JOP_PUT_INDEX, refslot, s, 0, 0); | ||||
|         } else { | ||||
|             JanetSlot valsym = janetc_cslot(janet_ckeywordv("value")); | ||||
|             JanetSlot tabslot = janetc_cslot(janet_wrap_table(entry)); | ||||
|             janetc_emit_sss(c, JOP_PUT, tabslot, valsym, s, 0); | ||||
|         } | ||||
|  | ||||
|         /* Add env entry to env */ | ||||
|         janet_table_put(c->env, janet_wrap_symbol(sym), janet_wrap_table(entry)); | ||||
|  | ||||
|         /* Put value in table when evaulated */ | ||||
|         janetc_emit_sss(c, JOP_PUT, tabslot, valsym, s, 0); | ||||
|     } | ||||
|     return namelocal(c, sym, 0, s); | ||||
| } | ||||
|   | ||||
| @@ -627,23 +627,31 @@ JanetBinding janet_resolve_ext(JanetTable *env, const uint8_t *sym) { | ||||
|         binding.deprecation = JANET_BINDING_DEP_NORMAL; | ||||
|     } | ||||
|  | ||||
|     if (!janet_checktype( | ||||
|                 janet_table_get(entry_table, janet_ckeywordv("macro")), | ||||
|                 JANET_NIL)) { | ||||
|     ref = janet_table_get(entry_table, janet_ckeywordv("ref")); | ||||
|     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) { | ||||
|         /* invalid, return empty binding */ | ||||
|         return binding; | ||||
|     } 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.type = JANET_BINDING_MACRO; | ||||
|         return binding; | ||||
|     } | ||||
|  | ||||
|     ref = janet_table_get(entry_table, janet_ckeywordv("ref")); | ||||
|     if (janet_checktype(ref, JANET_ARRAY)) { | ||||
|     } else if (is_redef) { | ||||
|         binding.value = ref; | ||||
|         binding.type = JANET_BINDING_VAR; | ||||
|         return binding; | ||||
|     } | ||||
|  | ||||
|         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; | ||||
|     } | ||||
|  | ||||
|     return binding; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1779,7 +1779,9 @@ typedef enum { | ||||
|     JANET_BINDING_NONE, | ||||
|     JANET_BINDING_DEF, | ||||
|     JANET_BINDING_VAR, | ||||
|     JANET_BINDING_MACRO | ||||
|     JANET_BINDING_MACRO, | ||||
|     JANET_BINDING_DEF_REF, | ||||
|     JANET_BINDING_MACRO_REF | ||||
| } JanetBindingType; | ||||
|  | ||||
| typedef struct { | ||||
|   | ||||
| @@ -295,6 +295,19 @@ | ||||
|     (++ i)) | ||||
|   (assert (= i 6) "when macro")) | ||||
|  | ||||
| # Redefs | ||||
|  | ||||
| (def noredef 0) | ||||
| (defn noredef-inc [] (+ 1 noredef)) | ||||
| (assert (= 1 (noredef-inc)) "result before redef without :redef") | ||||
| (def noredef 1) | ||||
| (assert (= 1 (noredef-inc)) "result after redef without :redef") | ||||
| (def redef :redef 0) | ||||
| (defn redef-inc [] (+ 1 redef)) | ||||
| (assert (= 1 (redef-inc)) "result before redef with :redef") | ||||
| (def redef :redef 1) | ||||
| (assert (= 2 (redef-inc)) "result before redef with :redef") | ||||
|  | ||||
| # Denormal tables and structs | ||||
|  | ||||
| (assert (= (length {1 2 nil 3}) 1) "nil key struct literal") | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Michael Camilleri
					Michael Camilleri