├── tests ├── pylite.cmd ├── basic │ └── test_1_if.py ├── test_grammar.py └── grammar │ ├── test_5_class.py │ ├── test_6_except.py │ ├── test_1_basetype.py │ ├── test_2_short_stmt.py │ ├── test_3_logic.py │ └── test_4_func.py ├── src ├── bind.c ├── deps │ ├── linenoise │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── osfix │ │ │ ├── linuxfix.h │ │ │ ├── linuxfix.c │ │ │ ├── winfix.c │ │ │ ├── Win32_ANSI.h │ │ │ └── winfix.h │ │ ├── LICENSE │ │ ├── license-ms.txt │ │ ├── linenoise.h │ │ └── README.markdown │ ├── khash_obj.c │ ├── platform.h │ ├── fpconv │ │ ├── fpconv.h │ │ ├── license │ │ ├── powers.h │ │ └── fpconv.c │ ├── platform.c │ ├── utfconvert.h │ └── kvec.h ├── utils │ ├── misc.h │ ├── misc.c │ ├── io │ │ ├── fs_simple.h │ │ ├── io_simple.h │ │ ├── fs_base.h │ │ ├── _io.h │ │ ├── io_base.h │ │ ├── fs_simple.c │ │ └── io_simple.c │ ├── ref.h │ ├── watch.c │ ├── watch.h │ ├── ref.c │ ├── config.c │ ├── debug.h │ ├── config.h │ └── static.c ├── pybind │ ├── typebind.c │ ├── typebind.h │ ├── extra.h │ ├── extra.c │ └── common.h ├── types │ ├── objectE.c │ ├── common │ │ ├── set.h │ │ ├── unusual.h │ │ ├── bool.h │ │ ├── tuple.h │ │ ├── unusual.c │ │ ├── type.h │ │ ├── bytes.h │ │ ├── bool.c │ │ ├── dict.h │ │ ├── type.c │ │ ├── list.h │ │ ├── string.h │ │ ├── number.h │ │ ├── tuple.c │ │ ├── set.c │ │ └── dict.c │ ├── extra │ │ ├── cpointer.h │ │ ├── cpointer.c │ │ ├── none.h │ │ ├── range.h │ │ ├── exception.c │ │ ├── none.c │ │ ├── property.c │ │ ├── range.c │ │ ├── property.h │ │ ├── code.h │ │ ├── module.h │ │ ├── code.c │ │ ├── module.c │ │ ├── iter.h │ │ ├── function.h │ │ ├── exception.h │ │ ├── function.c │ │ └── iter.c │ ├── all.h │ ├── custom.h │ ├── custom.c │ ├── objectE.h │ └── object.h ├── mods │ ├── io.h │ ├── os.h │ ├── cio.h │ ├── math.h │ ├── builtin.h │ ├── pltypes.h │ ├── unusualm.h │ ├── sys.h │ ├── pltypes.c │ ├── sys.c │ ├── unusualm.c │ ├── os.c │ └── cio.c ├── intp.h ├── gc.h ├── bind.h ├── api.h ├── parser.h ├── lexer.h ├── intp.c ├── vm.h └── shell.c ├── .travis.yml ├── ISSUE_TEMPLATE.md ├── .gitignore ├── LICENSE ├── README.md └── CMakeLists.txt /tests/pylite.cmd: -------------------------------------------------------------------------------- 1 | "../build/Release/pylite.exe" %1 %2 %3 %4 %5 -------------------------------------------------------------------------------- /src/bind.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fy0/python_lite/HEAD/src/bind.c -------------------------------------------------------------------------------- /src/deps/linenoise/.gitignore: -------------------------------------------------------------------------------- 1 | linenoise_example 2 | *.dSYM 3 | history.txt 4 | -------------------------------------------------------------------------------- /src/utils/misc.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fy0/python_lite/HEAD/src/utils/misc.h -------------------------------------------------------------------------------- /src/pybind/typebind.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fy0/python_lite/HEAD/src/pybind/typebind.c -------------------------------------------------------------------------------- /src/types/objectE.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fy0/python_lite/HEAD/src/types/objectE.c -------------------------------------------------------------------------------- /src/types/common/set.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fy0/python_lite/HEAD/src/types/common/set.h -------------------------------------------------------------------------------- /src/utils/misc.c: -------------------------------------------------------------------------------- 1 | 2 | #include "misc.h" 3 | #include "../intp.h" 4 | #include "../types/all.h" 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | 3 | script: 4 | mkdir build && cd build && cmake .. && make 5 | 6 | compiler: 7 | - clang 8 | - gcc 9 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | ## Operating system and pylite version: 3 | 4 | 5 | ## Issue description (what happened, and what was expected): 6 | 7 | 8 | ## Steps to reproduce: 9 | 10 | -------------------------------------------------------------------------------- /src/utils/io/fs_simple.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_UTILS_FS_SIMPLE_H 3 | #define PYLITE_UTILS_FS_SIMPLE_H 4 | 5 | #include "fs_base.h" 6 | 7 | PyLiteFS PyLiteFSSimple; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/mods/io.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_MODS_IO_H 3 | #define PYLITE_MODS_IO_H 4 | 5 | #include "../types/all.h" 6 | 7 | pl_bool_t pylt_mods_io_register(PyLiteInterpreter *I); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/mods/os.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_MODS_OS_H 3 | #define PYLITE_MODS_OS_H 4 | 5 | #include "../types/all.h" 6 | 7 | pl_bool_t pylt_mods_os_register(PyLiteInterpreter *I); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/mods/cio.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_MODS_CIO_H 3 | #define PYLITE_MODS_CIO_H 4 | 5 | #include "../types/all.h" 6 | 7 | pl_bool_t pylt_mods_cio_register(PyLiteInterpreter *I); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/mods/math.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_MODS_MATH_H 3 | #define PYLITE_MODS_MATH_H 4 | 5 | #include "../types/all.h" 6 | 7 | pl_bool_t pylt_mods_math_register(PyLiteInterpreter *I); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/mods/builtin.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_MODS_BUILTIN_H 3 | #define PYLITE_MODS_BUILTIN_H 4 | 5 | #include "../types/all.h" 6 | 7 | pl_bool_t pylt_mods_builtins_register(PyLiteInterpreter *I); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/mods/pltypes.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_MODS_PLTYPES_H 3 | #define PYLITE_MODS_PLTPES_H 4 | 5 | #include "../types/all.h" 6 | 7 | pl_bool_t pylt_mods_pltypes_register(PyLiteInterpreter *I); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/mods/unusualm.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_MODS_UNUSUAL_H 3 | #define PYLITE_MODS_UNUSUAL_H 4 | 5 | #include "../types/all.h" 6 | 7 | pl_bool_t pylt_mods_unusual_register(PyLiteInterpreter *I); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/deps/khash_obj.c: -------------------------------------------------------------------------------- 1 | 2 | #include "khash_obj.h" 3 | 4 | void* my_malloc(PyLiteInterpreter *I, size_t size) { 5 | void* ret = pylt_malloc(I, size); 6 | memset(ret, 0, size); 7 | return ret; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/mods/sys.h: -------------------------------------------------------------------------------- 1 | 2 | // sys 必须在 io 模块之后注册 3 | 4 | #ifndef PYLITE_MODS_SYS_H 5 | #define PYLITE_MODS_SYS_H 6 | 7 | #include "../types/all.h" 8 | 9 | pl_bool_t pylt_mods_sys_register(PyLiteInterpreter *I); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/pybind/typebind.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_BIND_TYPEBIND_H 3 | #define PYLITE_BIND_TYPEBIND_H 4 | 5 | #include "../types/all.h" 6 | 7 | void pylt_bind_all_types_register(PyLiteInterpreter *I, PyLiteModuleObject *mod); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/utils/io/io_simple.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_UTILS_IO_SIMPLE_H 3 | #define PYLITE_UTILS_IO_SIMPLE_H 4 | 5 | #include "io_base.h" 6 | 7 | typedef struct { 8 | int fno; 9 | int flag; 10 | pl_uint_t size; 11 | } PyLiteFileSimple; 12 | 13 | PyLiteIO PyLiteIOSimple; 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/utils/ref.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_REF_H 3 | #define PYLITE_REF_H 4 | 5 | #include "../types/object.h" 6 | 7 | typedef struct PyLiteRef { 8 | PyLiteObject *obj; 9 | } PyLiteRef; 10 | 11 | PyLiteRef* pylt_ref_new(PyLiteInterpreter *I, PyLiteObject *obj); 12 | void pylt_ref_free(PyLiteInterpreter *I, PyLiteRef *ref); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | build/ 10 | bak/ 11 | 12 | # Translations 13 | *.mo 14 | *.pot 15 | 16 | # Django stuff: 17 | *.log 18 | 19 | # Others 20 | .gitignore~ 21 | *.[ch]~ 22 | *.un~ 23 | *.py~ 24 | *.txt~ 25 | *.swp 26 | -------------------------------------------------------------------------------- /src/utils/watch.c: -------------------------------------------------------------------------------- 1 | 2 | #include "watch.h" 3 | 4 | void pylt_obj_watch(PyLiteInterpreter *I, PyLiteObject *container, PyLiteObject *key, PyLiteObject *func) { 5 | ; 6 | } 7 | 8 | void pylt_obj_unwatch(PyLiteInterpreter *I, PyLiteObject *watch) { 9 | ; 10 | } 11 | 12 | void pylt_obj_unwatch_all(PyLiteInterpreter *I, PyLiteObject *container) { 13 | ; 14 | } 15 | -------------------------------------------------------------------------------- /src/utils/watch.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_WATCH_H 3 | #define PYLITE_WATCH_H 4 | 5 | #include "../types/object.h" 6 | 7 | //PyLiteWatchObject; 8 | 9 | void pylt_obj_watch(PyLiteInterpreter *I, PyLiteObject *container, PyLiteObject *key, PyLiteObject *func); 10 | void pylt_obj_unwatch(PyLiteInterpreter *I, PyLiteObject *watch); 11 | void pylt_obj_unwatch_all(PyLiteInterpreter *I, PyLiteObject *container); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/deps/linenoise/Makefile: -------------------------------------------------------------------------------- 1 | STD= 2 | WARN= -Wall 3 | OPT= -Os 4 | 5 | R_CFLAGS= $(STD) $(WARN) $(OPT) $(DEBUG) $(CFLAGS) 6 | R_LDFLAGS= $(LDFLAGS) 7 | DEBUG= -g 8 | 9 | R_CC=$(CC) $(R_CFLAGS) 10 | R_LD=$(CC) $(R_LDFLAGS) 11 | 12 | linenoise.o: linenoise.h linenoise.c 13 | 14 | linenoise_example: linenoise.o example.o 15 | $(R_LD) -o $@ $^ 16 | 17 | .c.o: 18 | $(R_CC) -c $< 19 | 20 | clean: 21 | rm -f linenoise_example *.o 22 | -------------------------------------------------------------------------------- /src/utils/ref.c: -------------------------------------------------------------------------------- 1 | 2 | #include "ref.h" 3 | #include "../gc.h" 4 | 5 | PyLiteRef* pylt_ref_new(PyLiteInterpreter *I, PyLiteObject *obj) { 6 | PyLiteRef *ref = pylt_malloc(I, sizeof(PyLiteRef)); 7 | ref->obj = obj; 8 | pylt_gc_ref_add(I, ref); 9 | return ref; 10 | } 11 | 12 | 13 | void pylt_ref_free(PyLiteInterpreter *I, PyLiteRef *ref) { 14 | pylt_gc_ref_remove(I, ref); 15 | pylt_free_ex(I, ref); 16 | } 17 | -------------------------------------------------------------------------------- /src/utils/config.c: -------------------------------------------------------------------------------- 1 | 2 | #include "config.h" 3 | #include "../intp.h" 4 | 5 | void* pylt_realloc(PyLiteInterpreter *I, void* m, size_t osize, size_t nsize) { 6 | if (nsize == 0) { 7 | free(m); 8 | if (I && m) I->mem_used -= osize; 9 | return NULL; 10 | } else { 11 | void* ret = realloc(m, nsize); 12 | if (I) I->mem_used = I->mem_used - osize + nsize; 13 | return ret; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/utils/io/fs_base.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_UTILS_FS_BASE_H 3 | #define PYLITE_UTILS_FS_BASE_H 4 | 5 | #include "../../types/all.h" 6 | 7 | typedef pl_bool_t(*PyLiteFSFileExistsFunc)(PyLiteInterpreter *I, PyLiteStrObject *fn); 8 | typedef pl_bool_t(*PyLiteFSIsDirFunc)(PyLiteInterpreter *I, PyLiteStrObject *fn); 9 | 10 | typedef struct PyLiteFS { 11 | PyLiteFSFileExistsFunc exists; 12 | PyLiteFSIsDirFunc isdir; 13 | } PyLiteFS; 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/types/extra/cpointer.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_CPTR_H 3 | #define PYLITE_TYPES_CPTR_H 4 | 5 | #include "../object.h" 6 | 7 | typedef struct PyLiteCPtrObject { 8 | PyLiteObject_HEAD; 9 | void *ob_ptr; 10 | pl_bool_t auto_free; 11 | } PyLiteCPtrObject; 12 | 13 | pl_uint32_t pylt_obj_cptr_hash(PyLiteInterpreter *I, PyLiteCPtrObject *obj); 14 | PyLiteCPtrObject* pylt_obj_cptr_new(PyLiteInterpreter *I, void *ptr, pl_bool_t is_free_ptr); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/deps/linenoise/osfix/linuxfix.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _WIN32 3 | #ifndef CONSOLE_LINUX_FIX_H 4 | #define CONSOLE_LINUX_FIX_H 5 | 6 | int mycrt_read(int fd, void *buffer, unsigned int count); 7 | int mycrt_write(int fd, void *buffer, unsigned int count); 8 | 9 | #define read(fd,buffer,count) mycrt_read(fd,buffer,count) 10 | #define write(fd,buffer,count) mycrt_write(fd,buffer,count) 11 | //#define isatty(fd) mycrt_isatty(fd) 12 | 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /src/types/extra/cpointer.c: -------------------------------------------------------------------------------- 1 | 2 | #include "cpointer.h" 3 | #include "../../gc.h" 4 | 5 | pl_uint32_t pylt_obj_cptr_hash(PyLiteInterpreter *I, PyLiteCPtrObject *obj) { 6 | return (pl_uint32_t)obj->ob_ptr; 7 | } 8 | 9 | PyLiteCPtrObject* pylt_obj_cptr_new(PyLiteInterpreter *I, void *ptr, pl_bool_t is_free_ptr) { 10 | PyLiteObject_init(I, obj, PyLiteCPtrObject, PYLT_OBJ_TYPE_CPTR); 11 | obj->ob_ptr = ptr; 12 | obj->auto_free = is_free_ptr; 13 | return obj; 14 | } 15 | -------------------------------------------------------------------------------- /src/mods/pltypes.c: -------------------------------------------------------------------------------- 1 | 2 | #include "unusualm.h" 3 | #include "../bind.h" 4 | #include "../types/all.h" 5 | #include "../utils/misc.h" 6 | #include "../pybind/typebind.h" 7 | 8 | 9 | PyLiteModuleObject* pylt_mods_pltypes_loader(PyLiteInterpreter *I) { 10 | PyLiteModuleObject *mod = pylt_obj_module_new(I, NULL); 11 | pylt_bind_all_types_register(I, mod); 12 | return mod; 13 | } 14 | 15 | pl_bool_t pylt_mods_pltypes_register(PyLiteInterpreter *I) { 16 | return pylt_mod_register(I, _S(pltypes), &pylt_mods_pltypes_loader, true); 17 | } 18 | -------------------------------------------------------------------------------- /src/utils/debug.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_DEBUG_H 3 | #define PYLITE_DEBUG_H 4 | 5 | #include "../parser.h" 6 | 7 | #ifdef _MSC_VER 8 | #ifndef _DEBUG 9 | #undef PL_DEBUG_INFO 10 | #endif 11 | #endif // _MSC_VER 12 | 13 | //#define PL_DEBUG_INFO 14 | 15 | void debug_print_const_vals(PyLiteInterpreter *I, PyLiteCodeObject *code); 16 | void debug_print_opcodes(PyLiteInterpreter *I, PyLiteCodeObject *code); 17 | void debug_print_obj(PyLiteInterpreter *I, PyLiteObject *obj); 18 | 19 | void debug_test_lexer(PyLiteInterpreter *I, PyLiteFile *input); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/types/extra/none.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_NONE_H 3 | #define PYLITE_TYPES_NONE_H 4 | 5 | #include "../object.h" 6 | 7 | typedef struct PyLiteNoneObject { 8 | PyLiteObject_HEAD; 9 | } PyLiteNoneObject; 10 | 11 | pl_int_t pylt_obj_none_cmp(PyLiteInterpreter *I, PyLiteNoneObject *self, PyLiteObject *other); 12 | pl_bool_t pylt_obj_none_eq(PyLiteInterpreter *I, PyLiteNoneObject *self, PyLiteObject *other); 13 | pl_uint32_t pylt_obj_none_hash(PyLiteInterpreter *I, PyLiteNoneObject *obj); 14 | 15 | PyLiteNoneObject* pylt_obj_none_new(PyLiteInterpreter *I); 16 | 17 | PyLiteNoneObject PyLiteNone; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /tests/basic/test_1_if.py: -------------------------------------------------------------------------------- 1 | 2 | # 3 | a = 0 4 | 5 | if 1: 6 | a = 1 7 | 8 | assert a == 1 9 | 10 | # 11 | a = 0 12 | 13 | if 0: 14 | a = 1 15 | 16 | assert a == 0 17 | 18 | # 19 | if 1: 20 | a = 1 21 | else: 22 | a = 2 23 | 24 | assert a == 1 25 | 26 | # 27 | if 0: 28 | a = 2 29 | else: 30 | a = 1 31 | 32 | assert a == 1 33 | 34 | # 35 | 36 | def func(v): 37 | ret = 0 38 | if v == 1: 39 | ret = v 40 | elif v == 2: 41 | ret = 2 42 | elif v == 3: 43 | ret = 3 44 | return ret 45 | 46 | for i in range(4): 47 | assert i == func(i) 48 | -------------------------------------------------------------------------------- /src/deps/platform.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PLATFORM_UTILS_H 3 | #define PLATFORM_UTILS_H 4 | 5 | #if defined(_WIN32) && !defined(_WIN32_WCE) 6 | #define PLATFORM_WINDOWS 7 | #else 8 | #define PLATFORM_LINUX 9 | #endif 10 | 11 | #ifdef _MSC_VER 12 | #define _INLINE __inline 13 | #pragma execution_character_set("utf-8") 14 | #define _CRT_SECURE_NO_WARNINGS 15 | #pragma warning (disable: 4996) 16 | #else 17 | #define _INLINE inline 18 | #endif 19 | 20 | #define SIZEOF_LONG_LONG sizeof(long long) 21 | #define MAX_LONG_LONG_CHARS (2 + (SIZEOF_LONG_LONG*53-1) / 22) 22 | 23 | 24 | void printf_u8(const char *fmt, ...); 25 | 26 | void platform_init(); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/types/common/unusual.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_UNUSUAL_H 3 | #define PYLITE_TYPES_UNUSUAL_H 4 | 5 | #include "../object.h" 6 | 7 | typedef struct PyLiteUnusualObject { 8 | PyLiteObject_HEAD; 9 | } PyLiteUnusualObject; 10 | 11 | 12 | // unique values 13 | PyLiteUnusualObject PyLiteUseless; // placeholder, defalut value 14 | PyLiteUnusualObject PyLiteNotImplemented; 15 | 16 | // to fill defaults of function info 17 | PyLiteUnusualObject PyLiteParamArgs; 18 | PyLiteUnusualObject PyLiteParamKwargs; 19 | PyLiteUnusualObject PyLiteParamUndefined; 20 | 21 | struct PyLiteStrObject* pylt_obj_unusual_to_str(PyLiteInterpreter *I, PyLiteUnusualObject *self); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/types/extra/range.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_RANGE_H 3 | #define PYLITE_TYPES_RANGE_H 4 | 5 | #include "../object.h" 6 | 7 | typedef struct PyLiteRangeObject { 8 | PyLiteObject_HEAD; 9 | pl_int_t start; 10 | pl_int_t stop; 11 | pl_int_t step; // not zero 12 | } PyLiteRangeObject; 13 | 14 | PyLiteRangeObject* pylt_obj_range_new(PyLiteInterpreter *I, pl_int_t start, pl_int_t stop, pl_int_t step); 15 | pl_int_t pylt_obj_range_itertimes(PyLiteInterpreter *I, PyLiteRangeObject* range); 16 | 17 | void pylt_obj_range_rfree(PyLiteInterpreter *I, PyLiteRangeObject* self); 18 | void pylt_obj_range_free(PyLiteInterpreter *I, PyLiteRangeObject* self); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /tests/test_grammar.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | # Interpreter: python3 3 | # This just tests whether the parser accepts them all. 4 | 5 | import os 6 | 7 | PYLT_BIN = './pylite' 8 | 9 | for i in os.listdir('grammar'): 10 | if i.endswith('.py'): 11 | ret = os.popen('"%s" "./grammar/%s"' % (PYLT_BIN, i)).read() 12 | 13 | if 'ERROR at line' in ret: 14 | state = 'X' 15 | elif 'Traceback (most recent call last)' in ret: 16 | state = '-' 17 | else: 18 | state = 'O' 19 | print(ret) 20 | 21 | print('[%s] %s' % (state, i[:-3])) 22 | if state == 'X': 23 | i = ret.index('ERROR') 24 | print(ret[i:].strip()) 25 | -------------------------------------------------------------------------------- /src/mods/sys.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #include "sys.h" 7 | #include "../api.h" 8 | #include "../intp.h" 9 | #include "../bind.h" 10 | #include "../types/all.h" 11 | #include "../utils/misc.h" 12 | 13 | 14 | PyLiteModuleObject* pylt_mods_sys_loader(PyLiteInterpreter *I) { 15 | PyLiteModuleObject *mod = pylt_obj_module_new(I, _S(sys)); 16 | 17 | PyLiteModuleObject *mio = pl_getmod(I, _S(io)); 18 | PyLiteTypeObject *tTextIO = casttype(pylt_obj_mod_getattr(I, mio, _S(TextIO))); 19 | 20 | return mod; 21 | } 22 | 23 | pl_bool_t pylt_mods_sys_register(PyLiteInterpreter *I) { 24 | return pylt_mod_register(I, _S(sys), &pylt_mods_sys_loader, true); 25 | } 26 | -------------------------------------------------------------------------------- /src/types/extra/exception.c: -------------------------------------------------------------------------------- 1 | 2 | #include "exception.h" 3 | #include "../../gc.h" 4 | 5 | PyLiteBaseExceptionObject* pylt_obj_exception_new(PyLiteInterpreter *I, PyLiteTupleObject *args) { 6 | PyLiteObject_init(I, obj, PyLiteBaseExceptionObject, PYLT_OBJ_TYPE_BASE_EXCEPTION); 7 | obj->args = args ? args : pylt_obj_tuple_new(I, 0); 8 | obj->args->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 9 | return obj; 10 | } 11 | 12 | void pylt_obj_exception_rfree(PyLiteInterpreter *I, PyLiteBaseExceptionObject* self) { 13 | pylt_free_ex(I, self); 14 | } 15 | 16 | void pylt_obj_exception_free(PyLiteInterpreter *I, PyLiteBaseExceptionObject* self) { 17 | pylt_gc_remove(I, castobj(self)); 18 | pylt_obj_exception_rfree(I, self); 19 | } 20 | -------------------------------------------------------------------------------- /src/types/all.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_ALL_H 3 | #define PYLITE_TYPES_ALL_H 4 | 5 | #include "object.h" 6 | #include "common/number.h" 7 | #include "common/bool.h" 8 | 9 | #include "common/string.h" 10 | #include "common/bytes.h" 11 | #include "common/set.h" 12 | #include "common/list.h" 13 | #include "common/tuple.h" 14 | #include "common/dict.h" 15 | #include "common/type.h" 16 | #include "common/unusual.h" 17 | 18 | #include "extra/module.h" 19 | #include "extra/function.h" 20 | #include "extra/code.h" 21 | 22 | #include "extra/iter.h" 23 | #include "extra/property.h" 24 | #include "extra/none.h" 25 | #include "extra/cpointer.h" 26 | 27 | #include "extra/range.h" 28 | #include "extra/exception.h" 29 | 30 | #include "custom.h" 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/types/extra/none.c: -------------------------------------------------------------------------------- 1 | 2 | #include "none.h" 3 | 4 | PyLiteNoneObject PyLiteNone = { PYLT_OBJ_TYPE_NONE, PYLT_OBJ_FLAG_STATIC }; 5 | 6 | 7 | pl_int_t pylt_obj_none_cmp(PyLiteInterpreter *I, PyLiteNoneObject *self, PyLiteObject *other) { 8 | return 2; 9 | } 10 | 11 | pl_bool_t pylt_obj_none_eq(PyLiteInterpreter *I, PyLiteNoneObject *self, PyLiteObject *other) { 12 | switch (other->ob_type) { 13 | case PYLT_OBJ_TYPE_NONE: 14 | return true; 15 | default: 16 | return false; 17 | } 18 | } 19 | 20 | pl_uint32_t pylt_obj_none_chash(PyLiteInterpreter *I, PyLiteNoneObject *obj) { 21 | return 0xCAFEBABE; 22 | } 23 | 24 | PyLiteNoneObject* pylt_obj_none_new(PyLiteInterpreter *I) { 25 | return &PyLiteNone; 26 | } 27 | -------------------------------------------------------------------------------- /src/types/common/bool.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_BOOL_H 3 | #define PYLITE_TYPES_BOOL_H 4 | 5 | #include "../object.h" 6 | 7 | typedef struct PyLiteBoolObject { 8 | PyLiteObject_HEAD; 9 | bool ob_val; 10 | } PyLiteBoolObject; 11 | 12 | pl_int_t pylt_obj_bool_cmp(PyLiteInterpreter *I, PyLiteBoolObject *self, PyLiteObject *other); 13 | pl_bool_t pylt_obj_bool_eq(PyLiteInterpreter *I, PyLiteBoolObject *self, PyLiteObject *other); 14 | pl_uint32_t pylt_obj_bool_hash(PyLiteInterpreter *I, PyLiteBoolObject *obj); 15 | struct PyLiteStrObject* pylt_obj_bool_to_str(PyLiteInterpreter *I, PyLiteBoolObject *self); 16 | 17 | PyLiteBoolObject* pylt_obj_bool_new(PyLiteInterpreter *I, bool val); 18 | 19 | PyLiteBoolObject PyLiteTrue; 20 | PyLiteBoolObject PyLiteFalse; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tests/grammar/test_5_class.py: -------------------------------------------------------------------------------- 1 | 2 | class B: pass 3 | class B2(): pass 4 | class C1(B): pass 5 | class C2(B): pass 6 | #class D(C1, C2, B): pass 7 | class C: 8 | def meth1(self): pass 9 | def meth2(self, arg): pass 10 | def meth3(self, a1, a2): pass 11 | 12 | #def class_decorator(x): return x 13 | #@class_decorator 14 | #class G: pass 15 | 16 | 17 | class A: 18 | def test(self): 19 | print(self) 20 | return 1 21 | 22 | def test2(self, a): 23 | print(a) 24 | 25 | def __call__(self): 26 | print('__call__', self, type(self)) 27 | 28 | def __hash__(self): 29 | return 111 30 | 31 | a = A() 32 | b = A() 33 | A.b = 1 34 | 35 | class B(A): 36 | pass 37 | 38 | b = B() 39 | 40 | assert B.__base__ == A 41 | -------------------------------------------------------------------------------- /src/deps/linenoise/osfix/linuxfix.c: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _WIN32 3 | #include "linuxfix.h" 4 | #include 5 | #include 6 | 7 | int mycrt_read(int fd, void *buffer, unsigned int count) { 8 | wchar_t *s = (wchar_t *)buffer; 9 | for (unsigned int i = 0; i < count; ++i) { 10 | *s++ = fgetwc(stdin); 11 | } 12 | return count; 13 | } 14 | 15 | int mycrt_write(int fd, void *buffer, unsigned int count) { 16 | FILE *fp = NULL; 17 | wchar_t *s = (wchar_t *)buffer; 18 | 19 | if (fd == fileno(stdout)) fp = stdout; 20 | else if (fd == fileno(stderr)) fp = stderr; 21 | else return 0; 22 | 23 | for (unsigned int i = 0; i < count; ++i) { 24 | fputwc(s[i], fp); 25 | } 26 | fflush(fp); 27 | return count; 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/types/extra/property.c: -------------------------------------------------------------------------------- 1 | 2 | #include "property.h" 3 | #include "../../gc.h" 4 | 5 | PyLitePropertyObject* pylt_obj_property_new(PyLiteInterpreter *I, PyLiteObject *fget, PyLiteObject *fset) { 6 | PyLiteObject_init(I, obj, PyLitePropertyObject, PYLT_OBJ_TYPE_PROP); 7 | obj->fget.func = fget; 8 | obj->fset.func = fset; 9 | if (fget) fget->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 10 | if (fset) fset->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 11 | obj->ob_owner = NULL; 12 | return obj; 13 | } 14 | 15 | void pylt_obj_property_rfree(PyLiteInterpreter *I, PyLitePropertyObject *self) { 16 | pylt_free_ex(I, self); 17 | } 18 | 19 | void pylt_obj_property_free(PyLiteInterpreter *I, PyLitePropertyObject *self) { 20 | pylt_gc_remove(I, castobj(self)); 21 | pylt_obj_property_rfree(I, self); 22 | } 23 | -------------------------------------------------------------------------------- /src/types/extra/range.c: -------------------------------------------------------------------------------- 1 | 2 | #include "range.h" 3 | #include "../../utils/misc.h" 4 | #include "../../gc.h" 5 | 6 | PyLiteRangeObject* pylt_obj_range_new(PyLiteInterpreter *I, pl_int_t start, pl_int_t stop, pl_int_t step) { 7 | PyLiteObject_init(I, obj, PyLiteRangeObject, PYLT_OBJ_TYPE_RANGE); 8 | obj->start = start; 9 | obj->stop = stop; 10 | obj->step = step; 11 | return obj; 12 | } 13 | 14 | pl_int_t pylt_obj_range_itertimes(PyLiteInterpreter *I, PyLiteRangeObject* range) { 15 | return max(0, (pl_int_t)ceil((range->stop - range->start) / range->step)); 16 | } 17 | 18 | void pylt_obj_range_rfree(PyLiteInterpreter *I, PyLiteRangeObject* self) { 19 | pylt_free_ex(I, self); 20 | } 21 | 22 | void pylt_obj_range_free(PyLiteInterpreter *I, PyLiteRangeObject* self) { 23 | pylt_gc_remove(I, castobj(self)); 24 | pylt_obj_range_rfree(I, self); 25 | } 26 | -------------------------------------------------------------------------------- /src/mods/unusualm.c: -------------------------------------------------------------------------------- 1 | 2 | #include "unusualm.h" 3 | #include "../bind.h" 4 | #include "../types/all.h" 5 | #include "../utils/misc.h" 6 | 7 | 8 | PyLiteModuleObject* pylt_mods_unusual_loader(PyLiteInterpreter *I) { 9 | PyLiteModuleObject *mod = pylt_obj_module_new(I, NULL); 10 | pylt_obj_mod_setattr(I, mod, _S(useless), castobj(&PyLiteUseless)); 11 | pylt_obj_mod_setattr(I, mod, _S(NotImplemented), castobj(&PyLiteNotImplemented)); 12 | pylt_obj_mod_setattr(I, mod, _S(param_args), castobj(&PyLiteParamArgs)); 13 | pylt_obj_mod_setattr(I, mod, _S(param_kwargs), castobj(&PyLiteParamKwargs)); 14 | pylt_obj_mod_setattr(I, mod, _S(param_undefined), castobj(&PyLiteParamUndefined)); 15 | return mod; 16 | } 17 | 18 | pl_bool_t pylt_mods_unusual_register(PyLiteInterpreter *I) { 19 | return pylt_mod_register(I, _S(unusual), &pylt_mods_unusual_loader, true); 20 | } 21 | -------------------------------------------------------------------------------- /src/types/extra/property.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_PROPERTY_H 3 | #define PYLITE_TYPES_PROPERTY_H 4 | 5 | #include "../object.h" 6 | #include "function.h" 7 | 8 | typedef struct PyLitePropertyObject { 9 | PyLiteObject_HEAD; 10 | union { 11 | PyLiteCFunctionObject *cfunc; 12 | PyLiteFunctionObject *pyfunc; 13 | PyLiteObject *func; 14 | } fget; 15 | union { 16 | PyLiteCFunctionObject *cfunc; 17 | PyLiteFunctionObject *pyfunc; 18 | PyLiteObject *func; 19 | } fset; 20 | PyLiteObject *ob_owner; /* owner of object */ 21 | } PyLitePropertyObject; 22 | 23 | PyLitePropertyObject* pylt_obj_property_new(PyLiteInterpreter *I, PyLiteObject *fget, PyLiteObject *fset); 24 | void pylt_obj_property_rfree(PyLiteInterpreter *I, PyLitePropertyObject *self); 25 | void pylt_obj_property_free(PyLiteInterpreter *I, PyLitePropertyObject *self); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/deps/fpconv/fpconv.h: -------------------------------------------------------------------------------- 1 | #ifndef FPCONV_H 2 | #define FPCONV_H 3 | 4 | /* Fast and accurate double to string conversion based on Florian Loitsch's 5 | * Grisu-algorithm[1]. 6 | * 7 | * Input: 8 | * fp -> the double to convert, dest -> destination buffer. 9 | * The generated string will never be longer than 24 characters. 10 | * Make sure to pass a pointer to at least 24 bytes of memory. 11 | * The emitted string will not be null terminated. 12 | * 13 | * Output: 14 | * The number of written characters. 15 | * 16 | * Exemplary usage: 17 | * 18 | * void print(double d) 19 | * { 20 | * char buf[24 + 1] // plus null terminator 21 | * int str_len = fpconv_dtoa(d, buf); 22 | * 23 | * buf[str_len] = '\0'; 24 | * wprintf(L"%s", buf); 25 | * } 26 | * 27 | */ 28 | 29 | int fpconv_dtoa(double fp, char dest[24]); 30 | 31 | #endif 32 | 33 | /* [1] http://florian.loitsch.com/publications/dtoa-pldi2010.pdf */ 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 fy 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 19 | 3. This notice may not be removed or altered from any source 20 | distribution. 21 | 22 | -------------------------------------------------------------------------------- /src/utils/config.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_CONFIG_H 3 | #define PYLITE_CONFIG_H 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | typedef intptr_t pl_int_t; 10 | typedef uintptr_t pl_uint_t; 11 | typedef int32_t pl_int32_t; 12 | typedef uint32_t pl_uint32_t; 13 | typedef double pl_float_t; 14 | typedef bool pl_bool_t; 15 | 16 | typedef struct PyLiteInterpreter PyLiteInterpreter; 17 | 18 | #define PYLT_PATH_BUF_SIZE 256 19 | #define PYLT_PATH_BUF_WSIZE 256 20 | 21 | #define PYLT_LEX_BYTES_DEFAULT_BUFFER_SIZE 64 22 | #define PYLT_LEX_BYTES_DEFAULT_BUFFER_INC_STEP 32 23 | #define PYLT_LEX_STR_DEFAULT_BUFFER_SIZE 24 24 | #define PYLT_LEX_STR_DEFAULT_BUFFER_INC_STEP 24 25 | 26 | void* pylt_realloc(PyLiteInterpreter *I, void* m, size_t osize, size_t nsize); 27 | #define pylt_malloc(I, size) pylt_realloc(I, NULL, 0, size) 28 | #define pylt_free(I, m, s) pylt_realloc(I, (m), (s), 0) 29 | #define pylt_free_ex(I, m) pylt_realloc(I, (m), sizeof(*(m)), 0) 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/pybind/extra.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_BIND_EXTRA_H 3 | #define PYLITE_BIND_EXTRA_H 4 | 5 | #include "../types/object.h" 6 | 7 | // function/cfunction 8 | PyLiteObject* pylt_cls_method_function_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 9 | PyLiteObject* pylt_prop_function_args_types_get(PyLiteInterpreter *I, int argc, PyLiteObject **args); 10 | PyLiteObject* pylt_prop_function_defaults_get(PyLiteInterpreter *I, int argc, PyLiteObject **args); 11 | PyLiteObject* pylt_prop_function_parameters_get(PyLiteInterpreter *I, int argc, PyLiteObject **args); 12 | 13 | PyLiteObject* pylt_cls_method_iter_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 14 | 15 | PyLiteObject* pylt_cls_method_range_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 16 | 17 | PyLiteObject* pylt_cls_method_base_exception_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 18 | PyLiteObject* pylt_prop_base_exception_args_get(PyLiteInterpreter *I, int argc, PyLiteObject **args); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/types/extra/code.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_CODE_SNIPPET_H 3 | #define PYLITE_TYPES_CODE_SNIPPET_H 4 | 5 | #include "../object.h" 6 | #include "../common/set.h" 7 | #include "../common/list.h" 8 | #include "../../deps/kvec.h" 9 | 10 | typedef struct PyLiteInstruction { 11 | uint8_t code; 12 | uint8_t exarg; 13 | int16_t extra; 14 | } PyLiteInstruction; 15 | 16 | typedef struct PyLiteCodeObject { 17 | PyLiteObject_HEAD; 18 | PyLiteListObject *const_val; 19 | PyLiteSetObject *closure; 20 | kvec_t(PyLiteInstruction) opcodes; 21 | 22 | pl_bool_t with_debug_info; 23 | kvec_t(uint32_t) lnotab; 24 | } PyLiteCodeObject; 25 | 26 | void pylt_obj_code_add_to_gc(PyLiteInterpreter *I, PyLiteCodeObject *self); 27 | 28 | PyLiteCodeObject* pylt_obj_code_new(PyLiteInterpreter *I, pl_bool_t with_debug_info); 29 | void pylt_obj_code_rfree(PyLiteInterpreter *I, PyLiteCodeObject* self); 30 | void pylt_obj_code_free(PyLiteInterpreter *I, PyLiteCodeObject* self); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/types/custom.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_CUTSOM_H 3 | #define PYLITE_TYPES_CUTSOM_H 4 | 5 | #include "object.h" 6 | #include "common/dict.h" 7 | 8 | // Custom object 9 | 10 | typedef struct PyLiteCustomObject { 11 | uint32_t ob_type; 12 | uint32_t ob_flags; 13 | uint32_t ob_base; 14 | PyLiteDictObject *ob_attrs; 15 | PyLiteObject *base_obj; 16 | } PyLiteCustomObject; 17 | 18 | #define PyLiteCustomObject_HEAD \ 19 | uint32_t ob_type; \ 20 | uint32_t ob_flags; \ 21 | uint32_t ob_base; \ 22 | PyLiteDictObject *ob_attrs 23 | 24 | PyLiteObject* pylt_obj_cutstom_create(PyLiteInterpreter *I, uint32_t ob_type, PyLiteObject *base_obj); 25 | PyLiteObject* pylt_obj_custom_getattr(PyLiteInterpreter *I, PyLiteCustomObject *self, PyLiteObject *key, pl_bool_t *p_at_type); 26 | void pylt_obj_custom_setattr(PyLiteInterpreter *I, PyLiteCustomObject *self, PyLiteObject* key, PyLiteObject* value); 27 | pl_bool_t pylt_obj_custom_delattr(PyLiteInterpreter *I, PyLiteCustomObject *self, PyLiteObject* key); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/types/common/tuple.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_TUPLE_H 3 | #define PYLITE_TYPES_TUPLE_H 4 | 5 | #include "../object.h" 6 | 7 | typedef struct PyLiteTupleObject { 8 | PyLiteObject_HEAD; 9 | pl_int_t ob_size; 10 | PyLiteObject **ob_val; 11 | } PyLiteTupleObject; 12 | 13 | pl_bool_t pylt_obj_tuple_eq(PyLiteInterpreter *I, PyLiteTupleObject *self, PyLiteObject *other); 14 | 15 | struct PyLiteStrObject* pylt_obj_tuple_to_str(PyLiteInterpreter *I, PyLiteTupleObject *self); 16 | 17 | PyLiteObject* pylt_obj_tuple_getitem(PyLiteInterpreter *I, PyLiteTupleObject *self, int index); 18 | PyLiteTupleObject* pylt_obj_tuple_slice(PyLiteInterpreter *I, PyLiteTupleObject *self, pl_int_t *pstart, pl_int_t *pend, pl_int_t step); 19 | 20 | PyLiteTupleObject* pylt_obj_tuple_new(PyLiteInterpreter *I, pl_int_t size); 21 | PyLiteTupleObject* pylt_obj_tuple_new_with_data(PyLiteInterpreter *I, pl_int_t len, void *data); 22 | 23 | void pylt_obj_tuple_rfree(PyLiteInterpreter *I, PyLiteTupleObject *self); 24 | void pylt_obj_tuple_free(PyLiteInterpreter *I, PyLiteTupleObject *self); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/deps/fpconv/license: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2013 Andreas Samoljuk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /src/types/extra/module.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_MODULE_H 3 | #define PYLITE_TYPES_MODULE_H 4 | 5 | #include "../object.h" 6 | #include "../common/string.h" 7 | #include "../common/dict.h" 8 | #include "code.h" 9 | 10 | typedef struct PyLiteModuleObject { 11 | PyLiteObject_HEAD; 12 | PyLiteDictObject *ob_attrs; 13 | PyLiteCodeObject *code; 14 | 15 | pl_bool_t is_package; // is package(directory) 16 | PyLiteStrObject *name; // module name 17 | PyLiteObject *ob_owner; // owner of object 18 | // __file__, etc. 19 | } PyLiteModuleObject; 20 | 21 | PyLiteModuleObject* pylt_obj_module_new_ex(PyLiteInterpreter *I, PyLiteObject *owner, PyLiteStrObject *name); 22 | PyLiteModuleObject* pylt_obj_module_new(PyLiteInterpreter *I, PyLiteStrObject *name); 23 | void pylt_obj_mod_setattr(PyLiteInterpreter *I, PyLiteModuleObject *mod, PyLiteStrObject *key, PyLiteObject *value); 24 | PyLiteObject* pylt_obj_mod_getattr(PyLiteInterpreter *I, PyLiteModuleObject *self, PyLiteStrObject *key); 25 | void pylt_obj_module_rfree(PyLiteInterpreter *I, PyLiteModuleObject *self); 26 | void pylt_obj_module_free(PyLiteInterpreter *I, PyLiteModuleObject *self); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/types/common/unusual.c: -------------------------------------------------------------------------------- 1 | 2 | #include "unusual.h" 3 | #include "string.h" 4 | 5 | PyLiteUnusualObject PyLiteUseless = { PYLT_OBJ_TYPE_UNUSUAL, PYLT_OBJ_FLAG_STATIC }; 6 | PyLiteUnusualObject PyLiteNotImplemented = { PYLT_OBJ_TYPE_UNUSUAL, PYLT_OBJ_FLAG_STATIC }; 7 | 8 | PyLiteUnusualObject PyLiteParamArgs = { PYLT_OBJ_TYPE_UNUSUAL, PYLT_OBJ_FLAG_STATIC }; 9 | PyLiteUnusualObject PyLiteParamKwargs = { PYLT_OBJ_TYPE_UNUSUAL, PYLT_OBJ_FLAG_STATIC }; 10 | PyLiteUnusualObject PyLiteParamUndefined = { PYLT_OBJ_TYPE_UNUSUAL, PYLT_OBJ_FLAG_STATIC }; 11 | 12 | 13 | struct PyLiteStrObject* pylt_obj_unusual_to_str(PyLiteInterpreter *I, PyLiteUnusualObject *self) { 14 | if (self == &PyLiteNotImplemented) return pylt_obj_str_new_from_cstr(I, "NotImplemented", true); 15 | if (self == &PyLiteUseless) return pylt_obj_str_new_from_cstr(I, "", true); 16 | if (self == &PyLiteParamArgs) return pylt_obj_str_new_from_cstr(I, "", true); 17 | if (self == &PyLiteParamKwargs) return pylt_obj_str_new_from_cstr(I, "", true); 18 | if (self == &PyLiteParamUndefined) return pylt_obj_str_new_from_cstr(I, "", true); 19 | return NULL; 20 | } 21 | -------------------------------------------------------------------------------- /src/utils/io/_io.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_UTILS_IO_H 3 | #define PYLITE_UTILS_IO_H 4 | 5 | #include 6 | #include "io_base.h" 7 | #include "fs_base.h" 8 | #include "io_simple.h" 9 | 10 | PyLiteFile* pylt_io_open(PyLiteInterpreter *I, PyLiteStrObject *fn, int mode, int encoding); 11 | PyLiteFile* pylt_io_open_full(PyLiteInterpreter *I, PyLiteIO *io, PyLiteStrObject *fn, int mode, int encoding); 12 | 13 | pl_bool_t pylt_io_readable(PyLiteInterpreter *I, PyLiteFile *pf); 14 | pl_bool_t pylt_io_writeable(PyLiteInterpreter *I, PyLiteFile *pf); 15 | PyLiteStrObject* pylt_io_getencoding(PyLiteInterpreter *I, PyLiteFile *pf); 16 | 17 | int pylt_io_read(PyLiteInterpreter *I, PyLiteFile *pf, uint8_t *buf, pl_uint_t count); 18 | int pylt_io_readstr(PyLiteInterpreter *I, PyLiteFile *pf, uint32_t *buf, pl_uint_t count); 19 | 20 | int pylt_io_write(PyLiteInterpreter *I, PyLiteFile *pf, uint8_t *buf, pl_uint_t count); 21 | int pylt_io_writestr(PyLiteInterpreter *I, PyLiteFile *pf, uint32_t *buf, pl_uint_t count); 22 | 23 | int pylt_io_mode_to_posix(int mode); 24 | int pylt_io_mode_parse(PyLiteStrObject *mode, int *perr); 25 | 26 | FILE* pylt_io_fopen(PyLiteInterpreter *I, PyLiteStrObject *fn, PyLiteStrObject *mode); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /tests/grammar/test_6_except.py: -------------------------------------------------------------------------------- 1 | 2 | # raise 3 | 4 | try: raise RuntimeError('just testing') 5 | except RuntimeError: pass 6 | try: raise KeyboardInterrupt 7 | except KeyboardInterrupt: pass 8 | 9 | 10 | # try - except - finally 11 | 12 | try: 13 | 1/0 14 | except ZeroDivisionError: 15 | pass 16 | 17 | try: 1/0 18 | except EOFError: pass 19 | except TypeError as msg: pass 20 | except RuntimeError as msg: pass 21 | except: pass 22 | 23 | try: 1/0 24 | except (EOFError, TypeError, ZeroDivisionError): pass 25 | try: 1/0 26 | except (EOFError, TypeError, ZeroDivisionError) as msg: pass 27 | try: pass 28 | finally: pass 29 | 30 | 31 | try: 32 | a = 1 33 | asd 34 | except OSError: 35 | b = 2 36 | except NameError as e: 37 | #print(e) 38 | b = 4 39 | except: 40 | b = 3 41 | finally: 42 | b = 10 43 | 44 | 45 | try: 46 | a = 1 47 | except OSError: 48 | pass 49 | except NameError: 50 | pass 51 | except Exception as e: 52 | print(e) 53 | a = 2 54 | finally: 55 | d = 4 56 | 57 | c = 3 58 | 59 | try: 60 | for i, j, k in ((1,2),): 61 | pass 62 | except ValueError: 63 | pass 64 | 65 | try: 66 | for i, j, k in ((1,2,3,4),): 67 | pass 68 | except ValueError: 69 | pass 70 | -------------------------------------------------------------------------------- /src/deps/platform.c: -------------------------------------------------------------------------------- 1 | 2 | #include "platform.h" 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | void platform_init() { 9 | setlocale(LC_CTYPE, ""); 10 | } 11 | 12 | #ifdef PLATFORM_WINDOWS 13 | #include 14 | 15 | wchar_t* _utf8_to_16(const char* str) { 16 | int nwLen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); 17 | 18 | wchar_t *pwBuf = malloc(sizeof(wchar_t) * (nwLen + 1)); 19 | memset(pwBuf, 0, nwLen * 2 + 2); 20 | 21 | MultiByteToWideChar(CP_UTF8, 0, str, strlen(str), pwBuf, nwLen); 22 | 23 | return pwBuf; 24 | } 25 | #endif 26 | 27 | 28 | void printf_u8(const char *fmt, ...) { 29 | #if defined(PLATFORM_WINDOWS) 30 | int size; 31 | 32 | va_list args; 33 | va_start(args, fmt); 34 | size = vsnprintf(NULL, 0, fmt, args); 35 | va_end(args); 36 | 37 | char *buf = malloc(sizeof(char) * (size + 1)); 38 | 39 | va_start(args, fmt); 40 | vsprintf(buf, fmt, args); 41 | va_end(args); 42 | 43 | wchar_t* final_str = _utf8_to_16(buf); 44 | wprintf(final_str); 45 | 46 | free(buf); 47 | free(final_str); 48 | #else 49 | va_list args; 50 | va_start(args, fmt); 51 | vprintf(fmt, args); 52 | va_end(args); 53 | #endif 54 | } 55 | -------------------------------------------------------------------------------- /src/types/extra/code.c: -------------------------------------------------------------------------------- 1 | 2 | #include "code.h" 3 | #include "../../gc.h" 4 | 5 | 6 | void pylt_obj_code_add_to_gc(PyLiteInterpreter *I, PyLiteCodeObject *self) { 7 | PyLiteObject *obj; 8 | PyLiteListObject *lst = self->const_val; 9 | for (pl_int_t i = 0; i < lst->ob_size; ++i) { 10 | obj = lst->ob_val[i]; 11 | if (pl_iscode(obj)) pylt_obj_code_add_to_gc(I, castcode(obj)); 12 | else pylt_gc_add(I, obj); 13 | } 14 | pylt_gc_add(I, castobj(self)); 15 | } 16 | 17 | PyLiteCodeObject* pylt_obj_code_new(PyLiteInterpreter *I, pl_bool_t with_debug_info) { 18 | PyLiteObject_init(I, obj, PyLiteCodeObject, PYLT_OBJ_TYPE_CODE); 19 | obj->const_val = pylt_obj_list_new(I); 20 | obj->const_val->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 21 | obj->closure = NULL; 22 | kv_init(I, obj->opcodes); 23 | obj->with_debug_info = with_debug_info; 24 | if (with_debug_info) { 25 | kv_init(I, obj->lnotab); 26 | } 27 | return obj; 28 | } 29 | 30 | void pylt_obj_code_rfree(PyLiteInterpreter *I, PyLiteCodeObject* self) { 31 | //pylt_obj_list_free(I, self->const_val); 32 | kv_destroy(self->opcodes); 33 | pylt_free_ex(I, self); 34 | } 35 | 36 | void pylt_obj_code_free(PyLiteInterpreter *I, PyLiteCodeObject* self) { 37 | pylt_gc_remove(I, castobj(self)); 38 | pylt_obj_code_rfree(I, self); 39 | } 40 | -------------------------------------------------------------------------------- /tests/grammar/test_1_basetype.py: -------------------------------------------------------------------------------- 1 | 2 | # int 3 | 1 4 | 111 5 | 2147483647 6 | 7 | 0xff 8 | 0o377 9 | 0b1001 10 | 11 | -1 12 | -111 13 | -2147483648 14 | -0xff 15 | -0o337 16 | -0b1001 17 | 18 | 19 | # float 20 | 3.14 21 | 314. 22 | 0.314 23 | .314 24 | #3e14 25 | #3E14 26 | #3e-14 27 | #3e+14 28 | #3.e14 29 | #.3e14 30 | #3.1e4 31 | 32 | 33 | # bool 34 | True 35 | False 36 | 37 | 38 | # unusual 39 | None 40 | NotImplemented 41 | 42 | 43 | # str 44 | 'test' 45 | "test" 46 | '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n' 47 | "doesn't \"shrink\" does it" 48 | 'doesn\'t "shrink" does it' 49 | "does \"shrink\" doesn't it" 50 | 'does "shrink" doesn\'t it' 51 | """ 52 | The "quick" 53 | brown fox 54 | jumps over 55 | the 'lazy' dog. 56 | """ 57 | ''' 58 | The "quick" 59 | brown fox 60 | jumps over 61 | the 'lazy' dog. 62 | ''' 63 | 64 | 65 | # bytes 66 | b'bytes' 67 | b'123\'' 68 | b"123\"" 69 | b'''123''' 70 | b'''123\'''' 71 | 72 | 73 | # tuple 74 | () 75 | 1,2,3 76 | 1,2,3, 77 | (1,2,3) 78 | (1,2,3,) 79 | (1,2,3,(1,),(1,2,3)) 80 | 81 | 82 | # list 83 | [] 84 | [1,2,3] 85 | [1,2,3,] 86 | [1,2,3,(1,),(1,2,3)] 87 | 88 | 89 | # dict 90 | {} 91 | { 92 | 'a': 1, 93 | } 94 | { 95 | 'a': 1 96 | } 97 | 98 | 99 | # set 100 | {1,2,3} 101 | {1,2,3,} 102 | 103 | -------------------------------------------------------------------------------- /src/utils/io/io_base.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_UTILS_IO_BASE_H 3 | #define PYLITE_UTILS_IO_BASE_H 4 | 5 | #include "../../types/all.h" 6 | 7 | enum PYLT_IO_TEXT_ENCODING { 8 | PYLT_IOTE_UTF8 = 1, 9 | PYLT_IOTE_UTF16 = 2, 10 | PYLT_IOTE_UCS4 = 4, 11 | PYLT_IOTE_WCHAR = 8 12 | }; 13 | 14 | enum PYLT_IO_MODE { 15 | PYLT_IOMODE_READ = 1, 16 | PYLT_IOMODE_WRITE = 2, 17 | PYLT_IOMODE_APPEND = 4, 18 | PYLT_IOMODE_CREATE = 8, // EXCL 19 | 20 | PYLT_IOMODE_PLUS = 16, 21 | PYLT_IOMODE_BINARY = 32, 22 | }; 23 | 24 | typedef struct PyLiteIO; 25 | 26 | typedef struct { 27 | void *data; 28 | int mode; 29 | int encoding; 30 | struct PyLiteIO *io; 31 | } PyLiteFile; 32 | 33 | typedef void* (*PyLiteIOFileOpenFunc)(PyLiteInterpreter *I, PyLiteStrObject *fn, int openmode); 34 | typedef pl_int_t(*PyLiteIOFileCloseFunc)(PyLiteInterpreter *I, void *pfdata); 35 | typedef pl_int_t(*PyLiteIOReadFunc)(PyLiteInterpreter *I, void *pfdata, uint8_t *buf, pl_uint_t count); 36 | typedef pl_int_t(*PyLiteIOWriteFunc)(PyLiteInterpreter *I, void *pfdata, uint8_t *buf, pl_uint_t count); 37 | 38 | typedef struct PyLiteIO { 39 | PyLiteIOFileOpenFunc open; 40 | PyLiteIOFileCloseFunc close; 41 | PyLiteIOReadFunc read; 42 | PyLiteIOWriteFunc write; 43 | } PyLiteIO; 44 | 45 | #define pylt_io_openRead(I, fn) \ 46 | pylt_io_open(I, fn, PYLT_IOMODE_READ, PYLT_IOTE_UTF8) 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/types/extra/module.c: -------------------------------------------------------------------------------- 1 | 2 | #include "module.h" 3 | #include "../common/dict.h" 4 | #include "../../gc.h" 5 | 6 | PyLiteModuleObject* pylt_obj_module_new_ex(PyLiteInterpreter *I, PyLiteObject *owner, PyLiteStrObject *name) { 7 | PyLiteObject_init(I, obj, PyLiteModuleObject, PYLT_OBJ_TYPE_MODULE); 8 | obj->ob_attrs = pylt_obj_dict_new(I); 9 | obj->ob_attrs->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 10 | obj->ob_owner = owner; 11 | obj->name = name; 12 | obj->is_package = false; 13 | return obj; 14 | } 15 | 16 | PyLiteModuleObject* pylt_obj_module_new(PyLiteInterpreter *I, PyLiteStrObject *name) { 17 | return pylt_obj_module_new_ex(I, NULL, name); // owner NULL is interpreter 18 | } 19 | 20 | void pylt_obj_mod_setattr(PyLiteInterpreter *I, PyLiteModuleObject *mod, PyLiteStrObject *key, PyLiteObject *value) { 21 | pylt_obj_dict_setitem(I, (mod)->ob_attrs, castobj(key), value); 22 | } 23 | 24 | PyLiteObject* pylt_obj_mod_getattr(PyLiteInterpreter *I, PyLiteModuleObject *self, PyLiteStrObject *key) { 25 | return pylt_obj_dict_getitem(I, self->ob_attrs, castobj(key)); 26 | } 27 | 28 | void pylt_obj_module_rfree(PyLiteInterpreter *I, PyLiteModuleObject *self) { 29 | //pylt_obj_dict_free(I, self->ob_attrs); 30 | pylt_free_ex(I, self); 31 | } 32 | 33 | void pylt_obj_module_free(PyLiteInterpreter *I, PyLiteModuleObject *self) { 34 | pylt_gc_remove(I, castobj(self)); 35 | pylt_obj_module_rfree(I, self); 36 | } 37 | -------------------------------------------------------------------------------- /src/types/common/type.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_TYPE_H 3 | #define PYLITE_TYPES_TYPE_H 4 | 5 | #include "../object.h" 6 | #include "string.h" 7 | #include "dict.h" 8 | 9 | typedef struct PyLiteTypeObject { 10 | PyLiteObject_HEAD; 11 | PyLiteStrObject *name; /* type name */ 12 | pl_uint32_t ob_reftype; /* type code */ 13 | pl_uint32_t ob_base; /* parent type code */ 14 | PyLiteDictObject *ob_attrs; /* attrs */ 15 | PyLiteObject *ob_owner; /* owner of object */ 16 | pl_bool_t allow_inherit; 17 | } PyLiteTypeObject; 18 | 19 | PyLiteTypeObject* pylt_obj_type_new_with_type(PyLiteInterpreter *I, PyLiteStrObject *name, pl_uint32_t instance_type, pl_uint32_t base_type); 20 | PyLiteTypeObject* pylt_obj_type_new(PyLiteInterpreter *I, PyLiteStrObject *name, pl_uint32_t base_type, PyLiteDictObject *dict); 21 | 22 | PyLiteObject* pylt_obj_type_getattr(PyLiteInterpreter *I, PyLiteTypeObject *self, PyLiteObject *key, pl_bool_t *p_at_type); 23 | void pylt_obj_type_setattr(PyLiteInterpreter *I, PyLiteTypeObject *self, PyLiteObject* key, PyLiteObject* value); 24 | pl_bool_t pylt_obj_type_delattr(PyLiteInterpreter *I, PyLiteTypeObject *self, PyLiteObject* key); 25 | pl_uint32_t pylt_obj_type_hash(PyLiteInterpreter *I, PyLiteTypeObject *self); 26 | 27 | void pylt_obj_type_rfree(PyLiteInterpreter *I, PyLiteTypeObject *self); 28 | void pylt_obj_type_free(PyLiteInterpreter *I, PyLiteTypeObject *self); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/deps/linenoise/osfix/winfix.c: -------------------------------------------------------------------------------- 1 | 2 | #ifdef _WIN32 3 | 4 | #include 5 | #include 6 | #include "winfix.h" 7 | #include "Win32_ANSI.h" 8 | 9 | int mycrt_read(int fd, void *buffer, unsigned int count) { 10 | //return _read(fd, buffer, count); 11 | wchar_t *s = (wchar_t *)buffer; 12 | for (unsigned int i = 0; i < count; ++i) { 13 | *s++ = fgetwc(stdin); 14 | } 15 | return count; 16 | } 17 | 18 | int mycrt_write(int fd, void *buffer, unsigned int count) { 19 | if (fd == _fileno(stdout)) { 20 | DWORD bytesWritten = 0; 21 | if (FALSE != ParseAndPrintWString(GetStdHandle(STD_OUTPUT_HANDLE), buffer, (DWORD)count, &bytesWritten)) { 22 | return (int)bytesWritten; 23 | } else { 24 | errno = GetLastError(); 25 | return 0; 26 | } 27 | } else if (fd == _fileno(stderr)) { 28 | DWORD bytesWritten = 0; 29 | if (FALSE != ParseAndPrintWString(GetStdHandle(STD_ERROR_HANDLE), buffer, (DWORD)count, &bytesWritten)) { 30 | return (int)bytesWritten; 31 | } else { 32 | errno = GetLastError(); 33 | return 0; 34 | } 35 | } else { 36 | int retval = _write(fd, buffer, (unsigned int)count); 37 | if (retval == -1) { 38 | errno = GetLastError(); 39 | } 40 | return retval; 41 | } 42 | } 43 | 44 | int mycrt_isatty(int fd) { 45 | return _isatty(fd); 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/intp.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_STATE_H 3 | #define PYLITE_STATE_H 4 | 5 | #include "vm.h" 6 | #include "gc.h" 7 | #include "lexer.h" 8 | #include "parser.h" 9 | #include "deps/kvec.h" 10 | #include "types/common/set.h" 11 | #include "types/common/type.h" 12 | #include "utils/io/_io.h" 13 | 14 | typedef struct { 15 | PyLiteIO *defio; 16 | PyLiteFS *deffs; 17 | #ifdef PYLT_EXTMOD 18 | PyLiteFile *cin; 19 | PyLiteFile *cout; 20 | PyLiteFile *cerr; 21 | #endif 22 | } PyLiteSys; 23 | 24 | typedef struct PyLiteInterpreter { 25 | PyLiteVM vm; 26 | PyLiteGC gc; 27 | LexState *lexer; 28 | ParserState *parser; 29 | PyLiteSys sys; 30 | 31 | // loaded modules 32 | PyLiteDictObject *modules; 33 | // keys are modpaths(os/re/test.a) and values are their load functions 34 | PyLiteDictObject *cmodules_loader; 35 | // exception object when error occurred. NULL as default. 36 | PyLiteObject *error; 37 | // the last called func object 38 | PyLiteObject *recent_called; 39 | 40 | pl_uint_t mem_used; 41 | pl_int_t class_num; 42 | kvec_t(PyLiteTypeObject*) cls_base; 43 | } PyLiteInterpreter; 44 | 45 | PyLiteInterpreter* pylt_intp_new(); 46 | void pylt_intp_free(PyLiteInterpreter *I); 47 | 48 | void pylt_intp_init(PyLiteInterpreter *I); 49 | void pylt_intp_finalize(PyLiteInterpreter *I); 50 | void pylt_intp_loadf(PyLiteInterpreter *I, PyLiteFile *input); 51 | PyLiteCodeObject* pylt_intp_parsef(PyLiteInterpreter *I, PyLiteFile *input); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/deps/linenoise/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2014, Salvatore Sanfilippo 2 | Copyright (c) 2010-2013, Pieter Noordhuis 3 | 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, 10 | this list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 23 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /src/types/custom.c: -------------------------------------------------------------------------------- 1 | 2 | #include "custom.h" 3 | #include "common/type.h" 4 | #include "../api.h" 5 | 6 | PyLiteObject* pylt_obj_cutstom_create(PyLiteInterpreter *I, uint32_t ob_type, PyLiteObject *base_obj) { 7 | PyLiteObject_init(I, obj, PyLiteCustomObject, ob_type); 8 | obj->ob_attrs = pylt_obj_dict_new(I); 9 | obj->ob_attrs->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 10 | obj->base_obj = base_obj; 11 | return castobj(obj); 12 | } 13 | 14 | PyLiteObject* pylt_obj_custom_getattr(PyLiteInterpreter *I, PyLiteCustomObject *self, PyLiteObject *key, pl_bool_t *p_at_type) { 15 | PyLiteObject *obj = pylt_obj_dict_getitem(I, self->ob_attrs, key); 16 | if (!obj) { 17 | if (p_at_type) *p_at_type = true; 18 | PyLiteTypeObject *type = pl_type_by_code(I, self->ob_type); 19 | while (true) { 20 | obj = pylt_obj_dict_getitem(I, type->ob_attrs, key); 21 | if (obj) return obj; 22 | if (type->ob_reftype == PYLT_OBJ_TYPE_OBJ) break; 23 | type = pl_type_by_code(I, type->ob_base); 24 | } 25 | } 26 | if (p_at_type) *p_at_type = false; 27 | return obj; 28 | } 29 | 30 | void pylt_obj_custom_setattr(PyLiteInterpreter *I, PyLiteCustomObject *self, PyLiteObject* key, PyLiteObject* value) { 31 | pylt_obj_dict_setitem(I, self->ob_attrs, key, value); 32 | } 33 | 34 | pl_bool_t pylt_obj_custom_delattr(PyLiteInterpreter *I, PyLiteCustomObject *self, PyLiteObject* key) { 35 | return pylt_obj_dict_remove(I, self->ob_attrs, key); 36 | } 37 | -------------------------------------------------------------------------------- /src/deps/linenoise/license-ms.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006-2015, Salvatore Sanfilippo 2 | Modifications copyright (c) Microsoft Open Technologies, Inc. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | * Neither the name of Redis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | -------------------------------------------------------------------------------- /src/mods/os.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #include "os.h" 7 | #include "../api.h" 8 | #include "../intp.h" 9 | #include "../bind.h" 10 | #include "../types/all.h" 11 | #include "../utils/misc.h" 12 | 13 | 14 | PyLiteModuleObject* pylt_mods_os_loader(PyLiteInterpreter *I) { 15 | PyLiteModuleObject *mod = pylt_obj_module_new(I, _S(os)); 16 | 17 | pylt_obj_mod_setattr(I, mod, pl_strnew_u8(I, "O_ACCMODE", true), castobj(pylt_obj_int_new(I, 0000003))); 18 | pylt_obj_mod_setattr(I, mod, pl_strnew_u8(I, "O_RDONLY", true), castobj(pylt_obj_int_new(I, 0000000))); 19 | pylt_obj_mod_setattr(I, mod, pl_strnew_u8(I, "O_WRONLY", true), castobj(pylt_obj_int_new(I, 0000001))); 20 | pylt_obj_mod_setattr(I, mod, pl_strnew_u8(I, "O_RDWR", true), castobj(pylt_obj_int_new(I, 0000002))); 21 | pylt_obj_mod_setattr(I, mod, pl_strnew_u8(I, "O_CREAT", true), castobj(pylt_obj_int_new(I, 0000100))); 22 | pylt_obj_mod_setattr(I, mod, pl_strnew_u8(I, "O_EXCL", true), castobj(pylt_obj_int_new(I, 0000200))); 23 | pylt_obj_mod_setattr(I, mod, pl_strnew_u8(I, "O_NOCTTY", true), castobj(pylt_obj_int_new(I, 0000400))); 24 | pylt_obj_mod_setattr(I, mod, pl_strnew_u8(I, "O_TRUNC", true), castobj(pylt_obj_int_new(I, 0001000))); 25 | pylt_obj_mod_setattr(I, mod, pl_strnew_u8(I, "O_APPEND", true), castobj(pylt_obj_int_new(I, 0002000))); 26 | pylt_obj_mod_setattr(I, mod, pl_strnew_u8(I, "O_NONBLOCK", true), castobj(pylt_obj_int_new(I, 0004000))); 27 | 28 | return mod; 29 | } 30 | 31 | pl_bool_t pylt_mods_os_register(PyLiteInterpreter *I) { 32 | return pylt_mod_register(I, _S(os), &pylt_mods_os_loader, true); 33 | } 34 | -------------------------------------------------------------------------------- /src/types/extra/iter.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_ITER_H 3 | #define PYLITE_TYPES_ITER_H 4 | 5 | #include "../object.h" 6 | 7 | // Common Iterator 8 | typedef struct PyLiteIterObject { 9 | PyLiteObject_HEAD; 10 | PyLiteObject *base; 11 | PyLiteIterFunc iter_func; 12 | union { 13 | struct { 14 | pl_int_t count; 15 | pl_int_t index; 16 | } array; 17 | struct { 18 | pl_int_t count; 19 | pl_int32_t k; 20 | } hashmap; 21 | }; 22 | struct PyLiteIterObject *backup; 23 | } PyLiteIterObject; 24 | 25 | PyLiteIterObject* pylt_obj_iter_new(PyLiteInterpreter *I, PyLiteObject *obj); 26 | PyLiteObject* pylt_obj_iter_next(PyLiteInterpreter *I, PyLiteIterObject *iter); 27 | 28 | PyLiteObject* pylt_obj_bytes_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter); 29 | PyLiteObject* pylt_obj_str_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter); 30 | PyLiteObject* pylt_obj_tuple_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter); 31 | PyLiteObject* pylt_obj_list_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter); 32 | PyLiteObject* pylt_obj_set_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter); 33 | PyLiteObject* pylt_obj_dict_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter); 34 | PyLiteObject* pylt_obj_dict_items_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter); 35 | PyLiteObject* pylt_obj_range_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter); 36 | PyLiteObject* pylt_obj_custom_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter); 37 | 38 | void pylt_obj_iter_rfree(PyLiteInterpreter *I, PyLiteIterObject* self); 39 | void pylt_obj_iter_free(PyLiteInterpreter *I, PyLiteIterObject* self); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/gc.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_GC_H 3 | #define PYLITE_GC_H 4 | 5 | #include "utils/config.h" 6 | #include "utils/ref.h" 7 | #include "types/common/set.h" 8 | #include "types/common/bytes.h" 9 | #include "types/common/string.h" 10 | 11 | // use "(pl_int_t)" to avoid => warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 12 | #define up_hash_func(I, key) ((pl_uint32_t)(pl_int_t)(key)) 13 | #define up_hash_equal(I, a, b) ((a) == (b)) 14 | 15 | KHASHO_INIT(unique_ptr, PyLiteObject*, char, 0, up_hash_func, up_hash_equal); 16 | typedef khasho_t(unique_ptr) PyLiteUPSet; 17 | 18 | 19 | typedef struct PyLiteGC { 20 | // Tri-color Mark-and-sweep 21 | PyLiteUPSet *white; 22 | PyLiteUPSet *grey; 23 | PyLiteUPSet *black; 24 | 25 | // Keep reference alive 26 | PyLiteUPSet *refs; 27 | // Static containers 28 | PyLiteUPSet *statics; 29 | // Cache for str/bytes 30 | PyLiteSetObject *str_cached; 31 | } PyLiteGC; 32 | 33 | void pylt_gc_init(PyLiteInterpreter *I); 34 | void pylt_gc_finalize(PyLiteInterpreter *I); 35 | void pylt_gc_freeall(PyLiteInterpreter *I); 36 | void pylt_gc_add(PyLiteInterpreter *I, PyLiteObject *obj); 37 | void pylt_gc_remove(PyLiteInterpreter *I, PyLiteObject *obj); 38 | void pylt_gc_collect(PyLiteInterpreter *I); 39 | 40 | PyLiteStrObject* pylt_gc_cache_str_add(PyLiteInterpreter *I, PyLiteStrObject *key); 41 | PyLiteBytesObject* pylt_gc_cache_bytes_add(PyLiteInterpreter *I, PyLiteBytesObject *key); 42 | 43 | void pylt_gc_static_add(PyLiteInterpreter *I, PyLiteObject *obj); 44 | void pylt_gc_static_remove(PyLiteInterpreter *I, PyLiteObject *obj); 45 | 46 | void pylt_gc_ref_add(PyLiteInterpreter *I, PyLiteRef *ref); 47 | void pylt_gc_ref_remove(PyLiteInterpreter *I, PyLiteRef *ref); 48 | 49 | void pylt_gc_static_release(PyLiteInterpreter *I); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/types/common/bytes.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_BYTES_H 3 | #define PYLITE_TYPES_BYTES_H 4 | 5 | #include "../object.h" 6 | 7 | typedef struct PyLiteBytesObject { 8 | PyLiteObject_HEAD; 9 | uint32_t ob_hash; 10 | uint32_t ob_size; 11 | uint8_t *ob_val; 12 | } PyLiteBytesObject; 13 | 14 | pl_int_t pylt_obj_bytes_cmp(PyLiteInterpreter *I, PyLiteBytesObject *self, PyLiteObject *other); 15 | pl_bool_t pylt_obj_bytes_eq(PyLiteInterpreter *I, PyLiteBytesObject *self, PyLiteObject *other); 16 | pl_uint32_t pylt_obj_bytes_hash(PyLiteInterpreter *I, PyLiteBytesObject *obj); 17 | pl_uint32_t pylt_obj_bytes_forcehash(PyLiteInterpreter *I, PyLiteBytesObject *obj); 18 | 19 | PyLiteBytesObject* pylt_obj_bytes_getitem(PyLiteInterpreter *I, PyLiteBytesObject *self, int index); 20 | 21 | PyLiteObject* pylt_obj_bytes_mul(PyLiteInterpreter *I, PyLiteBytesObject *self, PyLiteObject *other); 22 | PyLiteObject* pylt_obj_bytes_plus(PyLiteInterpreter *I, PyLiteBytesObject *self, PyLiteObject *other); 23 | 24 | pl_int_t pylt_obj_bytes_index(PyLiteInterpreter *I, PyLiteBytesObject *self, PyLiteBytesObject *sub); 25 | pl_int_t pylt_obj_bytes_index_full(PyLiteInterpreter *I, PyLiteBytesObject *self, PyLiteBytesObject *sub, pl_int_t start, pl_int_t end); 26 | 27 | PyLiteBytesObject* pylt_obj_bytes_slice(PyLiteInterpreter *I, PyLiteBytesObject *self, pl_int_t *pstart, pl_int_t *pend, pl_int_t step); 28 | struct PyLiteStrObject* pylt_obj_bytes_to_str(PyLiteInterpreter *I, PyLiteBytesObject *self); 29 | 30 | PyLiteBytesObject* pylt_obj_bytes_new(PyLiteInterpreter *I, const char* str, int size, bool is_raw); 31 | PyLiteBytesObject* pylt_obj_bytes_new_empty(PyLiteInterpreter *I); 32 | 33 | // dont't free bytes/str object unless you know what will happen 34 | void pylt_obj_bytes_release(PyLiteInterpreter *I, PyLiteBytesObject *self); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/utils/io/fs_simple.c: -------------------------------------------------------------------------------- 1 | 2 | #include "fs_simple.h" 3 | #include "../misc.h" 4 | #include "../../api.h" 5 | #include 6 | #include 7 | 8 | pl_bool_t pylt_fs_simple_exists(PyLiteInterpreter *I, PyLiteStrObject *fn) { 9 | #ifdef PLATFORM_WINDOWS 10 | struct _stat64i32 stbuf; 11 | wchar_t fn_w[PYLT_PATH_BUF_WSIZE]; 12 | int ret = uc_ucs4str_to_utf16lez(fn->ob_val, fn->ob_size, (uint16_t*)fn_w, PYLT_PATH_BUF_WSIZE - 1); 13 | if (ret <= 0) { 14 | pl_error(I, pl_static.str.ValueError, "File name too long: %r", fn); 15 | return false; 16 | } 17 | return _wstat((const wchar_t *)(fn_w), &stbuf) == 0; 18 | #else 19 | char fn_u8[PYLT_PATH_BUF_SIZE]; 20 | struct stat stbuf; 21 | int ret = uc_ucs4str_to_utf8z(fn->ob_val, fn->ob_size, (char*)&fn_u8, PYLT_PATH_BUF_SIZE-1); 22 | if (ret < 0) return ret; 23 | return stat(fn_u8, &stbuf) == 0; 24 | #endif 25 | } 26 | 27 | pl_bool_t pylt_fs_simple_isdir(PyLiteInterpreter *I, PyLiteStrObject *fn) { 28 | #ifdef PLATFORM_WINDOWS 29 | struct _stat64i32 stbuf; 30 | wchar_t fn_w[PYLT_PATH_BUF_WSIZE]; 31 | int ret = uc_ucs4str_to_utf16lez(fn->ob_val, fn->ob_size, (uint16_t*)fn_w, PYLT_PATH_BUF_WSIZE - 1); 32 | if (ret <= 0) { 33 | pl_error(I, pl_static.str.ValueError, "File name too long: %r", fn); 34 | return false; 35 | } 36 | ret = _wstat((const wchar_t *)(fn_w), &stbuf); 37 | #else 38 | char fn_u8[PYLT_PATH_BUF_SIZE]; 39 | struct stat stbuf; 40 | int ret = uc_ucs4str_to_utf8z(fn->ob_val, fn->ob_size, (char*)&fn_u8, PYLT_PATH_BUF_SIZE - 1); 41 | if (ret < 0) return ret; 42 | ret = stat(fn_u8, &stbuf); 43 | #endif 44 | if (ret == 0) return false; 45 | return stbuf.st_mode & _S_IFDIR; 46 | } 47 | 48 | PyLiteFS PyLiteFSSimple = { 49 | .exists = &pylt_fs_simple_exists, 50 | .isdir = &pylt_fs_simple_isdir 51 | }; 52 | -------------------------------------------------------------------------------- /src/types/extra/function.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_FUNC_H 3 | #define PYLITE_TYPES_FUNC_H 4 | 5 | #include "../object.h" 6 | #include "../common/string.h" 7 | #include "../common/tuple.h" 8 | #include "../common/dict.h" 9 | #include "code.h" 10 | 11 | typedef struct PyLiteFunctionInfo { 12 | pl_int_t length; /* length of parameters */ 13 | pl_int_t minimal; /* minimal number of parameters */ 14 | 15 | PyLiteStrObject *name; 16 | PyLiteTupleObject *params; /* parameters' names */ 17 | pl_int_t *type_codes; /* parameters' type code */ 18 | PyLiteTupleObject *defaults; /* default values of parameters */ 19 | PyLiteStrObject *doc; 20 | PyLiteDictObject *closure; 21 | } PyLiteFunctionInfo; 22 | 23 | typedef struct PyLiteFunctionObject { 24 | PyLiteObject_HEAD; 25 | PyLiteObject *ob_owner; /* owner of object */ 26 | PyLiteFunctionInfo info; 27 | PyLiteCodeObject code; 28 | } PyLiteFunctionObject; 29 | 30 | typedef struct PyLiteCFunctionObject { 31 | PyLiteObject_HEAD; 32 | PyLiteObject *ob_owner; /* owner of object */ 33 | PyLiteFunctionInfo info; 34 | PyLiteCFunctionPtr code; /* the C pointer */ 35 | } PyLiteCFunctionObject; 36 | 37 | 38 | PyLiteFunctionObject* pylt_obj_func_new(PyLiteInterpreter *I, PyLiteCodeObject *code); 39 | PyLiteFunctionObject* pylt_obj_func_new_ex(PyLiteInterpreter *I, PyLiteStrObject *name, PyLiteListObject *params, PyLiteCodeObject *code, PyLiteDictObject *defaults, PyLiteStrObject *args, PyLiteStrObject *kwargs); 40 | PyLiteFunctionInfo* pylt_obj_func_get_info(PyLiteInterpreter *I, PyLiteObject *func); 41 | 42 | PyLiteCFunctionObject* pylt_obj_cfunc_new(PyLiteInterpreter *I, PyLiteStrObject *name, PyLiteTupleObject *param_names, PyLiteTupleObject *defaults, pl_uint_t *types, PyLiteCFunctionPtr cfunc); 43 | PyLiteCFunctionObject* pylt_obj_cfunc_new_no_args(PyLiteInterpreter *I, PyLiteStrObject *name, PyLiteCFunctionPtr cfunc); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/types/common/bool.c: -------------------------------------------------------------------------------- 1 | 2 | #include "bool.h" 3 | #include "number.h" 4 | #include "../../utils/misc.h" 5 | 6 | PyLiteBoolObject PyLiteTrue = { PYLT_OBJ_TYPE_BOOL, PYLT_OBJ_FLAG_STATIC, -1 }; 7 | PyLiteBoolObject PyLiteFalse = { PYLT_OBJ_TYPE_BOOL, PYLT_OBJ_FLAG_STATIC, 0 }; 8 | 9 | pl_int_t pylt_obj_bool_cmp(PyLiteInterpreter *I, PyLiteBoolObject *self, PyLiteObject *other) { 10 | switch (other->ob_type) { 11 | case PYLT_OBJ_TYPE_INT: 12 | if (self->ob_val < castint(other)->ob_val) return -1; 13 | if (self->ob_val > castint(other)->ob_val) return 1; 14 | else return 0; 15 | case PYLT_OBJ_TYPE_FLOAT: 16 | if (self->ob_val < castfloat(other)->ob_val) return -1; 17 | if (self->ob_val > castfloat(other)->ob_val) return 1; 18 | else return 0; 19 | case PYLT_OBJ_TYPE_BOOL: 20 | if (self->ob_val < castbool(other)->ob_val) return -1; 21 | if (self->ob_val > castbool(other)->ob_val) return 1; 22 | else return 0; 23 | default: 24 | return 2; 25 | } 26 | } 27 | 28 | pl_bool_t pylt_obj_bool_eq(PyLiteInterpreter *I, PyLiteBoolObject *self, PyLiteObject *other) { 29 | switch (other->ob_type) { 30 | case PYLT_OBJ_TYPE_INT: 31 | return self->ob_val == castint(other)->ob_val; 32 | case PYLT_OBJ_TYPE_FLOAT: 33 | return self->ob_val == castfloat(other)->ob_val; 34 | case PYLT_OBJ_TYPE_BOOL: 35 | return self->ob_val == castbool(other)->ob_val; 36 | default: 37 | return false; 38 | } 39 | } 40 | 41 | pl_uint32_t pylt_obj_bool_hash(PyLiteInterpreter *I, PyLiteBoolObject *obj) { 42 | return obj->ob_val; 43 | } 44 | 45 | struct PyLiteStrObject* pylt_obj_bool_to_str(PyLiteInterpreter *I, PyLiteBoolObject *self) { 46 | return (self->ob_val) ? pl_static.str.True : pl_static.str.False; 47 | } 48 | 49 | PyLiteBoolObject* pylt_obj_bool_new(PyLiteInterpreter *I, bool val) { 50 | return (val == false) ? &PyLiteFalse : &PyLiteTrue; 51 | } 52 | -------------------------------------------------------------------------------- /src/deps/utfconvert.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef UTFCONVERT_H 3 | #define UTFCONVERT_H 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | /* Return code if invalid. (xxx_wctomb) */ 10 | #define UC_RET_INVALID -1 11 | /* Return code if output buffer is too small. (xxx_wctomb, xxx_reset) */ 12 | #define UC_RET_TOOSMALL -2 13 | 14 | /** base part */ 15 | 16 | // return value: input used 17 | int uc_ucs4_from_utf8(const uint8_t *u8, int u8maxlen, uint32_t *pbuf); 18 | int uc_ucs4_from_utf16le(const uint16_t *u16, int u16maxlen, uint32_t *pbuf); 19 | 20 | // return value: output used 21 | int uc_ucs4_to_utf8(uint32_t wc, uint8_t *pbuf); 22 | int uc_ucs4_to_utf8_size(uint32_t wc); 23 | int uc_ucs4_to_utf16le(uint32_t wc, uint16_t *pbuf); 24 | int uc_ucs4_to_utf16le_size(uint32_t wc); 25 | 26 | int uc_wchar_from_utf8(const uint8_t *u8, int u8maxlen, wchar_t *pbuf, int *pbuf_used); 27 | int uc_wchar_to_utf8(wchar_t *wch, int wchmaxlen, uint8_t *pbuf); 28 | 29 | #define uc_utf8ch_size uc_ucs4_to_utf8_size 30 | #define uc_utf16lech_size uc_ucs4_to_utf16le_size 31 | 32 | /** extension part */ 33 | 34 | int uc_ucs4str_to_utf8(uint32_t *ucs4str, int ucs4str_len, uint8_t *buf, int buflen); 35 | int uc_ucs4str_to_utf8z(uint32_t *ucs4str, int ucs4str_len, uint8_t *buf, int buflen); 36 | int uc_ucs4str_to_utf8_size(uint32_t *ucs4str, int ucs4str_len); 37 | 38 | int uc_ucs4str_to_utf16le(uint32_t *ucs4str, int ucs4str_len, uint16_t *buf, int buflen); 39 | int uc_ucs4str_to_utf16lez(uint32_t *ucs4str, int ucs4str_len, uint16_t *buf, int buflen); 40 | int uc_ucs4str_to_utf16le_size(uint32_t *ucs4str, int ucs4str_len); 41 | 42 | int uc_ucs4str_to_wchar(uint32_t *ucs4str, int ucs4str_len, wchar_t *buf, int buflen); 43 | int uc_ucs4str_to_wcharz(uint32_t *ucs4str, int ucs4str_len, wchar_t *buf, int buflen); 44 | int uc_ucs4str_to_wchar_size(uint32_t *ucs4str, int ucs4str_len); 45 | 46 | int uc_ucs4str_from_wchar(const wchar_t *wstr, int wstr_len, uint32_t *pbuf, int *pbuf_used); 47 | int uc_ucs4str_from_utf8_size(const uint8_t *u8str, int u8str_len); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/deps/linenoise/osfix/Win32_ANSI.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), Microsoft Open Technologies, Inc. 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * - Redistributions of source code must retain the above copyright notice, 7 | * this list of conditions and the following disclaimer. 8 | * - Redistributions in binary form must reproduce the above copyright notice, 9 | * this list of conditions and the following disclaimer in the documentation 10 | * and/or other materials provided with the distribution. 11 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 12 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 13 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 14 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 15 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 16 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 17 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 18 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 19 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 20 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 21 | */ 22 | 23 | 24 | #ifndef WIN32_INTEROPA_ANSI_H 25 | #define WIN32_INTEROPA_ANSI_H 26 | 27 | #ifdef _WIN32 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | BOOL ParseAndPrintWString(HANDLE hDev, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten); 35 | //void ANSI_wprintf(char *format, ...); 36 | 37 | // include this file after stdio.h in order to redirect printf to the one that supports ANSI escape sequences 38 | //#define printf ANSI_printf 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | #endif // _WIN32 45 | 46 | #endif // WIN32_INTEROPA_ANSI_H 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # pylite 简蟒 ver 0.0.9 3 | 4 | A simple, lightweight implementation of python3-like language. 5 | 6 | ## Roadmap 7 | 8 | ### ver 0.1 9 | 10 | * ~~lexical scope~~ 11 | 12 | * ~~exception support~~ 13 | 14 | * ~~try - except - finally~~ 15 | 16 | * ~~simple import~~ 17 | 18 | * ~~slice grammar~~ 19 | 20 | * ~~lambda function~~ 21 | 22 | * ~~argument unpack~~ 23 | 24 | * package import 25 | 26 | * basic testcase 27 | 28 | 29 | ### ver 0.2 30 | 31 | * eval 32 | 33 | * xxx if xxx else xxx grammar 34 | 35 | * print fix for cycle reference 36 | 37 | * filesystem 38 | 39 | * ~~IO stream~~ 40 | 41 | * 'super' type 42 | 43 | * repl 44 | 45 | 46 | ### ver 0.3 47 | 48 | * dll load 49 | 50 | * decorator 51 | 52 | * ~~multiple value assign~~ 53 | 54 | * builtin regex engine 55 | 56 | * retval type hints 57 | 58 | 59 | ### ver 0.4 60 | 61 | * global/nonlocal 62 | 63 | * local variables optimization 64 | 65 | * unique integers 66 | 67 | * operator overloading support 68 | 69 | 70 | ### ver 0.5 71 | 72 | * yield support 73 | 74 | * clear memory leaks 75 | 76 | 77 | ### ver 0.6 78 | 79 | * make closure pass by reference 80 | 81 | 82 | ### ver 0.X 83 | 84 | * f-string 85 | 86 | * async/await 87 | 88 | * x for x in [...] 89 | 90 | * nameless function 91 | 92 | * libffi 93 | 94 | * JIT 95 | 96 | 97 | 98 | ### won't support 99 | 100 | * encodings except utf-8/ucs2/ucs4 101 | 102 | * while/for - else 103 | 104 | * multiple inheritance 105 | 106 | ## build 107 | 108 | cmake is required, and a c99 compiler: 109 | 110 | * gcc 4.8+ 111 | 112 | * clang 3.4+ 113 | 114 | * vs2013+ 115 | 116 | ```bash 117 | mkdir build 118 | cd build 119 | cmake .. 120 | ``` 121 | 122 | **make** (Linux/Mac/Mingw) 123 | Open **pylite.sln** and build. (Visual Studio) 124 | 125 | ## Example 126 | 127 | hello.py 128 | ```python 129 | print('Hello World!') 130 | ``` 131 | shell: 132 | ```bash 133 | pylite hello.py 134 | ``` 135 | 136 | No REPL yet. 137 | 138 | 139 | ## License 140 | * Zlib 141 | -------------------------------------------------------------------------------- /src/types/common/dict.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_DICT_H 3 | #define PYLITE_TYPES_DICT_H 4 | 5 | #include "../object.h" 6 | 7 | KHASHO_INIT(table, PyLiteObject*, PyLiteObject*, 1, pylt_obj_hash, pylt_obj_eq); 8 | 9 | typedef struct PyLiteDictObject { 10 | PyLiteObject_HEAD; 11 | khasho_t(table) *ob_val; 12 | } PyLiteDictObject; 13 | 14 | 15 | pl_int_t pylt_obj_dict_cmp(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject *other); 16 | pl_bool_t pylt_obj_dict_eq(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject *other); 17 | 18 | 19 | PyLiteObject* pylt_obj_dict_getitem(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject *key); 20 | void pylt_obj_dict_setitem(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject* key, PyLiteObject* value); 21 | 22 | pl_int_t pylt_obj_dict_len(PyLiteInterpreter *I, PyLiteDictObject *self); 23 | PyLiteDictObject* pylt_obj_dict_copy(PyLiteInterpreter *I, PyLiteDictObject *self); 24 | pl_bool_t pylt_obj_dict_has(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject *obj); 25 | pl_bool_t pylt_obj_dict_remove(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject *key); 26 | PyLiteObject* pylt_obj_dict_pop(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject *obj); 27 | void pylt_obj_dict_update(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteDictObject *other); 28 | 29 | pl_int32_t pylt_obj_dict_begin(PyLiteInterpreter *I, PyLiteDictObject *self); 30 | pl_int32_t pylt_obj_dict_end(PyLiteInterpreter *I, PyLiteDictObject *self); 31 | void pylt_obj_dict_next(PyLiteInterpreter *I, PyLiteDictObject *self, pl_int32_t *k); 32 | 33 | PyLiteObject* pylt_obj_dict_itemkey(PyLiteInterpreter *I, PyLiteDictObject *self, pl_int32_t k); 34 | PyLiteObject* pylt_obj_dict_itemvalue(PyLiteInterpreter *I, PyLiteDictObject *self, pl_int32_t k); 35 | void pylt_obj_dict_keyvalue(PyLiteInterpreter *I, PyLiteDictObject *self, pl_int32_t k, PyLiteObject **key, PyLiteObject **val); 36 | struct PyLiteStrObject* pylt_obj_dict_to_str(PyLiteInterpreter *I, PyLiteDictObject *self); 37 | 38 | PyLiteDictObject* pylt_obj_dict_new(PyLiteInterpreter *I); 39 | void pylt_obj_dict_rfree(PyLiteInterpreter *I, PyLiteDictObject *self); 40 | void pylt_obj_dict_free(PyLiteInterpreter *I, PyLiteDictObject *self); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 2.8) 3 | 4 | project (pylite) 5 | set(CMAKE_BUILD_TYPE Debug) 6 | #set(build_target shell) 7 | set(build_target playground) 8 | 9 | cmake_policy(SET CMP0015 OLD) 10 | 11 | macro(source_group_by_dir source_files) 12 | if(MSVC) 13 | set(sgbd_cur_dir ${CMAKE_CURRENT_SOURCE_DIR}) 14 | foreach(sgbd_file ${${source_files}}) 15 | string(REGEX REPLACE ${sgbd_cur_dir}/\(.*\) \\1 sgbd_fpath ${sgbd_file}) 16 | string(REGEX REPLACE "\(.*\)/.*" \\1 sgbd_group_name ${sgbd_fpath}) 17 | string(COMPARE EQUAL ${sgbd_fpath} ${sgbd_group_name} sgbd_nogroup) 18 | string(REPLACE "/" "\\" sgbd_group_name ${sgbd_group_name}) 19 | if(sgbd_nogroup) 20 | set(sgbd_group_name "\\") 21 | endif(sgbd_nogroup) 22 | source_group(${sgbd_group_name} FILES ${sgbd_file}) 23 | endforeach(sgbd_file) 24 | endif(MSVC) 25 | endmacro(source_group_by_dir) 26 | 27 | #if (MSVC) 28 | # set(CMAKE_C_FLAGS_DEBUG "/MTd") 29 | # set(CMAKE_C_FLAGS_RELEASE "/MT") 30 | # set(CMAKE_CXX_FLAGS_DEBUG "/MTd") 31 | # set(CMAKE_CXX_FLAGS_RELEASE "/MT") 32 | if (NOT MSVC) 33 | # SET(CMAKE_C_COMPILER "clang") 34 | set(CMAKE_C_FLAGS "-Wall") 35 | set(CMAKE_C_FLAGS "-std=c99") 36 | set(CMAKE_C_FLAGS_DEBUG "-g") 37 | set(CMAKE_C_FLAGS_RELEASE "-O2") 38 | endif(NOT MSVC) 39 | 40 | add_definitions(-DUNICODE -D_UNICODE) 41 | 42 | IF(${CMAKE_BUILD_TYPE} MATCHES "Debug") 43 | add_definitions(-DPYLT_DEBUG) 44 | add_definitions(-DPL_DEBUG_INFO) 45 | ENDIF() 46 | 47 | file(GLOB_RECURSE project_headers src/*.h) 48 | file(GLOB_RECURSE project_cpps src/*.c) 49 | set (SRC_LIST ${project_headers} ${project_cpps}) 50 | 51 | source_group_by_dir(SRC_LIST) 52 | 53 | IF(${build_target} MATCHES "shell") 54 | # shell 55 | add_definitions(-DSHELL) 56 | add_executable(pylite ${SRC_LIST}) 57 | 58 | if (NOT MSVC) 59 | target_link_libraries(pylite m) 60 | endif(NOT MSVC) 61 | ELSEIF(${build_target} MATCHES "playground") 62 | # playground 63 | add_definitions(-DPLAYGROUND) 64 | add_executable(pylite ${SRC_LIST}) 65 | 66 | if (NOT MSVC) 67 | target_link_libraries(pylite m) 68 | endif(NOT MSVC) 69 | ENDIF() 70 | 71 | -------------------------------------------------------------------------------- /tests/grammar/test_2_short_stmt.py: -------------------------------------------------------------------------------- 1 | 2 | # value assign 3 | 4 | a = 1 5 | 简蟒 = 2 6 | a2, b2 = 1, 2 7 | [a3, b3] = 1, 2 8 | (a4, b4) = 1, 2 9 | 10 | a, b = b, a = a4, b4 11 | a, b = b, a 12 | 13 | a5, b5 = b5, a5 = 1, 2 14 | 15 | # not support 16 | # a,b = x = 1,2 17 | 18 | # misc 19 | 20 | pass 21 | assert 1 22 | assert 1,2 23 | 24 | # operator 25 | 26 | not 1 27 | not True 28 | not False 29 | True is not False 30 | 31 | 1 or 2 32 | 1 and 0 or 2 33 | 34 | a == 1 35 | a != 1 36 | a < 2 37 | a <= 2 38 | a > 2 39 | a >= 2 40 | a == 1,2 41 | a == (1,2) 42 | 43 | lst = [1,2,3] 44 | 1 in lst 45 | 1 not in lst 46 | 1 + 1 not in lst 47 | 1 is 1 48 | 1 is not (1,) 49 | b = a | 简蟒 50 | c = a ^ 简蟒 51 | d = a & 简蟒 52 | a << 1 53 | a >> 1 54 | x = 1 << 1 >> 1 55 | +a + -a 56 | a * b 57 | a / b 58 | a // b 59 | a % b 60 | a ** 2 61 | 62 | a = 1 63 | a += 1 64 | a -= 1 65 | a /= 1 66 | a *= 1 67 | a %= 1 68 | a //= 1 69 | a **= 1 70 | 71 | a = 1 72 | a <<= 1 73 | a >>= 1 74 | 75 | 76 | x = 1 77 | x = 1 + 1 78 | x = 1 - 1 - 1 79 | x = 1 - 1 + 1 - 1 + 1 80 | 81 | x = 1 * 1 82 | x = 1 / 1 83 | x = 1 % 1 84 | x = 1 / 1 * 1 % 1 85 | 86 | x = +1 87 | x = -1 88 | x = ~1 89 | x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 90 | x = -1*1/1 + 1*1 - ---1*1 91 | 92 | lst = [1,2,3] 93 | lst[1] 94 | list.__base__ 95 | list.__base__.__base__ 96 | 97 | lst[:] 98 | lst[:3] 99 | lst[:-1] 100 | lst[0:3] 101 | lst[0:-1] 102 | lst[-1:] 103 | lst[0:10] 104 | 105 | lst[0] = 5 106 | lst[:2] = 1,2 107 | lst[:2] = [1,2] 108 | 109 | 110 | # del 111 | a = 1 112 | del a 113 | 114 | a = [1,2,3] 115 | del a[0] 116 | 117 | a = [1,2,3] 118 | del a[:2] 119 | 120 | a = [1,2,3] 121 | del a[:] 122 | 123 | a = [1,2,3] 124 | del a[:10] 125 | 126 | 127 | a = [1,2,3] 128 | del a[1:10] 129 | 130 | a = [1,2,3] 131 | del a[1:-1] 132 | 133 | a = [1,2,3] 134 | del a[:-1] 135 | 136 | a = [1,2,3] 137 | del a[1:] 138 | 139 | a = [1,2,3,4,5] 140 | del a[::2] 141 | 142 | class _: 143 | pass 144 | 145 | a = _() 146 | a.aaa = 1 147 | del a.aaa 148 | 149 | a, b, c = 1, 2, 3 150 | del a, b, c 151 | 152 | a, b, c = 1, 2, 3 153 | del [a, b, c] 154 | 155 | a, b, c = 1, 2, 3 156 | del (a, b, c) 157 | 158 | del [] 159 | del () 160 | 161 | # works on cpython, but too weird. not support. 162 | #del (a, (b, c)) 163 | -------------------------------------------------------------------------------- /tests/grammar/test_3_logic.py: -------------------------------------------------------------------------------- 1 | 2 | if True: 3 | pass 4 | 5 | 6 | if True: 7 | pass 8 | else: 9 | pass 10 | 11 | 12 | test = 1 13 | 14 | if test == 1: 15 | pass 16 | elif test == 2: 17 | a = 2 18 | elif test == 4: 19 | a = 2 20 | else: 21 | a = 3 22 | 23 | test = 4 24 | 25 | if test == 1: 26 | pass 27 | elif test == 2: 28 | a = 2 29 | elif test == 4: 30 | a = 2 31 | else: 32 | a = 3 33 | 34 | # It's different with cpython 35 | if 1,2,3,4: 36 | pass 37 | 38 | 39 | i = 0 40 | while i < 10: 41 | i += 1 42 | 43 | 44 | i = 0 45 | while i < 10: 46 | break 47 | 48 | 49 | i = 0 50 | while i < 10: 51 | i += 1 52 | continue 53 | i = 1000 54 | 55 | 56 | for i in [1,2,3]: 57 | a = i 58 | 59 | for i in range(10): 60 | a = i 61 | break 62 | 63 | 64 | for i in range(10): 65 | a = i 66 | continue 67 | a += 1 68 | 69 | for i in 1, 2, 3: pass 70 | for i, j, k in (): pass 71 | 72 | 73 | if True: pass 74 | 75 | 76 | if True: pass 77 | else: pass 78 | 79 | 80 | test = 1 81 | 82 | if test == 1: pass 83 | elif test == 2: a = 2 84 | elif test == 4: a = 2 85 | else: a = 3 86 | 87 | test = 4 88 | 89 | if test == 1: pass 90 | elif test == 2: a = 2 91 | elif test == 4: a = 2 92 | else: a = 3 93 | 94 | if 1: pass 95 | if 1: pass 96 | else: pass 97 | if 0: pass 98 | elif 0: pass 99 | if 0: pass 100 | elif 0: pass 101 | elif 0: pass 102 | elif 0: pass 103 | else: pass 104 | 105 | 106 | i = 0 107 | while i < 10: i += 1 108 | 109 | for i in range(10): pass 110 | 111 | if 1: pass 112 | if 1: 113 | pass 114 | if 1: 115 | # 116 | # 117 | # 118 | pass 119 | pass 120 | # 121 | pass 122 | # 123 | 124 | # test 125 | 126 | if not 1: pass 127 | if 1 and 1: pass 128 | if 1 or 1: pass 129 | if not not not 1: pass 130 | if not 1 and 1 and 1: pass 131 | if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass 132 | 133 | 134 | # compare 135 | 136 | if 1: pass 137 | x = (1 == 1) 138 | if 1 == 1: pass 139 | if 1 != 1: pass 140 | if 1 < 1: pass 141 | if 1 > 1: pass 142 | if 1 <= 1: pass 143 | if 1 >= 1: pass 144 | if 1 is 1: pass 145 | if 1 is not 1: pass 146 | if 1 in (): pass 147 | if 1 not in (): pass 148 | if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: pass 149 | -------------------------------------------------------------------------------- /src/bind.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_BIND_H 3 | #define PYLITE_BIND_H 4 | 5 | #include "utils/config.h" 6 | #include "types/all.h" 7 | 8 | pl_bool_t pylt_bind_cls_check(PyLiteInterpreter *I, PyLiteTypeObject *defclass, PyLiteStrObject *method_name, PyLiteTypeObject *givenclass); 9 | PyLiteObject* pylt_obj_typecast(PyLiteInterpreter *I, struct PyLiteTypeObject *type, PyLiteObject *obj); 10 | 11 | pl_bool_t pylt_mod_register(PyLiteInterpreter *I, PyLiteStrObject *modpath, PyLiteModuleLoaderFunc regfunc, pl_bool_t force); 12 | void pylt_type_register(PyLiteInterpreter *I, PyLiteModuleObject *mod, PyLiteTypeObject *type); 13 | void pylt_cprop_register(PyLiteInterpreter *I, PyLiteTypeObject *type, PyLiteStrObject *key, PyLiteCFunctionPtr cfget, PyLiteCFunctionPtr cfset); 14 | void pylt_attr_register(PyLiteInterpreter *I, PyLiteTypeObject *type, PyLiteStrObject *key, PyLiteObject *value); 15 | 16 | PyLiteCFunctionObject* pylt_cfunc_register(PyLiteInterpreter *I, PyLiteModuleObject *mod, PyLiteStrObject *name, PyLiteTupleObject *param_names, PyLiteTupleObject *defaults, pl_uint_t *types, PyLiteCFunctionPtr cfunc); 17 | PyLiteCFunctionObject* pylt_cmethod_register(PyLiteInterpreter *I, PyLiteTypeObject *type, PyLiteStrObject *name, PyLiteTupleObject *param_names, PyLiteTupleObject *defaults, pl_uint_t *types, PyLiteCFunctionPtr cfunc); 18 | PyLiteCFunctionObject* pylt_cmethod_register_0_args(PyLiteInterpreter *I, PyLiteTypeObject *type, PyLiteStrObject *name, PyLiteCFunctionPtr cfunc); 19 | PyLiteCFunctionObject* pylt_cmethod_register_1_args(PyLiteInterpreter *I, PyLiteTypeObject *type, PyLiteStrObject *name, PyLiteCFunctionPtr cfunc); 20 | PyLiteCFunctionObject* pylt_cclsmethod_register(PyLiteInterpreter *I, PyLiteTypeObject *type, PyLiteStrObject *name, PyLiteTupleObject *param_names, PyLiteTupleObject *defaults, pl_uint_t *types, PyLiteCFunctionPtr cfunc); 21 | PyLiteCFunctionObject* pylt_cclsmethod_register_0_args(PyLiteInterpreter *I, PyLiteTypeObject *type, PyLiteStrObject *name, PyLiteCFunctionPtr cfunc); 22 | 23 | #define _NS(I, str) pylt_obj_str_new_from_cstr(I, str, true) 24 | #define _NI(_int_val) pylt_obj_int_new(I, (_int_val)) 25 | 26 | // static string 27 | #define _S(name) pl_static.str.name 28 | 29 | PyLiteTupleObject* _NT(PyLiteInterpreter *I, int n, ...); 30 | PyLiteTupleObject* _NST(PyLiteInterpreter *I, int n, ...); 31 | 32 | pl_uint_t* _UINTS(PyLiteInterpreter *I, pl_uint_t n, ...); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/types/objectE.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_WITH_EXCEPTIONS_H 3 | #define PYLITE_WITH_EXCEPTIONS_H 4 | 5 | #include "all.h" 6 | 7 | // object api with exceptions 8 | 9 | PyLiteBytesObject* pylt_obj_bytes_Egetitem(PyLiteInterpreter *I, PyLiteBytesObject *self, PyLiteObject *index); 10 | PyLiteStrObject* pylt_obj_str_Egetitem(PyLiteInterpreter *I, PyLiteStrObject *self, PyLiteObject *index); 11 | PyLiteObject* pylt_obj_tuple_Egetitem(PyLiteInterpreter *I, PyLiteTupleObject *self, PyLiteObject *index); 12 | PyLiteObject* pylt_obj_list_Egetitem(PyLiteInterpreter *I, PyLiteListObject *self, PyLiteObject *index); 13 | PyLiteObject* pylt_obj_dict_Egetitem(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject *key); 14 | pl_bool_t pylt_obj_list_Esetitem(PyLiteInterpreter *I, PyLiteListObject *self, PyLiteObject *index, PyLiteObject* obj); 15 | 16 | pl_bool_t pylt_obj_dict_Eremove(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject *key); 17 | 18 | PyLiteObject* pylt_obj_Egetitem(PyLiteInterpreter *I, PyLiteObject *obj, PyLiteObject* key); 19 | pl_bool_t pylt_obj_Esetitem(PyLiteInterpreter *I, PyLiteObject *self, PyLiteObject* key, PyLiteObject* value); 20 | pl_bool_t pylt_obj_Edelitem(PyLiteInterpreter *I, PyLiteObject *obj, PyLiteObject* key); 21 | 22 | PyLiteObject* pylt_obj_Egetattr_ex(PyLiteInterpreter *I, PyLiteObject *obj, PyLiteObject* key, PyLiteObject* _default, pl_bool_t *p_at_type); 23 | PyLiteObject* pylt_obj_Egetattr(PyLiteInterpreter *I, PyLiteObject *obj, PyLiteObject* key, pl_bool_t *p_at_type); 24 | pl_bool_t pylt_obj_Esetattr(PyLiteInterpreter *I, PyLiteObject *self, PyLiteObject* key, PyLiteObject* value); 25 | pl_bool_t pylt_obj_Edelattr(PyLiteInterpreter *I, PyLiteObject *self, PyLiteObject* key); 26 | 27 | pl_int_t pylt_obj_Ecmp(PyLiteInterpreter *I, PyLiteObject *a, PyLiteObject *b); 28 | 29 | PyLiteObject* pylt_obj_Eslice_ex(PyLiteInterpreter *I, PyLiteObject *obj, PyLiteObject *start, PyLiteObject *end, PyLiteObject *step); 30 | void pylt_obj_Eslice_set_ex(PyLiteInterpreter *I, PyLiteObject *obj, PyLiteObject *start, PyLiteObject *end, PyLiteObject *step, PyLiteObject *val); 31 | void pylt_obj_Eslice_del_ex(PyLiteInterpreter *I, PyLiteObject *obj, PyLiteObject *start, PyLiteObject *end, PyLiteObject *step, PyLiteObject *val); 32 | 33 | 34 | PyLiteStrObject* pylt_obj_Eto_str(PyLiteInterpreter *I, PyLiteObject *obj); 35 | PyLiteStrObject* pylt_obj_Eto_repr(PyLiteInterpreter *I, PyLiteObject *obj); 36 | 37 | PyLiteIterObject* pylt_obj_iter_Enew(PyLiteInterpreter *I, PyLiteObject *obj); 38 | PyLiteObject* pylt_obj_iter_Enext(PyLiteInterpreter *I, PyLiteIterObject *iter); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/api.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_API_H 3 | #define PYLITE_API_H 4 | 5 | #include "utils/config.h" 6 | #include "types/all.h" 7 | #include "utils/ref.h" 8 | #include "gc.h" 9 | 10 | /* Class utils */ 11 | // get module instance, load builtin module if not loaded. 12 | PyLiteModuleObject* pl_getmod(PyLiteInterpreter *I, PyLiteStrObject *modpath); 13 | 14 | // get first builtin parent type (type of ob_base for custom type) 15 | pl_uint32_t pl_getbase_by_code(PyLiteInterpreter *I, pl_uint32_t type_code); 16 | pl_bool_t pl_isinstance(PyLiteInterpreter *I, PyLiteObject *obj, pl_uint32_t type_code); 17 | 18 | // return true if a is subclass of b 19 | pl_bool_t pl_issubclass(PyLiteInterpreter *I, PyLiteTypeObject *a, PyLiteTypeObject *b); 20 | 21 | PyLiteTypeObject* pl_type(PyLiteInterpreter *I, PyLiteObject *obj); 22 | PyLiteTypeObject* pl_type_by_code(PyLiteInterpreter *I, pl_uint32_t type_code); 23 | 24 | /* Code Execute */ 25 | PyLiteObject* pl_call(PyLiteInterpreter *I, PyLiteObject *callable, int argc, ...); 26 | PyLiteObject* pl_call_method(PyLiteInterpreter *I, PyLiteObject *self, PyLiteObject *callable, int argc, ...); 27 | PyLiteObject* pl_call_method_ex(PyLiteInterpreter *I, PyLiteObject *self, PyLiteObject *callable, PyLiteTupleObject *args, PyLiteDictObject *kwargs); 28 | 29 | /* String utils */ 30 | #define pl_strnew_u8 pylt_obj_str_new_from_cstr 31 | #define pl_strnew_w pylt_obj_str_new_from_wstr 32 | #define pl_format pylt_obj_str_new_from_format 33 | #define pl_formatT pylt_obj_str_new_from_format_with_tuple 34 | #define pl_cformat pylt_obj_str_new_from_cformat 35 | 36 | void pl_outputstr(PyLiteInterpreter *I, PyLiteStrObject *obj); 37 | 38 | /* Misc */ 39 | #define pl_assert(I, stmt, ret) if (!(stmt)) { pl_error(I, pl_static.str.RuntimeError, "panic"); return (ret); } 40 | #define pl_foreach_set(I, it, setobj) for (pl_int32_t it = pylt_obj_set_begin(I, setobj); it != pylt_obj_set_end(I, setobj); pylt_obj_set_next(I, setobj, &it)) 41 | #define pl_foreach_dict(I, it, dictobj) for (pl_int32_t it = pylt_obj_dict_begin(I, dictobj); it != pylt_obj_dict_end(I, dictobj); pylt_obj_dict_next(I, dictobj, &it)) 42 | #define pl_foreach_tuple(I, i, tobj) for (pl_int_t i = 0; i < casttuple(tobj)->ob_size; ++i) 43 | #define pl_foreach_list(I, i, lobj) for (pl_int_t i = 0; i < castlist(lobj)->ob_size; ++i) 44 | 45 | void pl_print(PyLiteInterpreter *I, const char *format, ...); 46 | void pl_error(PyLiteInterpreter *I, PyLiteStrObject *exception_name, const char *format, ...); 47 | void pl_error_by_type(PyLiteInterpreter *I, PyLiteTypeObject *exception_type, const char *format, ...); 48 | void pl_raise(PyLiteInterpreter *I, PyLiteObject *exception); 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/types/common/type.c: -------------------------------------------------------------------------------- 1 | 2 | #include "type.h" 3 | #include "dict.h" 4 | #include "../../intp.h" 5 | #include "../../api.h" 6 | 7 | PyLiteTypeObject* pylt_obj_type_new_with_type(PyLiteInterpreter *I, PyLiteStrObject *name, pl_uint32_t instance_type, pl_uint32_t base_type) { 8 | PyLiteObject_init(I, obj, PyLiteTypeObject, PYLT_OBJ_TYPE_TYPE); 9 | obj->name = name; 10 | obj->ob_attrs = pylt_obj_dict_new(I); 11 | obj->ob_attrs->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 12 | obj->ob_reftype = instance_type; 13 | obj->ob_base = base_type; 14 | obj->ob_owner = NULL; 15 | obj->allow_inherit = true; 16 | return obj; 17 | } 18 | 19 | PyLiteTypeObject* pylt_obj_type_new(PyLiteInterpreter *I, PyLiteStrObject *name, pl_uint32_t base_type, PyLiteDictObject *dict) { 20 | PyLiteTypeObject *type = pylt_obj_type_new_with_type(I, name, ++I->class_num, base_type); 21 | type->ob_attrs = (dict) ? pylt_obj_dict_copy(I, dict) : pylt_obj_dict_new(I); 22 | type->ob_attrs->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 23 | return type; 24 | } 25 | 26 | PyLiteObject* pylt_obj_type_getattr(PyLiteInterpreter *I, PyLiteTypeObject *self, PyLiteObject *key, pl_bool_t *p_at_type) { 27 | PyLiteObject *obj; 28 | if (p_at_type) *p_at_type = false; 29 | 30 | while (true) { 31 | obj = pylt_obj_dict_getitem(I, self->ob_attrs, key); 32 | if (obj) return obj; 33 | if (self->ob_reftype == PYLT_OBJ_TYPE_OBJ) break; 34 | self = pl_type_by_code(I, self->ob_base); 35 | //if (p_at_type) *p_at_type = true; 36 | } 37 | 38 | if (self->ob_reftype != PYLT_OBJ_TYPE_TYPE) { 39 | obj = pylt_obj_dict_getitem(I, pl_type_by_code(I, PYLT_OBJ_TYPE_TYPE)->ob_attrs, key); 40 | if (p_at_type) *p_at_type = true; 41 | if (obj) return obj; 42 | } 43 | 44 | return NULL; 45 | } 46 | 47 | 48 | void pylt_obj_type_setattr(PyLiteInterpreter *I, PyLiteTypeObject *self, PyLiteObject* key, PyLiteObject* value) { 49 | pylt_obj_dict_setitem(I, self->ob_attrs, key, value); 50 | } 51 | 52 | pl_bool_t pylt_obj_type_delattr(PyLiteInterpreter *I, PyLiteTypeObject *self, PyLiteObject* key) { 53 | return pylt_obj_dict_remove(I, self->ob_attrs, key); 54 | } 55 | 56 | 57 | pl_uint32_t pylt_obj_type_hash(PyLiteInterpreter *I, PyLiteTypeObject *self) { 58 | return self->ob_reftype; 59 | } 60 | 61 | void pylt_obj_type_rfree(PyLiteInterpreter *I, PyLiteTypeObject *self) { 62 | //pylt_obj_dict_free(I, self->ob_attrs); 63 | pylt_free_ex(I, self); 64 | } 65 | 66 | void pylt_obj_type_free(PyLiteInterpreter *I, PyLiteTypeObject *self) { 67 | pylt_gc_remove(I, castobj(self)); 68 | pylt_obj_type_rfree(I, self); 69 | } 70 | -------------------------------------------------------------------------------- /src/parser.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_PARSER_H 3 | #define PYLITE_PARSER_H 4 | 5 | #include "lexer.h" 6 | #include "deps/kvec.h" 7 | #include "types/all.h" 8 | 9 | typedef struct ParserInfo { 10 | int loop_depth; 11 | PyLiteCodeObject *code; 12 | struct ParserInfo *prev; 13 | } ParserInfo; 14 | 15 | typedef struct ParserState { 16 | LexState *ls; 17 | PyLiteInterpreter *I; 18 | 19 | ParserInfo *info; 20 | ParserInfo *info_used; 21 | 22 | struct { 23 | bool enable; 24 | bool can_be_left_val; 25 | pl_int_t startcode; 26 | pl_int_t expr_level; 27 | kvec_t(PyLiteInstruction) bc_cache; 28 | } lval_check; 29 | 30 | kvec_t(PyLiteDictObject*) var_tables; 31 | 32 | bool disable_op_in_parse; 33 | bool disable_expr_tuple_parse; 34 | bool disable_return_parse; 35 | pl_int_t token_count; 36 | } ParserState; 37 | 38 | PyLiteCodeObject* pylt_parser_parse(ParserState *ps); 39 | ParserState* pylt_parser_new(PyLiteInterpreter *I, LexState *ls); 40 | void pylt_parser_init(PyLiteInterpreter *I, ParserState *ps, LexState *ls); 41 | void pylt_parser_reset(PyLiteInterpreter *I, ParserState *ps, LexState *ls); 42 | void pylt_parser_finalize(PyLiteInterpreter *I, ParserState *ps); 43 | void pylt_parser_crash_finalize(PyLiteInterpreter *I, ParserState *ps); 44 | 45 | // SyntaxError: invalid syntax 46 | #define PYLT_ERR_PARSER_INVALID_SYNTAX -1 47 | // SyntaxError: (value error) invalid escape 48 | #define PYLT_ERR_PARSER_BYTES_INVALID_ESCAPE -2 49 | // SyntaxError: 'break' outside loop 50 | #define PYLT_ERR_PARSER_BREAK_OUTSIDE_LOOP -3 51 | // SyntaxError: 'continue' not properly in loop 52 | #define PYLT_ERR_PARSER_CONTINUE_OUTSIDE_LOOP -4 53 | // SyntaxError: can't assign to literal 54 | #define PYLT_ERR_PARSER_CANT_ASSIGN_TO_LITERAL -5 55 | // SyntaxError: keyword can't be an expression 56 | #define PYLT_ERR_PARSER_KEYWORD_CANT_BE_AN_EXPR -6 57 | // SyntaxError: non-keyword arg after keyword arg 58 | #define PYLT_ERR_PARSER_NON_KEYWORD_ARG_AFTER_KEYWORD_ARG -7 59 | // SyntaxError: 'return' outside function 60 | #define PYLT_ERR_PARSER_RETURN_OUTSIDE_FUNCTION -8 61 | // default 'except:' must be last 62 | #define PYLT_ERR_PARSER_EXCEPT_MUST_BE_LAST -9 63 | // expected 'finally' or 'except', got invalid token 64 | #define PYLT_ERR_PARSER_TRY_EXPECTED_FINALLY -10 65 | // SyntaxError: non - default argument follows default argument 66 | #define PYLT_ERR_PARSER_NON_DEFAULT_ARG_FOLLOW_DEFAULT_ARG -11 67 | 68 | // SyntaxError: different unpack sequences' size 69 | #define PYLT_ERR_PARSER_DIFFERENT_UNPACK_SEQUENCES_SIZE -19 70 | // SyntaxError: not enough values to unpack (expected A, got B) 71 | #define PYLT_ERR_PARSER_NOT_ENOUGH_VALUES_TO_UNPACK -20 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /src/types/common/list.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_LIST_H 3 | #define PYLITE_TYPES_LIST_H 4 | 5 | #include "../object.h" 6 | 7 | typedef struct PyLiteListObject { 8 | PyLiteObject_HEAD; 9 | pl_int_t ob_size; 10 | pl_int_t ob_maxsize; 11 | PyLiteObject **ob_val; 12 | } PyLiteListObject; 13 | 14 | pl_bool_t pylt_obj_list_eq(PyLiteInterpreter *I, PyLiteListObject *self, PyLiteObject *other); 15 | 16 | pl_int_t pylt_obj_list_append(PyLiteInterpreter *I, PyLiteListObject *self, PyLiteObject *obj); 17 | void pylt_obj_list_clear(PyLiteInterpreter *I, PyLiteListObject *self); 18 | PyLiteListObject* pylt_obj_list_copy(PyLiteInterpreter *I, PyLiteListObject *self); 19 | pl_uint_t pylt_obj_list_count(PyLiteInterpreter *I, PyLiteListObject *self); 20 | void pylt_obj_list_extend(PyLiteInterpreter *I, PyLiteListObject *self, PyLiteListObject *obj); 21 | pl_int_t pylt_obj_list_index(PyLiteInterpreter *I, PyLiteListObject *self, PyLiteObject *obj); 22 | pl_int_t pylt_obj_list_index_strict(PyLiteInterpreter *I, PyLiteListObject *self, PyLiteObject *obj); 23 | pl_bool_t pylt_obj_list_insert(PyLiteInterpreter *I, PyLiteListObject *self, pl_int_t index, PyLiteObject *obj); 24 | PyLiteObject* pylt_obj_list_pop(PyLiteInterpreter *I, PyLiteListObject *self); 25 | pl_bool_t pylt_obj_list_remove(PyLiteInterpreter *I, PyLiteListObject *self, PyLiteObject *obj); 26 | void pylt_obj_list_reverse(PyLiteInterpreter *I, PyLiteListObject *self); 27 | void pylt_obj_list_sort(PyLiteInterpreter *I, PyLiteListObject *self); 28 | 29 | PyLiteObject* pylt_obj_list_getitem(PyLiteInterpreter *I, PyLiteListObject *self, int index); 30 | pl_bool_t pylt_obj_list_setitem(PyLiteInterpreter *I, PyLiteListObject *self, int index, PyLiteObject* obj); 31 | pl_bool_t pylt_obj_list_delitem(PyLiteInterpreter *I, PyLiteListObject *self, int index); 32 | PyLiteListObject* pylt_obj_list_slice(PyLiteInterpreter *I, PyLiteListObject *self, pl_int_t *pstart, pl_int_t *pend, pl_int_t step); 33 | pl_int_t pylt_obj_list_slice_set(PyLiteInterpreter *I, PyLiteListObject *self, pl_int_t *pstart, pl_int_t *pend, pl_int_t step, PyLiteObject *val); 34 | void pylt_obj_list_slice_del(PyLiteInterpreter *I, PyLiteListObject *self, pl_int_t *pstart, pl_int_t *pend, pl_int_t step, PyLiteObject *val); 35 | 36 | pl_bool_t pylt_obj_list_has(PyLiteInterpreter *I, PyLiteListObject *self, PyLiteObject *obj); 37 | struct PyLiteStrObject* pylt_obj_list_to_str(PyLiteInterpreter *I, PyLiteListObject *self); 38 | 39 | PyLiteListObject* pylt_obj_list_new(PyLiteInterpreter *I); 40 | PyLiteListObject* pylt_obj_list_new_with_size(PyLiteInterpreter *I, pl_uint_t size); 41 | void pylt_obj_list_rfree(PyLiteInterpreter *I, PyLiteListObject *self); 42 | void pylt_obj_list_free(PyLiteInterpreter *I, PyLiteListObject *self); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/types/common/string.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_STRING_H 3 | #define PYLITE_TYPES_STRING_H 4 | 5 | #include "../object.h" 6 | 7 | typedef struct PyLiteStrObject { 8 | PyLiteObject_HEAD; 9 | uint32_t ob_hash; 10 | uint32_t ob_size; 11 | uint32_t *ob_val; 12 | } PyLiteStrObject; 13 | 14 | pl_int_t pylt_obj_str_cmp(PyLiteInterpreter *I, PyLiteStrObject *self, PyLiteObject *other); 15 | pl_bool_t pylt_obj_str_eq(PyLiteInterpreter *I, PyLiteStrObject *self, PyLiteObject *other); 16 | pl_uint32_t pylt_obj_str_hash(PyLiteInterpreter *I, PyLiteStrObject *obj); 17 | pl_uint32_t pylt_obj_str_forcehash(PyLiteInterpreter *I, PyLiteStrObject *obj); 18 | 19 | PyLiteStrObject* pylt_obj_str_getitem(PyLiteInterpreter *I, PyLiteStrObject *self, int index); 20 | 21 | PyLiteObject* pylt_obj_str_mul(PyLiteInterpreter *I, PyLiteStrObject *self, PyLiteObject *other); 22 | PyLiteObject* pylt_obj_str_mod(PyLiteInterpreter *I, PyLiteStrObject *self, PyLiteObject *other); 23 | PyLiteObject* pylt_obj_str_plus(PyLiteInterpreter *I, PyLiteStrObject *self, PyLiteObject *other); 24 | 25 | pl_int_t pylt_obj_str_index(PyLiteInterpreter *I, PyLiteStrObject *self, PyLiteStrObject *sub); 26 | pl_int_t pylt_obj_str_index_full(PyLiteInterpreter *I, PyLiteStrObject *self, PyLiteStrObject *sub, pl_int_t start, pl_int_t end); 27 | PyLiteStrObject* pylt_obj_str_join(PyLiteInterpreter *I, PyLiteStrObject *separator, PyLiteObject *seq); 28 | 29 | PyLiteStrObject* pylt_obj_str_slice(PyLiteInterpreter *I, PyLiteStrObject *self, pl_int_t *pstart, pl_int_t *pend, pl_int_t step); 30 | pl_bool_t pylt_obj_str_startswith(PyLiteInterpreter *I, PyLiteStrObject *self, PyLiteStrObject *sub); 31 | pl_bool_t pylt_obj_str_startswith_full(PyLiteInterpreter *I, PyLiteStrObject *self, PyLiteStrObject *sub, pl_int_t start, pl_int_t end); 32 | PyLiteStrObject* pylt_obj_str_to_repr(PyLiteInterpreter *I, PyLiteStrObject *self); 33 | 34 | PyLiteStrObject* pylt_obj_str_new(PyLiteInterpreter *I, uint32_t *str, int size, bool is_raw); 35 | PyLiteStrObject* pylt_obj_str_new_from_cstr(PyLiteInterpreter *I, const char *str, bool is_raw); 36 | PyLiteStrObject* pylt_obj_str_new_from_wstr(PyLiteInterpreter *I, const wchar_t *str, bool is_raw); 37 | 38 | PyLiteStrObject* pylt_obj_str_new_from_format_with_tuple(PyLiteInterpreter *I, PyLiteStrObject *format, struct PyLiteTupleObject *args); 39 | PyLiteStrObject* pylt_obj_str_new_from_format(PyLiteInterpreter *I, PyLiteStrObject *format, ...); 40 | PyLiteStrObject* pylt_obj_str_new_from_cformat(PyLiteInterpreter *I, const char *format, ...); 41 | PyLiteStrObject* pylt_obj_str_new_empty(PyLiteInterpreter *I); 42 | 43 | // dont't free bytes/str object unless you know what will happen 44 | void pylt_obj_str_release(PyLiteInterpreter *I, PyLiteStrObject *self); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/deps/linenoise/linenoise.h: -------------------------------------------------------------------------------- 1 | /* linenoise.h -- guerrilla line editing library against the idea that a 2 | * line editing lib needs to be 20,000 lines of C code. 3 | * 4 | * See linenoise.c for more information. 5 | * 6 | * ------------------------------------------------------------------------ 7 | * 8 | * Copyright (c) 2010, Salvatore Sanfilippo 9 | * Copyright (c) 2010, Pieter Noordhuis 10 | * 11 | * All rights reserved. 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions are 15 | * met: 16 | * 17 | * * Redistributions of source code must retain the above copyright 18 | * notice, this list of conditions and the following disclaimer. 19 | * 20 | * * Redistributions in binary form must reproduce the above copyright 21 | * notice, this list of conditions and the following disclaimer in the 22 | * documentation and/or other materials provided with the distribution. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef __LINENOISE_H 38 | #define __LINENOISE_H 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | typedef struct linenoiseCompletions { 45 | size_t len; 46 | wchar_t **cvec; 47 | } linenoiseCompletions; 48 | 49 | typedef void(linenoiseCompletionCallback)(const wchar_t *, linenoiseCompletions *); 50 | void linenoiseSetCompletionCallback(linenoiseCompletionCallback *); 51 | void linenoiseAddCompletion(linenoiseCompletions *, const wchar_t *); 52 | 53 | wchar_t *linenoise(const wchar_t *prompt); 54 | int linenoiseHistoryAdd(const wchar_t *line); 55 | int linenoiseHistorySetMaxLen(int len); 56 | int linenoiseHistorySave(const char *filename); 57 | int linenoiseHistoryLoad(const char *filename); 58 | void linenoiseClearScreen(void); 59 | void linenoiseSetMultiLine(int ml); 60 | void linenoisePrintKeyCodes(void); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif /* __LINENOISE_H */ 67 | -------------------------------------------------------------------------------- /src/pybind/extra.c: -------------------------------------------------------------------------------- 1 | 2 | #include "extra.h" 3 | #include "../api.h" 4 | #include "../bind.h" 5 | #include "../types/all.h" 6 | #include "../utils/misc.h" 7 | 8 | PyLiteObject* pylt_cls_method_function_new(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 9 | // won't supported 10 | return NULL; 11 | } 12 | 13 | PyLiteObject* pylt_prop_function_args_types_get(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 14 | PyLiteFunctionInfo *info = pylt_obj_func_get_info(I, args[0]); 15 | PyLiteTupleObject *data = pylt_obj_tuple_new(I, info->length); 16 | if (!info->type_codes) { 17 | for (pl_int_t i = 0; i < data->ob_size; ++i) { 18 | data->ob_val[i] = castobj(pl_type_by_code(I, PYLT_OBJ_TYPE_OBJ)); 19 | } 20 | } else { 21 | for (pl_int_t i = 0; i < data->ob_size; ++i) { 22 | pl_int_t typecode = info->type_codes[i]; 23 | data->ob_val[i] = castobj(pl_type_by_code(I, typecode ? typecode : PYLT_OBJ_TYPE_OBJ)); 24 | } 25 | } 26 | return castobj(data); 27 | } 28 | 29 | PyLiteObject* pylt_prop_function_defaults_get(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 30 | PyLiteFunctionInfo *info = pylt_obj_func_get_info(I, args[0]); 31 | return castobj(info->defaults); 32 | } 33 | 34 | PyLiteObject* pylt_prop_function_parameters_get(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 35 | PyLiteFunctionInfo *info = pylt_obj_func_get_info(I, args[0]); 36 | return castobj(info->params); 37 | } 38 | 39 | PyLiteObject* pylt_cls_method_iter_new(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 40 | if (!pylt_bind_cls_check(I, pl_type_by_code(I, PYLT_OBJ_TYPE_ITER), _S(__new__), casttype(args[0]))) 41 | return NULL; 42 | return pylt_obj_typecast(I, casttype(args[0]), castobj(pylt_obj_iter_new(I, args[1]))); 43 | } 44 | 45 | PyLiteObject* pylt_cls_method_range_new(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 46 | pl_int_t start, end; 47 | if (!pylt_bind_cls_check(I, pl_type_by_code(I, PYLT_OBJ_TYPE_RANGE), _S(__new__), casttype(args[0]))) 48 | return NULL; 49 | 50 | if (castnone(args[2]) == &PyLiteNone) { 51 | start = 0; 52 | end = dcast(int, args[1])->ob_val; 53 | } else { 54 | start = dcast(int, args[1])->ob_val; 55 | end = dcast(int, args[2])->ob_val; 56 | } 57 | 58 | return pylt_obj_typecast( 59 | I, 60 | dcast(type, args[0]), 61 | castobj(pylt_obj_range_new(I, start, end, dcast(int, args[3])->ob_val)) 62 | ); 63 | } 64 | 65 | PyLiteObject* pylt_cls_method_base_exception_new(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 66 | if (!pylt_bind_cls_check(I, pl_type_by_code(I, PYLT_OBJ_TYPE_BASE_EXCEPTION), _S(__new__), casttype(args[0]))) 67 | return NULL; 68 | 69 | return pylt_obj_typecast( 70 | I, 71 | dcast(type, args[0]), 72 | castobj(pylt_obj_exception_new(I, dcast(tuple, args[1]))) 73 | ); 74 | } 75 | 76 | PyLiteObject* pylt_prop_base_exception_args_get(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 77 | return castobj(dcast(except, args[1])->args); 78 | } 79 | -------------------------------------------------------------------------------- /src/lexer.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_LEXER_H 3 | #define PYLITE_LEXER_H 4 | 5 | #include "utils/config.h" 6 | #include "utils/io/_io.h" 7 | 8 | #define FIRST_TOKEN 128 9 | 10 | typedef enum TokenKind { 11 | // Common 12 | TK_END = FIRST_TOKEN, 13 | TK_COMMENTS, 14 | TK_NEWLINE, 15 | TK_INDENT, 16 | TK_DEDENT, 17 | 18 | TK_NAME, 19 | TK_INT, 20 | TK_FLOAT, 21 | TK_STRING, 22 | TK_BYTES, 23 | 24 | // Keywords 25 | TK_KW_FALSE, TK_KW_NONE, TK_KW_TRUE, TK_KW_AND, TK_KW_AS, TK_KW_ASSERT, TK_KW_BREAK, 26 | TK_KW_CLASS, TK_KW_CONTINUE, TK_KW_DEF, TK_KW_DEL, TK_KW_ELIF, TK_KW_ELSE, TK_KW_EXCEPT, 27 | TK_KW_FINALLY, TK_KW_FOR, TK_KW_FROM, TK_KW_GLOBAL, TK_KW_IF, TK_KW_IMPORT, TK_KW_IN, 28 | TK_KW_IS, TK_KW_LAMBDA, TK_KW_NONLOCAL, TK_KW_NOT, TK_KW_OR, TK_KW_PASS, TK_KW_RAISE, 29 | TK_KW_RETURN, TK_KW_TRY, TK_KW_WHILE, TK_KW_WITH, TK_KW_YIELD, 30 | 31 | // Operators 32 | // ** // << >> <= >= == != 33 | TK_OP_POW, TK_OP_FLOORDIV, TK_OP_LSHIFT, TK_OP_RSHIFT, TK_OP_LE, TK_OP_GE, TK_OP_EQ, TK_OP_NE, 34 | 35 | // Delimiters 36 | // -> 37 | // += -= *= /= //= %= @= 38 | // &= |= ^= >>= <<= **= 39 | TK_DE_RET_TYPE, 40 | TK_DE_PLUS_EQ, TK_DE_MINUS_EQ, TK_DE_MUL_EQ, TK_DE_DIV_EQ, TK_DE_FLOORDIV_EQ, TK_DE_MOD_EQ, TK_DE_MATMUL_EQ, 41 | TK_DE_BITAND_EQ, TK_DE_BITOR_EQ, TK_DE_BITXOR_EQ, TK_DE_RSHIFT_EQ, TK_DE_LSHIFT_EQ, TK_DE_POW_EQ, 42 | 43 | } TokenKind; 44 | 45 | typedef struct PyLiteObject PyLiteObject; 46 | 47 | typedef struct Token { 48 | uint32_t val; 49 | PyLiteObject *obj; 50 | } Token; 51 | 52 | typedef struct IndentInfo { 53 | struct IndentInfo *prev; 54 | int val; 55 | } IndentInfo; 56 | 57 | typedef struct LexExtraData { 58 | /* for bytes/str */ 59 | struct { 60 | char *buf; 61 | int pos; 62 | int size; 63 | } bytes; 64 | 65 | struct { 66 | uint32_t *buf; 67 | int pos; 68 | int size; 69 | } str; 70 | 71 | struct { 72 | bool on; 73 | int count; 74 | uint32_t buf[8]; 75 | } _record; 76 | } LexExtraData; 77 | 78 | typedef struct LexState { 79 | int linenumber; 80 | Token token; /* current token */ 81 | LexExtraData le; 82 | PyLiteFile* input; 83 | PyLiteInterpreter *I; 84 | 85 | uint32_t ch; 86 | int current_indent; 87 | int inside_couples; /* [...] (...) {...} */ 88 | IndentInfo *indent; /* indent stack */ 89 | IndentInfo *indent_used; 90 | } LexState; 91 | 92 | 93 | LexState* pylt_lex_new(PyLiteInterpreter *I, PyLiteFile *input); 94 | void pylt_lex_init(PyLiteInterpreter *I, LexState *ls, PyLiteFile *input); 95 | void pylt_lex_finalize(PyLiteInterpreter *I, LexState *ls); 96 | void pylt_lex_err(LexState *ls, int code); 97 | void pylt_lex_reset(LexState *ls, PyLiteFile *input); 98 | 99 | int pylt_lex_next(LexState *ls); 100 | const wchar_t* pylt_lex_get_token_name(uint32_t token); 101 | 102 | #define PYLT_ERR_LEX_INVALID_CHARACTER -101 103 | #define PYLT_ERR_LEX_INVALID_NUMBER -102 104 | // SyntaxError: EOL while scanning string literal 105 | #define PYLT_ERR_LEX_INVALID_STR_OR_BYTES -103 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /tests/grammar/test_4_func.py: -------------------------------------------------------------------------------- 1 | 2 | def f1(): pass 3 | f1() 4 | f1(*()) 5 | f1(*(), **{}) 6 | def f2(one_argument): pass 7 | def f3(two, arguments): pass 8 | 9 | def a1(one_arg,): pass 10 | def a2(two, args,): pass 11 | def v0(*rest): pass 12 | def v1(a, *rest): pass 13 | def v2(a, b, *rest): pass 14 | 15 | f1() 16 | f2(1) 17 | f2(1,) 18 | f3(1, 2) 19 | f3(1, 2,) 20 | v0() 21 | v0(1) 22 | v0(1,) 23 | v0(1,2) 24 | v0(1,2,3,4,5,6,7,8,9,0) 25 | v1(1) 26 | v1(1,) 27 | v1(1,2) 28 | v1(1,2,3) 29 | v1(1,2,3,4,5,6,7,8,9,0) 30 | v2(1,2) 31 | v2(1,2,3) 32 | v2(1,2,3,4) 33 | v2(1,2,3,4,5,6,7,8,9,0) 34 | 35 | def d01(a=1): pass 36 | d01() 37 | d01(1) 38 | d01(*(1,)) 39 | d01(**{'a':2}) 40 | def d11(a, b=1): pass 41 | d11(1) 42 | d11(1, 2) 43 | d11(1, **{'b':2}) 44 | def d21(a, b, c=1): pass 45 | d21(1, 2) 46 | d21(1, 2, 3) 47 | d21(*(1, 2, 3)) 48 | d21(1, *(2, 3)) 49 | d21(1, 2, *(3,)) 50 | d21(1, 2, **{'c':3}) 51 | def d02(a=1, b=2): pass 52 | d02() 53 | d02(1) 54 | d02(1, 2) 55 | d02(*(1, 2)) 56 | d02(1, *(2,)) 57 | d02(1, **{'b':2}) 58 | d02(**{'a': 1, 'b': 2}) 59 | def d12(a, b=1, c=2): pass 60 | d12(1) 61 | d12(1, 2) 62 | d12(1, 2, 3) 63 | def d22(a, b, c=1, d=2): pass 64 | d22(1, 2) 65 | d22(1, 2, 3) 66 | d22(1, 2, 3, 4) 67 | def d01v(a=1, *rest): pass 68 | d01v() 69 | d01v(1) 70 | d01v(1, 2) 71 | d01v(*(1, 2, 3, 4)) 72 | d01v(*(1,)) 73 | d01v(**{'a':2}) 74 | def d11v(a, b=1, *rest): pass 75 | d11v(1) 76 | d11v(1, 2) 77 | d11v(1, 2, 3) 78 | def d21v(a, b, c=1, *rest): pass 79 | d21v(1, 2) 80 | d21v(1, 2, 3) 81 | d21v(1, 2, 3, 4) 82 | d21v(*(1, 2, 3, 4)) 83 | d21v(1, 2, **{'c': 3}) 84 | def d02v(a=1, b=2, *rest): pass 85 | d02v() 86 | d02v(1) 87 | d02v(1, 2) 88 | d02v(1, 2, 3) 89 | d02v(1, *(2, 3, 4)) 90 | d02v(**{'a': 1, 'b': 2}) 91 | def d12v(a, b=1, c=2, *rest): pass 92 | d12v(1) 93 | d12v(1, 2) 94 | d12v(1, 2, 3) 95 | d12v(1, 2, 3, 4) 96 | d12v(*(1, 2, 3, 4)) 97 | d12v(1, 2, *(3, 4, 5)) 98 | d12v(1, *(2,), **{'c': 3}) 99 | def d22v(a, b, c=1, d=2, *rest): pass 100 | d22v(1, 2) 101 | d22v(1, 2, 3) 102 | d22v(1, 2, 3, 4) 103 | d22v(1, 2, 3, 4, 5) 104 | d22v(*(1, 2, 3, 4)) 105 | d22v(1, 2, *(3, 4, 5)) 106 | d22v(1, *(2, 3), **{'d': 4}) 107 | 108 | ''' 109 | # not supported now 110 | def pos0key1(*, key): return key 111 | pos0key1(key=100) 112 | def pos2key2(p1, p2, *, k1, k2=100): return p1,p2,k1,k2 113 | pos2key2(1, 2, k1=100) 114 | pos2key2(1, 2, k1=100, k2=200) 115 | pos2key2(1, 2, k2=100, k1=200) 116 | def pos2key2dict(p1, p2, *, k1=100, k2, **kwarg): return p1,p2,k1,k2,kwarg 117 | pos2key2dict(1,2,k2=100,tokwarg1=100,tokwarg2=200) 118 | pos2key2dict(1,2,tokwarg1=100,tokwarg2=200, k2=100) 119 | ''' 120 | 121 | 122 | # test MAKE_CLOSURE with a variety of oparg's 123 | closure = 1 124 | def f(): return closure 125 | def f(x=1): return closure 126 | #def f(*, k=1): return closure 127 | #def f() -> int: return closure 128 | 129 | l1 = lambda : 0 130 | #self.assertEqual(l1(), 0) 131 | l2 = lambda : a[d] # XXX just testing the expression 132 | #l3 = lambda : [2 < x for x in [-1, 3, 0]] 133 | #self.assertEqual(l3(), [0, 1, 0]) 134 | l4 = lambda x = lambda y = lambda z=1 : z : y() : x() 135 | #self.assertEqual(l4(), 1) 136 | l5 = lambda x, y, z=2: x + y + z 137 | #self.assertEqual(l5(1, 2), 5) 138 | #self.assertEqual(l5(1, 2, 3), 6) 139 | #l6 = lambda x, y, *, k=20: x+y+k 140 | -------------------------------------------------------------------------------- /src/deps/linenoise/README.markdown: -------------------------------------------------------------------------------- 1 | # Linenoise 2 | 3 | A minimal, zero-config, BSD licensed, readline replacement used in Redis, 4 | MongoDB, and Android. 5 | 6 | * Single and multi line editing mode with the usual key bindings implemented. 7 | * History handling. 8 | * Completion. 9 | * About 1,100 lines of BSD license source code. 10 | * Only uses a subset of VT100 escapes (ANSI.SYS compatible). 11 | 12 | ## Can a line editing library be 20k lines of code? 13 | 14 | Line editing with some support for history is a really important feature for command line utilities. Instead of retyping almost the same stuff again and again it's just much better to hit the up arrow and edit on syntax errors, or in order to try a slightly different command. But apparently code dealing with terminals is some sort of Black Magic: readline is 30k lines of code, libedit 20k. Is it reasonable to link small utilities to huge libraries just to get a minimal support for line editing? 15 | 16 | So what usually happens is either: 17 | 18 | * Large programs with configure scripts disabling line editing if readline is not present in the system, or not supporting it at all since readline is GPL licensed and libedit (the BSD clone) is not as known and available as readline is (Real world example of this problem: Tclsh). 19 | * Smaller programs not using a configure script not supporting line editing at all (A problem we had with Redis-cli for instance). 20 | 21 | The result is a pollution of binaries without line editing support. 22 | 23 | So I spent more or less two hours doing a reality check resulting in this little library: is it *really* needed for a line editing library to be 20k lines of code? Apparently not, it is possibe to get a very small, zero configuration, trivial to embed library, that solves the problem. Smaller programs will just include this, supporing line editing out of the box. Larger programs may use this little library or just checking with configure if readline/libedit is available and resorting to linenoise if not. 24 | 25 | ## Terminals, in 2010. 26 | 27 | Apparently almost every terminal you can happen to use today has some kind of support for basic VT100 escape sequences. So I tried to write a lib using just very basic VT100 features. The resulting library appears to work everywhere I tried to use it, and now can work even on ANSI.SYS compatible terminals, since no 28 | VT220 specific sequences are used anymore. 29 | 30 | The library is currently about 1100 lines of code. In order to use it in your project just look at the *example.c* file in the source distribution, it is trivial. Linenoise is BSD code, so you can use both in free software and commercial software. 31 | 32 | ## Tested with... 33 | 34 | * Linux text only console ($TERM = linux) 35 | * Linux KDE terminal application ($TERM = xterm) 36 | * Linux xterm ($TERM = xterm) 37 | * Linux Buildroot ($TERM = vt100) 38 | * Mac OS X iTerm ($TERM = xterm) 39 | * Mac OS X default Terminal.app ($TERM = xterm) 40 | * OpenBSD 4.5 through an OSX Terminal.app ($TERM = screen) 41 | * IBM AIX 6.1 42 | * FreeBSD xterm ($TERM = xterm) 43 | * ANSI.SYS 44 | 45 | Please test it everywhere you can and report back! 46 | 47 | ## Let's push this forward! 48 | 49 | Patches should be provided in the respect of linenoise sensibility for small 50 | easy to understand code. 51 | 52 | Send feedbacks to antirez at gmail 53 | -------------------------------------------------------------------------------- /src/intp.c: -------------------------------------------------------------------------------- 1 | 2 | #include "intp.h" 3 | #include "utils/misc.h" 4 | #include "utils/io/_io.h" 5 | #include "mods/pltypes.h" 6 | #include "mods/io.h" 7 | #include "mods/os.h" 8 | #include "mods/sys.h" 9 | #include "mods/cio.h" 10 | #include "mods/math.h" 11 | #include "mods/builtin.h" 12 | #include "mods/unusualm.h" 13 | 14 | #include "utils/io/fs_simple.h" 15 | #include "utils/io/io_simple.h" 16 | 17 | void pylt_intp_err(PyLiteInterpreter *I) { 18 | exit(-1); 19 | } 20 | 21 | PyLiteInterpreter* pylt_intp_new() { 22 | PyLiteInterpreter *I = pylt_malloc(NULL, sizeof(PyLiteInterpreter)); 23 | pylt_intp_init(I); 24 | return I; 25 | } 26 | 27 | void pylt_intp_free(PyLiteInterpreter *I) { 28 | pylt_intp_finalize(I); 29 | pylt_free_ex(NULL, I); 30 | } 31 | 32 | void pylt_intp_sys_init(PyLiteInterpreter *I) { 33 | I->sys.defio = &PyLiteIOSimple; 34 | I->sys.deffs = &PyLiteFSSimple; 35 | } 36 | 37 | void pylt_intp_init(PyLiteInterpreter *I) { 38 | I->mem_used = 0; 39 | pylt_intp_sys_init(I); 40 | pylt_gc_init(I); 41 | 42 | kv_init(I, I->cls_base); 43 | I->modules = pylt_obj_dict_new(I); 44 | I->cmodules_loader = pylt_obj_dict_new(I); 45 | I->error = NULL; 46 | 47 | I->lexer = NULL; 48 | I->parser = NULL; 49 | 50 | pylt_static_objs_init(I); 51 | 52 | // register builtins 53 | pylt_mods_pltypes_register(I); 54 | pylt_mods_io_register(I); 55 | pylt_mods_cio_register(I); 56 | pylt_mods_math_register(I); 57 | pylt_mods_os_register(I); 58 | pylt_mods_sys_register(I); 59 | pylt_mods_unusual_register(I); 60 | 61 | pylt_mods_builtins_register(I); 62 | pylt_vm_init(I, &I->vm); 63 | } 64 | 65 | void pylt_intp_finalize(PyLiteInterpreter *I) { 66 | pylt_gc_collect(I); 67 | if (I->lexer) pylt_lex_finalize(I, I->lexer); 68 | if (I->parser) pylt_parser_finalize(I, I->parser); 69 | pylt_vm_finalize(I); 70 | 71 | // free types 72 | /*for (pl_uint_t i = 1; i < kv_size(interpreter->cls_base); ++i) { 73 | pylt_obj_type_free(interpreter, kv_A(interpreter->cls_base, i)); 74 | }*/ 75 | kv_destroy(I->cls_base); 76 | 77 | // free modules 78 | /*PyLiteDictObject *dict = I->modules; 79 | for (pl_int32_t it = pylt_obj_dict_begin(I, dict); it != pylt_obj_dict_end(I, dict); pylt_obj_dict_next(I, dict, &it)) { 80 | PyLiteObject *k, *v; 81 | pylt_obj_dict_keyvalue(I, dict, it, &k, &v); 82 | pylt_obj_free(I, k); 83 | pylt_obj_free(I, v); 84 | }*/ 85 | 86 | //pylt_obj_dict_free(I, I->modules); 87 | pylt_gc_freeall(I); 88 | pylt_gc_finalize(I); 89 | 90 | if (I->lexer) pylt_free_ex(I, I->lexer); 91 | if (I->parser) pylt_free_ex(I, I->parser); 92 | } 93 | 94 | void pylt_intp_loadf(PyLiteInterpreter *I, PyLiteFile *input) { 95 | PyLiteCodeObject *code = pylt_intp_parsef(I, input); 96 | pylt_vm_load_code(I, code); 97 | } 98 | 99 | PyLiteCodeObject* pylt_intp_parsef(PyLiteInterpreter *I, PyLiteFile *input) { 100 | if (!I->lexer) I->lexer = pylt_lex_new(I, input); 101 | else pylt_lex_reset(I->lexer, input); 102 | if (!I->parser) I->parser = pylt_parser_new(I, I->lexer); 103 | else pylt_parser_reset(I, I->parser, I->lexer); 104 | 105 | PyLiteCodeObject *code = pylt_parser_parse(I->parser); 106 | pylt_obj_code_add_to_gc(I, code); 107 | return code; 108 | } 109 | -------------------------------------------------------------------------------- /src/types/extra/exception.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_EXCEPTION_H 3 | #define PYLITE_TYPES_EXCEPTION_H 4 | 5 | #include "../object.h" 6 | #include "../custom.h" 7 | #include "../common/string.h" 8 | #include "../common/tuple.h" 9 | 10 | typedef struct PyLiteBaseExceptionObject { 11 | PyLiteObject_HEAD; 12 | PyLiteTupleObject *args; 13 | } PyLiteBaseExceptionObject; 14 | 15 | typedef struct PyLiteExceptionObject { 16 | PyLiteCustomObject_HEAD; 17 | } PyLiteExceptionObject; 18 | 19 | #define PYLITE_EXCEPTION_DEFINE(x) \ 20 | typedef struct PyLiteE##x##Object { \ 21 | PyLiteCustomObject_HEAD; \ 22 | } PyLiteE##x##Object; 23 | 24 | // base exception 25 | PYLITE_EXCEPTION_DEFINE(SystemExit); 26 | PYLITE_EXCEPTION_DEFINE(KeyboardInterrupt); 27 | PYLITE_EXCEPTION_DEFINE(GeneratorExit); 28 | 29 | // --> exception 30 | PYLITE_EXCEPTION_DEFINE(StopIteration); 31 | PYLITE_EXCEPTION_DEFINE(StopAsyncIteration); 32 | PYLITE_EXCEPTION_DEFINE(ArithmeticError); 33 | PYLITE_EXCEPTION_DEFINE(AssertionError); 34 | PYLITE_EXCEPTION_DEFINE(AttributeError); 35 | PYLITE_EXCEPTION_DEFINE(BufferError); 36 | PYLITE_EXCEPTION_DEFINE(EOFError); 37 | PYLITE_EXCEPTION_DEFINE(ImportError); 38 | PYLITE_EXCEPTION_DEFINE(LookupError); 39 | PYLITE_EXCEPTION_DEFINE(MemoryError); 40 | PYLITE_EXCEPTION_DEFINE(NameError); 41 | PYLITE_EXCEPTION_DEFINE(OSError); 42 | PYLITE_EXCEPTION_DEFINE(ReferenceError); 43 | PYLITE_EXCEPTION_DEFINE(RuntimeError); 44 | PYLITE_EXCEPTION_DEFINE(SyntaxError); 45 | PYLITE_EXCEPTION_DEFINE(SystemError); 46 | PYLITE_EXCEPTION_DEFINE(TypeError); 47 | PYLITE_EXCEPTION_DEFINE(ValueError); 48 | PYLITE_EXCEPTION_DEFINE(Warning); 49 | 50 | // --> --> ArithmeticError 51 | PYLITE_EXCEPTION_DEFINE(FloatingPointError); 52 | PYLITE_EXCEPTION_DEFINE(OverflowError); 53 | PYLITE_EXCEPTION_DEFINE(ZeroDivisionError); 54 | 55 | // --> --> LookupError 56 | PYLITE_EXCEPTION_DEFINE(IndexError); 57 | PYLITE_EXCEPTION_DEFINE(KeyError); 58 | 59 | // --> --> OSError 60 | PYLITE_EXCEPTION_DEFINE(BlockingIOError); 61 | PYLITE_EXCEPTION_DEFINE(ChildProcessError); 62 | PYLITE_EXCEPTION_DEFINE(ConnectionError); 63 | PYLITE_EXCEPTION_DEFINE(FileExistsError); 64 | PYLITE_EXCEPTION_DEFINE(FileNotFoundError); 65 | PYLITE_EXCEPTION_DEFINE(InterruptedError); 66 | PYLITE_EXCEPTION_DEFINE(IsADirectoryError); 67 | PYLITE_EXCEPTION_DEFINE(NotADirectoryError); 68 | PYLITE_EXCEPTION_DEFINE(PermissionError); 69 | PYLITE_EXCEPTION_DEFINE(ProcessLookupError); 70 | PYLITE_EXCEPTION_DEFINE(TimeoutError); 71 | 72 | // --> --> RuntimeError 73 | PYLITE_EXCEPTION_DEFINE(NotImplementedError); 74 | PYLITE_EXCEPTION_DEFINE(RecursionError); 75 | 76 | // --> --> SyntaxError 77 | PYLITE_EXCEPTION_DEFINE(IndentationError); 78 | 79 | // --> --> Warning 80 | PYLITE_EXCEPTION_DEFINE(DeprecationWarning); 81 | PYLITE_EXCEPTION_DEFINE(PendingDeprecationWarning); 82 | PYLITE_EXCEPTION_DEFINE(RuntimeWarning); 83 | PYLITE_EXCEPTION_DEFINE(SyntaxWarning); 84 | PYLITE_EXCEPTION_DEFINE(UserWarning); 85 | PYLITE_EXCEPTION_DEFINE(FutureWarning); 86 | PYLITE_EXCEPTION_DEFINE(ImportWarning); 87 | PYLITE_EXCEPTION_DEFINE(UnicodeWarning); 88 | PYLITE_EXCEPTION_DEFINE(BytesWarning); 89 | PYLITE_EXCEPTION_DEFINE(ResourceWarning); 90 | 91 | PyLiteBaseExceptionObject* pylt_obj_exception_new(PyLiteInterpreter *I, PyLiteTupleObject *args); 92 | void pylt_obj_exception_rfree(PyLiteInterpreter *I, PyLiteBaseExceptionObject* self); 93 | void pylt_obj_exception_free(PyLiteInterpreter *I, PyLiteBaseExceptionObject* self); 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /src/pybind/common.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_BIND_COMMON_H 3 | #define PYLITE_BIND_COMMON_H 4 | 5 | #include "../types/object.h" 6 | 7 | PyLiteObject* pylt_cls_method_obj_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 8 | PyLiteObject* pylt_method_obj_repr(PyLiteInterpreter *I, int argc, PyLiteObject **args); 9 | PyLiteObject* pylt_method_obj_str(PyLiteInterpreter *I, int argc, PyLiteObject **args); 10 | 11 | PyLiteObject* pylt_method_type_mro(PyLiteInterpreter *I, int argc, PyLiteObject **args); 12 | PyLiteObject* pylt_prop_type_base_get(PyLiteInterpreter *I, int argc, PyLiteObject **args); 13 | PyLiteObject* pylt_cls_method_type_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 14 | 15 | PyLiteObject* pylt_cls_method_int_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 16 | PyLiteObject* pylt_method_int_is_integer(PyLiteInterpreter *I, int argc, PyLiteObject **args); 17 | 18 | PyLiteObject* pylt_cls_method_float_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 19 | 20 | PyLiteObject* pylt_cls_method_bool_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 21 | 22 | PyLiteObject* pylt_cls_method_str_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 23 | PyLiteObject* pylt_method_str_index(PyLiteInterpreter *I, int argc, PyLiteObject **args); 24 | PyLiteObject* pylt_method_str_join(PyLiteInterpreter *I, int argc, PyLiteObject **args); 25 | PyLiteObject* pylt_method_str_startswith(PyLiteInterpreter *I, int argc, PyLiteObject **args); 26 | 27 | PyLiteObject* pylt_cls_method_bytes_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 28 | 29 | PyLiteObject* pylt_cls_method_set_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 30 | PyLiteObject* pylt_method_set_add(PyLiteInterpreter *I, int argc, PyLiteObject **args); 31 | PyLiteObject* pylt_method_set_clear(PyLiteInterpreter *I, int argc, PyLiteObject **args); 32 | PyLiteObject* pylt_method_set_copy(PyLiteInterpreter *I, int argc, PyLiteObject **args); 33 | PyLiteObject* pylt_method_set_pop(PyLiteInterpreter *I, int argc, PyLiteObject **args); 34 | PyLiteObject* pylt_method_set_remove(PyLiteInterpreter *I, int argc, PyLiteObject **args); 35 | 36 | PyLiteObject* pylt_cls_method_list_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 37 | PyLiteObject* pylt_method_list_append(PyLiteInterpreter *I, int argc, PyLiteObject **args); 38 | PyLiteObject* pylt_method_list_clear(PyLiteInterpreter *I, int argc, PyLiteObject **args); 39 | PyLiteObject* pylt_method_list_copy(PyLiteInterpreter *I, int argc, PyLiteObject **args); 40 | PyLiteObject* pylt_method_list_count(PyLiteInterpreter *I, int argc, PyLiteObject **args); 41 | PyLiteObject* pylt_method_list_extend(PyLiteInterpreter *I, int argc, PyLiteObject **args); 42 | PyLiteObject* pylt_method_list_index(PyLiteInterpreter *I, int argc, PyLiteObject **args); 43 | PyLiteObject* pylt_method_list_insert(PyLiteInterpreter *I, int argc, PyLiteObject **args); 44 | PyLiteObject* pylt_method_list_pop(PyLiteInterpreter *I, int argc, PyLiteObject **args); 45 | PyLiteObject* pylt_method_list_remove(PyLiteInterpreter *I, int argc, PyLiteObject **args); 46 | PyLiteObject* pylt_method_list_reverse(PyLiteInterpreter *I, int argc, PyLiteObject **args); 47 | PyLiteObject* pylt_method_list_sort(PyLiteInterpreter *I, int argc, PyLiteObject **args); 48 | 49 | PyLiteObject* pylt_cls_method_tuple_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 50 | 51 | PyLiteObject* pylt_cls_method_dict_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 52 | PyLiteObject* pylt_cls_method_dict_items(PyLiteInterpreter *I, int argc, PyLiteObject **args); 53 | 54 | // A new function returns None 55 | PyLiteObject* pylt_cls_method_meaningless_new(PyLiteInterpreter *I, int argc, PyLiteObject **args); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/vm.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_VM_H 3 | #define PYLITE_VM_H 4 | 5 | #include "utils/config.h" 6 | #include "types/all.h" 7 | #include "api.h" 8 | 9 | enum { 10 | BC_OPERATOR, // 运算符 11 | BC_SET_VAL, // 赋值 12 | BC_SET_VALX, // 偏移赋值 13 | BC_LOAD_VAL, // 载入变量(入栈) 14 | BC_LOAD_VAL_, // 载入变量(入栈) 15 | BC_LOADNONE, // 载入 None 16 | BC_LOADCONST, // 载入常量 17 | BC_LOADLOCALS, // 载入本地变量空间 18 | BC_NEW_OBJ, // 新建对象 19 | BC_CALL, // 函数调用 20 | BC_RET, // 函数结束 21 | BC_HALT, // 程序结束 22 | BC_PRINT, // 测试输出 23 | BC_TEST, // 真值测试(为假则跳转) 24 | BC_JMP, // 跳转 25 | BC_JMP_BACK, // 前向跳转 26 | BC_POP, // 弹出一个值 27 | BC_POPN, // 弹出多个值 28 | BC_FORITER, // For循环 29 | BC_GET_ITEM, // 取下标 30 | BC_GET_ITEM_, // 取下标 31 | BC_SET_ITEM, // 存入下标 32 | BC_GET_ATTR, // 取属性 33 | BC_GET_ATTR_, // 取属性 34 | BC_SET_ATTR, // 存入属性 35 | BC_GET_SLICE, // 读取分片 36 | BC_GET_SLICE_, // 读取分片 37 | BC_SET_SLICE, // 设置分片 38 | BC_DEL_FORCE, // 强制释放 39 | BC_DEL_NAME, // 删除变量 40 | BC_DEL_ATTR, // 删除属性 41 | BC_DEL_ITEM, // 删除下标 42 | BC_DEL_SLICE, // 删除分片 43 | BC_ASSERT, // 真值断言 44 | BC_EXPT_SETUP, // 设定异常 45 | BC_EXPT_POPN, // 弹出异常 46 | BC_RAISE, // 抛出异常 47 | 48 | BC_UNPACK_SEQ, // 解包 49 | BC_UNPACK_ARG, // 参数解包 50 | BC_IMPORT_NAME, // 导入模块 51 | BC_DICT_COMBINE, // 字典拼合 52 | BC_NOP, // 空指令 53 | 54 | BC_PH_BREAK, // 伪指令,break (ph == placeholder) 55 | BC_PH_CONTINUE, // 伪指令,continue 56 | }; 57 | 58 | enum { 59 | OP_OR, 60 | OP_AND, 61 | OP_NOT, 62 | OP_IN, OP_NOT_IN, OP_IS, OP_IS_NOT, OP_LT, OP_LE, OP_GT, OP_GE, OP_NE, OP_EQ, 63 | OP_BITOR, 64 | OP_BITXOR, 65 | OP_BITAND, 66 | OP_LSHIFT, OP_RSHIFT, 67 | OP_PLUS, OP_MINUS, 68 | OP_MUL, OP_MATMUL, OP_DIV, OP_FLOORDIV, OP_MOD, 69 | OP_POS, OP_NEG, OP_BITNOT, 70 | OP_POW 71 | } OperatorValue; 72 | 73 | typedef struct PyLiteFrame { 74 | PyLiteDictObject *locals; 75 | PyLiteFunctionObject *func; 76 | PyLiteCodeObject *code; 77 | PyLiteInstruction *ip_saved; 78 | pl_bool_t halt_when_ret; 79 | } PyLiteFrame; 80 | 81 | typedef struct PyLiteExceptInfo { 82 | pl_uint32_t typecode; 83 | PyLiteInstruction *ip_catch; 84 | PyLiteFrame *frame; 85 | } PyLiteExceptInfo; 86 | 87 | typedef struct PyLiteContext { 88 | PyLiteInstruction *ip; 89 | pl_uint_t params_offset; 90 | kvec_t(uintptr_t) stack; 91 | kvec_t(PyLiteFrame) frames; 92 | kvec_t(PyLiteExceptInfo) expt_stack; 93 | } PyLiteContext; 94 | 95 | typedef struct PyLiteVM { 96 | PyLiteContext *ctx; 97 | PyLiteModuleObject *builtins; 98 | } PyLiteVM; 99 | 100 | void pylt_vm_load_code(PyLiteInterpreter *I, PyLiteCodeObject *code); 101 | void pylt_vm_push_code(PyLiteInterpreter *I, PyLiteCodeObject *code); 102 | void pylt_vm_push_func(PyLiteInterpreter *I, PyLiteFunctionObject *func); 103 | void pylt_vm_pop_frame(PyLiteInterpreter *I); 104 | 105 | const wchar_t* pylt_vm_get_op_name(int op); 106 | int token_to_op_val(uint32_t tk); 107 | int token_de_to_op_val(uint32_t tk); 108 | 109 | PyLiteDictObject *pl_vm_get_locals(PyLiteInterpreter *I); 110 | PyLiteFrame* pylt_vm_curframe(PyLiteInterpreter *I); 111 | 112 | void pylt_vm_init(PyLiteInterpreter *I, PyLiteVM *vm); 113 | void pylt_vm_finalize(PyLiteInterpreter *I); 114 | PyLiteDictObject* pylt_vm_run(PyLiteInterpreter *I); 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /src/shell.c: -------------------------------------------------------------------------------- 1 | 2 | #include "lexer.h" 3 | #include "parser.h" 4 | #include "utils/io/_io.h" 5 | #include "utils/debug.h" 6 | #include "vm.h" 7 | #include "api.h" 8 | #include "intp.h" 9 | 10 | #include "utils/misc.h" 11 | #include "types/object.h" 12 | 13 | #ifdef PLAYGROUND 14 | 15 | int main(int argc, char* argv[]) { 16 | platform_init(); 17 | PyLiteInterpreter *I = pylt_intp_new(); 18 | PyLiteFile *input = pylt_io_openRead(I, pl_cformat(I, (argc == 2) ? argv[1] : "test.py")); 19 | if (!input) return 0; 20 | 21 | /*debug_test_lexer(I, input); 22 | system("pause"); 23 | return 0;*/ 24 | 25 | pylt_intp_loadf(I, input); 26 | 27 | #ifdef PL_DEBUG_INFO 28 | putwchar('\n'); 29 | PyLiteCodeObject *code = kv_top(I->vm.ctx->frames).code; 30 | debug_print_const_vals(I, code); 31 | debug_print_opcodes(I, code); 32 | putwchar('\n'); 33 | #endif 34 | 35 | pylt_vm_run(I); 36 | pylt_intp_finalize(I); 37 | #ifdef PL_DEBUG_INFO 38 | #ifdef PLATFORM_WINDOWS 39 | system("pause"); 40 | #endif 41 | #endif 42 | return 0; 43 | } 44 | #endif 45 | 46 | #ifdef SHELL 47 | 48 | #include "deps/linenoise/linenoise.h" 49 | 50 | void completion(const wchar_t *buf, linenoiseCompletions *lc) { 51 | if (buf[0] == L'h') { 52 | linenoiseAddCompletion(lc, L"hello"); 53 | linenoiseAddCompletion(lc, L"hello there"); 54 | } else if (buf[0] == L'测') { 55 | linenoiseAddCompletion(lc, L"测试3"); 56 | } 57 | } 58 | 59 | int main(int argc, char* argv[]) { 60 | platform_init(); 61 | 62 | wchar_t *line; 63 | char *prgname = argv[0]; 64 | 65 | /* Parse options, with --multiline we enable multi line editing. */ 66 | while (argc > 1) { 67 | argc--; 68 | argv++; 69 | if (!strcmp(*argv, "--multiline")) { 70 | linenoiseSetMultiLine(1); 71 | printf("Multi-line mode enabled.\n"); 72 | } else if (!strcmp(*argv, "--keycodes")) { 73 | linenoisePrintKeyCodes(); 74 | exit(0); 75 | } else { 76 | fprintf(stderr, "Usage: %s [--multiline] [--keycodes]\n", prgname); 77 | exit(1); 78 | } 79 | } 80 | 81 | /* Set the completion callback. This will be called every time the 82 | * user uses the key. */ 83 | linenoiseSetCompletionCallback(completion); 84 | 85 | /* Load history from file. The history file is just a plain text file 86 | * where entries are separated by newlines. */ 87 | linenoiseHistoryLoad("history.txt"); /* Load the history at startup */ 88 | 89 | /* Now this is the main loop of the typical linenoise-based application. 90 | * The call to linenoise() will block as long as the user types something 91 | * and presses enter. 92 | * 93 | * The typed string is returned as a malloc() allocated string by 94 | * linenoise, so the user needs to free() it. */ 95 | while ((line = linenoise(L"a啊测试> ")) != NULL) { 96 | /* Do something with the string. */ 97 | if (line[0] != '\0' && line[0] != '/') { 98 | wprintf(L"echo: '%ls'\n", line); 99 | linenoiseHistoryAdd(line); /* Add to the history. */ 100 | linenoiseHistorySave("history.txt"); /* Save the history on disk. */ 101 | } else if (!wcsncmp(line, L"/historylen", 11)) { 102 | /* The "/historylen" command will change the history len. */ 103 | int len = wcstol(line + 11, NULL, 10); 104 | linenoiseHistorySetMaxLen(len); 105 | } else if (line[0] == '/') { 106 | printf_u8("Unreconized command: %s\n", line); 107 | } 108 | free(line); 109 | } 110 | return 0; 111 | } 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /src/utils/io/io_simple.c: -------------------------------------------------------------------------------- 1 | 2 | #include "../misc.h" 3 | #include "../../api.h" 4 | #include "../../intp.h" 5 | #include "../../types/all.h" 6 | #include "io.h" 7 | #include "io_simple.h" 8 | 9 | #include 10 | #include 11 | 12 | #ifdef PLATFORM_WINDOWS 13 | #include 14 | #include 15 | #define fileno(fp) _fileno(fp) 16 | #define read(fd,buffer,count) read(fd,buffer,count) 17 | #define write(fd,buffer,count) write(fd,buffer,count) 18 | #else 19 | #include 20 | #include 21 | #endif 22 | 23 | 24 | void* pylt_io_simple_fileopen(PyLiteInterpreter *I, PyLiteStrObject *fn, int mode) { 25 | int fd; 26 | int err = 0; 27 | #ifdef PLATFORM_WINDOWS 28 | wchar_t cfn[256]; 29 | 30 | int ret = uc_ucs4str_to_wcharz(fn->ob_val, fn->ob_size, (wchar_t*)&cfn, 255); 31 | if (ret < 0) { 32 | pl_error(I, pl_static.str.UnicodeEncodeError, "invalid filename."); 33 | return NULL; 34 | } 35 | 36 | int openflag = pylt_io_mode_to_posix(mode); 37 | if (openflag == -1) { 38 | pl_error(I, pl_static.str.ValueError, "must have exactly one of create/read/write/append mode"); 39 | return NULL; 40 | } 41 | 42 | fd = _wopen(cfn, openflag); 43 | #else 44 | char fn_u8[1024]; 45 | 46 | int ret = uc_ucs4str_to_utf8z(fn->ob_val, fn->ob_size, (char*)&fn_u8, 1023); 47 | if (ret < 0) { 48 | pl_error(I, pl_static.str.UnicodeEncodeError, "invalid filename."); 49 | return NULL; 50 | } 51 | 52 | int openflag = pylt_io_mode_to_posix(mode); 53 | if (openflag == -1) { 54 | pl_error(I, pl_static.str.ValueError, "must have exactly one of create/read/write/append mode"); 55 | return NULL; 56 | } 57 | 58 | fd = open(cfn, openmode); 59 | #endif 60 | if (fd != -1) { 61 | PyLiteFileSimple* pfs = pylt_malloc(I, sizeof(PyLiteFileSimple)); 62 | pfs->fno = fd; 63 | pfs->flag = openflag; 64 | 65 | struct stat stbuf; 66 | fstat(fd, &stbuf); 67 | pfs->size = stbuf.st_size; 68 | return pfs; 69 | } else { 70 | switch (errno) { 71 | case ENOENT: 72 | pl_error(I, pl_static.str.FileNotFoundError, "[Errno 2] No such file or directory: %r", fn); 73 | break; 74 | case EACCES: // open dir, windows 75 | pl_error(I, pl_static.str.PermissionError, "[Errno 13] Permission denied: %r", fn); 76 | break; 77 | case EISDIR: // open dir, linux 78 | pl_error(I, pl_static.str.IsADirectoryError, "[Errno 21] Is a directory: %r", fn); 79 | break; 80 | default: 81 | pl_error(I, pl_static.str.OSError, "[Errno %d] File Open Error: %r", pylt_obj_int_new(I, errno), fn); 82 | } 83 | return NULL; 84 | } 85 | } 86 | 87 | pl_int_t pylt_io_simple_fileclose(PyLiteInterpreter *I, void *pfdata) { 88 | PyLiteFileSimple *pfs = (PyLiteFileSimple*)pfdata; 89 | return close(pfs->fno); 90 | } 91 | 92 | pl_int_t pylt_io_simple_read(PyLiteInterpreter *I, void *pfdata, uint8_t *buf, pl_uint_t count) { 93 | PyLiteFileSimple *pfs = (PyLiteFileSimple*)pfdata; 94 | return read(pfs->fno, buf, count); 95 | } 96 | 97 | pl_int_t pylt_io_simple_write(PyLiteInterpreter *I, void *pfdata, uint8_t *buf, pl_uint_t count) { 98 | PyLiteFileSimple *pfs = (PyLiteFileSimple*)pfdata; 99 | return write(pfs->fno, buf, count); 100 | } 101 | 102 | PyLiteIO PyLiteIOSimple = { 103 | .open = &pylt_io_simple_fileopen, 104 | .close = &pylt_io_simple_fileclose, 105 | .read = &pylt_io_simple_read, 106 | .write = &pylt_io_simple_write 107 | }; 108 | -------------------------------------------------------------------------------- /src/deps/fpconv/powers.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define npowers 87 4 | #define steppowers 8 5 | #define firstpower -348 /* 10 ^ -348 */ 6 | 7 | #define expmax -32 8 | #define expmin -60 9 | 10 | 11 | typedef struct Fp { 12 | uint64_t frac; 13 | int exp; 14 | } Fp; 15 | 16 | static Fp powers_ten[] = { 17 | { 18054884314459144840U, -1220 }, { 13451937075301367670U, -1193 }, 18 | { 10022474136428063862U, -1166 }, { 14934650266808366570U, -1140 }, 19 | { 11127181549972568877U, -1113 }, { 16580792590934885855U, -1087 }, 20 | { 12353653155963782858U, -1060 }, { 18408377700990114895U, -1034 }, 21 | { 13715310171984221708U, -1007 }, { 10218702384817765436U, -980 }, 22 | { 15227053142812498563U, -954 }, { 11345038669416679861U, -927 }, 23 | { 16905424996341287883U, -901 }, { 12595523146049147757U, -874 }, 24 | { 9384396036005875287U, -847 }, { 13983839803942852151U, -821 }, 25 | { 10418772551374772303U, -794 }, { 15525180923007089351U, -768 }, 26 | { 11567161174868858868U, -741 }, { 17236413322193710309U, -715 }, 27 | { 12842128665889583758U, -688 }, { 9568131466127621947U, -661 }, 28 | { 14257626930069360058U, -635 }, { 10622759856335341974U, -608 }, 29 | { 15829145694278690180U, -582 }, { 11793632577567316726U, -555 }, 30 | { 17573882009934360870U, -529 }, { 13093562431584567480U, -502 }, 31 | { 9755464219737475723U, -475 }, { 14536774485912137811U, -449 }, 32 | { 10830740992659433045U, -422 }, { 16139061738043178685U, -396 }, 33 | { 12024538023802026127U, -369 }, { 17917957937422433684U, -343 }, 34 | { 13349918974505688015U, -316 }, { 9946464728195732843U, -289 }, 35 | { 14821387422376473014U, -263 }, { 11042794154864902060U, -236 }, 36 | { 16455045573212060422U, -210 }, { 12259964326927110867U, -183 }, 37 | { 18268770466636286478U, -157 }, { 13611294676837538539U, -130 }, 38 | { 10141204801825835212U, -103 }, { 15111572745182864684U, -77 }, 39 | { 11258999068426240000U, -50 }, { 16777216000000000000U, -24 }, 40 | { 12500000000000000000U, 3 }, { 9313225746154785156U, 30 }, 41 | { 13877787807814456755U, 56 }, { 10339757656912845936U, 83 }, 42 | { 15407439555097886824U, 109 }, { 11479437019748901445U, 136 }, 43 | { 17105694144590052135U, 162 }, { 12744735289059618216U, 189 }, 44 | { 9495567745759798747U, 216 }, { 14149498560666738074U, 242 }, 45 | { 10542197943230523224U, 269 }, { 15709099088952724970U, 295 }, 46 | { 11704190886730495818U, 322 }, { 17440603504673385349U, 348 }, 47 | { 12994262207056124023U, 375 }, { 9681479787123295682U, 402 }, 48 | { 14426529090290212157U, 428 }, { 10748601772107342003U, 455 }, 49 | { 16016664761464807395U, 481 }, { 11933345169920330789U, 508 }, 50 | { 17782069995880619868U, 534 }, { 13248674568444952270U, 561 }, 51 | { 9871031767461413346U, 588 }, { 14708983551653345445U, 614 }, 52 | { 10959046745042015199U, 641 }, { 16330252207878254650U, 667 }, 53 | { 12166986024289022870U, 694 }, { 18130221999122236476U, 720 }, 54 | { 13508068024458167312U, 747 }, { 10064294952495520794U, 774 }, 55 | { 14996968138956309548U, 800 }, { 11173611982879273257U, 827 }, 56 | { 16649979327439178909U, 853 }, { 12405201291620119593U, 880 }, 57 | { 9242595204427927429U, 907 }, { 13772540099066387757U, 933 }, 58 | { 10261342003245940623U, 960 }, { 15290591125556738113U, 986 }, 59 | { 11392378155556871081U, 1013 }, { 16975966327722178521U, 1039 }, 60 | { 12648080533535911531U, 1066 } 61 | }; 62 | 63 | static Fp find_cachedpow10(int exp, int* k) 64 | { 65 | const double one_log_ten = 0.30102999566398114; 66 | 67 | int approx = -(exp + npowers) * one_log_ten; 68 | int idx = (approx - firstpower) / steppowers; 69 | 70 | while(1) { 71 | int current = exp + powers_ten[idx].exp + 64; 72 | 73 | if(current < expmin) { 74 | idx++; 75 | continue; 76 | } 77 | 78 | if(current > expmax) { 79 | idx--; 80 | continue; 81 | } 82 | 83 | *k = (firstpower + idx * steppowers); 84 | 85 | return powers_ten[idx]; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/types/common/number.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_NUMBER_H 3 | #define PYLITE_TYPES_NUMBER_H 4 | 5 | #include "../object.h" 6 | 7 | typedef struct PyLiteIntObject { 8 | PyLiteObject_HEAD; 9 | pl_int_t ob_val; 10 | } PyLiteIntObject; 11 | 12 | 13 | typedef struct PyLiteFloatObject { 14 | PyLiteObject_HEAD; 15 | pl_float_t ob_val; 16 | } PyLiteFloatObject; 17 | 18 | 19 | pl_int_t pylt_obj_int_cmp(PyLiteInterpreter *I, PyLiteIntObject *self, PyLiteObject *other); 20 | pl_bool_t pylt_obj_int_eq(PyLiteInterpreter *I, PyLiteIntObject *self, PyLiteObject *other); 21 | pl_uint32_t pylt_obj_int_hash(PyLiteInterpreter *I, PyLiteIntObject *obj); 22 | 23 | PyLiteObject* pylt_obj_int_bitor(PyLiteInterpreter *I, PyLiteIntObject *self, PyLiteObject *other); 24 | PyLiteObject* pylt_obj_int_bitxor(PyLiteInterpreter *I, PyLiteIntObject *self, PyLiteObject *other); 25 | PyLiteObject* pylt_obj_int_bitand(PyLiteInterpreter *I, PyLiteIntObject *self, PyLiteObject *other); 26 | PyLiteObject* pylt_obj_int_bitls(PyLiteInterpreter *I, PyLiteIntObject *self, PyLiteObject *other); 27 | PyLiteObject* pylt_obj_int_bitrs(PyLiteInterpreter *I, PyLiteIntObject *self, PyLiteObject *other); 28 | 29 | PyLiteObject* pylt_obj_int_plus(PyLiteInterpreter *I, PyLiteIntObject *self, PyLiteObject *other); 30 | PyLiteObject* pylt_obj_int_minus(PyLiteInterpreter *I, PyLiteIntObject *self, PyLiteObject *other); 31 | PyLiteObject* pylt_obj_int_mul(PyLiteInterpreter *I, PyLiteIntObject *self, PyLiteObject *other); 32 | PyLiteObject* pylt_obj_int_div(PyLiteInterpreter *I, PyLiteIntObject *self, PyLiteObject *other); 33 | PyLiteObject* pylt_obj_int_floordiv(PyLiteInterpreter *I, PyLiteIntObject *self, PyLiteObject *other); 34 | PyLiteObject* pylt_obj_int_mod(PyLiteInterpreter *I, PyLiteIntObject *self, PyLiteObject *other); 35 | 36 | PyLiteObject* pylt_obj_int_positive(PyLiteInterpreter *I, PyLiteIntObject *self); 37 | PyLiteObject* pylt_obj_int_negative(PyLiteInterpreter *I, PyLiteIntObject *self); 38 | PyLiteObject* pylt_obj_int_bitnot(PyLiteInterpreter *I, PyLiteIntObject *self); 39 | PyLiteObject* pylt_obj_int_pow(PyLiteInterpreter *I, PyLiteIntObject *self, PyLiteObject *other); 40 | 41 | 42 | pl_int_t pylt_obj_float_cmp(PyLiteInterpreter *I, PyLiteFloatObject *self, PyLiteObject *other); 43 | pl_bool_t pylt_obj_float_eq(PyLiteInterpreter *I, PyLiteFloatObject *self, PyLiteObject *other); 44 | pl_uint32_t pylt_obj_float_hash(PyLiteInterpreter *I, PyLiteFloatObject *obj); 45 | 46 | PyLiteObject* pylt_obj_float_plus(PyLiteInterpreter *I, PyLiteFloatObject *self, PyLiteObject *other); 47 | PyLiteObject* pylt_obj_float_minus(PyLiteInterpreter *I, PyLiteFloatObject *self, PyLiteObject *other); 48 | PyLiteObject* pylt_obj_float_mul(PyLiteInterpreter *I, PyLiteFloatObject *self, PyLiteObject *other); 49 | PyLiteObject* pylt_obj_float_div(PyLiteInterpreter *I, PyLiteFloatObject *self, PyLiteObject *other); 50 | PyLiteObject* pylt_obj_float_floordiv(PyLiteInterpreter *I, PyLiteFloatObject *self, PyLiteObject *other); 51 | PyLiteObject* pylt_obj_float_mod(PyLiteInterpreter *I, PyLiteFloatObject *self, PyLiteObject *other); 52 | 53 | PyLiteObject* pylt_obj_float_positive(PyLiteInterpreter *I, PyLiteFloatObject *self); 54 | PyLiteObject* pylt_obj_float_negative(PyLiteInterpreter *I, PyLiteFloatObject *self); 55 | PyLiteObject* pylt_obj_float_pow(PyLiteInterpreter *I, PyLiteFloatObject *self, PyLiteObject *other); 56 | 57 | uint32_t* pylt_obj_int_to_ucs4(PyLiteInterpreter *I, PyLiteIntObject *self, pl_int_t *plen); 58 | struct PyLiteStrObject* pylt_obj_int_to_str(PyLiteInterpreter *I, PyLiteIntObject *self); 59 | uint32_t* pylt_obj_float_to_ucs4(PyLiteInterpreter *I, PyLiteFloatObject *self, pl_int_t *plen); 60 | struct PyLiteStrObject* pylt_obj_float_to_str(PyLiteInterpreter *I, PyLiteFloatObject *self); 61 | 62 | PyLiteIntObject* pylt_obj_int_new(PyLiteInterpreter *I, pl_int_t val); 63 | PyLiteFloatObject* pylt_obj_float_new(PyLiteInterpreter *I, double val); 64 | 65 | PyLiteIntObject* pylt_obj_int_new_from_cstr_full(PyLiteInterpreter *I, const char *str, pl_int_t size, pl_int_t base_n); 66 | PyLiteFloatObject* pylt_obj_float_new_from_cstr_full(PyLiteInterpreter *I, const char *str, pl_int_t size, pl_int_t point_pos); 67 | 68 | void pylt_obj_int_rfree(PyLiteInterpreter *I, PyLiteIntObject *self); 69 | void pylt_obj_int_free(PyLiteInterpreter *I, PyLiteIntObject *self); 70 | void pylt_obj_float_rfree(PyLiteInterpreter *I, PyLiteFloatObject *self); 71 | void pylt_obj_float_free(PyLiteInterpreter *I, PyLiteFloatObject *self); 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /src/deps/kvec.h: -------------------------------------------------------------------------------- 1 | /* The MIT License 2 | 3 | Copyright (c) 2008, by Attractive Chaos 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | */ 25 | 26 | /* 27 | An example: 28 | 29 | #include "kvec.h" 30 | int main() { 31 | kvec_t(int) array; 32 | kv_init(array); 33 | kv_push(int, array, 10); // append 34 | kv_a(int, array, 20) = 5; // dynamic 35 | kv_A(array, 20) = 4; // static 36 | kv_destroy(array); 37 | return 0; 38 | } 39 | */ 40 | 41 | /* 42 | 2008-09-22 (0.1.0): 43 | 44 | * The initial version. 45 | 46 | */ 47 | 48 | #ifndef AC_KVEC_H 49 | #define AC_KVEC_H 50 | 51 | #include 52 | #include "../utils/config.h" 53 | 54 | #ifndef krealloc 55 | #define krealloc(I,P,O,N) pylt_realloc(I,P,(O),(N)) 56 | #endif 57 | #ifndef kfree 58 | #define kfree(I,P,S) pylt_free(I, P, S) 59 | #define kfree_ex(I,P) pylt_free_ex(I, P) 60 | #endif 61 | 62 | #define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) 63 | 64 | #define kvec_t(type) struct { size_t n, m; type *a;PyLiteInterpreter *I; } 65 | #define kv_init(_I, v) ((v).n = (v).m = 0, (v).a = 0, (v).I = (_I)) 66 | #define kv_destroy(v) kfree((v).I, (v).a, sizeof(*((v).a)) * (v).m) 67 | #define kv_A(v, i) ((v).a[(i)]) 68 | #define kv_P(v, i) ((v).a + (i)) 69 | #define kv_top(v) ((v).a[(v).n-1]) 70 | #define kv_topn(v, num) ((v).a[(v).n-1-(num)]) 71 | #define kv_pop(v) ((v).a[--(v).n]) 72 | #define kv_popn(v, num) (v).n -= (num) 73 | #define kv_size(v) ((v).n) 74 | #define kv_max(v) ((v).m) 75 | #define kv_clear(v) ((v).n = 0) 76 | 77 | #define kv_resize(type, v, s) ((v).a = (type*)krealloc((v).I, (v).a, sizeof(type) * (v).m, sizeof(type) * (s)), (v).m = (s)) 78 | 79 | #define kv_shallowcopy(dest, src) { \ 80 | (dest).n = (src).n; (dest).m = (src).m; (dest).a = (src).a; (dest).I = (src).I; \ 81 | } 82 | 83 | #define kv_copy(type, v1, v0) do { \ 84 | if ((v1).m < (v0).n) kv_resize(type, v1, (v0).n); \ 85 | (v1).n = (v0).n; \ 86 | memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \ 87 | } while (0) \ 88 | 89 | #define kv_copy1(type, v1, v0) do { \ 90 | if ((v1).m < (v0).n) kv_resize(type, v1, (v0).n+1); \ 91 | (v1).n = (v0).n; \ 92 | memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \ 93 | } while (0) \ 94 | 95 | #define kv_push(type, v, x) do { \ 96 | if ((v).n == (v).m) { \ 97 | (v).m = (v).m? (v).m<<1 : 2; \ 98 | (v).a = (type*)krealloc((v).I, (v).a, sizeof(type) * (v).n, sizeof(type) * (v).m); \ 99 | } \ 100 | (v).a[(v).n++] = (x); \ 101 | } while (0) 102 | 103 | #define kv_pushp(type, v) (((v).n == (v).m)? \ 104 | ((v).m = ((v).m? (v).m<<1 : 2), \ 105 | (v).a = (type*)krealloc((v).I, (v).a, sizeof(type) * (v).n, sizeof(type) * (v).m), 0) \ 106 | : 0), ((v).a + ((v).n++)) 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /src/types/common/tuple.c: -------------------------------------------------------------------------------- 1 | 2 | #include "tuple.h" 3 | #include "string.h" 4 | #include "../../api.h" 5 | #include "../../utils/misc.h" 6 | 7 | // 将 index 转为标准形式并约束到可用范围 8 | #define index_fix(__index) \ 9 | if (__index < 0) __index += self->ob_size; \ 10 | if (__index < 0) __index = 0; \ 11 | else if (__index >= self->ob_size) __index = self->ob_size; 12 | 13 | 14 | #define index_chk(__index, failret) \ 15 | if (__index < 0) __index += self->ob_size; \ 16 | if (__index < 0 || __index >= self->ob_size) return failret; 17 | 18 | 19 | pl_bool_t pylt_obj_tuple_eq(PyLiteInterpreter *I, PyLiteTupleObject *self, PyLiteObject *other) { 20 | if (pl_istuple(other)) { 21 | if (casttuple(other)->ob_size != self->ob_size) return false; 22 | pl_foreach_tuple(I, i, self) { 23 | if (self->ob_val[i] != casttuple(other)->ob_val[i]) return false; 24 | } 25 | return true; 26 | } 27 | return false; 28 | } 29 | 30 | 31 | struct PyLiteStrObject* pylt_obj_tuple_to_str(PyLiteInterpreter *I, PyLiteTupleObject *self) { 32 | int index = 0; 33 | PyLiteStrObject *str; 34 | PyLiteStrObject **strlst = NULL; 35 | pl_uint_t tlen = self->ob_size; 36 | 37 | if (tlen == 0) { 38 | return pl_static.str.TMPL_EMPTY_TUPLE; // () 39 | } 40 | 41 | pl_uint32_t *data; 42 | pl_uint32_t comma_num = tlen - 1; 43 | pl_uint32_t data_len = 2 + comma_num * 2; // () + ', ' 44 | strlst = pylt_malloc(I, tlen * sizeof(PyLiteStrObject*)); 45 | 46 | for (pl_uint_t i = 0; i < tlen; ++i) { 47 | str = pylt_obj_to_repr(I, self->ob_val[i]); 48 | data_len += str->ob_size; 49 | strlst[index++] = str; 50 | } 51 | 52 | data = pylt_malloc(I, data_len * sizeof(uint32_t)); 53 | data[0] = '('; 54 | index = 1; 55 | for (pl_uint_t i = 0; i < tlen; ++i) { 56 | memcpy(data + index, strlst[i]->ob_val, strlst[i]->ob_size * sizeof(uint32_t)); 57 | index += strlst[i]->ob_size; 58 | if (i != tlen - 1) { 59 | data[index++] = ','; 60 | data[index++] = ' '; 61 | } 62 | } 63 | data[data_len - 1] = ')'; 64 | 65 | str = pylt_obj_str_new(I, data, data_len, true); 66 | pylt_free(I, data, data_len * sizeof(uint32_t)); 67 | pylt_free_ex(I, strlst); 68 | return str; 69 | } 70 | 71 | PyLiteTupleObject* pylt_obj_tuple_new(PyLiteInterpreter *I, pl_int_t len) { 72 | PyLiteTupleObject *obj = pylt_malloc(I, sizeof(PyLiteTupleObject)); 73 | obj->ob_type = PYLT_OBJ_TYPE_TUPLE; 74 | obj->ob_flags = 0; 75 | obj->ob_val = (len) ? pylt_malloc(I, len * sizeof(PyLiteObject*)) : NULL; 76 | obj->ob_size = len; 77 | return obj; 78 | } 79 | 80 | 81 | PyLiteTupleObject* pylt_obj_tuple_new_with_data(PyLiteInterpreter *I, pl_int_t len, void *data) { 82 | PyLiteTupleObject *obj = pylt_obj_tuple_new(I, len); 83 | if (len) memcpy(obj->ob_val, data, len * sizeof(PyLiteObject*)); 84 | return obj; 85 | } 86 | 87 | PyLiteObject* pylt_obj_tuple_getitem(PyLiteInterpreter *I, PyLiteTupleObject *self, int index) { 88 | if (index < 0) index += self->ob_size; 89 | if (index < 0 || index >= self->ob_size) return NULL; 90 | return self->ob_val[index]; 91 | } 92 | 93 | PyLiteTupleObject* pylt_obj_tuple_slice(PyLiteInterpreter *I, PyLiteTupleObject *self, pl_int_t *pstart, pl_int_t *pend, pl_int_t step) { 94 | pl_int_t start, end; 95 | if (step == 0) return NULL; 96 | start = pstart ? *pstart : (step > 0) ? 0 : self->ob_size; 97 | end = pend ? *pend : (step > 0) ? self->ob_size : 0; 98 | 99 | index_fix(start); 100 | index_fix(end); 101 | 102 | if (step < 0) { 103 | start -= 1; 104 | if (!pend) end -= 1; 105 | } 106 | 107 | pl_int_t count = (pl_int_t)ceil(abs(end - start) / abs(step)); 108 | PyLiteTupleObject *lst = pylt_obj_tuple_new(I, count); 109 | lst->ob_size = count; 110 | 111 | if (step == 1) { 112 | memcpy(lst->ob_val, self->ob_val + start, count * sizeof(PyLiteObject*)); 113 | } else { 114 | pl_int_t cur_index = start; 115 | for (pl_int_t i = 0; i < count; ++i) { 116 | lst->ob_val[i] = self->ob_val[cur_index]; 117 | cur_index += step; 118 | } 119 | } 120 | return lst; 121 | } 122 | 123 | void pylt_obj_tuple_rfree(PyLiteInterpreter *I, PyLiteTupleObject *self) { 124 | pylt_free(I, self->ob_val, sizeof(PyLiteObject*) * self->ob_size); 125 | pylt_free_ex(I, self); 126 | } 127 | 128 | void pylt_obj_tuple_free(PyLiteInterpreter *I, PyLiteTupleObject *self) { 129 | pylt_gc_remove(I, castobj(self)); 130 | pylt_obj_tuple_rfree(I, self); 131 | } 132 | -------------------------------------------------------------------------------- /src/mods/cio.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #include "cio.h" 7 | #include "../api.h" 8 | #include "../bind.h" 9 | #include "../types/all.h" 10 | #include "../utils/misc.h" 11 | #include "../utils/io/_io.h" 12 | 13 | PyLiteObject* pylt_mods_cio_fopen(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 14 | PyLiteStrObject *fn = caststr(args[0]); 15 | PyLiteStrObject *mode = caststr(args[1]); 16 | FILE *fp = pylt_io_fopen(I, fn, mode); 17 | 18 | if (!fp) { 19 | switch (errno) { 20 | case ENOENT: 21 | pl_error(I, pl_static.str.FileNotFoundError, "[Errno 2] No such file or directory: %r", args[0]); 22 | break; 23 | case EACCES: // open dir, windows 24 | pl_error(I, pl_static.str.PermissionError, "[Errno 13] Permission denied: %r", args[0]); 25 | break; 26 | case EISDIR: // open dir, linux 27 | pl_error(I, pl_static.str.IsADirectoryError, "[Errno 21] Is a directory: %r", args[0]); 28 | break; 29 | default: 30 | pl_error(I, pl_static.str.OSError, "[Errno %d] File Open Error: %r", pylt_obj_int_new(I, errno), args[0]); 31 | } 32 | } 33 | 34 | return castobj(pylt_obj_cptr_new(I, fp, false)); 35 | } 36 | 37 | PyLiteObject* pylt_mods_cio_fclose(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 38 | return castobj(pylt_obj_int_new(I, fclose(castcptr(args[0])->ob_ptr))); 39 | } 40 | 41 | 42 | PyLiteObject* pylt_mods_cio_fsize(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 43 | FILE *fp = castcptr(args[0])->ob_ptr; 44 | struct stat stbuf; 45 | fstat(fileno(fp), &stbuf); 46 | return castobj(pylt_obj_int_new(I, stbuf.st_size)); 47 | } 48 | 49 | 50 | PyLiteObject* pylt_mods_cio_fread(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 51 | // 这里有必要提一句,在Windows上,'r'模式下,fread之后的ftell就是一定会返回错误的值! 52 | // 不是BUG!切到'rb'就好了 53 | FILE *fp = castcptr(args[0])->ob_ptr; 54 | pl_int_t size = castint(args[1])->ob_val; 55 | 56 | /*long pos = ftell(fp); 57 | fseek(fp, 0, SEEK_END); 58 | long maxsize = ftell(fp) - pos; 59 | fseek(fp, pos, SEEK_SET); 60 | if (size > maxsize) size = maxsize;*/ 61 | 62 | uint8_t *buf = pylt_malloc(I, size+1); 63 | size_t read = fread(buf, size, 1, fp); 64 | if (read != 0) { 65 | PyLiteObject *ret = castobj(pylt_obj_bytes_new(I, (const char*)buf, size, true)); 66 | pylt_free(I, buf, size); 67 | return ret; 68 | } 69 | pylt_free(I, buf, size+1); 70 | return NULL; 71 | } 72 | 73 | // def fwrite(file, buffer: bytes) 74 | PyLiteObject* pylt_mods_cio_fwrite(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 75 | FILE *fp = castcptr(args[0])->ob_ptr; 76 | PyLiteBytesObject *buf = castbytes(args[1]); 77 | return castobj(pylt_obj_int_new(I, fwrite(buf->ob_val, buf->ob_size, 1, fp))); 78 | } 79 | 80 | // def ftell(file) 81 | PyLiteObject* pylt_mods_cio_ftell(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 82 | return castobj(pylt_obj_int_new(I, ftell(castcptr(args[0])->ob_ptr))); 83 | } 84 | 85 | 86 | // def fseek(file, offset: int, origin = SEEK_CUR: int) 87 | PyLiteObject* pylt_mods_cio_fseek(PyLiteInterpreter *I, int argc, PyLiteObject **args) { 88 | return castobj(pylt_obj_int_new(I, fseek(castcptr(args[0])->ob_ptr, castint(args[1])->ob_val, castint(args[2])->ob_val))); 89 | } 90 | 91 | 92 | PyLiteModuleObject* pylt_mods_cio_loader(PyLiteInterpreter *I) { 93 | PyLiteModuleObject *mod = pylt_obj_module_new(I, _S(cio)); 94 | 95 | pylt_obj_mod_setattr(I, mod, _NS(I, "SEEK_CUR"), castobj(pylt_obj_int_new(I, SEEK_CUR))); 96 | pylt_obj_mod_setattr(I, mod, _NS(I, "SEEK_END"), castobj(pylt_obj_int_new(I, SEEK_END))); 97 | pylt_obj_mod_setattr(I, mod, _NS(I, "SEEK_SET"), castobj(pylt_obj_int_new(I, SEEK_SET))); 98 | 99 | pylt_cfunc_register(I, mod, _NS(I, "fopen"), _NST(I, 2, "fn", "mode"), NULL, NULL, &pylt_mods_cio_fopen); 100 | pylt_cfunc_register(I, mod, _NS(I, "fclose"), _NST(I, 1, "file"), NULL, NULL, &pylt_mods_cio_fclose); 101 | pylt_cfunc_register(I, mod, _NS(I, "fsize"), _NST(I, 1, "file"), NULL, NULL, &pylt_mods_cio_fsize); 102 | pylt_cfunc_register(I, mod, _NS(I, "fread"), _NST(I, 2, "file", "size"), NULL, NULL, &pylt_mods_cio_fread); 103 | pylt_cfunc_register(I, mod, _NS(I, "fwrite"), _NST(I, 2, "file", "buf"), NULL, NULL, &pylt_mods_cio_fwrite); 104 | pylt_cfunc_register(I, mod, _NS(I, "ftell"), _NST(I, 1, "file"), NULL, NULL, &pylt_mods_cio_ftell); 105 | pylt_cfunc_register(I, mod, _NS(I, "fseek"), _NST(I, 3, "file", "offset", "origin"), _NT(I, 3, &PyLiteParamUndefined, &PyLiteParamUndefined, pylt_obj_int_new(I, SEEK_CUR)), NULL, &pylt_mods_cio_fseek); 106 | 107 | return mod; 108 | } 109 | 110 | pl_bool_t pylt_mods_cio_register(PyLiteInterpreter *I) { 111 | return pylt_mod_register(I, _S(cio), &pylt_mods_cio_loader, true); 112 | } 113 | -------------------------------------------------------------------------------- /src/types/extra/function.c: -------------------------------------------------------------------------------- 1 | 2 | #include "function.h" 3 | #include "../../vm.h" 4 | #include "../../bind.h" 5 | #include "../../intp.h" 6 | 7 | PyLiteDictObject* make_closure(PyLiteInterpreter *I, PyLiteCodeObject *code) { 8 | PyLiteContext *ctx = I->vm.ctx; 9 | PyLiteDictObject *closure = pylt_obj_dict_new(I); 10 | 11 | if (!code || !code->closure) return closure; 12 | pl_foreach_set(I, it, code->closure) { 13 | PyLiteObject *obj = NULL; 14 | PyLiteObject *name = pylt_obj_set_itemvalue(I, code->closure, it); 15 | for (int i = kv_size(ctx->frames) - 1; i >= 0; --i) { 16 | obj = pylt_obj_dict_getitem(I, kv_A(ctx->frames, i).locals, name); 17 | if (obj) { 18 | pylt_obj_dict_setitem(I, closure, name, obj); 19 | break; 20 | } 21 | } 22 | } 23 | 24 | return closure; 25 | } 26 | 27 | PyLiteFunctionObject* pylt_obj_func_new(PyLiteInterpreter *I, PyLiteCodeObject *code) { 28 | PyLiteObject_init(I, obj, PyLiteFunctionObject, PYLT_OBJ_TYPE_FUNCTION); 29 | memset(&obj->info, 0, sizeof(PyLiteFunctionInfo)); 30 | obj->ob_owner = NULL; 31 | 32 | if (code) { 33 | memcpy(&obj->code, code, sizeof(PyLiteCodeObject)); 34 | } else { 35 | obj->code.const_val = pylt_obj_list_new(I); 36 | obj->code.const_val->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 37 | kv_init(I, obj->code.opcodes); 38 | } 39 | obj->info.closure = make_closure(I, code); 40 | obj->info.closure->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 41 | return obj; 42 | } 43 | 44 | PyLiteFunctionObject* pylt_obj_func_new_ex(PyLiteInterpreter *I, PyLiteStrObject *name, PyLiteListObject *params, PyLiteCodeObject *code, PyLiteDictObject *defaults, PyLiteStrObject *args, PyLiteStrObject *kwargs) { 45 | PyLiteFunctionObject *func = pylt_obj_func_new(I, code); 46 | 47 | // set name and params 48 | func->info.name = name; 49 | func->info.length = params->ob_size; 50 | func->info.params = pylt_obj_tuple_new(I, params->ob_size); 51 | func->info.params->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 52 | memcpy(func->info.params->ob_val, params->ob_val, params->ob_size * sizeof(PyLiteObject*)); 53 | 54 | // set default values 55 | if (defaults || args || kwargs) { 56 | pl_int_t minimal = -1; 57 | PyLiteTupleObject *defvals = pylt_obj_tuple_new(I, params->ob_size); 58 | defvals->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 59 | 60 | for (int i = 0; i < params->ob_size; ++i) { 61 | PyLiteStrObject *name = caststr(params->ob_val[i]); 62 | if (name == args) { 63 | if (minimal == -1) minimal = i; 64 | defvals->ob_val[i] = castobj(&PyLiteParamArgs); 65 | } else if (name == kwargs) { 66 | if (minimal == -1) minimal = i; 67 | defvals->ob_val[i] = castobj(&PyLiteParamKwargs); 68 | } else if (defaults && pylt_obj_dict_has(I, defaults, castobj(name))) { 69 | if (minimal == -1) minimal = i; 70 | defvals->ob_val[i] = pylt_obj_dict_getitem(I, defaults, castobj(name)); 71 | } else defvals->ob_val[i] = castobj(&PyLiteParamUndefined); 72 | } 73 | 74 | func->info.defaults = defvals; 75 | func->info.minimal = minimal; 76 | } else { 77 | func->info.defaults = NULL; 78 | func->info.minimal = params->ob_size; 79 | } 80 | return func; 81 | } 82 | 83 | PyLiteFunctionInfo* pylt_obj_func_get_info(PyLiteInterpreter *I, PyLiteObject *func) { 84 | if (func->ob_type == PYLT_OBJ_TYPE_FUNCTION) 85 | return &castfunc(func)->info; 86 | if (func->ob_type == PYLT_OBJ_TYPE_CFUNCTION) 87 | return &castcfunc(func)->info; 88 | return NULL; 89 | } 90 | 91 | PyLiteCFunctionObject* pylt_obj_cfunc_new(PyLiteInterpreter *I, PyLiteStrObject *name, PyLiteTupleObject *param_names, PyLiteTupleObject *defaults, pl_uint_t *types, PyLiteCFunctionPtr cfunc) { 92 | PyLiteObject_init(I, func, PyLiteCFunctionObject, PYLT_OBJ_TYPE_CFUNCTION); 93 | func->info.length = param_names ? param_names->ob_size : 0; 94 | func->info.minimal = func->info.length; 95 | if (defaults) { 96 | pl_int_t skip = 0; 97 | for (pl_int_t i = 0; i < defaults->ob_size; ++i) { 98 | if (defaults->ob_val[i] == castobj(&PyLiteParamUndefined)) skip++; 99 | else break; 100 | } 101 | func->info.minimal -= (defaults->ob_size - skip); 102 | } 103 | 104 | func->ob_owner = NULL; 105 | func->info.name = name; 106 | func->info.doc = NULL; 107 | func->info.params = param_names ? param_names : NULL; 108 | func->info.defaults = defaults ? defaults : NULL; 109 | func->info.type_codes = types; 110 | func->info.closure = NULL; 111 | func->code = cfunc; 112 | 113 | if (func->info.params) func->info.params->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 114 | if (func->info.defaults) func->info.defaults->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 115 | 116 | return func; 117 | } 118 | 119 | PyLiteCFunctionObject* pylt_obj_cfunc_new_no_args(PyLiteInterpreter *I, PyLiteStrObject *name, PyLiteCFunctionPtr cfunc) { 120 | return pylt_obj_cfunc_new(I, name, NULL, NULL, NULL, cfunc); 121 | } 122 | -------------------------------------------------------------------------------- /src/types/common/set.c: -------------------------------------------------------------------------------- 1 | 2 | #include "set.h" 3 | #include "string.h" 4 | #include "../../utils/misc.h" 5 | #include "../../gc.h" 6 | 7 | 8 | pl_int_t pylt_obj_set_cmp(PyLiteInterpreter *I, PyLiteSetObject *self, PyLiteObject *other) { 9 | if (other->ob_type == PYLT_OBJ_TYPE_SET) { 10 | if (pylt_obj_set_eq(I, self, other)) return 0; 11 | if (pylt_obj_set_contains(I, self, castset(other))) return 1; 12 | if (pylt_obj_set_contains(I, castset(other), self)) return -1; 13 | return 3; 14 | } 15 | return 2; 16 | } 17 | 18 | 19 | pl_bool_t pylt_obj_set_eq(PyLiteInterpreter *I, PyLiteSetObject *self, PyLiteObject *other) { 20 | if (other->ob_type == PYLT_OBJ_TYPE_SET) { 21 | if (kho_size(self->ob_val) != kho_size(castset(other)->ob_val)) 22 | return false; 23 | 24 | for (khiter_t it = kho_begin(other->ob_val); it < kho_end(castset(other)->ob_val); ++it) { 25 | if (!kho_exist(castset(other)->ob_val, it)) continue; 26 | if (pylt_obj_set_has(I, self, kho_key(castset(other)->ob_val, it)) == NULL) return false; 27 | } 28 | return true; 29 | } 30 | return false; 31 | } 32 | 33 | pl_int_t pylt_obj_set_len(PyLiteInterpreter *I, PyLiteSetObject *self) { 34 | return (pl_int_t)kho_size(self->ob_val); 35 | } 36 | 37 | pl_bool_t pylt_obj_set_contains(PyLiteInterpreter *I, PyLiteSetObject *self, PyLiteSetObject *other) { 38 | if (kho_size(self->ob_val) <= kho_size(other->ob_val)) 39 | return false; 40 | 41 | for (khiter_t it = kho_begin(other->ob_val); it < kho_end(other->ob_val); ++it) { 42 | if (!kho_exist(other->ob_val, it)) continue; 43 | if (pylt_obj_set_has(I, self, kho_key(other->ob_val, it)) == NULL) return false; 44 | } 45 | return true; 46 | } 47 | 48 | pl_int_t pylt_obj_set_add(PyLiteInterpreter *I, PyLiteSetObject *self, PyLiteObject *obj) { 49 | int ret; 50 | if (!pylt_obj_hashable(I, obj)) return -1; 51 | kho_put(set_obj, self->ob_val, obj, &ret); 52 | return 0; 53 | } 54 | 55 | void pylt_obj_set_clear(PyLiteInterpreter *I, PyLiteSetObject *self) { 56 | kho_clear_set_obj(self->ob_val); 57 | } 58 | 59 | PyLiteSetObject* pylt_obj_set_copy(PyLiteInterpreter *I, PyLiteSetObject *self) { 60 | PyLiteSetObject *obj = pylt_obj_set_new(I); 61 | kho_resize(set_obj, obj->ob_val, pylt_obj_set_len(I, self)); 62 | 63 | for (pl_int32_t k = pylt_obj_set_begin(I, self); k != pylt_obj_set_end(I, self); pylt_obj_set_next(I, self, &k)) { 64 | pylt_obj_set_add(I, obj, pylt_obj_set_itemvalue(I, self, k)); 65 | } 66 | 67 | return obj; 68 | } 69 | 70 | PyLiteObject* pylt_obj_set_has(PyLiteInterpreter *I, PyLiteSetObject *self, PyLiteObject *obj) { 71 | khiter_t x = kho_get(set_obj, self->ob_val, obj); 72 | return (x != kho_end(self->ob_val)) ? kho_key(self->ob_val, x) : NULL; 73 | } 74 | 75 | pl_int_t pylt_obj_set_remove(PyLiteInterpreter *I, PyLiteSetObject *self, PyLiteObject *obj) { 76 | khiter_t x = kho_get(set_obj, self->ob_val, obj); 77 | if (x == kho_end(self->ob_val)) return -1; 78 | kho_del(set_obj, self->ob_val, x); 79 | return 0; 80 | } 81 | 82 | PyLiteObject* pylt_obj_set_pop(PyLiteInterpreter *I, PyLiteSetObject *self) { 83 | khiter_t k; 84 | if (kho_size(self->ob_val) == 0) 85 | return NULL; 86 | k = pylt_obj_set_begin(I, self); 87 | PyLiteObject *obj = pylt_obj_set_itemvalue(I, self, k); 88 | kho_del(set_obj, self->ob_val, k); 89 | return obj; 90 | } 91 | 92 | pl_int32_t pylt_obj_set_begin(PyLiteInterpreter *I, PyLiteSetObject *self) { 93 | pl_int32_t k = kho_begin(self->ob_val); 94 | while (k != kho_end(self->ob_val)) { 95 | if (kho_exist(self->ob_val, k)) return k; 96 | ++k; 97 | } 98 | return kho_end(self->ob_val); 99 | } 100 | 101 | pl_int32_t pylt_obj_set_end(PyLiteInterpreter *I, PyLiteSetObject *self) { 102 | return kho_end(self->ob_val); 103 | } 104 | 105 | PyLiteObject* pylt_obj_set_itemvalue(PyLiteInterpreter *I, PyLiteSetObject *self, pl_int32_t k) { 106 | return (kho_exist(self->ob_val, k)) ? castobj(kho_key(self->ob_val, k)) : NULL; 107 | } 108 | 109 | void pylt_obj_set_next(PyLiteInterpreter *I, PyLiteSetObject *self, pl_int32_t *k) { 110 | pl_int32_t key = *k; 111 | while (++key != kho_end(self->ob_val)) { 112 | if (kho_exist(self->ob_val, key)) { 113 | *k = key; 114 | return; 115 | } 116 | } 117 | *k = kho_end(self->ob_val); 118 | } 119 | 120 | struct PyLiteStrObject* pylt_obj_set_to_str(PyLiteInterpreter *I, PyLiteSetObject *self) { 121 | int index = 0; 122 | PyLiteStrObject *str; 123 | PyLiteStrObject **strlst = NULL; 124 | pl_uint_t slen = pylt_obj_set_len(I, self); 125 | 126 | if (slen == 0) { 127 | return pl_static.str.TMPL_EMPTY_SET; // set() 128 | } 129 | 130 | pl_uint32_t *data; 131 | pl_uint32_t comma_num = slen - 1; 132 | pl_uint32_t data_len = 2 + comma_num * 2; // {} + ', ' 133 | strlst = pylt_malloc(I, slen * sizeof(PyLiteStrObject*)); 134 | 135 | for (pl_int32_t k = pylt_obj_set_begin(I, self); k != pylt_obj_set_end(I, self); pylt_obj_set_next(I, self, &k)) { 136 | str = pylt_obj_to_repr(I, pylt_obj_set_itemvalue(I, self, k)); 137 | data_len += str->ob_size; 138 | strlst[index++] = str; 139 | } 140 | 141 | data = pylt_malloc(I, data_len * sizeof(uint32_t)); 142 | data[0] = '{'; 143 | index = 1; 144 | for (pl_uint_t i = 0; i < slen; ++i) { 145 | memcpy(data + index, strlst[i]->ob_val, strlst[i]->ob_size * sizeof(uint32_t)); 146 | index += strlst[i]->ob_size; 147 | if (i != slen - 1) { 148 | data[index++] = ','; 149 | data[index++] = ' '; 150 | } 151 | } 152 | data[data_len - 1] = '}'; 153 | 154 | str = pylt_obj_str_new(I, data, data_len, true); 155 | pylt_free(I, data, data_len * sizeof(uint32_t)); 156 | pylt_free_ex(I, strlst); 157 | return str; 158 | } 159 | 160 | PyLiteSetObject* pylt_obj_set_new(PyLiteInterpreter *I) { 161 | PyLiteObject_init(I, obj, PyLiteSetObject, PYLT_OBJ_TYPE_SET); 162 | obj->ob_val = kho_init(set_obj, state); 163 | return obj; 164 | } 165 | 166 | 167 | void pylt_obj_set_rfree(PyLiteInterpreter *I, PyLiteSetObject* self) { 168 | kho_destroy(set_obj, self->ob_val); 169 | pylt_free_ex(I, self); 170 | } 171 | 172 | void pylt_obj_set_free(PyLiteInterpreter *I, PyLiteSetObject* self) { 173 | pylt_gc_remove(I, castobj(self)); 174 | pylt_obj_set_rfree(I, self); 175 | } 176 | -------------------------------------------------------------------------------- /src/deps/linenoise/osfix/winfix.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef WIN32_INTEROP_FDAPI_FIX_M_H 3 | #define WIN32_INTEROP_FDAPI_FIX_M_H 4 | 5 | //#include "../../utfconvert/utfconvert.h" 6 | 7 | int mycrt_read(int fd, void *buffer, unsigned int count); 8 | int mycrt_write(int fd, void *buffer, unsigned int count); 9 | int mycrt_isatty(int fd); 10 | 11 | #define read(fd,buffer,count) mycrt_read(fd,buffer,count) 12 | #define write(fd,buffer,count) mycrt_write(fd,buffer,count) 13 | #define isatty(fd) mycrt_isatty(fd) 14 | 15 | int mk_wcswidth(const wchar_t *pwcs, size_t n); 16 | #define wcswidth(pwcs, n) mk_wcswidth(pwcs, n) 17 | 18 | #endif 19 | 20 | /* 21 | * Copyright (c), Microsoft Open Technologies, Inc. 22 | * All rights reserved. 23 | * Redistribution and use in source and binary forms, with or without 24 | * modification, are permitted provided that the following conditions are met: 25 | * - Redistributions of source code must retain the above copyright notice, 26 | * this list of conditions and the following disclaimer. 27 | * - Redistributions in binary form must reproduce the above copyright notice, 28 | * this list of conditions and the following disclaimer in the documentation 29 | * and/or other materials provided with the distribution. 30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 31 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 33 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 34 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 36 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 37 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 38 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | */ 41 | 42 | #ifndef WIN32_INTEROP_APIS_M_H 43 | #define WIN32_INTEROP_APIS_M_H 44 | 45 | #include 46 | #include 47 | #include // for rename 48 | 49 | // API replacement for non-fd stdio functions 50 | #define fseeko _fseeki64 51 | #define ftello _ftelli64 52 | #define snprintf _snprintf 53 | #define strcasecmp _stricmp 54 | #define strtoll _strtoi64 55 | 56 | #define swprintf _snwprintf 57 | 58 | #ifdef _WIN64 59 | #define strtol _strtoi64 60 | #define strtoul _strtoui64 61 | #endif 62 | 63 | #define sleep(x) Sleep((x)*1000) 64 | /* Redis calls usleep(1) to give thread some time. 65 | * Sleep(0) should do the same on Windows. 66 | * In other cases, usleep is called with millisec resolution 67 | * which can be directly translated to WinAPI Sleep() */ 68 | #undef usleep 69 | #define usleep(x) (x == 1) ? Sleep(0) : Sleep((int)((x)/1000)) 70 | 71 | 72 | /* following defined to choose little endian byte order */ 73 | #define __i386__ 1 74 | #if !defined(va_copy) 75 | #define va_copy(d,s) d = (s) 76 | #endif 77 | 78 | #define lseek lseek64 79 | 80 | #endif 81 | 82 | 83 | #ifndef WIN32_INTEROPA_PORTABILITY_H 84 | #define WIN32_INTEROPA_PORTABILITY_H 85 | 86 | 87 | #ifdef __cplusplus 88 | extern "C" 89 | { 90 | #endif 91 | 92 | /* Sometimes in the Windows port we make changes from: 93 | antirez_redis_statement(); 94 | to: 95 | #ifdef _WIN32 96 | windows_redis_statement(); 97 | #else 98 | antirez_redis_statement(); 99 | #endif 100 | 101 | If subsequently antirez changed that code, we might not detect the change during the next merge. 102 | The INDUCE_MERGE_CONFLICT macro expands to nothing, but it is used to make sure that the original line 103 | is modified with respect to the antirez version, so that any subsequent modifications will trigger a conflict 104 | during the next merge. 105 | 106 | Sample usage: 107 | #ifdef _WIN32 108 | windows_redis_statement(); 109 | #else 110 | antirez_redis_statement(); INDUCE_MERGE_CONFLICT 111 | #endif 112 | 113 | Don't use any parenthesis or semi-colon after INDUCE_MERGE_CONFLICT. 114 | Use it at the end of a line to preserve the original indentation. 115 | */ 116 | #define INDUCE_MERGE_CONFLICT 117 | 118 | /* Use WIN_PORT_FIX at the end of a line to mark places where we make changes to the code 119 | without using #ifdefs. Useful to keep the code more legible. Mainly intended for replacing 120 | the use of long (which is 64-bit on 64-bit Unix and 32-bit on 64-bit Windows) to portable types. 121 | In order to be eligible for an inline fix (without #ifdef), the change should be portable back to the Posix version. 122 | */ 123 | #define WIN_PORT_FIX 124 | 125 | #ifdef _WIN32 126 | #define IF_WIN32(x, y) x 127 | #define WIN32_ONLY(x) x 128 | #define POSIX_ONLY(x) 129 | #define inline __inline 130 | #else 131 | #define IF_WIN32(x, y) y 132 | #define WIN32_ONLY(x) 133 | #define POSIX_ONLY(x) x 134 | #endif 135 | 136 | #ifdef __cplusplus 137 | } 138 | #endif 139 | 140 | #endif 141 | 142 | 143 | /* 144 | * Modified by Henry Rawas (henryr@schakra.com) 145 | * - make it compatible with Visual Studio builds 146 | * - added wstrtod to handle INF, NAN 147 | * - added support for using IOCP with sockets 148 | */ 149 | 150 | #ifndef WIN32FIXES_M_H 151 | #define WIN32FIXES_M_H 152 | 153 | #pragma warning(error: 4005) 154 | #pragma warning(error: 4013) 155 | 156 | #ifdef WIN32 157 | #ifndef _WIN32 158 | #define _WIN32 159 | #endif 160 | #endif 161 | 162 | #define WIN32_LEAN_AND_MEAN 163 | #define NOGDI 164 | #define __USE_W32_SOCKETS 165 | 166 | #include 167 | #include 168 | #include 169 | #include // for _O_BINARY 170 | #include // for INT_MAX 171 | 172 | #define WNOHANG 1 173 | 174 | /* file mapping */ 175 | #define PROT_READ 1 176 | #define PROT_WRITE 2 177 | 178 | #define MAP_FAILED (void *) -1 179 | 180 | #define MAP_SHARED 1 181 | #define MAP_PRIVATE 2 182 | 183 | #if _MSC_VER < 1800 184 | #ifndef ECONNRESET 185 | #define ECONNRESET WSAECONNRESET 186 | #endif 187 | 188 | #ifndef EINPROGRESS 189 | #define EINPROGRESS WSAEINPROGRESS 190 | #endif 191 | 192 | #ifndef ETIMEDOUT 193 | #define ETIMEDOUT WSAETIMEDOUT 194 | #endif 195 | #endif 196 | 197 | // access check for executable uses X_OK. For Windows use READ access. 198 | #ifndef X_OK 199 | #define X_OK 4 200 | #endif 201 | 202 | #ifndef STDOUT_FILENO 203 | #define STDOUT_FILENO 1 204 | #endif 205 | 206 | #endif /* WIN32FIXES_H */ 207 | -------------------------------------------------------------------------------- /src/types/extra/iter.c: -------------------------------------------------------------------------------- 1 | 2 | #include "iter.h" 3 | #include "../all.h" 4 | #include "../objectE.h" 5 | #include "../../api.h" 6 | #include "../../utils/misc.h" 7 | 8 | PyLiteIterObject* pylt_obj_iter_new(PyLiteInterpreter *I, PyLiteObject *obj) { 9 | if (obj->ob_type == PYLT_OBJ_TYPE_ITER) return castiter(obj); 10 | PyLiteObject_init(I, iter, PyLiteIterObject, PYLT_OBJ_TYPE_ITER); 11 | 12 | iter->base = obj; 13 | iter->backup = NULL; 14 | 15 | switch (obj->ob_type) { 16 | case PYLT_OBJ_TYPE_BYTES: 17 | iter->array.count = castbytes(obj)->ob_size; 18 | iter->array.index = 0; 19 | iter->iter_func = &pylt_obj_bytes_iternext; 20 | return iter; 21 | case PYLT_OBJ_TYPE_STR: 22 | iter->array.count = caststr(obj)->ob_size; 23 | iter->array.index = 0; 24 | iter->iter_func = &pylt_obj_str_iternext; 25 | return iter; 26 | case PYLT_OBJ_TYPE_TUPLE: 27 | iter->array.count = casttuple(obj)->ob_size; 28 | iter->array.index = 0; 29 | iter->iter_func = &pylt_obj_tuple_iternext; 30 | return iter; 31 | case PYLT_OBJ_TYPE_LIST: 32 | iter->array.count = castlist(obj)->ob_size; 33 | iter->iter_func = &pylt_obj_list_iternext; 34 | iter->array.index = 0; 35 | return iter; 36 | case PYLT_OBJ_TYPE_SET: 37 | iter->hashmap.count = pylt_obj_set_len(I, castset(obj)); 38 | iter->hashmap.k = pylt_obj_set_begin(I, castset(obj)); 39 | iter->iter_func = &pylt_obj_set_iternext; 40 | return iter; 41 | case PYLT_OBJ_TYPE_DICT: 42 | iter->hashmap.count = pylt_obj_dict_len(I, castdict(obj)); 43 | iter->hashmap.k = pylt_obj_dict_begin(I, castdict(obj)); 44 | iter->iter_func = &pylt_obj_dict_iternext; 45 | return iter; 46 | case PYLT_OBJ_TYPE_RANGE: 47 | iter->array.count = pylt_obj_range_itertimes(I, castrange(obj)); 48 | iter->array.index = castrange(obj)->start; 49 | iter->iter_func = &pylt_obj_range_iternext; 50 | return iter; 51 | default: 52 | if (obj->ob_type > PYLT_OBJ_BUILTIN_TYPE_NUM) { 53 | PyLiteIterObject *niter; 54 | PyLiteObject *obj_func = pylt_obj_Egetattr(I, obj, castobj(pl_static.str.__iter__), NULL); 55 | if (obj_func) { 56 | niter = castiter(pl_call_method(I, obj, obj_func, 0, NULL)); 57 | if (pl_isiter(niter)) { 58 | pylt_free_ex(I, iter); 59 | return iter; 60 | } 61 | } else { 62 | iter->backup = pylt_obj_iter_new(I, castcustom(obj)->base_obj); 63 | iter->backup->ob_flags |= PYLT_OBJ_FLAG_CANFREE; 64 | if (iter->backup) { 65 | iter->iter_func = &pylt_obj_custom_iternext; 66 | return iter; 67 | } 68 | } 69 | } 70 | } 71 | 72 | pylt_free_ex(I, iter); 73 | return NULL; 74 | } 75 | 76 | PyLiteObject* pylt_obj_iter_next(PyLiteInterpreter *I, PyLiteIterObject *iter) { 77 | return (*iter->iter_func)(I, iter); 78 | } 79 | 80 | PyLiteObject* pylt_obj_bytes_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter) { 81 | char buf[1]; 82 | int len = castbytes(iter->base)->ob_size; 83 | if (iter->array.index == len) return NULL; 84 | else { 85 | buf[0] = castbytes(iter->base)->ob_val[iter->array.index++]; 86 | return castobj(pylt_obj_bytes_new(I, buf, 1, true)); 87 | } 88 | return NULL; 89 | } 90 | 91 | PyLiteObject* pylt_obj_str_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter) { 92 | uint32_t buf[1]; 93 | int len = caststr(iter->base)->ob_size; 94 | if (iter->array.index == len) return NULL; 95 | else { 96 | buf[0] = caststr(iter->base)->ob_val[iter->array.index++]; 97 | return castobj(pylt_obj_str_new(I, buf, 1, true)); 98 | } 99 | return NULL; 100 | } 101 | 102 | PyLiteObject* pylt_obj_tuple_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter) { 103 | int len = casttuple(iter->base)->ob_size; 104 | if (iter->array.index < len) { 105 | return casttuple(iter->base)->ob_val[iter->array.index++]; 106 | } 107 | return NULL; 108 | } 109 | 110 | PyLiteObject* pylt_obj_list_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter) { 111 | int len = castlist(iter->base)->ob_size; 112 | if (iter->array.index < len) { 113 | return castlist(iter->base)->ob_val[iter->array.index++]; 114 | } 115 | return NULL; 116 | } 117 | 118 | PyLiteObject* pylt_obj_set_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter) { 119 | PyLiteObject *ret; 120 | 121 | if (pylt_obj_set_len(I, castset(iter->base)) != iter->hashmap.count) 122 | return NULL; 123 | 124 | ret = pylt_obj_set_itemvalue(I, castset(iter->base), iter->hashmap.k); 125 | pylt_obj_set_next(I, castset(iter->base), &(iter->hashmap.k)); 126 | return ret; 127 | } 128 | 129 | PyLiteObject* pylt_obj_dict_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter) { 130 | PyLiteObject *ret; 131 | 132 | if (pylt_obj_dict_len(I, castdict(iter->base)) != iter->hashmap.count) 133 | return NULL; 134 | 135 | ret = pylt_obj_dict_itemkey(I, castdict(iter->base), iter->hashmap.k); 136 | pylt_obj_dict_next(I, castdict(iter->base), &(iter->hashmap.k)); 137 | return ret; 138 | } 139 | 140 | PyLiteObject* pylt_obj_dict_items_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter) { 141 | PyLiteObject *k, *v; 142 | PyLiteTupleObject *ret; 143 | 144 | if (pylt_obj_dict_len(I, castdict(iter->base)) != iter->hashmap.count) 145 | return NULL; 146 | 147 | pylt_obj_dict_keyvalue(I, castdict(iter->base), iter->hashmap.k, &k, &v); 148 | if (!k) return NULL; 149 | 150 | pylt_obj_dict_next(I, castdict(iter->base), &(iter->hashmap.k)); 151 | ret = pylt_obj_tuple_new(I, 2); 152 | ret->ob_val[0] = k; 153 | ret->ob_val[1] = v; 154 | return castobj(ret); 155 | } 156 | 157 | PyLiteObject* pylt_obj_range_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter) { 158 | PyLiteRangeObject *range = castrange(iter->base); 159 | pl_int_t index = iter->array.index; 160 | if ((index >= range->start) && (index < range->stop)) { 161 | iter->array.index += range->step; 162 | return castobj(pylt_obj_int_new(I, index)); 163 | } 164 | return NULL; 165 | } 166 | 167 | PyLiteObject* pylt_obj_custom_iternext(PyLiteInterpreter *I, PyLiteIterObject *iter) { 168 | return pylt_obj_iter_next(I, iter->backup); 169 | } 170 | 171 | void pylt_obj_iter_rfree(PyLiteInterpreter *I, PyLiteIterObject* self) { 172 | //if (self->backup) pylt_obj_iter_free(I, self->backup); 173 | pylt_free_ex(I, self); 174 | } 175 | 176 | void pylt_obj_iter_free(PyLiteInterpreter *I, PyLiteIterObject* self) { 177 | pylt_gc_remove(I, castobj(self)); 178 | pylt_obj_iter_rfree(I, self); 179 | } 180 | -------------------------------------------------------------------------------- /src/types/common/dict.c: -------------------------------------------------------------------------------- 1 | 2 | #include "dict.h" 3 | #include "string.h" 4 | #include "../../utils/misc.h" 5 | #include "../../api.h" 6 | 7 | pl_int_t pylt_obj_dict_cmp(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject *other) { 8 | return 2; 9 | } 10 | 11 | pl_bool_t pylt_obj_dict_eq(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject *other) { 12 | PyLiteDictObject *a, *b; 13 | 14 | if (other->ob_type == PYLT_OBJ_TYPE_DICT) { 15 | a = self; 16 | b = castdict(other); 17 | 18 | if (pylt_obj_dict_len(I, a) != pylt_obj_dict_len(I, b)) 19 | return false; 20 | 21 | pl_foreach_dict(I, it, a) { 22 | PyLiteObject *_a, *_b; 23 | _a = pylt_obj_dict_getitem(I, b, pylt_obj_dict_itemkey(I, a, it)); 24 | _b = pylt_obj_dict_itemvalue(I, a, it); 25 | if (!pylt_obj_eq(I, _a, _b)) return false; 26 | } 27 | return true; 28 | } 29 | return false; 30 | } 31 | 32 | pl_int_t pylt_obj_dict_len(PyLiteInterpreter *I, PyLiteDictObject *self) { 33 | return kho_size(self->ob_val); 34 | } 35 | 36 | PyLiteObject* pylt_obj_dict_getitem(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject *key) { 37 | khiter_t k = kho_get(table, self->ob_val, key); 38 | return k == kho_end(self->ob_val) ? NULL : kho_value(self->ob_val, k); 39 | } 40 | 41 | void pylt_obj_dict_setitem(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject* key, PyLiteObject* value) { 42 | int ret; 43 | khiter_t k = kho_put(table, self->ob_val, key, &ret); 44 | kho_value(self->ob_val, k) = value; 45 | } 46 | 47 | pl_bool_t pylt_obj_dict_has(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject *key) { 48 | return pylt_obj_dict_getitem(I, self, key) != NULL; 49 | } 50 | 51 | pl_bool_t pylt_obj_dict_remove(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject *key) { 52 | khiter_t k = kho_get(table, self->ob_val, key); 53 | if (k == kho_end(self->ob_val)) return false; 54 | else kho_del(table, self->ob_val, k); 55 | return true; 56 | } 57 | 58 | PyLiteObject* pylt_obj_dict_pop(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteObject *key) { 59 | PyLiteObject *obj = pylt_obj_dict_getitem(I, self, key); 60 | if (obj) { 61 | pylt_obj_dict_remove(I, self, key); 62 | return obj; 63 | } 64 | return NULL; 65 | } 66 | 67 | void pylt_obj_dict_update(PyLiteInterpreter *I, PyLiteDictObject *self, PyLiteDictObject *other) { 68 | PyLiteObject *key, *value; 69 | pl_foreach_dict(I, it, other) { 70 | pylt_obj_dict_keyvalue(I, other, it, &key, &value); 71 | pylt_obj_dict_setitem(I, self, key, value); 72 | } 73 | } 74 | 75 | pl_int32_t pylt_obj_dict_begin(PyLiteInterpreter *I, PyLiteDictObject *self) { 76 | pl_int32_t k = kho_begin(self->ob_val); 77 | while (k != kho_end(self->ob_val)) { 78 | if (kho_exist(self->ob_val, k)) return k; 79 | ++k; 80 | } 81 | return kho_end(self->ob_val); 82 | } 83 | 84 | pl_int32_t pylt_obj_dict_end(PyLiteInterpreter *I, PyLiteDictObject *self) { 85 | return kho_end(self->ob_val); 86 | } 87 | 88 | void pylt_obj_dict_next(PyLiteInterpreter *I, PyLiteDictObject *self, pl_int32_t *k) { 89 | pl_int32_t key = *k; 90 | while (++key != kho_end(self->ob_val)) { 91 | if (kho_exist(self->ob_val, key)) { 92 | *k = key; 93 | return; 94 | } 95 | } 96 | *k = kho_end(self->ob_val); 97 | } 98 | 99 | PyLiteObject* pylt_obj_dict_itemkey(PyLiteInterpreter *I, PyLiteDictObject *self, pl_int32_t k) { 100 | return (kho_exist(self->ob_val, k)) ? castobj(kho_key(self->ob_val, k)) : NULL; 101 | } 102 | 103 | PyLiteObject* pylt_obj_dict_itemvalue(PyLiteInterpreter *I, PyLiteDictObject *self, pl_int32_t k) { 104 | return (kho_exist(self->ob_val, k)) ? castobj(kho_val(self->ob_val, k)) : NULL; 105 | } 106 | 107 | void pylt_obj_dict_keyvalue(PyLiteInterpreter *I, PyLiteDictObject *self, pl_int32_t k, PyLiteObject **pkey, PyLiteObject **pval) { 108 | if (kho_exist(self->ob_val, k)) { 109 | *pkey = castobj(kho_key(self->ob_val, k)); 110 | *pval = castobj(kho_val(self->ob_val, k)); 111 | } else { 112 | *pkey = NULL; 113 | *pval = NULL; 114 | } 115 | } 116 | 117 | PyLiteDictObject* pylt_obj_dict_copy(PyLiteInterpreter *I, PyLiteDictObject *self) { 118 | PyLiteDictObject *obj = pylt_obj_dict_new(I); 119 | kho_resize(table, obj->ob_val, pylt_obj_dict_len(I, self)); 120 | 121 | for (pl_int32_t k = pylt_obj_dict_begin(I, self); k != pylt_obj_dict_end(I, self); pylt_obj_dict_next(I, self, &k)) { 122 | pylt_obj_dict_setitem(I, obj, pylt_obj_dict_itemkey(I, self, k), pylt_obj_dict_itemvalue(I, self, k)); 123 | } 124 | 125 | return obj; 126 | } 127 | 128 | struct PyLiteStrObject* pylt_obj_dict_to_str(PyLiteInterpreter *I, PyLiteDictObject *self) { 129 | int index = 0; 130 | PyLiteStrObject *str; 131 | PyLiteStrObject **strlst = NULL; 132 | pl_uint_t dlen = pylt_obj_dict_len(I, self); 133 | 134 | if (dlen == 0) { 135 | return pl_static.str.TMPL_EMPTY_DICT; // [] 136 | } 137 | 138 | pl_uint32_t *data; 139 | pl_uint32_t comma_num = dlen - 1; 140 | pl_uint32_t data_len = 2 + comma_num * 2 + dlen * 2; // {} + ', ' + ': ' 141 | strlst = pylt_malloc(I, dlen * 2 * sizeof(PyLiteStrObject*)); 142 | 143 | for (pl_int32_t k = pylt_obj_dict_begin(I, self); k != pylt_obj_dict_end(I, self); pylt_obj_dict_next(I, self, &k)) { 144 | str = pylt_obj_to_repr(I, pylt_obj_dict_itemkey(I, self, k)); 145 | data_len += str->ob_size; 146 | strlst[index++] = str; 147 | 148 | str = pylt_obj_to_repr(I, pylt_obj_dict_itemvalue(I, self, k)); 149 | data_len += str->ob_size; 150 | strlst[index++] = str; 151 | } 152 | 153 | data = pylt_malloc(I, data_len * sizeof(uint32_t)); 154 | data[0] = '{'; 155 | index = 1; 156 | for (pl_uint_t i = 0; i < dlen*2; ++i) { 157 | // key 158 | memcpy(data + index, strlst[i]->ob_val, strlst[i]->ob_size * sizeof(uint32_t)); 159 | index += strlst[i]->ob_size; 160 | 161 | // : 162 | data[index++] = ':'; 163 | data[index++] = ' '; 164 | ++i; 165 | 166 | // value 167 | memcpy(data + index, strlst[i]->ob_val, strlst[i]->ob_size * sizeof(uint32_t)); 168 | index += strlst[i]->ob_size; 169 | 170 | if (i != dlen*2 - 1) { 171 | data[index++] = ','; 172 | data[index++] = ' '; 173 | } 174 | } 175 | data[data_len - 1] = '}'; 176 | 177 | str = pylt_obj_str_new(I, data, data_len, true); 178 | pylt_free(I, data, data_len * sizeof(uint32_t)); 179 | pylt_free_ex(I, strlst); 180 | return str; 181 | } 182 | 183 | PyLiteDictObject* pylt_obj_dict_new(PyLiteInterpreter *I) { 184 | PyLiteObject_init(I, obj, PyLiteDictObject, PYLT_OBJ_TYPE_DICT); 185 | obj->ob_val = kho_init(table, state); 186 | return obj; 187 | } 188 | 189 | void pylt_obj_dict_rfree(PyLiteInterpreter *I, PyLiteDictObject *self) { 190 | kho_destroy(table, self->ob_val); 191 | pylt_free_ex(I, self); 192 | } 193 | 194 | void pylt_obj_dict_free(PyLiteInterpreter *I, PyLiteDictObject *self) { 195 | pylt_gc_remove(I, castobj(self)); 196 | pylt_obj_dict_rfree(I, self); 197 | } 198 | -------------------------------------------------------------------------------- /src/types/object.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PYLITE_TYPES_OBJECT_H 3 | #define PYLITE_TYPES_OBJECT_H 4 | 5 | #include "../utils/config.h" 6 | #include "../deps/khash_obj.h" 7 | 8 | // Object 9 | 10 | typedef struct PyLiteObject { 11 | uint32_t ob_type; 12 | uint32_t ob_flags; 13 | } PyLiteObject; 14 | 15 | #define PyLiteObject_HEAD \ 16 | uint32_t ob_type; \ 17 | uint32_t ob_flags 18 | 19 | #define PYLT_OBJ_FLAG_CANFREE 1 20 | #define PYLT_OBJ_FLAG_STATIC 2 21 | #define PYLT_OBJ_FLAG_WATCH 4 22 | 23 | /** All objects managed by GC. But by default, 24 | GC can't release object, otherwise with PYLT_OBJ_FLAG_CANFREE flag. 25 | */ 26 | #define PyLiteObject_init(I, obj, typestruct, typecode) \ 27 | struct typestruct *obj = (struct typestruct*)pylt_malloc(I, sizeof(struct typestruct)); \ 28 | obj->ob_type = typecode; \ 29 | obj->ob_flags = 0; \ 30 | pylt_gc_add(I, (PyLiteObject*)(obj)) 31 | 32 | 33 | enum PyLiteObjectTypeCode { 34 | PYLT_OBJ_TYPE_OBJ = 1, 35 | PYLT_OBJ_TYPE_INT, 36 | PYLT_OBJ_TYPE_FLOAT, 37 | PYLT_OBJ_TYPE_BOOL, 38 | 39 | PYLT_OBJ_TYPE_STR, // 5 40 | PYLT_OBJ_TYPE_BYTES, 41 | PYLT_OBJ_TYPE_SET, 42 | PYLT_OBJ_TYPE_LIST, 43 | PYLT_OBJ_TYPE_TUPLE, 44 | PYLT_OBJ_TYPE_DICT, 45 | 46 | PYLT_OBJ_TYPE_TYPE, // 11 47 | PYLT_OBJ_TYPE_UNUSUAL, 48 | 49 | PYLT_OBJ_TYPE_MODULE, // 13 50 | PYLT_OBJ_TYPE_FUNCTION, 51 | PYLT_OBJ_TYPE_CFUNCTION, 52 | PYLT_OBJ_TYPE_CODE, 53 | 54 | PYLT_OBJ_TYPE_ITER, // 17 55 | PYLT_OBJ_TYPE_PROP, 56 | PYLT_OBJ_TYPE_NONE, 57 | PYLT_OBJ_TYPE_CPTR, 58 | 59 | PYLT_OBJ_TYPE_RANGE, // 21 60 | 61 | PYLT_OBJ_TYPE_BASE_EXCEPTION, // 22 62 | 63 | PYLT_OBJ_TYPE_USERCLASS, // 23 64 | }; 65 | 66 | #define PYLT_OBJ_BUILTIN_TYPE_NUM PYLT_OBJ_TYPE_BASE_EXCEPTION 67 | 68 | 69 | // Object methods 70 | 71 | pl_int_t pylt_obj_cmp(PyLiteInterpreter *I, PyLiteObject *a, PyLiteObject *b); 72 | pl_bool_t pylt_obj_eq(PyLiteInterpreter *I, PyLiteObject *a, PyLiteObject *b); 73 | pl_uint32_t pylt_obj_hash(PyLiteInterpreter *I, PyLiteObject *obj); 74 | pl_int_t pylt_obj_len(PyLiteInterpreter *I, PyLiteObject *obj); 75 | 76 | pl_bool_t pylt_obj_hashable(PyLiteInterpreter *I, PyLiteObject *obj); 77 | pl_bool_t pylt_obj_iterable(PyLiteInterpreter *I, PyLiteObject *obj); 78 | pl_bool_t pylt_obj_istrue(PyLiteInterpreter *I, PyLiteObject *obj); 79 | 80 | PyLiteObject* pylt_obj_getattr_ex(PyLiteInterpreter *I, PyLiteObject *obj, PyLiteObject* key, PyLiteObject* _default, pl_bool_t *p_at_type); 81 | PyLiteObject* pylt_obj_getattr(PyLiteInterpreter *I, PyLiteObject *obj, PyLiteObject* key, pl_bool_t *p_at_type); 82 | pl_bool_t pylt_obj_setattr(PyLiteInterpreter *I, PyLiteObject *self, PyLiteObject* key, PyLiteObject* value); 83 | pl_bool_t pylt_obj_delattr(PyLiteInterpreter *I, PyLiteObject *self, PyLiteObject* key); 84 | 85 | //PyLiteObject* pylt_obj_getitem(PyLiteInterpreter *I, PyLiteObject *obj, PyLiteObject* key); 86 | //pl_bool_t pylt_obj_setitem(PyLiteInterpreter *I, PyLiteObject *self, PyLiteObject* key, PyLiteObject* value); 87 | 88 | pl_bool_t pylt_obj_has(PyLiteInterpreter *I, PyLiteObject *self, PyLiteObject *obj, pl_bool_t *is_valid); 89 | 90 | PyLiteObject* pylt_obj_op_unary(PyLiteInterpreter *I, int op, PyLiteObject *obj); 91 | PyLiteObject* pylt_obj_op_binary(PyLiteInterpreter *I, int op, PyLiteObject *a, PyLiteObject *b); 92 | 93 | // Type cast 94 | 95 | struct PyLiteIntObject; 96 | struct PyLiteFloatObject; 97 | struct PyLiteBoolObject; 98 | 99 | struct PyLiteStrObject; 100 | struct PyLiteBytesObject; 101 | struct PyLiteSetObject; 102 | struct PyLiteListObject; 103 | struct PyLiteTupleObject; 104 | struct PyLiteDictObject; 105 | struct PyLiteTypeObject; 106 | struct PyLiteUnusualObject; 107 | 108 | struct PyLiteCodeObject; 109 | struct PyLiteModuleObject; 110 | struct PyLiteFunctionObject; 111 | struct PyLiteCFunctionObject; 112 | 113 | struct PyLiteIterObject; 114 | struct PyLitePropertyObject; 115 | struct PyLiteNoneObject; 116 | struct PyLiteCPtrObject; 117 | 118 | struct PyLiteRangeObject; 119 | struct PyLiteBaseExceptionObject; 120 | 121 | struct PyLiteCustomObject; 122 | 123 | 124 | #define cast(t, exp) ((t)(exp)) 125 | #define castobj(i) cast(struct PyLiteObject*, (i)) 126 | #define castint(i) cast(struct PyLiteIntObject*, (i)) 127 | #define castfloat(i) cast(struct PyLiteFloatObject*, (i)) 128 | #define castbool(i) cast(struct PyLiteBoolObject*, (i)) 129 | 130 | #define caststr(i) cast(struct PyLiteStrObject*, (i)) 131 | #define castbytes(i) cast(struct PyLiteBytesObject*, (i)) 132 | #define castset(i) cast(struct PyLiteSetObject*, (i)) 133 | #define castlist(i) cast(struct PyLiteListObject*, (i)) 134 | #define casttuple(i) cast(struct PyLiteTupleObject*, (i)) 135 | #define castdict(i) cast(struct PyLiteDictObject*, (i)) 136 | #define casttype(i) cast(struct PyLiteTypeObject*, (i)) 137 | #define castunusual(i) cast(struct PyLiteUnusualObject*, (i)) 138 | 139 | #define castmod(i) cast(struct PyLiteModuleObject*, (i)) 140 | #define castfunc(i) cast(struct PyLiteFunctionObject*, (i)) 141 | #define castcfunc(i) cast(struct PyLiteCFunctionObject*, (i)) 142 | #define castcode(i) cast(struct PyLiteCodeObject*, (i)) 143 | 144 | #define castiter(i) cast(struct PyLiteIterObject*, (i)) 145 | #define castprop(i) cast(struct PyLitePropertyObject*, (i)) 146 | #define castnone(i) cast(struct PyLiteNoneObject*, (i)) 147 | #define castcptr(i) cast(struct PyLiteCPtrObject*, (i)) 148 | 149 | #define castrange(i) cast(struct PyLiteRangeObject*, (i)) 150 | #define castexcept(i) cast(struct PyLiteBaseExceptionObject*, (i)) 151 | 152 | #define castcustom(i) cast(struct PyLiteCustomObject*, (i)) 153 | 154 | #define dcast(type, i) cast##type(pylt_obj_getbase(i)) 155 | 156 | #define pl_isint(i) (i->ob_type == PYLT_OBJ_TYPE_INT) 157 | #define pl_isflt(i) (i->ob_type == PYLT_OBJ_TYPE_FLOAT) 158 | #define pl_isstr(i) (i->ob_type == PYLT_OBJ_TYPE_STR) 159 | #define pl_isbytes(i) (i->ob_type == PYLT_OBJ_TYPE_BYTES) 160 | #define pl_iset(i) (i->ob_type == PYLT_OBJ_TYPE_SET) 161 | #define pl_islist(i) (i->ob_type == PYLT_OBJ_TYPE_LIST) 162 | #define pl_istuple(i) (i->ob_type == PYLT_OBJ_TYPE_TUPLE) 163 | #define pl_isdict(i) (i->ob_type == PYLT_OBJ_TYPE_DICT) 164 | #define pl_istype(i) (i->ob_type == PYLT_OBJ_TYPE_TYPE) 165 | #define pl_isunusual(i) (i->ob_type == PYLT_OBJ_TYPE_UNUSUAL) 166 | #define pl_isiter(i) (i->ob_type == PYLT_OBJ_TYPE_ITER) 167 | #define pl_isnone(i) (i->ob_type == PYLT_OBJ_TYPE_NONE) 168 | #define pl_isnum(i) ((i->ob_type == PYLT_OBJ_TYPE_INT) || (i->ob_type == PYLT_OBJ_TYPE_FLOAT)) 169 | #define pl_isstrkind(i) ((i->ob_type == PYLT_OBJ_TYPE_STR) || (i->ob_type == PYLT_OBJ_TYPE_BYTES)) 170 | #define pl_ismod(i) (i->ob_type == PYLT_OBJ_TYPE_MODULE) 171 | #define pl_iscode(i) (i->ob_type == PYLT_OBJ_TYPE_CODE) 172 | #define pl_iscustom(i) (i->ob_type >= PYLT_OBJ_TYPE_USERCLASS) 173 | 174 | #define pl_iscustomtype(i) (pl_istype(i)) && (((struct PyLiteTypeObject*)i)->ob_reftype >= PYLT_OBJ_TYPE_USERCLASS) 175 | 176 | /** get base object of custom class object. get itself of builtin type's object */ 177 | PyLiteObject* pylt_obj_getbase(PyLiteObject *obj); 178 | struct PyLiteStrObject* pylt_obj_to_str(PyLiteInterpreter *I, PyLiteObject *obj); 179 | struct PyLiteStrObject* pylt_obj_to_repr(PyLiteInterpreter *I, PyLiteObject *obj); 180 | 181 | void pylt_obj_free(PyLiteInterpreter *I, PyLiteObject *obj); 182 | void pylt_obj_rfree(PyLiteInterpreter *I, PyLiteObject *obj); 183 | 184 | // Others 185 | 186 | typedef PyLiteObject* (*PyLiteObjUnaryOpFunc)(PyLiteInterpreter *I, PyLiteObject *obj); 187 | typedef PyLiteObject* (*PyLiteObjBinaryOpFunc)(PyLiteInterpreter *I, PyLiteObject *a, PyLiteObject *b); 188 | 189 | typedef PyLiteObject* (*PyLiteCFunctionPtr)(PyLiteInterpreter *I, int argc, PyLiteObject **args); 190 | typedef PyLiteObject* (*PyLiteIterFunc)(PyLiteInterpreter *I, struct PyLiteIterObject *iter); 191 | 192 | typedef pl_bool_t (*PyLiteModuleRegisterFunc)(PyLiteInterpreter *I); 193 | typedef struct PyLiteModuleObject* (*PyLiteModuleLoaderFunc)(PyLiteInterpreter *I); 194 | 195 | #endif 196 | -------------------------------------------------------------------------------- /src/utils/static.c: -------------------------------------------------------------------------------- 1 | 2 | #include "static.h" 3 | #include "../types/all.h" 4 | #include "../gc.h" 5 | 6 | static PyLiteStrObject* str_new_from_cstr_static(PyLiteInterpreter *I, const char *str, bool is_raw) { 7 | PyLiteStrObject *ret = pylt_obj_str_new_from_cstr(I, str, is_raw); 8 | pylt_gc_static_add(I, castobj(ret)); 9 | return ret; 10 | } 11 | 12 | 13 | #define sstr_new(_name) pl_static.str._name = str_new_from_cstr_static(I, #_name, true) 14 | #define sstr_new2(_name, _str) pl_static.str._name = str_new_from_cstr_static(I, (_str), true); 15 | 16 | // replace 17 | // [ \t]+PyLiteStrObject \*([A-Za-z0-9_]+); 18 | // sstr_new\($1\); 19 | 20 | // pl_static.str.([^ ]+) = pylt_obj_str_new_from_cstr_static\(I, "([^"]*)", true\); 21 | // sstr_new2\($1, "$2"\); 22 | 23 | void pylt_static_objs_init(PyLiteInterpreter *I) { 24 | sstr_new(__base__); 25 | sstr_new(__call__); 26 | sstr_new(__del__); 27 | sstr_new(__new__); 28 | sstr_new(__import__); 29 | sstr_new(__init__); 30 | sstr_new(__str__); 31 | sstr_new(__repr__); 32 | 33 | sstr_new(__add__); 34 | sstr_new(__div__); 35 | sstr_new(__floordiv__); 36 | sstr_new(__mul__); 37 | sstr_new(__neg__); 38 | sstr_new(__pos__); 39 | sstr_new(__pow__); 40 | sstr_new(__sub__); 41 | 42 | sstr_new(__lshift__); 43 | sstr_new(__rshift__); 44 | 45 | sstr_new(__hash__); 46 | sstr_new(__iter__); 47 | sstr_new(__cmp__); 48 | sstr_new(__eq__); 49 | sstr_new(__setattr__); 50 | sstr_new(__getattr__); 51 | sstr_new(__delattr__); 52 | sstr_new(__setitem__); 53 | sstr_new(__getitem__); 54 | sstr_new(__delitem__); 55 | 56 | sstr_new(__defaults__); 57 | sstr_new(__parameters__); 58 | sstr_new(__args_types__); 59 | 60 | sstr_new(abs); 61 | sstr_new(all); 62 | sstr_new(any); 63 | sstr_new(ascii); 64 | sstr_new(bin); 65 | sstr_new(bytearray); 66 | sstr_new(callable); 67 | sstr_new(chr); 68 | sstr_new(classmethod); 69 | sstr_new(compile); 70 | sstr_new(delattr); 71 | sstr_new(dir); 72 | sstr_new(divmod); 73 | sstr_new(enumerate); 74 | sstr_new(eval); 75 | sstr_new(exec); 76 | sstr_new(filter); 77 | sstr_new(format); 78 | sstr_new(frozenset); 79 | sstr_new(getattr); 80 | sstr_new(globals); 81 | sstr_new(hasattr); 82 | sstr_new(hash); 83 | sstr_new(help); 84 | sstr_new(hex); 85 | sstr_new(id); 86 | sstr_new(input); 87 | sstr_new(isinstance); 88 | sstr_new(issubclass); 89 | sstr_new(iter); 90 | sstr_new(len); 91 | sstr_new(locals); 92 | sstr_new(map); 93 | sstr_new(max); 94 | sstr_new(memoryview); 95 | sstr_new(min); 96 | sstr_new(next); 97 | sstr_new(oct); 98 | sstr_new(open); 99 | sstr_new(ord); 100 | sstr_new(pow); 101 | sstr_new(print); 102 | sstr_new(repr); 103 | sstr_new(reversed); 104 | sstr_new(round); 105 | sstr_new(setattr); 106 | sstr_new(slice); 107 | sstr_new(sorted); 108 | sstr_new(staticmethod); 109 | sstr_new(sum); 110 | sstr_new(super); 111 | sstr_new(vars); 112 | sstr_new(zip); 113 | 114 | // classes 115 | sstr_new(object); 116 | sstr_new2(int_, "int"); 117 | sstr_new2(float_, "float"); 118 | sstr_new2(bool_, "bool"); 119 | sstr_new(str); 120 | sstr_new(bytes); 121 | sstr_new(set); 122 | sstr_new(list); 123 | sstr_new(tuple); 124 | sstr_new(dict); 125 | sstr_new(type); 126 | sstr_new(unusual); 127 | 128 | sstr_new(module); 129 | sstr_new(function); 130 | sstr_new(cfunction); 131 | sstr_new(code); 132 | sstr_new(iterator); 133 | sstr_new2(property_, "property"); 134 | sstr_new(NoneType); 135 | sstr_new(cpointer); 136 | sstr_new(range); 137 | 138 | // object 139 | sstr_new(mro); 140 | 141 | // str 142 | sstr_new(join); 143 | sstr_new(sub); 144 | sstr_new(start); 145 | sstr_new(end); 146 | sstr_new(startswith); 147 | sstr_new(endswith); 148 | 149 | // int 150 | sstr_new(is_integer); 151 | 152 | // set 153 | sstr_new(add); 154 | sstr_new(clear); 155 | sstr_new(copy); 156 | sstr_new(pop); 157 | sstr_new(remove); 158 | 159 | // list 160 | sstr_new(append); 161 | sstr_new(count); 162 | sstr_new(index); 163 | sstr_new(extend); 164 | sstr_new(insert); 165 | sstr_new(reverse); 166 | 167 | // dict 168 | sstr_new(items); 169 | 170 | // unusual 171 | sstr_new(useless); 172 | sstr_new(NotImplemented); 173 | sstr_new(param_args); 174 | sstr_new(param_kwargs); 175 | sstr_new(param_undefined); 176 | 177 | // prop 178 | sstr_new(fget); 179 | sstr_new(fset); 180 | 181 | sstr_new(None); 182 | sstr_new(True); 183 | sstr_new(False); 184 | 185 | // misc 186 | sstr_new(cls); 187 | sstr_new(self); 188 | sstr_new(args); 189 | sstr_new(kwargs); 190 | sstr_new(param1); 191 | sstr_new(param2); 192 | sstr_new(param3); 193 | sstr_new(param4); 194 | sstr_new2(default_, "default"); 195 | sstr_new(__cobj__); 196 | 197 | sstr_new(x); 198 | sstr_new(y); 199 | 200 | // modules 201 | sstr_new(math); 202 | sstr_new(builtins); 203 | sstr_new(cio); 204 | 205 | sstr_new(io); 206 | sstr_new(BaseIO); 207 | sstr_new(BytesIO); 208 | sstr_new(TextIO); 209 | sstr_new(UnsupportedOperation); 210 | sstr_new(encoding); 211 | 212 | sstr_new(sys); 213 | sstr_new2(stdin_, "stdin"); 214 | sstr_new2(stdout_, "stdout"); 215 | sstr_new2(stderr_, "stderr"); 216 | 217 | sstr_new(os); 218 | 219 | sstr_new(pltypes); 220 | 221 | // exceptions 222 | sstr_new(BaseException); 223 | sstr_new(SystemExit); 224 | sstr_new(KeyboardInterrupt); 225 | sstr_new(GeneratorExit); 226 | sstr_new(Exception); 227 | sstr_new(StopIteration); 228 | sstr_new(StopAsyncIteration); 229 | sstr_new(ArithmeticError); 230 | sstr_new(FloatingPointError); 231 | sstr_new(OverflowError); 232 | sstr_new(ZeroDivisionError); 233 | sstr_new(AssertionError); 234 | sstr_new(AttributeError); 235 | sstr_new(BufferError); 236 | sstr_new(EOFError); 237 | sstr_new(ImportError); 238 | sstr_new(LookupError); 239 | sstr_new(IndexError); 240 | sstr_new(KeyError); 241 | sstr_new(MemoryError); 242 | sstr_new(NameError); 243 | sstr_new(OSError); 244 | sstr_new(BlockingIOError); 245 | sstr_new(ChildProcessError); 246 | sstr_new(ConnectionError); 247 | sstr_new(BrokenPipeError); 248 | sstr_new(ConnectionAbortedError); 249 | sstr_new(ConnectionRefusedError); 250 | sstr_new(ConnectionResetError); 251 | sstr_new(FileExistsError); 252 | sstr_new(FileNotFoundError); 253 | sstr_new(InterruptedError); 254 | sstr_new(IsADirectoryError); 255 | sstr_new(NotADirectoryError); 256 | sstr_new(PermissionError); 257 | sstr_new(ProcessLookupError); 258 | sstr_new(TimeoutError); 259 | sstr_new(ReferenceError); 260 | sstr_new(RuntimeError); 261 | sstr_new(NotImplementedError); 262 | sstr_new(RecursionError); 263 | sstr_new(SyntaxError); 264 | sstr_new(IndentationError); 265 | sstr_new(TabError); 266 | sstr_new(SystemError); 267 | sstr_new(TypeError); 268 | sstr_new(ValueError); 269 | sstr_new(UnicodeError); 270 | sstr_new(UnicodeDecodeError); 271 | sstr_new(UnicodeEncodeError); 272 | sstr_new(UnicodeTranslateError); 273 | sstr_new(Warning); 274 | sstr_new(DeprecationWarning); 275 | sstr_new(PendingDeprecationWarning); 276 | sstr_new(RuntimeWarning); 277 | sstr_new(SyntaxWarning); 278 | sstr_new(UserWarning); 279 | sstr_new(FutureWarning); 280 | sstr_new(ImportWarning); 281 | sstr_new(UnicodeWarning); 282 | sstr_new(BytesWarning); 283 | sstr_new(ResourceWarning); 284 | 285 | // template 286 | sstr_new2(TMPL_OBJECT_TO_STR, "<%s object at %p>"); 287 | sstr_new2(TMPL_CLASS_TO_STR, ""); 288 | sstr_new2(TMPL_MODULE_TO_STR, ""); 289 | sstr_new2(TMPL_FUNCTION_TO_STR, ""); 290 | sstr_new2(TMPL_CFUNCTION_TO_STR, ""); 291 | 292 | sstr_new2(TMPL_EMPTY_STR, ""); 293 | sstr_new2(TMPL_EMPTY_SET, "set()"); 294 | sstr_new2(TMPL_EMPTY_LIST, "[]"); 295 | sstr_new2(TMPL_EMPTY_TUPLE, "()"); 296 | sstr_new2(TMPL_EMPTY_DICT, "{}"); 297 | 298 | sstr_new2(TMPL_LAMBDA_FUNC_NAME, ""); 299 | } 300 | -------------------------------------------------------------------------------- /src/deps/fpconv/fpconv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "fpconv.h" 5 | #include "powers.h" 6 | 7 | #ifndef fc_inline 8 | #ifdef _MSC_VER 9 | #define fc_inline __inline 10 | #else 11 | #define fc_inline inline 12 | #endif 13 | #endif /* fc_inline */ 14 | 15 | #define fracmask 0x000FFFFFFFFFFFFFU 16 | #define expmask 0x7FF0000000000000U 17 | #define hiddenbit 0x0010000000000000U 18 | #define signmask 0x8000000000000000U 19 | #define expbias (1023 + 52) 20 | 21 | #define absv(n) ((n) < 0 ? -(n) : (n)) 22 | #define minv(a, b) ((a) < (b) ? (a) : (b)) 23 | 24 | static uint64_t tens[] = { 25 | 10000000000000000000U, 1000000000000000000U, 100000000000000000U, 26 | 10000000000000000U, 1000000000000000U, 100000000000000U, 27 | 10000000000000U, 1000000000000U, 100000000000U, 28 | 10000000000U, 1000000000U, 100000000U, 29 | 10000000U, 1000000U, 100000U, 30 | 10000U, 1000U, 100U, 31 | 10U, 1U 32 | }; 33 | 34 | static fc_inline uint64_t get_dbits(double d) 35 | { 36 | union { 37 | double dbl; 38 | uint64_t i; 39 | } dbl_bits = { d }; 40 | 41 | return dbl_bits.i; 42 | } 43 | 44 | static Fp build_fp(double d) 45 | { 46 | uint64_t bits = get_dbits(d); 47 | 48 | Fp fp; 49 | fp.frac = bits & fracmask; 50 | fp.exp = (bits & expmask) >> 52; 51 | 52 | if(fp.exp) { 53 | fp.frac += hiddenbit; 54 | fp.exp -= expbias; 55 | 56 | } else { 57 | fp.exp = -expbias + 1; 58 | } 59 | 60 | return fp; 61 | } 62 | 63 | static void normalize(Fp* fp) 64 | { 65 | while ((fp->frac & hiddenbit) == 0) { 66 | fp->frac <<= 1; 67 | fp->exp--; 68 | } 69 | 70 | int shift = 64 - 52 - 1; 71 | fp->frac <<= shift; 72 | fp->exp -= shift; 73 | } 74 | 75 | static void get_normalized_boundaries(Fp* fp, Fp* lower, Fp* upper) 76 | { 77 | upper->frac = (fp->frac << 1) + 1; 78 | upper->exp = fp->exp - 1; 79 | 80 | while ((upper->frac & (hiddenbit << 1)) == 0) { 81 | upper->frac <<= 1; 82 | upper->exp--; 83 | } 84 | 85 | int u_shift = 64 - 52 - 2; 86 | 87 | upper->frac <<= u_shift; 88 | upper->exp = upper->exp - u_shift; 89 | 90 | 91 | int l_shift = fp->frac == hiddenbit ? 2 : 1; 92 | 93 | lower->frac = (fp->frac << l_shift) - 1; 94 | lower->exp = fp->exp - l_shift; 95 | 96 | 97 | lower->frac <<= lower->exp - upper->exp; 98 | lower->exp = upper->exp; 99 | } 100 | 101 | static Fp multiply(Fp* a, Fp* b) 102 | { 103 | const uint64_t lomask = 0x00000000FFFFFFFF; 104 | 105 | uint64_t ah_bl = (a->frac >> 32) * (b->frac & lomask); 106 | uint64_t al_bh = (a->frac & lomask) * (b->frac >> 32); 107 | uint64_t al_bl = (a->frac & lomask) * (b->frac & lomask); 108 | uint64_t ah_bh = (a->frac >> 32) * (b->frac >> 32); 109 | 110 | uint64_t tmp = (ah_bl & lomask) + (al_bh & lomask) + (al_bl >> 32); 111 | /* round up */ 112 | tmp += 1U << 31; 113 | 114 | Fp fp = { 115 | ah_bh + (ah_bl >> 32) + (al_bh >> 32) + (tmp >> 32), 116 | a->exp + b->exp + 64 117 | }; 118 | 119 | return fp; 120 | } 121 | 122 | static void round_digit(char* digits, int ndigits, uint64_t delta, uint64_t rem, uint64_t kappa, uint64_t frac) 123 | { 124 | while (rem < frac && delta - rem >= kappa && 125 | (rem + kappa < frac || frac - rem > rem + kappa - frac)) { 126 | 127 | digits[ndigits - 1]--; 128 | rem += kappa; 129 | } 130 | } 131 | 132 | static int generate_digits(Fp* fp, Fp* upper, Fp* lower, char* digits, int* K) 133 | { 134 | uint64_t wfrac = upper->frac - fp->frac; 135 | uint64_t delta = upper->frac - lower->frac; 136 | 137 | Fp one; 138 | one.frac = 1ULL << -upper->exp; 139 | one.exp = upper->exp; 140 | 141 | uint64_t part1 = upper->frac >> -one.exp; 142 | uint64_t part2 = upper->frac & (one.frac - 1); 143 | 144 | int idx = 0, kappa = 10; 145 | uint64_t* divp; 146 | /* 1000000000 */ 147 | for(divp = tens + 10; kappa > 0; divp++) { 148 | 149 | uint64_t div = *divp; 150 | unsigned digit = part1 / div; 151 | 152 | if (digit || idx) { 153 | digits[idx++] = digit + '0'; 154 | } 155 | 156 | part1 -= digit * div; 157 | kappa--; 158 | 159 | uint64_t tmp = (part1 <<-one.exp) + part2; 160 | if (tmp <= delta) { 161 | *K += kappa; 162 | round_digit(digits, idx, delta, tmp, div << -one.exp, wfrac); 163 | 164 | return idx; 165 | } 166 | } 167 | 168 | /* 10 */ 169 | uint64_t* unit = tens + 18; 170 | 171 | while(true) { 172 | part2 *= 10; 173 | delta *= 10; 174 | kappa--; 175 | 176 | unsigned digit = part2 >> -one.exp; 177 | if (digit || idx) { 178 | digits[idx++] = digit + '0'; 179 | } 180 | 181 | part2 &= one.frac - 1; 182 | if (part2 < delta) { 183 | *K += kappa; 184 | round_digit(digits, idx, delta, part2, one.frac, wfrac * *unit); 185 | 186 | return idx; 187 | } 188 | 189 | unit--; 190 | } 191 | } 192 | 193 | static int grisu2(double d, char* digits, int* K) 194 | { 195 | Fp w = build_fp(d); 196 | 197 | Fp lower, upper; 198 | get_normalized_boundaries(&w, &lower, &upper); 199 | 200 | normalize(&w); 201 | 202 | int k; 203 | Fp cp = find_cachedpow10(upper.exp, &k); 204 | 205 | w = multiply(&w, &cp); 206 | upper = multiply(&upper, &cp); 207 | lower = multiply(&lower, &cp); 208 | 209 | lower.frac++; 210 | upper.frac--; 211 | 212 | *K = -k; 213 | 214 | return generate_digits(&w, &upper, &lower, digits, K); 215 | } 216 | 217 | static int emit_digits(char* digits, int ndigits, char* dest, int K, bool neg) 218 | { 219 | int exp = absv(K + ndigits - 1); 220 | 221 | /* write plain integer */ 222 | if(K >= 0 && (exp < (ndigits + 7))) { 223 | memcpy(dest, digits, ndigits); 224 | memset(dest + ndigits, '0', K); 225 | 226 | return ndigits + K; 227 | } 228 | 229 | /* write decimal w/o scientific notation */ 230 | if(K < 0 && (K > -7 || exp < 4)) { 231 | int offset = ndigits - absv(K); 232 | /* fp < 1.0 -> write leading zero */ 233 | if(offset <= 0) { 234 | offset = -offset; 235 | dest[0] = '0'; 236 | dest[1] = '.'; 237 | memset(dest + 2, '0', offset); 238 | memcpy(dest + offset + 2, digits, ndigits); 239 | 240 | return ndigits + 2 + offset; 241 | 242 | /* fp > 1.0 */ 243 | } else { 244 | memcpy(dest, digits, offset); 245 | dest[offset] = '.'; 246 | memcpy(dest + offset + 1, digits + offset, ndigits - offset); 247 | 248 | return ndigits + 1; 249 | } 250 | } 251 | 252 | /* write decimal w/ scientific notation */ 253 | ndigits = minv(ndigits, 18 - neg); 254 | 255 | int idx = 0; 256 | dest[idx++] = digits[0]; 257 | 258 | if(ndigits > 1) { 259 | dest[idx++] = '.'; 260 | memcpy(dest + idx, digits + 1, ndigits - 1); 261 | idx += ndigits - 1; 262 | } 263 | 264 | dest[idx++] = 'e'; 265 | 266 | char sign = K + ndigits - 1 < 0 ? '-' : '+'; 267 | dest[idx++] = sign; 268 | 269 | int cent = 0; 270 | 271 | if(exp > 99) { 272 | cent = exp / 100; 273 | dest[idx++] = cent + '0'; 274 | exp -= cent * 100; 275 | } 276 | if(exp > 9) { 277 | int dec = exp / 10; 278 | dest[idx++] = dec + '0'; 279 | exp -= dec * 10; 280 | 281 | } else if(cent) { 282 | dest[idx++] = '0'; 283 | } 284 | 285 | dest[idx++] = exp % 10 + '0'; 286 | 287 | return idx; 288 | } 289 | 290 | static int filter_special(double fp, char* dest) 291 | { 292 | if(fp == 0.0) { 293 | dest[0] = '0'; 294 | return 1; 295 | } 296 | 297 | uint64_t bits = get_dbits(fp); 298 | 299 | bool nan = (bits & expmask) == expmask; 300 | 301 | if(!nan) { 302 | return 0; 303 | } 304 | 305 | if(bits & fracmask) { 306 | dest[0] = 'n'; dest[1] = 'a'; dest[2] = 'n'; 307 | 308 | } else { 309 | dest[0] = 'i'; dest[1] = 'n'; dest[2] = 'f'; 310 | } 311 | 312 | return 3; 313 | } 314 | 315 | int fpconv_dtoa(double d, char dest[24]) 316 | { 317 | char digits[18]; 318 | 319 | int str_len = 0; 320 | bool neg = false; 321 | 322 | if(get_dbits(d) & signmask) { 323 | dest[0] = '-'; 324 | str_len++; 325 | neg = true; 326 | } 327 | 328 | int spec = filter_special(d, dest + str_len); 329 | 330 | if(spec) { 331 | return str_len + spec; 332 | } 333 | 334 | int K = 0; 335 | int ndigits = grisu2(d, digits, &K); 336 | 337 | str_len += emit_digits(digits, ndigits, dest + str_len, K, neg); 338 | 339 | return str_len; 340 | } 341 | --------------------------------------------------------------------------------