+added structures for class development; *updated readme doc; *updated exe icon.
This commit is contained in:
parent
bf9f5ec86c
commit
f6e9f9fbb1
4
HISTORY
4
HISTORY
@ -1,3 +1,7 @@
|
||||
Dec. 4 2015
|
||||
Updated icon
|
||||
Added structures for class development
|
||||
|
||||
Nov. 30 2015
|
||||
Improved stability for sub routine
|
||||
Improved error handling with shell
|
||||
|
40
README.md
40
README.md
@ -2,17 +2,21 @@
|
||||
|
||||
**Copyright (C) 2011 - 2015 [Wang Renxin](https://cn.linkedin.com/pub/wang-renxin/43/494/20). All rights reserved.**
|
||||
|
||||
Why are existing script interpreters so complex? Why is it so difficult to integrate with them? Why not try MY-BASIC today! Scripting should be simple and enjoyable.
|
||||
Why are existing script interpreters so complex? Why is it so difficult to integrate with them? Why not try MY-BASIC today! Script should be simple and enjoyable.
|
||||
|
||||
## Build status
|
||||
|
||||
[](https://travis-ci.org/paladin-t/my_basic)
|
||||
|
||||
## Development status
|
||||
|
||||
* Class support under development
|
||||
|
||||
## Contents
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Main features](#main-features)
|
||||
* [Scripting at a glance](#scripting-at-a-glance)
|
||||
* [Script at a glance](#script-at-a-glance)
|
||||
* [Interpreter workflow diagram](#interpreter-workflow-diagram)
|
||||
* [Installation](#installation)
|
||||
* [Wiki](#wiki)
|
||||
@ -20,22 +24,22 @@ Why are existing script interpreters so complex? Why is it so difficult to integ
|
||||
|
||||
## Introduction
|
||||
|
||||
MY-BASIC is a lightweight cross-platform easy extendable BASIC interpreter written in pure C with about 10,000 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 are able to easily combine MY-BASIC with an existing project in C, C++, Objective-C, etc. Scripting driven can make your projects more powerful, elegant and neat.
|
||||
MY-BASIC is a lightweight cross-platform easy extendable BASIC interpreter written in pure C with about 10,000 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. It's able to easily combine MY-BASIC with an existing project in C, C++, Objective-C, etc. Script driven can make your projects more powerful, elegant and neat.
|
||||
|
||||
## Main features
|
||||
|
||||
* It is totally **free** to use MY-BASIC for individual or commercial purpose under the MIT license
|
||||
* Written in clean **ANSI C**, source code portable
|
||||
* Written in clean **ANSI C**, source code is portable for a dozen of platforms
|
||||
* With most common BASIC syntax
|
||||
* **Lightweight** (within memory usage less than 128KB) and fast
|
||||
* Case-insensitive tokenization
|
||||
* Integer, float point, string, boolean, user defined data types, etc. with array support
|
||||
* Standard numeric functions, and standard string functions
|
||||
* Referenced usertype support
|
||||
* Collection implementation and manipulation functions for **`LIST`** and **`DICT`**
|
||||
* Automatic releasing of referenced objects (list, dictionary, referenced usertype, etc.) benefited from **Reference Counting** and **GC**
|
||||
* Standard numeric functions, and standard string functions
|
||||
* Automatic releasing of referenced objects (list, dictionary, referenced usertype, etc.) benefited from **Reference Counting** and **Garbage Collection**
|
||||
* Multiple file support by `IMPORT` statement
|
||||
* Structured user costomized **sub** routine definition by **`DEF/ENDDEF`** support, including tail recursion optimization
|
||||
* Structured user customizable **sub** routine definition by **`DEF/ENDDEF`** support, including tail recursion optimization
|
||||
* Structured `IF-THEN-ELSEIF-ELSE-ENDIF` support
|
||||
* Structured `FOR-TO-STEP-NEXT/WHILE-WEND/DO-UNTIL` support
|
||||
* `GOTO/GOSUB-RETURN` support
|
||||
@ -44,10 +48,10 @@ MY-BASIC is a lightweight cross-platform easy extendable BASIC interpreter writt
|
||||
* 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 projects in C, C++, Objective-C, etc.
|
||||
* It's able to learn how to build an interpreter from scratch with MY-BASIC
|
||||
* It's able to build your own dialect based on MY-BASIC
|
||||
* It's able to build your own dialect easily based on MY-BASIC
|
||||
* More features/modules under developing
|
||||
|
||||
## Scripting at a glance
|
||||
## Script at a glance
|
||||
|
||||
Come along with a traditional "hello world" script in MY-BASIC:
|
||||
|
||||
@ -75,20 +79,20 @@ Read the [MY-BASIC Quick Reference](MY-BASIC%20Quick%20Reference.pdf) (especiall
|
||||
This repository contains precompiled binaries for [Windows](output/my_basic.exe) and [OS X](output/my_basic_mac), it's efficient to download it and have a first impressive playground. Or you could make a build as follow.
|
||||
|
||||
* Open the Visual Studio solution `my_basic.sln` on Windows to build an executable
|
||||
* Open the XCode solution `my_basic_mac.xcodeproj` on OS X to build an OS X executable
|
||||
* Use the `makefile` with "make" toolchain to build an interpreter binary according to your platform
|
||||
* Open the Xcode solution `my_basic_mac.xcodeproj` on OS X to build an OS X executable
|
||||
* If you are not using VS or Xcode, use the `makefile` with a "make" toolchain to build an interpreter binary according to your own platform
|
||||
|
||||
To compile an interpreter binary for your own platform manually, please follow the steps.
|
||||
|
||||
* Retrieve at least `core` and `shell` folders for minimum build
|
||||
* Setup your compile toolchain configuration
|
||||
* Use your compiler to compile `core/my_basic.c` and `shell/main.c`, including `core/my_basic.h` is required for both source files, then link up your own executable
|
||||
1. Retrieve at least `core` and `shell` folders for minimum build
|
||||
2. Setup your compile toolchain configuration
|
||||
3. Use your compiler to compile `core/my_basic.c` and `shell/main.c`, including `core/my_basic.h` is required for both source files, then link up your own executable
|
||||
|
||||
The standalone interpreter supports three modes.
|
||||
|
||||
* Execute the binary directly without arguments to interactive with MY-BASIC
|
||||
* Execute the binary directly without arguments to enter MY-BASIC interactive mode
|
||||
* Pass a file path to the binary to load and run that script file
|
||||
* Pass an argument `-e` and an expression to evaluate and print it, eg. `-e "2 * (3 + 4)"`
|
||||
* Pass an argument `-e` followed by an expression to evaluate and print it, eg. `-e "2 * (3 + 4)"`
|
||||
|
||||
### Combine with exist projects
|
||||
|
||||
@ -96,10 +100,12 @@ MY-BASIC is cleanly written in a single C source file and an associated header f
|
||||
|
||||
You can definitely [link with MY-BASIC as a lib](https://github.com/paladin-t/my_basic/wiki/Link-with-MY_BASIC) as well.
|
||||
|
||||
For more details about using MY-BASIC when it's already integrated with exist projects, please see [MY-BASIC Quick Reference](MY-BASIC%20Quick%20Reference.pdf).
|
||||
For more details about using MY-BASIC when it's already integrated with a project, please see [MY-BASIC Quick Reference](MY-BASIC%20Quick%20Reference.pdf).
|
||||
|
||||
## [Wiki](https://github.com/paladin-t/my_basic/wiki)
|
||||
|
||||
Most of the fundamental topics are mentioned in the [MY-BASIC Quick Reference](MY-BASIC%20Quick%20Reference.pdf). There are some other scattered topics besides these aspects, such as the desine principle, machinism behind MY-BASIC, effective practice, etc; they are issued in the [Wiki](https://github.com/paladin-t/my_basic/wiki).
|
||||
|
||||
* Principles
|
||||
* [Passes](https://github.com/paladin-t/my_basic/wiki/Passes)
|
||||
* [Interpreter workflow diagram](https://github.com/paladin-t/my_basic/wiki/Interpreter-workflow-diagram)
|
||||
|
101
core/my_basic.c
101
core/my_basic.c
@ -81,7 +81,7 @@ extern "C" {
|
||||
/** Macros */
|
||||
#define _VER_MAJOR 1
|
||||
#define _VER_MINOR 1
|
||||
#define _VER_REVISION 101
|
||||
#define _VER_REVISION 102
|
||||
#define _VER_SUFFIX
|
||||
#define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION))
|
||||
#define _STRINGIZE(A) _MAKE_STRINGIZE(A)
|
||||
@ -229,6 +229,7 @@ static const char* _ERR_DESC[] = {
|
||||
"Invalid routine",
|
||||
"Routine expected",
|
||||
"Duplicate routine",
|
||||
"Invalid class",
|
||||
"Collection expected",
|
||||
"Iterator expected",
|
||||
"Collection or iterator expected",
|
||||
@ -261,8 +262,10 @@ typedef enum _data_e {
|
||||
_DT_DICT_IT,
|
||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||
_DT_LABEL, /* Label type, used for GOTO, GOSUB statement */
|
||||
_DT_ROUTINE, /* User defined sub routine in script */
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
_DT_CLASS, /* Object instance */
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
_DT_ROUTINE, /* User defined sub routine in script */
|
||||
_DT_SEP, /* Separator */
|
||||
_DT_EOS /* End of statement */
|
||||
} _data_e;
|
||||
@ -357,14 +360,18 @@ typedef struct _label_t {
|
||||
_ls_node_t* node;
|
||||
} _label_t;
|
||||
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
typedef struct _class_t {
|
||||
char* name;
|
||||
struct _running_context_t* scope;
|
||||
} _class_t;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
|
||||
typedef struct _routine_t {
|
||||
char* name;
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
_class_t* instance;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
struct _running_context_t* scope;
|
||||
_ls_node_t* entry;
|
||||
_ls_node_t* parameters;
|
||||
@ -396,8 +403,10 @@ typedef struct _object_t {
|
||||
_dict_it_t* dict_it;
|
||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||
_label_t* label;
|
||||
_routine_t* routine;
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
_class_t* instance;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
_routine_t* routine;
|
||||
char separator;
|
||||
mb_val_bytes_t bytes;
|
||||
_raw_t raw;
|
||||
@ -440,7 +449,9 @@ MBAPI const size_t MB_SIZEOF_ARR = _MB_MEM_TAG_SIZE + sizeof(_array_t);
|
||||
MBAPI const size_t MB_SIZEOF_VAR = _MB_MEM_TAG_SIZE + sizeof(_var_t);
|
||||
MBAPI const size_t MB_SIZEOF_LBL = _MB_MEM_TAG_SIZE + sizeof(_label_t);
|
||||
MBAPI const size_t MB_SIZEOF_RTN = _MB_MEM_TAG_SIZE + sizeof(_routine_t);
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
MBAPI const size_t MB_SIZEOF_CLS = _MB_MEM_TAG_SIZE + sizeof(_class_t);
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
#else /* MB_ENABLE_ALLOC_STAT */
|
||||
MBAPI const size_t MB_SIZEOF_INT = sizeof(int);
|
||||
MBAPI const size_t MB_SIZEOF_PTR = sizeof(intptr_t);
|
||||
@ -453,7 +464,9 @@ MBAPI const size_t MB_SIZEOF_ARR = sizeof(_array_t);
|
||||
MBAPI const size_t MB_SIZEOF_VAR = sizeof(_var_t);
|
||||
MBAPI const size_t MB_SIZEOF_LBL = sizeof(_label_t);
|
||||
MBAPI const size_t MB_SIZEOF_RTN = sizeof(_routine_t);
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
MBAPI const size_t MB_SIZEOF_CLS = sizeof(_class_t);
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
#endif /* MB_ENABLE_ALLOC_STAT */
|
||||
|
||||
#ifdef MB_ENABLE_SOURCE_TRACE
|
||||
@ -1150,9 +1163,11 @@ static unsigned _unref(_ref_t* ref, void* data);
|
||||
static void _create_ref(_ref_t* ref, _unref_func_t dtor, _data_e t, mb_interpreter_t* s);
|
||||
static void _destroy_ref(_ref_t* ref);
|
||||
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
static void _init_class(mb_interpreter_t* s, _class_t* instance, char* n);
|
||||
static void _begin_class(mb_interpreter_t* s);
|
||||
static void _end_class(mb_interpreter_t* s);
|
||||
static bool_t _end_class(mb_interpreter_t* s);
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
static void _init_routine(mb_interpreter_t* s, _routine_t* routine, char* n);
|
||||
static void _begin_routine(mb_interpreter_t* s);
|
||||
static bool_t _end_routine(mb_interpreter_t* s);
|
||||
@ -1415,8 +1430,10 @@ static const _func_t _core_libs[] = {
|
||||
{ "CALL", _core_call },
|
||||
{ "DEF", _core_def },
|
||||
{ "ENDDEF", _core_enddef },
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
{ "CLASS", _core_class },
|
||||
{ "ENDCLASS", _core_endclass },
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
|
||||
#ifdef MB_ENABLE_ALLOC_STAT
|
||||
{ "MEM", _core_mem },
|
||||
@ -3211,7 +3228,13 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
||||
/* Create a syntax symbol */
|
||||
int result = MB_FUNC_OK;
|
||||
_data_e type;
|
||||
union { _func_t* func; _array_t* array; _class_t* instance; _routine_t* routine; _var_t* var; _label_t* label; real_t float_point; int_t integer; _raw_t any; } tmp;
|
||||
union {
|
||||
_func_t* func; _array_t* array;
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
_class_t* instance;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
_routine_t* routine; _var_t* var; _label_t* label; real_t float_point; int_t integer; _raw_t any;
|
||||
} tmp;
|
||||
_raw_t value;
|
||||
unsigned int ul = 0;
|
||||
_parsing_context_t* context = 0;
|
||||
@ -3304,6 +3327,7 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
||||
}
|
||||
|
||||
break;
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
case _DT_CLASS:
|
||||
glbsyminscope = _search_identifier_in_scope_chain(s, 0, sym);
|
||||
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_CLASS) {
|
||||
@ -3332,6 +3356,7 @@ int _create_symbol(mb_interpreter_t* s, _ls_node_t* l, char* sym, _object_t** ob
|
||||
}
|
||||
|
||||
break;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
case _DT_ROUTINE:
|
||||
glbsyminscope = _search_identifier_in_scope_chain(s, 0, sym);
|
||||
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_ROUTINE) {
|
||||
@ -3563,6 +3588,7 @@ _end_import:
|
||||
goto _exit;
|
||||
}
|
||||
/* _class_t */
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
if(context->last_symbol) {
|
||||
glbsyminscope = _search_identifier_in_scope_chain(s, 0, sym);
|
||||
if(glbsyminscope && ((_object_t*)glbsyminscope->data)->type == _DT_CLASS) {
|
||||
@ -3581,26 +3607,28 @@ _end_import:
|
||||
goto _exit;
|
||||
}
|
||||
if(glbsyminscope && ((_object_t*)(glbsyminscope->data))->type == _DT_VAR) {
|
||||
tmp.obj = (_object_t*)(glbsyminscope->data);
|
||||
if(!tmp.obj->ref) {
|
||||
_ht_remove(running->var_dict, sym, _ls_cmp_extra_string);
|
||||
_dispose_object(tmp.obj);
|
||||
_handle_error_now(s, SE_RN_INVALID_CLASS, 0, MB_FUNC_ERR);
|
||||
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
if(_IS_FUNC(context->last_symbol, _core_def)) {
|
||||
if(context->routine_state > 1) {
|
||||
_handle_error_now(s, SE_RN_INVALID_CLASS, 0, MB_FUNC_ERR);
|
||||
|
||||
goto _exit;
|
||||
}
|
||||
tmp.obj->type = _DT_CLASS;
|
||||
tmp.obj->data.instance = (_class_t*)mb_malloc(sizeof(_class_t));
|
||||
_init_class(s, tmp.obj->data.instance, sym);
|
||||
_init_class(s, tmp.obj->data.instance, sym);
|
||||
_ht_set_or_insert(running->var_dict, sym, tmp.obj);
|
||||
}
|
||||
|
||||
result = _DT_CLASS;
|
||||
|
||||
goto _exit;
|
||||
} else if(_IS_FUNC(context->last_symbol, _core_endclass)) {
|
||||
_end_class(s);
|
||||
if(_end_class(s))
|
||||
_pop_scope(s);
|
||||
}
|
||||
}
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
/* _routine_t */
|
||||
if(context->last_symbol) {
|
||||
glbsyminscope = _search_identifier_in_scope_chain(s, 0, sym);
|
||||
@ -5080,6 +5108,7 @@ void _destroy_ref(_ref_t* ref) {
|
||||
ref->on_unref = 0;
|
||||
}
|
||||
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
void _init_class(mb_interpreter_t* s, _class_t* instance, char* n) {
|
||||
/* Initialize a class */
|
||||
_running_context_t* running = 0;
|
||||
@ -5105,15 +5134,23 @@ void _begin_class(mb_interpreter_t* s) {
|
||||
context->class_state++;
|
||||
}
|
||||
|
||||
void _end_class(mb_interpreter_t* s) {
|
||||
bool_t _end_class(mb_interpreter_t* s) {
|
||||
/* End parsing a class */
|
||||
_parsing_context_t* context = 0;
|
||||
|
||||
mb_assert(s);
|
||||
|
||||
context = s->parsing_context;
|
||||
if(!context->class_state) {
|
||||
_handle_error_now(s, SE_RN_INVALID_CLASS, 0, MB_FUNC_ERR);
|
||||
|
||||
return false;
|
||||
}
|
||||
context->class_state--;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
|
||||
void _init_routine(mb_interpreter_t* s, _routine_t* routine, char* n) {
|
||||
/* Initialize a routine */
|
||||
@ -5454,10 +5491,12 @@ int _clone_object(_object_t* obj, _object_t* tgt) {
|
||||
tgt->data.label->node = obj->data.label->node;
|
||||
|
||||
break;
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
case _DT_CLASS:
|
||||
mb_assert(0 && "Not implemented");
|
||||
|
||||
break;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
case _DT_ROUTINE:
|
||||
mb_assert(0 && "Not implemented");
|
||||
|
||||
@ -5545,6 +5584,7 @@ int _dispose_object(_object_t* obj) {
|
||||
}
|
||||
|
||||
break;
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
case _DT_CLASS:
|
||||
if(!obj->ref) {
|
||||
safe_free(obj->data.instance->name);
|
||||
@ -5555,6 +5595,7 @@ int _dispose_object(_object_t* obj) {
|
||||
}
|
||||
|
||||
break;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
case _DT_ROUTINE:
|
||||
if(!obj->ref) {
|
||||
safe_free(obj->data.routine->name);
|
||||
@ -5796,6 +5837,10 @@ _data_e _public_type_to_internal_type(mb_data_e t) {
|
||||
case MB_DT_DICT_IT:
|
||||
return _DT_DICT_IT;
|
||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
case MB_DT_CLASS:
|
||||
return _DT_CLASS;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
case MB_DT_ROUTINE:
|
||||
return _DT_ROUTINE;
|
||||
default:
|
||||
@ -5832,6 +5877,10 @@ mb_data_e _internal_type_to_public_type(_data_e t) {
|
||||
case _DT_DICT_IT:
|
||||
return MB_DT_DICT_IT;
|
||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
case _DT_CLASS:
|
||||
return MB_DT_CLASS;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
case _DT_ROUTINE:
|
||||
return MB_DT_ROUTINE;
|
||||
default:
|
||||
@ -5911,6 +5960,11 @@ int _public_value_to_internal_object(mb_value_t* pbl, _object_t* itn) {
|
||||
|
||||
break;
|
||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
case MB_DT_CLASS:
|
||||
itn->type = _DT_CLASS;
|
||||
itn->data.instance = (_class_t*)pbl->value.instance;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
case MB_DT_ROUTINE:
|
||||
itn->type = _DT_ROUTINE;
|
||||
itn->data.routine = (_routine_t*)pbl->value.routine;
|
||||
@ -5993,6 +6047,13 @@ int _internal_object_to_public_value(_object_t* itn, mb_value_t* pbl) {
|
||||
|
||||
break;
|
||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
case _DT_CLASS:
|
||||
pbl->type = MB_DT_CLASS;
|
||||
pbl->value.instance = itn->data.instance;
|
||||
|
||||
break;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
case _DT_ROUTINE:
|
||||
pbl->type = MB_DT_ROUTINE;
|
||||
pbl->value.routine = itn->data.routine;
|
||||
@ -6187,10 +6248,12 @@ int _execute_statement(mb_interpreter_t* s, _ls_node_t** l) {
|
||||
_handle_error_on_obj(s, SE_RN_INVALID_EXPRESSION, 0, DON(ast), MB_FUNC_ERR, _exit, result);
|
||||
|
||||
break;
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
case _DT_CLASS:
|
||||
mb_assert(0 && "Not implemented");
|
||||
|
||||
break;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
case _DT_ROUTINE:
|
||||
ast = ast->prev;
|
||||
result = _core_call(s, (void**)(&ast));
|
||||
@ -8175,6 +8238,12 @@ const char* mb_get_type_string(mb_data_e t) {
|
||||
case MB_DT_DICT_IT:
|
||||
return "DICT_ITERATOR";
|
||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
case MB_DT_CLASS:
|
||||
return "CLASS";
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
case MB_DT_ROUTINE:
|
||||
return "ROUTINE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
@ -81,6 +81,10 @@ extern "C" {
|
||||
# define MB_ENABLE_MODULE
|
||||
#endif /* MB_ENABLE_MODULE */
|
||||
|
||||
#ifndef MB_ENABLE_CLASS
|
||||
# define MB_ENABLE_CLASS
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
|
||||
#ifndef MB_COMPACT_MODE
|
||||
# define MB_COMPACT_MODE
|
||||
#endif /* MB_COMPACT_MODE */
|
||||
@ -309,6 +313,7 @@ typedef enum mb_error_e {
|
||||
SE_RN_INVALID_ROUTINE,
|
||||
SE_RN_ROUTINE_EXPECTED,
|
||||
SE_RN_DUPLICATE_ROUTINE,
|
||||
SE_RN_INVALID_CLASS,
|
||||
SE_RN_COLLECTION_EXPECTED,
|
||||
SE_RN_ITERATOR_EXPECTED,
|
||||
SE_RN_COLLECTION_OR_ITERATOR_EXPECTED,
|
||||
@ -337,7 +342,10 @@ typedef enum mb_data_e {
|
||||
MB_DT_DICT = 1 << 15,
|
||||
MB_DT_DICT_IT = 1 << 16,
|
||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||
MB_DT_ROUTINE = 1 << 24
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
MB_DT_CLASS = 1 << 24,
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
MB_DT_ROUTINE = 1 << 25
|
||||
} mb_data_e;
|
||||
|
||||
typedef unsigned char mb_val_bytes_t[sizeof(void*)];
|
||||
@ -356,6 +364,9 @@ typedef union mb_value_u {
|
||||
void* dict;
|
||||
void* dict_it;
|
||||
#endif /* MB_ENABLE_COLLECTION_LIB */
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
void* instance;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
void* routine;
|
||||
mb_val_bytes_t bytes;
|
||||
} mb_value_u;
|
||||
|
Binary file not shown.
@ -125,7 +125,11 @@ extern MBAPI const size_t MB_SIZEOF_ARR;
|
||||
extern MBAPI const size_t MB_SIZEOF_VAR;
|
||||
extern MBAPI const size_t MB_SIZEOF_LBL;
|
||||
extern MBAPI const size_t MB_SIZEOF_RTN;
|
||||
#ifdef MB_ENABLE_CLASS
|
||||
extern MBAPI const size_t MB_SIZEOF_CLS;
|
||||
#else /* MB_ENABLE_CLASS */
|
||||
static const size_t MB_SIZEOF_CLS = 20;
|
||||
#endif /* MB_ENABLE_CLASS */
|
||||
|
||||
typedef unsigned _pool_chunk_size_t;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user