]> Cypherpunks.ru repositories - gostls13.git/commitdiff
now checks for lvalue/rvalue context of
authorKen Thompson <ken@golang.org>
Mon, 16 Jun 2008 03:24:30 +0000 (20:24 -0700)
committerKen Thompson <ken@golang.org>
Mon, 16 Jun 2008 03:24:30 +0000 (20:24 -0700)
     expressions.
start of generics for calling builtin
     functions
start of map type
'any' demoted from reserved word to type

SVN=122808

15 files changed:
src/cmd/6g/cgen.c
src/cmd/6g/gen.c
src/cmd/gc/const.c
src/cmd/gc/dcl.c
src/cmd/gc/export.c
src/cmd/gc/go.h
src/cmd/gc/go.y
src/cmd/gc/lex.c
src/cmd/gc/subr.c
src/cmd/gc/sys.go
src/cmd/gc/sysimport.c
src/cmd/gc/walk.c
src/runtime/runtime.c
src/runtime/runtime.h
test/switch.go

index 94d6f57a823b423e66499ff8797c571e16ecf3f3..d42fb76cdd285171c4b0a9e0802c5725517b8e85 100644 (file)
@@ -331,15 +331,9 @@ agen(Node *n, Node *res)
                regfree(&n2);
                break;
 
-//     case OIND:
-//             nl = n->left;
-//             if(nl->addable) {
-//                     gopcode(P_LOAD, T_ADDR, nl);
-//                     break;
-//             }
-//             cgen(nl);
-//             gconv(T_ADDR, nl->type->etype);
-//             break;
+       case OIND:
+               cgen(nl, res);
+               break;
                
        case ODOT:
                t = nl->type;
index 4712b0c28c17881265cc16b1f73e05d01f097b73..ca67d73750423044bbb1971ae1a4c4471d17bc1e 100644 (file)
@@ -497,7 +497,7 @@ swgen(Node *n)
                n1.op = OEQ;
                n1.left = &tmp;
                n1.right = s->scase;
-               walktype(&n1, 0);
+               walktype(&n1, Erv);
                bgen(&n1, 1, s->sprog);
        }
        if(dflt != P) {
index cc8e7321a0626d5f1754d8a7a9f8658497885787..0a530b47d414a3828af14a30ed441227ba411d6b 100644 (file)
@@ -10,14 +10,15 @@ convlit(Node *n, Type *t)
 {
        int et;
 
-       if(n->op != OLITERAL)
+       if(n == N || n->op != OLITERAL || t == T)
                return;
-       if(t == T)
+
+       if(t->etype == TANY || isptrto(t, TANY)) {
+               defaultlit(n);
                return;
+       }
 
-       n->type = t;
        et = t->etype;
-
        switch(whatis(n)) {
        case Wlitint:
                if(isptrto(t, TSTRING)) {
@@ -72,6 +73,7 @@ convlit(Node *n, Type *t)
                }
                goto bad1;
        }
+       n->type = t;
        return;
 
 bad1:
@@ -122,9 +124,17 @@ evconst(Node *n)
        case Wlitstr:
                break;
        }
+
        if(wl != wr) {
-               yyerror("illegal combination of literals %d %d", nl->etype, nr->etype);
-               return;
+               if(wl == Wlitfloat && wr == Wlitint)
+                       convlit(n->right, n->left->type);
+               else
+               if(wl == Wlitint && wr == Wlitfloat)
+                       convlit(n->left, n->right->type);
+               else {
+                       yyerror("illegal combination of literals %d %d", nl->etype, nr->etype);
+                       return;
+               }
        }
 
        switch(TUP(n->op, wl)) {
index 95a2ff8c886d1bd04bb3553cc3bac9c476378c89..183da44704865c98e9ddc8c2a2ebcc8b51976cad 100644 (file)
@@ -37,9 +37,17 @@ loop:
 void
 dodcltype(Type *n, Type *t)
 {
+       Type *nt;
 
        if(n == T)
                return;
+       if(t->sym != S) {
+               // botch -- should be a complete deep copy
+               nt = typ(Txxx);
+               *nt = *t;
+               t = nt;
+               t->sym = S;
+       }
        addtyp(n, t, dclcontext);
 }
 
index f36b66d12e2c1b8fcb8bfc4162056485b3ee7bcd..21ed985e03a8f0a1032742a8da92fcc20ca47606 100644 (file)
@@ -217,6 +217,17 @@ dumpexporttype(Sym *s)
                }
                Bprint(bout, "%c\n", (et==TSTRUCT)? '}': '>');
                break;
+
+       case TMAP:
+               reexport(t->type);
+               reexport(t->down);
+
+               /* type 6 */
+               Bprint(bout, "\ttype ");
+               if(s->export != 0)
+                       Bprint(bout, "!");
+               Bprint(bout, "%lS [%lS] %lS\n", s, t->down->sym, t->type->sym);
+               break;
        }
 }
 
@@ -481,9 +492,18 @@ doimportv1(Node *ss, Node *st)
  * array type
  */
 void
-doimport1(Node *ss, Node *ss1, Node *s)
+doimport1(Node *ss, Node *si, Node *st)
 {
-       fatal("doimport1");
+       Type *t;
+       Sym *s;
+
+       t = typ(TMAP);
+       s = pkglookup(si->sym->name, si->psym->name);
+       t->down = s->otype;
+       s = pkglookup(st->sym->name, st->psym->name);
+       t->type = s->otype;
+
+       importaddtyp(ss, t);
 }
 
 /*
index 0ce1e6a9ceb808e5e72a35b5265bfa0cc843a841..c4153ee424dc418cbc12bb721c51dc7e49e6021f 100644 (file)
@@ -320,6 +320,15 @@ enum
        PSTATIC,
 };
 
+enum
+{
+       Exxx,
+       Eyyy,
+       Etop,           // evaluated at statement level
+       Elv,            // evaluated in lvalue context
+       Erv,            // evaluated in rvalue context
+};
+
 typedef        struct  Io      Io;
 struct Io
 {
@@ -359,6 +368,7 @@ EXTERN      uchar   isptr[NTYPE];
 EXTERN uchar   isint[NTYPE];
 EXTERN uchar   isfloat[NTYPE];
 EXTERN uchar   issigned[NTYPE];
+EXTERN uchar   issimple[NTYPE];
 EXTERN uchar   okforeq[NTYPE];
 EXTERN uchar   okforadd[NTYPE];
 EXTERN uchar   okforand[NTYPE];
@@ -447,6 +457,7 @@ int isptrto(Type*, int);
 int    isinter(Type*);
 int    isbytearray(Type*);
 int    eqtype(Type*, Type*, int);
+void   argtype(Node*, Type*);
 int    eqargs(Type*, Type*);
 ulong  typehash(Type*, int);
 void   frame(int);
@@ -457,6 +468,7 @@ void        ullmancalc(Node*);
 void   badtype(int, Type*, Type*);
 Type*  ptrto(Type*);
 Node*  cleanidlist(Node*);
+Node*  syslook(char*, int);
 
 Type** getthis(Type*);
 Type** getoutarg(Type*);
@@ -541,10 +553,10 @@ void      doimport7(Node*, Node*);
  */
 void   walk(Node*);
 void   walktype(Node*, int);
-Type*  walkswitch(Node*, Node*, Type*(*)(Node*, Type*));
+Type*  walkswitch(Node*, Type*(*)(Node*, Type*));
 int    casebody(Node*);
 int    whatis(Node*);
-void   walkdot(Node*);
+void   walkdot(Node*, int);
 Node*  ascompatee(int, Node**, Node**);
 Node*  ascompatet(int, Node**, Type**, int);
 Node*  ascompatte(int, Type**, Node**, int);
@@ -552,7 +564,8 @@ int ascompat(Type*, Type*);
 Node*  prcompat(Node*);
 Node*  nodpanic(long);
 Node*  newcompat(Node*);
-Node*  stringop(Node*);
+Node*  stringop(Node*, int);
+Node*  mapop(Node*, int);
 Node*  convas(Node*);
 void   arrayconv(Type*, Node*);
 Node*  reorder1(Node*);
index c20606300901b4746c340d80771188d53e2db789..519e3a9a68610ed0dd26e47371b059e1aaa36bdd 100644 (file)
@@ -12,7 +12,7 @@
        struct  Val     val;
        int             lint;
 }
-%token <sym>           LNAME LBASETYPE LATYPE LANY LPACK LACONST
+%token <sym>           LNAME LBASETYPE LATYPE LPACK LACONST
 %token <val>           LLITERAL LASOP
 %token                 LPACKAGE LIMPORT LEXPORT
 %token                 LMAP LCHAN LINTERFACE LFUNC LSTRUCT
@@ -191,7 +191,7 @@ vardcl:
        }
 |      new_name '=' expr
        {
-               walktype($3, 0);        // this is a little harry
+               walktype($3, Erv);      // this is a little harry
                defaultlit($3);
                dodclvar($1, $3->type);
 
@@ -201,13 +201,13 @@ vardcl:
 constdcl:
        new_name '=' expr
        {
-               walktype($3, 0);
+               walktype($3, Erv);
                dodclconst($1, $3);
                iota += 1;
        }
 |      new_name type '=' expr
        {
-               walktype($4, 0);
+               walktype($4, Erv);
                convlit($4, $2);
                dodclconst($1, $4);
                iota += 1;
@@ -257,7 +257,7 @@ simple_stmt:
        }
 |      new_name LCOLAS expr
        {
-               walktype($3, 0);        // this is a little harry
+               walktype($3, Erv);      // this is a little harry
                defaultlit($3);
                dodclvar($1, $3->type);
 
@@ -278,17 +278,23 @@ complex_stmt:
                        yyerror("switch statement must have case labels");
                $$ = $2;
                $$->op = OSWITCH;
+               //if($$->ninit != N && $$->ntest == N)
+               //      yyerror("switch expression should not be missing");
        }
 |      LIF if_stmt
        {
                popdcl("if/switch");
                $$ = $2;
+               //if($$->ninit != N && $$->ntest == N)
+               //      yyerror("if conditional should not be missing");
        }
 |      LIF if_stmt LELSE else_stmt1
        {
                popdcl("if/switch");
                $$ = $2;
                $$->nelse = $4;
+               //if($$->ninit != N && $$->ntest == N)
+               //      yyerror("if conditional should not be missing");
        }
 |      LRANGE range_stmt
        {
@@ -352,6 +358,8 @@ semi_stmt:
                popdcl("if/switch");
                $$ = $2;
                $$->nelse = $4;
+               //if($$->ninit != N && $$->ntest == N)
+               //      yyerror("if conditional should not be missing");
        }
 
 compound_stmt:
@@ -756,10 +764,6 @@ typeconv:
                $$->down = $3;
                $$->type = $5;
        }
-|      LANY
-       {
-               $$ = typ(TANY);
-       }
 
 type:
        latype
@@ -799,10 +803,6 @@ type:
        {
                $$ = dostruct(N, TINTER);
        }
-|      LANY
-       {
-               $$ = typ(TANY);
-       }
 |      fntypeh
 |      '*' type
        {
@@ -1284,8 +1284,10 @@ oarg_type_list:
  * an output package
  */
 hidden_import:
+       /* leftover import ignored */
+       LPACKAGE sym
        /* variables */
-       LVAR hidden_importsym hidden_importsym
+|      LVAR hidden_importsym hidden_importsym
        {
                // var
                doimportv1($2, $3);
index 91c35a126be6d6746e2365afe24beef34718da83..fbba021a1c8f45e8a1a05e2011ac413049756557 100644 (file)
@@ -845,8 +845,10 @@ static     struct
        "char",         LBASETYPE,      TUINT8,         // temp??
        "string",       LBASETYPE,      TSTRING,
 
+       "any",          LBASETYPE,      TANY,
+
 /* keywords */
-       "any",          LANY,           Txxx,
+//     "any",          LANY,           Txxx,
        "break",        LBREAK,         Txxx,
        "case",         LCASE,          Txxx,
        "chan",         LCHAN,          Txxx,
@@ -918,13 +920,17 @@ lexinit(void)
                        okforeq[i] = 1;
                        okforadd[i] = 1;
                        okforand[i] = 1;
+                       issimple[i] = 1;
                }
                if(isfloat[i]) {
                        okforeq[i] = 1;
                        okforadd[i] = 1;
+                       issimple[i] = 1;
                }
                switch(i) {
                case TBOOL:
+                       issimple[i] = 1;
+
                case TPTR32:
                case TPTR64:
                        okforeq[i] = 1;
index 37375342c04c5ddd17b0ee97d3d59d650f1524c8..8d24915359fb7507cc3434ad75eeef43c62f8adf 100644 (file)
@@ -36,7 +36,7 @@ warn(char *fmt, ...)
 {
        va_list arg;
 
-       print("%L warning: ");
+       print("%L: ");
        va_start(arg, fmt);
        vfprint(1, fmt, arg);
        va_end(arg);
@@ -50,7 +50,7 @@ fatal(char *fmt, ...)
 {
        va_list arg;
 
-       print("%L fatal error: ");
+       print("%L: fatal error: ");
        va_start(arg, fmt);
        vfprint(1, fmt, arg);
        va_end(arg);
@@ -344,7 +344,7 @@ aindex(Node *b, Type *t)
        if(t->etype == TDARRAY)
                yyerror("dynamic array type cannot be a dynamic array");
 
-       walktype(b, 0);
+       walktype(b, Erv);
        switch(whatis(b)) {
        default:
                yyerror("array bound must be a constant integer expression");
@@ -754,6 +754,7 @@ etnames[] =
        [TFIELD]        = "FIELD",
        [TSTRING]       = "STRING",
        [TCHAN]         = "CHAN",
+       [TANY]          = "ANY",
 };
 
 int
@@ -884,6 +885,7 @@ Tconv(Fmt *fp)
 
        strcpy(buf, "");
        if(t->sym != S) {
+               if(t->sym->name[0] != '_')
                snprint(buf, sizeof(buf), "<%S>", t->sym);
        }
        if(t->trecur > 5) {
@@ -908,13 +910,13 @@ Tconv(Fmt *fp)
 
        case TFUNC:
                if(fp->flags & FmtLong)
-                       snprint(buf1, sizeof(buf1), "%d%d%d(%lT,%lT,%lT)",
-                               t->thistuple, t->outtuple, t->intuple,
-                               t->type, t->type->down, t->type->down->down);
+                       snprint(buf1, sizeof(buf1), "%d%d%d(%lT,%lT)%lT",
+                               t->thistuple, t->intuple, t->outtuple,
+                               t->type, t->type->down->down, t->type->down);
                else
-                       snprint(buf1, sizeof(buf1), "%d%d%d(%T,%T,%T)",
-                               t->thistuple, t->outtuple, t->intuple,
-                               t->type, t->type->down, t->type->down->down);
+                       snprint(buf1, sizeof(buf1), "%d%d%d(%T,%T)%T",
+                               t->thistuple, t->intuple, t->outtuple,
+                               t->type, t->type->down->down, t->type->down);
                strncat(buf, buf1, sizeof(buf));
                break;
 
@@ -1205,6 +1207,141 @@ eqtype(Type *t1, Type *t2, int d)
        return eqtype(t1->type, t2->type, d+1);
 }
 
+static int
+subtype(Type **stp, Type *t)
+{
+       Type *st;
+
+loop:
+       st = *stp;
+       if(st == T)
+               return 0;
+       switch(st->etype) {
+       default:
+               return 0;
+
+       case TPTR32:
+       case TPTR64:
+               stp = &st->type;
+               goto loop;
+
+       case TANY:
+               *stp = t;
+               break;
+
+       case TMAP:
+               if(subtype(&st->down, t))
+                       break;
+               stp = &st->type;
+               goto loop;
+
+       case TFUNC:
+               for(;;) {
+                       if(subtype(&st->type, t))
+                               break;
+                       if(subtype(&st->type->down->down, t))
+                               break;
+                       if(subtype(&st->type->down, t))
+                               break;
+                       return 0;
+               }
+               break;
+
+       case TSTRUCT:
+               for(st=st->type; st!=T; st=st->down)
+                       if(subtype(&st->type, t))
+                               return 1;
+               return 0;
+       }
+       return 1;
+}
+
+void
+argtype(Node *on, Type *t)
+{
+       if(!subtype(&on->type, t))
+               fatal("argtype: failed %N %T\n", on, t);
+}
+
+Type*
+shallow(Type *t)
+{
+       Type *nt;
+
+       if(t == T)
+               return T;
+       nt = typ(0);
+       *nt = *t;
+       return nt;
+}
+
+Type*
+deep(Type *t)
+{
+       Type *nt, *xt;
+
+       if(t == T)
+               return T;
+
+       switch(t->etype) {
+       default:
+               nt = t; // share from here down
+               break;
+
+       case TPTR32:
+       case TPTR64:
+               nt = shallow(t);
+               nt->type = deep(t->type);
+               break;
+
+       case TMAP:
+               nt = shallow(t);
+               nt->down = deep(t->down);
+               nt->type = deep(t->type);
+               break;
+
+       case TFUNC:
+               nt = shallow(t);
+               nt->type = deep(t->type);
+               nt->type->down = deep(t->type->down);
+               nt->type->down->down = deep(t->type->down->down);
+               break;
+
+       case TSTRUCT:
+               nt = shallow(t);
+               nt->type = shallow(t->type);
+               xt = nt->type;
+
+               for(t=t->type; t!=T; t=t->down) {
+                       xt->type = deep(t->type);
+                       xt->down = shallow(t->down);
+                       xt = xt->down;
+               }
+               break;
+       }
+       return nt;
+}
+
+Node*
+syslook(char *name, int copy)
+{
+       Sym *s;
+       Node *n;
+
+       s = pkglookup(name, "sys");
+       if(s == S || s->oname == N)
+               fatal("looksys: cant find sys.%s", name);
+
+       if(!copy)
+               return s->oname;
+
+       n = nod(0, N, N);
+       *n = *s->oname;
+       n->type = deep(s->oname->type);
+
+       return n;
+}
+
 /*
  * are the arg names of two
  * functions the same. we know
@@ -1386,13 +1523,27 @@ out:
 void
 badtype(int o, Type *tl, Type *tr)
 {
-       yyerror("illegal types for operand");
+
+loop:
+       switch(o) {
+       case OCALL:
+               if(tl == T || tr == T)
+                       break;
+               if(isptr[tl->etype] && isptr[tr->etype]) {
+                       tl = tl->type;
+                       tr = tr->type;
+                       goto loop;
+               }
+               if(tl->etype != TFUNC || tr->etype != TFUNC)
+                       break;
+//             if(eqtype(t1, t2, 0))
+       }
+
+       yyerror("illegal types for operand: %O", o);
        if(tl != T)
-               print(" (%T)", tl);
-       print(" %O ", o);
+               print(" (%lT)\n", tl);
        if(tr != T)
-               print("(%T)", tr);
-       print("\n");
+               print(" (%lT)\n", tr);
 }
 
 /*
@@ -1605,6 +1756,11 @@ listnext(Iter *s)
 
        n = s->n;
        r = n->right;
+       if(r == N) {
+               s->an = &s->n;
+               s->n = N;
+               return N;
+       }
        if(r->op == OLIST) {
                s->n = r;
                s->an = &r->left;
index 89da8919fbd8eee74cfbb8213269894f8f834598..7e8fd5f03e9069848e8510be27a0cc2a4a85353c 100644 (file)
@@ -5,7 +5,7 @@
 
 package foop   // rename to avoid redeclaration
 
-func   mal(uint32) *byte;
+func   mal(uint32) *any;
 func   breakpoint();
 func   panicl(int32);
 
@@ -27,17 +27,27 @@ func        frexp(float64) (int32, float64);        // break fp into exp,fract
 func   ldexp(int32, float64) float64;          // make fp from exp,fract
 func   modf(float64) (float64, float64);       // break fp into double.double
 
+func   newmap(keysize uint32, valsize uint32,
+               keyalg uint32, valalg uint32,
+               hint uint32) (hmap *map[any]any);
+func   mapaccess1(hmap *map[any]any, key any) (val any);
+func   mapaccess2(hmap *map[any]any, key any) (val any, pres bool);
+func   mapdelete(hmap *map[any]any, key any);
+func   mapassign(hmap *map[any]any, any);
+
 export
        mal
        breakpoint
-       panicl
 
+       // print panic
+       panicl
        printbool
        printfloat
        printint
        printstring
        printpointer
 
+       // op string
        catstring
        cmpstring
        slicestring
@@ -49,4 +59,12 @@ export
        frexp
        ldexp
        modf
+
+       // op map
+       newmap
+       mapaccess1
+       mapaccess2
+       mapdelete
+       mapassign
+
        ;
index 776d5a76bbbe2c7d5361f041930e2ee804684b50..439c311eca37eb75e0a0a685645a2eb423d44cfe 100644 (file)
@@ -1,11 +1,12 @@
 char*  sysimport =
+       "package sys\n"
        "type sys._e002 {}\n"
-       "type sys.uint8 2\n"
-       "type sys._e003 *sys.uint8\n"
-       "type sys._o137 {_e135 sys._e003}\n"
+       "type sys.any 24\n"
+       "type sys._e003 *sys.any\n"
+       "type sys._o172 {_e170 sys._e003}\n"
        "type sys.uint32 6\n"
-       "type sys._i139 {_e136 sys.uint32}\n"
-       "type sys._e001 (sys._e002 sys._o137 sys._i139)\n"
+       "type sys._i174 {_e171 sys.uint32}\n"
+       "type sys._e001 (sys._e002 sys._o172 sys._i174)\n"
        "var !sys.mal sys._e001\n"
        "type sys._e005 {}\n"
        "type sys._e006 {}\n"
@@ -15,95 +16,131 @@ char*      sysimport =
        "type sys._e009 {}\n"
        "type sys._e010 {}\n"
        "type sys.int32 5\n"
-       "type sys._i145 {_e144 sys.int32}\n"
-       "type sys._e008 (sys._e009 sys._e010 sys._i145)\n"
+       "type sys._i180 {_e179 sys.int32}\n"
+       "type sys._e008 (sys._e009 sys._e010 sys._i180)\n"
        "var !sys.panicl sys._e008\n"
        "type sys._e012 {}\n"
        "type sys._e013 {}\n"
        "type sys.bool 12\n"
-       "type sys._i150 {_e149 sys.bool}\n"
-       "type sys._e011 (sys._e012 sys._e013 sys._i150)\n"
+       "type sys._i185 {_e184 sys.bool}\n"
+       "type sys._e011 (sys._e012 sys._e013 sys._i185)\n"
        "var !sys.printbool sys._e011\n"
        "type sys._e015 {}\n"
        "type sys._e016 {}\n"
        "type sys.float64 10\n"
-       "type sys._i155 {_e154 sys.float64}\n"
-       "type sys._e014 (sys._e015 sys._e016 sys._i155)\n"
+       "type sys._i190 {_e189 sys.float64}\n"
+       "type sys._e014 (sys._e015 sys._e016 sys._i190)\n"
        "var !sys.printfloat sys._e014\n"
        "type sys._e018 {}\n"
        "type sys._e019 {}\n"
        "type sys.int64 7\n"
-       "type sys._i160 {_e159 sys.int64}\n"
-       "type sys._e017 (sys._e018 sys._e019 sys._i160)\n"
+       "type sys._i195 {_e194 sys.int64}\n"
+       "type sys._e017 (sys._e018 sys._e019 sys._i195)\n"
        "var !sys.printint sys._e017\n"
        "type sys._e021 {}\n"
        "type sys._e022 {}\n"
        "type sys._e023 25\n"
        "type sys.string *sys._e023\n"
-       "type sys._i165 {_e164 sys.string}\n"
-       "type sys._e020 (sys._e021 sys._e022 sys._i165)\n"
+       "type sys._i200 {_e199 sys.string}\n"
+       "type sys._e020 (sys._e021 sys._e022 sys._i200)\n"
        "var !sys.printstring sys._e020\n"
        "type sys._e025 {}\n"
        "type sys._e026 {}\n"
+       "type sys.uint8 2\n"
        "type sys._e027 *sys.uint8\n"
-       "type sys._i170 {_e169 sys._e027}\n"
-       "type sys._e024 (sys._e025 sys._e026 sys._i170)\n"
+       "type sys._i205 {_e204 sys._e027}\n"
+       "type sys._e024 (sys._e025 sys._e026 sys._i205)\n"
        "var !sys.printpointer sys._e024\n"
        "type sys._e029 {}\n"
-       "type sys._o177 {_e174 sys.string}\n"
-       "type sys._i179 {_e175 sys.string _e176 sys.string}\n"
-       "type sys._e028 (sys._e029 sys._o177 sys._i179)\n"
+       "type sys._o212 {_e209 sys.string}\n"
+       "type sys._i214 {_e210 sys.string _e211 sys.string}\n"
+       "type sys._e028 (sys._e029 sys._o212 sys._i214)\n"
        "var !sys.catstring sys._e028\n"
        "type sys._e031 {}\n"
-       "type sys._o187 {_e184 sys.int32}\n"
-       "type sys._i189 {_e185 sys.string _e186 sys.string}\n"
-       "type sys._e030 (sys._e031 sys._o187 sys._i189)\n"
+       "type sys._o222 {_e219 sys.int32}\n"
+       "type sys._i224 {_e220 sys.string _e221 sys.string}\n"
+       "type sys._e030 (sys._e031 sys._o222 sys._i224)\n"
        "var !sys.cmpstring sys._e030\n"
        "type sys._e033 {}\n"
-       "type sys._o198 {_e194 sys.string}\n"
-       "type sys._i200 {_e195 sys.string _e196 sys.int32 _e197 sys.int32}\n"
-       "type sys._e032 (sys._e033 sys._o198 sys._i200)\n"
+       "type sys._o233 {_e229 sys.string}\n"
+       "type sys._i235 {_e230 sys.string _e231 sys.int32 _e232 sys.int32}\n"
+       "type sys._e032 (sys._e033 sys._o233 sys._i235)\n"
        "var !sys.slicestring sys._e032\n"
        "type sys._e035 {}\n"
-       "type sys._o209 {_e206 sys.uint8}\n"
-       "type sys._i211 {_e207 sys.string _e208 sys.int32}\n"
-       "type sys._e034 (sys._e035 sys._o209 sys._i211)\n"
+       "type sys._o244 {_e241 sys.uint8}\n"
+       "type sys._i246 {_e242 sys.string _e243 sys.int32}\n"
+       "type sys._e034 (sys._e035 sys._o244 sys._i246)\n"
        "var !sys.indexstring sys._e034\n"
        "type sys._e037 {}\n"
-       "type sys._o218 {_e216 sys.string}\n"
-       "type sys._i220 {_e217 sys.int64}\n"
-       "type sys._e036 (sys._e037 sys._o218 sys._i220)\n"
+       "type sys._o253 {_e251 sys.string}\n"
+       "type sys._i255 {_e252 sys.int64}\n"
+       "type sys._e036 (sys._e037 sys._o253 sys._i255)\n"
        "var !sys.intstring sys._e036\n"
        "type sys._e039 {}\n"
-       "type sys._o227 {_e224 sys.string}\n"
+       "type sys._o262 {_e259 sys.string}\n"
        "type sys._e040 *sys.uint8\n"
-       "type sys._i229 {_e225 sys._e040 _e226 sys.int32}\n"
-       "type sys._e038 (sys._e039 sys._o227 sys._i229)\n"
+       "type sys._i264 {_e260 sys._e040 _e261 sys.int32}\n"
+       "type sys._e038 (sys._e039 sys._o262 sys._i264)\n"
        "var !sys.byteastring sys._e038\n"
        "type sys._e042 {}\n"
        "type sys._e043 <>\n"
-       "type sys._o238 {_e234 sys._e043}\n"
+       "type sys._o273 {_e269 sys._e043}\n"
        "type sys._e044 *sys.uint8\n"
        "type sys._e045 *sys.uint8\n"
-       "type sys._s245 {}\n"
-       "type sys._e046 *sys._s245\n"
-       "type sys._i240 {_e235 sys._e044 _e236 sys._e045 _e237 sys._e046}\n"
-       "type sys._e041 (sys._e042 sys._o238 sys._i240)\n"
+       "type sys._s280 {}\n"
+       "type sys._e046 *sys._s280\n"
+       "type sys._i275 {_e270 sys._e044 _e271 sys._e045 _e272 sys._e046}\n"
+       "type sys._e041 (sys._e042 sys._o273 sys._i275)\n"
        "var !sys.mkiface sys._e041\n"
        "type sys._e048 {}\n"
-       "type sys._o251 {_e248 sys.int32 _e249 sys.float64}\n"
-       "type sys._i253 {_e250 sys.float64}\n"
-       "type sys._e047 (sys._e048 sys._o251 sys._i253)\n"
+       "type sys._o286 {_e283 sys.int32 _e284 sys.float64}\n"
+       "type sys._i288 {_e285 sys.float64}\n"
+       "type sys._e047 (sys._e048 sys._o286 sys._i288)\n"
        "var !sys.frexp sys._e047\n"
        "type sys._e050 {}\n"
-       "type sys._o260 {_e257 sys.float64}\n"
-       "type sys._i262 {_e258 sys.int32 _e259 sys.float64}\n"
-       "type sys._e049 (sys._e050 sys._o260 sys._i262)\n"
+       "type sys._o295 {_e292 sys.float64}\n"
+       "type sys._i297 {_e293 sys.int32 _e294 sys.float64}\n"
+       "type sys._e049 (sys._e050 sys._o295 sys._i297)\n"
        "var !sys.ldexp sys._e049\n"
        "type sys._e052 {}\n"
-       "type sys._o270 {_e267 sys.float64 _e268 sys.float64}\n"
-       "type sys._i272 {_e269 sys.float64}\n"
-       "type sys._e051 (sys._e052 sys._o270 sys._i272)\n"
+       "type sys._o305 {_e302 sys.float64 _e303 sys.float64}\n"
+       "type sys._i307 {_e304 sys.float64}\n"
+       "type sys._e051 (sys._e052 sys._o305 sys._i307)\n"
        "var !sys.modf sys._e051\n"
+       "type sys._e054 {}\n"
+       "type sys._e056 [sys.any] sys.any\n"
+       "type sys._e055 *sys._e056\n"
+       "type sys._o311 {hmap sys._e055}\n"
+       "type sys._i313 {keysize sys.uint32 valsize sys.uint32 keyalg sys.uint32 valalg sys.uint32 hint sys.uint32}\n"
+       "type sys._e053 (sys._e054 sys._o311 sys._i313)\n"
+       "var !sys.newmap sys._e053\n"
+       "type sys._e058 {}\n"
+       "type sys._o321 {val sys.any}\n"
+       "type sys._e060 [sys.any] sys.any\n"
+       "type sys._e059 *sys._e060\n"
+       "type sys._i323 {hmap sys._e059 key sys.any}\n"
+       "type sys._e057 (sys._e058 sys._o321 sys._i323)\n"
+       "var !sys.mapaccess1 sys._e057\n"
+       "type sys._e062 {}\n"
+       "type sys._o328 {val sys.any pres sys.bool}\n"
+       "type sys._e064 [sys.any] sys.any\n"
+       "type sys._e063 *sys._e064\n"
+       "type sys._i330 {hmap sys._e063 key sys.any}\n"
+       "type sys._e061 (sys._e062 sys._o328 sys._i330)\n"
+       "var !sys.mapaccess2 sys._e061\n"
+       "type sys._e066 {}\n"
+       "type sys._e067 {}\n"
+       "type sys._e069 [sys.any] sys.any\n"
+       "type sys._e068 *sys._e069\n"
+       "type sys._i335 {hmap sys._e068 key sys.any}\n"
+       "type sys._e065 (sys._e066 sys._e067 sys._i335)\n"
+       "var !sys.mapdelete sys._e065\n"
+       "type sys._e071 {}\n"
+       "type sys._e072 {}\n"
+       "type sys._e074 [sys.any] sys.any\n"
+       "type sys._e073 *sys._e074\n"
+       "type sys._i341 {hmap sys._e073 _e340 sys.any}\n"
+       "type sys._e070 (sys._e071 sys._e072 sys._i341)\n"
+       "var !sys.mapassign sys._e070\n"
        "))\n"
 ;
index 3952ad2e60d99d7c045e11237e97f5a987438862..d2bcb05ae4984f6089fdcf0ed6739b07b1630487 100644 (file)
@@ -13,7 +13,7 @@ void
 walk(Node *fn)
 {
        curfn = fn;
-       walktype(fn->nbody, 1);
+       walktype(fn->nbody, Etop);
 }
 
 void
@@ -32,6 +32,10 @@ walktype(Node *n, int top)
         */
 
        lno = dynlineno;
+       if(top == Exxx || top == Eyyy) {
+               dump("", n);
+               fatal("walktype: top=%d", top);
+       }
 
 loop:
        if(n == N)
@@ -39,6 +43,9 @@ loop:
        if(n->op != ONAME)
                dynlineno = n->lineno;  // for diagnostics
 
+if(debug['T'])
+print("%L walktype %O %d\n", n->op, top);
+
        t = T;
        et = Txxx;
 
@@ -48,21 +55,29 @@ loop:
                goto ret;
 
        case OPRINT:
-               walktype(n->left, 0);
+               if(top != Etop)
+                       goto nottop;
+               walktype(n->left, Erv);
                *n = *prcompat(n->left);
                goto ret;
 
        case OPANIC:
-               walktype(n->left, 0);
+               if(top != Etop)
+                       goto nottop;
+               walktype(n->left, Erv);
                *n = *nod(OLIST, prcompat(n->left), nodpanic(n->lineno));
                goto ret;
 
        case OLITERAL:
+               if(top != Erv)
+                       goto nottop;
                n->addable = 1;
                ullmancalc(n);
                goto ret;
 
        case ONAME:
+               if(top == Etop)
+                       goto nottop;
                n->addable = 1;
                ullmancalc(n);
                if(n->type == T) {
@@ -80,63 +95,65 @@ loop:
                goto loop;
 
        case OFOR:
-               if(!top)
+               if(top != Etop)
                        goto nottop;
-               walktype(n->ninit, 1);
-               walktype(n->ntest, 1);
-               walktype(n->nincr, 1);
+               walktype(n->ninit, Etop);
+               walktype(n->ntest, Erv);
+               walktype(n->nincr, Etop);
                n = n->nbody;
                goto loop;
 
        case OSWITCH:
-               if(!top)
+               if(top != Etop)
                        goto nottop;
 
                if(n->ntest == N)
                        n->ntest = booltrue;
-               walktype(n->ninit, 1);
-               walktype(n->ntest, 1);
-               walktype(n->nbody, 1);
-
+               walktype(n->ninit, Etop);
+               walktype(n->ntest, Erv);
+               walktype(n->nbody, Etop);
                // find common type
                if(n->ntest->type == T)
-                       n->ntest->type = walkswitch(n->ntest, n->nbody, sw1);
+                       n->ntest->type = walkswitch(n, sw1);
 
                // if that fails pick a type
                if(n->ntest->type == T)
-                       n->ntest->type = walkswitch(n->ntest, n->nbody, sw2);
+                       n->ntest->type = walkswitch(n, sw2);
 
                // set the type on all literals
                if(n->ntest->type != T)
-                       walkswitch(n->ntest, n->nbody, sw3);
+                       walkswitch(n, sw3);
 
-               walktype(n->ntest, 1);
+               walktype(n->ntest, Erv);
 
                n = n->nincr;
                goto loop;
 
        case OEMPTY:
-               if(!top)
+               if(top != Etop)
                        goto nottop;
                goto ret;
 
        case OIF:
-               if(!top)
+               if(top != Etop)
                        goto nottop;
-               walktype(n->ninit, 1);
-               walktype(n->ntest, 1);
-               walktype(n->nelse, 1);
+               walktype(n->ninit, Etop);
+               walktype(n->ntest, Erv);
+               walktype(n->nelse, Etop);
                n = n->nbody;
                goto loop;
 
        case OCALLMETH:
        case OCALLINTER:
        case OCALL:
+               if(top == Elv)
+                       goto nottop;
+
                n->ullman = UINF;
                if(n->type != T)
                        goto ret;
 
-               walktype(n->left, 0);
+               walktype(n->left, Erv);
                if(n->left == N)
                        goto ret;
 
@@ -162,7 +179,7 @@ loop:
                if(t->outtuple == 1)
                        n->type = n->type->type->type;
 
-               walktype(n->right, 0);
+               walktype(n->right, Erv);
 
                switch(n->op) {
                default:
@@ -190,19 +207,26 @@ loop:
                goto ret;
 
        case OAS:
-               if(!top)
+               if(top != Etop)
                        goto nottop;
 
-               r = n->right;
-               if(r == N)
-                       goto ret;
                l = n->left;
+               r = n->right;
                if(l == N)
                        goto ret;
 
+               walktype(l, Elv);
+               walktype(r, Erv);
+
+               if(l == N || l->type == T)
+                       goto ret;
+
+               convlit(r, l->type);
+               if(r == N || r->type == T)
+                       goto ret;
+
+
                if(r->op == OCALL && l->op == OLIST) {
-                       walktype(l, 0);
-                       walktype(r, 0);
                        l = ascompatet(n->op, &n->left, &r->type, 0);
                        if(l != N) {
                                *n = *nod(OLIST, r, reorder2(l));
@@ -210,8 +234,6 @@ loop:
                        goto ret;
                }
 
-               walktype(l, 0);
-               walktype(r, 0);
                l = ascompatee(n->op, &n->left, &n->right);
                if(l != N)
                        *n = *reorder3(l);
@@ -221,17 +243,26 @@ loop:
        case OCONTINUE:
        case OGOTO:
        case OLABEL:
+               if(top != Etop)
+                       goto nottop;
                goto ret;
 
        case OXCASE:
+               if(top != Etop)
+                       goto nottop;
                yyerror("case statement out of place");
                n->op = OCASE;
 
        case OCASE:
-               n = n->left;
+               if(top != Etop)
+                       goto nottop;
+               walktype(n->left, Erv);
+               n = n->right;
                goto loop;
 
        case OXFALL:
+               if(top != Etop)
+                       goto nottop;
                yyerror("fallthrough statement out of place");
                n->op = OFALL;
 
@@ -242,12 +273,16 @@ loop:
        case OS2I:
        case OI2S:
        case OI2I:
+               if(top != Erv)
+                       goto nottop;
                n->addable = 0;
-               walktype(n->left, 0);
+               walktype(n->left, Erv);
                goto ret;
 
        case OCONV:
-               walktype(n->left, 0);
+               if(top != Erv)
+                       goto nottop;
+               walktype(n->left, Erv);
                if(n->left == N)
                        goto ret;
 
@@ -271,12 +306,12 @@ loop:
                // to string
                if(isptrto(n->type, TSTRING)) {
                        if(isint[n->left->type->etype]) {
-                               *n = *stringop(n);
+                               *n = *stringop(n, top);
                                goto ret;
                        }
                        if(isbytearray(n->left->type) != 0) {
                                n->op = OARRAY;
-                               *n = *stringop(n);
+                               *n = *stringop(n, top);
                                goto ret;
                        }
                }
@@ -290,22 +325,28 @@ loop:
                goto ret;
 
        case ORETURN:
-               walktype(n->left, 0);
+               if(top != Etop)
+                       goto nottop;
+               walktype(n->left, Erv);
                l = ascompatte(n->op, getoutarg(curfn->type), &n->left, 1);
                if(l != N)
                        n->left = reorder4(l);
                goto ret;
 
        case ONOT:
-               walktype(n->left, 0);
+               if(top != Erv)
+                       goto nottop;
+               walktype(n->left, Erv);
                if(n->left == N || n->left->type == T)
                        goto ret;
                et = n->left->type->etype;
                break;
 
        case OASOP:
-               if(!top)
+               if(top != Etop)
                        goto nottop;
+               walktype(n->left, Elv);
+               goto com;
 
        case OLSH:
        case ORSH:
@@ -325,8 +366,12 @@ loop:
        case OSUB:
        case OMUL:
        case ODIV:
-               walktype(n->left, 0);
-               walktype(n->right, 0);
+               if(top != Erv)
+                       goto nottop;
+               walktype(n->left, Erv);
+
+       com:
+               walktype(n->right, Erv);
                if(n->left == N || n->right == N)
                        goto ret;
                convlit(n->left, n->right->type);
@@ -349,7 +394,7 @@ loop:
                case OADD:
                case OASOP:
                        if(isptrto(n->left->type, TSTRING)) {
-                               *n = *stringop(n);
+                               *n = *stringop(n, top);
                                goto ret;
                        }
                }
@@ -358,7 +403,9 @@ loop:
        case OMINUS:
        case OPLUS:
        case OCOM:
-               walktype(n->left, 0);
+               if(top != Erv)
+                       goto nottop;
+               walktype(n->left, Erv);
                if(n->left == N)
                        goto ret;
                evconst(n);
@@ -368,7 +415,9 @@ loop:
                break;
 
        case OLEN:
-               walktype(n->left, 0);
+               if(top != Erv)
+                       goto nottop;
+               walktype(n->left, Erv);
                evconst(n);
                ullmancalc(n);
                t = n->left->type;
@@ -387,8 +436,12 @@ loop:
 
        case OINDEX:
        case OINDEXPTR:
-               walktype(n->left, 0);
-               walktype(n->right, 0);
+               if(top == Etop)
+                       goto nottop;
+
+               walktype(n->left, top);
+               walktype(n->right, Erv);
+
                ullmancalc(n);
                if(n->left == N || n->right == N)
                        goto ret;
@@ -398,7 +451,7 @@ loop:
 
                // map
                if(isptrto(t, TMAP)) {
-                       fatal("index map");
+                       *n = *mapop(n, top);
                        goto ret;
                }
 
@@ -412,7 +465,7 @@ loop:
 
                // left side is string
                if(isptrto(t, TSTRING)) {
-                       *n = *stringop(n);
+                       *n = *stringop(n, top);
                        goto ret;
                }
 
@@ -427,12 +480,15 @@ loop:
                goto ret;
 
        case OSLICE:
-               walktype(n->left, 0);
-               walktype(n->right, 0);
+               if(top == Etop)
+                       goto nottop;
+
+               walktype(n->left, top);
+               walktype(n->right, Erv);
                if(n->left == N || n->right == N)
                        goto ret;
                if(isptrto(n->left->type, TSTRING)) {
-                       *n = *stringop(n);
+                       *n = *stringop(n, top);
                        goto ret;
                }
                badtype(OSLICE, n->left->type, T);
@@ -442,11 +498,15 @@ loop:
        case ODOTPTR:
        case ODOTMETH:
        case ODOTINTER:
-               walkdot(n);
+               if(top == Etop)
+                       goto nottop;
+               walkdot(n, top);
                goto ret;
 
        case OADDR:
-               walktype(n->left, 0);
+               if(top != Erv)
+                       goto nottop;
+               walktype(n->left, Elv);
                if(n->left == N)
                        goto ret;
                t = n->left->type;
@@ -456,7 +516,9 @@ loop:
                goto ret;
 
        case OIND:
-               walktype(n->left, 0);
+               if(top == Etop)
+                       goto nottop;
+               walktype(n->left, top);
                if(n->left == N)
                        goto ret;
                t = n->left->type;
@@ -468,6 +530,8 @@ loop:
                goto ret;
 
        case ONEW:
+               if(top != Erv)
+                       goto nottop;
                *n = *newcompat(n);
                goto ret;
        }
@@ -535,7 +599,7 @@ loop:
 
                l = nod(OSUB, l, n->left);
                *n = *l;
-               walktype(n, 0);
+               walktype(n, Erv);
                goto ret;
 
        case OLSH:
@@ -557,7 +621,8 @@ loop:
        goto ret;
 
 nottop:
-       fatal("walktype: not top %O", n->op);
+       dump("bad top", n);
+       fatal("walktype: top=%d %O", top, n->op);
        goto ret;
 
 badt:
@@ -615,16 +680,18 @@ sw3(Node *c, Type *place)
 }
 
 Type*
-walkswitch(Node *test, Node *body, Type*(*call)(Node*, Type*))
+walkswitch(Node *sw, Type*(*call)(Node*, Type*))
 {
        Node *n, *c;
        Type *place;
 
-       place = call(test, T);
+       place = call(sw->ntest, T);
 
-       n = body;
+       n = sw->nbody;
        if(n->op == OLIST)
                n = n->left;
+       if(n->op == OEMPTY)
+               return;
 
        for(; n!=N; n=n->right) {
                if(n->op != OCASE)
@@ -656,14 +723,11 @@ casebody(Node *n)
 
        oc = N;         // last case statement
        ot = N;         // last statement (look for XFALL)
-
        t = listfirst(&save, &n);
 
-       if(t->op != OXCASE)
-               return 0;
-
 loop:
        if(t == N) {
+               /* empty switch */
                if(oc == N)
                        return 0;
                return 1;
@@ -680,7 +744,7 @@ loop:
                        ot->op = OFALL;
        }
 
-       /* if first statement is not case then return 0 */
+       /* if first statement is not case */
        if(oc == N)
                return 0;
 
@@ -740,16 +804,19 @@ deep:
 }
 
 void
-walkdot(Node *n)
+walkdot(Node *n, int top)
 {
        Node *mn;
        Type *t, *f;
        int i;
 
+if(debug['T'])
+print("%L walkdot %O %d\n", n->op, top);
+
        if(n->left == N || n->right == N)
                return;
 
-       walktype(n->left, 0);
+       walktype(n->left, Erv);
        if(n->right->op != ONAME) {
                yyerror("rhs of . must be a name");
                return;
@@ -918,7 +985,6 @@ loop:
                        yyerror("error in shape across assignment");
                return rev(nn);
        }
-
        convlit(r, l->type);
        if(!ascompat(l->type, r->type)) {
                badtype(op, l->type, r->type);
@@ -971,14 +1037,14 @@ prcompat(Node *n)
        Iter save;
        int w;
        char *name;
-       Sym *s;
+       Node *on;
 
        r = N;
        l = listfirst(&save, &n);
 
 loop:
        if(l == N) {
-               walktype(r, 1);
+               walktype(r, Etop);
                return r;
        }
 
@@ -1006,11 +1072,8 @@ loop:
                break;
        }
 
-       s = pkglookup(name, "sys");
-       if(s == S || s->oname == N)
-               fatal("prcompat: cant find sys_%s", name);
-
-       t = *getinarg(s->oname->type);
+       on = syslook(name, 0);
+       t = *getinarg(on->type);
        if(t != nil)
                t = t->type;
        if(t != nil)
@@ -1022,9 +1085,9 @@ loop:
        }
 
        if(r == N)
-               r = nod(OCALL, s->oname, l);
+               r = nod(OCALL, on, l);
        else
-               r = nod(OLIST, r, nod(OCALL, s->oname, l));
+               r = nod(OLIST, r, nod(OCALL, on, l));
 
        l = listnext(&save);
        goto loop;
@@ -1033,57 +1096,55 @@ loop:
 Node*
 nodpanic(long lineno)
 {
-       Sym *s;
-       char *name;
-       Node *n;
-
-       name = "panicl";
-       s = pkglookup(name, "sys");
-       if(s == S || s->oname == N)
-               fatal("prcompat: cant find sys_%s", name);
+       Node *n, *on;
 
+       on = syslook("panicl", 0);
        n = nodintconst(lineno);
-       n = nod(OCALL, s->oname, n);
-       walktype(n, 1);
+       n = nod(OCALL, on, n);
+       walktype(n, Etop);
        return n;
 }
 
 Node*
 newcompat(Node *n)
 {
-       Node *r;
+       Node *r, *on;
        Type *t;
-       Sym *s;
+
+       t = n->type;
+       if(t == T || !isptr[t->etype] || t->type == T)
+               fatal("newcompat: type should be pointer %lT", t);
+
+       t = t->type;
+       if(t->etype == TMAP) {
+               r = mapop(n, Erv);
+               return r;
+       }
 
        if(n->left != N)
                yyerror("dont know what new(,e) means");
-       t = n->type;
-       if(t == T || !isptr[t->etype])
-               fatal("NEW sb pointer %lT", t);
 
-       dowidth(t->type);
+       dowidth(t);
+
+       on = syslook("mal", 1);
 
-       s = pkglookup("mal", "sys");
-       if(s == S || s->oname == N)
-               fatal("newcompat: cant find sys_mal");
+       argtype(on, t);
 
-       r = nodintconst(t->type->width);
-       r = nod(OCALL, s->oname, r);
-       walktype(r, 0);
+       r = nodintconst(t->width);
+       r = nod(OCALL, on, r);
+       walktype(r, Erv);
 
 //     r = nod(OCONV, r, N);
-       r->type = t;
+       r->type = n->type;
 
        return r;
 }
 
 Node*
-stringop(Node *n)
+stringop(Node *n, int top)
 {
-       Node *r, *c;
-       Sym *s;
-       long lno;
-       long l;
+       Node *r, *c, *on;
+       long lno, l;
 
        lno = dynlineno;
        dynlineno = n->lineno;
@@ -1099,23 +1160,18 @@ stringop(Node *n)
        case OLE:
        case OLT:
                // sys_cmpstring(s1, s2) :: 0
-               s = pkglookup("cmpstring", "sys");
-               if(s == S || s->oname == N)
-                       fatal("stringop: cant find sys_cmpstring");
-
+               on = syslook("cmpstring", 0);
                r = nod(OLIST, n->left, n->right);
-               r = nod(OCALL, s->oname, r);
+               r = nod(OCALL, on, r);
                c = nodintconst(0);
                r = nod(n->op, r, c);
                break;
 
        case OADD:
                // sys_catstring(s1, s2)
-               s = pkglookup("catstring", "sys");
-               if(s == S || s->oname == N)
-                       fatal("stringop: cant find sys_catstring");
+               on = syslook("catstring", 0);
                r = nod(OLIST, n->left, n->right);
-               r = nod(OCALL, s->oname, r);
+               r = nod(OCALL, on, r);
                break;
 
        case OASOP:
@@ -1126,11 +1182,11 @@ stringop(Node *n)
 
                case OADD:
                        // s1 = sys_catstring(s1, s2)
-                       s = pkglookup("catstring", "sys");
-                       if(s == S || s->oname == N || n->etype != OADD)
-                               fatal("stringop: cant find sys_catstring");
+                       if(n->etype != OADD)
+                               fatal("stringop: not cat");
                        r = nod(OLIST, n->left, n->right);
-                       r = nod(OCALL, s->oname, r);
+                       on = syslook("catstring", 0);
+                       r = nod(OCALL, on, r);
                        r = nod(OAS, n->left, r);
                        break;
                }
@@ -1138,10 +1194,6 @@ stringop(Node *n)
 
        case OSLICE:
                // sys_slicestring(s, lb, hb)
-               s = pkglookup("slicestring", "sys");
-               if(s == S || s->oname == N)
-                       fatal("stringop: cant find sys_slicestring");
-
                r = nod(OCONV, n->right->left, N);
                r->type = types[TINT32];
 
@@ -1149,43 +1201,30 @@ stringop(Node *n)
                c->type = types[TINT32];
 
                r = nod(OLIST, r, c);
-
                r = nod(OLIST, n->left, r);
-
-               r = nod(OCALL, s->oname, r);
+               on = syslook("slicestring", 0);
+               r = nod(OCALL, on, r);
                break;
 
        case OINDEX:
                // sys_indexstring(s, i)
-               s = pkglookup("indexstring", "sys");
-               if(s == S || s->oname == N)
-                       fatal("stringop: cant find sys_indexstring");
-
                r = nod(OCONV, n->right, N);
                r->type = types[TINT32];
-
                r = nod(OLIST, n->left, r);
-               r = nod(OCALL, s->oname, r);
+               on = syslook("indexstring", 0);
+               r = nod(OCALL, on, r);
                break;
 
        case OCONV:
                // sys_intstring(v)
-               s = pkglookup("intstring", "sys");
-               if(s == S || s->oname == N)
-                       fatal("stringop: cant find sys_intstring");
-
                r = nod(OCONV, n->left, N);
                r->type = types[TINT64];
-
-               r = nod(OCALL, s->oname, r);
+               on = syslook("intstring", 0);
+               r = nod(OCALL, on, r);
                break;
 
        case OARRAY:
                // byteastring(a, l)
-               s = pkglookup("byteastring", "sys");
-               if(s == S || s->oname == N)
-                       fatal("stringop: cant find sys_byteastring");
-
                c = nodintconst(0);
                r = nod(OINDEX, n->left, c);
                r = nod(OADDR, r, N);
@@ -1194,11 +1233,158 @@ stringop(Node *n)
                c = nodintconst(l-1);
 
                r = nod(OLIST, r, c);
-               r = nod(OCALL, s->oname, r);
+               on = syslook("byteastring", 0);
+               r = nod(OCALL, on, r);
+               break;
+       }
+
+       walktype(r, top);
+       dynlineno = lno;
+       return r;
+}
+
+Type*
+fixmap(Type *tm)
+{
+       Type *t;
+
+       t = tm->type;
+       if(t == T) {
+               fatal("fixmap: t nil");
+               return T;
+       }
+
+       if(t->etype != TMAP) {
+               fatal("fixmap: %O not map");
+               return T;
+       }
+
+       if(t->down == T || t->type == T) {
+               fatal("fixmap: map key/value types are nil");
+               return T;
+       }
+
+       dowidth(t->down);
+       dowidth(t->type);
+
+       return t;
+}
+
+static int
+algtype(Type *t)
+{
+       int a;
+
+       a = 0;
+       if(issimple[t->etype])
+               a = 1;          // simple mem
+       else
+       if(isptrto(t, TSTRING))
+               a = 2;          // string
+       else
+       if(isptr[t->etype])
+               a = 3;          // pointer
+       else
+       if(isinter(t))
+               a = 4;          // interface
+       else
+               fatal("algtype: cant find type %T", t);
+       return a;
+}
+
+Node*
+mapop(Node *n, int top)
+{
+       long lno;
+       Node *r, *a;
+       Type *t;
+       Node *on;
+       int alg1, alg2;
+
+       lno = dynlineno;
+       dynlineno = n->lineno;
+
+print("mapop %O\n", n->op);
+       r = n;
+       switch(n->op) {
+       default:
+               fatal("stringop: unknown op %E", n->op);
+
+       case ONEW:
+               // newmap(keysize uint32, valsize uint32,
+               //      keyalg uint32, valalg uint32,
+               //      hint uint32) (hmap *map[any]any);
+
+               t = fixmap(n->type);
+               if(t == T)
+                       break;
+
+               a = n->left;                            // hint
+               if(n->left == N)
+                       a = nodintconst(0);
+               r = a;
+               a = nodintconst(algtype(t->type));      // val algorithm
+               r = nod(OLIST, a, r);
+               a = nodintconst(algtype(t->down));      // key algorithm
+               r = nod(OLIST, a, r);
+               a = nodintconst(t->type->width);        // val width
+               r = nod(OLIST, a, r);
+               a = nodintconst(t->down->width);        // key width
+               r = nod(OLIST, a, r);
+
+               on = syslook("newmap", 1);
+
+print("type1=%lT\n", on->type);
+               argtype(on, t->down);   // any-1
+               argtype(on, t->type);   // any-2
+print("type5=%lT\n", on->type);
+
+               r = nod(OCALL, on, r);
+               walktype(r, top);
+               r->type = n->type;
+               break;
+
+       case OINDEX:
+       case OINDEXPTR:
+               // mapaccess1(hmap *map[any]any, key any) (val any);
+
+               t = fixmap(n->left->type);
+               if(t == T)
+                       break;
+
+               convlit(n->right, t->down);
+
+               if(!eqtype(n->right->type, t->down, 0)) {
+                       badtype(n->op, n->right->type, t->down);
+                       break;
+               }
+
+               a = n->right;                           // key
+               if(!isptr[t->down->etype]) {
+                       a = nod(OADDR, a, N);
+                       a->type = ptrto(t);
+               }
+               r = a;
+               a = n->left;                            // map
+               r = nod(OLIST, a, r);
+
+               on = syslook("mapaccess1", 1);
+
+print("type1=%lT\n", on->type);
+               argtype(on, t->down);   // any-1
+               argtype(on, t->type);   // any-2
+               argtype(on, t->down);   // any-3
+               argtype(on, t->type);   // any-4
+print("type5=%lT\n", on->type);
+
+               r = nod(OCALL, on, r);
+               walktype(r, Erv);
+               r->type = ptrto(t->type);
+               r = nod(OIND, r, N);
+               r->type = t->type;
                break;
        }
 
-       walktype(r, 1);
        dynlineno = lno;
        return r;
 }
@@ -1265,7 +1451,7 @@ ret:
 
        n->right = nod(o, r, N);
        n->right->type = l->type;
-       walktype(n, 1);
+       walktype(n, Etop);
        return n;
 }
 
@@ -1289,7 +1475,7 @@ loop:
        }
 
        c++;
-       walktype(l, 0);
+       walktype(l, Erv);
        convlit(l, t->type);
        if(!ascompat(l->type, t->type))
                badtype(OARRAY, l->type, t->type);
index b4c4a6ce309c447cef3a4cdc86f06890f895d235..724254a116f439b7f0a964c36c7d4278d26b5da3 100644 (file)
@@ -147,7 +147,7 @@ throw(int8 *s)
        sys_exit(1);
 }
 
-static void
+void
 mcpy(byte *t, byte *f, uint32 n)
 {
        while(n > 0) {
@@ -169,7 +169,7 @@ brk(uint32 n)
        return v;
 }
 
-static void*
+void*
 mal(uint32 n)
 {
        byte* v;
index 65c3278e599577218b6bbe6685932ff762e31a1e..a12ac29f5564519dada27284db845e92d385cff1 100644 (file)
@@ -84,6 +84,8 @@ enum
  */
 void   FLUSH(void*);
 void   prints(int8*);
+void   mcpy(byte*, byte*, uint32);
+void*  mal(uint32);
 void   sys_exit(int32);
 void   sys_write(int32, void*, int32);
 void   sys_breakpoint(void);
@@ -97,6 +99,7 @@ void  sys_printbool(bool);
 void   sys_printfloat(float64);
 void   sys_printint(int64);
 void   sys_printstring(string);
+void   sys_printpointer(void*);
 void   sys_catstring(string, string, string);
 void   sys_cmpstring(string, string, int32);
 void   sys_slicestring(string, int32, int32, string);
index 602265631ec0fb97f5d853676b1e88351d7cd534..5fb80c4971d0db809ca08593cf553f7f27ce165f 100644 (file)
@@ -16,6 +16,7 @@ func assert(cond bool, msg string) {
 func main() {
        i5 := 5;
        i7 := 7;
+       hello := "hello";
 
        switch true {
        case i5 < 5: assert(false, "<");
@@ -122,6 +123,13 @@ func main() {
        }
        assert(fired > 0, "fired");
 
+       switch hello {
+       case "wowie": assert(false, "wowie");
+       case "hello": assert(true, "hello");
+       case "jumpn": assert(false, "jumpn");
+       default: assert(false, "default");
+       }
+
        fired = 0;
        switch i := i5 + 2; i {
        case i7: fired = 1;