nydp 0.0.4 → 0.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e96bb2970aa18753721c5faa2c5aeec53a73245f
4
- data.tar.gz: 151802fddd1bcdb72ecddc6fb2e882b11c3d2ea4
3
+ metadata.gz: 8c1432b7602bbe14e2c346f16068b7f8aea35317
4
+ data.tar.gz: 664df28016183708d50c31a000088176ba6fe38a
5
5
  SHA512:
6
- metadata.gz: 437799e27e763566d9c6febf8ea154aea63bf66a7a9db57f6e8e8c033086646d9966c687d276578840dc0a974e5fdf7fb722ce9366bfb70d840f8e1b3906936f
7
- data.tar.gz: da65be98312e0b821e9c7fe3b39ae6a8944b87fc6a7d20e56aaffe6a8673f632bda2c7daa6bbefe488243d156e933e81c8f33ee29909b55aa264f2afaa570a83
6
+ metadata.gz: 08fa70dd03b03b37e7427524502c216a3f7b82cdd12d9800282d91020d4d59e8faa2fdf860038299d66559f12367125913b9e699d24fe476f656599a1d49b9da
7
+ data.tar.gz: 40746bd05d453ab458c4e389c215546e9ffadb27e53455387a112539adc5ef189d762072f4e8988086d8813892cb9a29e53af2794fb1591e51df52bfb294f4ae
data/lib/lisp/boot.nydp CHANGED
@@ -263,3 +263,16 @@
263
263
 
264
264
  (def build-keyword-args (pairs)
265
265
  (map (fn (ab) `(list (quote ,(car ab)) ,@(cdr ab))) pairs))
266
+
267
+ (mac dynamic (name)
268
+ (let with-mac-name (sym "w/~name")
269
+ (w/uniq prev
270
+ `(do
271
+ (mac ,with-mac-name (new-value . body)
272
+ (w/uniq result
273
+ `(let ,',prev (hash-get (thread-locals) ',',name)
274
+ (hash-set (thread-locals) ',',name ,new-value)
275
+ (let ,result (do ,@body)
276
+ (hash-set (thread-locals) ',',name ,',prev)
277
+ ,result))))
278
+ (def ,name () (hash-get (thread-locals) ',name))))))
@@ -22,8 +22,39 @@
22
22
 
23
23
  (register-test
24
24
  '(suite "Boot Tests"
25
+ (suite "list management"
26
+ ("'pair breaks a list into pairs"
27
+ (pairs '(1 a 2 b 3 c))
28
+ ((1 a) (2 b) (3 c)))
29
+
30
+ ("'flatten returns a flat list of things"
31
+ (flatten '((poo (x) (* x x)) (1 2 3)))
32
+ (poo x * x x 1 2 3)))
33
+
34
+ (suite "map"
35
+ ("maps a function over a list of numbers"
36
+ (map (fn (x) (* x x)) '(1 2 3))
37
+ (1 4 9)))
25
38
 
26
39
  (suite "quasiquote"
40
+ ("same as quote for standalone item"
41
+ `a
42
+ a)
43
+ ("same as quote for standalone list"
44
+ `(a b c)
45
+ (a b c))
46
+ ("substitutes single variables"
47
+ (let b 10 `(a ,b c))
48
+ (a 10 c))
49
+ ("substitutes a list"
50
+ (let b '(1 2 3) `(a ,@b c))
51
+ (a 1 2 3 c))
52
+ ("substitutes a list at the end of a given list"
53
+ (let b '(1 2 3) `(a ,b ,@b))
54
+ (a (1 2 3) 1 2 3))
55
+ ("more complicated substitution example"
56
+ (with (d '(1 2 3) g '(x y z)) `(a (b c ,d (e f ,@g))))
57
+ (a (b c (1 2 3) (e f x y z))))
27
58
  ("peeks inside nested quotes"
28
59
  `(a b '(c ,(+ 1 2)))
29
60
  (a b '(c 3)))
@@ -0,0 +1,14 @@
1
+ (dynamic foodynamic)
2
+
3
+ (def listfoody ()
4
+ (list (foodynamic)
5
+ (+ 6 (foodynamic))
6
+ (+ 10 (foodynamic))))
7
+
8
+ (register-test '(suite "dynamic scoping"
9
+ ("relies on thread-locals"
10
+ (list
11
+ (w/foodynamic 101 (listfoody))
12
+ (w/foodynamic 0 (listfoody))
13
+ (w/foodynamic 666 (listfoody)))
14
+ ((101 107 111) (0 6 10) (666 672 676)))))
@@ -16,7 +16,7 @@
16
16
  string)
17
17
 
18
18
  ("interpolates a string"
19
- "foobar %%(+ 1 2) you know"
19
+ "foobar ~(+ 1 2) you know"
20
20
  "foobar 3 you know")
21
21
 
22
22
  ("returns 'string for an interpolated string"
@@ -40,6 +40,14 @@
40
40
  (type-of nil)
41
41
  nil))
42
42
 
43
+ (suite "Ensuring"
44
+ ("gets called on the way out"
45
+ (let x 10
46
+ (ensuring (fn () (assign x (+ x 11)))
47
+ (fn () (assign x (+ x 22))))
48
+ x)
49
+ 43))
50
+
43
51
  (suite "Lists"
44
52
  (suite "cons"
45
53
  ("cons creates a list"
data/lib/nydp.rb CHANGED
@@ -8,7 +8,10 @@ module Nydp
8
8
  def self.testfiles; PLUGINS.map(&:testfiles).flatten ; end
9
9
  def self.plugin_names ; PLUGINS.map(&:name) ; end
10
10
  def self.loadall vm, ns, files
11
- files.each { |f| StreamRunner.new(vm, ns, File.new(f)).run }
11
+ files.each { |f|
12
+ reader = Nydp::StreamReader.new(File.new(f))
13
+ Nydp::Runner.new(vm, ns, reader).run
14
+ }
12
15
  end
13
16
 
14
17
  def self.repl
@@ -17,7 +20,8 @@ module Nydp
17
20
  setup(ns)
18
21
  vm = VM.new
19
22
  loadall vm, ns, loadfiles
20
- Repl.new(vm, ns, $stdin).run
23
+ reader = Nydp::ReadlineReader.new $stdin, "nydp > "
24
+ Nydp::Runner.new(vm, ns, reader, $stdout).run
21
25
  end
22
26
 
23
27
  def self.tests *options
@@ -28,7 +32,8 @@ module Nydp
28
32
  vm = VM.new
29
33
  loadall vm, ns, loadfiles
30
34
  loadall vm, ns, testfiles
31
- StreamRunner.new(vm, ns, "(run-all-tests #{verbose})").run
35
+ reader = Nydp::StringReader.new "(run-all-tests #{verbose})"
36
+ Nydp::Runner.new(vm, ns, reader).run
32
37
  end
33
38
 
34
39
  end
@@ -0,0 +1,25 @@
1
+ class Nydp::Builtin::Ensuring
2
+ include Nydp::Helper
3
+
4
+ class InvokeProtection
5
+ attr_reader :protection
6
+
7
+ def initialize protection
8
+ @protection = protection
9
+ end
10
+
11
+ def execute vm
12
+ protection.invoke vm, Nydp.NIL
13
+ end
14
+ end
15
+
16
+ def invoke vm, args
17
+ fn_ensure = args.car
18
+ fn_tricky = args.cdr.car
19
+
20
+ protection_instructions = Nydp::Pair.from_list [InvokeProtection.new(fn_ensure), Nydp::PopArg]
21
+ vm.push_instructions protection_instructions, vm.peek_context
22
+
23
+ fn_tricky.invoke vm, Nydp.NIL
24
+ end
25
+ end
@@ -4,7 +4,7 @@ class Nydp::Builtin::Eval
4
4
  end
5
5
 
6
6
  def invoke vm, args
7
- evaluator = Nydp::Runner.new Nydp::VM.new, @ns
7
+ evaluator = Nydp::Evaluator.new Nydp::VM.new, @ns
8
8
  vm.push_arg evaluator.evaluate args.car
9
9
  end
10
10
 
@@ -0,0 +1,7 @@
1
+ class Nydp::Builtin::ThreadLocals
2
+ include Nydp::Helper
3
+
4
+ def invoke vm, args
5
+ vm.push_arg vm.locals
6
+ end
7
+ end
data/lib/nydp/core.rb CHANGED
@@ -42,6 +42,7 @@ module Nydp
42
42
  Symbol.mk(:nil, ns).assign Nydp.NIL
43
43
  Symbol.mk(:t, ns).assign Nydp.T
44
44
  Symbol.mk(:sym, ns).assign Nydp::Builtin::ToSym.new(ns)
45
+ Symbol.mk(:ensuring, ns).assign(Nydp::Builtin::Ensuring.new)
45
46
  Symbol.mk(:inspect, ns).assign(Nydp::Builtin::Inspect.new)
46
47
  Symbol.mk(:comment, ns).assign(Nydp::Builtin::Comment.new)
47
48
  Symbol.mk(:millisecs, ns).assign(Nydp::Builtin::Millisecs.new)
@@ -51,6 +52,7 @@ module Nydp
51
52
  Symbol.mk("string-pieces",ns).assign(Nydp::Builtin::StringPieces.new)
52
53
  Symbol.mk("string-replace", ns).assign(Nydp::Builtin::StringReplace.new)
53
54
  Symbol.mk("string-split" , ns).assign(Nydp::Builtin::StringSplit.new )
55
+ Symbol.mk("thread-locals" , ns).assign(Nydp::Builtin::ThreadLocals.new)
54
56
  Symbol.mk("type-of", ns).assign(Nydp::Builtin::TypeOf.new(ns))
55
57
  Symbol.mk(:"eq?", ns).assign(Nydp::Builtin::IsEqual.new)
56
58
  Symbol.mk(:"pair?", ns).assign(Nydp::Builtin::IsPair.new)
data/lib/nydp/parser.rb CHANGED
@@ -87,8 +87,6 @@ module Nydp
87
87
  def next_form token, token_stream
88
88
  return nil if token.nil?
89
89
  case token.first
90
- when :embed_suffix
91
- Nydp.NIL
92
90
  when :string_open_delim
93
91
  string token_stream, token.last, close_delimiter_for(token.last)
94
92
  when :left_paren
@@ -0,0 +1,25 @@
1
+
2
+ # with thanks to @liwp ( http://blog.lauripesonen.com/ ) at http://stackoverflow.com/questions/2065923/irb-history-not-working
3
+ module Nydp
4
+ module ReadlineHistory
5
+ HISTFILE = "~/.nydp_history"
6
+ MAXHISTSIZE = 100
7
+
8
+ def setup_readline_history verbose=true
9
+ histfile = File::expand_path(HISTFILE)
10
+ begin
11
+ if File::exists?(histfile)
12
+ lines = IO::readlines(histfile).collect { |line| line.chomp }
13
+ Readline::HISTORY.push(*lines)
14
+ end
15
+ Kernel::at_exit do
16
+ lines = Readline::HISTORY.to_a.reverse.uniq.reverse
17
+ lines = lines[-MAXHISTSIZE, MAXHISTSIZE] if lines.size > MAXHISTSIZE
18
+ File::open(histfile, File::WRONLY|File::CREAT|File::TRUNC) { |io| io.puts lines.join("\n") }
19
+ end
20
+ rescue => e
21
+ puts "Error when configuring permanent history: #{e}" if verbose
22
+ end
23
+ end
24
+ end
25
+ end
data/lib/nydp/runner.rb CHANGED
@@ -1,5 +1,42 @@
1
+ require 'readline'
2
+ require 'nydp/readline_history'
3
+
1
4
  module Nydp
2
- class Runner
5
+ class StringReader
6
+ def initialize string ; @string = string ; end
7
+ def nextline
8
+ s = @string ; @string = nil ; s
9
+ end
10
+ end
11
+
12
+ class StreamReader
13
+ def initialize stream ; @stream = stream ; end
14
+ def nextline
15
+ @stream.readline unless @stream.eof?
16
+ end
17
+ end
18
+
19
+ class ReadlineReader
20
+ include Nydp::ReadlineHistory
21
+
22
+ def initialize stream, prompt
23
+ @prompt = prompt
24
+ setup_readline_history
25
+ end
26
+
27
+ # with thanks to http://ruby-doc.org/stdlib-1.9.3/libdoc/readline/rdoc/Readline.html
28
+ # and http://bogojoker.com/readline/
29
+ def nextline
30
+ line = Readline.readline(@prompt, true)
31
+ return nil if line.nil?
32
+ if line =~ /^\s*$/ or Readline::HISTORY.to_a[-2] == line
33
+ Readline::HISTORY.pop
34
+ end
35
+ line
36
+ end
37
+ end
38
+
39
+ class Evaluator
3
40
  attr_accessor :vm, :ns
4
41
 
5
42
  def initialize vm, ns
@@ -30,37 +67,34 @@ module Nydp
30
67
  end
31
68
  end
32
69
 
33
- class StreamRunner < Runner
34
- attr_accessor :stream, :parser
35
-
36
- def initialize vm, ns, stream
70
+ class Runner < Evaluator
71
+ def initialize vm, ns, stream, printer=nil
37
72
  super vm, ns
38
- @stream = stream
39
- @parser = Nydp::Parser.new(ns)
40
- @tokens = Nydp::Tokeniser.new stream
73
+ @printer = printer
74
+ @parser = Nydp::Parser.new(ns)
75
+ @tokens = Nydp::Tokeniser.new stream
41
76
  end
42
77
 
43
- def prompt *_
78
+ def print val
79
+ @printer.puts val if @printer
44
80
  end
45
81
 
46
82
  def run
47
83
  res = Nydp.NIL
48
- prompt
49
84
  while !@tokens.finished
50
- expr = parser.expression(@tokens)
85
+ expr = @parser.expression(@tokens)
51
86
  unless expr.nil?
52
- res = evaluate expr
53
- prompt res
87
+ begin
88
+ print(res = evaluate(expr))
89
+ rescue Exception => e
90
+ puts e.message
91
+ e.backtrace.each do |b|
92
+ puts b
93
+ end
94
+ end
54
95
  end
55
96
  end
56
97
  res
57
98
  end
58
99
  end
59
-
60
- class Repl < StreamRunner
61
- def prompt val=nil
62
- puts val if val
63
- print "nydp > "
64
- end
65
- end
66
100
  end
@@ -4,15 +4,20 @@ module Nydp
4
4
  class Tokeniser
5
5
  attr_accessor :state, :finished
6
6
 
7
- def initialize stream
8
- @stream = stream.is_a?(String) ? nil : stream
9
- @scanner = StringScanner.new(stream.is_a?(String) ? stream : "")
7
+ def initialize reader
8
+ @reader = reader
9
+ @scanner = StringScanner.new("")
10
10
  @state = :lisp
11
11
  end
12
12
 
13
13
  def no_more?
14
- @scanner << @stream.readline if @scanner.eos? && @stream && !@stream.eof?
15
- @scanner.eos?
14
+ if @scanner.eos?
15
+ nextline = @reader.nextline
16
+ return true if nextline.nil?
17
+ @scanner << nextline
18
+ end
19
+
20
+ false
16
21
  end
17
22
 
18
23
  def close_delimiter? scanner, delim
@@ -37,8 +42,8 @@ module Nydp
37
42
  elsif closer = close_delimiter?(s, close_delimiter)
38
43
  rep << closer
39
44
  return StringFragmentCloseToken.new(string, rep)
40
- elsif embed_suffix = s.scan(/%%/)
41
- rep << embed_suffix
45
+ elsif start_interpolation = s.scan(/~/)
46
+ rep << start_interpolation
42
47
  return StringFragmentToken.new(string, rep)
43
48
  else
44
49
  ch = s.getch
@@ -61,9 +66,6 @@ module Nydp
61
66
  tok = [:comment, comment[1..-1].strip]
62
67
  elsif open_str = s.scan(/"/)
63
68
  tok = [:string_open_delim, open_str]
64
- elsif embed_suffix = s.scan(/\]#/)
65
- self.state = :external_text
66
- tok = [:embed_suffix, embed_suffix]
67
69
  elsif list_prefix = s.scan(/[^\s()]*\(/)
68
70
  tok = [:left_paren, list_prefix[0...-1]]
69
71
  elsif list_prefix = s.scan(/[^\s()]*\{/)
data/lib/nydp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Nydp
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
data/lib/nydp/vm.rb CHANGED
@@ -1,12 +1,13 @@
1
1
  module Nydp
2
2
  class VM
3
3
  include Helper
4
- attr_accessor :instructions, :args, :contexts, :current_context
4
+ attr_accessor :instructions, :args, :contexts, :current_context, :locals
5
5
 
6
6
  def initialize
7
7
  @instructions = []
8
- @args = []
9
- @contexts = []
8
+ @args = []
9
+ @contexts = []
10
+ @locals = { }
10
11
  end
11
12
 
12
13
  def thread expr
data/spec/boot_spec.rb CHANGED
@@ -6,7 +6,8 @@ describe Nydp do
6
6
  before {
7
7
  Nydp.setup ns
8
8
  boot_path = File.expand_path File.join File.expand_path(File.dirname(__FILE__)), '../lib/lisp/boot.nydp'
9
- Nydp::StreamRunner.new(vm, ns, File.new(boot_path)).run
9
+ reader = Nydp::StreamReader.new(File.new(boot_path))
10
+ Nydp::Runner.new(vm, ns, reader).run
10
11
  }
11
12
 
12
13
  def list *things
@@ -23,45 +24,7 @@ describe Nydp do
23
24
  end
24
25
 
25
26
  def run txt
26
- Nydp::StreamRunner.new(vm, ns, txt).run
27
- end
28
-
29
- it "should map a function over a list of numbers" do
30
- expect(run "(map (fn (x) (* x x)) '(1 2 3))").to eq Nydp::Pair.from_list [1, 4, 9]
31
- end
32
-
33
- describe "quasiquote" do
34
- it "should quasiquote a standalone item" do
35
- expect(run "`a").to eq sym(:a)
36
- end
37
-
38
- it "should quasiquote a plain list" do
39
- expect(run "`(a b c)").to eq list :a, :b, :c
40
- end
41
-
42
- it "should quasiquote a plain list with a variable substitution" do
43
- expect(run "(assign b 10) `(a ,b c)").to eq list :a, 10, :c
44
- end
45
-
46
- it "should quasiquote a plain list with a list-variable substitution" do
47
- expect(run "(assign b '(1 2 3)) `(a ,@b c)").to eq list :a, 1, 2, 3, :c
48
- end
49
-
50
- it "should quasiquote a plain list with a list-variable substitution at the end" do
51
- expect(run "(assign b '(1 2 3)) `(a ,b ,@b)").to eq list :a, [1,2,3], 1, 2, 3
52
- end
53
-
54
- it "should quasiquote a plain list with a list-variable substitution at the end" do
55
- expect(run "(assign d '(1 2 3)) (assign g '(x y z)) `(a (b c ,d (e f ,@g)))").to eq list :a, [:b, :c, [1, 2, 3], [:e, :f, :x, :y, :z]]
56
- end
57
- end
58
-
59
- describe "pairs" do
60
- it "should break a list into pairs" do
61
- result = run "(pairs '(1 a 2 b 3 c))"
62
- expected = run "'((1 a) (2 b) (3 c))"
63
- expect(result).to eq expected
64
- end
27
+ Nydp::Runner.new(vm, ns, Nydp::StringReader.new(txt)).run
65
28
  end
66
29
 
67
30
  describe :let do
@@ -72,14 +35,6 @@ describe Nydp do
72
35
  end
73
36
  end
74
37
 
75
- describe :flatten do
76
- it "should return a flat list of things" do
77
- lisp = "(flatten '((poo (x) (* x x)) (1 2 3)))"
78
- result = run lisp
79
- expect(result).to eq list :poo, :x, :"*", :x, :x, 1, 2, 3
80
- end
81
- end
82
-
83
38
  describe :and do
84
39
  it "should produce some nested conds" do
85
40
  result = run "(pre-compile '(and a b c))"
@@ -20,7 +20,8 @@ describe Nydp::Parser do
20
20
  let(:colosyn) { Nydp::Symbol.mk :"colon-syntax", ns }
21
21
 
22
22
  def parse_string txt, open_delim, close_delim
23
- Nydp::Parser.new(ns).string(Nydp::Tokeniser.new(txt), open_delim, close_delim)
23
+ reader = Nydp::StringReader.new txt
24
+ Nydp::Parser.new(ns).string(Nydp::Tokeniser.new(reader), open_delim, close_delim)
24
25
  end
25
26
 
26
27
  it "should parse empty string" do
@@ -44,14 +45,14 @@ describe Nydp::Parser do
44
45
 
45
46
  it "should parse a string with embedded code, delimited by eof" do
46
47
  x1 = sym('string-pieces')
47
- x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ',':a fluffy bunny! %%')
48
+ x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ',':a fluffy bunny! ~')
48
49
  x2 = Nydp::StringAtom.new(x2.string, x2)
49
50
  x3 = sym('expr')
50
51
  x4 = Nydp::StringFragmentCloseToken.new(' a purple cow!',' a purple cow!')
51
52
  x4 = Nydp::StringAtom.new(x4.string, x4)
52
53
 
53
54
  expected = pair_list([x1,x2,x3,x4])
54
- actual = parse_string "a fluffy bunny! %%expr a purple cow!", ':', :eof
55
+ actual = parse_string "a fluffy bunny! ~expr a purple cow!", ':', :eof
55
56
  expect(actual).to eq expected
56
57
  end
57
58
 
@@ -62,14 +63,14 @@ describe Nydp::Parser do
62
63
  n4 = sym(:zop)
63
64
 
64
65
  x1 = sym('string-pieces')
65
- x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','------->a fluffy bunny! %%')
66
+ x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','------->a fluffy bunny! ~')
66
67
  x2 = Nydp::StringAtom.new(x2.string, x2)
67
68
  x3 = pair_list [n1, n2, n3, n4]
68
69
  x4 = Nydp::StringFragmentCloseToken.new(' a purple cow!',' a purple cow!')
69
70
  x4 = Nydp::StringAtom.new(x4.string, x4)
70
71
 
71
72
  expected = pair_list([x1,x2,x3,x4])
72
- actual = parse_string "a fluffy bunny! %%(foo bar \"an embedded bunny :)\" zop) a purple cow!", '------->', :eof
73
+ actual = parse_string "a fluffy bunny! ~(foo bar \"an embedded bunny :)\" zop) a purple cow!", '------->', :eof
73
74
  expect(actual).to eq expected
74
75
  end
75
76
 
@@ -78,7 +79,7 @@ describe Nydp::Parser do
78
79
  e2 = sym(:bunny)
79
80
 
80
81
  s1 = sym('string-pieces')
81
- s2 = Nydp::StringFragmentToken.new('a rather ','"a rather %%')
82
+ s2 = Nydp::StringFragmentToken.new('a rather ','"a rather ~')
82
83
  s2 = Nydp::StringAtom.new(s2.string, s2)
83
84
  s3 = pair_list [e1, e2]
84
85
  s4 = Nydp::StringFragmentCloseToken.new(' bunny :)',' bunny :)"')
@@ -90,14 +91,14 @@ describe Nydp::Parser do
90
91
  n4 = sym(:zop)
91
92
 
92
93
  x1 = sym('string-pieces')
93
- x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','------->a fluffy bunny! %%')
94
+ x2 = Nydp::StringFragmentToken.new('a fluffy bunny! ','------->a fluffy bunny! ~')
94
95
  x2 = Nydp::StringAtom.new(x2.string, x2)
95
96
  x3 = pair_list [n1, n2, n3, n4]
96
97
  x4 = Nydp::StringFragmentCloseToken.new(' a purple cow!',' a purple cow!')
97
98
  x4 = Nydp::StringAtom.new(x4.string, x4)
98
99
 
99
100
  expected = pair_list([x1,x2,x3,x4])
100
- actual = parse_string "a fluffy bunny! %%(foo bar \"a rather %%(describe bunny) bunny :)\" zop) a purple cow!", '------->', :eof
101
+ actual = parse_string "a fluffy bunny! ~(foo bar \"a rather ~(describe bunny) bunny :)\" zop) a purple cow!", '------->', :eof
101
102
  expect(actual).to eq expected
102
103
  end
103
104
 
data/spec/nypd_spec.rb CHANGED
@@ -6,7 +6,7 @@ describe Nydp do
6
6
 
7
7
  def run txt
8
8
  Nydp.setup ns
9
- Nydp::StreamRunner.new(vm, ns, txt).run
9
+ Nydp::Runner.new(vm, ns, Nydp::StringReader.new(txt)).run
10
10
  end
11
11
 
12
12
  it "should make a symbol from a string" do
data/spec/parser_spec.rb CHANGED
@@ -20,12 +20,14 @@ describe Nydp::Parser do
20
20
  let(:colosyn) { Nydp::Symbol.mk :"colon-syntax", ns }
21
21
 
22
22
  it "should return a stream of tokens" do
23
- t = Nydp::Tokeniser.new ""
23
+ reader = Nydp::StringReader.new ""
24
+ t = Nydp::Tokeniser.new reader
24
25
  expect(t.next_token).to eq nil
25
26
  end
26
27
 
27
28
  it "should return another stream of tokens" do
28
- t = Nydp::Tokeniser.new "(a b c 1 2 3)"
29
+ reader = Nydp::StringReader.new "(a b c 1 2 3)"
30
+ t = Nydp::Tokeniser.new reader
29
31
  tt = []
30
32
  tok = t.next_token
31
33
  while tok
data/spec/spec_helper.rb CHANGED
@@ -7,7 +7,8 @@ module SpecHelper
7
7
  end
8
8
 
9
9
  def parse txt
10
- Nydp::Parser.new(ns).expression(Nydp::Tokeniser.new txt)
10
+ reader = Nydp::StringReader.new txt
11
+ Nydp::Parser.new(ns).expression(Nydp::Tokeniser.new reader)
11
12
  end
12
13
 
13
14
  def pair_list xs, last=Nydp.NIL
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Nydp do
4
+ let(:parser) { Nydp::Parser.new(ns) }
5
+
6
+ def run vm, txt
7
+ Nydp::Runner.new(vm, ns, Nydp::StringReader.new(txt)).run
8
+ end
9
+
10
+ it "should isolate threadlocal values" do
11
+ Nydp.setup ns
12
+
13
+ vm0 = Nydp::VM.new
14
+ vm1 = Nydp::VM.new
15
+
16
+
17
+ run vm0, "(hash-set (thread-locals) 'testing (+ 1 2 3))"
18
+ run vm1, "(hash-set (thread-locals) 'testing (+ 6 7 8))"
19
+
20
+ val0 = run vm0, "(hash-get (thread-locals) 'testing)"
21
+ val1 = run vm1, "(hash-get (thread-locals) 'testing)"
22
+
23
+ expect(val0).to eq 6
24
+ expect(val1).to eq 21
25
+ end
26
+
27
+ 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.4
4
+ version: 0.0.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: 2015-03-05 00:00:00.000000000 Z
11
+ date: 2015-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -86,6 +86,7 @@ files:
86
86
  - lib/lisp/boot.nydp
87
87
  - lib/lisp/test-runner.nydp
88
88
  - lib/lisp/tests/boot-tests.nydp
89
+ - lib/lisp/tests/dynamic-scope-test.nydp
89
90
  - lib/lisp/tests/foundation-test.nydp
90
91
  - lib/nydp.rb
91
92
  - lib/nydp/assignment.rb
@@ -97,6 +98,7 @@ files:
97
98
  - lib/nydp/builtin/comment.rb
98
99
  - lib/nydp/builtin/cons.rb
99
100
  - lib/nydp/builtin/divide.rb
101
+ - lib/nydp/builtin/ensuring.rb
100
102
  - lib/nydp/builtin/error.rb
101
103
  - lib/nydp/builtin/eval.rb
102
104
  - lib/nydp/builtin/greater_than.rb
@@ -114,6 +116,7 @@ files:
114
116
  - lib/nydp/builtin/random_string.rb
115
117
  - lib/nydp/builtin/string_replace.rb
116
118
  - lib/nydp/builtin/string_split.rb
119
+ - lib/nydp/builtin/thread_locals.rb
117
120
  - lib/nydp/builtin/times.rb
118
121
  - lib/nydp/builtin/to_string.rb
119
122
  - lib/nydp/builtin/to_sym.rb
@@ -132,6 +135,7 @@ files:
132
135
  - lib/nydp/literal.rb
133
136
  - lib/nydp/pair.rb
134
137
  - lib/nydp/parser.rb
138
+ - lib/nydp/readline_history.rb
135
139
  - lib/nydp/runner.rb
136
140
  - lib/nydp/string_atom.rb
137
141
  - lib/nydp/string_token.rb
@@ -151,6 +155,7 @@ files:
151
155
  - spec/spec_helper.rb
152
156
  - spec/string_token_spec.rb
153
157
  - spec/symbol_spec.rb
158
+ - spec/thread_local_spec.rb
154
159
  homepage: http://github.com/conanite/nydp
155
160
  licenses:
156
161
  - MIT
@@ -184,3 +189,4 @@ test_files:
184
189
  - spec/spec_helper.rb
185
190
  - spec/string_token_spec.rb
186
191
  - spec/symbol_spec.rb
192
+ - spec/thread_local_spec.rb