nydp 0.5.1 → 0.6.0

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 (143) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/README.md +77 -56
  4. data/lib/lisp/core-000.nydp +1 -1
  5. data/lib/lisp/core-010-precompile.nydp +49 -29
  6. data/lib/lisp/core-012-utils.nydp +12 -8
  7. data/lib/lisp/core-015-documentation.nydp +41 -15
  8. data/lib/lisp/core-017-builtin-dox.nydp +621 -100
  9. data/lib/lisp/core-020-utils.nydp +33 -6
  10. data/lib/lisp/core-025-warnings.nydp +1 -1
  11. data/lib/lisp/core-030-syntax.nydp +64 -48
  12. data/lib/lisp/core-035-flow-control.nydp +20 -28
  13. data/lib/lisp/core-037-list-utils.nydp +84 -21
  14. data/lib/lisp/core-040-utils.nydp +8 -5
  15. data/lib/lisp/core-041-string-utils.nydp +17 -11
  16. data/lib/lisp/core-043-list-utils.nydp +140 -77
  17. data/lib/lisp/core-045-dox-utils.nydp +1 -0
  18. data/lib/lisp/core-050-test-runner.nydp +8 -12
  19. data/lib/lisp/core-070-prefix-list.nydp +19 -15
  20. data/lib/lisp/core-080-pretty-print.nydp +13 -5
  21. data/lib/lisp/core-090-hook.nydp +11 -11
  22. data/lib/lisp/core-100-utils.nydp +51 -66
  23. data/lib/lisp/core-110-hash-utils.nydp +34 -7
  24. data/lib/lisp/core-120-settings.nydp +14 -9
  25. data/lib/lisp/core-130-validations.nydp +28 -13
  26. data/lib/lisp/core-900-benchmarking.nydp +420 -47
  27. data/lib/lisp/tests/000-empty-args-examples.nydp +5 -0
  28. data/lib/lisp/tests/andify-examples.nydp +1 -1
  29. data/lib/lisp/tests/auto-hash-examples.nydp +6 -1
  30. data/lib/lisp/tests/best-examples.nydp +1 -1
  31. data/lib/lisp/tests/boot-tests.nydp +1 -1
  32. data/lib/lisp/tests/date-examples.nydp +129 -102
  33. data/lib/lisp/tests/destructuring-examples.nydp +1 -1
  34. data/lib/lisp/tests/dox-tests.nydp +2 -2
  35. data/lib/lisp/tests/hash-examples.nydp +58 -33
  36. data/lib/lisp/tests/list-tests.nydp +137 -1
  37. data/lib/lisp/tests/pretty-print-tests.nydp +12 -0
  38. data/lib/lisp/tests/rotate-2d-array-examples.nydp +26 -0
  39. data/lib/lisp/tests/sort-examples.nydp +5 -5
  40. data/lib/lisp/tests/string-tests.nydp +16 -5
  41. data/lib/lisp/tests/syntax-tests.nydp +10 -2
  42. data/lib/lisp/tests/time-examples.nydp +8 -1
  43. data/lib/lisp/tests/unparse-tests.nydp +13 -7
  44. data/lib/nydp/assignment.rb +15 -28
  45. data/lib/nydp/builtin/abs.rb +4 -3
  46. data/lib/nydp/builtin/apply.rb +8 -10
  47. data/lib/nydp/builtin/cdr_set.rb +1 -1
  48. data/lib/nydp/builtin/comment.rb +1 -3
  49. data/lib/nydp/builtin/date.rb +11 -28
  50. data/lib/nydp/builtin/divide.rb +3 -10
  51. data/lib/nydp/builtin/ensuring.rb +6 -21
  52. data/lib/nydp/builtin/error.rb +2 -4
  53. data/lib/nydp/builtin/eval.rb +9 -4
  54. data/lib/nydp/builtin/greater_than.rb +7 -8
  55. data/lib/nydp/builtin/handle_error.rb +10 -34
  56. data/lib/nydp/builtin/hash.rb +24 -45
  57. data/lib/nydp/builtin/inspect.rb +1 -3
  58. data/lib/nydp/builtin/is_equal.rb +4 -7
  59. data/lib/nydp/builtin/less_than.rb +6 -7
  60. data/lib/nydp/builtin/log.rb +7 -0
  61. data/lib/nydp/builtin/math_ceiling.rb +1 -3
  62. data/lib/nydp/builtin/math_floor.rb +1 -3
  63. data/lib/nydp/builtin/math_power.rb +1 -3
  64. data/lib/nydp/builtin/math_round.rb +2 -2
  65. data/lib/nydp/builtin/minus.rb +7 -14
  66. data/lib/nydp/builtin/parse.rb +5 -5
  67. data/lib/nydp/builtin/parse_in_string.rb +5 -7
  68. data/lib/nydp/builtin/plus.rb +14 -31
  69. data/lib/nydp/builtin/pre_compile.rb +1 -3
  70. data/lib/nydp/builtin/puts.rb +4 -8
  71. data/lib/nydp/builtin/quit.rb +1 -1
  72. data/lib/nydp/builtin/rand.rb +6 -11
  73. data/lib/nydp/builtin/random_string.rb +2 -4
  74. data/lib/nydp/builtin/rng.rb +25 -0
  75. data/lib/nydp/builtin/ruby_wrap.rb +27 -14
  76. data/lib/nydp/builtin/script_run.rb +1 -3
  77. data/lib/nydp/builtin/set_intersection.rb +3 -4
  78. data/lib/nydp/builtin/set_union.rb +3 -4
  79. data/lib/nydp/builtin/sort.rb +2 -7
  80. data/lib/nydp/builtin/string_match.rb +5 -13
  81. data/lib/nydp/builtin/string_replace.rb +2 -7
  82. data/lib/nydp/builtin/string_split.rb +3 -8
  83. data/lib/nydp/builtin/sym.rb +2 -9
  84. data/lib/nydp/builtin/thread_locals.rb +2 -2
  85. data/lib/nydp/builtin/time.rb +38 -44
  86. data/lib/nydp/builtin/times.rb +6 -15
  87. data/lib/nydp/builtin/to_integer.rb +8 -14
  88. data/lib/nydp/builtin/to_string.rb +2 -13
  89. data/lib/nydp/builtin/type_of.rb +10 -16
  90. data/lib/nydp/builtin/vm_info.rb +2 -10
  91. data/lib/nydp/builtin.rb +15 -37
  92. data/lib/nydp/compiler.rb +29 -19
  93. data/lib/nydp/cond.rb +95 -88
  94. data/lib/nydp/context_symbol.rb +11 -9
  95. data/lib/nydp/core.rb +74 -73
  96. data/lib/nydp/core_ext.rb +87 -26
  97. data/lib/nydp/date.rb +22 -19
  98. data/lib/nydp/error.rb +2 -3
  99. data/lib/nydp/function_invocation.rb +76 -289
  100. data/lib/nydp/helper.rb +18 -9
  101. data/lib/nydp/interpreted_function.rb +159 -25
  102. data/lib/nydp/lexical_context.rb +9 -8
  103. data/lib/nydp/lexical_context_builder.rb +1 -1
  104. data/lib/nydp/literal.rb +3 -7
  105. data/lib/nydp/loop.rb +72 -0
  106. data/lib/nydp/namespace.rb +52 -0
  107. data/lib/nydp/pair.rb +146 -50
  108. data/lib/nydp/parser.rb +9 -11
  109. data/lib/nydp/plugin.rb +88 -19
  110. data/lib/nydp/runner.rb +141 -23
  111. data/lib/nydp/symbol.rb +16 -26
  112. data/lib/nydp/symbol_lookup.rb +3 -2
  113. data/lib/nydp/tokeniser.rb +1 -1
  114. data/lib/nydp/truth.rb +2 -37
  115. data/lib/nydp/version.rb +1 -1
  116. data/lib/nydp.rb +33 -44
  117. data/nydp.gemspec +2 -1
  118. data/spec/date_spec.rb +26 -32
  119. data/spec/embedded_spec.rb +22 -22
  120. data/spec/error_spec.rb +12 -16
  121. data/spec/foreign_hash_spec.rb +21 -36
  122. data/spec/hash_non_hash_behaviour_spec.rb +12 -29
  123. data/spec/hash_spec.rb +36 -49
  124. data/spec/literal_spec.rb +6 -6
  125. data/spec/nydp_spec.rb +14 -14
  126. data/spec/pair_spec.rb +8 -8
  127. data/spec/parser_spec.rb +41 -37
  128. data/spec/rand_spec.rb +1 -4
  129. data/spec/spec_helper.rb +3 -3
  130. data/spec/string_atom_spec.rb +15 -16
  131. data/spec/symbol_spec.rb +27 -52
  132. data/spec/thread_local_spec.rb +23 -8
  133. data/spec/time_spec.rb +4 -10
  134. data/spec/tokeniser_spec.rb +10 -10
  135. metadata +25 -13
  136. data/lib/nydp/builtin/modulo.rb +0 -11
  137. data/lib/nydp/builtin/regexp.rb +0 -7
  138. data/lib/nydp/builtin/sqrt.rb +0 -7
  139. data/lib/nydp/builtin/string_pad_left.rb +0 -7
  140. data/lib/nydp/builtin/string_pad_right.rb +0 -7
  141. data/lib/nydp/hash.rb +0 -9
  142. data/lib/nydp/image_store.rb +0 -21
  143. data/lib/nydp/vm.rb +0 -129
@@ -1,37 +1,20 @@
1
1
  class Nydp::Builtin::Plus
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
- def builtin_invoke_1 vm ; vm.push_arg 0 ; end
5
- def builtin_invoke_2 vm, a ; vm.push_arg a ; end
6
- def builtin_invoke_3 vm, a0, a1 ; vm.push_arg(a0 + a1) ; end
7
- def builtin_invoke_4 vm, a0, a1, a2 ; vm.push_arg(a0 + a1 + a2) ; end
8
-
9
- def builtin_invoke vm, args
10
- vm.push_arg case args.car
11
- when Nydp::Pair
12
- sum(args, Nydp::NIL)
13
- when String
14
- string_concat("", args)
15
- else
16
- sum(args.cdr, args.car)
17
- end
18
- end
19
-
20
- def string_concat init, others
21
- while others && !Nydp::NIL.is?(others)
22
- init << others.car.to_s
23
- others = others.cdr
24
- end
25
- init
26
- end
4
+ def name ; "+" ; end
27
5
 
28
- def sum args, accum
29
- while args && !Nydp::NIL.is?(args)
30
- accum += args.car
31
- args = args.cdr
32
- end
33
- accum
6
+ def builtin_call *args
7
+ if args.empty?
8
+ 0
9
+ else
10
+ case args.first
11
+ when String
12
+ args.each_with_object("") { |str, res| res << str.to_s }
13
+ when Date
14
+ (args.shift._nydp_date + builtin_call(*args)).to_ruby
15
+ else
16
+ args.reduce &:+
17
+ end
18
+ end._nydp_wrapper
34
19
  end
35
-
36
- def name ; "+" ; end
37
20
  end
@@ -1,7 +1,5 @@
1
1
  class Nydp::Builtin::PreCompile
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
- def builtin_invoke vm, args
5
- vm.push_arg args.car
6
- end
4
+ def builtin_call *args ; args.first ; end
7
5
  end
@@ -1,14 +1,10 @@
1
1
  class Nydp::Builtin::Puts
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
- def builtin_invoke vm, args
5
- if Nydp::NIL.is? args
6
- puts
7
- else
8
- s = args.map { |a| a.to_s }
9
- puts s.join ' '
10
- end
11
- vm.push_arg args.car
4
+ def builtin_call *args
5
+ s = args.map { |a| a.to_s }
6
+ puts s.join ' '
7
+ args.first
12
8
  end
13
9
 
14
10
  def name ; "p" ; end
@@ -1,7 +1,7 @@
1
1
  class Nydp::Builtin::Quit
2
2
  include Nydp::Builtin::Base
3
3
 
4
- def builtin_invoke vm, args
4
+ def builtin_call *args
5
5
  exit
6
6
  end
7
7
  end
@@ -1,18 +1,13 @@
1
1
  class Nydp::Builtin::Rand
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
- def builtin_invoke_1 vm ; vm.push_arg rand ; end
5
- def builtin_invoke_2 vm, a ; vm.push_arg rand(a) ; end
6
- def builtin_invoke_3 vm, a0, a1 ; vm.push_arg(a0 + rand(a1 - a0)) ; end
7
- def builtin_invoke vm, args ;
8
- if Nydp::NIL.is? args
9
- builtin_invoke_1 vm
4
+ def builtin_call a0=nil, a1=nil
5
+ if a0 == nil
6
+ rand
7
+ elsif a1 == nil
8
+ rand(a0)
10
9
  else
11
- case args.size
12
- when 1 ; builtin_invoke_2 vm, args.car
13
- when 2 ; builtin_invoke_3 vm, args.car, args.cadr
14
- else ; raise "rand: 0, 1 or 2 args expected, got #{args.length}"
15
- end
10
+ (a0 + rand(a1 - a0))
16
11
  end
17
12
  end
18
13
  end
@@ -3,9 +3,7 @@ class Nydp::Builtin::RandomString
3
3
 
4
4
  RANDOM_CHARS = ["A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z","2","3","4","5","6","7","8","9"]
5
5
 
6
- def builtin_invoke vm, args
7
- length = args.car unless Nydp::NIL.is?(args)
8
- s = (0...(length || 10)).inject("") {|a,i| a << RANDOM_CHARS[rand(RANDOM_CHARS.size)] }
9
- vm.push_arg s
6
+ def builtin_call length=nil
7
+ (0...(length || 10)).inject("") {|a,i| a << RANDOM_CHARS[rand(RANDOM_CHARS.size)] }
10
8
  end
11
9
  end
@@ -0,0 +1,25 @@
1
+ class Nydp::Builtin::RNG
2
+ include Nydp::Builtin::Base, Singleton
3
+
4
+ def builtin_call a0=nil
5
+ if a0 == nil
6
+ Random.new
7
+ else
8
+ Random.new(a0)
9
+ end
10
+ end
11
+ end
12
+
13
+ class ::Random
14
+ include Nydp::Builtin::Base
15
+
16
+ def builtin_call a0=nil, a1=nil
17
+ if a0 == nil
18
+ self.rand
19
+ elsif a1 == nil
20
+ self.rand(a0)
21
+ else
22
+ (a0 + self.rand(a1 - a0))
23
+ end
24
+ end
25
+ end
@@ -8,14 +8,14 @@ class Nydp::Builtin::RubyWrap
8
8
  class Coder < Struct.new(:name, :size, :code, :helpers)
9
9
  def msize ; size + 1 ; end
10
10
 
11
- def arg_mapper
11
+ def arg_mapper_novm
12
12
  case size
13
13
  when 0 ; ""
14
- when 1 ; ", a0"
15
- when 2 ; ", a0, a1"
16
- when 3 ; ", a0, a1, a2"
17
- when 4 ; ", a0, a1, a2, a3"
18
- when 5 ; ", a0, a1, a2, a3, a4"
14
+ when 1 ; "a0=nil"
15
+ when 2 ; "a0=nil, a1=nil"
16
+ when 3 ; "a0=nil, a1=nil, a2=nil"
17
+ when 4 ; "a0=nil, a1=nil, a2=nil, a3=nil"
18
+ when 5 ; "a0=nil, a1=nil, a2=nil, a3=nil, a4=nil"
19
19
  else ; raise "maximum 5 arguments!"
20
20
  end
21
21
  end
@@ -31,12 +31,18 @@ class Nydp::Builtin::RubyWrap
31
31
  class #{name}
32
32
  include Nydp::Builtin::Base, Singleton#{helpers}
33
33
 
34
- def builtin_invoke_#{msize} vm#{ arg_mapper }
35
- vm.push_arg(#{code})
34
+ def builtin_call #{ arg_mapper_novm }
35
+ (#{code})
36
36
  end
37
37
 
38
- def builtin_invoke vm, args
39
- vm.push_arg(#{generic_code})
38
+ # return the ruby equivalent of this code if it was inlined inside another builtin
39
+ def inline_code arg_expressions
40
+ #{code.inspect}.
41
+ gsub(/a0/, arg_expressions[0]).
42
+ gsub(/a1/, arg_expressions[1]).
43
+ gsub(/a2/, arg_expressions[2]).
44
+ gsub(/a3/, arg_expressions[3]).
45
+ gsub(/a4/, arg_expressions[4])
40
46
  end
41
47
  end
42
48
  CODE
@@ -65,8 +71,15 @@ CODE
65
71
  end
66
72
 
67
73
  core_builder = builder ""
68
- core_builder.build(:Cons, 2, %{ Nydp::Pair.new(a0, a1) } )
69
- core_builder.build(:Car , 1, %{ a0.car } )
70
- core_builder.build(:Cdr , 1, %{ a0.cdr } )
71
- core_builder.build(:Log , 1, %{ r2n Nydp.logger.info(a0.to_s) } )
74
+ core_builder.build(:Cons , 2, %{ Nydp::Pair.new(a0, a1) } )
75
+ core_builder.build(:Car , 1, %{ a0.car } )
76
+ core_builder.build(:Cdr , 1, %{ a0.cdr } )
77
+ core_builder.build(:Ln , 1, %{ Math.log(a0) } )
78
+ core_builder.build(:Modulo , 2, %{ a0 % a1 } )
79
+ core_builder.build(:Sqrt , 1, %{ Math.sqrt a0 } )
80
+ core_builder.build(:Regexp , 1, %{ ::Regexp.compile(a0) } )
81
+ core_builder.build(:StringPadLeft , 3, %{ a0.to_s.rjust(a1, a2.to_s) } )
82
+ core_builder.build(:StringPadRight, 3, %{ a0.to_s.ljust(a1, a2.to_s) } )
83
+ core_builder.build(:ToList , 1, %{ a0.to_a._nydp_wrapper } )
84
+ core_builder.build(:StringForceEncoding, 2, %{ a0.to_s.force_encoding(a1)._nydp_wrapper } )
72
85
  end
@@ -1,7 +1,5 @@
1
1
  class Nydp::Builtin::ScriptRun
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
- def builtin_invoke vm, args
5
- vm.push_arg args
6
- end
4
+ def builtin_call *args ; args ; end
7
5
  end
@@ -1,8 +1,7 @@
1
1
  class Nydp::Builtin::SetIntersection
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
- def builtin_invoke_2 vm, a ; vm.push_arg a ; end
5
- def builtin_invoke_3 vm, a, b ; vm.push_arg(a & b) ; end
6
- def builtin_invoke_4 vm, a, b, c ; vm.push_arg(a & b & c) ; end
7
- def builtin_invoke vm, args ; vm.push_arg args.reduce &:& ; end
4
+ def builtin_call *args
5
+ args.reduce(&:&)._nydp_wrapper
6
+ end
8
7
  end
@@ -1,8 +1,7 @@
1
1
  class Nydp::Builtin::SetUnion
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
- def builtin_invoke_2 vm, a ; vm.push_arg a ; end
5
- def builtin_invoke_3 vm, a, b ; vm.push_arg(a | b) ; end
6
- def builtin_invoke_4 vm, a, b, c ; vm.push_arg(a | b | c) ; end
7
- def builtin_invoke vm, args ; vm.push_arg args.reduce &:| ; end
4
+ def builtin_call *args
5
+ args.reduce(&:|)._nydp_wrapper
6
+ end
8
7
  end
@@ -2,14 +2,9 @@ module Nydp
2
2
  class Builtin::Sort
3
3
  include Builtin::Base, Singleton
4
4
 
5
- def builtin_invoke vm, args
6
- vm.push_arg Pair.from_list to_array(args.car, []).sort
5
+ def builtin_call arg
6
+ arg.to_a.sort._nydp_wrapper
7
7
  end
8
8
 
9
- private
10
-
11
- def to_array pair, list
12
- pair.is_a?(Pair) ? to_array(pair.cdr, (list << pair.car)) : list
13
- end
14
9
  end
15
10
  end
@@ -1,21 +1,13 @@
1
1
  class Nydp::Builtin::StringMatch
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
- def builtin_invoke vm, args
5
- kmatch = Nydp::Symbol.mk :match , vm.ns
6
- kcaptures = Nydp::Symbol.mk :captures, vm.ns
7
- target = args.car.to_s
8
- pattern = Regexp.new(args.cdr.car.to_s)
9
- match = pattern.match target
4
+ def builtin_call target, pattern
5
+ target = target.to_s
6
+ pattern = Regexp.new(pattern.to_s) unless pattern.is_a? Regexp
7
+ match = pattern.match target
10
8
 
11
9
  if match
12
- result = Nydp::Hash.new
13
- result[kmatch] = match.to_s
14
- result[kcaptures] = Nydp::Pair.from_list match.captures.map { |cap| cap.to_s }
15
- else
16
- result = Nydp::NIL
10
+ { match: match.to_s, captures: (match.captures.map(&:to_s)._nydp_wrapper) }
17
11
  end
18
-
19
- vm.push_arg result
20
12
  end
21
13
  end
@@ -1,12 +1,7 @@
1
1
  class Nydp::Builtin::StringReplace
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
- def builtin_invoke vm, args
5
- to_remove = Regexp.new args.car.to_ruby
6
- to_insert = args.cdr.car.to_ruby
7
- target = args.cdr.cdr.car.to_s
8
- result = target.to_s.gsub to_remove, to_insert
9
-
10
- vm.push_arg result
4
+ def builtin_call remove, insert, str
5
+ str.to_s.to_s.gsub Regexp.new(remove.to_ruby), insert.to_ruby
11
6
  end
12
7
  end
@@ -1,13 +1,8 @@
1
1
  class Nydp::Builtin::StringSplit
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
- def builtin_invoke vm, args
5
- target = args.car.to_s
6
- separator = args.cdr.car
7
- separator = separator.to_s unless separator.is_a? Regexp
8
-
9
- result = target.split separator, -1
10
-
11
- vm.push_arg Nydp::Pair.from_list result
4
+ def builtin_call str, sep=nil
5
+ sep = sep.to_s unless sep.is_a? Regexp
6
+ Nydp::Pair.from_list str.to_s.split(sep, -1)
12
7
  end
13
8
  end
@@ -1,14 +1,7 @@
1
1
  class Nydp::Builtin::Sym
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
- def builtin_invoke vm, args
5
- arg = args.car
6
- val = case arg.class
7
- when Nydp::Symbol
8
- arg
9
- else
10
- Nydp::Symbol.mk arg.to_s.to_sym, vm.ns
11
- end
12
- vm.push_arg val
4
+ def builtin_call s
5
+ s.to_s.to_sym
13
6
  end
14
7
  end
@@ -1,7 +1,7 @@
1
1
  class Nydp::Builtin::ThreadLocals
2
2
  include Nydp::Helper, Nydp::Builtin::Base, Singleton
3
3
 
4
- def builtin_invoke vm, args
5
- vm.push_arg vm.locals
4
+ def builtin_call *args
5
+ Thread.current[:_nydp_thread_locals] ||= { }
6
6
  end
7
7
  end
@@ -2,51 +2,45 @@
2
2
  class Nydp::Builtin::Time
3
3
  include Nydp::Helper, Nydp::Builtin::Base, Singleton
4
4
 
5
- def builtin_invoke_1 vm
6
- vm.push_arg ::Time.now
7
- end
8
-
9
- # either an offset in seconds from now, or a Date to convert to a time, or a Time to subtract and return offset in seconds from now
10
- # when Numeric : return now + offset in seconds from now
11
- # when Nydp::Date : convert date to time
12
- # when Time : calculate and return now - Time offset in seconds
13
- def builtin_invoke_2 vm, arg
14
- case arg
15
- when Numeric # relative time in seconds
16
- vm.push_arg(Time.now + arg)
17
- when Nydp::Date
18
- vm.push_arg arg.to_ruby.to_time
19
- when ::Time
20
- vm.push_arg ::Time.now - arg
5
+ # when 0 arguments:
6
+ # return Time.now
7
+ # when 1 argument:
8
+ # either an offset in seconds from now, or a Date to convert to a time, or a Time to subtract and return offset in seconds from now
9
+ # when Numeric : return now + offset in seconds from now
10
+ # when Nydp::Date : convert date to time
11
+ # when Time : calculate and return now - Time offset in seconds
12
+ # when 2 arguments:
13
+ # first arg is a Time
14
+ # if second arg is numeric, add to first arg
15
+ # if second arg is a Time, subtract from first arg
16
+ def builtin_call y=:unset, mo=:unset, d=:unset, h=nil, mi=nil, s=nil, ms=nil
17
+ if y == :unset
18
+ ::Time.now
19
+ elsif mo == :unset
20
+ case y
21
+ when Numeric # relative time in seconds
22
+ (Time.now + y)
23
+ when ::Date
24
+ y.to_time
25
+ when ::Time
26
+ ::Time.now - y
27
+ else
28
+ puts
29
+ puts y.class
30
+ raise Nydp::Error.new "time : expected a number or a date or a time, got #{y._nydp_inspect}"
31
+ end
32
+ elsif d == :unset
33
+ # y is a date or time, mo is a number or time
34
+ case mo
35
+ when Numeric # relative time in seconds
36
+ (y + mo)
37
+ when ::Time
38
+ y - mo
39
+ else
40
+ raise Nydp::Error.new "time : expected a number or a date, got #{mo._nydp_inspect}"
41
+ end
21
42
  else
22
- raise Nydp::Error.new "time : expected a number or a date or a time, got #{arg.inspect}"
43
+ Time.new(y,mo,d,h,mi,s,ms)
23
44
  end
24
45
  end
25
-
26
- # first arg is a Time
27
- # if second arg is numeric, add to first arg
28
- # if second arg is a Time, subtract from first arg
29
- def builtin_invoke_3 vm, a0, a1
30
- case a1
31
- when Numeric # relative time in seconds
32
- vm.push_arg(a0 + a1)
33
- when ::Time
34
- vm.push_arg a0 - a1
35
- else
36
- raise Nydp::Error.new "time : expected a number or a date, got #{a1.inspect}"
37
- end
38
- end
39
-
40
- def builtin_invoke vm, args
41
- # assume ruby Time constructor args y mo d h mi s ms
42
- y = args.car
43
- mo = args.cdr.car
44
- d = args.cdr.cdr.car
45
- h = args.cdr.cdr.cdr.car if args.size > 3
46
- mi = args.cdr.cdr.cdr.cdr.car if args.size > 4
47
- s = args.cdr.cdr.cdr.cdr.cdr.car if args.size > 5
48
- ms = args.cdr.cdr.cdr.cdr.cdr.cdr.car if args.size > 6
49
-
50
- vm.push_arg(Time.new(y,mo,d,h,mi,s,ms))
51
- end
52
46
  end
@@ -1,22 +1,13 @@
1
1
  class Nydp::Builtin::Times
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
- def invoke_1 vm ; vm.push_arg 1 ; end
5
- def invoke_2 vm, a ; vm.push_arg a ; end
6
- def invoke_3 vm, a0, a1 ; vm.push_arg(a0 * a1) ; end
7
- def invoke_4 vm, a0, a1, a2 ; vm.push_arg(a0 * a1 * a2) ; end
8
-
9
- def builtin_invoke vm, args
10
- vm.push_arg multiply(args, 1)
11
- end
4
+ def name ; "*" ; end
12
5
 
13
- def multiply args, accum
14
- if Nydp::NIL.is? args
15
- accum
6
+ def builtin_call *args
7
+ if args.empty?
8
+ 1
16
9
  else
17
- multiply(args.cdr, (accum * args.car))
18
- end
10
+ args.reduce(&:*)
11
+ end._nydp_wrapper
19
12
  end
20
-
21
- def name ; "*" ; end
22
13
  end
@@ -2,22 +2,16 @@ module Nydp::Builtin
2
2
  class ToInteger
3
3
  include Nydp::Builtin::Base, Singleton
4
4
 
5
- def builtin_invoke_2 vm, arg
5
+ def builtin_call arg
6
6
  arg = n2r arg
7
7
 
8
- i = if arg.respond_to? :to_i
9
- arg.to_i
10
- elsif arg.respond_to? :to_time
11
- arg.to_time.to_i
12
- else
13
- arg.to_s.to_i
14
- end
15
-
16
- vm.push_arg r2n i
17
- end
18
-
19
- def builtin_invoke vm, args
20
- builtin_invoke_2 vm, args.car
8
+ if arg.respond_to? :to_i
9
+ arg.to_i
10
+ elsif arg.respond_to? :to_time
11
+ arg.to_time.to_i
12
+ else
13
+ arg.to_s.to_i
14
+ end
21
15
  end
22
16
  end
23
17
  end
@@ -2,23 +2,12 @@ module Nydp::Builtin
2
2
  class ToString
3
3
  include Nydp::Builtin::Base, Singleton
4
4
 
5
- def builtin_invoke vm, args
6
- vm.push_arg args.car.to_s
7
- end
5
+ def builtin_call arg=nil ; arg._nydp_to_s ; end
8
6
  end
9
7
 
10
8
  class StringLength
11
9
  include Nydp::Builtin::Base, Singleton
12
10
 
13
- def builtin_invoke vm, args
14
- arg = args.car
15
- val = case arg
16
- when String
17
- arg.length
18
- else
19
- 0
20
- end
21
- vm.push_arg val
22
- end
11
+ def builtin_call arg ; arg._nydp_to_s.length ; end
23
12
  end
24
13
  end
@@ -1,21 +1,15 @@
1
1
  class Nydp::Builtin::TypeOf
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
- def builtin_invoke_1 vm, a0
5
- typename = if a0.respond_to?(:nydp_type)
6
- a0.nydp_type.to_sym
7
- elsif a0.is_a? Numeric
8
- :number
9
- else
10
- "ruby/#{a0.class.name}".to_sym
11
- end
12
-
13
- type = Nydp::Symbol.mk(typename, vm.ns)
14
-
15
- vm.push_arg(type || Nydp::NIL)
16
- end
17
-
18
- def builtin_invoke vm, args
19
- builtin_invoke_1 vm, args.car
4
+ def builtin_call arg
5
+ if arg == nil
6
+ nil
7
+ elsif arg.respond_to?(:nydp_type)
8
+ arg.nydp_type.to_sym
9
+ elsif arg.is_a? Numeric
10
+ :number
11
+ else
12
+ "ruby/#{arg.class.name}".to_sym
13
+ end
20
14
  end
21
15
  end
@@ -1,15 +1,7 @@
1
1
  class Nydp::Builtin::VmInfo
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
- VMINFO_NS = { }
5
- CONTEXTS = Nydp::Symbol.mk :contexts, VMINFO_NS
6
- INSTRUCTIONS = Nydp::Symbol.mk :instructions, VMINFO_NS
7
- ARGS = Nydp::Symbol.mk :args, VMINFO_NS
8
-
9
- def builtin_invoke vm, args
10
- context_count = Nydp::Pair.new CONTEXTS, vm.contexts.size
11
- instruction_count = Nydp::Pair.new INSTRUCTIONS, vm.instructions.size
12
- arg_count = Nydp::Pair.new ARGS, vm.args.size
13
- vm.push_arg Nydp::Pair.from_list [context_count, instruction_count, arg_count]
4
+ def builtin_call *args
5
+ nil
14
6
  end
15
7
  end
data/lib/nydp/builtin.rb CHANGED
@@ -1,55 +1,33 @@
1
1
  module Nydp::Builtin
2
2
  module Base
3
+ @@reraise_errors = []
3
4
  include Nydp::Helper
4
5
 
5
- def builtin_invoke vm, args ; raise "#{self.class.name} : please implement #builtin_invoke" ; end
6
- def builtin_invoke_1 vm ; builtin_invoke vm, Nydp::NIL ; end
7
- def builtin_invoke_2 vm, a ; builtin_invoke vm, cons(a) ; end
8
- def builtin_invoke_3 vm, a0, a1 ; builtin_invoke vm, cons(a0, cons(a1)) ; end
9
- def builtin_invoke_4 vm, a0, a1, a2 ; builtin_invoke vm, cons(a0, cons(a1, cons(a2))) ; end
10
-
11
- def invoke_1 vm
12
- builtin_invoke_1 vm
13
- rescue StandardError => e
14
- handle_error e
15
- end
16
-
17
- def invoke_2 vm, arg
18
- builtin_invoke_2 vm, arg
19
- rescue StandardError => e
20
- handle_error e, arg
6
+ def self.ignore_errors kla
7
+ @@reraise_errors << kla
21
8
  end
22
9
 
23
- def invoke_3 vm, arg_0, arg_1
24
- builtin_invoke_3 vm, arg_0, arg_1
25
- rescue StandardError => e
26
- handle_error e, arg_0, arg_1
27
- end
28
-
29
- def invoke_4 vm, arg_0, arg_1, arg_2
30
- builtin_invoke_4 vm, arg_0, arg_1, arg_2
31
- rescue StandardError => e
32
- handle_error e, arg_0, arg_1, arg_2
33
- end
34
-
35
- # called from 'apply (among others)
36
- def invoke vm, args
37
- builtin_invoke vm, args
38
- rescue StandardError => e
39
- handle_error e, *(args.to_a)
40
- end
10
+ ignore_errors Nydp::Error
41
11
 
42
12
  def handle_error e, *args
43
13
  case e
44
- when Nydp::Error
14
+ when *@@reraise_errors
45
15
  raise e
46
16
  else
47
- arg_msg = args.map { |a| " #{a.inspect}"}.join("\n")
48
- new_msg = "Called #{self.inspect}\nwith args\n#{arg_msg}"
17
+ arg_msg = args.map { |a| "#{a._nydp_inspect}"}.join("\n").split(/\n/).map { |s| " #{s}"}.join("\n")
18
+ new_msg = "Called #{self._nydp_inspect}\nwith args\n#{arg_msg}"
49
19
  raise new_msg
50
20
  end
51
21
  end
52
22
 
23
+ def call *args
24
+ builtin_call *args
25
+ rescue => e
26
+ handle_error e, *args
27
+ end
28
+
29
+ alias _nydp_call call
30
+
53
31
  def name
54
32
  cname = self.class.name.split("::").last
55
33
  cname = cname.gsub(/([a-z])([A-Z])/) { |m| "#{m[0]}-#{m[1].downcase}" }