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

📄 var.c

📁 smallbasic for linux
💻 C
字号:
/***	SmallBasic Variable Manager.**	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*/#include "sys.h"#include "str.h"#include "var.h"extern word prog_line;/* ERROR MESSAGES */void	err_varisarray()	SEC(TRASH);void	err_varisarray()	{	rt_raise("EVAL: VARIABLE IS ARRAY"); }void	err_varisnotarray()	SEC(TRASH);void	err_varisnotarray()	{	rt_raise("EVAL: VARIABLE IS NOT AN ARRAY (USE DIM)"); }void	err_vararridx()		SEC(TRASH);void	err_vararridx()		{	rt_raise("EVAL: ARRAY-INDEX OUT OF RANGE"); }void	err_varnotnum()		SEC(TRASH);void	err_varnotnum()		{	rt_raise("EVAL: NOT A NUMBER"); }void	err_evsyntax()		SEC(TRASH);void	err_evsyntax()		{	rt_raise("EVAL: SYNTAX ERROR"); }/**	initialize a variable*/void	v_init(var_t *v){	v->const_flag = 0;	v->type = V_INT;	v->i = 0;	v->n = 0.0;	v->ptr = NULL;	v->size = 0;}/**/var_t*		v_new(){	var_t	*ptr;	ptr = (var_t *) tmp_alloc(sizeof(var_t));	v_init(ptr);	return ptr;}/**	release variable*/void	v_free(var_t *v){	int		i;	var_t	*elem;	if	( v->type == V_STR || v->type == V_PTR )	{		if	( v->ptr )			tmp_free(v->ptr);		v->ptr  = NULL;		v->size = 0;		}	else if ( v->type == V_ARRAY )	{		if	( v->ptr )	{			for ( i = 0; i < v->size; i ++ )	{				elem = (var_t *) (v->ptr + (sizeof(var_t) * i));				v_free(elem);				}			tmp_free(v->ptr);			v->ptr  = NULL;			v->size = 0;			}		}	v_init(v);}/**	returns the floating-point value of the variable v*/double	v_getval(var_t *v){	if	( v == NULL )		err_evsyntax();	else	{		switch ( v->type )	{		case V_INT:			return v->i;		case V_NUM:			return v->n;		case V_STR:			return numexpr_strtof(v->ptr);		default:			err_varisarray();			}		}	return 0;}/**	returns the integer value of the variable v*/long	v_igetval(var_t *v){	switch ( v->type )	{	case V_INT:		return v->i;	case V_NUM:		return v->n;	case V_STR:		return numexpr_strtol(v->ptr);	default:		err_varisarray();		}	return 0;}/**	return array element pointer*/var_t*	v_getelemptr(var_t *v, word index){	if	( v->type == V_ARRAY )	{		if	( index < v->size )			return (var_t*) (v->ptr+ (index * sizeof(var_t)) );		else	{			err_vararridx();			return NULL;			}		}	err_varisnotarray();	return NULL;}/**/void	v_resize_array(var_t *v, int size){	byte	*prev;	var_t	*elem;	int		i;	if	( v->type == V_ARRAY )	{		if	( v->size > size )	{			// resize down			// free vars			for ( i = size; i < v->size; i ++ )	{				elem = (var_t *) (v->ptr + (sizeof(var_t) * i));				v_free(elem);				}			// copy			prev = v->ptr;			v->ptr = tmp_alloc(size * sizeof(var_t));			memcpy(v->ptr, prev, size * sizeof(var_t));			// array data			v->size = size;			v->ubound[0] = v->lbound[0] + (size - 1);			v->maxdim = 1;			//			tmp_free(prev);			}		else	{			// resize up			// copy			prev = v->ptr;			v->ptr = tmp_alloc(size * sizeof(var_t));			memcpy(v->ptr, prev, v->size * sizeof(var_t));			// init vars			for ( i = v->size; i < size; i ++ )	{				elem = (var_t *) (v->ptr + (sizeof(var_t) * i));				v_init(elem);				}			// array data			v->size = size;			v->ubound[0] = v->lbound[0] + (size - 1);			v->maxdim = 1;			//			tmp_free(prev);			}		}	else		err_varisnotarray();}/**	returns true if the variable v is not empty (0 for nums)*/int		v_is_nonzero(var_t *v){	switch ( v->type )	{	case	V_INT:		return (v->i != 0);	case	V_NUM:		return (v->n != 0.0 && v->n != -0.0);	case	V_STR:	case	V_ARRAY:	case	V_PTR:		return (v->size != 0);		};	return 0;}/**	compare the variable a with the variable b*	returns*	-1		a < b*	+1		a > b*	0		a = b*/int		v_compare(var_t *a, var_t *b){	double	dt;	long	di;	if	( a->type == V_INT && b->type == V_INT )	{		di = (a->i - b->i); 		if	( di < 0 )			// ndc: 18/03/2001			return -1;		if	( di > 0 )			return 1;		return 0;		}	else if	( (a->type == V_INT || a->type == V_NUM) && (b->type == V_INT || b->type == V_NUM) )	{		dt = ( ((a->type == V_INT) ? a->i : a->n) - ((b->type == V_INT) ? b->i : b->n) ); 				if	( dt < 0.0 )		// ndc: 18/03/2001			return -1;		if ( dt > 0.0 )			return 1;		return 0;		}	if	( (a->type == V_STR) && (b->type == V_STR) )			return strcmp(a->ptr, b->ptr);	if	( (a->type == V_STR) && (b->type == V_NUM) )	{		if	( a->ptr[0] == '\0' || is_number(a->ptr) )	{	// compare nums			dt = v_getval(a);			return ( dt < b->n ) ? -1 : ((dt == b->n) ? 0 : 1);			}		//err_typemismatch();		return 1;		}	if	( (a->type == V_NUM) && (b->type == V_STR) )	{		if	( b->ptr[0] == '\0' || is_number(b->ptr) )	{	// compare nums			dt = v_getval(b);			return ( dt < a->n ) ? 1 : ((dt == a->n) ? 0 : -1);			}		//err_typemismatch();		return -1;		}	if	( (a->type == V_STR) && (b->type == V_INT) )	{		if	( a->ptr[0] == '\0' || is_number(a->ptr) )	{	// compare nums			di = v_igetval(a);			return ( di < b->i ) ? -1 : ((di == b->i) ? 0 : 1);			}		//err_typemismatch();		return 1;		}	if	( (a->type == V_INT) && (b->type == V_STR) )	{		if	( b->ptr[0] == '\0' || is_number(b->ptr) )	{	// compare nums			di = v_igetval(b);			return ( di < a->i ) ? 1 : ((di == a->i) ? 0 : -1);			}		//err_typemismatch();		return -1;		}	return 0;}/**/int		v_addtype(var_t *a, var_t *b){	if	( a->type == V_STR )		return V_STR;	if	( a->type == V_NUM || b->type == V_NUM )		return V_NUM;	if	( a->type == V_INT || b->type == V_STR )		return V_NUM;	return V_INT;}/**	add two variables*	result = a + b*/void	v_add(var_t *result, var_t *a, var_t *b){	char	tmpsb[64];	if	( a->type == V_STR && b->type == V_STR )	{		result->type = V_STR;		result->ptr = (char *) tmp_alloc(strlen(a->ptr) + strlen(b->ptr) + 1);		strcpy(result->ptr, a->ptr);		strcat(result->ptr, b->ptr);		result->size = strlen(result->ptr) + 1;		return;		}	else if ( a->type == V_INT && b->type == V_INT )	{		result->type = V_INT;		result->i = a->i + b->i;		return;		}	else if ( a->type == V_NUM && b->type == V_NUM )	{		result->type = V_NUM;		result->n = a->n + b->n;		return;		}	else if ( a->type == V_NUM && b->type == V_INT )	{		result->type = V_NUM;		result->n = a->n + b->i;		return;		}	else if ( a->type == V_INT && b->type == V_NUM )	{		result->type = V_NUM;		result->n = a->i + b->n;		return;		}	else if ( a->type == V_STR && (b->type == V_INT || b->type == V_NUM) )	{		if	( is_number(a->ptr) )	{			result->type = V_NUM;			if	( b->type == V_INT )				result->n = b->i + v_getval(a);			else				result->n = b->n + v_getval(a);			}		else	{			result->type = V_STR;			result->ptr = (char *) tmp_alloc(strlen(a->ptr) + 64);			strcpy(result->ptr, a->ptr);			if	( b->type == V_INT )				ltostr(b->i, tmpsb);			else				ftostr(b->n, tmpsb);			strcat(result->ptr, tmpsb);			result->size = strlen(result->ptr) + 1;			}		}	else if ( (a->type == V_INT || a->type == V_NUM) && b->type == V_STR )	{		if	( is_number(b->ptr) )	{			result->type = V_NUM;			if	( a->type == V_INT )				result->n = a->i + v_getval(b);			else				result->n = a->n + v_getval(b);			}		else	{			result->type = V_STR;			result->ptr = (char *) tmp_alloc(strlen(b->ptr) + 64);			if	( a->type == V_INT )				ltostr(a->i, tmpsb);			else				ftostr(a->n, tmpsb);			strcpy(result->ptr, tmpsb);			strcat(result->ptr, b->ptr);			result->size = strlen(result->ptr) + 1;			}		}}/**	assign (dest = src)*/void	v_set(var_t *dest, const var_t *src){	int		i;	var_t	*dest_vp, *src_vp;	v_free(dest);	*dest = *src;	dest->const_flag = 0;	if	( src->type == V_STR )	{		dest->ptr = tmp_alloc(strlen(src->ptr)+1);		strcpy(dest->ptr, src->ptr);		}	else if ( src->type == V_ARRAY )	{		dest->ptr = tmp_alloc(src->size * sizeof(var_t));		// copy each element		for ( i = 0; i < src->size; i ++ )	{			src_vp  = (var_t *) (src->ptr  + (sizeof(var_t) * i));			dest_vp = (var_t *) (dest->ptr + (sizeof(var_t) * i));			v_init(dest_vp);			v_set(dest_vp, src_vp);			}		}	else if ( src->type == V_PTR )	{		dest->ptr = tmp_alloc(src->size);		memcpy(dest->ptr, src->ptr, src->size);		}}/**	return a full copy of the 'source'*/var_t*	v_clone(const var_t *source){	var_t	*vnew;	vnew = (var_t *) tmp_alloc(sizeof(var_t));	v_init(vnew);	v_set(vnew, source);	return vnew;}/**	add b to a*/void	v_inc(var_t *a, var_t *b){	if	( a->type == V_INT && b->type == V_INT )		a->i += b->i;	else if	( a->type == V_NUM && b->type == V_NUM )		a->n += b->n;	else if	( a->type == V_NUM && b->type == V_INT )		a->n += b->i;	else if	( a->type == V_INT && b->type == V_NUM )	{		a->type = V_NUM;		a->n = a->i + b->n;		}	else		err_varnotnum();}/**/int		v_sign(var_t *x){	if	( x->type == V_INT )		return (x->i < 0) ? -1 : ((x->i == 0) ? 0 : 1);	else if	( x->type == V_NUM )		return (x->n < 0) ? -1 : ((x->n == 0) ? 0 : 1);	err_varnotnum();	return 0;}/**/void	v_createstr(var_t *v, const char *src){	int		l;	l = strlen(src) + 1;	v->type = V_STR;	v->ptr = tmp_alloc(l);	v->size = l;	strcpy(v->ptr, src);}/**	converts the variable to string-variable*/void	v_tostr(var_t *arg){	if	( arg->type != V_STR )	{		char	*tmp;		int		l;			tmp = tmp_alloc(64);				switch ( arg->type )	{		case	V_INT:			ltostr(arg->i, tmp);			break;		case	V_NUM:			ftostr(arg->n, tmp);			break;			}		l = strlen(tmp)+1;		arg->type = V_STR;		arg->ptr = tmp_alloc(l);		arg->size = l;		strcpy(arg->ptr, tmp);		tmp_free(tmp);		}}

⌨️ 快捷键说明

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