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

📄 litc.c

📁 自己做的一个C语言的解释器 给大家做个参考
💻 C
📖 第 1 页 / 共 2 页
字号:
		strcpy(i.var_name, token);
		local_push(i);
		get_token();
	}while(*token == ',');

	if(*token != ';')
		sntx_err(SEMI_EXPECTED);
}

/* Call a function */
void call(void)
{
	char *loc, *temp;
	int lvartemp;

	loc = find_func(token); /* find entry point of function */
	if(loc == NULL){
		sntx_err(FUNC_UNDEF); /* function not defined */
	}
	else{
		lvartemp = lvartos; /* save local var stack index */
		get_args(); /* get function arguments */
		temp = prog; /* save return location */
		func_push(lvartemp); /* save local var stack index */
		prog = loc; /* reset prog to start of function */
		get_params(); /* load the function's parameters with
						the values of the arguments */
		interp_block(); /* interpret the function */
		prog = temp; /* reset the program pointer */
		lvartos = func_pop(); /*reset the local var stack */
	}
}

/*
	Push the arguments to a function onto the local
	variable stack.
*/
void get_args(void)
{
	int value, count, temp[NUM_PARAMS];
	struct var_type i;

	count = 0;
	get_token();
	if(*token != '(')
		sntx_err(PAREN_EXPECTED);

	/* process a comma-separated list of values */
	do{
		eval_exp(&value);
		temp[count] = value; /* save temporarily */
		get_token();
		count++;
	}while(*token == ',');
	count--;

	/* now, push on local_var_stack in reverse order */
	for(; count >= 0; count--){
		i.value = temp[count];
		i.v_type = ARG;
		local_push(i);
	}
}

/* Get function parameters. */
void get_params(void)
{
	struct var_type *p;
	int i;

	i = lvartos - 1;
	do{ /* process comma-separated list of parameters */
		get_token();
		p = &local_var_stack[i];

		if(*token != ')'){
			if(tok != INT && tok != CHAR)
				sntx_err(TYPE_EXPECTED);

			p->v_type = token_type;
			get_token();

			/*link parameter name with argument already
			on local var stack */
			strcpy(p->var_name, token);

			get_token();
			i--;
		}
		else
			break;
	}while(*token == ',');

	if(*token != ')')
		sntx_err(PAREN_EXPECTED);
}

/* Return from a function. */
void func_ret(void)
{
	int value = 0;

	/* get return value, if any */
	eval_exp(&value);

	ret_value = value;
}

/* Push a local variable. */
void local_push(struct var_type i)
{
	if(lvartos > NUM_LOCAL_VARS)
		sntx_err(TOO_MANY_LVARS);

	local_var_stack[lvartos] = i;
	lvartos++;
}

/* Pop index into local variable stack. */
int func_pop(void)
{
	functos--;
	if(functos < 0)
		sntx_err(RET_NOCALL);

	return call_stack[functos];
}

/* Push index of local variable stack. */
void func_push(int i)
{
	if(functos > NUM_FUNC)
		sntx_err(NEST_FUNC);

	call_stack[functos] = i;
	functos++;
}

/* Assign a value to a variable. */
void assign_var(char *var_name, int value)
{
	register int i;

	/* first, see if it's a local variable */
	for(i = lvartos - 1; i >= call_stack[functos - 1]; i--){
		if(!strcmp(local_var_stack[i].var_name, var_name)){
			local_var_stack[i].value = value;
			return;
		}
	}

	if(i < call_stack[functos - 1]){
		/* if not local, try global var table */
		for(i = 0; i < NUM_GLOBAL_VARS; i++){
			if(!strcmp(global_vars[i].var_name, var_name)){
				global_vars[i].value = value;
				return;
			}
		}
	}

	sntx_err(NOT_VAR); /* variable not found */
}

/* Find the value of a variable */
int find_var(char *s)
{
	register int i;

	/* first, see if it's a local variable */
	for(i = lvartos - 1; i >= call_stack[functos - 1]; i--)
		if(!strcmp(local_var_stack[i].var_name, token))
			return local_var_stack[i].value;

	/* otherwise, try global vars */
	for(i = 0; i < NUM_GLOBAL_VARS; i++)
		if(!strcmp(global_vars[i].var_name, s))
			return global_vars[i].value;

	sntx_err(NOT_VAR); /* variable not found */
	return -1;
}

/*
	Determine if an identifier is a variable.
	Return 1 if variable is found, 0 othewise.
*/
int is_var(char *s)
{
	register int i;

	/* first, see if it's a local variable */
	for(i = lvartos - 1; i >= call_stack[functos - 1]; i--)
		if(!strcmp(local_var_stack[i].var_name, token))
			return 1;

	/* otherwise, try global vars */
	for(i = 0; i < NUM_GLOBAL_VARS; i++)
		if(!strcmp(global_vars[i].var_name, s))
			return 1;

	return 0;
}

/* Execute an if statement. */
void exec_if(void)
{
	int cond;

	eval_exp(&cond); /* get if expression */

	if(cond){ /* is true so process target of IF */
		interp_block();
	}
	else{
		/* otherwise skip around IF block and
			process the ELSE, if present */
		find_eob(); /* find start of next line */
		get_token();

		if(tok != ELSE){
			putback(); /* restore token if no ELSE is present */
			return;
		}
		interp_block();
	}
}

/* Execute a while loop. */
void exec_while(void)
{
	int cond;
	char *temp, *temp2;/*Rev 1.04 yock.yu 05-02-18*/

	putback();
	temp = prog; /* save location of top of while loop */
	temp2 = prog;/*Rev 1.04 yock.yu 05-02-18*/

	while(1){/*Rev 1.04 yock.yu 05-02-18*/
		get_token();
		eval_exp(&cond); /* check the conditional expression */
		if(cond)
			interp_block(); /* if true, interpret */
		else{ /* otherwise, skip around loop */
			/*find_eob();/*Rev 1.04 yock.yu 05-02-18*/
			prog = temp2;
			return;
		}
		if(temp2 < prog)/*Rev 1.04 yock.yu 05-02-18*/
			temp2 = prog;/*Rev 1.04 yock.yu 05-02-18*/
		
		prog = temp; /* loop back to top */
	}
}

/* Execute a do loop */
void exec_do(void)
{
	int cond;
	char *temp;

	putback();
	temp = prog; /* save location of top of do loop */

	get_token(); /* get start of loop */
	interp_block(); /*interpret loop */
	get_token();
	if(tok != WHILE)
		sntx_err(WHILE_EXPECTED);

	eval_exp(&cond); /* check the loop condition */
	if(cond)
		prog = temp; /* if true loop; otherwise, continue on */
}

/* Find the end of a block */
void find_eob(void)
{
	int brace;

/*Rev 1.03 yock.yu 05-02-16 start	*/
	if(bak_gblock == gblock){
		while(*(++prog) != '\r');
	}
	else{
/*Rev 1.03 yock.yu 05-02-16 end*/
		get_token();
		brace = 1;
		do{
			get_token();
			if(*token == '{')
				brace++;
			else if(*token == '}')
				brace--;
		}while(brace);
	}
}

/* Execute a for loop. */
void exec_for(void)
{
	int cond;
	char *temp, *temp2, *temp3;/*Rev 1.03 yock.yu 05-02-17*/
	int brace;

	get_token();
	eval_exp(&cond); /* initialization expression */
	if(*token != ';')
		sntx_err(SEMI_EXPECTED);
	prog++; /* get past the ; */
	temp = prog;
	temp3 = prog;
	for(;;){
		eval_exp(&cond); /* check the condition */
		if(*token != ';')
			sntx_err(SEMI_EXPECTED);
		prog++;
		temp2 = prog;

		/* find the start of the for block */
		brace = 1;
		while(brace){
			get_token();
			if(*token == '(')
				brace++;
			else if(*token == ')')
				brace--;
		}

		if(cond)
			interp_block(); /* if true, interpret */
		else{ /* otherwise, skip around loop */
			/*find_eob();*//*Rev 1.03 yock.yu 05-02-17*/
			prog = temp3;/*Rev 1.03 yock.yu 05-02-17*/
			return;
		}
		if(temp3 < prog)/*Rev 1.03 yock.yu 05-02-17*/
			temp3 = prog;/*Rev 1.03 yock.yu 05-02-17*/
		prog = temp2;
		eval_exp(&cond); /* do the increment */
		prog = temp; /* loop back to top */
	}
}

/*Rev 1.05 yock.yu 05-02-18 start*/
/* Execute branch condition. */
void exec_switch(void)
{
	int cond, val;

	eval_exp(&cond);

	get_token();
	if(token_type != BLOCK && *token != '{')
		sntx_err(QUOTE_EXPECTED);
	
	gblock++;

	while(1){
		get_token();
		if(tok != CASE)
			sntx_err(SYNTAX);

		eval_exp(&val);

		if(cond == val){
			while(tok != BREAK && *token != '}')
				interp_block();
			break;
		}
		else{
			do{
				get_token();
				if(*token == '}'){
					gblock--;
					return;
				}
			}while(tok != CASE);
			putback();
		}
	}

	find_eob();
}
/*Rev 1.05 yock.yu 05-02-18 end*/

⌨️ 快捷键说明

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