Class: Opal::Rewriters::ReturnableLogic

Inherits:
Base
  • Object
show all
Defined in:
lib/opal/rewriters/returnable_logic.rb

Constant Summary

Constants inherited from Base

Base::DUMMY_LOCATION

Instance Attribute Summary

Attributes inherited from Base

#current_node

Instance Method Summary collapse

Methods inherited from Base

#append_to_body, #begin_with_stmts, #dynamic!, #error, #on_top, #prepend_to_body, #process, s, #s, #stmts_of

Instance Method Details

#free_tmpObject



14
15
16
# File 'lib/opal/rewriters/returnable_logic.rb', line 14

def free_tmp
  @counter -= 1
end

#next_tmpObject



8
9
10
11
12
# File 'lib/opal/rewriters/returnable_logic.rb', line 8

def next_tmp
  @counter ||= 0
  @counter += 1
  "$ret_or_#{@counter}"
end

#on_and(node) ⇒ Object

a && b / a and b



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/opal/rewriters/returnable_logic.rb', line 63

def on_and(node)
  lhs, rhs = *node.children

  check_control_flow!(lhs)

  if node.meta[:if_test]
    lhs.meta[:if_test] = rhs.meta[:if_test] = true
    out = process(node.updated(:if, [lhs, rhs, s(:false)]))
  else
    lhs_tmp = next_tmp
    out = process(node.updated(:if, [s(:lvasgn, lhs_tmp, lhs), rhs, s(:js_tmp, lhs_tmp)]))
    free_tmp
  end
  out
end

#on_begin(node) ⇒ Object

Parser sometimes generates parentheses as a begin node. If it's a single node begin value, then let's forward the if_test metadata.



81
82
83
84
85
86
87
# File 'lib/opal/rewriters/returnable_logic.rb', line 81

def on_begin(node)
  if node.meta[:if_test] && node.children.count == 1
    node.children.first.meta[:if_test] = true
  end
  node.meta.delete(:if_test)
  super
end

#on_case(node) ⇒ Object



33
34
35
36
37
38
39
40
41
# File 'lib/opal/rewriters/returnable_logic.rb', line 33

def on_case(node)
  lhs, *whens, els = *node.children
  els ||= s(:nil)
  lhs_tmp = next_tmp if lhs

  out = build_if_from_when(node, lhs, lhs_tmp, whens, els)
  free_tmp if lhs
  out
end

#on_if(node) ⇒ Object



22
23
24
25
26
27
28
29
30
31
# File 'lib/opal/rewriters/returnable_logic.rb', line 22

def on_if(node)
  test, = *node.children

  check_control_flow!(test)

  # The if_test metadata signifies that we don't care about the return value except if it's
  # truthy or falsy. And those tests will be carried out by the respective $truthy helper calls.
  test.meta[:if_test] = true if test
  super
end

#on_or(node) ⇒ Object

a || b / a or b



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/opal/rewriters/returnable_logic.rb', line 44

def on_or(node)
  lhs, rhs = *node.children

  check_control_flow!(lhs)

  if node.meta[:if_test]
    # Let's forward the if_test to the lhs and rhs - since we don't care about the exact return
    # value of our or, we neither do care about a return value of our lhs or rhs.
    lhs.meta[:if_test] = rhs.meta[:if_test] = true
    out = process(node.updated(:if, [lhs, s(:true), rhs]))
  else
    lhs_tmp = next_tmp
    out = process(node.updated(:if, [s(:lvasgn, lhs_tmp, lhs), s(:js_tmp, lhs_tmp), rhs]))
    free_tmp
  end
  out
end

#reset_tmp_counter!Object



18
19
20
# File 'lib/opal/rewriters/returnable_logic.rb', line 18

def reset_tmp_counter!
  @counter = nil
end