Fixed a double precision float parsing bug on all 32bit systems, thanks to Pito for pointing it out; Fixed a exponential number parsing bug, thanks to Pito for pointing it out; Fixed a crash bug when a script begins with a meaningless negtive number.

This commit is contained in:
tony 2015-04-10 22:04:41 +08:00
parent eb5cd615ce
commit e872d26513
7 changed files with 784 additions and 734 deletions

View File

@ -1,3 +1,9 @@
Apr. 10 2015
Improved compatibility with PellesC
Fixed a double precision float parsing bug on all 32bit systems, thanks to Pito for pointing it out
Fixed a exponential number parsing bug, thanks to Pito for pointing it out
Fixed a crash bug when a script begins with a meaningless negtive number
Mar. 25 2015
Changed _strupr macro to mb_strupr function
Added an mb_strdup function

View File

@ -78,7 +78,7 @@ extern "C" {
/** Macros */
#define _VER_MAJOR 1
#define _VER_MINOR 0
#define _VER_REVISION 46
#define _VER_REVISION 47
#define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION))
/* Uncomment this line to treat warnings as error */
@ -258,6 +258,8 @@ typedef struct _label_t {
_ls_node_t* node;
} _label_t;
typedef unsigned char _raw_t[sizeof(union { int_t i; real_t r; void* p; })];
typedef struct _object_t {
_data_e type;
union {
@ -270,6 +272,7 @@ typedef struct _object_t {
_array_t* array;
_label_t* label;
char separator;
_raw_t raw;
} data;
bool_t ref;
int source_pos;
@ -594,6 +597,8 @@ static void* mb_malloc(size_t s);
static void* mb_realloc(void** p, size_t s);
static void mb_free(void* p);
static size_t mb_memtest(void*p, size_t s);
static char* mb_strupr(char* s);
#define safe_free(__p) do { if(__p) { mb_free(__p); __p = 0; } else { mb_assert(0 && "Memory already released"); } } while(0)
@ -656,7 +661,7 @@ static int _append_char_to_symbol(mb_interpreter_t* s, char c);
static int _cut_symbol(mb_interpreter_t* s, int pos, unsigned short row, unsigned short col);
static int _append_symbol(mb_interpreter_t* s, char* sym, bool_t* delsym, int pos, unsigned short row, unsigned short col);
static int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** obj, _ls_node_t*** asgn, bool_t* delsym);
static _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, void** value);
static _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value);
static int _parse_char(mb_interpreter_t* s, char c, int pos, unsigned short row, unsigned short col);
static void _set_error_pos(mb_interpreter_t* s, int pos, unsigned short row, unsigned short col);
@ -722,6 +727,8 @@ MBAPI int mb_dispose_value(mb_interpreter_t* s, mb_value_t val);
# endif /* _MSC_VER < 1300 */
#elif defined __BORLANDC__
# define _do_nothing do { printf("Unaccessable function: %s\n", __FUNC__); } while(0)
#elif defined __POCC__
# define _do_nothing do { printf("Unaccessable function: %s\n", __func__); } while(0)
#else /* _MSC_VER */
# define _do_nothing do { printf("Unaccessable function: %s\n", __FUNCTION__); } while(0)
#endif /* _MSC_VER */
@ -1545,6 +1552,16 @@ void mb_free(void* p) {
free(p);
}
size_t mb_memtest(void*p, size_t s) {
size_t result = 0;
size_t i = 0;
for(i = 0; i < s; i++) {
result += ((unsigned char*)p)[i];
}
return result;
}
char* mb_strupr(char* s) {
char* t = s;
@ -2165,8 +2182,8 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
/* Create a syntax symbol */
int result = MB_FUNC_OK;
_data_e type;
union { _func_t* func; _array_t* array; _var_t* var; _label_t* label; real_t float_point; int_t integer; void* any; } tmp;
void* value = 0;
union { _func_t* func; _array_t* array; _var_t* var; _label_t* label; real_t float_point; int_t integer; _raw_t any; } tmp;
_raw_t value;
unsigned int ul = 0;
_parsing_context_t* context = 0;
_ls_node_t* glbsyminscope = 0;
@ -2174,6 +2191,8 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
mb_assert(s && sym && obj);
memset(value, 0, sizeof(_raw_t));
context = (_parsing_context_t*)s->parsing_context;
*obj = (_object_t*)mb_malloc(sizeof(_object_t));
@ -2185,13 +2204,13 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
(*obj)->type = type;
switch(type) {
case _DT_INT:
tmp.any = value;
memcpy(tmp.any, value, sizeof(_raw_t));
(*obj)->data.integer = tmp.integer;
safe_free(sym);
break;
case _DT_REAL:
tmp.any = value;
memcpy(tmp.any, value, sizeof(_raw_t));
(*obj)->data.float_point = tmp.float_point;
safe_free(sym);
@ -2209,7 +2228,7 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
tmp.func = (_func_t*)mb_malloc(sizeof(_func_t));
memset(tmp.func, 0, sizeof(_func_t));
tmp.func->name = sym;
tmp.func->pointer = (mb_func_t)(intptr_t)value;
memcpy(&tmp.func->pointer, value, sizeof(tmp.func->pointer));
(*obj)->data.func = tmp.func;
break;
@ -2223,7 +2242,7 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
tmp.array = (_array_t*)mb_malloc(sizeof(_array_t));
memset(tmp.array, 0, sizeof(_array_t));
tmp.array->name = sym;
tmp.array->type = (_data_e)(int)(long)(intptr_t)value;
memcpy(&tmp.array->type, value, sizeof(tmp.array->type));
(*obj)->data.array = tmp.array;
ul = _ht_set_or_insert((_ht_node_t*)s->global_var_dict, sym, *obj);
@ -2266,8 +2285,8 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
break;
case _DT_LABEL:
if(context->current_char == ':') {
if(value) {
(*obj)->data.label = value;
if(mb_memtest(value, sizeof(_raw_t))) {
memcpy(&((*obj)->data.label), value, sizeof((*obj)->data.label));
(*obj)->ref = true;
*delsym = true;
} else {
@ -2309,15 +2328,17 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
return result;
}
_data_e _get_symbol_type(mb_interpreter_t* s, char* sym, void** value) {
_data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) {
/* Get the type of a syntax symbol */
_data_e result = _DT_NIL;
union { real_t float_point; int_t integer; _object_t* obj; void* any; } tmp;
union { real_t float_point; int_t integer; _object_t* obj; _raw_t any; } tmp;
char* conv_suc = 0;
_parsing_context_t* context = 0;
_ls_node_t* lclsyminscope = 0;
_ls_node_t* glbsyminscope = 0;
size_t _sl = 0;
_data_e en = _DT_ANY;
intptr_t ptr = 0;
mb_assert(s && sym);
_sl = strlen(sym);
@ -2328,7 +2349,7 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, void** value) {
/* int_t */
tmp.integer = (int_t)strtol(sym, &conv_suc, 0);
if(*conv_suc == '\0') {
*value = tmp.any;
memcpy(*value, tmp.any, sizeof(_raw_t));
result = _DT_INT;
@ -2337,7 +2358,7 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, void** value) {
/* real_t */
tmp.float_point = (real_t)strtod(sym, &conv_suc);
if(*conv_suc == '\0') {
*value = tmp.any;
memcpy(*value, tmp.any, sizeof(_raw_t));
result = _DT_REAL;
@ -2353,7 +2374,7 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, void** value) {
glbsyminscope = _ht_find((_ht_node_t*)s->global_var_dict, sym);
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_ARRAY) {
tmp.obj = (_object_t*)(glbsyminscope->data);
*value = (void*)(intptr_t)(tmp.obj->data.array->type);
memcpy(*value, &(tmp.obj->data.array->type), sizeof(tmp.obj->data.array->type));
result = _DT_ARRAY;
@ -2361,7 +2382,8 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, void** value) {
}
if(context->last_symbol && context->last_symbol->type == _DT_FUNC) {
if(strcmp("DIM", context->last_symbol->data.func->name) == 0) {
*value = (void*)(intptr_t)(sym[_sl - 1] == '$' ? _DT_STRING : _DT_REAL);
en = (sym[_sl - 1] == '$' ? _DT_STRING : _DT_REAL);
memcpy(*value, &en, sizeof(en));
result = _DT_ARRAY;
@ -2369,10 +2391,12 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, void** value) {
}
}
/* _func_t */
if(context->last_symbol && ((context->last_symbol->type == _DT_FUNC && context->last_symbol->data.func->pointer != _core_close_bracket) ||
context->last_symbol->type == _DT_SEP)) {
if(!context->last_symbol ||
(context->last_symbol && ((context->last_symbol->type == _DT_FUNC && context->last_symbol->data.func->pointer != _core_close_bracket) ||
context->last_symbol->type == _DT_SEP))) {
if(strcmp("-", sym) == 0) {
*value = (void*)(intptr_t)(_core_neg);
ptr = (intptr_t)_core_neg;
memcpy(*value, &ptr, sizeof(intptr_t));
result = _DT_FUNC;
@ -2382,7 +2406,8 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, void** value) {
lclsyminscope = _ht_find((_ht_node_t*)s->local_func_dict, sym);
glbsyminscope = _ht_find((_ht_node_t*)s->global_func_dict, sym);
if(lclsyminscope || glbsyminscope) {
*value = lclsyminscope ? lclsyminscope->data : glbsyminscope->data;
ptr = lclsyminscope ? (intptr_t)lclsyminscope->data : (intptr_t)glbsyminscope->data;
memcpy(*value, &ptr, sizeof(intptr_t));
result = _DT_FUNC;
@ -2404,7 +2429,7 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, void** value) {
glbsyminscope = _ht_find((_ht_node_t*)s->global_var_dict, sym);
if(glbsyminscope) {
if(((_object_t*)glbsyminscope->data)->type != _DT_LABEL) {
*value = glbsyminscope->data;
memcpy(*value, &glbsyminscope->data, sizeof(glbsyminscope->data));
result = _DT_VAR;
@ -2416,7 +2441,7 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, void** value) {
if(!context->last_symbol || context->last_symbol->type == _DT_EOS) {
glbsyminscope = _ht_find((_ht_node_t*)s->global_var_dict, sym);
if(glbsyminscope) {
*value = glbsyminscope->data;
memcpy(*value, &glbsyminscope->data, sizeof(glbsyminscope->data));
}
result = _DT_LABEL;
@ -2442,11 +2467,13 @@ int _parse_char(mb_interpreter_t* s, char c, int pos, unsigned short row, unsign
/* Parse a char */
int result = MB_FUNC_OK;
_parsing_context_t* context = 0;
char last_char = '\0';
mb_assert(s && s->parsing_context);
context = (_parsing_context_t*)(s->parsing_context);
last_char = context->current_char;
context->current_char = c;
if(context->parsing_state == _PS_NORMAL) {
@ -2478,9 +2505,13 @@ int _parse_char(mb_interpreter_t* s, char c, int pos, unsigned short row, unsign
if(_is_identifier_char(c)) {
result += _append_char_to_symbol(s, c);
} else if(_is_operator_char(c)) {
if((last_char == 'e' || last_char == 'E') && c == '-') {
result += _append_char_to_symbol(s, c);
} else {
context->symbol_state = _SS_OPERATOR;
result += _cut_symbol(s, pos, row, col);
result += _append_char_to_symbol(s, c);
}
} else {
_handle_error(s, SE_PS_INVALID_CHAR, pos, row, col, MB_FUNC_ERR, _exit, result);
}
@ -4217,9 +4248,13 @@ int _core_neg(mb_interpreter_t* s, void** l) {
running = (_running_context_t*)(s->running_context);
if(!_ls_empty(running->in_neg_expr)) {
inep = (int*)_ls_back(running->in_neg_expr)->data;
}
if(inep) {
(*inep)++;
}
mb_check(mb_attempt_func_begin(s, l));
@ -4227,7 +4262,9 @@ int _core_neg(mb_interpreter_t* s, void** l) {
mb_check(mb_attempt_func_end(s, l));
if(inep) {
(*inep)--;
}
switch(arg.type) {
case MB_DT_INT:

View File

@ -66,6 +66,8 @@ extern "C" {
# ifndef _strcmpi
# ifdef __BORLANDC__
# define _strcmpi stricmp
# elif defined __POCC__
# define _strcmpi _stricmp
# else /* __BORLANDC__*/
# define _strcmpi strcasecmp
# endif /* __BORLANDC__ */

Binary file not shown.

Binary file not shown.

View File

@ -81,13 +81,13 @@ BEGIN
VALUE "Comments", "MY-BASIC"
VALUE "CompanyName", "W. Renxin"
VALUE "FileDescription", "MY-BASIC interpreter"
VALUE "FileVersion", "1, 0, 0, 46"
VALUE "FileVersion", "1, 0, 0, 47"
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, 0, 0, 46"
VALUE "ProductVersion", "1, 0, 0, 47"
END
END
BLOCK "VarFileInfo"

View File

@ -52,6 +52,11 @@
# pragma warn -8066
#endif /* __BORLANDC__ */
#ifdef __POCC__
# define unlink _unlink
# define strdup _strdup
#endif /* __POCC__ */
#define _MAX_LINE_LENGTH 256
#define _str_eq(__str1, __str2) (_strcmpi(__str1, __str2) == 0)