case TSTRING: // implemented as pointer
w = wptr;
break;
- case TDARRAY:
- fatal("width of a dynamic array");
case TARRAY:
+ if(t->bound < 0)
+ fatal("width of a dynamic array");
if(t->type == T)
break;
dowidth(t->type);
- w = t->bound * t->type->width
-;// + offsetof(Array, b[0]);
+ w = t->bound * t->type->width;
break;
case TSTRUCT:
}
regalloc(&n1, nl->type, res);
cgen(nl, &n1);
- if(isptrto(n->type, TARRAY) && isptrto(nl->type, TDARRAY)) {
+ if(isptrarray(n->type) && isptrdarray(nl->type)) {
// convert dynamic array to static array
n2 = n1;
n2.op = OINDREG;
n2.type = types[tptr];
gins(AMOVQ, &n2, &n1);
}
- if(isptrto(n->type, TDARRAY) && isptrto(nl->type, TARRAY)) {
+ if(isptrdarray(n->type) && isptrarray(nl->type)) {
// conver static array to dynamic array
// it is assumed that the dope is just before the array
nodconst(&n2, types[tptr], offsetof(Array,b));
regfree(&n1);
break;
}
- if(isptrto(nl->type, TDARRAY)) {
+ if(isptrdarray(nl->type)) {
regalloc(&n1, types[tptr], res);
cgen(nl, &n1);
n1.op = OINDREG;
break;
case OCAP:
- if(isptrto(nl->type, TDARRAY)) {
+ if(isptrdarray(nl->type)) {
regalloc(&n1, types[tptr], res);
cgen(nl, &n1);
n1.op = OINDREG;
// i is in &n1
// w is width
- if(isptrto(nl->type, TDARRAY)) {
+ if(isptrdarray(nl->type)) {
regalloc(&n2, types[tptr], res);
gmove(res, &n2);
if(!debug['B']) {
// check bounds
nodconst(&n3, types[TUINT32], nl->type->bound);
- if(isptrto(nl->type, TARRAY))
+ if(isptrarray(nl->type))
nodconst(&n3, types[TUINT32], nl->type->type->bound);
gins(optoas(OCMP, types[TUINT32]), &n1, &n3);
switch(t->etype) {
case TSTRUCT:
case TARRAY:
- case TDARRAY:
case TINTER: // maybe remove later
return 1;
}
if(n->op != ODCLFIELD || n->type == T)
fatal("stotype: oops %N\n", n);
- if(n->type->etype == TDARRAY)
+ if(n->type->etype == TARRAY && n->type->bound < 0)
yyerror("type of a structure field cannot be an open array");
f = typ(TFIELD);
break;
case TARRAY:
- case TDARRAY:
reexport(t->type);
/* type 2 */
Bprint(bout, "\ttype ");
if(s->export != 0)
Bprint(bout, "!");
- if(et == TDARRAY) {
+ if(t->bound >= 0)
+ Bprint(bout, "%lS [%lud] %lS\n", s, t->bound, t->type->sym);
+ else
Bprint(bout, "%lS [] %lS\n", s, t->type->sym);
- break;
- }
- Bprint(bout, "%lS [%lud] %lS\n", s, t->bound, t->type->sym);
break;
case TPTR32:
Type *t;
Sym *s;
- if(b == nil) {
- t = typ(TDARRAY);
- t->dbound = N;
- } else {
- t = typ(TARRAY);
+ t = typ(TARRAY);
+ t->bound = -1;
+ if(b != nil)
t->bound = mpgetfix(b->u.xval);
- }
s = pkglookup(st->sym->name, st->psym->name);
t->type = s->otype;
vlong argwid;
// TARRAY
- int32 bound;
- Node* dbound;
+ int32 bound; // negative is dynamic array
};
#define T ((Type*)0)
TFUNC,
TARRAY,
- TDARRAY,
+ T_old_DARRAY,
TSTRUCT,
TCHAN,
TMAP,
Type* aindex(Node*, Type*);
int isnil(Node*);
int isptrto(Type*, int);
+int isptrarray(Type*);
+int isptrdarray(Type*);
int isinter(Type*);
int isbytearray(Type*);
int eqtype(Type*, Type*, int);
Type *r;
int bound;
+ bound = -1; // open bound
walktype(b, Erv);
switch(whatis(b)) {
default: // variable bound
- walktype(b, Erv);
- if(b->type != T && isint[b->type->etype])
- goto dyn;
yyerror("array bound must be an integer expression");
- bound = 0;
break;
case Wnil: // open bound
- goto dyn;
+ break;
case Wlitint: // fixed bound
bound = mpgetfix(b->val.u.xval);
+ if(bound < 0)
+ yyerror("array bound must be non negative");
break;
}
// fixed array
r = typ(TARRAY);
r->type = t;
- r->dbound = b;
r->bound = bound;
return r;
-
-dyn:
- // dynamic array
- r = typ(TDARRAY);
- r->type = t;
- r->dbound = b;
- r->bound = 0;
- return r;
}
void
[TPTR64] = "PTR64",
[TFUNC] = "FUNC",
[TARRAY] = "ARRAY",
- [TDARRAY] = "DARRAY",
+// [TDARRAY] = "DARRAY",
[TSTRUCT] = "STRUCT",
[TCHAN] = "CHAN",
[TMAP] = "MAP",
break;
case TARRAY:
- snprint(buf1, sizeof(buf1), "[%ld]%T", t->bound, t->type);
- strncat(buf, buf1, sizeof(buf));
- break;
-
- case TDARRAY:
- snprint(buf1, sizeof(buf1), "[]%T", t->type);
- if(t->dbound != N)
- snprint(buf1, sizeof(buf1), "[<expr>]%T", t->type);
+ if(t->bound >= 0)
+ snprint(buf1, sizeof(buf1), "[%ld]%T", t->bound, t->type);
+ else
+ snprint(buf1, sizeof(buf1), "[]%T", t->type);
strncat(buf, buf1, sizeof(buf));
break;
return 1;
}
+int
+isptrarray(Type *t)
+{
+ if(isptrto(t, TARRAY))
+ if(t->type->bound >= 0)
+ return 1;
+ return 0;
+}
+
+int
+isptrdarray(Type *t)
+{
+ if(isptrto(t, TARRAY))
+ if(t->type->bound < 0)
+ return 1;
+ return 0;
+}
+
int
isinter(Type *t)
{
case TPTR64:
case TCHAN:
case TARRAY:
- case TDARRAY:
stp = &st->type;
goto loop;
case TPTR64:
case TCHAN:
case TARRAY:
- case TDARRAY:
nt = shallow(t);
nt->type = deep(t->type);
break;
}
// convert dynamic to static generated by ONEW
- if(isptrto(t, TARRAY) && isptrto(l->type, TDARRAY))
+ if(isptrarray(t) && isptrdarray(l->type))
goto ret;
// if(t->etype == TARRAY) {
goto badt;
case TSTRING:
case TMAP:
- case TDARRAY:
break;
case TARRAY:
- nodconst(n, types[TINT32], t->bound);
+ if(t->bound >= 0)
+ nodconst(n, types[TINT32], t->bound);
break;
}
n->type = types[TINT32];
switch(t->etype) {
default:
goto badt;
- case TDARRAY:
- break;
case TARRAY:
- nodconst(n, types[TINT32], t->bound);
+ if(t->bound >= 0)
+ nodconst(n, types[TINT32], t->bound);
break;
}
n->type = types[TINT32];
*n = *mapop(n, top);
break;
- case TDARRAY:
case TARRAY:
// right side must be an int
if(n->right->type == T) {
*n = *stringop(n, top);
goto ret;
}
- if(t->etype == TDARRAY || t->etype == TARRAY) {
+ if(t->etype == TARRAY) {
*n = *arrayop(n, top);
goto ret;
}
if(isptrto(t1, TSTRUCT))
return 1;
- if(isptrto(t1, TDARRAY))
- if(isptrto(t2, TARRAY))
+ if(isptrdarray(t1))
+ if(isptrarray(t2))
return 1;
return 0;
}
r = chanop(n, Erv);
return r;
- case TDARRAY:
case TARRAY:
r = arrayop(n, Erv);
return r;
return T;
}
- if(t->etype != TDARRAY && t->etype != TARRAY) {
+ if(t->etype != TARRAY) {
fatal("fixarray: %lT not array", tm);
return T;
}
r = a;
a = listfirst(&save, &n->left); // max
+ a = listnext(&save);
if(a == N)
a = nodintconst(0);
a = nod(OCONV, a, N);
a->type = types[TUINT32];
r = list(a, r);
- a = t->dbound; // nel
- if(a == N)
+ a = listfirst(&save, &n->left); // nel
+ if(a == N) {
+ if(t->bound < 0)
+ yyerror("new open array must have size");
a = nodintconst(t->bound);
+ }
a = nod(OCONV, a, N);
a->type = types[TUINT32];
r = list(a, r);
return n;
case OSLICE:
- if(isptrto(n->left->type, TARRAY))
+ if(isptrarray(n->left->type))
goto slicestatic;
// arrayslices(old *[]any, lb uint32, hb uint32, width uint32) (ary *[]any)
return n;
}
- if(isptrto(lt, TDARRAY) && isptrto(rt, TARRAY)) {
+ if(isptrdarray(lt) && isptrarray(rt)) {
if(!eqtype(lt->type->type, rt->type->type, 0))
goto bad;
*n = *arrayop(n, Etop);