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

📄 scan.c

📁 smallbasic for linux
💻 C
📖 第 1 页 / 共 4 页
字号:
	char	pname[33], vname[33];	if	( scan_error )		return;	str_alltrim(text);	p = text;	if	( *p == ':' )	{		p ++;		bc_scan_cmd(p);		return;		}	// remark	if	( *p == '\'' || *p == '#' )	return;	// empty line	if	( *p == '\0' )		return;	lb_end = p = bc_getkeywordstr((char *)text, bc_name);	last_cmd = p;	p = get_param_sect(p, ":", bc_parm);	/* check old style labels */	if	( is_all_digits(bc_name) )	{		str_alltrim(bc_name);		idx = bc_get_label_id(bc_name);		bc_set_label_ip(idx);		if	( scan_error )		return;		// continue		last_cmd = p = bc_getkeywordstr(lb_end, bc_name);		if	( strlen(bc_name) == 0 )	{			if	( !p )	return;			if	( *p == '\0' ) return;			}		p = get_param_sect(p, ":", bc_parm);		}	/* what is this ? */	idx = bc_is_keyword(bc_name);	if	( idx == kwLET )	{	// old-style keyword LET		char	*p;		idx = -1;		p = bc_getkeywordstr(bc_parm, bc_name);		strcpy(bc_parm, p);		}	else if ( idx == kwDECLARE )	{ // declaration		char	*p;		decl = 1;		p = bc_getkeywordstr(bc_parm, bc_name);		idx = bc_is_keyword(bc_name);		strcpy(bc_parm, p);		if	( idx != kwPROC && idx != kwFUNC )	{			sc_raise("USE DECLARE WITH SUB|FUNC KEYWORD");			return;			}		}	//////	sharp = (bc_parm[0] == '#');	if	( bc_parm[0] == '=' && (idx != -1) )	{	// can't check arrays		sc_raise("%s: IS KEYWORD", bc_name);		return;                             		}	else if	( (bc_parm[0] == '=' || bc_parm[0] == '(') && (idx == -1) )	{		// add let command		bc_add2i(&bc_prog, kwLET, bc_get_var_id(bc_name));		if	( bc_parm[0] == '(' )	{			char	*p = strchr(bc_parm, '=');			char	*n;						if	( !p )					sc_raise("MISSING '='");			else	{				if	( *bc_next_char(bc_parm+1) == ')' )	{					bc_scan_expr(p, 0);					}				else	{					// ARRAY (LEFT)					*p = '\0';					n = p;					str_alltrim(bc_parm);					bc_parm[0] = ' ';					bc_parm[strlen(bc_parm)-1] = ' ';						bc_add1(&bc_prog,kwTYPE_LEVEL_BEGIN);					bc_scan_expr(bc_parm, 0);					bc_prog.ptr[bc_prog.count-1] = kwTYPE_LEVEL_END;						*n = '=';					bc_scan_expr(n, 0);					}				}			}		else			bc_scan_expr(bc_parm, 0);		}	else if ( /* idx == kwLET || */ idx == kwCONST )	{		p = bc_getkeywordstr(bc_parm, bc_name);		p = get_param_sect(p, ":", bc_parm);		if	( bc_is_keyword(bc_name) != -1 )			sc_raise("%s: IS KEYWORD", bc_name);		else	{			if	( !(bc_parm[0] == '=' || bc_parm[0] == '(') )					sc_raise("MISSING '='");			else	{				bc_add2i(&bc_prog,idx, bc_get_var_id(bc_name));				bc_scan_expr(bc_parm, 0);				}			}		}	else {		// add generic command		if	( idx != -1 )	{			if	( idx == kwLABEL )	{				str_alltrim(bc_parm);				idx = bc_get_label_id(bc_parm);				bc_set_label_ip(idx);				}			else if	( idx == kwEXIT )	{				bc_add1(&bc_prog, idx);				str_alltrim(bc_parm);				if	( strlen(bc_parm) )	{					idx = bc_is_keyword(bc_parm);					if	( idx == kwFOR || idx == kwLOOP || idx == kwPROC || idx == kwFUNC )							bc_add1(&bc_prog, idx);					else						sc_raise("USE EXIT [FOR|LOOP|SUB|FUNC]");					}				}			else if	( idx == kwDECLARE )	{				}			else if	( idx == kwPROC || idx == kwFUNC )	{				//				//	PROCEDURES/FUNCTIONS				//				char_p_t pars[64];				char	*lpar_ptr;				int		i, count, pidx;				lpar_ptr = strchr(bc_parm, '(');				if	( lpar_ptr )					*lpar_ptr = '\0';				bc_prepname(pname, bc_parm, 32);				if	( decl )	{					// declaration					if	( bc_proc_getip(pname) == 0xFFFF )						bc_addproc(pname);					}				else	{					if	( bc_proc_getip(pname) != 0xFFFF )						sc_raise("PROC/FUNC ALREADY DEFINED: %s", pname);					else {						if	( (pidx = bc_proc_setip(pname, bc_prog.count)) == -1 )	{							pidx = bc_addproc(pname);							bc_proc_setip(pname, bc_prog.count);							}						//						bc_add1(&bc_prog, kwGOTO);						bc_add1i(&bc_prog,0);						bc_add1(&bc_prog,0);						block_level ++; block_id ++;						bc_push();						bc_add1(&bc_prog, idx);						//						if	( bc_proc_level )	{							strcat(bc_proc, "/");							strcat(bc_proc, pname);							}						else							strcpy(bc_proc, pname);						if	( !scan_error )	{							bc_proc_level ++;							if	( idx == kwFUNC )	{	// setup dvar. {F}/{F}								char	*buf;								buf = tmp_alloc(strlen(bc_proc)+strlen(pname)+2);								#if defined(_PalmOS)								StrPrintF(buf, "%s/%s", bc_proc, pname);								#else								sprintf(buf, "%s/%s", bc_proc, pname);								#endif								proc_table[pidx].vid = bc_get_var_id(buf);								tmp_free(buf);								}							else								proc_table[pidx].vid = 0xFFFF;							// parameters							if	( lpar_ptr )	{								char	*buf;								buf = tmp_alloc(TEXT_LINE_SIZE);								*lpar_ptr = '(';								count = bc_getlist_insep(bc_parm, pars, "()", ",", 64);								bc_add2c(&bc_prog, kwTYPE_PARAM, count);								for ( i = 0; i < count; i ++ )	{									if	( strncmp(pars[i], "BYREF ", 6) == 0 )	{										bc_prepname(vname, pars[i]+6, 32);										vattr = 0x80;										}									else	{										bc_prepname(vname, pars[i], 32);										vattr = 0;										}																			if	( strchr(pars[i], '(') )	{										vattr |= 1;										}									bc_add1(&bc_prog, vattr);									#if defined(_PalmOS)									StrPrintF(buf, "%s/%s", bc_proc, vname);									#else									sprintf(buf, "%s/%s", bc_proc, vname);									#endif									bc_add1i(&bc_prog, bc_get_var_id(buf));									}								tmp_free(buf);								}							else	{								bc_add2c(&bc_prog, kwTYPE_PARAM, 0);								}							}						}					}				}			else if	( idx == kwLOCAL )	{	// local variables				char_p_t pars[64];				int		i, count;				count = bc_getlist(bc_parm, pars, ",", 64);				bc_add2c(&bc_prog, kwTYPE_CRVAR, count);				for ( i = 0; i < count; i ++ )	{					bc_prepname(vname, pars[i], 32);					if	( bc_proc_level )	{						char	*buf;						buf = tmp_alloc(strlen(bc_proc)+strlen(vname)+2);						#if defined(_PalmOS)						StrPrintF(buf, "%s/%s", bc_proc, vname);						#else						sprintf(buf, "%s/%s", bc_proc, vname);						#endif						bc_add1i(&bc_prog, bc_get_var_id(buf));						tmp_free(buf);						}					else						bc_add1i(&bc_prog, bc_get_var_id(vname));					}				}			else if ( idx == kwREM )					return;			else if ( idx == kwGOTO )	{				str_alltrim(bc_parm);				bc_push();				bc_add2i(&bc_prog, idx, bc_get_label_id(bc_parm));				bc_add1(&bc_prog, block_level);				}			else if ( idx == kwGOSUB )	{				str_alltrim(bc_parm);				bc_add2i(&bc_prog,idx, bc_get_label_id(bc_parm));				}			//			//	IF			//			else if ( idx == kwIF )	{				// from here, we can scan for inline IF				if	( bc_scan_inline_if(last_cmd) )	{					// inline-IFs					return;					}				else	{					block_level ++; block_id ++;					bc_push();	bc_add1(&bc_prog,idx);	bc_add1i(&bc_prog,0);	bc_add1i(&bc_prog,0);					bc_scan_expr(bc_parm, 0);					bc_add1(&bc_prog,kwTYPE_EOC);	//bc_eoc();					}				}			//			//	ON x GOTO|GOSUB ...			//			else if ( idx == kwON )	{				char	*p;				int		keep_ip, count;				char_p_t pars[64];				int		i;							idx = kwONJMP;		// WARNING!				bc_push();				bc_add1(&bc_prog,idx);				bc_add1i(&bc_prog,0); bc_add1i(&bc_prog,0);	// true/false ip (pass2)				if	( (p = strstr(bc_parm, " GOTO ")) != NULL )	{					bc_add1(&bc_prog, kwGOTO);	// the command					*p = '\0'; p += 6;					keep_ip = bc_prog.count;					bc_add1(&bc_prog, 0);			// the counter					//count = bc_scan_label_list(p);					count = bc_getlist(p, pars, ",", 64);					for ( i = 0; i < count; i ++ )							bc_add1i(&bc_prog, bc_get_label_id(pars[i]));					if	( count == 0 )						sc_raise("ON x GOTO WHERE?");					else							bc_prog.ptr[keep_ip] = count;					bc_scan_expr(bc_parm, 0);	// the expression					bc_eoc(&bc_prog);					}				else if	( (p = strstr(bc_parm, " GOSUB ")) != NULL )	{					bc_add1(&bc_prog,kwGOSUB);	// the command					*p = '\0';	p += 7;					keep_ip = bc_prog.count;					bc_add1(&bc_prog,0);			// the counter					//count = bc_scan_label_list(p);					count = bc_getlist(p, pars, ",", 64);					for ( i = 0; i < count; i ++ )							bc_add1i(&bc_prog, bc_get_label_id(pars[i]));					if	( count == 0 )						sc_raise("ON x GOSUB WHERE?");					else							bc_prog.ptr[keep_ip] = count;					bc_scan_expr(bc_parm, 0);	// the expression					bc_eoc(&bc_prog);					}				else					sc_raise("ON WHAT?");				}			//			//	FOR			//			else if ( idx == kwFOR )	{				char	*p = strchr(bc_parm, '=');				char	*p_lev;				char	*n;							block_level ++; block_id ++;				bc_push();					bc_add1(&bc_prog, kwFOR);					bc_add1i(&bc_prog, 0);				bc_add1i(&bc_prog, 0);				if	( !p )						sc_raise("FOR: MISSING '='");				else	{					*p = '\0';					n = p;					strcpy(bc_name, bc_parm);					str_alltrim(bc_name);					if	( !is_alpha(*bc_name) )						sc_raise("FOR: %s IS NOT A VARIABLE", bc_name);					else	{						p_lev = bc_name;						while ( is_alnum(*p_lev) || *p_lev == ' ' )	p_lev ++;						if	( *p_lev == '(' )								sc_raise("FOR: %s IS AN ARRAY", bc_name);						else	{							bc_add2i(&bc_prog, kwTYPE_VAR, bc_get_var_id(bc_name));							*n = '=';							bc_scan_expr(n+1, 0);							}						}					}				}			//			//	WHILE - REPEAT			//			else if ( idx == kwWHILE || idx == kwREPEAT )	{				// WHILE & REPEAT DOES NOT USE STACK 				block_level ++; block_id ++;				bc_push();	bc_add1(&bc_prog,idx);	bc_add1i(&bc_prog,0);	bc_add1i(&bc_prog,0);				bc_scan_expr(bc_parm, 0);				}			else if ( idx == kwELSE || idx == kwELIF )	{				bc_push();	bc_add1(&bc_prog,idx);	bc_add1i(&bc_prog,0);	bc_add1i(&bc_prog,0);				bc_scan_expr(bc_parm, 0);				}			else if ( idx == kwENDIF || idx == kwNEXT )	{				bc_push();	bc_add1(&bc_prog,idx);	bc_add1i(&bc_prog,0);	bc_add1i(&bc_prog,0);				block_level --;				}			else if ( idx == kwWEND || idx == kwUNTIL )	{				bc_push();	bc_add1(&bc_prog,idx);	bc_add1i(&bc_prog,0);	bc_add1i(&bc_prog,0);				// WHILE & REPEAT DOES NOT USE STACK				block_level --;				bc_scan_expr(bc_parm, 0);				}			else if (  idx == kwSTEP || idx == kwTO || idx == kwTHEN 					|| idx == kwCOS  || idx == kwSIN || idx == kwLEN || idx == kwLOOP  )		// functions...				{				sc_raise("%s: WRONG POSITION", bc_name);				}			else if ( idx == kwRESTORE )	{				bc_push();				bc_add2i(&bc_prog, idx, bc_get_label_id(bc_parm));				}			else if ( idx == kwEND )	{				if	( bc_proc_level )	{					char	*dol;					// UDP/F RETURN					dol = strrchr(bc_proc, '/');					if	( dol )						*dol = '\0';					else						*bc_proc = '\0';					bc_push();					bc_add1(&bc_prog, kwTYPE_RET);					bc_proc_level --;					block_level --; block_id ++;					}				else	{					// END OF PROG					bc_add1(&bc_prog, idx);					}				}			else if ( idx == kwSTOP )				bc_add1(&bc_prog, idx);			else if ( idx == kwDATA )					bc_scan_data(bc_parm);			else if ( idx == kwINPUT && sharp )	{				bc_add1(&bc_prog, kwFILEINPUT);				bc_scan_expr(bc_parm, 0);				}			else if ( idx == kwPRINT && sharp )	{				bc_add1(&bc_prog, kwFILEPRINT);				bc_scan_expr(bc_parm, 0);				}			else	{				bc_add1(&bc_prog, idx);				bc_scan_expr(bc_parm, 0);				}			}		else	{			int		udp;			udp = bc_get_proc_id(bc_name);			if	( udp == -1 )				sc_raise("%s: UNKNOWN COMMAND", bc_name);			else	{				bc_push();				bc_add2i(&bc_prog, kwTYPE_CALL_UDP, udp);				bc_add1i(&bc_prog, 0);				bc_add1(&bc_prog, kwTYPE_LEVEL_BEGIN);				bc_scan_expr(bc_parm, 0);				bc_add1(&bc_prog, kwTYPE_LEVEL_END);				}			}		}	if	( *p == ':' )	{		// command separator		bc_eoc(&bc_prog);		p ++;		bc_scan_cmd(p);		}}/**	skip command bytes*/word	bc_nextcmd(word ip) SEC(BCSCAN);word	bc_nextcmd(word ip){	word	code;	word	len;	code = bc_prog.ptr[ip];	ip ++;	switch ( code )	{	case	kwEXIT:		if	( bc_prog.ptr[ip] == kwFOR || bc_prog.ptr[ip] == kwLOOP ||		      bc_prog.ptr[ip] == kwPROC || bc_prog.ptr[ip] == kwFUNC )			ip ++;		break;	case	kwTYPE_SEP:	case	kwTYPE_LOGOPR:	case	kwTYPE_CMPOPR:	case	kwTYPE_ADDOPR:	case	kwTYPE_MULOPR:	case	kwTYPE_POWOPR:	case	kwTYPE_UNROPR:		ip ++;		break;	case	kwLET:	case	kwTYPE_LINE:	case	kwLABEL:	case	kwGOSUB:	case	kwRESTORE:	case	kwTYPE_VAR:	case	kwTYPE_CALL_UDP:	case	kwTYPE_CALL_UDF:		ip += 2;		break;	case	kwGOTO:		ip += 3;		break;	case	kwTYPE_CRVAR:		len = bc_prog.ptr[ip];		ip += (len * 2) + 1;		break;	case	kwTYPE_PARAM:		len = bc_prog.ptr[ip];		ip += (len * 3) + 1;		break;	case	kwONJMP:		ip += 5;		ip += (bc_prog.ptr[ip] << 1);		break;	case	kwTYPE_INT:		ip += 4;		break;	case	kwTYPE_NUM:		ip += 8;		break;	case	kwTYPE_STR:		memcpy(&len, bc_prog.ptr+ip, 2);		len += 2;		ip += len;		break;	case	kwIF:		case	kwFOR: 		case	kwWHILE:	case	kwREPEAT:	case	kwELSE:		case	kwELIF:	case	kwENDIF:	case	kwNEXT:		case	kwWEND:		case	kwUNTIL:		ip += 4;		break;		};	return ip;}/**	search for command (in byte-code)*/word	bc_search(word ip, byte code){	word	i = ip;	do	{		if	( code == bc_prog.ptr[i] )			return i;		i = bc_nextcmd(i);		} while ( i < bc_prog.count );	return 0xFFFF;}/**	search for End-Of-Command mark*/word	bc_search_eoc(word ip) SEC(BCSCAN);word	bc_search_eoc(word ip){	word	i = ip;	word	code;	do	{		code = bc_prog.ptr[i];		if	( code == kwTYPE_EOC || code == kwTYPE_LINE )			return i;		i = bc_nextcmd(i);		} while ( i < bc_prog.count );	return bc_prog.count;}/**	search stack*/word	bc_search_stack(word start, word code, word level) SEC(BCSCAN);word	bc_search_stack(word start, word code, word level){	word		i;	pass_node_t	node;	for ( i = start; i < stk_count; i ++ )	{		dbt_read(bc_stack, i, &node, sizeof(pass_node_t));		if	( node.level == level )	{			if	( bc_prog.ptr[node.pos] == code )				return node.pos;			}		}	return 0xFFFF;}/**	search stack backward*/word	bc_search_stack_backward(word start, word code, word level) SEC(BCSCAN);word	bc_search_stack_backward(word start, word code, word level){	word		i = start;	pass_node_t	node;	for ( ; i < stk_count; i -- )	{	// WARNING: ITS UNSIGNED, SO WE'LL SEARCH IN RANGE [0..STK_COUNT]		dbt_read(bc_stack, i, &node, sizeof(pass_node_t));		if	( node.level == level )	{			if	( bc_prog.ptr[node.pos] == code )				return node.pos;			}		}	return 0xFFFF;}/**	PASS 2 (write jumps for IF/FOR/WHILE/REPEAT)*/void	bc_pass2_scan(void) SEC(BCSCAN);void	bc_pass2_scan(){	word	i, j, true_ip, false_ip, label_id, w;	word	a_ip, b_ip, c_ip, count;	byte	code, level;	pass_node_t	node;	label_t	label;	dev_printf("\rPASS2: Node %d/%d", i, stk_count);	for ( i = 0; i < stk_count; i ++ )	{		if	( (i % 32) == 0 )			dev_printf("\rPASS2: Node %d/%d", i, stk_count);		dbt_read(bc_stack, i, &node, sizeof(pass_node_t));		scan_line = node.line;		strcpy(bc_sec, node.sec);		code = bc_prog.ptr[node.pos];		if	(  code != kwGOTO && code != kwRESTORE 		    && code != kwTYPE_CALL_UDP && code != kwTYPE_CALL_UDF 			&& code != kwPROC && code != kwFUNC && code != kwTYPE_RET )	{			true_ip = bc_search_eoc(node.pos+5);			memcpy(bc_prog.ptr+node.pos+1, &true_ip, 2);			}		switch ( code )	{		case kwPROC:		case kwFUNC:			// update start's GOTO			true_ip = bc_search_stack(i+1, kwTYPE_RET, node.level) + 1;			memcpy(bc_prog.ptr+node.pos-3, &true_ip, 2);			break;		case kwRESTORE:			memcpy(&label_id, bc_prog.ptr+node.pos+1, 2);

⌨️ 快捷键说明

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