⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpp.c

📁 LSI C-86 compiler,小日本写的C语言编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
					error(MSG_Xmiscls, p->name);
					Token = save;
					return (t);
				}
				while (iswhite(t) || t == '\n')
					t = egettok();
				Parms[i] = Token;
				nest = 0;
				while (t != 0 &&
					(t != ',' && t != ')' || nest != 0)) {
					if (t == '(')
						nest++;
					else if (t == ')')
						nest--;
					else if (t == '\n')
						*Token = ' ';
					Token = Tail;
					t = egettok();
				}
				while (Token > Parms[i] && iswhite(Token[-1]))
					Token--;
				*Token++ = '\0';
				if (t == ',')
					t = skip_egettok();
			}
			if (i != p->nparms)
				error(MSG_Xnumpar, p->name);
			for (; i < p->nparms; i++)
				Parms[i] = "";
		}
		/* let macro p sleep */
		p->flags &= ~DEFINED;
		if (Sleep >= SleepStack + MACNEST)
			error(MSG_macnst, NULL), exit(1);
		*Sleep++ = p;
		unget(MACFLAG);
		/* expand body */
		s = p->u.body;
		for (q = s + strlen(s); --q >= s; )
			if (*q == MACFLAG)
				ungets(Parms[get() - '0']);
			else
				unget(*q);
		Token = save;
	}
	return (t);
}




recursive
char	egettok()
{
	char	c;

	if ((c = egettok_eof()) == 0)
		error(MSG_unxeof, NULL), exit(1);
	return (c);
}


recursive
char	skip_egettok()
{
	char	t;

	while (t = egettok(), iswhite(t))
		;
	return (t);
}

void	skip_eol()
{
	while (Lex != '\n')
		gettok();
	put('\n');
}


void	do_include()
{
	char	t, c, buff[100], *p;

	t = skip_egettok();
	if (t == '"') {
		strcpy(buff, Token + 1);
		if (buff[strlen(buff) - 1] != '"')
			error(MSG_incmisquo, NULL);
		buff[strlen(buff) - 1] = '\0';
	}
	else if (t == '<') {
		p = buff;
		while ((c = get()) != '>') {
			if (c == '\n') {
				error(MSG_incmisbra, NULL);
				return;
			}
			*p++ = c;
		}
		*p = '\0';
	}
	else {
		error(MSG_incmisfil, NULL);
		return;
	}
#if	0
	skip_eol();
#endif
	pushFile(buff, t, NULL);
}

void	do_define()
{
	char	*name, *body, *p;
	char	t;
	int	i, np;
	char	*Parms[MAXPARM];
	bool	quote;

	/* get macro name */
	if (skip_gettok() != NAME) {
		error(MSG_defmisnam, NULL);
		skip_eol();
		return;
	}
	name = Token;
	Token = Tail + 1;
	np = -1;
	if ((t = gettok()) == '(') {
		/* parameter macro */
		np = 0;
		while ((t = skip_gettok()) == NAME) {
			Parms[np++] = Token;
			Token = Tail + 1;
			if ((t = skip_gettok()) != ',')
				break;
		}
		if (t != ')') {
			error(MSG_defbadpar, NULL);
			skip_eol();
			Token = Pool;
			return;
		}
		t = ' ';
	}
	/* get macro body */
	while (iswhite(t))
		t = gettok();
	body = p = Token;
	quote = NO;
	for (; t != '\n'; t = gettok()) {
		if (t == '#') {
			if ((t = get()) == '#') {
				/* ##: name concatenation */
				Token = p;
				t = get();
			} else {
				/* #: surround by double quote */
				quote = YES;
				Token = Tail;
			}
			while (iswhite(t))
				t = get();
			unget(t);
			continue;
		}
		if (quote)
			Token[-1] = '"';	/* change # to " */
		if (t == NAME) {
			for (i = 0; i < np; i++)
				if (strcmp(Parms[i], Token) == 0) {
					Token[0] = MACFLAG;
					Token[1] = '0' + i;
					Tail = Token + 2;
					break;
				}
		}
		if (quote)
			*Tail++ = '"';
		Token = Tail;
		if (! iswhite(t))
			p = Token;
		quote = NO;
	}
	*p = '\0';
	unget(t);
	/* register */
	install(name, body, np);
	Token = Pool;
}


void	do_undef()
{
	char	t;
	MACRO	*p;

	if ((t = skip_gettok()) != NAME)
		error(MSG_undmisnam, NULL);
	else {
		if ((p = lookup(Token)) != NULL)
			p->flags &= ~DEFINED;
	}
	skip_eol();
}





/*	Conditional Compilation		*/

int	search_else_endif()
{
	int	nest;
	char	t;
	FILEST	*fsave;
	int	lsave;

	fsave = FileSp;
	lsave = fsave->lineno;
	t = 0;
	nest = 1;
	for (;;) {
		skip_eol();
		if ((t = skip_gettok()) == '#') {
			t = skip_egettok();
			if (strcmp(Token, "if") == 0 ||
				strcmp(Token, "ifdef") == 0 ||
				strcmp(Token, "ifndef") == 0)
				nest++;
			else if (strcmp(Token, "endif") == 0) {
				if (--nest == 0) {
					Ifnest--;
					return (0);
				}
			} else if (nest == 1 &&
				(strcmp(Token, "else") == 0 ||
					strcmp(Token, "elif") == 0))
				return (1);
		} else if (t == 0) {
			error1(MSG_misendif, NULL, fsave->name, lsave);
			exit(1);
		}
	}
}



/*	special lex for #if	*/




char	twinlex(char c1, char c2, char l2, char c3, char l3)
{
	char	c;

	if ((c = get()) == c2)
		return (l2);
	if (c == c3)
		return (l3);
	unget(c);
	return (c1);
}


char	getlex1(char lex)
{
	switch (lex) {
	Case '<':
		return (twinlex('<', '<', SHR, '=', LE));
	Case '>':
		return (twinlex('>', '>', SHL, '=', GE));
	Case '=':
		return (twinlex('=', '=', EQ, 0, 0));
	Case '!':
		return (twinlex('!', '=', NE, 0, 0));
	Case '&':
		return (twinlex('&', '&', AND, 0, 0));
	Case '|':
		return (twinlex('|', '|', OR, 0, 0));
	Default:
		return (lex);
	}
}

char	ugetlex()
{
	return (EvalLex = getlex1(skip_gettok()));
}

recursive
char	getlex()
{
	return (EvalLex = getlex1(skip_egettok()));
}


tiny	levelof(char lex)
{
	switch (lex) {
	Case '?':		return (0);
	Case OR:		return (1);
	Case AND:		return (2);
	Case '|':		return (3);
	Case '^':		return (4);
	Case '&':		return (5);
	Case EQ: case NE:	return (6);
	Case '<': case LE: case '>': case GE:
				return (7);
	Case SHR: case SHL:	return (8);
	Case '+': case '-':	return (9);
	Case '*': case '/': case '%':
				return (10);
	Default:		return (11);
	}
}
#define	PRIMLEV	11



jmp_buf	Env;

void	synerror()
{
	error(MSG_ifsynX, Token);
	skip_eol();
	longjmp(Env, 1);
}

void	checkLex(char lex)
{
	if (EvalLex != lex)
		synerror();
}


char	digval(char c)
{
	c = tolower(c);
	if (isdigit(c))
		return (c - '0');
	if (islower(c))
		return (c - 'a' + 10);
	return (100);
}



long	valof(char *s)
{
	long	v, radix;
	char	c, *p;

	p = s;
	c = *p;
	if (c != '0')
		radix = 10;		/* decimal */
	else if (*++p == 'x' || *p == 'X')
		p++, radix = 16;	/* hexadecimal */
	else
		radix = 8;		/* octal */
	v = 0;
	while ((c = digval(*p)) < radix) {
		v = v * radix + c;
		p++;
	}
	/* skip suffixes */
	while ((c = tolower(*p)) == 'u' || c == 'l')
		p++;
	if (*p)
		error(MSG_badnum, s);
	return (v);
}



long	chaval(char *s)
{
	char	c, d;
	int	n;
	long	v;

	v = 0;
	while ((c = *s++) != '\0' && c != '\'') {
		if (is2byte(c) && *s) {
			v = (v << 16) | (c << 8) | *s++;
			continue;
		}
		if (c == '\\')
			switch (c = *s++) {
			Case 'a':	c = '\a';
			Case 'b':	c = '\b';
			Case 'f':	c = '\f';
			Case 'n':	c = '\n';
			Case 'r':	c = '\r';
			Case 't':	c = '\t';
			Case 'v':	c = '\v';
			Case 'x':
				c = 0;
				for (n = 0; n < 3; n++) {
					if ((d = digval(*s)) >= 16)
						break;
					c = c << 4 | d;
					s++;
				}
			Default:
				if ('0' <= c && c <= '7') {
					s--;
					c = 0;
					for (n = 0; n < 3; n++) {
						if ((d = digval(*s)) >= 8)
							break;
						c = c << 3 | d;
						s++;
					}
				}
			}
		v = v << 8 | c;
	}
	return (v);
}



recursive
long	eval1(tiny lev)
{
	long	v, w, u;
	char	op;

	if (lev == PRIMLEV) {
		if (EvalLex == '(') {
			v = eval0(0);
			checkLex(')');
			getlex();
			return (v);
		}
		if (EvalLex == '-')
			return (-eval0(PRIMLEV));
		if (EvalLex == '+')
			return (eval0(PRIMLEV));
		if (EvalLex == '~')
			return (~eval0(PRIMLEV));
		if (EvalLex == '!')
			return (!eval0(PRIMLEV));
		if (EvalLex == NUMBER) {
			v = valof(Token);
			getlex();
			return (v);
		}
		if (EvalLex == '\'') {
			v = chaval(Token + 1);
			getlex();
			return (v);
		}
		if (EvalLex == NAME && strcmp(Token, "defined") == 0) {
			if (ugetlex() == '(') {
				ugetlex(), checkLex(NAME);
				v = lookup(Token) != NULL;
				getlex(), checkLex(')');
			} else
				v = lookup(Token) != NULL;
			getlex();
			return (v);
		}
		if (EvalLex == NAME) {	/* undefined macro name */
			if (Undeferr)
				error(MSG_undefmacX, Token);
			getlex();
			return (0);
		}
		synerror();
	}
	v = eval1(lev + 1);
	while (levelof(EvalLex) == lev) {
		op = EvalLex;
		if (op == '?') {
			w = eval0(lev);
			checkLex(':');
			u = eval0(lev);
			return (v ? w : u);
		}
		w = eval0(lev + 1);
		switch (op) {
		Case '+':	v += w;
		Case '-':	v -= w;
		Case '*':	v *= w;
		Case '/':	v /= w;
		Case '%':	v %= w;
		Case '&':	v &= w;
		Case '|':	v |= w;
		Case '^':	v ^= w;
		Case SHR:	v <<= w;
		Case SHL:	v >>= w;
		Case EQ:	v = v == w;
		Case NE:	v = v != w;
		Case '>':	v = v > w;
		Case '<':	v = v < w;
		Case GE:	v = v >= w;
		Case LE:	v = v <= w;
		Case AND:	v = v && w;
		Case OR:	v = v || w;
		Default:	bug("eval1");
		}
	}
	return (v);
}


recursive
long	eval0(tiny lev)
{
	getlex();
	return (eval1(lev));
}


long	eval()
{
	long	v;

	if (setjmp(Env) == 0) {
		v = eval0(0);
		checkLex('\n');
		return (v);
	} else
		return (0);
}


void	do_if()
{
	if (Ifnest >= IFNEST)
		error(MSG_ifnst, NULL);
	else
		memcpy(&IfStack[Ifnest++], FileSp, sizeof(*FileSp));
	if (eval() == 0) {
		do {
			search_else_endif();
			if (strcmp(Token, "elif") != 0) {
				skip_eol();
				return;
			}
		} while (eval() == 0);
	}
}


void	do_ifdef(bool whendef)
{
	if (Ifnest >= IFNEST)
		error(MSG_ifnst, NULL);
	else
		memcpy(&IfStack[Ifnest++], FileSp, sizeof(*FileSp));
	if (skip_gettok() != NAME)
		error(MSG_ifdmisnam, NULL);
	else if ((lookup(Token) != NULL) != whendef) {
		do {
			search_else_endif();
			if (strcmp(Token, "elif") != 0) {
				skip_eol();
				return;
			}
		} while (eval() == 0);
	}
}


void	do_else_elif()
{
	if (Ifnest == 0)
		error(MSG_misif, NULL);
	/* skip until #endif */
	while (search_else_endif() != 0)
		;
	skip_eol();
}


void	do_endif()
{
	if (Ifnest == 0)
		error(MSG_misif, NULL);
	else
		Ifnest--;
	skip_eol();
}


void	do_line()
{
	if (skip_egettok() != NUMBER) {
		error(MSG_linmisnum, NULL);
		skip_eol();
		return;
	}
	FileSp->lineno = atoi(Token) - 1;
	if (skip_egettok() == '"') {
		Token[strlen(Token) - 1] = '\0';
		strcpy(FileSp->name, Token + 1);
	}
	while (Lex != '\n')
		gettok();
	Lineno = -1;
}


void	do_pragma()
{
	char	c;

	if (NoSharp)
		skip_eol();
	else {
		fput("#p");
		do {
			c = gettok();
			fput(Token);
		} while (c != '\n');
	}
}


void	do_error()
{
	char	msg[100];
	char	*p, c;

	p = msg;
	while ((c = get()) == ' ' || c == '\t')
		;
	while (p < msg + sizeof(msg) - 1 && c != '\n' && c != 0) {
		*p++ = c;
		c = get();
	}
	*p = '\0';
	while (c != '\n' && c != 0)
		c = get();
	unget(c);
	error(MSG_errordir, msg);
	get();
}


void	do_cpp()
{
	bool	tol;
	char	t;

	/* main loop */
	tol = YES;
	t = 0;
	while ((t = egettok_eof()) != 0) {
		if (t == '#' && tol) {
			DirectiveMode = YES;
			t = skip_gettok();
			if (t == '\n')
				;
			else if (strcmp(Token, "include") == 0)
				do_include();
			else if (strcmp(Token, "define") == 0)
				do_define();
			else if (strcmp(Token, "undef") == 0)
				do_undef();
			else if (strcmp(Token, "if") == 0)
				do_if();
			else if (strcmp(Token, "ifdef") == 0)
				do_ifdef(YES);
			else if (strcmp(Token, "ifndef") == 0)
				do_ifdef(NO);
			else if (strcmp(Token, "elif") == 0)
				do_else_elif();
			else if (strcmp(Token, "else") == 0)
				do_else_elif();
			else if (strcmp(Token, "endif") == 0)
				do_endif();
			else if (strcmp(Token, "line") == 0)
				do_line();
			else if (strcmp(Token, "pragma") == 0)
				do_pragma();
			else if (strcmp(Token, "error") == 0)
				do_error();
			else {
				error(MSG_badstmX, Token);
				skip_eol();
			}
			DirectiveMode = NO;
			lineadj();
		} else {
			fput(Token);
			if (t == '\n') {
				lineadj();
				tol = YES;
			}
			else if (!isspace(t))
				tol = NO;
		}
	}
	if (Ifnest != 0) {
		Ifnest--;
		error1(MSG_misendif, NULL, IfStack[Ifnest].name, IfStack[Ifnest].lineno);
	}
}


void	main(int argc, char *argv[])
{
	static	char	usage[] =
"LSI C preprocessor ver 1.5 [" __DATE__ "]\n\
\twritten by Mori Koichiro\n\
\tusage: cpp [-s] [-w] [-c] [-DMACRO] [-IINCDIR] [-ooutput] [input...]\n";

	char	c, *p, *s, *outf;
	int	i, inc;
	char	name[100];
	time_t	t;

	time(&t);
	Timep = localtime(&t);
	inc = 0;
	installf("__FILE__", macFile);
	installf("__LINE__", macLine);
	installf("__TIME__", macTime);
	installf("__DATE__", macDate);
	installf("__eval__", macEval);
	outf = NULL;
	while (++argv, --argc != 0 && argv[0][0] == '-') {
		p = argv[0] + 1;
		switch (*p++) {
		Case 'x':
			while (c = *p++)
				if (isalpha(c))
					Debug[tolower(c) - 'a'] = YES;
				else if (c == '#')
					setmem(Debug, 26, YES);
		Case 'w':
			NoWarn = YES;
		Case 'B':
			BCPL_comment = YES;
#if 0
		Case 'C':
			Keep_comment = YES;
#endif
		Case 'd':
			fprintf(stderr, "cpp: Warning: -d is obsolete; use -D\n");
		/* fall thru */
		case 'D':
			/* get macro definition */
			s = name;
			while ((c = *p++) != '\0' && c != '=')
				*s++ = c;
			*s = '\0';
			if (c == '\0')
				p = "1";
			install(name, p, -1);
		Case 'i':
			fprintf(stderr, "cpp: Warning: -i is obsolete; use -I\n");
		/* fall thru */
		case 'I':
			/* include directory */
			if (inc >= MAXDIR)
				fprintf(stderr, "too many -i\n"), exit(1);
			Incdir[inc++] = p;
		Case 's':
			NoSharp = YES;
		Case 'o':
			if (*p != '\0')
				outf = p;
			else if (++argv, --argc != 0)
				outf = *argv;
			else
				fprintf(stderr, usage), exit(1);
		Case 'j':
			Jap = *p - '0';
		Case 'c':
			CommNest = YES;
		Case 'y':
			Charcode = *p;
			if (Charcode != 0 && Charcode != '0' && Charcode != '1' && Charcode != '2')
				goto err;
		Default:
		err:
			fprintf(stderr, usage), exit(1);
		}
	}
	Incdir[inc] = NULL;
	if (outf == NULL)
		Ofp = stdout;
	else
		Ofp = efopen(outf, "w");
	if (argc == 0) {
		pushFile("", ' ', stdin);
		do_cpp();
	} else {
		for (i = 0; i < argc; i++) {
			pushFile(argv[i], ' ', NULL);
			do_cpp();
		}
	}
	efclose(Ofp);
	exit(Errcode);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -