diff --git a/HISTORY b/HISTORY index 8ae0a3a..fdca007 100755 --- a/HISTORY +++ b/HISTORY @@ -1,3 +1,8 @@ +Sep. 16 2015 +Added Nil type handling, including assignment, boolean operation, serialization, etc. +Added an MB_CONVERT_TO_INT_LEVEL macro, would convert float to integer as much as possible if this macro was enabled +Polished document + Sep. 11 2015 Added a duplicate sub routine error handling Added optional argument support for INPUT statement diff --git a/LICENSE b/LICENSE index f95323c..232f990 100755 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License -Copyright (c) 2011 - 2015 Wang Renxin +Copyright (C) 2011 - 2015 Wang Renxin 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 diff --git a/MY-BASIC Quick Reference.pdf b/MY-BASIC Quick Reference.pdf index 847de32..a0b4025 100755 Binary files a/MY-BASIC Quick Reference.pdf and b/MY-BASIC Quick Reference.pdf differ diff --git a/README.md b/README.md index e272b74..06b27f3 100755 --- a/README.md +++ b/README.md @@ -43,6 +43,8 @@ Come along with a traditional "hello world" script in MY-BASIC: input +Read the [MY-BASIC Quick Reference](MY-BASIC%20Quick%20Reference.pdf) (especially the "**Programming with BASIC**" section) to get more details about how to program in MY-BASIC. + ## [Interpreter workflow diagram](https://github.com/paladin-t/my_basic/wiki/Interpreter-workflow-diagram) ![](https://github.com/paladin-t/my_basic/blob/master/interpreter%20workflow%20diagram.png) diff --git a/core/my_basic.c b/core/my_basic.c index b4cae88..16667ab 100755 --- a/core/my_basic.c +++ b/core/my_basic.c @@ -79,7 +79,7 @@ extern "C" { /** Macros */ #define _VER_MAJOR 1 #define _VER_MINOR 1 -#define _VER_REVISION 69 +#define _VER_REVISION 70 #define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION)) /* Uncomment the line below to treat warning as error */ @@ -338,11 +338,9 @@ const size_t MB_SIZEOF_CLS = sizeof(_class_t); #ifdef MB_ENABLE_SOURCE_TRACE static const _object_t _OBJ_INT_UNIT = { _DT_INT, 1, false, 0, 0, 0 }; static const _object_t _OBJ_INT_ZERO = { _DT_INT, 0, false, 0, 0, 0 }; -static const _object_t _OBJ_NIL = { _DT_NIL, 0, false, 0, 0, 0 }; #else /* MB_ENABLE_SOURCE_TRACE */ static const _object_t _OBJ_INT_UNIT = { _DT_INT, 1, false, 0 }; static const _object_t _OBJ_INT_ZERO = { _DT_INT, 0, false, 0 }; -static const _object_t _OBJ_NIL = { _DT_NIL, 0, false, 0 }; #endif /* MB_ENABLE_SOURCE_TRACE */ static _object_t* _OBJ_BOOL_TRUE = 0; @@ -471,6 +469,18 @@ static _object_t* _exp_assign = 0; } \ } while(0) +#if MB_CONVERT_TO_INT_LEVEL == MB_CONVERT_TO_INT_LEVEL_NONE +# define _convert_to_int_if_posible(__o) ((void)(__o)) +#else /* MB_CONVERT_TO_INT_LEVEL == MB_CONVERT_TO_INT_LEVEL_NONE */ +# define _convert_to_int_if_posible(__o) \ + do { \ + if((__o)->type == _DT_REAL && (real_t)(int_t)(__o)->data.float_point == (__o)->data.float_point) { \ + (__o)->type = _DT_INT; \ + (__o)->data.integer = (int_t)(__o)->data.float_point; \ + } \ + } while(0) +#endif /* MB_CONVERT_TO_INT_LEVEL == MB_CONVERT_TO_INT_LEVEL_NONE */ + #define _instruct_common(__tuple) \ _object_t opndv1; \ _object_t opndv2; \ @@ -496,10 +506,7 @@ static _object_t* _exp_assign = 0; opndv1.type == _DT_INT ? opndv1.data.integer : opndv1.data.float_point, \ opndv2.type == _DT_INT ? opndv2.data.integer : opndv2.data.float_point); \ } \ - if(val->type == _DT_REAL && (real_t)(int_t)val->data.float_point == val->data.float_point) { \ - val->type = _DT_INT; \ - val->data.integer = (int_t)val->data.float_point; \ - } \ + _convert_to_int_if_posible(val); \ } while(0) #define _instruct_num_op_num(__optr, __tuple) \ do { \ @@ -518,10 +525,28 @@ static _object_t* _exp_assign = 0; ((opndv1.type == _DT_INT ? opndv1.data.integer : opndv1.data.float_point) __optr \ (opndv2.type == _DT_INT ? opndv2.data.integer : opndv2.data.float_point)); \ } \ - if(val->type == _DT_REAL && (real_t)(int_t)val->data.float_point == val->data.float_point) { \ - val->type = _DT_INT; \ - val->data.integer = (int_t)val->data.float_point; \ + _convert_to_int_if_posible(val); \ + } while(0) +#define _instruct_num_op_num_allow_nil(__optr, __tuple) \ + do { \ + _instruct_common(__tuple) \ + if(opndv1.type == _DT_NIL) { opndv1.type = _DT_INT; opndv1.data.integer = 0; } \ + if(opndv2.type == _DT_NIL) { opndv2.type = _DT_INT; opndv2.data.integer = 0; } \ + if(opndv1.type == _DT_INT && opndv2.type == _DT_INT) { \ + if((real_t)(opndv1.data.integer __optr opndv2.data.integer) == (real_t)opndv1.data.integer __optr (real_t)opndv2.data.integer) { \ + val->type = _DT_INT; \ + val->data.integer = opndv1.data.integer __optr opndv2.data.integer; \ + } else { \ + val->type = _DT_REAL; \ + val->data.float_point = (real_t)((real_t)opndv1.data.integer __optr (real_t)opndv2.data.integer); \ + } \ + } else { \ + val->type = _DT_REAL; \ + val->data.float_point = (real_t) \ + ((opndv1.type == _DT_INT ? opndv1.data.integer : opndv1.data.float_point) __optr \ + (opndv2.type == _DT_INT ? opndv2.data.integer : opndv2.data.float_point)); \ } \ + _convert_to_int_if_posible(val); \ } while(0) #define _instruct_int_op_int(__optr, __tuple) \ do { \ @@ -590,6 +615,21 @@ static _object_t* _exp_assign = 0; val->data.integer = __r; \ } while(0) +#define _math_calculate_fun_real(__s, __l, __a, __f, __exit, __result) \ + switch((__a).type) { \ + case MB_DT_INT: \ + (__a).value.float_point = (real_t)__f((real_t)(__a).value.integer); \ + (__a).type = MB_DT_REAL; \ + break; \ + case MB_DT_REAL: \ + (__a).value.float_point = (real_t)__f((__a).value.float_point); \ + break; \ + default: \ + _handle_error_on_obj(__s, SE_RN_NUMBER_EXPECTED, 0, ((__l) && *(__l)) ? ((_object_t*)(((_tuple3_t*)(*(__l)))->e1)) : 0, MB_FUNC_WARNING, __exit, __result); \ + break; \ + } \ + mb_convert_to_int_if_posible(__a); + #define _using_jump_set_of_instructional(__s, __obj, __exit, __result) \ do { \ if((__s)->jump_set & (~_JMP_INS)) { \ @@ -1909,7 +1949,7 @@ int _calc_expression(mb_interpreter_t* s, _ls_node_t** l, _object_t** val) { } c = (_object_t*)(_ls_popback(opnd)); - if(!c || !(c->type == _DT_INT || c->type == _DT_REAL || c->type == _DT_STRING || c->type == _DT_VAR || c->type == _DT_USERTYPE || c->type == _DT_ARRAY)) { + if(!c || !(c->type == _DT_NIL || c->type == _DT_INT || c->type == _DT_REAL || c->type == _DT_STRING || c->type == _DT_VAR || c->type == _DT_USERTYPE || c->type == _DT_ARRAY)) { _set_current_error(s, SE_RN_INVALID_DATA_TYPE, 0); result = MB_FUNC_ERR; @@ -2254,8 +2294,13 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob (*obj)->type = type; switch(type) { case _DT_NIL: - safe_free(*obj); - *obj = 0; + memcpy(tmp.any, value, sizeof(_raw_t)); + if(tmp.integer) { /* Nil type */ + (*obj)->type = _DT_NIL; + } else { /* End of line character */ + safe_free(*obj); + *obj = 0; + } safe_free(sym); break; @@ -2491,6 +2536,15 @@ _data_e _get_symbol_type(mb_interpreter_t* s, char* sym, _raw_t* value) { goto _exit; } + /* Nil */ + if(!strcmp(sym, "NIL")) { + tmp.integer = ~0; + memcpy(*value, tmp.any, sizeof(_raw_t)); + + result = _DT_NIL; + + goto _exit; + } /* _array_t */ glbsyminscope = _search_var_in_scope_chain(s, 0, sym); if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_ARRAY) { @@ -3490,6 +3544,8 @@ bool_t _is_internal_object(_object_t* obj) { _data_e _public_type_to_internal_type(mb_data_e t) { /* Convert a public mb_data_e type to an internal _data_e */ switch(t) { + case MB_DT_NIL: + return _DT_NIL; case MB_DT_INT: return _DT_INT; case MB_DT_REAL: @@ -3506,6 +3562,8 @@ _data_e _public_type_to_internal_type(mb_data_e t) { mb_data_e _internal_type_to_public_type(_data_e t) { /* Convert an internal mb_data_e type to a public _data_e */ switch(t) { + case _DT_NIL: + return MB_DT_NIL; case _DT_INT: return MB_DT_INT; case _DT_REAL: @@ -3526,6 +3584,11 @@ int _public_value_to_internal_object(mb_value_t* pbl, _object_t* itn) { mb_assert(pbl && itn); switch(pbl->type) { + case MB_DT_NIL: + itn->type = _DT_NIL; + itn->data.integer = false; + + break; case MB_DT_INT: itn->type = _DT_INT; itn->data.integer = pbl->value.integer; @@ -3567,6 +3630,11 @@ int _internal_object_to_public_value(_object_t* itn, mb_value_t* pbl) { mb_assert(pbl && itn); switch(itn->type) { + case _DT_NIL: + pbl->type = MB_DT_NIL; + pbl->value.integer = false; + + break; case _DT_INT: pbl->type = MB_DT_INT; pbl->value.integer = itn->data.integer; @@ -4538,6 +4606,7 @@ int mb_push_real(struct mb_interpreter_t* s, void** l, real_t val) { arg.type = MB_DT_REAL; arg.value.float_point = val; + mb_convert_to_int_if_posible(arg); mb_check(mb_push_value(s, l, arg)); return result; @@ -5218,6 +5287,7 @@ int _core_neg(mb_interpreter_t* s, void** l) { break; } + mb_check(mb_push_value(s, l, arg)); _exit: @@ -5408,7 +5478,7 @@ int _core_and(mb_interpreter_t* s, void** l) { mb_assert(s && l); - _instruct_num_op_num(&&, l); + _instruct_num_op_num_allow_nil(&&, l); return result; } @@ -5419,7 +5489,7 @@ int _core_or(mb_interpreter_t* s, void** l) { mb_assert(s && l); - _instruct_num_op_num(||, l); + _instruct_num_op_num_allow_nil(||, l); return result; } @@ -5438,6 +5508,11 @@ int _core_not(mb_interpreter_t* s, void** l) { mb_check(mb_attempt_func_end(s, l)); switch(arg.type) { + case MB_DT_NIL: + arg.value.integer = true; + arg.type = MB_DT_INT; + + break; case MB_DT_INT: arg.value.integer = (int_t)(!arg.value.integer); @@ -5448,6 +5523,9 @@ int _core_not(mb_interpreter_t* s, void** l) { break; default: + arg.value.integer = false; + arg.type = MB_DT_INT; + break; } mb_check(mb_push_int(s, l, arg.value.integer)); @@ -5639,7 +5717,6 @@ _elseif: result = _calc_expression(s, &ast, &val); if(result != MB_FUNC_OK) goto _exit; - mb_assert(val->type == _DT_INT); obj = (_object_t*)(ast->data); if(val->data.integer) { @@ -5966,7 +6043,6 @@ _loop_begin: result = _calc_expression(s, &ast, &loop_cond_ptr); if(result != MB_FUNC_OK) goto _exit; - mb_assert(loop_cond_ptr->type == _DT_INT); if(loop_cond_ptr->data.integer) { /* Keep looping */ @@ -6066,7 +6142,6 @@ _loop_begin: result = _calc_expression(s, &ast, &loop_cond_ptr); if(result != MB_FUNC_OK) goto _exit; - mb_assert(loop_cond_ptr->type == _DT_INT); if(loop_cond_ptr->data.integer) { /* End looping */ @@ -6402,6 +6477,7 @@ int _std_abs(mb_interpreter_t* s, void** l) { break; } + mb_check(mb_push_value(s, l, arg)); _exit: @@ -6455,21 +6531,8 @@ int _std_sqr(mb_interpreter_t* s, void** l) { mb_check(mb_attempt_close_bracket(s, l)); - switch(arg.type) { - case MB_DT_INT: - arg.value.float_point = (real_t)sqrt((real_t)arg.value.integer); - arg.type = MB_DT_REAL; + _math_calculate_fun_real(s, l, arg, sqrt, _exit, result); - break; - case MB_DT_REAL: - arg.value.float_point = (real_t)sqrt(arg.value.float_point); - - break; - default: - _handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, 0, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result); - - break; - } mb_check(mb_push_value(s, l, arg)); _exit: @@ -6641,21 +6704,8 @@ int _std_sin(mb_interpreter_t* s, void** l) { mb_check(mb_attempt_close_bracket(s, l)); - switch(arg.type) { - case MB_DT_INT: - arg.value.float_point = (real_t)sin((real_t)arg.value.integer); - arg.type = MB_DT_REAL; + _math_calculate_fun_real(s, l, arg, sin, _exit, result); - break; - case MB_DT_REAL: - arg.value.float_point = (real_t)sin(arg.value.float_point); - - break; - default: - _handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, 0, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result); - - break; - } mb_check(mb_push_value(s, l, arg)); _exit: @@ -6675,21 +6725,8 @@ int _std_cos(mb_interpreter_t* s, void** l) { mb_check(mb_attempt_close_bracket(s, l)); - switch(arg.type) { - case MB_DT_INT: - arg.value.float_point = (real_t)cos((real_t)arg.value.integer); - arg.type = MB_DT_REAL; + _math_calculate_fun_real(s, l, arg, cos, _exit, result); - break; - case MB_DT_REAL: - arg.value.float_point = (real_t)cos(arg.value.float_point); - - break; - default: - _handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, 0, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result); - - break; - } mb_check(mb_push_value(s, l, arg)); _exit: @@ -6709,21 +6746,8 @@ int _std_tan(mb_interpreter_t* s, void** l) { mb_check(mb_attempt_close_bracket(s, l)); - switch(arg.type) { - case MB_DT_INT: - arg.value.float_point = (real_t)tan((real_t)arg.value.integer); - arg.type = MB_DT_REAL; + _math_calculate_fun_real(s, l, arg, tan, _exit, result); - break; - case MB_DT_REAL: - arg.value.float_point = (real_t)tan(arg.value.float_point); - - break; - default: - _handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, 0, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result); - - break; - } mb_check(mb_push_value(s, l, arg)); _exit: @@ -6743,21 +6767,8 @@ int _std_asin(mb_interpreter_t* s, void** l) { mb_check(mb_attempt_close_bracket(s, l)); - switch(arg.type) { - case MB_DT_INT: - arg.value.float_point = (real_t)asin((real_t)arg.value.integer); - arg.type = MB_DT_REAL; + _math_calculate_fun_real(s, l, arg, asin, _exit, result); - break; - case MB_DT_REAL: - arg.value.float_point = (real_t)asin(arg.value.float_point); - - break; - default: - _handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, 0, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result); - - break; - } mb_check(mb_push_value(s, l, arg)); _exit: @@ -6777,21 +6788,8 @@ int _std_acos(mb_interpreter_t* s, void** l) { mb_check(mb_attempt_close_bracket(s, l)); - switch(arg.type) { - case MB_DT_INT: - arg.value.float_point = (real_t)acos((real_t)arg.value.integer); - arg.type = MB_DT_REAL; + _math_calculate_fun_real(s, l, arg, acos, _exit, result); - break; - case MB_DT_REAL: - arg.value.float_point = (real_t)acos(arg.value.float_point); - - break; - default: - _handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, 0, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result); - - break; - } mb_check(mb_push_value(s, l, arg)); _exit: @@ -6811,21 +6809,8 @@ int _std_atan(mb_interpreter_t* s, void** l) { mb_check(mb_attempt_close_bracket(s, l)); - switch(arg.type) { - case MB_DT_INT: - arg.value.float_point = (real_t)atan((real_t)arg.value.integer); - arg.type = MB_DT_REAL; + _math_calculate_fun_real(s, l, arg, atan, _exit, result); - break; - case MB_DT_REAL: - arg.value.float_point = (real_t)atan(arg.value.float_point); - - break; - default: - _handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, 0, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result); - - break; - } mb_check(mb_push_value(s, l, arg)); _exit: @@ -6845,21 +6830,8 @@ int _std_exp(mb_interpreter_t* s, void** l) { mb_check(mb_attempt_close_bracket(s, l)); - switch(arg.type) { - case MB_DT_INT: - arg.value.float_point = (real_t)exp((real_t)arg.value.integer); - arg.type = MB_DT_REAL; + _math_calculate_fun_real(s, l, arg, exp, _exit, result); - break; - case MB_DT_REAL: - arg.value.float_point = (real_t)exp(arg.value.float_point); - - break; - default: - _handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, 0, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result); - - break; - } mb_check(mb_push_value(s, l, arg)); _exit: @@ -6879,21 +6851,8 @@ int _std_log(mb_interpreter_t* s, void** l) { mb_check(mb_attempt_close_bracket(s, l)); - switch(arg.type) { - case MB_DT_INT: - arg.value.float_point = (real_t)log((real_t)arg.value.integer); - arg.type = MB_DT_REAL; + _math_calculate_fun_real(s, l, arg, log, _exit, result); - break; - case MB_DT_REAL: - arg.value.float_point = (real_t)log(arg.value.float_point); - - break; - default: - _handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, 0, (l && *l) ? ((_object_t*)(((_tuple3_t*)(*l))->e1)) : 0, MB_FUNC_WARNING, _exit, result); - - break; - } mb_check(mb_push_value(s, l, arg)); _exit: @@ -7149,6 +7108,7 @@ int _std_print(mb_interpreter_t* s, void** l) { obj = (_object_t*)(ast->data); do { switch(obj->type) { + case _DT_NIL: /* Fall through */ case _DT_INT: /* Fall through */ case _DT_REAL: /* Fall through */ case _DT_STRING: /* Fall through */ @@ -7156,7 +7116,9 @@ int _std_print(mb_interpreter_t* s, void** l) { case _DT_ARRAY: /* Fall through */ case _DT_FUNC: result = _calc_expression(s, &ast, &val_ptr); - if(val_ptr->type == _DT_INT) { + if(val_ptr->type == _DT_NIL) { + _get_printer(s)(MB_NIL); + } else if(val_ptr->type == _DT_INT) { _get_printer(s)(MB_INT_FMT, val_ptr->data.integer); } else if(val_ptr->type == _DT_REAL) { _get_printer(s)(MB_REAL_FMT, val_ptr->data.float_point); diff --git a/core/my_basic.h b/core/my_basic.h index 8bc9549..7e78716 100755 --- a/core/my_basic.h +++ b/core/my_basic.h @@ -58,50 +58,65 @@ extern "C" { # pragma pack(1) #endif /* MB_COMPACT_MODE */ +#ifndef MB_CONVERT_TO_INT_LEVEL_NONE +# define MB_CONVERT_TO_INT_LEVEL_NONE 0 +#endif /* MB_CONVERT_TO_INT_LEVEL_NONE */ + +#ifndef MB_CONVERT_TO_INT_LEVEL_ALL +# define MB_CONVERT_TO_INT_LEVEL_ALL 1 +#endif /* MB_CONVERT_TO_INT_LEVEL_ALL */ + +#ifndef MB_CONVERT_TO_INT_LEVEL +# define MB_CONVERT_TO_INT_LEVEL MB_CONVERT_TO_INT_LEVEL_ALL +#endif /* MB_CONVERT_TO_INT_LEVEL */ + #ifndef true # define true (!0) -#endif +#endif /* true */ #ifndef false # define false (0) -#endif +#endif /* false */ #ifndef bool_t # define bool_t int -#endif +#endif /* bool_t */ #ifndef int_t # define int_t int -#endif +#endif /* int_t */ #ifndef real_t # define real_t float -#endif +#endif /* real_t */ #ifndef mb_strtol # define mb_strtol(__s, __e, __r) strtol((__s), (__e), (__r)) -#endif +#endif /* mb_strtol */ #ifndef mb_strtod # define mb_strtod(__s, __e) strtod((__s), (__e)) -#endif +#endif /* mb_strtod */ #ifndef MB_INT_FMT # define MB_INT_FMT "%d" -#endif +#endif /* MB_INT_FMT */ #ifndef MB_REAL_FMT # define MB_REAL_FMT "%g" -#endif +#endif /* MB_REAL_FMT */ #ifndef MB_FNAN # define MB_FNAN 0xffc00000 -#endif +#endif /* MB_FNAN */ #ifndef MB_FINF # define MB_FINF 0x7f800000 -#endif +#endif /* MB_FINF */ #ifndef MB_EOS # define MB_EOS '\n' -#endif +#endif /* MB_EOS */ +#ifndef MB_NIL +# define MB_NIL "nil" +#endif /* MB_NIL */ #ifndef MB_NULL_STRING # define MB_NULL_STRING "(empty)" -#endif +#endif /* MB_NULL_STRING */ #ifndef _MSC_VER # ifndef _strcmpi @@ -163,6 +178,20 @@ extern "C" { # define mb_rem_res_fun(__s, __f) mb_remove_reserved_func(__s, #__f) #endif /* mb_rem_res_fun */ +#ifndef mb_convert_to_int_if_posible +# if MB_CONVERT_TO_INT_LEVEL == MB_CONVERT_TO_INT_LEVEL_NONE +# define mb_convert_to_int_if_posible(__v) ((void)(__v)) +# else /* MB_CONVERT_TO_INT_LEVEL == MB_CONVERT_TO_INT_LEVEL_NONE */ +# define mb_convert_to_int_if_posible(__v) \ + do { \ + if((__v).type == MB_DT_REAL && (real_t)(int_t)(__v).value.float_point == (__v).value.float_point) { \ + (__v).type = MB_DT_INT; \ + (__v).value.integer = (int_t)(__v).value.float_point; \ + } \ + } while(0) +# endif /* MB_CONVERT_TO_INT_LEVEL == MB_CONVERT_TO_INT_LEVEL_NONE */ +#endif /* mb_convert_to_int_if_posible */ + struct mb_interpreter_t; typedef enum mb_error_e { diff --git a/output/my_basic_mac b/output/my_basic_mac index 6f29fce..3e26a1b 100755 Binary files a/output/my_basic_mac and b/output/my_basic_mac differ diff --git a/resource/my_basic.rc b/resource/my_basic.rc index 01605c4..df6167d 100755 --- a/resource/my_basic.rc +++ b/resource/my_basic.rc @@ -36,8 +36,8 @@ IDI_ICON_MAIN ICON "icon.ico" VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,1,69,0 - PRODUCTVERSION 1,1,69,0 + FILEVERSION 1,1,70,0 + PRODUCTVERSION 1,1,70,0 FILEFLAGSMASK 0x17L # ifdef _DEBUG FILEFLAGS 0x1L @@ -55,13 +55,13 @@ VALUE "Comments", "MY-BASIC" VALUE "CompanyName", "Wang Renxin" VALUE "FileDescription", "MY-BASIC Interpreter for Windows" - VALUE "FileVersion", "1, 1, 69, 0" + VALUE "FileVersion", "1, 1, 70, 0" VALUE "InternalName", "my_basic" VALUE "LegalCopyright", "Copyright (C) 2011 - 2015 Wang Renxin" VALUE "LegalTrademarks", "MY-BASIC" VALUE "OriginalFilename", "my_basic.exe" VALUE "ProductName", "MY-BASIC" - VALUE "ProductVersion", "1, 1, 69, 0" + VALUE "ProductVersion", "1, 1, 70, 0" END END BLOCK "VarFileInfo"