added hcl_walkdic
fixed a bug of not printing the list closer properly in hcl_print(). enhanced error handling
This commit is contained in:
parent
4ddffc101d
commit
2201ee5a94
17
lib/dic.c
17
lib/dic.c
@ -277,3 +277,20 @@ hcl_oop_t hcl_makedic (hcl_t* hcl, hcl_oow_t inisize)
|
||||
|
||||
return (hcl_oop_t)obj;
|
||||
}
|
||||
|
||||
int hcl_walkdic (hcl_t* hcl, hcl_oop_dic_t dic, hcl_dic_walker_t walker, void* ctx)
|
||||
{
|
||||
hcl_oow_t i;
|
||||
|
||||
hcl_pushtmp (hcl, (hcl_oop_t*)&dic);
|
||||
|
||||
for (i = 0; i < HCL_OBJ_GET_SIZE(dic->bucket); i++)
|
||||
{
|
||||
hcl_oop_t tmp = dic->bucket->slot[i];
|
||||
if (HCL_IS_CONS(hcl, tmp) && walker(hcl, dic, (hcl_oop_cons_t)tmp, ctx) <= -1) return -1;
|
||||
}
|
||||
|
||||
hcl_poptmp (hcl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -59,13 +59,17 @@ static hcl_ooch_t errstr_29[] = {'d','i','v','i','d','e',' ','b','y',' ','z','e'
|
||||
static hcl_ooch_t errstr_30[] = {'I','/','O',' ','e','r','r','o','r','\0'};
|
||||
static hcl_ooch_t errstr_31[] = {'e','n','c','o','d','i','n','g',' ','c','o','n','v','e','r','s','i','o','n',' ','e','r','r','o','r','\0'};
|
||||
static hcl_ooch_t errstr_32[] = {'b','u','f','f','e','r',' ','f','u','l','l','\0'};
|
||||
static hcl_ooch_t errstr_33[] = {'s','y','n','t','a','x',' ','e','r','r','o','r','\0'};
|
||||
static hcl_ooch_t errstr_34[] = {'c','a','l','l',' ','e','r','r','o','r','\0'};
|
||||
static hcl_ooch_t errstr_35[] = {'r','e','c','a','l','l',' ','p','r','o','h','i','b','i','t','e','d','\0'};
|
||||
static hcl_ooch_t errstr_36[] = {'a','r','g','u','m','e','n','t',' ','n','u','m','b','e','r',' ','e','r','r','o','r','\0'};
|
||||
static hcl_ooch_t* errstr[] =
|
||||
{
|
||||
errstr_0, errstr_1, errstr_2, errstr_3, errstr_4, errstr_5, errstr_6, errstr_7,
|
||||
errstr_8, errstr_9, errstr_10, errstr_11, errstr_12, errstr_13, errstr_14, errstr_15,
|
||||
errstr_16, errstr_17, errstr_18, errstr_19, errstr_20, errstr_21, errstr_22, errstr_23,
|
||||
errstr_24, errstr_25, errstr_26, errstr_27, errstr_28, errstr_29, errstr_30, errstr_31,
|
||||
errstr_32
|
||||
errstr_32, errstr_33, errstr_34, errstr_35, errstr_36
|
||||
};
|
||||
|
||||
|
||||
|
@ -888,33 +888,6 @@ hcl_oop_t hcl_findsymbol (
|
||||
);
|
||||
|
||||
|
||||
/* ========================================================================= */
|
||||
/* dic.c */
|
||||
/* ========================================================================= */
|
||||
hcl_oop_cons_t hcl_putatsysdic (
|
||||
hcl_t* hcl,
|
||||
hcl_oop_t key,
|
||||
hcl_oop_t value
|
||||
);
|
||||
|
||||
hcl_oop_cons_t hcl_getatsysdic (
|
||||
hcl_t* hcl,
|
||||
hcl_oop_t key
|
||||
);
|
||||
|
||||
hcl_oop_cons_t hcl_putatdic (
|
||||
hcl_t* hcl,
|
||||
hcl_oop_dic_t dic,
|
||||
hcl_oop_t key,
|
||||
hcl_oop_t value
|
||||
);
|
||||
|
||||
hcl_oop_cons_t hcl_getatdic (
|
||||
hcl_t* hcl,
|
||||
hcl_oop_dic_t dic,
|
||||
hcl_oop_t key
|
||||
);
|
||||
|
||||
/* ========================================================================= */
|
||||
/* proc.c */
|
||||
/* ========================================================================= */
|
||||
@ -1139,8 +1112,7 @@ HCL_EXPORT int hcl_compile (
|
||||
hcl_mod_data_t* hcl_openmod (
|
||||
hcl_t* hcl,
|
||||
const hcl_ooch_t* name,
|
||||
hcl_oow_t namelen,
|
||||
int hints /* 0 or bitwise-ORed of hcl_mod_hint_t enumerators */
|
||||
hcl_oow_t namelen
|
||||
);
|
||||
|
||||
void hcl_closemod (
|
||||
@ -1148,12 +1120,6 @@ void hcl_closemod (
|
||||
hcl_mod_data_t* mdp
|
||||
);
|
||||
|
||||
int hcl_importmod (
|
||||
hcl_t* hcl,
|
||||
const hcl_ooch_t* name,
|
||||
hcl_oow_t len
|
||||
);
|
||||
|
||||
/*
|
||||
* The hcl_querymod() function finds a primitive function in modules
|
||||
* with a full primitive identifier.
|
||||
|
133
lib/hcl.c
133
lib/hcl.c
@ -200,14 +200,14 @@ void hcl_fini (hcl_t* hcl)
|
||||
|
||||
if (hcl->code.bc.arr)
|
||||
{
|
||||
hcl_freengcobj (hcl, hcl->code.bc.arr);
|
||||
hcl_freengcobj (hcl, (hcl_oop_t)hcl->code.bc.arr);
|
||||
hcl->code.bc.arr = HCL_NULL;
|
||||
hcl->code.bc.len = 0;
|
||||
}
|
||||
|
||||
if (hcl->code.lit.arr)
|
||||
{
|
||||
hcl_freengcobj (hcl, hcl->code.lit.arr);
|
||||
hcl_freengcobj (hcl, (hcl_oop_t)hcl->code.lit.arr);
|
||||
hcl->code.lit.arr = HCL_NULL;
|
||||
hcl->code.lit.len = 0;
|
||||
}
|
||||
@ -396,19 +396,13 @@ void hcl_freemem (hcl_t* hcl, void* ptr)
|
||||
|
||||
#if defined(HCL_ENABLE_STATIC_MODULE)
|
||||
|
||||
#if defined(HCL_ENABLE_MOD_CON)
|
||||
# include "../mod/_con.h"
|
||||
#endif
|
||||
#if defined(HCL_ENABLE_MOD_FFI)
|
||||
# include "../mod/_ffi.h"
|
||||
#endif
|
||||
#if defined(HCL_ENABLE_MOD_SCK)
|
||||
# include "../mod/_sck.h"
|
||||
#endif
|
||||
#include "../mod/_stdio.h"
|
||||
#if defined(HCL_ENABLE_MOD_X11)
|
||||
# include "../mod/_x11.h"
|
||||
#endif
|
||||
/*#include "../mod/_array.h"*/
|
||||
|
||||
static int hcl_mod_fake (hcl_t* hcl, hcl_mod_t* mod)
|
||||
{
|
||||
hcl_seterrbfmt (hcl, HCL_EPERM, "not allowed to load ___fake___ module");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct
|
||||
{
|
||||
@ -417,25 +411,11 @@ static struct
|
||||
}
|
||||
static_modtab[] =
|
||||
{
|
||||
#if defined(HCL_ENABLE_MOD_CON)
|
||||
{ "con", hcl_mod_con },
|
||||
#endif
|
||||
#if defined(HCL_ENABLE_MOD_FFI)
|
||||
{ "ffi", hcl_mod_ffi },
|
||||
#endif
|
||||
#if defined(HCL_ENABLE_MOD_SCK)
|
||||
{ "sck", hcl_mod_sck },
|
||||
{ "sck.addr", hcl_mod_sck_addr },
|
||||
#endif
|
||||
{ "stdio", hcl_mod_stdio },
|
||||
#if defined(HCL_ENABLE_MOD_X11)
|
||||
{ "x11", hcl_mod_x11 },
|
||||
/*{ "x11.win", hcl_mod_x11_win },*/
|
||||
#endif
|
||||
{ "___fake___", hcl_mod_fake },
|
||||
};
|
||||
#endif
|
||||
|
||||
hcl_mod_data_t* hcl_openmod (hcl_t* hcl, const hcl_ooch_t* name, hcl_oow_t namelen, int hints)
|
||||
hcl_mod_data_t* hcl_openmod (hcl_t* hcl, const hcl_ooch_t* name, hcl_oow_t namelen)
|
||||
{
|
||||
hcl_rbt_pair_t* pair;
|
||||
hcl_mod_data_t* mdp;
|
||||
@ -499,7 +479,6 @@ hcl_mod_data_t* hcl_openmod (hcl_t* hcl, const hcl_ooch_t* name, hcl_oow_t namel
|
||||
|
||||
mdp = (hcl_mod_data_t*)HCL_RBT_VPTR(pair);
|
||||
HCL_ASSERT (hcl, HCL_SIZEOF(mdp->mod.hints) == HCL_SIZEOF(int));
|
||||
mdp->mod.hints = hints;
|
||||
if (load(hcl, &mdp->mod) <= -1)
|
||||
{
|
||||
hcl_rbt_delete (&hcl->modtab, (hcl_ooch_t*)name, namelen);
|
||||
@ -546,8 +525,7 @@ hcl_mod_data_t* hcl_openmod (hcl_t* hcl, const hcl_ooch_t* name, hcl_oow_t namel
|
||||
load = hcl->vmprim.dl_getsym(hcl, md.handle, buf);
|
||||
if (!load)
|
||||
{
|
||||
const hcl_ooch_t* oldmsg = hcl_backuperrmsg (hcl);
|
||||
hcl_seterrbfmt (hcl, hcl_geterrnum(hcl), "unable to get module symbol [%js] in [%.*js] - %js", buf, namelen, name, oldmsg);
|
||||
hcl_seterrbfmt (hcl, hcl_geterrnum(hcl), "unable to get module symbol [%js] in [%.*js]", buf, namelen, name);
|
||||
HCL_DEBUG3 (hcl, "Cannot get a module symbol [%js] in [%.*js]\n", buf, namelen, name);
|
||||
hcl->vmprim.dl_close (hcl, md.handle);
|
||||
return HCL_NULL;
|
||||
@ -566,7 +544,6 @@ hcl_mod_data_t* hcl_openmod (hcl_t* hcl, const hcl_ooch_t* name, hcl_oow_t namel
|
||||
|
||||
mdp = (hcl_mod_data_t*)HCL_RBT_VPTR(pair);
|
||||
HCL_ASSERT (hcl, HCL_SIZEOF(mdp->mod.hints) == HCL_SIZEOF(int));
|
||||
mdp->mod.hints = hints;
|
||||
if (load(hcl, &mdp->mod) <= -1)
|
||||
{
|
||||
const hcl_ooch_t* oldmsg = hcl_backuperrmsg (hcl);
|
||||
@ -609,53 +586,6 @@ void hcl_closemod (hcl_t* hcl, hcl_mod_data_t* mdp)
|
||||
}
|
||||
}
|
||||
|
||||
int hcl_importmod (hcl_t* hcl, const hcl_ooch_t* name, hcl_oow_t len)
|
||||
{
|
||||
hcl_rbt_pair_t* pair;
|
||||
hcl_mod_data_t* mdp;
|
||||
int r = -1;
|
||||
|
||||
pair = hcl_rbt_search (&hcl->modtab, name, len);
|
||||
if (pair)
|
||||
{
|
||||
mdp = (hcl_mod_data_t*)HCL_RBT_VPTR(pair);
|
||||
HCL_ASSERT (hcl, mdp != HCL_NULL);
|
||||
|
||||
HCL_DEBUG1 (hcl, "Cannot import module [%js] - already active\n", mdp->mod.name);
|
||||
hcl_seterrbfmt (hcl, HCL_EPERM, "unable to import module [%js] - already active", mdp->mod.name);
|
||||
goto done2;
|
||||
}
|
||||
|
||||
mdp = hcl_openmod (hcl, name, len, HCL_MOD_LOAD_FOR_IMPORT);
|
||||
if (!mdp) goto done2;
|
||||
|
||||
if (!mdp->mod.import)
|
||||
{
|
||||
HCL_DEBUG1 (hcl, "Cannot import module [%js] - importing not supported by the module\n", mdp->mod.name);
|
||||
hcl_seterrbfmt (hcl, HCL_ENOIMPL, "unable to import module [%js] - not supported by the module", mdp->mod.name);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (mdp->mod.import (hcl, &mdp->mod) <= -1)
|
||||
{
|
||||
HCL_DEBUG1 (hcl, "Cannot import module [%js] - module's import() returned failure\n", mdp->mod.name);
|
||||
goto done;
|
||||
}
|
||||
|
||||
r = 0; /* everything successful */
|
||||
|
||||
done:
|
||||
/* close the module opened above.
|
||||
* [NOTE] if the import callback calls the hcl_querymod(), the returned
|
||||
* function pointers will get all invalidated here. so never do
|
||||
* anything like that */
|
||||
hcl_closemod (hcl, mdp);
|
||||
|
||||
done2:
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
hcl_pfbase_t* hcl_querymod (hcl_t* hcl, const hcl_ooch_t* pfid, hcl_oow_t pfidlen)
|
||||
{
|
||||
/* primitive function identifier
|
||||
@ -696,7 +626,7 @@ hcl_pfbase_t* hcl_querymod (hcl_t* hcl, const hcl_ooch_t* pfid, hcl_oow_t pfidle
|
||||
else
|
||||
{
|
||||
/* open a module using the part before the last period */
|
||||
mdp = hcl_openmod (hcl, pfid, mod_name_len, 0);
|
||||
mdp = hcl_openmod (hcl, pfid, mod_name_len);
|
||||
if (!mdp) return HCL_NULL;
|
||||
}
|
||||
|
||||
@ -713,3 +643,40 @@ hcl_pfbase_t* hcl_querymod (hcl_t* hcl, const hcl_ooch_t* pfid, hcl_oow_t pfidle
|
||||
return pfbase;
|
||||
}
|
||||
|
||||
|
||||
hcl_pfbase_t* hcl_findpfbase (hcl_t* hcl, hcl_pfinfo_t* pfinfo, hcl_oow_t pfcount, const hcl_ooch_t* name, hcl_oow_t namelen)
|
||||
{
|
||||
int n;
|
||||
|
||||
/* binary search */
|
||||
#if 0
|
||||
/* [NOTE] this algorithm is NOT underflow safe with hcl_oow_t types */
|
||||
int left, right, mid;
|
||||
|
||||
for (left = 0, right = pfcount - 1; left <= right; )
|
||||
{
|
||||
/*mid = (left + right) / 2;*/
|
||||
mid = left + ((right - left) / 2);
|
||||
|
||||
n = hcl_compoocharsoocstr (name, namelen, pfinfo[mid].mthname);
|
||||
if (n < 0) right = mid - 1; /* this substraction can make right negative. so i can't use hcl_oow_t for the variable */
|
||||
else if (n > 0) left = mid + 1;
|
||||
else return &pfinfo[mid].base;
|
||||
}
|
||||
#else
|
||||
/* [NOTE] this algorithm is underflow safe with hcl_oow_t types */
|
||||
hcl_oow_t base, mid, lim;
|
||||
|
||||
for (base = 0, lim = pfcount; lim > 0; lim >>= 1)
|
||||
{
|
||||
mid = base + (lim >> 1);
|
||||
n = hcl_compoocharsoocstr (name, namelen, pfinfo[mid].mthname);
|
||||
if (n == 0) return &pfinfo[mid].base;
|
||||
if (n > 0) { base = mid + 1; lim--; }
|
||||
}
|
||||
#endif
|
||||
|
||||
hcl_seterrnum (hcl, HCL_ENOENT);
|
||||
return HCL_NULL;
|
||||
}
|
||||
|
||||
|
25
lib/main.c
25
lib/main.c
@ -504,8 +504,11 @@ static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
|
||||
if (!handle)
|
||||
{
|
||||
hcl_bch_t* dash;
|
||||
hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open(ext) DL %js - %hs", name, sys_dl_error());
|
||||
HCL_DEBUG3 (hcl, "Failed to open(ext) DL %hs[%js] - %hs\n", &bufptr[len], name, sys_dl_error());
|
||||
const hcl_bch_t* dl_errstr;
|
||||
dl_errstr = sys_dl_error();
|
||||
HCL_DEBUG3 (hcl, "Failed to open(ext) DL %hs[%js] - %hs\n", &bufptr[len], name, dl_errstr);
|
||||
hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open(ext) DL %js - %hs", name, dl_errstr);
|
||||
|
||||
dash = hcl_rfindbchar(bufptr, hcl_countbcstr(bufptr), '-');
|
||||
if (dash)
|
||||
{
|
||||
@ -542,8 +545,10 @@ static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
|
||||
handle = sys_dl_open(bufptr);
|
||||
if (!handle)
|
||||
{
|
||||
hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open DL %js - %hs", name, sys_dl_error());
|
||||
HCL_DEBUG2 (hcl, "Failed to open DL %hs - %hs\n", bufptr, sys_dl_error());
|
||||
const hcl_bch_t* dl_errstr;
|
||||
dl_errstr = sys_dl_error();
|
||||
HCL_DEBUG2 (hcl, "Failed to open DL %hs - %hs\n", bufptr, dl_errstr);
|
||||
hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open DL %js - %hs", name, dl_errstr);
|
||||
}
|
||||
else HCL_DEBUG2 (hcl, "Opened DL %hs handle %p\n", bufptr, handle);
|
||||
}
|
||||
@ -552,8 +557,10 @@ static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
|
||||
handle = sys_dl_openext(bufptr);
|
||||
if (!handle)
|
||||
{
|
||||
hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open(ext) DL %js - %hs", name, sys_dl_error());
|
||||
HCL_DEBUG2 (hcl, "Failed to open(ext) DL %hs - %s\n", bufptr, sys_dl_error());
|
||||
const hcl_bch_t* dl_errstr;
|
||||
dl_errstr = sys_dl_error();
|
||||
HCL_DEBUG2 (hcl, "Failed to open(ext) DL %hs - %s\n", bufptr, dl_errstr);
|
||||
hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open(ext) DL %js - %hs", name, dl_errstr);
|
||||
}
|
||||
else HCL_DEBUG2 (hcl, "Opened(ext) DL %hs handle %p\n", bufptr, handle);
|
||||
}
|
||||
@ -642,7 +649,11 @@ static void* dl_getsym (hcl_t* hcl, void* handle, const hcl_ooch_t* name)
|
||||
sym = sys_dl_getsym(handle, symname);
|
||||
if (!sym)
|
||||
{
|
||||
hcl_seterrbfmt (hcl, HCL_ENOENT, "unable to get module symbol %hs", symname);
|
||||
const hcl_bch_t* dl_errstr;
|
||||
dl_errstr = sys_dl_error();
|
||||
HCL_DEBUG3 (hcl, "Failed to get module symbol %js from handle %p - %hs\n", name, handle, dl_errstr);
|
||||
hcl_seterrbfmt (hcl, HCL_ENOENT, "unable to get module symbol %hs - %hs", symname, dl_errstr);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
56
lib/prim.c
56
lib/prim.c
@ -487,3 +487,59 @@ int hcl_addbuiltinprims (hcl_t* hcl)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
static hcl_pfrc_t pf_hello (hcl_t* hcl, hcl_ooi_t nargs)
|
||||
{
|
||||
return prim_log(hcl, nargs);
|
||||
}
|
||||
|
||||
static int walker (hcl_t* hcl, hcl_oop_dic_t dic, hcl_oop_cons_t pair, void* ctx)
|
||||
{
|
||||
HCL_DEBUG2 (hcl, "walker ===> %O =====> %O\n", HCL_CONS_CAR(pair), HCL_CONS_CDR(pair));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static hcl_pfrc_t pf_walk (hcl_t* hcl, hcl_ooi_t nargs)
|
||||
{
|
||||
hcl_oop_t arg;
|
||||
|
||||
arg = HCL_STACK_GETARG(hcl, nargs, 0);
|
||||
if (!HCL_IS_DIC(hcl,arg))
|
||||
{
|
||||
hcl_seterrbfmt (hcl, HCL_EINVAL, "parameter not a dictionary - %O", arg);
|
||||
return HCL_PF_FAILURE;
|
||||
}
|
||||
|
||||
hcl_walkdic (hcl, (hcl_oop_dic_t)arg, walker, HCL_NULL);
|
||||
HCL_STACK_SETRET (hcl, nargs, hcl->_true);
|
||||
return HCL_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static hcl_pfinfo_t pfinfos[] =
|
||||
{
|
||||
{ { 'h','e','l','l','o','\0' }, 0, { pf_hello, 1, 1 } },
|
||||
{ { 'w','a','l','k','\0' }, 0, { pf_walk, 1, 1 } }
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static hcl_pfbase_t* query (hcl_t* hcl, hcl_mod_t* mod, const hcl_ooch_t* name, hcl_oow_t namelen)
|
||||
{
|
||||
return hcl_findpfbase (hcl, pfinfos, HCL_COUNTOF(pfinfos), name, namelen);
|
||||
}
|
||||
|
||||
static void unload (hcl_t* hcl, hcl_mod_t* mod)
|
||||
{
|
||||
}
|
||||
|
||||
int hcl_mod_test (hcl_t* hcl, hcl_mod_t* mod)
|
||||
{
|
||||
mod->query = query;
|
||||
mod->unload = unload;
|
||||
mod->ctx = HCL_NULL;
|
||||
return 0;
|
||||
}
|
||||
|
@ -296,6 +296,7 @@ next:
|
||||
* the variable p is */
|
||||
ps.type = PRINT_STACK_CONS;
|
||||
ps.obj = HCL_CONS_CDR(cur);
|
||||
ps.idx = concode; /* this is not an index but use this field to restore concode */
|
||||
x = push (hcl, &ps);
|
||||
if (x <= -1) return -1;
|
||||
|
||||
@ -309,6 +310,7 @@ next:
|
||||
resume_cons:
|
||||
HCL_ASSERT (hcl, ps.type == PRINT_STACK_CONS);
|
||||
cur = ps.obj; /* Get back the CDR pushed */
|
||||
concode = ps.idx; /* restore the concode */
|
||||
if (HCL_IS_NIL(hcl,cur))
|
||||
{
|
||||
/* The CDR part points to a NIL object, which
|
||||
|
Loading…
Reference in New Issue
Block a user