Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f35c452

Browse files
committed
setspecial
1 parent 5bd3463 commit f35c452

File tree

3 files changed

+49
-14
lines changed

3 files changed

+49
-14
lines changed

lib/syntax_tree/compiler.rb

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ def visit_assoc_splat(node)
438438
end
439439

440440
def visit_backref(node)
441-
iseq.getspecial(1, 2 * node.value[1..].to_i)
441+
iseq.getspecial(YARV::VM_SVAR_BACKREF, 2 * node.value[1..].to_i)
442442
end
443443

444444
def visit_bare_assoc_hash(node)
@@ -888,25 +888,49 @@ def visit_heredoc(node)
888888
end
889889

890890
def visit_if(node)
891-
visit(node.predicate)
892-
branchunless = iseq.branchunless(-1)
893-
visit(node.statements)
891+
if node.predicate.is_a?(RangeNode)
892+
iseq.getspecial(YARV::VM_SVAR_FLIPFLOP_START, 0)
893+
branchif = iseq.branchif(-1)
894894

895-
if last_statement?
896-
iseq.leave
897-
branchunless.patch!(iseq)
895+
visit(node.predicate.left)
896+
branchunless_true = iseq.branchunless(-1)
898897

899-
node.consequent ? visit(node.consequent) : iseq.putnil
898+
iseq.putobject(true)
899+
iseq.setspecial(YARV::VM_SVAR_FLIPFLOP_START)
900+
branchif.patch!(iseq)
901+
902+
visit(node.predicate.right)
903+
branchunless_false = iseq.branchunless(-1)
904+
905+
iseq.putobject(false)
906+
iseq.setspecial(YARV::VM_SVAR_FLIPFLOP_START)
907+
branchunless_false.patch!(iseq)
908+
909+
visit(node.statements)
910+
iseq.leave
911+
branchunless_true.patch!(iseq)
912+
iseq.putnil
900913
else
901-
iseq.pop
914+
visit(node.predicate)
915+
branchunless = iseq.branchunless(-1)
916+
visit(node.statements)
902917

903-
if node.consequent
904-
jump = iseq.jump(-1)
918+
if last_statement?
919+
iseq.leave
905920
branchunless.patch!(iseq)
906-
visit(node.consequent)
907-
jump[1] = iseq.label
921+
922+
node.consequent ? visit(node.consequent) : iseq.putnil
908923
else
909-
branchunless.patch!(iseq)
924+
iseq.pop
925+
926+
if node.consequent
927+
jump = iseq.jump(-1)
928+
branchunless.patch!(iseq)
929+
visit(node.consequent)
930+
jump[1] = iseq.label
931+
else
932+
branchunless.patch!(iseq)
933+
end
910934
end
911935
end
912936
end

lib/syntax_tree/yarv.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,11 @@ def setn(number)
765765
push([:setn, number])
766766
end
767767

768+
def setspecial(key)
769+
stack.change_by(-1)
770+
push([:setspecial, key])
771+
end
772+
768773
def splatarray(flag)
769774
stack.change_by(-1 + 1)
770775
push([:splatarray, flag])
@@ -817,5 +822,10 @@ def call_data(method_id, argc, flag = VM_CALL_ARGS_SIMPLE)
817822
VM_CALL_ZSUPER = 1 << 10
818823
VM_CALL_OPT_SEND = 1 << 11
819824
VM_CALL_KW_SPLAT_MUT = 1 << 12
825+
826+
# These constants correspond to the setspecial instruction.
827+
VM_SVAR_LASTLINE = 0 # $_
828+
VM_SVAR_BACKREF = 1 # $~
829+
VM_SVAR_FLIPFLOP_START = 2 # flipflop
820830
end
821831
end

test/compiler_test.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ class CompilerTest < Minitest::Test
285285
"foo ? bar : baz",
286286
"case foo when bar then 1 end",
287287
"case foo when bar then 1 else 2 end",
288+
"baz if (foo == 1) .. (bar == 1)",
288289
# Constructed values
289290
"foo..bar",
290291
"foo...bar",

0 commit comments

Comments
 (0)