LEFT | RIGHT |
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 <u.h> | 5 #include <u.h> |
6 #include <libc.h> | 6 #include <libc.h> |
7 #include "go.h" | 7 #include "go.h" |
8 #include "y.tab.h" | 8 #include "y.tab.h" |
9 #include <ar.h> | 9 #include <ar.h> |
10 | 10 |
(...skipping 11 matching lines...) Expand all Loading... |
22 static void lexinit1(void); | 22 static void lexinit1(void); |
23 static void lexfini(void); | 23 static void lexfini(void); |
24 static void yytinit(void); | 24 static void yytinit(void); |
25 static int getc(void); | 25 static int getc(void); |
26 static void ungetc(int); | 26 static void ungetc(int); |
27 static int32 getr(void); | 27 static int32 getr(void); |
28 static int escchar(int, int*, vlong*); | 28 static int escchar(int, int*, vlong*); |
29 static void addidir(char*); | 29 static void addidir(char*); |
30 static int getlinepragma(void); | 30 static int getlinepragma(void); |
31 static char *goos, *goarch, *goroot; | 31 static char *goos, *goarch, *goroot; |
| 32 |
| 33 // Compiler experiments. |
| 34 // These are controlled by the GCEXPERIMENT environment |
| 35 // variable recorded when the compiler is built. |
| 36 static struct { |
| 37 char *name; |
| 38 int *val; |
| 39 } exper[] = { |
| 40 {"rune32", &rune32}, |
| 41 }; |
| 42 |
| 43 static void |
| 44 addexp(char *s) |
| 45 { |
| 46 int i; |
| 47 ········ |
| 48 for(i=0; i<nelem(exper); i++) { |
| 49 if(strcmp(exper[i].name, s) == 0) { |
| 50 *exper[i].val = 1; |
| 51 return; |
| 52 } |
| 53 } |
| 54 ········ |
| 55 print("unknown experiment %s\n", s); |
| 56 exits("unknown experiment"); |
| 57 } |
| 58 |
| 59 static void |
| 60 setexp(void) |
| 61 { |
| 62 char *f[20]; |
| 63 int i, nf; |
| 64 ········ |
| 65 // The makefile #defines GOEXPERIMENT for us. |
| 66 nf = getfields(GOEXPERIMENT, f, nelem(f), 1, ","); |
| 67 for(i=0; i<nf; i++) |
| 68 addexp(f[i]); |
| 69 } |
| 70 |
| 71 char* |
| 72 expstring(void) |
| 73 { |
| 74 int i; |
| 75 static char buf[512]; |
| 76 |
| 77 strcpy(buf, "X"); |
| 78 for(i=0; i<nelem(exper); i++) |
| 79 if(*exper[i].val) |
| 80 seprint(buf+strlen(buf), buf+sizeof buf, ",%s", exper[i]
.name); |
| 81 if(strlen(buf) == 1) |
| 82 strcpy(buf, "X,none"); |
| 83 buf[1] = ':'; |
| 84 return buf; |
| 85 } |
32 | 86 |
33 // Our own isdigit, isspace, isalpha, isalnum that take care· | 87 // Our own isdigit, isspace, isalpha, isalnum that take care· |
34 // of EOF and other out of range arguments. | 88 // of EOF and other out of range arguments. |
35 static int | 89 static int |
36 yy_isdigit(int c) | 90 yy_isdigit(int c) |
37 { | 91 { |
38 return c >= 0 && c <= 0xFF && isdigit(c); | 92 return c >= 0 && c <= 0xFF && isdigit(c); |
39 } | 93 } |
40 | 94 |
41 static int | 95 static int |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 print(" -e no limit on number of errors printed\n"); | 141 print(" -e no limit on number of errors printed\n"); |
88 print(" -f print stack frame structure\n"); | 142 print(" -f print stack frame structure\n"); |
89 print(" -h panic on an error\n"); | 143 print(" -h panic on an error\n"); |
90 print(" -m print about moves to heap\n"); | 144 print(" -m print about moves to heap\n"); |
91 print(" -o file specify output file\n"); | 145 print(" -o file specify output file\n"); |
92 print(" -p assumed import path for this code\n"); | 146 print(" -p assumed import path for this code\n"); |
93 print(" -s disable escape analysis\n"); | 147 print(" -s disable escape analysis\n"); |
94 print(" -u disable package unsafe\n"); | 148 print(" -u disable package unsafe\n"); |
95 print(" -w print the parse tree after typing\n"); | 149 print(" -w print the parse tree after typing\n"); |
96 print(" -x print lex tokens\n"); | 150 print(" -x print lex tokens\n"); |
97 » exits(0); | 151 » exits("usage"); |
98 } | 152 } |
99 | 153 |
100 void | 154 void |
101 fault(int s) | 155 fault(int s) |
102 { | 156 { |
103 USED(s); | 157 USED(s); |
104 | 158 |
105 // If we've already complained about things | 159 // If we've already complained about things |
106 // in the program, don't bother complaining | 160 // in the program, don't bother complaining |
107 // about the seg fault too; let the user clean up | 161 // about the seg fault too; let the user clean up |
(...skipping 29 matching lines...) Expand all Loading... |
137 | 191 |
138 typepkg = mkpkg(strlit("type")); | 192 typepkg = mkpkg(strlit("type")); |
139 typepkg->name = "type"; | 193 typepkg->name = "type"; |
140 | 194 |
141 unsafepkg = mkpkg(strlit("unsafe")); | 195 unsafepkg = mkpkg(strlit("unsafe")); |
142 unsafepkg->name = "unsafe"; | 196 unsafepkg->name = "unsafe"; |
143 | 197 |
144 goroot = getgoroot(); | 198 goroot = getgoroot(); |
145 goos = getgoos(); | 199 goos = getgoos(); |
146 goarch = thestring; | 200 goarch = thestring; |
| 201 ········ |
| 202 setexp(); |
147 | 203 |
148 outfile = nil; | 204 outfile = nil; |
149 ARGBEGIN { | 205 ARGBEGIN { |
150 default: | 206 default: |
151 c = ARGC(); | 207 c = ARGC(); |
152 if(c >= 0 && c < sizeof(debug)) | 208 if(c >= 0 && c < sizeof(debug)) |
153 debug[c]++; | 209 debug[c]++; |
154 break; | 210 break; |
155 | 211 |
156 case 'o': | 212 case 'o': |
157 outfile = EARGF(usage()); | 213 outfile = EARGF(usage()); |
158 break; | 214 break; |
159 ········ | 215 ········ |
160 case 'p': | 216 case 'p': |
161 myimportpath = EARGF(usage()); | 217 myimportpath = EARGF(usage()); |
162 break; | 218 break; |
163 | 219 |
164 case 'I': | 220 case 'I': |
165 addidir(EARGF(usage())); | 221 addidir(EARGF(usage())); |
166 break; | 222 break; |
167 ········ | 223 ········ |
168 case 'u': | 224 case 'u': |
169 safemode = 1; | 225 safemode = 1; |
170 break; | 226 break; |
171 | 227 |
172 case 'V': | 228 case 'V': |
173 » » print("%cg version %s\n", thechar, getgoversion()); | 229 » » p = expstring(); |
| 230 » » if(strcmp(p, "X:none") == 0) |
| 231 » » » p = ""; |
| 232 » » print("%cg version %s%s%s\n", thechar, getgoversion(), *p ? " "
: "", p); |
174 exits(0); | 233 exits(0); |
175 } ARGEND | 234 } ARGEND |
176 | 235 |
177 if(argc < 1) | 236 if(argc < 1) |
178 usage(); | 237 usage(); |
179 | 238 |
180 // special flag to detect compilation of package runtime | 239 // special flag to detect compilation of package runtime |
181 compiling_runtime = debug['+']; | 240 compiling_runtime = debug['+']; |
182 | 241 |
183 pathname = mal(1000); | 242 pathname = mal(1000); |
184 if(getwd(pathname, 999) == 0) | 243 if(getwd(pathname, 999) == 0) |
185 strcpy(pathname, "/???"); | 244 strcpy(pathname, "/???"); |
186 | 245 |
187 if(yy_isalpha(pathname[0]) && pathname[1] == ':') { | 246 if(yy_isalpha(pathname[0]) && pathname[1] == ':') { |
188 // On Windows. | 247 // On Windows. |
189 windows = 1; | 248 windows = 1; |
190 | 249 |
191 // Canonicalize path by converting \ to / (Windows accepts both)
. | 250 // Canonicalize path by converting \ to / (Windows accepts both)
. |
192 for(p=pathname; *p; p++) | 251 for(p=pathname; *p; p++) |
193 if(*p == '\\') | 252 if(*p == '\\') |
194 *p = '/'; | 253 *p = '/'; |
195 } | 254 } |
196 | 255 |
197 fmtinstallgo(); | 256 fmtinstallgo(); |
198 fmtinstall('B', Bconv); // big numbers | |
199 fmtinstall('F', Fconv); // big float numbers | |
200 | |
201 betypeinit(); | 257 betypeinit(); |
202 if(widthptr == 0) | 258 if(widthptr == 0) |
203 fatal("betypeinit failed"); | 259 fatal("betypeinit failed"); |
204 | 260 |
205 lexinit(); | 261 lexinit(); |
206 typeinit(); | 262 typeinit(); |
207 lexinit1(); | 263 lexinit1(); |
208 yytinit(); | 264 yytinit(); |
209 | 265 |
210 blockgen = 1; | 266 blockgen = 1; |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 } | 581 } |
526 } | 582 } |
527 ········ | 583 ········ |
528 // check object header | 584 // check object header |
529 p = Brdstr(imp, '\n', 1); | 585 p = Brdstr(imp, '\n', 1); |
530 if(strcmp(p, "empty archive") != 0) { | 586 if(strcmp(p, "empty archive") != 0) { |
531 if(strncmp(p, "go object ", 10) != 0) { | 587 if(strncmp(p, "go object ", 10) != 0) { |
532 yyerror("import %s: not a go object file", file); | 588 yyerror("import %s: not a go object file", file); |
533 errorexit(); | 589 errorexit(); |
534 } | 590 } |
535 » » q = smprint("%s %s %s", getgoos(), thestring, getgoversion()); | 591 » » q = smprint("%s %s %s %s", getgoos(), thestring, getgoversion(),
expstring()); |
536 if(strcmp(p+10, q) != 0) { | 592 if(strcmp(p+10, q) != 0) { |
537 yyerror("import %s: object is [%s] expected [%s]", file,
p+10, q); | 593 yyerror("import %s: object is [%s] expected [%s]", file,
p+10, q); |
538 errorexit(); | 594 errorexit(); |
539 } | 595 } |
540 free(q); | 596 free(q); |
541 } | 597 } |
542 | 598 |
543 // assume files move (get installed) | 599 // assume files move (get installed) |
544 // so don't record the full path. | 600 // so don't record the full path. |
545 linehist(file + len - path->len - 2, -1, 1); // acts as #pragma lib | 601 linehist(file + len - path->len - 2, -1, 1); // acts as #pragma lib |
(...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1705 Sym *s, *s1; | 1761 Sym *s, *s1; |
1706 | 1762 |
1707 // byte alias | 1763 // byte alias |
1708 s = lookup("byte"); | 1764 s = lookup("byte"); |
1709 s->lexical = LNAME; | 1765 s->lexical = LNAME; |
1710 bytetype = typ(TUINT8); | 1766 bytetype = typ(TUINT8); |
1711 bytetype->sym = s; | 1767 bytetype->sym = s; |
1712 s1 = pkglookup("byte", builtinpkg); | 1768 s1 = pkglookup("byte", builtinpkg); |
1713 s1->lexical = LNAME; | 1769 s1->lexical = LNAME; |
1714 s1->def = typenod(bytetype); | 1770 s1->def = typenod(bytetype); |
| 1771 |
| 1772 // rune alias |
| 1773 s = lookup("rune"); |
| 1774 s->lexical = LNAME; |
| 1775 if(rune32) |
| 1776 runetype = typ(TINT32); |
| 1777 else |
| 1778 runetype = typ(TINT); |
| 1779 runetype->sym = s; |
| 1780 s1 = pkglookup("rune", builtinpkg); |
| 1781 s1->lexical = LNAME; |
| 1782 s1->def = typenod(runetype); |
1715 } | 1783 } |
1716 | 1784 |
1717 static void | 1785 static void |
1718 lexfini(void) | 1786 lexfini(void) |
1719 { | 1787 { |
1720 Sym *s; | 1788 Sym *s; |
1721 int lex, etype, i; | 1789 int lex, etype, i; |
1722 Val v; | 1790 Val v; |
1723 | 1791 |
1724 for(i=0; i<nelem(syms); i++) { | 1792 for(i=0; i<nelem(syms); i++) { |
(...skipping 20 matching lines...) Expand all Loading... |
1745 s = lookup(typedefs[i].name); | 1813 s = lookup(typedefs[i].name); |
1746 if(s->def == N) | 1814 if(s->def == N) |
1747 s->def = typenod(types[typedefs[i].etype]); | 1815 s->def = typenod(types[typedefs[i].etype]); |
1748 } | 1816 } |
1749 | 1817 |
1750 // there's only so much table-driven we can handle. | 1818 // there's only so much table-driven we can handle. |
1751 // these are special cases. | 1819 // these are special cases. |
1752 s = lookup("byte"); | 1820 s = lookup("byte"); |
1753 if(s->def == N) | 1821 if(s->def == N) |
1754 s->def = typenod(bytetype); | 1822 s->def = typenod(bytetype); |
| 1823 |
| 1824 s = lookup("rune"); |
| 1825 if(s->def == N) |
| 1826 s->def = typenod(runetype); |
1755 | 1827 |
1756 types[TNIL] = typ(TNIL); | 1828 types[TNIL] = typ(TNIL); |
1757 s = lookup("nil"); | 1829 s = lookup("nil"); |
1758 if(s->def == N) { | 1830 if(s->def == N) { |
1759 v.ctype = CTNIL; | 1831 v.ctype = CTNIL; |
1760 s->def = nodlit(v); | 1832 s->def = nodlit(v); |
1761 s->def->sym = s; | 1833 s->def->sym = s; |
1762 } | 1834 } |
1763 ········ | 1835 ········ |
1764 s = lookup("iota"); | 1836 s = lookup("iota"); |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1986 p = infile; | 2058 p = infile; |
1987 else | 2059 else |
1988 p = p+1; | 2060 p = p+1; |
1989 snprint(namebuf, sizeof(namebuf), "%s", p); | 2061 snprint(namebuf, sizeof(namebuf), "%s", p); |
1990 p = strrchr(namebuf, '.'); | 2062 p = strrchr(namebuf, '.'); |
1991 if(p != nil) | 2063 if(p != nil) |
1992 *p = 0; | 2064 *p = 0; |
1993 outfile = smprint("%s.%c", namebuf, thechar); | 2065 outfile = smprint("%s.%c", namebuf, thechar); |
1994 } | 2066 } |
1995 } | 2067 } |
LEFT | RIGHT |