class PosxmlCompiler::Jump
Constants
- INSTRUCTION_BREAK
- INSTRUCTION_CALLFUNCTION
- INSTRUCTION_ELSE
- INSTRUCTION_FUNCTION
- INSTRUCTION_FUNCTION_END
- INSTRUCTION_IF
- INSTRUCTION_IF_END
- INSTRUCTION_WHILE
- INSTRUCTION_WHILE_END
Attributes
instructions[R]
jumps[R]
Public Class Methods
new(instructions_array)
click to toggle source
# File lib/posxml_compiler/jump.rb, line 17 def initialize(instructions_array) @instructions = instructions_array @jumps = [] self.parse end
Public Instance Methods
parse()
click to toggle source
# File lib/posxml_compiler/jump.rb, line 30 def parse instructions_indexed = self.instructions.each_with_index.to_a.reverse stack_function = [] stack_while = [] stack_if = [] # It's necessary parse the list of functions first because a functions can # be called from anywhere, already declared or not tree_function = instructions_indexed.select do |instruction, index| instruction[:name] == INSTRUCTION_FUNCTION end.group_by do |instruction, index| instruction[:parameters]["name"][:original] end # instruction[:point] + 1 - Because of "\n" instructions_indexed.each do |instruction, index| case instruction[:name] when INSTRUCTION_FUNCTION_END stack_function << [index, instruction[:point]] when INSTRUCTION_FUNCTION reference, point = stack_function.pop @jumps << JumpPoint.new(self, INSTRUCTION_FUNCTION, index, reference, point) when INSTRUCTION_CALLFUNCTION reference, point = check_function_tree(tree_function, instruction) @jumps << JumpPoint.new(self, INSTRUCTION_CALLFUNCTION, index, reference, point) when INSTRUCTION_WHILE_END stack_while << [index, instruction[:point]] when INSTRUCTION_BREAK reference, point = stack_while.last raise PosxmlCompilerError.new("#{instruction[:line_number]}:While not found for <break") unless reference @jumps << JumpPoint.new(self, INSTRUCTION_BREAK, index, reference, point) when INSTRUCTION_WHILE reference, point = stack_while.pop @jumps << JumpPoint.new(self, INSTRUCTION_WHILE, index, reference, point) @jumps << JumpPoint.new(self, INSTRUCTION_WHILE_END, reference, index, instruction[:point] - 1) when INSTRUCTION_IF_END stack_if << [index, instruction[:point]] when INSTRUCTION_ELSE reference, point = stack_if.pop @jumps << JumpPoint.new(self, INSTRUCTION_ELSE, index, reference, point) stack_if << [index, instruction[:point], true] when INSTRUCTION_IF reference, point, is_else = stack_if.pop @jumps << JumpPoint.new(self, INSTRUCTION_IF, index, reference, point) end end # TODO add treatment for open/end statments check_addition end
persist!()
click to toggle source
# File lib/posxml_compiler/jump.rb, line 23 def persist! self.jumps.each do |jump| line = self.instructions[jump.persistence][:line] self.instructions[jump.persistence][:line] = line.insert(1, "#{jump.jump_value}\n") end end
Private Instance Methods
check_addition()
click to toggle source
# File lib/posxml_compiler/jump.rb, line 81 def check_addition self.jumps.each do |jump| jump.check_itself! end end
check_function_tree(tree, instruction)
click to toggle source
# File lib/posxml_compiler/jump.rb, line 87 def check_function_tree(tree, instruction) function_name = instruction[:parameters]["name"][:original] line_number = instruction[:line_number] unless function = tree[function_name] raise PosxmlCompilerError.new("#{line_number}:Function #{function_name} not found") unless reference end function_indexed = tree[function_name][0] [function_indexed[1], function_indexed[0][:point]] end