shithub: femtolisp

Download patch

ref: 06419ca6dde8b1d14ed2dbe5c5a0e37298c5706d
parent: 3f3bedb88862a0a955c8357081e4f8ba89b88b81
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Nov 26 16:14:35 EST 2024

no need to allocate for copies of constant symbol names

--- a/builtins.c
+++ b/builtins.c
@@ -135,7 +135,7 @@
 	argcount(nargs, 1);
 	if(__unlikely(!fl_isstring(args[0])))
 		type_error("string", args[0]);
-	return symbol(cvalue_data(args[0]));
+	return symbol(cvalue_data(args[0]), true);
 }
 
 BUILTIN("keyword?", keywordp)
--- a/cvalues.c
+++ b/cvalues.c
@@ -693,7 +693,7 @@
 		if(args[0] == FL(Nil))
 			return FL(nullsym);
 		if(args[0] == FL(eof))
-			return symbol("eof-object");
+			return FL(eof);
 		if(isbuiltin(args[0]))
 			return FL(builtinsym);
 		return FL(function);
@@ -913,7 +913,7 @@
 	cv->len = sizeof(value_t);
 	*(builtin_t*)cv->data = f;
 
-	value_t sym = symbol(name);
+	value_t sym = symbol(name, false);
 	((symbol_t*)ptr(sym))->dlcache = cv;
 	ptrhash_put(&FL(reverse_dlsym_lookup_table), cv, (void*)sym);
 
@@ -922,7 +922,7 @@
 
 #define cv_intern(tok) \
 	do{ \
-		FL(tok##sym) = symbol(#tok); \
+		FL(tok##sym) = symbol(#tok, false); \
 	}while(0)
 
 #define ctor_cv_intern(tok, nt, ctype) \
@@ -1453,12 +1453,12 @@
 	cv_intern(struct);
 	cv_intern(union);
 	cv_intern(void);
-	FL(cfunctionsym) = symbol("c-function");
+	FL(cfunctionsym) = symbol("c-function", false);
 
-	FL(stringtypesym) = symbol("*string-type*");
+	FL(stringtypesym) = symbol("*string-type*", false);
 	setc(FL(stringtypesym), fl_list2(FL(arraysym), FL(bytesym)));
 
-	FL(runestringtypesym) = symbol("*runestring-type*");
+	FL(runestringtypesym) = symbol("*runestring-type*", false);
 	setc(FL(runestringtypesym), fl_list2(FL(arraysym), FL(runesym)));
 
 	mk_primtype(int8, int8_t);
@@ -1482,6 +1482,6 @@
 	FL(stringtype) = get_type(symbol_value(FL(stringtypesym)));
 	FL(runestringtype) = get_type(symbol_value(FL(runestringtypesym)));
 
-	FL(emptystringsym) = symbol("*empty-string*");
+	FL(emptystringsym) = symbol("*empty-string*", false);
 	setc(FL(emptystringsym), cvalue_static_cstring(""));
 }
--- a/flisp.c
+++ b/flisp.c
@@ -126,7 +126,7 @@
 _Noreturn void
 type_error(const char *expected, value_t got)
 {
-	fl_raise(fl_listn(3, FL(TypeError), symbol(expected), got));
+	fl_raise(fl_listn(3, FL(TypeError), symbol(expected, false), got));
 }
 
 _Noreturn void
@@ -167,12 +167,12 @@
 }
 
 static symbol_t *
-mk_symbol(const char *str)
+mk_symbol(const char *str, bool copy)
 {
 	symbol_t *sym;
-	size_t len = strlen(str);
+	int len = strlen(str);
 
-	sym = calloc(1, sizeof(*sym)-sizeof(void*) + len + 1);
+	sym = calloc(1, sizeof(*sym) + (copy ? len+1 : 0));
 	assert(((uintptr_t)sym & 0x7) == 0); // make sure malloc aligns 8
 	sym->numtype = NONNUMERIC;
 	if(fl_is_keyword_name(str, len)){
@@ -183,7 +183,12 @@
 		sym->binding = UNBOUND;
 	}
 	sym->hash = memhash32(str, len)^0xAAAAAAAA;
-	memcpy(sym->name, str, len+1);
+	if(copy){
+		sym->name = (const char*)(sym+1);
+		memcpy((char*)sym->name, str, len+1);
+	}else{
+		sym->name = str;
+	}
 	return sym;
 }
 
@@ -197,13 +202,13 @@
 }
 
 value_t
-symbol(const char *str)
+symbol(const char *str, bool copy)
 {
 	symbol_t **pnode;
 
 	pnode = symtab_lookup(&FL(symtab), str);
 	if(*pnode == nil)
-		*pnode = mk_symbol(str);
+		*pnode = mk_symbol(str, copy);
 	return tagptr(*pnode, TAG_SYM);
 }
 
@@ -2139,71 +2144,71 @@
 	FL(t) = builtin(OP_BOOL_CONST_T);
 	FL(f) = builtin(OP_BOOL_CONST_F);
 	FL(eof) = builtin(OP_EOF_OBJECT);
-	FL(lambda) = symbol("λ");
-	FL(function) = symbol("function");
-	FL(quote) = symbol("quote");
-	FL(trycatch) = symbol("trycatch");
-	FL(backquote) = symbol("quasiquote");
-	FL(comma) = symbol("unquote");
-	FL(commaat) = symbol("unquote-splicing");
-	FL(commadot) = symbol("unquote-nsplicing");
-	FL(IOError) = symbol("io-error");
-	FL(ParseError) = symbol("parse-error");
-	FL(TypeError) = symbol("type-error");
-	FL(ArgError) = symbol("arg-error");
-	FL(UnboundError) = symbol("unbound-error");
-	FL(KeyError) = symbol("key-error");
-	FL(MemoryError) = symbol("memory-error");
-	FL(BoundsError) = symbol("bounds-error");
-	FL(DivideError) = symbol("divide-error");
-	FL(EnumerationError) = symbol("enumeration-error");
-	FL(Error) = symbol("error");
-	FL(pairsym) = symbol("pair");
-	FL(symbolsym) = symbol("symbol");
-	FL(fixnumsym) = symbol("fixnum");
-	FL(vectorsym) = symbol("vector");
-	FL(builtinsym) = symbol("builtin");
-	FL(booleansym) = symbol("boolean");
-	FL(nullsym) = symbol("null");
-	FL(definesym) = symbol("define");
-	FL(defmacrosym) = symbol("define-macro");
-	FL(forsym) = symbol("for");
-	FL(setqsym) = symbol("set!");
-	FL(evalsym) = symbol("eval");
-	FL(vu8sym) = symbol("vu8");
-	FL(fnsym) = symbol("fn");
-	FL(nulsym) = symbol("nul");
-	FL(alarmsym) = symbol("alarm");
-	FL(backspacesym) = symbol("backspace");
-	FL(tabsym) = symbol("tab");
-	FL(linefeedsym) = symbol("linefeed");
-	FL(vtabsym) = symbol("vtab");
-	FL(pagesym) = symbol("page");
-	FL(returnsym) = symbol("return");
-	FL(escsym) = symbol("esc");
-	FL(spacesym) = symbol("space");
-	FL(deletesym) = symbol("delete");
-	FL(newlinesym) = symbol("newline");
-	FL(tsym) = symbol("t");
-	FL(Tsym) = symbol("T");
-	FL(fsym) = symbol("f");
-	FL(Fsym) = symbol("F");
-	FL(builtins_table_sym) = symbol("*builtins*");
-	set(FL(printprettysym) = symbol("*print-pretty*"), FL(t));
-	set(FL(printreadablysym) = symbol("*print-readably*"), FL(t));
-	set(FL(printwidthsym) = symbol("*print-width*"), fixnum(FL(scr_width)));
-	set(FL(printlengthsym) = symbol("*print-length*"), FL(f));
-	set(FL(printlevelsym) = symbol("*print-level*"), FL(f));
+	FL(lambda) = symbol("λ", false);
+	FL(function) = symbol("function", false);
+	FL(quote) = symbol("quote", false);
+	FL(trycatch) = symbol("trycatch", false);
+	FL(backquote) = symbol("quasiquote", false);
+	FL(comma) = symbol("unquote", false);
+	FL(commaat) = symbol("unquote-splicing", false);
+	FL(commadot) = symbol("unquote-nsplicing", false);
+	FL(IOError) = symbol("io-error", false);
+	FL(ParseError) = symbol("parse-error", false);
+	FL(TypeError) = symbol("type-error", false);
+	FL(ArgError) = symbol("arg-error", false);
+	FL(UnboundError) = symbol("unbound-error", false);
+	FL(KeyError) = symbol("key-error", false);
+	FL(MemoryError) = symbol("memory-error", false);
+	FL(BoundsError) = symbol("bounds-error", false);
+	FL(DivideError) = symbol("divide-error", false);
+	FL(EnumerationError) = symbol("enumeration-error", false);
+	FL(Error) = symbol("error", false);
+	FL(pairsym) = symbol("pair", false);
+	FL(symbolsym) = symbol("symbol", false);
+	FL(fixnumsym) = symbol("fixnum", false);
+	FL(vectorsym) = symbol("vector", false);
+	FL(builtinsym) = symbol("builtin", false);
+	FL(booleansym) = symbol("boolean", false);
+	FL(nullsym) = symbol("null", false);
+	FL(definesym) = symbol("define", false);
+	FL(defmacrosym) = symbol("define-macro", false);
+	FL(forsym) = symbol("for", false);
+	FL(setqsym) = symbol("set!", false);
+	FL(evalsym) = symbol("eval", false);
+	FL(vu8sym) = symbol("vu8", false);
+	FL(fnsym) = symbol("fn", false);
+	FL(nulsym) = symbol("nul", false);
+	FL(alarmsym) = symbol("alarm", false);
+	FL(backspacesym) = symbol("backspace", false);
+	FL(tabsym) = symbol("tab", false);
+	FL(linefeedsym) = symbol("linefeed", false);
+	FL(vtabsym) = symbol("vtab", false);
+	FL(pagesym) = symbol("page", false);
+	FL(returnsym) = symbol("return", false);
+	FL(escsym) = symbol("esc", false);
+	FL(spacesym) = symbol("space", false);
+	FL(deletesym) = symbol("delete", false);
+	FL(newlinesym) = symbol("newline", false);
+	FL(tsym) = symbol("t", false);
+	FL(Tsym) = symbol("T", false);
+	FL(fsym) = symbol("f", false);
+	FL(Fsym) = symbol("F", false);
+	FL(builtins_table_sym) = symbol("*builtins*", false);
+	set(FL(printprettysym) = symbol("*print-pretty*", false), FL(t));
+	set(FL(printreadablysym) = symbol("*print-readably*", false), FL(t));
+	set(FL(printwidthsym) = symbol("*print-width*", false), fixnum(FL(scr_width)));
+	set(FL(printlengthsym) = symbol("*print-length*", false), FL(f));
+	set(FL(printlevelsym) = symbol("*print-level*", false), FL(f));
 	FL(lasterror) = FL(Nil);
 	for(i = 0; i < nelem(builtins); i++){
 		if(builtins[i].name)
-			setc(symbol(builtins[i].name), builtin(i));
+			setc(symbol(builtins[i].name, false), builtin(i));
 	}
-	setc(symbol("eq"), builtin(OP_EQ));
-	setc(symbol("procedure?"), builtin(OP_FUNCTIONP));
-	setc(symbol("top-level-bound?"), builtin(OP_BOUNDP));
+	setc(symbol("eq", false), builtin(OP_EQ));
+	setc(symbol("procedure?", false), builtin(OP_FUNCTIONP));
+	setc(symbol("top-level-bound?", false), builtin(OP_BOUNDP));
 
-	set(symbol("*os-name*"), symbol(__os_name__));
+	set(symbol("*os-name*", false), symbol(__os_name__, false));
 
 	FL(the_empty_vector) = tagptr(alloc_words(1), TAG_VECTOR);
 	vector_setsize(FL(the_empty_vector), 0);
@@ -2213,7 +2218,7 @@
 	FL(memory_exception_value) = fl_list2(FL(MemoryError), cvalue_static_cstring("out of memory"));
 	const builtinspec_t *b;
 	for(i = 0, b = builtin_fns; i < nelem(builtin_fns); i++, b++)
-		setc(symbol(b->name), cbuiltin(b->name, b->fptr));
+		setc(symbol(b->name, false), cbuiltin(b->name, b->fptr));
 
 	table_init();
 	iostream_init();
--- a/flisp.h
+++ b/flisp.h
@@ -58,6 +58,7 @@
 
 typedef struct _symbol_t {
 	fltype_t *type;
+	const char *name;
 	void *dlcache;	 // dlsym address
 	struct _symbol_t *left;
 	struct _symbol_t *right;
@@ -67,7 +68,6 @@
 	uint8_t size;
 	uint8_t align;
 	uint8_t flags;
-	char name[1];
 }symbol_t;
 
 typedef struct {
@@ -184,7 +184,7 @@
 
 /* symbol table */
 value_t gensym(void);
-value_t symbol(const char *str);
+value_t symbol(const char *str, bool copy);
 const char *symbol_name(value_t v);
 
 /* read, eval, print main entry points */
--- a/flmain.c
+++ b/flmain.c
@@ -48,7 +48,7 @@
 	int r = 1;
 	FL_TRY_EXTERN{
 		if(fl_load_system_image(f) == 0){
-			fl_applyn(1, symbol_value(symbol("__start")), argv_list(argc, argv));
+			fl_applyn(1, symbol_value(symbol("__start", false)), argv_list(argc, argv));
 			r = 0;
 		}
 	}
--- a/iostream.c
+++ b/iostream.c
@@ -412,16 +412,16 @@
 void
 iostream_init(void)
 {
-	FL(iostreamsym) = symbol("iostream");
-	FL(rdsym) = symbol(":read");
-	FL(wrsym) = symbol(":write");
-	FL(apsym) = symbol(":append");
-	FL(crsym) = symbol(":create");
-	FL(truncsym) = symbol(":truncate");
-	FL(instrsym) = symbol("*input-stream*");
-	FL(outstrsym) = symbol("*output-stream*");
+	FL(iostreamsym) = symbol("iostream", false);
+	FL(rdsym) = symbol(":read", false);
+	FL(wrsym) = symbol(":write", false);
+	FL(apsym) = symbol(":append", false);
+	FL(crsym) = symbol(":create", false);
+	FL(truncsym) = symbol(":truncate", false);
+	FL(instrsym) = symbol("*input-stream*", false);
+	FL(outstrsym) = symbol("*output-stream*", false);
 	FL(iostreamtype) = define_opaque_type(FL(iostreamsym), sizeof(ios_t), &iostream_vtable, nil);
-	setc(symbol("*stdout*"), cvalue_from_ref(FL(iostreamtype), ios_stdout, sizeof(ios_t), FL(Nil)));
-	setc(symbol("*stderr*"), cvalue_from_ref(FL(iostreamtype), ios_stderr, sizeof(ios_t), FL(Nil)));
-	setc(symbol("*stdin*" ), cvalue_from_ref(FL(iostreamtype), ios_stdin, sizeof(ios_t), FL(Nil)));
+	setc(symbol("*stdout*", false), cvalue_from_ref(FL(iostreamtype), ios_stdout, sizeof(ios_t), FL(Nil)));
+	setc(symbol("*stderr*", false), cvalue_from_ref(FL(iostreamtype), ios_stderr, sizeof(ios_t), FL(Nil)));
+	setc(symbol("*stdin*", false), cvalue_from_ref(FL(iostreamtype), ios_stdin, sizeof(ios_t), FL(Nil)));
 }
--- a/read.c
+++ b/read.c
@@ -235,7 +235,7 @@
 				}
 			}else if(cval >= 'a' && cval <= 'z'){
 				read_token(ctx, (char)cval, 0);
-				ctx->tokval = symbol(ctx->buf);
+				ctx->tokval = symbol(ctx->buf, true);
 				if(ctx->buf[1] == '\0') USED(cval); /* one character */
 				else if(ctx->tokval == FL(nulsym))       cval = 0x00;
 				else if(ctx->tokval == FL(alarmsym))     cval = 0x07;
@@ -333,7 +333,7 @@
 			}
 
 			ctx->toktype = TOK_SHARPSYM;
-			ctx->tokval = symbol(ctx->buf);
+			ctx->tokval = symbol(ctx->buf, true);
 		}else{
 			parse_error("unknown read macro");
 		}
@@ -357,7 +357,8 @@
 				return (ctx->toktype = TOK_NUM);
 		}
 		ctx->toktype = TOK_SYM;
-		ctx->tokval = symbol(strcmp(ctx->buf, "lambda") == 0 ? "λ" : ctx->buf);
+		char *name = (strcmp(ctx->buf, "lambda") == 0 || strcmp(ctx->buf, "λ") == 0) ? "λ" : ctx->buf;
+		ctx->tokval = symbol(name, name == ctx->buf);
 	}
 	return ctx->toktype;
 }
--- a/sixel.c
+++ b/sixel.c
@@ -252,6 +252,6 @@
 void
 fsixel_init(void)
 {
-	FL(fsosym) = symbol("sixel-output");
+	FL(fsosym) = symbol("sixel-output", false);
 	FL(fsotype) = define_opaque_type(FL(fsosym), sizeof(fso_t), &fso_vtable, nil);
 }
--- a/table.c
+++ b/table.c
@@ -197,6 +197,6 @@
 void
 table_init(void)
 {
-	FL(tablesym) = symbol("table");
+	FL(tablesym) = symbol("table", false);
 	FL(tabletype) = define_opaque_type(FL(tablesym), sizeof(htable_t), &table_vtable, nil);
 }