nydp 0.5.1 → 0.6.0

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 (143) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/README.md +77 -56
  4. data/lib/lisp/core-000.nydp +1 -1
  5. data/lib/lisp/core-010-precompile.nydp +49 -29
  6. data/lib/lisp/core-012-utils.nydp +12 -8
  7. data/lib/lisp/core-015-documentation.nydp +41 -15
  8. data/lib/lisp/core-017-builtin-dox.nydp +621 -100
  9. data/lib/lisp/core-020-utils.nydp +33 -6
  10. data/lib/lisp/core-025-warnings.nydp +1 -1
  11. data/lib/lisp/core-030-syntax.nydp +64 -48
  12. data/lib/lisp/core-035-flow-control.nydp +20 -28
  13. data/lib/lisp/core-037-list-utils.nydp +84 -21
  14. data/lib/lisp/core-040-utils.nydp +8 -5
  15. data/lib/lisp/core-041-string-utils.nydp +17 -11
  16. data/lib/lisp/core-043-list-utils.nydp +140 -77
  17. data/lib/lisp/core-045-dox-utils.nydp +1 -0
  18. data/lib/lisp/core-050-test-runner.nydp +8 -12
  19. data/lib/lisp/core-070-prefix-list.nydp +19 -15
  20. data/lib/lisp/core-080-pretty-print.nydp +13 -5
  21. data/lib/lisp/core-090-hook.nydp +11 -11
  22. data/lib/lisp/core-100-utils.nydp +51 -66
  23. data/lib/lisp/core-110-hash-utils.nydp +34 -7
  24. data/lib/lisp/core-120-settings.nydp +14 -9
  25. data/lib/lisp/core-130-validations.nydp +28 -13
  26. data/lib/lisp/core-900-benchmarking.nydp +420 -47
  27. data/lib/lisp/tests/000-empty-args-examples.nydp +5 -0
  28. data/lib/lisp/tests/andify-examples.nydp +1 -1
  29. data/lib/lisp/tests/auto-hash-examples.nydp +6 -1
  30. data/lib/lisp/tests/best-examples.nydp +1 -1
  31. data/lib/lisp/tests/boot-tests.nydp +1 -1
  32. data/lib/lisp/tests/date-examples.nydp +129 -102
  33. data/lib/lisp/tests/destructuring-examples.nydp +1 -1
  34. data/lib/lisp/tests/dox-tests.nydp +2 -2
  35. data/lib/lisp/tests/hash-examples.nydp +58 -33
  36. data/lib/lisp/tests/list-tests.nydp +137 -1
  37. data/lib/lisp/tests/pretty-print-tests.nydp +12 -0
  38. data/lib/lisp/tests/rotate-2d-array-examples.nydp +26 -0
  39. data/lib/lisp/tests/sort-examples.nydp +5 -5
  40. data/lib/lisp/tests/string-tests.nydp +16 -5
  41. data/lib/lisp/tests/syntax-tests.nydp +10 -2
  42. data/lib/lisp/tests/time-examples.nydp +8 -1
  43. data/lib/lisp/tests/unparse-tests.nydp +13 -7
  44. data/lib/nydp/assignment.rb +15 -28
  45. data/lib/nydp/builtin/abs.rb +4 -3
  46. data/lib/nydp/builtin/apply.rb +8 -10
  47. data/lib/nydp/builtin/cdr_set.rb +1 -1
  48. data/lib/nydp/builtin/comment.rb +1 -3
  49. data/lib/nydp/builtin/date.rb +11 -28
  50. data/lib/nydp/builtin/divide.rb +3 -10
  51. data/lib/nydp/builtin/ensuring.rb +6 -21
  52. data/lib/nydp/builtin/error.rb +2 -4
  53. data/lib/nydp/builtin/eval.rb +9 -4
  54. data/lib/nydp/builtin/greater_than.rb +7 -8
  55. data/lib/nydp/builtin/handle_error.rb +10 -34
  56. data/lib/nydp/builtin/hash.rb +24 -45
  57. data/lib/nydp/builtin/inspect.rb +1 -3
  58. data/lib/nydp/builtin/is_equal.rb +4 -7
  59. data/lib/nydp/builtin/less_than.rb +6 -7
  60. data/lib/nydp/builtin/log.rb +7 -0
  61. data/lib/nydp/builtin/math_ceiling.rb +1 -3
  62. data/lib/nydp/builtin/math_floor.rb +1 -3
  63. data/lib/nydp/builtin/math_power.rb +1 -3
  64. data/lib/nydp/builtin/math_round.rb +2 -2
  65. data/lib/nydp/builtin/minus.rb +7 -14
  66. data/lib/nydp/builtin/parse.rb +5 -5
  67. data/lib/nydp/builtin/parse_in_string.rb +5 -7
  68. data/lib/nydp/builtin/plus.rb +14 -31
  69. data/lib/nydp/builtin/pre_compile.rb +1 -3
  70. data/lib/nydp/builtin/puts.rb +4 -8
  71. data/lib/nydp/builtin/quit.rb +1 -1
  72. data/lib/nydp/builtin/rand.rb +6 -11
  73. data/lib/nydp/builtin/random_string.rb +2 -4
  74. data/lib/nydp/builtin/rng.rb +25 -0
  75. data/lib/nydp/builtin/ruby_wrap.rb +27 -14
  76. data/lib/nydp/builtin/script_run.rb +1 -3
  77. data/lib/nydp/builtin/set_intersection.rb +3 -4
  78. data/lib/nydp/builtin/set_union.rb +3 -4
  79. data/lib/nydp/builtin/sort.rb +2 -7
  80. data/lib/nydp/builtin/string_match.rb +5 -13
  81. data/lib/nydp/builtin/string_replace.rb +2 -7
  82. data/lib/nydp/builtin/string_split.rb +3 -8
  83. data/lib/nydp/builtin/sym.rb +2 -9
  84. data/lib/nydp/builtin/thread_locals.rb +2 -2
  85. data/lib/nydp/builtin/time.rb +38 -44
  86. data/lib/nydp/builtin/times.rb +6 -15
  87. data/lib/nydp/builtin/to_integer.rb +8 -14
  88. data/lib/nydp/builtin/to_string.rb +2 -13
  89. data/lib/nydp/builtin/type_of.rb +10 -16
  90. data/lib/nydp/builtin/vm_info.rb +2 -10
  91. data/lib/nydp/builtin.rb +15 -37
  92. data/lib/nydp/compiler.rb +29 -19
  93. data/lib/nydp/cond.rb +95 -88
  94. data/lib/nydp/context_symbol.rb +11 -9
  95. data/lib/nydp/core.rb +74 -73
  96. data/lib/nydp/core_ext.rb +87 -26
  97. data/lib/nydp/date.rb +22 -19
  98. data/lib/nydp/error.rb +2 -3
  99. data/lib/nydp/function_invocation.rb +76 -289
  100. data/lib/nydp/helper.rb +18 -9
  101. data/lib/nydp/interpreted_function.rb +159 -25
  102. data/lib/nydp/lexical_context.rb +9 -8
  103. data/lib/nydp/lexical_context_builder.rb +1 -1
  104. data/lib/nydp/literal.rb +3 -7
  105. data/lib/nydp/loop.rb +72 -0
  106. data/lib/nydp/namespace.rb +52 -0
  107. data/lib/nydp/pair.rb +146 -50
  108. data/lib/nydp/parser.rb +9 -11
  109. data/lib/nydp/plugin.rb +88 -19
  110. data/lib/nydp/runner.rb +141 -23
  111. data/lib/nydp/symbol.rb +16 -26
  112. data/lib/nydp/symbol_lookup.rb +3 -2
  113. data/lib/nydp/tokeniser.rb +1 -1
  114. data/lib/nydp/truth.rb +2 -37
  115. data/lib/nydp/version.rb +1 -1
  116. data/lib/nydp.rb +33 -44
  117. data/nydp.gemspec +2 -1
  118. data/spec/date_spec.rb +26 -32
  119. data/spec/embedded_spec.rb +22 -22
  120. data/spec/error_spec.rb +12 -16
  121. data/spec/foreign_hash_spec.rb +21 -36
  122. data/spec/hash_non_hash_behaviour_spec.rb +12 -29
  123. data/spec/hash_spec.rb +36 -49
  124. data/spec/literal_spec.rb +6 -6
  125. data/spec/nydp_spec.rb +14 -14
  126. data/spec/pair_spec.rb +8 -8
  127. data/spec/parser_spec.rb +41 -37
  128. data/spec/rand_spec.rb +1 -4
  129. data/spec/spec_helper.rb +3 -3
  130. data/spec/string_atom_spec.rb +15 -16
  131. data/spec/symbol_spec.rb +27 -52
  132. data/spec/thread_local_spec.rb +23 -8
  133. data/spec/time_spec.rb +4 -10
  134. data/spec/tokeniser_spec.rb +10 -10
  135. metadata +25 -13
  136. data/lib/nydp/builtin/modulo.rb +0 -11
  137. data/lib/nydp/builtin/regexp.rb +0 -7
  138. data/lib/nydp/builtin/sqrt.rb +0 -7
  139. data/lib/nydp/builtin/string_pad_left.rb +0 -7
  140. data/lib/nydp/builtin/string_pad_right.rb +0 -7
  141. data/lib/nydp/hash.rb +0 -9
  142. data/lib/nydp/image_store.rb +0 -21
  143. data/lib/nydp/vm.rb +0 -129
data/lib/nydp/symbol.rb CHANGED
@@ -10,6 +10,7 @@ class Nydp::Symbol
10
10
  def initialize name
11
11
  name = name.to_s
12
12
  @name = name.to_sym
13
+ raise "cannot be symbol : #{name.inspect}" if @name == :nil || @name == :t
13
14
  @inspection = "|#{name.gsub(/\|/, '\|')}|" if untidy(name)
14
15
  end
15
16
 
@@ -20,19 +21,21 @@ class Nydp::Symbol
20
21
  end
21
22
 
22
23
  def value context=nil
23
- raise Unbound.new("unbound symbol: #{self.inspect}") if @value == nil
24
24
  @value
25
25
  end
26
26
 
27
- def self.special name
28
- return Nydp::NIL if name == :nil
29
- return Nydp::T if name == :t
30
- nil
27
+ def ruby_name
28
+ "ns_#{name.to_s._nydp_name_to_rb_name}"
29
+ end
30
+
31
+ def compile_to_ruby indent, src, opts=nil
32
+ "#{indent}ns.#{ruby_name}"
31
33
  end
32
34
 
33
- def self.mk name, ns
34
- name = name.to_s.to_sym
35
- ns[name] ||= new(name)
35
+ def self.special name
36
+ return nil if name == :nil
37
+ return true if name == :t
38
+ nil
36
39
  end
37
40
 
38
41
  def self.find name, ns ; ns[name.to_sym] ; end
@@ -47,7 +50,11 @@ class Nydp::Symbol
47
50
  def < other ; self.name < other.name ; end
48
51
  def <=> other ; self.name <=> other.name ; end
49
52
  def assign value, _=nil ; @value = value ; end
50
- def execute vm ; vm.push_arg self.value ; end
53
+
54
+ def ns_assign ns, value
55
+ value.is_named(@name) if value.respond_to?(:is_named)
56
+ ns.send(:"#{ruby_name}=", value)
57
+ end
51
58
 
52
59
  def == other
53
60
  other.is_a?(Nydp::Symbol) && (self.name == other.name)
@@ -55,20 +62,3 @@ class Nydp::Symbol
55
62
 
56
63
  alias eql? ==
57
64
  end
58
-
59
- class Nydp::FrozenSymbol < Nydp::Symbol
60
- @@frozen = { }
61
-
62
- def self.mk name
63
- name = name.to_s.to_sym
64
- @@frozen[name] ||= new(name)
65
- end
66
-
67
- def value _=nil
68
- raise Unbound.new("frozen symbol: #{self.inspect}")
69
- end
70
-
71
- def assign v, _=nil
72
- raise "can't assign to frozen: #{self.inspect}"
73
- end
74
- end
@@ -11,7 +11,7 @@ module Nydp
11
11
  bindings
12
12
  end
13
13
 
14
- def self.build name, original_bindings
14
+ def self.build name, original_bindings, ns
15
15
  effective_bindings = skip_empty original_bindings
16
16
  depth = 0
17
17
  while NIL != effective_bindings
@@ -24,7 +24,8 @@ module Nydp
24
24
  effective_bindings = skip_empty effective_bindings.cdr
25
25
  end
26
26
  end
27
- name
27
+
28
+ Nydp::Symbol.new name.to_s.to_sym
28
29
  end
29
30
  end
30
31
  end
@@ -89,7 +89,7 @@ module Nydp
89
89
  @finished = true
90
90
  return nil
91
91
  elsif comment = s.scan(COMMENT)
92
- tok = [:comment, comment.gsub(/^;;?\s*/, '').strip]
92
+ tok = [:comment, comment.gsub(/^;;?\s?/, '')]
93
93
  elsif open_str = s.scan(QUOTE)
94
94
  tok = [:string_open_delim, open_str]
95
95
  elsif open_sym = s.scan(PIPE)
data/lib/nydp/truth.rb CHANGED
@@ -1,41 +1,6 @@
1
1
  require 'singleton'
2
2
 
3
3
  module Nydp
4
- class Truth
5
- include Singleton
6
- def init_with *; Nydp::T ; end
7
- def to_s ; 't' ; end
8
- def inspect ; 't' ; end
9
- def assign *_ ; self ; end
10
- def nydp_type ; :truth ; end
11
- def to_ruby ; true ; end
12
- def _nydp_get a ; Nydp::T ; end
13
- def _nydp_set a, v ; Nydp::T ; end
14
- end
15
-
16
- class Nil
17
- include Singleton, Enumerable
18
- def init_with * ; Nydp::NIL ; end
19
- def car ; self ; end
20
- def cdr ; self ; end
21
- def size ; 0 ; end
22
- def is? other ; self.equal? other ; end
23
- def isnt? other ; !self.equal? other ; end
24
- def to_s ; "" ; end
25
- def + other ; other ; end
26
- def copy ; self ; end
27
- def assign *_ ; self ; end
28
- def inspect ; "nil" ; end
29
- def nydp_type ; :nil ; end
30
- def to_ruby ; nil ; end
31
- def execute vm ; vm.push_arg self ; end
32
- def _nydp_get a ; Nydp::NIL ; end
33
- def _nydp_set a, v ; Nydp::NIL ; end
34
- def each ; ; end # nil behaves like an empty list
35
- def & other ; self ; end
36
- def | other ; other ; end
37
- end
38
-
39
- NIL = Nil.instance
40
- T = Truth.instance
4
+ NIL = nil
5
+ T = true
41
6
  end
data/lib/nydp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Nydp
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end
data/lib/nydp.rb CHANGED
@@ -2,30 +2,19 @@ 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
-
9
- class Namespace < Hash
10
- end
5
+ GENERATED_CLASS_PREFIX = "NydpGenerated"
11
6
 
12
- # TODO: write VM #apply_function so we have fewer calls to VM.new
13
- def self.apply_function ns, function_name, *args
14
- vm = VM.new(ns)
15
- function = Symbol.mk(function_name.to_sym, ns).value
16
- function.invoke vm, r2n(args)
17
- vm.thread
18
- rescue StandardError => e
19
- friendly_args = args.map { |a| a.respond_to?(:_nydp_compact_inspect) ? a._nydp_compact_inspect : a }
20
- raise Nydp::Error.new("Invoking #{function_name}\nwith args #{friendly_args.inspect}")
7
+ class << self
8
+ attr_accessor :logger # set this if you plan on using 'log
21
9
  end
22
10
 
23
- def self.reader txt ; Nydp::StringReader.new txt ; end
24
- def self.eval_src ns, src_txt, name=nil ; eval_with Nydp::Runner, ns, src_txt, name ; end
25
- def self.eval_with runner, ns, src_txt, name ; runner.new(VM.new(ns), ns, reader(src_txt), nil, name).run ; end
26
- def self.ms t1, t0 ; ((t1 - t0) * 1000).to_i ; end
27
- def self.new_tokeniser reader ; Nydp::Tokeniser.new reader ; end
28
- def self.new_parser ns ; Nydp::Parser.new(ns) ; end
11
+ def self.apply_function ns, name, *args ; ns.apply name, *args ; end
12
+ def self.reader name, txt ; Nydp::StringReader.new name, txt ; end
13
+ def self.eval_src ns, src_txt, name=nil ; eval_with Nydp::Runner, ns, src_txt, name ; end
14
+ def self.eval_with runner, ns, src_txt, name ; runner.new(ns, reader(name, src_txt), nil, name).run ; end
15
+ def self.ms t1, t0 ; ((t1 - t0) * 1000).to_i ; end
16
+ def self.new_tokeniser reader ; Nydp::Tokeniser.new reader ; end
17
+ def self.new_parser ; Nydp::Parser.new ; end
29
18
 
30
19
  def self.indent_message indent, msg
31
20
  msg.split(/\n/).map { |line| "#{indent}#{line}" }.join("\n")
@@ -39,7 +28,7 @@ module Nydp
39
28
  puts "\n#{indent}Caused by:"
40
29
  handle_run_error e.cause, "#{indent} "
41
30
  else
42
- e.backtrace.each do |b|
31
+ Nydp.enhance_backtrace(e.backtrace).each do |b|
43
32
  puts "#{indent}#{b}"
44
33
  end
45
34
  end
@@ -54,34 +43,34 @@ module Nydp
54
43
  end
55
44
 
56
45
  def self.repl options={ }
57
- toplevel do
58
- launch_time = Time.now
59
- silent = options.delete :silent
60
- ns = options.delete :ns
61
- last_script_time = Time.now
62
- puts "welcome to nydp #{options.inspect}" unless silent
63
- reader = Nydp::ReadlineReader.new $stdin, "nydp > "
64
- ns ||= build_nydp do |script|
65
- this_script_time = Time.now
66
- puts "script #{script} time #{ms this_script_time, last_script_time}ms" if options[:verbose]
67
- last_script_time = this_script_time
46
+ launch_time = Time.now
47
+ silent = options.delete :silent
48
+ ns = options.delete :ns
49
+ last_script_time = Time.now
50
+ puts "welcome to nydp #{options.inspect}" unless silent
51
+ reader = Nydp::ReadlineReader.new $stdin, "nydp > "
52
+ ns ||= build_nydp do |script|
53
+ this_script_time = Time.now
54
+ puts "script #{script} time #{ms this_script_time, last_script_time}ms" if options[:verbose]
55
+ last_script_time = this_script_time
56
+ end
57
+ load_time = Time.now
58
+ puts "nydp v#{Nydp::VERSION} repl ready in #{ms(load_time, launch_time)}ms" unless silent
59
+ puts "^D to exit" unless silent
60
+ while !options[:exit]
61
+ toplevel do
62
+ Nydp::Runner.new(ns, reader, $stdout, "<stdin>").run
63
+ options[:exit] = true
68
64
  end
69
- load_time = Time.now
70
- puts "nydp v#{Nydp::VERSION} repl ready in #{ms(load_time, launch_time)}ms" unless silent
71
- puts "^D to exit" unless silent
72
- return if options[:exit]
73
- Nydp::Runner.new(VM.new(ns), ns, reader, $stdout, "<stdin>").run
74
- # Nydp::Invocation.whazzup
75
65
  end
66
+ # Nydp::Invocation.whazzup
76
67
  end
77
68
 
78
69
  def self.tests *options
79
70
  toplevel do
80
- verbose = options.include?(:verbose) ? "t" : "nil"
71
+ verbose = options.include?(:verbose) ? true : nil
81
72
  puts "welcome to nydp : running tests"
82
- reader = Nydp::StringReader.new "(run-all-tests #{verbose})"
83
- ns = build_nydp
84
- Nydp::Runner.new(VM.new(ns), ns, reader, nil, "<test-runner>").run
73
+ build_nydp.apply :"run-all-tests", verbose
85
74
  end
86
75
  end
87
76
  end
@@ -105,4 +94,4 @@ require "nydp/string_token"
105
94
  require "nydp/tokeniser"
106
95
  require "nydp/parser"
107
96
  require "nydp/compiler"
108
- require "nydp/vm"
97
+ require "nydp/namespace"
data/nydp.gemspec CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "rake", "~> 12"
21
+ spec.add_development_dependency "irb"
22
+ spec.add_development_dependency "rake", "~> 13"
22
23
  spec.add_development_dependency 'rspec' #, '~> 3.1'
23
24
  end
data/spec/date_spec.rb CHANGED
@@ -2,33 +2,29 @@ require 'spec_helper'
2
2
 
3
3
  describe Nydp::Date do
4
4
 
5
- let(:ns) { { } }
6
- let(:vm) { Nydp::VM.new(ns) }
7
5
 
8
6
  it "converts ruby Date to Nydp::Date" do
9
7
  rd = Date.parse "2015-06-08"
10
8
  nd = Nydp.r2n rd
11
9
 
12
- expect(nd). to be_a Nydp::Date
10
+ expect(nd). to be_a ::Date
13
11
  expect(nd.to_s). to eq "2015-06-08"
14
- expect(nd.inspect).to eq "#<Date: 2015-06-08 ((2457182j,0s,0n),+0s,2299161j)>"
12
+ expect(nd._nydp_inspect).to eq "#<Date: 2015-06-08 ((2457182j,0s,0n),+0s,2299161j)>"
15
13
  expect(nd.to_ruby).to eq Date.parse("2015-06-08")
16
14
  end
17
15
 
18
16
  it "creates a new date" do
19
17
  df = Nydp::Builtin::Date.instance
20
- df.invoke_4 vm, 2015, 11, 18
21
- nd = vm.args.pop
22
- expect(nd).to be_a Nydp::Date
23
- expect(nd.ruby_date).to eq Date.parse("2015-11-18")
18
+ nd = df.call 2015, 11, 18
19
+ expect(nd).to be_a ::Date
20
+ expect(nd).to eq Date.parse("2015-11-18")
24
21
  end
25
22
 
26
23
  it "returns today" do
27
24
  df = Nydp::Builtin::Date.instance
28
- df.invoke_1 vm
29
- nd = vm.args.pop
30
- expect(nd).to be_a Nydp::Date
31
- expect(nd.ruby_date).to eq Date.today
25
+ nd = df.call
26
+ expect(nd).to be_a ::Date
27
+ expect(nd).to eq Date.today
32
28
  end
33
29
 
34
30
  it "returns date components" do
@@ -47,10 +43,9 @@ describe Nydp::Date do
47
43
  it "works with builtin minus" do
48
44
  minus = Nydp::Builtin::Minus.instance
49
45
 
50
- minus.invoke vm, pair_list([d1, d0])
51
- diff = vm.args.pop
46
+ diff = minus.call d1, d0
52
47
 
53
- expect(d0).to be_a Nydp::Date
48
+ expect(d0).to be_a ::Date
54
49
  expect(diff).to eq 6
55
50
  end
56
51
 
@@ -58,25 +53,25 @@ describe Nydp::Date do
58
53
  it "works with builtin greater-than when true" do
59
54
  f = Nydp::Builtin::GreaterThan.instance
60
55
 
61
- f.invoke vm, pair_list([d1, d0])
56
+ a = f.call d1, d0
62
57
 
63
- expect(vm.args.pop).to eq d0
58
+ expect(a).to eq d0
64
59
  end
65
60
 
66
61
  it "compares with nil" do
67
62
  f = Nydp::Builtin::GreaterThan.instance
68
63
 
69
- f.invoke vm, pair_list([d1, Nydp::NIL])
64
+ a = f.call d1, nil
70
65
 
71
- expect(vm.args.pop).to eq Nydp::NIL
66
+ expect(a).to eq Nydp::NIL
72
67
  end
73
68
 
74
69
  it "works with builtin greater-than when false" do
75
70
  f = Nydp::Builtin::GreaterThan.instance
76
71
 
77
- f.invoke vm, pair_list([d0, d1])
72
+ a = f.call d0, d1
78
73
 
79
- expect(vm.args.pop).to eq Nydp::NIL
74
+ expect(a).to eq Nydp::NIL
80
75
  end
81
76
  end
82
77
 
@@ -84,37 +79,36 @@ describe Nydp::Date do
84
79
  it "works with builtin less-than when true" do
85
80
  f = Nydp::Builtin::LessThan.instance
86
81
 
87
- f.invoke vm, pair_list([d0, d1])
82
+ a = f.call d0, d1
88
83
 
89
- expect(vm.args.pop).to eq d1
84
+ expect(a).to eq d1
90
85
  end
91
86
 
92
87
  it "works with builtin less-than when false" do
93
88
  f = Nydp::Builtin::LessThan.instance
94
89
 
95
- f.invoke vm, pair_list([d1, d0])
90
+ a = f.call d1, d0
96
91
 
97
- expect(vm.args.pop).to eq Nydp::NIL
92
+ expect(a).to eq Nydp::NIL
98
93
  end
99
94
 
100
95
  it "compares with nil" do
101
96
  f = Nydp::Builtin::LessThan.instance
102
97
 
103
- f.invoke vm, pair_list([d1, Nydp::NIL])
98
+ a = f.call d1, nil
104
99
 
105
- expect(vm.args.pop).to eq Nydp::NIL
100
+ expect(a).to eq Nydp::NIL
106
101
  end
107
102
  end
108
103
 
109
104
  it "works with builtin plus" do
110
105
  plus = Nydp::Builtin::Plus.instance
111
106
 
112
- plus.invoke vm, pair_list([d0, 5])
113
- sum = vm.args.pop
107
+ sum = plus.call d0, 5
114
108
 
115
- expect(d0) .to be_a Nydp::Date
116
- expect(sum).to be_a Nydp::Date
117
- expect(sum.ruby_date).to eq(Date.today + 5)
109
+ expect(d0) .to be_a ::Date
110
+ expect(sum).to be_a ::Date
111
+ expect(sum).to eq(Date.today + 5)
118
112
  end
119
113
  end
120
114
 
@@ -1,27 +1,27 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Nydp::Parser do
4
- let(:aa) { Nydp::Symbol.mk :aa, ns }
5
- let(:a) { Nydp::Symbol.mk :a, ns }
6
- let(:b) { Nydp::Symbol.mk :b, ns }
7
- let(:c) { Nydp::Symbol.mk :c, ns }
8
- let(:d) { Nydp::Symbol.mk :d, ns }
9
- let(:zz) { Nydp::Symbol.mk :zz, ns }
10
- let(:foo) { Nydp::Symbol.mk :foo, ns }
11
- let(:bar) { Nydp::Symbol.mk :bar, ns }
12
- let(:zab) { Nydp::Symbol.mk :zab, ns }
13
- let(:quote) { Nydp::Symbol.mk :quote, ns }
14
- let(:quasiquote) { Nydp::Symbol.mk :quasiquote, ns }
15
- let(:unquote) { Nydp::Symbol.mk :unquote, ns }
16
- let(:unquote_splicing) { Nydp::Symbol.mk :"unquote-splicing", ns }
17
- let(:comment) { Nydp::Symbol.mk :comment, ns }
18
- let(:dotsyn) { Nydp::Symbol.mk :"dot-syntax", ns }
19
- let(:cocosyn) { Nydp::Symbol.mk :"colon-colon-syntax", ns }
20
- let(:colosyn) { Nydp::Symbol.mk :"colon-syntax", ns }
4
+ let(:aa) { :aa }
5
+ let(:a) { :a }
6
+ let(:b) { :b }
7
+ let(:c) { :c }
8
+ let(:d) { :d }
9
+ let(:zz) { :zz }
10
+ let(:foo) { :foo }
11
+ let(:bar) { :bar }
12
+ let(:zab) { :zab }
13
+ let(:quote) { :quote }
14
+ let(:quasiquote) { :quasiquote }
15
+ let(:unquote) { :unquote }
16
+ let(:unquote_splicing) { :"unquote-splicing" }
17
+ let(:comment) { :comment }
18
+ let(:dotsyn) { :"dot-syntax" }
19
+ let(:cocosyn) { :"colon-colon-syntax" }
20
+ let(:colosyn) { :"colon-syntax" }
21
21
 
22
22
  def parse_string txt
23
- reader = Nydp::StringReader.new txt
24
- Nydp.new_parser(ns).embedded(Nydp.new_tokeniser(reader))
23
+ reader = Nydp::StringReader.new "test", txt
24
+ Nydp.new_parser.embedded(Nydp.new_tokeniser(reader))
25
25
  end
26
26
 
27
27
  it "should parse empty string" do
@@ -33,14 +33,14 @@ describe Nydp::Parser do
33
33
  it "should parse external text" do
34
34
  actual = parse_string "a fluffy bunny!"
35
35
  expect(actual) .to eq "a fluffy bunny!"
36
- expect(actual.inspect).to eq '"a fluffy bunny!"'
36
+ expect(actual._nydp_inspect).to eq '"a fluffy bunny!"'
37
37
  end
38
38
 
39
39
  it "should parse a string delimited by eof" do
40
40
  expected = pair_list([sym('string-pieces'), Nydp::StringFragmentCloseToken.new('a fluffy bunny!','a fluffy bunny!')])
41
41
  actual = parse_string "a fluffy bunny!"
42
42
  expect(actual) .to eq "a fluffy bunny!"
43
- expect(actual.inspect).to eq '"a fluffy bunny!"'
43
+ expect(actual._nydp_inspect).to eq '"a fluffy bunny!"'
44
44
  end
45
45
 
46
46
  it "should parse a string with embedded code, delimited by eof" do
@@ -104,6 +104,6 @@ describe Nydp::Parser do
104
104
 
105
105
  it "parses a string that looks like html with little bits of embedded code in it" do
106
106
  parsed = parse_string "<div id='item_~{id}'><label>~{data-label-1}</label> ~{data-content-1}</div>"
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>")'
107
+ expect(parsed._nydp_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
108
  end
109
109
  end
data/spec/error_spec.rb CHANGED
@@ -1,40 +1,36 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Nydp::VM do
4
- let(:ns) { { } }
5
- let(:vm) { Nydp::VM.new(ns) }
3
+ describe Nydp do
6
4
 
7
5
  def run txt
8
6
  Nydp.setup ns
9
- Nydp::Runner.new(vm, ns, Nydp::StringReader.new(txt)).run
7
+ Nydp::Runner.new(ns, Nydp::StringReader.new("test", txt)).run
10
8
  end
11
9
 
12
10
  describe "unhandled_error" do
13
11
  it "raises a helpful error" do
14
12
  error = nil
15
13
  begin
16
- run "dflkjdgjeirgjeoi"
14
+ run "(/ 10 0)"
17
15
  rescue StandardError => e
18
16
  error = e
19
17
  end
20
18
 
21
19
  expect(error).to be_a Nydp::Error
22
- expect(error.message).to eq "failed to eval dflkjdgjeirgjeoi"
20
+ expect(error.message).to eq "failed to eval (/ 10 0) from src (/ 10 0)"
23
21
 
24
- expect(error.cause).to be_a Nydp::Symbol::Unbound
25
- expect(error.cause.message).to eq "unbound symbol: dflkjdgjeirgjeoi"
22
+ expect(error.cause).to be_a RuntimeError
23
+ expect(error.cause.message).to eq "Called builtin//
24
+ with args
25
+ 10
26
+ 0"
26
27
 
27
- expect(vm.unhandled_error).to eq nil
28
+ expect(error.cause.cause).to be_a ZeroDivisionError
29
+ expect(error.cause.cause.message).to eq "divided by 0"
28
30
  end
29
31
 
30
32
  it "recovers quickly from an error" do
31
- begin
32
- run "dflkjdgjeirgjeoi"
33
- rescue
34
- end
35
-
36
- expect(vm.unhandled_error).to eq nil
37
-
33
+ run "dflkjdgjeirgjeoi"
38
34
  expect(run "(+ 2 3 4)").to eq 9
39
35
  end
40
36
  end
@@ -1,75 +1,61 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Nydp::Hash do
4
- let(:vm) { Nydp::VM.new(ns) }
3
+ describe ::Hash do
5
4
 
6
5
  describe "foreign hashes" do
7
6
  let(:ahash) { Hash.new }
8
7
 
9
8
  describe "hash set" do
10
9
  it "returns a new Nydp hash" do
11
- k = Nydp::Symbol.mk "keysym", ns
10
+ k = :keysym
12
11
  v = "foobar"
13
- args = pair_list [ahash, k, v]
14
- Nydp::Builtin::HashSet.instance.invoke vm, args
12
+ a = Nydp::Builtin::HashSet.instance.call ahash, k, v
15
13
 
16
14
  expect(ahash[:keysym]). to eq "foobar"
17
15
  expect(ahash[:keysym].class).to eq String
18
16
  expect(ahash.keys). to eq [:keysym]
19
17
 
20
- expect(vm.args.pop).to eq v
18
+ expect(a).to eq v
21
19
  end
22
20
  end
23
21
 
24
22
  describe "hash get" do
25
23
  it "converts ruby value to nydp value" do
26
24
  ahash[:keysym] = "avalue"
27
- k = sym("keysym")
28
- args = [ ahash, k ]
29
25
 
30
- Nydp::Builtin::HashGet.instance.invoke vm, pair_list(args)
26
+ a = Nydp::Builtin::HashGet.instance.call ahash, :keysym
31
27
 
32
- expect(vm.args.pop).to eq "avalue"
28
+ expect(a).to eq "avalue"
33
29
  end
34
30
 
35
31
  it "converts ruby nil to nydp value" do
36
- k = sym("keysym")
37
- args = [ ahash, k ]
32
+ a = Nydp::Builtin::HashGet.instance.call ahash, :keysym
38
33
 
39
- Nydp::Builtin::HashGet.instance.invoke vm, pair_list(args)
40
-
41
- expect(vm.args.pop).to eq Nydp::NIL
34
+ expect(a).to eq nil
42
35
  end
43
36
 
44
37
  it "converts ruby true to nydp value" do
45
38
  ahash[:keysym] = true
46
- k = sym("keysym")
47
- args = [ ahash, k ]
48
39
 
49
- Nydp::Builtin::HashGet.instance.invoke vm, pair_list(args)
40
+ a = Nydp::Builtin::HashGet.instance.call ahash, :keysym
50
41
 
51
- expect(vm.args.pop).to eq Nydp::T
42
+ expect(a).to eq true
52
43
  end
53
44
  end
54
45
 
55
46
  describe "key?" do
56
47
  it "returns t when key is present" do
57
48
  ahash[:simon] = 24
58
- k = sym("simon")
59
- args = [ ahash, k ]
60
49
 
61
- Nydp::Builtin::HashKeyPresent.instance.invoke vm, pair_list(args)
50
+ a = Nydp::Builtin::HashKeyPresent.instance.call ahash, :simon
62
51
 
63
- expect(vm.args.pop).to eq Nydp::T
52
+ expect(a).to eq true
64
53
  end
65
54
 
66
55
  it "returns nil when key is absent" do
67
- k = sym("simon")
68
- args = [ ahash, k ]
69
-
70
- Nydp::Builtin::HashKeyPresent.instance.invoke vm, pair_list(args)
56
+ a = Nydp::Builtin::HashKeyPresent.instance.call ahash, :simon
71
57
 
72
- expect(vm.args.pop).to eq Nydp::NIL
58
+ expect(a).to eq nil
73
59
  end
74
60
  end
75
61
 
@@ -77,23 +63,22 @@ describe Nydp::Hash do
77
63
  it "returns a list of keys" do
78
64
  ahash[:k0] = 42
79
65
  ahash[:k1] = 84
80
- args = [ahash]
81
66
 
82
- Nydp::Builtin::HashKeys.instance.invoke vm, pair_list(args)
67
+ a = Nydp::Builtin::HashKeys.instance.call ahash
83
68
 
84
- expect(vm.args.pop).to eq pair_list [sym("k0"), sym("k1")]
69
+ expect(a).to eq pair_list [:k0, :k1]
85
70
  end
86
71
  end
87
72
 
88
73
  describe "hash-slice" do
89
74
  it "returns a new hash containing only the given keys from the old hash" do
90
- ahash[:k0] = 42
91
- ahash[:k1] = 84
92
- args = [ahash, pair_list([sym("k0"), sym("k1")])]
75
+ ahash[:k0] = 42
76
+ ahash[:k1] = 84
77
+ ahash[:k2] = 126
93
78
 
94
- Nydp::Builtin::HashSlice.instance.invoke vm, pair_list(args)
79
+ a = Nydp::Builtin::HashSlice.instance.call ahash, pair_list([:k0, :k1])
95
80
 
96
- expect(vm.args.pop).to eq({ k0: 42, k1: 84 })
81
+ expect(a).to eq({ k0: 42, k1: 84 })
97
82
  end
98
83
  end
99
84
  end