nydp 0.4.5 → 0.4.6

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +44 -0
  3. data/lib/lisp/core-015-documentation.nydp +12 -7
  4. data/lib/lisp/core-017-builtin-dox.nydp +13 -12
  5. data/lib/lisp/core-030-syntax.nydp +24 -16
  6. data/lib/lisp/core-037-list-utils.nydp +0 -11
  7. data/lib/lisp/core-040-utils.nydp +11 -0
  8. data/lib/lisp/core-041-string-utils.nydp +1 -1
  9. data/lib/lisp/core-043-list-utils.nydp +6 -6
  10. data/lib/lisp/core-080-pretty-print.nydp +5 -0
  11. data/lib/lisp/core-090-hook.nydp +19 -7
  12. data/lib/lisp/core-120-settings.nydp +2 -2
  13. data/lib/lisp/core-130-validations.nydp +51 -0
  14. data/lib/lisp/core-900-benchmarking.nydp +59 -1
  15. data/lib/lisp/tests/multi-assign-examples.nydp +6 -0
  16. data/lib/lisp/tests/settings-examples.nydp +16 -0
  17. data/lib/lisp/tests/string-tests.nydp +4 -1
  18. data/lib/lisp/tests/to-integer-examples.nydp +16 -0
  19. data/lib/lisp/tests/validation-examples.nydp +15 -0
  20. data/lib/nydp.rb +4 -0
  21. data/lib/nydp/builtin/date.rb +6 -1
  22. data/lib/nydp/builtin/inspect.rb +1 -1
  23. data/lib/nydp/builtin/plus.rb +10 -2
  24. data/lib/nydp/builtin/random_string.rb +2 -2
  25. data/lib/nydp/builtin/ruby_wrap.rb +8 -5
  26. data/lib/nydp/builtin/string_match.rb +2 -2
  27. data/lib/nydp/builtin/string_pad_left.rb +1 -1
  28. data/lib/nydp/builtin/string_pad_right.rb +1 -1
  29. data/lib/nydp/builtin/string_replace.rb +1 -1
  30. data/lib/nydp/builtin/string_split.rb +1 -2
  31. data/lib/nydp/builtin/to_integer.rb +23 -0
  32. data/lib/nydp/builtin/to_string.rb +2 -9
  33. data/lib/nydp/core.rb +4 -2
  34. data/lib/nydp/core_ext.rb +13 -1
  35. data/lib/nydp/date.rb +1 -0
  36. data/lib/nydp/helper.rb +29 -7
  37. data/lib/nydp/pair.rb +8 -3
  38. data/lib/nydp/parser.rb +4 -5
  39. data/lib/nydp/truth.rb +2 -2
  40. data/lib/nydp/version.rb +1 -1
  41. data/lib/nydp/vm.rb +7 -0
  42. data/spec/embedded_spec.rb +12 -12
  43. data/spec/foreign_hash_spec.rb +2 -2
  44. data/spec/hash_non_hash_behaviour_spec.rb +7 -7
  45. data/spec/hash_spec.rb +2 -2
  46. data/spec/nydp_spec.rb +14 -2
  47. data/spec/parser_spec.rb +16 -16
  48. data/spec/rand_spec.rb +3 -3
  49. data/spec/spec_helper.rb +10 -1
  50. metadata +7 -2
@@ -0,0 +1,6 @@
1
+ (examples-for ampersand-syntax
2
+ ("assigns multiple values at once ; value of expr is last assigned value"
3
+ (with (a 1 b { foo 2 } c { d { e 3 } })
4
+ (let res (= a 10 b.foo 20 (&d.e c) 30)
5
+ (list a b.foo c.d.e res)))
6
+ (10 20 30 30)))
@@ -1,3 +1,6 @@
1
+ (def-setting "testing.reset.string" "hello world")
2
+ (def-setting "testing.reset.fn" to-string)
3
+
1
4
  (examples-for settings/fn
2
5
  ("returns arg if it is a sym"
3
6
  (settings/fn 'foobar)
@@ -22,3 +25,16 @@
22
25
  ("wraps arg in a fn expression if it is a complex expression"
23
26
  (settings/fn '(let foo this that (rfnwith (complex stuff) (%td.tricky#syntax))))
24
27
  (fn (_) (let foo this that (rfnwith (complex stuff) ((percent-syntax || (dot-syntax td tricky#syntax))))))))
28
+
29
+ (examples-for reset-setting
30
+ ("restores a setting to its original value"
31
+ (do (set-setting "testing.reset.string" "goodbye, dear life")
32
+ (reset-setting "testing.reset.string")
33
+ (setting "testing.reset.string"))
34
+ "hello world")
35
+
36
+ ("restores a setting to its original function value"
37
+ (do (set-setting "testing.reset.fn" "goodbye, dear life")
38
+ (reset-setting "testing.reset.fn")
39
+ (setting "testing.reset.fn"))
40
+ "testing.reset.fn"))
@@ -138,4 +138,7 @@ and args (\"world\" 36 6)"
138
138
  (examples-for string-strip
139
139
  ("removes leading whitespace" (string-strip " hello!") "hello!" )
140
140
  ("removes trailing whitespace" (string-strip "(world) ") "(world)" )
141
- ("removes leading and trailing whitespace" (string-strip "\n\nme\n\n") "me" ))
141
+ ("removes leading and trailing whitespace" (string-strip "\n\nme\n\n") "me" )
142
+ ("ignores leading and trailing whitespace for intenal lines"
143
+ (string-strip "\n\n me \n\n you \n\n\t them \t\n\n")
144
+ "me \n\n you \n\n\t them" ))
@@ -0,0 +1,16 @@
1
+ (examples-for to-integer
2
+ ("converts a string"
3
+ (to-integer "1234")
4
+ 1234)
5
+
6
+ ("converts a date"
7
+ (to-integer (date 2004 3 12))
8
+ 1079046000)
9
+
10
+ ("converts a time"
11
+ (to-integer (time 2004 3 12 18 45))
12
+ 1079113500)
13
+
14
+ ("returns nonsense for non-integer"
15
+ (to-integer { foo 'bar })
16
+ 0))
@@ -0,0 +1,15 @@
1
+ (validate/def string test-0 (if (< (len string) 6) (mf "length" "should be more than 6")))
2
+ (validate/def string test-0 (if (> (len string) 10) (mf "length" "should be less than 10")))
3
+
4
+ (examples-for validate
5
+ ("returns a message about a string being too short"
6
+ (to-string:validate "foo" 'test-0)
7
+ "{\"length\"=>(\"should be more than 6\")}")
8
+
9
+ ("returns a message about a string being too long"
10
+ (to-string:validate "foo bar toto titi" 'test-0)
11
+ "{\"length\"=>(\"should be less than 10\")}")
12
+
13
+ ("returns an empty hash"
14
+ (to-string:validate "foo bar" 'test-0)
15
+ "{}"))
@@ -2,6 +2,10 @@ require 'date'
2
2
  require 'set'
3
3
 
4
4
  module Nydp
5
+ class << self
6
+ attr_accessor :logger # not used by this gem but very useful in your app
7
+ end
8
+
5
9
  class Namespace < Hash
6
10
  end
7
11
 
@@ -16,7 +16,12 @@ class Nydp::Builtin::Date
16
16
 
17
17
  # it's a Time object (or any object that responds to #to_date)
18
18
  def builtin_invoke_2 vm, arg
19
- vm.push_arg(Nydp::Date.new arg.to_date)
19
+ arg = if arg.respond_to?(:to_date)
20
+ arg.to_date
21
+ elsif arg.is_a?(String)
22
+ ::Date.parse(arg)
23
+ end
24
+ vm.push_arg(Nydp::Date.new arg)
20
25
  end
21
26
 
22
27
  def builtin_invoke_3 vm, a0, a1
@@ -2,6 +2,6 @@ class Nydp::Builtin::Inspect
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
4
  def builtin_invoke vm, args
5
- vm.push_arg Nydp::StringAtom.new(args.car.inspect)
5
+ vm.push_arg args.car.inspect
6
6
  end
7
7
  end
@@ -10,13 +10,21 @@ class Nydp::Builtin::Plus
10
10
  vm.push_arg case args.car
11
11
  when Nydp::Pair
12
12
  sum(args, Nydp::NIL)
13
- when String, Nydp::StringAtom
14
- sum(args, Nydp::StringAtom.new(""))
13
+ when String
14
+ string_concat("", args)
15
15
  else
16
16
  sum(args.cdr, args.car)
17
17
  end
18
18
  end
19
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
27
+
20
28
  def sum args, accum
21
29
  while args && !Nydp::NIL.is?(args)
22
30
  accum += args.car
@@ -5,7 +5,7 @@ class Nydp::Builtin::RandomString
5
5
 
6
6
  def builtin_invoke vm, args
7
7
  length = args.car unless Nydp::NIL.is?(args)
8
- s = (0...(length || 10)).map { RANDOM_CHARS[rand(RANDOM_CHARS.size)] }.join
9
- vm.push_arg Nydp::StringAtom.new s
8
+ s = (0...(length || 10)).inject("") {|a,i| a << RANDOM_CHARS[rand(RANDOM_CHARS.size)] }
9
+ vm.push_arg s
10
10
  end
11
11
  end
@@ -15,7 +15,8 @@ class Nydp::Builtin::RubyWrap
15
15
  when 2 ; ", a0, a1"
16
16
  when 3 ; ", a0, a1, a2"
17
17
  when 4 ; ", a0, a1, a2, a3"
18
- else ; raise "maximum 4 arguments!"
18
+ when 5 ; ", a0, a1, a2, a3, a4"
19
+ else ; raise "maximum 5 arguments!"
19
20
  end
20
21
  end
21
22
 
@@ -24,7 +25,8 @@ class Nydp::Builtin::RubyWrap
24
25
  gsub(/a0/, "args.car").
25
26
  gsub(/a1/, "args.cdr.car").
26
27
  gsub(/a2/, "args.cdr.cdr.car").
27
- gsub(/a3/, "args.cdr.cdr.cdr.car")
28
+ gsub(/a3/, "args.cdr.cdr.cdr.car").
29
+ gsub(/a4/, "args.cdr.cdr.cdr.cdr.car")
28
30
  <<CODE
29
31
  class #{name}
30
32
  include Nydp::Builtin::Base, Singleton#{helpers}
@@ -63,7 +65,8 @@ CODE
63
65
  end
64
66
 
65
67
  core_builder = builder ""
66
- core_builder.build(:Cons, 2, %{ Nydp::Pair.new(a0, a1) })
67
- core_builder.build(:Car , 1, %{ a0.car })
68
- core_builder.build(:Cdr , 1, %{ a0.cdr })
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) } )
69
72
  end
@@ -10,8 +10,8 @@ class Nydp::Builtin::StringMatch
10
10
 
11
11
  if match
12
12
  result = Nydp::Hash.new
13
- result[kmatch] = Nydp::StringAtom.new match.to_s
14
- result[kcaptures] = Nydp::Pair.from_list match.captures.map { |cap| Nydp::StringAtom.new cap.to_s }
13
+ result[kmatch] = match.to_s
14
+ result[kcaptures] = Nydp::Pair.from_list match.captures.map { |cap| cap.to_s }
15
15
  else
16
16
  result = Nydp::NIL
17
17
  end
@@ -2,6 +2,6 @@ class Nydp::Builtin::StringPadLeft
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
4
  def builtin_invoke_4 vm, str, len, padding
5
- vm.push_arg Nydp::StringAtom.new str.to_s.rjust len, padding.to_s
5
+ vm.push_arg str.to_s.rjust(len, padding.to_s)
6
6
  end
7
7
  end
@@ -2,6 +2,6 @@ class Nydp::Builtin::StringPadRight
2
2
  include Nydp::Builtin::Base, Singleton
3
3
 
4
4
  def builtin_invoke_4 vm, str, len, padding
5
- vm.push_arg Nydp::StringAtom.new str.to_s.ljust len, padding.to_s
5
+ vm.push_arg str.to_s.ljust(len, padding.to_s)
6
6
  end
7
7
  end
@@ -7,6 +7,6 @@ class Nydp::Builtin::StringReplace
7
7
  target = args.cdr.cdr.car.to_s
8
8
  result = target.to_s.gsub to_remove, to_insert
9
9
 
10
- vm.push_arg Nydp::StringAtom.new result
10
+ vm.push_arg result
11
11
  end
12
12
  end
@@ -5,8 +5,7 @@ class Nydp::Builtin::StringSplit
5
5
  target = args.car.to_s
6
6
  separator = args.cdr.car.to_s
7
7
  result = target.split separator, -1
8
- list = result.map { |s| Nydp::StringAtom.new s }
9
8
 
10
- vm.push_arg Nydp::Pair.from_list list
9
+ vm.push_arg Nydp::Pair.from_list result
11
10
  end
12
11
  end
@@ -0,0 +1,23 @@
1
+ module Nydp::Builtin
2
+ class ToInteger
3
+ include Nydp::Builtin::Base, Singleton
4
+
5
+ def builtin_invoke_2 vm, arg
6
+ arg = n2r arg
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
21
+ end
22
+ end
23
+ end
@@ -3,14 +3,7 @@ module Nydp::Builtin
3
3
  include Nydp::Builtin::Base, Singleton
4
4
 
5
5
  def builtin_invoke vm, args
6
- arg = args.car
7
- val = case arg.class
8
- when Nydp::StringAtom
9
- arg
10
- else
11
- Nydp::StringAtom.new arg.to_s
12
- end
13
- vm.push_arg val
6
+ vm.push_arg args.car.to_s
14
7
  end
15
8
  end
16
9
 
@@ -20,7 +13,7 @@ module Nydp::Builtin
20
13
  def builtin_invoke vm, args
21
14
  arg = args.car
22
15
  val = case arg
23
- when Nydp::StringAtom
16
+ when String
24
17
  arg.length
25
18
  else
26
19
  0
@@ -26,8 +26,9 @@ module Nydp
26
26
 
27
27
  def setup ns
28
28
  Symbol.mk(:cons , ns).assign(Nydp::Builtin::RubyWrap::Cons.instance)
29
- Symbol.mk(:car , ns).assign(Nydp::Builtin::RubyWrap::Car.instance)
30
- Symbol.mk(:cdr , ns).assign(Nydp::Builtin::RubyWrap::Cdr.instance)
29
+ Symbol.mk(:car , ns).assign(Nydp::Builtin::RubyWrap::Car.instance )
30
+ Symbol.mk(:cdr , ns).assign(Nydp::Builtin::RubyWrap::Cdr.instance )
31
+ Symbol.mk(:log , ns).assign(Nydp::Builtin::RubyWrap::Log.instance )
31
32
 
32
33
  Symbol.mk(:+, ns).assign(Nydp::Builtin::Plus.instance)
33
34
  Symbol.mk(:-, ns).assign(Nydp::Builtin::Minus.instance)
@@ -59,6 +60,7 @@ module Nydp
59
60
  Symbol.mk("parse-in-string" , ns).assign(Nydp::Builtin::ParseInString.instance)
60
61
  Symbol.mk("random-string" , ns).assign(Nydp::Builtin::RandomString.instance)
61
62
  Symbol.mk("to-string" , ns).assign(Nydp::Builtin::ToString.instance)
63
+ Symbol.mk("to-integer" , ns).assign(Nydp::Builtin::ToInteger.instance)
62
64
  Symbol.mk("string-length" , ns).assign(Nydp::Builtin::StringLength.instance)
63
65
  Symbol.mk("string-replace" , ns).assign(Nydp::Builtin::StringReplace.instance)
64
66
  Symbol.mk("string-match" , ns).assign(Nydp::Builtin::StringMatch.instance)
@@ -6,6 +6,15 @@ class Object
6
6
  def lexical_reach n ; n ; end
7
7
  end
8
8
 
9
+ class Method
10
+ include Nydp::Converter
11
+ def invoke_1 vm ; vm.push_arg call._nydp_wrapper ; end
12
+ def invoke_2 vm, a0 ; vm.push_arg call(n2r(a0))._nydp_wrapper ; end
13
+ def invoke_3 vm, a0, a1 ; vm.push_arg call(n2r(a0), n2r(a1))._nydp_wrapper ; end
14
+ def invoke_4 vm, a0, a1, a2 ; vm.push_arg call(n2r(a0), n2r(a1), n2r(a2))._nydp_wrapper ; end
15
+ def invoke vm, args ; vm.push_arg call(*(args.map { |a| n2r a}))._nydp_wrapper ; end
16
+ end
17
+
9
18
  class NilClass
10
19
  def _nydp_wrapper ; Nydp::NIL ; end
11
20
  end
@@ -31,7 +40,10 @@ class ::Array
31
40
  end
32
41
 
33
42
  class ::String
34
- def _nydp_wrapper ; Nydp::StringAtom.new self ; end
43
+ # def _nydp_wrapper ; Nydp::StringAtom.new self ; end
44
+ def as_method_name ; self.gsub(/-/, '_').to_sym ; end
45
+ def nydp_type ; :string ; end
46
+ def to_ruby ; self ; end
35
47
  end
36
48
 
37
49
  class ::Hash
@@ -18,6 +18,7 @@ module Nydp
18
18
 
19
19
  def initialize ruby_date ; @ruby_date = ruby_date ; end
20
20
 
21
+ def to_date ; ruby_date ; end
21
22
  def to_s ; ruby_date.to_s ; end
22
23
  def to_ruby ; ruby_date ; end
23
24
  def inspect ; ruby_date.inspect ; end
@@ -1,17 +1,39 @@
1
1
  module Nydp
2
2
  module AutoWrap
3
3
  # include this and be sure to either override #_nydp_ok? or #_nydp_whitelist
4
- # #_nydp_whitelist should return a list of methods which are safe for nydp to invoke
5
- def _nydp_wrapper ; self ; end
6
- def _nydp_ok? method ; _nydp_whitelist.include? method ; end
7
- def _nydp_safe_send method, *args ; send method, *args if _nydp_ok? method ; end
8
- def _nydp_get key ; _nydp_safe_send(key.to_s.as_method_name) ; end
9
- def to_ruby ; self ; end
4
+ # #_nydp_whitelist should return a list of accessor (zero-arg) methods which are safe for nydp to invoke
5
+ # #_nydp_procify should return a list of methods that can be exposed to script code.
6
+ #
7
+ # class Blub
8
+ # _nydp_procs << :blubme
9
+ # def blubme where, when
10
+ # puts "blubme #{where}, #{when}"
11
+ # end
12
+ # end
13
+ #
14
+ # in nydp, if blub is an instance of Blub:
15
+ #
16
+ # (blub.blubme "here" "now")
17
+ #
18
+ # prints
19
+ #
20
+ # blubme here, now
21
+ #
22
+ def _nydp_wrapper ; self ; end
23
+ def _nydp_ok? method ; _nydp_whitelist.include? method ; end
24
+ def _nydp_procify? method ; _nydp_procs.include? method ; end # override to allow returning Method instances for given method name
25
+ def _nydp_get key ; _nydp_safe_send(key.to_s.as_method_name) ; end
26
+ def to_ruby ; self ; end
27
+ def _nydp_safe_send meth, *args
28
+ return send meth, *args if _nydp_ok?(meth)
29
+ return method(meth) if _nydp_procify?(meth)
30
+ end
10
31
  end
11
32
 
12
33
  class Struct < ::Struct
13
34
  include AutoWrap
14
35
  def _nydp_whitelist ; members ; end
36
+ def _nydp_procs ; [] ; end
15
37
  end
16
38
 
17
39
  module Converter
@@ -61,7 +83,7 @@ module Nydp
61
83
 
62
84
  def literal? expr
63
85
  case expr
64
- when String, Float, Integer, Fixnum, Nydp::Symbol, Nydp::StringAtom, Nydp::Truth, Nydp::Nil
86
+ when String, Float, Integer, Fixnum, Nydp::Symbol, Nydp::Truth, Nydp::Nil
65
87
  true
66
88
  else
67
89
  false
@@ -39,9 +39,14 @@ class Nydp::Pair
39
39
  end
40
40
 
41
41
  # returns Array of elements after calling #n2r on each element
42
- def to_ruby list=[]
43
- list << n2r(car)
44
- cdr.is_a?(Nydp::Pair) ? cdr.to_ruby(list) : list
42
+ def to_ruby list=[], pair=self
43
+ list << n2r(pair.car)
44
+ while(pair.cdr.is_a?(Nydp::Pair))
45
+ pair = pair.cdr
46
+ list << n2r(pair.car)
47
+ end
48
+
49
+ list
45
50
  end
46
51
 
47
52
  # returns Array of elements as they are
@@ -34,8 +34,7 @@ module Nydp
34
34
  when /^(.*),@$/
35
35
  prefix_list $1, Pair.from_list([sym(:"unquote-splicing"), list])
36
36
  else
37
- pfx = Nydp::StringAtom.new prefix
38
- Pair.from_list([sym(:"prefix-list"), pfx, list])
37
+ Pair.from_list([sym(:"prefix-list"), prefix, list])
39
38
  end
40
39
  end
41
40
 
@@ -111,7 +110,7 @@ module Nydp
111
110
  when :symbol
112
111
  parse_symbol token.last
113
112
  when :comment
114
- Pair.from_list [sym(:comment), Nydp::StringAtom.new(token.last)]
113
+ Pair.from_list [sym(:comment), token.last]
115
114
  else
116
115
  token.last
117
116
  end
@@ -132,11 +131,11 @@ module Nydp
132
131
  fragments = [sym(:"string-pieces")]
133
132
  string_token = token_stream.next_string_fragment(open_delimiter, close_delimiter, INTERPOLATION_SIGN, INTERPOLATION_ESCAPES)
134
133
  raise "unterminated string" if string_token.nil?
135
- fragments << Nydp::StringAtom.new(string_token.string)
134
+ fragments << string_token.string
136
135
  while !(string_token.is_a? StringFragmentCloseToken)
137
136
  fragments << expression(token_stream)
138
137
  string_token = token_stream.next_string_fragment('', close_delimiter, INTERPOLATION_SIGN, INTERPOLATION_ESCAPES)
139
- fragments << Nydp::StringAtom.new(string_token.string)
138
+ fragments << string_token.string
140
139
  end
141
140
 
142
141
  if fragments.size == 2
@@ -19,8 +19,8 @@ module Nydp
19
19
  def car ; self ; end
20
20
  def cdr ; self ; end
21
21
  def size ; 0 ; end
22
- def is? other ; self == other ; end
23
- def isnt? other ; self != other ; end
22
+ def is? other ; self.equal? other ; end
23
+ def isnt? other ; !self.equal? other ; end
24
24
  def to_s ; "" ; end
25
25
  def + other ; other ; end
26
26
  def copy ; self ; end