OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "go.h" | 5 #include "go.h" |
6 | 6 |
7 static Node* walkprint(Node*, NodeList**, int); | 7 static Node* walkprint(Node*, NodeList**, int); |
8 static Node* conv(Node*, Type*); | 8 static Node* conv(Node*, Type*); |
9 static Node* mapfn(char*, Type*); | 9 static Node* mapfn(char*, Type*); |
10 static Node* makenewvar(Type*, NodeList**, Node**); | 10 static Node* makenewvar(Type*, NodeList**, Node**); |
11 | 11 |
12 enum | |
13 { | |
14 Inone, | |
15 I2T, | |
16 I2T2, | |
17 I2I, | |
18 I2Ix, | |
19 I2I2, | |
20 T2I, | |
21 I2Isame, | |
22 E2T, | |
23 E2T2, | |
24 E2I, | |
25 E2I2, | |
26 I2E, | |
27 I2E2, | |
28 T2E, | |
29 E2Esame, | |
30 }; | |
31 | |
32 // can this code branch reach the end | 12 // can this code branch reach the end |
33 // without an undcontitional RETURN | 13 // without an undcontitional RETURN |
34 // this is hard, so it is conservative | 14 // this is hard, so it is conservative |
35 int | 15 int |
36 walkret(NodeList *l) | 16 walkret(NodeList *l) |
37 { | 17 { |
38 Node *n; | 18 Node *n; |
39 | 19 |
40 loop: | 20 loop: |
41 while(l && l->next) | 21 while(l && l->next) |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 t = n->type; | 142 t = n->type; |
163 t->sym = n->sym; | 143 t->sym = n->sym; |
164 t->local = n->local; | 144 t->local = n->local; |
165 t->vargen = n->vargen; | 145 t->vargen = n->vargen; |
166 t->siggen = 0; | 146 t->siggen = 0; |
167 t->method = nil; | 147 t->method = nil; |
168 t->nod = N; | 148 t->nod = N; |
169 t->printed = 0; | 149 t->printed = 0; |
170 t->deferwidth = 0; | 150 t->deferwidth = 0; |
171 | 151 |
172 » // double-check use of type as map key | 152 » // double-check use of type as map key. |
173 » // TODO(rsc): also use of type as receiver? | |
174 if(maplineno) { | 153 if(maplineno) { |
175 lineno = maplineno; | 154 lineno = maplineno; |
176 maptype(n->type, types[TBOOL]); | 155 maptype(n->type, types[TBOOL]); |
177 } | 156 } |
178 if(embedlineno) { | 157 if(embedlineno) { |
179 lineno = embedlineno; | 158 lineno = embedlineno; |
180 if(isptr[t->etype]) | 159 if(isptr[t->etype]) |
181 yyerror("embedded type cannot be a pointer"); | 160 yyerror("embedded type cannot be a pointer"); |
182 } | 161 } |
183 | 162 |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 default: | 413 default: |
435 walkexpr(&n->left, &n->ninit); | 414 walkexpr(&n->left, &n->ninit); |
436 break; | 415 break; |
437 } | 416 } |
438 break; | 417 break; |
439 | 418 |
440 case OFOR: | 419 case OFOR: |
441 walkstmtlist(n->ninit); | 420 walkstmtlist(n->ninit); |
442 if(n->ntest != N) { | 421 if(n->ntest != N) { |
443 walkstmtlist(n->ntest->ninit); | 422 walkstmtlist(n->ntest->ninit); |
444 » » » walkexpr(&n->ntest, &n->ninit); | 423 » » » init = n->ntest->ninit; |
| 424 » » » n->ntest->ninit = nil; |
| 425 » » » walkexpr(&n->ntest, &init); |
| 426 » » » n->ntest->ninit = concat(init, n->ntest->ninit); |
445 } | 427 } |
446 walkstmt(&n->nincr); | 428 walkstmt(&n->nincr); |
447 walkstmtlist(n->nbody); | 429 walkstmtlist(n->nbody); |
448 break; | 430 break; |
449 | 431 |
450 case OIF: | 432 case OIF: |
451 walkstmtlist(n->ninit); | 433 walkstmtlist(n->ninit); |
452 walkexpr(&n->ntest, &n->ninit); | 434 walkexpr(&n->ntest, &n->ninit); |
453 walkstmtlist(n->nbody); | 435 walkstmtlist(n->nbody); |
454 walkstmtlist(n->nelse); | 436 walkstmtlist(n->nelse); |
(...skipping 21 matching lines...) Expand all Loading... |
476 if(samelist(rl, n->list)) { | 458 if(samelist(rl, n->list)) { |
477 // special return in disguise | 459 // special return in disguise |
478 n->list = nil; | 460 n->list = nil; |
479 break; | 461 break; |
480 } | 462 } |
481 ll = ascompatee(n->op, rl, n->list, &n->ninit); | 463 ll = ascompatee(n->op, rl, n->list, &n->ninit); |
482 n->list = reorder3(ll); | 464 n->list = reorder3(ll); |
483 break; | 465 break; |
484 } | 466 } |
485 ll = ascompatte(n->op, getoutarg(curfn->type), n->list, 1, &n->n
init); | 467 ll = ascompatte(n->op, getoutarg(curfn->type), n->list, 1, &n->n
init); |
486 » » n->list = reorder4(ll); | 468 » » n->list = ll; |
487 break; | 469 break; |
488 | 470 |
489 case OSELECT: | 471 case OSELECT: |
490 walkselect(n); | 472 walkselect(n); |
491 break; | 473 break; |
492 | 474 |
493 case OSWITCH: | 475 case OSWITCH: |
494 walkswitch(n); | 476 walkswitch(n); |
495 break; | 477 break; |
496 | 478 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 | 516 |
535 void | 517 void |
536 walkexpr(Node **np, NodeList **init) | 518 walkexpr(Node **np, NodeList **init) |
537 { | 519 { |
538 Node *r, *l, *var, *a; | 520 Node *r, *l, *var, *a; |
539 NodeList *ll, *lr, *lpost; | 521 NodeList *ll, *lr, *lpost; |
540 Type *t; | 522 Type *t; |
541 int et; | 523 int et; |
542 int32 lno; | 524 int32 lno; |
543 Node *n, *fn; | 525 Node *n, *fn; |
| 526 char buf[100], *p; |
544 | 527 |
545 n = *np; | 528 n = *np; |
546 | 529 |
547 if(n == N) | 530 if(n == N) |
548 return; | 531 return; |
549 | 532 |
550 if(init == &n->ninit) { | 533 if(init == &n->ninit) { |
551 // not okay to use n->ninit when walking n, | 534 // not okay to use n->ninit when walking n, |
552 // because we might replace n with some other node | 535 // because we might replace n with some other node |
553 // and would lose the init list. | 536 // and would lose the init list. |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 walkexprlist(n->list, init); | 647 walkexprlist(n->list, init); |
665 ll = ascompatte(n->op, getinarg(t), n->list, 0, init); | 648 ll = ascompatte(n->op, getinarg(t), n->list, 0, init); |
666 n->list = reorder1(ll); | 649 n->list = reorder1(ll); |
667 if(isselect(n)) { | 650 if(isselect(n)) { |
668 // special prob with selectsend and selectrecv: | 651 // special prob with selectsend and selectrecv: |
669 // if chan is nil, they don't know big the channel | 652 // if chan is nil, they don't know big the channel |
670 // element is and therefore don't know how to find | 653 // element is and therefore don't know how to find |
671 // the output bool, so we clear it before the call. | 654 // the output bool, so we clear it before the call. |
672 Node *b; | 655 Node *b; |
673 b = nodbool(0); | 656 b = nodbool(0); |
| 657 typecheck(&b, Erv); |
674 lr = ascompatte(n->op, getoutarg(t), list1(b), 0, init); | 658 lr = ascompatte(n->op, getoutarg(t), list1(b), 0, init); |
675 n->list = concat(n->list, lr); | 659 n->list = concat(n->list, lr); |
676 } | 660 } |
677 goto ret; | 661 goto ret; |
678 | 662 |
679 case OCALLMETH: | 663 case OCALLMETH: |
680 t = n->left->type; | 664 t = n->left->type; |
681 if(n->list && n->list->n->op == OAS) | 665 if(n->list && n->list->n->op == OAS) |
682 goto ret; | 666 goto ret; |
683 walkexpr(&n->left, init); | 667 walkexpr(&n->left, init); |
(...skipping 19 matching lines...) Expand all Loading... |
703 if(l == N || r == N) | 687 if(l == N || r == N) |
704 goto ret; | 688 goto ret; |
705 r = ascompatee1(n->op, l, r, init); | 689 r = ascompatee1(n->op, l, r, init); |
706 if(r != N) { | 690 if(r != N) { |
707 r->dodata = n->dodata; | 691 r->dodata = n->dodata; |
708 n = r; | 692 n = r; |
709 } | 693 } |
710 goto ret; | 694 goto ret; |
711 | 695 |
712 case OAS2: | 696 case OAS2: |
713 as2: | |
714 *init = concat(*init, n->ninit); | 697 *init = concat(*init, n->ninit); |
715 n->ninit = nil; | 698 n->ninit = nil; |
716 walkexprlistsafe(n->list, init); | 699 walkexprlistsafe(n->list, init); |
717 walkexprlistsafe(n->rlist, init); | 700 walkexprlistsafe(n->rlist, init); |
718 ll = ascompatee(OAS, n->list, n->rlist, init); | 701 ll = ascompatee(OAS, n->list, n->rlist, init); |
719 ll = reorder3(ll); | 702 ll = reorder3(ll); |
720 n = liststmt(ll); | 703 n = liststmt(ll); |
721 goto ret; | 704 goto ret; |
722 | 705 |
723 case OAS2FUNC: | 706 case OAS2FUNC: |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 t = l->left->type; | 778 t = l->left->type; |
796 n = mkcall1(mapfn("mapassign2", t), T, init, l->left, l->right,
n->rlist->n, n->rlist->next->n); | 779 n = mkcall1(mapfn("mapassign2", t), T, init, l->left, l->right,
n->rlist->n, n->rlist->next->n); |
797 goto ret; | 780 goto ret; |
798 | 781 |
799 case OAS2DOTTYPE: | 782 case OAS2DOTTYPE: |
800 // a,b = i.(T) | 783 // a,b = i.(T) |
801 *init = concat(*init, n->ninit); | 784 *init = concat(*init, n->ninit); |
802 n->ninit = nil; | 785 n->ninit = nil; |
803 r = n->rlist->n; | 786 r = n->rlist->n; |
804 walkexprlistsafe(n->list, init); | 787 walkexprlistsafe(n->list, init); |
805 » » walkdottype(r, init); | 788 » » r->op = ODOTTYPE2; |
806 » » et = ifaceas1(r->type, r->left->type, 1); | 789 » » walkexpr(&r, init); |
807 » » switch(et) { | |
808 » » case I2Isame: | |
809 » » case E2Esame: | |
810 » » case I2E: | |
811 » » » n->rlist = list(list1(r->left), nodbool(1)); | |
812 » » » typechecklist(n->rlist, Erv); | |
813 » » » goto as2; | |
814 » » case I2T: | |
815 » » » et = I2T2; | |
816 » » » break; | |
817 » » case I2Ix: | |
818 » » » et = I2I2; | |
819 » » » break; | |
820 » » case E2I: | |
821 » » » et = E2I2; | |
822 » » » break; | |
823 » » case E2T: | |
824 » » » et = E2T2; | |
825 » » » break; | |
826 » » default: | |
827 » » » et = Inone; | |
828 » » » break; | |
829 » » } | |
830 » » if(et == Inone) | |
831 » » » break; | |
832 » » r = ifacecvt(r->type, r->left, et, init); | |
833 ll = ascompatet(n->op, n->list, &r->type, 0, init); | 790 ll = ascompatet(n->op, n->list, &r->type, 0, init); |
834 n = liststmt(concat(list1(r), ll)); | 791 n = liststmt(concat(list1(r), ll)); |
835 goto ret; | 792 goto ret; |
836 | 793 |
837 case ODOTTYPE: | 794 case ODOTTYPE: |
838 » » walkdottype(n, init); | 795 » case ODOTTYPE2:»»······· |
839 » » walkconv(&n, init); | 796 » » // Build name of function: assertI2E2 etc. |
| 797 » » strcpy(buf, "assert"); |
| 798 » » p = buf+strlen(buf); |
| 799 » » if(isnilinter(n->left->type)) |
| 800 » » » *p++ = 'E'; |
| 801 » » else |
| 802 » » » *p++ = 'I'; |
| 803 » » *p++ = '2'; |
| 804 » » if(isnilinter(n->type)) |
| 805 » » » *p++ = 'E'; |
| 806 » » else if(isinter(n->type)) |
| 807 » » » *p++ = 'I'; |
| 808 » » else |
| 809 » » » *p++ = 'T'; |
| 810 » » if(n->op == ODOTTYPE2) |
| 811 » » » *p++ = '2'; |
| 812 » » *p = '\0'; |
| 813 »······· |
| 814 » » fn = syslook(buf, 1); |
| 815 » » ll = list1(typename(n->type)); |
| 816 » » ll = list(ll, n->left); |
| 817 » » argtype(fn, n->left->type); |
| 818 » » argtype(fn, n->type); |
| 819 » » n = nod(OCALL, fn, N); |
| 820 » » n->list = ll; |
| 821 » » typecheck(&n, Erv | Efnstruct); |
| 822 » » walkexpr(&n, init); |
| 823 » » goto ret; |
| 824 |
| 825 » case OCONVIFACE: |
| 826 » » // Build name of function: convI2E etc. |
| 827 » » // Not all names are possible |
| 828 » » // (e.g., we'll never generate convE2E or convE2I). |
| 829 » » walkexpr(&n->left, init); |
| 830 » » strcpy(buf, "conv"); |
| 831 » » p = buf+strlen(buf); |
| 832 » » if(isnilinter(n->left->type)) |
| 833 » » » *p++ = 'E'; |
| 834 » » else if(isinter(n->left->type)) |
| 835 » » » *p++ = 'I'; |
| 836 » » else |
| 837 » » » *p++ = 'T'; |
| 838 » » *p++ = '2'; |
| 839 » » if(isnilinter(n->type)) |
| 840 » » » *p++ = 'E'; |
| 841 » » else |
| 842 » » » *p++ = 'I'; |
| 843 » » *p = '\0'; |
| 844 » »······· |
| 845 » » fn = syslook(buf, 1); |
| 846 » » ll = nil; |
| 847 » » if(!isinter(n->left->type)) |
| 848 » » » ll = list(ll, typename(n->left->type)); |
| 849 » » if(!isnilinter(n->type)) |
| 850 » » » ll = list(ll, typename(n->type)); |
| 851 » » ll = list(ll, n->left); |
| 852 » » argtype(fn, n->left->type); |
| 853 » » argtype(fn, n->type); |
| 854 » » dowidth(fn->type); |
| 855 » » n = nod(OCALL, fn, N); |
| 856 » » n->list = ll; |
| 857 » » typecheck(&n, Erv); |
| 858 » » walkexpr(&n, init); |
840 goto ret; | 859 goto ret; |
841 | 860 |
842 case OCONV: | 861 case OCONV: |
843 case OCONVNOP: | 862 case OCONVNOP: |
844 if(thechar == '5') { | 863 if(thechar == '5') { |
845 if(isfloat[n->left->type->etype] && | 864 if(isfloat[n->left->type->etype] && |
846 (n->type->etype == TINT64 || n->type->etype == TUINT6
4)) { | 865 (n->type->etype == TINT64 || n->type->etype == TUINT6
4)) { |
847 n = mkcall("float64toint64", n->type, init, conv
(n->left, types[TFLOAT64])); | 866 n = mkcall("float64toint64", n->type, init, conv
(n->left, types[TFLOAT64])); |
848 goto ret; | 867 goto ret; |
849 } | 868 } |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1169 argtype(fn, t->type); // any-1 | 1188 argtype(fn, t->type); // any-1 |
1170 n = mkcall1(fn, n->type, init, | 1189 n = mkcall1(fn, n->type, init, |
1171 typename(n->type), | 1190 typename(n->type), |
1172 conv(l, types[TINT64]), | 1191 conv(l, types[TINT64]), |
1173 conv(r, types[TINT64])); | 1192 conv(r, types[TINT64])); |
1174 goto ret; | 1193 goto ret; |
1175 | 1194 |
1176 case ORUNESTR: | 1195 case ORUNESTR: |
1177 // sys_intstring(v) | 1196 // sys_intstring(v) |
1178 n = mkcall("intstring", n->type, init, | 1197 n = mkcall("intstring", n->type, init, |
1179 » » » conv(n->left, types[TINT64]));» // TODO(rsc): int64?! | 1198 » » » conv(n->left, types[TINT64])); |
1180 goto ret; | 1199 goto ret; |
1181 | 1200 |
1182 case OARRAYBYTESTR: | 1201 case OARRAYBYTESTR: |
1183 // slicebytetostring([]byte) string; | 1202 // slicebytetostring([]byte) string; |
1184 n = mkcall("slicebytetostring", n->type, init, n->left); | 1203 n = mkcall("slicebytetostring", n->type, init, n->left); |
1185 goto ret; | 1204 goto ret; |
1186 | 1205 |
1187 case OARRAYRUNESTR: | 1206 case OARRAYRUNESTR: |
1188 // sliceinttostring([]int) string; | 1207 // sliceinttostring([]int) string; |
1189 n = mkcall("sliceinttostring", n->type, init, n->left); | 1208 n = mkcall("sliceinttostring", n->type, init, n->left); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1227 goto ret; | 1246 goto ret; |
1228 | 1247 |
1229 case OSEND: | 1248 case OSEND: |
1230 n = mkcall1(chanfn("chansend1", 2, n->left->type), T, init, n->l
eft, n->right); | 1249 n = mkcall1(chanfn("chansend1", 2, n->left->type), T, init, n->l
eft, n->right); |
1231 goto ret; | 1250 goto ret; |
1232 | 1251 |
1233 case OSENDNB: | 1252 case OSENDNB: |
1234 n = mkcall1(chanfn("chansend2", 2, n->left->type), n->type, init
, n->left, n->right); | 1253 n = mkcall1(chanfn("chansend2", 2, n->left->type), n->type, init
, n->left, n->right); |
1235 goto ret; | 1254 goto ret; |
1236 | 1255 |
1237 case OCONVIFACE: | |
1238 walkexpr(&n->left, init); | |
1239 n = ifacecvt(n->type, n->left, n->etype, init); | |
1240 goto ret; | |
1241 | |
1242 case OCLOSURE: | 1256 case OCLOSURE: |
1243 n = walkclosure(n, init); | 1257 n = walkclosure(n, init); |
1244 goto ret; | 1258 goto ret; |
1245 } | 1259 } |
1246 fatal("missing switch %O", n->op); | 1260 fatal("missing switch %O", n->op); |
1247 | 1261 |
1248 ret: | 1262 ret: |
1249 if(debug['w'] && n != N) | 1263 if(debug['w'] && n != N) |
1250 dump("walk", n); | 1264 dump("walk", n); |
1251 | 1265 |
(...skipping 12 matching lines...) Expand all Loading... |
1264 nas = nod(OAS, nvar, callnew(t->type)); | 1278 nas = nod(OAS, nvar, callnew(t->type)); |
1265 typecheck(&nas, Etop); | 1279 typecheck(&nas, Etop); |
1266 walkexpr(&nas, init); | 1280 walkexpr(&nas, init); |
1267 *init = list(*init, nas); | 1281 *init = list(*init, nas); |
1268 | 1282 |
1269 *nstar = nod(OIND, nvar, N); | 1283 *nstar = nod(OIND, nvar, N); |
1270 typecheck(nstar, Erv); | 1284 typecheck(nstar, Erv); |
1271 return nvar; | 1285 return nvar; |
1272 } | 1286 } |
1273 | 1287 |
1274 // TODO(rsc): cut | |
1275 void | |
1276 walkdottype(Node *n, NodeList **init) | |
1277 { | |
1278 walkexpr(&n->left, init); | |
1279 if(n->left == N) | |
1280 return; | |
1281 if(n->right != N) { | |
1282 walkexpr(&n->right, init); | |
1283 n->type = n->right->type; | |
1284 n->right = N; | |
1285 } | |
1286 } | |
1287 | |
1288 // TODO(rsc): cut | |
1289 void | |
1290 walkconv(Node **np, NodeList **init) | |
1291 { | |
1292 int et; | |
1293 char *what; | |
1294 Type *t; | |
1295 Node *l; | |
1296 Node *n; | |
1297 | |
1298 n = *np; | |
1299 t = n->type; | |
1300 if(t == T) | |
1301 return; | |
1302 walkexpr(&n->left, init); | |
1303 l = n->left; | |
1304 if(l == N) | |
1305 return; | |
1306 if(l->type == T) | |
1307 return; | |
1308 | |
1309 // if using .(T), interface assertion. | |
1310 if(n->op == ODOTTYPE) { | |
1311 et = ifaceas1(t, l->type, 1); | |
1312 if(et == I2Isame || et == E2Esame) { | |
1313 n->op = OCONVNOP; | |
1314 return; | |
1315 } | |
1316 if(et != Inone) { | |
1317 n = ifacecvt(t, l, et, init); | |
1318 *np = n; | |
1319 return; | |
1320 } | |
1321 goto bad; | |
1322 } | |
1323 | |
1324 fatal("walkconv"); | |
1325 | |
1326 bad: | |
1327 if(n->diag) | |
1328 return; | |
1329 n->diag = 1; | |
1330 if(n->op == ODOTTYPE) | |
1331 what = "type assertion"; | |
1332 else | |
1333 what = "conversion"; | |
1334 if(l->type != T) | |
1335 yyerror("invalid %s: %T to %T", what, l->type, t); | |
1336 } | |
1337 | |
1338 Node* | 1288 Node* |
1339 ascompatee1(int op, Node *l, Node *r, NodeList **init) | 1289 ascompatee1(int op, Node *l, Node *r, NodeList **init) |
1340 { | 1290 { |
1341 return convas(nod(OAS, l, r), init); | 1291 return convas(nod(OAS, l, r), init); |
1342 } | 1292 } |
1343 | 1293 |
1344 NodeList* | 1294 NodeList* |
1345 ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init) | 1295 ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init) |
1346 { | 1296 { |
1347 NodeList *ll, *lr, *nn; | 1297 NodeList *ll, *lr, *nn; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1411 r = structnext(&saver); | 1361 r = structnext(&saver); |
1412 continue; | 1362 continue; |
1413 } | 1363 } |
1414 | 1364 |
1415 // any lv that causes a fn call must be | 1365 // any lv that causes a fn call must be |
1416 // deferred until all the return arguments | 1366 // deferred until all the return arguments |
1417 // have been pulled from the output arguments | 1367 // have been pulled from the output arguments |
1418 if(fncall(l, r->type)) { | 1368 if(fncall(l, r->type)) { |
1419 tmp = nod(OXXX, N, N); | 1369 tmp = nod(OXXX, N, N); |
1420 tempname(tmp, r->type); | 1370 tempname(tmp, r->type); |
| 1371 typecheck(&tmp, Erv); |
1421 a = nod(OAS, l, tmp); | 1372 a = nod(OAS, l, tmp); |
1422 a = convas(a, init); | 1373 a = convas(a, init); |
1423 mm = list(mm, a); | 1374 mm = list(mm, a); |
1424 l = tmp; | 1375 l = tmp; |
1425 } | 1376 } |
1426 | 1377 |
1427 a = nod(OAS, l, nodarg(r, fp)); | 1378 a = nod(OAS, l, nodarg(r, fp)); |
1428 a = convas(a, init); | 1379 a = convas(a, init); |
1429 ullmancalc(a); | 1380 ullmancalc(a); |
1430 if(a->ullman >= UINF) | 1381 if(a->ullman >= UINF) |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1510 } | 1461 } |
1511 | 1462 |
1512 // make a named type for the struct | 1463 // make a named type for the struct |
1513 st = sigtype(st); | 1464 st = sigtype(st); |
1514 dowidth(st); | 1465 dowidth(st); |
1515 | 1466 |
1516 // now we have the size, make the struct | 1467 // now we have the size, make the struct |
1517 var = nod(OXXX, N, N); | 1468 var = nod(OXXX, N, N); |
1518 tempname(var, st); | 1469 tempname(var, st); |
1519 var->sym = lookup(".ddd"); | 1470 var->sym = lookup(".ddd"); |
| 1471 typecheck(&var, Erv); |
1520 | 1472 |
1521 // assign the fields to the struct. | 1473 // assign the fields to the struct. |
1522 // use the init list so that reorder1 doesn't reorder | 1474 // use the init list so that reorder1 doesn't reorder |
1523 // these assignments after the interface conversion | 1475 // these assignments after the interface conversion |
1524 // below. | 1476 // below. |
1525 t = st->type; | 1477 t = st->type; |
1526 for(lr=n; lr; lr=lr->next) { | 1478 for(lr=n; lr; lr=lr->next) { |
1527 r = lr->n; | 1479 r = lr->n; |
1528 r->left = nod(OXXX, N, N); | 1480 r->left = nod(OXXX, N, N); |
1529 *r->left = *var; | 1481 *r->left = *var; |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1920 | 1872 |
1921 dowidth(t->type); | 1873 dowidth(t->type); |
1922 | 1874 |
1923 return t; | 1875 return t; |
1924 | 1876 |
1925 bad: | 1877 bad: |
1926 yyerror("not a channel: %lT", t); | 1878 yyerror("not a channel: %lT", t); |
1927 return T; | 1879 return T; |
1928 } | 1880 } |
1929 | 1881 |
1930 /* | |
1931 * assigning src to dst involving interfaces? | |
1932 * return op to use. | |
1933 */ | |
1934 int | |
1935 ifaceas1(Type *dst, Type *src, int explicit) | |
1936 { | |
1937 if(src == T || dst == T) | |
1938 return Inone; | |
1939 | |
1940 if(explicit && !isinter(src)) | |
1941 yyerror("cannot use .(T) on non-interface type %T", src); | |
1942 | |
1943 if(isinter(dst)) { | |
1944 if(isinter(src)) { | |
1945 if(isnilinter(dst)) { | |
1946 if(isnilinter(src)) | |
1947 return E2Esame; | |
1948 return I2E; | |
1949 } | |
1950 if(eqtype(dst, src)) | |
1951 return I2Isame; | |
1952 ifacecheck(dst, src, lineno, explicit); | |
1953 if(isnilinter(src)) | |
1954 return E2I; | |
1955 if(explicit) | |
1956 return I2Ix; | |
1957 return I2I; | |
1958 } | |
1959 if(isnilinter(dst)) | |
1960 return T2E; | |
1961 ifacecheck(dst, src, lineno, explicit); | |
1962 return T2I; | |
1963 } | |
1964 if(isinter(src)) { | |
1965 ifacecheck(dst, src, lineno, explicit); | |
1966 if(isnilinter(src)) | |
1967 return E2T; | |
1968 return I2T; | |
1969 } | |
1970 return Inone; | |
1971 } | |
1972 | |
1973 /* | |
1974 * treat convert T to T as noop | |
1975 */ | |
1976 int | |
1977 ifaceas(Type *dst, Type *src, int explicit) | |
1978 { | |
1979 int et; | |
1980 | |
1981 et = ifaceas1(dst, src, explicit); | |
1982 if(et == I2Isame || et == E2Esame) | |
1983 et = Inone; | |
1984 return et; | |
1985 } | |
1986 | |
1987 static char* | |
1988 ifacename[] = | |
1989 { | |
1990 [I2T] = "ifaceI2T", | |
1991 [I2T2] = "ifaceI2T2", | |
1992 [I2I] = "ifaceI2I", | |
1993 [I2Ix] = "ifaceI2Ix", | |
1994 [I2I2] = "ifaceI2I2", | |
1995 [I2Isame] = "ifaceI2Isame", | |
1996 [E2T] = "ifaceE2T", | |
1997 [E2T2] = "ifaceE2T2", | |
1998 [E2I] = "ifaceE2I", | |
1999 [E2I2] = "ifaceE2I2", | |
2000 [I2E] = "ifaceI2E", | |
2001 [I2E2] = "ifaceI2E2", | |
2002 [T2I] = "ifaceT2I", | |
2003 [T2E] = "ifaceT2E", | |
2004 [E2Esame] = "ifaceE2Esame", | |
2005 }; | |
2006 | |
2007 Node* | |
2008 ifacecvt(Type *tl, Node *n, int et, NodeList **init) | |
2009 { | |
2010 Type *tr; | |
2011 Node *r, *on; | |
2012 NodeList *args; | |
2013 | |
2014 tr = n->type; | |
2015 | |
2016 switch(et) { | |
2017 default: | |
2018 fatal("ifacecvt: unknown op %d\n", et); | |
2019 | |
2020 case I2Isame: | |
2021 case E2Esame: | |
2022 return n; | |
2023 | |
2024 case T2I: | |
2025 // ifaceT2I(sigi *byte, sigt *byte, elem any) (ret any); | |
2026 args = list1(typename(tl)); // sigi | |
2027 args = list(args, typename(tr)); // sigt | |
2028 args = list(args, n); // elem | |
2029 | |
2030 on = syslook("ifaceT2I", 1); | |
2031 argtype(on, tr); | |
2032 argtype(on, tl); | |
2033 dowidth(on->type); | |
2034 break; | |
2035 | |
2036 case I2T: | |
2037 case I2T2: | |
2038 case I2I: | |
2039 case I2Ix: | |
2040 case I2I2: | |
2041 case E2T: | |
2042 case E2T2: | |
2043 case E2I: | |
2044 case E2I2: | |
2045 // iface[IT]2[IT][2](sigt *byte, iface any) (ret any[, ok bool])
; | |
2046 args = list1(typename(tl)); // sigi or sigt | |
2047 args = list(args, n); // iface | |
2048 | |
2049 on = syslook(ifacename[et], 1); | |
2050 argtype(on, tr); | |
2051 argtype(on, tl); | |
2052 break; | |
2053 | |
2054 case I2E: | |
2055 // TODO(rsc): Should do this in back end, without a call. | |
2056 // ifaceI2E(elem any) (ret any); | |
2057 args = list1(n); // elem | |
2058 | |
2059 on = syslook("ifaceI2E", 1); | |
2060 argtype(on, tr); | |
2061 argtype(on, tl); | |
2062 break; | |
2063 | |
2064 case T2E: | |
2065 // TODO(rsc): Should do this in back end for pointer case, witho
ut a call. | |
2066 // ifaceT2E(sigt *byte, elem any) (ret any); | |
2067 args = list1(typename(tr)); // sigt | |
2068 args = list(args, n); // elem | |
2069 | |
2070 on = syslook("ifaceT2E", 1); | |
2071 argtype(on, tr); | |
2072 argtype(on, tl); | |
2073 break; | |
2074 } | |
2075 | |
2076 dowidth(on->type); | |
2077 r = nod(OCALL, on, N); | |
2078 r->list = args; | |
2079 typecheck(&r, Erv | Efnstruct); | |
2080 walkexpr(&r, init); | |
2081 return r; | |
2082 } | |
2083 | |
2084 Node* | 1882 Node* |
2085 convas(Node *n, NodeList **init) | 1883 convas(Node *n, NodeList **init) |
2086 { | 1884 { |
2087 Node *l, *r; | 1885 Node *l, *r; |
2088 Type *lt, *rt; | 1886 Type *lt, *rt; |
2089 int et; | |
2090 | 1887 |
2091 if(n->op != OAS) | 1888 if(n->op != OAS) |
2092 fatal("convas: not OAS %O", n->op); | 1889 fatal("convas: not OAS %O", n->op); |
2093 n->typecheck = 1; | 1890 n->typecheck = 1; |
2094 | 1891 |
2095 lt = T; | 1892 lt = T; |
2096 rt = T; | 1893 rt = T; |
2097 | 1894 |
2098 l = n->left; | 1895 l = n->left; |
2099 r = n->right; | 1896 r = n->right; |
2100 if(l == N || r == N) | 1897 if(l == N || r == N) |
2101 goto out; | 1898 goto out; |
2102 | 1899 |
2103 lt = l->type; | 1900 lt = l->type; |
2104 rt = r->type; | 1901 rt = r->type; |
2105 if(lt == T || rt == T) | 1902 if(lt == T || rt == T) |
2106 goto out; | 1903 goto out; |
2107 | 1904 |
2108 if(isblank(n->left)) { | 1905 if(isblank(n->left)) { |
2109 defaultlit(&n->right, T); | 1906 defaultlit(&n->right, T); |
2110 goto out; | 1907 goto out; |
2111 } | 1908 } |
2112 | 1909 |
2113 if(n->left->op == OINDEXMAP) { | 1910 if(n->left->op == OINDEXMAP) { |
2114 n = mkcall1(mapfn("mapassign1", n->left->left->type), T, init, | 1911 n = mkcall1(mapfn("mapassign1", n->left->left->type), T, init, |
2115 n->left->left, n->left->right, n->right); | 1912 n->left->left, n->left->right, n->right); |
2116 goto out; | 1913 goto out; |
2117 } | 1914 } |
2118 | 1915 » |
2119 if(eqtype(lt, rt)) | 1916 if(eqtype(lt, rt)) |
2120 goto out; | 1917 goto out; |
2121 | 1918 »······· |
2122 » et = ifaceas(lt, rt, 0); | 1919 » n->right = assignconv(r, lt, "assignment"); |
2123 » if(et != Inone) { | 1920 » walkexpr(&n->right, init); |
2124 » » n->right = ifacecvt(lt, r, et, init); | |
2125 » » goto out; | |
2126 » } | |
2127 | 1921 |
2128 out: | 1922 out: |
2129 ullmancalc(n); | 1923 ullmancalc(n); |
2130 return n; | 1924 return n; |
2131 } | 1925 } |
2132 | 1926 |
2133 /* | 1927 /* |
2134 * from ascompat[te] | 1928 * from ascompat[te] |
2135 * evaluating actual function arguments. | 1929 * evaluating actual function arguments. |
2136 * f(a,b) | 1930 * f(a,b) |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2285 n1->left = q->right; | 2079 n1->left = q->right; |
2286 r = list(r, q); | 2080 r = list(r, q); |
2287 break; | 2081 break; |
2288 } | 2082 } |
2289 } | 2083 } |
2290 } | 2084 } |
2291 } | 2085 } |
2292 return concat(all, r); | 2086 return concat(all, r); |
2293 } | 2087 } |
2294 | 2088 |
2295 NodeList* | |
2296 reorder4(NodeList *ll) | |
2297 { | |
2298 /* | |
2299 * from ascompat[te] | |
2300 * return c,d | |
2301 * return expression assigned to output | |
2302 * parameters. there may be no problems. | |
2303 * | |
2304 * TODO(rsc): i don't believe that. | |
2305 * func f() (a, b int) { | |
2306 * a, b = 1, 2; | |
2307 * return b, a; | |
2308 * } | |
2309 */ | |
2310 return ll; | |
2311 } | |
2312 | |
2313 /* | 2089 /* |
2314 * walk through argin parameters. | 2090 * walk through argin parameters. |
2315 * generate and return code to allocate | 2091 * generate and return code to allocate |
2316 * copies of escaped parameters to the heap. | 2092 * copies of escaped parameters to the heap. |
2317 */ | 2093 */ |
2318 NodeList* | 2094 NodeList* |
2319 paramstoheap(Type **argin, int out) | 2095 paramstoheap(Type **argin, int out) |
2320 { | 2096 { |
2321 Type *t; | 2097 Type *t; |
2322 Iter savet; | 2098 Iter savet; |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2465 | 2241 |
2466 if(t->etype != TMAP) | 2242 if(t->etype != TMAP) |
2467 fatal("mapfn %T", t); | 2243 fatal("mapfn %T", t); |
2468 fn = syslook(name, 1); | 2244 fn = syslook(name, 1); |
2469 argtype(fn, t->down); | 2245 argtype(fn, t->down); |
2470 argtype(fn, t->type); | 2246 argtype(fn, t->type); |
2471 argtype(fn, t->down); | 2247 argtype(fn, t->down); |
2472 argtype(fn, t->type); | 2248 argtype(fn, t->type); |
2473 return fn; | 2249 return fn; |
2474 } | 2250 } |
OLD | NEW |