nydp 0.5.1 → 0.6.0

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