*improved stability by preventing assigning builtin boolean. *polished error constants.
This commit is contained in:
parent
2fd9519b09
commit
b1f2ffa538
3
HISTORY
3
HISTORY
@ -1,3 +1,6 @@
|
|||||||
|
May. 20 2017
|
||||||
|
Improved stability by preventing assigning builtin boolean
|
||||||
|
|
||||||
May. 18 2017
|
May. 18 2017
|
||||||
Fixed some memory potential leak when popped unexpected type of argument
|
Fixed some memory potential leak when popped unexpected type of argument
|
||||||
|
|
||||||
|
Binary file not shown.
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
MY-BASIC is a lightweight cross-platform easy extendable BASIC interpreter written in pure C with less than twenty thousand lines of source code. MY-BASIC is a dynamic typed programming language. It supports structured grammar, and implements a style of OOP called [prototype-based programming](https://en.wikipedia.org/wiki/Prototype-based_programming) paradigm, furthermore it offers a functional programming ability with [lambda abstraction](https://en.wikipedia.org/wiki/Anonymous_function). It is aimed to be either an embeddable scripting language or a standalone interpreter. The core is very lightweight; all in a C source file and an associated header file; simpleness of source file layout and tightness dependency make it extraordinarily tough. Anyone even C programming newbies could learn how to use it and add new scripting interfaces in five minutes. It's able to easily combine MY-BASIC with an existing project in C, C++, Java, Objective-C, Swift, C# and many other languages. Script driven can make your projects more powerful, elegant and neat. It's also able to learn how to build an interpreter from scratch with MY-BASIC, or build your own interpreter easily based on it.
|
MY-BASIC is a lightweight cross-platform easy extendable BASIC interpreter written in pure C with about twenty thousand lines of source code. MY-BASIC is a dynamic typed programming language. It supports structured grammar, and implements a style of OOP called [prototype-based programming](https://en.wikipedia.org/wiki/Prototype-based_programming) paradigm, furthermore it offers a functional programming ability with [lambda abstraction](https://en.wikipedia.org/wiki/Anonymous_function). It is aimed to be either an embeddable scripting language or a standalone interpreter. The core is very lightweight; all in a C source file and an associated header file; simpleness of source file layout and tightness dependency make it extraordinarily tough. Anyone even C programming newbies could learn how to use it and add new scripting interfaces in five minutes. It's able to easily combine MY-BASIC with an existing project in C, C++, Java, Objective-C, Swift, C# and many other languages. Script driven can make your projects more powerful, elegant and neat. It's also possible to learn how to build an interpreter from scratch with MY-BASIC, or build your own dialect easily based on it.
|
||||||
|
|
||||||
"MY-" in the name could be understood literally as "My" or "Make Your", it's up to you.
|
"MY-" in the name could be understood literally as "My" or "Make Your", it's up to you.
|
||||||
|
|
||||||
|
@ -233,7 +233,6 @@ typedef struct _ht_node_t {
|
|||||||
MBCONST static const char* const _ERR_DESC[] = {
|
MBCONST static const char* const _ERR_DESC[] = {
|
||||||
"No error",
|
"No error",
|
||||||
/** Common */
|
/** Common */
|
||||||
"Open MY-BASIC failed",
|
|
||||||
"A function with the same name already exists",
|
"A function with the same name already exists",
|
||||||
"A function with the name does not exists",
|
"A function with the name does not exists",
|
||||||
"Not supported",
|
"Not supported",
|
||||||
@ -245,36 +244,40 @@ MBCONST static const char* const _ERR_DESC[] = {
|
|||||||
"Empty program",
|
"Empty program",
|
||||||
"Program too long",
|
"Program too long",
|
||||||
"Syntax error",
|
"Syntax error",
|
||||||
|
"Out of memory",
|
||||||
"Invalid data type",
|
"Invalid data type",
|
||||||
"Type does not match",
|
"Type does not match",
|
||||||
"Number overflow",
|
"Number overflow",
|
||||||
"Invalid string",
|
"Invalid string",
|
||||||
|
"Number expected",
|
||||||
|
"Integer expected",
|
||||||
|
"String expected",
|
||||||
"Index out of bound",
|
"Index out of bound",
|
||||||
"Cannot find with given index",
|
"Cannot find with given index",
|
||||||
"Illegal bound",
|
"Illegal bound",
|
||||||
"Too many dimensions",
|
"Too many dimensions",
|
||||||
"Operation failed",
|
|
||||||
"Invalid operation usage",
|
|
||||||
"Dimension count out of bound",
|
"Dimension count out of bound",
|
||||||
"Rank out of bound",
|
"Rank out of bound",
|
||||||
"Complex array required",
|
"Complex array required",
|
||||||
|
"Array identifier expected",
|
||||||
|
"Array subscript expected",
|
||||||
|
"Variable expected",
|
||||||
|
"Variable or array expected",
|
||||||
|
"Invalid identifier usage",
|
||||||
|
"Duplicate identifier",
|
||||||
"Label does not exist",
|
"Label does not exist",
|
||||||
"No return point",
|
"No return point",
|
||||||
"Colon expected",
|
"Colon expected",
|
||||||
"Comma expected",
|
"Comma expected",
|
||||||
"Comma or semicolon expected",
|
"Comma or semicolon expected",
|
||||||
"Array identifier expected",
|
|
||||||
"Open bracket expected",
|
"Open bracket expected",
|
||||||
"Close bracket expected",
|
"Close bracket expected",
|
||||||
"Array subscript expected",
|
|
||||||
"Nested too deep",
|
"Nested too deep",
|
||||||
"Incomplete structure",
|
"Incomplete structure",
|
||||||
"Function expected",
|
"Operation failed",
|
||||||
"Variable or array identifier expected",
|
"Operator expected",
|
||||||
|
"Invalid operation usage",
|
||||||
"Assign operator expected",
|
"Assign operator expected",
|
||||||
"String expected",
|
|
||||||
"Number expected",
|
|
||||||
"Integer expected",
|
|
||||||
"ELSE statement expected",
|
"ELSE statement expected",
|
||||||
"ENDIF statement expected",
|
"ENDIF statement expected",
|
||||||
"TO statement expected",
|
"TO statement expected",
|
||||||
@ -282,15 +285,10 @@ MBCONST static const char* const _ERR_DESC[] = {
|
|||||||
"UNTIL statement expected",
|
"UNTIL statement expected",
|
||||||
"Loop variable expected",
|
"Loop variable expected",
|
||||||
"Jump label expected",
|
"Jump label expected",
|
||||||
"Variable expected",
|
|
||||||
"Invalid identifier usage",
|
|
||||||
"Duplicate identifier",
|
|
||||||
"Operator expected",
|
|
||||||
"Calculation error",
|
"Calculation error",
|
||||||
|
"Invalid expression",
|
||||||
"Divide by zero",
|
"Divide by zero",
|
||||||
"MOD by zero",
|
"MOD by zero",
|
||||||
"Invalid expression",
|
|
||||||
"Out of memory",
|
|
||||||
"Module not match",
|
"Module not match",
|
||||||
"Wrong function reached",
|
"Wrong function reached",
|
||||||
"Do not suspend in a routine",
|
"Do not suspend in a routine",
|
||||||
@ -308,13 +306,12 @@ MBCONST static const char* const _ERR_DESC[] = {
|
|||||||
"HASH and COMPARE must come together",
|
"HASH and COMPARE must come together",
|
||||||
"Cannot change ME",
|
"Cannot change ME",
|
||||||
"Invalid lambda",
|
"Invalid lambda",
|
||||||
|
"Empty collection",
|
||||||
"List expected",
|
"List expected",
|
||||||
"Collection expected",
|
"Collection expected",
|
||||||
"Iterator expected",
|
|
||||||
"Collection or iterator expected",
|
|
||||||
"Collection or iterator or class expected",
|
"Collection or iterator or class expected",
|
||||||
|
"Iterator expected",
|
||||||
"Invalid iterator",
|
"Invalid iterator",
|
||||||
"Empty collection",
|
|
||||||
"Referenced usertype expected",
|
"Referenced usertype expected",
|
||||||
"Referenced type expected",
|
"Referenced type expected",
|
||||||
"Reference count overflow",
|
"Reference count overflow",
|
||||||
@ -12399,7 +12396,7 @@ int mb_init_array(struct mb_interpreter_t* s, void** l, mb_data_e t, int* d, int
|
|||||||
} else if(t == MB_DT_STRING) {
|
} else if(t == MB_DT_STRING) {
|
||||||
type = _DT_STRING;
|
type = _DT_STRING;
|
||||||
} else {
|
} else {
|
||||||
_handle_error_on_obj(s, SE_RN_NEED_COMPLEX_ARRAY, s->source_file, DON2(l), MB_FUNC_ERR, _exit, result);
|
_handle_error_on_obj(s, SE_RN_COMPLEX_ARRAY_REQUIRED, s->source_file, DON2(l), MB_FUNC_ERR, _exit, result);
|
||||||
}
|
}
|
||||||
#else /* MB_SIMPLE_ARRAY */
|
#else /* MB_SIMPLE_ARRAY */
|
||||||
type = _DT_REAL;
|
type = _DT_REAL;
|
||||||
@ -14341,6 +14338,9 @@ static int _core_let(mb_interpreter_t* s, void** l) {
|
|||||||
evar = obj->data.variable;
|
evar = obj->data.variable;
|
||||||
var = _search_var_in_scope_chain(s, obj->data.variable);
|
var = _search_var_in_scope_chain(s, obj->data.variable);
|
||||||
if(var == evar) evar = 0;
|
if(var == evar) evar = 0;
|
||||||
|
if(var == _OBJ_BOOL_TRUE->data.variable || var == _OBJ_BOOL_FALSE->data.variable) {
|
||||||
|
_handle_error_on_obj(s, SE_RN_INVALID_ID_USAGE, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_handle_error_on_obj(s, SE_RN_VAR_OR_ARRAY_EXPECTED, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
_handle_error_on_obj(s, SE_RN_VAR_OR_ARRAY_EXPECTED, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
@ -16960,7 +16960,7 @@ static int _std_set(mb_interpreter_t* s, void** l) {
|
|||||||
_create_internal_object_from_public_value(&nv, &nobj);
|
_create_internal_object_from_public_value(&nv, &nobj);
|
||||||
fobj->data.variable->data = nobj;
|
fobj->data.variable->data = nobj;
|
||||||
} else {
|
} else {
|
||||||
_handle_error_on_obj(s, SE_RN_VARIABLE_EXPECTED, s->source_file, DON2(l), MB_FUNC_ERR, _exit, result);
|
_handle_error_on_obj(s, SE_RN_VAR_EXPECTED, s->source_file, DON2(l), MB_FUNC_ERR, _exit, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -17188,7 +17188,7 @@ static int _std_input(mb_interpreter_t* s, void** l) {
|
|||||||
obj = (_object_t*)ast->data;
|
obj = (_object_t*)ast->data;
|
||||||
}
|
}
|
||||||
if(obj->type != _DT_VAR) {
|
if(obj->type != _DT_VAR) {
|
||||||
_handle_error_on_obj(s, SE_RN_VARIABLE_EXPECTED, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
_handle_error_on_obj(s, SE_RN_VAR_EXPECTED, s->source_file, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||||
}
|
}
|
||||||
if(obj->data.variable->data->type == _DT_INT || obj->data.variable->data->type == _DT_REAL) {
|
if(obj->data.variable->data->type == _DT_INT || obj->data.variable->data->type == _DT_REAL) {
|
||||||
_get_inputer(s)(line, sizeof(line));
|
_get_inputer(s)(line, sizeof(line));
|
||||||
|
@ -384,7 +384,6 @@ struct mb_interpreter_t;
|
|||||||
typedef enum mb_error_e {
|
typedef enum mb_error_e {
|
||||||
SE_NO_ERR = 0,
|
SE_NO_ERR = 0,
|
||||||
/** Common */
|
/** Common */
|
||||||
SE_CM_OPEN_MB_FAILED,
|
|
||||||
SE_CM_FUNC_EXISTS,
|
SE_CM_FUNC_EXISTS,
|
||||||
SE_CM_FUNC_NOT_EXISTS,
|
SE_CM_FUNC_NOT_EXISTS,
|
||||||
SE_CM_NOT_SUPPORTED,
|
SE_CM_NOT_SUPPORTED,
|
||||||
@ -396,36 +395,40 @@ typedef enum mb_error_e {
|
|||||||
SE_RN_EMPTY_PROGRAM,
|
SE_RN_EMPTY_PROGRAM,
|
||||||
SE_RN_PROGRAM_TOO_LONG,
|
SE_RN_PROGRAM_TOO_LONG,
|
||||||
SE_RN_SYNTAX_ERROR,
|
SE_RN_SYNTAX_ERROR,
|
||||||
|
SE_RN_OUT_OF_MEMORY,
|
||||||
SE_RN_INVALID_DATA_TYPE,
|
SE_RN_INVALID_DATA_TYPE,
|
||||||
SE_RN_TYPE_NOT_MATCH,
|
SE_RN_TYPE_NOT_MATCH,
|
||||||
SE_RN_NUMBER_OVERFLOW,
|
SE_RN_NUMBER_OVERFLOW,
|
||||||
SE_RN_INVALID_STRING,
|
SE_RN_INVALID_STRING,
|
||||||
|
SE_RN_NUMBER_EXPECTED,
|
||||||
|
SE_RN_INTEGER_EXPECTED,
|
||||||
|
SE_RN_STRING_EXPECTED,
|
||||||
SE_RN_INDEX_OUT_OF_BOUND,
|
SE_RN_INDEX_OUT_OF_BOUND,
|
||||||
SE_RN_CANNOT_FIND_WITH_GIVEN_INDEX,
|
SE_RN_CANNOT_FIND_WITH_GIVEN_INDEX,
|
||||||
SE_RN_ILLEGAL_BOUND,
|
SE_RN_ILLEGAL_BOUND,
|
||||||
SE_RN_TOO_MANY_DIMENSIONS,
|
SE_RN_TOO_MANY_DIMENSIONS,
|
||||||
SE_RN_OPERATION_FAILED,
|
|
||||||
SE_RN_INVALID_OPERATION_USAGE,
|
|
||||||
SE_RN_DIMENSION_COUNT_OUT_OF_BOUND,
|
SE_RN_DIMENSION_COUNT_OUT_OF_BOUND,
|
||||||
SE_RN_RANK_OUT_OF_BOUND,
|
SE_RN_RANK_OUT_OF_BOUND,
|
||||||
SE_RN_NEED_COMPLEX_ARRAY,
|
SE_RN_COMPLEX_ARRAY_REQUIRED,
|
||||||
|
SE_RN_ARRAY_IDENTIFIER_EXPECTED,
|
||||||
|
SE_RN_ARRAY_SUBSCRIPT_EXPECTED,
|
||||||
|
SE_RN_VAR_EXPECTED,
|
||||||
|
SE_RN_VAR_OR_ARRAY_EXPECTED,
|
||||||
|
SE_RN_INVALID_ID_USAGE,
|
||||||
|
SE_RN_DUPLICATE_ID,
|
||||||
SE_RN_LABEL_NOT_EXISTS,
|
SE_RN_LABEL_NOT_EXISTS,
|
||||||
SE_RN_NO_RETURN_POINT,
|
SE_RN_NO_RETURN_POINT,
|
||||||
SE_RN_COLON_EXPECTED,
|
SE_RN_COLON_EXPECTED,
|
||||||
SE_RN_COMMA_EXPECTED,
|
SE_RN_COMMA_EXPECTED,
|
||||||
SE_RN_COMMA_OR_SEMICOLON_EXPECTED,
|
SE_RN_COMMA_OR_SEMICOLON_EXPECTED,
|
||||||
SE_RN_ARRAY_IDENTIFIER_EXPECTED,
|
|
||||||
SE_RN_OPEN_BRACKET_EXPECTED,
|
SE_RN_OPEN_BRACKET_EXPECTED,
|
||||||
SE_RN_CLOSE_BRACKET_EXPECTED,
|
SE_RN_CLOSE_BRACKET_EXPECTED,
|
||||||
SE_RN_ARRAY_SUBSCRIPT_EXPECTED,
|
|
||||||
SE_RN_NESTED_TOO_DEEP,
|
SE_RN_NESTED_TOO_DEEP,
|
||||||
SE_RN_INCOMPLETE_STRUCTURE,
|
SE_RN_INCOMPLETE_STRUCTURE,
|
||||||
SE_RN_FUNCTION_EXPECTED,
|
SE_RN_OPERATION_FAILED,
|
||||||
SE_RN_VAR_OR_ARRAY_EXPECTED,
|
SE_RN_OPERATOR_EXPECTED,
|
||||||
|
SE_RN_INVALID_OPERATION_USAGE,
|
||||||
SE_RN_ASSIGN_OPERATOR_EXPECTED,
|
SE_RN_ASSIGN_OPERATOR_EXPECTED,
|
||||||
SE_RN_STRING_EXPECTED,
|
|
||||||
SE_RN_NUMBER_EXPECTED,
|
|
||||||
SE_RN_INTEGER_EXPECTED,
|
|
||||||
SE_RN_ELSE_EXPECTED,
|
SE_RN_ELSE_EXPECTED,
|
||||||
SE_RN_ENDIF_EXPECTED,
|
SE_RN_ENDIF_EXPECTED,
|
||||||
SE_RN_TO_EXPECTED,
|
SE_RN_TO_EXPECTED,
|
||||||
@ -433,15 +436,10 @@ typedef enum mb_error_e {
|
|||||||
SE_RN_UNTIL_EXPECTED,
|
SE_RN_UNTIL_EXPECTED,
|
||||||
SE_RN_LOOP_VAR_EXPECTED,
|
SE_RN_LOOP_VAR_EXPECTED,
|
||||||
SE_RN_JUMP_LABEL_EXPECTED,
|
SE_RN_JUMP_LABEL_EXPECTED,
|
||||||
SE_RN_VARIABLE_EXPECTED,
|
|
||||||
SE_RN_INVALID_ID_USAGE,
|
|
||||||
SE_RN_DUPLICATE_ID,
|
|
||||||
SE_RN_OPERATOR_EXPECTED,
|
|
||||||
SE_RN_CALCULATION_ERROR,
|
SE_RN_CALCULATION_ERROR,
|
||||||
|
SE_RN_INVALID_EXPRESSION,
|
||||||
SE_RN_DIVIDE_BY_ZERO,
|
SE_RN_DIVIDE_BY_ZERO,
|
||||||
SE_RN_MOD_BY_ZERO,
|
SE_RN_MOD_BY_ZERO,
|
||||||
SE_RN_INVALID_EXPRESSION,
|
|
||||||
SE_RN_OUT_OF_MEMORY,
|
|
||||||
SE_RN_MODULE_NOT_MATCH,
|
SE_RN_MODULE_NOT_MATCH,
|
||||||
SE_RN_WRONG_FUNCTION_REACHED,
|
SE_RN_WRONG_FUNCTION_REACHED,
|
||||||
SE_RN_DO_NOT_SUSPEND_IN_A_ROUTINE,
|
SE_RN_DO_NOT_SUSPEND_IN_A_ROUTINE,
|
||||||
@ -459,13 +457,12 @@ typedef enum mb_error_e {
|
|||||||
SE_RN_HASH_AND_COMPARE_MUST_COME_TOGETHER,
|
SE_RN_HASH_AND_COMPARE_MUST_COME_TOGETHER,
|
||||||
SE_RN_CANNOT_CHANGE_ME,
|
SE_RN_CANNOT_CHANGE_ME,
|
||||||
SE_RN_INVALID_LAMBDA,
|
SE_RN_INVALID_LAMBDA,
|
||||||
|
SE_RN_EMPTY_COLLECTION,
|
||||||
SE_RN_LIST_EXPECTED,
|
SE_RN_LIST_EXPECTED,
|
||||||
SE_RN_COLLECTION_EXPECTED,
|
SE_RN_COLLECTION_EXPECTED,
|
||||||
SE_RN_ITERATOR_EXPECTED,
|
|
||||||
SE_RN_COLLECTION_OR_ITERATOR_EXPECTED,
|
|
||||||
SE_RN_COLLECTION_OR_ITERATOR_OR_CLASS_EXPECTED,
|
SE_RN_COLLECTION_OR_ITERATOR_OR_CLASS_EXPECTED,
|
||||||
|
SE_RN_ITERATOR_EXPECTED,
|
||||||
SE_RN_INVALID_ITERATOR,
|
SE_RN_INVALID_ITERATOR,
|
||||||
SE_RN_EMPTY_COLLECTION,
|
|
||||||
SE_RN_REFERENCED_USERTYPE_EXPECTED,
|
SE_RN_REFERENCED_USERTYPE_EXPECTED,
|
||||||
SE_RN_REFERENCED_TYPE_EXPECTED,
|
SE_RN_REFERENCED_TYPE_EXPECTED,
|
||||||
SE_RN_REFERENCE_COUNT_OVERFLOW,
|
SE_RN_REFERENCE_COUNT_OVERFLOW,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user