diff -r af5d8e985502 -r 765ab1b672a3 jitcraft/SemanticAnalysis.cpp --- a/jitcraft/SemanticAnalysis.cpp Sun Jul 01 14:52:57 2012 -0700 +++ b/jitcraft/SemanticAnalysis.cpp Sun Jul 01 16:36:39 2012 -0700 @@ -189,6 +189,28 @@ return false; } +static inline Type * +TypeCheckBinary(TokenKind token, Type *left, Type *right) +{ + if (!left || !right) + return NULL; + + if ((token >= TOK_PLUS && token <= TOK_SLASH) || + (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV)) + { + // If either side is a float, the other side must be a float or int. + if (left->isFloat() || right->isFloat()) { + assert(left->isFloat() || left->isInt32()); + assert(right->isFloat() || right->isInt32()); + return left->isFloat() ? left : right; + } + } + + assert(left->isInt32() && right->isInt32()); + assert(!left->tag() && !right->tag()); + return left; +} + void SemanticAnalysis::visit(Assignment *node) { @@ -214,34 +236,21 @@ node->setType(var->type()); } + if (node->token() != TOK_ASSIGN) + assert(TypeCheckBinary(node->token(), node->type(), node->expression()->type())); + assert(TypeCheckAssignment(node->type(), node->expression()->type())); } - void SemanticAnalysis::visit(BinaryExpression *node) { + // :TODO: use Local Type *left = visitForLoad(node->left()); Type *right = visitForLoad(node->right()); - if (node->token() >= TOK_PLUS && node->token() <= TOK_SLASH) { - // Both sides must be primitive. - if (!left || !right) - return; - - // If either side is a float, the other side must be a float or int. - if (left->isFloat() || right->isFloat()) { - assert(left->isFloat() || left->isInt32()); - assert(right->isFloat() || right->isInt32()); - node->setType(left->isFloat() ? left : right); - return; - } - } - - // For now, assert everything else is integer and untagged. - assert(left->isInt32() && right->isInt32()); - assert(!left->tag() && !right->tag()); - node->setType(left); + Type *result = TypeCheckBinary(node->token(), left, right); + node->setType(result); } void @@ -258,8 +267,8 @@ loopDepth_++; if (node->scope()) scope_ = node->scope(); - if (node->declaration()) - node->declaration()->accept(this); + if (node->initialization()) + node->initialization()->accept(this); if (node->condition()) visitForLoad(node->condition()); if (node->update())