nydp 0.0.6 → 0.0.7
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/.gitattributes +1 -0
- data/README.md +228 -14
- data/lib/lisp/bm.nydp +18 -0
- data/lib/lisp/boot.nydp +69 -10
- data/lib/lisp/tests/boot-tests.nydp +65 -1
- data/lib/lisp/tests/error-tests.nydp +22 -0
- data/lib/lisp/tests/foundation-test.nydp +14 -22
- data/lib/lisp/tests/parser-tests.nydp +55 -0
- data/lib/nydp.rb +22 -12
- data/lib/nydp/assignment.rb +3 -1
- data/lib/nydp/builtin.rb +2 -5
- data/lib/nydp/builtin/ensuring.rb +3 -0
- data/lib/nydp/builtin/eval.rb +5 -1
- data/lib/nydp/builtin/handle_error.rb +39 -0
- data/lib/nydp/builtin/parse_in_string.rb +11 -0
- data/lib/nydp/builtin/sqrt.rb +5 -0
- data/lib/nydp/context_symbol.rb +38 -6
- data/lib/nydp/core.rb +9 -6
- data/lib/nydp/error.rb +4 -0
- data/lib/nydp/function_invocation.rb +1 -1
- data/lib/nydp/lexical_context.rb +13 -3
- data/lib/nydp/parser.rb +19 -18
- data/lib/nydp/runner.rb +9 -4
- data/lib/nydp/string_atom.rb +6 -7
- data/lib/nydp/symbol_lookup.rb +2 -1
- data/lib/nydp/tokeniser.rb +7 -1
- data/lib/nydp/version.rb +1 -1
- data/lib/nydp/vm.rb +35 -12
- data/nydp.gemspec +2 -2
- data/spec/parser_spec.rb +10 -0
- metadata +11 -4
@@ -0,0 +1,22 @@
|
|
1
|
+
(register-test '(suite "Error Tests"
|
2
|
+
("'ensuring gets called on the way out"
|
3
|
+
(let x 10
|
4
|
+
(ensure (assign x (+ x 11))
|
5
|
+
(assign x (+ x 22)))
|
6
|
+
x)
|
7
|
+
43)
|
8
|
+
|
9
|
+
("'on-err handles errors"
|
10
|
+
(let x nil
|
11
|
+
(on-err (= x "impossible")
|
12
|
+
(= x (nil nil nil)))
|
13
|
+
x)
|
14
|
+
"impossible")
|
15
|
+
|
16
|
+
("'on-err handles errors but any ensuring clause gets called first"
|
17
|
+
(with (x nil y nil)
|
18
|
+
(on-err (= x 'impossible)
|
19
|
+
(ensure (assign y 'ensure-clause)
|
20
|
+
(nil nil nil)))
|
21
|
+
(list x y))
|
22
|
+
(impossible ensure-clause))))
|
@@ -1,4 +1,9 @@
|
|
1
1
|
(register-test '(suite "Foundation Tests"
|
2
|
+
(suite "maths"
|
3
|
+
("sqrt"
|
4
|
+
(sqrt 6.25)
|
5
|
+
2.5))
|
6
|
+
|
2
7
|
(suite "strings"
|
3
8
|
(suite "string-split"
|
4
9
|
("splits a string using given expression"
|
@@ -23,6 +28,15 @@
|
|
23
28
|
(type-of "foobar %%(+ 1 2)")
|
24
29
|
string)))
|
25
30
|
|
31
|
+
(suite "eq?"
|
32
|
+
("true for two empty symbols"
|
33
|
+
(eq? '|| '||)
|
34
|
+
t)
|
35
|
+
|
36
|
+
("nil for two different symbols"
|
37
|
+
(eq? 'foo 'bar)
|
38
|
+
nil))
|
39
|
+
|
26
40
|
(suite "truth and nil"
|
27
41
|
("t is boolean true"
|
28
42
|
(if t "hello" "goodbye")
|
@@ -40,14 +54,6 @@
|
|
40
54
|
(type-of nil)
|
41
55
|
nil))
|
42
56
|
|
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
|
-
|
51
57
|
(suite "assignment with '="
|
52
58
|
("assigns a symbol"
|
53
59
|
(pre-compile '(= this 'that))
|
@@ -66,20 +72,6 @@
|
|
66
72
|
(pre-compile '(= a.b.c.d 42))
|
67
73
|
(hash-set (hash-get (hash-get a 'b) 'c) 'd 42)))
|
68
74
|
|
69
|
-
|
70
|
-
(suite "parse"
|
71
|
-
("parses a colon-syntax symbol"
|
72
|
-
(parse "this:that")
|
73
|
-
((colon-syntax this that)) )
|
74
|
-
|
75
|
-
("parses a dot-syntax symbol"
|
76
|
-
(parse "this.that.zozo")
|
77
|
-
((dot-syntax this that zozo)) )
|
78
|
-
|
79
|
-
("parses an expression"
|
80
|
-
(parse "(foo bar \"hello, String\") 1 2 (3 t nil) nil")
|
81
|
-
((foo bar "hello, String") 1 2 (3 t nil))))
|
82
|
-
|
83
75
|
(suite "isa"
|
84
76
|
("t for 'pair for list"
|
85
77
|
(isa 'pair '(a b c))
|
@@ -0,0 +1,55 @@
|
|
1
|
+
(register-test '(suite "Parser tests"
|
2
|
+
(suite "brace-list"
|
3
|
+
("parses an empty brace list"
|
4
|
+
(parse "{}")
|
5
|
+
((brace-list)))
|
6
|
+
|
7
|
+
("parses a single-item list"
|
8
|
+
(parse "{foo}")
|
9
|
+
((brace-list foo)))
|
10
|
+
|
11
|
+
("parses a list"
|
12
|
+
(parse "{foo bar 1 2 3}")
|
13
|
+
((brace-list foo bar 1 2 3))))
|
14
|
+
|
15
|
+
(suite "parse"
|
16
|
+
("parses an empty symbol"
|
17
|
+
(parse "||")
|
18
|
+
(||) )
|
19
|
+
|
20
|
+
("parses a colon-syntax symbol"
|
21
|
+
(parse "this:that")
|
22
|
+
((colon-syntax this that)) )
|
23
|
+
|
24
|
+
("parses a dot-syntax symbol"
|
25
|
+
(parse "this.that.zozo")
|
26
|
+
((dot-syntax this that zozo)) )
|
27
|
+
|
28
|
+
("parses a mixed-syntax symbol"
|
29
|
+
(parse "this$that.zozo")
|
30
|
+
((dot-syntax (dollar-syntax this that) zozo)))
|
31
|
+
|
32
|
+
("parses a mixed-syntax prefix symbol"
|
33
|
+
(parse "$this.that.zozo")
|
34
|
+
((dot-syntax (dollar-syntax || this) that zozo)))
|
35
|
+
|
36
|
+
("parses a prefix dollar"
|
37
|
+
(parse "$this")
|
38
|
+
((dollar-syntax || this)))
|
39
|
+
|
40
|
+
("parses a prefix dollar-dot"
|
41
|
+
(parse "$.this")
|
42
|
+
((dot-syntax (dollar-syntax || ||) this)))
|
43
|
+
|
44
|
+
("parses an expression"
|
45
|
+
(parse "(foo bar \"hello, String\") 1 2 (3 t nil) nil")
|
46
|
+
((foo bar "hello, String") 1 2 (3 t nil))))
|
47
|
+
|
48
|
+
(suite "parse-in-string"
|
49
|
+
("parses a plain string"
|
50
|
+
(parse-in-string "hello, world, take me to your dealer")
|
51
|
+
"hello, world, take me to your dealer")
|
52
|
+
|
53
|
+
("parses a plain string with interpolations"
|
54
|
+
(parse-in-string (joinstr "" (list "hello, " '~ "(world), take me to your " '~ "dealer please")))
|
55
|
+
(string-pieces "hello, " (world) ", take me to your " dealer " please")))))
|
data/lib/nydp.rb
CHANGED
@@ -7,33 +7,43 @@ module Nydp
|
|
7
7
|
def self.loadfiles; PLUGINS.map(&:loadfiles).flatten ; end
|
8
8
|
def self.testfiles; PLUGINS.map(&:testfiles).flatten ; end
|
9
9
|
def self.plugin_names ; PLUGINS.map(&:name) ; end
|
10
|
-
def self.loadall
|
10
|
+
def self.loadall ns, files
|
11
|
+
vm = VM.new
|
11
12
|
files.each { |f|
|
12
13
|
reader = Nydp::StreamReader.new(File.new(f))
|
13
14
|
Nydp::Runner.new(vm, ns, reader).run
|
14
15
|
}
|
15
16
|
end
|
16
17
|
|
17
|
-
def self.
|
18
|
-
puts "welcome to nydp"
|
18
|
+
def self.build_nydp extra_files=nil
|
19
19
|
ns = { }
|
20
20
|
setup(ns)
|
21
|
-
|
22
|
-
loadall
|
21
|
+
loadall ns, loadfiles
|
22
|
+
loadall ns, extra_files if extra_files
|
23
|
+
ns
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.apply_function ns, function_name, *args
|
27
|
+
function = Nydp::Symbol.mk(function_name, ns).value
|
28
|
+
args = Nydp::Pair.from_list args
|
29
|
+
vm = VM.new
|
30
|
+
|
31
|
+
function.invoke vm, args
|
32
|
+
return vm.pop_arg
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.repl
|
36
|
+
puts "welcome to nydp"
|
37
|
+
puts "^D to exit"
|
23
38
|
reader = Nydp::ReadlineReader.new $stdin, "nydp > "
|
24
|
-
Nydp::Runner.new(
|
39
|
+
Nydp::Runner.new(VM.new, build_nydp, reader, $stdout).run
|
25
40
|
end
|
26
41
|
|
27
42
|
def self.tests *options
|
28
43
|
verbose = options.include?(:verbose) ? "t" : "nil"
|
29
44
|
puts "welcome to nydp : running tests"
|
30
|
-
ns = { }
|
31
|
-
setup(ns)
|
32
|
-
vm = VM.new
|
33
|
-
loadall vm, ns, loadfiles
|
34
|
-
loadall vm, ns, testfiles
|
35
45
|
reader = Nydp::StringReader.new "(run-all-tests #{verbose})"
|
36
|
-
Nydp::Runner.new(
|
46
|
+
Nydp::Runner.new(VM.new, build_nydp(testfiles), reader).run
|
37
47
|
end
|
38
48
|
|
39
49
|
end
|
data/lib/nydp/assignment.rb
CHANGED
@@ -30,9 +30,11 @@ module Nydp
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def to_s
|
33
|
-
"#assignment #{@instructions.cdr.car} #{@value_src}"
|
33
|
+
"#assignment #{@instructions.cdr.car} #{@value_src.inspect}"
|
34
34
|
end
|
35
35
|
|
36
|
+
def inspect; to_s ; end
|
37
|
+
|
36
38
|
def execute vm
|
37
39
|
vm.push_instructions @instructions, vm.peek_context
|
38
40
|
end
|
data/lib/nydp/builtin.rb
CHANGED
@@ -1,15 +1,12 @@
|
|
1
1
|
require 'nydp'
|
2
|
+
require 'nydp/error'
|
2
3
|
|
3
4
|
module Nydp::Builtin
|
4
5
|
module Base
|
5
|
-
def indent_text txt
|
6
|
-
txt.split(/\n/).map { |line| " #{line}"}.join("\n")
|
7
|
-
end
|
8
|
-
|
9
6
|
def invoke vm, args
|
10
7
|
builtin_invoke vm, args
|
11
8
|
rescue Exception => e
|
12
|
-
new_msg = "Invoking #{self.class.name}\nwith args #{args}\nraised\n#{indent_text e.message}"
|
9
|
+
new_msg = "Invoking #{self.class.name}\nwith args #{args}\nraised\n#{Nydp.indent_text e.message}"
|
13
10
|
raise $!, new_msg, $!.backtrace
|
14
11
|
end
|
15
12
|
end
|
data/lib/nydp/builtin/eval.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
require "nydp/vm"
|
2
|
+
|
3
|
+
class Nydp::Builtin::HandleError
|
4
|
+
include Nydp::Helper
|
5
|
+
|
6
|
+
class CatchError
|
7
|
+
include Nydp::Helper, Nydp::VM::HandleError
|
8
|
+
|
9
|
+
attr_reader :handler, :vm_arg_array_size
|
10
|
+
|
11
|
+
def initialize handler, vm_arg_array_size
|
12
|
+
@handler, @vm_arg_array_size = handler, vm_arg_array_size
|
13
|
+
end
|
14
|
+
|
15
|
+
def execute vm
|
16
|
+
e = vm.unhandled_error
|
17
|
+
vm.unhandled_error = nil
|
18
|
+
return unless e
|
19
|
+
|
20
|
+
vm.args = vm.args[0...vm_arg_array_size]
|
21
|
+
|
22
|
+
handler.invoke vm, cons(r2n e.message, nil)
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
"(on-err: #{handler})"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def invoke vm, args
|
31
|
+
fn_handle = args.car
|
32
|
+
fn_tricky = args.cdr.car
|
33
|
+
|
34
|
+
catcher_instructions = Nydp::Pair.from_list [CatchError.new(fn_handle, vm.args.size)]
|
35
|
+
vm.push_instructions catcher_instructions, vm.peek_context
|
36
|
+
|
37
|
+
fn_tricky.invoke vm, Nydp.NIL
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Nydp::Builtin::ParseInString
|
2
|
+
def initialize ns
|
3
|
+
@parser = Nydp::Parser.new(ns)
|
4
|
+
end
|
5
|
+
|
6
|
+
def invoke vm, args
|
7
|
+
tokens = Nydp::Tokeniser.new Nydp::StringReader.new args.car.to_s
|
8
|
+
expr = @parser.string(tokens, "", :eof)
|
9
|
+
vm.push_arg expr
|
10
|
+
end
|
11
|
+
end
|
data/lib/nydp/context_symbol.rb
CHANGED
@@ -1,22 +1,54 @@
|
|
1
1
|
module Nydp
|
2
|
+
class ContextLookup0 ; def self.get_context ctx; ctx; end; end
|
3
|
+
class ContextLookup1 ; def self.get_context ctx; ctx.parent; end; end
|
4
|
+
class ContextLookup2 ; def self.get_context ctx; ctx.parent.parent; end; end
|
5
|
+
class ContextLookup3 ; def self.get_context ctx; ctx.parent.parent.parent; end; end
|
6
|
+
class ContextLookup4 ; def self.get_context ctx; ctx.parent.parent.parent.parent; end; end
|
7
|
+
class ContextLookup5 ; def self.get_context ctx; ctx.parent.parent.parent.parent.parent; end; end
|
8
|
+
class ContextLookup6 ; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent; end; end
|
9
|
+
class ContextLookup7 ; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent; end; end
|
10
|
+
class ContextLookup8 ; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent; end; end
|
11
|
+
class ContextLookup9 ; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
|
12
|
+
class ContextLookup10; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
|
13
|
+
class ContextLookup11; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
|
14
|
+
class ContextLookup12; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
|
15
|
+
class ContextLookup13; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
|
16
|
+
class ContextLookup14; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
|
17
|
+
class ContextLookup15; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
|
18
|
+
class ContextLookup16; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
|
19
|
+
class ContextLookup17; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
|
20
|
+
class ContextLookup18; def self.get_context ctx; ctx.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.parent; end; end
|
21
|
+
class ContextLookupN
|
22
|
+
def initialize depth ; @depth = depth ; end
|
23
|
+
def get_context ctx ; ctx.nth(@depth) ; end
|
24
|
+
end
|
25
|
+
|
2
26
|
class ContextSymbol
|
3
|
-
attr_accessor :depth, :name
|
27
|
+
attr_accessor :depth, :name, :binding_index
|
4
28
|
|
5
|
-
def initialize depth, name
|
6
|
-
@
|
29
|
+
def initialize depth, name, binding_index
|
30
|
+
@ctx_lookup = build_lookup depth
|
31
|
+
@depth, @name, @binding_index = depth, name, binding_index
|
7
32
|
end
|
8
33
|
|
34
|
+
def get_context(context); @ctx_lookup.get_context context; end
|
35
|
+
|
9
36
|
def value context
|
10
|
-
context
|
37
|
+
get_context(context).at_index(binding_index)
|
11
38
|
end
|
12
39
|
|
13
40
|
def assign value, context
|
14
|
-
context
|
41
|
+
get_context(context).set_index(binding_index, value)
|
15
42
|
end
|
16
43
|
|
17
44
|
def inspect; to_s; end
|
18
45
|
def to_s
|
19
|
-
"[#{depth}]#{name}"
|
46
|
+
"[#{depth}##{binding_index}]#{name}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def build_lookup depth
|
50
|
+
fast = Nydp.const_get "ContextLookup#{depth}" rescue nil
|
51
|
+
return fast || ContextLookupN.new(depth)
|
20
52
|
end
|
21
53
|
end
|
22
54
|
end
|
data/lib/nydp/core.rb
CHANGED
@@ -41,6 +41,7 @@ module Nydp
|
|
41
41
|
Symbol.mk(:p, ns).assign(Nydp::Builtin::Puts.new)
|
42
42
|
Symbol.mk(:PI, ns).assign Literal.new(3.1415)
|
43
43
|
Symbol.mk(:nil, ns).assign Nydp.NIL
|
44
|
+
Symbol.mk(:sqrt, ns).assign Nydp::Builtin::Sqrt.new
|
44
45
|
Symbol.mk(:t, ns).assign Nydp.T
|
45
46
|
Symbol.mk(:sym, ns).assign Nydp::Builtin::ToSym.new(ns)
|
46
47
|
Symbol.mk(:ensuring, ns).assign(Nydp::Builtin::Ensuring.new)
|
@@ -48,12 +49,14 @@ module Nydp
|
|
48
49
|
Symbol.mk(:comment, ns).assign(Nydp::Builtin::Comment.new)
|
49
50
|
Symbol.mk(:millisecs, ns).assign(Nydp::Builtin::Millisecs.new)
|
50
51
|
Symbol.mk("load-tests", ns).assign(Nydp::Builtin::LoadTests.new(ns))
|
51
|
-
Symbol.mk("
|
52
|
-
Symbol.mk("
|
53
|
-
Symbol.mk("string
|
54
|
-
Symbol.mk("string
|
55
|
-
Symbol.mk("string-
|
56
|
-
Symbol.mk("
|
52
|
+
Symbol.mk("handle-error" , ns).assign(Nydp::Builtin::HandleError.new)
|
53
|
+
Symbol.mk("parse-in-string", ns).assign(Nydp::Builtin::ParseInString.new(ns))
|
54
|
+
Symbol.mk("random-string" , ns).assign(Nydp::Builtin::RandomString.new)
|
55
|
+
Symbol.mk("to-string" , ns).assign(Nydp::Builtin::ToString.new)
|
56
|
+
Symbol.mk("string-pieces" , ns).assign(Nydp::Builtin::StringPieces.new)
|
57
|
+
Symbol.mk("string-replace" , ns).assign(Nydp::Builtin::StringReplace.new)
|
58
|
+
Symbol.mk("string-split" , ns).assign(Nydp::Builtin::StringSplit.new )
|
59
|
+
Symbol.mk("thread-locals" , ns).assign(Nydp::Builtin::ThreadLocals.new)
|
57
60
|
Symbol.mk("type-of", ns).assign(Nydp::Builtin::TypeOf.new(ns))
|
58
61
|
Symbol.mk(:"eq?", ns).assign(Nydp::Builtin::IsEqual.new)
|
59
62
|
Symbol.mk(:"pair?", ns).assign(Nydp::Builtin::IsPair.new)
|
data/lib/nydp/error.rb
CHANGED
@@ -19,7 +19,7 @@ module Nydp
|
|
19
19
|
msg = "failed to execute invocation #{args.inspect}"
|
20
20
|
msg += "\nsource was #{source.inspect}"
|
21
21
|
msg += "\nfunction name was #{source.car.inspect}"
|
22
|
-
i_f = InvocationFailed.new "#{msg}\n#{
|
22
|
+
i_f = InvocationFailed.new "#{msg}\n#{e.message}"
|
23
23
|
i_f.set_backtrace e.backtrace
|
24
24
|
raise i_f
|
25
25
|
end
|
data/lib/nydp/lexical_context.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
class Nydp::LexicalContext
|
2
|
-
attr_reader :values, :parent
|
2
|
+
attr_reader :names, :values, :parent
|
3
3
|
|
4
4
|
def initialize parent
|
5
5
|
@parent = parent
|
6
|
-
@
|
6
|
+
@names = []
|
7
|
+
@values = []
|
7
8
|
end
|
8
9
|
|
9
10
|
def nth n
|
@@ -21,8 +22,17 @@ class Nydp::LexicalContext
|
|
21
22
|
values[name]
|
22
23
|
end
|
23
24
|
|
25
|
+
def at_index index
|
26
|
+
values[index]
|
27
|
+
end
|
28
|
+
|
24
29
|
def set name, value
|
25
|
-
|
30
|
+
names << name
|
31
|
+
values << value
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_index index, value
|
35
|
+
values[index] = value
|
26
36
|
end
|
27
37
|
|
28
38
|
def to_s_with_indent str
|