shithub: sl

Download patch

ref: 8bbdd2c99299b922e60a3e7868027909b97d918f
parent: 45de5e57e4f8eea540a5b4c39b5512c8513e6032
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Mar 18 14:35:53 EDT 2025

forbid modifying constants

--- a/src/builtins.c
+++ b/src/builtins.c
@@ -175,8 +175,9 @@
 {
 	argcount(nargs, 2);
 	sl_sym *sym = tosym(args[0]);
-	if(!isconst(sym))
-		sym->binding = args[1];
+	if(sl_unlikely(isconst(sym)))
+		const_error(sym);
+	sym->binding = args[1];
 	return args[1];
 }
 
@@ -184,8 +185,9 @@
 {
 	argcount(nargs, 1);
 	sl_sym *sym = tosym(args[0]);
-	if(!isconst(sym))
-		sym->binding = UNBOUND;
+	if(sl_unlikely(isconst(sym)))
+		const_error(sym);
+	sym->binding = UNBOUND;
 	return sl_void;
 }
 
--- a/src/sl.c
+++ b/src/sl.c
@@ -18,7 +18,7 @@
 sl_v sl_booleansym, sl_nullsym, sl_evalsym, sl_fnsym, sl_trimsym;
 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_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;
 
@@ -164,6 +164,17 @@
 }
 
 _Noreturn void
+const_error(const sl_sym *sym)
+{
+	lerrorf(
+		sl_errconst,
+		"modifying a %s is not permitted: %s",
+		iskeyword(sym) ? "keyword" : "constant",
+		sym->name
+	);
+}
+
+_Noreturn void
 unbound_error(sl_v sym)
 {
 	sl_raise(mk_listn(2, sl_errunbound, sym));
@@ -1253,6 +1264,7 @@
 	sl_errunbound = mk_csym("unbound-error");
 	sl_errkey = mk_csym("key-error");
 	sl_errmem = mk_csym("memory-error");
+	sl_errconst = mk_csym("const-error");
 	sl_errbounds = mk_csym("bounds-error");
 	sl_errdiv0 = mk_csym("divide-error");
 	sl_err = mk_csym("error");
--- a/src/sl.h
+++ b/src/sl.h
@@ -263,6 +263,7 @@
 _Noreturn void sl_raise(sl_v e);
 _Noreturn void type_error(const char *expected, sl_v got);
 _Noreturn void bounds_error(sl_v arr, sl_v ind);
+_Noreturn void const_error(const sl_sym *sym);
 _Noreturn void unbound_error(sl_v sym);
 _Noreturn void arity_error(int nargs, int c);
 
@@ -420,7 +421,7 @@
 extern sl_v sl_booleansym, sl_nullsym, sl_evalsym, sl_fnsym, sl_trimsym;
 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;
+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;
 
--- a/src/vm.h
+++ b/src/vm.h
@@ -848,9 +848,9 @@
 	v = vec_elt(v, i);
 	assert(issym(v));
 	sl_sym *sym = ptr(v);
-	v = sp[-1];
-	if(!isconst(sym))
-		sym->binding = v;
+	if(sl_unlikely(isconst(sym)))
+		const_error(sym);
+	sym->binding = sp[-1];
 	NEXT_OP;
 }