class Pione::Lang::Environment

Environment is a environment of language interpretation.

Public Instance Methods

add_package(package_name, parent_ids=[]) click to toggle source
# File lib/pione/lang/environment.rb, line 345
def add_package(package_name, parent_ids=[])
  # generate a new package id
  package_id = Util::PackageID.generate(self, package_name)
  # add package id table
  package_id_table[package_name] = package_id
  # make reference and definition
  ref = PackageExpr.new(name: package_name, package_id: package_id)
  definition = PackageDefinition.new(package_id: package_id, parent_ids: parent_ids)
  # set it to package table
  package_set(ref, definition)
  # return package id
  return package_id, definition
end
dumpable() click to toggle source

Return a new environment that we can dump. This is because deleagatable tables use hashs with default proc, so it is not able to dump by using Marshal.

# File lib/pione/lang/environment.rb, line 405
def dumpable
  set(variable_table: variable_table.dumpable, rule_table: rule_table.dumpable)
end
entrance_rule(package_id=current_package_id) click to toggle source

Return entrance rule.

@param package_id [String]

pakcage id

@return [RuleDeclaration]

entrance rule
# File lib/pione/lang/environment.rb, line 259
def entrance_rule(package_id=current_package_id)
  rule_get!(Lang::RuleExpr.new(entrance_rule_name(package_id)))
end
entrance_rule_name(package_id=current_package_id) click to toggle source

Return name of entrance rule.

@param package_id [String]

pakcage id

@return [String]

name of entrance rule
# File lib/pione/lang/environment.rb, line 240
def entrance_rule_name(package_id=current_package_id)
  # find main rule name from annotations
  annotations = package_get(Lang::PackageExpr.new(package_id: package_id)).annotations
  annotations.each do |annotation|
    if annotation.annotation_type == "Entrance"
      return annotation.pieces.first.name
    end
  end

  # default name
  return "Main"
end
find_ancestor_ids(package_id) click to toggle source

Find ancestor’s IDs of the package ID. The way of ancestors search is depth-first.

# File lib/pione/lang/environment.rb, line 303
def find_ancestor_ids(package_id)
  ancestor_ids = []
  if package = package_get(PackageExpr.new(package_id: package_id))
    ancestor_ids += package.parent_ids
    package.parent_ids.each do |parent_id|
      find_ancestor_ids(parent_id).each do |ancestor_id|
        if not(ancestor_ids.include?(ancestor_id))
          ancestor_ids << ancestor_id
        end
      end
    end
  end
  return ancestor_ids
end
find_package_id_by_package_name(package_name) click to toggle source
# File lib/pione/lang/environment.rb, line 298
def find_package_id_by_package_name(package_name)
  package_id_table[package_name]
end
layer() click to toggle source

Create a new environment which tables are overlayed current tables.

# File lib/pione/lang/environment.rb, line 319
def layer
  self.class.new(
    variable_table: VariableTable.new(variable_table),
    rule_table: RuleTable.new(rule_table),
    package_table: package_table,
    package_ids: package_ids,
    current_package_id: current_package_id,
    current_definition: current_definition
  )
end
make_root_rule(main_param_set) click to toggle source

Make a root rule definition.

@param main_param_set [ParameterSet]

main parameter set

@return [RuleDefinition]

root rule definition
# File lib/pione/lang/environment.rb, line 373
      def make_root_rule(main_param_set)
        # put variable of parameter set for main rule
        variable_set(Variable.new("MAIN_PARAM_SET"), ParameterSetSequence.of(main_param_set))

        # make root rule
        Package::Document.parse(<<-PIONE % entrance_rule_name, current_package_id, nil, nil, "*System*").eval(self)
           Rule Root
             input '*'.all or null
             output '*'.all
           Flow
             rule %s.param($MAIN_PARAM_SET)
           End
        PIONE
        rule_get(RuleExpr.new("Root"))
      end
merge_param_set(param_set, option={}) click to toggle source

Merge the parameter set as variables into this environment. Rebinding variables raise error, but it is ignored when force flag is true.

@param param_set [Lang::ParameterSet]

parameter set to be merged

@option option

# File lib/pione/lang/environment.rb, line 336
def merge_param_set(param_set, option={})
  param_set.keys.each do |key|
    var = Variable.new(name: key, package_id: current_package_id)
    val = param_set[key]
    option[:force] ? variable_set!(var, val) : variable_set(var, val)
  end
  return self
end
package_get(ref) click to toggle source

Get the definition of package.

# File lib/pione/lang/environment.rb, line 278
def package_get(ref)
  raise ArgumentError.new(ref.inspect) unless ref.package_id

  package_table.get(ref)
end
package_set(ref, val) click to toggle source

Set the definition of package.

# File lib/pione/lang/environment.rb, line 285
def package_set(ref, val)
  raise ArgumentError.new(ref.inspect) unless ref.package_id

  package_table.set(ref, val)
end
rule_get(ref) click to toggle source

Get the definition of rule expression. We use current package id if it is implicit.

# File lib/pione/lang/environment.rb, line 226
def rule_get(ref)
  rule_table.get(self, setup_package_id(ref))
end
rule_get!(ref) click to toggle source
# File lib/pione/lang/environment.rb, line 230
def rule_get!(ref)
  rule_table.get!(self, setup_package_id(ref))
end
rule_get_value(ref) click to toggle source

Get the expression of the reference.

# File lib/pione/lang/environment.rb, line 264
def rule_get_value(ref)
  if val = rule_table.get_value(self, setup_package_id(ref))
    return val
  else
    (raise UnboundError.new(ref))
  end
end
rule_set(ref, val) click to toggle source

Set the definition of rule expression.

# File lib/pione/lang/environment.rb, line 273
def rule_set(ref, val)
  rule_table.set(setup_package_id(ref), val)
end
setup_new_package(package_name, parent_ids=[]) click to toggle source

Introduce new package in the environment.

# File lib/pione/lang/environment.rb, line 360
def setup_new_package(package_name, parent_ids=[])
  package_id, definition = add_package(package_name, parent_ids)

  # update current package id
  set(current_package_id: package_id, current_definition: definition)
end
setup_package_id(ref) click to toggle source

Set current package id to the reference if the package id is unknown.

# File lib/pione/lang/environment.rb, line 390
def setup_package_id(ref)
  return ref if ref.package_id

  # check current package id
  unless current_package_id
    raise EnvironmentError.new("we couldn't determine the package id: %s" % ref)
  end

  # create new reference with the package id
  ref.set(package_id: current_package_id)
end
temp(temporary_info) { |x| ... } click to toggle source

Make a temporary environment with the temporary informations and evaluate the block in it. This is for evaluating declarations.

# File lib/pione/lang/environment.rb, line 293
def temp(temporary_info, &b)
  set(temporary_info).tap {|x| yield(x)}
  return nil
end
variable_get(ref) click to toggle source

Get the value of variable. We use current package id if it is implicit.

# File lib/pione/lang/environment.rb, line 207
def variable_get(ref)
  variable_table.get(self, setup_package_id(ref))
end
variable_get!(ref) click to toggle source
# File lib/pione/lang/environment.rb, line 211
def variable_get!(ref)
  variable_table.get!(self, setup_package_id(ref))
end
variable_set(ref, val) click to toggle source

Set the value of variable.

# File lib/pione/lang/environment.rb, line 216
def variable_set(ref, val)
  _val = val.kind_of?(Variable) ? setup_package_id(val) : val
  variable_table.set(setup_package_id(ref), val)
end
variable_set!(ref, val) click to toggle source
# File lib/pione/lang/environment.rb, line 221
def variable_set!(ref, val)
  variable_table.set!(setup_package_id(ref), val)
end