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
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