Added MacOS, gcc, and clang support. Preliminary crappy autoconf scripts of course.
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"
28 IsPrimitiveType(Type *type, PrimitiveType primitive)
33 if (!type->isPrimitive())
36 return primitive == type->primitive();
40 EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
45 *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
49 *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
58 EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
60 switch (expression->kind()) {
61 case AstNode::kBinaryExpression:
65 BinaryExpression *b = expression->toBinaryExpression();
66 if (!EvaluateForConstant(b->left(), &left) ||
67 !EvaluateForConstant(b->right(), &right))
71 return EvaluateBinaryOperation(b->token(), left, right, out);
74 case AstNode::kNameProxy:
76 NameProxy *proxy = expression->toNameProxy();
77 if (proxy->binding()->kind() != BoundName::CONSTANT)
80 NamedConstant *c = proxy->binding()->toNamedConstant();
81 if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
88 case AstNode::kIntegerLiteral:
89 *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
97 SemanticAnalysis::SemanticAnalysis(CompileContext &cc, ParseTree *tree)
106 SemanticAnalysis::analyze()
111 for (size_t i = 0; i < tree_->statements()->length(); i++) {
112 Statement *statement = tree_->statements()->at(i);
113 if (statement->isFunctionStatement()) {
114 FunctionStatement *funstmt = statement->toFunctionStatement();
115 if (!preanalyze(funstmt))
120 for (size_t i = 0; i < tree_->statements()->length(); i++) {
121 Statement *statement = tree_->statements()->at(i);
122 statement->accept(this);
125 return !cc_.failures();
129 SemanticAnalysis::visitAndApplyType(Expression *expression)
131 expression->accept(this);
132 return expression->type();
136 SemanticAnalysis::visitForLoad(Expression *expression)
139 Type *type = visitAndApplyType(expression);
143 if (type->isReference()) {
144 expression->setType(type->contained());
145 } else if (expression->isIndexExpression()) {
147 expression->setType(type->contained());
150 return expression->type();
154 SemanticAnalysis::visitForRef(Expression *expression)
156 expression->accept(this);
157 return expression->type();
160 static inline const char *
161 GetTypeName(Type *type)
165 if (type->isFunction())
167 if (type->isReference())
168 type = type->contained();
175 SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Type *type)
177 const char *op = TokenNames[token];
178 const char *name = GetTypeName(type);
180 cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
184 SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Type *left, Type *right)
186 const char *op = TokenNames[token];
187 const char *leftName = GetTypeName(left);
188 const char *rightName = GetTypeName(right);
190 cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
194 SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Type *left, Type *right)
196 if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
197 (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
199 // If either side is a float, the other side must be a float or int.
200 if (left->isFloat() || right->isFloat()) {
201 Type *floatType = left->isFloat() ? left : right;
202 Type *other = left->isFloat() ? right : left;
203 if (other->isFloat() || (other->isInt32() && !other->tag()))
208 if ((!left->isInt32() || left->tag()) ||
209 (!right->isInt32() || right->tag()))
211 binaryTypeError(node, token, left, right);
219 SemanticAnalysis::canTest(AstNode *node, Type *type)
221 if (type->isArray()) {
222 cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
229 SemanticAnalysis::visitForLValue(Expression *expression)
231 if (expression->isIndexExpression()) {
232 Type *type = visitAndApplyType(expression);
236 return type->contained();
239 if (!expression->isNameProxy()) {
240 cc_.reportError(expression->pos(), Message_ExpectedLValue);
244 NameProxy *proxy = expression->toNameProxy();
245 if (!proxy->binding()->kind() == BoundName::VARIABLE) {
246 cc_.reportError(expression->pos(), Message_ExpectedLValue);
250 Variable *var = proxy->binding()->toVariable();
254 if (var->type()->isReference())
255 return var->type()->contained();
260 SemanticAnalysis::visit(NameProxy *name)
262 name->setType(name->binding()->type());
266 SemanticAnalysis::visit(Assignment *node)
268 Type *exprType = visitForLoad(node->expression());
273 Type *type = visitForLValue(node->lvalue());
277 if (node->token() != TOK_ASSIGN) {
278 if (!typeCheckBinary(node, node->token(), type, exprType))
282 if (!typeCheckAssignment(node, exprType, type, true))
289 SemanticAnalysis::visit(IncDecExpression *node)
292 Type *type = visitForLValue(node->expression());
296 assert(!type->isReference());
298 if ((!type->isInt32() || (type->isInt32() && type->tag())) && !type->isFloat()) {
299 unaryTypeError(node, node->token(), type);
307 SemanticAnalysis::visit(BinaryExpression *node)
310 Type *left = visitForLoad(node->left());
311 Type *right = visitForLoad(node->right());
315 Type *result = typeCheckBinary(node, node->token(), left, right);
319 node->setType(result);
323 SemanticAnalysis::visit(ReturnStatement *node)
325 Type *type = visitForLoad(node->expression());
329 if (!typeCheckAssignment(node, type, function_->returnType(), true))
334 SemanticAnalysis::visit(ForStatement *node)
338 scope_ = node->scope();
340 if (node->initialization())
341 node->initialization()->accept(this);
343 if (node->condition()) {
344 Type *type = visitForLoad(node->condition());
345 if (!type || !canTest(node->condition(), type)) {
352 node->update()->accept(this);
354 node->body()->accept(this);
357 scope_ = scope_->enclosing();
362 SemanticAnalysis::visit(WhileStatement *node)
366 Type *type = visitForLoad(node->condition());
367 if (!type || !canTest(node->condition(), type)) {
372 node->body()->accept(this);
377 SemanticAnalysis::visit(BlockStatement *node)
380 scope_ = node->scope();
381 for (size_t i = 0; i < node->statements()->length(); i++) {
382 Statement *statement = node->statements()->at(i);
383 statement->accept(this);
386 scope_ = scope_->enclosing();
390 SemanticAnalysis::visit(VariableDeclaration *node)
393 Type *type = ZONE()->types()->getPrimitiveForTag(node->tag());
397 if (node->postDimensions()) {
399 if (node->initialization()) {
400 if ((init = visitAndApplyType(node->initialization())) == NULL)
404 if (node->postDimensions()->size() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
405 cc_.reportError(node->pos(), Message_MaximumArrayDepth);
409 // If we have an initializer, make sure it's the same type.
410 if (init && node->postDimensions()->size() != init->levels()) {
411 cc_.reportError(node->pos(), Message_ArrayInitializerDepth);
416 for (size_t i = node->postDimensions()->size() - 1; i < node->postDimensions()->size(); i--) {
417 Expression *expr = node->postDimensions()->at(i);
421 Type *exprType = visitForLoad(expr);
425 if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
426 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
431 if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
434 cc_.reportError(expr->pos(), Message_BadArraySize);
437 if (size >= INT_MAX / sizeof(int)) {
438 cc_.reportError(expr->pos(), Message_ArraySizeTooBig);
443 if (check->elements() == -1) {
444 cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
448 if (check->isCharArray()) {
449 if (check->elements() > size) {
450 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
453 } else if (check->elements() != size) {
454 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
460 cc_.reportError(node->pos(), Message_DynamicArrayHasInitializer);
464 // here until we get dynamic array support.
465 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
469 // Infer the size from the initializer.
471 cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
474 if (init->elements() == -1) {
475 cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
478 size = init->elements();
481 type = ZONE()->types()->unsafeArray(type, size);
486 check = check->contained();
489 // Right now, any array is allowed on the LIFO heap. In case the
490 // runtime actually decides to use the LIFO heap, we must reserve
491 // a slot so we can unwind the heap when the current scope leaves.
492 scope_->setUsesLifoHeap();
494 if (node->initialization()) {
495 Type *right = visitForLoad(node->initialization());
498 if (!typeCheckAssignment(node, type, right, true))
501 if (type->primitive() == PrimitiveType_Char) {
502 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
507 node->variable()->setType(type);
511 SemanticAnalysis::visit(IntegerLiteral *node)
513 node->setType(ZONE()->types()->getPrimitive(PrimitiveType_Int32));
517 SemanticAnalysis::visit(ExpressionStatement *node)
519 node->expression()->accept(this);
523 SemanticAnalysis::preanalyze(FunctionStatement *node)
527 FixedArray *args = FixedArray::New(ZONE(), node->parameters()->size(), Heap::Tenure_Old);
531 // Apply types to arguments.
532 for (size_t i = 0; i < node->parameters()->size(); i++) {
533 Parameter *parameter = node->parameters()->at(i);
535 Type *type = ZONE()->types()->getPrimitiveForTag(parameter->tag());
539 if (type->primitive() == PrimitiveType_Char) {
540 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
544 if (parameter->reference()) {
545 type = ZONE()->types()->getReference(type);
550 args->set(ZONE(), i, type);
551 parameter->variable()->setType(type);
554 Type *returnType = ZONE()->types()->getPrimitive(PrimitiveType_Int32);
558 Type *funtype = ZONE()->types()->newFunction(returnType, args);
562 node->fun()->setType(funtype);
567 SemanticAnalysis::visit(FunctionStatement *node)
569 function_ = node->fun()->type();
570 scope_ = node->scope();
571 node->body()->accept(this);
577 SemanticAnalysis::typeCheckArrayAssignment(AstNode *node, Type *given, Type *actual, bool forAssign)
579 if (!given->isArray()) {
580 cc_.reportError(node->pos(), Message_ExpectedArray);
583 if (given->levels() != actual->levels()) {
584 cc_.reportError(node->pos(), Message_ArrayDimensionsMismatch);
589 while (given->isArray()) {
590 if (actual->elements() != -1) {
592 if (given->elements() == -1 || actual->elements() == -1) {
593 cc_.reportError(node->pos(), Message_ArraySizeNotKnown);
597 if (actual->isCharArray()) {
598 // String assignment can have a truncated |given|.
599 if (given->elements() > actual->elements()) {
600 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
604 if (given->elements() != actual->elements()) {
605 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
610 if (actual->elements() != -1 && given->elements() != actual->elements()) {
611 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
616 given = given->contained();
617 actual = actual->contained();
620 if (given->primitive() != actual->primitive()) {
621 const char *givenTag = given->tag() ? given->tag() : "_";
622 const char *actualTag = given->tag() ? given->tag() : "_";
623 cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
631 SemanticAnalysis::typeCheckAssignment(AstNode *node, Type *given, Type *actual, bool forAssign)
633 if (actual->isArray())
634 return typeCheckArrayAssignment(node, given, actual, forAssign);
636 if (given->isArray()) {
637 cc_.reportError(node->pos(), Message_CannotAssignArrayToScalar);
641 if (!given->isPrimitive() || !actual->primitive()) {
642 cc_.reportError(node->pos(), Message_UnsupportedType);
646 // The given type may not have been dereferenced.
647 if (given->isReference())
648 given = given->contained();
649 if (actual->isReference())
650 actual = given->contained();
652 if (given->primitive() != actual->primitive()) {
653 const char *givenTag = given->tag() ? given->tag() : "_";
654 const char *actualTag = given->tag() ? given->tag() : "_";
655 cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
663 SemanticAnalysis::typeCheckParameter(AstNode *node, Type *given, Type *actual)
665 return typeCheckAssignment(node, given, actual, false);
669 SemanticAnalysis::visit(CallExpression *node)
671 Type *type = visitForLoad(node->callee());
675 if (!type->isFunction()) {
676 cc_.reportError(node->pos(), Message_CalleeNotFunction);
679 if (node->arguments()->size() != type->parameters()->length()) {
680 cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
684 for (unsigned i = 0; i < node->arguments()->size(); i++) {
685 // Note: we don't compute references unless the callee needs a
687 Expression *expression = node->arguments()->at(i);
688 Type *given = visitAndApplyType(expression);
692 // If it's an IndexExpression, we special case the ability to compute
694 if (expression->isIndexExpression())
695 given = given->contained();
697 Type *actual = type->parameterAt(i);
698 if (!typeCheckParameter(expression, given, actual))
701 // If the actual is a reference, and the given is not, we'll need to
702 // compute a reference, which may be allocated on the stack.
703 if (actual->isReference() && !given->isReference())
704 scope_->setUsesLifoHeap();
709 SemanticAnalysis::visit(IfStatement *node)
711 Type *type = visitForLoad(node->condition());
715 if (!canTest(node, type))
718 node->ifTrue()->accept(this);
720 node->ifFalse()->accept(this);
724 SemanticAnalysis::visit(IndexExpression *node)
727 Type *left = visitForRef(node->left());
728 Type *right = visitForLoad(node->right());
733 if (!right->isInt32()) {
734 cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
737 if (!left->isArray()) {
738 cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
745 SemanticAnalysis::visit(EnumStatement *node)
747 // Forbid the blessed types.
748 Name *tag = node->name();
749 if (!strcmp(tag, "Float") ||
750 !strcmp(tag, "String") ||
751 !strcmp(tag, "any") ||
752 !strcmp(tag, "bool"))
754 cc_.reportError(node->pos(), Message_InvalidEnumName);
758 Type *type = ZONE()->types()->getPrimitiveForTag(tag);
763 for (size_t i = 0; i < node->entries()->size(); i++) {
764 EnumStatement::Entry &entry = node->entries()->at(i);
766 BoxedPrimitive box = BoxedPrimitive::Int(value);
768 entry.expr->accept(this);
769 if (!EvaluateForConstant(entry.expr, &box)) {
770 cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
774 assert(box.type() == PrimitiveType_Int32);
778 entry.name->set(type, box);
784 SemanticAnalysis::visit(StringLiteral *node)
786 Type *type = ZONE()->types()->getPrimitive(PrimitiveType_Char);
790 type = Type::NewArray(ZONE(), type, node->string()->length() + 1, true);
798 SemanticAnalysis::visit(FloatLiteral *node)
800 Type *type = ZONE()->types()->getPrimitive(PrimitiveType_Float);
808 SemanticAnalysis::visit(BreakStatement *node)
811 cc_.reportError(node->pos(), Message_BreakOutsideLoop);
815 SemanticAnalysis::visit(ContinueStatement *node)
818 cc_.reportError(node->pos(), Message_ContinueOutsideLoop);