diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/prism/ffi.rb | 29 | ||||
-rw-r--r-- | lib/prism/parse_result.rb | 28 |
2 files changed, 55 insertions, 2 deletions
diff --git a/lib/prism/ffi.rb b/lib/prism/ffi.rb index eda61b3ead..35b91e41b2 100644 --- a/lib/prism/ffi.rb +++ b/lib/prism/ffi.rb @@ -478,10 +478,35 @@ module Prism values << scopes.length scopes.each do |scope| + locals = nil + forwarding = 0 + + case scope + when Array + locals = scope + when Scope + locals = scope.locals + + scope.forwarding.each do |forward| + case forward + when :* then forwarding |= 0x1 + when :** then forwarding |= 0x2 + when :& then forwarding |= 0x4 + when :"..." then forwarding |= 0x8 + else raise ArgumentError, "invalid forwarding value: #{forward}" + end + end + else + raise TypeError, "wrong argument type #{scope.class.inspect} (expected Array or Prism::Scope)" + end + template << "L" - values << scope.length + values << locals.length + + template << "C" + values << forwarding - scope.each do |local| + locals.each do |local| name = local.name template << "L" values << name.bytesize diff --git a/lib/prism/parse_result.rb b/lib/prism/parse_result.rb index e76ea7e17e..9a3e7c5b79 100644 --- a/lib/prism/parse_result.rb +++ b/lib/prism/parse_result.rb @@ -879,4 +879,32 @@ module Prism freeze end end + + # This object is passed to the various Prism.* methods that accept the + # `scopes` option as an element of the list. It defines both the local + # variables visible at that scope as well as the forwarding parameters + # available at that scope. + class Scope + # The list of local variables that are defined in this scope. This should be + # defined as an array of symbols. + attr_reader :locals + + # The list of local variables that are forwarded to the next scope. This + # should by defined as an array of symbols containing the specific values of + # :*, :**, :&, or :"...". + attr_reader :forwarding + + # Create a new scope object with the given locals and forwarding. + def initialize(locals, forwarding) + @locals = locals + @forwarding = forwarding + end + end + + # Create a new scope with the given locals and forwarding options that is + # suitable for passing into one of the Prism.* methods that accepts the + # `scopes` option. + def self.scope(locals: [], forwarding: []) + Scope.new(locals, forwarding) + end end |