1.1 --- a/jitcraft/SemanticAnalysis.cpp Sun Jul 01 11:25:36 2012 -0700
1.2 +++ b/jitcraft/SemanticAnalysis.cpp Sun Jul 01 14:52:57 2012 -0700
1.3 @@ -120,10 +120,15 @@
1.4 SemanticAnalysis::visitForLoad(Expression *expression)
1.5 {
1.6 expression->accept(this);
1.7 - if (expression->type()) {
1.8 - // :TODO: use Local
1.9 - Type *type = expression->type();
1.10 - if (type->isArray() || type->isReference())
1.11 + if (!expression->type())
1.12 + return NULL;
1.13 +
1.14 + // :TODO: use Local
1.15 + Type *type = expression->type();
1.16 + if (type->isReference()) {
1.17 + expression->setType(type->contained());
1.18 + } else if (expression->isIndexExpression()) {
1.19 + if (type->isArray())
1.20 expression->setType(type->contained());
1.21 }
1.22 return expression->type();
1.23 @@ -151,6 +156,39 @@
1.24 return false;
1.25 }
1.26
1.27 +static inline bool
1.28 +TypeCheckAssignment(Type *left, Type *right)
1.29 +{
1.30 + if (!left || !right)
1.31 + return false;
1.32 +
1.33 + if (left->isPrimitive()) {
1.34 + if (!right->isPrimitive())
1.35 + return false;
1.36 + return left->primitive() == right->primitive();
1.37 + }
1.38 +
1.39 + if (left->isArray() != right->isArray())
1.40 + return false;
1.41 +
1.42 + if (left->levels() != 1 || right->levels() != 1)
1.43 + return false;
1.44 +
1.45 + if (left->elements() == -1 || right->elements() == -1)
1.46 + return false;
1.47 +
1.48 + if (!TypeCheckAssignment(left->contained(), right->contained()))
1.49 + return false;
1.50 +
1.51 + if (left->elements() != right->elements()) {
1.52 + if (left->isCharArray() && (left->elements() >= right->elements()))
1.53 + return true;
1.54 + return false;
1.55 + }
1.56 +
1.57 + return false;
1.58 +}
1.59 +
1.60 void
1.61 SemanticAnalysis::visit(Assignment *node)
1.62 {
1.63 @@ -167,13 +205,16 @@
1.64 }
1.65
1.66 Variable *var = proxy->binding()->toVariable();
1.67 + if (!var->type())
1.68 + return;
1.69 +
1.70 if (var->type()->isReference())
1.71 node->setType(var->type()->contained());
1.72 else
1.73 node->setType(var->type());
1.74 }
1.75
1.76 - assert(TypeCheck(node->type(), node->expression()->type()));
1.77 + assert(TypeCheckAssignment(node->type(), node->expression()->type()));
1.78 }
1.79
1.80
1.81 @@ -260,11 +301,24 @@
1.82 return;
1.83
1.84 if (node->postDimensions()) {
1.85 + Type *init = NULL;
1.86 + if (node->initialization()) {
1.87 + node->initialization()->accept(this);
1.88 + if ((init = node->initialization()->type()) == NULL)
1.89 + return;
1.90 + }
1.91 +
1.92 if (node->postDimensions()->size() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
1.93 error();
1.94 return;
1.95 }
1.96
1.97 + // If we have an initializer, make sure it's the same type.
1.98 + if (init) {
1.99 + assert(init->levels() == node->postDimensions()->size());
1.100 + }
1.101 +
1.102 + Type *check = init;
1.103 for (size_t i = node->postDimensions()->size() - 1; i < node->postDimensions()->size(); i--) {
1.104 Expression *expr = node->postDimensions()->at(i);
1.105 visitForLoad(expr);
1.106 @@ -285,9 +339,28 @@
1.107 error();
1.108 return;
1.109 }
1.110 + } else {
1.111 + assert(false);
1.112 }
1.113
1.114 type = ZONE()->types()->unsafeArray(type, size);
1.115 +
1.116 + if (check) {
1.117 + assert(check->elements() != -1);
1.118 + assert(size != -1);
1.119 +
1.120 + // If we're assigning a string, we're allowed to pad with
1.121 + // zeroes.
1.122 + if (check->isCharArray()) {
1.123 + assert(type->isCharArray());
1.124 + assert(type->elements() >= check->elements());
1.125 + } else {
1.126 + assert(false);
1.127 + }
1.128 + }
1.129 +
1.130 + if (check)
1.131 + check = check->contained();
1.132 }
1.133
1.134 // Right now, any array is allowed on the LIFO heap. In case the
1.135 @@ -299,6 +372,10 @@
1.136 Type *right = visitForLoad(node->initialization());
1.137 assert(TypeCheck(type, right));
1.138 }
1.139 + if (type->primitive() == PrimitiveType_Char) {
1.140 + assert(false);
1.141 + return;
1.142 + }
1.143 }
1.144
1.145 node->variable()->setType(type);
1.146 @@ -477,6 +554,20 @@
1.147 }
1.148
1.149 void
1.150 +SemanticAnalysis::visit(StringLiteral *node)
1.151 +{
1.152 + Type *type = ZONE()->types()->getPrimitive(PrimitiveType_Char);
1.153 + if (!type)
1.154 + return;
1.155 +
1.156 + type = Type::NewArray(ZONE(), type, node->string()->length() + 1, true);
1.157 + if (!type)
1.158 + return;
1.159 +
1.160 + node->setType(type);
1.161 +}
1.162 +
1.163 +void
1.164 SemanticAnalysis::visit(FloatLiteral *node)
1.165 {
1.166 Type *type = ZONE()->types()->getPrimitive(PrimitiveType_Float);