diff --git a/HISTORY b/HISTORY index 40cff9c..178e4ec 100755 --- a/HISTORY +++ b/HISTORY @@ -1,3 +1,8 @@ +Aug. 25 2015 +Allowed a user to define the memory tag data type, unsigned short as default +Added an mb_set_memory_manager function, allows user defined memory management +Added referencable data type size constants + Aug. 11 2015 Fixed a wrong IF trunk processing bug, thanks to irony for pointing it out Fixed a crash bug with an invalid IF statement @@ -73,8 +78,8 @@ Dec. 9 2014 Improved compatibility with BCB May. 25 2014 -Added an mb_set_inputer function which allows the user to specify an INPUT reader, thanks to Michael P. Welch for suggestion -Added an mb_remove_reserved_func function which allows the user to disable/remove a reserved statement +Added an mb_set_inputer function which allows a user to specify an INPUT reader, thanks to Michael P. Welch for suggestion +Added an mb_remove_reserved_func function which allows a user to disable/remove a reserved statement May. 22 2014 Fixed a crash bug when missing colon in a combined line, thanks to Michael P. Welch for pointing it out diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 index 73ceea8..f95323c --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License -Copyright (c) 2011 - 2015 W. 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/README.md b/README.md index f2f47f4..c6e02d6 100755 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ For more details about using MY-BASIC when it's already integrated with exist pr * [Passes](https://github.com/paladin-t/my_basic/wiki/Passes) * [Interpreter workflow diagram](https://github.com/paladin-t/my_basic/wiki/Interpreter-workflow-diagram) * [Link with MY-BASIC](https://github.com/paladin-t/my_basic/wiki/Link-with-MY_BASIC) +* [Customize a memory allocator](https://github.com/paladin-t/my_basic/wiki/Customize-a-memory-allocator) * [Redirect PRINT and INPUT](https://github.com/paladin-t/my_basic/wiki/Redirect-PRINT-and-INPUT) * [Redefine int_t and real_t](https://github.com/paladin-t/my_basic/wiki/Redefine-int_t-and-real_t) * [Use usertype values](https://github.com/paladin-t/my_basic/wiki/Use-usertype-values) diff --git a/core/my_basic.c b/core/my_basic.c index 758530a..992cdde 100755 --- a/core/my_basic.c +++ b/core/my_basic.c @@ -3,7 +3,7 @@ ** ** For the latest info, see https://github.com/paladin-t/my_basic/ ** -** Copyright (C) 2011 - 2015 W. 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 @@ -78,7 +78,7 @@ extern "C" { /** Macros */ #define _VER_MAJOR 1 #define _VER_MINOR 1 -#define _VER_REVISION 62 +#define _VER_REVISION 63 #define _MB_VERSION ((_VER_MAJOR * 0x01000000) + (_VER_MINOR * 0x00010000) + (_VER_REVISION)) /* Uncomment this line to treat warnings as error */ @@ -299,6 +299,31 @@ typedef struct _object_t { #endif /* MB_ENABLE_SOURCE_TRACE */ } _object_t; +typedef unsigned short _mem_tag_t; +#define _MB_MEM_TAG_SIZE (sizeof(_mem_tag_t)) + +#ifdef MB_ENABLE_ALLOC_STAT +const size_t MB_SIZEOF_INT = _MB_MEM_TAG_SIZE + sizeof(int); +const size_t MB_SIZEOF_PTR = _MB_MEM_TAG_SIZE + sizeof(intptr_t); +const size_t MB_SIZEOF_LSN = _MB_MEM_TAG_SIZE + sizeof(_ls_node_t); +const size_t MB_SIZEOF_HTN = _MB_MEM_TAG_SIZE + sizeof(_ht_node_t); +const size_t MB_SIZEOF_OBJ = _MB_MEM_TAG_SIZE + sizeof(_object_t); +const size_t MB_SIZEOF_FUN = _MB_MEM_TAG_SIZE + sizeof(_func_t); +const size_t MB_SIZEOF_ARR = _MB_MEM_TAG_SIZE + sizeof(_array_t); +const size_t MB_SIZEOF_VAR = _MB_MEM_TAG_SIZE + sizeof(_var_t); +const size_t MB_SIZEOF_LBL = _MB_MEM_TAG_SIZE + sizeof(_label_t); +#else /* MB_ENABLE_ALLOC_STAT */ +const size_t MB_SIZEOF_INT = sizeof(int); +const size_t MB_SIZEOF_PTR = sizeof(intptr_t); +const size_t MB_SIZEOF_LSN = sizeof(_ls_node_t); +const size_t MB_SIZEOF_HTN = sizeof(_ht_node_t); +const size_t MB_SIZEOF_OBJ = sizeof(_object_t); +const size_t MB_SIZEOF_FUN = sizeof(_func_t); +const size_t MB_SIZEOF_ARR = sizeof(_array_t); +const size_t MB_SIZEOF_VAR = sizeof(_var_t); +const size_t MB_SIZEOF_LBL = sizeof(_label_t); +#endif /* MB_ENABLE_ALLOC_STAT */ + #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 }; @@ -606,9 +631,9 @@ static void _ht_clear(_ht_node_t* ht); static void _ht_destroy(_ht_node_t* ht); /** Memory operations */ -#define _MB_POINTER_SIZE (sizeof(intptr_t)) -#define _MB_WRITE_CHUNK_SIZE(t, s) (*((size_t*)((char*)(t) - _MB_POINTER_SIZE)) = s) -#define _MB_READ_CHUNK_SIZE(t) (*((size_t*)((char*)(t) - _MB_POINTER_SIZE))) +#define _MB_CHECK_MEM_TAG_SIZE(y, s) do { _mem_tag_t _tmp = (_mem_tag_t)s; if((y)_tmp != s) { mb_assert(0 && "\"_mem_tag_t\" is too small."); printf("The type \"_mem_tag_t\" is not precise enough to hold the given data, please redefine it!"); } } while(0) +#define _MB_WRITE_MEM_TAG_SIZE(t, s) (*((_mem_tag_t*)((char*)(t) - _MB_MEM_TAG_SIZE)) = (_mem_tag_t)s) +#define _MB_READ_MEM_TAG_SIZE(t) (*((_mem_tag_t*)((char*)(t) - _MB_MEM_TAG_SIZE))) #ifdef MB_ENABLE_ALLOC_STAT static volatile size_t _mb_allocated = 0; @@ -616,6 +641,9 @@ static volatile size_t _mb_allocated = 0; static volatile size_t _mb_allocated = (size_t)(~0); #endif /* MB_ENABLE_ALLOC_STAT */ +static mb_memory_allocate_func_t _mb_allocate_func = 0; +static mb_memory_free_func_t _mb_free_func = 0; + static void* mb_malloc(size_t s); static void mb_free(void* p); @@ -1305,14 +1333,18 @@ void* mb_malloc(size_t s) { char* ret = NULL; size_t rs = s; #ifdef MB_ENABLE_ALLOC_STAT - rs += _MB_POINTER_SIZE; + _MB_CHECK_MEM_TAG_SIZE(size_t, s); + rs += _MB_MEM_TAG_SIZE; #endif /* MB_ENABLE_ALLOC_STAT */ - ret = (char*)malloc(rs); + if(_mb_allocate_func) + ret = _mb_allocate_func((unsigned)rs); + else + ret = (char*)malloc(rs); mb_assert(ret); #ifdef MB_ENABLE_ALLOC_STAT _mb_allocated += s; - ret += _MB_POINTER_SIZE; - _MB_WRITE_CHUNK_SIZE(ret, s); + ret += _MB_MEM_TAG_SIZE; + _MB_WRITE_MEM_TAG_SIZE(ret, s); #endif /* MB_ENABLE_ALLOC_STAT */ return (void*)ret; @@ -1323,13 +1355,16 @@ void mb_free(void* p) { #ifdef MB_ENABLE_ALLOC_STAT do { - size_t os = _MB_READ_CHUNK_SIZE(p); + size_t os = _MB_READ_MEM_TAG_SIZE(p); _mb_allocated -= os; - p = (char*)p - _MB_POINTER_SIZE; + p = (char*)p - _MB_MEM_TAG_SIZE; } while(0); #endif /* MB_ENABLE_ALLOC_STAT */ - free(p); + if(_mb_free_func) + _mb_free_func(p); + else + free(p); } size_t mb_memtest(void*p, size_t s) { @@ -4443,6 +4478,15 @@ char* mb_memdup(char* val, unsigned size) { return result; } +int mb_set_memory_manager(mb_memory_allocate_func_t a, mb_memory_free_func_t f) { + /* Register an allocator and a freer globally */ + + _mb_allocate_func = a; + _mb_free_func = f; + + return 0; +} + /* ========================================================} */ /* diff --git a/core/my_basic.h b/core/my_basic.h index 8cb505e..de6893f 100755 --- a/core/my_basic.h +++ b/core/my_basic.h @@ -3,7 +3,7 @@ ** ** For the latest info, see https://github.com/paladin-t/my_basic/ ** -** Copyright (C) 2011 - 2015 W. 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 @@ -248,6 +248,8 @@ typedef void (* mb_debug_stepped_handler_t)(struct mb_interpreter_t*, int, unsig typedef void (* mb_error_handler_t)(struct mb_interpreter_t*, enum mb_error_e, 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); +typedef void (* mb_memory_free_func_t)(char* p); MBAPI unsigned int mb_ver(void); MBAPI const char* mb_ver_string(void); @@ -302,6 +304,7 @@ MBAPI int mb_set_inputer(struct mb_interpreter_t* s, mb_input_func_t p); MBAPI int mb_gets(char* buf, int s); MBAPI char* mb_memdup(char* val, unsigned size); +MBAPI int mb_set_memory_manager(mb_memory_allocate_func_t a, mb_memory_free_func_t f); #ifdef MB_COMPACT_MODE # pragma pack() diff --git a/output/my_basic.exe b/output/my_basic.exe index 0174f83..b70d667 100755 Binary files a/output/my_basic.exe and b/output/my_basic.exe differ diff --git a/output/my_basic_mac b/output/my_basic_mac index a5f85f3..a035c8a 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 a0625cf..e72acf7 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,61,0 - PRODUCTVERSION 1,1,61,0 + FILEVERSION 1,1,63,0 + PRODUCTVERSION 1,1,63,0 FILEFLAGSMASK 0x17L # ifdef _DEBUG FILEFLAGS 0x1L @@ -53,15 +53,15 @@ BLOCK "080404b0" BEGIN VALUE "Comments", "MY-BASIC" - VALUE "CompanyName", "W. Renxin" - VALUE "FileDescription", "MY-BASIC interpreter" - VALUE "FileVersion", "1, 1, 61, 0" + VALUE "CompanyName", "Wang Renxin" + VALUE "FileDescription", "MY-BASIC Interpreter for Windows" + VALUE "FileVersion", "1, 1, 63, 0" VALUE "InternalName", "my_basic" - VALUE "LegalCopyright", "Copyright (C) 2011 - 2015 W. Renxin" + 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, 61, 0" + VALUE "ProductVersion", "1, 1, 63, 0" END END BLOCK "VarFileInfo" diff --git a/resource/resource.h b/resource/resource.h index 36bbe45..0c7342f 100755 --- a/resource/resource.h +++ b/resource/resource.h @@ -2,7 +2,7 @@ // Microsoft Visual C++ generated include file. // Used by my_basic.rc // -#define IDI_ICON_MAIN 101 +#define IDI_ICON_MAIN 101 // Next default values for new objects // diff --git a/sample/sample01.bas b/sample/sample01.bas index 73a14c9..d605a41 100755 --- a/sample/sample01.bas +++ b/sample/sample01.bas @@ -1,5 +1,5 @@ ' This script is an example of MY-BASIC -' Copyright (c) 2011 - 2015 W. Renxin. All rights reserved. +' Copyright (c) 2011 - 2015 Wang Renxin. All rights reserved. ' For more information, see https://github.com/paladin-t/my_basic/ s$ = "hello " diff --git a/sample/sample02.bas b/sample/sample02.bas index 2f6fa0b..09a0a9b 100755 --- a/sample/sample02.bas +++ b/sample/sample02.bas @@ -1,5 +1,5 @@ ' This script is an example of MY-BASIC -' Copyright (c) 2011 - 2015 W. Renxin. All rights reserved. +' Copyright (c) 2011 - 2015 Wang Renxin. All rights reserved. ' For more information, see https://github.com/paladin-t/my_basic/ e = 50 diff --git a/sample/sample03.bas b/sample/sample03.bas index 57847a9..545c0b5 100755 --- a/sample/sample03.bas +++ b/sample/sample03.bas @@ -1,5 +1,5 @@ ' This script is an example of MY-BASIC -' Copyright (c) 2011 - 2015 W. Renxin. All rights reserved. +' Copyright (c) 2011 - 2015 Wang Renxin. All rights reserved. ' For more information, see https://github.com/paladin-t/my_basic/ PRINT "Input: " diff --git a/sample/sample04.bas b/sample/sample04.bas index 0bc2466..7c9be5d 100755 --- a/sample/sample04.bas +++ b/sample/sample04.bas @@ -1,5 +1,5 @@ ' This script is an example of MY-BASIC -' Copyright (c) 2011 - 2015 W. Renxin. All rights reserved. +' Copyright (c) 2011 - 2015 Wang Renxin. All rights reserved. ' For more information, see https://github.com/paladin-t/my_basic/ BEGIN: diff --git a/shell/main.c b/shell/main.c index 99c28e8..744f759 100755 --- a/shell/main.c +++ b/shell/main.c @@ -3,7 +3,7 @@ ** ** For the latest info, see https://github.com/paladin-t/my_basic/ ** -** Copyright (C) 2011 - 2015 W. 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 @@ -394,7 +394,7 @@ static void _kill_program(const char* path) { static void _show_tip(void) { printf("MY-BASIC Interpreter Shell - %s.\n", mb_ver_string()); - printf("Copyright (C) 2011 - 2015 W. 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("Input HELP and hint enter to view help information.\n"); }