+implemented tail recursion optimization in sub routine; +added array length gain in len function; *fixed a crash bug when returning nothing in a sub routine; *polished document.

This commit is contained in:
tony 2015-09-21 23:51:55 +08:00
parent a956338ec0
commit b6ab676ad7
7 changed files with 216 additions and 168 deletions

View File

@ -1,3 +1,9 @@
Sep. 21 2015
Implemented tail recursion optimization in sub routine
Added array length gain in LEN function
Fixed a crash bug when returning nothing in a sub routine
Polished document
Sep. 20 2015 Sep. 20 2015
Added array manipulation ability to script, it's able to assign an array to a variable or use it as a scripting interface argument Added array manipulation ability to script, it's able to assign an array to a variable or use it as a scripting interface argument
Added recursive sub routine support Added recursive sub routine support
@ -10,7 +16,7 @@ Added directly expression evaluation shell command
Sep. 17 2015 Sep. 17 2015
Allowed string in a boolean expression Allowed string in a boolean expression
Added support for sub routine in PRINT Added support for sub routine in PRINT
Fixed a repeated disposing bug when suing sub routine Fixed a repeated disposing bug when using sub routine
Sep. 16 2015 Sep. 16 2015
Added Nil type handling, including assignment, boolean operation, serialization, etc. Added Nil type handling, including assignment, boolean operation, serialization, etc.

Binary file not shown.

View File

@ -79,8 +79,12 @@ extern "C" {
/** Macros */ /** Macros */
#define _VER_MAJOR 1 #define _VER_MAJOR 1
#define _VER_MINOR 1 #define _VER_MINOR 1
#define _VER_REVISION 72 #define _VER_REVISION 73
#define _VER_SUFFIX
#define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION)) #define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION))
#define _STRINGIZE(A) _MAKE_STRINGIZE(A)
#define _MAKE_STRINGIZE(A) #A
#define _MB_VERSION_STRING _STRINGIZE(_VER_MAJOR._VER_MINOR._VER_REVISION _VER_SUFFIX)
/* Uncomment the line below to treat warning as error */ /* Uncomment the line below to treat warning as error */
/*#define _WARING_AS_ERROR*/ /*#define _WARING_AS_ERROR*/
@ -407,6 +411,7 @@ typedef struct mb_interpreter_t {
_parsing_context_t* parsing_context; _parsing_context_t* parsing_context;
_running_context_t* running_context; _running_context_t* running_context;
unsigned char jump_set; unsigned char jump_set;
_routine_t* last_routine;
_ls_node_t* sub_stack; _ls_node_t* sub_stack;
_ls_node_t* temp_values; _ls_node_t* temp_values;
_ls_node_t* suspent_point; _ls_node_t* suspent_point;
@ -985,11 +990,11 @@ static int _std_log(mb_interpreter_t* s, void** l);
static int _std_asc(mb_interpreter_t* s, void** l); static int _std_asc(mb_interpreter_t* s, void** l);
static int _std_chr(mb_interpreter_t* s, void** l); static int _std_chr(mb_interpreter_t* s, void** l);
static int _std_left(mb_interpreter_t* s, void** l); static int _std_left(mb_interpreter_t* s, void** l);
static int _std_len(mb_interpreter_t* s, void** l);
static int _std_mid(mb_interpreter_t* s, void** l); static int _std_mid(mb_interpreter_t* s, void** l);
static int _std_right(mb_interpreter_t* s, void** l); static int _std_right(mb_interpreter_t* s, void** l);
static int _std_str(mb_interpreter_t* s, void** l); static int _std_str(mb_interpreter_t* s, void** l);
static int _std_val(mb_interpreter_t* s, void** l); static int _std_val(mb_interpreter_t* s, void** l);
static int _std_len(mb_interpreter_t* s, void** l);
static int _std_print(mb_interpreter_t* s, void** l); static int _std_print(mb_interpreter_t* s, void** l);
static int _std_input(mb_interpreter_t* s, void** l); static int _std_input(mb_interpreter_t* s, void** l);
@ -1075,12 +1080,13 @@ static const _func_t _std_libs[] = {
{ "ASC", _std_asc }, { "ASC", _std_asc },
{ "CHR", _std_chr }, { "CHR", _std_chr },
{ "LEFT", _std_left }, { "LEFT", _std_left },
{ "LEN", _std_len },
{ "MID", _std_mid }, { "MID", _std_mid },
{ "RIGHT", _std_right }, { "RIGHT", _std_right },
{ "STR", _std_str }, { "STR", _std_str },
{ "VAL", _std_val }, { "VAL", _std_val },
{ "LEN", _std_len },
{ "PRINT", _std_print }, { "PRINT", _std_print },
{ "INPUT", _std_input } { "INPUT", _std_input }
}; };
@ -1839,6 +1845,8 @@ int _calc_expression(mb_interpreter_t* s, _ls_node_t** l, _object_t** val) {
memset(c, 0, sizeof(_object_t)); memset(c, 0, sizeof(_object_t));
_ls_pushback(garbage, c); _ls_pushback(garbage, c);
result = _public_value_to_internal_object(&running->intermediate_value, c); result = _public_value_to_internal_object(&running->intermediate_value, c);
if(c->type == _DT_STRING)
c->ref = true;
if(result != MB_FUNC_OK) if(result != MB_FUNC_OK)
goto _exit; goto _exit;
if(f) { if(f) {
@ -2018,9 +2026,27 @@ int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, _routine_t* r) {
_var_t* var = 0; _var_t* var = 0;
_ls_node_t* rnode = 0; _ls_node_t* rnode = 0;
_running_context_t* running = 0; _running_context_t* running = 0;
_routine_t* lastr = 0;
mb_assert(s && l && r); mb_assert(s && l && r);
if(s->last_routine && (s->last_routine->name == r->name || !strcmp(s->last_routine->name, r->name))) {
ast = (_ls_node_t*)(*l);
_skip_to(s, &ast, 0, _DT_EOS);
if(ast && ((_object_t*)(ast->data))->type == _DT_EOS)
ast = ast->next;
if(_IS_FUNC((_object_t*)(ast->data), _core_enddef)) { /* Tail recursion optimization */
*l = r->entry;
if(*l)
*l = (*l)->next;
goto _tail;
}
}
lastr = s->last_routine;
s->last_routine = r;
running = s->running_context; running = s->running_context;
mb_check(mb_attempt_open_bracket(s, (void**)l)); mb_check(mb_attempt_open_bracket(s, (void**)l));
@ -2094,6 +2120,9 @@ int _eval_routine(mb_interpreter_t* s, _ls_node_t** l, _routine_t* r) {
s->running_context->intermediate_value = running->intermediate_value; s->running_context->intermediate_value = running->intermediate_value;
_exit: _exit:
s->last_routine = lastr;
_tail:
return result; return result;
} }
@ -3846,6 +3875,8 @@ int _execute_statement(mb_interpreter_t* s, _ls_node_t** l) {
ast = (_ls_node_t*)_ls_popback(sub_stack); ast = (_ls_node_t*)_ls_popback(sub_stack);
} else if(obj && obj->type == _DT_FUNC && (_is_operator(obj->data.func->pointer) || _is_flow(obj->data.func->pointer))) { } else if(obj && obj->type == _DT_FUNC && (_is_operator(obj->data.func->pointer) || _is_flow(obj->data.func->pointer))) {
ast = ast->next; ast = ast->next;
} else if(obj && obj->type == _DT_FUNC) {
/* Do nothing */
} else if(obj && obj->type != _DT_FUNC) { } else if(obj && obj->type != _DT_FUNC) {
ast = ast->next; ast = ast->next;
} else { } else {
@ -4162,11 +4193,7 @@ unsigned int mb_ver(void) {
const char* mb_ver_string(void) { const char* mb_ver_string(void) {
/* Get the version text of this MY-BASIC system */ /* Get the version text of this MY-BASIC system */
static char buf[32] = { '\0' }; return _MB_VERSION_STRING;
if(!buf[0])
sprintf(buf, "%d.%d.%04d", _VER_MAJOR, _VER_MINOR, _VER_REVISION);
return buf;
} }
int mb_init(void) { int mb_init(void) {
@ -4353,6 +4380,7 @@ int mb_reset(struct mb_interpreter_t** s, bool_t clrf/* = false*/) {
mb_assert(s); mb_assert(s);
(*s)->jump_set = _JMP_NIL; (*s)->jump_set = _JMP_NIL;
(*s)->last_routine = 0;
(*s)->no_eat_comma_mark = 0; (*s)->no_eat_comma_mark = 0;
(*s)->last_error = SE_NO_ERR; (*s)->last_error = SE_NO_ERR;
(*s)->last_error_func = 0; (*s)->last_error_func = 0;
@ -6344,6 +6372,7 @@ int _core_return(mb_interpreter_t* s, void** l) {
if(running->prev) { if(running->prev) {
ast = (_ls_node_t*)(*l); ast = (_ls_node_t*)(*l);
ast = ast->next; ast = ast->next;
if(mb_has_arg(s, (void**)(&ast))) {
mb_check(mb_pop_value(s, (void**)(&ast), &arg)); mb_check(mb_pop_value(s, (void**)(&ast), &arg));
mb_check(mb_push_value(s, (void**)(&ast), arg)); mb_check(mb_push_value(s, (void**)(&ast), arg));
@ -6352,6 +6381,7 @@ int _core_return(mb_interpreter_t* s, void** l) {
_ls_clear(s->temp_values); _ls_clear(s->temp_values);
} }
} }
}
ast = (_ls_node_t*)_ls_popback(sub_stack); ast = (_ls_node_t*)_ls_popback(sub_stack);
if(!ast) { if(!ast) {
_handle_error_on_obj(s, SE_RN_NO_RETURN_POINT, 0, DON(ast), MB_FUNC_ERR, _exit, result); _handle_error_on_obj(s, SE_RN_NO_RETURN_POINT, 0, DON(ast), MB_FUNC_ERR, _exit, result);
@ -7027,43 +7057,6 @@ _exit:
return result; return result;
} }
int _std_len(mb_interpreter_t* s, void** l) {
/* Get the length of a string */
int result = MB_FUNC_OK;
_ls_node_t* ast = 0;
mb_value_t arg;
_array_t* arr = 0;
mb_assert(s && l);
ast = (_ls_node_t*)(*l);
mb_check(mb_attempt_open_bracket(s, l));
mb_check(mb_pop_value(s, l, &arg));
mb_check(mb_attempt_close_bracket(s, l));
switch(arg.type) {
case MB_DT_STRING:
mb_check(mb_push_int(s, l, (int_t)strlen(arg.value.string)));
break;
case MB_DT_ARRAY:
arr = (_array_t*)arg.value.array;
mb_check(mb_push_int(s, l, (int_t)arr->count));
break;
default:
_handle_error_on_obj(s, SE_RN_NOT_SUPPORTED, 0, DON(ast), MB_FUNC_ERR, _exit, result);
break;
}
_exit:
return result;
}
int _std_mid(mb_interpreter_t* s, void** l) { int _std_mid(mb_interpreter_t* s, void** l) {
/* Get a number of characters from a given position of a string */ /* Get a number of characters from a given position of a string */
int result = MB_FUNC_OK; int result = MB_FUNC_OK;
@ -7194,6 +7187,43 @@ _exit:
return result; return result;
} }
int _std_len(mb_interpreter_t* s, void** l) {
/* Get the length of a string or an array */
int result = MB_FUNC_OK;
_ls_node_t* ast = 0;
mb_value_t arg;
_array_t* arr = 0;
mb_assert(s && l);
ast = (_ls_node_t*)(*l);
mb_check(mb_attempt_open_bracket(s, l));
mb_check(mb_pop_value(s, l, &arg));
mb_check(mb_attempt_close_bracket(s, l));
switch(arg.type) {
case MB_DT_STRING:
mb_check(mb_push_int(s, l, (int_t)strlen(arg.value.string)));
break;
case MB_DT_ARRAY:
arr = (_array_t*)arg.value.array;
mb_check(mb_push_int(s, l, (int_t)arr->count));
break;
default:
_handle_error_on_obj(s, SE_RN_NOT_SUPPORTED, 0, DON(ast), MB_FUNC_ERR, _exit, result);
break;
}
_exit:
return result;
}
int _std_print(mb_interpreter_t* s, void** l) { int _std_print(mb_interpreter_t* s, void** l) {
/* PRINT statement */ /* PRINT statement */
int result = MB_FUNC_OK; int result = MB_FUNC_OK;

Binary file not shown.

Binary file not shown.

View File

@ -36,8 +36,8 @@
IDI_ICON_MAIN ICON "icon.ico" IDI_ICON_MAIN ICON "icon.ico"
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,1,72,0 FILEVERSION 1,1,73,0
PRODUCTVERSION 1,1,72,0 PRODUCTVERSION 1,1,73,0
FILEFLAGSMASK 0x17L FILEFLAGSMASK 0x17L
# ifdef _DEBUG # ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -55,13 +55,13 @@
VALUE "Comments", "MY-BASIC" VALUE "Comments", "MY-BASIC"
VALUE "CompanyName", "Wang Renxin" VALUE "CompanyName", "Wang Renxin"
VALUE "FileDescription", "MY-BASIC Interpreter for Windows" VALUE "FileDescription", "MY-BASIC Interpreter for Windows"
VALUE "FileVersion", "1, 1, 72, 0" VALUE "FileVersion", "1, 1, 73, 0"
VALUE "InternalName", "my_basic" VALUE "InternalName", "my_basic"
VALUE "LegalCopyright", "Copyright (C) 2011 - 2015 Wang Renxin" VALUE "LegalCopyright", "Copyright (C) 2011 - 2015 Wang 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, 1, 72, 0" VALUE "ProductVersion", "1, 1, 73, 0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -40,6 +40,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdarg.h>
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(disable : 4127) # pragma warning(disable : 4127)
@ -84,6 +85,17 @@ static struct mb_interpreter_t* bas = 0;
/* ========================================================} */ /* ========================================================} */
/*
** {========================================================
** Common
*/
#ifndef _printf
# define _printf printf
#endif /* _printf */
/* ========================================================} */
/* /*
** {======================================================== ** {========================================================
** Memory manipulation ** Memory manipulation
@ -426,18 +438,18 @@ static void _list_program(const char* sn, const char* cn) {
if(lsn == 0 && lcn == 0) { if(lsn == 0 && lcn == 0) {
long i = 0; long i = 0;
for(i = 0; i < c->count; ++i) { for(i = 0; i < c->count; ++i) {
printf("%ld]%s", i + 1, c->lines[i]); _printf("%ld]%s", i + 1, c->lines[i]);
} }
} else { } else {
long i = 0; long i = 0;
long e = 0; long e = 0;
if(lsn < 1 || lsn > c->count) { if(lsn < 1 || lsn > c->count) {
printf("Line number %ld out of bound.\n", lsn); _printf("Line number %ld out of bound.\n", lsn);
return; return;
} }
if(lcn < 0) { if(lcn < 0) {
printf("Invalid line count %ld.\n", lcn); _printf("Invalid line count %ld.\n", lcn);
return; return;
} }
@ -447,7 +459,7 @@ static void _list_program(const char* sn, const char* cn) {
if(i >= c->count) if(i >= c->count)
break; break;
printf("%ld]%s\n", i + 1, c->lines[i]); _printf("%ld]%s\n", i + 1, c->lines[i]);
} }
} }
} }
@ -461,13 +473,13 @@ static void _edit_program(const char* no) {
lno = atoi(no); lno = atoi(no);
if(lno < 1 || lno > c->count) { if(lno < 1 || lno > c->count) {
printf("Line number %ld out of bound.\n", lno); _printf("Line number %ld out of bound.\n", lno);
return; return;
} }
--lno; --lno;
memset(line, 0, _MAX_LINE_LENGTH); memset(line, 0, _MAX_LINE_LENGTH);
printf("%ld]", lno + 1); _printf("%ld]", lno + 1);
mb_gets(line, _MAX_LINE_LENGTH); mb_gets(line, _MAX_LINE_LENGTH);
l = (int)strlen(line); l = (int)strlen(line);
c->lines[lno] = (char*)realloc(c->lines[lno], l + 2); c->lines[lno] = (char*)realloc(c->lines[lno], l + 2);
@ -485,13 +497,13 @@ static void _insert_program(const char* no) {
lno = atoi(no); lno = atoi(no);
if(lno < 1 || lno > c->count) { if(lno < 1 || lno > c->count) {
printf("Line number %ld out of bound.\n", lno); _printf("Line number %ld out of bound.\n", lno);
return; return;
} }
--lno; --lno;
memset(line, 0, _MAX_LINE_LENGTH); memset(line, 0, _MAX_LINE_LENGTH);
printf("%ld]", lno + 1); _printf("%ld]", lno + 1);
mb_gets(line, _MAX_LINE_LENGTH); mb_gets(line, _MAX_LINE_LENGTH);
if(c->count + 1 == c->size) { if(c->count + 1 == c->size) {
c->size += _LINE_INC_STEP; c->size += _LINE_INC_STEP;
@ -512,7 +524,7 @@ static void _alter_program(const char* no) {
lno = atoi(no); lno = atoi(no);
if(lno < 1 || lno > c->count) { if(lno < 1 || lno > c->count) {
printf("Line number %ld out of bound.\n", lno); _printf("Line number %ld out of bound.\n", lno);
return; return;
} }
@ -530,24 +542,24 @@ static void _load_program(const char* path) {
_set_code(c, txt); _set_code(c, txt);
free(txt); free(txt);
if(c->count == 1) { if(c->count == 1) {
printf("Load done. %d line loaded.\n", c->count); _printf("Load done. %d line loaded.\n", c->count);
} else { } else {
printf("Load done. %d lines loaded.\n", c->count); _printf("Load done. %d lines loaded.\n", c->count);
} }
} else { } else {
printf("Cannot load file \"%s\".\n", path); _printf("Cannot load file \"%s\".\n", path);
} }
} }
static void _save_program(const char* path) { static void _save_program(const char* path) {
char* txt = _get_code(c); char* txt = _get_code(c);
if(!_save_file(path, txt)) { if(!_save_file(path, txt)) {
printf("Cannot save file \"%s\".\n", path); _printf("Cannot save file \"%s\".\n", path);
} else { } else {
if(c->count == 1) { if(c->count == 1) {
printf("Save done. %d line saved.\n", c->count); _printf("Save done. %d line saved.\n", c->count);
} else { } else {
printf("Save done. %d lines saved.\n", c->count); _printf("Save done. %d lines saved.\n", c->count);
} }
} }
free(txt); free(txt);
@ -555,41 +567,41 @@ static void _save_program(const char* path) {
static void _kill_program(const char* path) { static void _kill_program(const char* path) {
if(!unlink(path)) { if(!unlink(path)) {
printf("Delete file \"%s\" successfully.\n", path); _printf("Delete file \"%s\" successfully.\n", path);
} else { } else {
printf("Delete file \"%s\" failed.\n", path); _printf("Delete file \"%s\" failed.\n", path);
} }
} }
static void _show_tip(void) { static void _show_tip(void) {
printf("MY-BASIC Interpreter Shell - %s.\n", mb_ver_string()); _printf("MY-BASIC Interpreter Shell - %s.\n", mb_ver_string());
printf("Copyright (C) 2011 - 2015 Wang Renxin. All Rights Reserved.\n"); _printf("Copyright (C) 2011 - 2015 Wang Renxin. All Rights Reserved.\n");
printf("For more information, see https://github.com/paladin-t/my_basic/.\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"); _printf("Input HELP and hint enter to view help information.\n");
} }
static void _show_help(void) { static void _show_help(void) {
printf("Parameters:\n"); _printf("Parameters:\n");
printf(" %s - Start interactive mode without arguments.\n", _BIN_FILE_NAME); _printf(" %s - Start interactive mode without arguments.\n", _BIN_FILE_NAME);
printf(" %s *.* - Load and run a file.\n", _BIN_FILE_NAME); _printf(" %s *.* - Load and run a file.\n", _BIN_FILE_NAME);
printf(" %s -e \"expr\" - Evaluate an expression directly.\n", _BIN_FILE_NAME); _printf(" %s -e \"expr\" - Evaluate an expression directly.\n", _BIN_FILE_NAME);
printf("Interactive commands:\n"); _printf("Interactive commands:\n");
printf(" CLS - Clear screen\n"); _printf(" CLS - Clear screen\n");
printf(" NEW - Clear current program\n"); _printf(" NEW - Clear current program\n");
printf(" RUN - Run current program\n"); _printf(" RUN - Run current program\n");
printf(" BYE - Quit interpreter\n"); _printf(" BYE - Quit interpreter\n");
printf(" LIST - List current program\n"); _printf(" LIST - List current program\n");
printf(" Usage: LIST [l [n]], l is start line number, n is line count\n"); _printf(" Usage: LIST [l [n]], l is start line number, n is line count\n");
printf(" EDIT - Edit (modify/insert/remove) a line in current program\n"); _printf(" EDIT - Edit (modify/insert/remove) a line in current program\n");
printf(" Usage: EDIT n, n is line number\n"); _printf(" Usage: EDIT n, n is line number\n");
printf(" EDIT -I n, insert a line before a given line, n is line number\n"); _printf(" EDIT -I n, insert a line before a given line, n is line number\n");
printf(" EDIT -R n, remove a line, n is line number\n"); _printf(" EDIT -R n, remove a line, n is line number\n");
printf(" LOAD - Load a file as current program\n"); _printf(" LOAD - Load a file as current program\n");
printf(" Usage: LOAD *.*\n"); _printf(" Usage: LOAD *.*\n");
printf(" SAVE - Save current program to a file\n"); _printf(" SAVE - Save current program to a file\n");
printf(" Usage: SAVE *.*\n"); _printf(" Usage: SAVE *.*\n");
printf(" KILL - Delete a file\n"); _printf(" KILL - Delete a file\n");
printf(" Usage: KILL *.*\n"); _printf(" Usage: KILL *.*\n");
} }
static int _do_line(void) { static int _do_line(void) {
@ -600,7 +612,7 @@ static int _do_line(void) {
mb_assert(bas); mb_assert(bas);
memset(line, 0, _MAX_LINE_LENGTH); memset(line, 0, _MAX_LINE_LENGTH);
printf("]"); _printf("]");
mb_gets(line, _MAX_LINE_LENGTH); mb_gets(line, _MAX_LINE_LENGTH);
memcpy(dup, line, _MAX_LINE_LENGTH); memcpy(dup, line, _MAX_LINE_LENGTH);
@ -621,7 +633,7 @@ static int _do_line(void) {
for(i = 0; i < c->count; ++i) for(i = 0; i < c->count; ++i)
mb_load_string(bas, c->lines[i]); mb_load_string(bas, c->lines[i]);
result = mb_run(bas); result = mb_run(bas);
printf("\n"); _printf("\n");
} else if(_str_eq(line, "BYE")) { } else if(_str_eq(line, "BYE")) {
result = MB_FUNC_BYE; result = MB_FUNC_BYE;
} else if(_str_eq(line, "LIST")) { } else if(_str_eq(line, "LIST")) {
@ -667,7 +679,7 @@ static int _do_line(void) {
#define _CHECK_ARG(__c, __i, __e) \ #define _CHECK_ARG(__c, __i, __e) \
do { \ do { \
if(__c <= __i + 1) { \ if(__c <= __i + 1) { \
printf(__e); \ _printf(__e); \
return; \ return; \
} \ } \
} while(0) } while(0)
@ -676,7 +688,7 @@ static void _run_file(char* path) {
if(mb_load_file(bas, path) == MB_FUNC_OK) { if(mb_load_file(bas, path) == MB_FUNC_OK) {
mb_run(bas); mb_run(bas);
} else { } else {
printf("Invalid file or error code.\n"); _printf("Invalid file or error code.\n");
} }
} }
@ -690,7 +702,7 @@ static void _evaluate_expression(char* p) {
const char* const print = "PRINT "; const char* const print = "PRINT ";
if(!p) { if(!p) {
printf("Invalid expression.\n"); _printf("Invalid expression.\n");
return; return;
} }
@ -713,7 +725,7 @@ static void _evaluate_expression(char* p) {
if(mb_load_string(bas, p) == MB_FUNC_OK) { if(mb_load_string(bas, p) == MB_FUNC_OK) {
mb_run(bas); mb_run(bas);
} else { } else {
printf("Invalid expression.\n"); _printf("Invalid expression.\n");
} }
if(a) { if(a) {
free(e); free(e);
@ -732,7 +744,7 @@ static void _process_parameters(int argc, char* argv[]) {
_CHECK_ARG(argc, i, "-e: Expression expected.\n"); _CHECK_ARG(argc, i, "-e: Expression expected.\n");
p = argv[++i]; p = argv[++i];
} else { } else {
printf("Unknown argument: %s.\n", argv[i]); _printf("Unknown argument: %s.\n", argv[i]);
} }
} else { } else {
p = argv[i]; p = argv[i];
@ -790,7 +802,7 @@ static void _on_error(struct mb_interpreter_t* s, mb_error_e e, char* m, char* f
mb_unrefvar(f); mb_unrefvar(f);
mb_unrefvar(p); mb_unrefvar(p);
if(SE_NO_ERR != e) { if(SE_NO_ERR != e) {
printf("Error:\n [LINE] %d, [COL] %d,\n [CODE] %d, [MESSAGE] %s, [ABORT CODE] %d.\n", 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);
} }
} }
@ -862,7 +874,7 @@ int main(int argc, char* argv[]) {
} else if(argc >= 2) { } else if(argc >= 2) {
_process_parameters(argc, argv); _process_parameters(argc, argv);
} else { } else {
printf("Unknown arguments.\n"); _printf("Unknown arguments.\n");
_show_tip(); _show_tip();
} }