Skip to content

Commit

Permalink
vala: merge eval_ast into eval, add DEBUG-EVAL
Browse files Browse the repository at this point in the history
  • Loading branch information
asarhaddon committed Oct 16, 2024
1 parent b463373 commit 967c733
Show file tree
Hide file tree
Showing 10 changed files with 325 additions and 451 deletions.
11 changes: 2 additions & 9 deletions impls/vala/env.vala
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,11 @@ class Mal.Env : GC.Object {
data[key] = f;
}

public Mal.Env? find(Mal.Sym key) {
public new Mal.Val? get(Mal.Sym key) {
if (key in data)
return this;
return data[key];
if (outer == null)
return null;
return outer.find(key);
}

public new Mal.Val get(Mal.Sym key) throws Mal.Error {
var found = find(key);
if (found == null)
throw new Error.ENV_LOOKUP_FAILED("'%s' not found", key.v);
return found.data[key];
}
}
38 changes: 15 additions & 23 deletions impls/vala/step2_eval.vala
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,15 @@ class Mal.Main : GLib.Object {
}
}

public static Mal.Val eval_ast(Mal.Val ast, Mal.Env env)
public static Mal.Val EVAL(Mal.Val ast, Mal.Env env)
throws Mal.Error {
var roota = new GC.Root(ast); (void)roota;
var ast_root = new GC.Root(ast); (void)ast_root;
GC.Core.maybe_collect();

// stdout.printf("EVAL: %s\n", pr_str(ast));

if (ast is Mal.Sym)
return env.get(ast as Mal.Sym);
if (ast is Mal.List) {
var result = new Mal.List.empty();
var root = new GC.Root(result); (void)root;
foreach (var elt in (ast as Mal.List).vs)
result.vs.append(EVAL(elt, env));
return result;
}
if (ast is Mal.Vector) {
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
Expand All @@ -116,25 +113,20 @@ class Mal.Main : GLib.Object {
result.insert(key, EVAL(map[key], env));
return result;
}
return ast;
}

public static Mal.Val EVAL(Mal.Val ast, Mal.Env env)
throws Mal.Error {
var ast_root = new GC.Root(ast); (void)ast_root;
GC.Core.maybe_collect();

if (ast is Mal.List) {
unowned GLib.List<Mal.Val> list = (ast as Mal.List).vs;
if (list.first() == null)
return ast;
var newlist = eval_ast(ast, env) as Mal.List;
unowned GLib.List<Mal.Val> firstlink = newlist.vs.first();
var fn = firstlink.data as Mal.BuiltinFunction;
newlist.vs.remove_link(firstlink);
return fn.call(newlist);

Mal.Val firstdata = EVAL(list.first().data, env);
var newlist = new Mal.List.empty();
var root = new GC.Root(newlist); (void)root;
for (var iter = (ast as Mal.Listlike).iter().step(); iter.nonempty(); iter.step())
newlist.vs.append(EVAL(iter.deref(), env));

return (firstdata as Mal.BuiltinFunction).call(newlist);
} else {
return eval_ast(ast, env);
return ast;
}
}

Expand Down
71 changes: 34 additions & 37 deletions impls/vala/step3_env.vala
Original file line number Diff line number Diff line change
Expand Up @@ -69,38 +69,6 @@ class Mal.Main : GLib.Object {
}
}

public static Mal.Val eval_ast(Mal.Val ast, Mal.Env env)
throws Mal.Error {
var roota = new GC.Root(ast); (void)roota;
var roote = new GC.Root(env); (void)roote;
if (ast is Mal.Sym)
return env.get(ast as Mal.Sym);
if (ast is Mal.List) {
var result = new Mal.List.empty();
var root = new GC.Root(result); (void)root;
foreach (var elt in (ast as Mal.List).vs)
result.vs.append(EVAL(elt, env));
return result;
}
if (ast is Mal.Vector) {
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
var root = new GC.Root(result); (void)root;
var map = (ast as Mal.Hashmap).vs;
foreach (var key in map.get_keys())
result.insert(key, EVAL(map[key], env));
return result;
}
return ast;
}

private static Mal.Val define_eval(Mal.Val key, Mal.Val value,
Mal.Env env)
throws Mal.Error {
Expand All @@ -115,12 +83,40 @@ class Mal.Main : GLib.Object {
return val;
}

dbgevalsym = new Mal.Sym("DEBUG-EVAL");

public static Mal.Val EVAL(Mal.Val ast, Mal.Env env)
throws Mal.Error {
var ast_root = new GC.Root(ast); (void)ast_root;
var env_root = new GC.Root(env); (void)env_root;
GC.Core.maybe_collect();

var dbgeval = env.get(dbgevalsym);
if (dbgeval != null && dbgeval.truth_value())
stdout.printf("EVAL: %s\n", pr_str(ast));

if (ast is Mal.Sym)
var key = ast as Mal.Sym;
var val = env.get(key);
if (val == null)
throw new Error.ENV_LOOKUP_FAILED("'%s' not found", key.v);
return val;
if (ast is Mal.Vector) {
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
var root = new GC.Root(result); (void)root;
var map = (ast as Mal.Hashmap).vs;
foreach (var key in map.get_keys())
result.insert(key, EVAL(map[key], env));
return result;
}
if (ast is Mal.List) {
unowned GLib.List<Mal.Val> list = (ast as Mal.List).vs;
if (list.first() == null)
Expand Down Expand Up @@ -169,10 +165,11 @@ class Mal.Main : GLib.Object {
}
}

var newlist = eval_ast(ast, env) as Mal.List;
unowned GLib.List<Mal.Val> firstlink = newlist.vs.first();
Mal.Val firstdata = firstlink.data;
newlist.vs.remove_link(firstlink);
Mal.Val firstdata = EVAL(list.first().data, env);
var newlist = new Mal.List.empty();
var root = new GC.Root(newlist); (void)root;
for (var iter = (ast as Mal.Listlike).iter().step(); iter.nonempty(); iter.step())
newlist.vs.append(EVAL(iter.deref(), env));

if (firstdata is Mal.BuiltinFunction) {
return (firstdata as Mal.BuiltinFunction).call(newlist);
Expand All @@ -181,7 +178,7 @@ class Mal.Main : GLib.Object {
"bad value at start of list");
}
} else {
return eval_ast(ast, env);
return ast;
}
}

Expand Down
71 changes: 34 additions & 37 deletions impls/vala/step4_if_fn_do.vala
Original file line number Diff line number Diff line change
Expand Up @@ -24,38 +24,6 @@ class Mal.Main: GLib.Object {
}
}

public static Mal.Val eval_ast(Mal.Val ast, Mal.Env env)
throws Mal.Error {
var roota = new GC.Root(ast); (void)roota;
var roote = new GC.Root(env); (void)roote;
if (ast is Mal.Sym)
return env.get(ast as Mal.Sym);
if (ast is Mal.List) {
var result = new Mal.List.empty();
var root = new GC.Root(result); (void)root;
foreach (var elt in (ast as Mal.List).vs)
result.vs.append(EVAL(elt, env));
return result;
}
if (ast is Mal.Vector) {
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
var root = new GC.Root(result); (void)root;
var map = (ast as Mal.Hashmap).vs;
foreach (var key in map.get_keys())
result.insert(key, EVAL(map[key], env));
return result;
}
return ast;
}

private static Mal.Val define_eval(Mal.Val key, Mal.Val value,
Mal.Env env)
throws Mal.Error {
Expand All @@ -70,12 +38,40 @@ class Mal.Main: GLib.Object {
return val;
}

dbgevalsym = new Mal.Sym("DEBUG-EVAL");

public static Mal.Val EVAL(Mal.Val ast, Mal.Env env)
throws Mal.Error {
var ast_root = new GC.Root(ast); (void)ast_root;
var env_root = new GC.Root(env); (void)env_root;
GC.Core.maybe_collect();

var dbgeval = env.get(dbgevalsym);
if (dbgeval != null && dbgeval.truth_value())
stdout.printf("EVAL: %s\n", pr_str(ast));

if (ast is Mal.Sym)
var key = ast as Mal.Sym;
var val = env.get(key);
if (val == null)
throw new Error.ENV_LOOKUP_FAILED("'%s' not found", key.v);
return val;
if (ast is Mal.Vector) {
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
var root = new GC.Root(result); (void)root;
var map = (ast as Mal.Hashmap).vs;
foreach (var key in map.get_keys())
result.insert(key, EVAL(map[key], env));
return result;
}
if (ast is Mal.List) {
unowned GLib.List<Mal.Val> list = (ast as Mal.List).vs;
if (list.first() == null)
Expand Down Expand Up @@ -161,10 +157,11 @@ class Mal.Main: GLib.Object {
}
}

var newlist = eval_ast(ast, env) as Mal.List;
unowned GLib.List<Mal.Val> firstlink = newlist.vs.first();
Mal.Val firstdata = firstlink.data;
newlist.vs.remove_link(firstlink);
Mal.Val firstdata = EVAL(list.first().data, env);
var newlist = new Mal.List.empty();
var root = new GC.Root(newlist); (void)root;
for (var iter = (ast as Mal.Listlike).iter().step(); iter.nonempty(); iter.step())
newlist.vs.append(EVAL(iter.deref(), env));

if (firstdata is Mal.BuiltinFunction) {
return (firstdata as Mal.BuiltinFunction).call(newlist);
Expand All @@ -178,7 +175,7 @@ class Mal.Main: GLib.Object {
"bad value at start of list");
}
} else {
return eval_ast(ast, env);
return ast;
}
}

Expand Down
73 changes: 36 additions & 37 deletions impls/vala/step5_tco.vala
Original file line number Diff line number Diff line change
Expand Up @@ -24,38 +24,6 @@ class Mal.Main : GLib.Object {
}
}

public static Mal.Val eval_ast(Mal.Val ast, Mal.Env env)
throws Mal.Error {
var roota = new GC.Root(ast); (void)roota;
var roote = new GC.Root(env); (void)roote;
if (ast is Mal.Sym)
return env.get(ast as Mal.Sym);
if (ast is Mal.List) {
var result = new Mal.List.empty();
var root = new GC.Root(result); (void)root;
foreach (var elt in (ast as Mal.List).vs)
result.vs.append(EVAL(elt, env));
return result;
}
if (ast is Mal.Vector) {
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
var root = new GC.Root(result); (void)root;
var map = (ast as Mal.Hashmap).vs;
foreach (var key in map.get_keys())
result.insert(key, EVAL(map[key], env));
return result;
}
return ast;
}

private static Mal.Val define_eval(Mal.Val key, Mal.Val value,
Mal.Env env)
throws Mal.Error {
Expand All @@ -70,6 +38,8 @@ class Mal.Main : GLib.Object {
return val;
}

dbgevalsym = new Mal.Sym("DEBUG-EVAL");

public static Mal.Val EVAL(Mal.Val ast_, Mal.Env env_)
throws Mal.Error {
// Copy the implicitly 'unowned' function arguments into
Expand All @@ -85,6 +55,33 @@ class Mal.Main : GLib.Object {
ast_root.obj = ast;
env_root.obj = env;
GC.Core.maybe_collect();

var dbgeval = env.get(dbgevalsym);
if (dbgeval != null && dbgeval.truth_value())
stdout.printf("EVAL: %s\n", pr_str(ast));

if (ast is Mal.Sym)
var key = ast as Mal.Sym;
var val = env.get(key);
if (val == null)
throw new Error.ENV_LOOKUP_FAILED("'%s' not found", key.v);
return val;
if (ast is Mal.Vector) {
var vec = ast as Mal.Vector;
var result = new Mal.Vector.with_size(vec.length);
var root = new GC.Root(result); (void)root;
for (var i = 0; i < vec.length; i++)
result[i] = EVAL(vec[i], env);
return result;
}
if (ast is Mal.Hashmap) {
var result = new Mal.Hashmap();
var root = new GC.Root(result); (void)root;
var map = (ast as Mal.Hashmap).vs;
foreach (var key in map.get_keys())
result.insert(key, EVAL(map[key], env));
return result;
}
if (ast is Mal.List) {
unowned GLib.List<Mal.Val> list = (ast as Mal.List).vs;
if (list.first() == null)
Expand Down Expand Up @@ -172,10 +169,12 @@ class Mal.Main : GLib.Object {
}
}

var newlist = eval_ast(ast, env) as Mal.List;
unowned GLib.List<Mal.Val> firstlink = newlist.vs.first();
Mal.Val firstdata = firstlink.data;
newlist.vs.remove_link(firstlink);
Mal.Val firstdata = EVAL(list.first().data, env);
var newlist = new Mal.List.empty();
var root = new GC.Root(newlist); (void)root;
for (var iter = (ast as Mal.Listlike).iter().step();
iter.nonempty(); iter.step())
newlist.vs.append(EVAL(iter.deref(), env));

if (firstdata is Mal.BuiltinFunction) {
return (firstdata as Mal.BuiltinFunction).call(newlist);
Expand All @@ -189,7 +188,7 @@ class Mal.Main : GLib.Object {
"bad value at start of list");
}
} else {
return eval_ast(ast, env);
return ast;
}
}
}
Expand Down
Loading

0 comments on commit 967c733

Please sign in to comment.