jitcraft/SemanticAnalysis.cpp
changeset 22 765ab1b672a3
parent 21 af5d8e985502
child 23 8a31742781c1
     1.1 --- a/jitcraft/SemanticAnalysis.cpp	Sun Jul 01 14:52:57 2012 -0700
     1.2 +++ b/jitcraft/SemanticAnalysis.cpp	Sun Jul 01 16:36:39 2012 -0700
     1.3 @@ -189,6 +189,28 @@
     1.4      return false;
     1.5  }
     1.6  
     1.7 +static inline Type *
     1.8 +TypeCheckBinary(TokenKind token, Type *left, Type *right)
     1.9 +{
    1.10 +    if (!left || !right)
    1.11 +        return NULL;
    1.12 +
    1.13 +    if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
    1.14 +        (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
    1.15 +    {
    1.16 +        // If either side is a float, the other side must be a float or int.
    1.17 +        if (left->isFloat() || right->isFloat()) {
    1.18 +            assert(left->isFloat() || left->isInt32());
    1.19 +            assert(right->isFloat() || right->isInt32());
    1.20 +            return left->isFloat() ? left : right;
    1.21 +        }
    1.22 +    }
    1.23 +
    1.24 +    assert(left->isInt32() && right->isInt32());
    1.25 +    assert(!left->tag() && !right->tag());
    1.26 +    return left;
    1.27 +}
    1.28 +
    1.29  void
    1.30  SemanticAnalysis::visit(Assignment *node)
    1.31  {
    1.32 @@ -214,34 +236,21 @@
    1.33              node->setType(var->type());
    1.34      }
    1.35  
    1.36 +    if (node->token() != TOK_ASSIGN)
    1.37 +        assert(TypeCheckBinary(node->token(), node->type(), node->expression()->type()));
    1.38 +
    1.39      assert(TypeCheckAssignment(node->type(), node->expression()->type()));
    1.40  }
    1.41  
    1.42 -
    1.43  void
    1.44  SemanticAnalysis::visit(BinaryExpression *node)
    1.45  {
    1.46 +    // :TODO: use Local
    1.47      Type *left = visitForLoad(node->left());
    1.48      Type *right = visitForLoad(node->right());
    1.49  
    1.50 -    if (node->token() >= TOK_PLUS && node->token() <= TOK_SLASH) {
    1.51 -        // Both sides must be primitive.
    1.52 -        if (!left || !right)
    1.53 -            return;
    1.54 -
    1.55 -        // If either side is a float, the other side must be a float or int.
    1.56 -        if (left->isFloat() || right->isFloat()) {
    1.57 -            assert(left->isFloat() || left->isInt32());
    1.58 -            assert(right->isFloat() || right->isInt32());
    1.59 -            node->setType(left->isFloat() ? left : right);
    1.60 -            return;
    1.61 -        }
    1.62 -    }
    1.63 -
    1.64 -    // For now, assert everything else is integer and untagged.
    1.65 -    assert(left->isInt32() && right->isInt32());
    1.66 -    assert(!left->tag() && !right->tag());
    1.67 -    node->setType(left);
    1.68 +    Type *result = TypeCheckBinary(node->token(), left, right);
    1.69 +    node->setType(result);
    1.70  }
    1.71  
    1.72  void
    1.73 @@ -258,8 +267,8 @@
    1.74      loopDepth_++;
    1.75      if (node->scope())
    1.76          scope_ = node->scope();
    1.77 -    if (node->declaration())
    1.78 -        node->declaration()->accept(this);
    1.79 +    if (node->initialization())
    1.80 +        node->initialization()->accept(this);
    1.81      if (node->condition())
    1.82          visitForLoad(node->condition());
    1.83      if (node->update())