nydp 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +44 -0
- data/lib/lisp/core-010-precompile.nydp +13 -16
- data/lib/lisp/core-012-utils.nydp +21 -6
- data/lib/lisp/core-015-documentation.nydp +58 -24
- data/lib/lisp/core-017-builtin-dox.nydp +49 -42
- data/lib/lisp/core-020-utils.nydp +5 -5
- data/lib/lisp/core-030-syntax.nydp +191 -96
- data/lib/lisp/core-035-flow-control.nydp +41 -14
- data/lib/lisp/core-037-list-utils.nydp +36 -14
- data/lib/lisp/core-039-module.nydp +24 -0
- data/lib/lisp/core-040-utils.nydp +51 -23
- data/lib/lisp/core-041-string-utils.nydp +37 -9
- data/lib/lisp/core-042-date-utils.nydp +21 -1
- data/lib/lisp/core-043-list-utils.nydp +99 -73
- data/lib/lisp/core-045-dox-utils.nydp +5 -0
- data/lib/lisp/core-070-prefix-list.nydp +1 -1
- data/lib/lisp/core-080-pretty-print.nydp +57 -17
- data/lib/lisp/core-090-hook.nydp +35 -1
- data/lib/lisp/core-100-utils.nydp +110 -15
- data/lib/lisp/core-110-hash-utils.nydp +61 -0
- data/lib/lisp/core-120-settings.nydp +46 -0
- data/lib/lisp/core-130-validations.nydp +51 -0
- data/lib/lisp/{core-060-benchmarking.nydp → core-900-benchmarking.nydp} +107 -19
- data/lib/lisp/tests/accum-examples.nydp +28 -1
- data/lib/lisp/tests/aif-examples.nydp +8 -3
- data/lib/lisp/tests/andify-examples.nydp +7 -0
- data/lib/lisp/tests/at-syntax-examples.nydp +17 -0
- data/lib/lisp/tests/best-examples.nydp +9 -0
- data/lib/lisp/tests/builtin-tests.nydp +19 -0
- data/lib/lisp/tests/case-examples.nydp +14 -0
- data/lib/lisp/tests/cdr-set-examples.nydp +6 -0
- data/lib/lisp/tests/date-examples.nydp +56 -1
- data/lib/lisp/tests/destructuring-examples.nydp +46 -14
- data/lib/lisp/tests/detect-examples.nydp +12 -0
- data/lib/lisp/tests/dp-examples.nydp +24 -0
- data/lib/lisp/tests/each-tests.nydp +5 -0
- data/lib/lisp/tests/empty-examples.nydp +1 -1
- data/lib/lisp/tests/error-tests.nydp +4 -4
- data/lib/lisp/tests/explain-mac-examples.nydp +1 -1
- data/lib/lisp/tests/filter-forms-examples.nydp +15 -0
- data/lib/lisp/tests/foundation-test.nydp +12 -0
- data/lib/lisp/tests/hash-examples.nydp +26 -2
- data/lib/lisp/tests/list-grep-examples.nydp +40 -0
- data/lib/lisp/tests/list-tests.nydp +58 -1
- data/lib/lisp/tests/map-hash-examples.nydp +11 -0
- data/lib/lisp/tests/module-examples.nydp +10 -0
- data/lib/lisp/tests/multi-assign-examples.nydp +6 -0
- data/lib/lisp/tests/parser-tests.nydp +25 -0
- data/lib/lisp/tests/pretty-print-tests.nydp +17 -14
- data/lib/lisp/tests/set-difference-examples.nydp +8 -0
- data/lib/lisp/tests/set-intersection-examples.nydp +16 -0
- data/lib/lisp/tests/set-union-examples.nydp +8 -0
- data/lib/lisp/tests/settings-examples.nydp +40 -0
- data/lib/lisp/tests/sort-examples.nydp +8 -0
- data/lib/lisp/tests/string-tests.nydp +65 -1
- data/lib/lisp/tests/syntax-tests.nydp +5 -1
- data/lib/lisp/tests/to-integer-examples.nydp +16 -0
- data/lib/lisp/tests/validation-examples.nydp +15 -0
- data/lib/lisp/tests/zap-examples.nydp +12 -0
- data/lib/nydp.rb +13 -7
- data/lib/nydp/assignment.rb +10 -3
- data/lib/nydp/builtin.rb +1 -1
- data/lib/nydp/builtin/abs.rb +8 -0
- data/lib/nydp/builtin/cdr_set.rb +1 -6
- data/lib/nydp/builtin/date.rb +15 -1
- data/lib/nydp/builtin/error.rb +1 -1
- data/lib/nydp/builtin/handle_error.rb +1 -1
- data/lib/nydp/builtin/hash.rb +27 -45
- data/lib/nydp/builtin/inspect.rb +1 -1
- data/lib/nydp/builtin/plus.rb +10 -2
- data/lib/nydp/builtin/random_string.rb +2 -2
- data/lib/nydp/builtin/{car.rb → regexp.rb} +2 -2
- data/lib/nydp/builtin/ruby_wrap.rb +72 -0
- data/lib/nydp/builtin/string_match.rb +2 -2
- data/lib/nydp/builtin/string_pad_left.rb +7 -0
- data/lib/nydp/builtin/string_pad_right.rb +7 -0
- data/lib/nydp/builtin/string_replace.rb +1 -1
- data/lib/nydp/builtin/string_split.rb +4 -3
- data/lib/nydp/builtin/to_integer.rb +23 -0
- data/lib/nydp/builtin/to_string.rb +2 -9
- data/lib/nydp/builtin/type_of.rb +9 -6
- data/lib/nydp/closure.rb +0 -3
- data/lib/nydp/cond.rb +23 -1
- data/lib/nydp/context_symbol.rb +14 -6
- data/lib/nydp/core.rb +36 -28
- data/lib/nydp/core_ext.rb +54 -0
- data/lib/nydp/date.rb +37 -31
- data/lib/nydp/function_invocation.rb +34 -26
- data/lib/nydp/hash.rb +5 -6
- data/lib/nydp/helper.rb +41 -25
- data/lib/nydp/interpreted_function.rb +68 -40
- data/lib/nydp/literal.rb +1 -1
- data/lib/nydp/pair.rb +22 -5
- data/lib/nydp/parser.rb +11 -7
- data/lib/nydp/string_atom.rb +16 -22
- data/lib/nydp/symbol.rb +40 -27
- data/lib/nydp/symbol_lookup.rb +7 -7
- data/lib/nydp/tokeniser.rb +2 -2
- data/lib/nydp/truth.rb +17 -10
- data/lib/nydp/version.rb +1 -1
- data/lib/nydp/vm.rb +7 -2
- data/nydp.gemspec +2 -4
- data/spec/date_spec.rb +115 -22
- data/spec/embedded_spec.rb +12 -12
- data/spec/foreign_hash_spec.rb +14 -2
- data/spec/hash_non_hash_behaviour_spec.rb +7 -7
- data/spec/hash_spec.rb +24 -2
- data/spec/nydp_spec.rb +14 -2
- data/spec/pair_spec.rb +3 -1
- data/spec/parser_spec.rb +31 -20
- data/spec/rand_spec.rb +3 -3
- data/spec/spec_helper.rb +13 -1
- data/spec/symbol_spec.rb +31 -0
- data/spec/time_spec.rb +1 -1
- metadata +31 -38
- data/lib/nydp/builtin/cdr.rb +0 -7
- data/lib/nydp/builtin/cons.rb +0 -9
@@ -7,10 +7,18 @@
|
|
7
7
|
(⋃ '(a b c) '(a b d))
|
8
8
|
(a b c d))
|
9
9
|
|
10
|
+
("returns union of arg and nil"
|
11
|
+
(⋃ '(a b c) nil)
|
12
|
+
(a b c))
|
13
|
+
|
10
14
|
("returns union of three args"
|
11
15
|
(⋃ '(a b c d e) '(a b c d f) '(z b c d g))
|
12
16
|
(a b c d e f z g))
|
13
17
|
|
18
|
+
("returns union of arg nil arg"
|
19
|
+
(⋃ '(a b c d e) nil '(z b c d g))
|
20
|
+
(a b c d e z g))
|
21
|
+
|
14
22
|
("returns union of four args"
|
15
23
|
(⋃ '(a b c d e) '(a b c d f) '(z b d c g) '(z y g c d))
|
16
24
|
(a b c d e f z g y)))
|
@@ -0,0 +1,40 @@
|
|
1
|
+
(def-setting "testing.reset.string" "hello world")
|
2
|
+
(def-setting "testing.reset.fn" to-string)
|
3
|
+
|
4
|
+
(examples-for settings/fn
|
5
|
+
("returns arg if it is a sym"
|
6
|
+
(settings/fn 'foobar)
|
7
|
+
foobar)
|
8
|
+
|
9
|
+
("returns fn wrapper for arg if it is a string"
|
10
|
+
(settings/fn "hello")
|
11
|
+
(k "hello"))
|
12
|
+
|
13
|
+
("returns fn wrapper for arg if it is a number"
|
14
|
+
(settings/fn 42)
|
15
|
+
(k 42))
|
16
|
+
|
17
|
+
("returns fn wrapper for arg if it is nil"
|
18
|
+
(settings/fn nil)
|
19
|
+
(k nil))
|
20
|
+
|
21
|
+
("wraps arg in a fn expression if it is a hash"
|
22
|
+
(settings/fn '{ a 1 b 2 })
|
23
|
+
(k { a 1 b 2 }))
|
24
|
+
|
25
|
+
("wraps arg in a fn expression if it is a complex expression"
|
26
|
+
(settings/fn '(let foo this that (rfnwith (complex stuff) (%td.tricky#syntax))))
|
27
|
+
(fn (_) (let foo this that (rfnwith (complex stuff) ((percent-syntax || (dot-syntax td tricky#syntax))))))))
|
28
|
+
|
29
|
+
(examples-for reset-setting
|
30
|
+
("restores a setting to its original value"
|
31
|
+
(do (set-setting "testing.reset.string" "goodbye, dear life")
|
32
|
+
(reset-setting "testing.reset.string")
|
33
|
+
(setting "testing.reset.string"))
|
34
|
+
"hello world")
|
35
|
+
|
36
|
+
("restores a setting to its original function value"
|
37
|
+
(do (set-setting "testing.reset.fn" "goodbye, dear life")
|
38
|
+
(reset-setting "testing.reset.fn")
|
39
|
+
(setting "testing.reset.fn"))
|
40
|
+
"testing.reset.fn"))
|
@@ -28,3 +28,11 @@
|
|
28
28
|
(sort-by len
|
29
29
|
'("short" "very long" "sport" "very song" "min" "max"))
|
30
30
|
("max" "min" "sport" "short" "very song" "very long")))
|
31
|
+
|
32
|
+
(examples-for safe-sort-by
|
33
|
+
("sorts a list of hashes by a specified key"
|
34
|
+
(let hh (list { a 1 b 2 } { b 9 } { a 3 b 1 } { a nil b 8 })
|
35
|
+
(pp (safe-sort-by &a 99 hh)))
|
36
|
+
"({ a 1 b 2 } { a 3 b 1 }
|
37
|
+
{ a nil b 8 }
|
38
|
+
{ b 9 })"))
|
@@ -1,3 +1,51 @@
|
|
1
|
+
(examples-for string-eval-fn
|
2
|
+
("returns a function to eval a user-supplied string"
|
3
|
+
(let s "hello \~|u|, \~x + \~y is \~(+ x y), thank you!"
|
4
|
+
(let f (string-eval-fn s '(u x y))
|
5
|
+
(f "world" 37 5)))
|
6
|
+
"hello world, 37 + 5 is 42, thank you!"))
|
7
|
+
|
8
|
+
(examples-for string/eval-with-args
|
9
|
+
("evals a user-supplied string"
|
10
|
+
(let s "hello \~|u|, \~x + \~y is \~(+ x y), thank heavens!"
|
11
|
+
(string/eval-with-args s '(u x y) "world" 36 6))
|
12
|
+
"hello world, 36 + 6 is 42, thank heavens!")
|
13
|
+
|
14
|
+
("reports errors"
|
15
|
+
(on-err errors
|
16
|
+
(let s "hello \~|u|, \~x + \~y is \~(+ x y), thank heavens!"
|
17
|
+
(string/eval-with-args s '(a b c) "world" 36 6)))
|
18
|
+
("error evaluating \"hello \~|u|, \~x + \~y is \~(+ x y), thank heavens!\"
|
19
|
+
with arg names (a b c)
|
20
|
+
and args (\"world\" 36 6)"
|
21
|
+
"unbound symbol: y")))
|
22
|
+
|
23
|
+
(examples-for string/pad-left
|
24
|
+
("does not change a string whose length is greater than the given length"
|
25
|
+
(string/pad-left "Toronto" 3 "X")
|
26
|
+
"Toronto")
|
27
|
+
|
28
|
+
("adds left padding to a string such that the result is the given length"
|
29
|
+
(string/pad-left "toto" 8 "X")
|
30
|
+
"XXXXtoto")
|
31
|
+
|
32
|
+
("accepts multi-character padding"
|
33
|
+
(string/pad-left "toto" 12 "XYZ")
|
34
|
+
"XYZXYZXYtoto"))
|
35
|
+
|
36
|
+
(examples-for string/pad-right
|
37
|
+
("does not change a string whose length is greater than the given length"
|
38
|
+
(string/pad-right "Toronto" 3 "X")
|
39
|
+
"Toronto")
|
40
|
+
|
41
|
+
("adds right padding to a string such that the result is the given length"
|
42
|
+
(string/pad-right "toto" 8 "X")
|
43
|
+
"totoXXXX")
|
44
|
+
|
45
|
+
("accepts multi-character padding"
|
46
|
+
(string/pad-right "toto" 12 "XYZ")
|
47
|
+
"totoXYZXYZXY"))
|
48
|
+
|
1
49
|
(examples-for string-split
|
2
50
|
("splits a string using given expression"
|
3
51
|
(string-split "a and b and c and d" " and ")
|
@@ -7,6 +55,10 @@
|
|
7
55
|
(collect !empty? (string-split "word"))
|
8
56
|
("w" "o" "r" "d"))
|
9
57
|
|
58
|
+
("splits on regexp"
|
59
|
+
(string-split "hello, darkness ; my old friend\nI've come : to talk - with you again..." (regexp "\[\\n;:\\-,\]"))
|
60
|
+
("hello" " darkness " " my old friend" "I've come " " to talk " " with you again..."))
|
61
|
+
|
10
62
|
("returns empty leading, internal, and trailing segments"
|
11
63
|
(string-split "and" "and")
|
12
64
|
("" ""))
|
@@ -24,6 +76,15 @@
|
|
24
76
|
(string-replace "and|or" "x" "a and b or c and d")
|
25
77
|
"a x b x c x d"))
|
26
78
|
|
79
|
+
(examples-for string-truncate
|
80
|
+
("truncates a string to the given length"
|
81
|
+
(string-truncate "a and b and c and d" 8)
|
82
|
+
"a and b ")
|
83
|
+
|
84
|
+
("truncate to zero"
|
85
|
+
(string-truncate "a and b and long and complex" 0)
|
86
|
+
""))
|
87
|
+
|
27
88
|
(examples-for string-match
|
28
89
|
("no match returns nil"
|
29
90
|
(string-match "this that another" "XXXX")
|
@@ -81,4 +142,7 @@
|
|
81
142
|
(examples-for string-strip
|
82
143
|
("removes leading whitespace" (string-strip " hello!") "hello!" )
|
83
144
|
("removes trailing whitespace" (string-strip "(world) ") "(world)" )
|
84
|
-
("removes leading and trailing whitespace" (string-strip "\n\nme\n\n") "me" )
|
145
|
+
("removes leading and trailing whitespace" (string-strip "\n\nme\n\n") "me" )
|
146
|
+
("ignores leading and trailing whitespace for intenal lines"
|
147
|
+
(string-strip "\n\n me \n\n you \n\n\t them \t\n\n")
|
148
|
+
"me \n\n you \n\n\t them" ))
|
@@ -10,7 +10,11 @@
|
|
10
10
|
("dislikes no-prefix"
|
11
11
|
(on-err (joinstr "\n" errors)
|
12
12
|
(pre-compile '(:foo 1 2 3)))
|
13
|
-
"
|
13
|
+
"expanding
|
14
|
+
(colon-syntax || foo)
|
15
|
+
with
|
16
|
+
(fn names ((orf (hash-get colon-syntax-overrides car [0#0#0]names) default-colon-syntax) [0#0#0]names))
|
17
|
+
Irregular ': syntax: got (|| foo) : not prefix-syntax : in :foo"))
|
14
18
|
|
15
19
|
(examples-for prefix-list
|
16
20
|
("one argument"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
(examples-for to-integer
|
2
|
+
("converts a string"
|
3
|
+
(to-integer "1234")
|
4
|
+
1234)
|
5
|
+
|
6
|
+
("converts a date"
|
7
|
+
(to-integer (date 2004 3 12))
|
8
|
+
1079046000)
|
9
|
+
|
10
|
+
("converts a time"
|
11
|
+
(to-integer (time 2004 3 12 18 45))
|
12
|
+
1079113500)
|
13
|
+
|
14
|
+
("returns nonsense for non-integer"
|
15
|
+
(to-integer { foo 'bar })
|
16
|
+
0))
|
@@ -0,0 +1,15 @@
|
|
1
|
+
(validate/def string test-0 (if (< (len string) 6) (mf "length" "should be more than 6")))
|
2
|
+
(validate/def string test-0 (if (> (len string) 10) (mf "length" "should be less than 10")))
|
3
|
+
|
4
|
+
(examples-for validate
|
5
|
+
("returns a message about a string being too short"
|
6
|
+
(to-string:validate "foo" 'test-0)
|
7
|
+
"{\"length\"=>(\"should be more than 6\")}")
|
8
|
+
|
9
|
+
("returns a message about a string being too long"
|
10
|
+
(to-string:validate "foo bar toto titi" 'test-0)
|
11
|
+
"{\"length\"=>(\"should be less than 10\")}")
|
12
|
+
|
13
|
+
("returns an empty hash"
|
14
|
+
(to-string:validate "foo bar" 'test-0)
|
15
|
+
"{}"))
|
data/lib/nydp.rb
CHANGED
@@ -2,17 +2,22 @@ require 'date'
|
|
2
2
|
require 'set'
|
3
3
|
|
4
4
|
module Nydp
|
5
|
+
class << self
|
6
|
+
attr_accessor :logger # not used by this gem but very useful in your app
|
7
|
+
end
|
8
|
+
|
5
9
|
class Namespace < Hash
|
6
10
|
end
|
7
11
|
|
8
12
|
# TODO: write VM #apply_function so we have fewer calls to VM.new
|
9
13
|
def self.apply_function ns, function_name, *args
|
10
|
-
function = r2n(function_name.to_sym, ns).value
|
11
|
-
args = r2n args, ns
|
12
14
|
vm = VM.new(ns)
|
13
|
-
|
14
|
-
function.invoke vm, args
|
15
|
+
function = Symbol.mk(function_name.to_sym, ns).value
|
16
|
+
function.invoke vm, r2n(args)
|
15
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}")
|
16
21
|
end
|
17
22
|
|
18
23
|
def self.reader txt ; Nydp::StringReader.new txt ; end
|
@@ -50,9 +55,9 @@ module Nydp
|
|
50
55
|
|
51
56
|
def self.repl options={ }
|
52
57
|
toplevel do
|
53
|
-
|
54
|
-
|
55
|
-
|
58
|
+
launch_time = Time.now
|
59
|
+
silent = options.delete :silent
|
60
|
+
ns = options.delete :ns
|
56
61
|
last_script_time = Time.now
|
57
62
|
puts "welcome to nydp #{options.inspect}" unless silent
|
58
63
|
reader = Nydp::ReadlineReader.new $stdin, "nydp > "
|
@@ -89,6 +94,7 @@ require "nydp/error"
|
|
89
94
|
require "nydp/truth"
|
90
95
|
require "nydp/version"
|
91
96
|
require "nydp/helper"
|
97
|
+
require 'nydp/core_ext'
|
92
98
|
require "nydp/symbol"
|
93
99
|
require "nydp/symbol_lookup"
|
94
100
|
require "nydp/pair"
|
data/lib/nydp/assignment.rb
CHANGED
@@ -8,6 +8,8 @@ module Nydp
|
|
8
8
|
|
9
9
|
def execute vm
|
10
10
|
@name.assign vm.peek_arg, vm.current_context
|
11
|
+
rescue
|
12
|
+
raise "assigning #{@name.inspect}"
|
11
13
|
end
|
12
14
|
|
13
15
|
def to_s
|
@@ -26,9 +28,12 @@ module Nydp
|
|
26
28
|
end
|
27
29
|
|
28
30
|
def initialize name, value, value_src
|
29
|
-
@value_src = value_src
|
30
|
-
|
31
|
-
|
31
|
+
@name, @value, @value_src = name, value, value_src
|
32
|
+
@instructions = cons(value, cons(AssignmentInstruction.new(name)))
|
33
|
+
end
|
34
|
+
|
35
|
+
def lexical_reach n
|
36
|
+
[@name.lexical_reach(n), @value.lexical_reach(n)].max
|
32
37
|
end
|
33
38
|
|
34
39
|
def to_s
|
@@ -39,6 +44,8 @@ module Nydp
|
|
39
44
|
|
40
45
|
def execute vm
|
41
46
|
vm.push_ctx_instructions @instructions
|
47
|
+
rescue
|
48
|
+
raise "assigning #{@value.inspect} to #{@name.inspect}"
|
42
49
|
end
|
43
50
|
end
|
44
51
|
end
|
data/lib/nydp/builtin.rb
CHANGED
@@ -32,13 +32,13 @@ module Nydp::Builtin
|
|
32
32
|
handle_error e, arg_0, arg_1, arg_2
|
33
33
|
end
|
34
34
|
|
35
|
+
# called from 'apply (among others)
|
35
36
|
def invoke vm, args
|
36
37
|
builtin_invoke vm, args
|
37
38
|
rescue StandardError => e
|
38
39
|
handle_error e, *(args.to_a)
|
39
40
|
end
|
40
41
|
|
41
|
-
|
42
42
|
def handle_error e, *args
|
43
43
|
case e
|
44
44
|
when Nydp::Error
|
data/lib/nydp/builtin/cdr_set.rb
CHANGED
@@ -1,10 +1,5 @@
|
|
1
1
|
class Nydp::Builtin::CdrSet
|
2
2
|
include Nydp::Builtin::Base, Singleton
|
3
3
|
|
4
|
-
def builtin_invoke vm, args
|
5
|
-
pair = args.car
|
6
|
-
arg = args.cdr.car
|
7
|
-
pair.cdr = arg
|
8
|
-
vm.push_arg pair
|
9
|
-
end
|
4
|
+
def builtin_invoke vm, args ; vm.push_arg(args.car.cdr = args.cdr.car) ; end
|
10
5
|
end
|
data/lib/nydp/builtin/date.rb
CHANGED
@@ -1,13 +1,27 @@
|
|
1
1
|
class Nydp::Builtin::Date
|
2
2
|
include Nydp::Helper, Nydp::Builtin::Base, Singleton
|
3
3
|
|
4
|
+
def builtin_invoke vm, args
|
5
|
+
case args.size
|
6
|
+
when 0 ; builtin_invoke_1 vm
|
7
|
+
when 1 ; builtin_invoke_2 vm, args.car
|
8
|
+
when 2 ; builtin_invoke_3 vm, args.car, args.cdr.car
|
9
|
+
when 3 ; builtin_invoke_4 vm, args.car, args.cdr.car, args.cdr.cdr.car
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
4
13
|
def builtin_invoke_1 vm
|
5
14
|
vm.push_arg(Nydp::Date.new Date.today)
|
6
15
|
end
|
7
16
|
|
8
17
|
# it's a Time object (or any object that responds to #to_date)
|
9
18
|
def builtin_invoke_2 vm, arg
|
10
|
-
|
19
|
+
arg = if arg.respond_to?(:to_date)
|
20
|
+
arg.to_date
|
21
|
+
elsif arg.is_a?(String)
|
22
|
+
::Date.parse(arg)
|
23
|
+
end
|
24
|
+
vm.push_arg(Nydp::Date.new arg)
|
11
25
|
end
|
12
26
|
|
13
27
|
def builtin_invoke_3 vm, a0, a1
|
data/lib/nydp/builtin/error.rb
CHANGED
@@ -4,6 +4,6 @@ class Nydp::Builtin::Error
|
|
4
4
|
# override #invoke on nydp/builtin/base because
|
5
5
|
# we don't want to inherit error handling
|
6
6
|
def builtin_invoke vm, args
|
7
|
-
raise Nydp::Error.new(args.to_a.map(&:
|
7
|
+
raise Nydp::Error.new(args.to_a.map(&:to_s).join("\n"), vm.last_error)
|
8
8
|
end
|
9
9
|
end
|
data/lib/nydp/builtin/hash.rb
CHANGED
@@ -2,57 +2,33 @@ require "nydp/hash"
|
|
2
2
|
|
3
3
|
class Nydp::Builtin::Hash
|
4
4
|
include Nydp::Helper, Nydp::Builtin::Base, Singleton
|
5
|
+
|
5
6
|
def builtin_invoke vm, args
|
6
|
-
vm.push_arg(Nydp::Hash.new)
|
7
|
+
vm.push_arg(build_hash Nydp::Hash.new, args)
|
8
|
+
end
|
9
|
+
|
10
|
+
def build_hash h, args
|
11
|
+
return h if Nydp::NIL.is? args
|
12
|
+
k = args.car
|
13
|
+
rest = args.cdr
|
14
|
+
v = rest.car
|
15
|
+
h[k] = v
|
16
|
+
build_hash h, rest.cdr
|
7
17
|
end
|
8
18
|
end
|
9
19
|
|
10
20
|
class Nydp::Builtin::HashGet
|
11
21
|
include Nydp::Helper, Nydp::Builtin::Base, Singleton
|
12
22
|
def builtin_invoke vm, args
|
13
|
-
|
14
|
-
key = args.cdr.car
|
15
|
-
case hsh
|
16
|
-
when Nydp::Hash
|
17
|
-
vm.push_arg(hsh[key] || Nydp::NIL)
|
18
|
-
when NilClass, Nydp::NIL
|
19
|
-
vm.push_arg Nydp::NIL
|
20
|
-
else
|
21
|
-
v = hsh.respond_to?(:[]) ? hsh[n2r key] : ruby_call(hsh, key)
|
22
|
-
vm.push_arg(r2n v, vm.ns)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def ruby_call obj, method_name
|
27
|
-
if obj.respond_to? :_nydp_safe_methods
|
28
|
-
m = n2r(method_name).to_s.to_sym
|
29
|
-
allowed = obj._nydp_safe_methods
|
30
|
-
|
31
|
-
obj.send n2r(m) if allowed.include?(m)
|
32
|
-
else
|
33
|
-
raise "hash-get: Not a hash: #{obj.class.name}"
|
34
|
-
end
|
23
|
+
vm.push_arg(args.car._nydp_get(args.cdr.car)._nydp_wrapper || Nydp::NIL)
|
35
24
|
end
|
36
25
|
end
|
37
26
|
|
38
27
|
class Nydp::Builtin::HashSet
|
39
28
|
include Nydp::Helper, Nydp::Builtin::Base, Singleton
|
40
29
|
def builtin_invoke vm, args
|
41
|
-
hash = args.car
|
42
|
-
key = args.cdr.car
|
43
30
|
value = args.cdr.cdr.car
|
44
|
-
|
45
|
-
when Nydp::Hash
|
46
|
-
hash[key] = value
|
47
|
-
when NilClass, Nydp::NIL
|
48
|
-
nil
|
49
|
-
else
|
50
|
-
if hash.respond_to?(:[]=)
|
51
|
-
hash[n2r key] = n2r value
|
52
|
-
else
|
53
|
-
raise "hash-set: Not a hash: #{hash.class.name}"
|
54
|
-
end
|
55
|
-
end
|
31
|
+
args.car._nydp_set(args.cdr.car, value)
|
56
32
|
vm.push_arg value
|
57
33
|
end
|
58
34
|
end
|
@@ -60,14 +36,7 @@ end
|
|
60
36
|
class Nydp::Builtin::HashKeys
|
61
37
|
include Nydp::Helper, Nydp::Builtin::Base, Singleton
|
62
38
|
def builtin_invoke vm, args
|
63
|
-
|
64
|
-
if hash.is_a? Nydp::Hash
|
65
|
-
vm.push_arg Nydp::Pair.from_list hash.keys
|
66
|
-
elsif hash.respond_to?(:keys)
|
67
|
-
vm.push_arg r2n(hash.keys.to_a.sort, vm.ns)
|
68
|
-
else
|
69
|
-
vm.push_arg Nydp::NIL
|
70
|
-
end
|
39
|
+
vm.push_arg args.car._nydp_keys._nydp_wrapper
|
71
40
|
end
|
72
41
|
end
|
73
42
|
|
@@ -97,3 +66,16 @@ class Nydp::Builtin::HashMerge
|
|
97
66
|
vm.push_arg hash_0.merge hash_1
|
98
67
|
end
|
99
68
|
end
|
69
|
+
|
70
|
+
class Nydp::Builtin::HashSlice
|
71
|
+
include Nydp::Helper, Nydp::Builtin::Base, Singleton
|
72
|
+
|
73
|
+
def builtin_invoke vm, args
|
74
|
+
old = args.car
|
75
|
+
h = old.class.new
|
76
|
+
slice = args.cdr.car
|
77
|
+
slice = slice.map { |k| n2r k } unless old.is_a? Nydp::Hash
|
78
|
+
slice.each { |k| h[k] = old[k] if old.key?(k) }
|
79
|
+
vm.push_arg h
|
80
|
+
end
|
81
|
+
end
|