nydp 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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")))))
@@ -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 vm, ns, files
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.repl
18
- puts "welcome to nydp"
18
+ def self.build_nydp extra_files=nil
19
19
  ns = { }
20
20
  setup(ns)
21
- vm = VM.new
22
- loadall vm, ns, loadfiles
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(vm, ns, reader, $stdout).run
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(vm, ns, reader).run
46
+ Nydp::Runner.new(VM.new, build_nydp(testfiles), reader).run
37
47
  end
38
48
 
39
49
  end
@@ -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
@@ -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
@@ -1,7 +1,10 @@
1
+ require "nydp/vm"
2
+
1
3
  class Nydp::Builtin::Ensuring
2
4
  include Nydp::Helper
3
5
 
4
6
  class InvokeProtection
7
+ include Nydp::VM::Finally
5
8
  attr_reader :protection
6
9
 
7
10
  def initialize protection
@@ -9,6 +9,10 @@ class Nydp::Builtin::Eval
9
9
  end
10
10
 
11
11
  def to_s
12
- "Builtin:eval"
12
+ "eval"
13
+ end
14
+
15
+ def inspect
16
+ "Nydp::Builtin::Eval"
13
17
  end
14
18
  end
@@ -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
@@ -0,0 +1,5 @@
1
+ class Nydp::Builtin::Sqrt
2
+ def invoke vm, args
3
+ vm.push_arg Math.sqrt args.car
4
+ end
5
+ end
@@ -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
- @depth, @name = depth, name
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.nth(depth).at(name)
37
+ get_context(context).at_index(binding_index)
11
38
  end
12
39
 
13
40
  def assign value, context
14
- context.nth(depth).set(name, value)
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
@@ -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("random-string",ns).assign(Nydp::Builtin::RandomString.new)
52
- Symbol.mk("to-string", ns).assign(Nydp::Builtin::ToString.new)
53
- Symbol.mk("string-pieces",ns).assign(Nydp::Builtin::StringPieces.new)
54
- Symbol.mk("string-replace", ns).assign(Nydp::Builtin::StringReplace.new)
55
- Symbol.mk("string-split" , ns).assign(Nydp::Builtin::StringSplit.new )
56
- Symbol.mk("thread-locals" , ns).assign(Nydp::Builtin::ThreadLocals.new)
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)
@@ -1,4 +1,8 @@
1
1
  module Nydp
2
+ def self.indent_text txt
3
+ txt.split(/\n/).map { |line| " #{line}"}.join("\n")
4
+ end
5
+
2
6
  class Error < StandardError
3
7
  end
4
8
  end
@@ -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#{vm.error}#{e.message}"
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
@@ -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
- @values = { }
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
- values[name] = value
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