Class: RVM::Interpreter::Enviroment

Inherits:
Object
  • Object
show all
Defined in:
lib/rvm/interpreter.rb

Overview

This class represents the enviroment, the memory so to say for the VM. The enviroment holds enviromental variables like who executes the code, on what object it runs, what parameters where passed to the call and as well, and perhaps most importantly the local variables.

Some of the functions called will initialize new enviroments, as for example function calls.

Instance Method Summary collapse

Constructor Details

#initialize(init_data = {}, oldenv = nil) ⇒ Enviroment

This creates a new enviroment enviroment, it generates a new env default variables are set if not defined in data.

If oldenv is provided it will also fall back to see if not existing variables



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/rvm/interpreter.rb', line 68

def initialize init_data = {}, oldenv=nil
  
  @data = {
    :locals => {},
    :functions => {},
    :evaldeepth => 0,
    :params => []
  }.merge(init_data)
  
  # Make sure that all locals that are passed, are actually in a variable storage.
  if init_data[:locals]
    locals = @data[:locals]
    init_data[:locals].each do |k,v|
      if not v.is_a?(VariableStorage)
        locals[k] = VariableStorage.new(v)
      end
    end
  end
  
  @prev = oldenv || {}
  RVM::debug "data: #{data}\noldenv:#{oldenv}" if $DEBUG
  RVM::debug "Creating new enviroment with: #{@data.inspect} as child of #{@prev}" if $DEBUG
end

Instance Method Details

#[](k) ⇒ Object

Returns a local variable with the given name.

If the current enviroment does not have any local variables with the given name it tries the privious enviroments.

This returns the VariableData object NOT the value of the variable. Use read_var_val if you want to read the value of a variable.



114
115
116
117
118
# File 'lib/rvm/interpreter.rb', line 114

def [] k
  r = @data[:locals][k] || @prev[k]
  RVM::debug "Getting variable #{k} (#{r})" if $DEBUG
  r
end

#[]=(k, v) ⇒ Object

Sets a local variable witin the enviroment.

If the variable exists in a ‘higher’ enviroment the value is changed.

If not it is newly created in the current enviroment and thus not visible in upper enviroments.



126
127
128
129
130
131
132
133
134
135
# File 'lib/rvm/interpreter.rb', line 126

def []= k, v
  #TODO: add capability to have the privious env variables changed
  RVM::debug "Setting variable #{k} to #{v}" if $DEBUG
  if (r = self[k])
    r.val = v
  else
    @data[:locals][k] = VariableStorage.new(v)
  end
  v
end

#dataObject

allows raw access to the data, be carefull!



93
94
95
# File 'lib/rvm/interpreter.rb', line 93

def data
  @data
end

#def_function(k, b) ⇒ Object

This defines a function within the enviroment and lets you call it later on.

It also checks if the given block is truely a RVM::Classes::Block object.

Raises:

  • (ArgumentError)


156
157
158
159
160
161
# File 'lib/rvm/interpreter.rb', line 156

def def_function k, b
  raise(ArgumentError, "Function definitions must be of block class.") if not b.is_a?(RVM::Classes::Block)
  @data[:functions][k] = b
  RVM::debug "Setting functon #{k} (#{b})" if $DEBUG
  nil
end

#define(k, v) ⇒ Object

Defines a varialbe in the current scope, priviose variables are not changed



138
139
140
# File 'lib/rvm/interpreter.rb', line 138

def define k, v
  @data[:locals][k] = VariableStorage.new(v)
end

#function(k) ⇒ Object

Returns a function for the current enviroment. The result is to be execpted to be of the RVM::Classes::Block class.



144
145
146
147
148
149
150
151
# File 'lib/rvm/interpreter.rb', line 144

def function k
  r = @data[:functions][k]
  if not r and @prev.is_a? Enviroment
    r = @prev.function(k)
  end
  RVM::debug "Getting functon #{k} (#{r})" if $DEBUG
  r
end

#param(i) ⇒ Object

returns a parameter that was passed to the call. For function calls this is especially important, it beginns with 0.

If the current enviroment does not have the given paramenter it tries it’s ‘oldenv’ attrib to see if that had a object.



102
103
104
105
# File 'lib/rvm/interpreter.rb', line 102

def param i
  RVM::debug "Getting param #{i} (#{@data[:params][i]})" if $DEBUG
  @data[:params][i] || @prev.param(i)
end

#read_var_val(name) ⇒ Object

This functin is closely related to [] with the difference that it returns the value And not the VariableData object.



165
166
167
168
169
170
171
172
173
174
175
# File 'lib/rvm/interpreter.rb', line 165

def read_var_val name
  
  r = nil
  if (v = self[name])
    r = v.val
  else
    r = RVM::Classes[:error].new(0, "Variable #{name} is not defined.")
  end
  RVM::debug "Getting variable value #{name} (#{r})" if $DEBUG
  r
end