Use backward compatible variable initializers
This commit is contained in:
parent
486ec48a76
commit
023937e5ea
130
c/builtins.c
130
c/builtins.c
|
@ -47,12 +47,16 @@ size_t llength(value_t v)
|
|||
|
||||
static value_t fl_nconc(value_t *args, uint32_t nargs)
|
||||
{
|
||||
value_t lst, first;
|
||||
value_t *pcdr;
|
||||
struct cons *c;
|
||||
uint32_t i;
|
||||
|
||||
if (nargs == 0)
|
||||
return FL_NIL;
|
||||
value_t lst, first = FL_NIL;
|
||||
value_t *pcdr = &first;
|
||||
struct cons *c;
|
||||
uint32_t i = 0;
|
||||
first = FL_NIL;
|
||||
pcdr = &first;
|
||||
i = 0;
|
||||
while (1) {
|
||||
lst = args[i++];
|
||||
if (i >= nargs)
|
||||
|
@ -73,11 +77,13 @@ static value_t fl_nconc(value_t *args, uint32_t nargs)
|
|||
|
||||
static value_t fl_assq(value_t *args, uint32_t nargs)
|
||||
{
|
||||
argcount("assq", nargs, 2);
|
||||
value_t item = args[0];
|
||||
value_t v = args[1];
|
||||
value_t item;
|
||||
value_t v;
|
||||
value_t bind;
|
||||
|
||||
argcount("assq", nargs, 2);
|
||||
item = args[0];
|
||||
v = args[1];
|
||||
while (iscons(v)) {
|
||||
bind = car_(v);
|
||||
if (iscons(bind) && car_(bind) == item)
|
||||
|
@ -101,9 +107,11 @@ static value_t fl_memq(value_t *args, uint32_t nargs)
|
|||
|
||||
static value_t fl_length(value_t *args, uint32_t nargs)
|
||||
{
|
||||
argcount("length", nargs, 1);
|
||||
value_t a = args[0];
|
||||
value_t a;
|
||||
struct cvalue *cv;
|
||||
|
||||
argcount("length", nargs, 1);
|
||||
a = args[0];
|
||||
if (isvector(a)) {
|
||||
return fixnum(vector_size(a));
|
||||
} else if (iscprim(a)) {
|
||||
|
@ -123,12 +131,14 @@ static value_t fl_length(value_t *args, uint32_t nargs)
|
|||
return fixnum(llength(a));
|
||||
}
|
||||
type_error("length", "sequence", a);
|
||||
return FL_NIL; // TODO
|
||||
}
|
||||
|
||||
static value_t fl_f_raise(value_t *args, uint32_t nargs)
|
||||
{
|
||||
argcount("raise", nargs, 1);
|
||||
fl_raise(args[0]);
|
||||
return FL_NIL; // TODO
|
||||
}
|
||||
|
||||
static value_t fl_exit(value_t *args, uint32_t nargs)
|
||||
|
@ -157,8 +167,10 @@ static value_t fl_keywordp(value_t *args, uint32_t nargs)
|
|||
|
||||
static value_t fl_top_level_value(value_t *args, uint32_t nargs)
|
||||
{
|
||||
struct symbol *sym;
|
||||
|
||||
argcount("top-level-value", nargs, 1);
|
||||
struct symbol *sym = tosymbol(args[0], "top-level-value");
|
||||
sym = tosymbol(args[0], "top-level-value");
|
||||
if (sym->binding == UNBOUND)
|
||||
fl_raise(fl_list2(UnboundError, args[0]));
|
||||
return sym->binding;
|
||||
|
@ -166,8 +178,10 @@ static value_t fl_top_level_value(value_t *args, uint32_t nargs)
|
|||
|
||||
static value_t fl_set_top_level_value(value_t *args, uint32_t nargs)
|
||||
{
|
||||
struct symbol *sym;
|
||||
|
||||
argcount("set-top-level-value!", nargs, 2);
|
||||
struct symbol *sym = tosymbol(args[0], "set-top-level-value!");
|
||||
sym = tosymbol(args[0], "set-top-level-value!");
|
||||
if (!isconstant(sym))
|
||||
sym->binding = args[1];
|
||||
return args[1];
|
||||
|
@ -188,9 +202,11 @@ extern struct symbol *symtab;
|
|||
|
||||
value_t fl_global_env(value_t *args, uint32_t nargs)
|
||||
{
|
||||
value_t lst;
|
||||
|
||||
(void)args;
|
||||
argcount("environment", nargs, 0);
|
||||
value_t lst = FL_NIL;
|
||||
lst = FL_NIL;
|
||||
fl_gc_handle(&lst);
|
||||
global_env_list(symtab, &lst);
|
||||
fl_free_gc_handles(1);
|
||||
|
@ -214,15 +230,19 @@ static value_t fl_constantp(value_t *args, uint32_t nargs)
|
|||
|
||||
static value_t fl_integer_valuedp(value_t *args, uint32_t nargs)
|
||||
{
|
||||
value_t v;
|
||||
double d;
|
||||
void *data;
|
||||
|
||||
argcount("integer-valued?", nargs, 1);
|
||||
value_t v = args[0];
|
||||
v = args[0];
|
||||
if (isfixnum(v)) {
|
||||
return FL_T;
|
||||
} else if (iscprim(v)) {
|
||||
numerictype_t nt = cp_numtype((struct cprim *)ptr(v));
|
||||
if (nt < T_FLOAT)
|
||||
return FL_T;
|
||||
void *data = cp_data((struct cprim *)ptr(v));
|
||||
data = cp_data((struct cprim *)ptr(v));
|
||||
if (nt == T_FLOAT) {
|
||||
float f = *(float *)data;
|
||||
if (f < 0)
|
||||
|
@ -231,7 +251,7 @@ static value_t fl_integer_valuedp(value_t *args, uint32_t nargs)
|
|||
return FL_T;
|
||||
} else {
|
||||
assert(nt == T_DOUBLE);
|
||||
double d = *(double *)data;
|
||||
d = *(double *)data;
|
||||
if (d < 0)
|
||||
d = -d;
|
||||
if (d <= DBL_MAXINT && (double)(int64_t)d == d)
|
||||
|
@ -243,8 +263,10 @@ static value_t fl_integer_valuedp(value_t *args, uint32_t nargs)
|
|||
|
||||
static value_t fl_integerp(value_t *args, uint32_t nargs)
|
||||
{
|
||||
value_t v;
|
||||
|
||||
argcount("integer?", nargs, 1);
|
||||
value_t v = args[0];
|
||||
v = args[0];
|
||||
return (isfixnum(v) ||
|
||||
(iscprim(v) && cp_numtype((struct cprim *)ptr(v)) < T_FLOAT))
|
||||
? FL_T
|
||||
|
@ -261,6 +283,7 @@ static value_t fl_fixnum(value_t *args, uint32_t nargs)
|
|||
return fixnum(conv_to_long(cp_data(cp), cp_numtype(cp)));
|
||||
}
|
||||
type_error("fixnum", "number", args[0]);
|
||||
return FL_NIL; // TODO
|
||||
}
|
||||
|
||||
static value_t fl_truncate(value_t *args, uint32_t nargs)
|
||||
|
@ -289,12 +312,15 @@ static value_t fl_truncate(value_t *args, uint32_t nargs)
|
|||
return return_from_int64((int64_t)d);
|
||||
}
|
||||
type_error("truncate", "number", args[0]);
|
||||
return FL_NIL; // TODO
|
||||
}
|
||||
|
||||
static value_t fl_vector_alloc(value_t *args, uint32_t nargs)
|
||||
{
|
||||
fixnum_t i;
|
||||
value_t f, v;
|
||||
int k;
|
||||
|
||||
if (nargs == 0)
|
||||
lerror(ArgError, "vector.alloc: too few arguments");
|
||||
i = (fixnum_t)toulong(args[0], "vector.alloc");
|
||||
|
@ -305,7 +331,6 @@ static value_t fl_vector_alloc(value_t *args, uint32_t nargs)
|
|||
f = args[1];
|
||||
else
|
||||
f = FL_UNSPECIFIED;
|
||||
int k;
|
||||
for (k = 0; k < i; k++)
|
||||
vector_elt(v, k) = f;
|
||||
return v;
|
||||
|
@ -328,10 +353,13 @@ static double todouble(value_t a, char *fname)
|
|||
return conv_to_double(cp_data(cp), nt);
|
||||
}
|
||||
type_error(fname, "number", a);
|
||||
return FL_NIL; // TODO
|
||||
}
|
||||
|
||||
static value_t fl_path_cwd(value_t *args, uint32_t nargs)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
if (nargs > 1)
|
||||
argcount("path.cwd", nargs, 1);
|
||||
if (nargs == 0) {
|
||||
|
@ -339,7 +367,7 @@ static value_t fl_path_cwd(value_t *args, uint32_t nargs)
|
|||
get_cwd(buf, sizeof(buf));
|
||||
return string_from_cstr(buf);
|
||||
}
|
||||
char *ptr = tostring(args[0], "path.cwd");
|
||||
ptr = tostring(args[0], "path.cwd");
|
||||
if (set_cwd(ptr))
|
||||
lerrorf(IOError, "path.cwd: could not cd to %s", ptr);
|
||||
return FL_T;
|
||||
|
@ -347,16 +375,21 @@ static value_t fl_path_cwd(value_t *args, uint32_t nargs)
|
|||
|
||||
static value_t fl_path_exists(value_t *args, uint32_t nargs)
|
||||
{
|
||||
char *str;
|
||||
|
||||
argcount("path.exists?", nargs, 1);
|
||||
char *str = tostring(args[0], "path.exists?");
|
||||
str = tostring(args[0], "path.exists?");
|
||||
return os_path_exists(str) ? FL_T : FL_F;
|
||||
}
|
||||
|
||||
static value_t fl_os_getenv(value_t *args, uint32_t nargs)
|
||||
{
|
||||
char *name;
|
||||
char *val;
|
||||
|
||||
argcount("os.getenv", nargs, 1);
|
||||
char *name = tostring(args[0], "os.getenv");
|
||||
char *val = getenv(name);
|
||||
name = tostring(args[0], "os.getenv");
|
||||
val = getenv(name);
|
||||
if (val == NULL)
|
||||
return FL_F;
|
||||
if (*val == 0)
|
||||
|
@ -366,25 +399,30 @@ static value_t fl_os_getenv(value_t *args, uint32_t nargs)
|
|||
|
||||
static value_t fl_os_setenv(value_t *args, uint32_t nargs)
|
||||
{
|
||||
argcount("os.setenv", nargs, 2);
|
||||
char *name = tostring(args[0], "os.setenv");
|
||||
char *name;
|
||||
char *val;
|
||||
int result;
|
||||
|
||||
argcount("os.setenv", nargs, 2);
|
||||
name = tostring(args[0], "os.setenv");
|
||||
if (args[1] == FL_F) {
|
||||
result = unsetenv(name);
|
||||
unsetenv(name);
|
||||
} else {
|
||||
char *val = tostring(args[1], "os.setenv");
|
||||
val = tostring(args[1], "os.setenv");
|
||||
result = setenv(name, val, 1);
|
||||
if (result != 0) {
|
||||
lerror(ArgError, "os.setenv: invalid environment variable");
|
||||
}
|
||||
}
|
||||
if (result != 0)
|
||||
lerror(ArgError, "os.setenv: invalid environment variable");
|
||||
return FL_T;
|
||||
}
|
||||
|
||||
static value_t fl_rand(value_t *args, uint32_t nargs)
|
||||
{
|
||||
fixnum_t r;
|
||||
|
||||
(void)args;
|
||||
(void)nargs;
|
||||
fixnum_t r;
|
||||
#ifdef BITS64
|
||||
r = ((((uint64_t)random()) << 32) | random()) & 0x1fffffffffffffffLL;
|
||||
#else
|
||||
|
@ -392,30 +430,38 @@ static value_t fl_rand(value_t *args, uint32_t nargs)
|
|||
#endif
|
||||
return fixnum(r);
|
||||
}
|
||||
|
||||
static value_t fl_rand32(value_t *args, uint32_t nargs)
|
||||
{
|
||||
uint32_t r;
|
||||
|
||||
(void)args;
|
||||
(void)nargs;
|
||||
uint32_t r = random();
|
||||
r = random();
|
||||
#ifdef BITS64
|
||||
return fixnum(r);
|
||||
#else
|
||||
return mk_uint32(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
static value_t fl_rand64(value_t *args, uint32_t nargs)
|
||||
{
|
||||
uint64_t r;
|
||||
|
||||
(void)args;
|
||||
(void)nargs;
|
||||
uint64_t r = (((uint64_t)random()) << 32) | random();
|
||||
r = (((uint64_t)random()) << 32) | random();
|
||||
return mk_uint64(r);
|
||||
}
|
||||
|
||||
static value_t fl_randd(value_t *args, uint32_t nargs)
|
||||
{
|
||||
(void)args;
|
||||
(void)nargs;
|
||||
return mk_double(rand_double());
|
||||
}
|
||||
|
||||
static value_t fl_randf(value_t *args, uint32_t nargs)
|
||||
{
|
||||
(void)args;
|
||||
|
@ -423,17 +469,19 @@ static value_t fl_randf(value_t *args, uint32_t nargs)
|
|||
return mk_float(rand_float());
|
||||
}
|
||||
|
||||
#define MATH_FUNC_1ARG(name) \
|
||||
static value_t fl_##name(value_t *args, uint32_t nargs) \
|
||||
{ \
|
||||
argcount(#name, nargs, 1); \
|
||||
if (iscprim(args[0])) { \
|
||||
struct cprim *cp = (struct cprim *)ptr(args[0]); \
|
||||
numerictype_t nt = cp_numtype(cp); \
|
||||
if (nt == T_FLOAT) \
|
||||
return mk_float(name##f(*(float *)cp_data(cp))); \
|
||||
} \
|
||||
return mk_double(name(todouble(args[0], #name))); \
|
||||
#define MATH_FUNC_1ARG(name) \
|
||||
static value_t fl_##name(value_t *args, uint32_t nargs) \
|
||||
{ \
|
||||
argcount(#name, nargs, 1); \
|
||||
if (iscprim(args[0])) { \
|
||||
struct cprim *cp = (struct cprim *)ptr(args[0]); \
|
||||
numerictype_t nt = cp_numtype(cp); \
|
||||
if (nt == T_FLOAT) { \
|
||||
float f = *(float *)cp_data(cp); \
|
||||
return mk_float(name((double)f)); \
|
||||
} \
|
||||
} \
|
||||
return mk_double(name(todouble(args[0], #name))); \
|
||||
}
|
||||
|
||||
MATH_FUNC_1ARG(sqrt)
|
||||
|
|
156
c/cvalues.h
156
c/cvalues.h
|
@ -119,10 +119,11 @@ void cv_autorelease(struct cvalue *cv) { autorelease(cv); }
|
|||
|
||||
static value_t cprim(struct fltype *type, size_t sz)
|
||||
{
|
||||
struct cprim *pcp;
|
||||
|
||||
assert(!ismanaged((uintptr_t)type));
|
||||
assert(sz == type->size);
|
||||
struct cprim *pcp =
|
||||
(struct cprim *)alloc_words(CPRIM_NWORDS - 1 + NWORDS(sz));
|
||||
pcp = (struct cprim *)alloc_words(CPRIM_NWORDS - 1 + NWORDS(sz));
|
||||
pcp->type = type;
|
||||
return tagptr(pcp, TAG_CPRIM);
|
||||
}
|
||||
|
@ -130,8 +131,9 @@ static value_t cprim(struct fltype *type, size_t sz)
|
|||
value_t cvalue(struct fltype *type, size_t sz)
|
||||
{
|
||||
struct cvalue *pcv;
|
||||
int str = 0;
|
||||
int str;
|
||||
|
||||
str = 0;
|
||||
if (valid_numtype(type->numtype)) {
|
||||
return cprim(type, sz);
|
||||
}
|
||||
|
@ -168,6 +170,7 @@ value_t cvalue(struct fltype *type, size_t sz)
|
|||
value_t cvalue_from_data(struct fltype *type, void *data, size_t sz)
|
||||
{
|
||||
value_t cv;
|
||||
|
||||
cv = cvalue(type, sz);
|
||||
memcpy(cptr(cv), data, sz);
|
||||
return cv;
|
||||
|
@ -208,7 +211,9 @@ value_t cvalue_static_cstring(const char *str)
|
|||
|
||||
value_t string_from_cstrn(const char *str, size_t n)
|
||||
{
|
||||
value_t v = cvalue_string(n);
|
||||
value_t v;
|
||||
|
||||
v = cvalue_string(n);
|
||||
memcpy(cvalue_data(v), str, n);
|
||||
return v;
|
||||
}
|
||||
|
@ -226,12 +231,15 @@ int fl_isstring(value_t v)
|
|||
// convert to malloc representation (fixed address)
|
||||
void cv_pin(struct cvalue *cv)
|
||||
{
|
||||
size_t sz;
|
||||
void *data;
|
||||
|
||||
if (!isinlined(cv))
|
||||
return;
|
||||
size_t sz = cv_len(cv);
|
||||
sz = cv_len(cv);
|
||||
if (cv_isstr(cv))
|
||||
sz++;
|
||||
void *data = malloc(sz);
|
||||
data = malloc(sz);
|
||||
memcpy(data, cv_data(cv), sz);
|
||||
cv->data = data;
|
||||
autorelease(cv);
|
||||
|
@ -264,11 +272,12 @@ num_init(float, double, T_FLOAT) num_init(double, double, T_DOUBLE)
|
|||
#define num_ctor_init(typenam, ctype, tag) \
|
||||
value_t cvalue_##typenam(value_t *args, uint32_t nargs) \
|
||||
{ \
|
||||
value_t cp; \
|
||||
if (nargs == 0) { \
|
||||
PUSH(fixnum(0)); \
|
||||
args = &Stack[SP - 1]; \
|
||||
} \
|
||||
value_t cp = cprim(typenam##type, sizeof(ctype##_t)); \
|
||||
cp = cprim(typenam##type, sizeof(ctype##_t)); \
|
||||
if (cvalue_##ctype##_init(typenam##type, args[0], \
|
||||
cp_data((struct cprim *)ptr(cp)))) \
|
||||
type_error(#typenam, "number", args[0]); \
|
||||
|
@ -352,10 +361,13 @@ static int cvalue_enum_init(struct fltype *ft, value_t arg, void *dest)
|
|||
|
||||
value_t cvalue_enum(value_t *args, uint32_t nargs)
|
||||
{
|
||||
value_t cv, type;
|
||||
struct fltype *ft;
|
||||
|
||||
argcount("enum", nargs, 2);
|
||||
value_t type = fl_list2(enumsym, args[0]);
|
||||
struct fltype *ft = get_type(type);
|
||||
value_t cv = cvalue(ft, sizeof(int32_t));
|
||||
type = fl_list2(enumsym, args[0]);
|
||||
ft = get_type(type);
|
||||
cv = cvalue(ft, sizeof(int32_t));
|
||||
cvalue_enum_init(ft, args[1], cp_data((struct cprim *)ptr(cv)));
|
||||
return cv;
|
||||
}
|
||||
|
@ -443,18 +455,20 @@ static int cvalue_array_init(struct fltype *ft, value_t arg, void *dest)
|
|||
value_t cvalue_array(value_t *args, uint32_t nargs)
|
||||
{
|
||||
size_t elsize, cnt, sz, i;
|
||||
value_t arg;
|
||||
value_t arg, cv;
|
||||
struct fltype *type;
|
||||
char *dest;
|
||||
|
||||
if (nargs < 1)
|
||||
argcount("array", nargs, 1);
|
||||
|
||||
cnt = nargs - 1;
|
||||
struct fltype *type = get_array_type(args[0]);
|
||||
type = get_array_type(args[0]);
|
||||
elsize = type->elsz;
|
||||
sz = elsize * cnt;
|
||||
|
||||
value_t cv = cvalue(type, sz);
|
||||
char *dest = cv_data((struct cvalue *)ptr(cv));
|
||||
cv = cvalue(type, sz);
|
||||
dest = cv_data((struct cvalue *)ptr(cv));
|
||||
FOR_ARGS(i, 1, arg, args)
|
||||
{
|
||||
cvalue_init(type->eltype, arg, dest);
|
||||
|
@ -476,8 +490,8 @@ static size_t cvalue_struct_offs(value_t type, value_t field,
|
|||
value_t fld = car(cdr_(type));
|
||||
size_t fsz, ssz = 0;
|
||||
int al;
|
||||
*palign = 0;
|
||||
|
||||
*palign = 0;
|
||||
while (iscons(fld)) {
|
||||
fsz = ctype_sizeof(car(cdr(car_(fld))), &al);
|
||||
|
||||
|
@ -501,8 +515,8 @@ static size_t cvalue_union_size(value_t type, int *palign)
|
|||
value_t fld = car(cdr_(type));
|
||||
size_t fsz, usz = 0;
|
||||
int al;
|
||||
*palign = 0;
|
||||
|
||||
*palign = 0;
|
||||
while (iscons(fld)) {
|
||||
fsz = ctype_sizeof(car(cdr(car_(fld))), &al);
|
||||
if (al > *palign)
|
||||
|
@ -517,6 +531,9 @@ static size_t cvalue_union_size(value_t type, int *palign)
|
|||
// *palign is an output argument giving the alignment required by type
|
||||
size_t ctype_sizeof(value_t type, int *palign)
|
||||
{
|
||||
value_t hed, t, n;
|
||||
size_t sz;
|
||||
|
||||
if (type == int8sym || type == uint8sym || type == bytesym) {
|
||||
*palign = 1;
|
||||
return 1;
|
||||
|
@ -544,17 +561,17 @@ size_t ctype_sizeof(value_t type, int *palign)
|
|||
#endif
|
||||
}
|
||||
if (iscons(type)) {
|
||||
value_t hed = car_(type);
|
||||
hed = car_(type);
|
||||
if (hed == pointersym || hed == cfunctionsym) {
|
||||
*palign = ALIGNPTR;
|
||||
return sizeof(void *);
|
||||
}
|
||||
if (hed == arraysym) {
|
||||
value_t t = car(cdr_(type));
|
||||
t = car(cdr_(type));
|
||||
if (!iscons(cdr_(cdr_(type))))
|
||||
lerror(ArgError, "sizeof: incomplete type");
|
||||
value_t n = car_(cdr_(cdr_(type)));
|
||||
size_t sz = toulong(n, "sizeof");
|
||||
n = car_(cdr_(cdr_(type)));
|
||||
sz = toulong(n, "sizeof");
|
||||
return sz * ctype_sizeof(t, palign);
|
||||
} else if (hed == structsym) {
|
||||
return cvalue_struct_offs(type, NIL, 1, palign);
|
||||
|
@ -597,13 +614,14 @@ void to_sized_ptr(value_t v, char *fname, char **pdata, size_t *psz)
|
|||
|
||||
value_t cvalue_sizeof(value_t *args, uint32_t nargs)
|
||||
{
|
||||
char *data;
|
||||
size_t n;
|
||||
int a;
|
||||
|
||||
argcount("sizeof", nargs, 1);
|
||||
if (issymbol(args[0]) || iscons(args[0])) {
|
||||
int a;
|
||||
return size_wrap(ctype_sizeof(args[0], &a));
|
||||
}
|
||||
size_t n;
|
||||
char *data;
|
||||
to_sized_ptr(args[0], "sizeof", &data, &n);
|
||||
return size_wrap(n);
|
||||
}
|
||||
|
@ -637,10 +655,11 @@ value_t cvalue_typeof(value_t *args, uint32_t nargs)
|
|||
|
||||
static value_t cvalue_relocate(value_t v)
|
||||
{
|
||||
size_t nw;
|
||||
struct cvalue *cv = (struct cvalue *)ptr(v);
|
||||
struct cvalue *nv;
|
||||
struct fltype *t;
|
||||
value_t ncv;
|
||||
size_t nw;
|
||||
|
||||
nw = cv_nwords(cv);
|
||||
nv = (struct cvalue *)alloc_words(nw);
|
||||
|
@ -648,7 +667,7 @@ static value_t cvalue_relocate(value_t v)
|
|||
if (isinlined(cv))
|
||||
nv->data = &nv->_space[0];
|
||||
ncv = tagptr(nv, TAG_CVALUE);
|
||||
struct fltype *t = cv_class(cv);
|
||||
t = cv_class(cv);
|
||||
if (t->vtable != NULL && t->vtable->relocate != NULL)
|
||||
t->vtable->relocate(v, ncv);
|
||||
forward(v, ncv);
|
||||
|
@ -657,16 +676,20 @@ static value_t cvalue_relocate(value_t v)
|
|||
|
||||
value_t cvalue_copy(value_t v)
|
||||
{
|
||||
struct cvalue *ncv;
|
||||
struct cvalue *cv;
|
||||
size_t nw, len;
|
||||
|
||||
assert(iscvalue(v));
|
||||
PUSH(v);
|
||||
struct cvalue *cv = (struct cvalue *)ptr(v);
|
||||
size_t nw = cv_nwords(cv);
|
||||
struct cvalue *ncv = (struct cvalue *)alloc_words(nw);
|
||||
cv = (struct cvalue *)ptr(v);
|
||||
nw = cv_nwords(cv);
|
||||
ncv = (struct cvalue *)alloc_words(nw);
|
||||
v = POP();
|
||||
cv = (struct cvalue *)ptr(v);
|
||||
memcpy(ncv, cv, nw * sizeof(value_t));
|
||||
if (!isinlined(cv)) {
|
||||
size_t len = cv_len(cv);
|
||||
len = cv_len(cv);
|
||||
if (cv_isstr(cv))
|
||||
len++;
|
||||
ncv->data = malloc(len);
|
||||
|
@ -762,16 +785,17 @@ static numerictype_t sym_to_numtype(value_t type)
|
|||
// type, including user-defined.
|
||||
value_t cvalue_new(value_t *args, uint32_t nargs)
|
||||
{
|
||||
struct fltype *ft;
|
||||
value_t cv, type;
|
||||
size_t elsz, cnt;
|
||||
|
||||
if (nargs < 1 || nargs > 2)
|
||||
argcount("c-value", nargs, 2);
|
||||
value_t type = args[0];
|
||||
struct fltype *ft = get_type(type);
|
||||
value_t cv;
|
||||
type = args[0];
|
||||
ft = get_type(type);
|
||||
if (ft->eltype != NULL) {
|
||||
// special case to handle incomplete array types bla[]
|
||||
size_t elsz = ft->elsz;
|
||||
size_t cnt;
|
||||
|
||||
elsz = ft->elsz;
|
||||
if (iscons(cdr_(cdr_(type))))
|
||||
cnt = toulong(car_(cdr_(cdr_(type))), "array");
|
||||
else if (nargs == 2)
|
||||
|
@ -800,6 +824,7 @@ value_t cvalue_compare(value_t a, value_t b)
|
|||
size_t bsz = cv_len(cb);
|
||||
size_t minsz = asz < bsz ? asz : bsz;
|
||||
int diff = memcmp(adata, bdata, minsz);
|
||||
|
||||
if (diff == 0) {
|
||||
if (asz > bsz)
|
||||
return fixnum(1);
|
||||
|
@ -813,7 +838,9 @@ static void check_addr_args(char *fname, value_t arr, value_t ind,
|
|||
char **data, unsigned long *index)
|
||||
{
|
||||
size_t numel;
|
||||
struct cvalue *cv = (struct cvalue *)ptr(arr);
|
||||
struct cvalue *cv;
|
||||
|
||||
cv = (struct cvalue *)ptr(arr);
|
||||
*data = cv_data(cv);
|
||||
numel = cv_len(cv) / (cv_class(cv)->elsz);
|
||||
*index = toulong(ind, fname);
|
||||
|
@ -828,6 +855,9 @@ static value_t cvalue_array_aref(value_t *args)
|
|||
struct fltype *eltype = cv_class((struct cvalue *)ptr(args[0]))->eltype;
|
||||
value_t el = 0;
|
||||
numerictype_t nt = eltype->numtype;
|
||||
char *dest;
|
||||
size_t sz;
|
||||
|
||||
if (nt >= T_INT32)
|
||||
el = cvalue(eltype, eltype->size);
|
||||
check_addr_args("aref", args[0], args[1], &data, &index);
|
||||
|
@ -840,8 +870,8 @@ static value_t cvalue_array_aref(value_t *args)
|
|||
return fixnum(((int16_t *)data)[index]);
|
||||
return fixnum(((uint16_t *)data)[index]);
|
||||
}
|
||||
char *dest = cptr(el);
|
||||
size_t sz = eltype->size;
|
||||
dest = cptr(el);
|
||||
sz = eltype->size;
|
||||
if (sz == 1)
|
||||
*dest = data[index];
|
||||
else if (sz == 2)
|
||||
|
@ -858,19 +888,24 @@ static value_t cvalue_array_aref(value_t *args)
|
|||
static value_t cvalue_array_aset(value_t *args)
|
||||
{
|
||||
char *data;
|
||||
char *dest;
|
||||
unsigned long index;
|
||||
struct fltype *eltype = cv_class((struct cvalue *)ptr(args[0]))->eltype;
|
||||
struct fltype *eltype;
|
||||
|
||||
eltype = cv_class((struct cvalue *)ptr(args[0]))->eltype;
|
||||
check_addr_args("aset!", args[0], args[1], &data, &index);
|
||||
char *dest = data + index * eltype->size;
|
||||
dest = data + index * eltype->size;
|
||||
cvalue_init(eltype, args[2], dest);
|
||||
return args[2];
|
||||
}
|
||||
|
||||
value_t fl_builtin(value_t *args, uint32_t nargs)
|
||||
{
|
||||
argcount("builtin", nargs, 1);
|
||||
struct symbol *name = tosymbol(args[0], "builtin");
|
||||
struct symbol *name;
|
||||
struct cvalue *cv;
|
||||
|
||||
argcount("builtin", nargs, 1);
|
||||
name = tosymbol(args[0], "builtin");
|
||||
if (ismanaged(args[0]) || (cv = name->dlcache) == NULL) {
|
||||
lerrorf(ArgError, "builtin: function %s not found", name->name);
|
||||
}
|
||||
|
@ -879,17 +914,17 @@ value_t fl_builtin(value_t *args, uint32_t nargs)
|
|||
|
||||
value_t cbuiltin(char *name, builtin_t f)
|
||||
{
|
||||
struct cvalue *cv =
|
||||
(struct cvalue *)malloc(CVALUE_NWORDS * sizeof(value_t));
|
||||
struct cvalue *cv;
|
||||
value_t sym;
|
||||
|
||||
cv = (struct cvalue *)malloc(CVALUE_NWORDS * sizeof(value_t));
|
||||
cv->type = builtintype;
|
||||
cv->data = &cv->_space[0];
|
||||
cv->len = sizeof(value_t);
|
||||
*(void **)cv->data = f;
|
||||
|
||||
value_t sym = symbol(name);
|
||||
sym = symbol(name);
|
||||
((struct symbol *)ptr(sym))->dlcache = cv;
|
||||
ptrhash_put(&reverse_dlsym_lookup_table, cv, (void *)sym);
|
||||
|
||||
return tagptr(cv, TAG_CVALUE);
|
||||
}
|
||||
|
||||
|
@ -1183,6 +1218,7 @@ static value_t fl_neg(value_t n)
|
|||
}
|
||||
}
|
||||
type_error("-", "number", n);
|
||||
return FL_NIL; // TODO: remove
|
||||
}
|
||||
|
||||
static value_t fl_mul_any(value_t *args, uint32_t nargs, int64_t Saccum)
|
||||
|
@ -1555,14 +1591,15 @@ static value_t fl_logxor(value_t *args, uint32_t nargs)
|
|||
|
||||
static value_t fl_lognot(value_t *args, uint32_t nargs)
|
||||
{
|
||||
struct cprim *cp;
|
||||
void *aptr;
|
||||
value_t a;
|
||||
int ta;
|
||||
|
||||
argcount("lognot", nargs, 1);
|
||||
value_t a = args[0];
|
||||
a = args[0];
|
||||
if (isfixnum(a))
|
||||
return fixnum(~numval(a));
|
||||
struct cprim *cp;
|
||||
int ta;
|
||||
void *aptr;
|
||||
|
||||
if (iscprim(a)) {
|
||||
cp = (struct cprim *)ptr(a);
|
||||
ta = cp_numtype(cp);
|
||||
|
@ -1587,14 +1624,20 @@ static value_t fl_lognot(value_t *args, uint32_t nargs)
|
|||
}
|
||||
}
|
||||
type_error("lognot", "integer", a);
|
||||
return FL_NIL; // TODO: remove
|
||||
}
|
||||
|
||||
static value_t fl_ash(value_t *args, uint32_t nargs)
|
||||
{
|
||||
int64_t accum, i64;
|
||||
value_t a;
|
||||
fixnum_t n;
|
||||
int64_t accum;
|
||||
struct cprim *cp;
|
||||
void *aptr;
|
||||
int ta;
|
||||
|
||||
argcount("ash", nargs, 2);
|
||||
value_t a = args[0];
|
||||
a = args[0];
|
||||
n = tofixnum(args[1], "ash");
|
||||
if (isfixnum(a)) {
|
||||
if (n <= 0)
|
||||
|
@ -1605,9 +1648,6 @@ static value_t fl_ash(value_t *args, uint32_t nargs)
|
|||
else
|
||||
return return_from_int64(accum);
|
||||
}
|
||||
struct cprim *cp;
|
||||
int ta;
|
||||
void *aptr;
|
||||
if (iscprim(a)) {
|
||||
if (n == 0)
|
||||
return a;
|
||||
|
@ -1638,7 +1678,7 @@ static value_t fl_ash(value_t *args, uint32_t nargs)
|
|||
if (ta == T_UINT64)
|
||||
return return_from_uint64((*(uint64_t *)aptr) << n);
|
||||
else if (ta < T_FLOAT) {
|
||||
int64_t i64 = conv_to_int64(aptr, ta);
|
||||
i64 = conv_to_int64(aptr, ta);
|
||||
return return_from_int64(i64 << n);
|
||||
}
|
||||
}
|
||||
|
|
23
c/equal.h
23
c/equal.h
|
@ -54,15 +54,15 @@ static value_t bounded_vector_compare(value_t a, value_t b, int bound, int eq)
|
|||
static value_t bounded_compare(value_t a, value_t b, int bound, int eq)
|
||||
{
|
||||
value_t d;
|
||||
int taga, tagb, c;
|
||||
|
||||
compare_top:
|
||||
if (a == b)
|
||||
return fixnum(0);
|
||||
if (bound <= 0)
|
||||
return NIL;
|
||||
int taga = tag(a);
|
||||
int tagb = cmptag(b);
|
||||
int c;
|
||||
taga = tag(a);
|
||||
tagb = cmptag(b);
|
||||
switch (taga) {
|
||||
case TAG_NUM:
|
||||
case TAG_NUM1:
|
||||
|
@ -143,10 +143,11 @@ compare_top:
|
|||
static value_t cyc_vector_compare(value_t a, value_t b, struct htable *table,
|
||||
int eq)
|
||||
{
|
||||
size_t la = vector_size(a);
|
||||
size_t lb = vector_size(b);
|
||||
size_t m, i;
|
||||
value_t d, xa, xb, ca, cb;
|
||||
size_t m, i, la, lb;
|
||||
|
||||
la = vector_size(a);
|
||||
lb = vector_size(b);
|
||||
|
||||
// first try to prove them different with no recursion
|
||||
if (eq && (la != lb))
|
||||
|
@ -193,6 +194,7 @@ static value_t cyc_vector_compare(value_t a, value_t b, struct htable *table,
|
|||
static value_t cyc_compare(value_t a, value_t b, struct htable *table, int eq)
|
||||
{
|
||||
value_t d, ca, cb;
|
||||
|
||||
cyc_compare_top:
|
||||
if (a == b)
|
||||
return fixnum(0);
|
||||
|
@ -305,7 +307,6 @@ value_t fl_equal(value_t a, value_t b)
|
|||
// *oob: output argument, means we hit the limit specified by 'bound'
|
||||
static uintptr_t bounded_hash(value_t a, int bound, int *oob)
|
||||
{
|
||||
*oob = 0;
|
||||
union {
|
||||
double d;
|
||||
int64_t i64;
|
||||
|
@ -315,8 +316,12 @@ static uintptr_t bounded_hash(value_t a, int bound, int *oob)
|
|||
struct cvalue *cv;
|
||||
struct cprim *cp;
|
||||
void *data;
|
||||
uintptr_t h = 0;
|
||||
int oob2, tg = tag(a);
|
||||
uintptr_t h;
|
||||
int oob2, tg;
|
||||
|
||||
*oob = 0;
|
||||
h = 0;
|
||||
tg = tag(a);
|
||||
switch (tg) {
|
||||
case TAG_NUM:
|
||||
case TAG_NUM1:
|
||||
|
|
249
c/flisp.c
249
c/flisp.c
|
@ -189,6 +189,8 @@ void fl_restorestate(struct fl_exception_context *_ctx)
|
|||
|
||||
void fl_raise(value_t e)
|
||||
{
|
||||
struct fl_exception_context *thisctx;
|
||||
|
||||
fl_lasterror = e;
|
||||
// unwind read state
|
||||
while (readstate != fl_ctx->rdst) {
|
||||
|
@ -198,7 +200,7 @@ void fl_raise(value_t e)
|
|||
if (fl_throwing_frame == 0)
|
||||
fl_throwing_frame = curr_frame;
|
||||
N_GCHND = fl_ctx->ngchnd;
|
||||
struct fl_exception_context *thisctx = fl_ctx;
|
||||
thisctx = fl_ctx;
|
||||
if (fl_ctx->prev) // don't throw past toplevel
|
||||
fl_ctx = fl_ctx->prev;
|
||||
longjmp(thisctx->buf, 1);
|
||||
|
@ -207,6 +209,7 @@ void fl_raise(value_t e)
|
|||
static value_t make_error_msg(char *format, va_list args)
|
||||
{
|
||||
char msgbuf[512];
|
||||
|
||||
vsnprintf(msgbuf, sizeof(msgbuf), format, args);
|
||||
return string_from_cstr(msgbuf);
|
||||
}
|
||||
|
@ -214,19 +217,22 @@ static value_t make_error_msg(char *format, va_list args)
|
|||
void lerrorf(value_t e, char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
value_t msg;
|
||||
|
||||
PUSH(e);
|
||||
va_start(args, format);
|
||||
value_t msg = make_error_msg(format, args);
|
||||
msg = make_error_msg(format, args);
|
||||
va_end(args);
|
||||
|
||||
e = POP();
|
||||
fl_raise(fl_list2(e, msg));
|
||||
}
|
||||
|
||||
void lerror(value_t e, const char *msg)
|
||||
{
|
||||
value_t m;
|
||||
|
||||
PUSH(e);
|
||||
value_t m = cvalue_static_cstring(msg);
|
||||
m = cvalue_static_cstring(msg);
|
||||
e = POP();
|
||||
fl_raise(fl_list2(e, m));
|
||||
}
|
||||
|
@ -245,12 +251,14 @@ void bounds_error(char *fname, value_t arr, value_t ind)
|
|||
// --------------------------------------------------------
|
||||
|
||||
#define isstring fl_isstring
|
||||
// TODO: Remove the spurious return statement.
|
||||
#define SAFECAST_OP(type, ctype, cnvt) \
|
||||
ctype to##type(value_t v, char *fname) \
|
||||
{ \
|
||||
if (is##type(v)) \
|
||||
return (ctype)cnvt(v); \
|
||||
type_error(fname, #type, v); \
|
||||
return (ctype)FL_NIL; \
|
||||
}
|
||||
SAFECAST_OP(cons, struct cons *, ptr)
|
||||
SAFECAST_OP(symbol, struct symbol *, ptr)
|
||||
|
@ -325,10 +333,11 @@ static char gsname[2][16];
|
|||
static int gsnameno = 0;
|
||||
value_t fl_gensym(value_t *args, uint32_t nargs)
|
||||
{
|
||||
argcount("gensym", nargs, 0);
|
||||
struct gensym *gs;
|
||||
|
||||
(void)args;
|
||||
struct gensym *gs =
|
||||
(struct gensym *)alloc_words(sizeof(struct gensym) / sizeof(void *));
|
||||
argcount("gensym", nargs, 0);
|
||||
gs = (struct gensym *)alloc_words(sizeof(struct gensym) / sizeof(void *));
|
||||
gs->id = _gensym_ctr++;
|
||||
gs->binding = UNBOUND;
|
||||
gs->isconst = 0;
|
||||
|
@ -346,11 +355,13 @@ static value_t fl_gensymp(value_t *args, uint32_t nargs)
|
|||
|
||||
char *symbol_name(value_t v)
|
||||
{
|
||||
struct gensym *gs;
|
||||
char *n;
|
||||
|
||||
if (ismanaged(v)) {
|
||||
struct gensym *gs = (struct gensym *)ptr(v);
|
||||
gs = (struct gensym *)ptr(v);
|
||||
gsnameno = 1 - gsnameno;
|
||||
char *n =
|
||||
uint2str(gsname[gsnameno] + 1, sizeof(gsname[0]) - 1, gs->id, 10);
|
||||
n = uint2str(gsname[gsnameno] + 1, sizeof(gsname[0]) - 1, gs->id, 10);
|
||||
*(--n) = 'g';
|
||||
return n;
|
||||
}
|
||||
|
@ -402,13 +413,16 @@ static value_t the_empty_vector;
|
|||
|
||||
value_t alloc_vector(size_t n, int init)
|
||||
{
|
||||
value_t *c;
|
||||
value_t v;
|
||||
unsigned int i;
|
||||
|
||||
if (n == 0)
|
||||
return the_empty_vector;
|
||||
value_t *c = alloc_words(n + 1);
|
||||
value_t v = tagptr(c, TAG_VECTOR);
|
||||
c = alloc_words(n + 1);
|
||||
v = tagptr(c, TAG_VECTOR);
|
||||
vector_setsize(v, n);
|
||||
if (init) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < n; i++)
|
||||
vector_elt(v, i) = FL_UNSPECIFIED;
|
||||
}
|
||||
|
@ -451,8 +465,9 @@ void fl_free_gc_handles(uint32_t n)
|
|||
static value_t relocate(value_t v)
|
||||
{
|
||||
value_t a, d, nc, first, *pcdr;
|
||||
uintptr_t t = tag(v);
|
||||
uintptr_t t;
|
||||
|
||||
t = tag(v);
|
||||
if (t == TAG_CONS) {
|
||||
// iterative implementation allows arbitrarily long cons chains
|
||||
pcdr = &first;
|
||||
|
@ -694,9 +709,10 @@ value_t fl_apply(value_t f, value_t l)
|
|||
value_t fl_applyn(uint32_t n, value_t f, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, f);
|
||||
value_t v;
|
||||
size_t i;
|
||||
|
||||
va_start(ap, f);
|
||||
PUSH(f);
|
||||
while (SP + n > N_STACK)
|
||||
grow_stack();
|
||||
|
@ -704,7 +720,7 @@ value_t fl_applyn(uint32_t n, value_t f, ...)
|
|||
value_t a = va_arg(ap, value_t);
|
||||
PUSH(a);
|
||||
}
|
||||
value_t v = _applyn(n);
|
||||
v = _applyn(n);
|
||||
POPN(n + 1);
|
||||
va_end(ap);
|
||||
return v;
|
||||
|
@ -712,19 +728,22 @@ value_t fl_applyn(uint32_t n, value_t f, ...)
|
|||
|
||||
value_t fl_listn(size_t n, ...)
|
||||
{
|
||||
struct cons *c;
|
||||
struct cons *l;
|
||||
va_list ap;
|
||||
va_start(ap, n);
|
||||
uint32_t si = SP;
|
||||
uint32_t si;
|
||||
size_t i;
|
||||
|
||||
si = SP;
|
||||
va_start(ap, n);
|
||||
while (SP + n > N_STACK)
|
||||
grow_stack();
|
||||
for (i = 0; i < n; i++) {
|
||||
value_t a = va_arg(ap, value_t);
|
||||
PUSH(a);
|
||||
}
|
||||
struct cons *c = (struct cons *)alloc_words(n * 2);
|
||||
struct cons *l = c;
|
||||
c = (struct cons *)alloc_words(n * 2);
|
||||
l = c;
|
||||
for (i = 0; i < n; i++) {
|
||||
c->car = Stack[si++];
|
||||
c->cdr = tagptr(c + 1, TAG_CONS);
|
||||
|
@ -739,9 +758,11 @@ value_t fl_listn(size_t n, ...)
|
|||
|
||||
value_t fl_list2(value_t a, value_t b)
|
||||
{
|
||||
struct cons *c;
|
||||
|
||||
PUSH(a);
|
||||
PUSH(b);
|
||||
struct cons *c = (struct cons *)alloc_words(4);
|
||||
c = (struct cons *)alloc_words(4);
|
||||
b = POP();
|
||||
a = POP();
|
||||
c[0].car = a;
|
||||
|
@ -753,9 +774,11 @@ value_t fl_list2(value_t a, value_t b)
|
|||
|
||||
value_t fl_cons(value_t a, value_t b)
|
||||
{
|
||||
value_t c;
|
||||
|
||||
PUSH(a);
|
||||
PUSH(b);
|
||||
value_t c = mk_cons();
|
||||
c = mk_cons();
|
||||
cdr_(c) = POP();
|
||||
car_(c) = POP();
|
||||
return c;
|
||||
|
@ -763,10 +786,12 @@ value_t fl_cons(value_t a, value_t b)
|
|||
|
||||
int fl_isnumber(value_t v)
|
||||
{
|
||||
struct cprim *c;
|
||||
|
||||
if (isfixnum(v))
|
||||
return 1;
|
||||
if (iscprim(v)) {
|
||||
struct cprim *c = (struct cprim *)ptr(v);
|
||||
c = (struct cprim *)ptr(v);
|
||||
return c->type != wchartype;
|
||||
}
|
||||
return 0;
|
||||
|
@ -792,6 +817,7 @@ static value_t _list(value_t *args, uint32_t nargs, int star)
|
|||
struct cons *c;
|
||||
uint32_t i;
|
||||
value_t v;
|
||||
|
||||
v = cons_reserve(nargs);
|
||||
c = (struct cons *)ptr(v);
|
||||
for (i = 0; i < nargs; i++) {
|
||||
|
@ -808,13 +834,16 @@ static value_t _list(value_t *args, uint32_t nargs, int star)
|
|||
|
||||
static value_t copy_list(value_t L)
|
||||
{
|
||||
value_t *plcons;
|
||||
value_t *pL;
|
||||
value_t c;
|
||||
|
||||
if (!iscons(L))
|
||||
return NIL;
|
||||
PUSH(NIL);
|
||||
PUSH(L);
|
||||
value_t *plcons = &Stack[SP - 2];
|
||||
value_t *pL = &Stack[SP - 1];
|
||||
value_t c;
|
||||
plcons = &Stack[SP - 2];
|
||||
pL = &Stack[SP - 1];
|
||||
c = mk_cons();
|
||||
PUSH(c); // save first cons
|
||||
car_(c) = car_(*pL);
|
||||
|
@ -836,19 +865,22 @@ static value_t copy_list(value_t L)
|
|||
|
||||
static value_t do_trycatch(void)
|
||||
{
|
||||
uint32_t saveSP = SP;
|
||||
value_t v;
|
||||
value_t thunk = Stack[SP - 2];
|
||||
value_t v, thunk;
|
||||
uint32_t saveSP;
|
||||
|
||||
saveSP = SP;
|
||||
thunk = Stack[SP - 2];
|
||||
Stack[SP - 2] = Stack[SP - 1];
|
||||
Stack[SP - 1] = thunk;
|
||||
|
||||
FL_TRY { v = apply_cl(0); }
|
||||
FL_CATCH
|
||||
{
|
||||
v = Stack[saveSP - 2];
|
||||
PUSH(v);
|
||||
PUSH(fl_lasterror);
|
||||
v = apply_cl(1);
|
||||
FL_TRY { v = apply_cl(0); }
|
||||
FL_CATCH
|
||||
{
|
||||
v = Stack[saveSP - 2];
|
||||
PUSH(v);
|
||||
PUSH(fl_lasterror);
|
||||
v = apply_cl(1);
|
||||
}
|
||||
}
|
||||
SP = saveSP;
|
||||
return v;
|
||||
|
@ -862,14 +894,27 @@ static uint32_t process_keys(value_t kwtable, uint32_t nreq, uint32_t nkw,
|
|||
uint32_t nopt, uint32_t bp, uint32_t nargs,
|
||||
int va)
|
||||
{
|
||||
uint32_t extr = nopt + nkw;
|
||||
uint32_t ntot = nreq + extr;
|
||||
value_t args[extr], v;
|
||||
uint32_t i, a = 0, nrestargs;
|
||||
value_t s1 = Stack[SP - 1];
|
||||
value_t s2 = Stack[SP - 2];
|
||||
value_t s4 = Stack[SP - 4];
|
||||
value_t s5 = Stack[SP - 5];
|
||||
value_t hv;
|
||||
uintptr_t x;
|
||||
uintptr_t idx;
|
||||
uintptr_t n;
|
||||
uint32_t ntot;
|
||||
value_t v;
|
||||
uint32_t extr;
|
||||
value_t *args;
|
||||
uint32_t nrestargs, i, a;
|
||||
value_t s1, s2, s4, s5;
|
||||
|
||||
extr = nopt + nkw;
|
||||
ntot = nreq + extr;
|
||||
if (!(args = calloc(extr, sizeof(*args)))) {
|
||||
lerror(MemoryError, "out of memory");
|
||||
}
|
||||
a = 0;
|
||||
s1 = Stack[SP - 1];
|
||||
s2 = Stack[SP - 2];
|
||||
s4 = Stack[SP - 4];
|
||||
s5 = Stack[SP - 5];
|
||||
if (nargs < nreq)
|
||||
lerror(ArgError, "apply: too few arguments");
|
||||
for (i = 0; i < extr; i++)
|
||||
|
@ -885,16 +930,16 @@ static uint32_t process_keys(value_t kwtable, uint32_t nreq, uint32_t nkw,
|
|||
if (i >= nargs)
|
||||
goto no_kw;
|
||||
// now process keywords
|
||||
uintptr_t n = vector_size(kwtable) / 2;
|
||||
n = vector_size(kwtable) / 2;
|
||||
do {
|
||||
i++;
|
||||
if (i >= nargs)
|
||||
lerrorf(ArgError, "keyword %s requires an argument",
|
||||
symbol_name(v));
|
||||
value_t hv = fixnum(((struct symbol *)ptr(v))->hash);
|
||||
uintptr_t x = 2 * (labs(numval(hv)) % n);
|
||||
hv = fixnum(((struct symbol *)ptr(v))->hash);
|
||||
x = 2 * (labs(numval(hv)) % n);
|
||||
if (vector_elt(kwtable, x) == v) {
|
||||
uintptr_t idx = numval(vector_elt(kwtable, x + 1));
|
||||
idx = numval(vector_elt(kwtable, x + 1));
|
||||
assert(idx < nkw);
|
||||
idx += nopt;
|
||||
if (args[idx] == UNBOUND) {
|
||||
|
@ -2305,6 +2350,13 @@ void assign_global_builtins(struct builtinspec *b)
|
|||
|
||||
static value_t fl_function(value_t *args, uint32_t nargs)
|
||||
{
|
||||
struct cvalue *arr;
|
||||
char *data;
|
||||
int swap;
|
||||
uint32_t ms;
|
||||
struct function *fn;
|
||||
value_t fv;
|
||||
|
||||
if (nargs == 1 && issymbol(args[0]))
|
||||
return fl_builtin(args, nargs);
|
||||
if (nargs < 2 || nargs > 4)
|
||||
|
@ -2313,10 +2365,10 @@ static value_t fl_function(value_t *args, uint32_t nargs)
|
|||
type_error("function", "string", args[0]);
|
||||
if (!isvector(args[1]))
|
||||
type_error("function", "vector", args[1]);
|
||||
struct cvalue *arr = (struct cvalue *)ptr(args[0]);
|
||||
arr = (struct cvalue *)ptr(args[0]);
|
||||
cv_pin(arr);
|
||||
char *data = cv_data(arr);
|
||||
int swap = 0;
|
||||
data = cv_data(arr);
|
||||
swap = 0;
|
||||
if ((uint8_t)data[4] >= N_OPCODES) {
|
||||
// read syntax, shifted 48 for compact text representation
|
||||
size_t i, sz = cv_len(arr);
|
||||
|
@ -2327,10 +2379,10 @@ static value_t fl_function(value_t *args, uint32_t nargs)
|
|||
swap = 1;
|
||||
#endif
|
||||
}
|
||||
uint32_t ms = compute_maxstack((uint8_t *)data, cv_len(arr), swap);
|
||||
ms = compute_maxstack((uint8_t *)data, cv_len(arr), swap);
|
||||
PUT_INT32(data, ms);
|
||||
struct function *fn = (struct function *)alloc_words(4);
|
||||
value_t fv = tagptr(fn, TAG_FUNCTION);
|
||||
fn = (struct function *)alloc_words(4);
|
||||
fv = tagptr(fn, TAG_FUNCTION);
|
||||
fn->bcode = args[0];
|
||||
fn->vals = args[1];
|
||||
fn->env = NIL;
|
||||
|
@ -2356,32 +2408,40 @@ static value_t fl_function(value_t *args, uint32_t nargs)
|
|||
|
||||
static value_t fl_function_code(value_t *args, uint32_t nargs)
|
||||
{
|
||||
value_t v;
|
||||
|
||||
argcount("function:code", nargs, 1);
|
||||
value_t v = args[0];
|
||||
v = args[0];
|
||||
if (!isclosure(v))
|
||||
type_error("function:code", "function", v);
|
||||
return fn_bcode(v);
|
||||
}
|
||||
static value_t fl_function_vals(value_t *args, uint32_t nargs)
|
||||
{
|
||||
value_t v;
|
||||
|
||||
argcount("function:vals", nargs, 1);
|
||||
value_t v = args[0];
|
||||
v = args[0];
|
||||
if (!isclosure(v))
|
||||
type_error("function:vals", "function", v);
|
||||
return fn_vals(v);
|
||||
}
|
||||
static value_t fl_function_env(value_t *args, uint32_t nargs)
|
||||
{
|
||||
value_t v;
|
||||
|
||||
argcount("function:env", nargs, 1);
|
||||
value_t v = args[0];
|
||||
v = args[0];
|
||||
if (!isclosure(v))
|
||||
type_error("function:env", "function", v);
|
||||
return fn_env(v);
|
||||
}
|
||||
static value_t fl_function_name(value_t *args, uint32_t nargs)
|
||||
{
|
||||
value_t v;
|
||||
|
||||
argcount("function:name", nargs, 1);
|
||||
value_t v = args[0];
|
||||
v = args[0];
|
||||
if (!isclosure(v))
|
||||
type_error("function:name", "function", v);
|
||||
return fn_name(v);
|
||||
|
@ -2395,12 +2455,15 @@ value_t fl_copylist(value_t *args, uint32_t nargs)
|
|||
|
||||
value_t fl_append(value_t *args, uint32_t nargs)
|
||||
{
|
||||
value_t first, lst, lastcons;
|
||||
uint32_t i;
|
||||
|
||||
if (nargs == 0)
|
||||
return NIL;
|
||||
value_t first = NIL, lst, lastcons = NIL;
|
||||
first = lastcons = NIL;
|
||||
fl_gc_handle(&first);
|
||||
fl_gc_handle(&lastcons);
|
||||
uint32_t i = 0;
|
||||
i = 0;
|
||||
while (1) {
|
||||
lst = args[i++];
|
||||
if (i >= nargs)
|
||||
|
@ -2442,12 +2505,14 @@ value_t fl_stacktrace(value_t *args, uint32_t nargs)
|
|||
|
||||
value_t fl_map1(value_t *args, uint32_t nargs)
|
||||
{
|
||||
value_t first, last, v;
|
||||
int64_t argSP;
|
||||
|
||||
if (nargs < 2)
|
||||
lerror(ArgError, "map: too few arguments");
|
||||
if (!iscons(args[1]))
|
||||
return NIL;
|
||||
value_t first, last, v;
|
||||
int64_t argSP = args - Stack;
|
||||
argSP = args - Stack;
|
||||
assert(argSP >= 0 && argSP < N_STACK);
|
||||
if (nargs == 2) {
|
||||
if (SP + 3 > N_STACK)
|
||||
|
@ -2479,6 +2544,7 @@ value_t fl_map1(value_t *args, uint32_t nargs)
|
|||