Class: Lisp::EnvironmentFrame

Inherits:
Object
  • Object
show all
Defined in:
lib/rubylisp/environment_frame.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent, f = nil) ⇒ EnvironmentFrame

Returns a new instance of EnvironmentFrame.



17
18
19
20
21
# File 'lib/rubylisp/environment_frame.rb', line 17

def initialize(parent, f=nil)
  @bindings = []
  @parent = parent
  @frame = f
end

Instance Attribute Details

#frameObject

Returns the value of attribute frame.



5
6
7
# File 'lib/rubylisp/environment_frame.rb', line 5

def frame
  @frame
end

Class Method Details

.extending(parent, f = nil) ⇒ Object



12
13
14
15
# File 'lib/rubylisp/environment_frame.rb', line 12

def self.extending(parent, f=nil)
  f ||= parent.frame if parent && parent.has_frame?
  self.new(parent, f)
end

.globalObject



7
8
9
10
# File 'lib/rubylisp/environment_frame.rb', line 7

def self.global
  @@global_frame ||= EnvironmentFrame.new(nil)
  @@global_frame
end

Instance Method Details

#bind(symbol, value) ⇒ Object



47
48
49
50
51
52
53
54
# File 'lib/rubylisp/environment_frame.rb', line 47

def bind(symbol, value)
  b = self.binding_for(symbol)
  if b.nil?
    @bindings << Lisp::Binding.new(symbol, value)
  else
    b.value = value
  end
end

#bind_locally(symbol, value) ⇒ Object



76
77
78
79
80
81
82
83
# File 'lib/rubylisp/environment_frame.rb', line 76

def bind_locally(symbol, value)
  b = self.local_binding_for(symbol)
  if b.nil?
    @bindings << Lisp::Binding.new(symbol, value)
  else
    b.value = value
  end
end

#binding_for(symbol) ⇒ Object



40
41
42
43
44
45
# File 'lib/rubylisp/environment_frame.rb', line 40

def binding_for(symbol)
  binding = @bindings.detect {|b| b.symbol.name == symbol.name}
  return binding unless binding.nil?
  return @parent.binding_for(symbol) unless @parent.nil?
  nil
end

#dumpObject



108
109
110
111
112
# File 'lib/rubylisp/environment_frame.rb', line 108

def dump
  @bindings.each do |b|
    puts b.to_s
  end
end

#has_frame?Boolean

Returns:



23
24
25
# File 'lib/rubylisp/environment_frame.rb', line 23

def has_frame?
  !@frame.nil?
end

#is_name_bound?(str) ⇒ Boolean

Bindings following parent env frame pointer

Returns:



29
30
31
32
33
34
35
36
37
38
# File 'lib/rubylisp/environment_frame.rb', line 29

def is_name_bound?(str)
  if !@frame && @frame.has_slot?(Lisp:Symbol.named("#{str}:", true))
    return true
  end
    
  binding = @bindings.detect {|b| b.symbol.name == str}
  return true unless binding.nil?
  return false if @parent.nil?
  return @parent.is_name_bound?(str)
end

#local_binding_for(symbol) ⇒ Object

Bindings local to this env frame only



72
73
74
# File 'lib/rubylisp/environment_frame.rb', line 72

def local_binding_for(symbol)
  @bindings.detect {|b| b.symbol.name == symbol.name}
end

#quick_value_of(symbol_name) ⇒ Object



102
103
104
105
# File 'lib/rubylisp/environment_frame.rb', line 102

def quick_value_of(symbol_name)
  b = binding_for(Symbol.new(symbol_name))
  b.nil? ? nil : b.value
end

#set(symbol, value) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/rubylisp/environment_frame.rb', line 56

def set(symbol, value)
  naked_symbol = symbol.to_naked
  if @frame && @frame.has_slot?(naked_symbol)
    return @frame.at_put(naked_symbol, value)
  end
    
  b = self.binding_for(symbol)
  if b.nil?
    raise "#{symbol} is undefined."
  else
    b.value = value
  end
end

#value_of(symbol) ⇒ Object

Look up a symbol



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/rubylisp/environment_frame.rb', line 87

def value_of(symbol)
  b = local_binding_for(symbol)
  return b.value unless b.nil?
            
  naked_symbol = symbol.to_naked
  if @frame && @frame.has_slot?(naked_symbol)
    return @frame.get(naked_symbol)
  end

  b = binding_for(symbol)
  return b.value unless b.nil?
  nil
end