shithub: femtolisp

Download patch

ref: 1abba471c0aa02eb166c4acc3437e799e994fe49
parent: 96e8c5d8f56998045411b0bead00a0d4f68a4212
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Dec 23 14:58:02 EST 2024

add the_empty_string to clean up the mess

--- a/builtins.c
+++ b/builtins.c
@@ -395,8 +395,6 @@
 	char *val = getenv(name);
 	if(val == nil)
 		return FL_f;
-	if(*val == 0)
-		return symbol_value(FL(emptystringsym));
 	return cvalue_static_cstring(val);
 }
 
--- a/cvalues.c
+++ b/cvalues.c
@@ -109,7 +109,7 @@
 
 	if(type->eltype == FL(bytetype)){
 		if(sz == 0)
-			return symbol_value(FL(emptystringsym));
+			return FL(the_empty_string);
 		sz++;
 		str = 1;
 	}
@@ -175,6 +175,8 @@
 value_t
 cvalue_string(size_t sz)
 {
+	if(sz == 0)
+		return FL(the_empty_string);
 	return cvalue(FL(stringtype), sz);
 }
 
@@ -181,6 +183,8 @@
 value_t
 cvalue_static_cstring(const char *str)
 {
+	if(*str == 0)
+		return FL(the_empty_string);
 	return cvalue_from_ref(FL(stringtype), (char*)str, strlen(str), FL_nil);
 }
 
@@ -1485,8 +1489,6 @@
 	FL(mpinttype)->vtable = &mpint_vtable;
 
 	FL(stringtype) = get_type(symbol_value(FL(stringtypesym)));
+	FL(the_empty_string) = cvalue_from_ref(FL(stringtype), (char*)"", 0, FL_nil);
 	FL(runestringtype) = get_type(symbol_value(FL(runestringtypesym)));
-
-	FL(emptystringsym) = symbol("*empty-string*", false);
-	set(FL(emptystringsym), cvalue_static_cstring(""));
 }
--- a/flisp.boot
+++ b/flisp.boot
@@ -14,8 +14,7 @@
 	      #fn("6000n201l:" #()) #fn("6000n201m:" #()) 0 #fn("8000z0700}2:" #(vector))
 	      #fn("8000z0700}2:" #(aset!)) 0 0 0 0 0 0 0 0 0 0 0 #fn("9000n3012082>1|:" #(#fn("6000n1A061:" #())))
 	      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 #fn("8000z0700}2:" #(aref)) 0 0)
-	    *empty-string* "" *properties*
-	    #table(*funvars* #table(length= (lst n)  help (term))  *doc* #table(length= "Bounded length test.\n\nUse this instead of (= (length lst) n), since it avoids unnecessary\nwork and always terminates."  help "Display documentation for the specified term, if available."  *properties* "All properties of symbols recorded with putprop are recorded in this table."))
+	    *properties* #table(*funvars* #table(length= (lst n)  help (term))  *doc* #table(length= "Bounded length test.\n\nUse this instead of (= (length lst) n), since it avoids unnecessary\nwork and always terminates."  help "Display documentation for the specified term, if available."  *properties* "All properties of symbols recorded with putprop are recorded in this table."))
 	    *runestring-type* (array rune) *string-type* (array byte)
 	    *syntax-environment* #table(when #fn(";000z1200211POe4:" #(if begin))  help #fn("<000n170021527002252853\\0738551474504863B07450475086P51@30O47450@B0732627051524745047860:" #(getprop
   *doc* *funvars* princ newline print "no help for " #fn(string) void))  with-output-to #fn("<000z12021e1220e2e1e12315163:" #(#fn(nconc)
--- a/flisp.c
+++ b/flisp.c
@@ -493,6 +493,7 @@
 	FL(lasterror) = relocate(FL(lasterror));
 	FL(memory_exception_value) = relocate(FL(memory_exception_value));
 	FL(the_empty_vector) = relocate(FL(the_empty_vector));
+	FL(the_empty_string) = relocate(FL(the_empty_string));
 
 	sweep_finalizers();
 
--- a/flisp.h
+++ b/flisp.h
@@ -388,6 +388,7 @@
 	value_t UnboundError;
 
 	value_t the_empty_vector;
+	value_t the_empty_string;
 	value_t memory_exception_value;
 
 	value_t tablesym;
@@ -401,7 +402,7 @@
 	value_t int64sym, uint64sym, bignumsym;
 	value_t longsym, ulongsym, bytesym, runesym;
 	value_t structsym, arraysym, enumsym, cfunctionsym, voidsym, pointersym;
-	value_t stringtypesym, runestringtypesym, emptystringsym;
+	value_t stringtypesym, runestringtypesym;
 	value_t unionsym, floatsym, doublesym;
 
 	htable_t TypeTable;
--- a/iostream.c
+++ b/iostream.c
@@ -393,6 +393,8 @@
 		ios_trunc(st, 0);
 	}else{
 		uint8_t *b = ios_takebuf(st, &n); n--;
+		if(n == 0)
+			return FL(the_empty_string);
 		b[n] = '\0';
 		str = cvalue_from_ref(FL(stringtype), b, n, FL_nil);
 		cv_autorelease(ptr(str));
@@ -406,7 +408,11 @@
 	ios_t *src = toiostream(args[0]);
 	if(src->bm != bm_mem)
 		lerrorf(FL(ArgError), "requires memory stream");
-	return stream_to_string(&args[0]);
+	bool eof = ios_eof(src);
+	value_t v = stream_to_string(&args[0]);
+	if(eof && v == FL(the_empty_string))
+		v = FL_eof;
+	return v;
 }
 
 void
--- a/string.c
+++ b/string.c
@@ -197,8 +197,6 @@
 		if(n != endchar)
 			bounds_error(args[0], args[2]);
 	}
-	if(endbytes == startbytes)
-		return symbol_value(FL(emptystringsym));
 	value_t ns = cvalue_string(endbytes-startbytes);
 	s = cvalue_data(args[0]); // reload after alloc
 	memmove(cvalue_data(ns), s+startbytes, endbytes-startbytes);