1.1 --- a/jitcraft/SemanticAnalysis.cpp Tue Jun 26 00:58:55 2012 -0700
1.2 +++ b/jitcraft/SemanticAnalysis.cpp Wed Jun 27 02:21:56 2012 -0700
1.3 @@ -80,8 +80,8 @@
1.4 return true;
1.5 }
1.6
1.7 - case AstNode::kIntegerLiteralExpression:
1.8 - *out = BoxedPrimitive::Int(expression->toIntegerLiteralExpression()->value());
1.9 + case AstNode::kIntegerLiteral:
1.10 + *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
1.11 return true;
1.12
1.13 default:
1.14 @@ -111,15 +111,29 @@
1.15 name->setType(name->binding()->type());
1.16 }
1.17
1.18 +static inline bool
1.19 +TypeCheck(Type *left, Type *right)
1.20 +{
1.21 + if (!left || !right)
1.22 + return false;
1.23 +
1.24 + if (left->isPrimitive()) {
1.25 + if (!right->isPrimitive())
1.26 + return false;
1.27 + return left->primitive() == right->primitive();
1.28 + }
1.29 +
1.30 + return false;
1.31 +}
1.32 +
1.33 void
1.34 SemanticAnalysis::visit(Assignment *node)
1.35 {
1.36 node->expression()->accept(this);
1.37
1.38 if (node->lvalue()->isIndexExpression()) {
1.39 - node->lvalue()->accept(this);
1.40 -
1.41 - node->setType(node->lvalue()->type());
1.42 + node->lvalue()->accept(this);
1.43 + node->setType(node->lvalue()->type()->contained());
1.44 } else {
1.45 NameProxy *proxy = node->lvalue()->toNameProxy();
1.46 if (!proxy->binding()->kind() == BoundName::VARIABLE) {
1.47 @@ -130,11 +144,37 @@
1.48 Variable *var = proxy->binding()->toVariable();
1.49 node->setType(var->type());
1.50 }
1.51 +
1.52 + assert(TypeCheck(node->type(), node->expression()->type()));
1.53 }
1.54
1.55 +
1.56 void
1.57 SemanticAnalysis::visit(BinaryExpression *node)
1.58 {
1.59 + node->left()->accept(this);
1.60 + node->right()->accept(this);
1.61 +
1.62 + if (node->token() >= TOK_PLUS && node->token() <= TOK_SLASH) {
1.63 + // Both sides must be primitive.
1.64 + Type *left = node->left()->type();
1.65 + Type *right = node->right()->type();
1.66 + if (!left || !right)
1.67 + return;
1.68 +
1.69 + // If either side is a float, the other side must be a float or int.
1.70 + if (left->isFloat() || right->isFloat()) {
1.71 + assert(left->isFloat() || left->isInt());
1.72 + assert(right->isFloat() || right->isInt());
1.73 + node->setType(left->isFloat() ? left : right);
1.74 + return;
1.75 + }
1.76 +
1.77 + // Otherwise, both sides must be integer.
1.78 + assert(left->isInt() && right->isInt());
1.79 + node->setType(left);
1.80 + return;
1.81 + }
1.82 }
1.83
1.84 void
1.85 @@ -169,9 +209,7 @@
1.86 void
1.87 SemanticAnalysis::visit(VariableDeclaration *node)
1.88 {
1.89 - Tag *tag = NULL;
1.90 -
1.91 - Type *type = Type::NewPrimitive(tag);
1.92 + Type *type = Type::NewPrimitive(node->tag());
1.93 if (!type)
1.94 return;
1.95
1.96 @@ -191,8 +229,8 @@
1.97 }
1.98
1.99 int size = -1;
1.100 - if (expr->isIntegerLiteralExpression()) {
1.101 - size = expr->toIntegerLiteralExpression()->value();
1.102 + if (expr->isIntegerLiteral()) {
1.103 + size = expr->toIntegerLiteral()->value();
1.104 if (size <= 0) {
1.105 error();
1.106 return;
1.107 @@ -211,7 +249,7 @@
1.108 }
1.109
1.110 void
1.111 -SemanticAnalysis::visit(IntegerLiteralExpression *node)
1.112 +SemanticAnalysis::visit(IntegerLiteral *node)
1.113 {
1.114 Type *type = Type::NewPrimitive(NULL);
1.115 node->setType(type);
1.116 @@ -259,12 +297,8 @@
1.117 void
1.118 SemanticAnalysis::visit(EnumStatement *node)
1.119 {
1.120 - Tag *tag = NULL;
1.121 - if (node->name()) {
1.122 - tag = new Tag(node->name());
1.123 - if (!tag)
1.124 - return;
1.125 - }
1.126 + // :TODO: test "enum Float { ..."
1.127 + Name *tag = node->name();
1.128
1.129 Type *type = Type::NewPrimitive(tag);
1.130 if (!type)
1.131 @@ -288,3 +322,13 @@
1.132 value++;
1.133 }
1.134 }
1.135 +
1.136 +void
1.137 +SemanticAnalysis::visit(FloatLiteral *node)
1.138 +{
1.139 + Type *type = Type::NewPrimitive(PrimitiveType_Float);
1.140 + if (!type)
1.141 + return;
1.142 +
1.143 + node->setType(type);
1.144 +}