Class: TPPlus::Nodes::ConditionalNode

Inherits:
Object
  • Object
show all
Defined in:
lib/tp_plus/nodes/conditional_node.rb

Instance Method Summary collapse

Constructor Details

#initialize(type, condition, true_block, false_block) ⇒ ConditionalNode

Returns a new instance of ConditionalNode.



4
5
6
7
8
9
# File 'lib/tp_plus/nodes/conditional_node.rb', line 4

def initialize(type,condition,true_block,false_block)
  @type        = type
  @condition   = condition
  @true_block  = true_block.flatten.reject  {|n| n.is_a? TerminatorNode }
  @false_block = false_block.flatten.reject {|n| n.is_a? TerminatorNode }
end

Instance Method Details

#can_be_inlined?Boolean

Returns:

  • (Boolean)


31
32
33
34
35
36
# File 'lib/tp_plus/nodes/conditional_node.rb', line 31

def can_be_inlined?
  return false unless @false_block.empty?
  return false unless @true_block.length == 1

  @true_block.first.can_be_inlined?
end

#end_label(context) ⇒ Object



15
16
17
# File 'lib/tp_plus/nodes/conditional_node.rb', line 15

def end_label(context)
  @end_label ||= context.next_label
end

#eval(context, options = {}) ⇒ Object



48
49
50
51
52
53
54
55
56
57
# File 'lib/tp_plus/nodes/conditional_node.rb', line 48

def eval(context, options={})
  return InlineConditionalNode.new(@type,@condition,@true_block.first).eval(context) if can_be_inlined?

  if @false_block.empty?
    "IF #{parens(@condition.eval(context,opposite: opposite?), context)},JMP LBL[#{true_label(context)}] ;\n#{true_block(context)}LBL[#{true_label(context)}]"
  else
    # could be if-else or unless-else
    "IF #{parens(@condition.eval(context,opposite: opposite?), context)},JMP LBL[#{true_label(context)}] ;\n#{true_block(context)}JMP LBL[#{end_label(context)}] ;\nLBL[#{true_label(context)}] ;\n#{false_block(context)}LBL[#{end_label(context)}]"
  end
end

#false_block(context) ⇒ Object



23
24
25
# File 'lib/tp_plus/nodes/conditional_node.rb', line 23

def false_block(context)
  @f ||= string_for(@false_block,context)
end

#opposite?Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/tp_plus/nodes/conditional_node.rb', line 38

def opposite?
  @type == "if"
end

#parens(s, context) ⇒ Object



42
43
44
45
46
# File 'lib/tp_plus/nodes/conditional_node.rb', line 42

def parens(s, context)
  return s unless @condition.requires_mixed_logic?(context) || !@condition.is_a?(ExpressionNode)

  "(#{s})"
end

#string_for(block, context) ⇒ Object



27
28
29
# File 'lib/tp_plus/nodes/conditional_node.rb', line 27

def string_for(block,context)
  block.inject("") {|s,n| s << "#{n.eval(context)} ;\n" }
end

#true_block(context) ⇒ Object



19
20
21
# File 'lib/tp_plus/nodes/conditional_node.rb', line 19

def true_block(context)
  @t ||= string_for(@true_block,context)
end

#true_label(context) ⇒ Object



11
12
13
# File 'lib/tp_plus/nodes/conditional_node.rb', line 11

def true_label(context)
  @true_label ||= context.next_label
end