📄 var.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 + -