The Go Programming Language

Text file src/cmd/gc/lex.c

     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	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.