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

📄 ceval.c

📁 smallbasic for linux
💻 C
字号:
/**	expressions (byte-code)**	Nicholas Christopoulos**	This program is distributed under the terms of the GPL v2.0 or later*	Download the GNU Public License (GPL) from www.gnu.org*/#include "sys.h"#include "str.h"#include "kw.h"#include "panic.h"#include "bc.h"extern void	sc_raise(const char *fmt, ...) SEC(BCSCAN);extern int	scan_line;extern int	scan_error;#define	IP						bc_in->cp#define	CODE(x)					bc_in->ptr[(x)]#define	CODE_PEEK()				CODE(IP)#define	CHECKOP1(s)				if (CODE(IP) == kwTYPE_OPR && CODE(IP+1) == (s)) { IP += 2; return (s); }#define	CHECKOP2(s,o)			if (CODE(IP) == kwTYPE_OPR && CODE(IP+1) == (s)[0] && CODE(IP+2) == kwTYPE_OPR && CODE(IP+3) == (s)[1]) { IP += 4; return (o); }void	cev_udp(void)			SEC(TRASH);void	cev_udp(void)			{ sc_raise("(EXPR): UDP INSIDE EXPR"); }#if defined(_PalmOS)void	cev_missing_rp(void)	SEC(TRASH);void	cev_missing_rp(void)	{ sc_raise("(EXPR): MISSING ')'"); }void	cev_opr_err(void)		SEC(TRASH);void	cev_opr_err(void)		{ sc_raise("(EXPR): SYNTAX ERROR (1st OP)"); }#else#define	cev_missing_rp()		printf("C %s:%d, BAS: %d, EXPR: MISSING ')' (CS:IP=%d)", __FILE__, __LINE__, scan_line, CODE_PEEK() | scan_error++)#define	cev_opr_err()			printf("C %s:%d, BAS: %d, EXPR: SYNTAX ERROR (1st OP) (CS:IP=%d)", __FILE__, __LINE__, scan_line, CODE_PEEK() | scan_error++)#endifvoid	cev_log(void)	SEC(BCSCAN);static bc_t	*bc_in;static bc_t	*bc_out;#define	cev_add1(x)		bc_add1(bc_out, (x))#define	cev_add2(x, y)	bc_add2c(bc_out, (x), (y))/**	prim*/void	cev_prim(void)	SEC(BCSCAN);void	cev_prim(){	byte	code;	word	len;	if	( scan_error )	return;	code = CODE(IP);	IP ++;	cev_add1(code);	switch ( code )	{	case	kwTYPE_INT:		bc_add_n(bc_out, bc_in->ptr+bc_in->cp, 4);		IP += 4;		break;	case	kwTYPE_NUM:		bc_add_n(bc_out, bc_in->ptr+bc_in->cp, 8);		IP += 8;		break;	case	kwTYPE_STR:		memcpy(&len, bc_in->ptr+bc_in->cp, 2);		IP += 2;		bc_add1i(bc_out, len);		bc_add_n(bc_out, bc_in->ptr+bc_in->cp, len);		IP += len;		break;	case	kwTYPE_CALL_UDP:		cev_udp();		break;	case	kwTYPE_CALL_UDF:		bc_add_n(bc_out, bc_in->ptr+bc_in->cp, 2);		IP += 2;		// no 'break' here	case	kwTYPE_VAR:		bc_add_n(bc_out, bc_in->ptr+bc_in->cp, 2);		IP += 2;		if	( CODE_PEEK() == kwTYPE_LEVEL_BEGIN )	{			cev_add1(kwTYPE_LEVEL_BEGIN);			IP ++;			if	( CODE_PEEK() == kwTYPE_LEVEL_END )	{		// NULL ARRAYS				cev_add1(kwTYPE_LEVEL_END);				IP ++;				}			else	{				cev_log();				while ( CODE_PEEK() == kwTYPE_SEP || CODE_PEEK() == kwTO )	{	// DIM X(A TO B)					if	( CODE_PEEK() == kwTYPE_SEP )	{						cev_add1(CODE(IP));							IP ++;						}					cev_add1(CODE(IP));					IP ++;					cev_log();					}				if	( CODE_PEEK() != kwTYPE_LEVEL_END )							cev_missing_rp();				else	{					cev_add1(kwTYPE_LEVEL_END);					IP ++;					}				}			}		break;	default:		// function [(...)]		if	( CODE_PEEK() == kwTYPE_LEVEL_BEGIN )	{			cev_add1(kwTYPE_LEVEL_BEGIN);			IP ++;			cev_log();			while ( CODE_PEEK() == kwTYPE_SEP )	{				cev_add1(CODE(IP));			IP ++;				cev_add1(CODE(IP));			IP ++;				cev_log();				}			if	( CODE_PEEK() != kwTYPE_LEVEL_END )						cev_missing_rp();			else	{				cev_add1(kwTYPE_LEVEL_END);				IP ++;				}			}		};}/**	parenthesis*/void	cev_parenth(void) SEC(BCSCAN);void	cev_parenth(){	if	( scan_error )	return;	if	( CODE_PEEK() == kwTYPE_LEVEL_BEGIN )	{		cev_add1(kwTYPE_LEVEL_BEGIN);		IP ++;		cev_log();		// R = cev_log		if	( scan_error )	return;		if	( CODE_PEEK() != kwTYPE_LEVEL_END )	{			cev_missing_rp();			return;			}		else	{			cev_add1(kwTYPE_LEVEL_END);			IP ++;			}		}	else			cev_prim();}/**	unary*/void	cev_unary(void) SEC(BCSCAN);void	cev_unary(){	char	op;	if	( scan_error )	return;	if	( CODE(IP) == kwTYPE_UNROPR || CODE(IP) == kwTYPE_ADDOPR )	{		op = CODE(IP+1);		IP += 2;		}	else		op = 0;	cev_parenth();					// R = cev_parenth	if	( op )		cev_add2(kwTYPE_UNROPR, op);	// R = op R}/**	pow*/void	cev_pow(void)	SEC(BCSCAN);void	cev_pow(){	cev_unary();		// R = cev_unary	if	( scan_error )	return;	while ( CODE(IP) == kwTYPE_POWOPR )	{		IP += 2;		cev_add1(kwTYPE_EVPUSH);		// PUSH R		cev_unary();					// R = cev_unary		if	( scan_error )	return;		cev_add1(kwTYPE_EVPOP);			// POP LEFT		cev_add2(kwTYPE_POWOPR, '^');	// R = LEFT op R		}}/**	mul | div | mod*/void	cev_mul(void) SEC(BCSCAN);void	cev_mul(){	cev_pow();	// R = cev_pow()	if	( scan_error )	return;	while ( CODE(IP) == kwTYPE_MULOPR )	{		char	op;		op = CODE(++IP);	IP ++;		cev_add1(kwTYPE_EVPUSH);		// PUSH R		cev_pow();		if	( scan_error )	return;		cev_add1(kwTYPE_EVPOP);			// POP LEFT		cev_add2(kwTYPE_MULOPR, op);	// R = LEFT op R		}}/**	add | sub*/void	cev_add(void) SEC(BCSCAN);void	cev_add(){	cev_mul();		// R = cev_mul()	if	( scan_error )	return;	while ( CODE(IP) == kwTYPE_ADDOPR )	{		char	op;		IP ++;		op = CODE(IP);	IP ++;		cev_add1(kwTYPE_EVPUSH);		// PUSH R		cev_mul();						// R = cev_mul		if	( scan_error )	return;		cev_add1(kwTYPE_EVPOP);			// POP LEFT		cev_add2(kwTYPE_ADDOPR, op);	// R = LEFT op R		}}/**	compare*/void	cev_cmp(void)	SEC(BCSCAN);void	cev_cmp(){	cev_add();	// R = cev_add()	if	( scan_error )	return;	while ( CODE(IP) == kwTYPE_CMPOPR )	{		char	op;		IP ++;		op = CODE(IP);	IP ++;		cev_add1(kwTYPE_EVPUSH);		// PUSH R		cev_add();						// R = cev_add()		if	( scan_error )	return;		cev_add1(kwTYPE_EVPOP);			// POP LEFT		cev_add2(kwTYPE_CMPOPR, op);	// R = LEFT op R		}}/**	logical*/void	cev_log(void){	cev_cmp();	// R = cev_cmp()	if	( scan_error )	return;	while ( CODE(IP) == kwTYPE_LOGOPR )	{		char	op;		IP ++;		op = CODE(IP);	IP ++;		cev_add1(kwTYPE_EVPUSH);		// PUSH R		cev_cmp();	// right seg		// R = cev_cmp()		if	( scan_error )	return;		cev_add1(kwTYPE_EVPOP);			// POP LEFT		cev_add2(kwTYPE_LOGOPR, op);	// R = LEFT op R		}}/**	main*/void	expr_parser(bc_t *bc_src)		SEC(BCSCAN);void	expr_parser(bc_t *bc_src){	byte	code;	// init	bc_in  = bc_src;	bc_out = tmp_alloc(sizeof(bc_t));	bc_create(bc_out);	code = CODE_PEEK();	// NIL!	if	( code == kwTYPE_LINE || code == kwTYPE_EOC ) { // || code == kwFILLED || code == kwON || code == kwOFF )	{		bc_destroy(bc_out);		tmp_free(bc_out);		return;		}	// LET|CONST SPECIAL CODE	if ( code == kwTYPE_CMPOPR )	{		IP ++;		if	( CODE(IP) != '=' )	{			cev_opr_err();			bc_destroy(bc_out);			tmp_free(bc_out);			return;			}		else	{			IP ++;			cev_add2(kwTYPE_CMPOPR, '=');			}		}	// sep.	code = CODE_PEEK();	while ( code == kwTYPE_SEP )	{		cev_add1(CODE(IP));		IP ++;		cev_add1(CODE(IP));		IP ++;		code = CODE_PEEK();		}	// start	cev_log();	code = CODE_PEEK();	while ( code == kwTYPE_SEP || code == kwFILLED || code == kwCOLOR ||			 code == kwTO || code == kwSTEP || code == kwFORSEP || code == kwINPUTSEP ||			 code == kwINPUT || code == kwOUTPUT || code == kwAPPEND || code == kwAS )	{		if	( scan_error )	break;		if	( code == kwAS )	{			cev_add1(kwAS);			IP ++;			if	( CODE_PEEK() == kwTYPE_SEP )	{				cev_add1(kwTYPE_SEP);				IP ++;				cev_add1(CODE(IP));				IP ++;				}			}		else	{			cev_add1(CODE(IP));			IP ++;			if ( code == kwTYPE_SEP )	{				cev_add1(CODE(IP));				IP ++;				}			}		code = CODE_PEEK();		if	( code == kwTYPE_EOC || code == kwTYPE_LINE )			break;		cev_log();		code = CODE_PEEK();		}	// finish	if	( bc_out->count )	{		bc_in->count = 0;		bc_append(bc_in, bc_out);		}	bc_destroy(bc_out);	tmp_free(bc_out);}

⌨️ 快捷键说明

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