nydp 0.0.10.1 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -0
  3. data/lib/lisp/core-04-utils.nydp +2 -0
  4. data/lib/lisp/tests/builtin-tests.nydp +40 -0
  5. data/lib/lisp/tests/foundation-test.nydp +25 -0
  6. data/lib/lisp/tests/parser-tests.nydp +4 -0
  7. data/lib/nydp/builtin.rb +13 -4
  8. data/lib/nydp/builtin/apply.rb +2 -2
  9. data/lib/nydp/builtin/car.rb +3 -4
  10. data/lib/nydp/builtin/cdr.rb +3 -4
  11. data/lib/nydp/builtin/cdr_set.rb +3 -1
  12. data/lib/nydp/builtin/comment.rb +3 -1
  13. data/lib/nydp/builtin/cons.rb +6 -3
  14. data/lib/nydp/builtin/divide.rb +5 -1
  15. data/lib/nydp/builtin/ensuring.rb +2 -2
  16. data/lib/nydp/builtin/error.rb +5 -1
  17. data/lib/nydp/builtin/eval.rb +3 -9
  18. data/lib/nydp/builtin/greater_than.rb +5 -1
  19. data/lib/nydp/builtin/handle_error.rb +3 -2
  20. data/lib/nydp/builtin/inspect.rb +3 -1
  21. data/lib/nydp/builtin/is_equal.rb +5 -1
  22. data/lib/nydp/builtin/less_than.rb +5 -1
  23. data/lib/nydp/builtin/load_tests.rb +4 -1
  24. data/lib/nydp/builtin/millisecs.rb +2 -2
  25. data/lib/nydp/builtin/minus.rb +5 -1
  26. data/lib/nydp/builtin/parse.rb +3 -1
  27. data/lib/nydp/builtin/parse_in_string.rb +3 -1
  28. data/lib/nydp/builtin/plus.rb +4 -4
  29. data/lib/nydp/builtin/pre_compile.rb +3 -1
  30. data/lib/nydp/builtin/puts.rb +5 -1
  31. data/lib/nydp/builtin/quit.rb +3 -1
  32. data/lib/nydp/builtin/random_string.rb +3 -1
  33. data/lib/nydp/builtin/sqrt.rb +3 -1
  34. data/lib/nydp/builtin/string_match.rb +24 -0
  35. data/lib/nydp/builtin/string_replace.rb +4 -6
  36. data/lib/nydp/builtin/string_split.rb +3 -5
  37. data/lib/nydp/builtin/{to_sym.rb → sym.rb} +5 -2
  38. data/lib/nydp/builtin/thread_locals.rb +2 -2
  39. data/lib/nydp/builtin/times.rb +5 -1
  40. data/lib/nydp/builtin/to_string.rb +27 -21
  41. data/lib/nydp/builtin/today.rb +2 -2
  42. data/lib/nydp/builtin/type_of.rb +3 -1
  43. data/lib/nydp/builtin/vm_info.rb +3 -1
  44. data/lib/nydp/core.rb +3 -2
  45. data/lib/nydp/hash.rb +1 -0
  46. data/lib/nydp/symbol.rb +5 -8
  47. data/lib/nydp/tokeniser.rb +1 -1
  48. data/lib/nydp/version.rb +1 -1
  49. data/lib/nydp/vm.rb +9 -1
  50. data/spec/embedded_spec.rb +4 -0
  51. data/spec/error_spec.rb +12 -0
  52. data/spec/literal_spec.rb +8 -0
  53. metadata +5 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ebb185874a9dc692fc52b40620ef19385b49d644
4
- data.tar.gz: 6e63e8ffcf047ee20894abde0b0bb9ed497ba6ca
3
+ metadata.gz: 6cb7040e607f04ac084dcf352dfe736d7c800d0b
4
+ data.tar.gz: 6c157638bebfa82f3b027ed38aa12dd1452b8396
5
5
  SHA512:
6
- metadata.gz: a80c411a9b87d57de98530cb1729b4b10e9b406b09ca6a21a1fb7d0b40afa5323e9a2b545aa202faab76332b3eff0c32297677c3816f26a46e4715ef419ca1db
7
- data.tar.gz: ddc4305e8078bfb08e78b1b9c8891788d5501a3c085ba03a970ca6d59408deea2c6984f04d8d6579daa9e44596da1001dceee45af95f03d3b0a4c5a9e2b1e21f
6
+ metadata.gz: 231c62ab18da966168e4f1320f36bf9c1df91d9597cb4d68fee07bfac9b3e8ea8092ae9b1161a747483bc1711edfaa3985edcd1eeec2b7f59cc49825e63b8642
7
+ data.tar.gz: 96ab3742b6e55da13118b92ad3837517f7710e7fad80708361ca1f5909c0be726ec58ad8a57f48eef5a49610530a865bd325dc19cb860410665bda145da97cfd
data/README.md CHANGED
@@ -125,6 +125,27 @@ nydp > (pre-compile '(!eq? a b))
125
125
  ==> ((fn args (no (apply eq? args))) a b) ; equivalent to (no (eq? a b))
126
126
  ```
127
127
 
128
+ Ampersand-syntax - for example `&foo`, expands to a function which performs a hash-lookup on its argument.
129
+
130
+ ```lisp
131
+
132
+ nydp > (parse "&foo")
133
+ ((ampersand-syntax || foo))
134
+
135
+ nydp > (pre-compile (parse "&foo"))
136
+ ((fn (obj) (hash-get obj (quote foo))))
137
+
138
+ nydp > (assign hsh { foo 1 bar 2 })
139
+ nydp > (&lastname (car german-composers))
140
+ Bach
141
+
142
+ nydp > (map &lastname german-composers) ; ampersand-syntax creates a function you can pass around
143
+ (Bach Beethoven Wagner Mozart)
144
+
145
+ ```
146
+
147
+ As with all other syntax, you can of course override the `ampersand-syntax` macro to handle your special needs.
148
+
128
149
  Look for `SYMBOL_OPERATORS` in [parser.rb](lib/nydp/parser.rb) to see which syntax is recognised and in which order. The order of these definitions defines special-syntax-operator precedence.
129
150
 
130
151
  #### 3. Special list syntax
@@ -120,3 +120,5 @@
120
120
 
121
121
  (mac mapx (things x expr)
122
122
  `(map (fn (,x) ,expr) ,things))
123
+
124
+ (def empty? (things) (eq? (len things) 0))
@@ -0,0 +1,40 @@
1
+ (register-test '(suite "Builtin Tests"
2
+ ("car" (inspect car ) "builtin/car" )
3
+ ("cdr" (inspect cdr ) "builtin/cdr" )
4
+ ("cdr-set" (inspect cdr-set ) "builtin/cdr-set" )
5
+ ("cons" (inspect cons ) "builtin/cons" )
6
+ ("+" (inspect + ) "builtin/+" )
7
+ ("-" (inspect - ) "builtin/-" )
8
+ ("*" (inspect * ) "builtin/*" )
9
+ ("/" (inspect / ) "builtin//" )
10
+ (">" (inspect > ) "builtin/>" )
11
+ ("<" (inspect < ) "builtin/<" )
12
+ ("eval" (inspect eval ) "builtin/eval" )
13
+ ("hash" (inspect hash ) "builtin/hash" )
14
+ ("error" (inspect error ) "builtin/error" )
15
+ ("apply" (inspect apply ) "builtin/apply" )
16
+ ("error" (inspect error ) "builtin/error" )
17
+ ("parse" (inspect parse ) "builtin/parse" )
18
+ ("p" (inspect p ) "builtin/p" )
19
+ ("sqrt" (inspect sqrt ) "builtin/sqrt" )
20
+ ("sym" (inspect sym ) "builtin/sym" )
21
+ ("ensuring" (inspect ensuring ) "builtin/ensuring" )
22
+ ("inspect" (inspect inspect ) "builtin/inspect" )
23
+ ("comment" (inspect comment ) "builtin/comment" )
24
+ ("millisecs" (inspect millisecs ) "builtin/millisecs" )
25
+ ("load-tests" (inspect load-tests ) "builtin/load-tests" )
26
+ ("handle-error" (inspect handle-error ) "builtin/handle-error" )
27
+ ("parse-in-string" (inspect parse-in-string ) "builtin/parse-in-string" )
28
+ ("random-string" (inspect random-string ) "builtin/random-string" )
29
+ ("to-string" (inspect to-string ) "builtin/to-string" )
30
+ ("string-length" (inspect string-length ) "builtin/string-length" )
31
+ ("string-replace" (inspect string-replace ) "builtin/string-replace" )
32
+ ("string-split" (inspect string-split ) "builtin/string-split" )
33
+ ("thread-locals" (inspect thread-locals ) "builtin/thread-locals" )
34
+ ("eq?" (inspect eq? ) "builtin/eq?" )
35
+ ("hash-get" (inspect hash-get ) "builtin/hash-get" )
36
+ ("hash-set" (inspect hash-set ) "builtin/hash-set" )
37
+ ("hash-keys" (inspect hash-keys ) "builtin/hash-keys" )
38
+ ("hash-merge" (inspect hash-merge ) "builtin/hash-merge" )
39
+ ("vm-info" (inspect vm-info ) "builtin/vm-info" )
40
+ ))
@@ -15,11 +15,36 @@
15
15
  (string-replace "and" "or" "a and b and c and d")
16
16
  "a or b or c or d"))
17
17
 
18
+ (suite "regexp"
19
+ ("replace with regexp"
20
+ (string-replace "and|or" "x" "a and b or c and d")
21
+ "a x b x c x d")
22
+
23
+ ("match with regexp"
24
+ (let m (string-match "a and b and c and d" "and")
25
+ (list m.match m.captures))
26
+ ("and" nil))
27
+
28
+ ("match with regexp and capturing groups"
29
+ (let m (string-match " foo\b bar" "(^\\s+)")
30
+ (list m.match m.captures))
31
+ (" " (" ")))
32
+ )
33
+
34
+
18
35
  (suite "type-of"
19
36
  ("returns 'string"
20
37
  (type-of "foobar")
21
38
  string)
22
39
 
40
+ ("returns 'hash for new hash"
41
+ (type-of (hash))
42
+ hash)
43
+
44
+ ("returns 'hash for hash literal"
45
+ (type-of { a 1 b 2})
46
+ hash)
47
+
23
48
  ("returns 'number for an integer"
24
49
  (type-of 42)
25
50
  number)
@@ -54,6 +54,10 @@
54
54
  (parse-in-string (joinstr "" (list "hello, " '~ "(world), take me to your " '~ "dealer please")))
55
55
  (string-pieces "hello, " (world) ", take me to your " dealer " please"))
56
56
 
57
+ ("parses a plain string of html text with interpolations"
58
+ (parse-in-string "<div id='content_item_~~{id}'><label>~~{data-name-1}</label> ~~{data-text-1}</div>")
59
+ (string-pieces "<div id='content_item_" (brace-list id) "'><label>" (brace-list data-name-1) "</label> " (brace-list data-text-1) "</div>"))
60
+
57
61
  ("ignores standalone interpolation symbol"
58
62
  (parse-in-string (joinstr "" (list "hello " '~ " world")))
59
63
  "hello \~ world")
@@ -5,14 +5,23 @@ module Nydp::Builtin
5
5
  module Base
6
6
  def invoke vm, args
7
7
  builtin_invoke vm, args
8
+ rescue Nydp::Error => ne
9
+ raise ne
8
10
  rescue Exception => e
9
- new_msg = "Invoking #{self.class.name}\nwith args #{args}\nraised\n#{Nydp.indent_text e.message}"
11
+ new_msg = "Called #{self.inspect}\nwith args #{args.inspect}\nraised\n#{Nydp.indent_text e.message}"
10
12
  raise $!, new_msg, $!.backtrace
11
13
  end
12
- end
13
14
 
14
- def inspect ; self.class.name ; end
15
- def to_s ; self.class.name ; end
15
+ def name
16
+ cname = self.class.name.split("::").last
17
+ cname = cname.gsub(/([a-z])([A-Z])/) { |m| "#{m[0]}-#{m[1].downcase}" }
18
+ cname = cname.gsub(/^([A-Z])/) { |m| m.downcase }
19
+ cname
20
+ end
21
+
22
+ def inspect ; "builtin/#{name}" ; end
23
+ def to_s ; name ; end
24
+ end
16
25
  end
17
26
 
18
27
  Dir[File.join(File.dirname(__FILE__), "builtin", "**/*.rb")].each {|f|
@@ -1,7 +1,7 @@
1
1
  class Nydp::Builtin::Apply
2
- include Nydp::Helper
2
+ include Nydp::Helper, Nydp::Builtin::Base
3
3
 
4
- def invoke vm, args
4
+ def builtin_invoke vm, args
5
5
  args.car.invoke vm, apply_args(args.cdr)
6
6
  end
7
7
 
@@ -1,8 +1,7 @@
1
1
  class Nydp::Builtin::Car
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  vm.push_arg args.car.car
4
6
  end
5
-
6
- def to_s; "car"; end
7
- def inspect; "builtin:car"; end
8
7
  end
@@ -1,8 +1,7 @@
1
1
  class Nydp::Builtin::Cdr
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  vm.push_arg args.car.cdr
4
6
  end
5
-
6
- def to_s; "cdr"; end
7
- def inspect; "builtin:cdr"; end
8
7
  end
@@ -1,5 +1,7 @@
1
1
  class Nydp::Builtin::CdrSet
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  pair = args.car
4
6
  arg = args.cdr.car
5
7
  pair.cdr = arg
@@ -1,5 +1,7 @@
1
1
  class Nydp::Builtin::Comment
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  vm.push_arg Nydp.NIL
4
6
  end
5
7
  end
@@ -1,13 +1,16 @@
1
1
  module Nydp::Builtin
2
2
  class Cons
3
- def invoke vm, args
3
+ include Nydp::Builtin::Base
4
+
5
+ def builtin_invoke vm, args
4
6
  vm.push_arg Nydp::Pair.new(args.car, args.cdr.car)
5
7
  end
6
8
  end
7
9
 
8
10
  class IsPair
9
- include Nydp::Helper
10
- def invoke vm, args
11
+ include Nydp::Helper, Nydp::Builtin::Base
12
+
13
+ def builtin_invoke vm, args
11
14
  arg = args.car
12
15
  result = pair?(arg) ? Nydp.T : Nydp.NIL
13
16
  vm.push_arg result
@@ -1,5 +1,7 @@
1
1
  class Nydp::Builtin::Divide
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  vm.push_arg divide(args.cdr, args.car)
4
6
  end
5
7
 
@@ -10,4 +12,6 @@ class Nydp::Builtin::Divide
10
12
  divide(args.cdr, (accum / args.car))
11
13
  end
12
14
  end
15
+
16
+ def name ; "/" ; end
13
17
  end
@@ -1,7 +1,7 @@
1
1
  require "nydp/vm"
2
2
 
3
3
  class Nydp::Builtin::Ensuring
4
- include Nydp::Helper
4
+ include Nydp::Helper, Nydp::Builtin::Base
5
5
 
6
6
  class InvokeProtection
7
7
  include Nydp::VM::Finally
@@ -16,7 +16,7 @@ class Nydp::Builtin::Ensuring
16
16
  end
17
17
  end
18
18
 
19
- def invoke vm, args
19
+ def builtin_invoke vm, args
20
20
  fn_ensure = args.car
21
21
  fn_tricky = args.cdr.car
22
22
 
@@ -1,5 +1,9 @@
1
1
  class Nydp::Builtin::Error
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ # override #invoke on nydp/builtin/base because
5
+ # we don't want to inherit error handling
6
+ def builtin_invoke vm, args
3
7
  raise Nydp::Error.new(args.inspect)
4
8
  end
5
9
  end
@@ -1,18 +1,12 @@
1
1
  class Nydp::Builtin::Eval
2
+ include Nydp::Builtin::Base
3
+
2
4
  def initialize ns
3
5
  @ns = ns
4
6
  end
5
7
 
6
- def invoke vm, args
8
+ def builtin_invoke vm, args
7
9
  evaluator = Nydp::Evaluator.new Nydp::VM.new, @ns
8
10
  vm.push_arg evaluator.evaluate args.car
9
11
  end
10
-
11
- def to_s
12
- "eval"
13
- end
14
-
15
- def inspect
16
- "Nydp::Builtin::Eval"
17
- end
18
12
  end
@@ -1,5 +1,7 @@
1
1
  class Nydp::Builtin::GreaterThan
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  vm.push_arg (greater_than(args.car, args.cdr) ? Nydp.T : Nydp.NIL)
4
6
  end
5
7
 
@@ -7,4 +9,6 @@ class Nydp::Builtin::GreaterThan
7
9
  return true if Nydp.NIL.is? args
8
10
  (arg > args.car) && greater_than(args.car, args.cdr)
9
11
  end
12
+
13
+ def name ; ">" ; end
10
14
  end
@@ -1,7 +1,7 @@
1
1
  require "nydp/vm"
2
2
 
3
3
  class Nydp::Builtin::HandleError
4
- include Nydp::Helper
4
+ include Nydp::Helper, Nydp::Builtin::Base
5
5
 
6
6
  class CatchError
7
7
  include Nydp::Helper, Nydp::VM::HandleError
@@ -27,7 +27,8 @@ class Nydp::Builtin::HandleError
27
27
  end
28
28
  end
29
29
 
30
- def invoke vm, args
30
+
31
+ def builtin_invoke vm, args
31
32
  fn_handle = args.car
32
33
  fn_tricky = args.cdr.car
33
34
 
@@ -1,5 +1,7 @@
1
1
  class Nydp::Builtin::Inspect
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  vm.push_arg Nydp::StringAtom.new(args.car.inspect)
4
6
  end
5
7
  end
@@ -1,5 +1,9 @@
1
1
  class Nydp::Builtin::IsEqual
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  vm.push_arg ((args.car == args.cdr.car) ? Nydp.T : Nydp.NIL)
4
6
  end
7
+
8
+ def name ; "eq?" ; end
5
9
  end
@@ -1,5 +1,7 @@
1
1
  class Nydp::Builtin::LessThan
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  vm.push_arg (less_than(args.car, args.cdr) ? Nydp.T : Nydp.NIL)
4
6
  end
5
7
 
@@ -7,4 +9,6 @@ class Nydp::Builtin::LessThan
7
9
  return true if Nydp.NIL.is? args
8
10
  (arg < args.car) && less_than(args.car, args.cdr)
9
11
  end
12
+
13
+ def name ; "<" ; end
10
14
  end
@@ -1,8 +1,11 @@
1
1
  class Nydp::Builtin::LoadTests
2
+ include Nydp::Builtin::Base
3
+
2
4
  def initialize ns
3
5
  @ns = ns
4
6
  end
5
- def invoke vm, args
7
+
8
+ def builtin_invoke vm, args
6
9
  Nydp.loadall vm, @ns, Nydp.testfiles
7
10
  vm.push_arg Nydp.NIL
8
11
  end
@@ -1,7 +1,7 @@
1
1
  class Nydp::Builtin::Millisecs
2
- include Nydp::Helper
2
+ include Nydp::Helper, Nydp::Builtin::Base
3
3
 
4
- def invoke vm, args
4
+ def builtin_invoke vm, args
5
5
  vm.push_arg (Time.now.to_f * 1000).to_i
6
6
  end
7
7
  end
@@ -1,5 +1,7 @@
1
1
  class Nydp::Builtin::Minus
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  vm.push_arg diff(args.cdr, args.car)
4
6
  end
5
7
 
@@ -10,4 +12,6 @@ class Nydp::Builtin::Minus
10
12
  diff(args.cdr, (accum - args.car))
11
13
  end
12
14
  end
15
+
16
+ def name ; "-" ; end
13
17
  end
@@ -1,9 +1,11 @@
1
1
  class Nydp::Builtin::Parse
2
+ include Nydp::Builtin::Base
3
+
2
4
  def initialize ns
3
5
  @parser = Nydp::Parser.new(ns)
4
6
  end
5
7
 
6
- def invoke vm, args
8
+ def builtin_invoke vm, args
7
9
  tokens = Nydp::Tokeniser.new Nydp::StringReader.new args.car.to_s
8
10
  exprs = []
9
11
  while !tokens.finished
@@ -1,9 +1,11 @@
1
1
  class Nydp::Builtin::ParseInString
2
+ include Nydp::Builtin::Base
3
+
2
4
  def initialize ns
3
5
  @parser = Nydp::Parser.new(ns)
4
6
  end
5
7
 
6
- def invoke vm, args
8
+ def builtin_invoke vm, args
7
9
  tokens = Nydp::Tokeniser.new Nydp::StringReader.new args.car.to_s
8
10
  expr = @parser.string(tokens, "", :eof)
9
11
  vm.push_arg expr
@@ -1,5 +1,7 @@
1
1
  class Nydp::Builtin::Plus
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  vm.push_arg sum(args, origin(args.car))
4
6
  end
5
7
 
@@ -22,7 +24,5 @@ class Nydp::Builtin::Plus
22
24
  end
23
25
  end
24
26
 
25
- def to_s
26
- "Builtin:+"
27
- end
27
+ def name ; "+" ; end
28
28
  end
@@ -1,5 +1,7 @@
1
1
  class Nydp::Builtin::PreCompile
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  vm.push_arg args.car
4
6
  end
5
7
  end
@@ -1,7 +1,11 @@
1
1
  class Nydp::Builtin::Puts
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  s = args.map { |a| a.to_s }
4
6
  puts s.join ' '
5
7
  vm.push_arg args.car
6
8
  end
9
+
10
+ def name ; "p" ; end
7
11
  end
@@ -1,5 +1,7 @@
1
1
  class Nydp::Builtin::Quit
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  exit
4
6
  end
5
7
  end
@@ -1,7 +1,9 @@
1
1
  class Nydp::Builtin::RandomString
2
+ include Nydp::Builtin::Base
3
+
2
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"]
3
5
 
4
- def invoke vm, args
6
+ def builtin_invoke vm, args
5
7
  length = args.car unless Nydp.NIL.is?(args)
6
8
  s = (0...(length || 10)).map { @@random_chars[rand(@@random_chars.size)] }.join
7
9
  vm.push_arg Nydp::StringAtom.new s
@@ -1,5 +1,7 @@
1
1
  class Nydp::Builtin::Sqrt
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  vm.push_arg Math.sqrt args.car
4
6
  end
5
7
  end
@@ -0,0 +1,24 @@
1
+ class Nydp::Builtin::StringMatch
2
+ include Nydp::Builtin::Base
3
+
4
+ def initialize ns
5
+ @match = Nydp::Symbol.mk :match , ns
6
+ @captures = Nydp::Symbol.mk :captures, ns
7
+ end
8
+
9
+ def builtin_invoke vm, args
10
+ target = args.car.to_s
11
+ pattern = Regexp.new(args.cdr.car.to_s)
12
+ match = pattern.match target
13
+
14
+ if match
15
+ result = Nydp::Hash.new
16
+ result[@match] = Nydp::StringAtom.new match.to_s
17
+ result[@captures] = Nydp::Pair.from_list match.captures.map { |cap| Nydp::StringAtom.new cap.to_s }
18
+ else
19
+ result = Nydp.NIL
20
+ end
21
+
22
+ vm.push_arg result
23
+ end
24
+ end
@@ -1,14 +1,12 @@
1
1
  class Nydp::Builtin::StringReplace
2
- def invoke vm, args
3
- to_remove = args.car.to_s
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
5
+ to_remove = Regexp.new args.car.to_s
4
6
  to_insert = args.cdr.car.to_s
5
7
  target = args.cdr.cdr.car.to_s
6
8
  result = target.to_s.gsub to_remove, to_insert
7
9
 
8
10
  vm.push_arg Nydp::StringAtom.new result
9
11
  end
10
-
11
- def to_s
12
- "Builtin:string-replace"
13
- end
14
12
  end
@@ -1,5 +1,7 @@
1
1
  class Nydp::Builtin::StringSplit
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  target = args.car.to_s
4
6
  separator = args.cdr.car.to_s
5
7
  result = target.split separator
@@ -7,8 +9,4 @@ class Nydp::Builtin::StringSplit
7
9
 
8
10
  vm.push_arg Nydp::Pair.from_list list
9
11
  end
10
-
11
- def to_s
12
- "Builtin:string-split"
13
- end
14
12
  end
@@ -1,8 +1,11 @@
1
- class Nydp::Builtin::ToSym
1
+ class Nydp::Builtin::Sym
2
+ include Nydp::Builtin::Base
3
+
2
4
  def initialize ns
3
5
  @ns = ns
4
6
  end
5
- def invoke vm, args
7
+
8
+ def builtin_invoke vm, args
6
9
  arg = args.car
7
10
  val = case arg.class
8
11
  when Nydp::Symbol
@@ -1,7 +1,7 @@
1
1
  class Nydp::Builtin::ThreadLocals
2
- include Nydp::Helper
2
+ include Nydp::Helper, Nydp::Builtin::Base
3
3
 
4
- def invoke vm, args
4
+ def builtin_invoke vm, args
5
5
  vm.push_arg vm.locals
6
6
  end
7
7
  end
@@ -1,5 +1,7 @@
1
1
  class Nydp::Builtin::Times
2
- def invoke vm, args
2
+ include Nydp::Builtin::Base
3
+
4
+ def builtin_invoke vm, args
3
5
  vm.push_arg multiply(args, 1)
4
6
  end
5
7
 
@@ -10,4 +12,6 @@ class Nydp::Builtin::Times
10
12
  multiply(args.cdr, (accum * args.car))
11
13
  end
12
14
  end
15
+
16
+ def name ; "*" ; end
13
17
  end
@@ -1,25 +1,31 @@
1
- class Nydp::Builtin::ToString
2
- def invoke vm, args
3
- arg = args.car
4
- val = case arg.class
5
- when Nydp::StringAtom
6
- arg
7
- else
8
- Nydp::StringAtom.new arg.to_s
9
- end
10
- vm.push_arg val
1
+ module Nydp::Builtin
2
+ class ToString
3
+ include Nydp::Builtin::Base
4
+
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
14
+ end
11
15
  end
12
- end
13
16
 
14
- class Nydp::Builtin::StringLength
15
- def invoke vm, args
16
- arg = args.car
17
- val = case arg
18
- when Nydp::StringAtom
19
- arg.length
20
- else
21
- 0
22
- end
23
- vm.push_arg val
17
+ class StringLength
18
+ include Nydp::Builtin::Base
19
+
20
+ def builtin_invoke vm, args
21
+ arg = args.car
22
+ val = case arg
23
+ when Nydp::StringAtom
24
+ arg.length
25
+ else
26
+ 0
27
+ end
28
+ vm.push_arg val
29
+ end
24
30
  end
25
31
  end
@@ -1,7 +1,7 @@
1
1
  class Nydp::Builtin::Today
2
- include Nydp::Helper
2
+ include Nydp::Helper, Nydp::Builtin::Base
3
3
 
4
- def invoke vm, args
4
+ def builtin_invoke vm, args
5
5
  vm.push_arg(Nydp::Date.new Date.today)
6
6
  end
7
7
  end
@@ -1,9 +1,11 @@
1
1
  class Nydp::Builtin::TypeOf
2
+ include Nydp::Builtin::Base
3
+
2
4
  def initialize ns
3
5
  @ns = ns
4
6
  end
5
7
 
6
- def invoke vm, args
8
+ def builtin_invoke vm, args
7
9
  arg = args.car
8
10
  typename = if arg.respond_to?(:nydp_type)
9
11
  arg.nydp_type.to_sym
@@ -1,10 +1,12 @@
1
1
  class Nydp::Builtin::VmInfo
2
+ include Nydp::Builtin::Base
3
+
2
4
  VMINFO_NS = { }
3
5
  CONTEXTS = Nydp::Symbol.mk :contexts, VMINFO_NS
4
6
  INSTRUCTIONS = Nydp::Symbol.mk :instructions, VMINFO_NS
5
7
  ARGS = Nydp::Symbol.mk :args, VMINFO_NS
6
8
 
7
- def invoke vm, args
9
+ def builtin_invoke vm, args
8
10
  context_count = Nydp::Pair.new CONTEXTS, vm.contexts.size
9
11
  instruction_count = Nydp::Pair.new INSTRUCTIONS, vm.instructions.size
10
12
  arg_count = Nydp::Pair.new ARGS, vm.args.size
@@ -31,17 +31,17 @@ module Nydp
31
31
  Symbol.mk(:>, ns).assign(Nydp::Builtin::GreaterThan.new)
32
32
  Symbol.mk(:<, ns).assign(Nydp::Builtin::LessThan.new)
33
33
  Symbol.mk(:eval, ns).assign(Nydp::Builtin::Eval.new(ns))
34
+ Symbol.mk(:false, ns).assign(false)
34
35
  Symbol.mk(:hash, ns).assign(Nydp::Builtin::Hash.new)
35
36
  Symbol.mk(:apply, ns).assign(Nydp::Builtin::Apply.new)
36
37
  Symbol.mk(:error, ns).assign(Nydp::Builtin::Error.new)
37
- Symbol.mk(:quit, ns).assign(Nydp::Builtin::Quit.new)
38
38
  Symbol.mk(:parse, ns).assign(Nydp::Builtin::Parse.new(ns))
39
39
  Symbol.mk(:p, ns).assign(Nydp::Builtin::Puts.new)
40
40
  Symbol.mk(:PI, ns).assign Literal.new(3.1415)
41
41
  Symbol.mk(:nil, ns).assign Nydp.NIL
42
42
  Symbol.mk(:sqrt, ns).assign Nydp::Builtin::Sqrt.new
43
43
  Symbol.mk(:t, ns).assign Nydp.T
44
- Symbol.mk(:sym, ns).assign Nydp::Builtin::ToSym.new(ns)
44
+ Symbol.mk(:sym, ns).assign Nydp::Builtin::Sym.new(ns)
45
45
  Symbol.mk(:ensuring, ns).assign(Nydp::Builtin::Ensuring.new)
46
46
  Symbol.mk(:inspect, ns).assign(Nydp::Builtin::Inspect.new)
47
47
  Symbol.mk(:comment, ns).assign(Nydp::Builtin::Comment.new)
@@ -53,6 +53,7 @@ module Nydp
53
53
  Symbol.mk("to-string" , ns).assign(Nydp::Builtin::ToString.new)
54
54
  Symbol.mk("string-length" , ns).assign(Nydp::Builtin::StringLength.new)
55
55
  Symbol.mk("string-replace" , ns).assign(Nydp::Builtin::StringReplace.new)
56
+ Symbol.mk("string-match" , ns).assign(Nydp::Builtin::StringMatch.new(ns))
56
57
  Symbol.mk("string-split" , ns).assign(Nydp::Builtin::StringSplit.new )
57
58
  Symbol.mk("thread-locals" , ns).assign(Nydp::Builtin::ThreadLocals.new)
58
59
  Symbol.mk("type-of", ns).assign(Nydp::Builtin::TypeOf.new(ns))
@@ -1,6 +1,7 @@
1
1
  class Nydp::Hash < ::Hash
2
2
  include Nydp::Helper
3
3
 
4
+ def nydp_type ; :hash ; end
4
5
  def to_ruby
5
6
  @_ruby_hash ||= Hash.new { |h, k|
6
7
  self[case k
@@ -12,13 +12,9 @@ class Nydp::Symbol
12
12
  (str == "") || (str == nil) || (str =~ /\s/)
13
13
  end
14
14
 
15
- def is? nm
16
- self.name == nm.to_sym
17
- end
18
-
19
15
  def value context=nil
20
16
  raise "unbound symbol: #{self.inspect}" if @value == nil
21
- @value || Nydp.NIL
17
+ @value
22
18
  end
23
19
 
24
20
  def self.mk name, ns
@@ -33,9 +29,8 @@ class Nydp::Symbol
33
29
  sym
34
30
  end
35
31
 
36
- def self.find name, ns
37
- ns[name.to_sym]
38
- end
32
+
33
+ def self.find name, ns ; ns[name.to_sym] ; end
39
34
 
40
35
  def nydp_type ; :symbol ; end
41
36
  def inspect ; @inspection ; end
@@ -44,6 +39,8 @@ class Nydp::Symbol
44
39
  def to_ruby ; to_sym ; end
45
40
  def hash ; name.hash ; end
46
41
  def eql? other ; self == other ; end
42
+ def is? nm ; self.name == nm.to_sym ; end
43
+ def <=> other ; self.name <=> other.name ; end
47
44
 
48
45
  def == other
49
46
  other.is_a?(Nydp::Symbol) && (self.name == other.name)
@@ -84,7 +84,7 @@ module Nydp
84
84
  tok = [:sym_open_delim, open_sym]
85
85
  elsif list_prefix = s.scan(/[^\s()]*\(/)
86
86
  tok = [:left_paren, list_prefix[0...-1]]
87
- elsif list_prefix = s.scan(/[^\s()]*\{/)
87
+ elsif list_prefix = s.scan(/[^\s()\}\{]*\{/)
88
88
  tok = [:left_brace, list_prefix[0...-1]]
89
89
  elsif s.scan(/\)/)
90
90
  tok = [:right_paren]
@@ -1,3 +1,3 @@
1
1
  module Nydp
2
- VERSION = "0.0.10.1"
2
+ VERSION = "0.0.11"
3
3
  end
@@ -26,10 +26,18 @@ module Nydp
26
26
  handle_error e
27
27
  end
28
28
  end
29
- raise unhandled_error if unhandled_error
29
+ raise_unhandled_error
30
30
  pop_arg
31
31
  end
32
32
 
33
+ def raise_unhandled_error
34
+ if unhandled_error
35
+ e = unhandled_error
36
+ self.unhandled_error = nil
37
+ raise e
38
+ end
39
+ end
40
+
33
41
  def handle_error ex
34
42
  @unhandled_error = ex
35
43
 
@@ -102,4 +102,8 @@ describe Nydp::Parser do
102
102
  expect(actual).to eq expected
103
103
  end
104
104
 
105
+ it "parses a string that looks like html with little bits of embedded code in it" do
106
+ parsed = parse_string "<div id='item_~{id}'><label>~{data-label-1}</label> ~{data-content-1}</div>", '', :eof
107
+ expect(parsed.inspect).to eq '(string-pieces "<div id=\'item_" (brace-list id) "\'><label>" (brace-list data-label-1) "</label> " (brace-list data-content-1) "</div>")'
108
+ end
105
109
  end
@@ -14,6 +14,18 @@ describe Nydp::VM do
14
14
  proc = Proc.new { run "dflkjdgjeirgjeoi" }
15
15
  msg = "failed to eval dflkjdgjeirgjeoi\nerror was unbound symbol: dflkjdgjeirgjeoi"
16
16
  expect(proc).to raise_error RuntimeError, msg
17
+ expect(vm.unhandled_error).to eq nil
18
+ end
19
+
20
+ it "recovers quickly from an error" do
21
+ begin
22
+ run "dflkjdgjeirgjeoi"
23
+ rescue
24
+ end
25
+
26
+ expect(vm.unhandled_error).to eq nil
27
+
28
+ expect(run "(+ 2 3 4)").to eq 9
17
29
  end
18
30
  end
19
31
  end
@@ -18,4 +18,12 @@ describe Nydp::Literal do
18
18
  expect(Nydp.NIL.to_ruby).to eq nil
19
19
  end
20
20
  end
21
+
22
+ describe "false" do
23
+ it "is stored in toplevel namespace" do
24
+ Nydp::Core.new.setup ns
25
+ nydp_false = Nydp::Symbol.mk :false, ns
26
+ expect(nydp_false.value).to eq false
27
+ end
28
+ end
21
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nydp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10.1
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Conan Dalton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-25 00:00:00.000000000 Z
11
+ date: 2015-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -91,6 +91,7 @@ files:
91
91
  - lib/lisp/core-04-utils.nydp
92
92
  - lib/lisp/core-05-test-runner.nydp
93
93
  - lib/lisp/tests/boot-tests.nydp
94
+ - lib/lisp/tests/builtin-tests.nydp
94
95
  - lib/lisp/tests/dynamic-scope-test.nydp
95
96
  - lib/lisp/tests/error-tests.nydp
96
97
  - lib/lisp/tests/foundation-test.nydp
@@ -125,12 +126,13 @@ files:
125
126
  - lib/nydp/builtin/quit.rb
126
127
  - lib/nydp/builtin/random_string.rb
127
128
  - lib/nydp/builtin/sqrt.rb
129
+ - lib/nydp/builtin/string_match.rb
128
130
  - lib/nydp/builtin/string_replace.rb
129
131
  - lib/nydp/builtin/string_split.rb
132
+ - lib/nydp/builtin/sym.rb
130
133
  - lib/nydp/builtin/thread_locals.rb
131
134
  - lib/nydp/builtin/times.rb
132
135
  - lib/nydp/builtin/to_string.rb
133
- - lib/nydp/builtin/to_sym.rb
134
136
  - lib/nydp/builtin/today.rb
135
137
  - lib/nydp/builtin/type_of.rb
136
138
  - lib/nydp/builtin/vm_info.rb