nydp 0.0.10.1 → 0.0.11

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 (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