Class: XfOOrth::Context

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

Overview

Get information about this compiler 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

#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

#get_infoObject

Get introspection info.
Endemic Code Smells

  • :reek:FeatureEnvy :reek:TooManyStatements



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/fOOrth/library/introspection/context.rb', line 12

def get_info
  results = [["Level", depth]]

  @data.each do |key, value|
    results << ["", ""]

    if value.is_a?(AbstractWordSpec)
      results << ["Name", SymbolMap.unmap(key)]
      results << ["Mapping", key]
      results.concat(value.get_info)
    else
      results << ["Name",  key]
      results << ["Value", value]
    end

  end

  if (prev = self.previous)
    results.concat([["", ""]]).concat(prev.get_info)
  end

  results
end

#map_with_defaults(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
19
20
21
22
23
24
25
26
27
28
# File 'lib/fOOrth/compiler/context/map_name.rb', line 14

def map_with_defaults(name)
  if (@symbol = SymbolMap.map(@name = name))
    do_map_name ||
      case @name[0]
      when '.'
        TosSpec.new(@name, @symbol, [:temp])

      when '~'
        SelfSpec.new(@name, @symbol, [:temp])

      else
        spec_error
      end
  end
end

#map_without_defaults(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.



35
36
37
38
39
# File 'lib/fOOrth/compiler/context/map_name.rb', line 35

def map_without_defaults(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

#no_target_errorObject

Signal that no receiver was found in this context. This is an internal error indication.



60
61
62
# File 'lib/fOOrth/compiler/context.rb', line 60

def no_target_error
  error("F90: No target found in context.")
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

#targetObject

Get the current target.



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

def target
  self[:obj] || self[:cls] || self[:vm] || no_target_error
end

#target_classObject

Get the current target class.



54
55
56
# File 'lib/fOOrth/compiler/context.rb', line 54

def target_class
  self[:cls] || no_target_error
end

#target_objectObject

Get the current target object.



49
50
51
# File 'lib/fOOrth/compiler/context.rb', line 49

def target_object
  self[:obj] || no_target_error
end