Permalink
Browse files

Whoa; I just implemented quasiquote. That was way too easy.

  • Loading branch information...
1 parent e1ec4b8 commit 2eda0f6d07ddb3cacc3a4b78728019d5de26cb90 @technomancy committed Nov 8, 2008
Showing with 19 additions and 5 deletions.
  1. +12 −0 lib/bus_scheme/eval.rb
  2. +2 −5 lib/bus_scheme/primitives.rb
  3. +5 −0 test/test_eval.rb
View
@@ -55,4 +55,16 @@ def stacktrace
def stack
@@stack
end
+
+ # TODO: unquote-splicing
+ def quasiquote(arg)
+ if !arg.is_a? Cons or arg.empty?
+ arg
+ elsif arg.is_a? Cons and arg.car == 'unquote'.sym
+ eval(arg.cadr)
+ else
+ Cons.new(quasiquote(arg.car),
+ quasiquote(arg.cdr))
+ end
+ end
end
@@ -43,11 +43,8 @@ def self.special_form(identifier, value)
define 'exit', primitive { exit }
define 'quit', BusScheme['exit'.sym]
-
- # TODO: write
- special_form 'quasiquote', primitive { }
- special_form 'unquote', primitive { }
- special_form 'unquote-splicing', primitive { }
+ special_form 'quasiquote', primitive { |arg| quasiquote(arg) }
+ special_form 'qq', BusScheme['quasiquote'.sym]
# Primitives that can't be defined in terms of other forms:
special_form 'quote', primitive { |arg| arg }
View
@@ -87,6 +87,11 @@ def test_evals_string_ending_in_comment
;; should be four"
end
+ def test_quasi_quote
+ assert_evals_to([:hey.sym, :there.sym, "dude"].to_list,
+ '(qq (hey there (unquote (+ "du" "de"))))')
+ end
+
# def test_tail_call_optimization
# Timeout.timeout(1) do
# assert_nothing_raised { eval "((lambda (x) (x x)) (lambda (x) (x x)))" }

0 comments on commit 2eda0f6

Please sign in to comment.