nydp 0.2.3 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
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