From dab4e74659dee835330cd6c7b9422c981c2e0937 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Mon, 4 Sep 2017 21:00:08 +0300 Subject: [PATCH] Reworking if statement Using 2 phase approach Flattening tbd --- lib/mom/check.rb | 9 +++++++++ lib/mom/if_statement.rb | 14 ++++++++++++++ lib/mom/instruction.rb | 12 ++++++++++-- lib/mom/truth_check.rb | 16 ++++++---------- lib/vool/statements/if_statement.rb | 22 ++++++++-------------- 5 files changed, 47 insertions(+), 26 deletions(-) create mode 100644 lib/mom/check.rb create mode 100644 lib/mom/if_statement.rb diff --git a/lib/mom/check.rb b/lib/mom/check.rb new file mode 100644 index 00000000..85248a30 --- /dev/null +++ b/lib/mom/check.rb @@ -0,0 +1,9 @@ +module Mom + + # A base class for conditions in MOM + # Just a marker, no real functionality for now + + class Check < Instruction + + end +end diff --git a/lib/mom/if_statement.rb b/lib/mom/if_statement.rb new file mode 100644 index 00000000..c42794af --- /dev/null +++ b/lib/mom/if_statement.rb @@ -0,0 +1,14 @@ +module Mom + class IfStatement < Instruction + attr_reader :condition , :if_true , :if_false + + attr_accessor :hoisted + + def initialize( cond , if_true , if_false = nil) + @condition = cond + @if_true = if_true + @if_false = if_false + end + end + +end diff --git a/lib/mom/instruction.rb b/lib/mom/instruction.rb index 29af863d..9ee78d82 100644 --- a/lib/mom/instruction.rb +++ b/lib/mom/instruction.rb @@ -2,10 +2,17 @@ module Mom # Base class for MOM instructions class Instruction + attr :next_instruction + + # flattening will change the structure from a tree to a linked list (and use + # next_instruction to do so) + def flatten + raise "not implemented" + end end - # basically a label - class Noop + # A label with a name + class Label attr_reader :name def initialize(name) @name = name @@ -16,6 +23,7 @@ module Mom end require_relative "simple_call" +require_relative "if_statement" require_relative "truth_check" require_relative "jump" require_relative "slot_load" diff --git a/lib/mom/truth_check.rb b/lib/mom/truth_check.rb index dd9202b7..389993af 100644 --- a/lib/mom/truth_check.rb +++ b/lib/mom/truth_check.rb @@ -1,3 +1,5 @@ +require_relative "check" + module Mom # The funny thing about the ruby truth is that is is anything but false or nil @@ -5,17 +7,11 @@ module Mom # To implement the normal ruby logic, we check for false or nil and jump # to the false branch. true_block follows implicitly # - # The class only carries the blocks for analysis, and does - # - NOT imply any order - # - will not "handle" the blocks in subsequent processing. - # - class TruthCheck < Instruction - attr_reader :condition , :true_block , :false_block , :merge_block + class TruthCheck < Check + attr_reader :condition - def initialize(condition , true_block , false_block , merge_block) - @condition , @true_block , @false_block , @merge_block = condition , true_block , false_block , merge_block + def initialize(condition) + @condition = condition end end - - end diff --git a/lib/vool/statements/if_statement.rb b/lib/vool/statements/if_statement.rb index 365f734c..c675301e 100644 --- a/lib/vool/statements/if_statement.rb +++ b/lib/vool/statements/if_statement.rb @@ -10,19 +10,19 @@ module Vool end def to_mom( method ) - merge = Mom::Noop.new(:merge) - if_true = add_jump(@if_true.to_mom( method ) , merge) - if_false = add_jump(@if_false.to_mom( method ) , merge) - cond = hoist_condition( method ) - check = Mom::TruthCheck.new( cond.pop , if_true , if_false , merge) - [ *cond , check , if_true , if_false , merge ] + if_true = @if_true.to_mom( method ) + if_false = @if_false.to_mom( method ) + condition , hoisted = hoist_condition( method ) + check = Mom::IfStatement.new( Mom::TruthCheck.new(condition) , if_true , if_false ) + check.hoisted = hoisted.to_mom(method) if hoisted + check end def hoist_condition( method ) return [@condition] if @condition.is_a?(Vool::Named) local = method.create_tmp - assign = LocalAssignment.new( local , @condition).to_mom(method) - [assign , Vool::LocalVariable.new(local)] + assign = LocalAssignment.new( local , @condition) + [Vool::LocalVariable.new(local) , assign] end def collect(arr) @@ -44,11 +44,5 @@ module Vool @if_true != nil end - private - def add_jump( block , merge) - block = [block] unless block.is_a?(Array) - block << Mom::Jump.new(merge) - block - end end end