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;
}