ref: 35424e72a0a8b9069b3f24bb33b62892ca4b66d1
parent: b35c60cd64b6f630621163226d31f1e2fdc6c90d
parent: 3cfea02a4e7863afce7813a525fd6468be823846
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Fri Apr 4 23:53:27 EDT 2025
Merge branch 'unboxed'
--- a/boot/sl.boot
+++ b/boot/sl.boot
@@ -439,8 +439,9 @@
self-evaluating? #fn("n120051S;3Z040H;36040RS;JK0421051;3A040R;3:04022051Q:" #(#fn(gensym?)
#fn(const?) #fn(top-level-value)) self-evaluating?)
separate-doc-from-body #fn("\x8710002000W1000J60q?14I2021?65140<0=2287513F01JB0883=07388871P62:13X02487513O086258751513B07388=8788<P1P62:761510P:" #(#0#
- #fn("n1r520051L2;3a040KG21l2;3U040r2G22l2;3H040r3G23l2;3;040r4G24l2:" #(#fn(length) #\d #\o #\c
- #\-) doc?)
+ #fn("n1r520051L2;3i04210K5222Q;3[04210r25223Q;3L04210r35224Q;3=04210r45225Q:" #(#fn(str-length)
+ #fn(str-rune)
+ #\d #\o #\c #\-) doc?)
#fn(str?) separate-doc-from-body #fn(keyword?) #fn(str) reverse) separate-doc-from-body)
set-syntax! #fn("n220710163:" #(#fn(put!) *syntax-environment*) set-syntax!) sort
#fn("O200010003000W2000J7071?240=J400:0<7223182870>42418287>362:" #(#(:key 0) identity
@@ -468,7 +469,8 @@
#fn(str-length)
#fn(str-sub)) str-trim)
sym-set-doc #fn("z220151873601@401<87360q@401=21Z3\xb40883\xaf0228823528:<8:=74258<528=;3H04268=5126778=28295351~8=;3?042:2;8>>18<52718;8?P23527<02=8@534893>07<02>8953@30q^1^1^1^1^1^1^1@30q482B3[07?02@527A2B8:>182527<02@2C8:8;5253^1^1@30q47D60:" #(#fn(str?)
- str-join #fn(str-split) "\n" any #fn("n1E20051L2;3@040EG21l2;34040:" #(#fn(length) #\space))
+ str-join #fn(str-split) "\n" any #fn("n1E20051L2;3B04210E5222Q;34040:" #(#fn(str-length)
+ #fn(str-rune) #\space))
#fn(length) str-trim " " "" #fn(map) #fn("n170A2105152390220A62:0:" #(<= #fn(length)
#fn(str-sub))) putprop
*doc* *doc-extra* getprop *formals-list* filter #fn("n1700A52S:" #(member))
--- a/src/builtins.c
+++ b/src/builtins.c
@@ -100,12 +100,12 @@
n += llength(v);
return size_wrap(n);
}
+ if(isrune(a))
+ return fixnum(runelen(torune(a)));
if(iscprim(a)){
cv = ptr(a);
if(cp_class(cv) == sl_utf8type)
return fixnum(1);
- if(cp_class(cv) == sl_runetype)
- return fixnum(runelen(*(Rune*)cp_data(cv)));
}
if(iscvalue(a) && cv_class(ptr(a))->eltype != nil)
return size_wrap(cvalue_arrlen(a));
@@ -226,7 +226,7 @@
{
argcount(nargs, 1);
sl_v v = args[0];
- if(isfixnum(v) || ismp(v))
+ if(isfixnum(v) || isubnum(v) || ismp(v))
return sl_t;
if(iscprim(v)){
sl_numtype nt = cp_numtype(ptr(v));
@@ -256,7 +256,7 @@
{
argcount(nargs, 1);
sl_v v = args[0];
- return (isfixnum(v) || ismp(v) ||
+ return (isfixnum(v) || isubnum(v) || ismp(v) ||
(iscprim(v) && cp_numtype(ptr(v)) < T_FLOAT)) ?
sl_t : sl_nil;
}
@@ -274,6 +274,10 @@
sl_v v = args[0];
if(isfixnum(v))
return v;
+ if(isubnumu(v))
+ return fixnum(ubnumuval(v));
+ if(isubnums(v))
+ return fixnum(ubnumsval(v));
if(iscprim(v)){
void *p = ptr(v);
return fixnum(conv_to_s64(cp_data(p), cp_numtype(p)));
@@ -291,7 +295,7 @@
{
argcount(nargs, 1);
sl_v v = args[0];
- if(isfixnum(v) || ismp(v))
+ if(isfixnum(v) || isubnum(v) || ismp(v))
return v;
if(iscprim(v)){
sl_cprim *cp = ptr(v);
@@ -351,7 +355,11 @@
todouble(sl_v a)
{
if(isfixnum(a))
- return (double)numval(a);
+ return numval(a);
+ if(isubnumu(a))
+ return ubnumuval(a);
+ if(isubnums(a))
+ return ubnumsval(a);
if(iscprim(a)){
sl_cprim *cp = ptr(a);
sl_numtype nt = cp_numtype(cp);
--- a/src/compress.c
+++ b/src/compress.c
@@ -17,7 +17,8 @@
type_error("arr", args[0]);
u8int *in;
usize insz;
- to_sized_ptr(args[0], &in, &insz);
+ uintptr u;
+ to_sized_ptr(args[0], &in, &insz, &u);
int level = nargs > 1 ? tofixnum(args[1]) : 0;
if(level < 0)
level = 0;
@@ -47,7 +48,8 @@
u8int *in;
usize insz;
- to_sized_ptr(args[0], &in, &insz);
+ uintptr u;
+ to_sized_ptr(args[0], &in, &insz, &u);
if(!isarr(args[0]))
type_error("arr", args[0]);
usize outsz;
@@ -59,7 +61,7 @@
out = cvalue_data(v);
}else if(args[1] == sl_tosym){
v = args[2];
- to_sized_ptr(v, &out, &outsz);
+ to_sized_ptr(v, &out, &outsz, &u);
}else{
lerrorf(sl_errarg, "either :size or :to must be specified");
}
--- a/src/cvalues.c
+++ b/src/cvalues.c
@@ -15,6 +15,9 @@
#define owned(cv) ((uintptr)(cv)->type & CV_OWNED)
#define isinlined(cv) ((cv)->data == (cv)->_space)
+sl_type *unboxedtypes[T_UNBOXED_NUM];
+sl_v unboxedtypesyms[T_UNBOXED_NUM];
+
static void cvalue_init(sl_type *type, sl_v v, void *dest);
void
@@ -197,23 +200,52 @@
cv_autorelease(cv);
}
+static void
+cvalue_rune_init(sl_type *type, sl_v a, void *dest)
+{
+ Rune r;
+ USED(type);
+ if(isfixnum(a)){
+ r = numval(a);
+ }else if(isrune(a)){
+ r = torune(a);
+ }else if(isubnumu(a)){
+ uintptr v = ubnumuval(a);
+ r = conv_to_u32(&v, ubnumtype(a));
+ }else if(isubnums(a)){
+ intptr v = ubnumsval(a);
+ r = conv_to_u32(&v, ubnumtype(a));
+ }else if(iscprim(a)){
+ sl_cprim *cp = ptr(a);
+ r = conv_to_u32(cp_data(cp), cp_numtype(cp));
+ }else if(ismp(a)){
+ r = conv_to_u32(cv_data(ptr(a)), T_MP);
+ }else
+ type_error("num", a);
+ *((Rune*)dest) = r;
+}
+
#define num_init(ctype, cnvt, tag) \
static void \
- cvalue_##ctype##_init(sl_type *type, sl_v arg, void *dest) \
+ cvalue_##ctype##_init(sl_type *type, sl_v a, void *dest) \
{ \
ctype n; \
USED(type); \
- if(isfixnum(arg)) \
- n = (ctype)numval(arg); \
- else if(iscprim(arg)){ \
- sl_cprim *cp = ptr(arg); \
- void *p = cp_data(cp); \
- n = (ctype)conv_to_##cnvt(p, cp_numtype(cp)); \
- }else if(ismp(arg)){ \
- void *p = cv_data(ptr(arg)); \
- n = (ctype)conv_to_##cnvt(p, T_MP); \
+ if(isfixnum(a)){ \
+ n = (ctype)numval(a); \
+ }else if(isubnumu(a)){ \
+ uintptr v = ubnumuval(a); \
+ n = (ctype)conv_to_##cnvt(&v, ubnumtype(a)); \
+ }else if(isubnums(a)){ \
+ intptr v = ubnumsval(a); \
+ n = (ctype)conv_to_##cnvt(&v, ubnumtype(a)); \
+ }else if(iscprim(a)){ \
+ sl_cprim *cp = ptr(a); \
+ n = (ctype)conv_to_##cnvt(cp_data(cp), cp_numtype(cp)); \
+ }else if(ismp(a)){ \
+ n = (ctype)conv_to_##cnvt(cv_data(ptr(a)), T_MP); \
}else \
- type_error("num", arg); \
+ type_error("num", a); \
*((ctype*)dest) = n; \
}
@@ -228,6 +260,17 @@
num_init(float, double, T_FLOAT)
num_init(double, double, T_DOUBLE)
+BUILTIN("rune", rune)
+{
+ if(nargs == 0){
+ PUSH(fixnum(0));
+ args = sl.sp-1;
+ }
+ Rune r;
+ cvalue_rune_init(sl_runetype, args[0], &r);
+ return mk_rune(r);
+}
+
#define num_ctor_init(typenam, ctype, tag) \
static \
BUILTIN(#typenam, typenam) \
@@ -236,53 +279,102 @@
PUSH(fixnum(0)); \
args = sl.sp-1; \
} \
- sl_v cp = cprim(sl_##typenam##type, sizeof(ctype)); \
- cvalue_##ctype##_init(sl_##typenam##type, args[0], cp_data(ptr(cp))); \
- return cp; \
+ sl_v v = cprim(sl_##typenam##type, sizeof(ctype)); \
+ cvalue_##ctype##_init(sl_##typenam##type, args[0], cp_data(ptr(v))); \
+ return v; \
}
+#define num_ctor_init_unboxed(typenam, ctype, tag) \
+ static \
+ BUILTIN(#typenam, typenam) \
+ { \
+ if(nargs == 0){ \
+ PUSH(fixnum(0)); \
+ args = sl.sp-1; \
+ } \
+ sl_v v; \
+ if(tag < T_UNBOXED_NUM && \
+ sizeof(ctype) < sizeof(sl_v)){ \
+ ctype u; \
+ cvalue_##ctype##_init(sl_##typenam##type, args[0], &u); \
+ v = (sl_v)u<<TAG_EXT_BITS | tag<<4 | TAG_UNBOXED; \
+ }else{ \
+ v = cprim(sl_##typenam##type, sizeof(ctype)); \
+ cvalue_##ctype##_init(sl_##typenam##type, args[0], cp_data(ptr(v))); \
+ } \
+ return v; \
+ }
+
#define num_ctor_ctor(typenam, ctype, tag) \
- sl_v mk_##typenam(ctype n) \
+ sl_v \
+ mk_##typenam(ctype n) \
{ \
- sl_v cp = cprim(sl_##typenam##type, sizeof(ctype)); \
- *(ctype*)cp_data(ptr(cp)) = n; \
- return cp; \
+ sl_v v = cprim(sl_##typenam##type, sizeof(n)); \
+ *(ctype*)cp_data(ptr(v)) = n; \
+ return v; \
}
+#define num_ctor_ctor_unboxed(typenam, ctype, tag) \
+ sl_constfn \
+ sl_v \
+ mk_##typenam(ctype n) \
+ { \
+ sl_v v; \
+ if(tag < T_UNBOXED_NUM && \
+ (sizeof(n) < sizeof(sl_v) || fits_bits(n, UNBOXED_BITS))){ \
+ v = n<<TAG_EXT_BITS | tag<<4 | TAG_UNBOXED; \
+ }else{ \
+ v = cprim(sl_##typenam##type, sizeof(n)); \
+ *(ctype*)cp_data(ptr(v)) = n; \
+ } \
+ return v; \
+ }
+
#define num_ctor(typenam, ctype, tag) \
num_ctor_init(typenam, ctype, tag) \
num_ctor_ctor(typenam, ctype, tag)
-num_ctor_init(s8, s8int, T_S8)
-num_ctor_init(u8, u8int, T_U8)
-num_ctor_init(s16, s16int, T_S16)
-num_ctor_init(u16, u16int, T_U16)
-num_ctor(s32, s32int, T_S32)
-num_ctor(u32, u32int, T_U32)
-num_ctor(s64, s64int, T_S64)
-num_ctor(u64, u64int, T_U64)
+#define num_ctor_unboxed(typenam, ctype, tag) \
+ num_ctor_init_unboxed(typenam, ctype, tag) \
+ num_ctor_ctor_unboxed(typenam, ctype, tag)
+
+num_ctor_init_unboxed(s8, s8int, T_S8)
+num_ctor_init_unboxed(u8, u8int, T_U8)
+num_ctor_init_unboxed(s16, s16int, T_S16)
+num_ctor_init_unboxed(u16, u16int, T_U16)
+num_ctor_unboxed(s32, s32int, T_S32)
+num_ctor_unboxed(u32, u32int, T_U32)
+num_ctor_unboxed(s64, s64int, T_S64)
+num_ctor_unboxed(u64, u64int, T_U64)
num_ctor_init(utf8, u8int, T_U8)
num_ctor(float, float, T_FLOAT)
num_ctor(double, double, T_DOUBLE)
-num_ctor(rune, u32int, T_U32)
static void
-cvalue_mp_init(sl_type *type, sl_v arg, void *dest)
+cvalue_mp_init(sl_type *type, sl_v a, void *dest)
{
mpint *n;
USED(type);
- if(isfixnum(arg)){
- n = vtomp(numval(arg), nil);
- }else if(iscvalue(arg)){
- sl_cv *cv = ptr(arg);
+ if(isfixnum(a))
+ n = vtomp(numval(a), nil);
+ else if(isubnum(a)){
+ uintptr v;
+ void *p = &v;
+ if(isubnumu(a))
+ v = ubnumuval(a);
+ else
+ v = ubnumsval(a);
+ n = conv_to_mp(p, ubnumtype(a));
+ }else if(iscvalue(a)){
+ sl_cv *cv = ptr(a);
void *p = cv_data(cv);
n = conv_to_mp(p, cv_numtype(cv));
- }else if(iscprim(arg)){
- sl_cprim *cp = ptr(arg);
+ }else if(iscprim(a)){
+ sl_cprim *cp = ptr(a);
void *p = cp_data(cp);
n = conv_to_mp(p, cp_numtype(cp));
}else
- type_error("num", arg);
+ type_error("num", a);
*((mpint**)dest) = n;
}
@@ -316,6 +408,7 @@
static sl_cvtable mp_vtable = { nil, nil, free_mp, nil };
+sl_constfn
sl_v
size_wrap(usize sz)
{
@@ -330,6 +423,8 @@
{
if(isfixnum(n))
return (usize)numval(n);
+ if(isubnum(n))
+ return (usize)ubnumuval(n);
if(iscprim(n)){
sl_cprim *cp = ptr(n);
if(sizeof(usize) == 8)
@@ -344,6 +439,10 @@
{
if(isfixnum(n))
return numval(n);
+ if(isubnumu(n))
+ return ubnumuval(n);
+ if(isubnums(n))
+ return ubnumsval(n);
if(iscprim(n)){
sl_cprim *cp = ptr(n);
return conv_to_s64(cp_data(cp), cp_numtype(cp));
@@ -502,7 +601,9 @@
{
sl_sym *s;
- if(issym(type) && (s = ptr(type)) != nil && valid_numtype(s->numtype))
+ if(issym(type) &&
+ (s = ptr(type)) != nil &&
+ (valid_numtype(s->numtype) || type == sl_runesym))
return s->size;
if(iscons(type)){
@@ -522,8 +623,26 @@
// get pointer and size for any plain-old-data value
void
-to_sized_ptr(sl_v v, u8int **pdata, usize *psz)
+to_sized_ptr(sl_v v, u8int **pdata, usize *psz, uintptr *u)
{
+ if(isubnumu(v)){
+ *u = ubnumuval(v);
+ *pdata = (u8int*)u;
+ *psz = unboxedtypes[ubnumtype(v)]->size;
+ return;
+ }
+ if(isubnums(v)){
+ *u = ubnumsval(v);
+ *pdata = (u8int*)u;
+ *psz = unboxedtypes[ubnumtype(v)]->size;
+ return;
+ }
+ if(isrune(v)){
+ Rune r = torune(v);
+ *pdata = (u8int*)u;
+ *psz = runetochar((char*)u, &r);
+ return;
+ }
if(iscvalue(v)){
sl_cv *pcv = ptr(v);
sl_ios *x;
@@ -554,7 +673,8 @@
return size_wrap(ctype_sizeof(args[0]));
usize n;
u8int *data;
- to_sized_ptr(args[0], &data, &n);
+ uintptr u;
+ to_sized_ptr(args[0], &data, &n, &u);
return size_wrap(n);
}
@@ -561,26 +681,33 @@
sl_purefn
BUILTIN("typeof", typeof)
{
+ sl_v v = args[0];
argcount(nargs, 1);
- switch(tag(args[0])){
+ switch(tag(v)){
case TAG_CONS: return sl_conssym;
case TAG_FIXNUM: return sl_fixnumsym;
+ case TAG_UNBOXED:
+ if(isubnum(v))
+ return unboxedtypesyms[ubnumtype(v)];
+ if(isrune(v))
+ return sl_runesym;
+ abort();
case TAG_SYM: return sl_symsym;
case TAG_VEC:return sl_vecsym;
case TAG_FN:
- if(args[0] == sl_t)
+ if(v == sl_t)
return sl_booleansym;
- if(args[0] == sl_nil)
+ if(v == sl_nil)
return sl_nullsym;
- if(args[0] == sl_eof)
+ if(v == sl_eof)
return sl_eof;
- if(args[0] == sl_void)
+ if(v == sl_void)
return sl_void;
- if(isbuiltin(args[0]))
+ if(isbuiltin(v))
return sl_builtinsym;
return sl_fnsym;
}
- return cv_type(ptr(args[0]));
+ return cv_type(ptr(v));
}
sl_v
@@ -647,7 +774,9 @@
BUILTIN("plain-old-data?", plain_old_datap)
{
argcount(nargs, 1);
- return (iscprim(args[0]) ||
+ return (isubnum(args[0]) ||
+ iscprim(args[0]) ||
+ isrune(args[0]) ||
(iscvalue(args[0]) && cv_isPOD(ptr(args[0])))) ?
sl_t : sl_nil;
}
@@ -825,6 +954,7 @@
#define RETURN_NUM_AS(var, type) return(mk_##type(var))
+sl_constfn
sl_v
return_from_u64(u64int Uaccum)
{
@@ -927,6 +1057,19 @@
*pp = pi;
*pt = T_FIXNUM;
return true;
+ }else if(isubnum(a)){
+ if(isubnumu(a))
+ *pi = ubnumuval(a);
+ else
+ *pi = ubnumsval(a);
+ *pp = pi;
+ *pt = ubnumtype(a);
+ return true;
+ }else if(isrune(a)){
+ *pi = torune(a);
+ *pp = pi;
+ *pt = T_U32;
+ return true;
}else if(iscprim(a)){
cp = ptr(a);
*pp = cp_data(cp);
@@ -1215,15 +1358,15 @@
if(isfixnum(a))
return fixnum(~numval(a));
+ if(isubnumu(a))
+ return (~ubnumuval(a) & ~0xff) | (a & 0xff);
+ if(isubnums(a))
+ return (~ubnumsval(a) & ~0xff) | (a & 0xff);
if(iscprim(a)){
cp = ptr(a);
ta = cp_numtype(cp);
aptr = cp_data(cp);
switch(ta){
- case T_S8: return fixnum(~*(s8int *)aptr);
- case T_U8: return fixnum(~*(u8int *)aptr & 0xff);
- case T_S16: return fixnum(~*(s16int*)aptr);
- case T_U16: return fixnum(~*(u16int*)aptr & 0xffff);
case T_S32: return mk_s32(~*(s32int*)aptr);
case T_U32: return mk_u32(~*(u32int*)aptr);
case T_S64: return mk_s64(~*(s64int*)aptr);
@@ -1248,6 +1391,7 @@
{
sl_fx n;
s64int accum;
+ u64int u;
sl_cprim *cp;
int ta;
mpint *mp;
@@ -1259,8 +1403,8 @@
if(n == 0)
return a;
mp = nil;
- if(isfixnum(a)){
- accum = numval(a);
+ if(isfixnum(a) || isubnums(a)){
+ accum = isfixnum(a) ? numval(a) : ubnumsval(a);
if(n > -64 && n < 0)
return fixnum(accum>>(-n));
if(n < 0 || n >= 64 || sash_overflow_64(accum, n, &accum)){
@@ -1269,6 +1413,15 @@
}else
return fits_fixnum(accum) ? fixnum(accum) : return_from_s64(accum);
}
+ if(isubnumu(a)){
+ u = ubnumuval(a);
+ if(n > 0)
+ u = n < 64 ? u<<n : 0;
+ else
+ u = n > -64 ? u>>-n : 0;
+ accum = u;
+ return (accum >= 0 && fits_fixnum(accum)) ? fixnum(accum) : return_from_u64(u);
+ }
if(iscprim(a)){
cp = ptr(a);
ta = cp_numtype(cp);
@@ -1276,10 +1429,6 @@
if(n < 0){
n = -n;
switch(ta){
- case T_S8: return fixnum((*(s8int *)aptr) >> n);
- case T_U8: return fixnum((*(u8int *)aptr) >> n);
- case T_S16: return fixnum((*(s16int*)aptr) >> n);
- case T_U16: return fixnum((*(u16int*)aptr) >> n);
case T_S32: return mk_s32((*(s32int*)aptr) >> n);
case T_U32: return mk_u32((*(u32int*)aptr) >> n);
case T_S64: return mk_s64((*(s64int*)aptr) >> n);
@@ -1312,6 +1461,13 @@
htable_new(&slg.types, 256);
htable_new(&slg.reverse_dlsym_lookup, 256);
+ ctor_cv_intern(rune, NONNUMERIC, u32int);
+ sl_sym *sym = ptr(sl_runesym);
+ sym->numtype = NONNUMERIC;
+ sym->size = sizeof(Rune);
+ sl_runetype = get_type(sl_runesym);
+ sl_runetype->init = cvalue_rune_init;
+
sl_builtintype = define_opaque_type(sl_builtinsym, sizeof(builtin_t), nil, nil);
ctor_cv_intern(s8, T_S8, s8int);
@@ -1323,7 +1479,6 @@
ctor_cv_intern(s64, T_S64, s64int);
ctor_cv_intern(u64, T_U64, u64int);
ctor_cv_intern(utf8, T_U8, u8int);
- ctor_cv_intern(rune, T_U32, u32int);
ctor_cv_intern(float, T_FLOAT, float);
ctor_cv_intern(double, T_DOUBLE, double);
@@ -1338,7 +1493,6 @@
mk_primtype(s64, s64int);
mk_primtype(u64, u64int);
mk_primtype(utf8, u8int);
- mk_primtype(rune, u32int);
mk_primtype(float, float);
mk_primtype(double, double);
@@ -1346,6 +1500,23 @@
sl_mptype = get_type(sl_bignumsym);
sl_mptype->init = cvalue_mp_init;
sl_mptype->vtable = &mp_vtable;
+
+ unboxedtypes[T_S8] = sl_s8type;
+ unboxedtypes[T_U8] = sl_u8type;
+ unboxedtypes[T_S16] = sl_s16type;
+ unboxedtypes[T_U16] = sl_u16type;
+ unboxedtypes[T_S32] = sl_s32type;
+ unboxedtypes[T_U32] = sl_u32type;
+ unboxedtypes[T_S64] = sl_s64type;
+ unboxedtypes[T_U64] = sl_u64type;
+ unboxedtypesyms[T_S8] = sl_s8sym;
+ unboxedtypesyms[T_U8] = sl_u8sym;
+ unboxedtypesyms[T_S16] = sl_s16sym;
+ unboxedtypesyms[T_U16] = sl_u16sym;
+ unboxedtypesyms[T_S32] = sl_s32sym;
+ unboxedtypesyms[T_U32] = sl_u32sym;
+ unboxedtypesyms[T_S64] = sl_s64sym;
+ unboxedtypesyms[T_U64] = sl_u64sym;
sl_strtype = get_type(mk_list2(sl_arrsym, sl_utf8sym));
sl_emptystr = cvalue_from_ref(sl_strtype, (char*)"", 0);
--- a/src/cvalues.h
+++ b/src/cvalues.h
@@ -26,7 +26,7 @@
void cvalue_arr_init(sl_type *ft, sl_v arg, void *dest);
usize cvalue_arrlen(sl_v v) sl_purefn;
usize ctype_sizeof(sl_v type);
-void to_sized_ptr(sl_v v, u8int **pdata, usize *psz);
+void to_sized_ptr(sl_v v, u8int **pdata, usize *psz, uintptr *u);
sl_v cvalue_relocate(sl_v v);
sl_v cvalue_copy(sl_v v);
sl_v cvalue_compare(sl_v a, sl_v b) sl_purefn;
@@ -50,7 +50,6 @@
sl_v mk_u32(u32int n);
sl_v mk_s64(s64int n);
sl_v mk_u64(u64int n);
-sl_v mk_rune(Rune n);
sl_v mk_mp(mpint *n);
usize llength(sl_v v) sl_purefn;
--- a/src/equal.c
+++ b/src/equal.c
@@ -15,9 +15,6 @@
#define doublehash(a) int64to32hash(a)
#endif
-// comparable tag
-#define cmptag(v) (isfixnum(v) ? TAG_FIXNUM : tag(v))
-
static sl_v
eq_class(sl_htable *table, sl_v key)
{
@@ -77,22 +74,24 @@
if(bound <= 0)
return sl_nil;
int taga = tag(a);
- int tagb = cmptag(b);
+ int tagb = tag(b);
int c;
switch(taga){
case TAG_FIXNUM:
if(isfixnum(b))
return (sl_fx)a < (sl_fx)b ? fixnum(-1) : fixnum(1);
- if(iscprim(b)){
- if(cp_class(ptr(b)) == sl_runetype)
+ if(isubnum(b) || iscprim(b) || (iscvalue(b) && (cv = ptr(b), valid_numtype(cv_numtype(cv)))))
+ return fixnum(numeric_compare(a, b, eq, true, false));
+ if(isrune(b))
return fixnum(1);
+ return fixnum(-1);
+ case TAG_UNBOXED:
+ if(isrune(a))
+ return fixnum(isrune(b) && a == b ? 0 : -1);
+ if(isrune(b))
+ return fixnum(1);
+ if(isfixnum(b) || isubnum(b) || iscprim(b) || (iscvalue(b) && (cv = ptr(b), valid_numtype(cv_numtype(cv)))))
return fixnum(numeric_compare(a, b, eq, true, false));
- }
- if(iscvalue(b)){
- cv = ptr(b);
- if(valid_numtype(cv_numtype(cv)))
- return fixnum(numeric_compare(a, b, eq, true, false));
- }
return fixnum(-1);
case TAG_SYM:
if(eq || tagb < TAG_SYM)
@@ -105,11 +104,6 @@
return bounded_vec_compare(a, b, bound, eq);
break;
case TAG_CPRIM:
- if(cp_class(ptr(a)) == sl_runetype){
- if(!iscprim(b) || cp_class(ptr(b)) != sl_runetype)
- return fixnum(-1);
- }else if(iscprim(b) && cp_class(ptr(b)) == sl_runetype)
- return fixnum(1);
c = numeric_compare(a, b, eq, true, false);
if(c != 2)
return fixnum(c);
@@ -334,6 +328,16 @@
case TAG_FIXNUM:
u.d = (double)numval(a);
return doublehash(u.i64);
+ case TAG_UNBOXED:
+ if(isubnumu(a))
+ u.d = ubnumuval(a);
+ else if(isubnums(a))
+ u.d = ubnumsval(a);
+ else if(isrune(a))
+ return inthash(torune(a));
+ else
+ abort();
+ return doublehash(u.i64);
case TAG_FN:
if(uintval(a) > N_BUILTINS)
return bounded_hash(((sl_fn*)ptr(a))->bcode, bound, oob);
@@ -343,8 +347,6 @@
case TAG_CPRIM:
cp = ptr(a);
data = cp_data(cp);
- if(cp_class(cp) == sl_runetype)
- return inthash(*(Rune*)data);
nt = cp_numtype(cp);
u.d = conv_to_double(data, nt);
return doublehash(u.i64);
--- a/src/io.c
+++ b/src/io.c
@@ -196,11 +196,9 @@
{
argcount(nargs, 2);
sl_ios *s = toio(args[0]);
- sl_cprim *cp = ptr(args[1]);
- if(!iscprim(args[1]) || cp_class(cp) != sl_runetype)
+ if(!isrune(args[1]))
type_error("rune", args[1]);
- Rune r = *(Rune*)cp_data(cp);
- return fixnum(ios_putrune(s, r));
+ return fixnum(ios_putrune(s, torune(args[1])));
}
BUILTIN("io-skip", io_skip)
@@ -325,16 +323,15 @@
argcount(nargs, 2);
sl_ios *s = toio(args[0]);
sl_v v = args[1];
- sl_cprim *cp = ptr(v);
- if(iscprim(args[1]) && cp_class(cp) == sl_runetype){
+ if(isrune(v)){
if(nargs > 2)
lerrorf(sl_errarg, "offset argument not supported for characters");
- Rune r = *(Rune*)cp_data(ptr(args[1]));
- return fixnum(ios_putrune(s, r));
+ return fixnum(ios_putrune(s, torune(v)));
}
u8int *data;
usize sz, offs = 0;
- to_sized_ptr(v, &data, &sz);
+ uintptr u;
+ to_sized_ptr(v, &data, &sz, &u);
usize nb = sz;
if(nargs > 2){
get_start_count_args(args+1, nargs-1, sz, &offs, &nb);
@@ -346,10 +343,10 @@
static u8int
get_delim_arg(sl_v arg)
{
- usize uldelim = tosize(arg);
+ usize uldelim = isrune(arg) ? torune(arg) : tosize(arg);
if(uldelim > 0x7f){
// runes > 0x7f, or anything else > 0xff, are out of range
- if((iscprim(arg) && cp_class(ptr(arg)) == sl_runetype) || uldelim > 0xff)
+ if(isrune(arg) || uldelim > 0xff)
lerrorf(sl_errarg, "delimiter out of range");
}
return (u8int)uldelim;
--- a/src/plan9/lsd.c
+++ b/src/plan9/lsd.c
@@ -242,8 +242,8 @@
argcount(nargs, 3);
for(a = args; a < args+3; a++)
- if(sl_unlikely(!sl_isnum(*a)))
- type_error("num", *a);
+ if(sl_unlikely(!sl_isnum(*a)))
+ type_error("num", *a);
pc = tosize(args[0]);
sp = tosize(args[1]);
@@ -277,8 +277,8 @@
if(sl_unlikely(!sl_isstr(args[0]) && !sl_isnum(args[0])))
type_error("str|num", args[0]);
- if(isfixnum(args[0])){
- pid = numval(args[0]);
+ if(sl_isnum(args[0])){
+ pid = tosize(args[0]);
snprint(aout, sizeof(aout), "/proc/%d/text", pid);
}else{
len = cv_len(ptr(args[0]));
--- a/src/print.c
+++ b/src/print.c
@@ -187,7 +187,7 @@
if(sl_isstr(v))
return cv_len(ptr(v)) < SMALL_STR_LEN;
return (
- isfixnum(v) || isbuiltin(v) || iscprim(v) ||
+ isfixnum(v) || isunboxed(v) || isbuiltin(v) || iscprim(v) ||
v == sl_t || v == sl_nil || v == sl_eof || v == sl_void
);
}
@@ -233,7 +233,7 @@
const char *s = sym_name(v);
return u8_strwidth(s, strlen(s));
}
- if(iscprim(v) && ptr(v) != nil && cp_class(ptr(v)) == sl_runetype)
+ if(isrune(v))
return 4;
return -1;
}
@@ -385,7 +385,9 @@
}
}
+static void unboxed_print(sl_ios *f, sl_v v);
static void cvalue_print(sl_ios *f, sl_v v);
+static void rune_print(sl_ios *f, Rune r);
static bool
print_circle_prefix(sl_ios *f, sl_v v)
@@ -427,6 +429,9 @@
lerrorf(sl_errio, "write failed");
sl.hpos += n;
break;
+ case TAG_UNBOXED:
+ unboxed_print(f, v);
+ break;
case TAG_SYM:
name = sym_name(v);
if(sl.print_princ)
@@ -657,6 +662,45 @@
}
}
+static void
+rune_print(sl_ios *f, Rune r)
+{
+ char seq[UTFmax+1];
+ int n, nb = runetochar(seq, &r);
+ seq[nb] = '\0';
+ if(sl.print_princ){
+ outsn(f, seq, nb);
+ }else{
+ outsc(f, "#\\");
+ switch(r){
+ case 0x00: outsc(f, "nul"); break;
+ case 0x07: outsc(f, "alarm"); break;
+ case 0x08: outsc(f, "backspace"); break;
+ case 0x09: outsc(f, "tab"); break;
+ case 0x0a: outsc(f, "newline"); break;
+ case 0x0b: outsc(f, "vtab"); break;
+ case 0x0c: outsc(f, "page"); break;
+ case 0x0d: outsc(f, "return"); break;
+ case 0x1b: outsc(f, "esc"); break;
+ case ' ': outsc(f, "space"); break;
+ case 0x7f: outsc(f, "delete"); break;
+ default:
+ if(sl_iswprint(r))
+ outs(f, seq);
+ else{
+ n = ios_printf(f, "x%04"PRIx32, r);
+ if(n < 1)
+ goto err;
+ sl.hpos += n;
+ }
+ break;
+ }
+ }
+ return;
+err:
+ lerrorf(sl_errio, "write failed");
+}
+
// 'weak' means we don't need to accurately reproduce the type, so
// for example #s32(0) can be printed as just 0. this is used
// printing in a context where a type is already implied, e.g. inside
@@ -679,38 +723,7 @@
sl.hpos += n;
}
}else if(type == sl_runesym){
- Rune r = *(Rune*)data;
- char seq[UTFmax+1];
- int nb = runetochar(seq, &r);
- seq[nb] = '\0';
- if(sl.print_princ){
- outsn(f, seq, nb);
- }else{
- outsc(f, "#\\");
- switch(r){
- case 0x00: outsc(f, "nul"); break;
- case 0x07: outsc(f, "alarm"); break;
- case 0x08: outsc(f, "backspace"); break;
- case 0x09: outsc(f, "tab"); break;
- case 0x0a: outsc(f, "newline"); break;
- case 0x0b: outsc(f, "vtab"); break;
- case 0x0c: outsc(f, "page"); break;
- case 0x0d: outsc(f, "return"); break;
- case 0x1b: outsc(f, "esc"); break;
- case ' ': outsc(f, "space"); break;
- case 0x7f: outsc(f, "delete"); break;
- default:
- if(sl_iswprint(r))
- outs(f, seq);
- else{
- n = ios_printf(f, "x%04"PRIx32, r);
- if(n < 1)
- goto err;
- sl.hpos += n;
- }
- break;
- }
- }
+ rune_print(f, *(Rune*)data);
}else if(type == sl_floatsym || type == sl_doublesym){
char buf[64];
double d;
@@ -849,6 +862,26 @@
}
static void
+unboxed_print(sl_ios *f, sl_v v)
+{
+ uintptr u;
+
+ if(isubnumu(v))
+ u = ubnumuval(v);
+ else if(isubnums(v))
+ u = ubnumsval(v);
+ else if(isrune(v)){
+ rune_print(f, torune(v));
+ return;
+ }else
+ abort();
+ int numtype = ubnumtype(v);
+ sl_v typesym = unboxedtypesyms[numtype];
+ sl_type *type = unboxedtypes[numtype];
+ cvalue_printdata(f, &u, type->size, typesym, 0);
+}
+
+static void
cvalue_print(sl_ios *f, sl_v v)
{
sl_cv *cv = ptr(v);
@@ -877,10 +910,13 @@
static void
set_print_width(void)
{
- sl_v pw = sym_value(sl_printwidthsym);
- if(!isfixnum(pw))
- return;
- sl.scr_width = numval(pw);
+ sl_v v = sym_value(sl_printwidthsym);
+ if(isfixnum(v))
+ sl.scr_width = numval(v);
+ else if(isubnumu(v))
+ sl.scr_width = ubnumuval(v);
+ else if(isubnums(v))
+ sl.scr_width = ubnumsval(v);
}
void
@@ -891,9 +927,9 @@
set_print_width();
sl.print_princ = sym_value(sl_printreadablysym) == sl_nil;
sl_v pl = sym_value(sl_printlengthsym);
- sl.print_length = isfixnum(pl) ? numval(pl) : -1;
+ sl.print_length = sl_isnum(pl) ? numtofx(pl) : -1;
pl = sym_value(sl_printlevelsym);
- sl.print_level = isfixnum(pl) ? numval(pl) : -1;
+ sl.print_level = sl_isnum(pl) ? numtofx(pl) : -1;
sl.p_level = 0;
sl.printlabel = 0;
--- a/src/sl.c
+++ b/src/sl.c
@@ -385,7 +385,7 @@
{
sl_v a, d, nc, first, *pcdr;
- if(isfixnum(v))
+ if(isfixnum(v) || isunboxed(v))
return v;
uintptr t = tag(v);
@@ -692,12 +692,16 @@
bool
sl_isnum(sl_v v)
{
- if(isfixnum(v) || ismp(v))
+ if(isfixnum(v))
return true;
+ if(isubnum(v))
+ return true;
if(iscprim(v)){
sl_cprim *c = ptr(v);
- return c->type != sl_runetype && valid_numtype(c->type->numtype);
+ return valid_numtype(c->type->numtype);
}
+ if(ismp(v))
+ return true;
return false;
}
--- a/src/sl.h
+++ b/src/sl.h
@@ -15,11 +15,14 @@
TAG_CPRIM,
TAG_FN,
TAG_VEC,
- TAG_EXT,
+ TAG_UNBOXED,
TAG_CVALUE,
TAG_SYM,
TAG_CONS,
+ TAG_BITS = 3,
+ TAG_EXT_BITS = 8,
+
/* those were set to 7 and 3 strategically on purpose */
TAG_NONLEAF_MASK = TAG_CONS & TAG_VEC,
};
@@ -34,9 +37,9 @@
T_S16, T_U16,
T_S32, T_U32,
T_S64, T_U64,
- T_MP,
- T_FLOAT,
- T_DOUBLE,
+ T_UNBOXED_NUM,
+ T_MP = T_UNBOXED_NUM,
+ T_FLOAT, T_DOUBLE,
}sl_numtype;
typedef uintptr sl_v;
@@ -43,13 +46,15 @@
#if defined(BITS64)
typedef s64int sl_fx;
-#define FIXNUM_BITS 61
+#define FIXNUM_BITS (64-TAG_BITS)
+#define UNBOXED_BITS (64-TAG_EXT_BITS)
#define TOP_BIT (1ULL<<63)
#define T_FIXNUM T_S64
#define PRIdFIXNUM PRId64
#else
typedef s32int sl_fx;
-#define FIXNUM_BITS 29
+#define FIXNUM_BITS (32-TAG_BITS)
+#define UNBOXED_BITS (32-TAG_EXT_BITS)
#define TOP_BIT (1U<<31)
#define T_FIXNUM T_S32
#define PRIdFIXNUM PRId32
@@ -100,12 +105,15 @@
#define valid_numtype(v) ((v) <= T_DOUBLE)
#define UNBOUND ((sl_v)1) // an invalid value
#define tag(x) ((x) & 7)
+#define tagext(x) ((x) & 0xff)
#define ptr(x) ((void*)((uintptr)(x) & (~(uintptr)7)))
#define tagptr(p, t) ((sl_v)(p) | (t))
-#define fixnum(x) ((sl_v)(x)<<3)
-#define numval(x) ((sl_fx)(x)>>3)
-#define uintval(x) (((unsigned int)(x))>>3)
-#define builtin(n) tagptr(((sl_v)n<<3), TAG_FN)
+#define fixnum(x) ((sl_v)(x)<<TAG_BITS)
+#define numval(x) ((sl_fx)(x)>>TAG_BITS)
+#define ubnumsval(x) ((intptr)(x)>>(TAG_BITS+1+4))
+#define ubnumuval(x) ((uintptr)(x)>>(TAG_BITS+1+4))
+#define uintval(x) (((unsigned int)(x))>>TAG_BITS)
+#define builtin(n) tagptr(((sl_v)n<<TAG_BITS), TAG_FN)
#define iscons(x) (tag(x) == TAG_CONS)
#define issym(x) (tag(x) == TAG_SYM)
#define isfixnum(x) (tag(x) == TAG_FIXNUM)
@@ -113,9 +121,27 @@
#define isvec(x) (tag(x) == TAG_VEC)
#define iscvalue(x) (tag(x) == TAG_CVALUE)
#define iscprim(x) (tag(x) == TAG_CPRIM)
+#define isunboxed(x) (tag(x) == TAG_UNBOXED)
// doesn't lead to other values
#define leafp(a) (((a)&TAG_NONLEAF_MASK) != TAG_NONLEAF_MASK)
+/* UNBOXED
+ * integers: ...|xxxxxxxx|xxxxxxxx|xxxxxxxx|tttt0100|
+ * runes: ...|xxxxxxxx|xxxxxxxx|xxxxxxxx|11111100|
+ */
+#define TAG_UBNUM_SHIFT (TAG_BITS+1)
+#define isubnum(x) ((tagext(x) & ((1<<TAG_UBNUM_SHIFT)-1)) == (0<<TAG_BITS | TAG_UNBOXED))
+#define isubnums(x) ((tagext(x) & ((2<<TAG_UBNUM_SHIFT)-1)) == (0<<TAG_BITS | TAG_UNBOXED))
+#define isubnumu(x) ((tagext(x) & ((2<<TAG_UBNUM_SHIFT)-1)) == (2<<TAG_BITS | TAG_UNBOXED))
+#define ubnumtype(x) ((tagext(x)>>TAG_UBNUM_SHIFT) & 0xf)
+#define numtofx(v) (sl_fx)tooffset(v)
+extern sl_type *unboxedtypes[T_UNBOXED_NUM];
+extern sl_v unboxedtypesyms[T_UNBOXED_NUM];
+
+#define mk_rune(r) ((r)<<TAG_EXT_BITS | 0xfc)
+#define isrune(v) (((v) & 0xff) == 0xfc)
+#define torune(v) ((v)>>8)
+
// allocate n consecutive conses
#define cons_reserve(n) tagptr(alloc_words((n)*2), TAG_CONS)
#define cons_index(c) (((sl_cons*)ptr(c))-((sl_cons*)slg.fromspace))
@@ -130,8 +156,8 @@
*(sl_v*)ptr(v) = (sl_v)(to) | FWD_BIT; \
}while(0)
-#define vec_size(v) (((usize*)ptr(v))[0]>>3)
-#define vec_setsize(v, n) (((usize*)ptr(v))[0] = ((n)<<3))
+#define vec_size(v) (((usize*)ptr(v))[0]>>TAG_BITS)
+#define vec_setsize(v, n) (((usize*)ptr(v))[0] = ((n)<<TAG_BITS))
#define vec_elt(v, i) (((sl_v*)ptr(v))[1+(i)])
#define vec_grow_amt(x) ((x)<8 ? 5 : 6*((x)>>3))
// functions ending in _ are unsafe, faster versions
@@ -157,7 +183,7 @@
#define sym_to_numtype(s) (((sl_sym*)ptr(s))->numtype)
#define ismanaged(v) ((((u8int*)ptr(v)) >= slg.fromspace) && (((u8int*)ptr(v)) < slg.fromspace+slg.heapsize))
#define isgensym(x) (issym(x) && ismanaged(x))
-#define isfn(x) (tag(x) == TAG_FN && (x) > (N_BUILTINS<<3))
+#define isfn(x) (tag(x) == TAG_FN && (x) > (N_BUILTINS<<TAG_BITS))
#define iscbuiltin(x) (iscvalue(x) && cv_class(ptr(x)) == sl_builtintype)
// utility for iterating over all arguments in a builtin
// i=index, i0=start index, arg = var for each arg, args = arg array
@@ -279,7 +305,7 @@
void (*relocate)(sl_v oldv, sl_v newv);
void (*finalize)(sl_v self);
void (*print_traverse)(sl_v self);
-} sl_cvtable;
+}sl_cvtable;
typedef void (*cvinitfunc_t)(sl_type*, sl_v, void*);
--- a/src/sl_arith_any.h
+++ b/src/sl_arith_any.h
@@ -20,7 +20,15 @@
if(isfixnum(arg))
x = numval(arg);
else{
- if(iscprim(arg)){
+ if(isubnumu(arg)){
+ u64 = ubnumuval(arg);
+ a = &u64;
+ pt = ubnumtype(arg);
+ }else if(isubnums(arg)){
+ u64 = ubnumsval(arg);
+ a = &u64;
+ pt = ubnumtype(arg);
+ }else if(iscprim(arg)){
cp = ptr(arg);
a = cp_data(cp);
pt = cp_numtype(cp);
--- a/src/str.c
+++ b/src/str.c
@@ -44,12 +44,9 @@
BUILTIN("str-width", str_width)
{
argcount(nargs, 1);
- if(iscprim(args[0])){
- sl_cprim *cp = ptr(args[0]);
- if(cp_class(cp) == sl_runetype){
- int w = sl_wcwidth(*(Rune*)cp_data(cp));
- return w < 0 ? sl_nil : fixnum(w);
- }
+ if(isrune(args[0])){
+ int w = sl_wcwidth(torune(args[0]));
+ return w < 0 ? sl_nil : fixnum(w);
}
if(!sl_isstr(args[0]))
type_error("str", args[0]);
@@ -200,31 +197,31 @@
return mk_rune(r);
}
+sl_purefn
BUILTIN("rune-upcase", rune_upcase)
{
argcount(nargs, 1);
- sl_cprim *cp = ptr(args[0]);
- if(!iscprim(args[0]) || cp_class(cp) != sl_runetype)
+ if(!isrune(args[0]))
type_error("rune", args[0]);
- return mk_rune(toupperrune(*(Rune*)cp_data(cp)));
+ return mk_rune(toupperrune(torune(args[0])));
}
+sl_purefn
BUILTIN("rune-downcase", rune_downcase)
{
argcount(nargs, 1);
- sl_cprim *cp = ptr(args[0]);
- if(!iscprim(args[0]) || cp_class(cp) != sl_runetype)
+ if(!isrune(args[0]))
type_error("rune", args[0]);
- return mk_rune(tolowerrune(*(Rune*)cp_data(cp)));
+ return mk_rune(tolowerrune(torune(args[0])));
}
+sl_purefn
BUILTIN("rune-titlecase", rune_titlecase)
{
argcount(nargs, 1);
- sl_cprim *cp = ptr(args[0]);
- if(!iscprim(args[0]) || cp_class(cp) != sl_runetype)
+ if(!isrune(args[0]))
type_error("rune", args[0]);
- return mk_rune(totitlerune(*(Rune*)cp_data(cp)));
+ return mk_rune(totitlerune(torune(args[0])));
}
sl_purefn
@@ -231,10 +228,9 @@
BUILTIN("rune-alphabetic?", rune_alphabeticp)
{
argcount(nargs, 1);
- sl_cprim *cp = ptr(args[0]);
- if(!iscprim(args[0]) || cp_class(cp) != sl_runetype)
+ if(!isrune(args[0]))
type_error("rune", args[0]);
- return isalpharune(*(Rune*)cp_data(cp)) ? sl_t : sl_nil;
+ return isalpharune(torune(args[0])) ? sl_t : sl_nil;
}
sl_purefn
@@ -241,10 +237,9 @@
BUILTIN("rune-lower-case?", rune_lower_casep)
{
argcount(nargs, 1);
- sl_cprim *cp = ptr(args[0]);
- if(!iscprim(args[0]) || cp_class(cp) != sl_runetype)
+ if(!isrune(args[0]))
type_error("rune", args[0]);
- return islowerrune(*(Rune*)cp_data(cp)) ? sl_t : sl_nil;
+ return islowerrune(torune(args[0])) ? sl_t : sl_nil;
}
sl_purefn
@@ -251,10 +246,9 @@
BUILTIN("rune-upper-case?", rune_upper_casep)
{
argcount(nargs, 1);
- sl_cprim *cp = ptr(args[0]);
- if(!iscprim(args[0]) || cp_class(cp) != sl_runetype)
+ if(!isrune(args[0]))
type_error("rune", args[0]);
- return isupperrune(*(Rune*)cp_data(cp)) ? sl_t : sl_nil;
+ return isupperrune(torune(args[0])) ? sl_t : sl_nil;
}
sl_purefn
@@ -261,10 +255,9 @@
BUILTIN("rune-title-case?", rune_title_casep)
{
argcount(nargs, 1);
- sl_cprim *cp = ptr(args[0]);
- if(!iscprim(args[0]) || cp_class(cp) != sl_runetype)
+ if(!isrune(args[0]))
type_error("rune", args[0]);
- return istitlerune(*(Rune*)cp_data(cp)) ? sl_t : sl_nil;
+ return istitlerune(torune(args[0])) ? sl_t : sl_nil;
}
sl_purefn
@@ -271,10 +264,9 @@
BUILTIN("rune-numeric?", rune_numericp)
{
argcount(nargs, 1);
- sl_cprim *cp = ptr(args[0]);
- if(!iscprim(args[0]) || cp_class(cp) != sl_runetype)
+ if(!isrune(args[0]))
type_error("rune", args[0]);
- return isdigitrune(*(Rune*)cp_data(cp)) ? sl_t : sl_nil;
+ return isdigitrune(torune(args[0])) ? sl_t : sl_nil;
}
sl_purefn
@@ -281,10 +273,9 @@
BUILTIN("rune-whitespace?", rune_whitespacep)
{
argcount(nargs, 1);
- sl_cprim *cp = ptr(args[0]);
- if(!iscprim(args[0]) || cp_class(cp) != sl_runetype)
+ if(!isrune(args[0]))
type_error("rune", args[0]);
- return isspacerune(*(Rune*)cp_data(cp)) ? sl_t : sl_nil;
+ return isspacerune(torune(args[0])) ? sl_t : sl_nil;
}
BUILTIN("str-find", str_find)
@@ -304,9 +295,8 @@
usize ndbytes;
sl_v v = args[1];
char rbuf[UTFmax+1];
- sl_cprim *cp = ptr(v);
- if(iscprim(v) && cp_class(cp) == sl_runetype){
- Rune r = *(Rune*)cp_data(cp);
+ if(isrune(v)){
+ Rune r = torune(v);
ndbytes = runetochar(rbuf, &r);
nd = rbuf;
nd[ndbytes] = 0;
@@ -358,6 +348,10 @@
radix = get_radix_arg(args[1]);
if(isfixnum(n))
num = numval(n);
+ else if(isubnumu(n))
+ num = ubnumuval(n);
+ else if(isubnums(n))
+ num = ubnumsval(n);
else if(iscprim(n)){
void *data = ptr(n);
if(cp_numtype(data) < T_FLOAT)
--- a/src/system.sl
+++ b/src/system.sl
@@ -139,11 +139,11 @@
contains the rest of the terms."
:doc-group doc
(def (doc? kw)
- (and (> (length kw) 5)
- (= (aref kw 1) #\d)
- (= (aref kw 2) #\o)
- (= (aref kw 3) #\c)
- (= (aref kw 4) #\-)))
+ (and (> (str-length kw) 5)
+ (eq? (str-rune kw 1) #\d)
+ (eq? (str-rune kw 2) #\o)
+ (eq? (str-rune kw 3) #\c)
+ (eq? (str-rune kw 4) #\-)))
(let {[hd (car body)]
[tl (cdr body)]}
(cond [(and (str? hd) (not doc) tl)
@@ -162,8 +162,8 @@
(let* {[lines (str-split doc "\n")]
[hd (car lines)]
[tl (cdr lines)]
- [snd (any (λ (s) (and (> (length s) 0)
- (= (aref s 0) #\space)
+ [snd (any (λ (s) (and (> (str-length s) 0)
+ (eq? (str-rune s 0) #\space)
s))
tl)]
[indent (and snd
--- a/src/types.c
+++ b/src/types.c
@@ -33,7 +33,7 @@
ft->numtype = NONNUMERIC;
if(issym(t)){
ft->numtype = sym_to_numtype(t);
- assert(valid_numtype(ft->numtype));
+ assert(valid_numtype(ft->numtype) || t == sl_runesym);
((sl_sym*)ptr(t))->type = ft;
}
ft->size = sz;
--- a/src/vm.h
+++ b/src/vm.h
@@ -423,13 +423,13 @@
LABEL(apply_aref):;
sl_v v = sp[-n];
for(int i = n-1; i > 0; i--){
+ sl_v e = sp[-i];
+ usize isz = tosize(e);
if(isarr(v)){
sp[-i-1] = v;
v = cvalue_arr_aref(sp-i-1);
continue;
}
- sl_v e = sp[-i];
- usize isz = tosize(e);
if(isvec(v)){
if(sl_unlikely(isz >= vec_size(v))){
sl.sp = sp;
--- a/test/unittest.sl
+++ b/test/unittest.sl
@@ -83,7 +83,7 @@
(assert (> 9223372036854775808 9223372036854775807))
-(assert (fixnum? (- (aref "0" 0) #\0)))
+(assert-fail (fixnum? (- (str-rune "0" 0) #\0)))
(assert (= (ash #bignum(1) -9999) 0))
@@ -215,6 +215,7 @@
; long argument lists
(assert (= (apply + (iota 100000)) 4999950000))
+
(def ones (map (λ (x) 1) (iota 80000)))
(assert (= (eval `(if (< 2 1)
(+ ,@ones)
@@ -440,8 +441,8 @@
(assert (equal? 7 (aref a 1 2)))
(assert (equal? 5 (aref a 1 (1+ 0) 1)))
(assert-fail (aref a 1 1 3) bounds-error)
-(assert (equal? (fixnum #\l) (aref #("hello") 0 2)))
-(assert (equal? (fixnum #\o) (aref #("hello") 0 (1+ 3))))
+(assert (equal? #\l (rune (aref #("hello") 0 2))))
+(assert (equal? #\o (rune (aref #("hello") 0 (1+ 3)))))
(assert-fail (aref #("hello") 0 5))
(assert-fail (aref #("hello") 1 0))
(assert-fail (aref '(NIL) 0 0))
--- a/tools/bootstrap.sh
+++ b/tools/bootstrap.sh
@@ -1,4 +1,5 @@
#!/bin/sh
+set -x
test -e
P="$(pwd)"
F="$P/build/sl"
@@ -5,10 +6,10 @@
test -x $F || { meson setup -Dbuildtype=debug build . && ninja -C build || exit 1; }
test -x $F || { echo no $F found; exit 1; }
cd src && \
-$F ../tools/gen.sl && \
+$WRAPPER $F ../tools/gen.sl && \
cp ../boot/sl.boot ../boot/sl.boot.bak && \
-$F ../tools/mkboot0.sl builtins.sl instructions.sl system.sl compiler.sl > ../boot/sl.boot && \
+$WRAPPER $F ../tools/mkboot0.sl builtins.sl instructions.sl system.sl compiler.sl > ../boot/sl.boot && \
ninja -C ../build && \
cd ../boot && \
-$F ../tools/mkboot1.sl && \
+$WRAPPER $F -S 8m ../tools/mkboot1.sl && \
ninja -C ../build || { cp "$P/boot/sl.boot.bak" "$P/boot/sl.boot"; exit 1; }
--- a/tools/gen.sl
+++ b/tools/gen.sl
@@ -6,12 +6,12 @@
(def (name->cname name)
(let {[cname (buffer)]}
- (for 0 (1- (length name))
- (λ (i) (let {[r (rune (aref name i))]}
+ (for 0 (1- (str-length name))
+ (λ (i) (let {[r (str-rune name i)]}
(io-write cname
(cond [(rune-alphanumeric? r) (rune-upcase r)]
- [(= r #\?) #\P]
- [(= r #\_) #\_]
+ [(eq? r #\?) #\P]
+ [(eq? r #\_) #\_]
[else ""])))))
(io->str cname)))
--
⑨