1 #include <boost/foreach.hpp>
3 #include <core/assert.hh>
5 #include "type-checker-visitor.hh"
10 TypeCheckerVisitor::castTable_t
TypeCheckerVisitor::castTable_
;
12 TypeCheckerVisitor::TypeCheckerVisitor()
16 #define ADD_CAST_TABLE_ENTRY(Type1, Type2, Method) \
18 const id_t id1 = Type1::nodeTypeId(); \
19 const id_t id2 = Type2::nodeTypeId(); \
22 key = std::make_pair(id1, id2); \
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; \
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()
43 TypeCheckerVisitor::visit(File
& node
)
50 TypeCheckerVisitor::visit(Block
& node
)
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);
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
);
73 TypeCheckerVisitor::visit(IdExp
& node
)
76 const Symbol
* s
= scope_
->findSymbol(node
.name
);
83 TypeCheckerVisitor::visit(Symbol
& node
)
86 const Symbol
* s
= scope_
->findSymbol(node
.name
);
93 TypeCheckerVisitor::visit(CastExp
& node
)
96 node
.exp
->accept(*this);
101 TypeCheckerVisitor::visit(Type & node) \
103 node.left->accept(*this); \
104 node.right->accept(*this); \
106 * @todo check if type match \
107 * @todo look for an overloaded operator '+' \
108 * @todo the cast can be applied on both nodes \
110 CastExp * castExp = findCast(node.left->type, node.right->type); \
114 node.type = node.left->type; \
118 if (castExp->type == node.left->type) \
120 castExp->exp = node.right; \
121 node.right = castExp; \
125 castExp->exp = node.left; \
126 node.left = castExp; \
128 node.type = castExp->type; \
153 TypeCheckerVisitor::findCast(Type
* type1
,
160 if (type1
->nodeType
< type2
->nodeType
)
161 key
= std::make_pair(type1
->nodeType
, type2
->nodeType
);
163 key
= std::make_pair(type2
->nodeType
, type1
->nodeType
);
164 assert(castTable_
.count(key
) > 0);
166 CastExp
* castExp
= castTable_
[key
](type1
, type2
);
171 TypeCheckerVisitor::castBoolBool(Type
* /*type1*/,
178 TypeCheckerVisitor::castIntegerFloat(Type
* type1
,
181 CastExp
* castExp
= new CastExp();
185 if (type1
->nodeType
== IntegerType::nodeTypeId())
187 itype
= reinterpret_cast<IntegerType
*> (type1
);
188 ftype
= reinterpret_cast<FloatType
*> (type2
);
192 itype
= reinterpret_cast<IntegerType
*> (type2
);
193 ftype
= reinterpret_cast<FloatType
*> (type1
);
196 castExp
->type
= ftype
;
201 TypeCheckerVisitor::castIntegerInteger(Type
* type1
,
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
)
210 castExp
= new CastExp();
211 if (itype1
->size
> itype2
->size
)
212 castExp
->type
= itype1
;
214 castExp
->type
= itype2
;