refractored instructions to statements
[ozulis.git] / src / ast / simplify-visitor.cc
blob8f468e227894c90da2d4dd6c552395c442a8237b
1 #include <sstream>
2 #include <boost/foreach.hpp>
4 #include <core/assert.hh>
5 #include "simplify-visitor.hh"
7 namespace ast
9 /// @defgroup Visitors
10 /**
11 * @class SimplifyVisitor
12 * @ingroup Visitors
14 * <b>Algorithm</b><br>
15 * - on Block
16 * - for every instruction
17 * - split the instruction in 3 address instruction
20 SimplifyVisitor::SimplifyVisitor()
21 : BrowseVisitor(),
22 simplifications_(0),
23 replacement_(0),
24 nextId_(0)
28 SimplifyVisitor::~SimplifyVisitor()
32 std::string
33 SimplifyVisitor::nextId()
35 std::stringstream ss;
36 ss << "r" << ++nextId_;
37 return ss.str();
40 std::string
41 SimplifyVisitor::currentId() const
43 std::stringstream ss;
44 ss << "r" << nextId_;
45 return ss.str();
48 void
49 SimplifyVisitor::visit(Block & block)
51 /// @todo use a garbage collector
52 std::vector<Node *> * newList = new std::vector<Node *>();
54 BOOST_FOREACH (Node * node, (*block.statements))
56 assert(node);
57 simplifications_.clear();
58 node->accept(*this);
59 BOOST_FOREACH(Node * snode, simplifications_)
60 newList->push_back(snode);
61 //delete node;
63 //delete block.instrs;
65 block.statements = newList;
68 #define SIMPLIFY_BINARY_EXP(Type) \
69 /** \
70 * @internal \
71 * - Simplify childs \
72 * - Create a new id. \
73 * - Create a new assign exp to id. \
74 * - Create a IdExp and tell replace the parent's child with it. \
75 */ \
76 void \
77 SimplifyVisitor::visit(Type & node) \
78 { \
79 assert(node.left); \
80 node.left->accept(*this); \
81 node.left = replacement_; \
82 assert(node.right); \
83 node.right->accept(*this); \
84 node.right = replacement_; \
86 std::string name = nextId(); \
88 TmpResultExp * tmpRes = new TmpResultExp(); \
89 tmpRes->name = name; \
90 tmpRes->type = node.type; \
91 assert(tmpRes->type); \
92 replacement_ = tmpRes; \
94 AssignExp * assign = new AssignExp(); \
95 assign->dest = new Symbol(); \
96 assign->dest->name = name; \
97 assign->dest->type = node.type; \
98 assign->value = &node; \
99 assign->type = node.type; \
100 simplifications_.push_back(assign); \
103 SIMPLIFY_BINARY_EXP(EqExp)
104 SIMPLIFY_BINARY_EXP(NeqExp)
105 SIMPLIFY_BINARY_EXP(LtExp)
106 SIMPLIFY_BINARY_EXP(LtEqExp)
107 SIMPLIFY_BINARY_EXP(GtExp)
108 SIMPLIFY_BINARY_EXP(GtEqExp)
110 SIMPLIFY_BINARY_EXP(AddExp)
111 SIMPLIFY_BINARY_EXP(SubExp)
112 SIMPLIFY_BINARY_EXP(MulExp)
113 SIMPLIFY_BINARY_EXP(DivExp)
114 SIMPLIFY_BINARY_EXP(ModExp)
116 SIMPLIFY_BINARY_EXP(AndExp)
117 SIMPLIFY_BINARY_EXP(OrExp)
118 SIMPLIFY_BINARY_EXP(XorExp)
120 SIMPLIFY_BINARY_EXP(AndAndExp)
121 SIMPLIFY_BINARY_EXP(OrOrExp)
123 SIMPLIFY_BINARY_EXP(ShlExp)
124 SIMPLIFY_BINARY_EXP(AShrExp)
125 SIMPLIFY_BINARY_EXP(LShrExp)
127 void
128 SimplifyVisitor::visit(AssignExp & node)
130 assert(node.value);
131 node.value->accept(*this);
132 node.value = replacement_;
134 StoreVar * sv = new StoreVar();
135 sv->name = node.dest->name;
136 sv->value = replacement_;
137 simplifications_.push_back(sv);
139 delete &node;
142 void
143 SimplifyVisitor::visit(NumberExp & node)
145 replacement_ = &node;
148 void
149 SimplifyVisitor::visit(IdExp & node)
151 LoadVar * lv = new LoadVar();
152 lv->name = node.name;
153 lv->to = nextId();
154 lv->type = node.type;
155 simplifications_.push_back(lv);
157 TmpResultExp * tre = new TmpResultExp();
158 tre->name = lv->to;
159 tre->type = node.type;
160 replacement_ = tre;
161 delete &node;
165 * @internal
166 * develop the cast, and simplify it
168 void
169 SimplifyVisitor::visit(CastExp & node)
171 node.exp->accept(*this);
172 node.exp = replacement_;
174 AssignExp * assign = new AssignExp();
175 assign->value = &node;
176 assign->dest = new Symbol();
177 assign->dest->name = nextId();
178 assign->dest->type = node.type;
179 assign->type = node.type;
180 simplifications_.push_back(assign);
182 TmpResultExp * tre = new TmpResultExp();
183 tre->name = assign->dest->name;
184 tre->type = node.type;
185 replacement_ = tre;
188 void
189 SimplifyVisitor::visit(Label & node)
191 simplifications_.push_back(&node);
194 void
195 SimplifyVisitor::visit(Goto & node)
197 simplifications_.push_back(&node);