Class: Skeem::Runtime

Inherits:
Object
  • Object
show all
Defined in:
lib/skeem/runtime.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(anEnvironment, parent = nil) ⇒ Runtime

Returns a new instance of Runtime.



13
14
15
16
17
# File 'lib/skeem/runtime.rb', line 13

def initialize(anEnvironment, parent = nil)
  @env_stack = []
  push(anEnvironment)
  @call_stack = parent.nil? ? [] : parent.call_stack
end

Instance Attribute Details

#call_stackArray<ProcedureCall> (readonly)

Returns The call stack.

Returns:



11
12
13
# File 'lib/skeem/runtime.rb', line 11

def call_stack
  @call_stack
end

#env_stackArray<SkmFrame> (readonly)

Returns The current active frame.

Returns:

  • (Array<SkmFrame>)

    The current active frame



8
9
10
# File 'lib/skeem/runtime.rb', line 8

def env_stack
  @env_stack
end

Instance Method Details

#add_binding(aKey, anEntry) ⇒ Object



31
32
33
# File 'lib/skeem/runtime.rb', line 31

def add_binding(aKey, anEntry)
  environment.add_binding(aKey, anEntry)
end

#caller(index = -1)) ⇒ Object



120
121
122
# File 'lib/skeem/runtime.rb', line 120

def caller(index = -1)
  call_stack[index]
end

#depthObject



82
83
84
# File 'lib/skeem/runtime.rb', line 82

def depth
  env_stack.size
end

#environmentObject



19
20
21
# File 'lib/skeem/runtime.rb', line 19

def environment
  env_stack.last
end

#evaluate(aKey) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/skeem/runtime.rb', line 39

def evaluate(aKey)
  key_value = normalize_key(aKey)
  if include?(key_value)
    entry = environment.fetch(key_value)
    result = nil
    begin
      result = entry.evaluate(self)
    rescue NoMethodError => e
      # $stderr.puts 'In rescue block'
      # $stderr.puts key_value.inspect
      # $stderr.puts entry.inspect
      # $stderr.puts entry.expression.inspect
      raise e
    end
    result
  else
    err = StandardError
    key = aKey.kind_of?(SkmIdentifier) ? aKey.value : key_value
    err_msg = "Unbound variable: '#{key}'"
    raise err, err_msg
  end
end

#evaluate_form(aList) ⇒ Object

Parameters:

  • aList (SkmPair)

    first member is an identifier.



63
64
65
66
67
68
# File 'lib/skeem/runtime.rb', line 63

def evaluate_form(aList)
  # TODO: manage the cases where first_member is a keyword
  first_member = aList.car
  invokation = ProcedureCall.new(nil, first_member, aList.cdr.to_a)
  invokation.evaluate(self)
end

#fetch(aKey) ⇒ Object



27
28
29
# File 'lib/skeem/runtime.rb', line 27

def fetch(aKey)
  include?(aKey) ? environment.fetch(aKey) : nil
end

#include?(anIdentifier) ⇒ Boolean

Returns:

  • (Boolean)


23
24
25
# File 'lib/skeem/runtime.rb', line 23

def include?(anIdentifier)
  environment.include?(anIdentifier)
end

#nestObject



70
71
72
73
# File 'lib/skeem/runtime.rb', line 70

def nest
  nested = SkmFrame.new(environment)
  push(nested)
end

#popObject

Make the parent frame the current one inside the provided block



91
92
93
94
95
96
97
# File 'lib/skeem/runtime.rb', line 91

def pop
  if env_stack.empty?
    raise StandardError, 'Skeem environment stack empty!'
  end

  env_stack.pop
end

#pop_callObject



112
113
114
115
116
117
118
# File 'lib/skeem/runtime.rb', line 112

def pop_call
  if call_stack.empty?
    raise StandardError, 'Skeem call stack empty!'
  end

  call_stack.pop
end

#push(anEnvironment) ⇒ Object



86
87
88
# File 'lib/skeem/runtime.rb', line 86

def push(anEnvironment)
  env_stack.push(anEnvironment)
end

#push_call(aProcCall) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/skeem/runtime.rb', line 99

def push_call(aProcCall)
  if aProcCall.kind_of?(ProcedureCall)
    call_stack.push(aProcCall)
  else
    raise StandardError, "Invalid call object #{aProcCall.inspect}"
  end
  # $stderr.puts 'CALL STACK vvvv'
  # call_stack.each do |proc_call|
  # $stderr.puts proc_call.inspect
  # end
  # $stderr.puts 'CALL STACK ^^^^'
end

#unnestObject

Raises:

  • (StandardError)


75
76
77
78
79
80
# File 'lib/skeem/runtime.rb', line 75

def unnest
  raise StandardError, 'Cannot unnest environment' unless environment.parent

  environment.bindings.clear
  pop
end

#update_binding(aKey, anEntry) ⇒ Object



35
36
37
# File 'lib/skeem/runtime.rb', line 35

def update_binding(aKey, anEntry)
  environment.update_binding(aKey, anEntry)
end