nydp 0.4.5 → 0.4.6

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