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:
parent
eb5cd615ce
commit
e872d26513
6
HISTORY
6
HISTORY
@ -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
|
Mar. 25 2015
|
||||||
Changed _strupr macro to mb_strupr function
|
Changed _strupr macro to mb_strupr function
|
||||||
Added an mb_strdup function
|
Added an mb_strdup function
|
||||||
|
@ -78,7 +78,7 @@ extern "C" {
|
|||||||
/** Macros */
|
/** Macros */
|
||||||
#define _VER_MAJOR 1
|
#define _VER_MAJOR 1
|
||||||
#define _VER_MINOR 0
|
#define _VER_MINOR 0
|
||||||
#define _VER_REVISION 46
|
#define _VER_REVISION 47
|
||||||
#define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION))
|
#define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION))
|
||||||
|
|
||||||
/* Uncomment this line to treat warnings as error */
|
/* Uncomment this line to treat warnings as error */
|
||||||
@ -258,6 +258,8 @@ typedef struct _label_t {
|
|||||||
_ls_node_t* node;
|
_ls_node_t* node;
|
||||||
} _label_t;
|
} _label_t;
|
||||||
|
|
||||||
|
typedef unsigned char _raw_t[sizeof(union { int_t i; real_t r; void* p; })];
|
||||||
|
|
||||||
typedef struct _object_t {
|
typedef struct _object_t {
|
||||||
_data_e type;
|
_data_e type;
|
||||||
union {
|
union {
|
||||||
@ -270,6 +272,7 @@ typedef struct _object_t {
|
|||||||
_array_t* array;
|
_array_t* array;
|
||||||
_label_t* label;
|
_label_t* label;
|
||||||
char separator;
|
char separator;
|
||||||
|
_raw_t raw;
|
||||||
} data;
|
} data;
|
||||||
bool_t ref;
|
bool_t ref;
|
||||||
int source_pos;
|
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_realloc(void** p, size_t s);
|
||||||
static void mb_free(void* p);
|
static void mb_free(void* p);
|
||||||
|
|
||||||
|
static size_t mb_memtest(void*p, size_t s);
|
||||||
|
|
||||||
static char* mb_strupr(char* 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)
|
#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 _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 _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 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 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);
|
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 */
|
# endif /* _MSC_VER < 1300 */
|
||||||
#elif defined __BORLANDC__
|
#elif defined __BORLANDC__
|
||||||
# define _do_nothing do { printf("Unaccessable function: %s\n", __FUNC__); } while(0)
|
# 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 */
|
#else /* _MSC_VER */
|
||||||
# define _do_nothing do { printf("Unaccessable function: %s\n", __FUNCTION__); } while(0)
|
# define _do_nothing do { printf("Unaccessable function: %s\n", __FUNCTION__); } while(0)
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
@ -1545,6 +1552,16 @@ void mb_free(void* p) {
|
|||||||
free(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* mb_strupr(char* s) {
|
||||||
char* t = 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 */
|
/* Create a syntax symbol */
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
_data_e type;
|
_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;
|
union { _func_t* func; _array_t* array; _var_t* var; _label_t* label; real_t float_point; int_t integer; _raw_t any; } tmp;
|
||||||
void* value = 0;
|
_raw_t value;
|
||||||
unsigned int ul = 0;
|
unsigned int ul = 0;
|
||||||
_parsing_context_t* context = 0;
|
_parsing_context_t* context = 0;
|
||||||
_ls_node_t* glbsyminscope = 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);
|
mb_assert(s && sym && obj);
|
||||||
|
|
||||||
|
memset(value, 0, sizeof(_raw_t));
|
||||||
|
|
||||||
context = (_parsing_context_t*)s->parsing_context;
|
context = (_parsing_context_t*)s->parsing_context;
|
||||||
|
|
||||||
*obj = (_object_t*)mb_malloc(sizeof(_object_t));
|
*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;
|
(*obj)->type = type;
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case _DT_INT:
|
case _DT_INT:
|
||||||
tmp.any = value;
|
memcpy(tmp.any, value, sizeof(_raw_t));
|
||||||
(*obj)->data.integer = tmp.integer;
|
(*obj)->data.integer = tmp.integer;
|
||||||
safe_free(sym);
|
safe_free(sym);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case _DT_REAL:
|
case _DT_REAL:
|
||||||
tmp.any = value;
|
memcpy(tmp.any, value, sizeof(_raw_t));
|
||||||
(*obj)->data.float_point = tmp.float_point;
|
(*obj)->data.float_point = tmp.float_point;
|
||||||
safe_free(sym);
|
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));
|
tmp.func = (_func_t*)mb_malloc(sizeof(_func_t));
|
||||||
memset(tmp.func, 0, sizeof(_func_t));
|
memset(tmp.func, 0, sizeof(_func_t));
|
||||||
tmp.func->name = sym;
|
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;
|
(*obj)->data.func = tmp.func;
|
||||||
|
|
||||||
break;
|
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));
|
tmp.array = (_array_t*)mb_malloc(sizeof(_array_t));
|
||||||
memset(tmp.array, 0, sizeof(_array_t));
|
memset(tmp.array, 0, sizeof(_array_t));
|
||||||
tmp.array->name = sym;
|
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;
|
(*obj)->data.array = tmp.array;
|
||||||
|
|
||||||
ul = _ht_set_or_insert((_ht_node_t*)s->global_var_dict, sym, *obj);
|
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;
|
break;
|
||||||
case _DT_LABEL:
|
case _DT_LABEL:
|
||||||
if(context->current_char == ':') {
|
if(context->current_char == ':') {
|
||||||
if(value) {
|
if(mb_memtest(value, sizeof(_raw_t))) {
|
||||||
(*obj)->data.label = value;
|
memcpy(&((*obj)->data.label), value, sizeof((*obj)->data.label));
|
||||||
(*obj)->ref = true;
|
(*obj)->ref = true;
|
||||||
*delsym = true;
|
*delsym = true;
|
||||||
} else {
|
} else {
|
||||||
@ -2309,15 +2328,17 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
|||||||
return result;
|
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 */
|
/* Get the type of a syntax symbol */
|
||||||
_data_e result = _DT_NIL;
|
_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;
|
char* conv_suc = 0;
|
||||||
_parsing_context_t* context = 0;
|
_parsing_context_t* context = 0;
|
||||||
_ls_node_t* lclsyminscope = 0;
|
_ls_node_t* lclsyminscope = 0;
|
||||||
_ls_node_t* glbsyminscope = 0;
|
_ls_node_t* glbsyminscope = 0;
|
||||||
size_t _sl = 0;
|
size_t _sl = 0;
|
||||||
|
_data_e en = _DT_ANY;
|
||||||
|
intptr_t ptr = 0;
|
||||||
|
|
||||||
mb_assert(s && sym);
|
mb_assert(s && sym);
|
||||||
_sl = strlen(sym);
|
_sl = strlen(sym);
|
||||||
@ -2328,7 +2349,7 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, void** value) {
|
|||||||
/* int_t */
|
/* int_t */
|
||||||
tmp.integer = (int_t)strtol(sym, &conv_suc, 0);
|
tmp.integer = (int_t)strtol(sym, &conv_suc, 0);
|
||||||
if(*conv_suc == '\0') {
|
if(*conv_suc == '\0') {
|
||||||
*value = tmp.any;
|
memcpy(*value, tmp.any, sizeof(_raw_t));
|
||||||
|
|
||||||
result = _DT_INT;
|
result = _DT_INT;
|
||||||
|
|
||||||
@ -2337,7 +2358,7 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, void** value) {
|
|||||||
/* real_t */
|
/* real_t */
|
||||||
tmp.float_point = (real_t)strtod(sym, &conv_suc);
|
tmp.float_point = (real_t)strtod(sym, &conv_suc);
|
||||||
if(*conv_suc == '\0') {
|
if(*conv_suc == '\0') {
|
||||||
*value = tmp.any;
|
memcpy(*value, tmp.any, sizeof(_raw_t));
|
||||||
|
|
||||||
result = _DT_REAL;
|
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);
|
glbsyminscope = _ht_find((_ht_node_t*)s->global_var_dict, sym);
|
||||||
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_ARRAY) {
|
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_ARRAY) {
|
||||||
tmp.obj = (_object_t*)(glbsyminscope->data);
|
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;
|
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(context->last_symbol && context->last_symbol->type == _DT_FUNC) {
|
||||||
if(strcmp("DIM", context->last_symbol->data.func->name) == 0) {
|
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;
|
result = _DT_ARRAY;
|
||||||
|
|
||||||
@ -2369,10 +2391,12 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, void** value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* _func_t */
|
/* _func_t */
|
||||||
if(context->last_symbol && ((context->last_symbol->type == _DT_FUNC && context->last_symbol->data.func->pointer != _core_close_bracket) ||
|
if(!context->last_symbol ||
|
||||||
context->last_symbol->type == _DT_SEP)) {
|
(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) {
|
if(strcmp("-", sym) == 0) {
|
||||||
*value = (void*)(intptr_t)(_core_neg);
|
ptr = (intptr_t)_core_neg;
|
||||||
|
memcpy(*value, &ptr, sizeof(intptr_t));
|
||||||
|
|
||||||
result = _DT_FUNC;
|
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);
|
lclsyminscope = _ht_find((_ht_node_t*)s->local_func_dict, sym);
|
||||||
glbsyminscope = _ht_find((_ht_node_t*)s->global_func_dict, sym);
|
glbsyminscope = _ht_find((_ht_node_t*)s->global_func_dict, sym);
|
||||||
if(lclsyminscope || glbsyminscope) {
|
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;
|
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);
|
glbsyminscope = _ht_find((_ht_node_t*)s->global_var_dict, sym);
|
||||||
if(glbsyminscope) {
|
if(glbsyminscope) {
|
||||||
if(((_object_t*)glbsyminscope->data)->type != _DT_LABEL) {
|
if(((_object_t*)glbsyminscope->data)->type != _DT_LABEL) {
|
||||||
*value = glbsyminscope->data;
|
memcpy(*value, &glbsyminscope->data, sizeof(glbsyminscope->data));
|
||||||
|
|
||||||
result = _DT_VAR;
|
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) {
|
if(!context->last_symbol || context->last_symbol->type == _DT_EOS) {
|
||||||
glbsyminscope = _ht_find((_ht_node_t*)s->global_var_dict, sym);
|
glbsyminscope = _ht_find((_ht_node_t*)s->global_var_dict, sym);
|
||||||
if(glbsyminscope) {
|
if(glbsyminscope) {
|
||||||
*value = glbsyminscope->data;
|
memcpy(*value, &glbsyminscope->data, sizeof(glbsyminscope->data));
|
||||||
}
|
}
|
||||||
|
|
||||||
result = _DT_LABEL;
|
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 */
|
/* Parse a char */
|
||||||
int result = MB_FUNC_OK;
|
int result = MB_FUNC_OK;
|
||||||
_parsing_context_t* context = 0;
|
_parsing_context_t* context = 0;
|
||||||
|
char last_char = '\0';
|
||||||
|
|
||||||
mb_assert(s && s->parsing_context);
|
mb_assert(s && s->parsing_context);
|
||||||
|
|
||||||
context = (_parsing_context_t*)(s->parsing_context);
|
context = (_parsing_context_t*)(s->parsing_context);
|
||||||
|
|
||||||
|
last_char = context->current_char;
|
||||||
context->current_char = c;
|
context->current_char = c;
|
||||||
|
|
||||||
if(context->parsing_state == _PS_NORMAL) {
|
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)) {
|
if(_is_identifier_char(c)) {
|
||||||
result += _append_char_to_symbol(s, c);
|
result += _append_char_to_symbol(s, c);
|
||||||
} else if(_is_operator_char(c)) {
|
} else if(_is_operator_char(c)) {
|
||||||
context->symbol_state = _SS_OPERATOR;
|
if((last_char == 'e' || last_char == 'E') && c == '-') {
|
||||||
result += _cut_symbol(s, pos, row, col);
|
result += _append_char_to_symbol(s, 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 {
|
} else {
|
||||||
_handle_error(s, SE_PS_INVALID_CHAR, pos, row, col, MB_FUNC_ERR, _exit, result);
|
_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);
|
running = (_running_context_t*)(s->running_context);
|
||||||
|
|
||||||
inep = (int*)_ls_back(running->in_neg_expr)->data;
|
if(!_ls_empty(running->in_neg_expr)) {
|
||||||
|
inep = (int*)_ls_back(running->in_neg_expr)->data;
|
||||||
|
}
|
||||||
|
|
||||||
(*inep)++;
|
if(inep) {
|
||||||
|
(*inep)++;
|
||||||
|
}
|
||||||
|
|
||||||
mb_check(mb_attempt_func_begin(s, l));
|
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));
|
mb_check(mb_attempt_func_end(s, l));
|
||||||
|
|
||||||
(*inep)--;
|
if(inep) {
|
||||||
|
(*inep)--;
|
||||||
|
}
|
||||||
|
|
||||||
switch(arg.type) {
|
switch(arg.type) {
|
||||||
case MB_DT_INT:
|
case MB_DT_INT:
|
||||||
|
532
core/my_basic.h
532
core/my_basic.h
@ -1,265 +1,267 @@
|
|||||||
/*
|
/*
|
||||||
** This source file is part of MY-BASIC
|
** This source file is part of MY-BASIC
|
||||||
**
|
**
|
||||||
** For the latest info, see https://github.com/paladin-t/my_basic/
|
** For the latest info, see https://github.com/paladin-t/my_basic/
|
||||||
**
|
**
|
||||||
** Copyright (C) 2011 - 2015 W. Renxin
|
** Copyright (C) 2011 - 2015 W. Renxin
|
||||||
**
|
**
|
||||||
** Permission is hereby granted, free of charge, to any person obtaining a copy of
|
** Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
** this software and associated documentation files (the "Software"), to deal in
|
** this software and associated documentation files (the "Software"), to deal in
|
||||||
** the Software without restriction, including without limitation the rights to
|
** the Software without restriction, including without limitation the rights to
|
||||||
** use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
** use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
** the Software, and to permit persons to whom the Software is furnished to do so,
|
** the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
** subject to the following conditions:
|
** subject to the following conditions:
|
||||||
**
|
**
|
||||||
** The above copyright notice and this permission notice shall be included in all
|
** The above copyright notice and this permission notice shall be included in all
|
||||||
** copies or substantial portions of the Software.
|
** copies or substantial portions of the Software.
|
||||||
**
|
**
|
||||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
** FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
** FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
** COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
** COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
** IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
** IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MY_BASIC_H__
|
#ifndef __MY_BASIC_H__
|
||||||
#define __MY_BASIC_H__
|
#define __MY_BASIC_H__
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#ifndef MBAPI
|
#ifndef MBAPI
|
||||||
# define MBAPI
|
# define MBAPI
|
||||||
#endif /* MBAPI */
|
#endif /* MBAPI */
|
||||||
|
|
||||||
#ifndef MB_COMPACT_MODE
|
#ifndef MB_COMPACT_MODE
|
||||||
# define MB_COMPACT_MODE
|
# define MB_COMPACT_MODE
|
||||||
#endif /* MB_COMPACT_MODE */
|
#endif /* MB_COMPACT_MODE */
|
||||||
|
|
||||||
#ifdef MB_COMPACT_MODE
|
#ifdef MB_COMPACT_MODE
|
||||||
# pragma pack(1)
|
# pragma pack(1)
|
||||||
#endif /* MB_COMPACT_MODE */
|
#endif /* MB_COMPACT_MODE */
|
||||||
|
|
||||||
#ifndef true
|
#ifndef true
|
||||||
# define true (!0)
|
# define true (!0)
|
||||||
#endif
|
#endif
|
||||||
#ifndef false
|
#ifndef false
|
||||||
# define false (0)
|
# define false (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef bool_t
|
#ifndef bool_t
|
||||||
# define bool_t int
|
# define bool_t int
|
||||||
#endif
|
#endif
|
||||||
#ifndef byte_t
|
#ifndef byte_t
|
||||||
# define byte_t unsigned char
|
# define byte_t unsigned char
|
||||||
#endif
|
#endif
|
||||||
#ifndef int_t
|
#ifndef int_t
|
||||||
# define int_t int
|
# define int_t int
|
||||||
#endif
|
#endif
|
||||||
#ifndef real_t
|
#ifndef real_t
|
||||||
# define real_t float
|
# define real_t float
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
# ifndef _strcmpi
|
# ifndef _strcmpi
|
||||||
# ifdef __BORLANDC__
|
# ifdef __BORLANDC__
|
||||||
# define _strcmpi stricmp
|
# define _strcmpi stricmp
|
||||||
# else /* __BORLANDC__*/
|
# elif defined __POCC__
|
||||||
# define _strcmpi strcasecmp
|
# define _strcmpi _stricmp
|
||||||
# endif /* __BORLANDC__ */
|
# else /* __BORLANDC__*/
|
||||||
# endif /* _strcmpi */
|
# define _strcmpi strcasecmp
|
||||||
#endif /* _MSC_VER */
|
# endif /* __BORLANDC__ */
|
||||||
|
# endif /* _strcmpi */
|
||||||
#ifndef mb_assert
|
#endif /* _MSC_VER */
|
||||||
# define mb_assert(__a) do { ((void)(__a)); assert(__a); } while(0)
|
|
||||||
#endif /* mb_assert */
|
#ifndef mb_assert
|
||||||
|
# define mb_assert(__a) do { ((void)(__a)); assert(__a); } while(0)
|
||||||
#ifndef mb_static_assert
|
#endif /* mb_assert */
|
||||||
# define _static_assert_impl(cond, msg) typedef char static_assertion_##msg[(!!(cond)) * 2 - 1]
|
|
||||||
# define _compile_time_assert3(x, l) _static_assert_impl(x, static_assertion_at_line_##l)
|
#ifndef mb_static_assert
|
||||||
# define _compile_time_assert2(x, l) _compile_time_assert3(x, l)
|
# define _static_assert_impl(cond, msg) typedef char static_assertion_##msg[(!!(cond)) * 2 - 1]
|
||||||
# define mb_static_assert(x) _compile_time_assert2(x, __LINE__)
|
# define _compile_time_assert3(x, l) _static_assert_impl(x, static_assertion_at_line_##l)
|
||||||
#endif /* mb_static_assert */
|
# define _compile_time_assert2(x, l) _compile_time_assert3(x, l)
|
||||||
|
# define mb_static_assert(x) _compile_time_assert2(x, __LINE__)
|
||||||
#ifndef mb_unrefvar
|
#endif /* mb_static_assert */
|
||||||
# define mb_unrefvar(__v) ((void)(__v))
|
|
||||||
#endif /* mb_unrefvar */
|
#ifndef mb_unrefvar
|
||||||
|
# define mb_unrefvar(__v) ((void)(__v))
|
||||||
#ifndef MB_CODES
|
#endif /* mb_unrefvar */
|
||||||
# define MB_CODES
|
|
||||||
# define MB_FUNC_OK 0
|
#ifndef MB_CODES
|
||||||
# define MB_FUNC_BYE 1001
|
# define MB_CODES
|
||||||
# define MB_FUNC_WARNING 1002
|
# define MB_FUNC_OK 0
|
||||||
# define MB_FUNC_ERR 1003
|
# define MB_FUNC_BYE 1001
|
||||||
# define MB_FUNC_END 1004
|
# define MB_FUNC_WARNING 1002
|
||||||
# define MB_FUNC_SUSPEND 1005
|
# define MB_FUNC_ERR 1003
|
||||||
# define MB_PARSING_ERR 3001
|
# define MB_FUNC_END 1004
|
||||||
# define MB_LOOP_BREAK 5001
|
# define MB_FUNC_SUSPEND 1005
|
||||||
# define MB_LOOP_CONTINUE 5002
|
# define MB_PARSING_ERR 3001
|
||||||
# define MB_SUB_RETURN 5101
|
# define MB_LOOP_BREAK 5001
|
||||||
# define MB_EXTENDED_ABORT 9001
|
# define MB_LOOP_CONTINUE 5002
|
||||||
#endif /* MB_CODES */
|
# define MB_SUB_RETURN 5101
|
||||||
|
# define MB_EXTENDED_ABORT 9001
|
||||||
#ifndef mb_check
|
#endif /* MB_CODES */
|
||||||
# define mb_check(__r) { int __hr = __r; if(__hr != MB_FUNC_OK) { return __hr; } }
|
|
||||||
#endif /* mb_check */
|
#ifndef mb_check
|
||||||
|
# define mb_check(__r) { int __hr = __r; if(__hr != MB_FUNC_OK) { return __hr; } }
|
||||||
#ifndef mb_reg_fun
|
#endif /* mb_check */
|
||||||
# define mb_reg_fun(__s, __f) mb_register_func(__s, #__f, __f)
|
|
||||||
#endif /* mb_reg_fun */
|
#ifndef mb_reg_fun
|
||||||
#ifndef mb_rem_fun
|
# define mb_reg_fun(__s, __f) mb_register_func(__s, #__f, __f)
|
||||||
# define mb_rem_fun(__s, __f) mb_remove_func(__s, #__f)
|
#endif /* mb_reg_fun */
|
||||||
#endif /* mb_rem_fun */
|
#ifndef mb_rem_fun
|
||||||
#ifndef mb_rem_res_fun
|
# define mb_rem_fun(__s, __f) mb_remove_func(__s, #__f)
|
||||||
# define mb_rem_res_fun(__s, __f) mb_remove_reserved_func(__s, #__f)
|
#endif /* mb_rem_fun */
|
||||||
#endif /* mb_rem_res_fun */
|
#ifndef mb_rem_res_fun
|
||||||
|
# define mb_rem_res_fun(__s, __f) mb_remove_reserved_func(__s, #__f)
|
||||||
struct mb_interpreter_t;
|
#endif /* mb_rem_res_fun */
|
||||||
|
|
||||||
typedef enum mb_error_e {
|
struct mb_interpreter_t;
|
||||||
SE_NO_ERR = 0,
|
|
||||||
/** Common */
|
typedef enum mb_error_e {
|
||||||
SE_CM_MB_OPEN_FAILED,
|
SE_NO_ERR = 0,
|
||||||
SE_CM_FUNC_EXISTS,
|
/** Common */
|
||||||
SE_CM_FUNC_NOT_EXISTS,
|
SE_CM_MB_OPEN_FAILED,
|
||||||
/** Parsing */
|
SE_CM_FUNC_EXISTS,
|
||||||
SE_PS_FILE_OPEN_FAILED,
|
SE_CM_FUNC_NOT_EXISTS,
|
||||||
SE_PS_SYMBOL_TOO_LONG,
|
/** Parsing */
|
||||||
SE_PS_INVALID_CHAR,
|
SE_PS_FILE_OPEN_FAILED,
|
||||||
/** Running */
|
SE_PS_SYMBOL_TOO_LONG,
|
||||||
SE_RN_NOT_SUPPORTED,
|
SE_PS_INVALID_CHAR,
|
||||||
SE_RN_EMPTY_PROGRAM,
|
/** Running */
|
||||||
SE_RN_SYNTAX,
|
SE_RN_NOT_SUPPORTED,
|
||||||
SE_RN_INVALID_DATA_TYPE,
|
SE_RN_EMPTY_PROGRAM,
|
||||||
SE_RN_TYPE_NOT_MATCH,
|
SE_RN_SYNTAX,
|
||||||
SE_RN_ILLEGAL_BOUND,
|
SE_RN_INVALID_DATA_TYPE,
|
||||||
SE_RN_DIMENSION_TOO_MUCH,
|
SE_RN_TYPE_NOT_MATCH,
|
||||||
SE_RN_OPERATION_FAILED,
|
SE_RN_ILLEGAL_BOUND,
|
||||||
SE_RN_DIMENSION_OUT_OF_BOUND,
|
SE_RN_DIMENSION_TOO_MUCH,
|
||||||
SE_RN_ARRAY_OUT_OF_BOUND,
|
SE_RN_OPERATION_FAILED,
|
||||||
SE_RN_LABEL_NOT_EXISTS,
|
SE_RN_DIMENSION_OUT_OF_BOUND,
|
||||||
SE_RN_NO_RETURN_POINT,
|
SE_RN_ARRAY_OUT_OF_BOUND,
|
||||||
SE_RN_COLON_EXPECTED,
|
SE_RN_LABEL_NOT_EXISTS,
|
||||||
SE_RN_COMMA_OR_SEMICOLON_EXPECTED,
|
SE_RN_NO_RETURN_POINT,
|
||||||
SE_RN_ARRAY_IDENTIFIER_EXPECTED,
|
SE_RN_COLON_EXPECTED,
|
||||||
SE_RN_OPEN_BRACKET_EXPECTED,
|
SE_RN_COMMA_OR_SEMICOLON_EXPECTED,
|
||||||
SE_RN_CLOSE_BRACKET_EXPECTED,
|
SE_RN_ARRAY_IDENTIFIER_EXPECTED,
|
||||||
SE_RN_ARRAY_SUBSCRIPT_EXPECTED,
|
SE_RN_OPEN_BRACKET_EXPECTED,
|
||||||
SE_RN_STRUCTURE_NOT_COMPLETED,
|
SE_RN_CLOSE_BRACKET_EXPECTED,
|
||||||
SE_RN_FUNCTION_EXPECTED,
|
SE_RN_ARRAY_SUBSCRIPT_EXPECTED,
|
||||||
SE_RN_STRING_EXPECTED,
|
SE_RN_STRUCTURE_NOT_COMPLETED,
|
||||||
SE_RN_VAR_OR_ARRAY_EXPECTED,
|
SE_RN_FUNCTION_EXPECTED,
|
||||||
SE_RN_ASSIGN_OPERATOR_EXPECTED,
|
SE_RN_STRING_EXPECTED,
|
||||||
SE_RN_INTEGER_EXPECTED,
|
SE_RN_VAR_OR_ARRAY_EXPECTED,
|
||||||
SE_RN_ELSE_EXPECTED,
|
SE_RN_ASSIGN_OPERATOR_EXPECTED,
|
||||||
SE_RN_TO_EXPECTED,
|
SE_RN_INTEGER_EXPECTED,
|
||||||
SE_RN_NEXT_EXPECTED,
|
SE_RN_ELSE_EXPECTED,
|
||||||
SE_RN_UNTIL_EXPECTED,
|
SE_RN_TO_EXPECTED,
|
||||||
SE_RN_LOOP_VAR_EXPECTED,
|
SE_RN_NEXT_EXPECTED,
|
||||||
SE_RN_JUMP_LABEL_EXPECTED,
|
SE_RN_UNTIL_EXPECTED,
|
||||||
SE_RN_VARIABLE_EXPECTED,
|
SE_RN_LOOP_VAR_EXPECTED,
|
||||||
SE_RN_INVALID_ID_USAGE,
|
SE_RN_JUMP_LABEL_EXPECTED,
|
||||||
SE_RN_OPERATOR_EXPECTED,
|
SE_RN_VARIABLE_EXPECTED,
|
||||||
SE_RN_CALCULATION_ERROR,
|
SE_RN_INVALID_ID_USAGE,
|
||||||
SE_RN_DIVIDE_BY_ZERO,
|
SE_RN_OPERATOR_EXPECTED,
|
||||||
SE_RN_MOD_BY_ZERO,
|
SE_RN_CALCULATION_ERROR,
|
||||||
SE_RN_INVALID_EXPRESSION,
|
SE_RN_DIVIDE_BY_ZERO,
|
||||||
SE_RN_OUT_OF_MEMORY,
|
SE_RN_MOD_BY_ZERO,
|
||||||
/** Extended abort */
|
SE_RN_INVALID_EXPRESSION,
|
||||||
SE_EA_EXTENDED_ABORT,
|
SE_RN_OUT_OF_MEMORY,
|
||||||
/** Extra */
|
/** Extended abort */
|
||||||
SE_COUNT
|
SE_EA_EXTENDED_ABORT,
|
||||||
} mb_error_e;
|
/** Extra */
|
||||||
|
SE_COUNT
|
||||||
typedef enum mb_data_e {
|
} mb_error_e;
|
||||||
MB_DT_NIL = -1,
|
|
||||||
MB_DT_INT = 0,
|
typedef enum mb_data_e {
|
||||||
MB_DT_REAL,
|
MB_DT_NIL = -1,
|
||||||
MB_DT_STRING
|
MB_DT_INT = 0,
|
||||||
} mb_data_e;
|
MB_DT_REAL,
|
||||||
|
MB_DT_STRING
|
||||||
typedef union mb_value_u {
|
} mb_data_e;
|
||||||
int_t integer;
|
|
||||||
real_t float_point;
|
typedef union mb_value_u {
|
||||||
char* string;
|
int_t integer;
|
||||||
} mb_value_u;
|
real_t float_point;
|
||||||
|
char* string;
|
||||||
typedef struct mb_value_t {
|
} mb_value_u;
|
||||||
mb_data_e type;
|
|
||||||
mb_value_u value;
|
typedef struct mb_value_t {
|
||||||
} mb_value_t;
|
mb_data_e type;
|
||||||
|
mb_value_u value;
|
||||||
typedef void (* mb_error_handler_t)(struct mb_interpreter_t*, enum mb_error_e, char*, int, unsigned short, unsigned short, int);
|
} mb_value_t;
|
||||||
typedef int (* mb_func_t)(struct mb_interpreter_t*, void**);
|
|
||||||
typedef int (* mb_print_func_t)(const char*, ...);
|
typedef void (* mb_error_handler_t)(struct mb_interpreter_t*, enum mb_error_e, char*, int, unsigned short, unsigned short, int);
|
||||||
typedef int (* mb_input_func_t)(char*, int);
|
typedef int (* mb_func_t)(struct mb_interpreter_t*, void**);
|
||||||
|
typedef int (* mb_print_func_t)(const char*, ...);
|
||||||
typedef struct mb_interpreter_t {
|
typedef int (* mb_input_func_t)(char*, int);
|
||||||
void* local_func_dict;
|
|
||||||
void* global_func_dict;
|
typedef struct mb_interpreter_t {
|
||||||
void* global_var_dict;
|
void* local_func_dict;
|
||||||
void* ast;
|
void* global_func_dict;
|
||||||
void* parsing_context;
|
void* global_var_dict;
|
||||||
void* running_context;
|
void* ast;
|
||||||
mb_error_e last_error;
|
void* parsing_context;
|
||||||
int last_error_pos;
|
void* running_context;
|
||||||
unsigned short last_error_row;
|
mb_error_e last_error;
|
||||||
unsigned short last_error_col;
|
int last_error_pos;
|
||||||
mb_error_handler_t error_handler;
|
unsigned short last_error_row;
|
||||||
mb_print_func_t printer;
|
unsigned short last_error_col;
|
||||||
mb_input_func_t inputer;
|
mb_error_handler_t error_handler;
|
||||||
void* userdata;
|
mb_print_func_t printer;
|
||||||
} mb_interpreter_t;
|
mb_input_func_t inputer;
|
||||||
|
void* userdata;
|
||||||
MBAPI unsigned int mb_ver(void);
|
} mb_interpreter_t;
|
||||||
MBAPI const char* mb_ver_string(void);
|
|
||||||
|
MBAPI unsigned int mb_ver(void);
|
||||||
MBAPI int mb_init(void);
|
MBAPI const char* mb_ver_string(void);
|
||||||
MBAPI int mb_dispose(void);
|
|
||||||
MBAPI int mb_open(mb_interpreter_t** s);
|
MBAPI int mb_init(void);
|
||||||
MBAPI int mb_close(mb_interpreter_t** s);
|
MBAPI int mb_dispose(void);
|
||||||
MBAPI int mb_reset(mb_interpreter_t** s, bool_t clrf);
|
MBAPI int mb_open(mb_interpreter_t** s);
|
||||||
|
MBAPI int mb_close(mb_interpreter_t** s);
|
||||||
MBAPI int mb_register_func(mb_interpreter_t* s, const char* n, mb_func_t f);
|
MBAPI int mb_reset(mb_interpreter_t** s, bool_t clrf);
|
||||||
MBAPI int mb_remove_func(mb_interpreter_t* s, const char* n);
|
|
||||||
MBAPI int mb_remove_reserved_func(mb_interpreter_t* s, const char* n);
|
MBAPI int mb_register_func(mb_interpreter_t* s, const char* n, mb_func_t f);
|
||||||
|
MBAPI int mb_remove_func(mb_interpreter_t* s, const char* n);
|
||||||
MBAPI int mb_attempt_func_begin(mb_interpreter_t* s, void** l);
|
MBAPI int mb_remove_reserved_func(mb_interpreter_t* s, const char* n);
|
||||||
MBAPI int mb_attempt_func_end(mb_interpreter_t* s, void** l);
|
|
||||||
MBAPI int mb_attempt_open_bracket(mb_interpreter_t* s, void** l);
|
MBAPI int mb_attempt_func_begin(mb_interpreter_t* s, void** l);
|
||||||
MBAPI int mb_attempt_close_bracket(mb_interpreter_t* s, void** l);
|
MBAPI int mb_attempt_func_end(mb_interpreter_t* s, void** l);
|
||||||
MBAPI int mb_pop_int(mb_interpreter_t* s, void** l, int_t* val);
|
MBAPI int mb_attempt_open_bracket(mb_interpreter_t* s, void** l);
|
||||||
MBAPI int mb_pop_real(mb_interpreter_t* s, void** l, real_t* val);
|
MBAPI int mb_attempt_close_bracket(mb_interpreter_t* s, void** l);
|
||||||
MBAPI int mb_pop_string(mb_interpreter_t* s, void** l, char** val);
|
MBAPI int mb_pop_int(mb_interpreter_t* s, void** l, int_t* val);
|
||||||
MBAPI int mb_pop_value(mb_interpreter_t* s, void** l, mb_value_t* val);
|
MBAPI int mb_pop_real(mb_interpreter_t* s, void** l, real_t* val);
|
||||||
MBAPI int mb_push_int(mb_interpreter_t* s, void** l, int_t val);
|
MBAPI int mb_pop_string(mb_interpreter_t* s, void** l, char** val);
|
||||||
MBAPI int mb_push_real(mb_interpreter_t* s, void** l, real_t val);
|
MBAPI int mb_pop_value(mb_interpreter_t* s, void** l, mb_value_t* val);
|
||||||
MBAPI int mb_push_string(mb_interpreter_t* s, void** l, char* val);
|
MBAPI int mb_push_int(mb_interpreter_t* s, void** l, int_t val);
|
||||||
MBAPI int mb_push_value(mb_interpreter_t* s, void** l, mb_value_t val);
|
MBAPI int mb_push_real(mb_interpreter_t* s, void** l, real_t val);
|
||||||
|
MBAPI int mb_push_string(mb_interpreter_t* s, void** l, char* val);
|
||||||
MBAPI int mb_load_string(mb_interpreter_t* s, const char* l);
|
MBAPI int mb_push_value(mb_interpreter_t* s, void** l, mb_value_t val);
|
||||||
MBAPI int mb_load_file(mb_interpreter_t* s, const char* f);
|
|
||||||
MBAPI int mb_run(mb_interpreter_t* s);
|
MBAPI int mb_load_string(mb_interpreter_t* s, const char* l);
|
||||||
MBAPI int mb_suspend(mb_interpreter_t* s, void** l);
|
MBAPI int mb_load_file(mb_interpreter_t* s, const char* f);
|
||||||
|
MBAPI int mb_run(mb_interpreter_t* s);
|
||||||
MBAPI mb_error_e mb_get_last_error(mb_interpreter_t* s);
|
MBAPI int mb_suspend(mb_interpreter_t* s, void** l);
|
||||||
MBAPI const char* mb_get_error_desc(mb_error_e err);
|
|
||||||
MBAPI int mb_set_error_handler(mb_interpreter_t* s, mb_error_handler_t h);
|
MBAPI mb_error_e mb_get_last_error(mb_interpreter_t* s);
|
||||||
MBAPI int mb_set_printer(mb_interpreter_t* s, mb_print_func_t p);
|
MBAPI const char* mb_get_error_desc(mb_error_e err);
|
||||||
MBAPI int mb_set_inputer(mb_interpreter_t* s, mb_input_func_t p);
|
MBAPI int mb_set_error_handler(mb_interpreter_t* s, mb_error_handler_t h);
|
||||||
|
MBAPI int mb_set_printer(mb_interpreter_t* s, mb_print_func_t p);
|
||||||
MBAPI int mb_gets(char* buf, int s);
|
MBAPI int mb_set_inputer(mb_interpreter_t* s, mb_input_func_t p);
|
||||||
|
|
||||||
MBAPI char* mb_strdup(char* val, unsigned size);
|
MBAPI int mb_gets(char* buf, int s);
|
||||||
|
|
||||||
#ifdef MB_COMPACT_MODE
|
MBAPI char* mb_strdup(char* val, unsigned size);
|
||||||
# pragma pack()
|
|
||||||
#endif /* MB_COMPACT_MODE */
|
#ifdef MB_COMPACT_MODE
|
||||||
|
# pragma pack()
|
||||||
#ifdef __cplusplus
|
#endif /* MB_COMPACT_MODE */
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
#endif /* __MY_BASIC_H__ */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* __MY_BASIC_H__ */
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -81,13 +81,13 @@ BEGIN
|
|||||||
VALUE "Comments", "MY-BASIC"
|
VALUE "Comments", "MY-BASIC"
|
||||||
VALUE "CompanyName", "W. Renxin"
|
VALUE "CompanyName", "W. Renxin"
|
||||||
VALUE "FileDescription", "MY-BASIC interpreter"
|
VALUE "FileDescription", "MY-BASIC interpreter"
|
||||||
VALUE "FileVersion", "1, 0, 0, 46"
|
VALUE "FileVersion", "1, 0, 0, 47"
|
||||||
VALUE "InternalName", "my_basic"
|
VALUE "InternalName", "my_basic"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2011 - 2015 W. Renxin"
|
VALUE "LegalCopyright", "Copyright (C) 2011 - 2015 W. Renxin"
|
||||||
VALUE "LegalTrademarks", "MY-BASIC"
|
VALUE "LegalTrademarks", "MY-BASIC"
|
||||||
VALUE "OriginalFilename", "my_basic.exe"
|
VALUE "OriginalFilename", "my_basic.exe"
|
||||||
VALUE "ProductName", "MY-BASIC"
|
VALUE "ProductName", "MY-BASIC"
|
||||||
VALUE "ProductVersion", "1, 0, 0, 46"
|
VALUE "ProductVersion", "1, 0, 0, 47"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
883
shell/main.c
883
shell/main.c
@ -1,439 +1,444 @@
|
|||||||
/*
|
/*
|
||||||
** This source file is part of MY-BASIC
|
** This source file is part of MY-BASIC
|
||||||
**
|
**
|
||||||
** For the latest info, see https://github.com/paladin-t/my_basic/
|
** For the latest info, see https://github.com/paladin-t/my_basic/
|
||||||
**
|
**
|
||||||
** Copyright (C) 2011 - 2015 W. Renxin
|
** Copyright (C) 2011 - 2015 W. Renxin
|
||||||
**
|
**
|
||||||
** Permission is hereby granted, free of charge, to any person obtaining a copy of
|
** Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
** this software and associated documentation files (the "Software"), to deal in
|
** this software and associated documentation files (the "Software"), to deal in
|
||||||
** the Software without restriction, including without limitation the rights to
|
** the Software without restriction, including without limitation the rights to
|
||||||
** use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
** use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
** the Software, and to permit persons to whom the Software is furnished to do so,
|
** the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
** subject to the following conditions:
|
** subject to the following conditions:
|
||||||
**
|
**
|
||||||
** The above copyright notice and this permission notice shall be included in all
|
** The above copyright notice and this permission notice shall be included in all
|
||||||
** copies or substantial portions of the Software.
|
** copies or substantial portions of the Software.
|
||||||
**
|
**
|
||||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
** FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
** FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
** COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
** COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
** IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
** IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# ifndef _CRT_SECURE_NO_WARNINGS
|
# ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
# define _CRT_SECURE_NO_WARNINGS
|
# define _CRT_SECURE_NO_WARNINGS
|
||||||
# endif /* _CRT_SECURE_NO_WARNINGS */
|
# endif /* _CRT_SECURE_NO_WARNINGS */
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
#include "../core/my_basic.h"
|
#include "../core/my_basic.h"
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# include <crtdbg.h>
|
# include <crtdbg.h>
|
||||||
# include <conio.h>
|
# include <conio.h>
|
||||||
#elif !defined __BORLANDC__
|
#elif !defined __BORLANDC__
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(disable : 4127)
|
# pragma warning(disable : 4127)
|
||||||
# pragma warning(disable : 4996)
|
# pragma warning(disable : 4996)
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
# pragma warn -8004
|
# pragma warn -8004
|
||||||
# pragma warn -8008
|
# pragma warn -8008
|
||||||
# pragma warn -8066
|
# pragma warn -8066
|
||||||
#endif /* __BORLANDC__ */
|
#endif /* __BORLANDC__ */
|
||||||
|
|
||||||
#define _MAX_LINE_LENGTH 256
|
#ifdef __POCC__
|
||||||
#define _str_eq(__str1, __str2) (_strcmpi(__str1, __str2) == 0)
|
# define unlink _unlink
|
||||||
|
# define strdup _strdup
|
||||||
#define _LINE_INC_STEP 16
|
#endif /* __POCC__ */
|
||||||
|
|
||||||
#define _NO_END(s) (MB_FUNC_OK == s || MB_FUNC_SUSPEND == s || MB_FUNC_WARNING == s || MB_FUNC_ERR == s || MB_FUNC_END == s)
|
#define _MAX_LINE_LENGTH 256
|
||||||
|
#define _str_eq(__str1, __str2) (_strcmpi(__str1, __str2) == 0)
|
||||||
typedef struct _code_line_t {
|
|
||||||
char** lines;
|
#define _LINE_INC_STEP 16
|
||||||
int count;
|
|
||||||
int size;
|
#define _NO_END(s) (MB_FUNC_OK == s || MB_FUNC_SUSPEND == s || MB_FUNC_WARNING == s || MB_FUNC_ERR == s || MB_FUNC_END == s)
|
||||||
} _code_line_t;
|
|
||||||
|
typedef struct _code_line_t {
|
||||||
static mb_interpreter_t* bas = 0;
|
char** lines;
|
||||||
|
int count;
|
||||||
static _code_line_t* c = 0;
|
int size;
|
||||||
|
} _code_line_t;
|
||||||
static _code_line_t* _create_code(void) {
|
|
||||||
_code_line_t* result = (_code_line_t*)malloc(sizeof(_code_line_t));
|
static mb_interpreter_t* bas = 0;
|
||||||
result->count = 0;
|
|
||||||
result->size = _LINE_INC_STEP;
|
static _code_line_t* c = 0;
|
||||||
result->lines = (char**)malloc(sizeof(char*) * result->size);
|
|
||||||
|
static _code_line_t* _create_code(void) {
|
||||||
return result;
|
_code_line_t* result = (_code_line_t*)malloc(sizeof(_code_line_t));
|
||||||
}
|
result->count = 0;
|
||||||
|
result->size = _LINE_INC_STEP;
|
||||||
static void _destroy_code(_code_line_t* code) {
|
result->lines = (char**)malloc(sizeof(char*) * result->size);
|
||||||
int i = 0;
|
|
||||||
mb_assert(code);
|
return result;
|
||||||
for(i = 0; i < code->count; ++i) {
|
}
|
||||||
free(code->lines[i]);
|
|
||||||
}
|
static void _destroy_code(_code_line_t* code) {
|
||||||
free(code->lines);
|
int i = 0;
|
||||||
free(code);
|
mb_assert(code);
|
||||||
}
|
for(i = 0; i < code->count; ++i) {
|
||||||
|
free(code->lines[i]);
|
||||||
static void _clear_code(_code_line_t* code) {
|
}
|
||||||
int i = 0;
|
free(code->lines);
|
||||||
mb_assert(code);
|
free(code);
|
||||||
for(i = 0; i < code->count; ++i) {
|
}
|
||||||
free(code->lines[i]);
|
|
||||||
}
|
static void _clear_code(_code_line_t* code) {
|
||||||
code->count = 0;
|
int i = 0;
|
||||||
}
|
mb_assert(code);
|
||||||
|
for(i = 0; i < code->count; ++i) {
|
||||||
static void _append_line(_code_line_t* code, char* txt) {
|
free(code->lines[i]);
|
||||||
mb_assert(code && txt);
|
}
|
||||||
if(code->count + 1 == code->size) {
|
code->count = 0;
|
||||||
code->size += _LINE_INC_STEP;
|
}
|
||||||
code->lines = (char**)realloc(code->lines, sizeof(char*) * code->size);
|
|
||||||
}
|
static void _append_line(_code_line_t* code, char* txt) {
|
||||||
code->lines[code->count++] = strdup(txt);
|
mb_assert(code && txt);
|
||||||
}
|
if(code->count + 1 == code->size) {
|
||||||
|
code->size += _LINE_INC_STEP;
|
||||||
static char* _get_code(_code_line_t* code) {
|
code->lines = (char**)realloc(code->lines, sizeof(char*) * code->size);
|
||||||
char* result = 0;
|
}
|
||||||
int i = 0;
|
code->lines[code->count++] = strdup(txt);
|
||||||
mb_assert(code);
|
}
|
||||||
result = (char*)malloc((_MAX_LINE_LENGTH + 2) * code->count + 1);
|
|
||||||
result[0] = '\0';
|
static char* _get_code(_code_line_t* code) {
|
||||||
for(i = 0; i < code->count; ++i) {
|
char* result = 0;
|
||||||
result = strcat(result, code->lines[i]);
|
int i = 0;
|
||||||
if(i != code->count - 1) {
|
mb_assert(code);
|
||||||
result = strcat(result, "\r\n");
|
result = (char*)malloc((_MAX_LINE_LENGTH + 2) * code->count + 1);
|
||||||
}
|
result[0] = '\0';
|
||||||
}
|
for(i = 0; i < code->count; ++i) {
|
||||||
|
result = strcat(result, code->lines[i]);
|
||||||
return result;
|
if(i != code->count - 1) {
|
||||||
}
|
result = strcat(result, "\r\n");
|
||||||
|
}
|
||||||
static void _set_code(_code_line_t* code, char* txt) {
|
}
|
||||||
char* cursor = 0;
|
|
||||||
char _c = '\0';
|
return result;
|
||||||
mb_assert(code);
|
}
|
||||||
if(!txt) {
|
|
||||||
return;
|
static void _set_code(_code_line_t* code, char* txt) {
|
||||||
}
|
char* cursor = 0;
|
||||||
_clear_code(code);
|
char _c = '\0';
|
||||||
cursor = txt;
|
mb_assert(code);
|
||||||
do {
|
if(!txt) {
|
||||||
_c = *cursor;
|
return;
|
||||||
if(_c == '\r' || _c == '\n' || _c == '\0') {
|
}
|
||||||
cursor[0] = '\0';
|
_clear_code(code);
|
||||||
if(_c == '\r' && *(cursor + 1) == '\n') {
|
cursor = txt;
|
||||||
++cursor;
|
do {
|
||||||
}
|
_c = *cursor;
|
||||||
_append_line(code, txt);
|
if(_c == '\r' || _c == '\n' || _c == '\0') {
|
||||||
txt = cursor + 1;
|
cursor[0] = '\0';
|
||||||
}
|
if(_c == '\r' && *(cursor + 1) == '\n') {
|
||||||
++cursor;
|
++cursor;
|
||||||
} while(_c);
|
}
|
||||||
}
|
_append_line(code, txt);
|
||||||
|
txt = cursor + 1;
|
||||||
static char* _load_file(const char* path) {
|
}
|
||||||
FILE* fp = 0;
|
++cursor;
|
||||||
char* result = 0;
|
} while(_c);
|
||||||
long curpos = 0;
|
}
|
||||||
long l = 0;
|
|
||||||
mb_assert(path);
|
static char* _load_file(const char* path) {
|
||||||
fp = fopen(path, "rb");
|
FILE* fp = 0;
|
||||||
if(fp) {
|
char* result = 0;
|
||||||
curpos = ftell(fp);
|
long curpos = 0;
|
||||||
fseek(fp, 0L, SEEK_END);
|
long l = 0;
|
||||||
l = ftell(fp);
|
mb_assert(path);
|
||||||
fseek(fp, curpos, SEEK_SET);
|
fp = fopen(path, "rb");
|
||||||
result = (char*)malloc((size_t)(l + 1));
|
if(fp) {
|
||||||
mb_assert(result);
|
curpos = ftell(fp);
|
||||||
fread(result, 1, l, fp);
|
fseek(fp, 0L, SEEK_END);
|
||||||
fclose(fp);
|
l = ftell(fp);
|
||||||
result[l] = '\0';
|
fseek(fp, curpos, SEEK_SET);
|
||||||
}
|
result = (char*)malloc((size_t)(l + 1));
|
||||||
|
mb_assert(result);
|
||||||
return result;
|
fread(result, 1, l, fp);
|
||||||
}
|
fclose(fp);
|
||||||
|
result[l] = '\0';
|
||||||
static int _save_file(const char* path, const char* txt) {
|
}
|
||||||
FILE* fp = 0;
|
|
||||||
mb_assert(path && txt);
|
return result;
|
||||||
fp = fopen(path, "wb");
|
}
|
||||||
if(fp) {
|
|
||||||
fwrite(txt, sizeof(char), strlen(txt), fp);
|
static int _save_file(const char* path, const char* txt) {
|
||||||
fclose(fp);
|
FILE* fp = 0;
|
||||||
|
mb_assert(path && txt);
|
||||||
return 1;
|
fp = fopen(path, "wb");
|
||||||
}
|
if(fp) {
|
||||||
|
fwrite(txt, sizeof(char), strlen(txt), fp);
|
||||||
return 0;
|
fclose(fp);
|
||||||
}
|
|
||||||
|
return 1;
|
||||||
static int beep(mb_interpreter_t* s, void** l) {
|
}
|
||||||
int result = MB_FUNC_OK;
|
|
||||||
|
return 0;
|
||||||
mb_assert(s && l);
|
}
|
||||||
|
|
||||||
mb_check(mb_attempt_func_begin(s, l));
|
static int beep(mb_interpreter_t* s, void** l) {
|
||||||
mb_check(mb_attempt_func_end(s, l));
|
int result = MB_FUNC_OK;
|
||||||
|
|
||||||
putchar('\a');
|
mb_assert(s && l);
|
||||||
|
|
||||||
return result;
|
mb_check(mb_attempt_func_begin(s, l));
|
||||||
}
|
mb_check(mb_attempt_func_end(s, l));
|
||||||
|
|
||||||
static void _on_error(mb_interpreter_t* s, mb_error_e e, char* m, int p, unsigned short row, unsigned short col, int abort_code) {
|
putchar('\a');
|
||||||
mb_unrefvar(s);
|
|
||||||
if(SE_NO_ERR != e) {
|
return result;
|
||||||
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);
|
}
|
||||||
}
|
|
||||||
}
|
static void _on_error(mb_interpreter_t* s, mb_error_e e, char* m, int p, unsigned short row, unsigned short col, int abort_code) {
|
||||||
|
mb_unrefvar(s);
|
||||||
static void _on_startup(void) {
|
if(SE_NO_ERR != e) {
|
||||||
c = _create_code();
|
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);
|
||||||
|
}
|
||||||
mb_init();
|
}
|
||||||
|
|
||||||
mb_open(&bas);
|
static void _on_startup(void) {
|
||||||
mb_set_error_handler(bas, _on_error);
|
c = _create_code();
|
||||||
|
|
||||||
mb_reg_fun(bas, beep);
|
mb_init();
|
||||||
}
|
|
||||||
|
mb_open(&bas);
|
||||||
static void _on_exit(void) {
|
mb_set_error_handler(bas, _on_error);
|
||||||
mb_close(&bas);
|
|
||||||
|
mb_reg_fun(bas, beep);
|
||||||
mb_dispose();
|
}
|
||||||
|
|
||||||
_destroy_code(c);
|
static void _on_exit(void) {
|
||||||
c = 0;
|
mb_close(&bas);
|
||||||
|
|
||||||
#if defined _MSC_VER && !defined _WIN64
|
mb_dispose();
|
||||||
if(0 != _CrtDumpMemoryLeaks()) { _asm { int 3 } }
|
|
||||||
#endif /* _MSC_VER && !_WIN64 */
|
_destroy_code(c);
|
||||||
}
|
c = 0;
|
||||||
|
|
||||||
static void _clear_screen(void) {
|
#if defined _MSC_VER && !defined _WIN64
|
||||||
#ifdef _MSC_VER
|
if(0 != _CrtDumpMemoryLeaks()) { _asm { int 3 } }
|
||||||
system("cls");
|
#endif /* _MSC_VER && !_WIN64 */
|
||||||
#else /* _MSC_VER */
|
}
|
||||||
system("clear");
|
|
||||||
#endif /* _MSC_VER */
|
static void _clear_screen(void) {
|
||||||
}
|
#ifdef _MSC_VER
|
||||||
|
system("cls");
|
||||||
static int _new_program(void) {
|
#else /* _MSC_VER */
|
||||||
_clear_code(c);
|
system("clear");
|
||||||
|
#endif /* _MSC_VER */
|
||||||
return mb_reset(&bas, false);
|
}
|
||||||
}
|
|
||||||
|
static int _new_program(void) {
|
||||||
static void _list_program(const char* sn, const char* cn) {
|
_clear_code(c);
|
||||||
long lsn = 0;
|
|
||||||
long lcn = 0;
|
return mb_reset(&bas, false);
|
||||||
mb_assert(sn && cn);
|
}
|
||||||
lsn = atoi(sn);
|
|
||||||
lcn = atoi(cn);
|
static void _list_program(const char* sn, const char* cn) {
|
||||||
if(lsn == 0 && lcn == 0) {
|
long lsn = 0;
|
||||||
char* txt = _get_code(c);
|
long lcn = 0;
|
||||||
printf("%s\n", txt);
|
mb_assert(sn && cn);
|
||||||
free(txt);
|
lsn = atoi(sn);
|
||||||
} else {
|
lcn = atoi(cn);
|
||||||
long i = 0;
|
if(lsn == 0 && lcn == 0) {
|
||||||
long e = 0;
|
char* txt = _get_code(c);
|
||||||
if(lsn < 1 || lsn > c->count) {
|
printf("%s\n", txt);
|
||||||
printf("Line number %ld out of bound.\n", lsn);
|
free(txt);
|
||||||
|
} else {
|
||||||
return;
|
long i = 0;
|
||||||
}
|
long e = 0;
|
||||||
if(lcn < 0) {
|
if(lsn < 1 || lsn > c->count) {
|
||||||
printf("Invalid line count %ld.\n", lcn);
|
printf("Line number %ld out of bound.\n", lsn);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
--lsn;
|
if(lcn < 0) {
|
||||||
e = lcn ? lsn + lcn : c->count;
|
printf("Invalid line count %ld.\n", lcn);
|
||||||
for(i = lsn; i < e; ++i) {
|
|
||||||
if(i >= c->count) {
|
return;
|
||||||
break;
|
}
|
||||||
}
|
--lsn;
|
||||||
printf("%s\n", c->lines[i]);
|
e = lcn ? lsn + lcn : c->count;
|
||||||
}
|
for(i = lsn; i < e; ++i) {
|
||||||
}
|
if(i >= c->count) {
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
static void _edit_program(const char* no) {
|
printf("%s\n", c->lines[i]);
|
||||||
char line[_MAX_LINE_LENGTH];
|
}
|
||||||
long lno = 0;
|
}
|
||||||
mb_assert(no);
|
}
|
||||||
lno = atoi(no);
|
|
||||||
if(lno < 1 || lno > c->count) {
|
static void _edit_program(const char* no) {
|
||||||
printf("Line number %ld out of bound.\n", lno);
|
char line[_MAX_LINE_LENGTH];
|
||||||
|
long lno = 0;
|
||||||
return;
|
mb_assert(no);
|
||||||
}
|
lno = atoi(no);
|
||||||
--lno;
|
if(lno < 1 || lno > c->count) {
|
||||||
memset(line, 0, _MAX_LINE_LENGTH);
|
printf("Line number %ld out of bound.\n", lno);
|
||||||
printf("%ld]", lno + 1);
|
|
||||||
mb_gets(line, _MAX_LINE_LENGTH);
|
return;
|
||||||
c->lines[lno] = (char*)realloc(c->lines[lno], strlen(line) + 1);
|
}
|
||||||
strcpy(c->lines[lno], line);
|
--lno;
|
||||||
}
|
memset(line, 0, _MAX_LINE_LENGTH);
|
||||||
|
printf("%ld]", lno + 1);
|
||||||
static void _load_program(const char* path) {
|
mb_gets(line, _MAX_LINE_LENGTH);
|
||||||
char* txt = _load_file(path);
|
c->lines[lno] = (char*)realloc(c->lines[lno], strlen(line) + 1);
|
||||||
if(txt) {
|
strcpy(c->lines[lno], line);
|
||||||
_new_program();
|
}
|
||||||
_set_code(c, txt);
|
|
||||||
free(txt);
|
static void _load_program(const char* path) {
|
||||||
if(c->count == 1) {
|
char* txt = _load_file(path);
|
||||||
printf("Load done. %d line loaded.\n", c->count);
|
if(txt) {
|
||||||
} else {
|
_new_program();
|
||||||
printf("Load done. %d lines loaded.\n", c->count);
|
_set_code(c, txt);
|
||||||
}
|
free(txt);
|
||||||
} else {
|
if(c->count == 1) {
|
||||||
printf("Cannot load file \"%s\"\n", path);
|
printf("Load done. %d line loaded.\n", c->count);
|
||||||
}
|
} else {
|
||||||
}
|
printf("Load done. %d lines loaded.\n", c->count);
|
||||||
|
}
|
||||||
static void _save_program(const char* path) {
|
} else {
|
||||||
char* txt = _get_code(c);
|
printf("Cannot load file \"%s\"\n", path);
|
||||||
if(!_save_file(path, txt)) {
|
}
|
||||||
printf("Cannot save file \"%s\"\n", path);
|
}
|
||||||
} else {
|
|
||||||
if(c->count == 1) {
|
static void _save_program(const char* path) {
|
||||||
printf("Save done. %d line saved.\n", c->count);
|
char* txt = _get_code(c);
|
||||||
} else {
|
if(!_save_file(path, txt)) {
|
||||||
printf("Save done. %d lines saved.\n", c->count);
|
printf("Cannot save file \"%s\"\n", path);
|
||||||
}
|
} else {
|
||||||
}
|
if(c->count == 1) {
|
||||||
free(txt);
|
printf("Save done. %d line saved.\n", c->count);
|
||||||
}
|
} else {
|
||||||
|
printf("Save done. %d lines saved.\n", c->count);
|
||||||
static void _kill_program(const char* path) {
|
}
|
||||||
if(!unlink(path)) {
|
}
|
||||||
printf("Delete file \"%s\" successfully.\n", path);
|
free(txt);
|
||||||
} else {
|
}
|
||||||
printf("Delete file \"%s\" failed.\n", path);
|
|
||||||
}
|
static void _kill_program(const char* path) {
|
||||||
}
|
if(!unlink(path)) {
|
||||||
|
printf("Delete file \"%s\" successfully.\n", path);
|
||||||
static void _show_tip(void) {
|
} else {
|
||||||
printf("MY-BASIC Interpreter Shell - %s.\n", mb_ver_string());
|
printf("Delete file \"%s\" failed.\n", path);
|
||||||
printf("Copyright (C) 2011 - 2015 W. Renxin. All Rights Reserved.\n");
|
}
|
||||||
printf("For more information, see https://github.com/paladin-t/my_basic/.\n");
|
}
|
||||||
printf("Input HELP and hint enter to view help information.\n");
|
|
||||||
}
|
static void _show_tip(void) {
|
||||||
|
printf("MY-BASIC Interpreter Shell - %s.\n", mb_ver_string());
|
||||||
static void _show_help(void) {
|
printf("Copyright (C) 2011 - 2015 W. Renxin. All Rights Reserved.\n");
|
||||||
printf("Commands:\n");
|
printf("For more information, see https://github.com/paladin-t/my_basic/.\n");
|
||||||
printf(" CLS - Clear screen\n");
|
printf("Input HELP and hint enter to view help information.\n");
|
||||||
printf(" NEW - Clear current program\n");
|
}
|
||||||
printf(" RUN - Run current program\n");
|
|
||||||
printf(" BYE - Quit interpreter\n");
|
static void _show_help(void) {
|
||||||
printf(" LIST - List current program\n");
|
printf("Commands:\n");
|
||||||
printf(" Usage: LIST [l [n]], l is start line number, n is line count\n");
|
printf(" CLS - Clear screen\n");
|
||||||
printf(" EDIT - Edit a line in current program\n");
|
printf(" NEW - Clear current program\n");
|
||||||
printf(" Usage: EDIT n, n is line number\n");
|
printf(" RUN - Run current program\n");
|
||||||
printf(" LOAD - Load a file as current program\n");
|
printf(" BYE - Quit interpreter\n");
|
||||||
printf(" Usage: LOAD *.*\n");
|
printf(" LIST - List current program\n");
|
||||||
printf(" SAVE - Save current program to a file\n");
|
printf(" Usage: LIST [l [n]], l is start line number, n is line count\n");
|
||||||
printf(" Usage: SAVE *.*\n");
|
printf(" EDIT - Edit a line in current program\n");
|
||||||
printf(" KILL - Delete a file\n");
|
printf(" Usage: EDIT n, n is line number\n");
|
||||||
printf(" Usage: KILL *.*\n");
|
printf(" LOAD - Load a file as current program\n");
|
||||||
}
|
printf(" Usage: LOAD *.*\n");
|
||||||
|
printf(" SAVE - Save current program to a file\n");
|
||||||
static int _do_line(void) {
|
printf(" Usage: SAVE *.*\n");
|
||||||
int result = MB_FUNC_OK;
|
printf(" KILL - Delete a file\n");
|
||||||
char line[_MAX_LINE_LENGTH];
|
printf(" Usage: KILL *.*\n");
|
||||||
char dup[_MAX_LINE_LENGTH];
|
}
|
||||||
|
|
||||||
mb_assert(bas);
|
static int _do_line(void) {
|
||||||
|
int result = MB_FUNC_OK;
|
||||||
memset(line, 0, _MAX_LINE_LENGTH);
|
char line[_MAX_LINE_LENGTH];
|
||||||
printf("]");
|
char dup[_MAX_LINE_LENGTH];
|
||||||
mb_gets(line, _MAX_LINE_LENGTH);
|
|
||||||
|
mb_assert(bas);
|
||||||
memcpy(dup, line, _MAX_LINE_LENGTH);
|
|
||||||
strtok(line, " ");
|
memset(line, 0, _MAX_LINE_LENGTH);
|
||||||
|
printf("]");
|
||||||
if(_str_eq(line, "")) {
|
mb_gets(line, _MAX_LINE_LENGTH);
|
||||||
/* Do nothing */
|
|
||||||
} else if(_str_eq(line, "HELP")) {
|
memcpy(dup, line, _MAX_LINE_LENGTH);
|
||||||
_show_help();
|
strtok(line, " ");
|
||||||
} else if(_str_eq(line, "CLS")) {
|
|
||||||
_clear_screen();
|
if(_str_eq(line, "")) {
|
||||||
} else if(_str_eq(line, "NEW")) {
|
/* Do nothing */
|
||||||
result = _new_program();
|
} else if(_str_eq(line, "HELP")) {
|
||||||
} else if(_str_eq(line, "RUN")) {
|
_show_help();
|
||||||
char* txt = _get_code(c);
|
} else if(_str_eq(line, "CLS")) {
|
||||||
result = mb_reset(&bas, false);
|
_clear_screen();
|
||||||
result = mb_load_string(bas, txt);
|
} else if(_str_eq(line, "NEW")) {
|
||||||
free(txt);
|
result = _new_program();
|
||||||
result = mb_run(bas);
|
} else if(_str_eq(line, "RUN")) {
|
||||||
printf("\n");
|
char* txt = _get_code(c);
|
||||||
} else if(_str_eq(line, "BYE")) {
|
result = mb_reset(&bas, false);
|
||||||
result = MB_FUNC_BYE;
|
result = mb_load_string(bas, txt);
|
||||||
} else if(_str_eq(line, "LIST")) {
|
free(txt);
|
||||||
char* sn = line + strlen(line) + 1;
|
result = mb_run(bas);
|
||||||
char* cn = 0;
|
printf("\n");
|
||||||
strtok(sn, " ");
|
} else if(_str_eq(line, "BYE")) {
|
||||||
cn = sn + strlen(sn) + 1;
|
result = MB_FUNC_BYE;
|
||||||
_list_program(sn, cn);
|
} else if(_str_eq(line, "LIST")) {
|
||||||
} else if(_str_eq(line, "EDIT")) {
|
char* sn = line + strlen(line) + 1;
|
||||||
char* no = line + strlen(line) + 1;
|
char* cn = 0;
|
||||||
_edit_program(no);
|
strtok(sn, " ");
|
||||||
} else if(_str_eq(line, "LOAD")) {
|
cn = sn + strlen(sn) + 1;
|
||||||
char* path = line + strlen(line) + 1;
|
_list_program(sn, cn);
|
||||||
_load_program(path);
|
} else if(_str_eq(line, "EDIT")) {
|
||||||
} else if(_str_eq(line, "SAVE")) {
|
char* no = line + strlen(line) + 1;
|
||||||
char* path = line + strlen(line) + 1;
|
_edit_program(no);
|
||||||
_save_program(path);
|
} else if(_str_eq(line, "LOAD")) {
|
||||||
} else if(_str_eq(line, "KILL")) {
|
char* path = line + strlen(line) + 1;
|
||||||
char* path = line + strlen(line) + 1;
|
_load_program(path);
|
||||||
_kill_program(path);
|
} else if(_str_eq(line, "SAVE")) {
|
||||||
} else {
|
char* path = line + strlen(line) + 1;
|
||||||
_append_line(c, dup);
|
_save_program(path);
|
||||||
}
|
} else if(_str_eq(line, "KILL")) {
|
||||||
|
char* path = line + strlen(line) + 1;
|
||||||
return result;
|
_kill_program(path);
|
||||||
}
|
} else {
|
||||||
|
_append_line(c, dup);
|
||||||
int main(int argc, char* argv[]) {
|
}
|
||||||
int status = 0;
|
|
||||||
|
return result;
|
||||||
#if defined _MSC_VER && !defined _WIN64
|
}
|
||||||
_CrtSetBreakAlloc(0);
|
|
||||||
#endif /* _MSC_VER && !_WIN64 */
|
int main(int argc, char* argv[]) {
|
||||||
|
int status = 0;
|
||||||
atexit(_on_exit);
|
|
||||||
|
#if defined _MSC_VER && !defined _WIN64
|
||||||
_on_startup();
|
_CrtSetBreakAlloc(0);
|
||||||
|
#endif /* _MSC_VER && !_WIN64 */
|
||||||
if(argc == 1) {
|
|
||||||
_show_tip();
|
atexit(_on_exit);
|
||||||
do {
|
|
||||||
status = _do_line();
|
_on_startup();
|
||||||
} while(_NO_END(status));
|
|
||||||
} else if(argc == 2) {
|
if(argc == 1) {
|
||||||
if(mb_load_file(bas, argv[1]) == MB_FUNC_OK) {
|
_show_tip();
|
||||||
mb_run(bas);
|
do {
|
||||||
}
|
status = _do_line();
|
||||||
} else {
|
} while(_NO_END(status));
|
||||||
printf("Unknown arguments\n");
|
} else if(argc == 2) {
|
||||||
_show_tip();
|
if(mb_load_file(bas, argv[1]) == MB_FUNC_OK) {
|
||||||
}
|
mb_run(bas);
|
||||||
|
}
|
||||||
return 0;
|
} else {
|
||||||
}
|
printf("Unknown arguments\n");
|
||||||
|
_show_tip();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user