nydp 0.5.1 → 0.6.0
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/.gitignore +1 -0
- data/README.md +77 -56
- data/lib/lisp/core-000.nydp +1 -1
- data/lib/lisp/core-010-precompile.nydp +49 -29
- data/lib/lisp/core-012-utils.nydp +12 -8
- data/lib/lisp/core-015-documentation.nydp +41 -15
- data/lib/lisp/core-017-builtin-dox.nydp +621 -100
- data/lib/lisp/core-020-utils.nydp +33 -6
- data/lib/lisp/core-025-warnings.nydp +1 -1
- data/lib/lisp/core-030-syntax.nydp +64 -48
- data/lib/lisp/core-035-flow-control.nydp +20 -28
- data/lib/lisp/core-037-list-utils.nydp +84 -21
- data/lib/lisp/core-040-utils.nydp +8 -5
- data/lib/lisp/core-041-string-utils.nydp +17 -11
- data/lib/lisp/core-043-list-utils.nydp +140 -77
- data/lib/lisp/core-045-dox-utils.nydp +1 -0
- data/lib/lisp/core-050-test-runner.nydp +8 -12
- data/lib/lisp/core-070-prefix-list.nydp +19 -15
- data/lib/lisp/core-080-pretty-print.nydp +13 -5
- data/lib/lisp/core-090-hook.nydp +11 -11
- data/lib/lisp/core-100-utils.nydp +51 -66
- data/lib/lisp/core-110-hash-utils.nydp +34 -7
- data/lib/lisp/core-120-settings.nydp +14 -9
- data/lib/lisp/core-130-validations.nydp +28 -13
- data/lib/lisp/core-900-benchmarking.nydp +420 -47
- data/lib/lisp/tests/000-empty-args-examples.nydp +5 -0
- data/lib/lisp/tests/andify-examples.nydp +1 -1
- data/lib/lisp/tests/auto-hash-examples.nydp +6 -1
- data/lib/lisp/tests/best-examples.nydp +1 -1
- data/lib/lisp/tests/boot-tests.nydp +1 -1
- data/lib/lisp/tests/date-examples.nydp +129 -102
- data/lib/lisp/tests/destructuring-examples.nydp +1 -1
- data/lib/lisp/tests/dox-tests.nydp +2 -2
- data/lib/lisp/tests/hash-examples.nydp +58 -33
- data/lib/lisp/tests/list-tests.nydp +137 -1
- data/lib/lisp/tests/pretty-print-tests.nydp +12 -0
- data/lib/lisp/tests/rotate-2d-array-examples.nydp +26 -0
- data/lib/lisp/tests/sort-examples.nydp +5 -5
- data/lib/lisp/tests/string-tests.nydp +16 -5
- data/lib/lisp/tests/syntax-tests.nydp +10 -2
- data/lib/lisp/tests/time-examples.nydp +8 -1
- data/lib/lisp/tests/unparse-tests.nydp +13 -7
- data/lib/nydp/assignment.rb +15 -28
- data/lib/nydp/builtin/abs.rb +4 -3
- data/lib/nydp/builtin/apply.rb +8 -10
- data/lib/nydp/builtin/cdr_set.rb +1 -1
- data/lib/nydp/builtin/comment.rb +1 -3
- data/lib/nydp/builtin/date.rb +11 -28
- data/lib/nydp/builtin/divide.rb +3 -10
- data/lib/nydp/builtin/ensuring.rb +6 -21
- data/lib/nydp/builtin/error.rb +2 -4
- data/lib/nydp/builtin/eval.rb +9 -4
- data/lib/nydp/builtin/greater_than.rb +7 -8
- data/lib/nydp/builtin/handle_error.rb +10 -34
- data/lib/nydp/builtin/hash.rb +24 -45
- data/lib/nydp/builtin/inspect.rb +1 -3
- data/lib/nydp/builtin/is_equal.rb +4 -7
- data/lib/nydp/builtin/less_than.rb +6 -7
- data/lib/nydp/builtin/log.rb +7 -0
- data/lib/nydp/builtin/math_ceiling.rb +1 -3
- data/lib/nydp/builtin/math_floor.rb +1 -3
- data/lib/nydp/builtin/math_power.rb +1 -3
- data/lib/nydp/builtin/math_round.rb +2 -2
- data/lib/nydp/builtin/minus.rb +7 -14
- data/lib/nydp/builtin/parse.rb +5 -5
- data/lib/nydp/builtin/parse_in_string.rb +5 -7
- data/lib/nydp/builtin/plus.rb +14 -31
- data/lib/nydp/builtin/pre_compile.rb +1 -3
- data/lib/nydp/builtin/puts.rb +4 -8
- data/lib/nydp/builtin/quit.rb +1 -1
- data/lib/nydp/builtin/rand.rb +6 -11
- data/lib/nydp/builtin/random_string.rb +2 -4
- data/lib/nydp/builtin/rng.rb +25 -0
- data/lib/nydp/builtin/ruby_wrap.rb +27 -14
- data/lib/nydp/builtin/script_run.rb +1 -3
- data/lib/nydp/builtin/set_intersection.rb +3 -4
- data/lib/nydp/builtin/set_union.rb +3 -4
- data/lib/nydp/builtin/sort.rb +2 -7
- data/lib/nydp/builtin/string_match.rb +5 -13
- data/lib/nydp/builtin/string_replace.rb +2 -7
- data/lib/nydp/builtin/string_split.rb +3 -8
- data/lib/nydp/builtin/sym.rb +2 -9
- data/lib/nydp/builtin/thread_locals.rb +2 -2
- data/lib/nydp/builtin/time.rb +38 -44
- data/lib/nydp/builtin/times.rb +6 -15
- data/lib/nydp/builtin/to_integer.rb +8 -14
- data/lib/nydp/builtin/to_string.rb +2 -13
- data/lib/nydp/builtin/type_of.rb +10 -16
- data/lib/nydp/builtin/vm_info.rb +2 -10
- data/lib/nydp/builtin.rb +15 -37
- data/lib/nydp/compiler.rb +29 -19
- data/lib/nydp/cond.rb +95 -88
- data/lib/nydp/context_symbol.rb +11 -9
- data/lib/nydp/core.rb +74 -73
- data/lib/nydp/core_ext.rb +87 -26
- data/lib/nydp/date.rb +22 -19
- data/lib/nydp/error.rb +2 -3
- data/lib/nydp/function_invocation.rb +76 -289
- data/lib/nydp/helper.rb +18 -9
- data/lib/nydp/interpreted_function.rb +159 -25
- data/lib/nydp/lexical_context.rb +9 -8
- data/lib/nydp/lexical_context_builder.rb +1 -1
- data/lib/nydp/literal.rb +3 -7
- data/lib/nydp/loop.rb +72 -0
- data/lib/nydp/namespace.rb +52 -0
- data/lib/nydp/pair.rb +146 -50
- data/lib/nydp/parser.rb +9 -11
- data/lib/nydp/plugin.rb +88 -19
- data/lib/nydp/runner.rb +141 -23
- data/lib/nydp/symbol.rb +16 -26
- data/lib/nydp/symbol_lookup.rb +3 -2
- data/lib/nydp/tokeniser.rb +1 -1
- data/lib/nydp/truth.rb +2 -37
- data/lib/nydp/version.rb +1 -1
- data/lib/nydp.rb +33 -44
- data/nydp.gemspec +2 -1
- data/spec/date_spec.rb +26 -32
- data/spec/embedded_spec.rb +22 -22
- data/spec/error_spec.rb +12 -16
- data/spec/foreign_hash_spec.rb +21 -36
- data/spec/hash_non_hash_behaviour_spec.rb +12 -29
- data/spec/hash_spec.rb +36 -49
- data/spec/literal_spec.rb +6 -6
- data/spec/nydp_spec.rb +14 -14
- data/spec/pair_spec.rb +8 -8
- data/spec/parser_spec.rb +41 -37
- data/spec/rand_spec.rb +1 -4
- data/spec/spec_helper.rb +3 -3
- data/spec/string_atom_spec.rb +15 -16
- data/spec/symbol_spec.rb +27 -52
- data/spec/thread_local_spec.rb +23 -8
- data/spec/time_spec.rb +4 -10
- data/spec/tokeniser_spec.rb +10 -10
- metadata +25 -13
- data/lib/nydp/builtin/modulo.rb +0 -11
- data/lib/nydp/builtin/regexp.rb +0 -7
- data/lib/nydp/builtin/sqrt.rb +0 -7
- data/lib/nydp/builtin/string_pad_left.rb +0 -7
- data/lib/nydp/builtin/string_pad_right.rb +0 -7
- data/lib/nydp/hash.rb +0 -9
- data/lib/nydp/image_store.rb +0 -21
- data/lib/nydp/vm.rb +0 -129
data/lib/nydp/symbol.rb
CHANGED
|
@@ -10,6 +10,7 @@ class Nydp::Symbol
|
|
|
10
10
|
def initialize name
|
|
11
11
|
name = name.to_s
|
|
12
12
|
@name = name.to_sym
|
|
13
|
+
raise "cannot be symbol : #{name.inspect}" if @name == :nil || @name == :t
|
|
13
14
|
@inspection = "|#{name.gsub(/\|/, '\|')}|" if untidy(name)
|
|
14
15
|
end
|
|
15
16
|
|
|
@@ -20,19 +21,21 @@ class Nydp::Symbol
|
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
def value context=nil
|
|
23
|
-
raise Unbound.new("unbound symbol: #{self.inspect}") if @value == nil
|
|
24
24
|
@value
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
def
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
def ruby_name
|
|
28
|
+
"ns_#{name.to_s._nydp_name_to_rb_name}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def compile_to_ruby indent, src, opts=nil
|
|
32
|
+
"#{indent}ns.#{ruby_name}"
|
|
31
33
|
end
|
|
32
34
|
|
|
33
|
-
def self.
|
|
34
|
-
name
|
|
35
|
-
|
|
35
|
+
def self.special name
|
|
36
|
+
return nil if name == :nil
|
|
37
|
+
return true if name == :t
|
|
38
|
+
nil
|
|
36
39
|
end
|
|
37
40
|
|
|
38
41
|
def self.find name, ns ; ns[name.to_sym] ; end
|
|
@@ -47,7 +50,11 @@ class Nydp::Symbol
|
|
|
47
50
|
def < other ; self.name < other.name ; end
|
|
48
51
|
def <=> other ; self.name <=> other.name ; end
|
|
49
52
|
def assign value, _=nil ; @value = value ; end
|
|
50
|
-
|
|
53
|
+
|
|
54
|
+
def ns_assign ns, value
|
|
55
|
+
value.is_named(@name) if value.respond_to?(:is_named)
|
|
56
|
+
ns.send(:"#{ruby_name}=", value)
|
|
57
|
+
end
|
|
51
58
|
|
|
52
59
|
def == other
|
|
53
60
|
other.is_a?(Nydp::Symbol) && (self.name == other.name)
|
|
@@ -55,20 +62,3 @@ class Nydp::Symbol
|
|
|
55
62
|
|
|
56
63
|
alias eql? ==
|
|
57
64
|
end
|
|
58
|
-
|
|
59
|
-
class Nydp::FrozenSymbol < Nydp::Symbol
|
|
60
|
-
@@frozen = { }
|
|
61
|
-
|
|
62
|
-
def self.mk name
|
|
63
|
-
name = name.to_s.to_sym
|
|
64
|
-
@@frozen[name] ||= new(name)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def value _=nil
|
|
68
|
-
raise Unbound.new("frozen symbol: #{self.inspect}")
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def assign v, _=nil
|
|
72
|
-
raise "can't assign to frozen: #{self.inspect}"
|
|
73
|
-
end
|
|
74
|
-
end
|
data/lib/nydp/symbol_lookup.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Nydp
|
|
|
11
11
|
bindings
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def self.build name, original_bindings
|
|
14
|
+
def self.build name, original_bindings, ns
|
|
15
15
|
effective_bindings = skip_empty original_bindings
|
|
16
16
|
depth = 0
|
|
17
17
|
while NIL != effective_bindings
|
|
@@ -24,7 +24,8 @@ module Nydp
|
|
|
24
24
|
effective_bindings = skip_empty effective_bindings.cdr
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
|
-
|
|
27
|
+
|
|
28
|
+
Nydp::Symbol.new name.to_s.to_sym
|
|
28
29
|
end
|
|
29
30
|
end
|
|
30
31
|
end
|
data/lib/nydp/tokeniser.rb
CHANGED
|
@@ -89,7 +89,7 @@ module Nydp
|
|
|
89
89
|
@finished = true
|
|
90
90
|
return nil
|
|
91
91
|
elsif comment = s.scan(COMMENT)
|
|
92
|
-
tok = [:comment, comment.gsub(/^;;?\s
|
|
92
|
+
tok = [:comment, comment.gsub(/^;;?\s?/, '')]
|
|
93
93
|
elsif open_str = s.scan(QUOTE)
|
|
94
94
|
tok = [:string_open_delim, open_str]
|
|
95
95
|
elsif open_sym = s.scan(PIPE)
|
data/lib/nydp/truth.rb
CHANGED
|
@@ -1,41 +1,6 @@
|
|
|
1
1
|
require 'singleton'
|
|
2
2
|
|
|
3
3
|
module Nydp
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def init_with *; Nydp::T ; end
|
|
7
|
-
def to_s ; 't' ; end
|
|
8
|
-
def inspect ; 't' ; end
|
|
9
|
-
def assign *_ ; self ; end
|
|
10
|
-
def nydp_type ; :truth ; end
|
|
11
|
-
def to_ruby ; true ; end
|
|
12
|
-
def _nydp_get a ; Nydp::T ; end
|
|
13
|
-
def _nydp_set a, v ; Nydp::T ; end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
class Nil
|
|
17
|
-
include Singleton, Enumerable
|
|
18
|
-
def init_with * ; Nydp::NIL ; end
|
|
19
|
-
def car ; self ; end
|
|
20
|
-
def cdr ; self ; end
|
|
21
|
-
def size ; 0 ; end
|
|
22
|
-
def is? other ; self.equal? other ; end
|
|
23
|
-
def isnt? other ; !self.equal? other ; end
|
|
24
|
-
def to_s ; "" ; end
|
|
25
|
-
def + other ; other ; end
|
|
26
|
-
def copy ; self ; end
|
|
27
|
-
def assign *_ ; self ; end
|
|
28
|
-
def inspect ; "nil" ; end
|
|
29
|
-
def nydp_type ; :nil ; end
|
|
30
|
-
def to_ruby ; nil ; end
|
|
31
|
-
def execute vm ; vm.push_arg self ; end
|
|
32
|
-
def _nydp_get a ; Nydp::NIL ; end
|
|
33
|
-
def _nydp_set a, v ; Nydp::NIL ; end
|
|
34
|
-
def each ; ; end # nil behaves like an empty list
|
|
35
|
-
def & other ; self ; end
|
|
36
|
-
def | other ; other ; end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
NIL = Nil.instance
|
|
40
|
-
T = Truth.instance
|
|
4
|
+
NIL = nil
|
|
5
|
+
T = true
|
|
41
6
|
end
|
data/lib/nydp/version.rb
CHANGED
data/lib/nydp.rb
CHANGED
|
@@ -2,30 +2,19 @@ require 'date'
|
|
|
2
2
|
require 'set'
|
|
3
3
|
|
|
4
4
|
module Nydp
|
|
5
|
-
|
|
6
|
-
attr_accessor :logger # not used by this gem but very useful in your app
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
class Namespace < Hash
|
|
10
|
-
end
|
|
5
|
+
GENERATED_CLASS_PREFIX = "NydpGenerated"
|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
vm = VM.new(ns)
|
|
15
|
-
function = Symbol.mk(function_name.to_sym, ns).value
|
|
16
|
-
function.invoke vm, r2n(args)
|
|
17
|
-
vm.thread
|
|
18
|
-
rescue StandardError => e
|
|
19
|
-
friendly_args = args.map { |a| a.respond_to?(:_nydp_compact_inspect) ? a._nydp_compact_inspect : a }
|
|
20
|
-
raise Nydp::Error.new("Invoking #{function_name}\nwith args #{friendly_args.inspect}")
|
|
7
|
+
class << self
|
|
8
|
+
attr_accessor :logger # set this if you plan on using 'log
|
|
21
9
|
end
|
|
22
10
|
|
|
23
|
-
def self.
|
|
24
|
-
def self.
|
|
25
|
-
def self.
|
|
26
|
-
def self.
|
|
27
|
-
def self.
|
|
28
|
-
def self.
|
|
11
|
+
def self.apply_function ns, name, *args ; ns.apply name, *args ; end
|
|
12
|
+
def self.reader name, txt ; Nydp::StringReader.new name, txt ; end
|
|
13
|
+
def self.eval_src ns, src_txt, name=nil ; eval_with Nydp::Runner, ns, src_txt, name ; end
|
|
14
|
+
def self.eval_with runner, ns, src_txt, name ; runner.new(ns, reader(name, src_txt), nil, name).run ; end
|
|
15
|
+
def self.ms t1, t0 ; ((t1 - t0) * 1000).to_i ; end
|
|
16
|
+
def self.new_tokeniser reader ; Nydp::Tokeniser.new reader ; end
|
|
17
|
+
def self.new_parser ; Nydp::Parser.new ; end
|
|
29
18
|
|
|
30
19
|
def self.indent_message indent, msg
|
|
31
20
|
msg.split(/\n/).map { |line| "#{indent}#{line}" }.join("\n")
|
|
@@ -39,7 +28,7 @@ module Nydp
|
|
|
39
28
|
puts "\n#{indent}Caused by:"
|
|
40
29
|
handle_run_error e.cause, "#{indent} "
|
|
41
30
|
else
|
|
42
|
-
e.backtrace.each do |b|
|
|
31
|
+
Nydp.enhance_backtrace(e.backtrace).each do |b|
|
|
43
32
|
puts "#{indent}#{b}"
|
|
44
33
|
end
|
|
45
34
|
end
|
|
@@ -54,34 +43,34 @@ module Nydp
|
|
|
54
43
|
end
|
|
55
44
|
|
|
56
45
|
def self.repl options={ }
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
46
|
+
launch_time = Time.now
|
|
47
|
+
silent = options.delete :silent
|
|
48
|
+
ns = options.delete :ns
|
|
49
|
+
last_script_time = Time.now
|
|
50
|
+
puts "welcome to nydp #{options.inspect}" unless silent
|
|
51
|
+
reader = Nydp::ReadlineReader.new $stdin, "nydp > "
|
|
52
|
+
ns ||= build_nydp do |script|
|
|
53
|
+
this_script_time = Time.now
|
|
54
|
+
puts "script #{script} time #{ms this_script_time, last_script_time}ms" if options[:verbose]
|
|
55
|
+
last_script_time = this_script_time
|
|
56
|
+
end
|
|
57
|
+
load_time = Time.now
|
|
58
|
+
puts "nydp v#{Nydp::VERSION} repl ready in #{ms(load_time, launch_time)}ms" unless silent
|
|
59
|
+
puts "^D to exit" unless silent
|
|
60
|
+
while !options[:exit]
|
|
61
|
+
toplevel do
|
|
62
|
+
Nydp::Runner.new(ns, reader, $stdout, "<stdin>").run
|
|
63
|
+
options[:exit] = true
|
|
68
64
|
end
|
|
69
|
-
load_time = Time.now
|
|
70
|
-
puts "nydp v#{Nydp::VERSION} repl ready in #{ms(load_time, launch_time)}ms" unless silent
|
|
71
|
-
puts "^D to exit" unless silent
|
|
72
|
-
return if options[:exit]
|
|
73
|
-
Nydp::Runner.new(VM.new(ns), ns, reader, $stdout, "<stdin>").run
|
|
74
|
-
# Nydp::Invocation.whazzup
|
|
75
65
|
end
|
|
66
|
+
# Nydp::Invocation.whazzup
|
|
76
67
|
end
|
|
77
68
|
|
|
78
69
|
def self.tests *options
|
|
79
70
|
toplevel do
|
|
80
|
-
verbose = options.include?(:verbose) ?
|
|
71
|
+
verbose = options.include?(:verbose) ? true : nil
|
|
81
72
|
puts "welcome to nydp : running tests"
|
|
82
|
-
|
|
83
|
-
ns = build_nydp
|
|
84
|
-
Nydp::Runner.new(VM.new(ns), ns, reader, nil, "<test-runner>").run
|
|
73
|
+
build_nydp.apply :"run-all-tests", verbose
|
|
85
74
|
end
|
|
86
75
|
end
|
|
87
76
|
end
|
|
@@ -105,4 +94,4 @@ require "nydp/string_token"
|
|
|
105
94
|
require "nydp/tokeniser"
|
|
106
95
|
require "nydp/parser"
|
|
107
96
|
require "nydp/compiler"
|
|
108
|
-
require "nydp/
|
|
97
|
+
require "nydp/namespace"
|
data/nydp.gemspec
CHANGED
|
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
19
|
spec.require_paths = ["lib"]
|
|
20
20
|
|
|
21
|
-
spec.add_development_dependency "
|
|
21
|
+
spec.add_development_dependency "irb"
|
|
22
|
+
spec.add_development_dependency "rake", "~> 13"
|
|
22
23
|
spec.add_development_dependency 'rspec' #, '~> 3.1'
|
|
23
24
|
end
|
data/spec/date_spec.rb
CHANGED
|
@@ -2,33 +2,29 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
describe Nydp::Date do
|
|
4
4
|
|
|
5
|
-
let(:ns) { { } }
|
|
6
|
-
let(:vm) { Nydp::VM.new(ns) }
|
|
7
5
|
|
|
8
6
|
it "converts ruby Date to Nydp::Date" do
|
|
9
7
|
rd = Date.parse "2015-06-08"
|
|
10
8
|
nd = Nydp.r2n rd
|
|
11
9
|
|
|
12
|
-
expect(nd). to be_a
|
|
10
|
+
expect(nd). to be_a ::Date
|
|
13
11
|
expect(nd.to_s). to eq "2015-06-08"
|
|
14
|
-
expect(nd.
|
|
12
|
+
expect(nd._nydp_inspect).to eq "#<Date: 2015-06-08 ((2457182j,0s,0n),+0s,2299161j)>"
|
|
15
13
|
expect(nd.to_ruby).to eq Date.parse("2015-06-08")
|
|
16
14
|
end
|
|
17
15
|
|
|
18
16
|
it "creates a new date" do
|
|
19
17
|
df = Nydp::Builtin::Date.instance
|
|
20
|
-
df.
|
|
21
|
-
nd
|
|
22
|
-
expect(nd).to
|
|
23
|
-
expect(nd.ruby_date).to eq Date.parse("2015-11-18")
|
|
18
|
+
nd = df.call 2015, 11, 18
|
|
19
|
+
expect(nd).to be_a ::Date
|
|
20
|
+
expect(nd).to eq Date.parse("2015-11-18")
|
|
24
21
|
end
|
|
25
22
|
|
|
26
23
|
it "returns today" do
|
|
27
24
|
df = Nydp::Builtin::Date.instance
|
|
28
|
-
df.
|
|
29
|
-
nd
|
|
30
|
-
expect(nd).to
|
|
31
|
-
expect(nd.ruby_date).to eq Date.today
|
|
25
|
+
nd = df.call
|
|
26
|
+
expect(nd).to be_a ::Date
|
|
27
|
+
expect(nd).to eq Date.today
|
|
32
28
|
end
|
|
33
29
|
|
|
34
30
|
it "returns date components" do
|
|
@@ -47,10 +43,9 @@ describe Nydp::Date do
|
|
|
47
43
|
it "works with builtin minus" do
|
|
48
44
|
minus = Nydp::Builtin::Minus.instance
|
|
49
45
|
|
|
50
|
-
minus.
|
|
51
|
-
diff = vm.args.pop
|
|
46
|
+
diff = minus.call d1, d0
|
|
52
47
|
|
|
53
|
-
expect(d0).to be_a
|
|
48
|
+
expect(d0).to be_a ::Date
|
|
54
49
|
expect(diff).to eq 6
|
|
55
50
|
end
|
|
56
51
|
|
|
@@ -58,25 +53,25 @@ describe Nydp::Date do
|
|
|
58
53
|
it "works with builtin greater-than when true" do
|
|
59
54
|
f = Nydp::Builtin::GreaterThan.instance
|
|
60
55
|
|
|
61
|
-
f.
|
|
56
|
+
a = f.call d1, d0
|
|
62
57
|
|
|
63
|
-
expect(
|
|
58
|
+
expect(a).to eq d0
|
|
64
59
|
end
|
|
65
60
|
|
|
66
61
|
it "compares with nil" do
|
|
67
62
|
f = Nydp::Builtin::GreaterThan.instance
|
|
68
63
|
|
|
69
|
-
f.
|
|
64
|
+
a = f.call d1, nil
|
|
70
65
|
|
|
71
|
-
expect(
|
|
66
|
+
expect(a).to eq Nydp::NIL
|
|
72
67
|
end
|
|
73
68
|
|
|
74
69
|
it "works with builtin greater-than when false" do
|
|
75
70
|
f = Nydp::Builtin::GreaterThan.instance
|
|
76
71
|
|
|
77
|
-
f.
|
|
72
|
+
a = f.call d0, d1
|
|
78
73
|
|
|
79
|
-
expect(
|
|
74
|
+
expect(a).to eq Nydp::NIL
|
|
80
75
|
end
|
|
81
76
|
end
|
|
82
77
|
|
|
@@ -84,37 +79,36 @@ describe Nydp::Date do
|
|
|
84
79
|
it "works with builtin less-than when true" do
|
|
85
80
|
f = Nydp::Builtin::LessThan.instance
|
|
86
81
|
|
|
87
|
-
f.
|
|
82
|
+
a = f.call d0, d1
|
|
88
83
|
|
|
89
|
-
expect(
|
|
84
|
+
expect(a).to eq d1
|
|
90
85
|
end
|
|
91
86
|
|
|
92
87
|
it "works with builtin less-than when false" do
|
|
93
88
|
f = Nydp::Builtin::LessThan.instance
|
|
94
89
|
|
|
95
|
-
f.
|
|
90
|
+
a = f.call d1, d0
|
|
96
91
|
|
|
97
|
-
expect(
|
|
92
|
+
expect(a).to eq Nydp::NIL
|
|
98
93
|
end
|
|
99
94
|
|
|
100
95
|
it "compares with nil" do
|
|
101
96
|
f = Nydp::Builtin::LessThan.instance
|
|
102
97
|
|
|
103
|
-
f.
|
|
98
|
+
a = f.call d1, nil
|
|
104
99
|
|
|
105
|
-
expect(
|
|
100
|
+
expect(a).to eq Nydp::NIL
|
|
106
101
|
end
|
|
107
102
|
end
|
|
108
103
|
|
|
109
104
|
it "works with builtin plus" do
|
|
110
105
|
plus = Nydp::Builtin::Plus.instance
|
|
111
106
|
|
|
112
|
-
plus.
|
|
113
|
-
sum = vm.args.pop
|
|
107
|
+
sum = plus.call d0, 5
|
|
114
108
|
|
|
115
|
-
expect(d0) .to be_a
|
|
116
|
-
expect(sum).to be_a
|
|
117
|
-
expect(sum
|
|
109
|
+
expect(d0) .to be_a ::Date
|
|
110
|
+
expect(sum).to be_a ::Date
|
|
111
|
+
expect(sum).to eq(Date.today + 5)
|
|
118
112
|
end
|
|
119
113
|
end
|
|
120
114
|
|
data/spec/embedded_spec.rb
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Nydp::Parser do
|
|
4
|
-
let(:aa) {
|
|
5
|
-
let(:a) {
|
|
6
|
-
let(:b) {
|
|
7
|
-
let(:c) {
|
|
8
|
-
let(:d) {
|
|
9
|
-
let(:zz) {
|
|
10
|
-
let(:foo) {
|
|
11
|
-
let(:bar) {
|
|
12
|
-
let(:zab) {
|
|
13
|
-
let(:quote) {
|
|
14
|
-
let(:quasiquote) {
|
|
15
|
-
let(:unquote) {
|
|
16
|
-
let(:unquote_splicing) {
|
|
17
|
-
let(:comment) {
|
|
18
|
-
let(:dotsyn) {
|
|
19
|
-
let(:cocosyn) {
|
|
20
|
-
let(:colosyn) {
|
|
4
|
+
let(:aa) { :aa }
|
|
5
|
+
let(:a) { :a }
|
|
6
|
+
let(:b) { :b }
|
|
7
|
+
let(:c) { :c }
|
|
8
|
+
let(:d) { :d }
|
|
9
|
+
let(:zz) { :zz }
|
|
10
|
+
let(:foo) { :foo }
|
|
11
|
+
let(:bar) { :bar }
|
|
12
|
+
let(:zab) { :zab }
|
|
13
|
+
let(:quote) { :quote }
|
|
14
|
+
let(:quasiquote) { :quasiquote }
|
|
15
|
+
let(:unquote) { :unquote }
|
|
16
|
+
let(:unquote_splicing) { :"unquote-splicing" }
|
|
17
|
+
let(:comment) { :comment }
|
|
18
|
+
let(:dotsyn) { :"dot-syntax" }
|
|
19
|
+
let(:cocosyn) { :"colon-colon-syntax" }
|
|
20
|
+
let(:colosyn) { :"colon-syntax" }
|
|
21
21
|
|
|
22
22
|
def parse_string txt
|
|
23
|
-
reader = Nydp::StringReader.new txt
|
|
24
|
-
Nydp.new_parser
|
|
23
|
+
reader = Nydp::StringReader.new "test", txt
|
|
24
|
+
Nydp.new_parser.embedded(Nydp.new_tokeniser(reader))
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it "should parse empty string" do
|
|
@@ -33,14 +33,14 @@ describe Nydp::Parser do
|
|
|
33
33
|
it "should parse external text" do
|
|
34
34
|
actual = parse_string "a fluffy bunny!"
|
|
35
35
|
expect(actual) .to eq "a fluffy bunny!"
|
|
36
|
-
expect(actual.
|
|
36
|
+
expect(actual._nydp_inspect).to eq '"a fluffy bunny!"'
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
it "should parse a string delimited by eof" do
|
|
40
40
|
expected = pair_list([sym('string-pieces'), Nydp::StringFragmentCloseToken.new('a fluffy bunny!','a fluffy bunny!')])
|
|
41
41
|
actual = parse_string "a fluffy bunny!"
|
|
42
42
|
expect(actual) .to eq "a fluffy bunny!"
|
|
43
|
-
expect(actual.
|
|
43
|
+
expect(actual._nydp_inspect).to eq '"a fluffy bunny!"'
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
it "should parse a string with embedded code, delimited by eof" do
|
|
@@ -104,6 +104,6 @@ describe Nydp::Parser do
|
|
|
104
104
|
|
|
105
105
|
it "parses a string that looks like html with little bits of embedded code in it" do
|
|
106
106
|
parsed = parse_string "<div id='item_~{id}'><label>~{data-label-1}</label> ~{data-content-1}</div>"
|
|
107
|
-
expect(parsed.
|
|
107
|
+
expect(parsed._nydp_inspect).to eq '(string-pieces "<div id=\'item_" (brace-list id) "\'><label>" (brace-list data-label-1) "</label> " (brace-list data-content-1) "</div>")'
|
|
108
108
|
end
|
|
109
109
|
end
|
data/spec/error_spec.rb
CHANGED
|
@@ -1,40 +1,36 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
describe Nydp
|
|
4
|
-
let(:ns) { { } }
|
|
5
|
-
let(:vm) { Nydp::VM.new(ns) }
|
|
3
|
+
describe Nydp do
|
|
6
4
|
|
|
7
5
|
def run txt
|
|
8
6
|
Nydp.setup ns
|
|
9
|
-
Nydp::Runner.new(
|
|
7
|
+
Nydp::Runner.new(ns, Nydp::StringReader.new("test", txt)).run
|
|
10
8
|
end
|
|
11
9
|
|
|
12
10
|
describe "unhandled_error" do
|
|
13
11
|
it "raises a helpful error" do
|
|
14
12
|
error = nil
|
|
15
13
|
begin
|
|
16
|
-
run "
|
|
14
|
+
run "(/ 10 0)"
|
|
17
15
|
rescue StandardError => e
|
|
18
16
|
error = e
|
|
19
17
|
end
|
|
20
18
|
|
|
21
19
|
expect(error).to be_a Nydp::Error
|
|
22
|
-
expect(error.message).to eq "failed to eval
|
|
20
|
+
expect(error.message).to eq "failed to eval (/ 10 0) from src (/ 10 0)"
|
|
23
21
|
|
|
24
|
-
expect(error.cause).to be_a
|
|
25
|
-
expect(error.cause.message).to eq "
|
|
22
|
+
expect(error.cause).to be_a RuntimeError
|
|
23
|
+
expect(error.cause.message).to eq "Called builtin//
|
|
24
|
+
with args
|
|
25
|
+
10
|
|
26
|
+
0"
|
|
26
27
|
|
|
27
|
-
expect(
|
|
28
|
+
expect(error.cause.cause).to be_a ZeroDivisionError
|
|
29
|
+
expect(error.cause.cause.message).to eq "divided by 0"
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
it "recovers quickly from an error" do
|
|
31
|
-
|
|
32
|
-
run "dflkjdgjeirgjeoi"
|
|
33
|
-
rescue
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
expect(vm.unhandled_error).to eq nil
|
|
37
|
-
|
|
33
|
+
run "dflkjdgjeirgjeoi"
|
|
38
34
|
expect(run "(+ 2 3 4)").to eq 9
|
|
39
35
|
end
|
|
40
36
|
end
|
data/spec/foreign_hash_spec.rb
CHANGED
|
@@ -1,75 +1,61 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
|
|
3
|
-
describe
|
|
4
|
-
let(:vm) { Nydp::VM.new(ns) }
|
|
3
|
+
describe ::Hash do
|
|
5
4
|
|
|
6
5
|
describe "foreign hashes" do
|
|
7
6
|
let(:ahash) { Hash.new }
|
|
8
7
|
|
|
9
8
|
describe "hash set" do
|
|
10
9
|
it "returns a new Nydp hash" do
|
|
11
|
-
k =
|
|
10
|
+
k = :keysym
|
|
12
11
|
v = "foobar"
|
|
13
|
-
|
|
14
|
-
Nydp::Builtin::HashSet.instance.invoke vm, args
|
|
12
|
+
a = Nydp::Builtin::HashSet.instance.call ahash, k, v
|
|
15
13
|
|
|
16
14
|
expect(ahash[:keysym]). to eq "foobar"
|
|
17
15
|
expect(ahash[:keysym].class).to eq String
|
|
18
16
|
expect(ahash.keys). to eq [:keysym]
|
|
19
17
|
|
|
20
|
-
expect(
|
|
18
|
+
expect(a).to eq v
|
|
21
19
|
end
|
|
22
20
|
end
|
|
23
21
|
|
|
24
22
|
describe "hash get" do
|
|
25
23
|
it "converts ruby value to nydp value" do
|
|
26
24
|
ahash[:keysym] = "avalue"
|
|
27
|
-
k = sym("keysym")
|
|
28
|
-
args = [ ahash, k ]
|
|
29
25
|
|
|
30
|
-
Nydp::Builtin::HashGet.instance.
|
|
26
|
+
a = Nydp::Builtin::HashGet.instance.call ahash, :keysym
|
|
31
27
|
|
|
32
|
-
expect(
|
|
28
|
+
expect(a).to eq "avalue"
|
|
33
29
|
end
|
|
34
30
|
|
|
35
31
|
it "converts ruby nil to nydp value" do
|
|
36
|
-
|
|
37
|
-
args = [ ahash, k ]
|
|
32
|
+
a = Nydp::Builtin::HashGet.instance.call ahash, :keysym
|
|
38
33
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
expect(vm.args.pop).to eq Nydp::NIL
|
|
34
|
+
expect(a).to eq nil
|
|
42
35
|
end
|
|
43
36
|
|
|
44
37
|
it "converts ruby true to nydp value" do
|
|
45
38
|
ahash[:keysym] = true
|
|
46
|
-
k = sym("keysym")
|
|
47
|
-
args = [ ahash, k ]
|
|
48
39
|
|
|
49
|
-
Nydp::Builtin::HashGet.instance.
|
|
40
|
+
a = Nydp::Builtin::HashGet.instance.call ahash, :keysym
|
|
50
41
|
|
|
51
|
-
expect(
|
|
42
|
+
expect(a).to eq true
|
|
52
43
|
end
|
|
53
44
|
end
|
|
54
45
|
|
|
55
46
|
describe "key?" do
|
|
56
47
|
it "returns t when key is present" do
|
|
57
48
|
ahash[:simon] = 24
|
|
58
|
-
k = sym("simon")
|
|
59
|
-
args = [ ahash, k ]
|
|
60
49
|
|
|
61
|
-
Nydp::Builtin::HashKeyPresent.instance.
|
|
50
|
+
a = Nydp::Builtin::HashKeyPresent.instance.call ahash, :simon
|
|
62
51
|
|
|
63
|
-
expect(
|
|
52
|
+
expect(a).to eq true
|
|
64
53
|
end
|
|
65
54
|
|
|
66
55
|
it "returns nil when key is absent" do
|
|
67
|
-
|
|
68
|
-
args = [ ahash, k ]
|
|
69
|
-
|
|
70
|
-
Nydp::Builtin::HashKeyPresent.instance.invoke vm, pair_list(args)
|
|
56
|
+
a = Nydp::Builtin::HashKeyPresent.instance.call ahash, :simon
|
|
71
57
|
|
|
72
|
-
expect(
|
|
58
|
+
expect(a).to eq nil
|
|
73
59
|
end
|
|
74
60
|
end
|
|
75
61
|
|
|
@@ -77,23 +63,22 @@ describe Nydp::Hash do
|
|
|
77
63
|
it "returns a list of keys" do
|
|
78
64
|
ahash[:k0] = 42
|
|
79
65
|
ahash[:k1] = 84
|
|
80
|
-
args = [ahash]
|
|
81
66
|
|
|
82
|
-
Nydp::Builtin::HashKeys.instance.
|
|
67
|
+
a = Nydp::Builtin::HashKeys.instance.call ahash
|
|
83
68
|
|
|
84
|
-
expect(
|
|
69
|
+
expect(a).to eq pair_list [:k0, :k1]
|
|
85
70
|
end
|
|
86
71
|
end
|
|
87
72
|
|
|
88
73
|
describe "hash-slice" do
|
|
89
74
|
it "returns a new hash containing only the given keys from the old hash" do
|
|
90
|
-
ahash[:k0] =
|
|
91
|
-
ahash[:k1] =
|
|
92
|
-
|
|
75
|
+
ahash[:k0] = 42
|
|
76
|
+
ahash[:k1] = 84
|
|
77
|
+
ahash[:k2] = 126
|
|
93
78
|
|
|
94
|
-
Nydp::Builtin::HashSlice.instance.
|
|
79
|
+
a = Nydp::Builtin::HashSlice.instance.call ahash, pair_list([:k0, :k1])
|
|
95
80
|
|
|
96
|
-
expect(
|
|
81
|
+
expect(a).to eq({ k0: 42, k1: 84 })
|
|
97
82
|
end
|
|
98
83
|
end
|
|
99
84
|
end
|