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(BoolType
, FloatType
, castBoolFloat
);
34 ADD_CAST_TABLE_ENTRY(BoolType
, DoubleType
, castBoolDouble
);
35 ADD_CAST_TABLE_ENTRY(IntegerType
, IntegerType
, castIntegerInteger
);
36 ADD_CAST_TABLE_ENTRY(IntegerType
, FloatType
, castIntegerFloat
);
37 ADD_CAST_TABLE_ENTRY(IntegerType
, DoubleType
, castIntegerDouble
);
38 ADD_CAST_TABLE_ENTRY(FloatType
, FloatType
, castFloatFloat
);
39 ADD_CAST_TABLE_ENTRY(FloatType
, DoubleType
, castFloatDouble
);
43 TypeCheckerVisitor::~TypeCheckerVisitor()
48 TypeCheckerVisitor::visit(File
& node
)
55 TypeCheckerVisitor::visit(Block
& node
)
58 // We must respect this order
59 BOOST_FOREACH (Node
* varDecl
, (*node
.varDecls
))
60 varDecl
->accept(*this);
61 BOOST_FOREACH (Node
* statement
, (*node
.statements
))
62 statement
->accept(*this);
66 TypeCheckerVisitor::visit(AssignExp
& node
)
68 node
.dest
->accept(*this);
69 node
.value
->accept(*this);
70 CastExp
* castExp
= new CastExp();
71 castExp
->type
= node
.dest
->type
;
72 castExp
->exp
= node
.value
;
73 assert(node
.dest
->type
);
78 TypeCheckerVisitor::visit(IdExp
& node
)
81 const Symbol
* s
= scope_
->findSymbol(node
.name
);
88 TypeCheckerVisitor::visit(Symbol
& node
)
91 const Symbol
* s
= scope_
->findSymbol(node
.name
);
98 TypeCheckerVisitor::visit(CastExp
& node
)
101 node
.exp
->accept(*this);
104 #define VISIT(Type) \
106 TypeCheckerVisitor::visit(Type & node) \
108 node.left->accept(*this); \
109 node.right->accept(*this); \
111 * @todo check if type match \
112 * @todo look for an overloaded operator '+' \
113 * @todo the cast can be applied on both nodes \
115 CastExp * castExp = findCast(node.left->type, node.right->type); \
119 node.type = node.left->type; \
123 if (castExp->type == node.left->type) \
125 castExp->exp = node.right; \
126 node.right = castExp; \
130 castExp->exp = node.left; \
131 node.left = castExp; \
133 node.type = castExp->type; \
158 TypeCheckerVisitor::findCast(Type
* type1
,
165 if (type1
->nodeType
< type2
->nodeType
)
166 key
= std::make_pair(type1
->nodeType
, type2
->nodeType
);
168 key
= std::make_pair(type2
->nodeType
, type1
->nodeType
);
169 assert(castTable_
.count(key
) > 0);
171 CastExp
* castExp
= castTable_
[key
](type1
, type2
);
175 #define DUMMY_CAST(Type1, Type2) \
177 TypeCheckerVisitor::cast##Type1##Type2(Type * /*type1*/, \
183 DUMMY_CAST(Bool
, Bool
)
184 DUMMY_CAST(Float
, Float
)
186 #define TRIVIAL_CAST(Type1, Type2) \
188 TypeCheckerVisitor::cast##Type1##Type2(Type * type1, \
191 CastExp * castExp = new CastExp(); \
193 if (type1->nodeType == Type2##Type::nodeTypeId()) \
194 castExp->type = type1; \
196 castExp->type = type2; \
200 TRIVIAL_CAST(Bool
, Integer
)
201 TRIVIAL_CAST(Bool
, Float
)
202 TRIVIAL_CAST(Bool
, Double
)
203 TRIVIAL_CAST(Integer
, Float
)
204 TRIVIAL_CAST(Integer
, Double
)
205 TRIVIAL_CAST(Float
, Double
)
208 TypeCheckerVisitor::castIntegerInteger(Type
* type1
,
211 CastExp
* castExp
= 0;
212 IntegerType
* itype1
= reinterpret_cast<IntegerType
*> (type1
);
213 IntegerType
* itype2
= reinterpret_cast<IntegerType
*> (type2
);
215 if (itype1
->size
== itype2
->size
&& itype1
->isSigned
== itype2
->isSigned
)
217 castExp
= new CastExp();
218 if (itype1
->size
> itype2
->size
)
219 castExp
->type
= itype1
;
221 castExp
->type
= itype2
;