nydp 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/bin/nydp +1 -1
  3. data/lib/lisp/core-000.nydp +1 -0
  4. data/lib/lisp/core-010-precompile.nydp +15 -15
  5. data/lib/lisp/core-012-utils.nydp +6 -5
  6. data/lib/lisp/core-020-utils.nydp +20 -6
  7. data/lib/lisp/core-030-syntax.nydp +14 -16
  8. data/lib/lisp/core-035-flow-control.nydp +26 -8
  9. data/lib/lisp/core-040-utils.nydp +4 -15
  10. data/lib/lisp/core-041-string-utils.nydp +3 -3
  11. data/lib/lisp/core-043-list-utils.nydp +81 -16
  12. data/lib/lisp/core-045-dox-utils.nydp +2 -2
  13. data/lib/lisp/core-060-benchmarking.nydp +92 -27
  14. data/lib/lisp/tests/all-examples.nydp +20 -0
  15. data/lib/lisp/tests/any-examples.nydp +28 -0
  16. data/lib/lisp/tests/builtin-tests.nydp +3 -1
  17. data/lib/lisp/tests/collect-tests.nydp +10 -0
  18. data/lib/lisp/tests/curry-tests.nydp +7 -2
  19. data/lib/lisp/tests/error-tests.nydp +11 -0
  20. data/lib/lisp/tests/foundation-test.nydp +66 -0
  21. data/lib/lisp/tests/len-examples.nydp +1 -0
  22. data/lib/lisp/tests/list-gsub-examples.nydp +25 -0
  23. data/lib/lisp/tests/list-match-examples.nydp +40 -0
  24. data/lib/lisp/tests/list-tests.nydp +13 -0
  25. data/lib/lisp/tests/none-examples.nydp +16 -0
  26. data/lib/lisp/tests/parser-tests.nydp +4 -5
  27. data/lib/lisp/tests/quasiquote-examples.nydp +2 -0
  28. data/lib/lisp/tests/syntax-tests.nydp +3 -2
  29. data/lib/lisp/tests/tuples-examples.nydp +2 -2
  30. data/lib/nydp.rb +50 -18
  31. data/lib/nydp/assignment.rb +3 -1
  32. data/lib/nydp/builtin.rb +15 -13
  33. data/lib/nydp/builtin/error.rb +1 -1
  34. data/lib/nydp/builtin/handle_error.rb +8 -2
  35. data/lib/nydp/builtin/parse_in_string.rb +1 -1
  36. data/lib/nydp/builtin/plus.rb +4 -4
  37. data/lib/nydp/closure.rb +5 -1
  38. data/lib/nydp/compiler.rb +2 -3
  39. data/lib/nydp/cond.rb +134 -13
  40. data/lib/nydp/context_symbol.rb +4 -1
  41. data/lib/nydp/error.rb +8 -0
  42. data/lib/nydp/function_invocation.rb +46 -48
  43. data/lib/nydp/helper.rb +15 -0
  44. data/lib/nydp/interpreted_function.rb +10 -14
  45. data/lib/nydp/lexical_context.rb +13 -2
  46. data/lib/nydp/lexical_context_builder.rb +28 -13
  47. data/lib/nydp/pair.rb +35 -36
  48. data/lib/nydp/parser.rb +3 -0
  49. data/lib/nydp/runner.rb +4 -32
  50. data/lib/nydp/string_atom.rb +3 -2
  51. data/lib/nydp/symbol.rb +1 -1
  52. data/lib/nydp/symbol_lookup.rb +9 -1
  53. data/lib/nydp/truth.rb +1 -1
  54. data/lib/nydp/version.rb +1 -1
  55. data/lib/nydp/vm.rb +2 -2
  56. data/nydp.gemspec +1 -1
  57. data/spec/error_spec.rb +14 -4
  58. data/spec/hash_non_hash_behaviour_spec.rb +19 -12
  59. data/spec/hash_spec.rb +0 -13
  60. data/spec/pair_spec.rb +17 -3
  61. data/spec/spec_helper.rb +13 -1
  62. data/spec/symbol_spec.rb +1 -1
  63. metadata +9 -4
@@ -0,0 +1,16 @@
1
+ (examples-for none?
2
+ ("nil when any items match"
3
+ (none? num? '(1 nil nil 4))
4
+ nil)
5
+
6
+ ("nil for a non-nil atom"
7
+ (and (none? string? "really, all") t)
8
+ nil)
9
+
10
+ ("t for nil"
11
+ (none? x1 nil)
12
+ t)
13
+
14
+ ("t when all items are nil"
15
+ (and (none? x1 '(nil nil nil nil)) t)
16
+ t))
@@ -36,10 +36,9 @@
36
36
  (parse "$this.that.zozo")
37
37
  ((dot-syntax (dollar-syntax || this) that zozo)))
38
38
 
39
-
40
- ("parses an expression"
39
+ ("parses a list of expressions"
41
40
  (parse "(foo bar \"hello, String\") 1 2 (3 t nil) nil")
42
- ((foo bar "hello, String") 1 2 (3 t nil))))
41
+ ((foo bar "hello, String") 1 2 (3 t nil) nil)))
43
42
 
44
43
  (examples-for parse-in-string
45
44
  ("parses a plain string"
@@ -67,5 +66,5 @@
67
66
  13)
68
67
 
69
68
  ("reports parse errors gracefully"
70
- (on-err "CAUGHT: ~err" (parse-in-string (joinstr "" "blah ~~(\"stri...")))
71
- "CAUGHT: parse error: \"unterminated string\" in\n blah ~~(\"stri..." ))
69
+ (on-err "CAUGHT: ~(joinstr "\n" errors)" (parse-in-string (joinstr "" "blah ~~(\"stri...")))
70
+ "CAUGHT: parse error: \"unterminated string\" in\n blah ~~(\"stri...\nunterminated string" ))
@@ -4,7 +4,9 @@
4
4
  ("substitutes single variables" (let b 10 `(a ,b c)) (a 10 c))
5
5
  ("substitutes a list" (let b '(1 2 3) `(a ,@b c)) (a 1 2 3 c))
6
6
  ("substitutes a list at the end of a given list" (let b '(1 2 3) `(a ,b ,@b)) (a (1 2 3) 1 2 3))
7
+ ("unquotes an improper tail" (let c 42 `(a b . ,c)) (a b . 42))
7
8
  ("more complicated substitution example" (with (d '(1 2 3) g '(x y z)) `(a (b c ,d (e f ,@g)))) (a (b c (1 2 3) (e f x y z))))
8
9
  ("peeks inside nested quotes" `(a b '(c ,(+ 1 2))) (a b '(c 3)))
9
10
  ("handles nested unquote-splicing" ``(a ,,@(list '+ 1 2) b) `((a ,(+ 1 2) b)))
11
+ ("unquote-splices an improper tail" (let c '(1 2 3) `(a b . ,@c)) (a b 1 2 3))
10
12
  ("returns nested quasiquotes" `(a b `(c d ,(+ 1 2) ,,(+ 3 4))) (a b `(c d ,(+ 1 2) ,7))))
@@ -8,8 +8,9 @@
8
8
  b)
9
9
 
10
10
  ("dislikes no-prefix"
11
- (on-err err (pre-compile '(:foo 1 2 3)))
12
- "(\"Irregular ': syntax: got (|| foo) : not prefix-syntax : in :foo\")"))
11
+ (on-err (joinstr "\n" errors)
12
+ (pre-compile '(:foo 1 2 3)))
13
+ "\"Irregular ': syntax: got (|| foo) : not prefix-syntax : in :foo\""))
13
14
 
14
15
  (examples-for prefix-list
15
16
  ("one argument"
@@ -5,7 +5,7 @@
5
5
 
6
6
  ("returns single list for fewer than n items"
7
7
  (tuples 4 '(a b) )
8
- ((a b nil nil)))
8
+ ((a b)))
9
9
 
10
10
  ("returns exactly one list for exactly n items"
11
11
  (tuples 5 '(a b c d e) )
@@ -13,4 +13,4 @@
13
13
 
14
14
  ("returns the given list split into sublist each having n items"
15
15
  (tuples 3 '(a b c d e f g) )
16
- ((a b c) (d e f) (g nil nil))))
16
+ ((a b c) (d e f) (g))))
@@ -4,6 +4,7 @@ require 'set'
4
4
  module Nydp
5
5
  class Namespace < Hash
6
6
  end
7
+
7
8
  def self.apply_function ns, function_name, *args
8
9
  function = r2n(function_name.to_sym, ns).value
9
10
  args = r2n args, ns
@@ -15,32 +16,63 @@ module Nydp
15
16
 
16
17
  def self.reader txt ; Nydp::StringReader.new txt ; end
17
18
  def self.eval_src ns, src_txt, name=nil ; eval_with Nydp::Runner, ns, src_txt, name ; end
18
- def self.eval_src! ns, src_txt, name=nil ; eval_with Nydp::ExplodeRunner, ns, src_txt, name ; end
19
19
  def self.eval_with runner, ns, src_txt, name ; runner.new(VM.new(ns), ns, reader(src_txt), nil, name).run ; end
20
20
  def self.ms t1, t0 ; ((t1 - t0) * 1000).to_i ; end
21
21
 
22
+ def self.indent_message indent, msg
23
+ msg.split(/\n/).map { |line| "#{indent}#{line}" }.join("\n")
24
+ end
25
+
26
+ def self.handle_run_error e, indent=""
27
+ puts "#{indent}#{e.class.name}"
28
+ puts "#{indent_message indent, e.message}"
29
+ if e.cause
30
+ puts "#{indent}#{e.backtrace.first}"
31
+ puts "\n#{indent}Caused by:"
32
+ handle_run_error e.cause, "#{indent} "
33
+ else
34
+ e.backtrace.each do |b|
35
+ puts "#{indent}#{b}"
36
+ end
37
+ end
38
+ end
39
+
40
+ def self.toplevel
41
+ begin
42
+ yield
43
+ rescue StandardError => e
44
+ handle_run_error e
45
+ end
46
+ end
47
+
22
48
  def self.repl options={ }
23
- launch_time = Time.now
24
- last_script_time = Time.now
25
- puts "welcome to nydp"
26
- reader = Nydp::ReadlineReader.new $stdin, "nydp > "
27
- ns = build_nydp do |script|
28
- this_script_time = Time.now
29
- puts "script #{script} time #{ms this_script_time, last_script_time}ms" if options[:verbose]
30
- last_script_time = this_script_time
49
+ toplevel do
50
+ silent = options[:silent]
51
+ launch_time = Time.now
52
+ last_script_time = Time.now
53
+ puts "welcome to nydp #{options.inspect}" unless silent
54
+ reader = Nydp::ReadlineReader.new $stdin, "nydp > "
55
+ ns = build_nydp do |script|
56
+ this_script_time = Time.now
57
+ puts "script #{script} time #{ms this_script_time, last_script_time}ms" if options[:verbose]
58
+ last_script_time = this_script_time
59
+ end
60
+ load_time = Time.now
61
+ puts "nydp v#{Nydp::VERSION} repl ready in #{ms(load_time, launch_time)}ms" unless silent
62
+ puts "^D to exit" unless silent
63
+ return if options[:exit]
64
+ Nydp::Runner.new(VM.new(ns), ns, reader, $stdout, "<stdin>").run
31
65
  end
32
- load_time = Time.now
33
- puts "repl ready in #{ms(load_time, launch_time)}ms"
34
- puts "^D to exit"
35
- Nydp::Runner.new(VM.new(ns), ns, reader, $stdout, "<stdin>").run
36
66
  end
37
67
 
38
68
  def self.tests *options
39
- verbose = options.include?(:verbose) ? "t" : "nil"
40
- puts "welcome to nydp : running tests"
41
- reader = Nydp::StringReader.new "(run-all-tests #{verbose})"
42
- ns = build_nydp
43
- Nydp::Runner.new(VM.new(ns), ns, reader, nil, "<test-runner>").run
69
+ toplevel do
70
+ verbose = options.include?(:verbose) ? "t" : "nil"
71
+ puts "welcome to nydp : running tests"
72
+ reader = Nydp::StringReader.new "(run-all-tests #{verbose})"
73
+ ns = build_nydp
74
+ Nydp::Runner.new(VM.new(ns), ns, reader, nil, "<test-runner>").run
75
+ end
44
76
  end
45
77
  end
46
78
 
@@ -1,5 +1,7 @@
1
1
  module Nydp
2
2
  class AssignmentInstruction
3
+ attr_accessor :name
4
+
3
5
  def initialize name
4
6
  @name = name
5
7
  end
@@ -30,7 +32,7 @@ module Nydp
30
32
  end
31
33
 
32
34
  def to_s
33
- "#assignment #{@instructions.cdr.car} #{@value_src.inspect}"
35
+ "(assign #{@instructions.cdr.car.name} #{@value_src.inspect})"
34
36
  end
35
37
 
36
38
  def inspect; to_s ; end
@@ -10,41 +10,43 @@ module Nydp::Builtin
10
10
 
11
11
  def invoke_1 vm
12
12
  builtin_invoke_1 vm
13
- rescue Exception => e
14
- handle_error e, Nydp::NIL
13
+ rescue StandardError => e
14
+ handle_error e
15
15
  end
16
16
 
17
17
  def invoke_2 vm, arg
18
18
  builtin_invoke_2 vm, arg
19
- rescue Exception => e
20
- handle_error e, cons(arg)
19
+ rescue StandardError => e
20
+ handle_error e, arg
21
21
  end
22
22
 
23
23
  def invoke_3 vm, arg_0, arg_1
24
24
  builtin_invoke_3 vm, arg_0, arg_1
25
- rescue Exception => e
26
- handle_error e, cons(arg_0, cons(arg_1))
25
+ rescue StandardError => e
26
+ handle_error e, arg_0, arg_1
27
27
  end
28
28
 
29
29
  def invoke_4 vm, arg_0, arg_1, arg_2
30
30
  builtin_invoke_4 vm, arg_0, arg_1, arg_2
31
- rescue Exception => e
32
- handle_error e, cons(arg_0, cons(arg_1, cons(arg_2)))
31
+ rescue StandardError => e
32
+ handle_error e, arg_0, arg_1, arg_2
33
33
  end
34
34
 
35
35
  def invoke vm, args
36
36
  builtin_invoke vm, args
37
- rescue Exception => e
38
- handle_error e, args
37
+ rescue StandardError => e
38
+ handle_error e, *(args.to_a)
39
39
  end
40
40
 
41
- def handle_error e, args
41
+
42
+ def handle_error e, *args
42
43
  case e
43
44
  when Nydp::Error
44
45
  raise e
45
46
  else
46
- new_msg = "Called #{self.inspect}\nwith args #{args.inspect}\nraised\n#{Nydp.indent_text e.message}\nat #{e.backtrace.first}"
47
- raise $!, new_msg, $!.backtrace
47
+ arg_msg = args.map { |a| " #{a.inspect}"}.join("\n")
48
+ new_msg = "Called #{self.inspect}\nwith args\n#{arg_msg}"
49
+ raise new_msg
48
50
  end
49
51
  end
50
52
 
@@ -4,6 +4,6 @@ class Nydp::Builtin::Error
4
4
  # override #invoke on nydp/builtin/base because
5
5
  # we don't want to inherit error handling
6
6
  def builtin_invoke vm, args
7
- raise Nydp::Error.new(args.inspect)
7
+ raise Nydp::Error.new(args.to_a.map(&:inspect).join("\n"), vm.last_error)
8
8
  end
9
9
  end
@@ -13,13 +13,19 @@ class Nydp::Builtin::HandleError
13
13
  end
14
14
 
15
15
  def execute vm
16
- e = vm.unhandled_error
16
+ e = vm.last_error = vm.unhandled_error
17
17
  vm.unhandled_error = nil
18
18
  return unless e
19
19
 
20
20
  vm.args = vm.args[0...vm_arg_array_size]
21
21
 
22
- handler.invoke vm, cons(r2n e.message, nil)
22
+ msgs = []
23
+ while e
24
+ msgs << e.message
25
+ e = e.cause
26
+ end
27
+
28
+ handler.invoke_2 vm, vm.r2n(msgs)
23
29
  end
24
30
 
25
31
  def to_s
@@ -7,7 +7,7 @@ class Nydp::Builtin::ParseInString
7
7
  tokens = Nydp::Tokeniser.new Nydp::StringReader.new parsable
8
8
  expr = parser.string(tokens, "", :eof)
9
9
  vm.push_arg expr
10
- rescue Exception => e
10
+ rescue StandardError => e
11
11
  new_msg = "parse error: #{e.message.inspect} in\n#{Nydp.indent_text parsable}"
12
12
  raise Nydp::Error.new new_msg
13
13
  end
@@ -18,11 +18,11 @@ class Nydp::Builtin::Plus
18
18
  end
19
19
 
20
20
  def sum args, accum
21
- if Nydp::NIL.is? args
22
- accum
23
- else
24
- sum(args.cdr, (accum + args.car))
21
+ while args && !Nydp::NIL.is?(args)
22
+ accum += args.car
23
+ args = args.cdr
25
24
  end
25
+ accum
26
26
  end
27
27
 
28
28
  def name ; "+" ; end
@@ -4,6 +4,9 @@ module Nydp
4
4
 
5
5
  def initialize ifn, context
6
6
  @ifn, @context = ifn, context
7
+ # TODO don't create a closure where it's not needed (zero_arg functions), use parent context instead
8
+ # TODO see SymbolLookup for how to ensure variable references stay on track
9
+ # TODO see InterpretedFunction for where to not instantiate new LexicalContext
7
10
  end
8
11
 
9
12
  def invoke_1 vm
@@ -28,7 +31,8 @@ module Nydp
28
31
 
29
32
  def nydp_type ; "fn" ; end
30
33
  def to_s
31
- "(closure #{context.inspect} : #{ifn.to_s})"
34
+ "(closure #{context.to_s} : #{ifn.to_s})"
32
35
  end
36
+ def inspect ; to_s ; end
33
37
  end
34
38
  end
@@ -9,9 +9,8 @@ module Nydp
9
9
 
10
10
  def self.compile expression, bindings
11
11
  compile_expr expression, bindings
12
- rescue Exception => e
13
- new_msg = "failed to compile expression #{expression.inspect},\nerror was #{e.message}"
14
- raise $!, new_msg, $!.backtrace
12
+ rescue StandardError => e
13
+ raise Nydp::Error.new "failed to compile expression:\n#{expression.inspect}"
15
14
  end
16
15
 
17
16
  def self.compile_expr expression, bindings
@@ -1,23 +1,20 @@
1
1
  module Nydp
2
2
  class ExecuteConditionalInstruction
3
3
  extend Helper
4
- attr_reader :when_true, :when_false
5
4
 
6
5
  def initialize when_true, when_false
7
6
  @when_true, @when_false = when_true, when_false
8
7
  end
9
8
 
10
9
  def execute vm
11
- truth = !Nydp::NIL.is?(vm.args.pop)
12
- vm.instructions.push (truth ? when_true : when_false)
13
- vm.contexts.push vm.current_context
10
+ (Nydp::NIL.is?(vm.args.pop) ? @when_false : @when_true).execute vm
14
11
  end
15
12
 
16
13
  def inspect
17
- "when_true:#{when_true.inspect}:when_false:#{when_false.inspect}"
14
+ "when_true:#{@when_true.inspect}:when_false:#{@when_false.inspect}"
18
15
  end
19
16
  def to_s
20
- "#{when_true.car.to_s} #{when_false.car.to_s}"
17
+ "#{@when_true.to_s} #{@when_false.to_s}"
21
18
  end
22
19
  end
23
20
 
@@ -33,26 +30,150 @@ module Nydp
33
30
  def execute vm
34
31
  vm.instructions.push conditional
35
32
  vm.contexts.push vm.current_context
36
- vm.instructions.push condition
37
- vm.contexts.push vm.current_context
33
+ condition.execute vm
38
34
  end
39
35
 
40
36
  def inspect
41
37
  "cond:#{condition.inspect}:#{conditional.inspect}"
42
38
  end
43
39
  def to_s
44
- "(cond #{condition.car.to_s} #{conditional.to_s})"
40
+ "(cond #{condition.to_s} #{conditional.to_s})"
45
41
  end
46
42
 
47
43
  def self.build expressions, bindings
48
44
  if expressions.is_a? Nydp::Pair
49
- cond = cons Compiler.compile expressions.car, bindings
50
- when_true = cons Compiler.compile expressions.cdr.car, bindings
51
- when_false = cons Compiler.compile expressions.cdr.cdr.car, bindings
52
- new(cond, when_true, when_false)
45
+ cond = Compiler.compile expressions.car, bindings
46
+ when_true = Compiler.compile expressions.cdr.car, bindings
47
+ when_false = Compiler.compile expressions.cdr.cdr.car, bindings
48
+ csig = sig(cond)
49
+ # puts cond_sig
50
+ # TODO : handle literal nil explicitly (if x y) -> #when_false is literal nil, we can hardcode that
51
+ # todo : handle "OR" explicitly -> (if x x y) -> when #cond equals #when_true, hardcode this case
52
+ case csig
53
+ when "LEX"
54
+ Cond_LEX.build(cond, when_true, when_false)
55
+ when "SYM"
56
+ Cond_SYM.new(cond, cons(when_true), cons(when_false))
57
+ else
58
+ new(cond, when_true, when_false)
59
+ end
53
60
  else
54
61
  raise "can't compile Cond: #{expr.inspect}"
55
62
  end
56
63
  end
57
64
  end
65
+
66
+ class CondBase
67
+ extend Helper
68
+ include Helper
69
+
70
+ def initialize cond, when_true, when_false
71
+ @condition, @when_true, @when_false = cond, when_true, when_false
72
+ end
73
+
74
+ def inspect ; "cond:#{@condition.inspect}:#{@when_true.inspect}:#{@when_false.inspect}" ; end
75
+ def to_s ; "(cond #{@condition.to_s} #{@when_true.to_s} #{@when_false.to_s})" ; end
76
+ end
77
+
78
+ class Cond_LEX < CondBase
79
+ def execute vm
80
+ truth = !Nydp::NIL.is?(@condition.value vm.current_context)
81
+ vm.instructions.push (truth ? @when_true : @when_false)
82
+ vm.contexts.push vm.current_context
83
+ end
84
+
85
+ def self.build cond, when_true, when_false
86
+ tsig = sig(when_true)
87
+ fsig = sig(when_false)
88
+ cond_sig = "#{tsig}_#{fsig}"
89
+
90
+ # if (cond == when_true)
91
+ # OR_LEX.build cond, when_false
92
+
93
+ if (cond == when_true) && (fsig == "LIT")
94
+ OR_LEX_LIT.new cond, nil, when_false
95
+ elsif (cond == when_true) && (fsig == "LEX")
96
+ OR_LEX_LEX.new cond, nil, when_false
97
+ else
98
+ case cond_sig
99
+ when "LIT_LIT"
100
+ Nydp::Cond_LEX_LIT_LIT.new(cond, when_true.expression, when_false.expression)
101
+ when "LEX_LIT"
102
+ Nydp::Cond_LEX_LEX_LIT.new(cond, when_true, when_false.expression)
103
+ when "CND_LIT"
104
+ Nydp::Cond_LEX_CND_LIT.new(cond, when_true, when_false.expression)
105
+ else
106
+ Nydp::Cond_LEX.new(cond, cons(when_true), cons(when_false))
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ class OR_LEX_LIT < CondBase
113
+ def execute vm
114
+ value = @condition.value vm.current_context
115
+ vm.push_arg(!Nydp::NIL.is?(value) ? value : @when_false)
116
+ end
117
+ end
118
+
119
+ class OR_LEX_LEX < CondBase
120
+ def execute vm
121
+ value = @condition.value vm.current_context
122
+ vm.push_arg(!Nydp::NIL.is?(value) ? value : (@when_false.value vm.current_context))
123
+ end
124
+ end
125
+
126
+ # class OR_LEX < CondBase
127
+ # def execute vm
128
+ # value = @condition.value vm.current_context
129
+ # if !Nydp::NIL.is?(value)
130
+ # vm.push_arg value
131
+ # else
132
+ # @when_false.execute vm
133
+ # end
134
+ # end
135
+
136
+ # def self.build cond, when_false
137
+ # case sig(when_false)
138
+ # when "LIT"
139
+ # OR_LEX_LIT.new(cond, nil, when_false)
140
+ # when "LEX"
141
+ # OR_LEX_LEX.new(cond, nil, when_false)
142
+ # else
143
+ # OR_LEX.new(cond, nil, when_false)
144
+ # end
145
+ # end
146
+ # end
147
+
148
+ class Cond_LEX_LIT_LIT < CondBase # (def no (arg) (cond arg nil t))
149
+ def execute vm
150
+ truth = !Nydp::NIL.is?(@condition.value vm.current_context)
151
+ vm.push_arg(truth ? @when_true : @when_false)
152
+ end
153
+ end
154
+
155
+ class Cond_LEX_LEX_LIT < CondBase
156
+ def execute vm
157
+ truth = !Nydp::NIL.is?(@condition.value vm.current_context)
158
+ vm.push_arg(truth ? (@when_true.value vm.current_context) : @when_false)
159
+ end
160
+ end
161
+
162
+ class Cond_LEX_CND_LIT < CondBase
163
+ def execute vm
164
+ if !Nydp::NIL.is?(@condition.value vm.current_context)
165
+ @when_true.execute vm
166
+ else
167
+ vm.push_arg @when_false
168
+ end
169
+ end
170
+ end
171
+
172
+ class Cond_SYM < CondBase
173
+ def execute vm
174
+ truth = !Nydp::NIL.is?(@condition.value)
175
+ vm.instructions.push (truth ? @when_true : @when_false)
176
+ vm.contexts.push vm.current_context
177
+ end
178
+ end
58
179
  end