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

📄 scan.c

📁 smallbasic for linux
💻 C
📖 第 1 页 / 共 4 页
字号:
			dbt_read(lab_table, label_id, &label, sizeof(label_t));			count = first_data_ip + label.dp;			memcpy(bc_prog.ptr+node.pos+1, &count, 2);	// change LABEL-ID with DataPointer			break;		case kwTYPE_CALL_UDP:		case kwTYPE_CALL_UDF:			// update real IP			memcpy(&label_id, bc_prog.ptr+node.pos+1, 2);			true_ip = proc_table[label_id].ip + 5;			memcpy(bc_prog.ptr+node.pos+1, &true_ip, 2);				// update return-var ID			true_ip = proc_table[label_id].vid;			memcpy(bc_prog.ptr+node.pos+3, &true_ip, 2);				break;		case kwONJMP:			// kwONJMP:1 trueip:2 falseip:2 command:1 count:1 label1:2 label2:2 ...			count = bc_prog.ptr[node.pos+6];			// change label IDs with the real IPs			for ( j = 0; j < count; j ++ )	{				memcpy(&label_id, bc_prog.ptr+node.pos+(j<<1)+7, 2);				dbt_read(lab_table, label_id, &label, sizeof(label_t));				w = label.ip;				memcpy(bc_prog.ptr+node.pos+(j<<1)+7, &w, 2);				}			break;		case kwGOTO:	// LONG JUMPS			memcpy(&label_id, bc_prog.ptr+node.pos+1, 2);			dbt_read(lab_table, label_id, &label, sizeof(label_t));			w = label.ip;			memcpy(bc_prog.ptr+node.pos+1, &w, 2);	// change LABEL-ID with IP			level = bc_prog.ptr[node.pos+3];			bc_prog.ptr[node.pos+3] = 0; // number of POPs ?????????			if	( level >= label.level )				bc_prog.ptr[node.pos+3] = level - label.level; // number of POPs			else					bc_prog.ptr[node.pos+3] = 0; // number of POPs ?????????			break;		case kwFOR:			a_ip = bc_search(node.pos+5, kwTO);			false_ip = bc_search_stack(i+1, kwNEXT, node.level);			if	( false_ip == 0xFFFF )	{				sc_raise("'FOR' WITHOUT 'NEXT'");				return;				}			if	( a_ip > false_ip || a_ip == 0xFFFF )	{				sc_raise("'FOR' WITHOUT 'TO'");				return;				}			memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2);			break;		case kwWHILE:			false_ip = bc_search_stack(i+1, kwWEND, node.level);			if	( false_ip == 0xFFFF )	{				sc_raise("'WHILE' WITHOUT 'WEND'");				return;				}			memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2);			break;		case kwREPEAT:			false_ip = bc_search_stack(i+1, kwUNTIL, node.level);			if	( false_ip == 0xFFFF )	{				sc_raise("'REPEAT' WITHOUT 'UNTIL'");				return;				}			memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2);			break;		case kwIF:		case kwELIF:			a_ip = bc_search_stack(i+1, kwELSE,  node.level);			b_ip = bc_search_stack(i+1, kwENDIF, node.level);			c_ip = bc_search_stack(i+1, kwELIF,  node.level);			false_ip = a_ip;			if	( b_ip < false_ip )				false_ip = b_ip;			if	( c_ip < false_ip )				false_ip = c_ip;			if	( false_ip == 0xFFFF )	{				sc_raise("'IF' WITHOUT 'ENDIF'");				return;				}			memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2);			break;		case kwELSE:			false_ip = bc_search_stack(i+1, kwENDIF, node.level);			if	( false_ip == 0xFFFF )	{				sc_raise("'IF' WITHOUT 'ENDIF'");				return;				}			memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2);			break;///////////////		case kwTYPE_RET:			break;		case kwWEND:			false_ip = bc_search_stack_backward(i-1, kwWHILE, node.level);			if	( false_ip == 0xFFFF )	{				sc_raise("'WEND' WITHOUT 'WHILE'");				return;				}			memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2);			break;		case kwUNTIL:			false_ip = bc_search_stack_backward(i-1, kwREPEAT, node.level);			if	( false_ip == 0xFFFF )	{				sc_raise("'UNTIL' WITHOUT 'REPEAT'");				return;				}			memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2);			break;		case kwNEXT:			false_ip = bc_search_stack_backward(i-1, kwFOR, node.level);			if	( false_ip == 0xFFFF )	{				sc_raise("'NEXT' WITHOUT 'FOR'");				return;				}			memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2);			break;		case kwENDIF:			false_ip = bc_search_stack_backward(i-1, kwIF, node.level);			if	( false_ip == 0xFFFF )	{				sc_raise("'ENDIF' WITHOUT 'IF'");				return;				}			memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2);			break;			};		}	dev_printf("\rPASS2: Node %d/%d\n", stk_count, stk_count);}/**	initialize*/void	bc_init() SEC(BCSCAN);void	bc_init(){	#if defined(_PalmOS)	dev_cls();	#endif	bc_name = tmp_alloc(TEXT_LINE_SIZE);	bc_parm = tmp_alloc(TEXT_LINE_SIZE);	bc_temp = tmp_alloc(TEXT_LINE_SIZE);	bc_proc = tmp_alloc(TEXT_LINE_SIZE);	scan_line = 0;	scan_error = 0;	lab_count = 0;	var_count = 0;	stk_count = 0;	proc_count = 0;	block_level = 0;	block_id = 0;	first_data_ip = 0xFFFF;	bc_proc_level = 0;	bc_proc[0] = '\0';	var_table  = (var_t*)       tmp_alloc(GROWSIZE * sizeof(var_t));	lab_table  = dbt_create("BCS-LBL.VMT");	proc_table = (proc_t*)      tmp_alloc(GROWSIZE * sizeof(proc_t));	bc_stack   = dbt_create("BCS-STK.VMT");	var_size   = /* lab_size = stk_size = */ proc_size  = GROWSIZE;	var_count  = lab_count = stk_count = proc_count = 0;	bc_create(&bc_prog);	bc_create(&bc_data);	if	( !var_table || !lab_table || !proc_table || !bc_stack )			panic("bc_init(): OUT OF MEMORY");	dev_printf("VMT Initialization...\n");	dbt_prealloc(lab_table, os_cclabs1, sizeof(label_t));	dbt_prealloc(bc_stack, os_ccpass2, sizeof(pass_node_t));	/*	*	create system variables	*/	bc_get_var_id("OSVER");	bc_get_var_id("OSNAME");	bc_get_var_id("SBVER");	bc_get_var_id("PI");	bc_get_var_id("XMAX");	bc_get_var_id("YMAX");	bc_get_var_id("BPP");	bc_get_var_id("TRUE");	bc_get_var_id("FALSE");	bc_get_var_id("LINECHART");	bc_get_var_id("BARCHART");}/**	clean up*/void	bc_close() SEC(BCSCAN);void	bc_close(){	int		i;	#if defined(_PalmOS)//	LocalID		lid;	#endif	bc_destroy(&bc_prog);	bc_destroy(&bc_data);	for ( i = 0; i < var_count; i ++ )		tmp_free(var_table[i].name);	for ( i = 0; i < proc_count; i ++ )		tmp_free(proc_table[i].name);	tmp_free(var_table);	dbt_close(lab_table);	tmp_free(proc_table);	dbt_close(bc_stack);//	#if defined(_PalmOS)//	if ( (lid = DmFindDatabase(0, "BCS-LBL.VMT")) != 0 )	DmDeleteDatabase(0, lid);//	if ( (lid = DmFindDatabase(0, "BCS-STK.VMT")) != 0 )	DmDeleteDatabase(0, lid);//	#endif	var_count = lab_count = stk_count = proc_count = 0;	tmp_free(bc_proc);	tmp_free(bc_temp);	tmp_free(bc_parm);	tmp_free(bc_name);}/**	returns true if the 'fileName' exists*/int		basFileExist(const char *basfile){	int		check = 0;	char	*p, *fileName;	#if defined(_PalmOS)	LocalID	lid;	#endif	fileName = tmp_alloc(strlen(basfile)+1);	strcpy(fileName, basfile);	p = strchr(fileName, '.');	if	( !p )			strcat(fileName, ".bas");	else	{		if	( str_istr(fileName, ".bas") == NULL )			strcat(fileName, ".bas");		}	#if defined(_PalmOS)	lid = DmFindDatabase(0, fileName);	check = (lid != 0);	#else		#if defined(_Win32)		check = (access(fileName, 0) == 0);		#else		check = (access(fileName, R_OK) == 0);		#endif	#endif	tmp_free(fileName);	return check;}/**/void	bc_load(const char *fileName) SEC(BCSCAN);void	bc_load(const char *fileName){#if defined(_PalmOS)	DmOpenRef	fp;	LocalID		lid;	int			l, i;	VoidPtr		rec_p = NULL;	VoidHand	rec_h = NULL;#else	int		unxh;	struct stat st;#endif	strcpy(bc_fileName, fileName);#if defined(_PalmOS)	lid = DmFindDatabase(0, (char *) fileName);	fp = DmOpenDatabase(0, lid, dmModeReadWrite);	if	( !fp )	{		panic("LOAD: CAN'T OPEN FILE %s", fileName);		return;		}	l = DmNumRecords(fp) - 1;	if	( l <= 0 )	{		panic("LOAD: BAD FILE STRUCTURE %s", fileName);		return;		}	for ( i = 0; i < l; i ++ )	{		rec_h = DmGetRecord(fp, i+1);		if	( !rec_h )			panic("LOAD: CAN'T GET RECORD %s", fileName);		rec_p = mem_lock(rec_h);		if	( !rec_p )			panic("LOAD: CAN'T LOCK RECORD %s", fileName);		if	( i == 0 && strlen(rec_p+6) == 0 )			bc_scan("Main", rec_p+70);	// + sizeof(sec_t);		else			bc_scan(rec_p+6, rec_p+70);	// + sizeof(sec_t);		mem_unlock(rec_h);		DmReleaseRecord(fp, i+1, 0);		if	( bc_get_error() )			break;		}	DmCloseDatabase(fp);#else	stat(fileName, &st);	unxh = open(fileName, 0);	if	( unxh == -1 )	{		panic("can't open %s\n", fileName);		return;		}	else	{		char	*buff;		/* read & compile file */		buff = (char *) tmp_alloc(st.st_size+1);		read(unxh, buff, st.st_size);		buff[st.st_size] = '\0';		bc_scan(NULL, buff);		tmp_free(buff);		close(unxh);		}#endif}/***	PASS 1*/void	bc_scan(const char *section, const char *text){	char	*ps, *p, lc = 0;	int		quotes, len;	char	pname[33];	char	*code_line;	char	*new_text;	code_line = tmp_alloc(TEXT_LINE_SIZE);	new_text = tmp_alloc((len=(strlen(text) + 4)));	memset(new_text, 0, len);	/*	*	Make it simple text	*		* space-chars is only the space	*		* CR/LF are fixed	*		* control chars are out	*/	if	( section )		strncpy(bc_sec, section, 32);	else		strncpy(bc_sec, "Main", 32);	bc_sec[32] = '\0';//	dev_printf("Preparing text...\n");	p = (char *) text;	ps = new_text;	quotes = 0;	while ( *p )	{		if	( !quotes )	{			if ( *p == '\n' )	{				*ps ++ = '\n';				while ( *(p+1) == ' ' || *(p+1) == '\t' )					p ++;				}			else if ( (*p == '\t' || *p == ' ') && lc != ' ' )				*ps ++ = ' ';			else if	( (*p > ' ') || (*p & 0x80) )				*ps ++ = to_upper(*p);			lc = *ps;			}		else			*ps ++ = *p;		if	( *p == '\"' )				quotes = !quotes;		p ++;		}	*ps = '\0';		strcat(new_text, "\n");	/*	*///	dev_printf("Scanning for routines...\n");	p = ps = new_text;	bc_proc_level = 0;	*bc_proc = '\0';	while ( *p )	{		if	( strncmp("#INC:", p, 5) == 0 )	{			char	*crp  = NULL;			p += 5;			if	( *p == '\"' )	{				p ++;				crp = p;				while ( *crp != '\0' && *crp != '\"' )					crp ++;				if	( *crp == '\0' )	{					sc_raise("#INC: MISSING \"");					break;					}				*crp = '\0';				lc = '\"';				}			else	{				crp = strchr(p, '\n');				*crp = '\0';				lc = '\n';				}			strcpy(code_line, p);			str_alltrim(code_line);			if	( !basFileExist(code_line) )					sc_raise("FILE %s: FILE %s DOES NOT EXISTS", bc_fileName, code_line);			else	{				#if defined(_PalmOS) 				char	fileName[65];				#else				char	fileName[1024];				#endif				char	sec[33];								strcpy(sec, bc_sec);				strcpy(fileName, bc_fileName);				if	( strchr(code_line, '.') == NULL )					strcat(code_line, ".bas");				bc_load(code_line);				strcpy(bc_fileName, fileName);				strcpy(bc_sec, sec);				}			*crp = lc;			}		if	( (strncmp("SUB ", p, 4) == 0) || (strncmp("FUNC ", p, 5) == 0) )	{			char	*lpar = NULL;			char	*crp  = NULL;			if	( *p == 'S' )				p += 4;			else				p += 5;			// close string			lpar = strchr(p, '(');			crp  = strchr(p, '\n');			if	( lpar && crp )	{				if	( lpar < crp )		{					*lpar = '\0';					crp = NULL;					}				else	{					*crp = '\0';					lpar = NULL;					}				}			else if ( lpar )				*lpar = '\0';			else if ( crp )				*crp = '\0';			// add declaration			bc_prepname(pname, p, 32);			bc_addproc(pname);			if	( bc_proc_level )	{				strcat(bc_proc, "/");				strcat(bc_proc, pname);				}			else				strcpy(bc_proc, pname);			bc_proc_level ++;			// restore string			if	( lpar )				*lpar = '(';			else	{				if	( crp )					*crp = '\n';				}			}		else if ( bc_proc_level )	{			if	( strncmp("END ", p, 4) == 0 || strncmp("END\n", p, 4) == 0 )	{				char	*dol;				dol = strrchr(bc_proc, '/');				if	( dol )					*dol = '\0';				else					*bc_proc = '\0';				bc_proc_level --;				}			}		// skip text line		while ( *p != '\0' && *p != '\n' )			p ++;		if	( *p )			p ++;		}	if	( bc_proc_level )		sc_raise("FILE %s: SUB/FUNC END, MISSING", bc_fileName);	bc_proc_level = 0;	*bc_proc = '\0';	dev_printf("File: \033\[1m%s\033\[0m\nSection: \033\[1m%s\033\[0m\n", bc_fileName, bc_sec);	/*	*	start	*/	if	( !scan_error )	{		scan_line = 0;	// remove this for common line nums		dev_printf("PASS1: Line %d", scan_line+1);		ps = p = new_text;		while ( *p )	{			if	( *p == '\n' )	{				*p = '\0';				scan_line ++;				if	( (scan_line % 32) == 0 )					dev_printf("\rPASS1: Line %d", scan_line);				bc_add2i(&bc_prog, kwTYPE_LINE, scan_line);				strcpy(code_line, ps);				bc_scan_cmd(code_line);				if	( scan_error )					break;				ps = p+1;				}			if	( scan_error )				break;			p ++;			}		}	tmp_free(code_line);	tmp_free(new_text);	bc_eoc(&bc_prog);	bc_resize(&bc_prog, bc_prog.count);	if	( !scan_error )	{		dev_printf("\rPASS1: Line %d; finished\n", scan_line+1);		#if !defined(_PalmOS)		dev_printf("\rMemUsed: %d\n", memmgr_getalloc());		#endif		dev_printf("\n");		}}/**	PASS 2*/void	bc_pass2(void) SEC(BCSCAN);void	bc_pass2(){	dev_printf("PASS2...");	if	( bc_proc_level )			sc_raise("MISSING SUB/FUNC-END");	else if	( block_level )			sc_raise("MISSING LOOP-END");	else	{		first_data_ip = bc_prog.count;		bc_pass2_scan();		}	if	( bc_data.count )			bc_append(&bc_prog, &bc_data);}/**	create bytecode*/mem_t	bc_createbin(void) SEC(BCSCAN);mem_t	bc_createbin(){	word   		len, i;	mem_t		buff_h;	byte		*buff;	label_t		label;	dev_printf("Creating byte-code...\n");	// total length	len = 10; 					// num of vars + num of labels + def.data_ip + size of bytecode var	len += (lab_count * 2);		// size of label table	len += bc_prog.count;		// size of bytecode	buff_h = mem_alloc(len+4); 	// +4 (checkop1233)	buff = mem_lock(buff_h);	// number of variables	memcpy(buff, &var_count, 2);	// number of labels	memcpy(buff+2, &lab_count, 2);	// label table	for ( i = 0; i < lab_count; i ++ )	{		dbt_read(lab_table, i, &label, sizeof(label_t));		memcpy(buff+(i<<1)+4, &label.ip, 2);		}	// first data ip	memcpy(buff+(lab_count<<1)+4, &first_data_ip, 2);	// program length	memcpy(buff+(lab_count<<1)+6, &bc_prog.count, 2);	// the program itself	memcpy(buff+(lab_count<<1)+8, bc_prog.ptr, bc_prog.count);	dev_printf("Variables  %d\n", var_count);	dev_printf("Labels     %d\n", lab_count);	dev_printf("Proc/Func  %d\n", proc_count);	dev_printf("Code size  %d\n", bc_prog.count);	dev_printf("\n");	mem_unlock(buff_h);	return buff_h;	}

⌨️ 快捷键说明

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