From b8ee29b22fbaa7a01f2754b4d6dd9af52e02017c Mon Sep 17 00:00:00 2001 From: Joel Martin Date: Thu, 18 Dec 2014 20:33:49 -0600 Subject: All: add keywords. Also, fix nth and count to match cloure. --- cs/core.cs | 31 +++++++++++++++++++++++++++++-- cs/env.cs | 14 +++++++------- cs/printer.cs | 4 +++- cs/reader.cs | 6 ++++-- cs/step2_eval.cs | 2 +- cs/step3_env.cs | 21 ++++++++++++--------- cs/step4_if_fn_do.cs | 11 +++++------ cs/step5_tco.cs | 11 +++++------ cs/step6_file.cs | 16 ++++++++-------- cs/step7_quote.cs | 16 ++++++++-------- cs/step8_macros.cs | 24 ++++++++++++------------ cs/step9_try.cs | 24 ++++++++++++------------ cs/stepA_interop.cs | 24 ++++++++++++------------ cs/types.cs | 4 +++- 14 files changed, 121 insertions(+), 87 deletions(-) (limited to 'cs') diff --git a/cs/core.cs b/cs/core.cs index 8bbf6be..3e40681 100644 --- a/cs/core.cs +++ b/cs/core.cs @@ -35,6 +35,19 @@ namespace Mal { static MalFunc symbol_Q = new MalFunc( a => a[0] is MalSymbol ? True : False); + static MalFunc keyword = new MalFunc( + a => new MalString("\u029e" + ((MalString)a[0]).getValue())); + + static MalFunc keyword_Q = new MalFunc( + a => { + if (a[0] is MalString && + ((MalString)a[0]).getValue()[0] == '\u029e') { + return True; + } else { + return False; + } + } ); + // Number functions static MalFunc time_ms = new MalFunc( @@ -159,7 +172,15 @@ namespace Mal { }); static MalFunc nth = new MalFunc( - a => ((MalList)a[0])[ (int)((MalInt)a[1]).getValue() ]); + a => { + var idx = (int)((MalInt)a[1]).getValue(); + if (idx < ((MalList)a[0]).size()) { + return ((MalList)a[0])[idx]; + } else { + throw new Mal.types.MalException( + "nth: index out of range"); + } + }); static MalFunc first = new MalFunc( a => ((MalList)a[0])[0]); @@ -171,7 +192,11 @@ namespace Mal { a => ((MalList)a[0]).size() == 0 ? True : False); static MalFunc count = new MalFunc( - a => new MalInt(((MalList)a[0]).size())); + a => { + return (a[0] == Nil) + ? new MalInt(0) + :new MalInt(((MalList)a[0]).size()); + }); static MalFunc conj = new MalFunc( a => { @@ -254,6 +279,8 @@ namespace Mal { {"false?", false_Q}, {"symbol", new MalFunc(a => new MalSymbol((MalString)a[0]))}, {"symbol?", symbol_Q}, + {"keyword", keyword}, + {"keyword?", keyword_Q}, {"pr-str", pr_str}, {"str", str}, diff --git a/cs/env.cs b/cs/env.cs index cb5318f..39ab100 100644 --- a/cs/env.cs +++ b/cs/env.cs @@ -26,8 +26,8 @@ namespace Mal { } } - public Env find(string key) { - if (data.ContainsKey(key)) { + public Env find(MalSymbol key) { + if (data.ContainsKey(key.getName())) { return this; } else if (outer != null) { return outer.find(key); @@ -36,18 +36,18 @@ namespace Mal { } } - public MalVal get(string key) { + public MalVal get(MalSymbol key) { Env e = find(key); if (e == null) { throw new Mal.types.MalException( - "'" + key + "' not found"); + "'" + key.getName() + "' not found"); } else { - return e.data[key]; + return e.data[key.getName()]; } } - public Env set(string key, MalVal value) { - data[key] = value; + public Env set(MalSymbol key, MalVal value) { + data[key.getName()] = value; return this; } } diff --git a/cs/printer.cs b/cs/printer.cs index b5e8c63..8b10dd1 100644 --- a/cs/printer.cs +++ b/cs/printer.cs @@ -20,7 +20,9 @@ namespace Mal { string delim, bool print_readably) { List strs = new List(); foreach (KeyValuePair entry in value) { - if (print_readably) { + if (entry.Key.Length > 0 && entry.Key[0] == '\u029e') { + strs.Add(":" + entry.Key.Substring(1)); + } else if (print_readably) { strs.Add("\"" + entry.Key.ToString() + "\""); } else { strs.Add(entry.Key.ToString()); diff --git a/cs/reader.cs b/cs/reader.cs index dbc74af..10973aa 100644 --- a/cs/reader.cs +++ b/cs/reader.cs @@ -53,7 +53,7 @@ namespace Mal { public static MalVal read_atom(Reader rdr) { string token = rdr.next(); - string pattern = @"(^-?[0-9]+$)|(^-?[0-9][0-9.]*$)|(^nil$)|(^true$)|(^false$)|^("".*"")$|(^[^""]*$)"; + string pattern = @"(^-?[0-9]+$)|(^-?[0-9][0-9.]*$)|(^nil$)|(^true$)|(^false$)|^("".*"")$|:(.*)|(^[^""]*$)"; Regex regex = new Regex(pattern); Match match = regex.Match(token); //Console.WriteLine("token: ^" + token + "$"); @@ -75,7 +75,9 @@ namespace Mal { .Replace("\\n", "\n"); return new Mal.types.MalString(str); } else if (match.Groups[7].Value != String.Empty) { - return new Mal.types.MalSymbol(match.Groups[7].Value); + return new Mal.types.MalString("\u029e" + match.Groups[7].Value); + } else if (match.Groups[8].Value != String.Empty) { + return new Mal.types.MalSymbol(match.Groups[8].Value); } else { throw new ParseError("unrecognized '" + match.Groups[0] + "'"); } diff --git a/cs/step2_eval.cs b/cs/step2_eval.cs index 1e3866e..8c68336 100644 --- a/cs/step2_eval.cs +++ b/cs/step2_eval.cs @@ -45,7 +45,7 @@ namespace Mal { static MalVal EVAL(MalVal orig_ast, Dictionary env) { MalVal a0; - //System.out.println("EVAL: " + printer._pr_str(orig_ast, true)); + //Console.WriteLine("EVAL: " + printer._pr_str(orig_ast, true)); if (!orig_ast.list_Q()) { return eval_ast(orig_ast, env); } diff --git a/cs/step3_env.cs b/cs/step3_env.cs index 9977811..6c4f2fe 100644 --- a/cs/step3_env.cs +++ b/cs/step3_env.cs @@ -22,8 +22,7 @@ namespace Mal { // eval static MalVal eval_ast(MalVal ast, Env env) { if (ast is MalSymbol) { - MalSymbol sym = (MalSymbol)ast; - return env.get(sym.getName()); + return env.get((MalSymbol)ast); } else if (ast is MalList) { MalList old_lst = (MalList)ast; MalList new_lst = ast.list_Q() ? new MalList() @@ -47,7 +46,7 @@ namespace Mal { static MalVal EVAL(MalVal orig_ast, Env env) { MalVal a0, a1, a2, res; MalList el; - //System.out.println("EVAL: " + printer._pr_str(orig_ast, true)); + //Console.WriteLine("EVAL: " + printer._pr_str(orig_ast, true)); if (!orig_ast.list_Q()) { return eval_ast(orig_ast, env); } @@ -66,7 +65,7 @@ namespace Mal { a1 = ast[1]; a2 = ast[2]; res = EVAL(a2, env); - env.set(((MalSymbol)a1).getName(), res); + env.set((MalSymbol)a1, res); return res; case "let*": a1 = ast[1]; @@ -77,7 +76,7 @@ namespace Mal { for(int i=0; i<((MalList)a1).size(); i+=2) { key = (MalSymbol)((MalList)a1)[i]; val = ((MalList)a1)[i+1]; - let_env.set(key.getName(), EVAL(val, let_env)); + let_env.set(key, EVAL(val, let_env)); } return EVAL(a2, let_env); default: @@ -96,10 +95,14 @@ namespace Mal { static void Main(string[] args) { var repl_env = new Mal.env.Env(null); Func RE = (string str) => EVAL(READ(str), repl_env); - repl_env.set("+", new MalFunc(a => (MalInt)a[0] + (MalInt)a[1]) ); - repl_env.set("-", new MalFunc(a => (MalInt)a[0] - (MalInt)a[1]) ); - repl_env.set("*", new MalFunc(a => (MalInt)a[0] * (MalInt)a[1]) ); - repl_env.set("/", new MalFunc(a => (MalInt)a[0] / (MalInt)a[1]) ); + repl_env.set(new MalSymbol("+"), new MalFunc( + a => (MalInt)a[0] + (MalInt)a[1]) ); + repl_env.set(new MalSymbol("-"), new MalFunc( + a => (MalInt)a[0] - (MalInt)a[1]) ); + repl_env.set(new MalSymbol("*"), new MalFunc( + a => (MalInt)a[0] * (MalInt)a[1]) ); + repl_env.set(new MalSymbol("/"), new MalFunc( + a => (MalInt)a[0] / (MalInt)a[1]) ); if (args.Length > 0 && args[0] == "--raw") { Mal.readline.mode = Mal.readline.Mode.Raw; diff --git a/cs/step4_if_fn_do.cs b/cs/step4_if_fn_do.cs index ff8c3b9..aefe226 100644 --- a/cs/step4_if_fn_do.cs +++ b/cs/step4_if_fn_do.cs @@ -22,8 +22,7 @@ namespace Mal { // eval static MalVal eval_ast(MalVal ast, Env env) { if (ast is MalSymbol) { - MalSymbol sym = (MalSymbol)ast; - return env.get(sym.getName()); + return env.get((MalSymbol)ast); } else if (ast is MalList) { MalList old_lst = (MalList)ast; MalList new_lst = ast.list_Q() ? new MalList() @@ -47,7 +46,7 @@ namespace Mal { static MalVal EVAL(MalVal orig_ast, Env env) { MalVal a0, a1, a2, a3, res; MalList el; - //System.out.println("EVAL: " + printer._pr_str(orig_ast, true)); + //Console.WriteLine("EVAL: " + printer._pr_str(orig_ast, true)); if (!orig_ast.list_Q()) { return eval_ast(orig_ast, env); } @@ -65,7 +64,7 @@ namespace Mal { a1 = ast[1]; a2 = ast[2]; res = EVAL(a2, env); - env.set(((MalSymbol)a1).getName(), res); + env.set((MalSymbol)a1, res); return res; case "let*": a1 = ast[1]; @@ -76,7 +75,7 @@ namespace Mal { for(int i=0; i<((MalList)a1).size(); i+=2) { key = (MalSymbol)((MalList)a1)[i]; val = ((MalList)a1)[i+1]; - let_env.set(key.getName(), EVAL(val, let_env)); + let_env.set(key, EVAL(val, let_env)); } return EVAL(a2, let_env); case "do": @@ -123,7 +122,7 @@ namespace Mal { // core.cs: defined using C# foreach (var entry in core.ns) { - repl_env.set(entry.Key, entry.Value); + repl_env.set(new MalSymbol(entry.Key), entry.Value); } // core.mal: defined using the language itself diff --git a/cs/step5_tco.cs b/cs/step5_tco.cs index f1307f0..55d414a 100644 --- a/cs/step5_tco.cs +++ b/cs/step5_tco.cs @@ -22,8 +22,7 @@ namespace Mal { // eval static MalVal eval_ast(MalVal ast, Env env) { if (ast is MalSymbol) { - MalSymbol sym = (MalSymbol)ast; - return env.get(sym.getName()); + return env.get((MalSymbol)ast); } else if (ast is MalList) { MalList old_lst = (MalList)ast; MalList new_lst = ast.list_Q() ? new MalList() @@ -50,7 +49,7 @@ namespace Mal { while (true) { - //System.out.println("EVAL: " + printer._pr_str(orig_ast, true)); + //Console.WriteLine("EVAL: " + printer._pr_str(orig_ast, true)); if (!orig_ast.list_Q()) { return eval_ast(orig_ast, env); } @@ -68,7 +67,7 @@ namespace Mal { a1 = ast[1]; a2 = ast[2]; res = EVAL(a2, env); - env.set(((MalSymbol)a1).getName(), res); + env.set((MalSymbol)a1, res); return res; case "let*": a1 = ast[1]; @@ -79,7 +78,7 @@ namespace Mal { for(int i=0; i<((MalList)a1).size(); i+=2) { key = (MalSymbol)((MalList)a1)[i]; val = ((MalList)a1)[i+1]; - let_env.set(key.getName(), EVAL(val, let_env)); + let_env.set(key, EVAL(val, let_env)); } orig_ast = a2; env = let_env; @@ -137,7 +136,7 @@ namespace Mal { // core.cs: defined using C# foreach (var entry in core.ns) { - repl_env.set(entry.Key, entry.Value); + repl_env.set(new MalSymbol(entry.Key), entry.Value); } // core.mal: defined using the language itself diff --git a/cs/step6_file.cs b/cs/step6_file.cs index c885922..a84e87c 100644 --- a/cs/step6_file.cs +++ b/cs/step6_file.cs @@ -23,8 +23,7 @@ namespace Mal { // eval static MalVal eval_ast(MalVal ast, Env env) { if (ast is MalSymbol) { - MalSymbol sym = (MalSymbol)ast; - return env.get(sym.getName()); + return env.get((MalSymbol)ast); } else if (ast is MalList) { MalList old_lst = (MalList)ast; MalList new_lst = ast.list_Q() ? new MalList() @@ -51,7 +50,7 @@ namespace Mal { while (true) { - //System.out.println("EVAL: " + printer._pr_str(orig_ast, true)); + //Console.WriteLine("EVAL: " + printer._pr_str(orig_ast, true)); if (!orig_ast.list_Q()) { return eval_ast(orig_ast, env); } @@ -69,7 +68,7 @@ namespace Mal { a1 = ast[1]; a2 = ast[2]; res = EVAL(a2, env); - env.set(((MalSymbol)a1).getName(), res); + env.set((MalSymbol)a1, res); return res; case "let*": a1 = ast[1]; @@ -80,7 +79,7 @@ namespace Mal { for(int i=0; i<((MalList)a1).size(); i+=2) { key = (MalSymbol)((MalList)a1)[i]; val = ((MalList)a1)[i+1]; - let_env.set(key.getName(), EVAL(val, let_env)); + let_env.set(key, EVAL(val, let_env)); } orig_ast = a2; env = let_env; @@ -138,9 +137,10 @@ namespace Mal { // core.cs: defined using C# foreach (var entry in core.ns) { - repl_env.set(entry.Key, entry.Value); + repl_env.set(new MalSymbol(entry.Key), entry.Value); } - repl_env.set("eval", new MalFunc(a => EVAL(a[0], repl_env))); + repl_env.set(new MalSymbol("eval"), new MalFunc( + a => EVAL(a[0], repl_env))); int fileIdx = 1; if (args.Length > 0 && args[0] == "--raw") { Mal.readline.mode = Mal.readline.Mode.Raw; @@ -150,7 +150,7 @@ namespace Mal { for (int i=fileIdx; i < args.Length; i++) { _argv.conj_BANG(new MalString(args[i])); } - repl_env.set("*ARGV*", _argv); + repl_env.set(new MalSymbol("*ARGV*"), _argv); // core.mal: defined using the language itself RE("(def! not (fn* (a) (if a false true)))"); diff --git a/cs/step7_quote.cs b/cs/step7_quote.cs index c25498f..7b03152 100644 --- a/cs/step7_quote.cs +++ b/cs/step7_quote.cs @@ -50,8 +50,7 @@ namespace Mal { static MalVal eval_ast(MalVal ast, Env env) { if (ast is MalSymbol) { - MalSymbol sym = (MalSymbol)ast; - return env.get(sym.getName()); + return env.get((MalSymbol)ast); } else if (ast is MalList) { MalList old_lst = (MalList)ast; MalList new_lst = ast.list_Q() ? new MalList() @@ -78,7 +77,7 @@ namespace Mal { while (true) { - //System.out.println("EVAL: " + printer._pr_str(orig_ast, true)); + //Console.WriteLine("EVAL: " + printer._pr_str(orig_ast, true)); if (!orig_ast.list_Q()) { return eval_ast(orig_ast, env); } @@ -96,7 +95,7 @@ namespace Mal { a1 = ast[1]; a2 = ast[2]; res = EVAL(a2, env); - env.set(((MalSymbol)a1).getName(), res); + env.set((MalSymbol)a1, res); return res; case "let*": a1 = ast[1]; @@ -107,7 +106,7 @@ namespace Mal { for(int i=0; i<((MalList)a1).size(); i+=2) { key = (MalSymbol)((MalList)a1)[i]; val = ((MalList)a1)[i+1]; - let_env.set(key.getName(), EVAL(val, let_env)); + let_env.set(key, EVAL(val, let_env)); } orig_ast = a2; env = let_env; @@ -170,9 +169,10 @@ namespace Mal { // core.cs: defined using C# foreach (var entry in core.ns) { - repl_env.set(entry.Key, entry.Value); + repl_env.set(new MalSymbol(entry.Key), entry.Value); } - repl_env.set("eval", new MalFunc(a => EVAL(a[0], repl_env))); + repl_env.set(new MalSymbol("eval"), new MalFunc( + a => EVAL(a[0], repl_env))); int fileIdx = 1; if (args.Length > 0 && args[0] == "--raw") { Mal.readline.mode = Mal.readline.Mode.Raw; @@ -182,7 +182,7 @@ namespace Mal { for (int i=fileIdx; i < args.Length; i++) { _argv.conj_BANG(new MalString(args[i])); } - repl_env.set("*ARGV*", _argv); + repl_env.set(new MalSymbol("*ARGV*"), _argv); // core.mal: defined using the language itself RE("(def! not (fn* (a) (if a false true)))"); diff --git a/cs/step8_macros.cs b/cs/step8_macros.cs index ccc0242..cac1411 100644 --- a/cs/step8_macros.cs +++ b/cs/step8_macros.cs @@ -52,8 +52,8 @@ namespace Mal { if (ast is MalList) { MalVal a0 = ((MalList)ast)[0]; if (a0 is MalSymbol && - env.find(((MalSymbol)a0).getName()) != null) { - MalVal mac = env.get(((MalSymbol)a0).getName()); + env.find((MalSymbol)a0) != null) { + MalVal mac = env.get((MalSymbol)a0); if (mac is MalFunc && ((MalFunc)mac).isMacro()) { return true; @@ -66,7 +66,7 @@ namespace Mal { public static MalVal macroexpand(MalVal ast, Env env) { while (is_macro_call(ast, env)) { MalSymbol a0 = (MalSymbol)((MalList)ast)[0]; - MalFunc mac = (MalFunc) env.get(a0.getName()); + MalFunc mac = (MalFunc) env.get(a0); ast = mac.apply(((MalList)ast).rest()); } return ast; @@ -74,8 +74,7 @@ namespace Mal { static MalVal eval_ast(MalVal ast, Env env) { if (ast is MalSymbol) { - MalSymbol sym = (MalSymbol)ast; - return env.get(sym.getName()); + return env.get((MalSymbol)ast); } else if (ast is MalList) { MalList old_lst = (MalList)ast; MalList new_lst = ast.list_Q() ? new MalList() @@ -102,7 +101,7 @@ namespace Mal { while (true) { - //System.out.println("EVAL: " + printer._pr_str(orig_ast, true)); + //Console.WriteLine("EVAL: " + printer._pr_str(orig_ast, true)); if (!orig_ast.list_Q()) { return eval_ast(orig_ast, env); } @@ -123,7 +122,7 @@ namespace Mal { a1 = ast[1]; a2 = ast[2]; res = EVAL(a2, env); - env.set(((MalSymbol)a1).getName(), res); + env.set((MalSymbol)a1, res); return res; case "let*": a1 = ast[1]; @@ -134,7 +133,7 @@ namespace Mal { for(int i=0; i<((MalList)a1).size(); i+=2) { key = (MalSymbol)((MalList)a1)[i]; val = ((MalList)a1)[i+1]; - let_env.set(key.getName(), EVAL(val, let_env)); + let_env.set(key, EVAL(val, let_env)); } orig_ast = a2; env = let_env; @@ -149,7 +148,7 @@ namespace Mal { a2 = ast[2]; res = EVAL(a2, env); ((MalFunc)res).setMacro(); - env.set(((MalSymbol)a1).getName(), res); + env.set(((MalSymbol)a1), res); return res; case "macroexpand": a1 = ast[1]; @@ -207,9 +206,10 @@ namespace Mal { // core.cs: defined using C# foreach (var entry in core.ns) { - repl_env.set(entry.Key, entry.Value); + repl_env.set(new MalSymbol(entry.Key), entry.Value); } - repl_env.set("eval", new MalFunc(a => EVAL(a[0], repl_env))); + repl_env.set(new MalSymbol("eval"), new MalFunc( + a => EVAL(a[0], repl_env))); int fileIdx = 1; if (args.Length > 0 && args[0] == "--raw") { Mal.readline.mode = Mal.readline.Mode.Raw; @@ -219,7 +219,7 @@ namespace Mal { for (int i=fileIdx; i < args.Length; i++) { _argv.conj_BANG(new MalString(args[i])); } - repl_env.set("*ARGV*", _argv); + repl_env.set(new MalSymbol("*ARGV*"), _argv); // core.mal: defined using the language itself RE("(def! not (fn* (a) (if a false true)))"); diff --git a/cs/step9_try.cs b/cs/step9_try.cs index 1d724d1..bea360c 100644 --- a/cs/step9_try.cs +++ b/cs/step9_try.cs @@ -52,8 +52,8 @@ namespace Mal { if (ast is MalList) { MalVal a0 = ((MalList)ast)[0]; if (a0 is MalSymbol && - env.find(((MalSymbol)a0).getName()) != null) { - MalVal mac = env.get(((MalSymbol)a0).getName()); + env.find((MalSymbol)a0) != null) { + MalVal mac = env.get((MalSymbol)a0); if (mac is MalFunc && ((MalFunc)mac).isMacro()) { return true; @@ -66,7 +66,7 @@ namespace Mal { public static MalVal macroexpand(MalVal ast, Env env) { while (is_macro_call(ast, env)) { MalSymbol a0 = (MalSymbol)((MalList)ast)[0]; - MalFunc mac = (MalFunc) env.get(a0.getName()); + MalFunc mac = (MalFunc) env.get(a0); ast = mac.apply(((MalList)ast).rest()); } return ast; @@ -74,8 +74,7 @@ namespace Mal { static MalVal eval_ast(MalVal ast, Env env) { if (ast is MalSymbol) { - MalSymbol sym = (MalSymbol)ast; - return env.get(sym.getName()); + return env.get((MalSymbol)ast); } else if (ast is MalList) { MalList old_lst = (MalList)ast; MalList new_lst = ast.list_Q() ? new MalList() @@ -102,7 +101,7 @@ namespace Mal { while (true) { - //System.out.println("EVAL: " + printer._pr_str(orig_ast, true)); + //Console.WriteLine("EVAL: " + printer._pr_str(orig_ast, true)); if (!orig_ast.list_Q()) { return eval_ast(orig_ast, env); } @@ -123,7 +122,7 @@ namespace Mal { a1 = ast[1]; a2 = ast[2]; res = EVAL(a2, env); - env.set(((MalSymbol)a1).getName(), res); + env.set((MalSymbol)a1, res); return res; case "let*": a1 = ast[1]; @@ -134,7 +133,7 @@ namespace Mal { for(int i=0; i<((MalList)a1).size(); i+=2) { key = (MalSymbol)((MalList)a1)[i]; val = ((MalList)a1)[i+1]; - let_env.set(key.getName(), EVAL(val, let_env)); + let_env.set(key, EVAL(val, let_env)); } orig_ast = a2; env = let_env; @@ -149,7 +148,7 @@ namespace Mal { a2 = ast[2]; res = EVAL(a2, env); ((MalFunc)res).setMacro(); - env.set(((MalSymbol)a1).getName(), res); + env.set(((MalSymbol)a1), res); return res; case "macroexpand": a1 = ast[1]; @@ -228,9 +227,10 @@ namespace Mal { // core.cs: defined using C# foreach (var entry in core.ns) { - repl_env.set(entry.Key, entry.Value); + repl_env.set(new MalSymbol(entry.Key), entry.Value); } - repl_env.set("eval", new MalFunc(a => EVAL(a[0], repl_env))); + repl_env.set(new MalSymbol("eval"), new MalFunc( + a => EVAL(a[0], repl_env))); int fileIdx = 1; if (args.Length > 0 && args[0] == "--raw") { Mal.readline.mode = Mal.readline.Mode.Raw; @@ -240,7 +240,7 @@ namespace Mal { for (int i=fileIdx; i < args.Length; i++) { _argv.conj_BANG(new MalString(args[i])); } - repl_env.set("*ARGV*", _argv); + repl_env.set(new MalSymbol("*ARGV*"), _argv); // core.mal: defined using the language itself RE("(def! not (fn* (a) (if a false true)))"); diff --git a/cs/stepA_interop.cs b/cs/stepA_interop.cs index f51f824..2e8fc12 100644 --- a/cs/stepA_interop.cs +++ b/cs/stepA_interop.cs @@ -52,8 +52,8 @@ namespace Mal { if (ast is MalList) { MalVal a0 = ((MalList)ast)[0]; if (a0 is MalSymbol && - env.find(((MalSymbol)a0).getName()) != null) { - MalVal mac = env.get(((MalSymbol)a0).getName()); + env.find((MalSymbol)a0) != null) { + MalVal mac = env.get((MalSymbol)a0); if (mac is MalFunc && ((MalFunc)mac).isMacro()) { return true; @@ -66,7 +66,7 @@ namespace Mal { public static MalVal macroexpand(MalVal ast, Env env) { while (is_macro_call(ast, env)) { MalSymbol a0 = (MalSymbol)((MalList)ast)[0]; - MalFunc mac = (MalFunc) env.get(a0.getName()); + MalFunc mac = (MalFunc) env.get(a0); ast = mac.apply(((MalList)ast).rest()); } return ast; @@ -74,8 +74,7 @@ namespace Mal { static MalVal eval_ast(MalVal ast, Env env) { if (ast is MalSymbol) { - MalSymbol sym = (MalSymbol)ast; - return env.get(sym.getName()); + return env.get((MalSymbol)ast); } else if (ast is MalList) { MalList old_lst = (MalList)ast; MalList new_lst = ast.list_Q() ? new MalList() @@ -102,7 +101,7 @@ namespace Mal { while (true) { - //System.out.println("EVAL: " + printer._pr_str(orig_ast, true)); + //Console.WriteLine("EVAL: " + printer._pr_str(orig_ast, true)); if (!orig_ast.list_Q()) { return eval_ast(orig_ast, env); } @@ -123,7 +122,7 @@ namespace Mal { a1 = ast[1]; a2 = ast[2]; res = EVAL(a2, env); - env.set(((MalSymbol)a1).getName(), res); + env.set((MalSymbol)a1, res); return res; case "let*": a1 = ast[1]; @@ -134,7 +133,7 @@ namespace Mal { for(int i=0; i<((MalList)a1).size(); i+=2) { key = (MalSymbol)((MalList)a1)[i]; val = ((MalList)a1)[i+1]; - let_env.set(key.getName(), EVAL(val, let_env)); + let_env.set(key, EVAL(val, let_env)); } orig_ast = a2; env = let_env; @@ -149,7 +148,7 @@ namespace Mal { a2 = ast[2]; res = EVAL(a2, env); ((MalFunc)res).setMacro(); - env.set(((MalSymbol)a1).getName(), res); + env.set(((MalSymbol)a1), res); return res; case "macroexpand": a1 = ast[1]; @@ -228,9 +227,10 @@ namespace Mal { // core.cs: defined using C# foreach (var entry in core.ns) { - repl_env.set(entry.Key, entry.Value); + repl_env.set(new MalSymbol(entry.Key), entry.Value); } - repl_env.set("eval", new MalFunc(a => EVAL(a[0], repl_env))); + repl_env.set(new MalSymbol("eval"), new MalFunc( + a => EVAL(a[0], repl_env))); int fileIdx = 1; if (args.Length > 0 && args[0] == "--raw") { Mal.readline.mode = Mal.readline.Mode.Raw; @@ -240,7 +240,7 @@ namespace Mal { for (int i=fileIdx; i < args.Length; i++) { _argv.conj_BANG(new MalString(args[i])); } - repl_env.set("*ARGV*", _argv); + repl_env.set(new MalSymbol("*ARGV*"), _argv); // core.mal: defined using the language itself RE("(def! *host-language* \"c#\")"); diff --git a/cs/types.cs b/cs/types.cs index c2f46c9..b96a9f4 100644 --- a/cs/types.cs +++ b/cs/types.cs @@ -160,7 +160,9 @@ namespace Mal { return "\"" + value + "\""; } public override string ToString(bool print_readably) { - if (print_readably) { + if (value.Length > 0 && value[0] == '\u029e') { + return ":" + value.Substring(1); + } else if (print_readably) { return "\"" + value.Replace("\\", "\\\\") .Replace("\"", "\\\"") .Replace("\n", "\\n") + "\""; -- cgit v1.2.3