aboutsummaryrefslogtreecommitdiff
path: root/ruby
diff options
context:
space:
mode:
Diffstat (limited to 'ruby')
-rw-r--r--ruby/step2_eval.rb6
-rw-r--r--ruby/step3_env.rb6
-rw-r--r--ruby/step4_if_fn_do.rb6
-rw-r--r--ruby/step5_tco.rb6
-rw-r--r--ruby/step6_file.rb6
-rw-r--r--ruby/step7_quote.rb6
-rw-r--r--ruby/step8_macros.rb17
-rw-r--r--ruby/step9_interop.rb17
-rw-r--r--ruby/stepA_more.rb18
-rw-r--r--ruby/types.rb5
10 files changed, 70 insertions, 23 deletions
diff --git a/ruby/step2_eval.rb b/ruby/step2_eval.rb
index 9cbae24..9318099 100644
--- a/ruby/step2_eval.rb
+++ b/ruby/step2_eval.rb
@@ -18,12 +18,18 @@ def eval_ast(ast, env)
List.new ast.map{|a| EVAL(a, env)}
when Vector
Vector.new ast.map{|a| EVAL(a, env)}
+ when Hash
+ new_hm = {}
+ ast.each{|k,v| new_hm[EVAL(k,env)] = EVAL(v, env)}
+ new_hm
else
ast
end
end
def EVAL(ast, env)
+ #puts "EVAL: #{_pr_str(ast, true)}"
+
if not ast.is_a? List
return eval_ast(ast, env)
end
diff --git a/ruby/step3_env.rb b/ruby/step3_env.rb
index 9d1c373..ee80432 100644
--- a/ruby/step3_env.rb
+++ b/ruby/step3_env.rb
@@ -18,12 +18,18 @@ def eval_ast(ast, env)
List.new ast.map{|a| EVAL(a, env)}
when Vector
Vector.new ast.map{|a| EVAL(a, env)}
+ when Hash
+ new_hm = {}
+ ast.each{|k,v| new_hm[EVAL(k,env)] = EVAL(v, env)}
+ new_hm
else
ast
end
end
def EVAL(ast, env)
+ #puts "EVAL: #{_pr_str(ast, true)}"
+
if not ast.is_a? List
return eval_ast(ast, env)
end
diff --git a/ruby/step4_if_fn_do.rb b/ruby/step4_if_fn_do.rb
index e2e3e29..e99ed6c 100644
--- a/ruby/step4_if_fn_do.rb
+++ b/ruby/step4_if_fn_do.rb
@@ -19,12 +19,18 @@ def eval_ast(ast, env)
List.new ast.map{|a| EVAL(a, env)}
when Vector
Vector.new ast.map{|a| EVAL(a, env)}
+ when Hash
+ new_hm = {}
+ ast.each{|k,v| new_hm[EVAL(k,env)] = EVAL(v, env)}
+ new_hm
else
ast
end
end
def EVAL(ast, env)
+ #puts "EVAL: #{_pr_str(ast, true)}"
+
if not ast.is_a? List
return eval_ast(ast, env)
end
diff --git a/ruby/step5_tco.rb b/ruby/step5_tco.rb
index 8eb73c8..0b28a09 100644
--- a/ruby/step5_tco.rb
+++ b/ruby/step5_tco.rb
@@ -19,6 +19,10 @@ def eval_ast(ast, env)
List.new ast.map{|a| EVAL(a, env)}
when Vector
Vector.new ast.map{|a| EVAL(a, env)}
+ when Hash
+ new_hm = {}
+ ast.each{|k,v| new_hm[EVAL(k,env)] = EVAL(v, env)}
+ new_hm
else
ast
end
@@ -27,6 +31,8 @@ end
def EVAL(ast, env)
while true
+ #puts "EVAL: #{_pr_str(ast, true)}"
+
if not ast.is_a? List
return eval_ast(ast, env)
end
diff --git a/ruby/step6_file.rb b/ruby/step6_file.rb
index 9d0324f..01d1988 100644
--- a/ruby/step6_file.rb
+++ b/ruby/step6_file.rb
@@ -19,6 +19,10 @@ def eval_ast(ast, env)
List.new ast.map{|a| EVAL(a, env)}
when Vector
Vector.new ast.map{|a| EVAL(a, env)}
+ when Hash
+ new_hm = {}
+ ast.each{|k,v| new_hm[EVAL(k,env)] = EVAL(v, env)}
+ new_hm
else
ast
end
@@ -27,6 +31,8 @@ end
def EVAL(ast, env)
while true
+ #puts "EVAL: #{_pr_str(ast, true)}"
+
if not ast.is_a? List
return eval_ast(ast, env)
end
diff --git a/ruby/step7_quote.rb b/ruby/step7_quote.rb
index 6e6acca..d2ad6ed 100644
--- a/ruby/step7_quote.rb
+++ b/ruby/step7_quote.rb
@@ -35,6 +35,10 @@ def eval_ast(ast, env)
List.new ast.map{|a| EVAL(a, env)}
when Vector
Vector.new ast.map{|a| EVAL(a, env)}
+ when Hash
+ new_hm = {}
+ ast.each{|k,v| new_hm[EVAL(k,env)] = EVAL(v, env)}
+ new_hm
else
ast
end
@@ -43,6 +47,8 @@ end
def EVAL(ast, env)
while true
+ #puts "EVAL: #{_pr_str(ast, true)}"
+
if not ast.is_a? List
return eval_ast(ast, env)
end
diff --git a/ruby/step8_macros.rb b/ruby/step8_macros.rb
index 6d88d82..13a742d 100644
--- a/ruby/step8_macros.rb
+++ b/ruby/step8_macros.rb
@@ -11,20 +11,19 @@ def READ(str)
end
# eval
-def is_pair(x)
+def pair?(x)
return sequential?(x) && x.size > 0
end
def quasiquote(ast)
- if not is_pair(ast)
- return List.new([:quote, ast])
+ if not pair?(ast)
+ return List.new [:quote, ast]
elsif ast[0] == :unquote
return ast[1]
- elsif is_pair(ast[0]) && ast[0][0] == :"splice-unquote"
- #p "xxx:", ast, List.new([:concat, ast[0][1], quasiquote(ast.drop(1))])
- return List.new([:concat, ast[0][1], quasiquote(ast.drop(1))])
+ elsif pair?(ast[0]) && ast[0][0] == :"splice-unquote"
+ return List.new [:concat, ast[0][1], quasiquote(ast.drop(1))]
else
- return List.new([:cons, quasiquote(ast[0]), quasiquote(ast.drop(1))])
+ return List.new [:cons, quasiquote(ast[0]), quasiquote(ast.drop(1))]
end
end
@@ -52,6 +51,10 @@ def eval_ast(ast, env)
List.new ast.map{|a| EVAL(a, env)}
when Vector
Vector.new ast.map{|a| EVAL(a, env)}
+ when Hash
+ new_hm = {}
+ ast.each{|k,v| new_hm[EVAL(k,env)] = EVAL(v, env)}
+ new_hm
else
ast
end
diff --git a/ruby/step9_interop.rb b/ruby/step9_interop.rb
index e27bdfa..011aea0 100644
--- a/ruby/step9_interop.rb
+++ b/ruby/step9_interop.rb
@@ -11,20 +11,19 @@ def READ(str)
end
# eval
-def is_pair(x)
+def pair?(x)
return sequential?(x) && x.size > 0
end
def quasiquote(ast)
- if not is_pair(ast)
- return List.new([:quote, ast])
+ if not pair?(ast)
+ return List.new [:quote, ast]
elsif ast[0] == :unquote
return ast[1]
- elsif is_pair(ast[0]) && ast[0][0] == :"splice-unquote"
- #p "xxx:", ast, List.new([:concat, ast[0][1], quasiquote(ast.drop(1))])
- return List.new([:concat, ast[0][1], quasiquote(ast.drop(1))])
+ elsif pair?(ast[0]) && ast[0][0] == :"splice-unquote"
+ return List.new [:concat, ast[0][1], quasiquote(ast.drop(1))]
else
- return List.new([:cons, quasiquote(ast[0]), quasiquote(ast.drop(1))])
+ return List.new [:cons, quasiquote(ast[0]), quasiquote(ast.drop(1))]
end
end
@@ -52,6 +51,10 @@ def eval_ast(ast, env)
List.new ast.map{|a| EVAL(a, env)}
when Vector
Vector.new ast.map{|a| EVAL(a, env)}
+ when Hash
+ new_hm = {}
+ ast.each{|k,v| new_hm[EVAL(k,env)] = EVAL(v, env)}
+ new_hm
else
ast
end
diff --git a/ruby/stepA_more.rb b/ruby/stepA_more.rb
index ed8a4f8..b166d79 100644
--- a/ruby/stepA_more.rb
+++ b/ruby/stepA_more.rb
@@ -11,20 +11,19 @@ def READ(str)
end
# eval
-def is_pair(x)
+def pair?(x)
return sequential?(x) && x.size > 0
end
def quasiquote(ast)
- if not is_pair(ast)
- return List.new([:quote, ast])
+ if not pair?(ast)
+ return List.new [:quote, ast]
elsif ast[0] == :unquote
return ast[1]
- elsif is_pair(ast[0]) && ast[0][0] == :"splice-unquote"
- #p "xxx:", ast, List.new([:concat, ast[0][1], quasiquote(ast.drop(1))])
- return List.new([:concat, ast[0][1], quasiquote(ast.drop(1))])
+ elsif pair?(ast[0]) && ast[0][0] == :"splice-unquote"
+ return List.new [:concat, ast[0][1], quasiquote(ast.drop(1))]
else
- return List.new([:cons, quasiquote(ast[0]), quasiquote(ast.drop(1))])
+ return List.new [:cons, quasiquote(ast[0]), quasiquote(ast.drop(1))]
end
end
@@ -52,6 +51,10 @@ def eval_ast(ast, env)
List.new ast.map{|a| EVAL(a, env)}
when Vector
Vector.new ast.map{|a| EVAL(a, env)}
+ when Hash
+ new_hm = {}
+ ast.each{|k,v| new_hm[EVAL(k,env)] = EVAL(v, env)}
+ new_hm
else
ast
end
@@ -159,7 +162,6 @@ _ref[:slurp, lambda {|f| File.read(f) }]
RE["(def! not (fn* (a) (if a false true)))"]
RE["(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["(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["(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))"]
p Dir.pwd
diff --git a/ruby/types.rb b/ruby/types.rb
index b16e391..72d24d1 100644
--- a/ruby/types.rb
+++ b/ruby/types.rb
@@ -31,8 +31,11 @@ def sequential?(obj)
return obj.is_a?(List) || obj.is_a?(Vector)
end
-class Function < Proc
+class Proc # re-open and add meta
attr_accessor :meta
+end
+
+class Function < Proc
attr_accessor :ast
attr_accessor :env
attr_accessor :params