Class: Peruby::Op::Variable

Inherits:
Base
  • Object
show all
Defined in:
lib/peruby/op/variable.rb

Overview

Variable read and lvalue lookup.

Instance Method Summary collapse

Methods inherited from Base

#local_slot, #run_subroutine, #warning_directive?

Constructor Details

#initialize(sigil, name) ⇒ Variable

Returns a new instance of Variable.



7
8
9
10
11
12
13
# File 'lib/peruby/op/variable.rb', line 7

def initialize(sigil, name)
  @sigil = sigil
  @name = name
  @key = [sigil, name].freeze
  @dynamic_match = (sigil == :scalar && name.match?(/\A(?:\d+|[&`'+])\z/)) ||
                   (%i[array hash].include?(sigil) && %w[- +].include?(name))
end

Instance Method Details

#aggregate(env, kind, dereference: false) ⇒ Object



107
108
109
110
111
# File 'lib/peruby/op/variable.rb', line 107

def aggregate(env, kind, dereference: false)
  return dereference_aggregate(env, kind) if dereference

  kind == @sigil ? lookup(env) : env.fetch(kind, @name)
end

#aggregate_assignment?Boolean

Returns:

  • (Boolean)


84
# File 'lib/peruby/op/variable.rb', line 84

def aggregate_assignment? = %i[array hash].include?(@sigil)

#aggregate_callable(kind, dereference: false) ⇒ Object



113
114
115
116
117
# File 'lib/peruby/op/variable.rb', line 113

def aggregate_callable(kind, dereference: false)
  return ->(env) { aggregate(env, kind, dereference:) } if dereference || kind != @sigil

  lookup_callable
end

#argument_cells(env) ⇒ Object



70
71
72
73
74
75
76
77
# File 'lib/peruby/op/variable.rb', line 70

def argument_cells(env)
  value = lookup(env)
  return value.list if value.is_a?(PerlHash)

  return value.list if value.is_a?(PerlArray)

  value.respond_to?(:cells) ? value.cells.dup : [value]
end

#assign_values(env, values) ⇒ Object



96
97
98
99
100
101
102
103
104
105
# File 'lib/peruby/op/variable.rb', line 96

def assign_values(env, values)
  target = lookup(env)
  if @sigil == :array
    target.cells.replace(values.map { |value| Scalar.new(value) })
  else
    target.cells.clear
    values.each_slice(2) { |key, value| target.slot(Conv.to_str(key)).set(value) }
  end
  target
end

#first_cell(env) ⇒ Object



79
80
81
82
# File 'lib/peruby/op/variable.rb', line 79

def first_cell(env)
  value = lookup(env)
  value.respond_to?(:cells) ? value.cells.first : value
end

#first_cell_callableObject



49
50
51
52
# File 'lib/peruby/op/variable.rb', line 49

def first_cell_callable
  lookup = lookup_callable
  ->(env) { (value = lookup.call(env)).respond_to?(:cells) ? value.cells.first : value }
end

#localize(env, stack) ⇒ Object

Raises:



86
87
88
89
90
91
92
93
94
# File 'lib/peruby/op/variable.rb', line 86

def localize(env, stack)
  value = lookup(env)
  return stack.localize_scalar(value) if @sigil == :scalar
  return stack.localize_array_value(value) if @sigil == :array
  return stack.localize_hash_value(value) if @sigil == :hash
  return stack.localize_entire_glob(value) if @sigil == :glob

  raise PerlError, "Can't localize #{@sigil} variable"
end

#lvalue(env, context) ⇒ Object



65
66
67
68
# File 'lib/peruby/op/variable.rb', line 65

def lvalue(env, context)
  value = lookup(env)
  context == :list && value.respond_to?(:cells) ? value.cells : value
end

#lvalue_callableObject



47
# File 'lib/peruby/op/variable.rb', line 47

def lvalue_callable = lookup_callable

#result(value, context) ⇒ Object



54
55
56
57
58
59
60
61
62
63
# File 'lib/peruby/op/variable.rb', line 54

def result(value, context)
  return value.list if context == :list && value.is_a?(PerlHash)
  return value.list if context == :list && value.is_a?(PerlArray)
  return value.cells.dup if context == :list && value.respond_to?(:cells)
  return [value] if context == :list
  return value.size if @sigil == :array
  return value.cells.size if @sigil == :hash

  value.get
end

#run(env, context) ⇒ Object



15
16
17
18
# File 'lib/peruby/op/variable.rb', line 15

def run(env, context)
  value = lookup(env)
  result(value, context)
end

#scalar_callableObject



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/peruby/op/variable.rb', line 35

def scalar_callable
  lookup = lookup_callable
  sigil = @sigil
  lambda do |env|
    value = lookup.call(env)
    next value.size if sigil == :array
    next value.cells.size if sigil == :hash

    value.value
  end
end

#to_callableObject



20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/peruby/op/variable.rb', line 20

def to_callable
  lookup = lookup_callable
  lambda do |env, context|
    value = lookup.call(env)
    return value.list if context == :list && value.is_a?(PerlHash)
    return value.list if context == :list && value.is_a?(PerlArray)
    return value.cells.dup if context == :list && value.respond_to?(:cells)
    return [value] if context == :list
    return value.size if @sigil == :array
    return value.cells.size if @sigil == :hash

    value.value
  end
end