diff -r e020a14e21be -r af5d8e985502 jitcraft/SemanticAnalysis.cpp --- a/jitcraft/SemanticAnalysis.cpp Sun Jul 01 11:25:36 2012 -0700 +++ b/jitcraft/SemanticAnalysis.cpp Sun Jul 01 14:52:57 2012 -0700 @@ -120,10 +120,15 @@ SemanticAnalysis::visitForLoad(Expression *expression) { expression->accept(this); - if (expression->type()) { - // :TODO: use Local - Type *type = expression->type(); - if (type->isArray() || type->isReference()) + if (!expression->type()) + return NULL; + + // :TODO: use Local + Type *type = expression->type(); + if (type->isReference()) { + expression->setType(type->contained()); + } else if (expression->isIndexExpression()) { + if (type->isArray()) expression->setType(type->contained()); } return expression->type(); @@ -151,6 +156,39 @@ return false; } +static inline bool +TypeCheckAssignment(Type *left, Type *right) +{ + if (!left || !right) + return false; + + if (left->isPrimitive()) { + if (!right->isPrimitive()) + return false; + return left->primitive() == right->primitive(); + } + + if (left->isArray() != right->isArray()) + return false; + + if (left->levels() != 1 || right->levels() != 1) + return false; + + if (left->elements() == -1 || right->elements() == -1) + return false; + + if (!TypeCheckAssignment(left->contained(), right->contained())) + return false; + + if (left->elements() != right->elements()) { + if (left->isCharArray() && (left->elements() >= right->elements())) + return true; + return false; + } + + return false; +} + void SemanticAnalysis::visit(Assignment *node) { @@ -167,13 +205,16 @@ } Variable *var = proxy->binding()->toVariable(); + if (!var->type()) + return; + if (var->type()->isReference()) node->setType(var->type()->contained()); else node->setType(var->type()); } - assert(TypeCheck(node->type(), node->expression()->type())); + assert(TypeCheckAssignment(node->type(), node->expression()->type())); } @@ -260,11 +301,24 @@ return; if (node->postDimensions()) { + Type *init = NULL; + if (node->initialization()) { + node->initialization()->accept(this); + if ((init = node->initialization()->type()) == NULL) + return; + } + if (node->postDimensions()->size() > Type::MAX_UNSAFE_ARRAY_DEPTH) { error(); return; } + // If we have an initializer, make sure it's the same type. + if (init) { + assert(init->levels() == node->postDimensions()->size()); + } + + Type *check = init; for (size_t i = node->postDimensions()->size() - 1; i < node->postDimensions()->size(); i--) { Expression *expr = node->postDimensions()->at(i); visitForLoad(expr); @@ -285,9 +339,28 @@ error(); return; } + } else { + assert(false); } type = ZONE()->types()->unsafeArray(type, size); + + if (check) { + assert(check->elements() != -1); + assert(size != -1); + + // If we're assigning a string, we're allowed to pad with + // zeroes. + if (check->isCharArray()) { + assert(type->isCharArray()); + assert(type->elements() >= check->elements()); + } else { + assert(false); + } + } + + if (check) + check = check->contained(); } // Right now, any array is allowed on the LIFO heap. In case the @@ -299,6 +372,10 @@ Type *right = visitForLoad(node->initialization()); assert(TypeCheck(type, right)); } + if (type->primitive() == PrimitiveType_Char) { + assert(false); + return; + } } node->variable()->setType(type); @@ -477,6 +554,20 @@ } void +SemanticAnalysis::visit(StringLiteral *node) +{ + Type *type = ZONE()->types()->getPrimitive(PrimitiveType_Char); + if (!type) + return; + + type = Type::NewArray(ZONE(), type, node->string()->length() + 1, true); + if (!type) + return; + + node->setType(type); +} + +void SemanticAnalysis::visit(FloatLiteral *node) { Type *type = ZONE()->types()->getPrimitive(PrimitiveType_Float);