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

📄 scan.c

📁 smallbasic for linux
💻 C
📖 第 1 页 / 共 4 页
字号:
/***	SmallBasic pseudo-compiler.	Converts the source to byte-code.**	2000-05-27, 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*/#define SCAN_MODULE#include "sys.h"#include "str.h"#include "panic.h"#include "device.h"#include "kw.h"#include "bc.h"#include "smbas.h"void	bc_scan_cmd(char *text) 				SEC(BCSCAN);int		bc_scan_inline_if(char *text) 			SEC(BCSCAN);int		bc_is_keyword(char *name) 				SEC(BCSCAN);word	bc_search(word ip, byte code) 			SEC(BCSCAN);#if defined(_PalmOS) static char	bc_fileName[65];#elsestatic char	bc_fileName[1024];#endif#define	TEXT_LINE_SIZE		512extern void	expr_parser(bc_t *bc)			 	SEC(BCSCAN);struct keyword_s {	char	name[16];		/* keyword */	byte	code;			/* byte-code */	};struct keyword_s keyword_table[] = {{ "$$$_int", 	kwTYPE_INT		},{ "$$$_dbl",	kwTYPE_NUM		},{ "$$$_str",	kwTYPE_STR		},{ "$$$_log",	kwTYPE_LOGOPR	},{ "$$$_cmp",	kwTYPE_CMPOPR	},{ "$$$_add",	kwTYPE_ADDOPR	},{ "$$$_mul",	kwTYPE_MULOPR	},{ "$$$_pow",	kwTYPE_POWOPR	},{ "$$$_unr",	kwTYPE_UNROPR	},{ "$$$_var",	kwTYPE_VAR	},{ "$$$_line",	kwTYPE_LINE	},{ "$$$_LPAR",	kwTYPE_LEVEL_BEGIN	},{ "$$$_RPAR",	kwTYPE_LEVEL_END	},{ "$$$_CRVAR",	kwTYPE_CRVAR	},{ "LOCAL", 		kwLOCAL	},{ "SUB", 		kwPROC	},{ "FUNC", 		kwFUNC	},{ "BYREF",		kwBYREF	},{ "DECLARE",	kwDECLARE	},{ "LET", 		kwLET	},{ "CONST", 		kwCONST	},{ "DIM", 		kwDIM	},{ "STOP",		kwSTOP	},{ "END",		kwEND	},{ "PRINT",		kwPRINT	},{ "INPUT",		kwINPUT	},{ "PEN",		kwPEN	},{ "CLS",		kwCLS	},{ "REM",		kwREM	},{ "CHAIN",		kwCHAIN	},{ "ON",			kwON	},{ "OFF",		kwOFF	},{ "LABEL",		kwLABEL	},{ "GOTO",		kwGOTO	},{ "IF",			kwIF	},{ "THEN",		kwTHEN	},{ "ELSE",		kwELSE	},{ "ELIF",		kwELIF	},{ "ELSEIF",		kwELIF	},{ "ENDIF",		kwENDIF	},{ "FI",			kwENDIF	},{ "FOR",		kwFOR	},{ "TO",			kwTO	},{ "STEP",		kwSTEP	},{ "NEXT",		kwNEXT	},{ "WHILE",		kwWHILE	},{ "WEND",		kwWEND	},{ "REPEAT",		kwREPEAT	},{ "UNTIL",		kwUNTIL	},{ "GOSUB",		kwGOSUB	},{ "RETURN",		kwRETURN	},{ "READ",		kwREAD	},{ "DATA",		kwDATA	},{ "RESTORE",	kwRESTORE	},{ "EXIT",		kwEXIT	},{ "LOOP",		kwLOOP	},{ "RND", 		kwRND	},{ "ABS",		kwABS	},{ "LEN",		kwLEN	},{ "COS",		kwCOS	},{ "SIN",		kwSIN	},{ "TAN",		kwTAN	},{ "ACOS",		kwACOS	},{ "ASIN",		kwASIN	},{ "ATAN",		kwATAN	},{ "ATN",		kwATAN	},{ "ACOSH",		kwACOSH	},{ "ASINH",		kwASINH	},{ "ATANH", 		kwATANH	},{ "ATNH",		kwATANH	},{ "COSH",		kwCOSH	},{ "SINH",		kwSINH	},{ "TANH",		kwTANH	},{ "EXP",		kwEXP	},{ "LOG",		kwLOG	},{ "LOG10",		kwLOG10	},{ "SQR",		kwSQR	},{ "INT",		kwINT	},{ "CINT",		kwCINT	},{ "CDBL",		kwCDBL	},{ "FIX",		kwFIX	},{ "SGN",		kwSGN	},{ "ASC", 		kwASC	},{ "VAL", 		kwVAL	},{ "RANDOMIZE",	kwRANDOMIZE	},{ "ATAN2",		kwATAN2	},{ "POW",		kwPOW	},{ "ROUND",		kwROUND	},{ "DEG",		kwDEG	},{ "RAD",		kwRAD	},{ "LBOUND",		kwLBOUND	},{ "UBOUND",		kwUBOUND	},{ "ERASE", 		kwERASE	},{ "CHR",		kwCHR	},{ "HEX",		kwHEX	},{ "OCT",		kwOCT	},{ "LCASE",		kwLCASE	},{ "UCASE",		kwUCASE	},{ "LTRIM",		kwLTRIM	},{ "RTRIM",		kwRTRIM	},{ "STRING"	,	kwSTRING	},{ "STR"	,		kwSTR	},{ "LEFT",		kwLEFT	},{ "RIGHT",		kwRIGHT	},{ "INSTR",		kwINSTR	},{ "MID",		kwMID	},{ "SPACE",		kwSPACE	},{ "TIME",		kwTIME	},{ "DATE",		kwDATE	},{ "SPLIT",		kwWSPLIT	},{ "AT",			kwAT	},{ "LOCATE",		kwLOCATE	},{ "TICKSPERSEC", kwTICKSPERSEC	},{ "TICKS",		kwTICKS	},{ "TIMER",		kwTIMER	},{ "FRE",		kwFRE	},{ "PSET",		kwPSET	},{ "LINE",		kwLINE	},{ "RECT",		kwRECT	},{ "COLOR",		kwCOLOR	},{ "FILLED",		kwFILLED	},{ "CIRCLE",		kwCIRCLE	},{ "BEEP",		kwBEEP	},{ "SOUND",		kwSOUND	},{ "PAUSE",		kwPAUSE	},{ "INKEY",		kwINKEY	},{ "TAB",		kwTAB	},{ "CAT",		kwCAT	},{ "DELAY",		kwDELAY	},{ "ARC",		kwARC	},{ "DRAW",		kwDRAW	},{ "PLAY",		kwPLAY	},{ "RUN",		kwRUN	},{ "TXTW",		kwTEXTWIDTH	},{ "TXTH",		kwTEXTHEIGHT	},{ "CHART",		kwCHART	},{ "MAX",		kwMAX	},{ "MIN",		kwMIN	},{ "DRAWPOLY",	kwDRAWPOLY	},/* file I/O */{ "FREEFILE",	kwFREEFILE	},{ "OPEN", 		kwOPEN	},{ "OUTPUT",		kwOUTPUT	},	// OPEN's args{ "APPEND",		kwAPPEND	},	// OPEN's args{ "AS",			kwAS },		// OPEN's args{ "CLOSE", 		kwCLOSE  },{ "LINEINPUT", 	kwLINEINPUT },		// The QB's keyword is "LINE INPUT"{ "EOF", 		kwEOF	 },{ "KILL", 		kwKILL	 },{ "EXIST", 		kwEXIST	},{ "SEEK", 		kwSEEK	},{ "LOF", 		kwLOF	},{ "COPY", 		kwCOPY	},{ "RENAME", 	kwRENAME	},//{ "INPUT", 		kwFINPUT },	// not needed/* DEBUG */{ "TRON",		kwTRON	},{ "TROFF",		kwTROFF	},{ "LOGPRINT",	kwLOGPRINT	},#ifdef BC_DEBUG{ "BCDUMP",		kwBCDUMP	},{ "STKDUMP",	kwSTKDUMP	},#endif{ "", 0 }};/**	Notes:*		block_level = the depth of nested block*		block_id	= unique number of each block (based on stack use)**		Example:*		? xxx			' level 0, id 0*		for i=1 to 20	' level 1, id 1*			? yyy		' level 1, id 1*			if a=1 		' level 2, id 2 (our IF uses stack)*				...		' level 2, id 2*			else		' level 2, id 2	// not 3*				...		' level 2, id 2*			fi			' level 2, id 2*			if a=2		' level 2, id 3*				...		' level 2, id 3*			fi			' level 2, id 3*			? zzz		' level 1, id 1*		next			' level 1, id 1*		? ooo			' level 0, id 0*/int			scan_error;int			scan_line;			// source line countstatic int	block_level;		// block level (FOR-NEXT,IF-FI,etc)static int	block_id;			// unique ID for blocks (FOR-NEXT,IF-FI,etc)static word	first_data_ip = 0xFFFF;// ndc: 2001-03-01 static allocation (non tmp_alloc()) does not use the dynamic RAM and reduces the fragmentationstatic char	*bc_name;static char	*bc_parm;static char	*bc_temp;static char *bc_proc;static char	bc_sec[33];static int  bc_proc_level = 0;static bc_t	bc_prog;static bc_t	bc_data;#define	GROWSIZE	128/**	variable node*/struct var_s	{	char	*name;	};typedef struct var_s var_t;static var_t	*var_table;static word		var_count;static word		var_size;/**	LABELS LIST*/struct label_s	{//	char	*name;	char	name[33];	word	ip;			// instruction pointer	byte	level;		// block level (used for GOTOs)	word	block_id;	// block_id (FOR-NEXT,IF-FI,etc) used for GOTOs	word	dp;			// data pointer	};typedef struct label_s label_t;//static label_t	*lab_table;//static word		lab_count;//static word		lab_size;static dbt_t	lab_table;static word		lab_count;/**	PROCEDURES/FUNCTIONS LIST*/struct proc_s	{	char	*name;	word	ip;			// instruction pointer	word	vid;		// variable index (for functions)	byte	level;		// block level (used for GOTOs)	word	block_id;	// block_id (FOR-NEXT,IF-FI,etc) used for GOTOs	};typedef struct proc_s proc_t;static proc_t	*proc_table;static word		proc_count;static word		proc_size;/**	PASS2 - STACK*/struct pass_node_s	{	char	sec[33];	word	pos;		// instruction position	word	line;		// the source-text line	byte	level;		// block level	word	block_id;	// block ID		};typedef struct pass_node_s pass_node_t;static dbt_t	bc_stack;static word		stk_count;/***	raise a compiler error*/void	sc_raise(const char *fmt, ...){	char	*buff;	va_list ap;	va_start(ap, fmt);	scan_error = 1;	buff = tmp_alloc(TEXT_LINE_SIZE);	#if defined(_PalmOS)	StrVPrintF(buff, fmt, ap);	#else	vsprintf(buff, fmt, ap);	#endif	va_end(ap);		dev_printf("\n* ERROR AT %s:%d *\n> %s\n", bc_sec, scan_line, buff);	tmp_free(buff);}/**/char*	bc_prepname(char *dest, const char *source, int size) SEC(BCSCAN);char*	bc_prepname(char *dest, const char *source, int size){	char	*p = (char *) source;	while ( *p == ' ' )		p ++;	strncpy(dest, p, size);	dest[size] = '\0';	p = dest;	while ( *p && (is_alpha(*p) || is_digit(*p) || *p == '$' || *p == '/') )		p ++;	*p = '\0';	str_alltrim(dest);	return dest;}/**	returns the ID of the label. If there is no one, then it creates one*/int		bc_get_label_id(const char *label_name) SEC(BCSCAN);int		bc_get_label_id(const char *label_name){	int		idx = -1;	int		i;	char	name[33];	label_t	label;	bc_prepname(name, label_name, 32);	for ( i = 0; i < lab_count; i ++ )	{		dbt_read(lab_table, i, &label, sizeof(label_t));		if	( strcmp(label.name, name) == 0 )	{			idx = i;			break;			}		}	if	( idx == -1 )	{/*		if ( lab_count >= lab_size ) {			lab_size += GROWSIZE;			lab_table = (label_t *) tmp_realloc(lab_table, lab_size * sizeof(label_t));			}		idx = lab_count;		lab_count ++;		lab_table[idx].name = tmp_alloc(strlen(name)+1);		strcpy(lab_table[idx].name, name);		lab_table[idx].ip = 0xFFFF;		lab_table[idx].dp = 0xFFFF;		lab_table[idx].level = block_level;		lab_table[idx].block_id = block_id;*/		strcpy(label.name, name);		label.ip = 0xFFFF;		label.dp = 0xFFFF;		label.level = block_level;		label.block_id = block_id;		dbt_write(lab_table, lab_count, &label, sizeof(label_t));		idx = lab_count;		lab_count ++;		}	return idx;}/**	set LABEL's position (IP)*/void	bc_set_label_ip(int idx) SEC(BCSCAN);void	bc_set_label_ip(int idx){	label_t	label;	dbt_read(lab_table, idx, &label, sizeof(label_t));/*	lab_table[idx].ip = bc_prog.count;	lab_table[idx].dp = bc_data.count;	lab_table[idx].level = block_level;	lab_table[idx].block_id = block_id;*/	label.ip = bc_prog.count;	label.dp = bc_data.count;	label.level = block_level;	label.block_id = block_id;	dbt_write(lab_table, idx, &label, sizeof(label_t));}/**/int		bc_get_proc_id(const char *proc_name) SEC(BCSCAN);int		bc_get_proc_id(const char *proc_name){	int		idx = -1;	int		i;	char	tmp[33];	char	*name = bc_temp;	if	( bc_proc_level )	{		// search the procedure's table for this LOCAL PROC		bc_prepname(tmp, proc_name, 32);		strcpy(name, bc_proc);		strcat(name, "/");		strcat(name, tmp);		for ( i = 0; i < proc_count; i ++ )	{			if	( strcmp(proc_table[i].name, name) == 0 )	{				idx = i;				break;				}			}		}	if	( idx == -1 )	{		// search the procedure's table for this GLOBAL PROC		bc_prepname(name, proc_name, 32);		for ( i = 0; i < proc_count; i ++ )	{			if	( strcmp(proc_table[i].name, name) == 0 )	{				idx = i;				break;				}			}		}	return idx;}/**/int		bc_addproc(const char *proc_name) SEC(BCSCAN);int		bc_addproc(const char *proc_name){	char	tmp[33];	char	*name = bc_temp;	int		idx = -1, i;	//	bc_prepname(tmp, proc_name, 32);	if	( bc_proc_level )	{		strcpy(name, bc_proc);		strcat(name, "/");		strcat(name, tmp);		}	else		strcpy(name, tmp);	for ( i = 0; i < proc_count; i ++ )	{		if	( strcmp(proc_table[i].name, name) == 0 )	{			idx = i;			break;			}		}	if	( idx == -1 )	{		if ( proc_count >= proc_size ) {			proc_size += GROWSIZE;			proc_table = tmp_realloc(proc_table, proc_size * sizeof(proc_t));			}		if	( !is_alpha(proc_name[0]) )			sc_raise("WRONG PROC NAME: %s", proc_name);		else	{			proc_table[proc_count].name = tmp_alloc(strlen(name)+1);			proc_table[proc_count].ip = 0xFFFF; //bc_prog.count;			proc_table[proc_count].level = block_level;			proc_table[proc_count].block_id = block_id;			strcpy(proc_table[proc_count].name, name);			idx = proc_count;			proc_count ++;			}		}	return idx;}int		bc_proc_setip(const char *proc_name, word ip) SEC(BCSCAN);int		bc_proc_setip(const char *proc_name, word ip){	int		idx;		idx = bc_get_proc_id(proc_name);	if	( idx != -1 )	{		proc_table[idx].ip = bc_prog.count;		proc_table[idx].level = block_level;		proc_table[idx].block_id = block_id;		}	return idx;}word	bc_proc_getip(const char *proc_name) SEC(BCSCAN);word	bc_proc_getip(const char *proc_name){	int		idx;		idx = bc_get_proc_id(proc_name);	if	( idx != -1 )			return proc_table[idx].ip;	return 0xFFFF;}/**/char	*get_param_sect(char *text, const char *delim, char *dest) SEC(BCSCAN);char	*get_param_sect(char *text, const char *delim, char *dest){	char	*p = (char *) text;	char	*d = dest;	int		quotes = 0, level = 0, skip_ch = 0;	if	( p == NULL )	{		*dest = '\0';		return 0;		}	while ( is_space(*p) )	p ++;	while ( *p )	{		if	( quotes )	{			if	( *p == '\"' )				quotes = 0;			}		else	{			switch ( *p )	{			case	'\"':				quotes = 1;				break;			case	'(':				level ++;				break;			case	')':				level --;				break;			case	'\n':			case	'\r':				skip_ch = 1;				break;				};			}		// delim check		if	( delim != NULL && level <= 0 && quotes == 0 )	{			if	( strchr(delim, *p) != NULL )					break;			}		// copy		if	( !skip_ch )	{			*d = *p;			d ++;			}		else			skip_ch = 0;		p ++;		}	*d = '\0';		if	( quotes )		sc_raise("MISSING (\")");	if	( level > 0 )		sc_raise("MISSING \')\'");	if	( level < 0 )		sc_raise("MISSING \'(\'");	str_alltrim(dest);	return p;}/**/int		bc_get_error(void) SEC(BCSCAN);int		bc_get_error(){	return scan_error;}/**	checking for missing labels*/void	bc_check_labels(void) SEC(BCSCAN);void	bc_check_labels(){	int		i;	label_t	label;	for ( i = 0; i < lab_count; i ++ )	{		dbt_read(lab_table, i, &label, sizeof(label_t));		if	( label.ip == 0xFFFF )	{			sc_raise("LABEL NOT DEFINED: %s", label.name);			break;			}		}}/**	returns the id of the variable 'name'*/int		bc_get_var_id(const char *var_name) SEC(BCSCAN);int		bc_get_var_id(const char *var_name){	int		idx = -1;	int		i;	char	tmp[33];	char	*name = bc_temp;	if	( bc_proc_level )	{		// search local name-space		bc_prepname(tmp, var_name, 32);		#if defined(_PalmOS)		StrPrintF(name, "%s/%s", bc_proc, tmp);		#else		sprintf(name, "%s/%s", bc_proc, tmp);		#endif		for ( i = 0; i < var_count; i ++ )	{			if	( strcmp(var_table[i].name, name) == 0 )	{				idx = i;				break;				}			}		}

⌨️ 快捷键说明

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