Skip to content

Commit

Permalink
rewritten arguments handling
Browse files Browse the repository at this point in the history
  • Loading branch information
iliabylich committed Dec 27, 2019
1 parent 643aac3 commit 79e3742
Show file tree
Hide file tree
Showing 12 changed files with 176 additions and 105 deletions.
4 changes: 2 additions & 2 deletions executor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -528,8 +528,8 @@ def execute_splatarray((_flag))
elsif value == nil
result = value.to_a
else
if value.respond_to?(:to_a, true)
result = value.send(:to_a)
if __respond_to?(value, :to_a, true)
result = value.__send__(:to_a)
if result == nil
result = [value]
elsif !result.is_a?(Array)
Expand Down
8 changes: 8 additions & 0 deletions tags/language/block_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
fails:A block yielded a single Array assigns the Array to a single rest argument
fails:A block yielded a single Array assigns nil to unassigned required arguments
fails:A block yielded a single Array assigns elements to post arguments
fails:A block yielded a single Array assigns elements to required arguments when a keyword rest argument is present
fails:A block yielded a single Array assigns symbol keys from a Hash to keyword arguments
fails:A block yielded a single Array assigns symbol keys from a Hash returned by #to_hash to keyword arguments
fails:A block yielded a single Array calls #to_hash on the argument and uses resulting hash as first argument when optional argument and keyword argument accepted
Expand Down Expand Up @@ -26,7 +29,12 @@ fails:A block taking |*a| arguments does not call #to_ary if the single yielded
fails:A block taking |a, | arguments calls #to_ary to convert a single yielded object to an Array
fails:A block taking |a, | arguments raises a TypeError if #to_ary does not return an Array
fails:A block taking |(a, b), c| arguments calls #to_ary to convert a single yielded object to an Array
fails:A block taking |*a, b:| merges the hash into the splatted array
fails:A block arguments with _ extracts arguments with _
fails:A block arguments with _ assigns the first variable named
fails:Post-args appear after a splat
fails:Post-args are required
fails:Post-args with optional args gathers remaining args in the splat
fails:Post-args with optional args overrides the optional arg before gathering in the splat
fails:Post-args with optional args uses the required arg before the optional and the splat
fails:Post-args with optional args overrides the optional args from left to right before gathering the splat
1 change: 1 addition & 0 deletions tags/language/for_tags.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
fails:The for expression returns expr
fails:The for expression allows 'break' to have an argument which becomes the value of the for expression
15 changes: 15 additions & 0 deletions tags/language/hash_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@
fails:Hash literal {} should return an empty hash
fails:Hash literal {} should return a new hash populated with the given elements
fails:Hash literal freezes string keys on initialization
fails:Hash literal checks duplicated keys on initialization
fails:Hash literal accepts a hanging comma
fails:Hash literal recognizes '=' at the end of the key
fails:Hash literal constructs a new hash with the given elements
fails:Hash literal ignores a hanging comma
fails:Hash literal accepts mixed 'key: value' and 'key => value' syntax
fails:Hash literal accepts mixed 'key: value', 'key => value' and '"key"': value' syntax
fails:Hash literal expands an '**{}' element into the containing Hash literal initialization
fails:Hash literal expands an '**obj' element into the containing Hash literal initialization
fails:Hash literal expands a BasicObject using ** into the containing Hash literal initialization
fails:Hash literal expands an '**{}' element with the last key/value pair taking precedence
fails:Hash literal merges multiple nested '**obj' in Hash literals
fails:Hash literal calls #to_hash to expand an '**obj' element
fails:Hash literal raises a TypeError if any splatted elements keys are not symbols
8 changes: 6 additions & 2 deletions tags/language/lambda_tags.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
fails:A lambda literal -> () { } returns a lambda
fails:A lambda literal -> () { } assigns variables from parameters for definition '@a = -> (a={}) { a }'
fails:A lambda literal -> () { } assigns variables from parameters for definition '@a = -> (**) { }'
fails:A lambda literal -> () { } assigns variables from parameters for definition '@a = -> (**k) { k }'
fails:A lambda literal -> () { } assigns variables from parameters for definition '@a = -> (*, **k) { k }'
fails:"A lambda literal -> () { } assigns variables from parameters for definition \n @a = -> (a, b=1, *c, (*d, (e)), f: 2, g:, h:, **k, &l) do\n [a, b, c, d, e, f, g, h, k, l]\n end"
fails:"A lambda literal -> () { } assigns variables from parameters for definition \n @a = -> a, b=1, *c, d, e:, f: 2, g:, **k, &l do\n [a, b, c, d, e, f, g, k, l]\n end"
fails:A lambda expression 'lambda { ... }' returns a lambda
fails:A lambda expression 'lambda { ... }' with an implicit block can be created
fails:"A lambda expression 'lambda { ... }' assigns variables from parameters for definition \n def m(*a) yield(*a) end\n @a = lambda { |a| a }"
fails:A lambda expression 'lambda { ... }' assigns variables from parameters for definition '@a = lambda { |a, | a }'
fails:"A lambda expression 'lambda { ... }' assigns variables from parameters for definition \n def m(a) yield a end\n def m2() yield end\n @a = lambda { |a, | a }"
fails:A lambda expression 'lambda { ... }' assigns variables from parameters for definition '@a = lambda { |a={}| a }'
fails:A lambda expression 'lambda { ... }' assigns variables from parameters for definition '@a = lambda { |**| }'
fails:A lambda expression 'lambda { ... }' assigns variables from parameters for definition '@a = lambda { |**k| k }'
fails:A lambda expression 'lambda { ... }' assigns variables from parameters for definition '@a = lambda { |*, **k| k }'
fails:"A lambda expression 'lambda { ... }' assigns variables from parameters for definition \n @a = lambda do |a, b=1, *c, (*d, (e)), f: 2, g:, h:, **k, &l|\n [a, b, c, d, e, f, g, h, k, l]\n end"
fails:"A lambda expression 'lambda { ... }' assigns variables from parameters for definition \n @a = lambda do |a, b=1, *c, d, e:, f: 2, g:, **k, &l|\n [a, b, c, d, e, f, g, k, l]\n end"
11 changes: 5 additions & 6 deletions tags/language/method_tags.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
fails:A method assigns local variables from method parameters for definition 'def m(a:) a end'
fails:A method assigns local variables from method parameters for definition 'def m(a, b: 1) [a, b] end'
fails:A method assigns local variables from method parameters for definition 'def m(**) end'
fails:A method assigns local variables from method parameters for definition 'def m(**k) k end'
fails:A method assigns local variables from method parameters for definition 'def m(a, **) a end'
fails:A method assigns local variables from method parameters for definition 'def m(a, **k) [a, k] end'
fails:A method assigns local variables from method parameters for definition 'def m(a=1, b) [a, b] end'
Expand All @@ -14,6 +15,9 @@ fails:"A method assigns local variables from method parameters for definition \n
fails:A method assigns local variables from method parameters for definition 'def m(a=1, b:) [a, b] end'
fails:A method assigns local variables from method parameters for definition 'def m(a=1, b: 2) [a, b] end'
fails:A method assigns local variables from method parameters for definition 'def m(a=1, **) a end'
fails:A method assigns local variables from method parameters for definition 'def m(a=1, **k) [a, k] end'
fails:A method assigns local variables from method parameters for definition 'def m(*, a) a end'
fails:A method assigns local variables from method parameters for definition 'def m(*a, b) [a, b] end'
fails:A method assigns local variables from method parameters for definition 'def m(*a, b:) [a, b] end'
fails:A method assigns local variables from method parameters for definition 'def m(*a, b: 1) [a, b] end'
fails:A method assigns local variables from method parameters for definition 'def m(*, **) end'
Expand All @@ -23,8 +27,3 @@ fails:A method assigns local variables from method parameters for definition 'de
fails:A method assigns local variables from method parameters for definition 'def m(*a, **k) [a, k] end'
fails:A method assigns local variables from method parameters for definition 'def m(a:, b:) [a, b] end'
fails:A method assigns local variables from method parameters for definition 'def m(a:, b: 1) [a, b] end'
fails:A method assigns local variables from method parameters for definition 'def m(a:, **) a end'
fails:A method assigns local variables from method parameters for definition 'def m(a:, **k) [a, k] end'
fails:"A method assigns local variables from method parameters for definition \n def m(a, b=1, *c, d, e:, f: 2, g:, **k, &l)\n [a, b, c, d, e, f, g, k, l]\n end"
fails:"A method assigns local variables from method parameters for definition \n def m(a, b = nil, c = nil, d, e: nil, **f)\n [a, b, c, d, e, f]\n end"
fails:A method assigns keyword arguments from a passed Hash without modifying it for definition 'def m(a: nil); a; end'
3 changes: 3 additions & 0 deletions tags/language/proc_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
fails:A Proc taking zero arguments raises an ArgumentError if a value is passed
fails:A Proc taking || arguments raises an ArgumentError if a value is passed
fails:A Proc taking |a, *b| arguments does not destructure a single Array value yielded
fails:A Proc taking |a, | arguments raises an ArgumentError when passed more than one value
fails:A Proc taking |a, | arguments does not destructure when passed a single Array
9 changes: 9 additions & 0 deletions tags/language/send_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
fails:Invoking a method with only mandatory arguments raises ArgumentError if the methods arity doesn't match
fails:Invoking a method with optional arguments raises ArgumentError if extra arguments are passed
fails:Invoking a method with mandatory and optional arguments raises an ArgumentError if too many values are passed
fails:Invoking a private getter method does not permit self as a receiver
fails:Invoking a method accepts final explicit literal Hash arguments after the splat
fails:Invoking a method accepts final implicit literal Hash arguments after the splat
fails:Invoking a method accepts final Hash arguments after the splat
fails:Invoking a method accepts mandatory and explicit literal Hash arguments after the splat
fails:Invoking a method accepts mandatory and implicit literal Hash arguments after the splat
fails:Invoking a method accepts mandatory and Hash arguments after the splat
fails:Invoking a method expands the Array elements from the splat after executing the arguments and block if no other arguments follow the splat
fails:Invoking a method with optional argument(s), expands an array to arguments grouped in parentheses
fails:Invoking a method with required args after the rest arguments binds the required arguments first
Expand Down
2 changes: 2 additions & 0 deletions tags/language/yield_tags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ fails:The yield call taking a single argument yielding to a lambda passes an emp
fails:The yield call taking a single argument yielding to a lambda passes a single, multi-value Array
fails:The yield call taking a single argument yielding to a lambda should not destructure an Array into multiple arguments
fails:The yield call taking multiple arguments raises a LocalJumpError when the method is not passed a block
fails:The yield call taking multiple arguments raises an ArgumentError if too many arguments are passed to a lambda
fails:The yield call taking a single splatted argument raises a LocalJumpError when the method is not passed a block
fails:The yield call taking multiple arguments with a splat raises a LocalJumpError when the method is not passed a block
fails:The yield call taking multiple arguments with a splat passes the arguments to the block
Expand All @@ -15,3 +16,4 @@ fails:The yield call taking multiple arguments with a splat passes the Array ele
fails:The yield call taking multiple arguments with a splat does not pass an argument value if the splatted argument is nil
fails:The yield call taking matching arguments with splats and post args raises a LocalJumpError when the method is not passed a block
fails:The yield call taking matching arguments with splats and post args passes the arguments to the block
fails:The yield call taking a splat and a keyword argument passes it as an array of the values and a hash
9 changes: 8 additions & 1 deletion vm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,14 @@ def execute(iseq, **payload)
depth_before = frame_stack.size

before = frame_stack.size
push_frame(iseq, **payload)

begin
push_frame(iseq, **payload)
rescue Exception => e
pop_frame(reason: "propagating error during push_frame #{e}")
raise
end

pushed_frame = current_frame

if (before_eval = payload[:before_eval]); before_eval.call; end
Expand Down
2 changes: 1 addition & 1 deletion vm/frame_stack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def each
def push(frame)
@stack << frame
if @stack.size > 100
raise '(vm) stack overflow'
raise VM::InternalError, '(vm) stack overflow'
end
frame
end
Expand Down
Loading

0 comments on commit 79e3742

Please sign in to comment.