1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 #define EXTERN
6 #include "go.h"
7 #include "y.tab.h"
8 #include <ar.h>
9
10 #undef getc
11 #undef ungetc
12 #define getc ccgetc
13 #define ungetc ccungetc
14
15 extern int yychar;
16 int windows;
17 int yyprev;
18 int yylast;
19
20 static void lexinit(void);
21 static void lexfini(void);
22 static void yytinit(void);
23 static int getc(void);
24 static void ungetc(int);
25 static int32 getr(void);
26 static int escchar(int, int*, vlong*);
27 static void addidir(char*);
28 static int getlinepragma(void);
29 static char *goos, *goarch, *goroot;
30
31 // Our own isdigit, isspace, isalpha, isalnum that take care
32 // of EOF and other out of range arguments.
33 static int
34 yy_isdigit(int c)
35 {
36 return c >= 0 && c <= 0xFF && isdigit(c);
37 }
38
39 static int
40 yy_isspace(int c)
41 {
42 return c >= 0 && c <= 0xFF && isspace(c);
43 }
44
45 static int
46 yy_isalpha(int c)
47 {
48 return c >= 0 && c <= 0xFF && isalpha(c);
49 }
50
51 static int
52 yy_isalnum(int c)
53 {
54 return c >= 0 && c <= 0xFF && isalnum(c);
55 }
56
57 // Disallow use of isdigit etc.
58 #undef isdigit
59 #undef isspace
60 #undef isalpha
61 #undef isalnum
62 #define isdigit use_yy_isdigit_instead_of_isdigit
63 #define isspace use_yy_isspace_instead_of_isspace
64 #define isalpha use_yy_isalpha_instead_of_isalpha
65 #define isalnum use_yy_isalnum_instead_of_isalnum
66
67 #define DBG if(!debug['x']);else print
68 enum
69 {
70 EOF = -1,
71 };
72
73 void
74 usage(void)
75 {
76 print("gc: usage: %cg [flags] file.go...\n", thechar);
77 print("flags:\n");
78 // -A is allow use of "any" type, for bootstrapping
79 print(" -I DIR search for packages in DIR\n");
80 print(" -d print declarations\n");
81 print(" -e no limit on number of errors printed\n");
82 print(" -f print stack frame structure\n");
83 print(" -h panic on an error\n");
84 print(" -o file specify output file\n");
85 print(" -S print the assembly language\n");
86 print(" -V print the compiler version\n");
87 print(" -u disable package unsafe\n");
88 print(" -w print the parse tree after typing\n");
89 print(" -x print lex tokens\n");
90 exit(0);
91 }
92
93 void
94 fault(int s)
95 {
96 // If we've already complained about things
97 // in the program, don't bother complaining
98 // about the seg fault too; let the user clean up
99 // the code and try again.
100 if(nsavederrors + nerrors > 0)
101 errorexit();
102 fatal("fault");
103 }
104
105 int
106 main(int argc, char *argv[])
107 {
108 int i, c;
109 NodeList *l;
110 char *p;
111
112 signal(SIGBUS, fault);
113 signal(SIGSEGV, fault);
114
115 localpkg = mkpkg(strlit(""));
116 localpkg->prefix = "\"\"";
117
118 builtinpkg = mkpkg(strlit("go.builtin"));
119
120 gostringpkg = mkpkg(strlit("go.string"));
121 gostringpkg->name = "go.string";
122 gostringpkg->prefix = "go.string"; // not go%2estring
123
124 runtimepkg = mkpkg(strlit("runtime"));
125 runtimepkg->name = "runtime";
126
127 typepkg = mkpkg(strlit("type"));
128 typepkg->name = "type";
129
130 unsafepkg = mkpkg(strlit("unsafe"));
131 unsafepkg->name = "unsafe";
132
133 goroot = getgoroot();
134 goos = getgoos();
135 goarch = thestring;
136
137 outfile = nil;
138 ARGBEGIN {
139 default:
140 c = ARGC();
141 if(c >= 0 && c < sizeof(debug))
142 debug[c]++;
143 break;
144
145 case 'o':
146 outfile = EARGF(usage());
147 break;
148
149 case 'I':
150 addidir(EARGF(usage()));
151 break;
152
153 case 'u':
154 safemode = 1;
155 break;
156
157 case 'V':
158 print("%cg version %s\n", thechar, getgoversion());
159 exit(0);
160 } ARGEND
161
162 if(argc < 1)
163 usage();
164
165 // special flag to detect compilation of package runtime
166 compiling_runtime = debug['+'];
167
168 pathname = mal(1000);
169 if(getwd(pathname, 999) == 0)
170 strcpy(pathname, "/???");
171
172 if(yy_isalpha(pathname[0]) && pathname[1] == ':') {
173 // On Windows.
174 windows = 1;
175
176 // Canonicalize path by converting \ to / (Windows accepts both).
177 for(p=pathname; *p; p++)
178 if(*p == '\\')
179 *p = '/';
180 }
181
182 fmtinstall('O', Oconv); // node opcodes
183 fmtinstall('E', Econv); // etype opcodes
184 fmtinstall('J', Jconv); // all the node flags
185 fmtinstall('S', Sconv); // sym pointer
186 fmtinstall('T', Tconv); // type pointer
187 fmtinstall('N', Nconv); // node pointer
188 fmtinstall('Z', Zconv); // escaped string
189 fmtinstall('L', Lconv); // line number
190 fmtinstall('B', Bconv); // big numbers
191 fmtinstall('F', Fconv); // big float numbers
192
193 betypeinit();
194 if(widthptr == 0)
195 fatal("betypeinit failed");
196
197 lexinit();
198 typeinit();
199 yytinit();
200
201 blockgen = 1;
202 dclcontext = PEXTERN;
203 nerrors = 0;
204 lexlineno = 1;
205
206 for(i=0; i<argc; i++) {
207 infile = argv[i];
208 linehist(infile, 0, 0);
209
210 curio.infile = infile;
211 curio.bin = Bopen(infile, OREAD);
212 if(curio.bin == nil) {
213 print("open %s: %r\n", infile);
214 errorexit();
215 }
216 curio.peekc = 0;
217 curio.peekc1 = 0;
218 curio.nlsemi = 0;
219
220 block = 1;
221 iota = -1000000;
222
223 yyparse();
224 if(nsyntaxerrors != 0)
225 errorexit();
226
227 linehist(nil, 0, 0);
228 if(curio.bin != nil)
229 Bterm(curio.bin);
230 }
231 testdclstack();
232 mkpackage(localpkg->name); // final import not used checks
233 lexfini();
234
235 typecheckok = 1;
236 if(debug['f'])
237 frame(1);
238
239 // Process top-level declarations in four phases.
240 // Phase 1: const, type, and names and types of funcs.
241 // This will gather all the information about types
242 // and methods but doesn't depend on any of it.
243 // Phase 2: Variable assignments.
244 // To check interface assignments, depends on phase 1.
245 // Phase 3: Type check function bodies.
246 // Phase 4: Compile function bodies.
247 defercheckwidth();
248 for(l=xtop; l; l=l->next)
249 if(l->n->op != ODCL && l->n->op != OAS)
250 typecheck(&l->n, Etop);
251 for(l=xtop; l; l=l->next)
252 if(l->n->op == ODCL || l->n->op == OAS)
253 typecheck(&l->n, Etop);
254 resumetypecopy();
255 resumecheckwidth();
256
257 for(l=xtop; l; l=l->next) {
258 if(l->n->op == ODCLFUNC || l->n->op == OCLOSURE) {
259 curfn = l->n;
260 saveerrors();
261 typechecklist(l->n->nbody, Etop);
262 if(nerrors != 0)
263 l->n->nbody = nil; // type errors; do not compile
264 }
265 }
266
267 curfn = nil;
268
269 if(nsavederrors+nerrors)
270 errorexit();
271
272 for(l=xtop; l; l=l->next)
273 if(l->n->op == ODCLFUNC)
274 funccompile(l->n, 0);
275
276 if(nsavederrors+nerrors == 0)
277 fninit(xtop);
278
279 while(closures) {
280 l = closures;
281 closures = nil;
282 for(; l; l=l->next) {
283 funccompile(l->n, 1);
284 }
285 }
286
287 for(l=externdcl; l; l=l->next)
288 if(l->n->op == ONAME)
289 typecheck(&l->n, Erv);
290
291 if(nerrors+nsavederrors)
292 errorexit();
293
294 dumpobj();
295
296 if(nerrors+nsavederrors)
297 errorexit();
298
299 flusherrors();
300 exit(0);
301 return 0;
302 }
303
304 void
305 saveerrors(void)
306 {
307 nsavederrors += nerrors;
308 nerrors = 0;
309 }
310
311 static int
312 arsize(Biobuf *b, char *name)
313 {
314 struct ar_hdr *a;
315
316 if((a = Brdline(b, '\n')) == nil)
317 return -1;
318 if(Blinelen(b) != sizeof(struct ar_hdr))
319 return -1;
320 if(strncmp(a->name, name, strlen(name)) != 0)
321 return -1;
322 return atoi(a->size);
323 }
324
325 static int
326 skiptopkgdef(Biobuf *b)
327 {
328 char *p;
329 int sz;
330
331 /* archive header */
332 if((p = Brdline(b, '\n')) == nil)
333 return 0;
334 if(Blinelen(b) != 8)
335 return 0;
336 if(memcmp(p, "!<arch>\n", 8) != 0)
337 return 0;
338 /* symbol table is first; skip it */
339 sz = arsize(b, "__.SYMDEF");
340 if(sz < 0)
341 return 0;
342 Bseek(b, sz, 1);
343 /* package export block is second */
344 sz = arsize(b, "__.PKGDEF");
345 if(sz <= 0)
346 return 0;
347 return 1;
348 }
349
350 static void
351 addidir(char* dir)
352 {
353 Idir** pp;
354
355 if(dir == nil)
356 return;
357
358 for(pp = &idirs; *pp != nil; pp = &(*pp)->link)
359 ;
360 *pp = mal(sizeof(Idir));
361 (*pp)->link = nil;
362 (*pp)->dir = dir;
363 }
364
365 // is this path a local name? begins with ./ or ../ or /
366 static int
367 islocalname(Strlit *name)
368 {
369 if(!windows && name->len >= 1 && name->s[0] == '/')
370 return 1;
371 if(windows && name->len >= 3 &&
372 yy_isalpha(name->s[0]) && name->s[1] == ':' && name->s[2] == '/')
373 return 1;
374 if(name->len >= 2 && strncmp(name->s, "./", 2) == 0)
375 return 1;
376 if(name->len >= 3 && strncmp(name->s, "../", 3) == 0)
377 return 1;
378 return 0;
379 }
380
381 static int
382 findpkg(Strlit *name)
383 {
384 Idir *p;
385 char *q;
386
387 if(islocalname(name)) {
388 if(safemode)
389 return 0;
390 // try .a before .6. important for building libraries:
391 // if there is an array.6 in the array.a library,
392 // want to find all of array.a, not just array.6.
393 snprint(namebuf, sizeof(namebuf), "%Z.a", name);
394 if(access(namebuf, 0) >= 0)
395 return 1;
396 snprint(namebuf, sizeof(namebuf), "%Z.%c", name, thechar);
397 if(access(namebuf, 0) >= 0)
398 return 1;
399 return 0;
400 }
401
402 // local imports should be canonicalized already.
403 // don't want to see "container/../container/vector"
404 // as different from "container/vector".
405 q = mal(name->len+1);
406 memmove(q, name->s, name->len);
407 q[name->len] = '\0';
408 cleanname(q);
409 if(strlen(q) != name->len || memcmp(q, name->s, name->len) != 0) {
410 yyerror("non-canonical import path %Z (should be %s)", name, q);
411 return 0;
412 }
413
414 for(p = idirs; p != nil; p = p->link) {
415 snprint(namebuf, sizeof(namebuf), "%s/%Z.a", p->dir, name);
416 if(access(namebuf, 0) >= 0)
417 return 1;
418 snprint(namebuf, sizeof(namebuf), "%s/%Z.%c", p->dir, name, thechar);
419 if(access(namebuf, 0) >= 0)
420 return 1;
421 }
422 if(goroot != nil) {
423 snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s/%Z.a", goroot, goos, goarch, name);
424 if(access(namebuf, 0) >= 0)
425 return 1;
426 snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s/%Z.%c", goroot, goos, goarch, name, thechar);
427 if(access(namebuf, 0) >= 0)
428 return 1;
429 }
430 return 0;
431 }
432
433 void
434 importfile(Val *f, int line)
435 {
436 Biobuf *imp;
437 char *file, *p, *q;
438 int32 c;
439 int len;
440 Strlit *path;
441 char *cleanbuf;
442
443 // TODO(rsc): don't bother reloading imports more than once?
444
445 if(f->ctype != CTSTR) {
446 yyerror("import statement not a string");
447 return;
448 }
449
450 if(strlen(f->u.sval->s) != f->u.sval->len) {
451 yyerror("import path contains NUL");
452 errorexit();
453 }
454
455 // The package name main is no longer reserved,
456 // but we reserve the import path "main" to identify
457 // the main package, just as we reserve the import
458 // path "math" to identify the standard math package.
459 if(strcmp(f->u.sval->s, "main") == 0) {
460 yyerror("cannot import \"main\"");
461 errorexit();
462 }
463
464 if(strcmp(f->u.sval->s, "unsafe") == 0) {
465 if(safemode) {
466 yyerror("cannot import package unsafe");
467 errorexit();
468 }
469 importpkg = mkpkg(f->u.sval);
470 cannedimports("unsafe.6", unsafeimport);
471 return;
472 }
473
474 path = f->u.sval;
475 if(islocalname(path)) {
476 cleanbuf = mal(strlen(pathname) + strlen(path->s) + 2);
477 strcpy(cleanbuf, pathname);
478 strcat(cleanbuf, "/");
479 strcat(cleanbuf, path->s);
480 cleanname(cleanbuf);
481 path = strlit(cleanbuf);
482 }
483
484 if(!findpkg(path)) {
485 yyerror("can't find import: %Z", f->u.sval);
486 errorexit();
487 }
488 importpkg = mkpkg(path);
489
490 imp = Bopen(namebuf, OREAD);
491 if(imp == nil) {
492 yyerror("can't open import: %Z: %r", f->u.sval);
493 errorexit();
494 }
495 file = strdup(namebuf);
496
497 len = strlen(namebuf);
498 if(len > 2 && namebuf[len-2] == '.' && namebuf[len-1] == 'a') {
499 if(!skiptopkgdef(imp)) {
500 yyerror("import %s: not a package file", file);
501 errorexit();
502 }
503 }
504
505 // check object header
506 p = Brdstr(imp, '\n', 1);
507 if(strcmp(p, "empty archive") != 0) {
508 if(strncmp(p, "go object ", 10) != 0) {
509 yyerror("import %s: not a go object file", file);
510 errorexit();
511 }
512 q = smprint("%s %s %s", getgoos(), thestring, getgoversion());
513 if(strcmp(p+10, q) != 0) {
514 yyerror("import %s: object is [%s] expected [%s]", file, p+10, q);
515 errorexit();
516 }
517 free(q);
518 }
519
520 // assume files move (get installed)
521 // so don't record the full path.
522 linehist(file + len - path->len - 2, -1, 1); // acts as #pragma lib
523
524 /*
525 * position the input right
526 * after $$ and return
527 */
528 pushedio = curio;
529 curio.bin = imp;
530 curio.peekc = 0;
531 curio.peekc1 = 0;
532 curio.infile = file;
533 curio.nlsemi = 0;
534 typecheckok = 1;
535
536 for(;;) {
537 c = getc();
538 if(c == EOF)
539 break;
540 if(c != '$')
541 continue;
542 c = getc();
543 if(c == EOF)
544 break;
545 if(c != '$')
546 continue;
547 return;
548 }
549 yyerror("no import in: %Z", f->u.sval);
550 unimportfile();
551 }
552
553 void
554 unimportfile(void)
555 {
556 if(curio.bin != nil) {
557 Bterm(curio.bin);
558 curio.bin = nil;
559 } else
560 lexlineno--; // re correct sys.6 line number
561
562 curio = pushedio;
563 pushedio.bin = nil;
564 incannedimport = 0;
565 typecheckok = 0;
566 }
567
568 void
569 cannedimports(char *file, char *cp)
570 {
571 lexlineno++; // if sys.6 is included on line 1,
572
573 pushedio = curio;
574 curio.bin = nil;
575 curio.peekc = 0;
576 curio.peekc1 = 0;
577 curio.infile = file;
578 curio.cp = cp;
579 curio.nlsemi = 0;
580 curio.importsafe = 0;
581
582 typecheckok = 1;
583 incannedimport = 1;
584 }
585
586 static int
587 isfrog(int c)
588 {
589 // complain about possibly invisible control characters
590 if(c < 0)
591 return 1;
592 if(c < ' ') {
593 if(c == '\n' || c== '\r' || c == '\t') // good white space
594 return 0;
595 return 1;
596 }
597 if(0x7f <= c && c <= 0xa0) // DEL, unicode block including unbreakable space.
598 return 1;
599 return 0;
600 }
601
602 typedef struct Loophack Loophack;
603 struct Loophack {
604 int v;
605 Loophack *next;
606 };
607
608 static int32
609 _yylex(void)
610 {
611 int c, c1, clen, escflag, ncp;
612 vlong v;
613 char *cp, *ep;
614 Rune rune;
615 Sym *s;
616 static Loophack *lstk;
617 Loophack *h;
618
619 prevlineno = lineno;
620
621 l0:
622 c = getc();
623 if(yy_isspace(c)) {
624 if(c == '\n' && curio.nlsemi) {
625 ungetc(c);
626 DBG("lex: implicit semi\n");
627 return ';';
628 }
629 goto l0;
630 }
631
632 lineno = lexlineno; /* start of token */
633
634 if(c >= Runeself) {
635 /* all multibyte runes are alpha */
636 cp = lexbuf;
637 ep = lexbuf+sizeof lexbuf;
638 goto talph;
639 }
640
641 if(yy_isalpha(c)) {
642 cp = lexbuf;
643 ep = lexbuf+sizeof lexbuf;
644 goto talph;
645 }
646
647 if(yy_isdigit(c))
648 goto tnum;
649
650 switch(c) {
651 case EOF:
652 lineno = prevlineno;
653 ungetc(EOF);
654 return -1;
655
656 case '_':
657 cp = lexbuf;
658 ep = lexbuf+sizeof lexbuf;
659 goto talph;
660
661 case '.':
662 c1 = getc();
663 if(yy_isdigit(c1)) {
664 cp = lexbuf;
665 ep = lexbuf+sizeof lexbuf;
666 *cp++ = c;
667 c = c1;
668 c1 = 0;
669 goto casedot;
670 }
671 if(c1 == '.') {
672 c1 = getc();
673 if(c1 == '.') {
674 c = LDDD;
675 goto lx;
676 }
677 ungetc(c1);
678 c1 = '.';
679 }
680 break;
681
682 case '"':
683 /* "..." */
684 strcpy(lexbuf, "\"<string>\"");
685 cp = mal(8);
686 clen = sizeof(int32);
687 ncp = 8;
688
689 for(;;) {
690 if(clen+UTFmax > ncp) {
691 cp = remal(cp, ncp, ncp);
692 ncp += ncp;
693 }
694 if(escchar('"', &escflag, &v))
695 break;
696 if(v < Runeself || escflag) {
697 cp[clen++] = v;
698 } else {
699 rune = v;
700 c = runelen(rune);
701 runetochar(cp+clen, &rune);
702 clen += c;
703 }
704 }
705 goto strlit;
706
707 case '`':
708 /* `...` */
709 strcpy(lexbuf, "`<string>`");
710 cp = mal(8);
711 clen = sizeof(int32);
712 ncp = 8;
713
714 for(;;) {
715 if(clen+UTFmax > ncp) {
716 cp = remal(cp, ncp, ncp);
717 ncp += ncp;
718 }
719 c = getr();
720 if(c == EOF) {
721 yyerror("eof in string");
722 break;
723 }
724 if(c == '`')
725 break;
726 rune = c;
727 clen += runetochar(cp+clen, &rune);
728 }
729
730 strlit:
731 *(int32*)cp = clen-sizeof(int32); // length
732 do {
733 cp[clen++] = 0;
734 } while(clen & MAXALIGN);
735 yylval.val.u.sval = (Strlit*)cp;
736 yylval.val.ctype = CTSTR;
737 DBG("lex: string literal\n");
738 strcpy(litbuf, "string literal");
739 return LLITERAL;
740
741 case '\'':
742 /* '.' */
743 if(escchar('\'', &escflag, &v)) {
744 yyerror("empty character literal or unescaped ' in character literal");
745 v = '\'';
746 }
747 if(!escchar('\'', &escflag, &v)) {
748 yyerror("missing '");
749 ungetc(v);
750 }
751 yylval.val.u.xval = mal(sizeof(*yylval.val.u.xval));
752 mpmovecfix(yylval.val.u.xval, v);
753 yylval.val.ctype = CTINT;
754 DBG("lex: codepoint literal\n");
755 strcpy(litbuf, "string literal");
756 return LLITERAL;
757
758 case '/':
759 c1 = getc();
760 if(c1 == '*') {
761 int nl;
762
763 nl = 0;
764 for(;;) {
765 c = getr();
766 if(c == '\n')
767 nl = 1;
768 while(c == '*') {
769 c = getr();
770 if(c == '/') {
771 if(nl)
772 ungetc('\n');
773 goto l0;
774 }
775 if(c == '\n')
776 nl = 1;
777 }
778 if(c == EOF) {
779 yyerror("eof in comment");
780 errorexit();
781 }
782 }
783 }
784 if(c1 == '/') {
785 c = getlinepragma();
786 for(;;) {
787 if(c == '\n' || c == EOF) {
788 ungetc(c);
789 goto l0;
790 }
791 c = getr();
792 }
793 }
794 if(c1 == '=') {
795 c = ODIV;
796 goto asop;
797 }
798 break;
799
800 case ':':
801 c1 = getc();
802 if(c1 == '=') {
803 c = LCOLAS;
804 goto lx;
805 }
806 break;
807
808 case '*':
809 c1 = getc();
810 if(c1 == '=') {
811 c = OMUL;
812 goto asop;
813 }
814 break;
815
816 case '%':
817 c1 = getc();
818 if(c1 == '=') {
819 c = OMOD;
820 goto asop;
821 }
822 break;
823
824 case '+':
825 c1 = getc();
826 if(c1 == '+') {
827 c = LINC;
828 goto lx;
829 }
830 if(c1 == '=') {
831 c = OADD;
832 goto asop;
833 }
834 break;
835
836 case '-':
837 c1 = getc();
838 if(c1 == '-') {
839 c = LDEC;
840 goto lx;
841 }
842 if(c1 == '=') {
843 c = OSUB;
844 goto asop;
845 }
846 break;
847
848 case '>':
849 c1 = getc();
850 if(c1 == '>') {
851 c = LRSH;
852 c1 = getc();
853 if(c1 == '=') {
854 c = ORSH;
855 goto asop;
856 }
857 break;
858 }
859 if(c1 == '=') {
860 c = LGE;
861 goto lx;
862 }
863 c = LGT;
864 break;
865
866 case '<':
867 c1 = getc();
868 if(c1 == '<') {
869 c = LLSH;
870 c1 = getc();
871 if(c1 == '=') {
872 c = OLSH;
873 goto asop;
874 }
875 break;
876 }
877 if(c1 == '=') {
878 c = LLE;
879 goto lx;
880 }
881 if(c1 == '-') {
882 c = LCOMM;
883 goto lx;
884 }
885 c = LLT;
886 break;
887
888 case '=':
889 c1 = getc();
890 if(c1 == '=') {
891 c = LEQ;
892 goto lx;
893 }
894 break;
895
896 case '!':
897 c1 = getc();
898 if(c1 == '=') {
899 c = LNE;
900 goto lx;
901 }
902 break;
903
904 case '&':
905 c1 = getc();
906 if(c1 == '&') {
907 c = LANDAND;
908 goto lx;
909 }
910 if(c1 == '^') {
911 c = LANDNOT;
912 c1 = getc();
913 if(c1 == '=') {
914 c = OANDNOT;
915 goto asop;
916 }
917 break;
918 }
919 if(c1 == '=') {
920 c = OAND;
921 goto asop;
922 }
923 break;
924
925 case '|':
926 c1 = getc();
927 if(c1 == '|') {
928 c = LOROR;
929 goto lx;
930 }
931 if(c1 == '=') {
932 c = OOR;
933 goto asop;
934 }
935 break;
936
937 case '^':
938 c1 = getc();
939 if(c1 == '=') {
940 c = OXOR;
941 goto asop;
942 }
943 break;
944
945 /*
946 * clumsy dance:
947 * to implement rule that disallows
948 * if T{1}[0] { ... }
949 * but allows
950 * if (T{1}[0]) { ... }
951 * the block bodies for if/for/switch/select
952 * begin with an LBODY token, not '{'.
953 *
954 * when we see the keyword, the next
955 * non-parenthesized '{' becomes an LBODY.
956 * loophack is normally 0.
957 * a keyword makes it go up to 1.
958 * parens push loophack onto a stack and go back to 0.
959 * a '{' with loophack == 1 becomes LBODY and disables loophack.
960 *
961 * i said it was clumsy.
962 */
963 case '(':
964 case '[':
965 if(loophack || lstk != nil) {
966 h = malloc(sizeof *h);
967 h->v = loophack;
968 h->next = lstk;
969 lstk = h;
970 loophack = 0;
971 }
972 goto lx;
973 case ')':
974 case ']':
975 if(lstk != nil) {
976 h = lstk;
977 loophack = h->v;
978 lstk = h->next;
979 free(h);
980 }
981 goto lx;
982 case '{':
983 if(loophack == 1) {
984 DBG("%L lex: LBODY\n", lexlineno);
985 loophack = 0;
986 return LBODY;
987 }
988 goto lx;
989
990 default:
991 goto lx;
992 }
993 ungetc(c1);
994
995 lx:
996 if(c > 0xff)
997 DBG("%L lex: TOKEN %s\n", lexlineno, lexname(c));
998 else
999 DBG("%L lex: TOKEN '%c'\n", lexlineno, c);
1000 if(isfrog(c)) {
1001 yyerror("illegal character 0x%ux", c);
1002 goto l0;
1003 }
1004 if(importpkg == nil && (c == '#' || c == '$' || c == '?' || c == '@' || c == '\\')) {
1005 yyerror("%s: unexpected %c", "syntax error", c);
1006 goto l0;
1007 }
1008 return c;
1009
1010 asop:
1011 yylval.lint = c; // rathole to hold which asop
1012 DBG("lex: TOKEN ASOP %c\n", c);
1013 return LASOP;
1014
1015 talph:
1016 /*
1017 * cp is set to lexbuf and some
1018 * prefix has been stored
1019 */
1020 for(;;) {
1021 if(cp+10 >= ep) {
1022 yyerror("identifier too long");
1023 errorexit();
1024 }
1025 if(c >= Runeself) {
1026 ungetc(c);
1027 rune = getr();
1028 // 0xb7 · is used for internal names
1029 if(!isalpharune(rune) && !isdigitrune(rune) && (importpkg == nil || rune != 0xb7))
1030 yyerror("invalid identifier character 0x%ux", rune);
1031 cp += runetochar(cp, &rune);
1032 } else if(!yy_isalnum(c) && c != '_')
1033 break;
1034 else
1035 *cp++ = c;
1036 c = getc();
1037 }
1038 *cp = 0;
1039 ungetc(c);
1040
1041 s = lookup(lexbuf);
1042 switch(s->lexical) {
1043 case LIGNORE:
1044 goto l0;
1045
1046 case LFOR:
1047 case LIF:
1048 case LSWITCH:
1049 case LSELECT:
1050 loophack = 1; // see comment about loophack above
1051 break;
1052 }
1053
1054 DBG("lex: %S %s\n", s, lexname(s->lexical));
1055 yylval.sym = s;
1056 return s->lexical;
1057
1058 tnum:
1059 c1 = 0;
1060 cp = lexbuf;
1061 ep = lexbuf+sizeof lexbuf;
1062 if(c != '0') {
1063 for(;;) {
1064 if(cp+10 >= ep) {
1065 yyerror("identifier too long");
1066 errorexit();
1067 }
1068 *cp++ = c;
1069 c = getc();
1070 if(yy_isdigit(c))
1071 continue;
1072 goto dc;
1073 }
1074 }
1075 *cp++ = c;
1076 c = getc();
1077 if(c == 'x' || c == 'X') {
1078 for(;;) {
1079 if(cp+10 >= ep) {
1080 yyerror("identifier too long");
1081 errorexit();
1082 }
1083 *cp++ = c;
1084 c = getc();
1085 if(yy_isdigit(c))
1086 continue;
1087 if(c >= 'a' && c <= 'f')
1088 continue;
1089 if(c >= 'A' && c <= 'F')
1090 continue;
1091 if(cp == lexbuf+2)
1092 yyerror("malformed hex constant");
1093 goto ncu;
1094 }
1095 }
1096
1097 if(c == 'p') // 0p begins floating point zero
1098 goto casep;
1099
1100 c1 = 0;
1101 for(;;) {
1102 if(cp+10 >= ep) {
1103 yyerror("identifier too long");
1104 errorexit();
1105 }
1106 if(!yy_isdigit(c))
1107 break;
1108 if(c < '0' || c > '7')
1109 c1 = 1; // not octal
1110 *cp++ = c;
1111 c = getc();
1112 }
1113 if(c == '.')
1114 goto casedot;
1115 if(c == 'e' || c == 'E')
1116 goto casee;
1117 if(c == 'i')
1118 goto casei;
1119 if(c1)
1120 yyerror("malformed octal constant");
1121 goto ncu;
1122
1123 dc:
1124 if(c == '.')
1125 goto casedot;
1126 if(c == 'e' || c == 'E')
1127 goto casee;
1128 if(c == 'p' || c == 'P')
1129 goto casep;
1130 if(c == 'i')
1131 goto casei;
1132
1133 ncu:
1134 *cp = 0;
1135 ungetc(c);
1136
1137 yylval.val.u.xval = mal(sizeof(*yylval.val.u.xval));
1138 mpatofix(yylval.val.u.xval, lexbuf);
1139 if(yylval.val.u.xval->ovf) {
1140 yyerror("overflow in constant");
1141 mpmovecfix(yylval.val.u.xval, 0);
1142 }
1143 yylval.val.ctype = CTINT;
1144 DBG("lex: integer literal\n");
1145 strcpy(litbuf, "literal ");
1146 strcat(litbuf, lexbuf);
1147 return LLITERAL;
1148
1149 casedot:
1150 for(;;) {
1151 if(cp+10 >= ep) {
1152 yyerror("identifier too long");
1153 errorexit();
1154 }
1155 *cp++ = c;
1156 c = getc();
1157 if(!yy_isdigit(c))
1158 break;
1159 }
1160 if(c == 'i')
1161 goto casei;
1162 if(c != 'e' && c != 'E')
1163 goto caseout;
1164
1165 casee:
1166 *cp++ = 'e';
1167 c = getc();
1168 if(c == '+' || c == '-') {
1169 *cp++ = c;
1170 c = getc();
1171 }
1172 if(!yy_isdigit(c))
1173 yyerror("malformed fp constant exponent");
1174 while(yy_isdigit(c)) {
1175 if(cp+10 >= ep) {
1176 yyerror("identifier too long");
1177 errorexit();
1178 }
1179 *cp++ = c;
1180 c = getc();
1181 }
1182 if(c == 'i')
1183 goto casei;
1184 goto caseout;
1185
1186 casep:
1187 *cp++ = 'p';
1188 c = getc();
1189 if(c == '+' || c == '-') {
1190 *cp++ = c;
1191 c = getc();
1192 }
1193 if(!yy_isdigit(c))
1194 yyerror("malformed fp constant exponent");
1195 while(yy_isdigit(c)) {
1196 if(cp+10 >= ep) {
1197 yyerror("identifier too long");
1198 errorexit();
1199 }
1200 *cp++ = c;
1201 c = getc();
1202 }
1203 if(c == 'i')
1204 goto casei;
1205 goto caseout;
1206
1207 casei:
1208 // imaginary constant
1209 *cp = 0;
1210 yylval.val.u.cval = mal(sizeof(*yylval.val.u.cval));
1211 mpmovecflt(&yylval.val.u.cval->real, 0.0);
1212 mpatoflt(&yylval.val.u.cval->imag, lexbuf);
1213 if(yylval.val.u.cval->imag.val.ovf) {
1214 yyerror("overflow in imaginary constant");
1215 mpmovecflt(&yylval.val.u.cval->real, 0.0);
1216 }
1217 yylval.val.ctype = CTCPLX;
1218 DBG("lex: imaginary literal\n");
1219 strcpy(litbuf, "literal ");
1220 strcat(litbuf, lexbuf);
1221 return LLITERAL;
1222
1223 caseout:
1224 *cp = 0;
1225 ungetc(c);
1226
1227 yylval.val.u.fval = mal(sizeof(*yylval.val.u.fval));
1228 mpatoflt(yylval.val.u.fval, lexbuf);
1229 if(yylval.val.u.fval->val.ovf) {
1230 yyerror("overflow in float constant");
1231 mpmovecflt(yylval.val.u.fval, 0.0);
1232 }
1233 yylval.val.ctype = CTFLT;
1234 DBG("lex: floating literal\n");
1235 strcpy(litbuf, "literal ");
1236 strcat(litbuf, lexbuf);
1237 return LLITERAL;
1238 }
1239
1240 /*
1241 * read and interpret syntax that looks like
1242 * //line parse.y:15
1243 * as a discontinuity in sequential line numbers.
1244 * the next line of input comes from parse.y:15
1245 */
1246 static int
1247 getlinepragma(void)
1248 {
1249 int i, c, n;
1250 char *cp, *ep;
1251 Hist *h;
1252
1253 for(i=0; i<5; i++) {
1254 c = getr();
1255 if(c != "line "[i])
1256 goto out;
1257 }
1258
1259 cp = lexbuf;
1260 ep = lexbuf+sizeof(lexbuf)-5;
1261 for(;;) {
1262 c = getr();
1263 if(c == '\n' || c == EOF)
1264 goto out;
1265 if(c == ' ')
1266 continue;
1267 if(c == ':')
1268 break;
1269 if(cp < ep)
1270 *cp++ = c;
1271 }
1272 *cp = 0;
1273
1274 n = 0;
1275 for(;;) {
1276 c = getr();
1277 if(!yy_isdigit(c))
1278 break;
1279 n = n*10 + (c-'0');
1280 if(n > 1e8) {
1281 yyerror("line number out of range");
1282 errorexit();
1283 }
1284 }
1285
1286 if(c != '\n' || n <= 0)
1287 goto out;
1288
1289 // try to avoid allocating file name over and over
1290 for(h=hist; h!=H; h=h->link) {
1291 if(h->name != nil && strcmp(h->name, lexbuf) == 0) {
1292 linehist(h->name, n, 0);
1293 goto out;
1294 }
1295 }
1296 linehist(strdup(lexbuf), n, 0);
1297
1298 out:
1299 return c;
1300 }
1301
1302 int32
1303 yylex(void)
1304 {
1305 int lx;
1306
1307 lx = _yylex();
1308
1309 if(curio.nlsemi && lx == EOF) {
1310 // Treat EOF as "end of line" for the purposes
1311 // of inserting a semicolon.
1312 lx = ';';
1313 }
1314
1315 switch(lx) {
1316 case LNAME:
1317 case LLITERAL:
1318 case LBREAK:
1319 case LCONTINUE:
1320 case LFALL:
1321 case LRETURN:
1322 case LINC:
1323 case LDEC:
1324 case ')':
1325 case '}':
1326 case ']':
1327 curio.nlsemi = 1;
1328 break;
1329 default:
1330 curio.nlsemi = 0;
1331 break;
1332 }
1333
1334 // Track last two tokens returned by yylex.
1335 yyprev = yylast;
1336 yylast = lx;
1337 return lx;
1338 }
1339
1340 static int
1341 getc(void)
1342 {
1343 int c;
1344
1345 c = curio.peekc;
1346 if(c != 0) {
1347 curio.peekc = curio.peekc1;
1348 curio.peekc1 = 0;
1349 if(c == '\n' && pushedio.bin == nil)
1350 lexlineno++;
1351 return c;
1352 }
1353
1354 if(curio.bin == nil) {
1355 c = *curio.cp & 0xff;
1356 if(c != 0)
1357 curio.cp++;
1358 } else
1359 c = Bgetc(curio.bin);
1360
1361 switch(c) {
1362 case 0:
1363 if(curio.bin != nil) {
1364 yyerror("illegal NUL byte");
1365 break;
1366 }
1367 case EOF:
1368 // insert \n at EOF
1369 if(curio.eofnl)
1370 return EOF;
1371 curio.eofnl = 1;
1372 c = '\n';
1373 case '\n':
1374 if(pushedio.bin == nil)
1375 lexlineno++;
1376 break;
1377 }
1378 return c;
1379 }
1380
1381 static void
1382 ungetc(int c)
1383 {
1384 curio.peekc1 = curio.peekc;
1385 curio.peekc = c;
1386 if(c == '\n' && pushedio.bin == nil)
1387 lexlineno--;
1388 }
1389
1390 static int32
1391 getr(void)
1392 {
1393 int c, i;
1394 char str[UTFmax+1];
1395 Rune rune;
1396
1397 c = getc();
1398 if(c < Runeself)
1399 return c;
1400 i = 0;
1401 str[i++] = c;
1402
1403 loop:
1404 c = getc();
1405 str[i++] = c;
1406 if(!fullrune(str, i))
1407 goto loop;
1408 c = chartorune(&rune, str);
1409 if(rune == Runeerror && c == 1) {
1410 lineno = lexlineno;
1411 yyerror("illegal UTF-8 sequence");
1412 flusherrors();
1413 print("\t");
1414 for(c=0; c<i; c++)
1415 print("%s%.2x", c > 0 ? " " : "", *(uchar*)(str+c));
1416 print("\n");
1417 }
1418 return rune;
1419 }
1420
1421 static int
1422 escchar(int e, int *escflg, vlong *val)
1423 {
1424 int i, u, c;
1425 vlong l;
1426
1427 *escflg = 0;
1428
1429 c = getr();
1430 switch(c) {
1431 case EOF:
1432 yyerror("eof in string");
1433 return 1;
1434 case '\n':
1435 yyerror("newline in string");
1436 return 1;
1437 case '\\':
1438 break;
1439 default:
1440 if(c == e)
1441 return 1;
1442 *val = c;
1443 return 0;
1444 }
1445
1446 u = 0;
1447 c = getr();
1448 switch(c) {
1449 case 'x':
1450 *escflg = 1; // it's a byte
1451 i = 2;
1452 goto hex;
1453
1454 case 'u':
1455 i = 4;
1456 u = 1;
1457 goto hex;
1458
1459 case 'U':
1460 i = 8;
1461 u = 1;
1462 goto hex;
1463
1464 case '0':
1465 case '1':
1466 case '2':
1467 case '3':
1468 case '4':
1469 case '5':
1470 case '6':
1471 case '7':
1472 *escflg = 1; // it's a byte
1473 goto oct;
1474
1475 case 'a': c = '\a'; break;
1476 case 'b': c = '\b'; break;
1477 case 'f': c = '\f'; break;
1478 case 'n': c = '\n'; break;
1479 case 'r': c = '\r'; break;
1480 case 't': c = '\t'; break;
1481 case 'v': c = '\v'; break;
1482 case '\\': c = '\\'; break;
1483
1484 default:
1485 if(c != e)
1486 yyerror("unknown escape sequence: %c", c);
1487 }
1488 *val = c;
1489 return 0;
1490
1491 hex:
1492 l = 0;
1493 for(; i>0; i--) {
1494 c = getc();
1495 if(c >= '0' && c <= '9') {
1496 l = l*16 + c-'0';
1497 continue;
1498 }
1499 if(c >= 'a' && c <= 'f') {
1500 l = l*16 + c-'a' + 10;
1501 continue;
1502 }
1503 if(c >= 'A' && c <= 'F') {
1504 l = l*16 + c-'A' + 10;
1505 continue;
1506 }
1507 yyerror("non-hex character in escape sequence: %c", c);
1508 ungetc(c);
1509 break;
1510 }
1511 if(u && (l > Runemax || (0xd800 <= l && l < 0xe000))) {
1512 yyerror("invalid Unicode code point in escape sequence: %#llx", l);
1513 l = Runeerror;
1514 }
1515 *val = l;
1516 return 0;
1517
1518 oct:
1519 l = c - '0';
1520 for(i=2; i>0; i--) {
1521 c = getc();
1522 if(c >= '0' && c <= '7') {
1523 l = l*8 + c-'0';
1524 continue;
1525 }
1526 yyerror("non-octal character in escape sequence: %c", c);
1527 ungetc(c);
1528 }
1529 if(l > 255)
1530 yyerror("octal escape value > 255: %d", l);
1531
1532 *val = l;
1533 return 0;
1534 }
1535
1536 static struct
1537 {
1538 char* name;
1539 int lexical;
1540 int etype;
1541 int op;
1542 } syms[] =
1543 {
1544 /* name lexical etype op
1545 */
1546 /* basic types */
1547 "int8", LNAME, TINT8, OXXX,
1548 "int16", LNAME, TINT16, OXXX,
1549 "int32", LNAME, TINT32, OXXX,
1550 "int64", LNAME, TINT64, OXXX,
1551
1552 "uint8", LNAME, TUINT8, OXXX,
1553 "uint16", LNAME, TUINT16, OXXX,
1554 "uint32", LNAME, TUINT32, OXXX,
1555 "uint64", LNAME, TUINT64, OXXX,
1556
1557 "float32", LNAME, TFLOAT32, OXXX,
1558 "float64", LNAME, TFLOAT64, OXXX,
1559
1560 "complex64", LNAME, TCOMPLEX64, OXXX,
1561 "complex128", LNAME, TCOMPLEX128, OXXX,
1562
1563 "bool", LNAME, TBOOL, OXXX,
1564 "byte", LNAME, TUINT8, OXXX,
1565 "string", LNAME, TSTRING, OXXX,
1566
1567 "any", LNAME, TANY, OXXX,
1568
1569 "break", LBREAK, Txxx, OXXX,
1570 "case", LCASE, Txxx, OXXX,
1571 "chan", LCHAN, Txxx, OXXX,
1572 "const", LCONST, Txxx, OXXX,
1573 "continue", LCONTINUE, Txxx, OXXX,
1574 "default", LDEFAULT, Txxx, OXXX,
1575 "else", LELSE, Txxx, OXXX,
1576 "defer", LDEFER, Txxx, OXXX,
1577 "fallthrough", LFALL, Txxx, OXXX,
1578 "for", LFOR, Txxx, OXXX,
1579 "func", LFUNC, Txxx, OXXX,
1580 "go", LGO, Txxx, OXXX,
1581 "goto", LGOTO, Txxx, OXXX,
1582 "if", LIF, Txxx, OXXX,
1583 "import", LIMPORT, Txxx, OXXX,
1584 "interface", LINTERFACE, Txxx, OXXX,
1585 "map", LMAP, Txxx, OXXX,
1586 "package", LPACKAGE, Txxx, OXXX,
1587 "range", LRANGE, Txxx, OXXX,
1588 "return", LRETURN, Txxx, OXXX,
1589 "select", LSELECT, Txxx, OXXX,
1590 "struct", LSTRUCT, Txxx, OXXX,
1591 "switch", LSWITCH, Txxx, OXXX,
1592 "type", LTYPE, Txxx, OXXX,
1593 "var", LVAR, Txxx, OXXX,
1594
1595 "append", LNAME, Txxx, OAPPEND,
1596 "cap", LNAME, Txxx, OCAP,
1597 "close", LNAME, Txxx, OCLOSE,
1598 "complex", LNAME, Txxx, OCOMPLEX,
1599 "copy", LNAME, Txxx, OCOPY,
1600 "imag", LNAME, Txxx, OIMAG,
1601 "len", LNAME, Txxx, OLEN,
1602 "make", LNAME, Txxx, OMAKE,
1603 "new", LNAME, Txxx, ONEW,
1604 "panic", LNAME, Txxx, OPANIC,
1605 "print", LNAME, Txxx, OPRINT,
1606 "println", LNAME, Txxx, OPRINTN,
1607 "real", LNAME, Txxx, OREAL,
1608 "recover", LNAME, Txxx, ORECOVER,
1609
1610 "notwithstanding", LIGNORE, Txxx, OXXX,
1611 "thetruthofthematter", LIGNORE, Txxx, OXXX,
1612 "despiteallobjections", LIGNORE, Txxx, OXXX,
1613 "whereas", LIGNORE, Txxx, OXXX,
1614 "insofaras", LIGNORE, Txxx, OXXX,
1615 };
1616
1617 static void
1618 lexinit(void)
1619 {
1620 int i, lex;
1621 Sym *s, *s1;
1622 Type *t;
1623 int etype;
1624
1625 /*
1626 * initialize basic types array
1627 * initialize known symbols
1628 */
1629 for(i=0; i<nelem(syms); i++) {
1630 lex = syms[i].lexical;
1631 s = lookup(syms[i].name);
1632 s->lexical = lex;
1633
1634 etype = syms[i].etype;
1635 if(etype != Txxx) {
1636 if(etype < 0 || etype >= nelem(types))
1637 fatal("lexinit: %s bad etype", s->name);
1638 t = types[etype];
1639 if(t == T) {
1640 t = typ(etype);
1641 t->sym = s;
1642
1643 if(etype != TANY && etype != TSTRING)
1644 dowidth(t);
1645 types[etype] = t;
1646 }
1647 s1 = pkglookup(syms[i].name, builtinpkg);
1648 s1->lexical = LNAME;
1649 s1->def = typenod(t);
1650 continue;
1651 }
1652 }
1653
1654 // logically, the type of a string literal.
1655 // types[TSTRING] is the named type string
1656 // (the type of x in var x string or var x = "hello").
1657 // this is the ideal form
1658 // (the type of x in const x = "hello").
1659 idealstring = typ(TSTRING);
1660 idealbool = typ(TBOOL);
1661
1662 s = pkglookup("true", builtinpkg);
1663 s->def = nodbool(1);
1664 s->def->sym = lookup("true");
1665 s->def->type = idealbool;
1666
1667 s = pkglookup("false", builtinpkg);
1668 s->def = nodbool(0);
1669 s->def->sym = lookup("false");
1670 s->def->type = idealbool;
1671
1672 s = lookup("_");
1673 s->block = -100;
1674 s->def = nod(ONAME, N, N);
1675 s->def->sym = s;
1676 types[TBLANK] = typ(TBLANK);
1677 s->def->type = types[TBLANK];
1678 nblank = s->def;
1679 }
1680
1681 static void
1682 lexfini(void)
1683 {
1684 Sym *s;
1685 int lex, etype, i;
1686 Val v;
1687
1688 for(i=0; i<nelem(syms); i++) {
1689 lex = syms[i].lexical;
1690 if(lex != LNAME)
1691 continue;
1692 s = lookup(syms[i].name);
1693 s->lexical = lex;
1694
1695 etype = syms[i].etype;
1696 if(etype != Txxx && (etype != TANY || debug['A']) && s->def == N)
1697 s->def = typenod(types[etype]);
1698
1699 etype = syms[i].op;
1700 if(etype != OXXX && s->def == N) {
1701 s->def = nod(ONAME, N, N);
1702 s->def->sym = s;
1703 s->def->etype = etype;
1704 s->def->builtin = 1;
1705 }
1706 }
1707
1708 for(i=0; typedefs[i].name; i++) {
1709 s = lookup(typedefs[i].name);
1710 if(s->def == N)
1711 s->def = typenod(types[typedefs[i].etype]);
1712 }
1713
1714 // there's only so much table-driven we can handle.
1715 // these are special cases.
1716 types[TNIL] = typ(TNIL);
1717 s = lookup("nil");
1718 if(s->def == N) {
1719 v.ctype = CTNIL;
1720 s->def = nodlit(v);
1721 s->def->sym = s;
1722 }
1723
1724 s = lookup("iota");
1725 if(s->def == N) {
1726 s->def = nod(OIOTA, N, N);
1727 s->def->sym = s;
1728 }
1729
1730 s = lookup("true");
1731 if(s->def == N) {
1732 s->def = nodbool(1);
1733 s->def->sym = s;
1734 }
1735
1736 s = lookup("false");
1737 if(s->def == N) {
1738 s->def = nodbool(0);
1739 s->def->sym = s;
1740 }
1741
1742 nodfp = nod(ONAME, N, N);
1743 nodfp->noescape = 1;
1744 nodfp->type = types[TINT32];
1745 nodfp->xoffset = 0;
1746 nodfp->class = PPARAM;
1747 nodfp->sym = lookup(".fp");
1748 }
1749
1750 struct
1751 {
1752 int lex;
1753 char* name;
1754 } lexn[] =
1755 {
1756 LANDAND, "ANDAND",
1757 LASOP, "ASOP",
1758 LBREAK, "BREAK",
1759 LCASE, "CASE",
1760 LCHAN, "CHAN",
1761 LCOLAS, "COLAS",
1762 LCONST, "CONST",
1763 LCONTINUE, "CONTINUE",
1764 LDEC, "DEC",
1765 LDEFER, "DEFER",
1766 LELSE, "ELSE",
1767 LEQ, "EQ",
1768 LFALL, "FALL",
1769 LFOR, "FOR",
1770 LFUNC, "FUNC",
1771 LGE, "GE",
1772 LGO, "GO",
1773 LGOTO, "GOTO",
1774 LGT, "GT",
1775 LIF, "IF",
1776 LIMPORT, "IMPORT",
1777 LINC, "INC",
1778 LINTERFACE, "INTERFACE",
1779 LLE, "LE",
1780 LLITERAL, "LITERAL",
1781 LLSH, "LSH",
1782 LLT, "LT",
1783 LMAP, "MAP",
1784 LNAME, "NAME",
1785 LNE, "NE",
1786 LOROR, "OROR",
1787 LPACKAGE, "PACKAGE",
1788 LRANGE, "RANGE",
1789 LRETURN, "RETURN",
1790 LRSH, "RSH",
1791 LSTRUCT, "STRUCT",
1792 LSWITCH, "SWITCH",
1793 LTYPE, "TYPE",
1794 LVAR, "VAR",
1795 };
1796
1797 char*
1798 lexname(int lex)
1799 {
1800 int i;
1801 static char buf[100];
1802
1803 for(i=0; i<nelem(lexn); i++)
1804 if(lexn[i].lex == lex)
1805 return lexn[i].name;
1806 snprint(buf, sizeof(buf), "LEX-%d", lex);
1807 return buf;
1808 }
1809
1810 struct
1811 {
1812 char *have;
1813 char *want;
1814 } yytfix[] =
1815 {
1816 "$end", "EOF",
1817 "LLITERAL", "literal",
1818 "LASOP", "op=",
1819 "LBREAK", "break",
1820 "LCASE", "case",
1821 "LCOLAS", ":=",
1822 "LCONST", "const",
1823 "LCONTINUE", "continue",
1824 "LDDD", "...",
1825 "LDEFAULT", "default",
1826 "LDEFER", "defer",
1827 "LELSE", "else",
1828 "LFALL", "fallthrough",
1829 "LFOR", "for",
1830 "LFUNC", "func",
1831 "LGO", "go",
1832 "LGOTO", "goto",
1833 "LIF", "if",
1834 "LIMPORT", "import",
1835 "LINTERFACE", "interface",
1836 "LMAP", "map",
1837 "LNAME", "name",
1838 "LPACKAGE", "package",
1839 "LRANGE", "range",
1840 "LRETURN", "return",
1841 "LSELECT", "select",
1842 "LSTRUCT", "struct",
1843 "LSWITCH", "switch",
1844 "LTYPE", "type",
1845 "LVAR", "var",
1846 "LANDAND", "&&",
1847 "LANDNOT", "&^",
1848 "LBODY", "{",
1849 "LCOMM", "<-",
1850 "LDEC", "--",
1851 "LINC", "++",
1852 "LEQ", "==",
1853 "LGE", ">=",
1854 "LGT", ">",
1855 "LLE", "<=",
1856 "LLT", "<",
1857 "LLSH", "<<",
1858 "LRSH", ">>",
1859 "LOROR", "||",
1860 "LNE", "!=",
1861
1862 // spell out to avoid confusion with punctuation in error messages
1863 "';'", "semicolon or newline",
1864 "','", "comma",
1865 };
1866
1867 static void
1868 yytinit(void)
1869 {
1870 int i, j;
1871 extern char *yytname[];
1872 char *s, *t;
1873
1874 for(i=0; yytname[i] != nil; i++) {
1875 s = yytname[i];
1876
1877 if(strcmp(s, "LLITERAL") == 0) {
1878 strcpy(litbuf, "literal");
1879 yytname[i] = litbuf;
1880 goto loop;
1881 }
1882
1883 // apply yytfix if possible
1884 for(j=0; j<nelem(yytfix); j++) {
1885 if(strcmp(s, yytfix[j].have) == 0) {
1886 yytname[i] = yytfix[j].want;
1887 goto loop;
1888 }
1889 }
1890
1891 // turn 'x' into x.
1892 if(s[0] == '\'') {
1893 t = strdup(s+1);
1894 t[strlen(t)-1] = '\0';
1895 yytname[i] = t;
1896 }
1897 loop:;
1898 }
1899 }
1900
1901 void
1902 mkpackage(char* pkgname)
1903 {
1904 Sym *s;
1905 int32 h;
1906 char *p;
1907
1908 if(localpkg->name == nil) {
1909 if(strcmp(pkgname, "_") == 0)
1910 yyerror("invalid package name _");
1911 localpkg->name = pkgname;
1912 } else {
1913 if(strcmp(pkgname, localpkg->name) != 0)
1914 yyerror("package %s; expected %s", pkgname, localpkg->name);
1915 for(h=0; h<NHASH; h++) {
1916 for(s = hash[h]; s != S; s = s->link) {
1917 if(s->def == N || s->pkg != localpkg)
1918 continue;
1919 if(s->def->op == OPACK) {
1920 // throw away top-level package name leftover
1921 // from previous file.
1922 // leave s->block set to cause redeclaration
1923 // errors if a conflicting top-level name is
1924 // introduced by a different file.
1925 if(!s->def->used && !nsyntaxerrors)
1926 yyerrorl(s->def->lineno, "imported and not used: %Z", s->def->pkg->path);
1927 s->def = N;
1928 continue;
1929 }
1930 if(s->def->sym != s) {
1931 // throw away top-level name left over
1932 // from previous import . "x"
1933 if(s->def->pack != N && !s->def->pack->used && !nsyntaxerrors) {
1934 yyerrorl(s->def->pack->lineno, "imported and not used: %Z", s->def->pack->pkg->path);
1935 s->def->pack->used = 1;
1936 }
1937 s->def = N;
1938 continue;
1939 }
1940 }
1941 }
1942 }
1943
1944 if(outfile == nil) {
1945 p = strrchr(infile, '/');
1946 if(p == nil)
1947 p = infile;
1948 else
1949 p = p+1;
1950 snprint(namebuf, sizeof(namebuf), "%s", p);
1951 p = strrchr(namebuf, '.');
1952 if(p != nil)
1953 *p = 0;
1954 outfile = smprint("%s.%c", namebuf, thechar);
1955 }
1956 }