adding CPRIM type, smaller representation for primitives
bug fixes in opaque type handling
This commit is contained in:
parent
88938bc6d1
commit
d8132ad204
|
@ -174,23 +174,21 @@ value_t fl_constantp(value_t *args, u_int32_t nargs)
|
||||||
value_t fl_fixnum(value_t *args, u_int32_t nargs)
|
value_t fl_fixnum(value_t *args, u_int32_t nargs)
|
||||||
{
|
{
|
||||||
argcount("fixnum", nargs, 1);
|
argcount("fixnum", nargs, 1);
|
||||||
if (isfixnum(args[0]))
|
if (isfixnum(args[0])) {
|
||||||
return args[0];
|
return args[0];
|
||||||
if (iscvalue(args[0])) {
|
}
|
||||||
|
else if (iscprim(args[0])) {
|
||||||
|
cprim_t *cp = (cprim_t*)ptr(args[0]);
|
||||||
|
return fixnum(conv_to_long(cp_data(cp), cp_numtype(cp)));
|
||||||
|
}
|
||||||
|
else if (isstring(args[0])) {
|
||||||
cvalue_t *cv = (cvalue_t*)ptr(args[0]);
|
cvalue_t *cv = (cvalue_t*)ptr(args[0]);
|
||||||
long i;
|
char *pend;
|
||||||
if (cv_isstr(cv)) {
|
errno = 0;
|
||||||
char *pend;
|
long i = strtol(cv_data(cv), &pend, 0);
|
||||||
errno = 0;
|
if (*pend != '\0' || errno!=0)
|
||||||
i = strtol(cv_data(cv), &pend, 0);
|
lerror(ArgError, "fixnum: invalid string");
|
||||||
if (*pend != '\0' || errno!=0)
|
return fixnum(i);
|
||||||
lerror(ArgError, "fixnum: invalid string");
|
|
||||||
return fixnum(i);
|
|
||||||
}
|
|
||||||
else if (valid_numtype(cv_numtype(cv))) {
|
|
||||||
i = conv_to_long(cv_data(cv), cv_numtype(cv));
|
|
||||||
return fixnum(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
lerror(ArgError, "fixnum: cannot convert argument");
|
lerror(ArgError, "fixnum: cannot convert argument");
|
||||||
}
|
}
|
||||||
|
@ -200,22 +198,20 @@ value_t fl_truncate(value_t *args, u_int32_t nargs)
|
||||||
argcount("truncate", nargs, 1);
|
argcount("truncate", nargs, 1);
|
||||||
if (isfixnum(args[0]))
|
if (isfixnum(args[0]))
|
||||||
return args[0];
|
return args[0];
|
||||||
if (iscvalue(args[0])) {
|
if (iscprim(args[0])) {
|
||||||
cvalue_t *cv = (cvalue_t*)ptr(args[0]);
|
cprim_t *cp = (cprim_t*)ptr(args[0]);
|
||||||
void *data = cv_data(cv);
|
void *data = cp_data(cp);
|
||||||
numerictype_t nt = cv_numtype(cv);
|
numerictype_t nt = cp_numtype(cp);
|
||||||
if (valid_numtype(nt)) {
|
double d;
|
||||||
double d;
|
if (nt == T_FLOAT)
|
||||||
if (nt == T_FLOAT)
|
d = (double)*(float*)data;
|
||||||
d = (double)*(float*)data;
|
else if (nt == T_DOUBLE)
|
||||||
else if (nt == T_DOUBLE)
|
d = *(double*)data;
|
||||||
d = *(double*)data;
|
else
|
||||||
else
|
return args[0];
|
||||||
return args[0];
|
if (d > 0)
|
||||||
if (d > 0)
|
return return_from_uint64((uint64_t)d);
|
||||||
return return_from_uint64((uint64_t)d);
|
return return_from_int64((int64_t)d);
|
||||||
return return_from_int64((int64_t)d);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
type_error("truncate", "number", args[0]);
|
type_error("truncate", "number", args[0]);
|
||||||
}
|
}
|
||||||
|
@ -253,11 +249,10 @@ static double todouble(value_t a, char *fname)
|
||||||
{
|
{
|
||||||
if (isfixnum(a))
|
if (isfixnum(a))
|
||||||
return (double)numval(a);
|
return (double)numval(a);
|
||||||
if (iscvalue(a)) {
|
if (iscprim(a)) {
|
||||||
cvalue_t *cv = (cvalue_t*)ptr(a);
|
cprim_t *cp = (cprim_t*)ptr(a);
|
||||||
numerictype_t nt = cv_numtype(cv);
|
numerictype_t nt = cp_numtype(cp);
|
||||||
if (valid_numtype(nt))
|
return conv_to_double(cp_data(cp), nt);
|
||||||
return conv_to_double(cv_data(cv), nt);
|
|
||||||
}
|
}
|
||||||
type_error(fname, "number", a);
|
type_error(fname, "number", a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,11 +117,21 @@ void cv_autorelease(cvalue_t *cv)
|
||||||
autorelease(cv);
|
autorelease(cv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static value_t cprim(fltype_t *type, size_t sz)
|
||||||
|
{
|
||||||
|
cprim_t *pcp = (cprim_t*)alloc_words(CPRIM_NWORDS-1+NWORDS(sz));
|
||||||
|
pcp->type = type;
|
||||||
|
return tagptr(pcp, TAG_CPRIM);
|
||||||
|
}
|
||||||
|
|
||||||
value_t cvalue(fltype_t *type, size_t sz)
|
value_t cvalue(fltype_t *type, size_t sz)
|
||||||
{
|
{
|
||||||
cvalue_t *pcv;
|
cvalue_t *pcv;
|
||||||
int str=0;
|
int str=0;
|
||||||
|
|
||||||
|
if (valid_numtype(type->numtype)) {
|
||||||
|
return cprim(type, sz);
|
||||||
|
}
|
||||||
if (type->eltype == bytetype) {
|
if (type->eltype == bytetype) {
|
||||||
if (sz == 0)
|
if (sz == 0)
|
||||||
return symbol_value(emptystringsym);
|
return symbol_value(emptystringsym);
|
||||||
|
@ -155,11 +165,9 @@ value_t cvalue(fltype_t *type, size_t sz)
|
||||||
|
|
||||||
value_t cvalue_from_data(fltype_t *type, void *data, size_t sz)
|
value_t cvalue_from_data(fltype_t *type, void *data, size_t sz)
|
||||||
{
|
{
|
||||||
cvalue_t *pcv;
|
|
||||||
value_t cv;
|
value_t cv;
|
||||||
cv = cvalue(type, sz);
|
cv = cvalue(type, sz);
|
||||||
pcv = (cvalue_t*)ptr(cv);
|
memcpy(cptr(cv), data, sz);
|
||||||
memcpy(cv_data(pcv), data, sz);
|
|
||||||
return cv;
|
return cv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,35 +250,29 @@ static void cvalue_##typenam##_init(fltype_t *type, value_t arg, \
|
||||||
if (isfixnum(arg)) { \
|
if (isfixnum(arg)) { \
|
||||||
n = numval(arg); \
|
n = numval(arg); \
|
||||||
} \
|
} \
|
||||||
else if (iscvalue(arg)) { \
|
else if (iscprim(arg)) { \
|
||||||
cvalue_t *cv = (cvalue_t*)ptr(arg); \
|
cprim_t *cp = (cprim_t*)ptr(arg); \
|
||||||
void *p = cv_data(cv); \
|
void *p = cp_data(cp); \
|
||||||
if (valid_numtype(cv_numtype(cv))) \
|
n = (ctype##_t)conv_to_##cnvt(p, cp_numtype(cp)); \
|
||||||
n = (ctype##_t)conv_to_##cnvt(p, cv_numtype(cv)); \
|
|
||||||
else \
|
|
||||||
goto cnvt_error; \
|
|
||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
goto cnvt_error; \
|
type_error(#typenam, "number", arg); \
|
||||||
} \
|
} \
|
||||||
*((ctype##_t*)dest) = n; \
|
*((ctype##_t*)dest) = n; \
|
||||||
return; \
|
|
||||||
cnvt_error: \
|
|
||||||
type_error(#typenam, "number", arg); \
|
|
||||||
} \
|
} \
|
||||||
value_t cvalue_##typenam(value_t *args, u_int32_t nargs) \
|
value_t cvalue_##typenam(value_t *args, u_int32_t nargs) \
|
||||||
{ \
|
{ \
|
||||||
if (nargs==0) { PUSH(fixnum(0)); args = &Stack[SP-1]; } \
|
if (nargs==0) { PUSH(fixnum(0)); args = &Stack[SP-1]; } \
|
||||||
value_t cv = cvalue(typenam##type, sizeof(ctype##_t)); \
|
value_t cp = cprim(typenam##type, sizeof(ctype##_t)); \
|
||||||
cvalue_##typenam##_init(typenam##type, \
|
cvalue_##typenam##_init(typenam##type, \
|
||||||
args[0], &((cvalue_t*)ptr(cv))->_space[0]); \
|
args[0], cp_data((cprim_t*)ptr(cp))); \
|
||||||
return cv; \
|
return cp; \
|
||||||
} \
|
} \
|
||||||
value_t mk_##typenam(ctype##_t n) \
|
value_t mk_##typenam(ctype##_t n) \
|
||||||
{ \
|
{ \
|
||||||
value_t cv = cvalue(typenam##type, sizeof(ctype##_t)); \
|
value_t cp = cprim(typenam##type, sizeof(ctype##_t)); \
|
||||||
*(ctype##_t*)&((cvalue_t*)ptr(cv))->_space[0] = n; \
|
*(ctype##_t*)cp_data((cprim_t*)ptr(cp)) = n; \
|
||||||
return cv; \
|
return cp; \
|
||||||
}
|
}
|
||||||
|
|
||||||
num_ctor(int8, int8, int32, T_INT8)
|
num_ctor(int8, int8, int32, T_INT8)
|
||||||
|
@ -305,11 +307,9 @@ size_t toulong(value_t n, char *fname)
|
||||||
{
|
{
|
||||||
if (isfixnum(n))
|
if (isfixnum(n))
|
||||||
return numval(n);
|
return numval(n);
|
||||||
if (iscvalue(n)) {
|
if (iscprim(n)) {
|
||||||
cvalue_t *cv = (cvalue_t*)ptr(n);
|
cprim_t *cp = (cprim_t*)ptr(n);
|
||||||
if (valid_numtype(cv_numtype(cv))) {
|
return conv_to_ulong(cp_data(cp), cp_numtype(cp));
|
||||||
return conv_to_ulong(cv_data(cv), cv_numtype(cv));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
type_error(fname, "number", n);
|
type_error(fname, "number", n);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -338,11 +338,12 @@ static void cvalue_enum_init(fltype_t *ft, value_t arg, void *dest)
|
||||||
if (isfixnum(arg)) {
|
if (isfixnum(arg)) {
|
||||||
n = (int)numval(arg);
|
n = (int)numval(arg);
|
||||||
}
|
}
|
||||||
else if (iscvalue(arg)) {
|
else if (iscprim(arg)) {
|
||||||
cvalue_t *cv = (cvalue_t*)ptr(arg);
|
cprim_t *cp = (cprim_t*)ptr(arg);
|
||||||
if (!valid_numtype(cv_numtype(cv)))
|
n = conv_to_int32(cp_data(cp), cp_numtype(cp));
|
||||||
type_error("enum", "number", arg);
|
}
|
||||||
n = conv_to_int32(cv_data(cv), cv_numtype(cv));
|
else {
|
||||||
|
type_error("enum", "number", arg);
|
||||||
}
|
}
|
||||||
if ((unsigned)n >= llength(syms))
|
if ((unsigned)n >= llength(syms))
|
||||||
lerror(ArgError, "enum: value out of range");
|
lerror(ArgError, "enum: value out of range");
|
||||||
|
@ -354,8 +355,8 @@ value_t cvalue_enum(value_t *args, u_int32_t nargs)
|
||||||
argcount("enum", nargs, 2);
|
argcount("enum", nargs, 2);
|
||||||
value_t type = list2(enumsym, args[0]);
|
value_t type = list2(enumsym, args[0]);
|
||||||
fltype_t *ft = get_type(type);
|
fltype_t *ft = get_type(type);
|
||||||
value_t cv = cvalue(ft, 4);
|
value_t cv = cvalue(ft, sizeof(int32_t));
|
||||||
cvalue_enum_init(ft, args[1], cv_data((cvalue_t*)ptr(cv)));
|
cvalue_enum_init(ft, args[1], cp_data((cprim_t*)ptr(cv)));
|
||||||
return cv;
|
return cv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,12 +595,15 @@ size_t ctype_sizeof(value_t type, int *palign)
|
||||||
|
|
||||||
value_t cvalue_sizeof(value_t *args, u_int32_t nargs)
|
value_t cvalue_sizeof(value_t *args, u_int32_t nargs)
|
||||||
{
|
{
|
||||||
cvalue_t *cv;
|
|
||||||
argcount("sizeof", nargs, 1);
|
argcount("sizeof", nargs, 1);
|
||||||
if (iscvalue(args[0])) {
|
if (iscvalue(args[0])) {
|
||||||
cv = (cvalue_t*)ptr(args[0]);
|
cvalue_t *cv = (cvalue_t*)ptr(args[0]);
|
||||||
return size_wrap(cv_len(cv));
|
return size_wrap(cv_len(cv));
|
||||||
}
|
}
|
||||||
|
else if (iscprim(args[0])) {
|
||||||
|
cprim_t *cp = (cprim_t*)ptr(args[0]);
|
||||||
|
return fixnum(cp_class(cp)->size);
|
||||||
|
}
|
||||||
int a;
|
int a;
|
||||||
return size_wrap(ctype_sizeof(args[0], &a));
|
return size_wrap(ctype_sizeof(args[0], &a));
|
||||||
}
|
}
|
||||||
|
@ -720,7 +724,7 @@ value_t cvalue_new(value_t *args, u_int32_t nargs)
|
||||||
else {
|
else {
|
||||||
cv = cvalue(ft, ft->size);
|
cv = cvalue(ft, ft->size);
|
||||||
if (nargs == 2)
|
if (nargs == 2)
|
||||||
cvalue_init(ft, args[1], cv_data((cvalue_t*)ptr(cv)));
|
cvalue_init(ft, args[1], cptr(cv));
|
||||||
}
|
}
|
||||||
return cv;
|
return cv;
|
||||||
}
|
}
|
||||||
|
@ -763,7 +767,7 @@ static value_t cvalue_array_aref(value_t *args)
|
||||||
fltype_t *eltype = cv_class((cvalue_t*)ptr(args[0]))->eltype;
|
fltype_t *eltype = cv_class((cvalue_t*)ptr(args[0]))->eltype;
|
||||||
value_t el = cvalue(eltype, eltype->size);
|
value_t el = cvalue(eltype, eltype->size);
|
||||||
check_addr_args("aref", args[0], args[1], &data, &index);
|
check_addr_args("aref", args[0], args[1], &data, &index);
|
||||||
char *dest = cv_data((cvalue_t*)ptr(el));
|
char *dest = cptr(el);
|
||||||
size_t sz = eltype->size;
|
size_t sz = eltype->size;
|
||||||
if (sz == 1)
|
if (sz == 1)
|
||||||
*dest = data[index];
|
*dest = data[index];
|
||||||
|
@ -792,8 +796,8 @@ value_t fl_builtin(value_t *args, u_int32_t nargs)
|
||||||
{
|
{
|
||||||
argcount("builtin", nargs, 1);
|
argcount("builtin", nargs, 1);
|
||||||
symbol_t *name = tosymbol(args[0], "builtin");
|
symbol_t *name = tosymbol(args[0], "builtin");
|
||||||
builtin_t f = (builtin_t)name->dlcache;
|
builtin_t f;
|
||||||
if (f == NULL) {
|
if (ismanaged(args[0]) || (f=(builtin_t)name->dlcache) == NULL) {
|
||||||
lerror(ArgError, "builtin: function not found");
|
lerror(ArgError, "builtin: function not found");
|
||||||
}
|
}
|
||||||
return tagptr(f, TAG_BUILTIN);
|
return tagptr(f, TAG_BUILTIN);
|
||||||
|
@ -926,11 +930,11 @@ value_t fl_add_any(value_t *args, u_int32_t nargs, fixnum_t carryIn)
|
||||||
Saccum += numval(args[i]);
|
Saccum += numval(args[i]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (iscvalue(args[i])) {
|
else if (iscprim(args[i])) {
|
||||||
cvalue_t *cv = (cvalue_t*)ptr(args[i]);
|
cprim_t *cp = (cprim_t*)ptr(args[i]);
|
||||||
void *a = cv_data(cv);
|
void *a = cp_data(cp);
|
||||||
int64_t i64;
|
int64_t i64;
|
||||||
switch(cv_numtype(cv)) {
|
switch(cp_numtype(cp)) {
|
||||||
case T_INT8: Saccum += *(int8_t*)a; break;
|
case T_INT8: Saccum += *(int8_t*)a; break;
|
||||||
case T_UINT8: Saccum += *(uint8_t*)a; break;
|
case T_UINT8: Saccum += *(uint8_t*)a; break;
|
||||||
case T_INT16: Saccum += *(int16_t*)a; break;
|
case T_INT16: Saccum += *(int16_t*)a; break;
|
||||||
|
@ -987,13 +991,13 @@ value_t fl_neg(value_t n)
|
||||||
if (isfixnum(n)) {
|
if (isfixnum(n)) {
|
||||||
return fixnum(-numval(n));
|
return fixnum(-numval(n));
|
||||||
}
|
}
|
||||||
else if (iscvalue(n)) {
|
else if (iscprim(n)) {
|
||||||
cvalue_t *cv = (cvalue_t*)ptr(n);
|
cprim_t *cp = (cprim_t*)ptr(n);
|
||||||
void *a = cv_data(cv);
|
void *a = cp_data(cp);
|
||||||
uint32_t ui32;
|
uint32_t ui32;
|
||||||
int32_t i32;
|
int32_t i32;
|
||||||
int64_t i64;
|
int64_t i64;
|
||||||
switch(cv_numtype(cv)) {
|
switch(cp_numtype(cp)) {
|
||||||
case T_INT8: return fixnum(-(int32_t)*(int8_t*)a);
|
case T_INT8: return fixnum(-(int32_t)*(int8_t*)a);
|
||||||
case T_UINT8: return fixnum(-(int32_t)*(uint8_t*)a);
|
case T_UINT8: return fixnum(-(int32_t)*(uint8_t*)a);
|
||||||
case T_INT16: return fixnum(-(int32_t)*(int16_t*)a);
|
case T_INT16: return fixnum(-(int32_t)*(int16_t*)a);
|
||||||
|
@ -1032,11 +1036,11 @@ value_t fl_mul_any(value_t *args, u_int32_t nargs, int64_t Saccum)
|
||||||
Saccum *= numval(args[i]);
|
Saccum *= numval(args[i]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (iscvalue(args[i])) {
|
else if (iscprim(args[i])) {
|
||||||
cvalue_t *cv = (cvalue_t*)ptr(args[i]);
|
cprim_t *cp = (cprim_t*)ptr(args[i]);
|
||||||
void *a = cv_data(cv);
|
void *a = cp_data(cp);
|
||||||
int64_t i64;
|
int64_t i64;
|
||||||
switch(cv_numtype(cv)) {
|
switch(cp_numtype(cp)) {
|
||||||
case T_INT8: Saccum *= *(int8_t*)a; break;
|
case T_INT8: Saccum *= *(int8_t*)a; break;
|
||||||
case T_UINT8: Saccum *= *(uint8_t*)a; break;
|
case T_UINT8: Saccum *= *(uint8_t*)a; break;
|
||||||
case T_INT16: Saccum *= *(int16_t*)a; break;
|
case T_INT16: Saccum *= *(int16_t*)a; break;
|
||||||
|
@ -1088,18 +1092,18 @@ value_t fl_div2(value_t a, value_t b)
|
||||||
int_t ai, bi;
|
int_t ai, bi;
|
||||||
int ta, tb;
|
int ta, tb;
|
||||||
void *aptr=NULL, *bptr=NULL;
|
void *aptr=NULL, *bptr=NULL;
|
||||||
cvalue_t *cv;
|
cprim_t *cp;
|
||||||
|
|
||||||
if (isfixnum(a)) {
|
if (isfixnum(a)) {
|
||||||
ai = numval(a);
|
ai = numval(a);
|
||||||
aptr = &ai;
|
aptr = &ai;
|
||||||
ta = T_FIXNUM;
|
ta = T_FIXNUM;
|
||||||
}
|
}
|
||||||
else if (iscvalue(a)) {
|
else if (iscprim(a)) {
|
||||||
cv = (cvalue_t*)ptr(a);
|
cp = (cprim_t*)ptr(a);
|
||||||
ta = cv_numtype(cv);
|
ta = cp_numtype(cp);
|
||||||
if (ta <= T_DOUBLE)
|
if (ta <= T_DOUBLE)
|
||||||
aptr = cv_data(cv);
|
aptr = cp_data(cp);
|
||||||
}
|
}
|
||||||
if (aptr == NULL)
|
if (aptr == NULL)
|
||||||
type_error("/", "number", a);
|
type_error("/", "number", a);
|
||||||
|
@ -1108,11 +1112,11 @@ value_t fl_div2(value_t a, value_t b)
|
||||||
bptr = &bi;
|
bptr = &bi;
|
||||||
tb = T_FIXNUM;
|
tb = T_FIXNUM;
|
||||||
}
|
}
|
||||||
else if (iscvalue(b)) {
|
else if (iscprim(b)) {
|
||||||
cv = (cvalue_t*)ptr(b);
|
cp = (cprim_t*)ptr(b);
|
||||||
tb = cv_numtype(cv);
|
tb = cp_numtype(cp);
|
||||||
if (tb <= T_DOUBLE)
|
if (tb <= T_DOUBLE)
|
||||||
bptr = cv_data(cv);
|
bptr = cp_data(cp);
|
||||||
}
|
}
|
||||||
if (bptr == NULL)
|
if (bptr == NULL)
|
||||||
type_error("/", "number", b);
|
type_error("/", "number", b);
|
||||||
|
@ -1174,12 +1178,12 @@ value_t fl_div2(value_t a, value_t b)
|
||||||
|
|
||||||
static void *int_data_ptr(value_t a, int *pnumtype, char *fname)
|
static void *int_data_ptr(value_t a, int *pnumtype, char *fname)
|
||||||
{
|
{
|
||||||
cvalue_t *cv;
|
cprim_t *cp;
|
||||||
if (iscvalue(a)) {
|
if (iscprim(a)) {
|
||||||
cv = (cvalue_t*)ptr(a);
|
cp = (cprim_t*)ptr(a);
|
||||||
*pnumtype = cv_numtype(cv);
|
*pnumtype = cp_numtype(cp);
|
||||||
if (*pnumtype < T_FLOAT)
|
if (*pnumtype < T_FLOAT)
|
||||||
return cv_data(cv);
|
return cp_data(cp);
|
||||||
}
|
}
|
||||||
type_error(fname, "integer", a);
|
type_error(fname, "integer", a);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1187,14 +1191,14 @@ static void *int_data_ptr(value_t a, int *pnumtype, char *fname)
|
||||||
|
|
||||||
value_t fl_bitwise_not(value_t a)
|
value_t fl_bitwise_not(value_t a)
|
||||||
{
|
{
|
||||||
cvalue_t *cv;
|
cprim_t *cp;
|
||||||
int ta;
|
int ta;
|
||||||
void *aptr;
|
void *aptr;
|
||||||
|
|
||||||
if (iscvalue(a)) {
|
if (iscprim(a)) {
|
||||||
cv = (cvalue_t*)ptr(a);
|
cp = (cprim_t*)ptr(a);
|
||||||
ta = cv_numtype(cv);
|
ta = cp_numtype(cp);
|
||||||
aptr = cv_data(cv);
|
aptr = cp_data(cp);
|
||||||
switch (ta) {
|
switch (ta) {
|
||||||
case T_INT8: return mk_int8(~*(int8_t *)aptr);
|
case T_INT8: return mk_int8(~*(int8_t *)aptr);
|
||||||
case T_UINT8: return mk_uint8(~*(uint8_t *)aptr);
|
case T_UINT8: return mk_uint8(~*(uint8_t *)aptr);
|
||||||
|
@ -1213,13 +1217,13 @@ value_t fl_bitwise_not(value_t a)
|
||||||
#define BITSHIFT_OP(name, op) \
|
#define BITSHIFT_OP(name, op) \
|
||||||
value_t fl_##name(value_t a, int n) \
|
value_t fl_##name(value_t a, int n) \
|
||||||
{ \
|
{ \
|
||||||
cvalue_t *cv; \
|
cprim_t *cp; \
|
||||||
int ta; \
|
int ta; \
|
||||||
void *aptr; \
|
void *aptr; \
|
||||||
if (iscvalue(a)) { \
|
if (iscprim(a)) { \
|
||||||
cv = (cvalue_t*)ptr(a); \
|
cp = (cprim_t*)ptr(a); \
|
||||||
ta = cv_numtype(cv); \
|
ta = cp_numtype(cp); \
|
||||||
aptr = cv_data(cv); \
|
aptr = cp_data(cp); \
|
||||||
switch (ta) { \
|
switch (ta) { \
|
||||||
case T_INT8: return mk_int8((*(int8_t *)aptr) op n); \
|
case T_INT8: return mk_int8((*(int8_t *)aptr) op n); \
|
||||||
case T_UINT8: return mk_uint8((*(uint8_t *)aptr) op n); \
|
case T_UINT8: return mk_uint8((*(uint8_t *)aptr) op n); \
|
||||||
|
|
|
@ -33,23 +33,18 @@ static void eq_union(htable_t *table, value_t a, value_t b,
|
||||||
ptrhash_put(table, (void*)b, (void*)ca);
|
ptrhash_put(table, (void*)b, (void*)ca);
|
||||||
}
|
}
|
||||||
|
|
||||||
// a is a fixnum, b is a cvalue
|
// a is a fixnum, b is a cprim
|
||||||
static value_t compare_num_cvalue(value_t a, value_t b, int eq)
|
static value_t compare_num_cprim(value_t a, value_t b, int eq)
|
||||||
{
|
{
|
||||||
cvalue_t *bcv = (cvalue_t*)ptr(b);
|
cprim_t *bcp = (cprim_t*)ptr(b);
|
||||||
numerictype_t bt;
|
numerictype_t bt = cp_numtype(bcp);
|
||||||
if (valid_numtype(bt=cv_numtype(bcv))) {
|
fixnum_t ia = numval(a);
|
||||||
fixnum_t ia = numval(a);
|
void *bptr = cp_data(bcp);
|
||||||
void *bptr = cv_data(bcv);
|
if (cmp_eq(&ia, T_FIXNUM, bptr, bt))
|
||||||
if (cmp_eq(&ia, T_FIXNUM, bptr, bt))
|
return fixnum(0);
|
||||||
return fixnum(0);
|
if (eq) return fixnum(1);
|
||||||
if (eq) return fixnum(1);
|
if (cmp_lt(&ia, T_FIXNUM, bptr, bt))
|
||||||
if (cmp_lt(&ia, T_FIXNUM, bptr, bt))
|
|
||||||
return fixnum(-1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return fixnum(-1);
|
return fixnum(-1);
|
||||||
}
|
|
||||||
return fixnum(1);
|
return fixnum(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +69,7 @@ static value_t bounded_vector_compare(value_t a, value_t b, int bound, int eq)
|
||||||
}
|
}
|
||||||
|
|
||||||
// strange comparisons are resolved arbitrarily but consistently.
|
// strange comparisons are resolved arbitrarily but consistently.
|
||||||
// ordering: number < builtin < cvalue < vector < symbol < cons
|
// ordering: number < cprim < builtin < cvalue < vector < symbol < cons
|
||||||
static value_t bounded_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;
|
value_t d;
|
||||||
|
@ -91,8 +86,8 @@ static value_t bounded_compare(value_t a, value_t b, int bound, int eq)
|
||||||
if (isfixnum(b)) {
|
if (isfixnum(b)) {
|
||||||
return (numval(a) < numval(b)) ? fixnum(-1) : fixnum(1);
|
return (numval(a) < numval(b)) ? fixnum(-1) : fixnum(1);
|
||||||
}
|
}
|
||||||
if (iscvalue(b)) {
|
if (iscprim(b)) {
|
||||||
return compare_num_cvalue(a, b, eq);
|
return compare_num_cprim(a, b, eq);
|
||||||
}
|
}
|
||||||
return fixnum(-1);
|
return fixnum(-1);
|
||||||
case TAG_SYM:
|
case TAG_SYM:
|
||||||
|
@ -104,27 +99,26 @@ static value_t bounded_compare(value_t a, value_t b, int bound, int eq)
|
||||||
if (isvector(b))
|
if (isvector(b))
|
||||||
return bounded_vector_compare(a, b, bound, eq);
|
return bounded_vector_compare(a, b, bound, eq);
|
||||||
break;
|
break;
|
||||||
case TAG_CVALUE:
|
case TAG_CPRIM:
|
||||||
if (iscvalue(b)) {
|
if (iscprim(b)) {
|
||||||
cvalue_t *acv=(cvalue_t*)ptr(a), *bcv=(cvalue_t*)ptr(b);
|
cprim_t *acp=(cprim_t*)ptr(a), *bcp=(cprim_t*)ptr(b);
|
||||||
numerictype_t at, bt;
|
numerictype_t at=cp_numtype(acp), bt=cp_numtype(bcp);
|
||||||
if (valid_numtype(at=cv_numtype(acv)) &&
|
void *aptr=cp_data(acp), *bptr=cp_data(bcp);
|
||||||
valid_numtype(bt=cv_numtype(bcv))) {
|
if (cmp_eq(aptr, at, bptr, bt))
|
||||||
void *aptr = cv_data(acv);
|
return fixnum(0);
|
||||||
void *bptr = cv_data(bcv);
|
if (eq) return fixnum(1);
|
||||||
if (cmp_eq(aptr, at, bptr, bt))
|
if (cmp_lt(aptr, at, bptr, bt))
|
||||||
return fixnum(0);
|
return fixnum(-1);
|
||||||
if (eq) return fixnum(1);
|
return fixnum(1);
|
||||||
if (cmp_lt(aptr, at, bptr, bt))
|
|
||||||
return fixnum(-1);
|
|
||||||
return fixnum(1);
|
|
||||||
}
|
|
||||||
return cvalue_compare(a, b);
|
|
||||||
}
|
}
|
||||||
else if (isfixnum(b)) {
|
else if (isfixnum(b)) {
|
||||||
return fixnum(-numval(compare_num_cvalue(b, a, eq)));
|
return fixnum(-numval(compare_num_cprim(b, a, eq)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TAG_CVALUE:
|
||||||
|
if (iscvalue(b))
|
||||||
|
return cvalue_compare(a, b);
|
||||||
|
break;
|
||||||
case TAG_BUILTIN:
|
case TAG_BUILTIN:
|
||||||
if (tagb == TAG_BUILTIN) {
|
if (tagb == TAG_BUILTIN) {
|
||||||
return (uintval(a) < uintval(b)) ? fixnum(-1) : fixnum(1);
|
return (uintval(a) < uintval(b)) ? fixnum(-1) : fixnum(1);
|
||||||
|
@ -288,6 +282,7 @@ static uptrint_t bounded_hash(value_t a, int bound)
|
||||||
numerictype_t nt;
|
numerictype_t nt;
|
||||||
size_t i, len;
|
size_t i, len;
|
||||||
cvalue_t *cv;
|
cvalue_t *cv;
|
||||||
|
cprim_t *cp;
|
||||||
void *data;
|
void *data;
|
||||||
if (bound <= 0) return 0;
|
if (bound <= 0) return 0;
|
||||||
uptrint_t h = 0;
|
uptrint_t h = 0;
|
||||||
|
@ -301,17 +296,17 @@ static uptrint_t bounded_hash(value_t a, int bound)
|
||||||
return inthash(a);
|
return inthash(a);
|
||||||
case TAG_SYM:
|
case TAG_SYM:
|
||||||
return ((symbol_t*)ptr(a))->hash;
|
return ((symbol_t*)ptr(a))->hash;
|
||||||
|
case TAG_CPRIM:
|
||||||
|
cp = (cprim_t*)ptr(a);
|
||||||
|
data = cp_data(cp);
|
||||||
|
nt = cp_numtype(cp);
|
||||||
|
d = conv_to_double(data, nt);
|
||||||
|
if (d==0) d = 0.0; // normalize -0
|
||||||
|
return doublehash(*(int64_t*)&d);
|
||||||
case TAG_CVALUE:
|
case TAG_CVALUE:
|
||||||
cv = (cvalue_t*)ptr(a);
|
cv = (cvalue_t*)ptr(a);
|
||||||
data = cv_data(cv);
|
data = cv_data(cv);
|
||||||
if (valid_numtype(nt=cv_numtype(cv))) {
|
return memhash(data, cv_len(cv));
|
||||||
d = conv_to_double(data, nt);
|
|
||||||
if (d==0) d = 0.0; // normalize -0
|
|
||||||
return doublehash(*(int64_t*)&d);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return memhash(data, cv_len(cv));
|
|
||||||
}
|
|
||||||
case TAG_VECTOR:
|
case TAG_VECTOR:
|
||||||
len = vector_size(a);
|
len = vector_size(a);
|
||||||
for(i=0; i < len; i++) {
|
for(i=0; i < len; i++) {
|
||||||
|
|
|
@ -197,7 +197,7 @@ static symbol_t *mk_symbol(char *str)
|
||||||
sym->binding = UNBOUND;
|
sym->binding = UNBOUND;
|
||||||
sym->syntax = 0;
|
sym->syntax = 0;
|
||||||
}
|
}
|
||||||
sym->type = NULL;
|
sym->type = sym->dlcache = NULL;
|
||||||
sym->hash = memhash32(str, len)^0xAAAAAAAA;
|
sym->hash = memhash32(str, len)^0xAAAAAAAA;
|
||||||
strcpy(&sym->name[0], str);
|
strcpy(&sym->name[0], str);
|
||||||
return sym;
|
return sym;
|
||||||
|
@ -351,8 +351,9 @@ static int symchar(char c);
|
||||||
static value_t relocate(value_t v)
|
static value_t relocate(value_t v)
|
||||||
{
|
{
|
||||||
value_t a, d, nc, first, *pcdr;
|
value_t a, d, nc, first, *pcdr;
|
||||||
|
uptrint_t t = tag(v);
|
||||||
|
|
||||||
if (iscons(v)) {
|
if (t == TAG_CONS) {
|
||||||
// iterative implementation allows arbitrarily long cons chains
|
// iterative implementation allows arbitrarily long cons chains
|
||||||
pcdr = &first;
|
pcdr = &first;
|
||||||
do {
|
do {
|
||||||
|
@ -370,11 +371,12 @@ static value_t relocate(value_t v)
|
||||||
*pcdr = (d==NIL) ? NIL : relocate(d);
|
*pcdr = (d==NIL) ? NIL : relocate(d);
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
uptrint_t t = tag(v);
|
|
||||||
if ((t&(t-1)) == 0) return v; // tags 0,1,2,4
|
if ((t&3) == 0) return v;
|
||||||
if (isforwarded(v))
|
if (!ismanaged(v)) return v;
|
||||||
return forwardloc(v);
|
if (isforwarded(v)) return forwardloc(v);
|
||||||
if (isvector(v)) {
|
|
||||||
|
if (t == TAG_VECTOR) {
|
||||||
// N.B.: 0-length vectors secretly have space for a first element
|
// N.B.: 0-length vectors secretly have space for a first element
|
||||||
size_t i, newsz, sz = vector_size(v);
|
size_t i, newsz, sz = vector_size(v);
|
||||||
newsz = sz;
|
newsz = sz;
|
||||||
|
@ -393,11 +395,20 @@ static value_t relocate(value_t v)
|
||||||
vector_elt(nc,i) = NIL;
|
vector_elt(nc,i) = NIL;
|
||||||
return nc;
|
return nc;
|
||||||
}
|
}
|
||||||
else if (iscvalue(v)) {
|
else if (t == TAG_CPRIM) {
|
||||||
|
cprim_t *pcp = (cprim_t*)ptr(v);
|
||||||
|
size_t nw = CPRIM_NWORDS-1+NWORDS(cp_class(pcp)->size);
|
||||||
|
cprim_t *ncp = (cprim_t*)alloc_words(nw);
|
||||||
|
while (nw--)
|
||||||
|
((value_t*)ncp)[nw] = ((value_t*)pcp)[nw];
|
||||||
|
nc = tagptr(ncp, TAG_CPRIM);
|
||||||
|
forward(v, nc);
|
||||||
|
return nc;
|
||||||
|
}
|
||||||
|
else if (t == TAG_CVALUE) {
|
||||||
return cvalue_relocate(v);
|
return cvalue_relocate(v);
|
||||||
}
|
}
|
||||||
else if (ismanaged(v)) {
|
else if (t == TAG_SYM) {
|
||||||
assert(issymbol(v));
|
|
||||||
gensym_t *gs = (gensym_t*)ptr(v);
|
gensym_t *gs = (gensym_t*)ptr(v);
|
||||||
gensym_t *ng = (gensym_t*)alloc_words(sizeof(gensym_t)/sizeof(void*));
|
gensym_t *ng = (gensym_t*)alloc_words(sizeof(gensym_t)/sizeof(void*));
|
||||||
ng->id = gs->id;
|
ng->id = gs->id;
|
||||||
|
@ -571,9 +582,7 @@ static value_t vector_grow(value_t v)
|
||||||
|
|
||||||
int isnumber(value_t v)
|
int isnumber(value_t v)
|
||||||
{
|
{
|
||||||
return (isfixnum(v) ||
|
return (isfixnum(v) || iscprim(v));
|
||||||
(iscvalue(v) &&
|
|
||||||
valid_numtype(cv_numtype((cvalue_t*)ptr(v)))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// read -----------------------------------------------------------------------
|
// read -----------------------------------------------------------------------
|
||||||
|
@ -928,19 +937,21 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
||||||
v = fixnum(vector_size(Stack[SP-1]));
|
v = fixnum(vector_size(Stack[SP-1]));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (iscvalue(Stack[SP-1])) {
|
else if (iscprim(Stack[SP-1])) {
|
||||||
cv = (cvalue_t*)ptr(Stack[SP-1]);
|
cv = (cvalue_t*)ptr(Stack[SP-1]);
|
||||||
v = cv_type(cv);
|
if (cp_class(cv) == bytetype) {
|
||||||
if (iscons(v) && car_(v) == arraysym) {
|
|
||||||
v = size_wrap(cvalue_arraylen(Stack[SP-1]));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (v == bytesym) {
|
|
||||||
v = fixnum(1);
|
v = fixnum(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (v == wcharsym) {
|
else if (cp_class(cv) == wchartype) {
|
||||||
v = fixnum(u8_charlen(*(uint32_t*)cv_data(cv)));
|
v = fixnum(u8_charlen(*(uint32_t*)cp_data((cprim_t*)cv)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (iscvalue(Stack[SP-1])) {
|
||||||
|
cv = (cvalue_t*)ptr(Stack[SP-1]);
|
||||||
|
if (cv_class(cv)->eltype != NULL) {
|
||||||
|
v = size_wrap(cvalue_arraylen(Stack[SP-1]));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -999,10 +1010,7 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
|
||||||
break;
|
break;
|
||||||
case F_NUMBERP:
|
case F_NUMBERP:
|
||||||
argcount("numberp", nargs, 1);
|
argcount("numberp", nargs, 1);
|
||||||
v = ((isfixnum(Stack[SP-1]) ||
|
v = (isfixnum(Stack[SP-1]) || iscprim(Stack[SP-1]) ? T : NIL);
|
||||||
(iscvalue(Stack[SP-1]) &&
|
|
||||||
valid_numtype(cv_numtype((cvalue_t*)ptr(Stack[SP-1]))) ))
|
|
||||||
? T : NIL);
|
|
||||||
break;
|
break;
|
||||||
case F_FIXNUMP:
|
case F_FIXNUMP:
|
||||||
argcount("fixnump", nargs, 1);
|
argcount("fixnump", nargs, 1);
|
||||||
|
|
|
@ -30,7 +30,7 @@ typedef struct _symbol_t {
|
||||||
} symbol_t;
|
} symbol_t;
|
||||||
|
|
||||||
#define TAG_NUM 0x0
|
#define TAG_NUM 0x0
|
||||||
//0x1 unused
|
#define TAG_CPRIM 0x1
|
||||||
#define TAG_BUILTIN 0x2
|
#define TAG_BUILTIN 0x2
|
||||||
#define TAG_VECTOR 0x3
|
#define TAG_VECTOR 0x3
|
||||||
#define TAG_NUM1 0x4
|
#define TAG_NUM1 0x4
|
||||||
|
@ -61,6 +61,7 @@ typedef struct _symbol_t {
|
||||||
#define isbuiltinish(x) (tag(x) == TAG_BUILTIN)
|
#define isbuiltinish(x) (tag(x) == TAG_BUILTIN)
|
||||||
#define isvector(x) (tag(x) == TAG_VECTOR)
|
#define isvector(x) (tag(x) == TAG_VECTOR)
|
||||||
#define iscvalue(x) (tag(x) == TAG_CVALUE)
|
#define iscvalue(x) (tag(x) == TAG_CVALUE)
|
||||||
|
#define iscprim(x) (tag(x) == TAG_CPRIM)
|
||||||
#define selfevaluating(x) (tag(x)<6)
|
#define selfevaluating(x) (tag(x)<6)
|
||||||
// comparable with ==
|
// comparable with ==
|
||||||
#define eq_comparable(a,b) (!(((a)|(b))&1))
|
#define eq_comparable(a,b) (!(((a)|(b))&1))
|
||||||
|
@ -212,12 +213,19 @@ typedef struct {
|
||||||
#define cv_len(cv) ((cv)->len)
|
#define cv_len(cv) ((cv)->len)
|
||||||
#define cv_type(cv) (cv_class(cv)->type)
|
#define cv_type(cv) (cv_class(cv)->type)
|
||||||
#define cv_data(cv) ((cv)->data)
|
#define cv_data(cv) ((cv)->data)
|
||||||
#define cv_numtype(cv) (cv_class(cv)->numtype)
|
|
||||||
#define cv_isstr(cv) (cv_class(cv)->eltype == bytetype)
|
#define cv_isstr(cv) (cv_class(cv)->eltype == bytetype)
|
||||||
|
|
||||||
#define cvalue_data(v) cv_data((cvalue_t*)ptr(v))
|
#define cvalue_data(v) cv_data((cvalue_t*)ptr(v))
|
||||||
|
|
||||||
#define valid_numtype(v) ((v) < N_NUMTYPES)
|
#define valid_numtype(v) ((v) < N_NUMTYPES)
|
||||||
|
#define cp_class(cp) ((cp)->type)
|
||||||
|
#define cp_type(cp) (cp_class(cp)->type)
|
||||||
|
#define cp_numtype(cp) (cp_class(cp)->numtype)
|
||||||
|
#define cp_data(cp) (&(cp)->_space[0])
|
||||||
|
|
||||||
|
// WARNING: multiple evaluation!
|
||||||
|
#define cptr(v) \
|
||||||
|
(iscprim(v) ? cp_data((cprim_t*)ptr(v)) : cv_data((cvalue_t*)ptr(v)))
|
||||||
|
|
||||||
/* C type names corresponding to cvalues type names */
|
/* C type names corresponding to cvalues type names */
|
||||||
typedef unsigned long ulong;
|
typedef unsigned long ulong;
|
||||||
|
|
|
@ -68,6 +68,9 @@ void print_traverse(value_t v)
|
||||||
for(i=0; i < vector_size(v); i++)
|
for(i=0; i < vector_size(v); i++)
|
||||||
print_traverse(vector_elt(v,i));
|
print_traverse(vector_elt(v,i));
|
||||||
}
|
}
|
||||||
|
else if (iscprim(v)) {
|
||||||
|
mark_cons(v);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
assert(iscvalue(v));
|
assert(iscvalue(v));
|
||||||
cvalue_t *cv = (cvalue_t*)ptr(v);
|
cvalue_t *cv = (cvalue_t*)ptr(v);
|
||||||
|
@ -342,6 +345,7 @@ void fl_print_child(ios_t *f, value_t v, int princ)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TAG_CVALUE:
|
case TAG_CVALUE:
|
||||||
|
case TAG_CPRIM:
|
||||||
case TAG_VECTOR:
|
case TAG_VECTOR:
|
||||||
case TAG_CONS:
|
case TAG_CONS:
|
||||||
if ((label=(value_t)ptrhash_get(&printconses, (void*)v)) !=
|
if ((label=(value_t)ptrhash_get(&printconses, (void*)v)) !=
|
||||||
|
@ -377,7 +381,7 @@ void fl_print_child(ios_t *f, value_t v, int princ)
|
||||||
outc(']', f);
|
outc(']', f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (iscvalue(v)) {
|
if (iscvalue(v) || iscprim(v)) {
|
||||||
unmark_cons(v);
|
unmark_cons(v);
|
||||||
cvalue_print(f, v, princ);
|
cvalue_print(f, v, princ);
|
||||||
break;
|
break;
|
||||||
|
@ -584,7 +588,7 @@ static void cvalue_printdata(ios_t *f, void *data, size_t len, value_t type,
|
||||||
void cvalue_print(ios_t *f, value_t v, int princ)
|
void cvalue_print(ios_t *f, value_t v, int princ)
|
||||||
{
|
{
|
||||||
cvalue_t *cv = (cvalue_t*)ptr(v);
|
cvalue_t *cv = (cvalue_t*)ptr(v);
|
||||||
void *data = cv_data(cv);
|
void *data = cptr(v);
|
||||||
|
|
||||||
if (cv_class(cv) == builtintype) {
|
if (cv_class(cv) == builtintype) {
|
||||||
HPOS+=ios_printf(f, "#<builtin @0x%08lx>",
|
HPOS+=ios_printf(f, "#<builtin @0x%08lx>",
|
||||||
|
@ -595,7 +599,9 @@ void cvalue_print(ios_t *f, value_t v, int princ)
|
||||||
cv_class(cv)->vtable->print(v, f, princ);
|
cv_class(cv)->vtable->print(v, f, princ);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cvalue_printdata(f, data, cv_len(cv), cv_type(cv), princ, 0);
|
value_t type = cv_type(cv);
|
||||||
|
size_t len = iscprim(v) ? cv_class(cv)->size : cv_len(cv);
|
||||||
|
cvalue_printdata(f, data, len, type, princ, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,9 +66,8 @@ value_t fl_string_encode(value_t *args, u_int32_t nargs)
|
||||||
argcount("string.encode", nargs, 1);
|
argcount("string.encode", nargs, 1);
|
||||||
if (iscvalue(args[0])) {
|
if (iscvalue(args[0])) {
|
||||||
cvalue_t *cv = (cvalue_t*)ptr(args[0]);
|
cvalue_t *cv = (cvalue_t*)ptr(args[0]);
|
||||||
value_t t = cv_type(cv);
|
fltype_t *t = cv_class(cv);
|
||||||
if (iscons(t) && car_(t) == arraysym &&
|
if (t->eltype == wchartype) {
|
||||||
iscons(cdr_(t)) && car_(cdr_(t)) == wcharsym) {
|
|
||||||
size_t nc = cv_len(cv) / sizeof(uint32_t);
|
size_t nc = cv_len(cv) / sizeof(uint32_t);
|
||||||
uint32_t *ptr = (uint32_t*)cv_data(cv);
|
uint32_t *ptr = (uint32_t*)cv_data(cv);
|
||||||
size_t nbytes = u8_codingsize(ptr, nc);
|
size_t nbytes = u8_codingsize(ptr, nc);
|
||||||
|
@ -111,30 +110,32 @@ value_t fl_string(value_t *args, u_int32_t nargs)
|
||||||
u_int32_t i;
|
u_int32_t i;
|
||||||
size_t len, sz = 0;
|
size_t len, sz = 0;
|
||||||
cvalue_t *temp;
|
cvalue_t *temp;
|
||||||
|
cprim_t *cp;
|
||||||
char *data;
|
char *data;
|
||||||
uint32_t wc;
|
uint32_t wc;
|
||||||
|
|
||||||
for(i=0; i < nargs; i++) {
|
for(i=0; i < nargs; i++) {
|
||||||
if (issymbol(args[i])) {
|
cv = args[i];
|
||||||
sz += strlen(symbol_name(args[i]));
|
if (issymbol(cv)) {
|
||||||
|
sz += strlen(symbol_name(cv));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (iscvalue(args[i])) {
|
else if (iscprim(cv)) {
|
||||||
temp = (cvalue_t*)ptr(args[i]);
|
cp = (cprim_t*)ptr(cv);
|
||||||
t = cv_type(temp);
|
t = cp_type(cp);
|
||||||
if (t == bytesym) {
|
if (t == bytesym) {
|
||||||
sz++;
|
sz++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (t == wcharsym) {
|
else if (t == wcharsym) {
|
||||||
wc = *(uint32_t*)cv_data(temp);
|
wc = *(uint32_t*)cp_data(cp);
|
||||||
sz += u8_charlen(wc);
|
sz += u8_charlen(wc);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (cv_isstr(temp)) {
|
}
|
||||||
sz += cv_len(temp);
|
else if (isstring(cv)) {
|
||||||
continue;
|
sz += cv_len((cvalue_t*)ptr(cv));
|
||||||
}
|
continue;
|
||||||
}
|
}
|
||||||
args[i] = print_to_string(args[i], 0);
|
args[i] = print_to_string(args[i], 0);
|
||||||
if (nargs == 1) // convert single value to string
|
if (nargs == 1) // convert single value to string
|
||||||
|
@ -149,21 +150,25 @@ value_t fl_string(value_t *args, u_int32_t nargs)
|
||||||
char *name = symbol_name(args[i]);
|
char *name = symbol_name(args[i]);
|
||||||
while (*name) *ptr++ = *name++;
|
while (*name) *ptr++ = *name++;
|
||||||
}
|
}
|
||||||
else {
|
else if (iscprim(args[i])) {
|
||||||
temp = (cvalue_t*)ptr(args[i]);
|
cp = (cprim_t*)ptr(args[i]);
|
||||||
t = cv_type(temp);
|
t = cp_type(cp);
|
||||||
data = cvalue_data(args[i]);
|
data = cp_data(cp);
|
||||||
if (t == bytesym) {
|
if (t == bytesym) {
|
||||||
*ptr++ = *(char*)data;
|
*ptr++ = *(char*)data;
|
||||||
}
|
}
|
||||||
else if (t == wcharsym) {
|
else {
|
||||||
|
// wchar
|
||||||
ptr += u8_wc_toutf8(ptr, *(uint32_t*)data);
|
ptr += u8_wc_toutf8(ptr, *(uint32_t*)data);
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
len = cv_len(temp);
|
else {
|
||||||
memcpy(ptr, data, len);
|
// string
|
||||||
ptr += len;
|
temp = (cvalue_t*)ptr(args[i]);
|
||||||
}
|
data = cv_data(temp);
|
||||||
|
len = cv_len(temp);
|
||||||
|
memcpy(ptr, data, len);
|
||||||
|
ptr += len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cv;
|
return cv;
|
||||||
|
@ -266,20 +271,21 @@ value_t fl_string_find(value_t *args, u_int32_t nargs)
|
||||||
if (start > len)
|
if (start > len)
|
||||||
bounds_error("string.find", args[0], args[2]);
|
bounds_error("string.find", args[0], args[2]);
|
||||||
char *needle; size_t needlesz;
|
char *needle; size_t needlesz;
|
||||||
if (!iscvalue(args[1]))
|
|
||||||
type_error("string.find", "string", args[1]);
|
value_t v = args[1];
|
||||||
cvalue_t *cv = (cvalue_t*)ptr(args[1]);
|
cprim_t *cp = (cprim_t*)ptr(v);
|
||||||
if (cv_class(cv) == wchartype) {
|
if (iscprim(v) && cp_class(cp) == wchartype) {
|
||||||
uint32_t c = *(uint32_t*)cv_data(cv);
|
uint32_t c = *(uint32_t*)cp_data(cp);
|
||||||
if (c <= 0x7f)
|
if (c <= 0x7f)
|
||||||
return mem_find_byte(s, (char)c, start, len);
|
return mem_find_byte(s, (char)c, start, len);
|
||||||
needlesz = u8_toutf8(cbuf, sizeof(cbuf), &c, 1);
|
needlesz = u8_toutf8(cbuf, sizeof(cbuf), &c, 1);
|
||||||
needle = cbuf;
|
needle = cbuf;
|
||||||
}
|
}
|
||||||
else if (cv_class(cv) == bytetype) {
|
else if (iscprim(v) && cp_class(cp) == bytetype) {
|
||||||
return mem_find_byte(s, *(char*)cv_data(cv), start, len);
|
return mem_find_byte(s, *(char*)cp_data(cp), start, len);
|
||||||
}
|
}
|
||||||
else if (isstring(args[1])) {
|
else if (isstring(v)) {
|
||||||
|
cvalue_t *cv = (cvalue_t*)ptr(v);
|
||||||
needlesz = cv_len(cv);
|
needlesz = cv_len(cv);
|
||||||
needle = (char*)cv_data(cv);
|
needle = (char*)cv_data(cv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,9 @@
|
||||||
* read support for #' for compatibility
|
* read support for #' for compatibility
|
||||||
* #\c read character as code (including UTF-8 support!)
|
* #\c read character as code (including UTF-8 support!)
|
||||||
* #| |# block comments
|
* #| |# block comments
|
||||||
- here-data for binary serialization. proposed syntax:
|
? here-data for binary serialization. proposed syntax:
|
||||||
#>size:data, e.g. #>6:000000
|
#>size:data, e.g. #>6:000000
|
||||||
|
? better read syntax for packed arrays, e.g. #double[3 1 4]
|
||||||
* use syntax environment concept for user-defined macros to plug
|
* use syntax environment concept for user-defined macros to plug
|
||||||
that hole in the semantics
|
that hole in the semantics
|
||||||
* make more builtins generic. if typecheck fails, call out to the
|
* make more builtins generic. if typecheck fails, call out to the
|
||||||
|
@ -102,9 +103,10 @@ possible optimizations:
|
||||||
env in-place in tail position
|
env in-place in tail position
|
||||||
- allocate memory by mmap'ing a large uncommitted block that we cut
|
- allocate memory by mmap'ing a large uncommitted block that we cut
|
||||||
in half. then each half heap can be grown without moving addresses.
|
in half. then each half heap can be grown without moving addresses.
|
||||||
- try making (list ...) a builtin by moving the list-building code to
|
* try making (list ...) a builtin by moving the list-building code to
|
||||||
a static function, see if vararg call performance is affected.
|
a static function, see if vararg call performance is affected.
|
||||||
- try making foldl a builtin, implement table iterator as table.foldl
|
- try making foldl a builtin, implement table iterator as table.foldl
|
||||||
|
. not great, since then it can't be CPS converted
|
||||||
* represent lambda environment as a vector (in lispv)
|
* represent lambda environment as a vector (in lispv)
|
||||||
x setq builtin (didn't help)
|
x setq builtin (didn't help)
|
||||||
(- list builtin, to use cons_reserve)
|
(- list builtin, to use cons_reserve)
|
||||||
|
@ -131,6 +133,10 @@ for internal use:
|
||||||
improve by making lambda lists vectors somehow?
|
improve by making lambda lists vectors somehow?
|
||||||
* fast builtin bounded iteration construct (for lo hi (lambda (x) ...))
|
* fast builtin bounded iteration construct (for lo hi (lambda (x) ...))
|
||||||
* represent guest function as a tagged function pointer; allocate nothing
|
* represent guest function as a tagged function pointer; allocate nothing
|
||||||
|
- when an instance of (array type n) is requested, use (array type)
|
||||||
|
instead, unless the value is part of an aggregate (e.g. struct).
|
||||||
|
. this avoids allocating a new type for every size.
|
||||||
|
. and/or add function array.alloc
|
||||||
|
|
||||||
bugs:
|
bugs:
|
||||||
* with the fully recursive (simpler) relocate(), the size of cons chains
|
* with the fully recursive (simpler) relocate(), the size of cons chains
|
||||||
|
@ -925,7 +931,7 @@ switch to miser mode, otherwise default is ok, for example:
|
||||||
|
|
||||||
consolidated todo list as of 8/30:
|
consolidated todo list as of 8/30:
|
||||||
* new cvalues, types representation
|
* new cvalues, types representation
|
||||||
- use the unused tag for TAG_PRIM, add smaller prim representation
|
* use the unused tag for TAG_PRIM, add smaller prim representation
|
||||||
* finalizers in gc
|
* finalizers in gc
|
||||||
* hashtable
|
* hashtable
|
||||||
* generic aref/aset
|
* generic aref/aset
|
||||||
|
|
|
@ -66,12 +66,8 @@ fltype_t *get_array_type(value_t eltype)
|
||||||
fltype_t *define_opaque_type(value_t sym, size_t sz, cvtable_t *vtab,
|
fltype_t *define_opaque_type(value_t sym, size_t sz, cvtable_t *vtab,
|
||||||
cvinitfunc_t init)
|
cvinitfunc_t init)
|
||||||
{
|
{
|
||||||
void **bp = equalhash_bp(&TypeTable, (void*)sym);
|
|
||||||
if (*bp != HT_NOTFOUND)
|
|
||||||
return *bp;
|
|
||||||
fltype_t *ft = (fltype_t*)malloc(sizeof(fltype_t));
|
fltype_t *ft = (fltype_t*)malloc(sizeof(fltype_t));
|
||||||
ft->type = sym;
|
ft->type = sym;
|
||||||
((symbol_t*)ptr(sym))->type = ft;
|
|
||||||
ft->size = sz;
|
ft->size = sz;
|
||||||
ft->numtype = N_NUMTYPES;
|
ft->numtype = N_NUMTYPES;
|
||||||
ft->vtable = vtab;
|
ft->vtable = vtab;
|
||||||
|
@ -80,7 +76,6 @@ fltype_t *define_opaque_type(value_t sym, size_t sz, cvtable_t *vtab,
|
||||||
ft->elsz = 0;
|
ft->elsz = 0;
|
||||||
ft->marked = 1;
|
ft->marked = 1;
|
||||||
ft->init = init;
|
ft->init = init;
|
||||||
*bp = ft;
|
|
||||||
return ft;
|
return ft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue