fixed cast bool, bool
[ozulis.git] / src / ast / type-checker-visitor.cc
blob4058ae896e581a291d8a3c59fe0d264f160fd4f1
1 #include <boost/foreach.hpp>
3 #include <core/assert.hh>
5 #include "type-checker-visitor.hh"
6 #include "scope.hh"
8 namespace ast
10 TypeCheckerVisitor::castTable_t TypeCheckerVisitor::castTable_;
12 TypeCheckerVisitor::TypeCheckerVisitor()
13 : BrowseVisitor(),
14 scope_()
16 #define ADD_CAST_TABLE_ENTRY(Type1, Type2, Method) \
17 do { \
18 const id_t id1 = Type1::nodeTypeId(); \
19 const id_t id2 = Type2::nodeTypeId(); \
20 castTableKey_t key; \
21 if (id1 < id2) \
22 key = std::make_pair(id1, id2); \
23 else \
24 key = std::make_pair(id2, id1); \
25 assert_msg(!castTable_.count(key), \
26 "the same key has been insterted two times"); \
27 castTable_[key] = TypeCheckerVisitor::Method; \
28 } while (0)
30 if (castTable_.empty())
32 ADD_CAST_TABLE_ENTRY(BoolType, BoolType, castBoolBool);
33 ADD_CAST_TABLE_ENTRY(FloatType, IntegerType, castIntegerFloat);
34 ADD_CAST_TABLE_ENTRY(IntegerType, IntegerType, castIntegerInteger);
38 TypeCheckerVisitor::~TypeCheckerVisitor()
42 void
43 TypeCheckerVisitor::visit(File & node)
45 scope_ = node.scope;
46 super_t::visit(node);
49 void
50 TypeCheckerVisitor::visit(Block & node)
52 scope_ = node.scope;
53 // We must respect this order
54 BOOST_FOREACH (Node * varDecl, (*node.varDecls))
55 varDecl->accept(*this);
56 BOOST_FOREACH (Node * statement, (*node.statements))
57 statement->accept(*this);
60 void
61 TypeCheckerVisitor::visit(AssignExp & node)
63 node.dest->accept(*this);
64 node.value->accept(*this);
65 CastExp * castExp = new CastExp();
66 castExp->type = node.dest->type;
67 castExp->exp = node.value;
68 assert(node.dest->type);
69 node.value = castExp;
72 void
73 TypeCheckerVisitor::visit(IdExp & node)
75 assert(scope_);
76 const Symbol * s = scope_->findSymbol(node.name);
77 assert(s);
78 assert(s->type);
79 node.type = s->type;
82 void
83 TypeCheckerVisitor::visit(Symbol & node)
85 assert(scope_);
86 const Symbol * s = scope_->findSymbol(node.name);
87 assert(s);
88 assert(s->type);
89 node.type = s->type;
92 void
93 TypeCheckerVisitor::visit(CastExp & node)
95 assert(node.exp);
96 node.exp->accept(*this);
99 #define VISIT(Type) \
100 void \
101 TypeCheckerVisitor::visit(Type & node) \
103 node.left->accept(*this); \
104 node.right->accept(*this); \
105 /** \
106 * @todo check if type match \
107 * @todo look for an overloaded operator '+' \
108 * @todo the cast can be applied on both nodes \
109 */ \
110 CastExp * castExp = findCast(node.left->type, node.right->type); \
112 if (!castExp) \
114 node.type = node.left->type; \
115 return; \
118 if (castExp->type == node.left->type) \
120 castExp->exp = node.right; \
121 node.right = castExp; \
123 else \
125 castExp->exp = node.left; \
126 node.left = castExp; \
128 node.type = castExp->type; \
131 VISIT(AddExp)
132 VISIT(SubExp)
133 VISIT(MulExp)
134 VISIT(DivExp)
135 VISIT(ModExp)
137 VISIT(AndExp)
138 VISIT(OrExp)
139 VISIT(XorExp)
141 VISIT(ShlExp)
142 VISIT(AShrExp)
143 VISIT(LShrExp)
145 VISIT(EqExp)
146 VISIT(NeqExp)
147 VISIT(LtExp)
148 VISIT(LtEqExp)
149 VISIT(GtExp)
150 VISIT(GtEqExp)
152 CastExp *
153 TypeCheckerVisitor::findCast(Type * type1,
154 Type * type2)
156 assert(type1);
157 assert(type2);
159 castTableKey_t key;
160 if (type1->nodeType < type2->nodeType)
161 key = std::make_pair(type1->nodeType, type2->nodeType);
162 else
163 key = std::make_pair(type2->nodeType, type1->nodeType);
164 assert(castTable_.count(key) > 0);
166 CastExp * castExp = castTable_[key](type1, type2);
167 return castExp;
170 CastExp *
171 TypeCheckerVisitor::castBoolBool(Type * /*type1*/,
172 Type * /*type2*/)
174 return 0;
177 CastExp *
178 TypeCheckerVisitor::castIntegerFloat(Type * type1,
179 Type * type2)
181 CastExp * castExp = new CastExp();
182 IntegerType * itype;
183 FloatType * ftype;
185 if (type1->nodeType == IntegerType::nodeTypeId())
187 itype = reinterpret_cast<IntegerType *> (type1);
188 ftype = reinterpret_cast<FloatType *> (type2);
190 else
192 itype = reinterpret_cast<IntegerType *> (type2);
193 ftype = reinterpret_cast<FloatType *> (type1);
196 castExp->type = ftype;
197 return castExp;
200 CastExp *
201 TypeCheckerVisitor::castIntegerInteger(Type * type1,
202 Type * type2)
204 CastExp * castExp = 0;
205 IntegerType * itype1 = reinterpret_cast<IntegerType *> (type1);
206 IntegerType * itype2 = reinterpret_cast<IntegerType *> (type2);
208 if (itype1->size == itype2->size && itype1->isSigned == itype2->isSigned)
209 return 0;
210 castExp = new CastExp();
211 if (itype1->size > itype2->size)
212 castExp->type = itype1;
213 else
214 castExp->type = itype2;
215 return castExp;