Suport for goto and labels
[ozulis.git] / src / ast / simplify-visitor.cc
blob0bffb3f48430ced807b527ae79cc63835a9ac025
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.instrs))
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;
64 block.instrs = newList;
67 #define SIMPLIFY_BINARY_EXP(Type) \
68 /** \
69 * @internal \
70 * - Simplify childs \
71 * - Create a new id. \
72 * - Create a new assign exp to id. \
73 * - Create a IdExp and tell replace the parent's child with it. \
74 */ \
75 void \
76 SimplifyVisitor::visit(Type & node) \
77 { \
78 assert(node.left); \
79 node.left->accept(*this); \
80 node.left = replacement_; \
81 assert(node.right); \
82 node.right->accept(*this); \
83 node.right = replacement_; \
85 std::string name = nextId(); \
87 TmpResultExp * tmpRes = new TmpResultExp(); \
88 tmpRes->name = name; \
89 replacement_ = tmpRes; \
91 AssignExp * assign = new AssignExp(); \
92 assign->name = name; \
93 assign->value = &node; \
94 simplifications_.push_back(assign); \
97 SIMPLIFY_BINARY_EXP(EqExp)
98 SIMPLIFY_BINARY_EXP(NeqExp)
99 SIMPLIFY_BINARY_EXP(LtExp)
100 SIMPLIFY_BINARY_EXP(LtEqExp)
101 SIMPLIFY_BINARY_EXP(GtExp)
102 SIMPLIFY_BINARY_EXP(GtEqExp)
104 SIMPLIFY_BINARY_EXP(AddExp)
105 SIMPLIFY_BINARY_EXP(SubExp)
106 SIMPLIFY_BINARY_EXP(MulExp)
107 SIMPLIFY_BINARY_EXP(DivExp)
108 SIMPLIFY_BINARY_EXP(ModExp)
110 SIMPLIFY_BINARY_EXP(AndExp)
111 SIMPLIFY_BINARY_EXP(OrExp)
112 SIMPLIFY_BINARY_EXP(XorExp)
114 SIMPLIFY_BINARY_EXP(AndAndExp)
115 SIMPLIFY_BINARY_EXP(OrOrExp)
117 SIMPLIFY_BINARY_EXP(ShlExp)
118 SIMPLIFY_BINARY_EXP(AShrExp)
119 SIMPLIFY_BINARY_EXP(LShrExp)
121 void
122 SimplifyVisitor::visit(AssignExp & node)
124 assert(node.value);
125 node.value->accept(*this);
126 node.value = replacement_;
128 StoreVar * sv = new StoreVar();
129 sv->name = node.name;
130 sv->value = replacement_;
131 simplifications_.push_back(sv);
133 delete &node;
136 void
137 SimplifyVisitor::visit(NumberExp & node)
139 replacement_ = &node;
142 void
143 SimplifyVisitor::visit(IdExp & node)
145 LoadVar * lv = new LoadVar();
146 lv->name = node.name;
147 lv->to = nextId();
148 simplifications_.push_back(lv);
150 TmpResultExp * tre = new TmpResultExp();
151 tre->name = lv->to;
152 replacement_ = tre;
153 delete &node;
156 void
157 SimplifyVisitor::visit(Label & node)
159 simplifications_.push_back(&node);
162 void
163 SimplifyVisitor::visit(Goto & node)
165 simplifications_.push_back(&node);