+mixed array support; *some bugfix

This commit is contained in:
tony 2015-04-13 22:32:41 +08:00
parent 29f72c4d8a
commit 2ff04a09bc
7 changed files with 156 additions and 38 deletions

View File

@ -1,3 +1,9 @@
Apr. 13 2015
Added mixed integer/float array support
Added warning prompt when passing strings to maths functions
Fixed a memory leak when storing strings in an array
Polisned the interpreter commands
Apr. 11 2015
Moved struct mb_interpreter_t from my_basic.h to my_basic.c
Added an mb_has_argument interface to tell whether there is any more argument

View File

@ -78,7 +78,7 @@ extern "C" {
/** Macros */
#define _VER_MAJOR 1
#define _VER_MINOR 0
#define _VER_REVISION 48
#define _VER_REVISION 49
#define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION))
/* Uncomment this line to treat warnings as error */
@ -190,9 +190,10 @@ static const char* _ERR_DESC[] = {
"Array subscript expected",
"Structure not completed",
"Function expected",
"String expected",
"Variable or array identifier expected",
"Assign operator expected",
"String expected",
"Number expected",
"Integer expected",
"ELSE statement expected",
"TO statement expected",
@ -249,8 +250,11 @@ typedef struct _var_t {
typedef struct _array_t {
char* name;
_data_e type;
unsigned int count;
#ifndef MB_SIMPLE_ARRAY
_data_e* types;
#endif /* MB_SIMPLE_ARRAY */
void* raw;
unsigned int count;
int dimension_count;
int dimensions[_MAX_DIMENSION_COUNT];
} _array_t;
@ -260,7 +264,9 @@ 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 union _raw_u { int_t i; real_t r; void* p; } _raw_u;
typedef unsigned char _raw_t[sizeof(_raw_u)];
typedef struct _object_t {
_data_e type;
@ -1894,7 +1900,10 @@ int _calc_expression(mb_interpreter_t* s, _ls_node_t** l, _object_t** val) {
memset(arr_elem, 0, sizeof(_object_t));
_ls_pushback(garbage, arr_elem);
arr_elem->type = arr_type;
if(arr_type == _DT_REAL) {
arr_elem->ref = true;
if(arr_type == _DT_INT) {
arr_elem->data.integer = arr_val.integer;
} else if(arr_type == _DT_REAL) {
arr_elem->data.float_point = arr_val.float_point;
} else if(arr_type == _DT_STRING) {
arr_elem->data.string = arr_val.string;
@ -2608,6 +2617,7 @@ int_t _get_size_of(_data_e type) {
/* Get the size of a data type */
int_t result = 0;
#ifdef MB_SIMPLE_ARRAY
if(type == _DT_INT) {
result = sizeof(int_t);
} else if(type == _DT_REAL) {
@ -2617,6 +2627,9 @@ int_t _get_size_of(_data_e type) {
} else {
mb_assert(0 && "Unsupported");
}
#else /* MB_SIMPLE_ARRAY */
result = sizeof(_raw_u);
#endif /* MB_SIMPLE_ARRAY */
return result;
}
@ -2726,8 +2739,18 @@ bool_t _get_array_elem(mb_interpreter_t* s, _array_t* arr, unsigned int index, m
pos = (unsigned int)(elemsize * index);
rawptr = (void*)((intptr_t)arr->raw + pos);
if(arr->type == _DT_REAL) {
#ifdef MB_SIMPLE_ARRAY
val->float_point = *((real_t*)rawptr);
*type = _DT_REAL;
#else /* MB_SIMPLE_ARRAY */
if(arr->types[index] == _DT_REAL) {
val->float_point = *((real_t*)rawptr);
*type = _DT_REAL;
} else {
val->integer = *((int_t*)rawptr);
*type = _DT_INT;
}
#endif /* MB_SIMPLE_ARRAY */
} else if(arr->type == _DT_STRING) {
val->string = *((char**)rawptr);
*type = _DT_STRING;
@ -2752,9 +2775,17 @@ bool_t _set_array_elem(mb_interpreter_t* s, _array_t* arr, unsigned int index, m
pos = (unsigned int)(elemsize * index);
rawptr = (void*)((intptr_t)arr->raw + pos);
if(*type == _DT_INT) {
#ifdef MB_SIMPLE_ARRAY
*((real_t*)rawptr) = (real_t)val->integer;
#else /* MB_SIMPLE_ARRAY */
*((int_t*)rawptr) = val->integer;
arr->types[index] = _DT_INT;
#endif /* MB_SIMPLE_ARRAY */
} else if(*type == _DT_REAL) {
*((real_t*)rawptr) = val->float_point;
#ifndef MB_SIMPLE_ARRAY
arr->types[index] = _DT_REAL;
#endif /* MB_SIMPLE_ARRAY */
} else if(*type == _DT_STRING) {
size_t _sl = strlen(val->string);
*((char**)rawptr) = (char*)mb_malloc(_sl + 1);
@ -2769,47 +2800,56 @@ bool_t _set_array_elem(mb_interpreter_t* s, _array_t* arr, unsigned int index, m
void _init_array(_array_t* arr) {
/* Initialize an array */
int elemsize = 0;
#ifndef MB_SIMPLE_ARRAY
unsigned int ul = 0;
#endif
mb_assert(arr);
#ifdef MB_SIMPLE_ARRAY
elemsize = (int)_get_size_of(arr->type);
#else /* MB_SIMPLE_ARRAY */
elemsize = (int)_get_size_of(_DT_ANY);
#endif /* MB_SIMPLE_ARRAY */
mb_assert(arr->count > 0);
mb_assert(!arr->raw);
arr->raw = (void*)mb_malloc(elemsize * arr->count);
if(arr->raw) {
memset(arr->raw, 0, elemsize * arr->count);
}
#ifndef MB_SIMPLE_ARRAY
arr->types = (_data_e*)mb_malloc(sizeof(_data_e) * arr->count);
if(arr->types) {
for(ul = 0; ul < arr->count; ++ul) {
arr->types[ul] = _DT_INT;
}
}
#endif /* MB_SIMPLE_ARRAY */
}
void _clear_array(_array_t* arr) {
/* Clear an array */
char** strs = 0;
char* str = 0;
int_t elemsize = 0;
unsigned int pos = 0;
void* rawptr = 0;
unsigned int ul = 0;
mb_assert(arr);
if(arr->raw) {
switch(arr->type) {
case _DT_INT: /* Fall through */
case _DT_REAL:
safe_free(arr->raw);
break;
case _DT_STRING:
strs = (char**)arr->raw;
if(arr->type == _DT_STRING) {
for(ul = 0; ul < arr->count; ++ul) {
if(strs[ul]) {
safe_free(strs[ul]);
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);
}
}
safe_free(arr->raw);
break;
default:
mb_assert(0 && "Unsupported");
break;
}
safe_free(arr->raw);
arr->raw = 0;
}
}
@ -2820,6 +2860,11 @@ void _destroy_array(_array_t* arr) {
_clear_array(arr);
safe_free(arr->name);
#ifndef MB_SIMPLE_ARRAY
if(arr->types) {
safe_free(arr->types);
}
#endif /* MB_SIMPLE_ARRAY */
safe_free(arr);
}
@ -4352,10 +4397,13 @@ int _core_neg(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_value(s, l, arg));
_exit:
return result;
}
@ -4646,16 +4694,28 @@ int _core_let(mb_interpreter_t* s, void** l) {
}
} else if(arr) {
mb_value_u _val;
if(val->type == _DT_INT) {
switch(val->type) {
case _DT_INT:
_val.integer = val->data.integer;
} else if(val->type == _DT_REAL) {
break;
case _DT_REAL:
_val.float_point = val->data.float_point;
} else if(val->type == _DT_STRING) {
break;
case _DT_STRING:
_val.string = val->data.string;
} else {
break;
default:
mb_assert(0 && "Unsupported");
break;
}
_set_array_elem(s, arr, arr_idx, &_val, &val->type);
if(val->type == _DT_STRING && !val->ref) {
safe_free(val->data.string);
}
}
safe_free(val);
@ -5323,10 +5383,13 @@ int _std_abs(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_value(s, l, arg));
_exit:
return result;
}
@ -5354,10 +5417,13 @@ int _std_sgn(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_int(s, l, arg.value.integer));
_exit:
return result;
}
@ -5385,10 +5451,13 @@ int _std_sqr(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_value(s, l, arg));
_exit:
return result;
}
@ -5416,10 +5485,13 @@ int _std_floor(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_int(s, l, arg.value.integer));
_exit:
return result;
}
@ -5447,10 +5519,13 @@ int _std_ceil(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_int(s, l, arg.value.integer));
_exit:
return result;
}
@ -5478,10 +5553,13 @@ int _std_fix(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_int(s, l, arg.value.integer));
_exit:
return result;
}
@ -5509,10 +5587,13 @@ int _std_round(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_int(s, l, arg.value.integer));
_exit:
return result;
}
@ -5556,10 +5637,13 @@ int _std_sin(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_value(s, l, arg));
_exit:
return result;
}
@ -5587,10 +5671,13 @@ int _std_cos(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_value(s, l, arg));
_exit:
return result;
}
@ -5618,10 +5705,13 @@ int _std_tan(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_value(s, l, arg));
_exit:
return result;
}
@ -5649,10 +5739,13 @@ int _std_asin(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_value(s, l, arg));
_exit:
return result;
}
@ -5680,10 +5773,13 @@ int _std_acos(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_value(s, l, arg));
_exit:
return result;
}
@ -5711,10 +5807,13 @@ int _std_atan(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_value(s, l, arg));
_exit:
return result;
}
@ -5742,10 +5841,13 @@ int _std_exp(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_value(s, l, arg));
_exit:
return result;
}
@ -5773,10 +5875,13 @@ int _std_log(mb_interpreter_t* s, void** l) {
break;
default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result);
break;
}
mb_check(mb_push_value(s, l, arg));
_exit:
return result;
}

View File

@ -38,6 +38,10 @@ extern "C" {
# define MB_ENABLE_SOURCE_TRACE
#endif /* MB_ENABLE_SOURCE_TRACE */
#ifndef MB_SIMPLE_ARRAY
# define MB_SIMPLE_ARRAY
#endif /* MB_SIMPLE_ARRAY */
#ifndef MB_COMPACT_MODE
# define MB_COMPACT_MODE
#endif /* MB_COMPACT_MODE */
@ -155,9 +159,10 @@ typedef enum mb_error_e {
SE_RN_ARRAY_SUBSCRIPT_EXPECTED,
SE_RN_STRUCTURE_NOT_COMPLETED,
SE_RN_FUNCTION_EXPECTED,
SE_RN_STRING_EXPECTED,
SE_RN_VAR_OR_ARRAY_EXPECTED,
SE_RN_ASSIGN_OPERATOR_EXPECTED,
SE_RN_STRING_EXPECTED,
SE_RN_NUMBER_EXPECTED,
SE_RN_INTEGER_EXPECTED,
SE_RN_ELSE_EXPECTED,
SE_RN_TO_EXPECTED,

Binary file not shown.

Binary file not shown.

View File

@ -62,8 +62,8 @@ IDI_ICON_MAIN ICON "icon.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,45
PRODUCTVERSION 1,0,0,45
FILEVERSION 1,0,0,49
PRODUCTVERSION 1,0,0,49
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -81,13 +81,13 @@ BEGIN
VALUE "Comments", "MY-BASIC"
VALUE "CompanyName", "W. Renxin"
VALUE "FileDescription", "MY-BASIC interpreter"
VALUE "FileVersion", "1, 0, 0, 48"
VALUE "FileVersion", "1, 0, 0, 49"
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, 48"
VALUE "ProductVersion", "1, 0, 0, 49"
END
END
BLOCK "VarFileInfo"

View File

@ -120,7 +120,7 @@ static char* _get_code(_code_line_t* code) {
for(i = 0; i < code->count; ++i) {
result = strcat(result, code->lines[i]);
if(i != code->count - 1) {
result = strcat(result, "\r\n");
result = strcat(result, "\n");
}
}
@ -201,8 +201,9 @@ static int beep(struct mb_interpreter_t* s, void** l) {
static void _on_error(struct mb_interpreter_t* s, mb_error_e e, char* m, int p, unsigned short row, unsigned short col, int abort_code) {
mb_unrefvar(s);
mb_unrefvar(p);
if(SE_NO_ERR != e) {
printf("Error:\n [POS] %d, [ROW] %d, [COL] %d,\n [CODE] %d, [MESSAGE] %s, [ABORT CODE] %d\n", p, row, col, e, m, abort_code);
printf("Error:\n [LINE] %d, [COL] %d,\n [CODE] %d, [MESSAGE] %s, [ABORT CODE] %d\n", row, col, e, m, abort_code);
}
}
@ -251,9 +252,10 @@ static void _list_program(const char* sn, const char* cn) {
lsn = atoi(sn);
lcn = atoi(cn);
if(lsn == 0 && lcn == 0) {
char* txt = _get_code(c);
printf("%s\n", txt);
free(txt);
long i = 0;
for(i = 0; i < c->count; ++i) {
printf("%d]%s\n", i + 1, c->lines[i]);
}
} else {
long i = 0;
long e = 0;
@ -273,7 +275,7 @@ static void _list_program(const char* sn, const char* cn) {
if(i >= c->count) {
break;
}
printf("%s\n", c->lines[i]);
printf("%d]%s\n", i + 1, c->lines[i]);
}
}
}