nydp 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/lisp/boot.nydp +13 -0
- data/lib/lisp/tests/boot-tests.nydp +31 -0
- data/lib/lisp/tests/dynamic-scope-test.nydp +14 -0
- data/lib/lisp/tests/foundation-test.nydp +9 -1
- data/lib/nydp.rb +8 -3
- data/lib/nydp/builtin/ensuring.rb +25 -0
- data/lib/nydp/builtin/eval.rb +1 -1
- data/lib/nydp/builtin/thread_locals.rb +7 -0
- data/lib/nydp/core.rb +2 -0
- data/lib/nydp/parser.rb +0 -2
- data/lib/nydp/readline_history.rb +25 -0
- data/lib/nydp/runner.rb +54 -20
- data/lib/nydp/tokeniser.rb +12 -10
- data/lib/nydp/version.rb +1 -1
- data/lib/nydp/vm.rb +4 -3
- data/spec/boot_spec.rb +3 -48
- data/spec/embedded_spec.rb +9 -8
- data/spec/nypd_spec.rb +1 -1
- data/spec/parser_spec.rb +4 -2
- data/spec/spec_helper.rb +2 -1
- data/spec/thread_local_spec.rb +27 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c1432b7602bbe14e2c346f16068b7f8aea35317
|
4
|
+
data.tar.gz: 664df28016183708d50c31a000088176ba6fe38a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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|
|
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
|
-
|
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
|
-
|
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
|
data/lib/nydp/builtin/eval.rb
CHANGED
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
@@ -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
|
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
|
34
|
-
|
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
|
-
@
|
39
|
-
@parser
|
40
|
-
@tokens
|
73
|
+
@printer = printer
|
74
|
+
@parser = Nydp::Parser.new(ns)
|
75
|
+
@tokens = Nydp::Tokeniser.new stream
|
41
76
|
end
|
42
77
|
|
43
|
-
def
|
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
|
-
|
53
|
-
|
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
|
data/lib/nydp/tokeniser.rb
CHANGED
@@ -4,15 +4,20 @@ module Nydp
|
|
4
4
|
class Tokeniser
|
5
5
|
attr_accessor :state, :finished
|
6
6
|
|
7
|
-
def initialize
|
8
|
-
@
|
9
|
-
@scanner = StringScanner.new(
|
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
|
-
|
15
|
-
|
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
|
41
|
-
rep <<
|
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
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::
|
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::
|
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))"
|
data/spec/embedded_spec.rb
CHANGED
@@ -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::
|
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!
|
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!
|
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!
|
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
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
|
-
|
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
|
-
|
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
@@ -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
|
+
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-
|
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
|