aboutsummaryrefslogtreecommitdiff
path: root/cs
diff options
context:
space:
mode:
Diffstat (limited to 'cs')
-rw-r--r--cs/core.cs20
-rw-r--r--cs/step1_read_print.cs8
-rw-r--r--cs/step2_eval.cs13
-rw-r--r--cs/step3_env.cs34
-rw-r--r--cs/step4_if_fn_do.cs46
-rw-r--r--cs/step5_tco.cs44
-rw-r--r--cs/step6_file.cs54
-rw-r--r--cs/step7_quote.cs28
-rw-r--r--cs/step8_macros.cs30
-rw-r--r--cs/stepA_more.cs44
-rw-r--r--cs/types.cs3
11 files changed, 129 insertions, 195 deletions
diff --git a/cs/core.cs b/cs/core.cs
index 13f082e..62a121c 100644
--- a/cs/core.cs
+++ b/cs/core.cs
@@ -1,4 +1,5 @@
using System;
+using System.IO;
using System.Collections.Generic;
using MalVal = Mal.types.MalVal;
using MalConstant = Mal.types.MalConstant;
@@ -54,6 +55,21 @@ namespace Mal {
return Nil;
} );
+ static public MalFunction mal_readline = new MalFunction(
+ a => {
+ var line = readline.Readline(((MalString)a[0]).getValue());
+ if (line == null) { return types.Nil; }
+ else { return new MalString(line); }
+ } );
+
+ static public MalFunction read_string = new MalFunction(
+ a => reader.read_str(((MalString)a[0]).getValue()));
+
+ static public MalFunction slurp = new MalFunction(
+ a => new MalString(File.ReadAllText(
+ ((MalString)a[0]).getValue())));
+
+
// List/Vector functions
static public MalFunction list_Q = new MalFunction(
a => a[0].GetType() == typeof(MalList) ? True : False);
@@ -233,10 +249,14 @@ namespace Mal {
{"true?", true_Q},
{"false?", false_Q},
{"symbol?", symbol_Q},
+
{"pr-str", pr_str},
{"str", str},
{"prn", prn},
{"println", println},
+ {"readline", mal_readline},
+ {"read-string", read_string},
+ {"slurp", slurp},
{"<", new MalFunction(a => (MalInteger)a[0] < (MalInteger)a[1])},
{"<=", new MalFunction(a => (MalInteger)a[0] <= (MalInteger)a[1])},
{">", new MalFunction(a => (MalInteger)a[0] > (MalInteger)a[1])},
diff --git a/cs/step1_read_print.cs b/cs/step1_read_print.cs
index 92a8b65..62cd7ad 100644
--- a/cs/step1_read_print.cs
+++ b/cs/step1_read_print.cs
@@ -31,7 +31,6 @@ namespace Mal {
if (args.Length > 0 && args[0] == "--raw") {
Mal.readline.mode = Mal.readline.Mode.Raw;
}
-
while (true) {
string line;
try {
@@ -45,13 +44,10 @@ namespace Mal {
Console.WriteLine(PRINT(RE(null, line)));
} catch (Mal.types.MalContinue) {
continue;
- } catch (Mal.types.MalError e) {
+ } catch (Exception e) {
Console.WriteLine("Error: " + e.Message);
+ Console.WriteLine(e.StackTrace);
continue;
- } catch (Mal.reader.ParseError e) {
- Console.WriteLine(e.Message);
- continue;
-
}
}
}
diff --git a/cs/step2_eval.cs b/cs/step2_eval.cs
index 09bf36d..dc467de 100644
--- a/cs/step2_eval.cs
+++ b/cs/step2_eval.cs
@@ -53,13 +53,13 @@ namespace Mal {
// apply list
MalList ast = (MalList)orig_ast;
if (ast.size() == 0) { return ast; }
- a0 = ast.nth(0);
+ a0 = ast[0];
if (!(a0 is MalSymbol)) {
throw new Mal.types.MalError("attempt to apply on non-symbol '"
+ Mal.printer._pr_str(a0,true) + "'");
}
var el = (MalList)eval_ast(ast, env);
- var f = (MalFunction)el.nth(0);
+ var f = (MalFunction)el[0];
return f.apply(el.rest());
}
@@ -92,10 +92,10 @@ namespace Mal {
{"*", multiply},
{"/", divide},
};
+
if (args.Length > 0 && args[0] == "--raw") {
Mal.readline.mode = Mal.readline.Mode.Raw;
}
-
while (true) {
string line;
try {
@@ -109,14 +109,9 @@ namespace Mal {
Console.WriteLine(PRINT(RE(repl_env, line)));
} catch (Mal.types.MalContinue) {
continue;
- } catch (Mal.reader.ParseError e) {
- Console.WriteLine(e.Message);
- continue;
- } catch (Mal.types.MalError e) {
- Console.WriteLine("Error: " + e.Message);
- continue;
} catch (Exception e) {
Console.WriteLine("Error: " + e.Message);
+ Console.WriteLine(e.StackTrace);
continue;
}
}
diff --git a/cs/step3_env.cs b/cs/step3_env.cs
index 032fadd..ba859eb 100644
--- a/cs/step3_env.cs
+++ b/cs/step3_env.cs
@@ -55,7 +55,7 @@ namespace Mal {
// apply list
MalList ast = (MalList)orig_ast;
if (ast.size() == 0) { return ast; }
- a0 = ast.nth(0);
+ a0 = ast[0];
if (!(a0 is MalSymbol)) {
throw new Mal.types.MalError("attempt to apply on non-symbol '"
+ Mal.printer._pr_str(a0,true) + "'");
@@ -63,26 +63,26 @@ namespace Mal {
switch (((MalSymbol)a0).getName()) {
case "def!":
- a1 = ast.nth(1);
- a2 = ast.nth(2);
+ a1 = ast[1];
+ a2 = ast[2];
res = EVAL(a2, env);
env.set(((MalSymbol)a1).getName(), res);
return res;
case "let*":
- a1 = ast.nth(1);
- a2 = ast.nth(2);
+ a1 = ast[1];
+ a2 = ast[2];
MalSymbol key;
MalVal val;
Env let_env = new Env(env);
for(int i=0; i<((MalList)a1).size(); i+=2) {
- key = (MalSymbol)((MalList)a1).nth(i);
- val = ((MalList)a1).nth(i+1);
+ key = (MalSymbol)((MalList)a1)[i];
+ val = ((MalList)a1)[i+1];
let_env.set(key.getName(), EVAL(val, let_env));
}
return EVAL(a2, let_env);
default:
el = (MalList)eval_ast(ast, env);
- var f = (MalFunction)el.nth(0);
+ var f = (MalFunction)el[0];
return f.apply(el.rest());
}
}
@@ -96,9 +96,6 @@ namespace Mal {
static MalVal RE(Env env, string str) {
return EVAL(READ(str), env);
}
- public static Env _ref(Env env, string name, MalVal mv) {
- return env.set(name, mv);
- }
static public MalFunction plus = new MalFunction(
a => (MalInteger)a[0] + (MalInteger)a[1] );
@@ -114,10 +111,10 @@ namespace Mal {
string prompt = "user> ";
var repl_env = new Mal.env.Env(null);
- _ref(repl_env, "+", plus);
- _ref(repl_env, "-", minus);
- _ref(repl_env, "*", multiply);
- _ref(repl_env, "/", divide);
+ repl_env.set("+", plus);
+ repl_env.set("-", minus);
+ repl_env.set("*", multiply);
+ repl_env.set("/", divide);
if (args.Length > 0 && args[0] == "--raw") {
Mal.readline.mode = Mal.readline.Mode.Raw;
@@ -135,14 +132,9 @@ namespace Mal {
Console.WriteLine(PRINT(RE(repl_env, line)));
} catch (Mal.types.MalContinue) {
continue;
- } catch (Mal.reader.ParseError e) {
- Console.WriteLine(e.Message);
- continue;
- } catch (Mal.types.MalException e) {
- Console.WriteLine("Error: " + e.getValue());
- continue;
} catch (Exception e) {
Console.WriteLine("Error: " + e.Message);
+ Console.WriteLine(e.StackTrace);
continue;
}
}
diff --git a/cs/step4_if_fn_do.cs b/cs/step4_if_fn_do.cs
index d0ca882..2383c31 100644
--- a/cs/step4_if_fn_do.cs
+++ b/cs/step4_if_fn_do.cs
@@ -55,58 +55,58 @@ namespace Mal {
// apply list
MalList ast = (MalList)orig_ast;
if (ast.size() == 0) { return ast; }
- a0 = ast.nth(0);
+ a0 = ast[0];
String a0sym = a0 is MalSymbol ? ((MalSymbol)a0).getName()
: "__<*fn*>__";
switch (a0sym) {
case "def!":
- a1 = ast.nth(1);
- a2 = ast.nth(2);
+ a1 = ast[1];
+ a2 = ast[2];
res = EVAL(a2, env);
env.set(((MalSymbol)a1).getName(), res);
return res;
case "let*":
- a1 = ast.nth(1);
- a2 = ast.nth(2);
+ a1 = ast[1];
+ a2 = ast[2];
MalSymbol key;
MalVal val;
Env let_env = new Env(env);
for(int i=0; i<((MalList)a1).size(); i+=2) {
- key = (MalSymbol)((MalList)a1).nth(i);
- val = ((MalList)a1).nth(i+1);
+ key = (MalSymbol)((MalList)a1)[i];
+ val = ((MalList)a1)[i+1];
let_env.set(key.getName(), EVAL(val, let_env));
}
return EVAL(a2, let_env);
case "do":
el = (MalList)eval_ast(ast.rest(), env);
- return el.nth(el.size()-1);
+ return el[el.size()-1];
case "if":
- a1 = ast.nth(1);
+ a1 = ast[1];
MalVal cond = EVAL(a1, env);
if (cond == Mal.types.Nil || cond == Mal.types.False) {
// eval false slot form
if (ast.size() > 3) {
- a3 = ast.nth(3);
+ a3 = ast[3];
return EVAL(a3, env);
} else {
return Mal.types.Nil;
}
} else {
// eval true slot form
- a2 = ast.nth(2);
+ a2 = ast[2];
return EVAL(a2, env);
}
case "fn*":
- MalList a1f = (MalList)ast.nth(1);
- MalVal a2f = ast.nth(2);
+ MalList a1f = (MalList)ast[1];
+ MalVal a2f = ast[2];
Env cur_env = env;
return new MalFunction(
args => EVAL(a2f, new Env(cur_env, a1f, args)) );
default:
el = (MalList)eval_ast(ast, env);
- var f = (MalFunction)el.nth(0);
+ var f = (MalFunction)el[0];
return f.apply(el.rest());
}
}
@@ -120,18 +120,17 @@ namespace Mal {
static MalVal RE(Env env, string str) {
return EVAL(READ(str), env);
}
- public static Env _ref(Env env, string name, MalVal mv) {
- return env.set(name, mv);
- }
static void Main(string[] args) {
string prompt = "user> ";
- var repl_env = new Mal.env.Env(null);
- foreach (var entry in Mal.core.ns) {
- _ref(repl_env, entry.Key, entry.Value);
+ // core.cs: defined using C#
+ var repl_env = new env.Env(null);
+ foreach (var entry in core.ns) {
+ repl_env.set(entry.Key, entry.Value);
}
+ // core.mal: defined using the language itself
RE(repl_env, "(def! not (fn* (a) (if a false true)))");
if (args.Length > 0 && args[0] == "--raw") {
@@ -150,14 +149,9 @@ namespace Mal {
Console.WriteLine(PRINT(RE(repl_env, line)));
} catch (Mal.types.MalContinue) {
continue;
- } catch (Mal.reader.ParseError e) {
- Console.WriteLine(e.Message);
- continue;
- } catch (Mal.types.MalException e) {
- Console.WriteLine("Error: " + e.getValue());
- continue;
} catch (Exception e) {
Console.WriteLine("Error: " + e.Message);
+ Console.WriteLine(e.StackTrace);
continue;
}
}
diff --git a/cs/step5_tco.cs b/cs/step5_tco.cs
index 18b2fc9..b04d16e 100644
--- a/cs/step5_tco.cs
+++ b/cs/step5_tco.cs
@@ -13,7 +13,7 @@ using MalFunction = Mal.types.MalFunction;
using Env = Mal.env.Env;
namespace Mal {
- class step4_if_fn_do {
+ class step5_tco {
// read
static MalVal READ(string str) {
return reader.read_str(str);
@@ -58,36 +58,36 @@ namespace Mal {
// apply list
MalList ast = (MalList)orig_ast;
if (ast.size() == 0) { return ast; }
- a0 = ast.nth(0);
+ a0 = ast[0];
String a0sym = a0 is MalSymbol ? ((MalSymbol)a0).getName()
: "__<*fn*>__";
switch (a0sym) {
case "def!":
- a1 = ast.nth(1);
- a2 = ast.nth(2);
+ a1 = ast[1];
+ a2 = ast[2];
res = EVAL(a2, env);
env.set(((MalSymbol)a1).getName(), res);
return res;
case "let*":
- a1 = ast.nth(1);
- a2 = ast.nth(2);
+ a1 = ast[1];
+ a2 = ast[2];
MalSymbol key;
MalVal val;
Env let_env = new Env(env);
for(int i=0; i<((MalList)a1).size(); i+=2) {
- key = (MalSymbol)((MalList)a1).nth(i);
- val = ((MalList)a1).nth(i+1);
+ key = (MalSymbol)((MalList)a1)[i];
+ val = ((MalList)a1)[i+1];
let_env.set(key.getName(), EVAL(val, let_env));
}
return EVAL(a2, let_env);
case "do":
eval_ast(ast.slice(1, ast.size()-1), env);
- orig_ast = ast.nth(ast.size()-1);
+ orig_ast = ast[ast.size()-1];
break;
case "if":
- a1 = ast.nth(1);
+ a1 = ast[1];
MalVal cond = EVAL(a1, env);
if (cond == Mal.types.Nil || cond == Mal.types.False) {
// eval false slot form
@@ -102,14 +102,14 @@ namespace Mal {
}
break;
case "fn*":
- MalList a1f = (MalList)ast.nth(1);
- MalVal a2f = ast.nth(2);
+ MalList a1f = (MalList)ast[1];
+ MalVal a2f = ast[2];
Env cur_env = env;
return new MalFunction(a2f, env, a1f,
args => EVAL(a2f, new Env(cur_env, a1f, args)) );
default:
el = (MalList)eval_ast(ast, env);
- var f = (MalFunction)el.nth(0);
+ var f = (MalFunction)el[0];
MalVal fnast = f.getAst();
if (fnast != null) {
orig_ast = fnast;
@@ -132,18 +132,17 @@ namespace Mal {
static MalVal RE(Env env, string str) {
return EVAL(READ(str), env);
}
- public static Env _ref(Env env, string name, MalVal mv) {
- return env.set(name, mv);
- }
static void Main(string[] args) {
string prompt = "user> ";
- var repl_env = new Mal.env.Env(null);
- foreach (var entry in Mal.core.ns) {
- _ref(repl_env, entry.Key, entry.Value);
+ // core.cs: defined using C#
+ var repl_env = new env.Env(null);
+ foreach (var entry in core.ns) {
+ repl_env.set(entry.Key, entry.Value);
}
+ // core.mal: defined using the language itself
RE(repl_env, "(def! not (fn* (a) (if a false true)))");
if (args.Length > 0 && args[0] == "--raw") {
@@ -162,14 +161,9 @@ namespace Mal {
Console.WriteLine(PRINT(RE(repl_env, line)));
} catch (Mal.types.MalContinue) {
continue;
- } catch (Mal.reader.ParseError e) {
- Console.WriteLine(e.Message);
- continue;
- } catch (Mal.types.MalException e) {
- Console.WriteLine("Error: " + e.getValue());
- continue;
} catch (Exception e) {
Console.WriteLine("Error: " + e.Message);
+ Console.WriteLine(e.StackTrace);
continue;
}
}
diff --git a/cs/step6_file.cs b/cs/step6_file.cs
index b02cedb..cb2157e 100644
--- a/cs/step6_file.cs
+++ b/cs/step6_file.cs
@@ -4,7 +4,6 @@ using System.Collections;
using System.Collections.Generic;
using Mal;
using MalVal = Mal.types.MalVal;
-using MalString = Mal.types.MalString;
using MalSymbol = Mal.types.MalSymbol;
using MalInteger = Mal.types.MalInteger;
using MalList = Mal.types.MalList;
@@ -14,7 +13,7 @@ using MalFunction = Mal.types.MalFunction;
using Env = Mal.env.Env;
namespace Mal {
- class step4_if_fn_do {
+ class step6_file {
// read
static MalVal READ(string str) {
return reader.read_str(str);
@@ -59,36 +58,36 @@ namespace Mal {
// apply list
MalList ast = (MalList)orig_ast;
if (ast.size() == 0) { return ast; }
- a0 = ast.nth(0);
+ a0 = ast[0];
String a0sym = a0 is MalSymbol ? ((MalSymbol)a0).getName()
: "__<*fn*>__";
switch (a0sym) {
case "def!":
- a1 = ast.nth(1);
- a2 = ast.nth(2);
+ a1 = ast[1];
+ a2 = ast[2];
res = EVAL(a2, env);
env.set(((MalSymbol)a1).getName(), res);
return res;
case "let*":
- a1 = ast.nth(1);
- a2 = ast.nth(2);
+ a1 = ast[1];
+ a2 = ast[2];
MalSymbol key;
MalVal val;
Env let_env = new Env(env);
for(int i=0; i<((MalList)a1).size(); i+=2) {
- key = (MalSymbol)((MalList)a1).nth(i);
- val = ((MalList)a1).nth(i+1);
+ key = (MalSymbol)((MalList)a1)[i];
+ val = ((MalList)a1)[i+1];
let_env.set(key.getName(), EVAL(val, let_env));
}
return EVAL(a2, let_env);
case "do":
eval_ast(ast.slice(1, ast.size()-1), env);
- orig_ast = ast.nth(ast.size()-1);
+ orig_ast = ast[ast.size()-1];
break;
case "if":
- a1 = ast.nth(1);
+ a1 = ast[1];
MalVal cond = EVAL(a1, env);
if (cond == Mal.types.Nil || cond == Mal.types.False) {
// eval false slot form
@@ -103,14 +102,14 @@ namespace Mal {
}
break;
case "fn*":
- MalList a1f = (MalList)ast.nth(1);
- MalVal a2f = ast.nth(2);
+ MalList a1f = (MalList)ast[1];
+ MalVal a2f = ast[2];
Env cur_env = env;
return new MalFunction(a2f, env, a1f,
args => EVAL(a2f, new Env(cur_env, a1f, args)) );
default:
el = (MalList)eval_ast(ast, env);
- var f = (MalFunction)el.nth(0);
+ var f = (MalFunction)el[0];
MalVal fnast = f.getAst();
if (fnast != null) {
orig_ast = fnast;
@@ -133,26 +132,18 @@ namespace Mal {
static MalVal RE(Env env, string str) {
return EVAL(READ(str), env);
}
- public static Env _ref(Env env, string name, MalVal mv) {
- return env.set(name, mv);
- }
-
static void Main(string[] args) {
string prompt = "user> ";
- var repl_env = new Mal.env.Env(null);
- foreach (var entry in Mal.core.ns) {
- _ref(repl_env, entry.Key, entry.Value);
+ // core.cs: defined using C#
+ var repl_env = new env.Env(null);
+ foreach (var entry in core.ns) {
+ repl_env.set(entry.Key, entry.Value);
}
- _ref(repl_env, "read-string", new MalFunction(
- a => reader.read_str(((MalString)a[0]).getValue())));
- _ref(repl_env, "eval", new MalFunction(
- a => EVAL(a[0], repl_env)));
- _ref(repl_env, "slurp", new MalFunction(
- a => new MalString(File.ReadAllText(
- ((MalString)a[0]).getValue()))));
+ repl_env.set("eval", new MalFunction(a => EVAL(a[0], repl_env)));
+ // core.mal: defined using the language itself
RE(repl_env, "(def! not (fn* (a) (if a false true)))");
RE(repl_env, "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))");
@@ -180,14 +171,9 @@ namespace Mal {
Console.WriteLine(PRINT(RE(repl_env, line)));
} catch (Mal.types.MalContinue) {
continue;
- } catch (Mal.reader.ParseError e) {
- Console.WriteLine(e.Message);
- continue;
- } catch (Mal.types.MalException e) {
- Console.WriteLine("Error: " + e.getValue());
- continue;
} catch (Exception e) {
Console.WriteLine("Error: " + e.Message);
+ Console.WriteLine(e.StackTrace);
continue;
}
}
diff --git a/cs/step7_quote.cs b/cs/step7_quote.cs
index 61f638f..6f08abb 100644
--- a/cs/step7_quote.cs
+++ b/cs/step7_quote.cs
@@ -14,7 +14,7 @@ using MalFunction = Mal.types.MalFunction;
using Env = Mal.env.Env;
namespace Mal {
- class step4_if_fn_do {
+ class step7_quote {
// read
static MalVal READ(string str) {
return reader.read_str(str);
@@ -164,26 +164,18 @@ namespace Mal {
static MalVal RE(Env env, string str) {
return EVAL(READ(str), env);
}
- public static Env _ref(Env env, string name, MalVal mv) {
- return env.set(name, mv);
- }
-
static void Main(string[] args) {
string prompt = "user> ";
- var repl_env = new Mal.env.Env(null);
- foreach (var entry in Mal.core.ns) {
- _ref(repl_env, entry.Key, entry.Value);
+ // core.cs: defined using C#
+ var repl_env = new env.Env(null);
+ foreach (var entry in core.ns) {
+ repl_env.set(entry.Key, entry.Value);
}
- _ref(repl_env, "read-string", new MalFunction(
- a => reader.read_str(((MalString)a[0]).getValue())));
- _ref(repl_env, "eval", new MalFunction(
- a => EVAL(a[0], repl_env)));
- _ref(repl_env, "slurp", new MalFunction(
- a => new MalString(File.ReadAllText(
- ((MalString)a[0]).getValue()))));
+ repl_env.set("eval", new MalFunction(a => EVAL(a[0], repl_env)));
+ // core.mal: defined using the language itself
RE(repl_env, "(def! not (fn* (a) (if a false true)))");
RE(repl_env, "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))");
@@ -211,12 +203,6 @@ namespace Mal {
Console.WriteLine(PRINT(RE(repl_env, line)));
} catch (Mal.types.MalContinue) {
continue;
- } catch (Mal.reader.ParseError e) {
- Console.WriteLine(e.Message);
- continue;
- } catch (Mal.types.MalException e) {
- Console.WriteLine("Error: " + e.getValue());
- continue;
} catch (Exception e) {
Console.WriteLine("Error: " + e.Message);
Console.WriteLine(e.StackTrace);
diff --git a/cs/step8_macros.cs b/cs/step8_macros.cs
index fe085f9..caa8f0a 100644
--- a/cs/step8_macros.cs
+++ b/cs/step8_macros.cs
@@ -14,7 +14,7 @@ using MalFunction = Mal.types.MalFunction;
using Env = Mal.env.Env;
namespace Mal {
- class step4_if_fn_do {
+ class step8_macros {
// read
static MalVal READ(string str) {
return reader.read_str(str);
@@ -201,28 +201,22 @@ namespace Mal {
static MalVal RE(Env env, string str) {
return EVAL(READ(str), env);
}
- public static Env _ref(Env env, string name, MalVal mv) {
- return env.set(name, mv);
- }
-
static void Main(string[] args) {
string prompt = "user> ";
- var repl_env = new Mal.env.Env(null);
- foreach (var entry in Mal.core.ns) {
- _ref(repl_env, entry.Key, entry.Value);
+ // core.cs: defined using C#
+ var repl_env = new env.Env(null);
+ foreach (var entry in core.ns) {
+ repl_env.set(entry.Key, entry.Value);
}
- _ref(repl_env, "read-string", new MalFunction(
- a => reader.read_str(((MalString)a[0]).getValue())));
- _ref(repl_env, "eval", new MalFunction(
- a => EVAL(a[0], repl_env)));
- _ref(repl_env, "slurp", new MalFunction(
- a => new MalString(File.ReadAllText(
- ((MalString)a[0]).getValue()))));
+ repl_env.set("eval", new MalFunction(a => EVAL(a[0], repl_env)));
+ // core.mal: defined using the language itself
RE(repl_env, "(def! not (fn* (a) (if a false true)))");
RE(repl_env, "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))");
+ RE(repl_env, "(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))");
+ RE(repl_env, "(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))");
int fileIdx = 0;
if (args.Length > 0 && args[0] == "--raw") {
@@ -248,12 +242,6 @@ namespace Mal {
Console.WriteLine(PRINT(RE(repl_env, line)));
} catch (Mal.types.MalContinue) {
continue;
- } catch (Mal.reader.ParseError e) {
- Console.WriteLine(e.Message);
- continue;
- } catch (Mal.types.MalException e) {
- Console.WriteLine("Error: " + e.getValue());
- continue;
} catch (Exception e) {
Console.WriteLine("Error: " + e.Message);
Console.WriteLine(e.StackTrace);
diff --git a/cs/stepA_more.cs b/cs/stepA_more.cs
index 97b1e84..cbbc91f 100644
--- a/cs/stepA_more.cs
+++ b/cs/stepA_more.cs
@@ -3,7 +3,6 @@ using System.IO;
using System.Collections;
using System.Collections.Generic;
using Mal;
-using MalException = Mal.types.MalException;
using MalVal = Mal.types.MalVal;
using MalString = Mal.types.MalString;
using MalSymbol = Mal.types.MalSymbol;
@@ -161,8 +160,8 @@ namespace Mal {
a2 = ast[2];
MalVal a20 = ((MalList)a2)[0];
if (((MalSymbol)a20).getName() == "catch*") {
- if (e is MalException) {
- exc = ((MalException)e).getValue();
+ if (e is Mal.types.MalException) {
+ exc = ((Mal.types.MalException)e).getValue();
} else {
exc = new MalString(e.StackTrace);
}
@@ -180,12 +179,12 @@ namespace Mal {
case "if":
a1 = ast[1];
MalVal cond = EVAL(a1, env);
- if (cond == types.Nil || cond == types.False) {
+ if (cond == Mal.types.Nil || cond == Mal.types.False) {
// eval false slot form
if (ast.size() > 3) {
orig_ast = ast[3];
} else {
- return types.Nil;
+ return Mal.types.Nil;
}
} else {
// eval true slot form
@@ -223,40 +222,26 @@ namespace Mal {
static MalVal RE(Env env, string str) {
return EVAL(READ(str), env);
}
- public static Env _ref(Env env, string name, MalVal mv) {
- return env.set(name, mv);
- }
-
static void Main(string[] args) {
string prompt = "user> ";
+ // core.cs: defined using C#
var repl_env = new env.Env(null);
foreach (var entry in core.ns) {
- _ref(repl_env, entry.Key, entry.Value);
+ repl_env.set(entry.Key, entry.Value);
}
- _ref(repl_env, "readline", new MalFunction(
- a => {
- var line = readline.Readline(((MalString)a[0]).getValue());
- if (line == null) { return types.Nil; }
- else { return new MalString(line); }
- }));
- _ref(repl_env, "read-string", new MalFunction(
- a => reader.read_str(((MalString)a[0]).getValue())));
- _ref(repl_env, "eval", new MalFunction(
- a => EVAL(a[0], repl_env)));
- _ref(repl_env, "slurp", new MalFunction(
- a => new MalString(File.ReadAllText(
- ((MalString)a[0]).getValue()))));
+ repl_env.set("eval", new MalFunction(a => EVAL(a[0], repl_env)));
+ // core.mal: defined using the language itself
RE(repl_env, "(def! not (fn* (a) (if a false true)))");
+ RE(repl_env, "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))");
RE(repl_env, "(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))");
RE(repl_env, "(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))");
- RE(repl_env, "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))");
int fileIdx = 0;
if (args.Length > 0 && args[0] == "--raw") {
- readline.mode = readline.Mode.Raw;
+ Mal.readline.mode = Mal.readline.Mode.Raw;
fileIdx = 1;
}
if (args.Length > fileIdx) {
@@ -268,7 +253,7 @@ namespace Mal {
while (true) {
string line;
try {
- line = readline.Readline(prompt);
+ line = Mal.readline.Readline(prompt);
if (line == null) { break; }
} catch (IOException e) {
Console.WriteLine("IOException: " + e.Message);
@@ -276,12 +261,9 @@ namespace Mal {
}
try {
Console.WriteLine(PRINT(RE(repl_env, line)));
- } catch (types.MalContinue) {
- continue;
- } catch (reader.ParseError e) {
- Console.WriteLine(e.Message);
+ } catch (Mal.types.MalContinue) {
continue;
- } catch (MalException e) {
+ } catch (Mal.types.MalException e) {
Console.WriteLine("Error: " +
printer._pr_str(e.getValue(), false));
continue;
diff --git a/cs/types.cs b/cs/types.cs
index 34985ad..b49adb6 100644
--- a/cs/types.cs
+++ b/cs/types.cs
@@ -19,10 +19,11 @@ namespace Mal {
// Thrown by throw function
public class MalException : MalThrowable {
MalVal value;
+ //string Message;
public MalException(MalVal value) {
this.value = value;
}
- public MalException(string value) {
+ public MalException(string value) :base(value) {
this.value = new MalString(value);
}
public MalVal getValue() { return value; }