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



122
123
124
# File 'lib/skeem/runtime.rb', line 122

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

#depthObject



84
85
86
# File 'lib/skeem/runtime.rb', line 84

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

rubocop: disable Lint/UselessRescue



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

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.



65
66
67
68
69
70
# File 'lib/skeem/runtime.rb', line 65

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



72
73
74
75
# File 'lib/skeem/runtime.rb', line 72

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

#popObject

Make the parent frame the current one inside the provided block



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

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

  env_stack.pop
end

#pop_callObject



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

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

  call_stack.pop
end

#push(anEnvironment) ⇒ Object



88
89
90
# File 'lib/skeem/runtime.rb', line 88

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

#push_call(aProcCall) ⇒ Object



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

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)


77
78
79
80
81
82
# File 'lib/skeem/runtime.rb', line 77

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