Implemented break and continue support.
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"
24 IsPrimitiveType(Type *type, PrimitiveType primitive)
29 if (!type->isPrimitive())
32 return primitive == type->primitive();
36 EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
41 *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
45 *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
53 EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
55 switch (expression->kind()) {
56 case AstNode::kBinaryExpression:
60 BinaryExpression *b = expression->toBinaryExpression();
61 if (!EvaluateForConstant(b->left(), &left) ||
62 !EvaluateForConstant(b->right(), &right))
66 return EvaluateBinaryOperation(b->token(), left, right, out);
69 case AstNode::kNameProxy:
71 NameProxy *proxy = expression->toNameProxy();
72 if (proxy->binding()->kind() != BoundName::CONSTANT)
75 NamedConstant *c = proxy->binding()->toNamedConstant();
76 if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
83 case AstNode::kIntegerLiteral:
84 *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
92 SemanticAnalysis::SemanticAnalysis(ParseTree *tree)
99 SemanticAnalysis::analyze()
101 for (size_t i = 0; i < tree_->statements()->length(); i++) {
102 Statement *statement = tree_->statements()->at(i);
103 statement->accept(this);
110 SemanticAnalysis::visit(NameProxy *name)
112 name->setType(name->binding()->type());
116 SemanticAnalysis::visitForLoad(Expression *expression)
118 expression->accept(this);
119 if (expression->type() && expression->type()->isArray())
120 expression->setType(expression->type()->contained());
121 return expression->type();
125 SemanticAnalysis::visitForRef(Expression *expression)
127 expression->accept(this);
128 return expression->type();
132 TypeCheck(Type *left, Type *right)
137 if (left->isPrimitive()) {
138 if (!right->isPrimitive())
140 return left->primitive() == right->primitive();
147 SemanticAnalysis::visit(Assignment *node)
149 visitForLoad(node->expression());
151 if (node->lvalue()->isIndexExpression()) {
152 node->lvalue()->accept(this);
153 node->setType(node->lvalue()->type()->contained());
155 NameProxy *proxy = node->lvalue()->toNameProxy();
156 if (!proxy->binding()->kind() == BoundName::VARIABLE) {
157 fprintf(stderr, "error\n");
161 Variable *var = proxy->binding()->toVariable();
162 node->setType(var->type());
165 assert(TypeCheck(node->type(), node->expression()->type()));
170 SemanticAnalysis::visit(BinaryExpression *node)
172 Type *left = visitForLoad(node->left());
173 Type *right = visitForLoad(node->right());
175 if (node->token() >= TOK_PLUS && node->token() <= TOK_SLASH) {
176 // Both sides must be primitive.
180 // If either side is a float, the other side must be a float or int.
181 if (left->isFloat() || right->isFloat()) {
182 assert(left->isFloat() || left->isInt());
183 assert(right->isFloat() || right->isInt());
184 node->setType(left->isFloat() ? left : right);
189 // For now, assert everything else is integer and untagged.
190 assert(left->isInt() && right->isInt());
191 assert(!left->tag() && !right->tag());
196 SemanticAnalysis::visit(ReturnStatement *node)
198 visitForLoad(node->expression());
204 SemanticAnalysis::visit(ForStatement *node)
207 if (node->declaration())
208 node->declaration()->accept(this);
209 if (node->condition())
210 visitForLoad(node->condition());
212 node->update()->accept(this);
213 node->body()->accept(this);
218 SemanticAnalysis::visit(WhileStatement *node)
221 node->condition()->accept(this);
222 node->body()->accept(this);
227 SemanticAnalysis::visit(BlockStatement *node)
229 for (size_t i = 0; i < node->statements()->length(); i++) {
230 Statement *statement = node->statements()->at(i);
231 statement->accept(this);
236 SemanticAnalysis::visit(VariableDeclaration *node)
238 Type *type = Type::NewPrimitive(node->tag());
242 if (node->postDimensions()) {
243 if (node->postDimensions()->size() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
248 for (size_t i = node->postDimensions()->size() - 1; i < node->postDimensions()->size(); i--) {
249 Expression *expr = node->postDimensions()->at(i);
252 if (!IsPrimitiveType(expr->type(), PrimitiveType_Int32)) {
253 typeError(expr, "integer");
258 if (expr->isIntegerLiteral()) {
259 size = expr->toIntegerLiteral()->value();
264 if (size >= INT_MAX / sizeof(int)) {
270 type = Type::NewUnsafeArray(type, size);
273 if (node->initialization()) {
274 Type *right = visitForLoad(node->initialization());
275 assert(TypeCheck(type, right));
279 node->variable()->setType(type);
283 SemanticAnalysis::visit(IntegerLiteral *node)
285 Type *type = Type::NewPrimitive(NULL);
290 SemanticAnalysis::visit(ExpressionStatement *node)
292 node->expression()->accept(this);
296 SemanticAnalysis::visit(FunctionStatement *node)
298 node->body()->accept(this);
302 SemanticAnalysis::visit(CallExpression *node)
307 SemanticAnalysis::visit(IfStatement *node)
309 visitForLoad(node->condition());
310 node->ifTrue()->accept(this);
312 node->ifFalse()->accept(this);
316 SemanticAnalysis::visit(IndexExpression *node)
318 Type *left = visitForRef(node->left());
319 Type *right = visitForLoad(node->right());
321 if (!right || !right->isInt()) {
322 typeError(node->right(), "integer");
325 if (!left || !left->isArray() || !left->contained()->isPrimitive()) {
326 typeError(node->left(), "array");
333 SemanticAnalysis::visit(EnumStatement *node)
335 // :TODO: test "enum Float { ..."
336 Name *tag = node->name();
338 Type *type = Type::NewPrimitive(tag);
343 for (size_t i = 0; i < node->entries()->size(); i++) {
344 EnumStatement::Entry &entry = node->entries()->at(i);
346 BoxedPrimitive box = BoxedPrimitive::Int(value);
348 entry.expr->accept(this);
349 if (!EvaluateForConstant(entry.expr, &box))
350 fprintf(stderr, "expected constant integer expression\n");
352 assert(box.type() == PrimitiveType_Int32);
356 entry.name->set(type, box);
362 SemanticAnalysis::visit(FloatLiteral *node)
364 Type *type = Type::NewPrimitive(PrimitiveType_Float);
372 SemanticAnalysis::visit(BreakStatement *node)
374 assert(loopDepth_ > 0);
378 SemanticAnalysis::visit(ContinueStatement *node)
380 assert(loopDepth_ > 0);