+added sub routine type insurance; *prompted more friendly dummy function message; *polished code and document

This commit is contained in:
tony 2015-09-02 21:29:29 +08:00
parent 1c1771280c
commit 789cc76eb3
9 changed files with 271 additions and 207 deletions

View File

@ -1,3 +1,8 @@
Sep. 2 2015
Added sub routine type insurance
Prompted more friendly dummy function message
Polished code and document
Sep. 1 2015
Added support for user customized routine by DEF/ENDDEF

Binary file not shown.

View File

@ -4,28 +4,31 @@ Copyright (C) 2011 - 2015 [Wang Renxin](https://twitter.com/wangrenxin)
[LinkedIn](https://cn.linkedin.com/pub/wang-renxin/43/494/20)
Why are existing script interpreters so complex? Why is it so difficult to integrate with them? Why not try MY-BASIC today!
## Introduction
MY-BASIC is a tiny cross-platform easy extendable BASIC interpreter written in pure C with about 7000 lines of source code. Its grammar is similar to structured BASIC in early era, but without line number. It is aimed to be either an embeddable scripting language or a standalone interpreter. The core is pretty light; all in a C source file and an associated header file. You can combine MY-BASIC with an existing C, C++, Objective-C, etc. project easily, scripting driven can make your projects more powerful, elegant and neat.
MY-BASIC is a tiny cross-platform easy extendable BASIC interpreter written in pure C with about 7000 lines of source code. Its grammar is similar to structured BASIC. It is aimed to be either an embeddable scripting language or a standalone interpreter. The core is pretty light; all in a C source file and an associated header file. You can combine MY-BASIC with an existing C, C++, Objective-C, etc. project easily, scripting driven can make your projects more powerful, elegant and neat.
## Main features
* It is free
* Written in clean ANSI C, source code portable
* Most retro BASIC like syntax, without line numbers
* With most common BASIC syntax
* Small (within memory usage less than 128KB) and fast
* Case-insensitive tokenization
* Integer, float point, string, boolean, user defined data types with array support
* `IF-THEN-ELSEIF-ELSE-ENDIF` support
* `FOR-TO-STEP-NEXT/WHILE-WEND/DO-UNTIL` support
* Integer, float point, string, boolean, user defined data types with array support, etc.
* Structured `IF-THEN-ELSEIF-ELSE-ENDIF` support
* Structured `FOR-TO-STEP-NEXT/WHILE-WEND/DO-UNTIL` support
* Structured user costomized sub routine definition by `DEF/ENDDEF` support
* `GOTO/GOSUB-RETURN` support
* Standard numeric functions
* Standard string functions
* Debug APIs
* High expansibility, easy to use APIs, easy to write customized scripting interfaces
* It's able to use it as a standalone interpreter, or integrate it with existing C, C++, Objective-C, etc. projects
* It's able to learn how to build an interpreter from scratch from it
* It's able to build your own dialect based on it
* It's able to learn how to build an interpreter from scratch from MY-BASIC
* It's able to build your own dialect based on MY-BASIC
* More features/modules under developing
## [Interpreter workflow diagram](https://github.com/paladin-t/my_basic/wiki/Interpreter-workflow-diagram)

File diff suppressed because it is too large Load Diff

View File

@ -215,7 +215,9 @@ typedef enum mb_error_e {
SE_RN_MOD_BY_ZERO,
SE_RN_INVALID_EXPRESSION,
SE_RN_OUT_OF_MEMORY,
SE_RN_WRONG_FUNCTION_REACHED,
SE_RN_DONT_SUSPEND_IN_A_ROUTINE,
SE_RN_DONT_MIX_INSTRUCTIONAL_AND_STRUCTURED,
SE_RN_ROUTINE_EXPECTED,
/** Extended abort */
SE_EA_EXTENDED_ABORT,
@ -249,7 +251,7 @@ typedef unsigned short mb_mem_tag_t;
typedef int (* mb_func_t)(struct mb_interpreter_t*, void**);
typedef void (* mb_debug_stepped_handler_t)(struct mb_interpreter_t*, int, unsigned short, unsigned short);
typedef void (* mb_error_handler_t)(struct mb_interpreter_t*, enum mb_error_e, char*, int, unsigned short, unsigned short, int);
typedef void (* mb_error_handler_t)(struct mb_interpreter_t*, enum mb_error_e, char*, char*, int, unsigned short, unsigned short, int);
typedef int (* mb_print_func_t)(const char*, ...);
typedef int (* mb_input_func_t)(char*, int);
typedef char* (* mb_memory_allocate_func_t)(unsigned s);

Binary file not shown.

Binary file not shown.

View File

@ -36,8 +36,8 @@
IDI_ICON_MAIN ICON "icon.ico"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,1,65,0
PRODUCTVERSION 1,1,65,0
FILEVERSION 1,1,66,0
PRODUCTVERSION 1,1,66,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, 65, 0"
VALUE "FileVersion", "1, 1, 66, 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, 65, 0"
VALUE "ProductVersion", "1, 1, 66, 0"
END
END
BLOCK "VarFileInfo"

View File

@ -43,6 +43,7 @@
#ifdef _MSC_VER
# pragma warning(disable : 4127)
# pragma warning(disable : 4706)
# pragma warning(disable : 4996)
#endif /* _MSC_VER */
@ -265,7 +266,9 @@ static _code_line_t* _create_code(void) {
static void _destroy_code(_code_line_t* code) {
int i = 0;
mb_assert(code);
for(i = 0; i < code->count; ++i) {
free(code->lines[i]);
}
@ -275,7 +278,9 @@ static void _destroy_code(_code_line_t* code) {
static void _clear_code(_code_line_t* code) {
int i = 0;
mb_assert(code);
for(i = 0; i < code->count; ++i) {
free(code->lines[i]);
}
@ -285,7 +290,9 @@ static void _clear_code(_code_line_t* code) {
static void _append_line(_code_line_t* code, char* txt) {
int l = 0;
char* buf = 0;
mb_assert(code && txt);
if(code->count + 1 == code->size) {
code->size += _LINE_INC_STEP;
code->lines = (char**)realloc(code->lines, sizeof(char*) * code->size);
@ -301,7 +308,9 @@ static void _append_line(_code_line_t* code, char* txt) {
static char* _get_code(_code_line_t* code) {
char* result = 0;
int i = 0;
mb_assert(code);
result = (char*)malloc((_MAX_LINE_LENGTH + 2) * code->count + 1);
result[0] = '\0';
for(i = 0; i < code->count; ++i) {
@ -316,7 +325,9 @@ static char* _get_code(_code_line_t* code) {
static void _set_code(_code_line_t* code, char* txt) {
char* cursor = 0;
char _c = '\0';
mb_assert(code);
if(!txt)
return;
@ -340,7 +351,9 @@ static char* _load_file(const char* path) {
char* result = 0;
long curpos = 0;
long l = 0;
mb_assert(path);
fp = fopen(path, "rb");
if(fp) {
curpos = ftell(fp);
@ -359,7 +372,9 @@ static char* _load_file(const char* path) {
static int _save_file(const char* path, const char* txt) {
FILE* fp = 0;
mb_assert(path && txt);
fp = fopen(path, "wb");
if(fp) {
fwrite(txt, sizeof(char), strlen(txt), fp);
@ -395,7 +410,9 @@ static int _new_program(void) {
static void _list_program(const char* sn, const char* cn) {
long lsn = 0;
long lcn = 0;
mb_assert(sn && cn);
lsn = atoi(sn);
lcn = atoi(cn);
if(lsn == 0 && lcn == 0) {
@ -430,7 +447,9 @@ static void _list_program(const char* sn, const char* cn) {
static void _edit_program(const char* no) {
char line[_MAX_LINE_LENGTH];
long lno = 0;
mb_assert(no);
lno = atoi(no);
if(lno < 1 || lno > c->count) {
printf("Line number %ld out of bound.\n", lno);
@ -449,7 +468,9 @@ static void _insert_program(const char* no) {
char line[_MAX_LINE_LENGTH];
long lno = 0;
int i = 0;
mb_assert(no);
lno = atoi(no);
if(lno < 1 || lno > c->count) {
printf("Line number %ld out of bound.\n", lno);
@ -474,7 +495,9 @@ static void _insert_program(const char* no) {
static void _alter_program(const char* no) {
long lno = 0;
long i = 0;
mb_assert(no);
lno = atoi(no);
if(lno < 1 || lno > c->count) {
printf("Line number %ld out of bound.\n", lno);
@ -652,8 +675,9 @@ static void _on_stepped(struct mb_interpreter_t* s, int p, unsigned short row, u
mb_unrefvar(col);
}
static void _on_error(struct mb_interpreter_t* s, mb_error_e e, char* m, int p, unsigned short row, unsigned short col, int abort_code) {
static void _on_error(struct mb_interpreter_t* s, mb_error_e e, char* m, char* f, int p, unsigned short row, unsigned short col, int abort_code) {
mb_unrefvar(s);
mb_unrefvar(f);
mb_unrefvar(p);
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);