static Type* sw2(Node*, Type*);
static Type* sw3(Node*, Type*);
static Node* curfn;
+static Node* addtop;
void
walk(Node *fn)
}
void
-walktype(Node *n, int top)
+walktype1(Node *n, int top)
{
Node *r, *l;
Type *t;
* compile-time constants are evaluated.
*/
- if(top == Exxx || top == Eyyy) {
- dump("", n);
- fatal("walktype: bad top=%d", top);
- }
-
loop:
if(n == N)
goto ret;
fatal("walktype: switch 1 unknown op %N", n);
goto ret;
+ case OLIST:
+ walktype(n->left, top);
+ n = n->right;
+ goto loop;
+
case OPRINT:
if(top != Etop)
goto nottop;
}
goto ret;
- case OLIST:
- walktype(n->left, top);
- n = n->right;
- goto loop;
-
case OFOR:
if(top != Etop)
goto nottop;
goto ret;
convlit(l, t);
+ if(l->type == T)
+ goto ret;
// nil conversion
if(eqtype(t, l->type, 0)) {
*n = *stringop(n, top);
goto ret;
}
- if(isbytearray(l->type) != 0) {
+ if(bytearraysz(l->type) != -2) {
n->op = OARRAY;
*n = *stringop(n, top);
goto ret;
if(isptrarray(t) && isptrdarray(l->type))
goto ret;
-// if(t->etype == TARRAY) {
-// arrayconv(t, l);
-// goto ret;
-// }
-
+ // interface and structure
r = isandss(n->type, l);
if(r != N) {
*n = *r;
goto ret;
}
+
+ // structure literal
+ if(t->etype == TSTRUCT) {
+ r = structlit(n);
+ *n = *r;
+ goto ret;
+ }
+
badtype(n->op, l->type, t);
goto ret;
stringop(Node *n, int top)
{
Node *r, *c, *on;
+ Type *t;
int32 l;
switch(n->op) {
break;
case OARRAY:
- // byteastring(a, l)
+ // byteastring(*byte, int32) string;
+ t = n->left->type;
+ l = bytearraysz(t);
+
+ // &a[0]
c = nodintconst(0);
r = nod(OINDEX, n->left, c);
r = nod(OADDR, r, N);
- l = isbytearray(n->left->type);
- c = nodintconst(l-1);
-
+ if(l >= 0) {
+ // static size
+ c = nodintconst(l);
+ } else {
+ // dynamic size
+ c = nod(OLEN, n->left, N);
+ }
r = list(r, c);
+
on = syslook("byteastring", 0);
r = nod(OCALL, on, r);
break;
return r;
}
+void
+walktype(Node *n, int top)
+{
+ Node *r;
+
+ walktype1(n, top);
+ while(top == Etop && addtop != N) {
+ r = addtop;
+ addtop = N;
+ walktype1(r, top);
+ n->ninit = list(r, n->ninit);
+ }
+}
+
void
diagnamed(Type *t)
{
return n;
}
-//void
-//arrayconv(Type *t, Node *n)
-//{
-// int c;
-// Iter save;
-// Node *l;
-//
-// l = listfirst(&save, &n);
-// c = 0;
-//
-//loop:
-// if(l == N) {
-// if(t->bound == 0)
-// t->bound = c;
-// if(t->bound == 0 || t->bound < c)
-// yyerror("error with array convert bounds");
-// return;
-// }
-//
-// c++;
-// walktype(l, Erv);
-// convlit(l, t->type);
-// if(!ascompat(l->type, t->type))
-// badtype(OARRAY, l->type, t->type);
-// l = listnext(&save);
-// goto loop;
-//}
-
Node*
old2new(Node *n, Type *t)
{
*/
return n;
}
+
+Node*
+structlit(Node *n)
+{
+ Iter savel, saver;
+ Type *l, *t;
+ Node *var, *r, *a;
+
+ t = n->type;
+ if(t->etype != TSTRUCT)
+ fatal("structlit: not struct");
+
+print("\nstruct lit %lT\n", t);
+
+ var = nod(OXXX, N, N);
+ tempname(var, t);
+
+ l = structfirst(&savel, &n->type);
+ r = listfirst(&saver, &n->left);
+
+loop:
+ if(l == T || r == N) {
+ if(l != T || r != N)
+ yyerror("error in shape struct literal");
+ return var;
+ }
+
+ // build list of var.field = expr
+
+ a = nod(ODOT, var, newname(l->sym));
+ a = nod(OAS, a, r);
+ addtop = list(addtop, a);
+
+ l = structnext(&savel);
+ r = listnext(&saver);
+ goto loop;
+}