Skip to content

Commit

Permalink
vala: prevent defmacro! from mutating its argument
Browse files Browse the repository at this point in the history
  • Loading branch information
asarhaddon committed Oct 16, 2024
1 parent 192617c commit 7b51fd5
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 15 deletions.
22 changes: 17 additions & 5 deletions impls/vala/step8_macros.vala
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,26 @@ class Mal.Main : GLib.Object {
var sym = first as Mal.Sym;
switch (sym.v) {
case "def!":
case "defmacro!":
if (list.length() != 3)
throw new Mal.Error.BAD_PARAMS(
"def!: expected two values");
var val = define_eval(list.next.data, list.next.next.data, env);
if (sym.v == "defmacro!" && val is Mal.Function) {
(val as Mal.Function).is_macro = true;
}
return define_eval(list.next.data, list.next.next.data,
env);
case "defmacro!":
if (list.length() != 3)
throw new Mal.Error.BAD_PARAMS(
"defmacro!: expected two values");
var symkey = list.next.data as Mal.Sym;
if (symkey == null)
throw new Mal.Error.BAD_PARAMS(
"defmacro!: expects a symbol");
var val = EVAL(list.next.next.data, env) as Mal.Function;
if (val == null)
throw new Mal.Error.BAD_PARAMS(
"defmacro!: expected a function");
val = val.copy();
val.is_macro = true;
env.set(symkey, val);
return val;
case "let*":
if (list.length() != 3)
Expand Down
22 changes: 17 additions & 5 deletions impls/vala/step9_try.vala
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,26 @@ class Mal.Main : GLib.Object {
var sym = first as Mal.Sym;
switch (sym.v) {
case "def!":
case "defmacro!":
if (list.length() != 3)
throw new Mal.Error.BAD_PARAMS(
"def!: expected two values");
var val = define_eval(list.next.data, list.next.next.data, env);
if (sym.v == "defmacro!" && val is Mal.Function) {
(val as Mal.Function).is_macro = true;
}
return define_eval(list.next.data, list.next.next.data,
env);
case "defmacro!":
if (list.length() != 3)
throw new Mal.Error.BAD_PARAMS(
"defmacro!: expected two values");
var symkey = list.next.data as Mal.Sym;
if (symkey == null)
throw new Mal.Error.BAD_PARAMS(
"defmacro!: expects a symbol");
var val = EVAL(list.next.next.data, env) as Mal.Function;
if (val == null)
throw new Mal.Error.BAD_PARAMS(
"defmacro!: expected a function");
val = val.copy();
val.is_macro = true;
env.set(symkey, val);
return val;
case "let*":
if (list.length() != 3)
Expand Down
22 changes: 17 additions & 5 deletions impls/vala/stepA_mal.vala
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,26 @@ class Mal.Main : GLib.Object {
var sym = first as Mal.Sym;
switch (sym.v) {
case "def!":
case "defmacro!":
if (list.length() != 3)
throw new Mal.Error.BAD_PARAMS(
"def!: expected two values");
var val = define_eval(list.next.data, list.next.next.data, env);
if (sym.v == "defmacro!" && val is Mal.Function) {
(val as Mal.Function).is_macro = true;
}
return define_eval(list.next.data, list.next.next.data,
env);
case "defmacro!":
if (list.length() != 3)
throw new Mal.Error.BAD_PARAMS(
"defmacro!: expected two values");
var symkey = list.next.data as Mal.Sym;
if (symkey == null)
throw new Mal.Error.BAD_PARAMS(
"defmacro!: expects a symbol");
var val = EVAL(list.next.next.data, env) as Mal.Function;
if (val == null)
throw new Mal.Error.BAD_PARAMS(
"defmacro!: expected a function");
val = val.copy();
val.is_macro = true;
env.set(symkey, val);
return val;
case "let*":
if (list.length() != 3)
Expand Down

0 comments on commit 7b51fd5

Please sign in to comment.