Class: XfOOrth::Context

Inherits:
Object show all
Defined in:
lib/fOOrth/compiler/context.rb,
lib/fOOrth/debug/context_dump.rb,
lib/fOOrth/compiler/context/tags.rb,
lib/fOOrth/compiler/context/locals.rb,
lib/fOOrth/compiler/context/map_name.rb

Overview

  • compiler/context/map_name.rb - The fOOrth language mapping of names in a context.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(previous, data = {}) ⇒ Context

Setup an instance of compiler context.
Parameters:

  • previous - The previous context object or nil if there is none.

  • data - A hash of context data.



23
24
25
# File 'lib/fOOrth/compiler/context.rb', line 23

def initialize(previous, data={})
  @previous, @data = previous, data
end

Instance Attribute Details

#previousObject (readonly)

The previous context object that this one builds on. Set to nil if there is none.



17
18
19
# File 'lib/fOOrth/compiler/context.rb', line 17

def previous
  @previous
end

Instance Method Details

#[](index) ⇒ Object

Retrieve the data value currently in effect.



10
11
12
# File 'lib/fOOrth/compiler/context/tags.rb', line 10

def [](index)
  @data[index] || (previous && previous[index])
end

#[]=(index, value) ⇒ Object

Set a data value.



15
16
17
# File 'lib/fOOrth/compiler/context/tags.rb', line 15

def []=(index,value)
  @data[index] = value
end

#check_depth(expected_depth) ⇒ Object

Is the current nesting level what is expected?
Parameters

  • expected_depth - the expected nesting depth.


Notes

  • Raises an error (F12) on incorrect nesting.



37
38
39
40
41
# File 'lib/fOOrth/compiler/context.rb', line 37

def check_depth(expected_depth)
  if expected_depth - self.depth != 0
    error "F12: Error, Invalid control/structure nesting."
  end
end

#check_set(symbol, expect) ⇒ Object

Validate a current data value.
Parameters:

  • symbol - The symbol of the value to be tested.

  • expect - An array of valid values.


Note:

  • Throws a XfOOrthError if the value is not valid.

  • To check for no value, use [nil] for expect.

  • Returns true to facilitate testing only.



37
38
39
40
41
42
43
44
45
# File 'lib/fOOrth/compiler/context/tags.rb', line 37

def check_set(symbol, expect)
  current = self[symbol]

  unless expect.include?(current)
    error "F10: Found a #{current.inspect}, excpected #{expect}"
  end

  true
end

#create_local_method(name, spec_class, options, &block) ⇒ Object

Create a local method on this context.
Parameters:

  • name - The name of the method to create.

  • spec_class - The specification class to use.

  • options - An array of options.

  • block - A block to associate with the name.


Returns

  • The spec created for the shared method.



17
18
19
20
# File 'lib/fOOrth/compiler/context/locals.rb', line 17

def create_local_method(name, spec_class, options, &block)
  sym = SymbolMap.add_entry(name)
  self[sym] = spec_class.new(name, sym, options, &block)
end

#debug_dump(vm) ⇒ Object

Dump the context chain to the console for debug.
Parameters

  • vm - The current virtual machine for this thread.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/fOOrth/debug/context_dump.rb', line 12

def debug_dump(vm)
  puts "\nContext level #{self.depth}"

  @data.each do |key, value|
    if key == :vm
      puts "virtual machine => #{value.foorth_name}"
    else
      if (name = SymbolMap.unmap(key))
        key = name.inspect
      end

      puts "#{key} => #{value}"
    end
  end

  (prev = self.previous) && prev.debug_dump(vm)
end

#depthObject

How many levels of nested context are there?



28
29
30
# File 'lib/fOOrth/compiler/context.rb', line 28

def depth
  1 + (previous ? previous.depth : 0)
end

#map(name) ⇒ Object

Map a name to a specification.
Parameters:

  • name - The string to be mapped.


Returns:

  • The specification that corresponds to the name or nil if none found.



14
15
16
17
18
# File 'lib/fOOrth/compiler/context/map_name.rb', line 14

def map(name)
  if (@symbol = SymbolMap.map(@name = name))
    do_map_name
  end
end

#merge(new_data) ⇒ Object

Merge in a hash of tag data.



25
26
27
# File 'lib/fOOrth/compiler/context/tags.rb', line 25

def merge(new_data)
  @data.merge!(new_data)
end

#recvrObject

Get the currently define method receiver



44
45
46
# File 'lib/fOOrth/compiler/context.rb', line 44

def recvr
  self[:obj] || self[:cls] || self[:vm] || error("F90: No message receiver.")
end

#remove_local_method(name) ⇒ Object

Remove a local method on this context.
Parameters:

  • The name of the method to remove.



25
26
27
28
29
30
31
# File 'lib/fOOrth/compiler/context/locals.rb', line 25

def remove_local_method(name)
  if (sym = SymbolMap.map(name))
    @data.delete(sym)
  else
    error "F90: Unable to remove local method #{name}"
  end
end

#tagsObject

Get the compile tags in effect.



20
21
22
# File 'lib/fOOrth/compiler/context/tags.rb', line 20

def tags
  @data[:tags] || []
end