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

📄 codegen.c

📁 Calc Software Package for Number Calc
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (gettoken() != T_LEFTBRACE) {		scanerror(T_SEMICOLON, "Missing left brace for initialization list");		(void) tokenmode(oldmode);		return -1;	}	for (index = 0; ; index++) {		switch(gettoken()) {		case T_COMMA:		case T_NEWLINE:			continue;		case T_RIGHTBRACE:			(void) tokenmode(oldmode);			return index;		case T_LEFTBRACE:			rescantoken();			addop(OP_DUPLICATE);			addopone(OP_ELEMADDR, index);			(void) getinitlist();			break;		default:			rescantoken();			getopassignment();		}		addopone(OP_ELEMINIT, index);		switch (gettoken()) {		case T_COMMA:		case T_NEWLINE:			continue;		case T_RIGHTBRACE:			(void) tokenmode(oldmode);			return index;		default:			scanerror(T_SEMICOLON,				  "Missing right brace for initialization list");			(void) tokenmode(oldmode);			return -1;		}	}}/* * Get a condition. * condition = '(' assignment ')'. */static voidgetcondition(void){	if (gettoken() != T_LEFTPAREN) {		scanerror(T_SEMICOLON,			  "Missing left parenthesis for condition");		return;	}	(void) getexprlist();	if (gettoken() != T_RIGHTPAREN) {		scanerror(T_SEMICOLON,			  "Missing right parenthesis for condition");		return;	}}/* * Get an expression list consisting of one or more expressions, * separated by commas.	 The value of the list is that of the final expression. * This is the top level routine for parsing expressions. * Returns flags describing the type of the last assignment or expression found. * exprlist = assignment [ ',' assignment ] ... */static intgetexprlist(void){	int	type;	type = getopassignment();	while (gettoken() == T_COMMA) {		addop(OP_POP);		type = getopassignment();	}	rescantoken();	return type;}/* * Get an opassignment or possibly just an assignment or expression. * Returns flags describing the type of assignment or expression found. * assignment = lvalue '=' assignment *	| lvalue '+=' assignment *	| lvalue '-=' assignment *	| lvalue '*=' assignment *	| lvalue '/=' assignment *	| lvalue '%=' assignment *	| lvalue '//=' assignment *	| lvalue '&=' assignment *	| lvalue '|=' assignment *	| lvalue '<<=' assignment *	| lvalue '>>=' assignment *	| lvalue '^=' assignment *	| lvalue '**=' assignment *	| orcond. */static intgetopassignment(void){	int type;		/* type of expression */	long op;		/* opcode to generate */	type = getassignment();	switch (gettoken()) {	case T_PLUSEQUALS:	op = OP_ADD; break;	case T_MINUSEQUALS:	op = OP_SUB; break;	case T_MULTEQUALS:	op = OP_MUL; break;	case T_DIVEQUALS:	op = OP_DIV; break;	case T_SLASHSLASHEQUALS: op = OP_QUO; break;	case T_MODEQUALS:	op = OP_MOD; break;	case T_ANDEQUALS:	op = OP_AND; break;	case T_OREQUALS:	op = OP_OR; break;	case T_LSHIFTEQUALS:	op = OP_LEFTSHIFT; break;	case T_RSHIFTEQUALS:	op = OP_RIGHTSHIFT; break;	case T_POWEREQUALS:	op = OP_POWER; break;	case T_HASHEQUALS:	op = OP_HASHOP; break;	case T_TILDEEQUALS:	op = OP_XOR; break;	case T_BACKSLASHEQUALS: op = OP_SETMINUS; break;	default:		rescantoken();		return type;	}	if (isrvalue(type)) {		scanerror(T_NULL, "Illegal assignment");		(void) getopassignment();		return (EXPR_RVALUE | EXPR_ASSIGN);	}	writeindexop();	for(;;) {		addop(OP_DUPLICATE);		if (gettoken() == T_LEFTBRACE) {			rescantoken();			addop(OP_DUPVALUE);			getinitlist();			while (gettoken() == T_ASSIGN)				getinitlist();			rescantoken();		} else {			rescantoken();			(void) getassignment();		}		addop(op);		addop(OP_ASSIGN);		switch (gettoken()) {		case T_PLUSEQUALS:	op = OP_ADD; break;		case T_MINUSEQUALS:	op = OP_SUB; break;		case T_MULTEQUALS:	op = OP_MUL; break;		case T_DIVEQUALS:	op = OP_DIV; break;		case T_SLASHSLASHEQUALS: op = OP_QUO; break;		case T_MODEQUALS:	op = OP_MOD; break;		case T_ANDEQUALS:	op = OP_AND; break;		case T_OREQUALS:	op = OP_OR; break;		case T_LSHIFTEQUALS:	op = OP_LEFTSHIFT; break;		case T_RSHIFTEQUALS:	op = OP_RIGHTSHIFT; break;		case T_POWEREQUALS:	op = OP_POWER; break;		case T_HASHEQUALS:	op = OP_HASHOP; break;		case T_TILDEEQUALS:	op = OP_XOR; break;		case T_BACKSLASHEQUALS: op = OP_SETMINUS; break;		default:			rescantoken();			return EXPR_ASSIGN;		}	}}/* * Get an assignment (lvalue = ...) or possibly just an expression */static intgetassignment (void){	int type;		/* type of expression */	switch(gettoken()) {	case T_COMMA:	case T_SEMICOLON:	case T_NEWLINE:	case T_RIGHTPAREN:	case T_RIGHTBRACKET:	case T_RIGHTBRACE:	case T_EOF:		addop(OP_UNDEF);		rescantoken();		return EXPR_RVALUE;	}	rescantoken();	type = getaltcond();	switch (gettoken()) {	case T_NUMBER:	case T_IMAGINARY:		addopone(OP_NUMBER, tokennumber());		type = (EXPR_RVALUE | EXPR_CONST);		/*FALLTHRU*/	case T_STRING:	case T_SYMBOL:	case T_OLDVALUE:	case T_LEFTPAREN:	case T_PLUSPLUS:	case T_MINUSMINUS:	case T_NOT:		scanerror(T_NULL, "Missing operator");		return type;	case T_ASSIGN:		break;	default:		rescantoken();		return type;	}	if (isrvalue(type)) {		scanerror(T_SEMICOLON, "Illegal assignment");		(void) getassignment();		return (EXPR_RVALUE | EXPR_ASSIGN);	}	writeindexop();	if (gettoken() == T_LEFTBRACE) {		rescantoken();		getinitlist();		while (gettoken() == T_ASSIGN)			getinitlist();		rescantoken();		return EXPR_ASSIGN;	}	rescantoken();	(void) getassignment();	addop(OP_ASSIGN);	return EXPR_ASSIGN;}/* * Get a possible conditional result expression (question mark). * Flags are returned indicating the type of expression found. * altcond = orcond [ '?' orcond ':' altcond ]. */static intgetaltcond(void){	int type;		/* type of expression */	LABEL donelab;		/* label for done */	LABEL altlab;		/* label for alternate expression */	type = getorcond();	if (gettoken() != T_QUESTIONMARK) {		rescantoken();		return type;	}	clearlabel(&donelab);	clearlabel(&altlab);	addoplabel(OP_JUMPZ, &altlab);	type = getaltcond();	if (gettoken() != T_COLON) {		scanerror(T_SEMICOLON,			  "Missing colon for conditional expression");		return EXPR_RVALUE;	}	addoplabel(OP_JUMP, &donelab);	setlabel(&altlab);	type |= getaltcond();	setlabel(&donelab);	return type;}/* * Get a possible conditional or expression. * Flags are returned indicating the type of expression found. * orcond = andcond [ '||' andcond ] ... */static intgetorcond(void){	int type;		/* type of expression */	LABEL donelab;		/* label for done */	clearlabel(&donelab);	type = getandcond();	while (gettoken() == T_OROR) {		addoplabel(OP_CONDORJUMP, &donelab);		type |= getandcond();	}	rescantoken();	if (donelab.l_chain >= 0)		setlabel(&donelab);	return type;}/* * Get a possible conditional and expression. * Flags are returned indicating the type of expression found. * andcond = relation [ '&&' relation ] ... */static intgetandcond(void){	int type;		/* type of expression */	LABEL donelab;		/* label for done */	clearlabel(&donelab);	type = getrelation();	while (gettoken() == T_ANDAND) {		addoplabel(OP_CONDANDJUMP, &donelab);		type |= getrelation();	}	rescantoken();	if (donelab.l_chain >= 0)		setlabel(&donelab);	return type;}/* * Get a possible relation (equality or inequality), or just an expression. * Flags are returned indicating the type of relation found. * relation = sum '==' sum *	| sum '!=' sum *	| sum '<=' sum *	| sum '>=' sum *	| sum '<' sum *	| sum '>' sum *	| sum. */static intgetrelation(void){	int type;		/* type of expression */	long op;		/* opcode to generate */	type = getsum();	switch (gettoken()) {	case T_EQ: op = OP_EQ; break;	case T_NE: op = OP_NE; break;	case T_LT: op = OP_LT; break;	case T_GT: op = OP_GT; break;	case T_LE: op = OP_LE; break;	case T_GE: op = OP_GE; break;	default:		rescantoken();		return type;	}	if (islvalue(type))		addop(OP_GETVALUE);	(void) getsum();	addop(op);	return EXPR_RVALUE;}/* * Get an expression made up of sums of products. * Flags indicating the type of expression found are returned. * sum = product [ {'+' | '-'} product ] ... */static intgetsum(void){	int type;		/* type of expression found */	long op;		/* opcode to generate */	type = EXPR_RVALUE;	switch(gettoken()) {	case T_PLUS:		(void) getproduct();		addop(OP_PLUS);		break;	case T_MINUS:		(void) getproduct();		addop(OP_NEGATE);		break;	default:		rescantoken();		type = getproduct();	}	for (;;) {		switch (gettoken()) {		case T_PLUS:	op = OP_ADD; break;		case T_MINUS:	op = OP_SUB; break;		case T_HASH: op = OP_HASHOP; break;		default:			rescantoken();			return type;		}		if (islvalue(type))			addop(OP_GETVALUE);		(void) getproduct();		addop(op);		type = EXPR_RVALUE;	}}/* * Get the product of arithmetic or expressions. * Flags indicating the type of expression found are returned. * product = orexpr [ {'*' | '/' | '//' | '%'} orexpr ] ... */static intgetproduct(void){	int type;		/* type of value found */	long op;		/* opcode to generate */	type = getorexpr();	for (;;) {		switch (gettoken()) {		case T_MULT:	op = OP_MUL; break;		case T_DIV:	op = OP_DIV; break;		case T_MOD:	op = OP_MOD; break;		case T_SLASHSLASH: op = OP_QUO; break;		default:			rescantoken();			return type;		}		if (islvalue(type))			addop(OP_GETVALUE);		(void) getorexpr();		addop(op);		type = EXPR_RVALUE;	}}/* * Get an expression made up of arithmetic or operators. * Flags indicating the type of expression found are returned. * orexpr = andexpr [ '|' andexpr ] ... */static intgetorexpr(void){	int type;		/* type of value found */	type = getandexpr();	while (gettoken() == T_OR) {		if (islvalue(type))			addop(OP_GETVALUE);		(void) getandexpr();		addop(OP_OR);		type = EXPR_RVALUE;	}	rescantoken();	return type;}/* * Get an expression made up of arithmetic and operators. * Flags indicating the type of expression found are returned. * andexpr = shiftexpr [ '&' shiftexpr ] ... */static intgetandexpr(void){	int type;		/* type of value found */	long op;	type = getshiftexpr();	for (;;) {		switch (gettoken()) {		case T_AND: op = OP_AND; break;		case T_TILDE: op = OP_XOR; break;		case T_BACKSLASH: op = OP_SETMINUS; break;		default:			rescantoken();			return type;		}		if (islvalue(type))			addop(OP_GETVALUE);		(void) getshiftexpr();		addop(op);		type = EXPR_RVALUE;	}}/* * Get a shift or power expression. * Flags indicating the type of expression found are returned. * shift = '+' shift *	 | '-' shift *	 | '/' shift *	 | '\' shift *	 | '~' shift *	 | '#' shift *	 | reference '^' shiftexpr *	 | reference '<<' shiftexpr *	 | reference '>>' shiftexpr *	 | reference. */static intgetshiftexpr(void){	int type;		/* type of value found */	long op;		/* opcode to generate */	op = 0;	switch (gettoken()) {	case T_PLUS:		op = OP_PLUS; break;	case T_MINUS:		op = OP_NEGATE; break;	case T_NOT:		op = OP_NOT; break;	case T_DIV:		op = OP_INVERT; break;	case T_BACKSLASH:	op = OP_BACKSLASH; break;	case T_TILDE:		op = OP_COMP; break;	case T_HASH:		op = OP_CONTENT; break;	}	if (op) {		(void) getshiftexpr();		addop(op);		return EXPR_RVALUE;	}	rescantoken();	type = getreference();	switch (gettoken()) {	case T_POWER:		op = OP_POWER; break;	case T_LEFTSHIFT:	op = OP_LEFTSHIFT; break;	case T_RIGHTSHIFT:	op = OP_RIGHTSHIFT; break;	default:		rescantoken();		return type;	}	if (islvalue(type))		addop(OP_GETVALUE);	(void) getshiftexpr();	addop(op);	return EXPR_RVALUE;}/* * set an address or dereference indicator * address = '&' term * dereference = '*' term */static intgetreference(void){	int type;	switch(gettoken()) {	case T_ANDAND:		scanerror(T_NULL, "&& used as prefix operator");		/*FALLTHRU*/	case T_AND:		type = getreference();		addop(OP_PTR);		type = EXPR_RVALUE;		break;	case T_MULT:		(void) getreference();		addop(OP_DEREF);		type = 0;		break;	case T_POWER:			/* '**' or '^' */		(void) getreference();		addop(OP_DEREF);		addop(OP_DEREF);		type = 0;		break;	default:		rescantoken();		type = getincdecexpr();	}	return type;}/* * get an increment or decrement expression * ++expr, --expr, expr++, expr-- */static intgetincdecexpr(void){	int type;	int tok;	type = getterm();	tok = gettoken();	if (tok == T_PLUSPLUS || tok == T_MINUSMINUS) {		if (isrvalue(type))				scanerror(T_NULL, "Bad ++ usage");		writeindexop();		if (tok == T_PLUSPLUS)			addop(OP_POSTINC);		else			addop(OP_POSTDEC);		for (;;) {			tok = gettoken();			switch(tok) {			case T_PLUSPLUS:				addop(OP_PREINC);				continue;			case T_MINUSMINUS:				addop(OP_PREDEC);				continue;			default:				addop(OP_POP);				break;			}			break;		}		type = EXPR_RVALUE | EXPR_ASSIGN;	}	if (tok == T_NOT) {		addopfunction(OP_CALL, getbuiltinfunc("fact"), 1);		tok = gettoken();		type = EXPR_RVALUE;	}	rescantoken();	return type;}/* * Get a single term. * Flags indicating the type of value found are returned. * term = lvalue *	| lvalue '[' assignment ']' *	| lvalue '++' *	| lvalue '--' *	| real_number *	| imaginary_number *	| '.' *	| string *	| '(' assignment ')' *	| function [ '(' [assignment  [',' assignment] ] ')' ] *	| '!' term */static intgetterm(void){	int type;		/* type of term found */	int oldmode;	type = 0;	switch (gettoken()) {	case T_NUMBER:		addopone(OP_NUMBER, tokennumber());		type = (EXPR_RVALUE | EXPR_CONST);		break;	case T_IMAGINARY:		addopone(OP_IMAGINARY, tokennumber());		type = (EXPR_RVALUE | EXPR_CONST);		break;	case T_OLDVALUE:		addop(OP_OLDVALUE);		type = 0;		break;	case T_STRING:		addopone(OP_STRING, tokenstring());		type = EXPR_RVALUE;		break;	case T_PLUSPLUS:		if (isrvalue(getterm()))			scanerror(T_NULL, "Bad ++ usage");		writeindexop();		addop(OP_PREINC);		type = EXPR_ASSIGN;		break;	case T_MINUSMINUS:		if (isrvalue(getterm()))			scanerror(T_NULL, "Bad -- usage");		writeindexop();		addop(OP_PREDEC);		type = EXPR_ASSIGN;		break;	case T_LEFTPAREN:		oldmode = tokenmode(TM_DEFAULT);		type = getexprlist();		if (gettoken() != T_RIGHTPAREN)			scanerror(T_SEMICOLON,				  "Missing right parenthesis");		(void) tokenmode(oldmode);		break;	case T_MAT:		getonematrix(SYM_UNDEFINED);		type = EXPR_ASSIGN;		break;	case T_OBJ:

⌨️ 快捷键说明

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