diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/TODO | 33 | ||||
| -rw-r--r-- | docs/steps/step0_repl.txt | 11 | ||||
| -rw-r--r-- | docs/steps/step1_read_print.txt | 14 | ||||
| -rw-r--r-- | docs/steps/step2_eval.txt | 25 | ||||
| -rw-r--r-- | docs/steps/step3_env.txt | 38 | ||||
| -rw-r--r-- | docs/steps/step4_if_fn_do.txt | 76 | ||||
| -rw-r--r-- | docs/steps/step5_tco.txt | 78 | ||||
| -rw-r--r-- | docs/steps/step6_file.txt | 85 | ||||
| -rw-r--r-- | docs/steps/step7_quote.txt | 92 | ||||
| -rw-r--r-- | docs/steps/step8_macros.txt | 102 | ||||
| -rw-r--r-- | docs/steps/step9_try.txt | 109 | ||||
| -rw-r--r-- | docs/steps/stepA_interop.txt | 112 | ||||
| -rw-r--r-- | docs/steps/stepA_interop2.txt | 131 |
13 files changed, 1 insertions, 905 deletions
@@ -1,16 +1,13 @@ All: - * keyword type (with hash-map key support) - * Move *host-language* from step9 to stepA - change perf test to run for 10 seconds and then calculate number of iterations per second - redefine (defmacro!) as (def! (macro*)) - runtest expect fixes: - stop using expect, so we can drop --raw option - fix long lines in runtext/expect - - add license file - add re (use in rep) everywhere and use that (to avoid printing) - move conj and sequential? to core.mal - - Implement/fix interop: C#, Java, Mal, PHP, Postscript, Ruby + - Implement/fix interop - regular expression matching in runtest - Print full exception when test gets EOF from expect @@ -66,8 +63,6 @@ Javascript: - interop: callbacks using Mal functions Make: - * large number handling (move away from peano) - * then fix time-ms/perf.mal - allow '_' in make variable names - hash-map with space in key string - Fix: make -f stepA_interop.mk ../mal/step6_file.mal @@ -95,33 +90,12 @@ Python: - python3 compatibility R: - - Links: - - https://stat.ethz.ch/R-manual/R-devel/library/base/html/readline.html - - http://dssm.unipa.it/CRAN/web/packages/rdyncall/rdyncall.pdf - - http://www.dyncall.org/docs/FFI.pdf - tracebacks in errors - fix running from different directory Ruby: Rust: - - Links: - - http://doc.rust-lang.org/index.html - - http://doc.rust-lang.org/intro.html - - http://doc.rust-lang.org/guide.html - - http://rustbyexample.com/index.html - - http://www.rustforrubyists.com/book/index.html - - http://pzol.github.io/getting_rusty/ - - - http://featherweightmusings.blogspot.com/2014/05/rust-for-c-programmers-part-6-rc-gc-and.html - - http://pzol.github.io/getting_rusty/posts/20140417_destructuring_in_rust/ (destructuring) - - http://featherweightmusings.blogspot.com/2014/07/rust-for-c-programmers-part-8.html (destructuring) - - http://featherweightmusings.blogspot.co.nz/2014/07/rust-for-c-programmers-part-9.html (destructuruing and matching) - - http://blog.thiago.me/notes-about-rust-modules/ - - http://doc.rust-lang.org/std/io/io - - https://github.com/shaleh/rust-readline/blob/master/src/lib.rs - - http://stackoverflow.com/questions/23942627/does-rust-0-10-have-a-rl-package - - http://blog.skylight.io/rust-means-never-having-to-close-a-socket/ - use built-in regex once fixed: https://github.com/rust-lang/rust/issues/18034 https://github.com/rust-lang/rust/issues/18035 @@ -130,14 +104,9 @@ Racket - metadata on collections Scala - - aptitude install scala - - http://learnxinyminutes.com/docs/scala/ - readline VB.Net - - aptitude install mono-vbnc - - http://www.codeproject.com/Articles/9978/Complete-Comparison-for-VB-NET-and-C - - http://msdn.microsoft.com/en-us/library/8hb2a397.aspx - convert readline.cs to readline.vb diff --git a/docs/steps/step0_repl.txt b/docs/steps/step0_repl.txt deleted file mode 100644 index db31e58..0000000 --- a/docs/steps/step0_repl.txt +++ /dev/null @@ -1,11 +0,0 @@ ---- step0_repl ---------------------------------- -READ(str): return str - -EVAL(ast,any): return ast - -PRINT(exp): return exp - -rep(str): return PRINT(EVAL(READ(str),"")) - -main loop: println(rep(readline("user> "))) - diff --git a/docs/steps/step1_read_print.txt b/docs/steps/step1_read_print.txt deleted file mode 100644 index 3a0fd7c..0000000 --- a/docs/steps/step1_read_print.txt +++ /dev/null @@ -1,14 +0,0 @@ ---- step1_read_print ---------------------------- -import reader, printer - -READ(str): return reader.read_str(str) - -EVAL(ast,env): return ast - -PRINT(exp): return printer.pr_str(exp) - -rep(str): return PRINT(EVAL(READ(str),"")) - -main loop: - try: println(rep(readline("user> "))) - catch e: println("Error: ", e) diff --git a/docs/steps/step2_eval.txt b/docs/steps/step2_eval.txt deleted file mode 100644 index beb5500..0000000 --- a/docs/steps/step2_eval.txt +++ /dev/null @@ -1,25 +0,0 @@ ---- step2_eval ---------------------------------- -import types, reader, printer - -READ(str): return reader.read_str(str) - -eval_ast(ast,env): - switch type(ast): - symbol: return lookup(env, ast) OR raise "'" + ast + "' not found" - list,vector: return ast.map((x) -> EVAL(x,env)) - hash: return ast.map((k,v) -> list(k, EVAL(v,env))) - _default_: return ast - -EVAL(ast,env): - if not list?(ast): return eval_ast(ast, env) - f, args = eval_ast(ast, env) - return apply(f, args) - -PRINT(exp): return printer.pr_str(exp) - -repl_env = {'+: add_fn, ...} -rep(str): return PRINT(EVAL(READ(str),repl_env)) - -main loop: - try: println(rep(readline("user> "))) - catch e: println("Error: ", e) diff --git a/docs/steps/step3_env.txt b/docs/steps/step3_env.txt deleted file mode 100644 index a1de572..0000000 --- a/docs/steps/step3_env.txt +++ /dev/null @@ -1,38 +0,0 @@ ---- step3_env ----------------------------------- -import types, reader, printer, env - -READ(str): return reader.read_str(str) - -eval_ast(ast,env): - switch type(ast): - symbol: return env.get(ast) - list,vector: return ast.map((x) -> EVAL(x,env)) - hash: return ast.map((k,v) -> list(k, EVAL(v,env))) - _default_: return ast - -EVAL(ast,env): - if not list?(ast): return eval_ast(ast, env) - switch ast[0]: - 'def!: return env.set(ast[1], EVAL(ast[2], env)) - 'let*: return EVAL(ast[2], ...) - _default_: f, args = eval_ast(ast, env) - return apply(f, args) - -PRINT(exp): return printer.pr_str(exp) - -repl_env = new Env() -rep(str): return PRINT(EVAL(READ(str),repl_env)) - -repl_env.set('+, add_fn) - ... - -main loop: - try: println(rep(readline("user> "))) - catch e: println("Error: ", e) - ---- env module ---------------------------------- -class Env (outer=null) - data = hash_map() - set(k,v): return data.set(k,v) - find(k): return data.has(k) ? this : (if outer ? find(outer) : null) - get(k): return data.find(k).get(k) OR raise "'" + k + "' not found" diff --git a/docs/steps/step4_if_fn_do.txt b/docs/steps/step4_if_fn_do.txt deleted file mode 100644 index 805d9b1..0000000 --- a/docs/steps/step4_if_fn_do.txt +++ /dev/null @@ -1,76 +0,0 @@ ---- step4_if_fn_do ------------------------------ -import types, reader, printer, env, core - -READ(str): return reader.read_str(str) - -eval_ast(ast,env): - switch type(ast): - symbol: return env.get(ast) - list,vector: return ast.map((x) -> EVAL(x,env)) - hash: return ast.map((k,v) -> list(k, EVAL(v,env))) - _default_: return ast - -EVAL(ast,env): - if not list?(ast): return eval_ast(ast, env) - switch ast[0]: - 'def!: return env.set(ast[1], EVAL(ast[2], env)) - 'let*: return EVAL(ast[2], ...) - 'do: return eval_ast(rest(ast), env)[-1] - 'if: return EVAL(EVAL(ast[1], env) ? ast[2] : ast[3], env) - 'fn*: return (...a) -> EVAL(ast[2], new Env(env, ast[1], a)) - _default_: f, args = eval_ast(ast, env) - return apply(f, args) - -PRINT(exp): return printer.pr_str(exp) - -repl_env = new Env() -rep(str): return PRINT(EVAL(READ(str),repl_env)) - -;; core.EXT: defined using Racket -core.ns.map((k,v) -> (repl_env.set(k, v))) - -;; core.mal: defined using the language itself -rep("(def! not (fn* (a) (if a false true)))") - -main loop: - try: println(rep(readline("user> "))) - catch e: println("Error: ", e) - ---- env module ---------------------------------- -class Env (outer=null,binds=[],exprs=[]) - data = hash_map() - foreach b, i in binds: - if binds[i] == '&: data[binds[i+1]] = exprs.drop(i); break - else: data[binds[i]] = exprs[i] - set(k,v): return data.set(k,v) - find(k): return data.has(k) ? this : (if outer ? find(outer) : null) - get(k): return data.find(k).get(k) OR raise "'" + k + "' not found" - ---- core module --------------------------------- -ns = {'=: equal?, - 'nil?: nil?, - 'true?: true?, - 'false?: false?, - 'symbol?: symbol?, - - 'pr-str: (a) -> a.map(|s| pr_str(e,true)).join(" ")), - 'str: (a) -> a.map(|s| pr_str(e,false)).join("")), - 'prn: (a) -> println(a.map(|s| pr_str(e,true)).join(" ")), - 'println: (a) -> println(a.map(|s| pr_str(e,false)).join(" ")), - - '<: lt, - '<=: lte, - '>: gt, - '>=: gte, - '+: add, - '-: sub, - '*: mult, - '/: div, - - 'list: list, - 'list?: list?, - 'hash-map: hash_map, - 'map?: hash_map?, - - 'empty?: empty?, - 'count: count} diff --git a/docs/steps/step5_tco.txt b/docs/steps/step5_tco.txt deleted file mode 100644 index 30e2a46..0000000 --- a/docs/steps/step5_tco.txt +++ /dev/null @@ -1,78 +0,0 @@ ---- step5_tco ----------------------------------- -import types, reader, printer, env, core - -READ(str): return reader.read_str(str) - -eval_ast(ast,env): - switch type(ast): - symbol: return env.get(ast) - list,vector: return ast.map((x) -> EVAL(x,env)) - hash: return ast.map((k,v) -> list(k, EVAL(v,env))) - _default_: return ast - -EVAL(ast,env): - while true: - if not list?(ast): return eval_ast(ast, env) - switch ast[0]: - 'def!: return env.set(ast[1], EVAL(ast[2], env)) - 'let*: env = ...; ast = ast[2] // TCO - 'do: ast = eval_ast(ast[1..-1], env)[-1] // TCO - 'if: EVAL(ast[1], env) ? ast = ast[2] : ast = ast[3] // TCO - 'fn*: return new MalFunc(...) - _default_: f, args = eval_ast(ast, env) - if malfunc?(ast[0]): ast = ast[0].fn; env = ... // TCO - else: return apply(f, args) - -PRINT(exp): return printer.pr_str(exp) - -repl_env = new Env() -rep(str): return PRINT(EVAL(READ(str),repl_env)) - -;; core.EXT: defined using Racket -core.ns.map((k,v) -> (repl_env.set(k, v))) - -;; core.mal: defined using the language itself -rep("(def! not (fn* (a) (if a false true)))") - -main loop: - try: println(rep(readline("user> "))) - catch e: println("Error: ", e) - ---- env module ---------------------------------- -class Env (outer=null,binds=[],exprs=[]) - data = hash_map() - foreach b, i in binds: - if binds[i] == '&: data[binds[i+1]] = exprs.drop(i); break - else: data[binds[i]] = exprs[i] - set(k,v): return data.set(k,v) - find(k): return data.has(k) ? this : (if outer ? find(outer) : null) - get(k): return data.find(k).get(k) OR raise "'" + k + "' not found" - ---- core module --------------------------------- -ns = {'=: equal?, - 'nil?: nil?, - 'true?: true?, - 'false?: false?, - 'symbol?: symbol?, - - 'pr-str: (a) -> a.map(|s| pr_str(e,true)).join(" ")), - 'str: (a) -> a.map(|s| pr_str(e,false)).join("")), - 'prn: (a) -> println(a.map(|s| pr_str(e,true)).join(" ")), - 'println: (a) -> println(a.map(|s| pr_str(e,false)).join(" ")), - - '<: lt, - '<=: lte, - '>: gt, - '>=: gte, - '+: add, - '-: sub, - '*: mult, - '/: div, - - 'list: list, - 'list?: list?, - 'hash-map: hash_map, - 'map?: hash_map?, - - 'empty?: empty?, - 'count: count} diff --git a/docs/steps/step6_file.txt b/docs/steps/step6_file.txt deleted file mode 100644 index bccf8fa..0000000 --- a/docs/steps/step6_file.txt +++ /dev/null @@ -1,85 +0,0 @@ ---- step6_file ---------------------------------- -import types, reader, printer, env, core - -READ(str): return reader.read_str(str) - -eval_ast(ast,env): - switch type(ast): - symbol: return env.get(ast) - list,vector: return ast.map((x) -> EVAL(x,env)) - hash: return ast.map((k,v) -> list(k, EVAL(v,env))) - _default_: return ast - -EVAL(ast,env): - while true: - if not list?(ast): return eval_ast(ast, env) - switch ast[0]: - 'def!: return env.set(ast[1], EVAL(ast[2], env)) - 'let*: env = ...; ast = ast[2] // TCO - 'do: ast = eval_ast(ast[1..-1], env)[-1] // TCO - 'if: EVAL(ast[1], env) ? ast = ast[2] : ast = ast[3] // TCO - 'fn*: return new MalFunc(...) - _default_: f, args = eval_ast(ast, env) - if malfunc?(ast[0]): ast = ast[0].fn; env = ... // TCO - else: return apply(f, args) - -PRINT(exp): return printer.pr_str(exp) - -repl_env = new Env() -rep(str): return PRINT(EVAL(READ(str),repl_env)) - -;; core.EXT: defined using Racket -core.ns.map((k,v) -> (repl_env.set(k, v))) -repl_env.set('eval, (ast) -> EVAL(ast, repl-env)) -repl_env.set('*ARGV*, cmdline_args[1..]) - -;; core.mal: defined using the language itself -rep("(def! not (fn* (a) (if a false true)))") -rep("(def! load-file (fn* (f) ...))") - -if cmdline_args: rep("(load-file \"" + args[0] + "\")"); exit 0 - -main loop: - try: println(rep(readline("user> "))) - catch e: println("Error: ", e) - ---- env module ---------------------------------- -class Env (outer=null,binds=[],exprs=[]) - data = hash_map() - foreach b, i in binds: - if binds[i] == '&: data[binds[i+1]] = exprs.drop(i); break - else: data[binds[i]] = exprs[i] - set(k,v): return data.set(k,v) - find(k): return data.has(k) ? this : (if outer ? find(outer) : null) - get(k): return data.find(k).get(k) OR raise "'" + k + "' not found" - ---- core module --------------------------------- -ns = {'=: equal?, - 'nil?: nil?, - 'true?: true?, - 'false?: false?, - 'symbol?: symbol?, - - 'pr-str: (a) -> a.map(|s| pr_str(e,true)).join(" ")), - 'str: (a) -> a.map(|s| pr_str(e,false)).join("")), - 'prn: (a) -> println(a.map(|s| pr_str(e,true)).join(" ")), - 'println: (a) -> println(a.map(|s| pr_str(e,false)).join(" ")), - 'read-string: read_str, - 'slurp read-file, - - '<: lt, - '<=: lte, - '>: gt, - '>=: gte, - '+: add, - '-: sub, - '*: mult, - '/: div, - - 'list: list, - 'list?: list?, - 'hash-map: hash_map, - 'map?: hash_map?, - - 'empty?: empty?, - 'count: count} diff --git a/docs/steps/step7_quote.txt b/docs/steps/step7_quote.txt deleted file mode 100644 index c166257..0000000 --- a/docs/steps/step7_quote.txt +++ /dev/null @@ -1,92 +0,0 @@ ---- step7_quote --------------------------------- -import types, reader, printer, env, core - -READ(str): return reader.read_str(str) - -pair?(ast): return ... // true if non-empty sequence -quasiquote(ast): return ... // quasiquote - -eval_ast(ast,env): - switch type(ast): - symbol: return env.get(ast) - list,vector: return ast.map((x) -> EVAL(x,env)) - hash: return ast.map((k,v) -> list(k, EVAL(v,env))) - _default_: return ast - -EVAL(ast,env): - while true: - if not list?(ast): return eval_ast(ast, env) - switch ast[0]: - 'def!: return env.set(ast[1], EVAL(ast[2], env)) - 'let*: env = ...; ast = ast[2] // TCO - 'quote: return ast[1] - 'quasiquote: ast = quasiquote(ast[1]) // TCO - 'do: ast = eval_ast(ast[1..-1], env)[-1] // TCO - 'if: EVAL(ast[1], env) ? ast = ast[2] : ast = ast[3] // TCO - 'fn*: return new MalFunc(...) - _default_: f, args = eval_ast(ast, env) - if malfunc?(ast[0]): ast = ast[0].fn; env = ... // TCO - else: return apply(f, args) - -PRINT(exp): return printer.pr_str(exp) - -repl_env = new Env() -rep(str): return PRINT(EVAL(READ(str),repl_env)) - -;; core.EXT: defined using Racket -core.ns.map((k,v) -> (repl_env.set(k, v))) -repl_env.set('eval, (ast) -> EVAL(ast, repl-env)) -repl_env.set('*ARGV*, cmdline_args[1..]) - -;; core.mal: defined using the language itself -rep("(def! not (fn* (a) (if a false true)))") -rep("(def! load-file (fn* (f) ...))") - -if cmdline_args: rep("(load-file \"" + args[0] + "\")"); exit 0 - -main loop: - try: println(rep(readline("user> "))) - catch e: println("Error: ", e) - ---- env module ---------------------------------- -class Env (outer=null,binds=[],exprs=[]) - data = hash_map() - foreach b, i in binds: - if binds[i] == '&: data[binds[i+1]] = exprs.drop(i); break - else: data[binds[i]] = exprs[i] - set(k,v): return data.set(k,v) - find(k): return data.has(k) ? this : (if outer ? find(outer) : null) - get(k): return data.find(k).get(k) OR raise "'" + k + "' not found" - ---- core module --------------------------------- -ns = {'=: equal?, - 'nil?: nil?, - 'true?: true?, - 'false?: false?, - 'symbol?: symbol?, - - 'pr-str: (a) -> a.map(|s| pr_str(e,true)).join(" ")), - 'str: (a) -> a.map(|s| pr_str(e,false)).join("")), - 'prn: (a) -> println(a.map(|s| pr_str(e,true)).join(" ")), - 'println: (a) -> println(a.map(|s| pr_str(e,false)).join(" ")), - 'read-string: read_str, - 'slurp read-file, - - '<: lt, - '<=: lte, - '>: gt, - '>=: gte, - '+: add, - '-: sub, - '*: mult, - '/: div, - - 'list: list, - 'list?: list?, - 'hash-map: hash_map, - 'map?: hash_map?, - - 'cons: (a) -> concat([a[0]], a[1]), - 'concat: (a) -> reduce(concat, [], a), - 'empty?: empty?, - 'count: count} diff --git a/docs/steps/step8_macros.txt b/docs/steps/step8_macros.txt deleted file mode 100644 index da68191..0000000 --- a/docs/steps/step8_macros.txt +++ /dev/null @@ -1,102 +0,0 @@ ---- step8_macros -------------------------------- -import types, reader, printer, env, core - -READ(str): return reader.read_str(str) - -pair?(ast): return ... // true if non-empty sequence -quasiquote(ast): return ... // quasiquote - -macro?(ast, env): return ... // true if macro function -macroexpand(ast, env): return ... // recursive macro expansion - -eval_ast(ast,env): - switch type(ast): - symbol: return env.get(ast) - list,vector: return ast.map((x) -> EVAL(x,env)) - hash: return ast.map((k,v) -> list(k, EVAL(v,env))) - _default_: return ast - -EVAL(ast,env): - while true: - if not list?(ast): return eval_ast(ast, env) - switch ast[0]: - 'def!: return env.set(ast[1], EVAL(ast[2], env)) - 'let*: env = ...; ast = ast[2] // TCO - 'quote: return ast[1] - 'quasiquote: ast = quasiquote(ast[1]) // TCO - 'defmacro!: return ... // like def!, but set macro property - 'macroexpand: return macroexpand(ast[1], env) - 'do: ast = eval_ast(ast[1..-1], env)[-1] // TCO - 'if: EVAL(ast[1], env) ? ast = ast[2] : ast = ast[3] // TCO - 'fn*: return new MalFunc(...) - _default_: f, args = eval_ast(ast, env) - if malfunc?(ast[0]): ast = ast[0].fn; env = ... // TCO - else: return apply(f, args) - -PRINT(exp): return printer.pr_str(exp) - -repl_env = new Env() -rep(str): return PRINT(EVAL(READ(str),repl_env)) - -;; core.EXT: defined using Racket -core.ns.map((k,v) -> (repl_env.set(k, v))) -repl_env.set('eval, (ast) -> EVAL(ast, repl-env)) -repl_env.set('*ARGV*, cmdline_args[1..]) - -;; core.mal: defined using the language itself -rep("(def! not (fn* (a) (if a false true)))") -rep("(def! load-file (fn* (f) ...))") -rep("(defmacro! cond (fn* (& xs) ...))") -rep("(defmacro! or (fn* (& xs) ...))") - -if cmdline_args: rep("(load-file \"" + args[0] + "\")"); exit 0 - -main loop: - try: println(rep(readline("user> "))) - catch e: println("Error: ", e) - ---- env module ---------------------------------- -class Env (outer=null,binds=[],exprs=[]) - data = hash_map() - foreach b, i in binds: - if binds[i] == '&: data[binds[i+1]] = exprs.drop(i); break - else: data[binds[i]] = exprs[i] - set(k,v): return data.set(k,v) - find(k): return data.has(k) ? this : (if outer ? find(outer) : null) - get(k): return data.find(k).get(k) OR raise "'" + k + "' not found" - ---- core module --------------------------------- -ns = {'=: equal?, - 'nil?: nil?, - 'true?: true?, - 'false?: false?, - 'symbol?: symbol?, - - 'pr-str: (a) -> a.map(|s| pr_str(e,true)).join(" ")), - 'str: (a) -> a.map(|s| pr_str(e,false)).join("")), - 'prn: (a) -> println(a.map(|s| pr_str(e,true)).join(" ")), - 'println: (a) -> println(a.map(|s| pr_str(e,false)).join(" ")), - 'read-string: read_str, - 'slurp read-file, - - '<: lt, - '<=: lte, - '>: gt, - '>=: gte, - '+: add, - '-: sub, - '*: mult, - '/: div, - - 'list: list, - 'list?: list?, - 'hash-map: hash_map, - 'map?: hash_map?, - - 'cons: (a) -> concat([a[0]], a[1]), - 'concat: (a) -> reduce(concat, [], a), - 'nth: (a) -> a[0][a[1]] OR raise "nth: index out of range", - 'first: (a) -> a[0][0] OR nil, - 'rest: (a) -> a[0][1..] OR list(), - 'empty?: empty?, - 'count: count} diff --git a/docs/steps/step9_try.txt b/docs/steps/step9_try.txt deleted file mode 100644 index f0bb5c9..0000000 --- a/docs/steps/step9_try.txt +++ /dev/null @@ -1,109 +0,0 @@ ---- step9_try ----------------------------------- -import types, reader, printer, env, core - -READ(str): return reader.read_str(str) - -pair?(ast): return ... // true if non-empty sequence -quasiquote(ast): return ... // quasiquote - -macro?(ast, env): return ... // true if macro function -macroexpand(ast, env): return ... // recursive macro expansion - -eval_ast(ast,env): - switch type(ast): - symbol: return env.get(ast) - list,vector: return ast.map((x) -> EVAL(x,env)) - hash: return ast.map((k,v) -> list(k, EVAL(v,env))) - _default_: return ast - -EVAL(ast,env): - while true: - if not list?(ast): return eval_ast(ast, env) - switch ast[0]: - 'def!: return env.set(ast[1], EVAL(ast[2], env)) - 'let*: env = ...; ast = ast[2] // TCO - 'quote: return ast[1] - 'quasiquote: ast = quasiquote(ast[1]) // TCO - 'defmacro!: return ... // like def!, but set macro property - 'macroexpand: return macroexpand(ast[1], env) - 'try*: return ... // try/catch native and malval exceptions - 'do: ast = eval_ast(ast[1..-1], env)[-1] // TCO - 'if: EVAL(ast[1], env) ? ast = ast[2] : ast = ast[3] // TCO - 'fn*: return new MalFunc(...) - _default_: f, args = eval_ast(ast, env) - if malfunc?(ast[0]): ast = ast[0].fn; env = ... // TCO - else: return apply(f, args) - -PRINT(exp): return printer.pr_str(exp) - -repl_env = new Env() -rep(str): return PRINT(EVAL(READ(str),repl_env)) - -;; core.EXT: defined using Racket -core.ns.map((k,v) -> (repl_env.set(k, v))) -repl_env.set('eval, (ast) -> EVAL(ast, repl-env)) -repl_env.set('*ARGV*, cmdline_args[1..]) - -;; core.mal: defined using the language itself -rep("(def! not (fn* (a) (if a false true)))") -rep("(def! load-file (fn* (f) ...))") -rep("(defmacro! cond (fn* (& xs) ...))") -rep("(defmacro! or (fn* (& xs) ...))") - -if cmdline_args: rep("(load-file \"" + args[0] + "\")"); exit 0 - -main loop: - try: println(rep(readline("user> "))) - catch e: println("Error: ", e) - ---- env module ---------------------------------- -class Env (outer=null,binds=[],exprs=[]) - data = hash_map() - foreach b, i in binds: - if binds[i] == '&: data[binds[i+1]] = exprs.drop(i); break - else: data[binds[i]] = exprs[i] - set(k,v): return data.set(k,v) - find(k): return data.has(k) ? this : (if outer ? find(outer) : null) - get(k): return data.find(k).get(k) OR raise "'" + k + "' not found" - ---- core module --------------------------------- -ns = {'=: equal?, - 'throw: throw, - - 'nil?: nil?, - 'true?: true?, - 'false?: false?, - 'symbol: symbol, - 'symbol?: symbol?, - - 'pr-str: (a) -> a.map(|s| pr_str(e,true)).join(" ")), - 'str: (a) -> a.map(|s| pr_str(e,false)).join("")), - 'prn: (a) -> println(a.map(|s| pr_str(e,true)).join(" ")), - 'println: (a) -> println(a.map(|s| pr_str(e,false)).join(" ")), - 'read-string: read_str, - 'readline: readline, - 'slurp read-file, - - '<: lt, - '<=: lte, - '>: gt, - '>=: gte, - '+: add, - '-: sub, - '*: mult, - '/: div, - - 'list: list, - 'list?: list?, - 'hash-map: hash_map, - 'map?: hash_map?, - - 'cons: (a) -> concat([a[0]], a[1]), - 'concat: (a) -> reduce(concat, [], a), - 'nth: (a) -> a[0][a[1]] OR raise "nth: index out of range", - 'first: (a) -> a[0][0] OR nil, - 'rest: (a) -> a[0][1..] OR list(), - 'empty?: empty?, - 'count: count, - 'apply: apply, - 'map: map} diff --git a/docs/steps/stepA_interop.txt b/docs/steps/stepA_interop.txt deleted file mode 100644 index c909056..0000000 --- a/docs/steps/stepA_interop.txt +++ /dev/null @@ -1,112 +0,0 @@ ---- stepA_interop ------------------------------- -import types, reader, printer, env, core - -READ(str): return reader.read_str(str) - -pair?(ast): return ... // true if non-empty sequence -quasiquote(ast): return ... // quasiquote - -macro?(ast, env): return ... // true if macro function -macroexpand(ast, env): return ... // recursive macro expansion - -eval_ast(ast,env): - switch type(ast): - symbol: return env.get(ast) - list,vector: return ast.map((x) -> EVAL(x,env)) - hash: return ast.map((k,v) -> list(k, EVAL(v,env))) - _default_: return ast - -EVAL(ast,env): - while true: - if not list?(ast): return eval_ast(ast, env) - switch ast[0]: - 'def!: return env.set(ast[1], EVAL(ast[2], env)) - 'let*: env = ...; ast = ast[2] // TCO - 'quote: return ast[1] - 'quasiquote: ast = quasiquote(ast[1]) // TCO - 'defmacro!: return ... // like def!, but set macro property - 'macroexpand: return macroexpand(ast[1], env) - 'try*: return ... // try/catch native and malval exceptions - 'do: ast = eval_ast(ast[1..-1], env)[-1] // TCO - 'if: EVAL(ast[1], env) ? ast = ast[2] : ast = ast[3] // TCO - 'fn*: return new MalFunc(...) - _default_: f, args = eval_ast(ast, env) - if malfunc?(ast[0]): ast = ast[0].fn; env = ... // TCO - else: return apply(f, args) - -PRINT(exp): return printer.pr_str(exp) - -repl_env = new Env() -rep(str): return PRINT(EVAL(READ(str),repl_env)) - -;; core.EXT: defined using Racket -core.ns.map((k,v) -> (repl_env.set(k, v))) -repl_env.set('eval, (ast) -> EVAL(ast, repl-env)) -repl_env.set('*ARGV*, cmdline_args[1..]) - -;; core.mal: defined using the language itself -rep("(def! *host-language* \"racket\")") -rep("(def! not (fn* (a) (if a false true)))") -rep("(def! load-file (fn* (f) ...))") -rep("(defmacro! cond (fn* (& xs) ...))") -rep("(defmacro! or (fn* (& xs) ...))") - -if cmdline_args: rep("(load-file \"" + args[0] + "\")"); exit 0 - -rep("(println (str \"Mal [\" *host-language* \"]\"))") -main loop: - try: println(rep(readline("user> "))) - catch e: println("Error: ", e) - ---- env module ---------------------------------- -class Env (outer=null,binds=[],exprs=[]) - data = hash_map() - foreach b, i in binds: - if binds[i] == '&: data[binds[i+1]] = exprs.drop(i); break - else: data[binds[i]] = exprs[i] - set(k,v): return data.set(k,v) - find(k): return data.has(k) ? this : (if outer ? find(outer) : null) - get(k): return data.find(k).get(k) OR raise "'" + k + "' not found" - ---- core module --------------------------------- -ns = {'=: equal?, - 'throw: throw, - - 'nil?: nil?, - 'true?: true?, - 'false?: false?, - 'symbol: symbol, - 'symbol?: symbol?, - - 'pr-str: (a) -> a.map(|s| pr_str(e,true)).join(" ")), - 'str: (a) -> a.map(|s| pr_str(e,false)).join("")), - 'prn: (a) -> println(a.map(|s| pr_str(e,true)).join(" ")), - 'println: (a) -> println(a.map(|s| pr_str(e,false)).join(" ")), - 'read-string: read_str, - 'readline: readline, - 'slurp read-file, - - '<: lt, - '<=: lte, - '>: gt, - '>=: gte, - '+: add, - '-: sub, - '*: mult, - '/: div, - 'time-ms cur-epoch-millis, - - 'list: list, - 'list?: list?, - 'hash-map: hash_map, - 'map?: hash_map?, - - 'cons: (a) -> concat([a[0]], a[1]), - 'concat: (a) -> reduce(concat, [], a), - 'nth: (a) -> a[0][a[1]] OR raise "nth: index out of range", - 'first: (a) -> a[0][0] OR nil, - 'rest: (a) -> a[0][1..] OR list(), - 'empty?: empty?, - 'count: count, - 'apply: apply, - 'map: map} diff --git a/docs/steps/stepA_interop2.txt b/docs/steps/stepA_interop2.txt deleted file mode 100644 index 05dfe8c..0000000 --- a/docs/steps/stepA_interop2.txt +++ /dev/null @@ -1,131 +0,0 @@ ---- stepA_interop ------------------------------- -import types, reader, printer, env, core - -READ(str): return reader.read_str(str) - -pair?(ast): return ... // true if non-empty sequence -quasiquote(ast): return ... // quasiquote - -macro?(ast, env): return ... // true if macro function -macroexpand(ast, env): return ... // recursive macro expansion - -eval_ast(ast,env): - switch type(ast): - symbol: return env.get(ast) - list,vector: return ast.map((x) -> EVAL(x,env)) - hash: return ast.map((k,v) -> list(k, EVAL(v,env))) - _default_: return ast - -EVAL(ast,env): - while true: - if not list?(ast): return eval_ast(ast, env) - switch ast[0]: - 'def!: return env.set(ast[1], EVAL(ast[2], env)) - 'let*: env = ...; ast = ast[2] // TCO - 'quote: return ast[1] - 'quasiquote: ast = quasiquote(ast[1]) // TCO - 'defmacro!: return ... // like def!, but set macro property - 'macroexpand: return macroexpand(ast[1], env) - 'try*: return ... // try/catch native and malval exceptions - 'do: ast = eval_ast(ast[1..-1], env)[-1] // TCO - 'if: EVAL(ast[1], env) ? ast = ast[2] : ast = ast[3] // TCO - 'fn*: return new MalFunc(...) - _default_: f, args = eval_ast(ast, env) - if malfunc?(ast[0]): ast = ast[0].fn; env = ... // TCO - else: return apply(f, args) - -PRINT(exp): return printer.pr_str(exp) - -repl_env = new Env() -rep(str): return PRINT(EVAL(READ(str),repl_env)) - -;; core.EXT: defined using Racket -core.ns.map((k,v) -> (repl_env.set(k, v))) -repl_env.set('eval, (ast) -> EVAL(ast, repl-env)) -repl_env.set('*ARGV*, cmdline_args[1..]) - -;; core.mal: defined using the language itself -rep("(def! *host-language* \"racket\")") -rep("(def! not (fn* (a) (if a false true)))") -rep("(def! load-file (fn* (f) ...))") -rep("(defmacro! cond (fn* (& xs) ...))") -rep("(defmacro! or (fn* (& xs) ...))") - -if cmdline_args: rep("(load-file \"" + args[0] + "\")"); exit 0 - -rep("(println (str \"Mal [\" *host-language* \"]\"))") -main loop: - try: println(rep(readline("user> "))) - catch e: println("Error: ", e) - ---- env module ---------------------------------- -class Env (outer=null,binds=[],exprs=[]) - data = hash_map() - foreach b, i in binds: - if binds[i] == '&: data[binds[i+1]] = exprs.drop(i); break - else: data[binds[i]] = exprs[i] - set(k,v): return data.set(k,v) - find(k): return data.has(k) ? this : (if outer ? find(outer) : null) - get(k): return data.find(k).get(k) OR raise "'" + k + "' not found" - ---- core module --------------------------------- -ns = {'=: equal?, - 'throw: throw, - - 'nil?: nil?, - 'true?: true?, - 'false?: false?, - 'symbol: symbol, - 'symbol?: symbol?, - 'keyword: keyword, - 'keyword?: keyword?, - - 'pr-str: (a) -> a.map(|s| pr_str(e,true)).join(" ")), - 'str: (a) -> a.map(|s| pr_str(e,false)).join("")), - 'prn: (a) -> println(a.map(|s| pr_str(e,true)).join(" ")), - 'println: (a) -> println(a.map(|s| pr_str(e,false)).join(" ")), - 'read-string: read_str, - 'readline: readline, - 'slurp read-file, - - '<: lt, - '<=: lte, - '>: gt, - '>=: gte, - '+: add, - '-: sub, - '*: mult, - '/: div, - - 'list: list, - 'list?: list?, - 'vector: vector, - 'vector?: vector?, - 'hash-map: hash_map, - 'map?: hash_map?, - 'assoc: assoc, - 'dissoc: dissoc, - 'get: get, - 'contains?: contains?, - 'keys: keys, - 'vals: vals, - - 'sequential? sequential?, - 'cons: (a) -> concat([a[0]], a[1]), - 'concat: (a) -> reduce(concat, [], a), - 'nth: (a) -> a[0][a[1]] OR raise "nth: index out of range", - 'first: (a) -> a[0][0] OR nil, - 'rest: (a) -> a[0][1..] OR list(), - 'empty?: empty?, - 'count: count, - 'apply: apply, - 'map: map, - 'conj: conj, - - 'meta: (a) -> a[0].meta, - 'with-meta: (a) -> a[0].with_meta(a[1]), - 'atom: (a) -> new Atom(a[0]), - 'atom?: (a) -> type(a[0]) == "atom", - 'deref: (a) -> a[0].val, - 'reset!: (a) -> a[0].val = a[1], - 'swap!: swap!} |
