Scanning, parsing, and static analysis now report errors properly.
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"
27 IsPrimitiveType(Type *type, PrimitiveType primitive)
32 if (!type->isPrimitive())
35 return primitive == type->primitive();
39 EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
44 *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
48 *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
56 EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
58 switch (expression->kind()) {
59 case AstNode::kBinaryExpression:
63 BinaryExpression *b = expression->toBinaryExpression();
64 if (!EvaluateForConstant(b->left(), &left) ||
65 !EvaluateForConstant(b->right(), &right))
69 return EvaluateBinaryOperation(b->token(), left, right, out);
72 case AstNode::kNameProxy:
74 NameProxy *proxy = expression->toNameProxy();
75 if (proxy->binding()->kind() != BoundName::CONSTANT)
78 NamedConstant *c = proxy->binding()->toNamedConstant();
79 if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
86 case AstNode::kIntegerLiteral:
87 *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
95 SemanticAnalysis::SemanticAnalysis(CompileContext &cc, ParseTree *tree)
104 SemanticAnalysis::analyze()
109 for (size_t i = 0; i < tree_->statements()->length(); i++) {
110 Statement *statement = tree_->statements()->at(i);
111 if (statement->isFunctionStatement()) {
112 FunctionStatement *funstmt = statement->toFunctionStatement();
113 if (!preanalyze(funstmt))
118 for (size_t i = 0; i < tree_->statements()->length(); i++) {
119 Statement *statement = tree_->statements()->at(i);
120 statement->accept(this);
123 return !cc_.failures();
127 SemanticAnalysis::visitAndApplyType(Expression *expression)
129 expression->accept(this);
130 return expression->type();
134 SemanticAnalysis::visitForLoad(Expression *expression)
137 Type *type = visitAndApplyType(expression);
141 if (type->isReference()) {
142 expression->setType(type->contained());
143 } else if (expression->isIndexExpression()) {
145 expression->setType(type->contained());
148 return expression->type();
152 SemanticAnalysis::visitForRef(Expression *expression)
154 expression->accept(this);
155 return expression->type();
158 static inline const char *
159 GetTypeName(Type *type)
163 if (type->isFunction())
165 if (type->isReference())
166 type = type->contained();
173 SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Type *type)
175 const char *op = TokenNames[token];
176 const char *name = GetTypeName(type);
178 cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
182 SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Type *left, Type *right)
184 const char *op = TokenNames[token];
185 const char *leftName = GetTypeName(left);
186 const char *rightName = GetTypeName(right);
188 cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
192 SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Type *left, Type *right)
194 if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
195 (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
197 // If either side is a float, the other side must be a float or int.
198 if (left->isFloat() || right->isFloat()) {
199 Type *floatType = left->isFloat() ? left : right;
200 Type *other = left->isFloat() ? right : left;
201 if (other->isFloat() || (other->isInt32() && !other->tag()))
206 if ((!left->isInt32() || left->tag()) ||
207 (!right->isInt32() || right->tag()))
209 binaryTypeError(node, token, left, right);
217 SemanticAnalysis::canTest(AstNode *node, Type *type)
219 if (type->isArray()) {
220 cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
227 SemanticAnalysis::visitForLValue(Expression *expression)
229 if (expression->isIndexExpression()) {
230 Type *type = visitAndApplyType(expression);
234 return type->contained();
237 if (!expression->isNameProxy()) {
238 cc_.reportError(expression->pos(), Message_ExpectedLValue);
242 NameProxy *proxy = expression->toNameProxy();
243 if (!proxy->binding()->kind() == BoundName::VARIABLE) {
244 cc_.reportError(expression->pos(), Message_ExpectedLValue);
248 Variable *var = proxy->binding()->toVariable();
252 if (var->type()->isReference())
253 return var->type()->contained();
258 SemanticAnalysis::visit(NameProxy *name)
260 name->setType(name->binding()->type());
264 SemanticAnalysis::visit(Assignment *node)
266 Type *exprType = visitForLoad(node->expression());
271 Type *type = visitForLValue(node->lvalue());
275 if (node->token() != TOK_ASSIGN) {
276 if (!typeCheckBinary(node, node->token(), type, exprType))
280 if (!typeCheckAssignment(node, exprType, type, true))
287 SemanticAnalysis::visit(IncDecExpression *node)
290 Type *type = visitForLValue(node->expression());
294 assert(!type->isReference());
296 if ((!type->isInt32() || (type->isInt32() && type->tag())) && !type->isFloat()) {
297 unaryTypeError(node, node->token(), type);
305 SemanticAnalysis::visit(BinaryExpression *node)
308 Type *left = visitForLoad(node->left());
309 Type *right = visitForLoad(node->right());
313 Type *result = typeCheckBinary(node, node->token(), left, right);
317 node->setType(result);
321 SemanticAnalysis::visit(ReturnStatement *node)
323 Type *type = visitForLoad(node->expression());
327 if (!typeCheckAssignment(node, type, function_->returnType(), true))
332 SemanticAnalysis::visit(ForStatement *node)
336 scope_ = node->scope();
338 if (node->initialization())
339 node->initialization()->accept(this);
341 if (node->condition()) {
342 Type *type = visitForLoad(node->condition());
343 if (!type || !canTest(node->condition(), type)) {
350 node->update()->accept(this);
352 node->body()->accept(this);
355 scope_ = scope_->enclosing();
360 SemanticAnalysis::visit(WhileStatement *node)
364 Type *type = visitForLoad(node->condition());
365 if (!type || !canTest(node->condition(), type)) {
370 node->body()->accept(this);
375 SemanticAnalysis::visit(BlockStatement *node)
378 scope_ = node->scope();
379 for (size_t i = 0; i < node->statements()->length(); i++) {
380 Statement *statement = node->statements()->at(i);
381 statement->accept(this);
384 scope_ = scope_->enclosing();
388 SemanticAnalysis::visit(VariableDeclaration *node)
391 Type *type = ZONE()->types()->getPrimitiveForTag(node->tag());
395 if (node->postDimensions()) {
397 if (node->initialization()) {
398 if ((init = visitAndApplyType(node->initialization())) == NULL)
402 if (node->postDimensions()->size() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
403 cc_.reportError(node->pos(), Message_MaximumArrayDepth);
407 // If we have an initializer, make sure it's the same type.
408 if (init && node->postDimensions()->size() != init->levels()) {
409 cc_.reportError(node->pos(), Message_ArrayInitializerDepth);
414 for (size_t i = node->postDimensions()->size() - 1; i < node->postDimensions()->size(); i--) {
415 Expression *expr = node->postDimensions()->at(i);
419 Type *exprType = visitForLoad(expr);
423 if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
424 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
429 if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
432 cc_.reportError(expr->pos(), Message_BadArraySize);
435 if (size >= INT_MAX / sizeof(int)) {
436 cc_.reportError(expr->pos(), Message_ArraySizeTooBig);
441 if (check->elements() == -1) {
442 cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
446 if (check->isCharArray()) {
447 if (check->elements() > size) {
448 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
451 } else if (check->elements() != size) {
452 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
458 cc_.reportError(node->pos(), Message_DynamicArrayHasInitializer);
462 // here until we get dynamic array support.
463 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
467 // Infer the size from the initializer.
469 cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
472 if (init->elements() == -1) {
473 cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
476 size = init->elements();
479 type = ZONE()->types()->unsafeArray(type, size);
484 check = check->contained();
487 // Right now, any array is allowed on the LIFO heap. In case the
488 // runtime actually decides to use the LIFO heap, we must reserve
489 // a slot so we can unwind the heap when the current scope leaves.
490 scope_->setUsesLifoHeap();
492 if (node->initialization()) {
493 Type *right = visitForLoad(node->initialization());
496 if (!typeCheckAssignment(node, type, right, true))
499 if (type->primitive() == PrimitiveType_Char) {
500 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
505 node->variable()->setType(type);
509 SemanticAnalysis::visit(IntegerLiteral *node)
511 node->setType(ZONE()->types()->getPrimitive(PrimitiveType_Int32));
515 SemanticAnalysis::visit(ExpressionStatement *node)
517 node->expression()->accept(this);
521 SemanticAnalysis::preanalyze(FunctionStatement *node)
525 FixedArray *args = FixedArray::New(ZONE(), node->parameters()->size(), Heap::Tenure_Old);
529 // Apply types to arguments.
530 for (size_t i = 0; i < node->parameters()->size(); i++) {
531 Parameter *parameter = node->parameters()->at(i);
533 Type *type = ZONE()->types()->getPrimitiveForTag(parameter->tag());
537 if (type->primitive() == PrimitiveType_Char) {
538 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
542 if (parameter->reference()) {
543 type = ZONE()->types()->getReference(type);
548 args->set(ZONE(), i, type);
549 parameter->variable()->setType(type);
552 Type *returnType = ZONE()->types()->getPrimitive(PrimitiveType_Int32);
556 Type *funtype = ZONE()->types()->newFunction(returnType, args);
560 node->fun()->setType(funtype);
565 SemanticAnalysis::visit(FunctionStatement *node)
567 function_ = node->fun()->type();
568 scope_ = node->scope();
569 node->body()->accept(this);
575 SemanticAnalysis::typeCheckArrayAssignment(AstNode *node, Type *given, Type *actual, bool forAssign)
577 if (!given->isArray()) {
578 cc_.reportError(node->pos(), Message_ExpectedArray);
581 if (given->levels() != actual->levels()) {
582 cc_.reportError(node->pos(), Message_ArrayDimensionsMismatch);
587 while (given->isArray()) {
588 if (actual->elements() != -1) {
590 if (given->elements() == -1 || actual->elements() == -1) {
591 cc_.reportError(node->pos(), Message_ArraySizeNotKnown);
595 if (actual->isCharArray()) {
596 // String assignment can have a truncated |given|.
597 if (given->elements() > actual->elements()) {
598 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
602 if (given->elements() != actual->elements()) {
603 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
608 if (actual->elements() != -1 && given->elements() != actual->elements()) {
609 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
614 given = given->contained();
615 actual = actual->contained();
618 if (given->primitive() != actual->primitive()) {
619 const char *givenTag = given->tag() ? given->tag() : "_";
620 const char *actualTag = given->tag() ? given->tag() : "_";
621 cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
629 SemanticAnalysis::typeCheckAssignment(AstNode *node, Type *given, Type *actual, bool forAssign)
631 if (actual->isArray())
632 return typeCheckArrayAssignment(node, given, actual, forAssign);
634 if (given->isArray()) {
635 cc_.reportError(node->pos(), Message_CannotAssignArrayToScalar);
639 if (!given->isPrimitive() || !actual->primitive()) {
640 cc_.reportError(node->pos(), Message_UnsupportedType);
644 // The given type may not have been dereferenced.
645 if (given->isReference())
646 given = given->contained();
647 if (actual->isReference())
648 actual = given->contained();
650 if (given->primitive() != actual->primitive()) {
651 const char *givenTag = given->tag() ? given->tag() : "_";
652 const char *actualTag = given->tag() ? given->tag() : "_";
653 cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
661 SemanticAnalysis::typeCheckParameter(AstNode *node, Type *given, Type *actual)
663 return typeCheckAssignment(node, given, actual, false);
667 SemanticAnalysis::visit(CallExpression *node)
669 Type *type = visitForLoad(node->callee());
673 if (!type->isFunction()) {
674 cc_.reportError(node->pos(), Message_CalleeNotFunction);
677 if (node->arguments()->size() != type->parameters()->length()) {
678 cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
682 for (unsigned i = 0; i < node->arguments()->size(); i++) {
683 // Note: we don't compute references unless the callee needs a
685 Expression *expression = node->arguments()->at(i);
686 Type *given = visitAndApplyType(expression);
690 // If it's an IndexExpression, we special case the ability to compute
692 if (expression->isIndexExpression())
693 given = given->contained();
695 Type *actual = type->parameterAt(i);
696 if (!typeCheckParameter(expression, given, actual))
699 // If the actual is a reference, and the given is not, we'll need to
700 // compute a reference, which may be allocated on the stack.
701 if (actual->isReference() && !given->isReference())
702 scope_->setUsesLifoHeap();
707 SemanticAnalysis::visit(IfStatement *node)
709 Type *type = visitForLoad(node->condition());
713 if (!canTest(node, type))
716 node->ifTrue()->accept(this);
718 node->ifFalse()->accept(this);
722 SemanticAnalysis::visit(IndexExpression *node)
725 Type *left = visitForRef(node->left());
726 Type *right = visitForLoad(node->right());
731 if (!right->isInt32()) {
732 cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
735 if (!left->isArray()) {
736 cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
743 SemanticAnalysis::visit(EnumStatement *node)
745 // Forbid the blessed types.
746 Name *tag = node->name();
747 if (!strcmp(tag, "Float") ||
748 !strcmp(tag, "String") ||
749 !strcmp(tag, "any") ||
750 !strcmp(tag, "bool"))
752 cc_.reportError(node->pos(), Message_InvalidEnumName);
756 Type *type = ZONE()->types()->getPrimitiveForTag(tag);
761 for (size_t i = 0; i < node->entries()->size(); i++) {
762 EnumStatement::Entry &entry = node->entries()->at(i);
764 BoxedPrimitive box = BoxedPrimitive::Int(value);
766 entry.expr->accept(this);
767 if (!EvaluateForConstant(entry.expr, &box)) {
768 cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
772 assert(box.type() == PrimitiveType_Int32);
776 entry.name->set(type, box);
782 SemanticAnalysis::visit(StringLiteral *node)
784 Type *type = ZONE()->types()->getPrimitive(PrimitiveType_Char);
788 type = Type::NewArray(ZONE(), type, node->string()->length() + 1, true);
796 SemanticAnalysis::visit(FloatLiteral *node)
798 Type *type = ZONE()->types()->getPrimitive(PrimitiveType_Float);
806 SemanticAnalysis::visit(BreakStatement *node)
809 cc_.reportError(node->pos(), Message_BreakOutsideLoop);
813 SemanticAnalysis::visit(ContinueStatement *node)
816 cc_.reportError(node->pos(), Message_ContinueOutsideLoop);