1.1 --- a/src/compiler/SemanticAnalysis.cpp Thu Dec 27 21:07:03 2012 -0800
1.2 +++ b/src/compiler/SemanticAnalysis.cpp Fri Dec 28 17:13:51 2012 -0800
1.3 @@ -694,13 +694,66 @@
1.4 } else {
1.5 Local<Type> actual(zone_, fun->parameterAt(i));
1.6
1.7 - if (expression->isIndexExpression()) {
1.8 - // Temporarily disabled.
1.9 - assert(!actual->isArray());
1.10 +
1.11 + if (expression->isIndexExpression() && arg->isIndex()) {
1.12 + // If the expression is the form x[y], and this produced a
1.13 + // normal array indexing operation, then we apply some
1.14 + // special rules.
1.15 +
1.16 if (actual->isReference()) {
1.17 + // Disabled, since this doesn't have easily definable or
1.18 + // sensible semantics with SP2 arrays, but we don't want
1.19 + // to silently break SP1 semantics.
1.20 cc_.reportError(expression->pos(), Message_CannotComputeIndexRef);
1.21 return;
1.22 }
1.23 +
1.24 + // As a special rule to account for SP1 semantics, we allow x[y]
1.25 + // to automatically compute a sliced, read-only array view if
1.26 + // the desired type is an array of one more dimension than x[y]
1.27 + // would return.
1.28 + //
1.29 + // As an additional restriction, this is only allowed for
1.30 + // one-level char arrays, to minimize potential issues until
1.31 + // we determine whether more compatibility is needed.
1.32 + //
1.33 + // Internally, for sanity, the dependent array operation does
1.34 + // not necessarily create a dependent array. For extensible
1.35 + // arrays, we instead create a duplicate arrary of just the
1.36 + // sliced portion, rather than deal with the complexity of the
1.37 + // source array being resized.
1.38 + //
1.39 + // Note that we don't really know whether a dependent array
1.40 + // will be dependent at compile-time, so the dependent type's
1.41 + // just inherits from the source.
1.42 + if (actual->isArray()) {
1.43 + HIndex *index = arg->toIndex();
1.44 + Local<ArrayType> basetype(zone_, ArrayType::cast(index->base()->type()));
1.45 + Local<ArrayType> atype(zone_, ArrayType::cast(actual));
1.46 +
1.47 + if (atype->isCharArray() && basetype->isCharArray()) {
1.48 + // There is no possible way this will type check, so
1.49 + // it's safe to just try something completely
1.50 + // different.
1.51 + Local<Type> slicetype(zone_);
1.52 + if (basetype->isFixedLength()) {
1.53 + // If the base type is fixed length, we need to
1.54 + // compute a new dynamic array type based on the
1.55 + // fixed array's contents and qualifiers.
1.56 + Local<Type> contained(zone_, basetype->contained());
1.57 + slicetype = zone_->types()->newArray(contained, ArrayType::DYNAMIC_ARRAY_SIZE);
1.58 + if (!slicetype)
1.59 + return;
1.60 + slicetype = zone_->types()->qualify(slicetype, basetype->quals());
1.61 + if (!slicetype)
1.62 + return;
1.63 + } else {
1.64 + slicetype = basetype;
1.65 + }
1.66 + arg = new (pool_) HNewDependentArray(expression, slicetype, index->base(), index->index());
1.67 + given = arg->type();
1.68 + }
1.69 + }
1.70 }
1.71
1.72 if (actual->isReference()) {
1.73 @@ -830,10 +883,17 @@
1.74 Type *
1.75 SemanticAnalysis::coercionType(TokenKind token, HIR *left, HIR *right)
1.76 {
1.77 - Handle<Type> l = left->type();
1.78 - Handle<Type> r = right->type();
1.79 + Local<Type> l(zone_, left->type());
1.80 + Local<Type> r(zone_, right->type());
1.81
1.82 - if (token >= TOK_PLUS && token <= TOK_SLASH) {
1.83 + if (l->isPod())
1.84 + l = l->unqualified();
1.85 + if (r->isPod())
1.86 + r = r->unqualified();
1.87 +
1.88 + if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
1.89 + (token >= TOK_EQUALS && token <= TOK_GE))
1.90 + {
1.91 // We allow: [float|int32] + [float|int32]
1.92 if (l->isFloat() && r->isInt32())
1.93 return l;
1.94 @@ -841,6 +901,11 @@
1.95 return r;
1.96 if (l->isInt32() && r->isInt32())
1.97 return l;
1.98 +
1.99 + if (l->isChar() && r->isInt32())
1.100 + return r;
1.101 + if (l->isInt32() && r->isChar())
1.102 + return l;
1.103 }
1.104
1.105 // :TODO: remove
1.106 @@ -1097,23 +1162,36 @@
1.107 return;
1.108
1.109 switch (node->token()) {
1.110 + case TOK_TILDE:
1.111 + {
1.112 + if (!hir->type()->isInt32() && !hir->type()->isEnum()) {
1.113 + char name[255];
1.114 + cc_.reportError(node->pos(), Message_InvalidUnaryType,
1.115 + "~",
1.116 + GetTypeName(hir->type(), name, sizeof(name)));
1.117 + }
1.118 + Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
1.119 + hir_ = new (pool_) HUnary(node, hir->type(), TOK_TILDE, hir);
1.120 + return;
1.121 + }
1.122 +
1.123 case TOK_MINUS:
1.124 {
1.125 - if (hir->type()->isInt32() || hir->type()->isEnum()) {
1.126 - Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
1.127 - hir_ = new (pool_) HUnary(node, type, TOK_MINUS, hir);
1.128 - return;
1.129 - }
1.130 - if (hir->type()->isFloat()) {
1.131 - hir_ = new (pool_) HUnary(node, hir->type(), TOK_MINUS, hir);
1.132 - return;
1.133 - }
1.134 + if (hir->type()->isInt32() || hir->type()->isEnum()) {
1.135 + Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
1.136 + hir_ = new (pool_) HUnary(node, type, TOK_MINUS, hir);
1.137 + return;
1.138 + }
1.139 + if (hir->type()->isFloat()) {
1.140 + hir_ = new (pool_) HUnary(node, hir->type(), TOK_MINUS, hir);
1.141 + return;
1.142 + }
1.143
1.144 - char name[255];
1.145 - cc_.reportError(node->pos(), Message_InvalidUnaryType,
1.146 - "-",
1.147 - GetTypeName(hir->type(), name, sizeof(name)));
1.148 - break;
1.149 + char name[255];
1.150 + cc_.reportError(node->pos(), Message_InvalidUnaryType,
1.151 + "-",
1.152 + GetTypeName(hir->type(), name, sizeof(name)));
1.153 + break;
1.154 }
1.155
1.156 default:
1.157 @@ -1195,8 +1273,13 @@
1.158
1.159 BinaryExpression *bin = expr->toBinaryExpression();
1.160 if (token == TOK_AND || token == TOK_OR) {
1.161 - assert(false);
1.162 - //visitForLogicTest(expr, trueBranch, falseBranch, fallthrough);
1.163 + Label next;
1.164 + if (token == TOK_AND)
1.165 + visitForTest(bin->left(), &next, falseBranch, &next);
1.166 + else
1.167 + visitForTest(bin->left(), trueBranch, &next, &next);
1.168 + __ bind(&next);
1.169 + visitForTest(bin->right(), trueBranch, falseBranch, fallthrough);
1.170 return;
1.171 }
1.172