class PosxmlCompiler::Variable

Constants

CALLFUNCTION_NAME
FUNCTION_NAME
FUNCTION_PARAMETER
VARIABLE_INTEGER
VARIABLE_LIMIT
VARIABLE_PARAMETER_NAME
VARIABLE_PARAMETER_VALUE
VARIABLE_REFERENCE
VARIABLE_STRING
VARIABLE_STRING_LIMIT
VARIABLE_STRING_MAX_SIZE

Attributes

functions[RW]
number[RW]
number_strings[RW]
variables[RW]
xsd[RW]

Public Class Methods

new(xsd, functions) click to toggle source
# File lib/posxml_compiler/variable.rb, line 18
def initialize(xsd, functions)
  @functions       = functions
  @number          = 0
  @number_strings  = 0
  @variables       = {}
  @xsd             = xsd
end

Public Instance Methods

check_typing_mismatch(instruction, parameter_name, variable_struct) click to toggle source
# File lib/posxml_compiler/variable.rb, line 26
def check_typing_mismatch(instruction, parameter_name, variable_struct)
  type = self.xsd.parameter_type(instruction, parameter_name)

  return true if type == :string_or_integer

  case variable_struct[:type]
  when type # match everything is ok
  when :string_or_integer # match everything is ok
  when nil # not defined yet, it's ok for now
  when :string
    raise PosxmlCompiler::VariableTypeError.new("Wrong argument type '#{variable_struct[:type]}' for instruction #{instruction}, parameter #{parameter_name} (expected type '#{type}')")
  when :integer
    raise PosxmlCompiler::VariableTypeError.new("Wrong argument type '#{variable_struct[:type]}' for instruction #{instruction}, parameter #{parameter_name} (expected type '#{type}')")
  else
    raise PosxmlCompiler::VariableTypeError.new("Wrong argument type '#{variable_struct[:type]}' for instruction #{instruction}, parameter #{parameter_name} (expected type '#{type}')")
  end

  return true
end
create(instruction, parameter, value, reference = false) click to toggle source

reference true is a variable that is been referenced without been previously created

# File lib/posxml_compiler/variable.rb, line 47
def create(instruction, parameter, value, reference = false)
  validate_size(parameter, value)
  case instruction
  when FUNCTION_NAME
    create_function_variable(value, instruction)
  when CALLFUNCTION_NAME
    create_function_variable(value, instruction)
  when VARIABLE_STRING
    create_type_variable(parameter, value, :string, reference)
  when VARIABLE_INTEGER
    create_type_variable(parameter, value, :integer, reference)
  else
    create_ordinary_variable(instruction, parameter, value, reference)
  end
end
find(instruction, parameter, name) click to toggle source
# File lib/posxml_compiler/variable.rb, line 63
def find(instruction, parameter, name)
  if instruction == VARIABLE_STRING || instruction == VARIABLE_INTEGER
    if parameter == VARIABLE_PARAMETER_NAME
      remove_reference_struct(self.variables[name])
    else # VARIABLE_PARAMETER_VALUE can return a reference for other variable
      self.variables[name]
    end
  else
    self.variables[name]
  end
end
get(instruction, parameter, value) click to toggle source

Receive:

("function", "name", "functionbla")
("if", "variable", "$(sKeyTouchScreen)")
("if", "operator", "equalto")
("if", "value", "KEY_CLEAR")

Return:

{:original => "functionbla", :value => "functionbla", :type => :string}
{:original => "$(sKeyTouchScreen)", :value => "$(1)", :type => :string}
{:original => "$(!sBufRecv[2])", :value => "$(2.&2)", :type => :string}
{:original => "$(!sBufRecv[$(iFound)])", :value => "$(2.$&3)", :type => :string}
{:original => "$(sBufRecv[$(iFound)])", :value => "$(2.$3)", :type => :string}
{:original => "equalto", :value => "equalto", :type => :string}
{:original => "KEY_CLEAR", :value => "KEY_CLEAR", :type => :string}
  • Important, the struct returned only has a parameter value with $()

    if isn't the stringvariable and integervariable value. Because those
    instructions require the variable number without $().
# File lib/posxml_compiler/variable.rb, line 97
def get(instruction, parameter, value)
  if value.include? VARIABLE_REFERENCE
    value = remove_reference(value)
    if variable_struct = self.find(instruction, parameter, value)
      check_typing_mismatch(instruction, parameter, variable_struct)
      variable_struct
    else
      self.create(instruction, parameter, value, true)
    end
  else
    # Not a reference for other variable
    self.create(instruction, parameter, value)
  end
end
multiple_reference?(str, reference) click to toggle source
# File lib/posxml_compiler/variable.rb, line 75
def multiple_reference?(str, reference)
  reference && str.include?("[")
end
next_number(name, type) click to toggle source
# File lib/posxml_compiler/variable.rb, line 129
def next_number(name, type)
  value = self.number += 1
  if type == :string
    if (self.number_strings += 1) > VARIABLE_STRING_LIMIT
      raise PosxmlCompiler::VariableStringLimitError.new("#{type} variable #{name} exceed the number of string variables")
    end
  end
  if value > VARIABLE_LIMIT
    raise PosxmlCompiler::VariableLimitError.new("#{type} variable #{name} exceed the number of variables")
  end
  "$(#{value})"
end
parameter_scheme(original = nil, value = nil, type = nil, reference = false) click to toggle source
# File lib/posxml_compiler/variable.rb, line 112
def parameter_scheme(original = nil, value = nil, type = nil, reference = false)
  if reference
    value, index_variable, range_index = parse_index_variable(value, reference)
    if index_variable
      variable1 = self.get(VARIABLE_STRING, VARIABLE_PARAMETER_VALUE, value)
      variable2 = self.get(VARIABLE_INTEGER, VARIABLE_PARAMETER_VALUE, index_variable)
      format = format_multiple_reference(range_index, variable1[:value], variable2[:value])

      {:original => original, :value => format, :type => type, :index_variable => index_variable}
    else
      {:original => original, :value => "#{VARIABLE_REFERENCE}#{value})", :type => type}
    end
  else
    {:original => original, :value => value, :type => type}
  end
end

Private Instance Methods

create_function_variable(value, instruction) click to toggle source
# File lib/posxml_compiler/variable.rb, line 159
def create_function_variable(value, instruction)
  raise PosxmlCompiler::VariableNameError.new("#{instruction} name #{value} can't be a reference") if value.include?(VARIABLE_REFERENCE)
  self.parameter_scheme(value, self.functions.get(value), :string)
end
create_ordinary_variable(instruction, parameter, value, reference) click to toggle source
# File lib/posxml_compiler/variable.rb, line 164
def create_ordinary_variable(instruction, parameter, value, reference)
  if reference
    type = self.xsd.parameter_type(instruction, parameter)
    if self.multiple_reference?(value, reference)
      self.parameter_scheme(value, value, type, reference)
    else
      raise PosxmlCompiler::VariableUndefinedError.new("Variable #{value} undefined") unless self.variables[value]
      self.variables[value] = self.parameter_scheme(value, value, type, reference)
    end
  else
    # isn't important consider a type in this case
    self.parameter_scheme(value, value)
  end
end
create_type_variable(parameter, value, type, reference) click to toggle source
# File lib/posxml_compiler/variable.rb, line 143
def create_type_variable(parameter, value, type, reference)
  if parameter == VARIABLE_PARAMETER_NAME
    unless self.variables[value]
      number = remove_reference(next_number(parameter, type))
      self.variables[value] = self.parameter_scheme(value, number, type, true)
    end
    remove_reference_struct(self.variables[value])
  else
    # If is value, reference and the variable doesn't exists should raise an error because it wasn't declared
    if parameter == VARIABLE_PARAMETER_VALUE && self.variables[value].nil? && reference && ! self.multiple_reference?(value, reference)
      raise PosxmlCompiler::VariableUndefinedError.new("Variable #{value} undefined")
    end
    self.parameter_scheme(value, value, type, reference)
  end
end
format_multiple_reference(range_index, variable1, variable2) click to toggle source
# File lib/posxml_compiler/variable.rb, line 202
def format_multiple_reference(range_index, variable1, variable2)
  str1 = variable1.sub(VARIABLE_REFERENCE, "").sub(")", "") # Format value to be like "123"
  str2 = variable2.sub("(", "").sub(")", "") # format value to be "$123")
  # At the end "$(123.$&456)" or "$(123.&456)" (no reference)
  if range_index
    if str2.include?("$") # no reference
      format = "#{VARIABLE_REFERENCE}#{str1}.#{str2.insert(1, "&")})"
    else
      format = "#{VARIABLE_REFERENCE}#{str1}.#{str2.insert(0, "&")})"
    end
  else
    if str2.include?("$") # no reference
      format = "#{VARIABLE_REFERENCE}#{str1}.#{str2.insert(1, " ")})"
    else
      format = "#{VARIABLE_REFERENCE}#{str1}.#{str2.insert(0, " ")})"
    end
  end
end
parse_index_variable(value, reference) click to toggle source

parse_index_variable

receive "!sBufRecv[$(iFound)]"
return  ["!sBufRecv", iFound, true]

or

receive "sBufRecv[$(iFound)]"
return  ["sBufRecv", iFound, false]
# File lib/posxml_compiler/variable.rb, line 185
def parse_index_variable(value, reference)
  #if reference && value.include?("[")
  if self.multiple_reference?(value, reference)
    index = "#{value.match(/\[(.+)\]/)[1]}"
    str = "$(#{value.split("[")[0]})"

    if str[2] == "!"
      str[2] = ""
      [str, index, true]
    else
      [str, index, false]
    end
  else
    value
  end
end
remove_reference(str) click to toggle source
# File lib/posxml_compiler/variable.rb, line 234
def remove_reference(str)
  string = str.to_s
  if string.include? VARIABLE_REFERENCE
    string.to_s[2..-2]
  else
    string
  end
end
remove_reference_struct(data) click to toggle source
# File lib/posxml_compiler/variable.rb, line 227
def remove_reference_struct(data)
  return unless data
  struct = data.dup
  struct[:value] = remove_reference(struct[:value])
  struct
end
validate_size(name, original) click to toggle source
# File lib/posxml_compiler/variable.rb, line 221
def validate_size(name, original)
  if original.size > VARIABLE_STRING_MAX_SIZE
    raise PosxmlCompiler::StringSizeError.new("string variable #{name} exceed #{VARIABLE_STRING_MAX_SIZE} bytes [#{original}]")
  end
end