ref: 4725ee7c0550674bb6e4500bd0c3a962c9784945
parent: dd8b10efc2d43bc81c75bb44ab5261a331a49c53
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Fri Apr 18 12:52:28 EDT 2025
make type errors more descriptive
--- a/boot/sl.boot
+++ b/boot/sl.boot
@@ -134,7 +134,7 @@
8(53) seta #u8(15) seta.l #u8(73) brnn #u8(26) loadnil #u8(65) loadg #u8(7) loada #u8(8) tcall #u8(6))
S #fn("z1700215286380861}2:7223062:" #(getprop constructor error "no default constructor for struct: ") S)
__finish #fn("n120Z3>021220>17062:q:" #(*exit-hooks* #fn(for-each)
-w4^147025d;350426;J50427w8429w:4qw;47<w=47>w?47@wA:" #(*os-name*
+w4^147025d;350426;J50427w8429w:4qw;47<w=47>w?47@wA:" #(*os-name*
#fn("n0702161:" #(princ "#;> ")) *prompt* "dos" "\\" "/" *directory-separator* "\n" *linefeed*
*exit-hooks* *stdout* *io-out* *stdin* *io-in* *stderr* *io-err*) __init_globals)
__rcscript #fn("n0708421c360q@T08422c37023@G08424c3=07526514q@4027^184;3904288451708622c37029@402:^185;3=042;857<865387;3D042=8751;39047>8761:" #(*os-name*
@@ -187,18 +187,19 @@
3q07401q895440r40r4GKMp4750183=530r40r4G8:UMp47608237027@40288:63:89[;3904798951892:Cf07089152J\\0212:517:d3P07;83r2523E07401q83T5447602:62:89B3N089<2<CF07=83513=07>01828364:8:360q@F07401q895440r40r4GKMp4750183=530r40r4G8;UMp48:360q@=00r40r4Gr/Mp48:3C07?018283898:8;67:760823702@@402A8;63:" #(in-env?
#fn(top-level-value) length> 255 compile-in compile-arglist emit tcall.l call.l
builtin->instruction cadr length= λ inlineable? compile-let compile-builtin-call tcall call) compile-app)
-8:360q@=00r40r4Gr/Mp48:3C07?018283898:8;67:760823702@@402A8;63:" #(in-env?
- #fn(top-level-value) length> 255 compile-in compile-arglist emit tcall.l call.l
+8:360q@=00r40r4Gr/Mp48:3C07?018283898:8;67:760823702@@402A8;63:" #(in-env?
+ #fn(top-level-value) length> 255 compile-in compile-arglist emit tcall.l call.l
+ builtin->instruction cadr length= λ inlineable? compile-let compile-builtin-call tcall call) compile-app)
in->instruction cadr length= λ inlineable? compile-let compile-builtin-call tcall call) compile-app)
compile-arglist #fn("n3202101>282524228261:" #(#fn(for-each)
#fn("n170AFq0544Ar4Ar4GKMp:" #(compile-in))
- #(compile-in
- void emit pop compile-begin) compile-begin)
+ile-builtin-call #fn("n7I202186850>3?;514227385q538<3I07483=8<52J=075858<52@30q4858=26CL086El23:07702862:770858663:8=29C708;60:8=2:C708;60:8=2;C]086El23:07702<62:86r2l23:07702=62:770858663:8=2>Cm086El23:07585K62:86Kl23:07702?62:86r2l23:07702@62:770858663:8=2ACL086El23:07702B62:770858663:8=2CCL086El23:07585K62:770858663:8=2DCN086El23<07702E2F63:770858663:8=2GCX086r2L23;07585r262:770823702H@402G8663:8=2ICb086r2l23:07702J62:r286L23?07708586r3~63:7585r262:7708562:" #(#0#
+ #fn("n0AEl239070FK62:7192FA63:" #(argc-error emit) num-compare)
63:8=29C708;60:8=2:C708;60:8=2;C]086El23:07702<62:86r2l23:07702=62:770858663:8=2>Cm086El23:07585K62:86Kl23:07702?62:86r2l23:07702@62:770858663:8=2ACL086El23:07702B62:770858663:8=2CCL086El23:07585K62:770858663:8=2DCN086El23<07702E2F63:770858663:8=2GCX086r2L23;07585r262:770823702H@402G8663:8=2ICb086r2l23:07702J62:r286L23?07708586r3~63:7585r262:7708562:" #(#0#
#fn("n0AEl239070FK62:7192FA63:" #(argc-error emit) num-compare)
#fn(get) arg-counts length= argc-error list emit loadnil < = + load0 add2 - neg sub2 * load1 /
vec loadv #() apply tapply aref aref2) compile-builtin-call)
-) arg-counts length= argc-error list emit loadnil < = + load0 add2 - neg sub2 * load1 /
+neg sub2 * load1 /
8@55@30q48<3?02M8:2N8<53@408:8<3=02M8:8<52@408:7O08D7P7Q1518E52537R878F<52487r42;8E51r4Mp47S878FD7Q1515447?872T5247U2V7W87EG517X87518>5387r3G62:" #(#1=#fn("z0I:" #() void)
#fn("n10<0=863J0702185>18652;J904A<8661:q:" #(any #fn("n1A0Q;3404A:")) any-duplicates)
make-code-emitter lastcdr lambda:vars filter cons? #fn(map) caddr cddr λ #fn(length) keyword-arg?
@@ -205,8 +206,8 @@
licates)
make-code-emitter lastcdr lambda:vars filter cons? #fn(map) caddr cddr λ #fn(length) keyword-arg?
error "compile error: duplicate argument: " emit optargs bcode:indexfor make-perfect-hash-table
-t-optional-arg-inits #fn(append)
- (NIL NIL NIL NIL) extend-env complex-bindings lambda:body box-vars compile-in ret values #fn(fn)
+onal-arg-inits #fn(append)
+ (NIL NIL NIL NIL) extend-env complex-bindings lambda:body box-vars compile-in ret values #fn(fn)
compile-if #fn("n420502050205083T718351728351B3;0738351@30q8;DC=07401828<64:8;J=07401828=64:7401q8;89554750268953475027885347401828<544823<07502852@;0750298:53475027895347401828=544750278:63:" #(#fn(gensym)
caddr cdddr cadddr compile-in emit brn label ret jmp) compile-if)
compile-in #fn("\x8740005000W4000J60q?4483R3<0700183D64:83H3\x97083EC:07102262:83KC:07102362:83DC:07102462:83J:07102562:7683513:07102762:7883513<0710298363:7102:8363:83<2;C<07<0183=63:83<RS;JD0483<Z;J;047=83<1523=07>01828364:83<892?CS07@83T513>07A018283T64:7102:83T63:892BC=07C01828364:892DC>07E018283=64:892FC;07G018363:892HCD07I2J183>22K01>262:892LC@07M018283=8465:892NC>07O018283=64:892PCE07Q0183T2D7R8351P64:892SCS07A01D83=B38083T@607T505447102U62:892VC\x91083T7W7R8351518;<<8;=8:R360q@807X2Y5148<3Y07Z8:8<8=<B;3F048=<<2HQ;3:047[8=<5153@30q47\\018:8=<64:892]Cp07A01q2Hq83Te35447^7_835151360q@807X2`5147A01q7_83515447102]62:7>01828364:" #(compile-sym
@@ -263,7 +264,7 @@
n eq? brne nreconc) emit)
emit-optional-arg-inits #fn("n582B3\xa60205071022845347382513<07102452@30q4710258953476077178838452q53q7982515447102:845347102;5247102<895347=0182=8384KM65:q:" #(#fn(gensym)
emit bounda cddar dup brnn compile-in extend-env list-head cadar seta pop label
--arg-inits) emit-optional-arg-inits)
+-arg-inits) emit-optional-arg-inits)
452255025502650qqEI8>87L23\xbc14868>G?<48<27CP02889868>KMG298;515348>r2M?>@\x8b12:8;2;7<883k08<8C2=C702>@X08C2?C702@@L08C2AC702B@@08C2CC702D@408<^1@408<525248>KM?>48>87L2;3804868>G?=42E8<2F523`0288:298;518=5342:8;883707G@407HE515248>KM?>@\xeb08<2ICH02:8;2J8=515248>KM?>@\xce08=X3\xc708<2E8?2K523H02:8;2J8=515248>KM?>@\x9f02E8?2L523\x8102:8;2J8=515248>KM?>42:8;2J868>G515248>KM?>48<2MCK02:8;2J868>G515248>KM?>@30q@E02:8;2N8=515248>KM?>^1@30q@\x9f.42O2P8;8889>38:5242Q8;61:" #(reverse!
list->vec #fn(length) >= 65536 #fn(table) #fn(buffer) label #fn(put!)
#fn(sizeof) #fn(io-write) #fn(get) Instructions jmp jmp.l brne brne.l brnn brnn.l brn brn.l #fn(memq)
@@ -311,11 +312,10 @@
08708253;J50482:" #(#fn(get) *properties*) getprop)
help-print-header #fn("O200020004000W2000J60q?24W3000J7021?3413A02223830>2152@V07483514823@074750512652@70770514785047860:" #(#(:kind
0 NIL NIL :lpad 1 NIL NIL) "" #fn(for-each) #fn("n170A51471F0P5147260:" #(princ print newline))
-F0P5147260:" #(princ print newline))
- princ caddr " (group)" print newline) help-print-header)
- hex5 #fn("n170210r@52r52263:" #(str-lpad #fn(num->str) #\0) hex5) identity
- #fn("n10:" #() identity) in-env? #fn("n21B;3F042001<52;J:047101=62:" #(#fn(assq)
- in-env?) in-env?)
+F0P5147260:" #(princ print newline))
+ princ caddr " (group)" print newline) help-print-header)
+ hex5 #fn("n170210r@52r52263:" #(str-lpad #fn(num->str) #\0) hex5) identity
+ #fn("n10:" #() identity) in-env? #fn("n21B;3F042001<52;J:047101=62:" #(#fn(assq)
l #fn("n1205021850524228561:" #(#fn(buffer)
#fn(io-copy)
#fn(io->str)) io-readall)
@@ -390,12 +390,13 @@
top-level-value #fn(write)
#fn(io-write)
*linefeed* #fn(io-close)))
-61:" #(#fn(raise)))) make-system-image)
- map! #fn("n21I1B3B04101<51_41=?1@\x1d/4:" #() map!) map-int
- #fn("n2E1L2;3S040E51qPqb78786_4K7015121870>2|486:" #(1- #fn("n1A<F051qPN4AA<=_:")) map-int)
- max #fn("z113;070210163:0:" #(foldl #fn("n201L23401:0:")) max) member
- #fn("n21<0d3401:13:07001=62:q:" #(member) member) memv #fn("n21<0c3401:13:07001=62:q:" #(memv) memv)
- min #fn("z113;070210163:0:" #(foldl #fn("n201L23400:1:")) min) mod
+61:" #(#fn(raise)))) make-system-image)
+ map! #fn("n21I1B3B04101<51_41=?1@\x1d/4:" #() map!) map-int
+ #fn("n2E1L2;3S040E51qPqb78786_4K7015121870>2|486:" #(1- #fn("n1A<F051qPN4AA<=_:")) map-int)
+ max #fn("z113;070210163:0:" #(foldl #fn("n201L23401:0:")) max) member
+ #fn("n21<0d3401:13:07001=62:q:" #(member) member) memv #fn("n21<0c3401:13:07001=62:q:" #(memv) memv)
+ min #fn("z113;070210163:0:" #(foldl #fn("n201L23400:1:")) min) mod
+ #fn("n207001521i2~:" #(div) mod) mod0 #fn("n2001k1i2~:" #() mod0) negative?
ion #fn("n2I2021?65148601qe1qe164:" #(#0#
#fn("n48283PI1B3Z0401<513?0821<qPN=?2@<0831<qPN=?341=?1@\x05/47088<=88==62:" #(values) partition-)) partition)
positive? #fn("n1E0L2:" #() positive?) princ
--- a/src/builtins.c
+++ b/src/builtins.c
@@ -40,7 +40,7 @@
c = ptr(c->cdr);
pcdr = &c->cdr;
}else if(lst != sl_nil){
- bthrow(type_error("cons", lst));
+ bthrow(type_error(nil, "cons", lst));
}
}
*pcdr = lst;
@@ -118,7 +118,7 @@
}
if(a == sl_nil)
return fixnum(0);
- bthrow(type_error("sequence", a));
+ bthrow(type_error(nil, "sequence", a));
}
_Noreturn
@@ -288,7 +288,7 @@
sl_cv *p = ptr(v);
return fixnum(conv_to_s64(v, cv_data(p), cv_numtype(p)));
}
- bthrow(type_error("num", v));
+ bthrow(type_error(nil, "num", v));
}
BUILTIN("truncate", truncate)
@@ -320,7 +320,7 @@
return return_from_s64((s64int)d);
}
}
- bthrow(type_error("num", v));
+ bthrow(type_error(nil, "num", v));
}
BUILTIN("vec-alloc", vec_alloc)
@@ -365,7 +365,7 @@
sl_numtype nt = cv_numtype(cv);
return conv_to_double(a, cv_data(cv), nt);
}
- bthrow(type_error("num", a));
+ bthrow(type_error(nil, "num", a));
}
BUILTIN("time->str", time_str)
--- a/src/compiler.sl
+++ b/src/compiler.sl
@@ -9,6 +9,9 @@
(defmacro (bcode:sp b) `(aref ,b 4))
(defmacro (bcode:stack b n) `(aset! ,b 4 (+ (bcode:sp ,b) ,n)))
+(def (compile-error . rest)
+ (apply error (cons "compile error: " rest)))
+
;; get an index for a referenced value in a bytecode object
(def (bcode:indexfor b v)
(let ((const-to-idx (bcode:ctable b))
@@ -340,10 +343,9 @@
(length lst))
(def (argc-error head count)
- (error "compile error: " head " expects " count
- (if (= count 1)
- " argument."
- " arguments.")))
+ (compile-error head " expects " count (if (= count 1)
+ " argument."
+ " arguments.")))
(def builtin->instruction
(let ((b2i (table num? 'num? cons 'cons
@@ -511,7 +513,7 @@
(doc (car (car doc+value)))
(value (cdr doc+value)))
(unless (sym? name)
- (error "set!: name must be a symbol"))
+ (type-error "set!" 'symbol name "name"))
(when doc
(sym-set-doc name doc (and (cons? (car value))
(eq? (car (car value)) 'λ)
@@ -519,7 +521,7 @@
(compile-set! g env name (car value))))
(trycatch (compile-in g env NIL `(λ () ,(cadr x)))
(unless (1arg-lambda? (caddr x))
- (error "trycatch: second form must be a 1-argument lambda"))
+ (compile-error "trycatch: second form must be a 1-argument lambda"))
(compile-in g env NIL (caddr x))
(emit g 'trycatch))
(else (compile-app g env tail? x))))))
@@ -538,7 +540,7 @@
(cond ((or (not l) (sym? l)) T)
((and (cons? l) (sym? (car l)))
(if (or opt kw)
- (error "compile error: invalid argument list "
+ (compile-error "invalid argument list "
o ": optional arguments must come after required")
(check-formals (cdr l) o opt kw)))
((and (cons? l) (cons? (car l)))
@@ -546,21 +548,21 @@
(or (length= (car l) 2) ; default value
(and (length= (car l) 3) ; default value and "var-supplied"
(sym? (caddar l)))))
- (error "compile error: invalid optional argument " (car l)
+ (compile-error "invalid optional argument " (car l)
" in list " o))
(if (keyword? (caar l))
(check-formals (cdr l) o opt T)
(if kw
- (error "compile error: invalid argument list "
+ (compile-error "invalid argument list "
o ": keyword arguments must come last.")
(check-formals (cdr l) o T kw))))
((cons? l)
- (error "compile error: invalid formal argument " (car l)
+ (compile-error "invalid formal argument " (car l)
" in list " o))
(else
(if (eq? l o)
- (error "compile error: invalid argument list " o)
- (error "compile error: invalid formal argument " l
+ (compile-error "invalid argument list " o)
+ (compile-error "invalid formal argument " l
" in list " o)))))
(check-formals l l NIL NIL)
(map (λ (s) (if (cons? s) (keyword->sym (car s)) s))
@@ -589,7 +591,7 @@
(cddr x)
(if (sym? form)
#.void
- (error "compile error: invalid syntax " (print-to-str x))))))
+ (compile-error "invalid syntax " (print-to-str x))))))
(if (sym? form)
`(set! ,form ,(car body))
`(set! ,(car form)
@@ -721,7 +723,7 @@
(dupv (any-duplicates vars)))
(when dupv
- (error "compile error: duplicate argument: " dupv))
+ (compile-error "duplicate argument: " dupv))
;; emit argument checking prologue
(when opta
--- a/src/compress.c
+++ b/src/compress.c
@@ -14,7 +14,7 @@
argcount(nargs, 2);
if(!isarr(args[0]))
- bthrow(type_error("arr", args[0]));
+ bthrow(type_error("data", "arr", args[0]));
u8int *in;
usize insz;
uintptr u;
@@ -51,7 +51,7 @@
uintptr u;
to_sized_ptr(args[0], &in, &insz, &u);
if(!isarr(args[0]))
- bthrow(type_error("arr", args[0]));
+ bthrow(type_error("data", "arr", args[0]));
usize outsz;
u8int *out;
sl_v v;
--- a/src/cvalues.c
+++ b/src/cvalues.c
@@ -203,7 +203,7 @@
sl_fx v = ubnumval(a);
r = conv_to_u32(a, &v, ubnumtype(a));
}else
- cthrow(type_error("num", a), type);
+ cthrow(type_error(nil, "num", a), type);
*((Rune*)dest) = r;
}
@@ -221,7 +221,7 @@
}else if(iscvalue(a)){ \
n = (ctype)conv_to_##cnvt(a, cv_data(ptr(a)), cv_numtype(ptr(a))); \
}else \
- cthrow(type_error("num", a), type); \
+ cthrow(type_error(nil, "num", a), type); \
*((ctype*)dest) = n; \
}
@@ -351,7 +351,7 @@
void *p = cv_data(cv);
n = conv_to_bignum(a, p, cv_numtype(cv));
}else
- cthrow(type_error("num", a), type);
+ cthrow(type_error(nil, "num", a), type);
*((mpint**)dest) = n;
}
@@ -409,7 +409,7 @@
return conv_to_u64(n, cv_data(cv), cv_numtype(cv));
return conv_to_u32(n, cv_data(cv), cv_numtype(cv));
}
- cthrow(type_error("num", n), n);
+ cthrow(type_error(nil, "num", n), n);
}
soffset
@@ -425,7 +425,7 @@
return conv_to_s64(n, cv_data(cv), cv_numtype(cv));
return conv_to_s32(n, cv_data(cv), cv_numtype(cv));
}
- cthrow(type_error("num", n), n);
+ cthrow(type_error(nil, "num", n), n);
}
bool
@@ -508,7 +508,7 @@
}
if(cnt == 1)
cvalue_init(eltype, arg, dest);
- cthrow(type_error("sequence", arg), ft);
+ cthrow(type_error(nil, "sequence", arg), ft);
}
BUILTIN("arr", arr)
@@ -529,7 +529,7 @@
int i;
FOR_ARGS(i, 1, arg, args){
if(!sl_isnum(arg) && type->eltype != sl_runetype)
- bthrow(type_error("num", arg));
+ bthrow(type_error("element", "num", arg));
cvalue_init(type->eltype, arg, dest);
dest += elsize;
}
@@ -556,8 +556,8 @@
a = 2;
for(i = 0; i < cnt; i++){
sl_v arg = args[a];
- if(!sl_isnum(arg))
- bthrow(type_error("num", arg));
+ if(!sl_isnum(arg) && type->eltype != sl_runetype)
+ bthrow(type_error("element", "num", arg));
cvalue_init(type->eltype, arg, dest);
dest += elsize;
if((a = (a + 1) % nargs) < 2)
@@ -629,7 +629,7 @@
return;
}
}
- cthrow(type_error("plain-old-data", v), v);
+ cthrow(type_error(nil, "plain-old-data", v), v);
}
BUILTIN("sizeof", sizeof)
@@ -1021,7 +1021,7 @@
}
}
- cthrow(type_error("num", n), n);
+ cthrow(type_error(nil, "num", n), n);
}
bool
@@ -1071,12 +1071,12 @@
}
if(!num_to_ptr(a, &ai, &ta, &aptr)){
if(typeerr)
- cthrow(type_error("num", a), a);
+ cthrow(type_error("a", "num", a), a);
return 2;
}
if(!num_to_ptr(b, &bi, &tb, &bptr)){
if(typeerr)
- cthrow(type_error("num", b), a);
+ cthrow(type_error("b", "num", b), a);
return 2;
}
if(eq && eqnans && ((ta >= T_FLT) != (tb >= T_FLT)))
@@ -1105,14 +1105,14 @@
void *aptr, *bptr;
if(!num_to_ptr(a, &ai, &ta, &aptr))
- cthrow(type_error("num", a), a);
+ cthrow(type_error("a", "num", a), a);
if(!num_to_ptr(b, &bi, &tb, &bptr))
- cthrow(type_error("num", b), a);
+ cthrow(type_error("b", "num", b), a);
// a pointer is not exactly a number
if(ta == T_P32 || ta == T_P64)
- cthrow(type_error("num", a), a);
+ cthrow(type_error("a", "num", a), a);
if(tb == T_P32 || tb == T_P64)
- cthrow(type_error("num", b), a);
+ cthrow(type_error("b", "num", b), a);
da = conv_to_double(a, aptr, ta);
db = conv_to_double(b, bptr, tb);
@@ -1137,14 +1137,14 @@
mpint *x;
if(!num_to_ptr(a, &ai, &ta, &aptr))
- cthrow(type_error("num", a), a);
+ cthrow(type_error("a", "num", a), a);
if(!num_to_ptr(b, &bi, &tb, &bptr))
- cthrow(type_error("num", b), a);
+ cthrow(type_error("b", "num", b), a);
// a pointer is not exactly a number
if(ta == T_P32 || ta == T_P64)
- cthrow(type_error("num", a), a);
+ cthrow(type_error("a", "num", a), a);
if(tb == T_P32 || tb == T_P64)
- cthrow(type_error("num", b), a);
+ cthrow(type_error("b", "num", b), a);
if(ta == T_BIG){
if(tb == T_BIG){
@@ -1201,9 +1201,9 @@
s64int b64;
if(!num_to_ptr(a, &ai, &ta, &aptr) || ta >= T_FLT)
- cthrow(type_error("int", a), a);
+ cthrow(type_error("a", "int", a), a);
if(!num_to_ptr(b, &bi, &tb, &bptr) || tb >= T_FLT)
- cthrow(type_error("int", b), a);
+ cthrow(type_error("b", "int", b), a);
if(ta < tb){
itmp = ta; ta = tb; tb = itmp;
@@ -1349,7 +1349,7 @@
default: abort();
}
}
- bthrow(type_error("int", a));
+ bthrow(type_error(nil, "int", a));
}
#define sash_overflow_64(a, b, c) ( \
@@ -1418,7 +1418,7 @@
assert(fits_fixnum(accum));
return fixnum((sl_fx)accum);
}
- bthrow(type_error("int", a));
+ bthrow(type_error(nil, "int", a));
}
void
--- a/src/io.c
+++ b/src/io.c
@@ -71,7 +71,7 @@
toio(sl_v v)
{
if(sl_unlikely(!isio(v)))
- cthrow(type_error("io", v), v);
+ cthrow(type_error(nil, "io", v), v);
return value2c(ios*, v);
}
@@ -197,7 +197,7 @@
argcount(nargs, 2);
ios *s = toio(args[0]);
if(!isrune(args[1]))
- bthrow(type_error("rune", args[1]));
+ bthrow(type_error(nil, "rune", args[1]));
return fixnum(ios_putrune(s, torune(args[1])));
}
--- a/src/operators.c
+++ b/src/operators.c
@@ -13,11 +13,11 @@
case T_U32: case T_P32: return uitomp(*(u32int*)data, nil);
case T_S64: return vtomp(*(s64int*)data, nil);
case T_U64: case T_P64: return uvtomp(*(u64int*)data, nil);
- case T_BIG: return mpcopy(*(mpint**)data);
- case T_FLT: return dtomp(*(float*)data, nil);
- case T_DBL: return dtomp(*(double*)data, nil);
+ case T_BIG: return mpcopy(*(mpint**)data);
+ case T_FLT: return dtomp(*(float*)data, nil);
+ case T_DBL: return dtomp(*(double*)data, nil);
}
- cthrow(type_error("num", v), v);
+ cthrow(type_error(nil, "num", v), v);
}
sl_purefn
@@ -42,7 +42,7 @@
case T_FLT: return *(float*)data;
case T_DBL: return *(double*)data;
}
- cthrow(type_error("num", v), v);
+ cthrow(type_error(nil, "num", v), v);
}
// FIXME sign with mpint
@@ -64,7 +64,7 @@
case T_FLT: return (ctype)*(float*)data; \
case T_DBL: return (ctype)*(double*)data; \
} \
- cthrow(type_error("num", v), v); \
+ cthrow(type_error(nil, "num", v), v); \
}
CONV_TO_INTTYPE(s64, s64int)
@@ -100,7 +100,7 @@
s = *(double*)data;
return s;
}
- cthrow(type_error("num", v), v);
+ cthrow(type_error(nil, "num", v), v);
}
sl_purefn
--- a/src/plan9/lsd.c
+++ b/src/plan9/lsd.c
@@ -249,7 +249,7 @@
argcount(nargs, 3);
for(a = args; a < args+3; a++)
if(sl_unlikely(!sl_isnum(*a)))
- bthrow(type_error("num", *a));
+ bthrow(type_error(nil, "num", *a));
pc = tosize(args[0]);
sp = tosize(args[1]);
@@ -281,7 +281,7 @@
pid = -1;
argcount(nargs, 1);
if(sl_unlikely(!sl_isstr(args[0]) && !sl_isnum(args[0])))
- bthrow(type_error("str|num", args[0]));
+ bthrow(type_error("program", "(or str num)", args[0]));
if(sl_isnum(args[0])){
pid = tosize(args[0]);
@@ -343,7 +343,7 @@
argv[0] = aout;
for(i = 0; i < nargs; i++){
if(sl_unlikely(!sl_isstr(args[i])))
- bthrow(type_error("str", args[i]));
+ bthrow(type_error(nil, "str", args[i]));
argv[i+1] = cvalue_data(args[i]);
}
argv[i+1] = nil;
@@ -372,7 +372,7 @@
argcount(nargs, 1);
if(sl_unlikely(!sl_isnum(args[0])))
- bthrow(type_error("num", args[0]));
+ bthrow(type_error("addr", "num", args[0]));
addr = tosize(args[0]);
n = machdata->foll(coremap, addr, rget, f);
@@ -394,7 +394,7 @@
argcount(nargs, 1);
if(sl_unlikely(!sl_isnum(args[0])))
- bthrow(type_error("num", args[0]));
+ bthrow(type_error("addr", "num", args[0]));
addr = tosize(args[0]);
if(machdata->das(coremap, addr, 'i', buf, sizeof(buf)) < 0)
@@ -409,7 +409,7 @@
argcount(nargs, 1);
if(sl_unlikely(!sl_isnum(args[0])))
- bthrow(type_error("num", args[0]));
+ bthrow(type_error("addr", "num", args[0]));
addr = tosize(args[0]);
sz = machdata->instsize(coremap, addr);
@@ -425,7 +425,7 @@
argcount(nargs, 1);
if(sl_unlikely(!sl_isnum(args[0])))
- bthrow(type_error("num", args[0]));
+ bthrow(type_error("addr", "num", args[0]));
addr = tosize(args[0]);
if(!fileline(buf, sizeof(buf), addr))
@@ -441,9 +441,9 @@
argcount(nargs, 2);
if(sl_unlikely(!sl_isstr(args[0])))
- bthrow(type_error("str", args[0]));
+ bthrow(type_error("file", "str", args[0]));
if(sl_unlikely(!isfixnum(args[1])))
- bthrow(type_error("num", args[1]));
+ bthrow(type_error("line", "num", args[1]));
file = cvalue_data(args[0]);
line = numval(args[1]);
@@ -460,7 +460,7 @@
argcount(nargs, 1);
if(sl_unlikely(!sl_isnum(args[0])))
- bthrow(type_error("num", args[0]));
+ bthrow(type_error("addr", "num", args[0]));
addr = tosize(args[0]);
if(!findsym(addr, CTEXT, &s))
--- a/src/sl.c
+++ b/src/sl.c
@@ -168,9 +168,11 @@
}
_Noreturn void
-type_error(const char *expected, sl_v got)
+type_error(const char *what, const char *expected, sl_v got)
{
- sl_raise(mk_listn(3, sl_errtype, mk_sym(expected, false), got));
+ if(what == nil)
+ sl_raise(mk_listn(3, sl_errtype, mk_sym(expected, false), got));
+ sl_raise(mk_listn(4, sl_errtype, mk_sym(what, false), mk_sym(expected, false), got));
}
_Noreturn void
@@ -205,7 +207,7 @@
{ \
if(sl_likely(is##type(v))) \
return (ctype)cnvt(v); \
- cthrow(type_error(#type, v), v); \
+ cthrow(type_error("value", #type, v), v); \
}
SAFECAST_OP(cons, sl_cons*, ptr)
SAFECAST_OP(sym, sl_sym*, ptr)
@@ -600,7 +602,7 @@
}else if(isfn(f)){
v = apply_cl(n);
}else{
- cthrow(type_error("fn", f), n);
+ cthrow(type_error(nil, "fn", f), n);
}
sl.sp = saveSP;
return v;
@@ -969,12 +971,12 @@
if(nargs < 1 || nargs > 4)
argcount(nargs, 1);
if(sl_unlikely(!sl_isstr(args[0])))
- bthrow(type_error("str", args[0]));
+ bthrow(type_error("code", "str", args[0]));
sl_v vals = sl_emptyvec;
if(nargs > 1){
vals = args[1];
if(sl_unlikely(!isvec(vals)))
- bthrow(type_error("vec", vals));
+ bthrow(type_error("vals", "vec", vals));
}
sl_cv *arr = ptr(args[0]);
cv_pin(arr);
@@ -1000,12 +1002,12 @@
fn->env = args[2];
if(nargs > 3){
if(sl_unlikely(!issym(args[3])))
- bthrow(type_error("sym", args[3]));
+ bthrow(type_error("name", "sym", args[3]));
fn->name = args[3];
}
}
if(sl_unlikely(isgensym(fn->name)))
- bthrow(lerrorf(sl_errarg, "name should not be a gensym"));
+ bthrow(lerrorf(sl_errarg, "name must not be a gensym"));
}
return fv;
}
@@ -1016,7 +1018,7 @@
argcount(nargs, 1);
sl_v v = args[0];
if(sl_unlikely(!isfn(v)))
- bthrow(type_error("fn", v));
+ bthrow(type_error(nil, "fn", v));
if(sl_unlikely(iscbuiltin(v) || isbuiltin(v)))
return v;
return fn_bcode(v);
@@ -1028,7 +1030,7 @@
argcount(nargs, 1);
sl_v v = args[0];
if(sl_unlikely(!isfn(v)))
- bthrow(type_error("fn", v));
+ bthrow(type_error(nil, "fn", v));
if(sl_unlikely(iscbuiltin(v) || isbuiltin(v)))
return sl_emptyvec;
return fn_vals(v);
@@ -1040,7 +1042,7 @@
argcount(nargs, 1);
sl_v v = args[0];
if(sl_unlikely(!isfn(v)))
- bthrow(type_error("fn", v));
+ bthrow(type_error(nil, "fn", v));
if(sl_unlikely(iscbuiltin(v) || isbuiltin(v)))
return sl_nil;
return fn_env(v);
@@ -1060,7 +1062,7 @@
}
if(isfn(v))
return fn_name(v);
- bthrow(type_error("fn", v));
+ bthrow(type_error(nil, "fn", v));
}
BUILTIN("copy-list", copy_list)
@@ -1087,7 +1089,7 @@
cdr_(lastcons) = lst;
lastcons = tagptr((((sl_cons*)slg.curheap)-1), TAG_CONS);
}else if(lst != sl_nil){
- bthrow(type_error("cons", lst));
+ bthrow(type_error(nil, "cons", lst));
}
}
sl_free_gc_handles(2);
@@ -1138,15 +1140,15 @@
else if(rt == sl_tablesym)
rtype = RT_TBL;
else
- bthrow(type_error("sequence type designator", rt));
+ bthrow(type_error("result-type", "sequence type specifier", rt));
}else if(iscons(rt)){
if(car_(rt) != sl_arrsym)
- bthrow(type_error("array type designator", rt));
+ bthrow(type_error("result-type", "array type specifier", rt));
rtype = RT_ARR;
arrtype = car_(cdr_(rt));
get_arr_type(arrtype);
}else{
- bthrow(type_error("sequence type designator", rt));
+ bthrow(type_error("result-type", "sequence type specifier", rt));
}
sl_v *k = sl.sp;
PUSH(sl_nil);
--- a/src/sl.h
+++ b/src/sl.h
@@ -295,7 +295,7 @@
void sl_savestate(sl_exctx *_ctx);
void sl_restorestate(sl_exctx *_ctx);
_Noreturn void sl_raise(sl_v e);
-_Noreturn void type_error(const char *expected, sl_v got);
+_Noreturn void type_error(const char *what, const char *expected, sl_v got);
_Noreturn void bounds_error(sl_v arr, sl_v ind);
_Noreturn void const_error(sl_v sym);
_Noreturn void unbound_error(sl_v sym);
--- a/src/sl_arith_any.h
+++ b/src/sl_arith_any.h
@@ -32,7 +32,7 @@
typeerr:
mpfree(Maccum);
mpfree(m);
- type_error("num", arg);
+ type_error(nil, "num", arg);
}
switch(pt){
case T_DBL: Faccum = ARITH_OP(Faccum, *(double*)a); inexact = true; continue;
--- a/src/str.c
+++ b/src/str.c
@@ -22,7 +22,7 @@
if(nargs < 1 || nargs > 3)
argcount(nargs, 1);
if(!sl_isstr(args[0]))
- bthrow(type_error("str", args[0]));
+ bthrow(type_error(nil, "str", args[0]));
usize len = cv_len(ptr(args[0]));
usize stop = len;
if(nargs > 1){
@@ -49,7 +49,7 @@
return w < 0 ? sl_nil : fixnum(w);
}
if(!sl_isstr(args[0]))
- bthrow(type_error("str", args[0]));
+ bthrow(type_error(nil, "str", args[0]));
char *str = tostr(args[0]);
usize len = cv_len(ptr(args[0]));
ssize w = u8_strwidth(str, len);
@@ -60,7 +60,7 @@
{
argcount(nargs, 1);
if(!sl_isstr(args[0]))
- bthrow(type_error("str", args[0]));
+ bthrow(type_error(nil, "str", args[0]));
usize len = cv_len(ptr(args[0]));
sl_v ns = cvalue_str(len);
u8_reverse(cvalue_data(ns), cvalue_data(args[0]), len);
@@ -202,7 +202,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- bthrow(type_error("rune", args[0]));
+ bthrow(type_error(nil, "rune", args[0]));
return mk_rune(toupperrune(torune(args[0])));
}
@@ -211,7 +211,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- bthrow(type_error("rune", args[0]));
+ bthrow(type_error(nil, "rune", args[0]));
return mk_rune(tolowerrune(torune(args[0])));
}
@@ -220,7 +220,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- bthrow(type_error("rune", args[0]));
+ bthrow(type_error(nil, "rune", args[0]));
return mk_rune(totitlerune(torune(args[0])));
}
@@ -229,7 +229,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- bthrow(type_error("rune", args[0]));
+ bthrow(type_error(nil, "rune", args[0]));
return isalpharune(torune(args[0])) ? sl_t : sl_nil;
}
@@ -238,7 +238,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- bthrow(type_error("rune", args[0]));
+ bthrow(type_error(nil, "rune", args[0]));
return islowerrune(torune(args[0])) ? sl_t : sl_nil;
}
@@ -247,7 +247,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- bthrow(type_error("rune", args[0]));
+ bthrow(type_error(nil, "rune", args[0]));
return isupperrune(torune(args[0])) ? sl_t : sl_nil;
}
@@ -256,7 +256,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- bthrow(type_error("rune", args[0]));
+ bthrow(type_error(nil, "rune", args[0]));
return istitlerune(torune(args[0])) ? sl_t : sl_nil;
}
@@ -265,7 +265,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- bthrow(type_error("rune", args[0]));
+ bthrow(type_error(nil, "rune", args[0]));
return isdigitrune(torune(args[0])) ? sl_t : sl_nil;
}
@@ -274,7 +274,7 @@
{
argcount(nargs, 1);
if(!isrune(args[0]))
- bthrow(type_error("rune", args[0]));
+ bthrow(type_error(nil, "rune", args[0]));
return isspacerune(torune(args[0])) ? sl_t : sl_nil;
}
@@ -305,7 +305,7 @@
ndbytes = cv_len(cv);
nd = (char*)cv_data(cv);
}else{
- bthrow(type_error("str or rune", args[1]));
+ bthrow(type_error("needle", "(or str rune)", args[1]));
}
if(ndbytes == 0)
return size_wrap(startrune);
@@ -372,7 +372,7 @@
else
return fn_builtin_str(args, nargs);
}else{
- bthrow(type_error("int", n));
+ bthrow(type_error(nil, "num", n));
}
if(numval(sl_compare(args[0], fixnum(0), false)) < 0){
num = -num;
--- a/src/system.sl
+++ b/src/system.sl
@@ -1466,7 +1466,12 @@
(when loc
(princ (io-filename (car loc)) ":" (cadr loc) ":" (caddr loc) ": "))
(cond ((eq? k 'type-error)
- (princ "type error: expected " (car a) ", got " (type-of (cadr a)) ": ")
+ (princ "type error: ")
+ (unless (length= a 2)
+ (princ (car a) ": ")
+ (set! a (cdr a)))
+ (for-each (λ (s) (princ s ": ")) (cddr a))
+ (princ "expected " (car a) ", got " (type-of (cadr a)) ": ")
(print (cadr a)))
((eq? k 'bounds-error)
--- a/src/table.c
+++ b/src/table.c
@@ -85,7 +85,7 @@
totable(sl_v v)
{
if(!ishashtable(v))
- cthrow(type_error("table", v), v);
+ cthrow(type_error(nil, "table", v), v);
return cvalue_data(v);
}
--- a/src/vm.h
+++ b/src/vm.h
@@ -55,7 +55,7 @@
}
int i = uintval(v);
if(!isbuiltin(v))
- type_error("fn", v);
+ type_error("builtin", "fn", v);
sl_fx s = builtins[i].nargs;
if(s >= 0)
argcount(n, s);
@@ -100,7 +100,7 @@
sp[-1] = v;
NEXT_OP;
}
- type_error("fn", v);
+ type_error(tail ? "tcall" : "call", "fn", v);
}
OP(OP_ARGC) {
@@ -260,7 +260,7 @@
v = car_(v);
else if(sl_unlikely(v != sl_nil)){
SYNC;
- type_error("cons", v);
+ type_error("car", "cons", v);
}
sp[-1] = v;
NEXT_OP;
@@ -322,7 +322,7 @@
v = cdr_(v);
else if(sl_unlikely(v != sl_nil)){
SYNC;
- type_error("cons", v);
+ type_error("cdr", "cons", v);
}
sp[-1] = v;
NEXT_OP;
@@ -386,7 +386,7 @@
sl_v v = sp[-2];
if(sl_unlikely(!iscons(v))){
SYNC;
- type_error("cons", v);
+ type_error("set-car!", "cons", v);
}
car_(v) = sp[-1];
sp--;
@@ -439,7 +439,7 @@
continue;
}
if(!iscons(v))
- type_error("sequence", v);
+ type_error("aref", "sequence", v);
for(sl_v v0 = v;; isz--){
if(isz == 0){
v = car_(v);
@@ -485,7 +485,7 @@
sl_v v = sp[-2];
if(sl_unlikely(!iscons(v))){
SYNC;
- type_error("cons", v);
+ type_error("set-cdr!", "cons", v);
}
cdr_(v) = sp[-1];
sp--;
@@ -518,7 +518,7 @@
continue;
}
if(sl_unlikely(!iscons(v)))
- type_error("sequence", v);
+ type_error("aset!", "sequence", v);
for(sl_v v0 = v;; isz--){
if(isz == 0){
v = car_(v);
@@ -550,7 +550,7 @@
}else if(isarr(v)){
e = cvalue_arr_aset(sp-3);
}else{
- type_error("sequence", v);
+ type_error("aset!", "sequence", v);
}
sp -= n;
*sp++ = e;
@@ -679,7 +679,7 @@
LABEL(cadr_nil):
if(sl_unlikely(v != sl_nil)){
SYNC;
- type_error("cons", v);
+ type_error("cadr", "cons", v);
}
}
sp[-1] = v;