Imported garbage collection allocator and converted Type to a gc object.
2 * Copyright (C) 2012 David Anderson
4 * This file is part of JITCraft.
6 * JITCraft is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License as published by the Free
8 * Software Foundation, either version 3 of the License, or (at your option)
11 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * JITCraft. If not, see http://www.gnu.org/licenses/.
18 #include "SemanticAnalysis.h"
21 #include "TypeManager.h"
26 IsPrimitiveType(Type *type, PrimitiveType primitive)
31 if (!type->isPrimitive())
34 return primitive == type->primitive();
38 EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
43 *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
47 *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
55 EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
57 switch (expression->kind()) {
58 case AstNode::kBinaryExpression:
62 BinaryExpression *b = expression->toBinaryExpression();
63 if (!EvaluateForConstant(b->left(), &left) ||
64 !EvaluateForConstant(b->right(), &right))
68 return EvaluateBinaryOperation(b->token(), left, right, out);
71 case AstNode::kNameProxy:
73 NameProxy *proxy = expression->toNameProxy();
74 if (proxy->binding()->kind() != BoundName::CONSTANT)
77 NamedConstant *c = proxy->binding()->toNamedConstant();
78 if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
85 case AstNode::kIntegerLiteral:
86 *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
94 SemanticAnalysis::SemanticAnalysis(ParseTree *tree)
101 SemanticAnalysis::analyze()
103 for (size_t i = 0; i < tree_->statements()->length(); i++) {
104 Statement *statement = tree_->statements()->at(i);
105 statement->accept(this);
112 SemanticAnalysis::visit(NameProxy *name)
114 name->setType(name->binding()->type());
118 SemanticAnalysis::visitForLoad(Expression *expression)
120 expression->accept(this);
121 if (expression->type() && expression->type()->isArray())
122 expression->setType(expression->type()->contained());
123 return expression->type();
127 SemanticAnalysis::visitForRef(Expression *expression)
129 expression->accept(this);
130 return expression->type();
134 TypeCheck(Type *left, Type *right)
139 if (left->isPrimitive()) {
140 if (!right->isPrimitive())
142 return left->primitive() == right->primitive();
149 SemanticAnalysis::visit(Assignment *node)
151 visitForLoad(node->expression());
153 if (node->lvalue()->isIndexExpression()) {
154 node->lvalue()->accept(this);
155 node->setType(node->lvalue()->type()->contained());
157 NameProxy *proxy = node->lvalue()->toNameProxy();
158 if (!proxy->binding()->kind() == BoundName::VARIABLE) {
159 fprintf(stderr, "error\n");
163 Variable *var = proxy->binding()->toVariable();
164 node->setType(var->type());
167 assert(TypeCheck(node->type(), node->expression()->type()));
172 SemanticAnalysis::visit(BinaryExpression *node)
174 Type *left = visitForLoad(node->left());
175 Type *right = visitForLoad(node->right());
177 if (node->token() >= TOK_PLUS && node->token() <= TOK_SLASH) {
178 // Both sides must be primitive.
182 // If either side is a float, the other side must be a float or int.
183 if (left->isFloat() || right->isFloat()) {
184 assert(left->isFloat() || left->isInt());
185 assert(right->isFloat() || right->isInt());
186 node->setType(left->isFloat() ? left : right);
191 // For now, assert everything else is integer and untagged.
192 assert(left->isInt() && right->isInt());
193 assert(!left->tag() && !right->tag());
198 SemanticAnalysis::visit(ReturnStatement *node)
200 visitForLoad(node->expression());
206 SemanticAnalysis::visit(ForStatement *node)
209 if (node->declaration())
210 node->declaration()->accept(this);
211 if (node->condition())
212 visitForLoad(node->condition());
214 node->update()->accept(this);
215 node->body()->accept(this);
220 SemanticAnalysis::visit(WhileStatement *node)
223 node->condition()->accept(this);
224 node->body()->accept(this);
229 SemanticAnalysis::visit(BlockStatement *node)
231 for (size_t i = 0; i < node->statements()->length(); i++) {
232 Statement *statement = node->statements()->at(i);
233 statement->accept(this);
238 SemanticAnalysis::visit(VariableDeclaration *node)
240 Type *type = ZONE()->types()->getPrimitiveForTag(node->tag());
244 if (node->postDimensions()) {
245 if (node->postDimensions()->size() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
250 for (size_t i = node->postDimensions()->size() - 1; i < node->postDimensions()->size(); i--) {
251 Expression *expr = node->postDimensions()->at(i);
254 if (!IsPrimitiveType(expr->type(), PrimitiveType_Int32)) {
255 typeError(expr, "integer");
260 if (expr->isIntegerLiteral()) {
261 size = expr->toIntegerLiteral()->value();
266 if (size >= INT_MAX / sizeof(int)) {
272 type = ZONE()->types()->unsafeArray(type, size);
275 if (node->initialization()) {
276 Type *right = visitForLoad(node->initialization());
277 assert(TypeCheck(type, right));
281 node->variable()->setType(type);
285 SemanticAnalysis::visit(IntegerLiteral *node)
287 node->setType(ZONE()->types()->getPrimitive(PrimitiveType_Int32));
291 SemanticAnalysis::visit(ExpressionStatement *node)
293 node->expression()->accept(this);
297 SemanticAnalysis::visit(FunctionStatement *node)
299 node->body()->accept(this);
303 SemanticAnalysis::visit(CallExpression *node)
308 SemanticAnalysis::visit(IfStatement *node)
310 visitForLoad(node->condition());
311 node->ifTrue()->accept(this);
313 node->ifFalse()->accept(this);
317 SemanticAnalysis::visit(IndexExpression *node)
319 Type *left = visitForRef(node->left());
320 Type *right = visitForLoad(node->right());
322 if (!right || !right->isInt()) {
323 typeError(node->right(), "integer");
326 if (!left || !left->isArray() || !left->contained()->isPrimitive()) {
327 typeError(node->left(), "array");
334 SemanticAnalysis::visit(EnumStatement *node)
336 // :TODO: test "enum Float { ..."
337 Name *tag = node->name();
339 Type *type = ZONE()->types()->getPrimitiveForTag(tag);
344 for (size_t i = 0; i < node->entries()->size(); i++) {
345 EnumStatement::Entry &entry = node->entries()->at(i);
347 BoxedPrimitive box = BoxedPrimitive::Int(value);
349 entry.expr->accept(this);
350 if (!EvaluateForConstant(entry.expr, &box))
351 fprintf(stderr, "expected constant integer expression\n");
353 assert(box.type() == PrimitiveType_Int32);
357 entry.name->set(type, box);
363 SemanticAnalysis::visit(FloatLiteral *node)
365 Type *type = ZONE()->types()->getPrimitive(PrimitiveType_Float);
373 SemanticAnalysis::visit(BreakStatement *node)
375 assert(loopDepth_ > 0);
379 SemanticAnalysis::visit(ContinueStatement *node)
381 assert(loopDepth_ > 0);