Class: Crokus::TACBuilder

Inherits:
Transformer show all
Defined in:
lib/crokus/tac_builder.rb

Constant Summary collapse

OP_ASSIGN =
Token.new([:assign,"=",[0,0]])

Instance Attribute Summary

Attributes inherited from Transformer

#code

Instance Method Summary collapse

Methods inherited from Transformer

#initialize, #transform, #visitAddressOf, #visitArrayOf, #visitArrayOrStructInit, #visitArrow, #visitBody, #visitBreak, #visitCase, #visitCastedExpr, #visitCasting, #visitCharLit, #visitCommaStmt, #visitContinue, #visitDecl, #visitDefine, #visitDeref, #visitDesignUnit, #visitDoWhile, #visitDotted, #visitElse, #visitFloatLit, #visitFor, #visitFormalArg, #visitFunCall, #visitFunctionProto, #visitGoto, #visitIdent, #visitIf, #visitInclude, #visitIntLit, #visitLabeledStmt, #visitLabelledStmt, #visitPointerTo, #visitPostFixAccu, #visitPreFixAccu, #visitReturn, #visitSizeof, #visitStrLit, #visitStruct, #visitSwitch, #visitToken, #visitType, #visitTypedef, #visitUnary, #visitWhile

Constructor Details

This class inherits a constructor from Crokus::Transformer

Instance Method Details

#build(cfg) ⇒ Object



12
13
14
15
16
17
18
19
# File 'lib/crokus/tac_builder.rb', line 12

def build cfg
  bb0=cfg.starter
  @tmp_id=0
  @visited=[]
  visit_rec(bb0)
  cfg.name="tac_#{cfg.name}"
  cfg.print
end

#new_tmpObject



21
22
23
24
25
26
# File 'lib/crokus/tac_builder.rb', line 21

def new_tmp
  @tmp_id||=0
  tok=Token.create "$"+@tmp_id.to_s
  @tmp_id+=1
  tok
end

#visit_rec(bb) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/crokus/tac_builder.rb', line 28

def visit_rec bb
  @visited << bb
  @current=bb
  @new_stmts=[]
  #@post_stmts=[]
  bb.stmts.each do |stmt|
    @new_stmts << stmt.accept(self)
  end
  bb.stmts=@new_stmts
  #bb.stmts << @post_stmts
  bb.stmts.flatten!
  bb.succs.each do |bb|
    unless @visited.include? bb
      visit_rec(bb)
    end
  end
end

#visitAssign(assign, args = nil) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/crokus/tac_builder.rb', line 46

def visitAssign assign,args=nil
  assign_1= super(assign)
  if assign_1.lhs.is_a? Indexed
    if (rhs=assign_1.rhs).is_a? Indexed
      rhs=rhs.accept(self)
      tmp=new_tmp()
      @new_stmts << Assign.new(tmp,OP_ASSIGN,rhs)
      assign_1.rhs=tmp
    end
  end
  unless assign.op.kind==:assign
    rhs=assign_1.rhs
    rhs.accept(self)
    tmp=new_tmp()
    @new_stmts << Assign.new(tmp,OP_ASSIGN,rhs)
    assign_1.rhs=tmp
  end
  assign_1
end

#visitBinary(bin, args = nil) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/crokus/tac_builder.rb', line 81

def visitBinary bin,args=nil
  ret=Binary.new(bin.lhs,bin.op,bin.rhs)
  ret.lhs=bin.lhs.accept(self)
  if bin.lhs.respond_to?(:lhs) or bin.lhs.is_a?(FunCall)#Binary,Indexed,etc
    #lhs=bin.lhs.accept(self)
    tmp=new_tmp()
    @new_stmts << Assign.new(tmp,OP_ASSIGN,ret.lhs)
    ret.lhs=tmp
  end
  ret.rhs=bin.rhs.accept(self)
  if bin.rhs.respond_to?(:lhs) or bin.rhs.is_a?(FunCall) #Binary,Indexed,etc
    # rhs=bin.rhs.accept()
    tmp=new_tmp()
    @new_stmts << Assign.new(tmp,OP_ASSIGN,ret.rhs)
    ret.rhs=tmp
  end
  return ret
end

#visitCondExpr(ternary, args = nil) ⇒ Object

TBC



123
124
125
126
127
128
# File 'lib/crokus/tac_builder.rb', line 123

def visitCondExpr ternary,args=nil
  cond=ternary.cond.accept(self)
  lhs=ternary.lhs.accept(self)
  rhs=ternary.rhs.accept(self)
  CondExpr.new(cond,lhs,rhs)
end

#visitFunction(func, args = nil) ⇒ Object



7
8
9
10
# File 'lib/crokus/tac_builder.rb', line 7

def visitFunction func,args=nil
  puts " "*1+"|--[+] tac builder for '#{func.name}'"
  build func.cfg
end

#visitIndexed(idx, args = nil) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/crokus/tac_builder.rb', line 100

def visitIndexed idx,args=nil
  lhs=idx.lhs.accept(self)
  ret=Indexed.new(lhs,idx.rhs)
  if idx.rhs.respond_to? :lhs # WARNING : Indexed! Pointed! etc
    lhs=idx.rhs.accept(self)
    tmp=new_tmp()
    @new_stmts << Assign.new(tmp,OP_ASSIGN,lhs)
    ret.rhs=tmp
  end
  return ret
end

#visitITE(ite, args = nil) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/crokus/tac_builder.rb', line 66

def visitITE ite,args=nil
  ret=ITE.new(ite.cond,ite.trueBranch,ite.falseBranch)
  case ite.cond
  when Binary
    cond=ite.cond.accept(self)
    tmp=new_tmp()
    @new_stmts << Assign.new(tmp,OP_ASSIGN,cond)
    ret.cond=tmp
  when Parenth
    cond=ite.cond.accept(self)
    ret.cond=cond.expr
  end
  ret
end

#visitParenth(par, args = nil) ⇒ Object



112
113
114
115
116
117
118
119
120
# File 'lib/crokus/tac_builder.rb', line 112

def visitParenth par,args=nil
  ret=Parenth.new(par.expr)
  e=par.expr.accept(self)
  tmp=new_tmp()
  @new_stmts||=[]
  @new_stmts << Assign.new(tmp,OP_ASSIGN,e)
  ret.expr=tmp
  return ret
end