class MODL::Parser::OrphanHandler

Public Class Methods

adopt(global, structures) click to toggle source

Look for any orphan pairs at the top level and adopt them into a map Its an error if there are duplicate keys or mixed types at the top.

# File lib/modl/parser/orphan_handler.rb, line 44
def self.adopt(global, structures)
  #
  # Separate out any top-level pairs into a separate hash, checking for duplicates on the way.
  #
  if structures
    pairs = Hash.new

    # This will replace the existing structures array
    new_structures = []

    structures.each do |s|
      if s.pair
        # skip hidden pairs and instructions
        if s.pair.key.start_with?('*') || s.pair.key.start_with?('_') || s.pair.key == '?'
          new_structures.push(s)
          next
        end

        if pairs.has_key?(s.pair.key)
          raise InterpreterError, 'Duplicate top level keys are not allowed.'
        else
          pairs[s.pair.key] = s
        end
      else
        if pairs.length > 0 && !all_hidden(pairs.keys) && !s.top_level_conditional
          raise InterpreterError, 'Mixed top-level types are not allowed.'
        else
          new_structures.push(s)
        end
      end
    end

    if pairs.length > 0
      #
      # Create a map for the pairs and insert them into it.
      #
      new_map = MODL::Parser::Parsed::ParsedMap.new(global)
      pairs.values.each do |p|
        new_map.mapItems.push p unless p.pair.key.start_with?('_')
      end

      # Add the map to a new structure and insert it at the front of the structures list
      new_struct = MODL::Parser::Parsed::ParsedStructure.new(global)
      new_struct.map = new_map
      new_structures.unshift(new_struct)

      # Replace the existing structures with the new structures.
      return new_structures
    end
  end
  structures
end
all_hidden(str_array) click to toggle source

Return true if all strings start with '_'

# File lib/modl/parser/orphan_handler.rb, line 31
def self.all_hidden(str_array)
  if str_array && str_array.length > 0
    str_array.each do |s|
      return false unless s.start_with?('_')
    end
  end
  true
end