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 +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
|