nydp 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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 +30 -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 +88 -24
  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.0"
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