Skip to content

Commit

Permalink
vala: fix self-host: fix defmacro! return value.
Browse files Browse the repository at this point in the history
The mal implementation uses the defmacro! function from the host
language/environment and assumes that it returns a macro function (and
ignores the environment modification effect). The vala implementation
was setting the is_macro flag at the wrong time so that the final
returned value from defmacro! was a function without the macro flag set.

Also, add a deferrable test of `defmacro!` to make sure it returns
a macro.
  • Loading branch information
kanaka committed Aug 21, 2024
1 parent a160866 commit 39563fd
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 19 deletions.
4 changes: 4 additions & 0 deletions impls/tests/step8_macros.mal
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ x
(let* [x (cond false "no" true "yes")] x)
;=>"yes"

;; Test return value of defmacro!
(let* [m (defmacro! _ (fn* [] 1))] (macro? m))
;=>true

;>>> soft=True
;>>> optional=True
;;
Expand Down
6 changes: 5 additions & 1 deletion impls/vala/core.vala
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,11 @@ class Mal.BuiltinFunctionKeyword : Mal.BuiltinFunction {
}
public override string name() { return "keyword"; }
public override Mal.Val call(Mal.List args) throws Mal.Error {
if (args.vs.length() != 1 || !(args.vs.data is Mal.String))
if (args.vs.length() != 1)
throw new Mal.Error.BAD_PARAMS("%s: expected one string", name());
else if (args.vs.data is Mal.Keyword)
return args.vs.data;
else if (!(args.vs.data is Mal.String))
throw new Mal.Error.BAD_PARAMS("%s: expected one string", name());
return new Mal.Keyword((args.vs.data as Mal.String).v);
}
Expand Down
12 changes: 6 additions & 6 deletions impls/vala/step8_macros.vala
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ class Mal.Main : GLib.Object {
}

private static Mal.Val define_eval(Mal.Val key, Mal.Val value,
Mal.Env env,
bool is_macro = false)
Mal.Env env)
throws Mal.Error {
var rootk = new GC.Root(key); (void)rootk;
var roote = new GC.Root(env); (void)roote;
Expand All @@ -81,8 +80,6 @@ class Mal.Main : GLib.Object {
throw new Mal.Error.BAD_PARAMS(
"let*: expected a symbol to define");
var val = EVAL(value, env);
if (val is Mal.Function)
(val as Mal.Function).is_macro = is_macro;
env.set(symkey, val);
return val;
}
Expand Down Expand Up @@ -209,8 +206,11 @@ class Mal.Main : GLib.Object {
if (list.length() != 3)
throw new Mal.Error.BAD_PARAMS(
"def!: expected two values");
return define_eval(list.next.data, list.next.next.data,
env, sym.v == "defmacro!");
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 val;
case "let*":
if (list.length() != 3)
throw new Mal.Error.BAD_PARAMS(
Expand Down
12 changes: 6 additions & 6 deletions impls/vala/step9_try.vala
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ class Mal.Main : GLib.Object {
}

private static Mal.Val define_eval(Mal.Val key, Mal.Val value,
Mal.Env env,
bool is_macro = false)
Mal.Env env)
throws Mal.Error {
var rootk = new GC.Root(key); (void)rootk;
var roote = new GC.Root(env); (void)roote;
Expand All @@ -82,8 +81,6 @@ class Mal.Main : GLib.Object {
throw new Mal.Error.BAD_PARAMS(
"let*: expected a symbol to define");
var val = EVAL(value, env);
if (val is Mal.Function)
(val as Mal.Function).is_macro = is_macro;
env.set(symkey, val);
return val;
}
Expand Down Expand Up @@ -212,8 +209,11 @@ class Mal.Main : GLib.Object {
if (list.length() != 3)
throw new Mal.Error.BAD_PARAMS(
"def!: expected two values");
return define_eval(list.next.data, list.next.next.data,
env, sym.v == "defmacro!");
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 val;
case "let*":
if (list.length() != 3)
throw new Mal.Error.BAD_PARAMS(
Expand Down
12 changes: 6 additions & 6 deletions impls/vala/stepA_mal.vala
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ class Mal.Main : GLib.Object {
}

private static Mal.Val define_eval(Mal.Val key, Mal.Val value,
Mal.Env env,
bool is_macro = false)
Mal.Env env)
throws Mal.Error {
var rootk = new GC.Root(key); (void)rootk;
var roote = new GC.Root(env); (void)roote;
Expand All @@ -82,8 +81,6 @@ class Mal.Main : GLib.Object {
throw new Mal.Error.BAD_PARAMS(
"let*: expected a symbol to define");
var val = EVAL(value, env);
if (val is Mal.Function)
(val as Mal.Function).is_macro = is_macro;
env.set(symkey, val);
return val;
}
Expand Down Expand Up @@ -212,8 +209,11 @@ class Mal.Main : GLib.Object {
if (list.length() != 3)
throw new Mal.Error.BAD_PARAMS(
"def!: expected two values");
return define_eval(list.next.data, list.next.next.data,
env, sym.v == "defmacro!");
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 val;
case "let*":
if (list.length() != 3)
throw new Mal.Error.BAD_PARAMS(
Expand Down

0 comments on commit 39563fd

Please sign in to comment.