nydp 0.2.3 → 0.2.5

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/bin/nydp +1 -1
  3. data/lib/lisp/core-000.nydp +1 -0
  4. data/lib/lisp/core-010-precompile.nydp +15 -15
  5. data/lib/lisp/core-012-utils.nydp +6 -5
  6. data/lib/lisp/core-020-utils.nydp +20 -6
  7. data/lib/lisp/core-030-syntax.nydp +14 -16
  8. data/lib/lisp/core-035-flow-control.nydp +26 -8
  9. data/lib/lisp/core-040-utils.nydp +4 -15
  10. data/lib/lisp/core-041-string-utils.nydp +3 -3
  11. data/lib/lisp/core-043-list-utils.nydp +81 -16
  12. data/lib/lisp/core-045-dox-utils.nydp +2 -2
  13. data/lib/lisp/core-060-benchmarking.nydp +92 -27
  14. data/lib/lisp/tests/all-examples.nydp +20 -0
  15. data/lib/lisp/tests/any-examples.nydp +28 -0
  16. data/lib/lisp/tests/builtin-tests.nydp +3 -1
  17. data/lib/lisp/tests/collect-tests.nydp +10 -0
  18. data/lib/lisp/tests/curry-tests.nydp +7 -2
  19. data/lib/lisp/tests/error-tests.nydp +11 -0
  20. data/lib/lisp/tests/foundation-test.nydp +66 -0
  21. data/lib/lisp/tests/len-examples.nydp +1 -0
  22. data/lib/lisp/tests/list-gsub-examples.nydp +25 -0
  23. data/lib/lisp/tests/list-match-examples.nydp +40 -0
  24. data/lib/lisp/tests/list-tests.nydp +13 -0
  25. data/lib/lisp/tests/none-examples.nydp +16 -0
  26. data/lib/lisp/tests/parser-tests.nydp +4 -5
  27. data/lib/lisp/tests/quasiquote-examples.nydp +2 -0
  28. data/lib/lisp/tests/syntax-tests.nydp +3 -2
  29. data/lib/lisp/tests/tuples-examples.nydp +2 -2
  30. data/lib/nydp.rb +50 -18
  31. data/lib/nydp/assignment.rb +3 -1
  32. data/lib/nydp/builtin.rb +15 -13
  33. data/lib/nydp/builtin/error.rb +1 -1
  34. data/lib/nydp/builtin/handle_error.rb +8 -2
  35. data/lib/nydp/builtin/parse_in_string.rb +1 -1
  36. data/lib/nydp/builtin/plus.rb +4 -4
  37. data/lib/nydp/closure.rb +5 -1
  38. data/lib/nydp/compiler.rb +2 -3
  39. data/lib/nydp/cond.rb +134 -13
  40. data/lib/nydp/context_symbol.rb +4 -1
  41. data/lib/nydp/error.rb +8 -0
  42. data/lib/nydp/function_invocation.rb +46 -48
  43. data/lib/nydp/helper.rb +15 -0
  44. data/lib/nydp/interpreted_function.rb +10 -14
  45. data/lib/nydp/lexical_context.rb +13 -2
  46. data/lib/nydp/lexical_context_builder.rb +28 -13
  47. data/lib/nydp/pair.rb +35 -36
  48. data/lib/nydp/parser.rb +3 -0
  49. data/lib/nydp/runner.rb +4 -32
  50. data/lib/nydp/string_atom.rb +3 -2
  51. data/lib/nydp/symbol.rb +1 -1
  52. data/lib/nydp/symbol_lookup.rb +9 -1
  53. data/lib/nydp/truth.rb +1 -1
  54. data/lib/nydp/version.rb +1 -1
  55. data/lib/nydp/vm.rb +2 -2
  56. data/nydp.gemspec +1 -1
  57. data/spec/error_spec.rb +14 -4
  58. data/spec/hash_non_hash_behaviour_spec.rb +19 -12
  59. data/spec/hash_spec.rb +0 -13
  60. data/spec/pair_spec.rb +17 -3
  61. data/spec/spec_helper.rb +13 -1
  62. data/spec/symbol_spec.rb +1 -1
  63. metadata +9 -4
@@ -8,21 +8,32 @@ class Nydp::Pair
8
8
  @car, @cdr = car, cdr
9
9
  end
10
10
 
11
- def nydp_type ; :pair ; end
12
- def caar ; car.car ; end
13
- def cadr ; cdr.car ; end
14
- def cdar ; car.cdr ; end
15
- def cddr ; cdr.cdr ; end
16
- def car= thing ; @car = thing ; @_hash = nil ; end
17
- def cdr= thing ; @cdr = thing ; @_hash = nil ; end
18
- def hash ; @_hash ||= (car.hash + cdr.hash) ; end
19
- def eql? other ; self == other ; end
20
-
11
+ def nydp_type ; :pair ; end
12
+ def caar ; car.car ; end
13
+ def cadr ; cdr.car ; end
14
+ def cdar ; car.cdr ; end
15
+ def cddr ; cdr.cdr ; end
16
+ def car= thing ; @car = thing ; @_hash = nil ; end
17
+ def cdr= thing ; @cdr = thing ; @_hash = nil ; end
18
+ def hash ; @_hash ||= (car.hash + cdr.hash) ; end
19
+ def eql? other ; self == other ; end
20
+ def copy ; cons(car, cdr.copy) ; end
21
+ def + other ; copy.append other ; end
22
+ def size ; 1 + (cdr.is_a?(Nydp::Pair) ? cdr.size : 0) ; end
23
+ def inspect ; "(#{inspect_rest})" ; end
24
+
25
+ # returns Array of elements after calling #n2r on each element
21
26
  def to_ruby list=[]
22
27
  list << n2r(car)
23
28
  cdr.is_a?(Nydp::Pair) ? cdr.to_ruby(list) : list
24
29
  end
25
30
 
31
+ # returns Array of elements as they are
32
+ def to_a list=[]
33
+ list << car
34
+ cdr.is_a?(Nydp::Pair) ? cdr.to_a(list) : list
35
+ end
36
+
26
37
  def self.parse_list list
27
38
  if sym? list.slice(-2), "."
28
39
  from_list(list[0...-2], list.slice(-1))
@@ -39,20 +50,8 @@ class Nydp::Pair
39
50
  end
40
51
  end
41
52
 
42
- def copy
43
- cons(car, cdr.copy)
44
- end
45
-
46
- def + other
47
- copy.append other
48
- end
49
-
50
53
  def == other
51
- (other.respond_to? :car) && (self.car == other.car) && (self.cdr == other.cdr)
52
- end
53
-
54
- def size
55
- 1 + (cdr.is_a?(Nydp::Pair) ? cdr.size : 0)
54
+ Nydp::NIL.isnt?(other) && (other.respond_to? :car) && (self.car == other.car) && (self.cdr == other.cdr)
56
55
  end
57
56
 
58
57
  def proper?
@@ -64,10 +63,6 @@ class Nydp::Pair
64
63
  cdr.each(&block) unless Nydp::NIL.is?(cdr)
65
64
  end
66
65
 
67
- def inspect
68
- "(#{inspect_rest})"
69
- end
70
-
71
66
  def to_s
72
67
  if car.is_a?(Nydp::Symbol) && car.is?(:quote)
73
68
  if Nydp::NIL.is? cdr.cdr
@@ -117,15 +112,19 @@ class Nydp::Pair
117
112
  end
118
113
 
119
114
  def inspect_rest
120
- cdr_s = if cdr.is_a?(self.class)
121
- cdr.inspect_rest
122
- elsif cdr == Nydp::NIL
123
- nil
124
- else
125
- ". #{cdr.inspect}"
126
- end
127
-
128
- [car.inspect, cdr_s].compact.join " "
115
+ res = [car.inspect]
116
+ it = cdr
117
+ while it && it != Nydp::NIL
118
+ if it.is_a?(self.class)
119
+ res << it.car.inspect
120
+ it = it.cdr
121
+ else
122
+ res << "."
123
+ res << it.inspect
124
+ it = nil
125
+ end
126
+ end
127
+ res.compact.join " "
129
128
  end
130
129
 
131
130
  def append thing
@@ -4,6 +4,9 @@ module Nydp
4
4
 
5
5
  def initialize ns
6
6
  @ns = ns
7
+ # TODO pre-initialize all the hard-coded syms used here, eg
8
+ # @quote = sym(:quote)
9
+ # @quasiquote = sym(:quasiquote)
7
10
  end
8
11
 
9
12
  def sym name
@@ -50,22 +50,13 @@ module Nydp
50
50
  def compile_and_eval expr
51
51
  begin
52
52
  vm.thread Pair.new(Compiler.compile(expr, Nydp::NIL), Nydp::NIL)
53
- rescue Exception => e
54
- new_msg = "failed to eval #{expr.inspect}\nerror was #{Nydp.indent_text e.message}"
55
- raise e.class, new_msg, e.backtrace
53
+ rescue StandardError => e
54
+ raise Nydp::Error, "failed to eval #{expr.inspect}"
56
55
  end
57
56
  end
58
57
 
59
- def quote expr
60
- Pair.from_list [@quote, expr]
61
- end
62
-
63
- def precompile expr
64
- Pair.from_list [@precompile, quote(expr)]
65
- end
66
-
67
58
  def pre_compile expr
68
- compile_and_eval(precompile(expr))
59
+ compile_and_eval(Pair.from_list [@precompile, Pair.from_list([@quote, expr])])
69
60
  end
70
61
 
71
62
  def evaluate expr
@@ -85,26 +76,13 @@ module Nydp
85
76
  @printer.puts val.inspect if @printer
86
77
  end
87
78
 
88
- def handle_run_error e
89
- puts e.message
90
- e.backtrace.each do |b|
91
- puts b
92
- end
93
- end
94
-
95
79
  def run
96
80
  Nydp.apply_function ns, :"script-run", :"script-start", name
97
81
  res = Nydp::NIL
98
82
  begin
99
83
  while !@tokens.finished
100
84
  expr = @parser.expression(@tokens)
101
- unless expr.nil?
102
- begin
103
- print(res = evaluate(expr))
104
- rescue Exception => e
105
- handle_run_error e
106
- end
107
- end
85
+ print(res = evaluate(expr)) unless expr.nil?
108
86
  end
109
87
  ensure
110
88
  Nydp.apply_function ns, :"script-run", :"script-end", name
@@ -112,10 +90,4 @@ module Nydp
112
90
  res
113
91
  end
114
92
  end
115
-
116
- class ExplodeRunner < Runner
117
- def handle_run_error e
118
- raise e
119
- end
120
- end
121
93
  end
@@ -13,8 +13,9 @@ module Nydp
13
13
  def inspect ; string.inspect ; end
14
14
  def hash ; string.hash ; end
15
15
  def length ; string.length ; end
16
- def > other ; self.string > other.string ; end
17
- def < other ; self.string < other.string ; end
16
+ def > other ; self.string > other.string ; end
17
+ def < other ; self.string < other.string ; end
18
+ def * other ; StringAtom.new(string * other) ; end
18
19
 
19
20
  def <=> other
20
21
  self < other ? -1 : (self == other ? 0 : 1)
@@ -15,7 +15,7 @@ class Nydp::Symbol
15
15
  end
16
16
 
17
17
  def value context=nil
18
- raise "unbound symbol: #{self.inspect}" if @value == nil
18
+ raise Nydp::Error.new("unbound symbol: #{self.inspect}") if @value == nil
19
19
  @value
20
20
  end
21
21
 
@@ -4,7 +4,15 @@ module Nydp
4
4
  class SymbolLookup
5
5
  extend Helper
6
6
 
7
+ def self.skip_empty bindings
8
+ while Nydp::NIL.isnt?(bindings) && bindings.car.empty?
9
+ bindings = bindings.cdr
10
+ end
11
+ bindings
12
+ end
13
+
7
14
  def self.build name, bindings
15
+ bindings = skip_empty bindings
8
16
  depth = 0
9
17
  while Nydp::NIL.isnt? bindings
10
18
  here = bindings.car
@@ -13,7 +21,7 @@ module Nydp
13
21
  return ContextSymbol.build(depth, name, binding_index)
14
22
  else
15
23
  depth += 1
16
- bindings = bindings.cdr
24
+ bindings = skip_empty bindings.cdr
17
25
  end
18
26
  end
19
27
  name
@@ -18,7 +18,7 @@ module Nydp
18
18
  def cdr ; self ; end
19
19
  def size ; 0 ; end
20
20
  def is? other ; other.class == self.class ; end
21
- def isnt? other ; !is?(other) ; end
21
+ def isnt? other ; other.class != self.class ; end
22
22
  def to_s ; "" ; end
23
23
  def + other ; other ; end
24
24
  def copy ; self ; end
@@ -1,3 +1,3 @@
1
1
  module Nydp
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.5"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  module Nydp
2
2
  class VM
3
3
  include Helper
4
- attr_accessor :instructions, :args, :contexts, :current_context, :locals, :unhandled_error, :ns
4
+ attr_accessor :instructions, :args, :contexts, :current_context, :locals, :unhandled_error, :last_error, :ns
5
5
 
6
6
  module Finally ; end
7
7
  module HandleError ; end
@@ -30,7 +30,7 @@ module Nydp
30
30
  instructions.push thisi.cdr
31
31
  end
32
32
  thisi.car.execute(self)
33
- rescue Exception => e
33
+ rescue StandardError => e
34
34
  handle_error e
35
35
  end
36
36
  end
@@ -20,6 +20,6 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
- spec.add_development_dependency 'rspec', '~> 2.9'
23
+ spec.add_development_dependency 'rspec', '~> 3.1'
24
24
  spec.add_development_dependency 'rspec_numbering_formatter'
25
25
  end
@@ -6,14 +6,24 @@ describe Nydp::VM do
6
6
 
7
7
  def run txt
8
8
  Nydp.setup ns
9
- Nydp::ExplodeRunner.new(vm, ns, Nydp::StringReader.new(txt)).run
9
+ Nydp::Runner.new(vm, ns, Nydp::StringReader.new(txt)).run
10
10
  end
11
11
 
12
12
  describe "unhandled_error" do
13
13
  it "raises a helpful error" do
14
- proc = Proc.new { run "dflkjdgjeirgjeoi" }
15
- msg = "failed to eval dflkjdgjeirgjeoi\nerror was unbound symbol: dflkjdgjeirgjeoi"
16
- expect(proc).to raise_error RuntimeError, msg
14
+ error = nil
15
+ begin
16
+ run "dflkjdgjeirgjeoi"
17
+ rescue StandardError => e
18
+ error = e
19
+ end
20
+
21
+ expect(error).to be_a Nydp::Error
22
+ expect(error.message).to eq "failed to eval dflkjdgjeirgjeoi"
23
+
24
+ expect(error.cause).to be_a Nydp::Error
25
+ expect(error.cause.message).to eq "unbound symbol: dflkjdgjeirgjeoi"
26
+
17
27
  expect(vm.unhandled_error).to eq nil
18
28
  end
19
29
 
@@ -44,6 +44,10 @@ describe Nydp::Hash do
44
44
  describe "unfriendly non-hash" do
45
45
  let(:ahash) { Nydp::StringAtom.new "this here ain't no hash, hombre" }
46
46
 
47
+ def cleanup_err_msg txt
48
+ txt.gsub(/at \/.*:in `builtin_invoke'/, '<error info>')
49
+ end
50
+
47
51
  describe "hash set" do
48
52
  it "does nothing, returns its value" do
49
53
  k = Nydp::Symbol.mk "keysym", ns
@@ -52,15 +56,17 @@ describe Nydp::Hash do
52
56
 
53
57
  begin
54
58
  Nydp::Builtin::HashSet.instance.invoke vm, args
55
- rescue Exception => e
59
+ rescue StandardError => e
56
60
  error = e
57
61
  end
58
62
 
59
- expect(error.message.gsub(/at \/.*:in `builtin_invoke'/, '<error info>')).to eq "Called builtin/hash-set
60
- with args (\"this here ain't no hash, hombre\" keysym \"foobar\")
61
- raised
62
- hash-set: Not a hash: Nydp::StringAtom
63
- <error info>"
63
+ expect(cleanup_err_msg error.message).to eq "Called builtin/hash-set
64
+ with args
65
+ \"this here ain't no hash, hombre\"
66
+ keysym
67
+ \"foobar\""
68
+
69
+ expect(cleanup_err_msg error.cause.message).to eq "hash-set: Not a hash: Nydp::StringAtom"
64
70
  end
65
71
  end
66
72
 
@@ -71,15 +77,16 @@ raised
71
77
 
72
78
  begin
73
79
  Nydp::Builtin::HashGet.instance.invoke vm, pair_list(args)
74
- rescue Exception => e
80
+ rescue StandardError => e
75
81
  error = e
76
82
  end
77
83
 
78
- expect(error.message.gsub(/at \/.*:in `ruby_call'/, '<error info>')).to eq "Called builtin/hash-get
79
- with args (\"this here ain't no hash, hombre\" keysym)
80
- raised
81
- hash-get: Not a hash: Nydp::StringAtom
82
- <error info>"
84
+ expect(cleanup_err_msg error.message).to eq "Called builtin/hash-get
85
+ with args
86
+ \"this here ain't no hash, hombre\"
87
+ keysym"
88
+
89
+ expect(cleanup_err_msg error.cause.message).to eq "hash-get: Not a hash: Nydp::StringAtom"
83
90
  end
84
91
  end
85
92
  end
@@ -2,19 +2,6 @@ require "spec_helper"
2
2
 
3
3
  describe Nydp::Hash do
4
4
 
5
- class TestThing
6
- attr_accessor :a, :b, :c
7
- def initialize a, b, c
8
- @a, @b, @c = a, b, c
9
- end
10
-
11
- def inspect
12
- "(TestThing #{a.inspect} #{b.inspect})"
13
- end
14
-
15
- def _nydp_safe_methods ; %i{ a b } ; end
16
- end
17
-
18
5
  let(:vm) { Nydp::VM.new(ns) }
19
6
 
20
7
  describe "#to_ruby" do
@@ -21,6 +21,14 @@ describe Nydp::Pair do
21
21
  expect(Nydp::Pair.new(NIL, NIL)).to eq Nydp::Pair.new(NIL, NIL)
22
22
  end
23
23
 
24
+ it "there is no empty list, only NIL" do
25
+ expect(Nydp::Pair.from_list([])).to eq Nydp::NIL
26
+ end
27
+
28
+ it "is false for (nil) == nil" do
29
+ expect(Nydp::Pair.from_list([Nydp::NIL]) == Nydp::NIL).to eq false
30
+ end
31
+
24
32
  it "should be true for nested empty lists" do
25
33
  e1 = Nydp::Pair.new(Nydp::NIL, Nydp::NIL)
26
34
  e2 = Nydp::Pair.new(Nydp::NIL, Nydp::NIL)
@@ -77,10 +85,16 @@ describe Nydp::Pair do
77
85
  expect(p.cdr).to eq Nydp::NIL
78
86
  end
79
87
 
80
- it "should convert to a ruby list" do
81
- pair = pair_list [:a, :b, :c, :d]
88
+ it "#to_ruby converts self and each element to ruby equivalent" do
89
+ pair = pair_list [a, b, pair_list([a, b]), c, d]
82
90
  ruby = pair.to_ruby
83
- expect(ruby).to eq [:a, :b, :c, :d]
91
+ expect(ruby).to eq [:a, :b, [:a, :b], :c, :d]
92
+ end
93
+
94
+ it "#to_a converts to a ruby Array without converting elements" do
95
+ pair = pair_list [a, b, pair_list([a, b]), c, d]
96
+ ruby = pair.to_a
97
+ expect(ruby).to eq [a, b, pair_list([a, b]), c, d]
84
98
  end
85
99
 
86
100
  it "should have size zero when empty" do
@@ -21,10 +21,22 @@ module SpecHelper
21
21
  end
22
22
 
23
23
  RSpec.configure do |config|
24
- config.treat_symbols_as_metadata_keys_with_true_values = true
25
24
  config.run_all_when_everything_filtered = true
26
25
  config.filter_run :focus
27
26
  config.order = 'random'
28
27
  config.include Nydp::Helper
29
28
  config.include SpecHelper
30
29
  end
30
+
31
+ class TestThing
32
+ attr_accessor :a, :b, :c
33
+ def initialize a, b, c
34
+ @a, @b, @c = a, b, c
35
+ end
36
+
37
+ def inspect
38
+ "(TestThing #{a.inspect} #{b.inspect})"
39
+ end
40
+
41
+ def _nydp_safe_methods ; %i{ a b } ; end
42
+ end
@@ -17,7 +17,7 @@ describe Nydp::Symbol do
17
17
 
18
18
  it "should create a new symbol" do
19
19
  sym = Nydp::Symbol.mk :foo, ns
20
- expect(sym.name.should).to eq :foo
20
+ expect(sym.name).to eq :foo
21
21
  end
22
22
 
23
23
  it "should not create a new symbol when the symbol already exists" do
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.2.3
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Conan Dalton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-28 00:00:00.000000000 Z
11
+ date: 2017-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '2.9'
47
+ version: '3.1'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '2.9'
54
+ version: '3.1'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec_numbering_formatter
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -106,6 +106,8 @@ files:
106
106
  - lib/lisp/core-100-utils.nydp
107
107
  - lib/lisp/tests/accum-examples.nydp
108
108
  - lib/lisp/tests/add-hook-examples.nydp
109
+ - lib/lisp/tests/all-examples.nydp
110
+ - lib/lisp/tests/any-examples.nydp
109
111
  - lib/lisp/tests/auto-hash-examples.nydp
110
112
  - lib/lisp/tests/best-examples.nydp
111
113
  - lib/lisp/tests/boot-tests.nydp
@@ -133,8 +135,11 @@ files:
133
135
  - lib/lisp/tests/invocation-tests.nydp
134
136
  - lib/lisp/tests/isa-examples.nydp
135
137
  - lib/lisp/tests/len-examples.nydp
138
+ - lib/lisp/tests/list-gsub-examples.nydp
139
+ - lib/lisp/tests/list-match-examples.nydp
136
140
  - lib/lisp/tests/list-tests.nydp
137
141
  - lib/lisp/tests/mapsum-examples.nydp
142
+ - lib/lisp/tests/none-examples.nydp
138
143
  - lib/lisp/tests/orequal-examples.nydp
139
144
  - lib/lisp/tests/parser-tests.nydp
140
145
  - lib/lisp/tests/plus-plus-examples.nydp