shithub: sl

Download patch

ref: 39517070479e7453b62fb8aeb2cb52e869b33fbb
parent: f04bb5fdca94bc8bf82887d2b76655b5a5bf984c
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Apr 21 13:50:56 EDT 2025

redefine UNBOUND as a "special"-tagged sl_unbound

--- a/src/builtins.c
+++ b/src/builtins.c
@@ -160,7 +160,7 @@
 {
 	argcount(nargs, 1);
 	sl_sym *sym = tosym(args[0]);
-	if(sym->binding == UNBOUND)
+	if(sym->binding == sl_unbound)
 		bthrow(unbound_error(args[0]));
 	return sym->binding;
 }
@@ -181,7 +181,7 @@
 	sl_sym *sym = tosym(args[0]);
 	if(sl_unlikely(isconst(sym)))
 		bthrow(const_error(args[0]));
-	sym->binding = UNBOUND;
+	sym->binding = sl_unbound;
 	return sl_void;
 }
 
@@ -194,7 +194,7 @@
 	const char *k = nil;
 	sl_sym *v;
 	while(Tnext(slg.symbols, &k, (void**)&v)){
-		if(v->binding != UNBOUND && (v->flags & FLAG_KEYWORD) == 0)
+		if(v->binding != sl_unbound && (v->flags & FLAG_KEYWORD) == 0)
 			lst = mk_cons(tagptr(v, TAG_SYM), lst);
 	}
 	sl_free_gc_handles(1);
--- a/src/read.c
+++ b/src/read.c
@@ -316,7 +316,7 @@
 			return peek(ctx);
 		}else if(c == ';'){
 			// datum comment
-			(void)do_read_sexpr(ctx, UNBOUND); // skip
+			(void)do_read_sexpr(ctx, sl_unbound); // skip
 			return peek(ctx);
 		}else if(c == ':'){
 			// gensym
@@ -418,7 +418,7 @@
 	sl_v v = sl_emptyvec, elt;
 	u32int i = 0;
 	PUSH(v);
-	if(label != UNBOUND)
+	if(label != sl_unbound)
 		ptrhash_put(&sl.readstate->backrefs, (void*)label, (void*)v);
 	while(peek(ctx) != closer){
 		if(ios_eof(RS))
@@ -425,11 +425,11 @@
 			parse_error(ctx, "unexpected EOI");
 		v = sl.sp[-1]; // reload after possible alloc in peek()
 		if(i >= vec_size(v)){
-			v = sl.sp[-1] = vec_grow(v, label != UNBOUND);
-			if(label != UNBOUND)
+			v = sl.sp[-1] = vec_grow(v, label != sl_unbound);
+			if(label != sl_unbound)
 				ptrhash_put(&sl.readstate->backrefs, (void*)label, (void*)v);
 		}
-		elt = do_read_sexpr(ctx, UNBOUND);
+		elt = do_read_sexpr(ctx, sl_unbound);
 		v = sl.sp[-1];
 		assert(i < vec_size(v));
 		vec_elt(v, i) = elt;
@@ -611,11 +611,11 @@
 		else{
 			pval = ipval;
 			*pval = c;
-			if(label != UNBOUND)
+			if(label != sl_unbound)
 				ptrhash_put(&sl.readstate->backrefs, (void*)label, (void*)c);
 		}
 		*pc = c;
-		c = do_read_sexpr(ctx, UNBOUND);
+		c = do_read_sexpr(ctx, sl_unbound);
 		pc = ipc;
 		car_(*pc) = c;
 
@@ -622,7 +622,7 @@
 		t = peek(ctx);
 		if(t == TOK_DOT){
 			take(ctx);
-			c = do_read_sexpr(ctx, UNBOUND);
+			c = do_read_sexpr(ctx, sl_unbound);
 			pc = ipc;
 			cdr_(*pc) = c;
 			t = peek(ctx);
@@ -688,9 +688,9 @@
 		cdr_(v) = tagptr((sl_cons*)ptr(v)+1, TAG_CONS);
 		car_(cdr_(v)) = cdr_(cdr_(v)) = sl_nil;
 		PUSH(v);
-		if(label != UNBOUND)
+		if(label != sl_unbound)
 			ptrhash_put(&sl.readstate->backrefs, (void*)label, (void*)v);
-		v = do_read_sexpr(ctx, UNBOUND);
+		v = do_read_sexpr(ctx, sl_unbound);
 		car_(cdr_(sl.sp[-1])) = v;
 		return POP();
 	case TOK_SHARPQUOTE:
@@ -707,7 +707,7 @@
 			parse_error(ctx, "expected argument list for %s", sym_name(ctx->tokval));
 		}
 		PUSH(sl_nil);
-		read_list(ctx, UNBOUND, c == '(' ? TOK_CLOSE : (c == '[' ? TOK_CLOSEB : TOK_CLOSEC));
+		read_list(ctx, sl_unbound, c == '(' ? TOK_CLOSE : (c == '[' ? TOK_CLOSEB : TOK_CLOSEC));
 		if(sym == sl_vu8sym){
 			sym = sl_arrsym;
 			sl.sp[-1] = mk_cons(sl_u8sym, sl.sp[-1]);
@@ -714,7 +714,7 @@
 		}
 		v = sym_value(sym);
 		sl.readstate->errloc = loc0;
-		if(v == UNBOUND)
+		if(v == sl_unbound)
 			unbound_error(sym);
 		return sl_apply(v, POP());
 	case TOK_SHARPOPEN:
@@ -726,10 +726,10 @@
 		// (... #2=#.#0# ... )	OK
 		// (... #2=#.(#2#) ... )  DO NOT WANT
 		loc0 = ctx->loc;
-		sym = do_read_sexpr(ctx, UNBOUND);
+		sym = do_read_sexpr(ctx, sl_unbound);
 		if(issym(sym)){
 			v = sym_value(sym);
-			if(v == UNBOUND){
+			if(v == sl_unbound){
 				sl.readstate->errloc = loc0;
 				unbound_error(sym);
 			}
@@ -786,7 +786,7 @@
 	ctx.ws = ws;
 	sl_gc_handle(&ctx.tokval);
 
-	sl_v v = do_read_sexpr(&ctx, UNBOUND);
+	sl_v v = do_read_sexpr(&ctx, sl_unbound);
 
 	sl_free_gc_handles(1);
 	sl.readstate = state.prev;
--- a/src/sl.c
+++ b/src/sl.c
@@ -226,7 +226,7 @@
 		sym->flags = FLAG_KEYWORD;
 		setc(s, s);
 	}else{
-		sym->binding = UNBOUND;
+		sym->binding = sl_unbound;
 		sym->flags = 0;
 	}
 	sym->type = nil;
@@ -270,7 +270,7 @@
 	USED(args);
 	sl_gensym *gs = alloc_words(sizeof(sl_gensym)/sizeof(sl_v));
 	gs->id = slg.gensym_ctr++;
-	gs->binding = UNBOUND;
+	gs->binding = sl_unbound;
 	gs->type = nil;
 	return tagptr(gs, TAG_SYM);
 }
@@ -472,7 +472,7 @@
 		ng->type = gs->type;
 		nc = tagptr(ng, TAG_SYM);
 		forward(v, nc);
-		if(sl_likely(ng->binding != UNBOUND))
+		if(sl_likely(ng->binding != sl_unbound))
 			ng->binding = sl_relocate(ng->binding);
 		return nc;
 	}
@@ -485,7 +485,7 @@
 	const char *k = nil;
 	sl_sym *v;
 	while(Tnext(slg.symbols, &k, (void**)&v)){
-		if(v->binding != UNBOUND)
+		if(v->binding != sl_unbound)
 			v->binding = sl_relocate(v->binding);
 	}
 }
@@ -797,7 +797,7 @@
 	if(sl_unlikely(extr > nelem(args)))
 		cthrow(lerrorf(sl_errarg, "too many arguments"), kwtable);
 	for(i = 0; i < extr; i++)
-		args[i] = UNBOUND;
+		args[i] = sl_unbound;
 	for(i = nreq; i < nargs; i++){
 		v = bp[i];
 		if(issym(v) && iskeyword((sl_sym*)ptr(v)))
@@ -821,7 +821,7 @@
 			intptr idx = numval(vec_elt(kwtable, x+1));
 			assert(idx < nkw);
 			idx += nopt;
-			if(args[idx] == UNBOUND){
+			if(args[idx] == sl_unbound){
 				// if duplicate key, keep first value
 				args[idx] = bp[i];
 			}
@@ -942,8 +942,8 @@
 		for(int i = 1; i < sz; i++){
 			sl_v si = bp[i];
 			// if there's an error evaluating argument defaults some slots
-			// might be left set to UNBOUND
-			vec_elt(v, i+1) = si == UNBOUND ? sl_void : si;
+			// might be left set to sl_unbound
+			vec_elt(v, i+1) = si == sl_unbound ? sl_void : si;
 		}
 		lst = mk_cons(v, lst);
 		top = (sl_v*)top[-3];
@@ -1126,7 +1126,7 @@
 	bool rtdecl = true;
 	if(rt == sl_nil)
 		rtype = RT_NIL;
-	else if(rt == UNBOUND)
+	else if(rt == sl_unbound)
 		rtdecl = false;
 	else if(issym(rt)){
 		if(rt == sl_listsym)
@@ -1299,7 +1299,7 @@
 		argcount(nargs, 2);
 	sl_v v = args[0];
 	return isfn(v)
-		? map_seq(UNBOUND, args, nargs)
+		? map_seq(sl_unbound, args, nargs)
 		: map_seq(v, args+1, nargs-1);
 }
 
@@ -1509,7 +1509,7 @@
 				while(iscons(e)){
 					sl_sym *sym = tosym(car_(e));
 					e = cdr_(e);
-					if(sym->binding != UNBOUND)
+					if(sym->binding != sl_unbound)
 						ios_printf(ios_stderr, "%s redefined on boot\n", sym->name);
 					sym->binding = car_(e);
 					e = cdr_(e);
--- a/src/sl.h
+++ b/src/sl.h
@@ -105,7 +105,6 @@
 #define ANYARGS -10000
 #define NONNUMERIC (0xff)
 #define valid_numtype(v) ((v) <= T_DBL)
-#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)))
@@ -374,6 +373,7 @@
 #include "opcodes.h"
 
 enum {
+	sl_unbound = special(0),
 	sl_nil = special(1),
 	sl_t = special(2),
 	sl_void = special(3),
--- a/src/vm.h
+++ b/src/vm.h
@@ -163,7 +163,7 @@
 	}
 	assert(issym(v));
 	sl_sym *sym = ptr(v);
-	if(sl_unlikely(sym->binding == UNBOUND)){
+	if(sl_unlikely(sym->binding == sl_unbound)){
 		SYNC;
 		unbound_error(v);
 	}
@@ -586,7 +586,7 @@
 	NEXT_OP;
 
 OP(OP_BOUNDA)
-	*sp++ = bp[GET_S32(ip)] != UNBOUND ? sl_t : sl_nil;
+	*sp++ = bp[GET_S32(ip)] != sl_unbound ? sl_t : sl_nil;
 	ip += 4;
 	NEXT_OP;
 
@@ -616,7 +616,7 @@
 		sl.curr_frame = sp;
 		ipd = sp-1;
 		for(i = 0; i < x; i++)
-			bp[nargs+i] = UNBOUND;
+			bp[nargs+i] = sl_unbound;
 		nargs += x;
 	}
 	NEXT_OP;
@@ -639,7 +639,7 @@
 OP(OP_BOUNDP) {
 	SYNC;
 	sl_sym *sym = tosym(sp[-1]);
-	sp[-1] = sym->binding == UNBOUND ? sl_nil : sl_t;
+	sp[-1] = sym->binding == sl_unbound ? sl_nil : sl_t;
 	NEXT_OP;
 }