Added support for bitwise operators.
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)
98 SemanticAnalysis::analyze()
100 for (size_t i = 0; i < tree_->statements()->length(); i++) {
101 Statement *statement = tree_->statements()->at(i);
102 statement->accept(this);
109 SemanticAnalysis::visit(NameProxy *name)
111 name->setType(name->binding()->type());
115 SemanticAnalysis::visitForLoad(Expression *expression)
117 expression->accept(this);
118 if (expression->type() && expression->type()->isArray())
119 expression->setType(expression->type()->contained());
120 return expression->type();
124 SemanticAnalysis::visitForRef(Expression *expression)
126 expression->accept(this);
127 return expression->type();
131 TypeCheck(Type *left, Type *right)
136 if (left->isPrimitive()) {
137 if (!right->isPrimitive())
139 return left->primitive() == right->primitive();
146 SemanticAnalysis::visit(Assignment *node)
148 visitForLoad(node->expression());
150 if (node->lvalue()->isIndexExpression()) {
151 node->lvalue()->accept(this);
152 node->setType(node->lvalue()->type()->contained());
154 NameProxy *proxy = node->lvalue()->toNameProxy();
155 if (!proxy->binding()->kind() == BoundName::VARIABLE) {
156 fprintf(stderr, "error\n");
160 Variable *var = proxy->binding()->toVariable();
161 node->setType(var->type());
164 assert(TypeCheck(node->type(), node->expression()->type()));
169 SemanticAnalysis::visit(BinaryExpression *node)
171 Type *left = visitForLoad(node->left());
172 Type *right = visitForLoad(node->right());
174 if (node->token() >= TOK_PLUS && node->token() <= TOK_SLASH) {
175 // Both sides must be primitive.
179 // If either side is a float, the other side must be a float or int.
180 if (left->isFloat() || right->isFloat()) {
181 assert(left->isFloat() || left->isInt());
182 assert(right->isFloat() || right->isInt());
183 node->setType(left->isFloat() ? left : right);
188 // For now, assert everything else is integer and untagged.
189 assert(left->isInt() && right->isInt());
190 assert(!left->tag() && !right->tag());
195 SemanticAnalysis::visit(ReturnStatement *node)
197 visitForLoad(node->expression());
203 SemanticAnalysis::visit(ForStatement *node)
205 if (node->declaration())
206 node->declaration()->accept(this);
207 if (node->condition())
208 visitForLoad(node->condition());
210 node->update()->accept(this);
211 node->body()->accept(this);
215 SemanticAnalysis::visit(BlockStatement *node)
217 for (size_t i = 0; i < node->statements()->length(); i++) {
218 Statement *statement = node->statements()->at(i);
219 statement->accept(this);
224 SemanticAnalysis::visit(VariableDeclaration *node)
226 Type *type = Type::NewPrimitive(node->tag());
230 if (node->postDimensions()) {
231 if (node->postDimensions()->size() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
236 for (size_t i = node->postDimensions()->size() - 1; i < node->postDimensions()->size(); i--) {
237 Expression *expr = node->postDimensions()->at(i);
240 if (!IsPrimitiveType(expr->type(), PrimitiveType_Int32)) {
241 typeError(expr, "integer");
246 if (expr->isIntegerLiteral()) {
247 size = expr->toIntegerLiteral()->value();
252 if (size >= INT_MAX / sizeof(int)) {
258 type = Type::NewUnsafeArray(type, size);
261 Type *right = visitForLoad(node->initialization());
262 assert(TypeCheck(type, right));
265 node->variable()->setType(type);
269 SemanticAnalysis::visit(IntegerLiteral *node)
271 Type *type = Type::NewPrimitive(NULL);
276 SemanticAnalysis::visit(ExpressionStatement *node)
278 node->expression()->accept(this);
282 SemanticAnalysis::visit(FunctionStatement *node)
284 node->body()->accept(this);
288 SemanticAnalysis::visit(CallExpression *node)
293 SemanticAnalysis::visit(IfStatement *node)
298 SemanticAnalysis::visit(IndexExpression *node)
300 Type *left = visitForRef(node->left());
301 Type *right = visitForLoad(node->right());
303 if (!right || !right->isInt()) {
304 typeError(node->right(), "integer");
307 if (!left || !left->isArray() || !left->contained()->isPrimitive()) {
308 typeError(node->left(), "array");
315 SemanticAnalysis::visit(EnumStatement *node)
317 // :TODO: test "enum Float { ..."
318 Name *tag = node->name();
320 Type *type = Type::NewPrimitive(tag);
325 for (size_t i = 0; i < node->entries()->size(); i++) {
326 EnumStatement::Entry &entry = node->entries()->at(i);
328 BoxedPrimitive box = BoxedPrimitive::Int(value);
330 entry.expr->accept(this);
331 if (!EvaluateForConstant(entry.expr, &box))
332 fprintf(stderr, "expected constant integer expression\n");
334 assert(box.type() == PrimitiveType_Int32);
338 entry.name->set(type, box);
344 SemanticAnalysis::visit(FloatLiteral *node)
346 Type *type = Type::NewPrimitive(PrimitiveType_Float);