aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2014-04-13 15:36:02 -0500
committerJoel Martin <github@martintribe.org>2014-04-13 15:36:02 -0500
commit8adb082743f12402d0817018ab1e8ff0c0e4729e (patch)
treeba3c69589adfb799c71190ede43ab5cefceda6f6
parent3e8a088f48ea6030191c15457aafdd1b30387ca0 (diff)
downloadmal-8adb082743f12402d0817018ab1e8ff0c0e4729e.tar.gz
mal-8adb082743f12402d0817018ab1e8ff0c0e4729e.zip
Java, JS: cleanup and sync steps.
- Java: less direct use of obj.value attribute.
-rw-r--r--README.md10
-rw-r--r--docs/TODO21
-rw-r--r--java/src/main/java/mal/core.java60
-rw-r--r--java/src/main/java/mal/step5_tco.java2
-rw-r--r--java/src/main/java/mal/step6_file.java6
-rw-r--r--java/src/main/java/mal/step7_quote.java6
-rw-r--r--java/src/main/java/mal/step8_macros.java8
-rw-r--r--java/src/main/java/mal/stepA_more.java2
-rw-r--r--java/src/main/java/mal/types.java3
-rw-r--r--js/step5_tco.js2
-rw-r--r--js/step6_file.js2
-rw-r--r--js/step7_quote.js10
-rw-r--r--js/step8_macros.js10
-rw-r--r--js/step9_interop.js10
-rw-r--r--js/stepA_more.js10
15 files changed, 102 insertions, 60 deletions
diff --git a/README.md b/README.md
index 2653b90..4b34c12 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
## Description
Mal is an interpreter for a subset of the Clojure programming
-language. Mal is implemetated from scratch in 11 different languages:
+language. Mal is implemetated from scratch in 12 different languages:
* Bash shell
* C
@@ -16,6 +16,7 @@ language. Mal is implemetated from scratch in 11 different languages:
* PHP
* Postscript
* Python
+* Ruby
Mal is also a learning tool. Each implentation of mal is separated
@@ -140,3 +141,10 @@ gs -q -dNODISPLAY stepX_YYY.ps
cd python
python stepX_YYY.py
```
+
+### Ruby (1.8)
+
+```
+cd ruby
+ruby stepX_YYY.rb
+```
diff --git a/docs/TODO b/docs/TODO
index 3e068d7..5b5a240 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -5,6 +5,7 @@ All:
- hash-map with space in key string (make)
- keyword type
- gensym reader inside quasiquote
+ - can let* and quasiquote be TCO'd ?
- more interop tests
- regular expression matching in runtest
@@ -20,18 +21,13 @@ C:
- come up with better way to do 20 vararg code
C#:
- - http://msdn.microsoft.com/en-us/library/ms228362.aspx
- - http://www.tutorialspoint.com/csharp
- - Readline:
- - http://stackoverflow.com/questions/2024170/is-there-a-net-library-similar-to-gnu-readline
- - http://tirania.org/blog/archive/2008/Aug-26.html
- - https://github.com/deveel/deveelrl
-
+ - step9_interop
Clojure:
Java:
- step9_interop
+ - store ILambda in function (like c#)?
Javascript:
@@ -50,10 +46,13 @@ PHP:
Postscript:
- negative numbers
- - debug self-hosting of mal step1
+ - fix self-hosting of mal step1
Python:
+Ruby:
+
+
---------------------------------------------
@@ -63,6 +62,10 @@ Future Implementations:
- http://www.rustforrubyists.com/book/index.html
- http://static.rust-lang.org/doc/0.9/complement-cheatsheet.html
- http://pzol.github.io/getting_rusty/
+ - release notes:
+ - https://github.com/mozilla/rust/wiki/Doc-detailed-release-notes
+ - this week in rust:
+ - http://cmr.github.io/
- readline:
- http://redbrain.co.uk/2013/11/09/rust-and-readline-c-ffi/
- http://www.reddit.com/r/rust/comments/1q9pqc/rust_cffi_and_readline/
@@ -72,6 +75,8 @@ Future Implementations:
- http://static.rust-lang.org/doc/master/std/hashmap/struct.HashMap.html
- vector/list:
- http://static.rust-lang.org/doc/master/std/vec/index.html
+ - example code:
+ - https://github.com/dradtke/rust-dominion/blob/master/dominion/mod.rs
- Redmonk languages from Jan 2014:
http://sogrady-media.redmonk.com/sogrady/files/2014/01/lang-rank-114-wm.png
diff --git a/java/src/main/java/mal/core.java b/java/src/main/java/mal/core.java
index 3200c0e..e1e6705 100644
--- a/java/src/main/java/mal/core.java
+++ b/java/src/main/java/mal/core.java
@@ -162,9 +162,7 @@ public class core {
}
};
- //
- // Hash map operations
- //
+ // HashMap functions
static MalFunction new_hash_map = new MalFunction() {
public MalVal apply(MalList a) throws MalThrowable {
return new MalHashMap(a);
@@ -271,42 +269,22 @@ public class core {
static MalFunction cons = new MalFunction() {
public MalVal apply(MalList a) throws MalThrowable {
- MalList lst = new MalList();
- lst.value.addAll(((MalList)a.nth(1)).value);
- lst.value.add(0, a.nth(0));
- return (MalVal) lst;
+ List<MalVal> lst = new ArrayList<MalVal>();
+ lst.add(a.nth(0));
+ lst.addAll(((MalList)a.nth(1)).getList());
+ return (MalVal)new MalList(lst);
}
};
static MalFunction concat = new MalFunction() {
public MalVal apply(MalList a) throws MalThrowable {
if (a.size() == 0) { return new MalList(); }
- MalList lst = new MalList();
- lst.value.addAll(((MalList)a.nth(0)).value);
+ List<MalVal> lst = new ArrayList<MalVal>();
+ lst.addAll(((MalList)a.nth(0)).value);
for(Integer i=1; i<a.size(); i++) {
- lst.value.addAll(((MalList)a.nth(i)).value);
+ lst.addAll(((MalList)a.nth(i)).value);
}
- return (MalVal) lst;
- }
- };
-
- static MalFunction conj = new MalFunction() {
- public MalVal apply(MalList a) throws MalThrowable {
- MalList src_seq = (MalList)a.nth(0), new_seq;
- if (a.nth(0) instanceof MalVector) {
- new_seq = new MalVector();
- new_seq.value.addAll(src_seq.value);
- for(Integer i=1; i<a.size(); i++) {
- new_seq.value.add(a.nth(i));
- }
- } else {
- new_seq = new MalList();
- new_seq.value.addAll(src_seq.value);
- for(Integer i=1; i<a.size(); i++) {
- new_seq.value.add(0, a.nth(i));
- }
- }
- return (MalVal) new_seq;
+ return (MalVal)new MalList(lst);
}
};
@@ -331,6 +309,26 @@ public class core {
}
};
+ static MalFunction conj = new MalFunction() {
+ public MalVal apply(MalList a) throws MalThrowable {
+ MalList src_seq = (MalList)a.nth(0), new_seq;
+ if (a.nth(0) instanceof MalVector) {
+ new_seq = new MalVector();
+ new_seq.value.addAll(src_seq.value);
+ for(Integer i=1; i<a.size(); i++) {
+ new_seq.value.add(a.nth(i));
+ }
+ } else {
+ new_seq = new MalList();
+ new_seq.value.addAll(src_seq.value);
+ for(Integer i=1; i<a.size(); i++) {
+ new_seq.value.add(0, a.nth(i));
+ }
+ }
+ return (MalVal) new_seq;
+ }
+ };
+
// General list related functions
static MalFunction apply = new MalFunction() {
public MalVal apply(MalList a) throws MalThrowable {
diff --git a/java/src/main/java/mal/step5_tco.java b/java/src/main/java/mal/step5_tco.java
index 43b93c6..9cd42d5 100644
--- a/java/src/main/java/mal/step5_tco.java
+++ b/java/src/main/java/mal/step5_tco.java
@@ -115,7 +115,7 @@ public class step5_tco {
MalVal fnast = f.getAst();
if (fnast != null) {
orig_ast = fnast;
- env = new Env(f.getEnv(), f.getParams(), el.slice(1));
+ env = f.genEnv(el.slice(1));
} else {
return f.apply(el.rest());
}
diff --git a/java/src/main/java/mal/step6_file.java b/java/src/main/java/mal/step6_file.java
index 0a1a99b..8d05b50 100644
--- a/java/src/main/java/mal/step6_file.java
+++ b/java/src/main/java/mal/step6_file.java
@@ -118,7 +118,7 @@ public class step6_file {
MalVal fnast = f.getAst();
if (fnast != null) {
orig_ast = fnast;
- env = new Env(f.getEnv(), f.getParams(), el.slice(1));
+ env = f.genEnv(el.slice(1));
} else {
return f.apply(el.rest());
}
@@ -157,6 +157,10 @@ public class step6_file {
}
_ref(repl_env, "read-string", new MalFunction() {
public MalVal apply(MalList args) throws MalThrowable {
+ try {
+ return reader.read_str(((MalString)args.nth(0)).getValue());
+ } catch (MalContinue c) {
+ return types.Nil;
return reader.read_str(((MalString)args.nth(0)).getValue());
}
});
diff --git a/java/src/main/java/mal/step7_quote.java b/java/src/main/java/mal/step7_quote.java
index 7105671..fbebb10 100644
--- a/java/src/main/java/mal/step7_quote.java
+++ b/java/src/main/java/mal/step7_quote.java
@@ -149,7 +149,7 @@ public class step7_quote {
MalVal fnast = f.getAst();
if (fnast != null) {
orig_ast = fnast;
- env = new Env(f.getEnv(), f.getParams(), el.slice(1));
+ env = f.genEnv(el.slice(1));
} else {
return f.apply(el.rest());
}
@@ -188,6 +188,10 @@ public class step7_quote {
}
_ref(repl_env, "read-string", new MalFunction() {
public MalVal apply(MalList args) throws MalThrowable {
+ try {
+ return reader.read_str(((MalString)args.nth(0)).getValue());
+ } catch (MalContinue c) {
+ return types.Nil;
return reader.read_str(((MalString)args.nth(0)).getValue());
}
});
diff --git a/java/src/main/java/mal/step8_macros.java b/java/src/main/java/mal/step8_macros.java
index c834119..bb99818 100644
--- a/java/src/main/java/mal/step8_macros.java
+++ b/java/src/main/java/mal/step8_macros.java
@@ -187,7 +187,7 @@ public class step8_macros {
MalVal fnast = f.getAst();
if (fnast != null) {
orig_ast = fnast;
- env = new Env(f.getEnv(), f.getParams(), el.slice(1));
+ env = f.genEnv(el.slice(1));
} else {
return f.apply(el.rest());
}
@@ -226,7 +226,11 @@ public class step8_macros {
}
_ref(repl_env, "read-string", new MalFunction() {
public MalVal apply(MalList args) throws MalThrowable {
- return reader.read_str(((MalString)args.nth(0)).getValue());
+ try {
+ return reader.read_str(((MalString)args.nth(0)).getValue());
+ } catch (MalContinue c) {
+ return types.Nil;
+ }
}
});
_ref(repl_env, "eval", new MalFunction() {
diff --git a/java/src/main/java/mal/stepA_more.java b/java/src/main/java/mal/stepA_more.java
index 9f4fb07..76b8501 100644
--- a/java/src/main/java/mal/stepA_more.java
+++ b/java/src/main/java/mal/stepA_more.java
@@ -213,7 +213,7 @@ public class stepA_more {
MalVal fnast = f.getAst();
if (fnast != null) {
orig_ast = fnast;
- env = new Env(f.getEnv(), f.getParams(), el.slice(1));
+ env = f.genEnv(el.slice(1));
} else {
return f.apply(el.rest());
}
diff --git a/java/src/main/java/mal/types.java b/java/src/main/java/mal/types.java
index a53c0e9..7ad419a 100644
--- a/java/src/main/java/mal/types.java
+++ b/java/src/main/java/mal/types.java
@@ -355,6 +355,9 @@ public class types {
public MalVal getAst() { return ast; }
public Env getEnv() { return env; }
public MalList getParams() { return params; }
+ public Env genEnv(MalList args) {
+ return new Env(env, params, args);
+ }
public Boolean isMacro() { return macro; }
public void setMacro() { macro = true; }
}
diff --git a/js/step5_tco.js b/js/step5_tco.js
index 9ba7a98..dbeaa90 100644
--- a/js/step5_tco.js
+++ b/js/step5_tco.js
@@ -68,7 +68,7 @@ function _EVAL(ast, env) {
case "fn*":
return types._function(EVAL, Env, a2, env, a1);
default:
- var el = eval_ast(ast, env), f = el[0], meta = f.__meta__;
+ var el = eval_ast(ast, env), f = el[0];
if (f.__ast__) {
ast = f.__ast__;
env = f.__gen_env__(el.slice(1));
diff --git a/js/step6_file.js b/js/step6_file.js
index ab4ba2f..ee39501 100644
--- a/js/step6_file.js
+++ b/js/step6_file.js
@@ -68,7 +68,7 @@ function _EVAL(ast, env) {
case "fn*":
return types._function(EVAL, Env, a2, env, a1);
default:
- var el = eval_ast(ast, env), f = el[0], meta = f.__meta__;
+ var el = eval_ast(ast, env), f = el[0];
if (f.__ast__) {
ast = f.__ast__;
env = f.__gen_env__(el.slice(1));
diff --git a/js/step7_quote.js b/js/step7_quote.js
index 3125083..6782647 100644
--- a/js/step7_quote.js
+++ b/js/step7_quote.js
@@ -23,9 +23,13 @@ function quasiquote(ast) {
} else if (ast[0].value === 'unquote') {
return ast[1];
} else if (is_pair(ast[0]) && ast[0][0].value === 'splice-unquote') {
- return [types._symbol("concat"), ast[0][1], quasiquote(ast.slice(1))];
+ return [types._symbol("concat"),
+ ast[0][1],
+ quasiquote(ast.slice(1))];
} else {
- return [types._symbol("cons"), quasiquote(ast[0]), quasiquote(ast.slice(1))];
+ return [types._symbol("cons"),
+ quasiquote(ast[0]),
+ quasiquote(ast.slice(1))];
}
}
@@ -88,7 +92,7 @@ function _EVAL(ast, env) {
case "fn*":
return types._function(EVAL, Env, a2, env, a1);
default:
- var el = eval_ast(ast, env), f = el[0], meta = f.__meta__;
+ var el = eval_ast(ast, env), f = el[0];
if (f.__ast__) {
ast = f.__ast__;
env = f.__gen_env__(el.slice(1));
diff --git a/js/step8_macros.js b/js/step8_macros.js
index 190cadc..f50bba4 100644
--- a/js/step8_macros.js
+++ b/js/step8_macros.js
@@ -23,9 +23,13 @@ function quasiquote(ast) {
} else if (ast[0].value === 'unquote') {
return ast[1];
} else if (is_pair(ast[0]) && ast[0][0].value === 'splice-unquote') {
- return [types._symbol("concat"), ast[0][1], quasiquote(ast.slice(1))];
+ return [types._symbol("concat"),
+ ast[0][1],
+ quasiquote(ast.slice(1))];
} else {
- return [types._symbol("cons"), quasiquote(ast[0]), quasiquote(ast.slice(1))];
+ return [types._symbol("cons"),
+ quasiquote(ast[0]),
+ quasiquote(ast.slice(1))];
}
}
@@ -112,7 +116,7 @@ function _EVAL(ast, env) {
case "fn*":
return types._function(EVAL, Env, a2, env, a1);
default:
- var el = eval_ast(ast, env), f = el[0], meta = f.__meta__;
+ var el = eval_ast(ast, env), f = el[0];
if (f.__ast__) {
ast = f.__ast__;
env = f.__gen_env__(el.slice(1));
diff --git a/js/step9_interop.js b/js/step9_interop.js
index 0fd7044..4987931 100644
--- a/js/step9_interop.js
+++ b/js/step9_interop.js
@@ -23,9 +23,13 @@ function quasiquote(ast) {
} else if (ast[0].value === 'unquote') {
return ast[1];
} else if (is_pair(ast[0]) && ast[0][0].value === 'splice-unquote') {
- return [types._symbol("concat"), ast[0][1], quasiquote(ast.slice(1))];
+ return [types._symbol("concat"),
+ ast[0][1],
+ quasiquote(ast.slice(1))];
} else {
- return [types._symbol("cons"), quasiquote(ast[0]), quasiquote(ast.slice(1))];
+ return [types._symbol("cons"),
+ quasiquote(ast[0]),
+ quasiquote(ast.slice(1))];
}
}
@@ -118,7 +122,7 @@ function _EVAL(ast, env) {
case "fn*":
return types._function(EVAL, Env, a2, env, a1);
default:
- var el = eval_ast(ast, env), f = el[0], meta = f.__meta__;
+ var el = eval_ast(ast, env), f = el[0];
if (f.__ast__) {
ast = f.__ast__;
env = f.__gen_env__(el.slice(1));
diff --git a/js/stepA_more.js b/js/stepA_more.js
index 6a2b949..a4fe21a 100644
--- a/js/stepA_more.js
+++ b/js/stepA_more.js
@@ -23,9 +23,13 @@ function quasiquote(ast) {
} else if (ast[0].value === 'unquote') {
return ast[1];
} else if (is_pair(ast[0]) && ast[0][0].value === 'splice-unquote') {
- return [types._symbol("concat"), ast[0][1], quasiquote(ast.slice(1))];
+ return [types._symbol("concat"),
+ ast[0][1],
+ quasiquote(ast.slice(1))];
} else {
- return [types._symbol("cons"), quasiquote(ast[0]), quasiquote(ast.slice(1))];
+ return [types._symbol("cons"),
+ quasiquote(ast[0]),
+ quasiquote(ast.slice(1))];
}
}
@@ -129,7 +133,7 @@ function _EVAL(ast, env) {
case "fn*":
return types._function(EVAL, Env, a2, env, a1);
default:
- var el = eval_ast(ast, env), f = el[0], meta = f.__meta__;
+ var el = eval_ast(ast, env), f = el[0];
if (f.__ast__) {
ast = f.__ast__;
env = f.__gen_env__(el.slice(1));