shithub: sl

Download patch

ref: 10761d0795aac177de09b4069e26a651e78d944f
parent: 37ccd97debd294f6d66ab64ad954ed866920d1d8
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sun Apr 27 19:51:06 EDT 2025

refactor #\... to avoid using symbols

Also provide more names and aliases while at it.

--- a/src/print.c
+++ b/src/print.c
@@ -669,19 +669,11 @@
 		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(r < nelem(ascii2name))
+			outs(f, ascii2name[r]);
+		else if(r == 0x7f)
+			outsc(f, "delete");
+		else{
 			if(sl_iswprint(r))
 				outs(f, seq);
 			else{
@@ -690,7 +682,6 @@
 					goto err;
 				sl.hpos += n;
 			}
-			break;
 		}
 	}
 	return;
--- a/src/read.c
+++ b/src/read.c
@@ -11,6 +11,16 @@
 	TOK_OPENC, TOK_CLOSEC, TOK_VERBATIM,
 };
 
+static Tbl *name2rune;
+
+const char *ascii2name[0x20+1] = {
+	"nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
+	"backspace", "tab", "newline", "vt", "page", "return", "so", "si",
+	"dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
+	"can", "em", "sub", "esc", "fs", "gs", "rs", "us",
+	"space",
+};
+
 #define PAtLoc "at %"PRIu32":%"PRIu32
 
 typedef struct Rctx Rctx;
@@ -234,36 +244,25 @@
 			ctx->toktype = TOK_SHARPQUOTE;
 		else if(c == '\\'){
 			Rune cval;
+			ctx->tokval = sl_nil;
 			if(ios_getrune(RS, &cval) == IOS_EOF)
 				parse_error(ctx, "EOI in character constant");
-			if(cval == 'u' || cval == 'U' || cval == 'x'){
-				read_token(ctx, 'u', 0);
-				if(ctx->buf[1] != '\0'){ // not a solitary 'u','U','x'
-					if(!sl_read_numtok(&ctx->buf[1], &ctx->tokval, 16))
-						parse_error(ctx, "invalid hex character constant: %s", &ctx->buf[1]);
-					cval = numval(ctx->tokval);
+			if((cval >= 'a' && cval <= 'z') || cval == 'U'){
+				const char *k;
+				read_token(ctx, cval, false);
+				if(ctx->buf[1] != 0){
+					if(cval == 'u' || cval == 'U' || cval == 'x'){
+						if(!sl_read_numtok(&ctx->buf[1], &ctx->tokval, 16))
+							parse_error(ctx, "invalid hex character constant: %s", &ctx->buf[1]);
+						ctx->tokval = mk_rune(numval(ctx->tokval));
+					}else if(!Tgetkv(name2rune, ctx->buf, strlen(ctx->buf), &k, (void**)&ctx->tokval)){
+						parse_error(ctx, "unknown character %s", ctx->buf);
+					}
 				}
-			}else if(cval >= 'a' && cval <= 'z'){
-				read_token(ctx, cval, 0);
-				ctx->tokval = mk_sym(ctx->buf, true);
-				if(ctx->buf[1] == '\0') USED(cval); /* one character */
-				else if(ctx->tokval == sl_nulsym)       cval = 0x00;
-				else if(ctx->tokval == sl_alarmsym)     cval = 0x07;
-				else if(ctx->tokval == sl_backspacesym) cval = 0x08;
-				else if(ctx->tokval == sl_tabsym)       cval = 0x09;
-				else if(ctx->tokval == sl_linefeedsym)  cval = 0x0A;
-				else if(ctx->tokval == sl_newlinesym)   cval = 0x0A;
-				else if(ctx->tokval == sl_vtabsym)      cval = 0x0B;
-				else if(ctx->tokval == sl_pagesym)      cval = 0x0C;
-				else if(ctx->tokval == sl_returnsym)    cval = 0x0D;
-				else if(ctx->tokval == sl_escsym)       cval = 0x1B;
-				else if(ctx->tokval == sl_spacesym)     cval = 0x20;
-				else if(ctx->tokval == sl_deletesym)    cval = 0x7F;
-				else
-					parse_error(ctx, "unknown character #\\%s", ctx->buf);
 			}
 			ctx->toktype = TOK_NUM;
-			ctx->tokval = mk_rune(cval);
+			if(ctx->tokval == sl_nil)
+				ctx->tokval = mk_rune(cval);
 		}else if(c == '('){
 			ctx->toktype = TOK_SHARPOPEN;
 		}else if(c == '<'){
@@ -793,4 +792,30 @@
 	sl.readstate = state.prev;
 	free_readstate(&state);
 	return v;
+}
+
+#define mk_name2rune(r, s) mk_rune2name_(r, s, strlen(s))
+
+static Rune
+mk_rune2name_(Rune r, const char *str, int len)
+{
+	name2rune = Tsetl(name2rune, str, len, (void*)mk_rune(r));
+	return r;
+}
+
+void
+sl_read_init(void)
+{
+	for(Rune r = 0; r < nelem(ascii2name); r++)
+		mk_name2rune(r, ascii2name[r]);
+
+	mk_name2rune(0x00, "null");
+	mk_name2rune(0x08, "bs");
+	mk_name2rune(mk_name2rune(0x0a, "nl"), "linefeed");
+	mk_name2rune(0x0b, "vtab");
+	mk_name2rune(0x0c, "ff");
+	mk_name2rune(0x0d, "cr");
+	mk_name2rune(0x1b, "escape");
+	mk_name2rune(0x20, "sp");
+	mk_name2rune(mk_name2rune(0x7f, "delete"), "del");
 }
--- a/src/read.h
+++ b/src/read.h
@@ -1,7 +1,10 @@
 #pragma once
 
+extern const char *ascii2name[0x20+1];
+
 sl_v sl_read_sexpr(sl_v f, bool ws);
 bool sl_read_numtok(const char *tok, sl_v *pval, int base);
+void sl_read_init(void);
 
 // defines which characters are ordinary symbol characters.
 // exceptions are '.', which is an ordinary symbol character
--- a/src/sl.c
+++ b/src/sl.c
@@ -16,8 +16,6 @@
 sl_v sl_conssym, sl_symsym, sl_fixnumsym, sl_vecsym, sl_builtinsym, sl_vu8sym;
 sl_v sl_defsym, sl_defmacrosym, sl_forsym, sl_setqsym, sl_listsym;
 sl_v sl_booleansym, sl_nullsym, sl_evalsym, sl_fnsym, sl_trimsym, sl_strsym;
-sl_v sl_nulsym, sl_alarmsym, sl_backspacesym, sl_tabsym, sl_linefeedsym, sl_newlinesym;
-sl_v sl_vtabsym, sl_pagesym, sl_returnsym, sl_escsym, sl_spacesym, sl_deletesym;
 sl_v sl_errio, sl_errparse, sl_errtype, sl_errarg, sl_errmem, sl_errconst;
 sl_v sl_errdiv0, sl_errbounds, sl_err, sl_errkey, sl_errunbound, sl_erroom;
 sl_v sl_emptyvec, sl_emptystr, sl_vecstructsym, sl_structsym;
@@ -1419,18 +1417,7 @@
 	sl_vu8sym = mk_csym("vu8");
 	sl_fnsym = mk_csym("fn");
 	sl_trimsym = mk_csym(":trim");
-	sl_nulsym = mk_csym("nul");
-	sl_alarmsym = mk_csym("alarm");
-	sl_backspacesym = mk_csym("backspace");
-	sl_tabsym = mk_csym("tab");
-	sl_linefeedsym = mk_csym("linefeed");
-	sl_vtabsym = mk_csym("vtab");
-	sl_pagesym = mk_csym("page");
-	sl_returnsym = mk_csym("return");
-	sl_escsym = mk_csym("esc");
-	sl_spacesym = mk_csym("space");
-	sl_deletesym = mk_csym("delete");
-	sl_newlinesym = mk_csym("newline");
+
 	sl_vecstructsym = mk_csym("%struct%");
 	sl_structsym = mk_csym("struct");
 	sl_builtinssym = mk_csym("*builtins*");
@@ -1453,6 +1440,7 @@
 	sl_emptyvec = tagptr(alloc_words(2), TAG_VEC);
 	vec_setsize(sl_emptyvec, 0, VEC_VEC);
 
+	sl_read_init();
 	cvalues_init();
 
 	set(mk_csym("*os-name*"), cvalue_static_cstr(__os_name__));
--- a/src/sl.h
+++ b/src/sl.h
@@ -132,7 +132,7 @@
 extern sl_type *unboxedtypes[T_UNBOXED_NUM];
 extern sl_v unboxedtypesyms[T_UNBOXED_NUM];
 
-#define mk_rune(r) ((r)<<TAG_EXT_BITS | 0xfc)
+#define mk_rune(r) (((sl_v)(r))<<TAG_EXT_BITS | 0xfc)
 #define isrune(v) (((v) & 0xff) == 0xfc)
 #define torune(v) ((v)>>8)
 
@@ -457,8 +457,6 @@
 extern sl_v sl_conssym, sl_symsym, sl_fixnumsym, sl_vecsym, sl_builtinsym, sl_vu8sym;
 extern sl_v sl_defsym, sl_defmacrosym, sl_forsym, sl_setqsym, sl_listsym;
 extern sl_v sl_booleansym, sl_nullsym, sl_evalsym, sl_fnsym, sl_trimsym, sl_strsym;
-extern sl_v sl_nulsym, sl_alarmsym, sl_backspacesym, sl_tabsym, sl_linefeedsym, sl_newlinesym;
-extern sl_v sl_vtabsym, sl_pagesym, sl_returnsym, sl_escsym, sl_spacesym, sl_deletesym;
 extern sl_v sl_errio, sl_errparse, sl_errtype, sl_errarg, sl_errmem, sl_errconst;
 extern sl_v sl_errdiv0, sl_errbounds, sl_err, sl_errkey, sl_errunbound, sl_erroom;
 extern sl_v sl_emptyvec, sl_emptystr;