mirror of
https://github.com/janet-lang/janet
synced 2024-11-19 07:04:48 +00:00
Move missing symbol lookup to compiler
This commit is contained in:
parent
d396180939
commit
fad0ce3ced
@ -197,6 +197,39 @@ void janetc_popscope_keepslot(JanetCompiler *c, JanetSlot retslot) {
|
||||
}
|
||||
}
|
||||
|
||||
static int lookup_missing(
|
||||
JanetCompiler *c,
|
||||
const uint8_t *sym,
|
||||
JanetFunction *handler,
|
||||
Janet *out) {
|
||||
Janet args[2] = { janet_wrap_symbol(sym), janet_wrap_table(c->env) };
|
||||
JanetFiber *fiberp = janet_fiber(handler, 64, 2, args);
|
||||
if (NULL == fiberp) {
|
||||
int32_t minar = handler->def->min_arity;
|
||||
int32_t maxar = handler->def->max_arity;
|
||||
const uint8_t *es = NULL;
|
||||
if (minar > 2)
|
||||
es = janet_formatc("lookup handler arity mismatch, minimum at most 2, got %d", minar);
|
||||
if (maxar < 2)
|
||||
es = janet_formatc("lookup handler arity mismatch, maximum at least 2, got %d", maxar);
|
||||
janetc_error(c, es);
|
||||
return 0;
|
||||
}
|
||||
fiberp->env = c->env;
|
||||
int lock = janet_gclock();
|
||||
Janet tempOut;
|
||||
JanetSignal status = janet_continue(fiberp, janet_wrap_nil(), &tempOut);
|
||||
janet_gcunlock(lock);
|
||||
if (status != JANET_SIGNAL_OK) {
|
||||
janetc_error(c, janet_formatc("(lookup) %V", tempOut));
|
||||
return 0;
|
||||
} else {
|
||||
*out = tempOut;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Allow searching for symbols. Return information about the symbol */
|
||||
JanetSlot janetc_resolve(
|
||||
JanetCompiler *c,
|
||||
@ -230,6 +263,23 @@ JanetSlot janetc_resolve(
|
||||
/* Symbol not found - check for global */
|
||||
{
|
||||
JanetBinding binding = janet_resolve_ext(c->env, sym);
|
||||
if (binding.type == JANET_BINDING_NONE) {
|
||||
Janet handler = janet_table_get(c->env, janet_ckeywordv("missing-symbol"));
|
||||
switch (janet_type(handler)) {
|
||||
case JANET_NIL:
|
||||
break;
|
||||
case JANET_FUNCTION:
|
||||
Janet entry;
|
||||
if (!lookup_missing(c, sym, janet_unwrap_function(handler), &entry))
|
||||
return janetc_cslot(janet_wrap_nil());
|
||||
binding = janet_binding_from_entry(entry);
|
||||
break;
|
||||
default:
|
||||
janetc_error(c, janet_formatc("invalid lookup handler %V", handler));
|
||||
return janetc_cslot(janet_wrap_nil());
|
||||
}
|
||||
}
|
||||
|
||||
switch (binding.type) {
|
||||
default:
|
||||
case JANET_BINDING_NONE:
|
||||
|
@ -597,9 +597,8 @@ void janet_core_cfuns_ext(JanetTable *env, const char *regprefix, const JanetReg
|
||||
}
|
||||
#endif
|
||||
|
||||
JanetBinding janet_resolve_ext(JanetTable *env, const uint8_t *sym) {
|
||||
JanetBinding janet_binding_from_entry(Janet entry) {
|
||||
JanetTable *entry_table;
|
||||
Janet entry = janet_table_get(env, janet_wrap_symbol(sym));
|
||||
JanetBinding binding = {
|
||||
JANET_BINDING_NONE,
|
||||
janet_wrap_nil(),
|
||||
@ -607,21 +606,8 @@ JanetBinding janet_resolve_ext(JanetTable *env, const uint8_t *sym) {
|
||||
};
|
||||
|
||||
/* Check environment for entry */
|
||||
if (!janet_checktype(entry, JANET_TABLE)) {
|
||||
Janet lookup_entry = janet_table_get(env, janet_ckeywordv("missing-symbol"));
|
||||
if (janet_checktype(lookup_entry, JANET_FUNCTION)) {
|
||||
JanetFunction *lookup = janet_unwrap_function(lookup_entry);
|
||||
Janet args[2] = { janet_wrap_symbol(sym), janet_wrap_table(env) };
|
||||
JanetFiber *fiberp = janet_fiber(lookup, 64, 2, args);
|
||||
if (NULL == fiberp) return binding;
|
||||
fiberp->env = env;
|
||||
int lock = janet_gclock();
|
||||
JanetSignal status = janet_continue(fiberp, janet_wrap_nil(), &entry);
|
||||
janet_gcunlock(lock);
|
||||
if (status != JANET_SIGNAL_OK) return binding;
|
||||
}
|
||||
if (!janet_checktype(entry, JANET_TABLE)) return binding;
|
||||
}
|
||||
if (!janet_checktype(entry, JANET_TABLE))
|
||||
return binding;
|
||||
entry_table = janet_unwrap_table(entry);
|
||||
|
||||
/* deprecation check */
|
||||
@ -662,6 +648,11 @@ JanetBinding janet_resolve_ext(JanetTable *env, const uint8_t *sym) {
|
||||
return binding;
|
||||
}
|
||||
|
||||
JanetBinding janet_resolve_ext(JanetTable *env, const uint8_t *sym) {
|
||||
Janet entry = janet_table_get(env, janet_wrap_symbol(sym));
|
||||
return janet_binding_from_entry(entry);
|
||||
}
|
||||
|
||||
JanetBindingType janet_resolve(JanetTable *env, const uint8_t *sym, Janet *out) {
|
||||
JanetBinding binding = janet_resolve_ext(env, sym);
|
||||
if (binding.type == JANET_BINDING_DYNAMIC_DEF || binding.type == JANET_BINDING_DYNAMIC_MACRO) {
|
||||
|
@ -84,6 +84,7 @@ void janet_buffer_format(
|
||||
int32_t argc,
|
||||
Janet *argv);
|
||||
Janet janet_next_impl(Janet ds, Janet key, int is_interpreter);
|
||||
JanetBinding janet_binding_from_entry(Janet entry);
|
||||
|
||||
/* Registry functions */
|
||||
void janet_registry_put(
|
||||
|
Loading…
Reference in New Issue
Block a user