+Improved array; *Polished data precision related macros.
This commit is contained in:
parent
40bc0a9d0e
commit
2a56f4374c
5
HISTORY
5
HISTORY
@ -1,3 +1,8 @@
|
||||
May. 5 2015
|
||||
Added string type support for non-simple array
|
||||
Fixed a memory leak when storing strings to a non-string array
|
||||
Polished data precision related macros
|
||||
|
||||
Apr. 27 2015
|
||||
Added code line inserting/removing to interpreter shell
|
||||
Changed mb_dispose_value as public
|
||||
|
118
core/my_basic.c
118
core/my_basic.c
@ -51,6 +51,7 @@ extern "C" {
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4127)
|
||||
# pragma warning(disable : 4305)
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#ifdef __APPLE__
|
||||
@ -62,7 +63,7 @@ extern "C" {
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn -8004
|
||||
# pragma warn -8008
|
||||
# pragma warn -8066
|
||||
# pragma warn -8012
|
||||
#endif /* __BORLANDC__ */
|
||||
|
||||
#ifdef MB_COMPACT_MODE
|
||||
@ -77,7 +78,7 @@ extern "C" {
|
||||
/** Macros */
|
||||
#define _VER_MAJOR 1
|
||||
#define _VER_MINOR 1
|
||||
#define _VER_REVISION 52
|
||||
#define _VER_REVISION 53
|
||||
#define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION))
|
||||
|
||||
/* Uncomment this line to treat warnings as error */
|
||||
@ -211,12 +212,6 @@ static const char* _ERR_DESC[] = {
|
||||
mb_static_assert(_countof(_ERR_DESC) == SE_COUNT);
|
||||
|
||||
/* Data type */
|
||||
#define _EOS '\n'
|
||||
#define _NULL_STRING "(empty)"
|
||||
|
||||
#define _FNAN 0xffc00000
|
||||
#define _FINF 0x7f800000
|
||||
|
||||
typedef enum _data_e {
|
||||
_DT_NIL = -1,
|
||||
_DT_ANY = 0,
|
||||
@ -377,6 +372,28 @@ static const char _PRECEDE_TABLE[19][19] = {
|
||||
|
||||
static _object_t* _exp_assign = 0;
|
||||
|
||||
#define _set_real_with_hex(__r, __i) \
|
||||
do { \
|
||||
if(sizeof(__r) == sizeof(unsigned char)) { \
|
||||
unsigned char __b = __i; \
|
||||
memcpy(&__r, &__b, sizeof(__r)); \
|
||||
} else if(sizeof(__r) == sizeof(unsigned short)) { \
|
||||
unsigned short __b = __i; \
|
||||
memcpy(&__r, &__b, sizeof(__r)); \
|
||||
} else if(sizeof(__r) == sizeof(unsigned)) { \
|
||||
unsigned __b = __i; \
|
||||
memcpy(&__r, &__b, sizeof(__r)); \
|
||||
} else if(sizeof(__r) == sizeof(unsigned long)) { \
|
||||
unsigned long __b = __i; \
|
||||
memcpy(&__r, &__b, sizeof(__r)); \
|
||||
} else if(sizeof(__r) == sizeof(unsigned long long)) { \
|
||||
unsigned long long __b = __i; \
|
||||
memcpy(&__r, &__b, sizeof(__r)); \
|
||||
} else { \
|
||||
mb_assert(0 && "Invalid real number precision."); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define _instruct_common(__tuple) \
|
||||
_object_t opndv1; \
|
||||
_object_t opndv2; \
|
||||
@ -480,10 +497,10 @@ static _object_t* _exp_assign = 0;
|
||||
if((opndv2.type == _DT_INT && opndv2.data.integer == 0) || (opndv2.type == _DT_REAL && opndv2.data.float_point == 0.0f)) { \
|
||||
if((opndv1.type == _DT_INT && opndv1.data.integer == 0) || (opndv1.type == _DT_REAL && opndv1.data.float_point == 0.0f)) { \
|
||||
val->type = _DT_REAL; \
|
||||
val->data.integer = _FNAN; \
|
||||
_set_real_with_hex(val->data.float_point, MB_FNAN); \
|
||||
} else { \
|
||||
val->type = _DT_REAL; \
|
||||
val->data.integer = _FINF; \
|
||||
_set_real_with_hex(val->data.float_point, MB_FINF); \
|
||||
} \
|
||||
_handle_error_on_obj((__s), __kind, ((__tuple) && *(__tuple)) ? ((_object_t*)(((_tuple3_t*)(*(__tuple)))->e1)) : 0, MB_FUNC_WARNING, __exit, __result); \
|
||||
} \
|
||||
@ -651,7 +668,7 @@ static bool_t _try_get_value(_object_t* obj, mb_value_u* val, _data_e expected);
|
||||
|
||||
static int _get_array_index(mb_interpreter_t* s, _ls_node_t** l, unsigned int* index);
|
||||
static bool_t _get_array_elem(mb_interpreter_t* s, _array_t* arr, unsigned int index, mb_value_u* val, _data_e* type);
|
||||
static bool_t _set_array_elem(mb_interpreter_t* s, _array_t* arr, unsigned int index, mb_value_u* val, _data_e* type);
|
||||
static int _set_array_elem(mb_interpreter_t* s, _ls_node_t* ast, _array_t* arr, unsigned int index, mb_value_u* val, _data_e* type);
|
||||
|
||||
static void _init_array(_array_t* arr);
|
||||
static void _clear_array(_array_t* arr);
|
||||
@ -2101,7 +2118,11 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
||||
}
|
||||
if(context->last_symbol && context->last_symbol->type == _DT_FUNC) {
|
||||
if(strcmp("DIM", context->last_symbol->data.func->name) == 0) {
|
||||
#ifdef MB_SIMPLE_ARRAY
|
||||
en = (sym[_sl - 1] == '$' ? _DT_STRING : _DT_REAL);
|
||||
#else /* MB_SIMPLE_ARRAY */
|
||||
en = _DT_REAL;
|
||||
#endif /* MB_SIMPLE_ARRAY */
|
||||
memcpy(*value, &en, sizeof(en));
|
||||
|
||||
result = _DT_ARRAY;
|
||||
@ -2132,8 +2153,8 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
|
||||
|
||||
goto _exit;
|
||||
}
|
||||
/* _EOS */
|
||||
if(_sl == 1 && sym[0] == _EOS) {
|
||||
/* MB_EOS */
|
||||
if(_sl == 1 && sym[0] == MB_EOS) {
|
||||
result = _DT_EOS;
|
||||
|
||||
goto _exit;
|
||||
@ -2203,7 +2224,7 @@ int _parse_char(mb_interpreter_t* s, char c, int pos, unsigned short row, unsign
|
||||
result += _cut_symbol(s, pos, row, col);
|
||||
} else if(_is_newline(c)) { /* \r \n EOF */
|
||||
result += _cut_symbol(s, pos, row, col);
|
||||
result += _append_char_to_symbol(s, _EOS);
|
||||
result += _append_char_to_symbol(s, MB_EOS);
|
||||
result += _cut_symbol(s, pos, row, col);
|
||||
} else if(_is_separator(c) || _is_bracket(c)) { /* , ; : ( ) */
|
||||
result += _cut_symbol(s, pos, row, col);
|
||||
@ -2215,7 +2236,7 @@ int _parse_char(mb_interpreter_t* s, char c, int pos, unsigned short row, unsign
|
||||
context->parsing_state = _PS_STRING;
|
||||
} else if(_is_comment(c)) { /* ' */
|
||||
result += _cut_symbol(s, pos, row, col);
|
||||
result += _append_char_to_symbol(s, _EOS);
|
||||
result += _append_char_to_symbol(s, MB_EOS);
|
||||
result += _cut_symbol(s, pos, row, col);
|
||||
context->parsing_state = _PS_COMMENT;
|
||||
} else {
|
||||
@ -2295,6 +2316,7 @@ int_t _get_size_of(_data_e type) {
|
||||
mb_assert(0 && "Unsupported");
|
||||
}
|
||||
#else /* MB_SIMPLE_ARRAY */
|
||||
mb_unrefvar(type);
|
||||
result = sizeof(_raw_u);
|
||||
#endif /* MB_SIMPLE_ARRAY */
|
||||
|
||||
@ -2416,6 +2438,9 @@ bool_t _get_array_elem(mb_interpreter_t* s, _array_t* arr, unsigned int index, m
|
||||
} else if(arr->types[index] == _DT_USERTYPE) {
|
||||
val->usertype = *((void**)rawptr);
|
||||
*type = _DT_USERTYPE;
|
||||
} else if(arr->types[index] == _DT_STRING) {
|
||||
val->string = *((char**)rawptr);
|
||||
*type = _DT_STRING;
|
||||
} else {
|
||||
mb_assert(0 && "Unsupported");
|
||||
}
|
||||
@ -2430,12 +2455,13 @@ bool_t _get_array_elem(mb_interpreter_t* s, _array_t* arr, unsigned int index, m
|
||||
return result;
|
||||
}
|
||||
|
||||
bool_t _set_array_elem(mb_interpreter_t* s, _array_t* arr, unsigned int index, mb_value_u* val, _data_e* type) {
|
||||
int _set_array_elem(mb_interpreter_t* s, _ls_node_t* ast, _array_t* arr, unsigned int index, mb_value_u* val, _data_e* type) {
|
||||
/* Set the value of an element in an array */
|
||||
bool_t result = true;
|
||||
int result = MB_FUNC_OK;
|
||||
int_t elemsize = 0;
|
||||
unsigned int pos = 0;
|
||||
void* rawptr = 0;
|
||||
mb_unrefvar(ast);
|
||||
|
||||
mb_assert(s && arr && val);
|
||||
|
||||
@ -2456,7 +2482,15 @@ bool_t _set_array_elem(mb_interpreter_t* s, _array_t* arr, unsigned int index, m
|
||||
arr->types[index] = _DT_REAL;
|
||||
#endif /* MB_SIMPLE_ARRAY */
|
||||
} else if(*type == _DT_STRING) {
|
||||
size_t _sl = strlen(val->string);
|
||||
size_t _sl = 0;
|
||||
#ifndef MB_SIMPLE_ARRAY
|
||||
arr->types[index] = _DT_STRING;
|
||||
#else /* MB_SIMPLE_ARRAY */
|
||||
if(arr->type != _DT_STRING) {
|
||||
_handle_error_on_obj(s, SE_RN_STRING_EXPECTED, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||
}
|
||||
#endif /* MB_SIMPLE_ARRAY */
|
||||
_sl = strlen(val->string);
|
||||
*((char**)rawptr) = (char*)mb_malloc(_sl + 1);
|
||||
memcpy(*((char**)rawptr), val->string, _sl + 1);
|
||||
#ifndef MB_SIMPLE_ARRAY
|
||||
@ -2468,15 +2502,15 @@ bool_t _set_array_elem(mb_interpreter_t* s, _array_t* arr, unsigned int index, m
|
||||
mb_assert(0 && "Unsupported");
|
||||
}
|
||||
|
||||
goto _exit; /* Avoid an unreferenced warning */
|
||||
|
||||
_exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
void _init_array(_array_t* arr) {
|
||||
/* Initialize an array */
|
||||
int elemsize = 0;
|
||||
#ifndef MB_SIMPLE_ARRAY
|
||||
unsigned int ul = 0;
|
||||
#endif
|
||||
|
||||
mb_assert(arr);
|
||||
|
||||
@ -2494,6 +2528,7 @@ void _init_array(_array_t* arr) {
|
||||
#ifndef MB_SIMPLE_ARRAY
|
||||
arr->types = (_data_e*)mb_malloc(sizeof(_data_e) * arr->count);
|
||||
if(arr->types) {
|
||||
unsigned int ul = 0;
|
||||
for(ul = 0; ul < arr->count; ++ul) {
|
||||
arr->types[ul] = _DT_INT;
|
||||
}
|
||||
@ -2512,6 +2547,21 @@ void _clear_array(_array_t* arr) {
|
||||
mb_assert(arr);
|
||||
|
||||
if(arr->raw) {
|
||||
#ifndef MB_SIMPLE_ARRAY
|
||||
if(arr->type == _DT_REAL) {
|
||||
for(ul = 0; ul < arr->count; ++ul) {
|
||||
if(arr->types[ul] == _DT_STRING) {
|
||||
elemsize = _get_size_of(arr->type);
|
||||
pos = (unsigned int)(elemsize * ul);
|
||||
rawptr = (void*)((intptr_t)arr->raw + pos);
|
||||
str = *((char**)rawptr);
|
||||
if(str) {
|
||||
safe_free(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* MB_SIMPLE_ARRAY */
|
||||
if(arr->type == _DT_STRING) {
|
||||
for(ul = 0; ul < arr->count; ++ul) {
|
||||
elemsize = _get_size_of(arr->type);
|
||||
@ -2983,11 +3033,10 @@ int _skip_struct(mb_interpreter_t* s, _ls_node_t** l, mb_func_t open_func, mb_fu
|
||||
obj_prev = (_object_t*)(ast->data);
|
||||
ast = ast->next;
|
||||
obj = (_object_t*)(ast->data);
|
||||
if(_IS_FUNC(obj, open_func)) {
|
||||
if(_IS_FUNC(obj, open_func))
|
||||
++count;
|
||||
} else if(_IS_FUNC(obj, close_func) && _IS_EOS(obj_prev)) {
|
||||
else if(_IS_FUNC(obj, close_func) && _IS_EOS(obj_prev))
|
||||
--count;
|
||||
}
|
||||
} while(count);
|
||||
|
||||
_exit:
|
||||
@ -3780,7 +3829,7 @@ int mb_load_string(struct mb_interpreter_t* s, const char* l) {
|
||||
_col = col;
|
||||
++i;
|
||||
};
|
||||
status = _parse_char(s, _EOS, i, row, col);
|
||||
status = _parse_char(s, MB_EOS, i, row, col);
|
||||
|
||||
_exit:
|
||||
context->parsing_state = _PS_NORMAL;
|
||||
@ -4511,7 +4560,9 @@ int _core_let(mb_interpreter_t* s, void** l) {
|
||||
|
||||
break;
|
||||
}
|
||||
_set_array_elem(s, arr, arr_idx, &_val, &val->type);
|
||||
result = _set_array_elem(s, ast, arr, arr_idx, &_val, &val->type);
|
||||
if(result != MB_FUNC_OK)
|
||||
goto _exit;
|
||||
if(val->type == _DT_STRING && !val->ref) {
|
||||
safe_free(val->data.string);
|
||||
}
|
||||
@ -5897,9 +5948,9 @@ int _std_str(mb_interpreter_t* s, void** l) {
|
||||
chr = (char*)mb_malloc(32);
|
||||
memset(chr, 0, 32);
|
||||
if(arg.type == MB_DT_INT) {
|
||||
sprintf(chr, "%d", arg.value.integer);
|
||||
sprintf(chr, MB_INT_FMT, arg.value.integer);
|
||||
} else if(arg.type == MB_DT_REAL) {
|
||||
sprintf(chr, "%g", arg.value.float_point);
|
||||
sprintf(chr, MB_REAL_FMT, arg.value.float_point);
|
||||
} else {
|
||||
result = MB_FUNC_ERR;
|
||||
|
||||
@ -5980,11 +6031,11 @@ int _std_print(mb_interpreter_t* s, void** l) {
|
||||
case _DT_FUNC:
|
||||
result = _calc_expression(s, &ast, &val_ptr);
|
||||
if(val_ptr->type == _DT_INT) {
|
||||
_get_printer(s)("%d", val_ptr->data.integer);
|
||||
_get_printer(s)(MB_INT_FMT, val_ptr->data.integer);
|
||||
} else if(val_ptr->type == _DT_REAL) {
|
||||
_get_printer(s)("%g", val_ptr->data.float_point);
|
||||
_get_printer(s)(MB_REAL_FMT, val_ptr->data.float_point);
|
||||
} else if(val_ptr->type == _DT_STRING) {
|
||||
_get_printer(s)("%s", (val_ptr->data.string ? val_ptr->data.string : _NULL_STRING));
|
||||
_get_printer(s)("%s", (val_ptr->data.string ? val_ptr->data.string : MB_NULL_STRING));
|
||||
if(!val_ptr->ref) {
|
||||
safe_free(val_ptr->data.string);
|
||||
}
|
||||
@ -5993,9 +6044,8 @@ int _std_print(mb_interpreter_t* s, void** l) {
|
||||
goto _exit;
|
||||
/* Fall through */
|
||||
case _DT_SEP:
|
||||
if(!ast) {
|
||||
if(!ast)
|
||||
break;
|
||||
}
|
||||
obj = (_object_t*)(ast->data);
|
||||
#ifdef _COMMA_AS_NEWLINE
|
||||
if(obj->data.separator == ',') {
|
||||
@ -6098,7 +6148,7 @@ _exit:
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn .8004
|
||||
# pragma warn .8008
|
||||
# pragma warn .8066
|
||||
# pragma warn .8012
|
||||
#endif /* __BORLANDC__ */
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
@ -68,9 +68,6 @@ extern "C" {
|
||||
#ifndef bool_t
|
||||
# define bool_t int
|
||||
#endif
|
||||
#ifndef byte_t
|
||||
# define byte_t unsigned char
|
||||
#endif
|
||||
#ifndef int_t
|
||||
# define int_t int
|
||||
#endif
|
||||
@ -78,6 +75,27 @@ extern "C" {
|
||||
# define real_t float
|
||||
#endif
|
||||
|
||||
#ifndef MB_INT_FMT
|
||||
# define MB_INT_FMT "%d"
|
||||
#endif
|
||||
#ifndef MB_REAL_FMT
|
||||
# define MB_REAL_FMT "%g"
|
||||
#endif
|
||||
|
||||
#ifndef MB_FNAN
|
||||
# define MB_FNAN 0xffc00000
|
||||
#endif
|
||||
#ifndef MB_FINF
|
||||
# define MB_FINF 0x7f800000
|
||||
#endif
|
||||
|
||||
#ifndef MB_EOS
|
||||
# define MB_EOS '\n'
|
||||
#endif
|
||||
#ifndef MB_NULL_STRING
|
||||
# define MB_NULL_STRING "(empty)"
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# ifndef _strcmpi
|
||||
# ifdef __BORLANDC__
|
||||
|
Binary file not shown.
Binary file not shown.
@ -36,8 +36,8 @@
|
||||
IDI_ICON_MAIN ICON "icon.ico"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,1,52,0
|
||||
PRODUCTVERSION 1,1,52,0
|
||||
FILEVERSION 1,1,53,0
|
||||
PRODUCTVERSION 1,1,53,0
|
||||
FILEFLAGSMASK 0x17L
|
||||
# ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -55,13 +55,13 @@
|
||||
VALUE "Comments", "MY-BASIC"
|
||||
VALUE "CompanyName", "W. Renxin"
|
||||
VALUE "FileDescription", "MY-BASIC interpreter"
|
||||
VALUE "FileVersion", "1, 1, 52, 0"
|
||||
VALUE "FileVersion", "1, 1, 53, 0"
|
||||
VALUE "InternalName", "my_basic"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2011 - 2015 W. Renxin"
|
||||
VALUE "LegalTrademarks", "MY-BASIC"
|
||||
VALUE "OriginalFilename", "my_basic.exe"
|
||||
VALUE "ProductName", "MY-BASIC"
|
||||
VALUE "ProductVersion", "1, 1, 52, 0"
|
||||
VALUE "ProductVersion", "1, 1, 53, 0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
Loading…
x
Reference in New Issue
Block a user