diff --git a/examples/pikapython/CMakeLists.txt b/examples/pikapython/CMakeLists.txt new file mode 100644 index 00000000..552eab3f --- /dev/null +++ b/examples/pikapython/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.15) + +include(proj.conf) + +find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) + +file(GLOB_RECURSE sources "${CMAKE_CURRENT_SOURCE_DIR}/pikapython/*.c") + +target_sources(app PRIVATE ${sources}) + +sdk_add_include_directories(.) +sdk_add_include_directories(pikapython/pikascript-core) +sdk_add_include_directories(pikapython/pikascript-api) + +sdk_set_main_file(main.c) + +project(pikapython) diff --git a/examples/pikapython/Makefile b/examples/pikapython/Makefile new file mode 100644 index 00000000..b6fa1597 --- /dev/null +++ b/examples/pikapython/Makefile @@ -0,0 +1,13 @@ +SDK_DEMO_PATH ?= . +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../.. + +export BL_SDK_BASE + +CHIP ?= bl602 +BOARD ?= bl602dk +CROSS_COMPILE ?= riscv64-unknown-elf- + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(BL_SDK_BASE)/project.build diff --git a/examples/pikapython/main.c b/examples/pikapython/main.c new file mode 100644 index 00000000..8d97563b --- /dev/null +++ b/examples/pikapython/main.c @@ -0,0 +1,11 @@ +#include +#include "board.h" +#include "ff.h" +#include "log.h" +#include "pikaScript.h" +#include "vlibc_stdio.h" + +int main(void) { + board_init(); + pikaScriptInit(); +} diff --git a/examples/pikapython/pikapython/PikaDebug.pyi b/examples/pikapython/pikapython/PikaDebug.pyi new file mode 100644 index 00000000..eceee774 --- /dev/null +++ b/examples/pikapython/pikapython/PikaDebug.pyi @@ -0,0 +1,6 @@ +class Debuger: + def __init__(self): + pass + + def set_trace(self): + pass diff --git a/examples/pikapython/pikapython/PikaObj.pyi b/examples/pikapython/pikapython/PikaObj.pyi new file mode 100644 index 00000000..9a85df17 --- /dev/null +++ b/examples/pikapython/pikapython/PikaObj.pyi @@ -0,0 +1,24 @@ +class TinyObj: + ... + + +class BaseObj(TinyObj): + ... + + +class pointer: + ... + + +class any: + ... + + +class int64: + ... + + +def printNoEnd(val: any): ... +def abstractmethod(fn): ... +def PIKA_C_MACRO_IF(fn): ... +def PIKA_C_MACRO_IFDEF(fn): ... diff --git a/examples/pikapython/pikapython/PikaStdData.pyi b/examples/pikapython/pikapython/PikaStdData.pyi new file mode 100644 index 00000000..6352ec94 --- /dev/null +++ b/examples/pikapython/pikapython/PikaStdData.pyi @@ -0,0 +1,171 @@ +from PikaObj import * + + +class Tuple: + def __init__(self): ... + + def get(self, i: int) -> any: + """get an arg by the index""" + + def len(self) -> int: + """get the length of list""" + + def __iter__(self) -> any: + """support for loop""" + + def __next__(self) -> any: + """support for loop""" + + def __getitem__(self, __key: any) -> any: + """support val = list[]""" + + def __del__(self): ... + def __str__(self) -> str: ... + def __len__(self) -> int: ... + + def __contains__(self, val: any) -> int: + """ support val in list """ + + +class List(Tuple): + def __init__(self): ... + + def append(self, arg: any): + """add an arg after the end of list""" + + def set(self, i: int, arg: any): + """set an arg by the index""" + + def reverse(self): + """reverse the list""" + + def pop(self) -> any: + """pop the last element""" + + def remove(self, val: any): + """remove the first element""" + + def insert(self, i: int, arg: any): + """insert an arg before the index""" + + def __setitem__(self, __key: any, __val: any): + """support list[] = val""" + + def __str__(self) -> str: ... + + def __add__(self, others: List) -> List: + """ support list + list""" + + +class Dict: + def __init__(self): + """ get an arg by the key """ + + def get(self, key: str) -> any: ... + + def set(self, key: str, arg: any): + """ set an arg by the key """ + + def remove(self, key: str): + """ remove an arg by the key """ + + def __iter__(self) -> any: ... + def __next__(self) -> any: ... + + def __setitem__(self, __key: any, __val: any): + """ support dict[] = val """ + + def __getitem__(self, __key: any) -> any: + """ support val = dict[] """ + + def __del__(self): ... + def __str__(self) -> str: ... + def keys(self) -> dict_keys: ... + def items(self) -> dict_items: ... + def __len__(self) -> int: ... + + def __contains__(self, val: any) -> int: + """ support val in dict """ + + def update(self, other: Dict): + """ update dict """ + + +class dict_keys: + def __iter__(self) -> any: ... + def __next__(self) -> any: ... + def __str__(self) -> str: ... + def __len__(self) -> int: ... + + +class dict_items: + def __iter__(self) -> any: ... + def __next__(self) -> any: ... + def __str__(self) -> str: ... + def __len__(self) -> int: ... + + +class String: + def __init__(self, s: str): ... + def set(self, s: str): ... + def get(self) -> str: ... + def __iter__(self) -> any: ... + def __next__(self) -> any: ... + + def __setitem__(self, __key: any, __val: any): + """ support string[] = val """ + + def __getitem__(self, __key: any) -> any: + """ support val = string[] """ + + def __str__(self) -> str: + """ support str() """ + + def __len__(self) -> int: ... + def encode(self, *encoding) -> bytes: ... + def startswith(self, prefix: str) -> int: ... + def endswith(self, suffix: str) -> int: ... + def isdigit(self) -> int: ... + def islower(self) -> int: ... + def isalnum(self) -> int: ... + def isalpha(self) -> int: ... + def isspace(self) -> int: ... + def split(self, s: str) -> List: ... + def replace(self, old: str, new: str) -> str: ... + def strip(self, *chrs) -> str: ... + def format(self, *vars) -> str: ... + + +class ByteArray: + def __init__(self, bytes: any): + """ convert a bytes to ByteArray """ + + def __iter__(self) -> any: + """ support for loop """ + + def __next__(self) -> any: + """ support for loop """ + + def __getitem__(self, __key: int) -> int: + """ support [] index """ + + def __setitem__(self, __key: int, __val: int): ... + def __str__(self) -> str: ... + def decode(self) -> str: ... + + +class FILEIO: + def init(self, path: str, mode: str) -> int: ... + def read(self, *size) -> any: ... + def write(self, s: any) -> int: ... + def close(self): ... + def seek(self, offset: int, *fromwhere) -> int: ... + def tell(self) -> int: ... + def readline(self) -> str: ... + def readlines(self) -> List: ... + def writelines(self, lines: List): ... + + +class Utils: + def int_to_bytes(self, val: int) -> bytes: + """ convert a int to bytes """ diff --git a/examples/pikapython/pikapython/PikaStdLib.pyi b/examples/pikapython/pikapython/PikaStdLib.pyi new file mode 100644 index 00000000..a84b5ad2 --- /dev/null +++ b/examples/pikapython/pikapython/PikaStdLib.pyi @@ -0,0 +1,130 @@ +from PikaObj import * + + +class MemChecker: + def max(self): ... + def now(self): ... + + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def getMax(self) -> float: ... + + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def getNow(self) -> float: ... + + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def resetMax(self): ... + + +class SysObj: + @staticmethod + def int(arg: any) -> int: ... + + @staticmethod + def float(arg: any) -> float: ... + + @staticmethod + def str(arg: any) -> str: ... + + @staticmethod + def iter(arg: any) -> any: ... + + @staticmethod + def range(*ax) -> any: ... + + @staticmethod + def print(*val, **ops): ... + + @staticmethod + def __setitem__(obj: any, key: any, val: any) -> any: ... + + @staticmethod + def __getitem__(obj: any, key: any) -> any: ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def type(arg: any) -> any: ... + + @staticmethod + def len(arg: any) -> int: ... + + @staticmethod + @PIKA_C_MACRO_IF("PIKA_BUILTIN_STRUCT_ENABLE") + def list(*val) -> any: ... + + @staticmethod + @PIKA_C_MACRO_IF("PIKA_BUILTIN_STRUCT_ENABLE") + def dict(*val) -> any: ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def hex(val: int) -> str: ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def ord(val: str) -> int: ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def chr(val: int) -> str: ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def bytes(val: any) -> bytes: ... + + @staticmethod + @PIKA_C_MACRO_IF("PIKA_SYNTAX_FORMAT_ENABLE") + def cformat(fmt: str, *var) -> str: ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def id(obj: any) -> int: ... + + @staticmethod + @PIKA_C_MACRO_IF("PIKA_FILEIO_ENABLE") + def open(path: str, mode: str) -> object: ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def dir(obj: object) -> list: ... + + @staticmethod + @PIKA_C_MACRO_IF("PIKA_EXEC_ENABLE") + def exec(code: str): ... + + @staticmethod + @PIKA_C_MACRO_IF("PIKA_EXEC_ENABLE") + def eval(code: str) -> any: ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def getattr(obj: object, name: str) -> any: ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def setattr(obj: object, name: str, val: any): ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def hasattr(obj: object, name: str) -> int: ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def exit(): ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def input(*info) -> str: ... + + @staticmethod + @PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE") + def help(name: str): ... + + +@PIKA_C_MACRO_IF("0") +class RangeObj: + def __next__(self) -> any: ... + + +@PIKA_C_MACRO_IF("0") +class StringObj: + def __next__(self) -> any: ... diff --git a/examples/pikapython/pikapython/PikaStdTask.pyi b/examples/pikapython/pikapython/PikaStdTask.pyi new file mode 100644 index 00000000..e262d60e --- /dev/null +++ b/examples/pikapython/pikapython/PikaStdTask.pyi @@ -0,0 +1,37 @@ +import PikaStdData +import PikaStdLib + + +class Task(PikaStdLib.SysObj): + calls = PikaStdData.List() + + def __init__(self): + pass + + # regist a function to be called always + def call_always(self, fun_todo: any): + pass + + # regist a function to be called when fun_when() return 'True' + def call_when(self, fun_todo: any, fun_when: any): + pass + + # regist a function to be called periodically + def call_period_ms(self, fun_todo: any, period_ms: int): + pass + + # run all registed function once + def run_once(self): + pass + + # run all registed function forever + def run_forever(self): + pass + + # run all registed function until time is up + def run_until_ms(self, until_ms: int): + pass + + # need be overried to supply the system tick + def platformGetTick(self): + pass diff --git a/examples/pikapython/pikapython/main.py b/examples/pikapython/pikapython/main.py new file mode 100644 index 00000000..c31a56ca --- /dev/null +++ b/examples/pikapython/pikapython/main.py @@ -0,0 +1 @@ +print('hello PikaPython!') diff --git a/examples/pikapython/pikapython/pikaPackage.exe b/examples/pikapython/pikapython/pikaPackage.exe new file mode 100644 index 00000000..e3f11124 Binary files /dev/null and b/examples/pikapython/pikapython/pikaPackage.exe differ diff --git a/examples/pikapython/pikapython/pikascript-api/PikaDebug.h b/examples/pikapython/pikapython/pikascript-api/PikaDebug.h new file mode 100644 index 00000000..384668c7 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaDebug.h @@ -0,0 +1,22 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaDebug__H +#define __PikaDebug__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaDebug(Args *args); + +Arg* PikaDebug_Debuger(PikaObj *self); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaDebug_Debuger.h b/examples/pikapython/pikapython/pikascript-api/PikaDebug_Debuger.h new file mode 100644 index 00000000..5a8f1b0d --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaDebug_Debuger.h @@ -0,0 +1,23 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaDebug_Debuger__H +#define __PikaDebug_Debuger__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaDebug_Debuger(Args *args); + +void PikaDebug_Debuger___init__(PikaObj *self); +void PikaDebug_Debuger_set_trace(PikaObj *self); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaMain.h b/examples/pikapython/pikapython/pikascript-api/PikaMain.h new file mode 100644 index 00000000..38fa53ba --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaMain.h @@ -0,0 +1,21 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaMain__H +#define __PikaMain__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaMain(Args *args); + + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdData.h b/examples/pikapython/pikapython/pikascript-api/PikaStdData.h new file mode 100644 index 00000000..637de8e9 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdData.h @@ -0,0 +1,30 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdData__H +#define __PikaStdData__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdData(Args *args); + +Arg* PikaStdData_ByteArray(PikaObj *self); +Arg* PikaStdData_Dict(PikaObj *self); +Arg* PikaStdData_FILEIO(PikaObj *self); +Arg* PikaStdData_List(PikaObj *self); +Arg* PikaStdData_String(PikaObj *self); +Arg* PikaStdData_Tuple(PikaObj *self); +Arg* PikaStdData_Utils(PikaObj *self); +Arg* PikaStdData_dict_items(PikaObj *self); +Arg* PikaStdData_dict_keys(PikaObj *self); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdData_ByteArray.h b/examples/pikapython/pikapython/pikascript-api/PikaStdData_ByteArray.h new file mode 100644 index 00000000..9f4ee428 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdData_ByteArray.h @@ -0,0 +1,28 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdData_ByteArray__H +#define __PikaStdData_ByteArray__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdData_ByteArray(Args *args); + +int PikaStdData_ByteArray___getitem__(PikaObj *self, int __key); +void PikaStdData_ByteArray___init__(PikaObj *self, Arg* bytes); +Arg* PikaStdData_ByteArray___iter__(PikaObj *self); +Arg* PikaStdData_ByteArray___next__(PikaObj *self); +void PikaStdData_ByteArray___setitem__(PikaObj *self, int __key, int __val); +char* PikaStdData_ByteArray___str__(PikaObj *self); +char* PikaStdData_ByteArray_decode(PikaObj *self); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdData_Dict.h b/examples/pikapython/pikapython/pikascript-api/PikaStdData_Dict.h new file mode 100644 index 00000000..61f8d767 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdData_Dict.h @@ -0,0 +1,36 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdData_Dict__H +#define __PikaStdData_Dict__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdData_Dict(Args *args); + +int PikaStdData_Dict___contains__(PikaObj *self, Arg* val); +void PikaStdData_Dict___del__(PikaObj *self); +Arg* PikaStdData_Dict___getitem__(PikaObj *self, Arg* __key); +void PikaStdData_Dict___init__(PikaObj *self); +Arg* PikaStdData_Dict___iter__(PikaObj *self); +int PikaStdData_Dict___len__(PikaObj *self); +Arg* PikaStdData_Dict___next__(PikaObj *self); +void PikaStdData_Dict___setitem__(PikaObj *self, Arg* __key, Arg* __val); +char* PikaStdData_Dict___str__(PikaObj *self); +Arg* PikaStdData_Dict_get(PikaObj *self, char* key); +PikaObj* PikaStdData_Dict_items(PikaObj *self); +PikaObj* PikaStdData_Dict_keys(PikaObj *self); +void PikaStdData_Dict_remove(PikaObj *self, char* key); +void PikaStdData_Dict_set(PikaObj *self, char* key, Arg* arg); +void PikaStdData_Dict_update(PikaObj *self, PikaObj* other); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdData_FILEIO.h b/examples/pikapython/pikapython/pikascript-api/PikaStdData_FILEIO.h new file mode 100644 index 00000000..5477e0b3 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdData_FILEIO.h @@ -0,0 +1,30 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdData_FILEIO__H +#define __PikaStdData_FILEIO__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdData_FILEIO(Args *args); + +void PikaStdData_FILEIO_close(PikaObj *self); +int PikaStdData_FILEIO_init(PikaObj *self, char* path, char* mode); +Arg* PikaStdData_FILEIO_read(PikaObj *self, PikaTuple* size); +char* PikaStdData_FILEIO_readline(PikaObj *self); +PikaObj* PikaStdData_FILEIO_readlines(PikaObj *self); +int PikaStdData_FILEIO_seek(PikaObj *self, int offset, PikaTuple* fromwhere); +int PikaStdData_FILEIO_tell(PikaObj *self); +int PikaStdData_FILEIO_write(PikaObj *self, Arg* s); +void PikaStdData_FILEIO_writelines(PikaObj *self, PikaObj* lines); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdData_List.h b/examples/pikapython/pikapython/pikascript-api/PikaStdData_List.h new file mode 100644 index 00000000..3fe8840f --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdData_List.h @@ -0,0 +1,31 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdData_List__H +#define __PikaStdData_List__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdData_List(Args *args); + +PikaObj* PikaStdData_List___add__(PikaObj *self, PikaObj* others); +void PikaStdData_List___init__(PikaObj *self); +void PikaStdData_List___setitem__(PikaObj *self, Arg* __key, Arg* __val); +char* PikaStdData_List___str__(PikaObj *self); +void PikaStdData_List_append(PikaObj *self, Arg* arg); +void PikaStdData_List_insert(PikaObj *self, int i, Arg* arg); +Arg* PikaStdData_List_pop(PikaObj *self); +void PikaStdData_List_remove(PikaObj *self, Arg* val); +void PikaStdData_List_reverse(PikaObj *self); +void PikaStdData_List_set(PikaObj *self, int i, Arg* arg); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdData_String.h b/examples/pikapython/pikapython/pikascript-api/PikaStdData_String.h new file mode 100644 index 00000000..f061a5a0 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdData_String.h @@ -0,0 +1,42 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdData_String__H +#define __PikaStdData_String__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdData_String(Args *args); + +Arg* PikaStdData_String___getitem__(PikaObj *self, Arg* __key); +void PikaStdData_String___init__(PikaObj *self, char* s); +Arg* PikaStdData_String___iter__(PikaObj *self); +int PikaStdData_String___len__(PikaObj *self); +Arg* PikaStdData_String___next__(PikaObj *self); +void PikaStdData_String___setitem__(PikaObj *self, Arg* __key, Arg* __val); +char* PikaStdData_String___str__(PikaObj *self); +Arg* PikaStdData_String_encode(PikaObj *self, PikaTuple* encoding); +int PikaStdData_String_endswith(PikaObj *self, char* suffix); +char* PikaStdData_String_format(PikaObj *self, PikaTuple* vars); +char* PikaStdData_String_get(PikaObj *self); +int PikaStdData_String_isalnum(PikaObj *self); +int PikaStdData_String_isalpha(PikaObj *self); +int PikaStdData_String_isdigit(PikaObj *self); +int PikaStdData_String_islower(PikaObj *self); +int PikaStdData_String_isspace(PikaObj *self); +char* PikaStdData_String_replace(PikaObj *self, char* old, char* new); +void PikaStdData_String_set(PikaObj *self, char* s); +PikaObj* PikaStdData_String_split(PikaObj *self, char* s); +int PikaStdData_String_startswith(PikaObj *self, char* prefix); +char* PikaStdData_String_strip(PikaObj *self, PikaTuple* chrs); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdData_Tuple.h b/examples/pikapython/pikapython/pikascript-api/PikaStdData_Tuple.h new file mode 100644 index 00000000..c09be162 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdData_Tuple.h @@ -0,0 +1,31 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdData_Tuple__H +#define __PikaStdData_Tuple__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdData_Tuple(Args *args); + +int PikaStdData_Tuple___contains__(PikaObj *self, Arg* val); +void PikaStdData_Tuple___del__(PikaObj *self); +Arg* PikaStdData_Tuple___getitem__(PikaObj *self, Arg* __key); +void PikaStdData_Tuple___init__(PikaObj *self); +Arg* PikaStdData_Tuple___iter__(PikaObj *self); +int PikaStdData_Tuple___len__(PikaObj *self); +Arg* PikaStdData_Tuple___next__(PikaObj *self); +char* PikaStdData_Tuple___str__(PikaObj *self); +Arg* PikaStdData_Tuple_get(PikaObj *self, int i); +int PikaStdData_Tuple_len(PikaObj *self); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdData_Utils.h b/examples/pikapython/pikapython/pikascript-api/PikaStdData_Utils.h new file mode 100644 index 00000000..892f8498 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdData_Utils.h @@ -0,0 +1,22 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdData_Utils__H +#define __PikaStdData_Utils__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdData_Utils(Args *args); + +Arg* PikaStdData_Utils_int_to_bytes(PikaObj *self, int val); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdData_dict_items.h b/examples/pikapython/pikapython/pikascript-api/PikaStdData_dict_items.h new file mode 100644 index 00000000..35640ad7 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdData_dict_items.h @@ -0,0 +1,25 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdData_dict_items__H +#define __PikaStdData_dict_items__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdData_dict_items(Args *args); + +Arg* PikaStdData_dict_items___iter__(PikaObj *self); +int PikaStdData_dict_items___len__(PikaObj *self); +Arg* PikaStdData_dict_items___next__(PikaObj *self); +char* PikaStdData_dict_items___str__(PikaObj *self); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdData_dict_keys.h b/examples/pikapython/pikapython/pikascript-api/PikaStdData_dict_keys.h new file mode 100644 index 00000000..832d293b --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdData_dict_keys.h @@ -0,0 +1,25 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdData_dict_keys__H +#define __PikaStdData_dict_keys__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdData_dict_keys(Args *args); + +Arg* PikaStdData_dict_keys___iter__(PikaObj *self); +int PikaStdData_dict_keys___len__(PikaObj *self); +Arg* PikaStdData_dict_keys___next__(PikaObj *self); +char* PikaStdData_dict_keys___str__(PikaObj *self); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdLib.h b/examples/pikapython/pikapython/pikascript-api/PikaStdLib.h new file mode 100644 index 00000000..d0ac36ec --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdLib.h @@ -0,0 +1,25 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdLib__H +#define __PikaStdLib__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdLib(Args *args); + +Arg* PikaStdLib_MemChecker(PikaObj *self); +Arg* PikaStdLib_RangeObj(PikaObj *self); +Arg* PikaStdLib_StringObj(PikaObj *self); +Arg* PikaStdLib_SysObj(PikaObj *self); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdLib_MemChecker.h b/examples/pikapython/pikapython/pikascript-api/PikaStdLib_MemChecker.h new file mode 100644 index 00000000..7e835e6e --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdLib_MemChecker.h @@ -0,0 +1,26 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdLib_MemChecker__H +#define __PikaStdLib_MemChecker__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdLib_MemChecker(Args *args); + +pika_float PikaStdLib_MemChecker_getMax(PikaObj *self); +pika_float PikaStdLib_MemChecker_getNow(PikaObj *self); +void PikaStdLib_MemChecker_max(PikaObj *self); +void PikaStdLib_MemChecker_now(PikaObj *self); +void PikaStdLib_MemChecker_resetMax(PikaObj *self); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdLib_RangeObj.h b/examples/pikapython/pikapython/pikascript-api/PikaStdLib_RangeObj.h new file mode 100644 index 00000000..317f7b4c --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdLib_RangeObj.h @@ -0,0 +1,22 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdLib_RangeObj__H +#define __PikaStdLib_RangeObj__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdLib_RangeObj(Args *args); + +Arg* PikaStdLib_RangeObj___next__(PikaObj *self); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdLib_StringObj.h b/examples/pikapython/pikapython/pikascript-api/PikaStdLib_StringObj.h new file mode 100644 index 00000000..290bd9f3 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdLib_StringObj.h @@ -0,0 +1,22 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdLib_StringObj__H +#define __PikaStdLib_StringObj__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdLib_StringObj(Args *args); + +Arg* PikaStdLib_StringObj___next__(PikaObj *self); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdLib_SysObj.h b/examples/pikapython/pikapython/pikascript-api/PikaStdLib_SysObj.h new file mode 100644 index 00000000..00d3e337 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdLib_SysObj.h @@ -0,0 +1,49 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdLib_SysObj__H +#define __PikaStdLib_SysObj__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdLib_SysObj(Args *args); + +Arg* PikaStdLib_SysObj___getitem__(PikaObj *self, Arg* obj, Arg* key); +Arg* PikaStdLib_SysObj___setitem__(PikaObj *self, Arg* obj, Arg* key, Arg* val); +Arg* PikaStdLib_SysObj_bytes(PikaObj *self, Arg* val); +char* PikaStdLib_SysObj_cformat(PikaObj *self, char* fmt, PikaTuple* var); +char* PikaStdLib_SysObj_chr(PikaObj *self, int val); +Arg* PikaStdLib_SysObj_dict(PikaObj *self, PikaTuple* val); +PikaObj* PikaStdLib_SysObj_dir(PikaObj *self, PikaObj* obj); +Arg* PikaStdLib_SysObj_eval(PikaObj *self, char* code); +void PikaStdLib_SysObj_exec(PikaObj *self, char* code); +void PikaStdLib_SysObj_exit(PikaObj *self); +pika_float PikaStdLib_SysObj_float(PikaObj *self, Arg* arg); +Arg* PikaStdLib_SysObj_getattr(PikaObj *self, PikaObj* obj, char* name); +int PikaStdLib_SysObj_hasattr(PikaObj *self, PikaObj* obj, char* name); +void PikaStdLib_SysObj_help(PikaObj *self, char* name); +char* PikaStdLib_SysObj_hex(PikaObj *self, int val); +int PikaStdLib_SysObj_id(PikaObj *self, Arg* obj); +char* PikaStdLib_SysObj_input(PikaObj *self, PikaTuple* info); +int PikaStdLib_SysObj_int(PikaObj *self, Arg* arg); +Arg* PikaStdLib_SysObj_iter(PikaObj *self, Arg* arg); +int PikaStdLib_SysObj_len(PikaObj *self, Arg* arg); +Arg* PikaStdLib_SysObj_list(PikaObj *self, PikaTuple* val); +PikaObj* PikaStdLib_SysObj_open(PikaObj *self, char* path, char* mode); +int PikaStdLib_SysObj_ord(PikaObj *self, char* val); +void PikaStdLib_SysObj_print(PikaObj *self, PikaTuple* val, PikaDict* ops); +Arg* PikaStdLib_SysObj_range(PikaObj *self, PikaTuple* ax); +void PikaStdLib_SysObj_setattr(PikaObj *self, PikaObj* obj, char* name, Arg* val); +char* PikaStdLib_SysObj_str(PikaObj *self, Arg* arg); +Arg* PikaStdLib_SysObj_type(PikaObj *self, Arg* arg); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdTask.h b/examples/pikapython/pikapython/pikascript-api/PikaStdTask.h new file mode 100644 index 00000000..0d621eda --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdTask.h @@ -0,0 +1,22 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdTask__H +#define __PikaStdTask__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdTask(Args *args); + +Arg* PikaStdTask_Task(PikaObj *self); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/PikaStdTask_Task.h b/examples/pikapython/pikapython/pikascript-api/PikaStdTask_Task.h new file mode 100644 index 00000000..a4a6e360 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/PikaStdTask_Task.h @@ -0,0 +1,29 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#ifndef __PikaStdTask_Task__H +#define __PikaStdTask_Task__H +#include +#include +#include "PikaObj.h" + +PikaObj *New_PikaStdTask_Task(Args *args); + +void PikaStdTask_Task___init__(PikaObj *self); +void PikaStdTask_Task_call_always(PikaObj *self, Arg* fun_todo); +void PikaStdTask_Task_call_period_ms(PikaObj *self, Arg* fun_todo, int period_ms); +void PikaStdTask_Task_call_when(PikaObj *self, Arg* fun_todo, Arg* fun_when); +void PikaStdTask_Task_platformGetTick(PikaObj *self); +void PikaStdTask_Task_run_forever(PikaObj *self); +void PikaStdTask_Task_run_once(PikaObj *self); +void PikaStdTask_Task_run_until_ms(PikaObj *self, int until_ms); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-api/__asset_pikaModules_py_a.c b/examples/pikapython/pikapython/pikascript-api/__asset_pikaModules_py_a.c new file mode 100644 index 00000000..44c5daf9 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/__asset_pikaModules_py_a.c @@ -0,0 +1,14 @@ +#include "PikaPlatform.h" +/* warning: auto generated file, please do not modify */ +PIKA_BYTECODE_ALIGN const unsigned char pikaModules_py_a[] = { + 0x7f, 0x70, 0x79, 0x61, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x83, 0x01, 0x00, + 0x00, 0x02, 0x13, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x68, 0x65, 0x6c, + 0x6c, 0x6f, 0x20, 0x50, 0x69, 0x6b, 0x61, 0x50, 0x79, 0x74, 0x68, 0x6f, + 0x6e, 0x21, 0x00, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x00, +}; diff --git a/examples/pikapython/pikapython/pikascript-api/__pikaBinding.c b/examples/pikapython/pikapython/pikascript-api/__pikaBinding.c new file mode 100644 index 00000000..4f5e9835 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/__pikaBinding.c @@ -0,0 +1,1888 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#include +#include +#include "BaseObj.h" +#include "PikaDebug.h" +#include "TinyObj.h" +#include "PikaDebug_Debuger.h" +#include "TinyObj.h" +#include "PikaMain.h" +#include "PikaStdLib_SysObj.h" +#include "PikaStdData.h" +#include "TinyObj.h" +#include "PikaStdData_ByteArray.h" +#include "TinyObj.h" +#include "PikaStdData_Dict.h" +#include "TinyObj.h" +#include "PikaStdData_FILEIO.h" +#include "TinyObj.h" +#include "PikaStdData_List.h" +#include "PikaStdData_Tuple.h" +#include "PikaStdData_String.h" +#include "TinyObj.h" +#include "PikaStdData_Tuple.h" +#include "TinyObj.h" +#include "PikaStdData_Utils.h" +#include "TinyObj.h" +#include "PikaStdData_dict_items.h" +#include "TinyObj.h" +#include "PikaStdData_dict_keys.h" +#include "TinyObj.h" +#include "PikaStdLib.h" +#include "TinyObj.h" +#include "PikaStdLib_MemChecker.h" +#include "TinyObj.h" +#include "PikaStdLib_RangeObj.h" +#include "TinyObj.h" +#include "PikaStdLib_StringObj.h" +#include "TinyObj.h" +#include "PikaStdLib_SysObj.h" +#include "TinyObj.h" +#include "PikaStdTask.h" +#include "TinyObj.h" +#include "PikaStdTask_Task.h" +#include "PikaStdLib_SysObj.h" +#include "PikaStdData_List.h" + +#ifndef PIKA_MODULE_PIKADEBUG_DISABLE +void PikaDebug_DebugerMethod(PikaObj *self, Args *args){ + Arg* res = PikaDebug_Debuger(self); + method_returnArg(args, res); +} +method_typedef( + PikaDebug_Debuger, + "Debuger", "" +); + +class_def(PikaDebug){ + __BEFORE_MOETHOD_DEF + constructor_def(PikaDebug_Debuger, 1761613187), +}; +class_inhert(PikaDebug, TinyObj); + +PikaObj *New_PikaDebug(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaDebug); + return self; +} +#endif + +#ifndef PIKA_MODULE_PIKADEBUG_DISABLE +void PikaDebug_Debuger___init__Method(PikaObj *self, Args *args){ + PikaDebug_Debuger___init__(self); +} +method_typedef( + PikaDebug_Debuger___init__, + "__init__", "" +); + +void PikaDebug_Debuger_set_traceMethod(PikaObj *self, Args *args){ + PikaDebug_Debuger_set_trace(self); +} +method_typedef( + PikaDebug_Debuger_set_trace, + "set_trace", "" +); + +class_def(PikaDebug_Debuger){ + __BEFORE_MOETHOD_DEF + method_def(PikaDebug_Debuger___init__, 904762485), + method_def(PikaDebug_Debuger_set_trace, 1131228543), +}; +class_inhert(PikaDebug_Debuger, TinyObj); + +PikaObj *New_PikaDebug_Debuger(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaDebug_Debuger); + return self; +} + +Arg *PikaDebug_Debuger(PikaObj *self){ + return obj_newObjInPackage(New_PikaDebug_Debuger); +} +#endif + +#ifndef PIKA_MODULE_MAIN_DISABLE +class_def(PikaMain){ + __BEFORE_MOETHOD_DEF +}; +class_inhert(PikaMain, PikaStdLib_SysObj); + +PikaObj *New_PikaMain(Args *args){ + PikaObj *self = New_PikaStdLib_SysObj(args); + obj_setClass(self, PikaMain); + return self; +} + +Arg *PikaMain(PikaObj *self){ + return obj_newObjInPackage(New_PikaMain); +} +#endif + +#ifndef PIKA_MODULE_PIKASTDDATA_DISABLE +void PikaStdData_ByteArrayMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdData_ByteArray(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_ByteArray, + "ByteArray", "" +); + +void PikaStdData_DictMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdData_Dict(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_Dict, + "Dict", "" +); + +void PikaStdData_FILEIOMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdData_FILEIO(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_FILEIO, + "FILEIO", "" +); + +void PikaStdData_ListMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdData_List(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_List, + "List", "" +); + +void PikaStdData_StringMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdData_String(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_String, + "String", "" +); + +void PikaStdData_TupleMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdData_Tuple(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_Tuple, + "Tuple", "" +); + +void PikaStdData_UtilsMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdData_Utils(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_Utils, + "Utils", "" +); + +void PikaStdData_dict_itemsMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdData_dict_items(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_dict_items, + "dict_items", "" +); + +void PikaStdData_dict_keysMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdData_dict_keys(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_dict_keys, + "dict_keys", "" +); + +class_def(PikaStdData){ + __BEFORE_MOETHOD_DEF + constructor_def(PikaStdData_Tuple, 238099855), + constructor_def(PikaStdData_Utils, 239242230), + constructor_def(PikaStdData_FILEIO, 813431197), + constructor_def(PikaStdData_dict_keys, 872966404), + constructor_def(PikaStdData_dict_items, 888749258), + constructor_def(PikaStdData_String, 1374591964), + constructor_def(PikaStdData_ByteArray, 1998882840), + constructor_def(PikaStdData_Dict, 2089035049), + constructor_def(PikaStdData_List, 2089323073), +}; +class_inhert(PikaStdData, TinyObj); + +PikaObj *New_PikaStdData(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdData); + return self; +} +#endif + +#ifndef PIKA_MODULE_PIKASTDDATA_DISABLE +void PikaStdData_ByteArray___getitem__Method(PikaObj *self, Args *args){ + int __key = args_getInt(args, "__key"); + int res = PikaStdData_ByteArray___getitem__(self, __key); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_ByteArray___getitem__, + "__getitem__", "__key" +); + +void PikaStdData_ByteArray___init__Method(PikaObj *self, Args *args){ + Arg* bytes = args_getArg(args, "bytes"); + PikaStdData_ByteArray___init__(self, bytes); +} +method_typedef( + PikaStdData_ByteArray___init__, + "__init__", "bytes" +); + +void PikaStdData_ByteArray___iter__Method(PikaObj *self, Args *args){ + Arg* res = PikaStdData_ByteArray___iter__(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_ByteArray___iter__, + "__iter__", "" +); + +void PikaStdData_ByteArray___next__Method(PikaObj *self, Args *args){ + Arg* res = PikaStdData_ByteArray___next__(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_ByteArray___next__, + "__next__", "" +); + +void PikaStdData_ByteArray___setitem__Method(PikaObj *self, Args *args){ + int __key = args_getInt(args, "__key"); + int __val = args_getInt(args, "__val"); + PikaStdData_ByteArray___setitem__(self, __key, __val); +} +method_typedef( + PikaStdData_ByteArray___setitem__, + "__setitem__", "__key,__val" +); + +void PikaStdData_ByteArray___str__Method(PikaObj *self, Args *args){ + char* res = PikaStdData_ByteArray___str__(self); + method_returnStr(args, res); +} +method_typedef( + PikaStdData_ByteArray___str__, + "__str__", "" +); + +void PikaStdData_ByteArray_decodeMethod(PikaObj *self, Args *args){ + char* res = PikaStdData_ByteArray_decode(self); + method_returnStr(args, res); +} +method_typedef( + PikaStdData_ByteArray_decode, + "decode", "" +); + +class_def(PikaStdData_ByteArray){ + __BEFORE_MOETHOD_DEF + method_def(PikaStdData_ByteArray___init__, 904762485), + method_def(PikaStdData_ByteArray___iter__, 911732085), + method_def(PikaStdData_ByteArray___next__, 1090305216), + method_def(PikaStdData_ByteArray___setitem__, 1364865276), + method_def(PikaStdData_ByteArray___getitem__, 1535436016), + method_def(PikaStdData_ByteArray_decode, 2021571977), + method_def(PikaStdData_ByteArray___str__, 2056834106), +}; +class_inhert(PikaStdData_ByteArray, TinyObj); + +PikaObj *New_PikaStdData_ByteArray(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdData_ByteArray); + return self; +} + +Arg *PikaStdData_ByteArray(PikaObj *self){ + return obj_newObjInPackage(New_PikaStdData_ByteArray); +} +#endif + +#ifndef PIKA_MODULE_PIKASTDDATA_DISABLE +void PikaStdData_Dict___contains__Method(PikaObj *self, Args *args){ + Arg* val = args_getArg(args, "val"); + int res = PikaStdData_Dict___contains__(self, val); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_Dict___contains__, + "__contains__", "val" +); + +void PikaStdData_Dict___del__Method(PikaObj *self, Args *args){ + PikaStdData_Dict___del__(self); +} +method_typedef( + PikaStdData_Dict___del__, + "__del__", "" +); + +void PikaStdData_Dict___getitem__Method(PikaObj *self, Args *args){ + Arg* __key = args_getArg(args, "__key"); + Arg* res = PikaStdData_Dict___getitem__(self, __key); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_Dict___getitem__, + "__getitem__", "__key" +); + +void PikaStdData_Dict___init__Method(PikaObj *self, Args *args){ + PikaStdData_Dict___init__(self); +} +method_typedef( + PikaStdData_Dict___init__, + "__init__", "" +); + +void PikaStdData_Dict___iter__Method(PikaObj *self, Args *args){ + Arg* res = PikaStdData_Dict___iter__(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_Dict___iter__, + "__iter__", "" +); + +void PikaStdData_Dict___len__Method(PikaObj *self, Args *args){ + int res = PikaStdData_Dict___len__(self); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_Dict___len__, + "__len__", "" +); + +void PikaStdData_Dict___next__Method(PikaObj *self, Args *args){ + Arg* res = PikaStdData_Dict___next__(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_Dict___next__, + "__next__", "" +); + +void PikaStdData_Dict___setitem__Method(PikaObj *self, Args *args){ + Arg* __key = args_getArg(args, "__key"); + Arg* __val = args_getArg(args, "__val"); + PikaStdData_Dict___setitem__(self, __key, __val); +} +method_typedef( + PikaStdData_Dict___setitem__, + "__setitem__", "__key,__val" +); + +void PikaStdData_Dict___str__Method(PikaObj *self, Args *args){ + char* res = PikaStdData_Dict___str__(self); + method_returnStr(args, res); +} +method_typedef( + PikaStdData_Dict___str__, + "__str__", "" +); + +void PikaStdData_Dict_getMethod(PikaObj *self, Args *args){ + char* key = args_getStr(args, "key"); + Arg* res = PikaStdData_Dict_get(self, key); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_Dict_get, + "get", "key" +); + +void PikaStdData_Dict_itemsMethod(PikaObj *self, Args *args){ + PikaObj* res = PikaStdData_Dict_items(self); + method_returnObj(args, res); +} +method_typedef( + PikaStdData_Dict_items, + "items", "" +); + +void PikaStdData_Dict_keysMethod(PikaObj *self, Args *args){ + PikaObj* res = PikaStdData_Dict_keys(self); + method_returnObj(args, res); +} +method_typedef( + PikaStdData_Dict_keys, + "keys", "" +); + +void PikaStdData_Dict_removeMethod(PikaObj *self, Args *args){ + char* key = args_getStr(args, "key"); + PikaStdData_Dict_remove(self, key); +} +method_typedef( + PikaStdData_Dict_remove, + "remove", "key" +); + +void PikaStdData_Dict_setMethod(PikaObj *self, Args *args){ + char* key = args_getStr(args, "key"); + Arg* arg = args_getArg(args, "arg"); + PikaStdData_Dict_set(self, key, arg); +} +method_typedef( + PikaStdData_Dict_set, + "set", "key,arg" +); + +void PikaStdData_Dict_updateMethod(PikaObj *self, Args *args){ + PikaObj* other = args_getPtr(args, "other"); + PikaStdData_Dict_update(self, other); +} +method_typedef( + PikaStdData_Dict_update, + "update", "other" +); + +class_def(PikaStdData_Dict){ + __BEFORE_MOETHOD_DEF + method_def(PikaStdData_Dict_get, 193492613), + method_def(PikaStdData_Dict_set, 193505681), + method_def(PikaStdData_Dict_items, 262956327), + method_def(PikaStdData_Dict_remove, 422343795), + method_def(PikaStdData_Dict_update, 552456360), + method_def(PikaStdData_Dict___init__, 904762485), + method_def(PikaStdData_Dict___iter__, 911732085), + method_def(PikaStdData_Dict___next__, 1090305216), + method_def(PikaStdData_Dict___setitem__, 1364865276), + method_def(PikaStdData_Dict___getitem__, 1535436016), + method_def(PikaStdData_Dict___contains__, 1644201824), + method_def(PikaStdData_Dict___del__, 2038499702), + method_def(PikaStdData_Dict___len__, 2047989248), + method_def(PikaStdData_Dict___str__, 2056834106), + method_def(PikaStdData_Dict_keys, 2090432961), +}; +class_inhert(PikaStdData_Dict, TinyObj); + +PikaObj *New_PikaStdData_Dict(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdData_Dict); + return self; +} + +Arg *PikaStdData_Dict(PikaObj *self){ + return obj_newObjInPackage(New_PikaStdData_Dict); +} +#endif + +#ifndef PIKA_MODULE_PIKASTDDATA_DISABLE +void PikaStdData_FILEIO_closeMethod(PikaObj *self, Args *args){ + PikaStdData_FILEIO_close(self); +} +method_typedef( + PikaStdData_FILEIO_close, + "close", "" +); + +void PikaStdData_FILEIO_initMethod(PikaObj *self, Args *args){ + char* path = args_getStr(args, "path"); + char* mode = args_getStr(args, "mode"); + int res = PikaStdData_FILEIO_init(self, path, mode); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_FILEIO_init, + "init", "path,mode" +); + +void PikaStdData_FILEIO_readMethod(PikaObj *self, Args *args){ + PikaTuple* size = args_getTuple(args, "size"); + Arg* res = PikaStdData_FILEIO_read(self, size); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_FILEIO_read, + "read", "*size" +); + +void PikaStdData_FILEIO_readlineMethod(PikaObj *self, Args *args){ + char* res = PikaStdData_FILEIO_readline(self); + method_returnStr(args, res); +} +method_typedef( + PikaStdData_FILEIO_readline, + "readline", "" +); + +void PikaStdData_FILEIO_readlinesMethod(PikaObj *self, Args *args){ + PikaObj* res = PikaStdData_FILEIO_readlines(self); + method_returnObj(args, res); +} +method_typedef( + PikaStdData_FILEIO_readlines, + "readlines", "" +); + +void PikaStdData_FILEIO_seekMethod(PikaObj *self, Args *args){ + int offset = args_getInt(args, "offset"); + PikaTuple* fromwhere = args_getTuple(args, "fromwhere"); + int res = PikaStdData_FILEIO_seek(self, offset, fromwhere); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_FILEIO_seek, + "seek", "offset,*fromwhere" +); + +void PikaStdData_FILEIO_tellMethod(PikaObj *self, Args *args){ + int res = PikaStdData_FILEIO_tell(self); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_FILEIO_tell, + "tell", "" +); + +void PikaStdData_FILEIO_writeMethod(PikaObj *self, Args *args){ + Arg* s = args_getArg(args, "s"); + int res = PikaStdData_FILEIO_write(self, s); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_FILEIO_write, + "write", "s" +); + +void PikaStdData_FILEIO_writelinesMethod(PikaObj *self, Args *args){ + PikaObj* lines = args_getPtr(args, "lines"); + PikaStdData_FILEIO_writelines(self, lines); +} +method_typedef( + PikaStdData_FILEIO_writelines, + "writelines", "lines" +); + +class_def(PikaStdData_FILEIO){ + __BEFORE_MOETHOD_DEF + method_def(PikaStdData_FILEIO_close, 255564379), + method_def(PikaStdData_FILEIO_write, 279491920), + method_def(PikaStdData_FILEIO_readlines, 594708860), + method_def(PikaStdData_FILEIO_writelines, 836522731), + method_def(PikaStdData_FILEIO_readline, 2035354601), + method_def(PikaStdData_FILEIO_init, 2090370361), + method_def(PikaStdData_FILEIO_read, 2090683713), + method_def(PikaStdData_FILEIO_seek, 2090719789), + method_def(PikaStdData_FILEIO_tell, 2090755958), +}; +class_inhert(PikaStdData_FILEIO, TinyObj); + +PikaObj *New_PikaStdData_FILEIO(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdData_FILEIO); + return self; +} + +Arg *PikaStdData_FILEIO(PikaObj *self){ + return obj_newObjInPackage(New_PikaStdData_FILEIO); +} +#endif + +#ifndef PIKA_MODULE_PIKASTDDATA_DISABLE +void PikaStdData_List___add__Method(PikaObj *self, Args *args){ + PikaObj* others = args_getPtr(args, "others"); + PikaObj* res = PikaStdData_List___add__(self, others); + method_returnObj(args, res); +} +method_typedef( + PikaStdData_List___add__, + "__add__", "others" +); + +void PikaStdData_List___init__Method(PikaObj *self, Args *args){ + PikaStdData_List___init__(self); +} +method_typedef( + PikaStdData_List___init__, + "__init__", "" +); + +void PikaStdData_List___setitem__Method(PikaObj *self, Args *args){ + Arg* __key = args_getArg(args, "__key"); + Arg* __val = args_getArg(args, "__val"); + PikaStdData_List___setitem__(self, __key, __val); +} +method_typedef( + PikaStdData_List___setitem__, + "__setitem__", "__key,__val" +); + +void PikaStdData_List___str__Method(PikaObj *self, Args *args){ + char* res = PikaStdData_List___str__(self); + method_returnStr(args, res); +} +method_typedef( + PikaStdData_List___str__, + "__str__", "" +); + +void PikaStdData_List_appendMethod(PikaObj *self, Args *args){ + Arg* arg = args_getArg(args, "arg"); + PikaStdData_List_append(self, arg); +} +method_typedef( + PikaStdData_List_append, + "append", "arg" +); + +void PikaStdData_List_insertMethod(PikaObj *self, Args *args){ + int i = args_getInt(args, "i"); + Arg* arg = args_getArg(args, "arg"); + PikaStdData_List_insert(self, i, arg); +} +method_typedef( + PikaStdData_List_insert, + "insert", "i,arg" +); + +void PikaStdData_List_popMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdData_List_pop(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_List_pop, + "pop", "" +); + +void PikaStdData_List_removeMethod(PikaObj *self, Args *args){ + Arg* val = args_getArg(args, "val"); + PikaStdData_List_remove(self, val); +} +method_typedef( + PikaStdData_List_remove, + "remove", "val" +); + +void PikaStdData_List_reverseMethod(PikaObj *self, Args *args){ + PikaStdData_List_reverse(self); +} +method_typedef( + PikaStdData_List_reverse, + "reverse", "" +); + +void PikaStdData_List_setMethod(PikaObj *self, Args *args){ + int i = args_getInt(args, "i"); + Arg* arg = args_getArg(args, "arg"); + PikaStdData_List_set(self, i, arg); +} +method_typedef( + PikaStdData_List_set, + "set", "i,arg" +); + +class_def(PikaStdData_List){ + __BEFORE_MOETHOD_DEF + method_def(PikaStdData_List_insert, 81003162), + method_def(PikaStdData_List_pop, 193502740), + method_def(PikaStdData_List_set, 193505681), + method_def(PikaStdData_List_remove, 422343795), + method_def(PikaStdData_List___init__, 904762485), + method_def(PikaStdData_List_reverse, 1062753473), + method_def(PikaStdData_List___setitem__, 1364865276), + method_def(PikaStdData_List_append, 1917667549), + method_def(PikaStdData_List___add__, 2034897290), + method_def(PikaStdData_List___str__, 2056834106), +}; +class_inhert(PikaStdData_List, PikaStdData_Tuple); + +PikaObj *New_PikaStdData_List(Args *args){ + PikaObj *self = New_PikaStdData_Tuple(args); + obj_setClass(self, PikaStdData_List); + return self; +} + +Arg *PikaStdData_List(PikaObj *self){ + return obj_newObjInPackage(New_PikaStdData_List); +} +#endif + +#ifndef PIKA_MODULE_PIKASTDDATA_DISABLE +void PikaStdData_String___getitem__Method(PikaObj *self, Args *args){ + Arg* __key = args_getArg(args, "__key"); + Arg* res = PikaStdData_String___getitem__(self, __key); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_String___getitem__, + "__getitem__", "__key" +); + +void PikaStdData_String___init__Method(PikaObj *self, Args *args){ + char* s = args_getStr(args, "s"); + PikaStdData_String___init__(self, s); +} +method_typedef( + PikaStdData_String___init__, + "__init__", "s" +); + +void PikaStdData_String___iter__Method(PikaObj *self, Args *args){ + Arg* res = PikaStdData_String___iter__(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_String___iter__, + "__iter__", "" +); + +void PikaStdData_String___len__Method(PikaObj *self, Args *args){ + int res = PikaStdData_String___len__(self); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_String___len__, + "__len__", "" +); + +void PikaStdData_String___next__Method(PikaObj *self, Args *args){ + Arg* res = PikaStdData_String___next__(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_String___next__, + "__next__", "" +); + +void PikaStdData_String___setitem__Method(PikaObj *self, Args *args){ + Arg* __key = args_getArg(args, "__key"); + Arg* __val = args_getArg(args, "__val"); + PikaStdData_String___setitem__(self, __key, __val); +} +method_typedef( + PikaStdData_String___setitem__, + "__setitem__", "__key,__val" +); + +void PikaStdData_String___str__Method(PikaObj *self, Args *args){ + char* res = PikaStdData_String___str__(self); + method_returnStr(args, res); +} +method_typedef( + PikaStdData_String___str__, + "__str__", "" +); + +void PikaStdData_String_encodeMethod(PikaObj *self, Args *args){ + PikaTuple* encoding = args_getTuple(args, "encoding"); + Arg* res = PikaStdData_String_encode(self, encoding); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_String_encode, + "encode", "*encoding" +); + +void PikaStdData_String_endswithMethod(PikaObj *self, Args *args){ + char* suffix = args_getStr(args, "suffix"); + int res = PikaStdData_String_endswith(self, suffix); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_String_endswith, + "endswith", "suffix" +); + +void PikaStdData_String_formatMethod(PikaObj *self, Args *args){ + PikaTuple* vars = args_getTuple(args, "vars"); + char* res = PikaStdData_String_format(self, vars); + method_returnStr(args, res); +} +method_typedef( + PikaStdData_String_format, + "format", "*vars" +); + +void PikaStdData_String_getMethod(PikaObj *self, Args *args){ + char* res = PikaStdData_String_get(self); + method_returnStr(args, res); +} +method_typedef( + PikaStdData_String_get, + "get", "" +); + +void PikaStdData_String_isalnumMethod(PikaObj *self, Args *args){ + int res = PikaStdData_String_isalnum(self); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_String_isalnum, + "isalnum", "" +); + +void PikaStdData_String_isalphaMethod(PikaObj *self, Args *args){ + int res = PikaStdData_String_isalpha(self); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_String_isalpha, + "isalpha", "" +); + +void PikaStdData_String_isdigitMethod(PikaObj *self, Args *args){ + int res = PikaStdData_String_isdigit(self); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_String_isdigit, + "isdigit", "" +); + +void PikaStdData_String_islowerMethod(PikaObj *self, Args *args){ + int res = PikaStdData_String_islower(self); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_String_islower, + "islower", "" +); + +void PikaStdData_String_isspaceMethod(PikaObj *self, Args *args){ + int res = PikaStdData_String_isspace(self); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_String_isspace, + "isspace", "" +); + +void PikaStdData_String_replaceMethod(PikaObj *self, Args *args){ + char* old = args_getStr(args, "old"); + char* new = args_getStr(args, "new"); + char* res = PikaStdData_String_replace(self, old, new); + method_returnStr(args, res); +} +method_typedef( + PikaStdData_String_replace, + "replace", "old,new" +); + +void PikaStdData_String_setMethod(PikaObj *self, Args *args){ + char* s = args_getStr(args, "s"); + PikaStdData_String_set(self, s); +} +method_typedef( + PikaStdData_String_set, + "set", "s" +); + +void PikaStdData_String_splitMethod(PikaObj *self, Args *args){ + char* s = args_getStr(args, "s"); + PikaObj* res = PikaStdData_String_split(self, s); + method_returnObj(args, res); +} +method_typedef( + PikaStdData_String_split, + "split", "s" +); + +void PikaStdData_String_startswithMethod(PikaObj *self, Args *args){ + char* prefix = args_getStr(args, "prefix"); + int res = PikaStdData_String_startswith(self, prefix); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_String_startswith, + "startswith", "prefix" +); + +void PikaStdData_String_stripMethod(PikaObj *self, Args *args){ + PikaTuple* chrs = args_getTuple(args, "chrs"); + char* res = PikaStdData_String_strip(self, chrs); + method_returnStr(args, res); +} +method_typedef( + PikaStdData_String_strip, + "strip", "*chrs" +); + +class_def(PikaStdData_String){ + __BEFORE_MOETHOD_DEF + method_def(PikaStdData_String_get, 193492613), + method_def(PikaStdData_String_set, 193505681), + method_def(PikaStdData_String_split, 274679281), + method_def(PikaStdData_String_strip, 274829559), + method_def(PikaStdData_String_isalnum, 700198430), + method_def(PikaStdData_String_isalpha, 700200167), + method_def(PikaStdData_String_isdigit, 703640370), + method_def(PikaStdData_String_islower, 713360650), + method_def(PikaStdData_String_isspace, 721673997), + method_def(PikaStdData_String_startswith, 841709250), + method_def(PikaStdData_String___init__, 904762485), + method_def(PikaStdData_String___iter__, 911732085), + method_def(PikaStdData_String_endswith, 920277419), + method_def(PikaStdData_String_replace, 1055870465), + method_def(PikaStdData_String___next__, 1090305216), + method_def(PikaStdData_String___setitem__, 1364865276), + method_def(PikaStdData_String___getitem__, 1535436016), + method_def(PikaStdData_String___len__, 2047989248), + method_def(PikaStdData_String___str__, 2056834106), + method_def(PikaStdData_String_encode, 2071380659), + method_def(PikaStdData_String_format, 2112238766), +}; +class_inhert(PikaStdData_String, TinyObj); + +PikaObj *New_PikaStdData_String(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdData_String); + return self; +} + +Arg *PikaStdData_String(PikaObj *self){ + return obj_newObjInPackage(New_PikaStdData_String); +} +#endif + +#ifndef PIKA_MODULE_PIKASTDDATA_DISABLE +void PikaStdData_Tuple___contains__Method(PikaObj *self, Args *args){ + Arg* val = args_getArg(args, "val"); + int res = PikaStdData_Tuple___contains__(self, val); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_Tuple___contains__, + "__contains__", "val" +); + +void PikaStdData_Tuple___del__Method(PikaObj *self, Args *args){ + PikaStdData_Tuple___del__(self); +} +method_typedef( + PikaStdData_Tuple___del__, + "__del__", "" +); + +void PikaStdData_Tuple___getitem__Method(PikaObj *self, Args *args){ + Arg* __key = args_getArg(args, "__key"); + Arg* res = PikaStdData_Tuple___getitem__(self, __key); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_Tuple___getitem__, + "__getitem__", "__key" +); + +void PikaStdData_Tuple___init__Method(PikaObj *self, Args *args){ + PikaStdData_Tuple___init__(self); +} +method_typedef( + PikaStdData_Tuple___init__, + "__init__", "" +); + +void PikaStdData_Tuple___iter__Method(PikaObj *self, Args *args){ + Arg* res = PikaStdData_Tuple___iter__(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_Tuple___iter__, + "__iter__", "" +); + +void PikaStdData_Tuple___len__Method(PikaObj *self, Args *args){ + int res = PikaStdData_Tuple___len__(self); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_Tuple___len__, + "__len__", "" +); + +void PikaStdData_Tuple___next__Method(PikaObj *self, Args *args){ + Arg* res = PikaStdData_Tuple___next__(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_Tuple___next__, + "__next__", "" +); + +void PikaStdData_Tuple___str__Method(PikaObj *self, Args *args){ + char* res = PikaStdData_Tuple___str__(self); + method_returnStr(args, res); +} +method_typedef( + PikaStdData_Tuple___str__, + "__str__", "" +); + +void PikaStdData_Tuple_getMethod(PikaObj *self, Args *args){ + int i = args_getInt(args, "i"); + Arg* res = PikaStdData_Tuple_get(self, i); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_Tuple_get, + "get", "i" +); + +void PikaStdData_Tuple_lenMethod(PikaObj *self, Args *args){ + int res = PikaStdData_Tuple_len(self); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_Tuple_len, + "len", "" +); + +class_def(PikaStdData_Tuple){ + __BEFORE_MOETHOD_DEF + method_def(PikaStdData_Tuple_get, 193492613), + method_def(PikaStdData_Tuple_len, 193498052), + method_def(PikaStdData_Tuple___init__, 904762485), + method_def(PikaStdData_Tuple___iter__, 911732085), + method_def(PikaStdData_Tuple___next__, 1090305216), + method_def(PikaStdData_Tuple___getitem__, 1535436016), + method_def(PikaStdData_Tuple___contains__, 1644201824), + method_def(PikaStdData_Tuple___del__, 2038499702), + method_def(PikaStdData_Tuple___len__, 2047989248), + method_def(PikaStdData_Tuple___str__, 2056834106), +}; +class_inhert(PikaStdData_Tuple, TinyObj); + +PikaObj *New_PikaStdData_Tuple(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdData_Tuple); + return self; +} + +Arg *PikaStdData_Tuple(PikaObj *self){ + return obj_newObjInPackage(New_PikaStdData_Tuple); +} +#endif + +#ifndef PIKA_MODULE_PIKASTDDATA_DISABLE +void PikaStdData_Utils_int_to_bytesMethod(PikaObj *self, Args *args){ + int val = args_getInt(args, "val"); + Arg* res = PikaStdData_Utils_int_to_bytes(self, val); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_Utils_int_to_bytes, + "int_to_bytes", "val" +); + +class_def(PikaStdData_Utils){ + __BEFORE_MOETHOD_DEF + method_def(PikaStdData_Utils_int_to_bytes, 476200216), +}; +class_inhert(PikaStdData_Utils, TinyObj); + +PikaObj *New_PikaStdData_Utils(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdData_Utils); + return self; +} + +Arg *PikaStdData_Utils(PikaObj *self){ + return obj_newObjInPackage(New_PikaStdData_Utils); +} +#endif + +#ifndef PIKA_MODULE_PIKASTDDATA_DISABLE +void PikaStdData_dict_items___iter__Method(PikaObj *self, Args *args){ + Arg* res = PikaStdData_dict_items___iter__(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_dict_items___iter__, + "__iter__", "" +); + +void PikaStdData_dict_items___len__Method(PikaObj *self, Args *args){ + int res = PikaStdData_dict_items___len__(self); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_dict_items___len__, + "__len__", "" +); + +void PikaStdData_dict_items___next__Method(PikaObj *self, Args *args){ + Arg* res = PikaStdData_dict_items___next__(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_dict_items___next__, + "__next__", "" +); + +void PikaStdData_dict_items___str__Method(PikaObj *self, Args *args){ + char* res = PikaStdData_dict_items___str__(self); + method_returnStr(args, res); +} +method_typedef( + PikaStdData_dict_items___str__, + "__str__", "" +); + +class_def(PikaStdData_dict_items){ + __BEFORE_MOETHOD_DEF + method_def(PikaStdData_dict_items___iter__, 911732085), + method_def(PikaStdData_dict_items___next__, 1090305216), + method_def(PikaStdData_dict_items___len__, 2047989248), + method_def(PikaStdData_dict_items___str__, 2056834106), +}; +class_inhert(PikaStdData_dict_items, TinyObj); + +PikaObj *New_PikaStdData_dict_items(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdData_dict_items); + return self; +} + +Arg *PikaStdData_dict_items(PikaObj *self){ + return obj_newObjInPackage(New_PikaStdData_dict_items); +} +#endif + +#ifndef PIKA_MODULE_PIKASTDDATA_DISABLE +void PikaStdData_dict_keys___iter__Method(PikaObj *self, Args *args){ + Arg* res = PikaStdData_dict_keys___iter__(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_dict_keys___iter__, + "__iter__", "" +); + +void PikaStdData_dict_keys___len__Method(PikaObj *self, Args *args){ + int res = PikaStdData_dict_keys___len__(self); + method_returnInt(args, res); +} +method_typedef( + PikaStdData_dict_keys___len__, + "__len__", "" +); + +void PikaStdData_dict_keys___next__Method(PikaObj *self, Args *args){ + Arg* res = PikaStdData_dict_keys___next__(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdData_dict_keys___next__, + "__next__", "" +); + +void PikaStdData_dict_keys___str__Method(PikaObj *self, Args *args){ + char* res = PikaStdData_dict_keys___str__(self); + method_returnStr(args, res); +} +method_typedef( + PikaStdData_dict_keys___str__, + "__str__", "" +); + +class_def(PikaStdData_dict_keys){ + __BEFORE_MOETHOD_DEF + method_def(PikaStdData_dict_keys___iter__, 911732085), + method_def(PikaStdData_dict_keys___next__, 1090305216), + method_def(PikaStdData_dict_keys___len__, 2047989248), + method_def(PikaStdData_dict_keys___str__, 2056834106), +}; +class_inhert(PikaStdData_dict_keys, TinyObj); + +PikaObj *New_PikaStdData_dict_keys(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdData_dict_keys); + return self; +} + +Arg *PikaStdData_dict_keys(PikaObj *self){ + return obj_newObjInPackage(New_PikaStdData_dict_keys); +} +#endif + +#ifndef PIKA_MODULE_PIKASTDLIB_DISABLE +void PikaStdLib_MemCheckerMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdLib_MemChecker(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_MemChecker, + "MemChecker", "" +); + +void PikaStdLib_RangeObjMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdLib_RangeObj(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_RangeObj, + "RangeObj", "" +); + +void PikaStdLib_StringObjMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdLib_StringObj(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_StringObj, + "StringObj", "" +); + +void PikaStdLib_SysObjMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdLib_SysObj(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_SysObj, + "SysObj", "" +); + +class_def(PikaStdLib){ + __BEFORE_MOETHOD_DEF +#if 0 + constructor_def(PikaStdLib_StringObj, 145144695), +#endif + constructor_def(PikaStdLib_MemChecker, 426635353), + constructor_def(PikaStdLib_SysObj, 1380528799), +#if 0 + constructor_def(PikaStdLib_RangeObj, 1538428845), +#endif +}; +class_inhert(PikaStdLib, TinyObj); + +PikaObj *New_PikaStdLib(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdLib); + return self; +} +#endif + +#ifndef PIKA_MODULE_PIKASTDLIB_DISABLE +void PikaStdLib_MemChecker_getMaxMethod(PikaObj *self, Args *args){ + pika_float res = PikaStdLib_MemChecker_getMax(self); + method_returnFloat(args, res); +} +method_typedef( + PikaStdLib_MemChecker_getMax, + "getMax", "" +); + +void PikaStdLib_MemChecker_getNowMethod(PikaObj *self, Args *args){ + pika_float res = PikaStdLib_MemChecker_getNow(self); + method_returnFloat(args, res); +} +method_typedef( + PikaStdLib_MemChecker_getNow, + "getNow", "" +); + +void PikaStdLib_MemChecker_maxMethod(PikaObj *self, Args *args){ + PikaStdLib_MemChecker_max(self); +} +method_typedef( + PikaStdLib_MemChecker_max, + "max", "" +); + +void PikaStdLib_MemChecker_nowMethod(PikaObj *self, Args *args){ + PikaStdLib_MemChecker_now(self); +} +method_typedef( + PikaStdLib_MemChecker_now, + "now", "" +); + +void PikaStdLib_MemChecker_resetMaxMethod(PikaObj *self, Args *args){ + PikaStdLib_MemChecker_resetMax(self); +} +method_typedef( + PikaStdLib_MemChecker_resetMax, + "resetMax", "" +); + +class_def(PikaStdLib_MemChecker){ + __BEFORE_MOETHOD_DEF + method_def(PikaStdLib_MemChecker_max, 193499019), + method_def(PikaStdLib_MemChecker_now, 193500569), +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_MemChecker_resetMax, 593750542), +#endif +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_MemChecker_getMax, 2139551979), +#endif +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_MemChecker_getNow, 2139553529), +#endif +}; +class_inhert(PikaStdLib_MemChecker, TinyObj); + +PikaObj *New_PikaStdLib_MemChecker(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdLib_MemChecker); + return self; +} + +Arg *PikaStdLib_MemChecker(PikaObj *self){ + return obj_newObjInPackage(New_PikaStdLib_MemChecker); +} +#endif + +#ifndef PIKA_MODULE_PIKASTDLIB_DISABLE +void PikaStdLib_RangeObj___next__Method(PikaObj *self, Args *args){ + Arg* res = PikaStdLib_RangeObj___next__(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_RangeObj___next__, + "__next__", "" +); + +class_def(PikaStdLib_RangeObj){ + __BEFORE_MOETHOD_DEF + method_def(PikaStdLib_RangeObj___next__, 1090305216), +}; +class_inhert(PikaStdLib_RangeObj, TinyObj); + +PikaObj *New_PikaStdLib_RangeObj(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdLib_RangeObj); + return self; +} + +Arg *PikaStdLib_RangeObj(PikaObj *self){ + return obj_newObjInPackage(New_PikaStdLib_RangeObj); +} +#endif + +#ifndef PIKA_MODULE_PIKASTDLIB_DISABLE +void PikaStdLib_StringObj___next__Method(PikaObj *self, Args *args){ + Arg* res = PikaStdLib_StringObj___next__(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_StringObj___next__, + "__next__", "" +); + +class_def(PikaStdLib_StringObj){ + __BEFORE_MOETHOD_DEF + method_def(PikaStdLib_StringObj___next__, 1090305216), +}; +class_inhert(PikaStdLib_StringObj, TinyObj); + +PikaObj *New_PikaStdLib_StringObj(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdLib_StringObj); + return self; +} + +Arg *PikaStdLib_StringObj(PikaObj *self){ + return obj_newObjInPackage(New_PikaStdLib_StringObj); +} +#endif + +#ifndef PIKA_MODULE_PIKASTDLIB_DISABLE +void PikaStdLib_SysObj___getitem__Method(PikaObj *self, Args *args){ + Arg* obj = args_getArg(args, "obj"); + Arg* key = args_getArg(args, "key"); + Arg* res = PikaStdLib_SysObj___getitem__(self, obj, key); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_SysObj___getitem__, + "__getitem__", "obj,key" +); + +void PikaStdLib_SysObj___setitem__Method(PikaObj *self, Args *args){ + Arg* obj = args_getArg(args, "obj"); + Arg* key = args_getArg(args, "key"); + Arg* val = args_getArg(args, "val"); + Arg* res = PikaStdLib_SysObj___setitem__(self, obj, key, val); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_SysObj___setitem__, + "__setitem__", "obj,key,val" +); + +void PikaStdLib_SysObj_bytesMethod(PikaObj *self, Args *args){ + Arg* val = args_getArg(args, "val"); + Arg* res = PikaStdLib_SysObj_bytes(self, val); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_SysObj_bytes, + "bytes", "val" +); + +void PikaStdLib_SysObj_cformatMethod(PikaObj *self, Args *args){ + char* fmt = args_getStr(args, "fmt"); + PikaTuple* var = args_getTuple(args, "var"); + char* res = PikaStdLib_SysObj_cformat(self, fmt, var); + method_returnStr(args, res); +} +method_typedef( + PikaStdLib_SysObj_cformat, + "cformat", "fmt,*var" +); + +void PikaStdLib_SysObj_chrMethod(PikaObj *self, Args *args){ + int val = args_getInt(args, "val"); + char* res = PikaStdLib_SysObj_chr(self, val); + method_returnStr(args, res); +} +method_typedef( + PikaStdLib_SysObj_chr, + "chr", "val" +); + +void PikaStdLib_SysObj_dictMethod(PikaObj *self, Args *args){ + PikaTuple* val = args_getTuple(args, "val"); + Arg* res = PikaStdLib_SysObj_dict(self, val); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_SysObj_dict, + "dict", "*val" +); + +void PikaStdLib_SysObj_dirMethod(PikaObj *self, Args *args){ + PikaObj* obj = args_getPtr(args, "obj"); + PikaObj* res = PikaStdLib_SysObj_dir(self, obj); + method_returnObj(args, res); +} +method_typedef( + PikaStdLib_SysObj_dir, + "dir", "obj" +); + +void PikaStdLib_SysObj_evalMethod(PikaObj *self, Args *args){ + char* code = args_getStr(args, "code"); + Arg* res = PikaStdLib_SysObj_eval(self, code); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_SysObj_eval, + "eval", "code" +); + +void PikaStdLib_SysObj_execMethod(PikaObj *self, Args *args){ + char* code = args_getStr(args, "code"); + PikaStdLib_SysObj_exec(self, code); +} +method_typedef( + PikaStdLib_SysObj_exec, + "exec", "code" +); + +void PikaStdLib_SysObj_exitMethod(PikaObj *self, Args *args){ + PikaStdLib_SysObj_exit(self); +} +method_typedef( + PikaStdLib_SysObj_exit, + "exit", "" +); + +void PikaStdLib_SysObj_floatMethod(PikaObj *self, Args *args){ + Arg* arg = args_getArg(args, "arg"); + pika_float res = PikaStdLib_SysObj_float(self, arg); + method_returnFloat(args, res); +} +method_typedef( + PikaStdLib_SysObj_float, + "float", "arg" +); + +void PikaStdLib_SysObj_getattrMethod(PikaObj *self, Args *args){ + PikaObj* obj = args_getPtr(args, "obj"); + char* name = args_getStr(args, "name"); + Arg* res = PikaStdLib_SysObj_getattr(self, obj, name); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_SysObj_getattr, + "getattr", "obj,name" +); + +void PikaStdLib_SysObj_hasattrMethod(PikaObj *self, Args *args){ + PikaObj* obj = args_getPtr(args, "obj"); + char* name = args_getStr(args, "name"); + int res = PikaStdLib_SysObj_hasattr(self, obj, name); + method_returnInt(args, res); +} +method_typedef( + PikaStdLib_SysObj_hasattr, + "hasattr", "obj,name" +); + +void PikaStdLib_SysObj_helpMethod(PikaObj *self, Args *args){ + char* name = args_getStr(args, "name"); + PikaStdLib_SysObj_help(self, name); +} +method_typedef( + PikaStdLib_SysObj_help, + "help", "name" +); + +void PikaStdLib_SysObj_hexMethod(PikaObj *self, Args *args){ + int val = args_getInt(args, "val"); + char* res = PikaStdLib_SysObj_hex(self, val); + method_returnStr(args, res); +} +method_typedef( + PikaStdLib_SysObj_hex, + "hex", "val" +); + +void PikaStdLib_SysObj_idMethod(PikaObj *self, Args *args){ + Arg* obj = args_getArg(args, "obj"); + int res = PikaStdLib_SysObj_id(self, obj); + method_returnInt(args, res); +} +method_typedef( + PikaStdLib_SysObj_id, + "id", "obj" +); + +void PikaStdLib_SysObj_inputMethod(PikaObj *self, Args *args){ + PikaTuple* info = args_getTuple(args, "info"); + char* res = PikaStdLib_SysObj_input(self, info); + method_returnStr(args, res); +} +method_typedef( + PikaStdLib_SysObj_input, + "input", "*info" +); + +void PikaStdLib_SysObj_intMethod(PikaObj *self, Args *args){ + Arg* arg = args_getArg(args, "arg"); + int res = PikaStdLib_SysObj_int(self, arg); + method_returnInt(args, res); +} +method_typedef( + PikaStdLib_SysObj_int, + "int", "arg" +); + +void PikaStdLib_SysObj_iterMethod(PikaObj *self, Args *args){ + Arg* arg = args_getArg(args, "arg"); + Arg* res = PikaStdLib_SysObj_iter(self, arg); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_SysObj_iter, + "iter", "arg" +); + +void PikaStdLib_SysObj_lenMethod(PikaObj *self, Args *args){ + Arg* arg = args_getArg(args, "arg"); + int res = PikaStdLib_SysObj_len(self, arg); + method_returnInt(args, res); +} +method_typedef( + PikaStdLib_SysObj_len, + "len", "arg" +); + +void PikaStdLib_SysObj_listMethod(PikaObj *self, Args *args){ + PikaTuple* val = args_getTuple(args, "val"); + Arg* res = PikaStdLib_SysObj_list(self, val); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_SysObj_list, + "list", "*val" +); + +void PikaStdLib_SysObj_openMethod(PikaObj *self, Args *args){ + char* path = args_getStr(args, "path"); + char* mode = args_getStr(args, "mode"); + PikaObj* res = PikaStdLib_SysObj_open(self, path, mode); + method_returnObj(args, res); +} +method_typedef( + PikaStdLib_SysObj_open, + "open", "path,mode" +); + +void PikaStdLib_SysObj_ordMethod(PikaObj *self, Args *args){ + char* val = args_getStr(args, "val"); + int res = PikaStdLib_SysObj_ord(self, val); + method_returnInt(args, res); +} +method_typedef( + PikaStdLib_SysObj_ord, + "ord", "val" +); + +void PikaStdLib_SysObj_printMethod(PikaObj *self, Args *args){ + PikaTuple* val = args_getTuple(args, "val"); + PikaDict* ops = args_getDict(args, "ops"); + PikaStdLib_SysObj_print(self, val, ops); +} +method_typedef( + PikaStdLib_SysObj_print, + "print", "*val,**ops" +); + +void PikaStdLib_SysObj_rangeMethod(PikaObj *self, Args *args){ + PikaTuple* ax = args_getTuple(args, "ax"); + Arg* res = PikaStdLib_SysObj_range(self, ax); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_SysObj_range, + "range", "*ax" +); + +void PikaStdLib_SysObj_setattrMethod(PikaObj *self, Args *args){ + PikaObj* obj = args_getPtr(args, "obj"); + char* name = args_getStr(args, "name"); + Arg* val = args_getArg(args, "val"); + PikaStdLib_SysObj_setattr(self, obj, name, val); +} +method_typedef( + PikaStdLib_SysObj_setattr, + "setattr", "obj,name,val" +); + +void PikaStdLib_SysObj_strMethod(PikaObj *self, Args *args){ + Arg* arg = args_getArg(args, "arg"); + char* res = PikaStdLib_SysObj_str(self, arg); + method_returnStr(args, res); +} +method_typedef( + PikaStdLib_SysObj_str, + "str", "arg" +); + +void PikaStdLib_SysObj_typeMethod(PikaObj *self, Args *args){ + Arg* arg = args_getArg(args, "arg"); + Arg* res = PikaStdLib_SysObj_type(self, arg); + method_returnArg(args, res); +} +method_typedef( + PikaStdLib_SysObj_type, + "type", "arg" +); + +class_def(PikaStdLib_SysObj){ + __BEFORE_MOETHOD_DEF +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_SysObj_id, 5863474), +#endif +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_SysObj_chr, 193488354), +#endif +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_SysObj_dir, 193489476), +#endif +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_SysObj_hex, 193493706), +#endif + method_def(PikaStdLib_SysObj_int, 193495088), + method_def(PikaStdLib_SysObj_len, 193498052), +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_SysObj_ord, 193501738), +#endif + method_def(PikaStdLib_SysObj_str, 193506174), +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_SysObj_setattr, 204224428), +#endif +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_SysObj_bytes, 254850636), +#endif + method_def(PikaStdLib_SysObj_float, 259121563), +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_SysObj_input, 262752949), +#endif + method_def(PikaStdLib_SysObj_print, 271190290), + method_def(PikaStdLib_SysObj_range, 272956402), +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_SysObj_hasattr, 872734812), +#endif +#if PIKA_SYNTAX_FORMAT_ENABLE + method_def(PikaStdLib_SysObj_cformat, 1049381873), +#endif + method_def(PikaStdLib_SysObj___setitem__, 1364865276), + method_def(PikaStdLib_SysObj___getitem__, 1535436016), +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_SysObj_getattr, 1886477984), +#endif +#if PIKA_BUILTIN_STRUCT_ENABLE + method_def(PikaStdLib_SysObj_dict, 2090185033), +#endif +#if PIKA_EXEC_ENABLE + method_def(PikaStdLib_SysObj_eval, 2090235053), +#endif +#if PIKA_EXEC_ENABLE + method_def(PikaStdLib_SysObj_exec, 2090237354), +#endif +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_SysObj_exit, 2090237503), +#endif +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_SysObj_help, 2090324718), +#endif + method_def(PikaStdLib_SysObj_iter, 2090376761), +#if PIKA_BUILTIN_STRUCT_ENABLE + method_def(PikaStdLib_SysObj_list, 2090473057), +#endif +#if PIKA_FILEIO_ENABLE + method_def(PikaStdLib_SysObj_open, 2090588023), +#endif +#if !PIKA_NANO_ENABLE + method_def(PikaStdLib_SysObj_type, 2090777863), +#endif +}; +class_inhert(PikaStdLib_SysObj, TinyObj); + +PikaObj *New_PikaStdLib_SysObj(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdLib_SysObj); + return self; +} + +Arg *PikaStdLib_SysObj(PikaObj *self){ + return obj_newObjInPackage(New_PikaStdLib_SysObj); +} +#endif + +#ifndef PIKA_MODULE_PIKASTDTASK_DISABLE +void PikaStdTask_TaskMethod(PikaObj *self, Args *args){ + Arg* res = PikaStdTask_Task(self); + method_returnArg(args, res); +} +method_typedef( + PikaStdTask_Task, + "Task", "" +); + +class_def(PikaStdTask){ + __BEFORE_MOETHOD_DEF + constructor_def(PikaStdTask_Task, 2089601848), +}; +class_inhert(PikaStdTask, TinyObj); + +PikaObj *New_PikaStdTask(Args *args){ + PikaObj *self = New_TinyObj(args); + obj_setClass(self, PikaStdTask); + return self; +} +#endif + +#ifndef PIKA_MODULE_PIKASTDTASK_DISABLE +void PikaStdTask_Task___init__Method(PikaObj *self, Args *args){ + PikaStdTask_Task___init__(self); +} +method_typedef( + PikaStdTask_Task___init__, + "__init__", "" +); + +void PikaStdTask_Task_call_alwaysMethod(PikaObj *self, Args *args){ + Arg* fun_todo = args_getArg(args, "fun_todo"); + PikaStdTask_Task_call_always(self, fun_todo); +} +method_typedef( + PikaStdTask_Task_call_always, + "call_always", "fun_todo" +); + +void PikaStdTask_Task_call_period_msMethod(PikaObj *self, Args *args){ + Arg* fun_todo = args_getArg(args, "fun_todo"); + int period_ms = args_getInt(args, "period_ms"); + PikaStdTask_Task_call_period_ms(self, fun_todo, period_ms); +} +method_typedef( + PikaStdTask_Task_call_period_ms, + "call_period_ms", "fun_todo,period_ms" +); + +void PikaStdTask_Task_call_whenMethod(PikaObj *self, Args *args){ + Arg* fun_todo = args_getArg(args, "fun_todo"); + Arg* fun_when = args_getArg(args, "fun_when"); + PikaStdTask_Task_call_when(self, fun_todo, fun_when); +} +method_typedef( + PikaStdTask_Task_call_when, + "call_when", "fun_todo,fun_when" +); + +void PikaStdTask_Task_platformGetTickMethod(PikaObj *self, Args *args){ + PikaStdTask_Task_platformGetTick(self); +} +method_typedef( + PikaStdTask_Task_platformGetTick, + "platformGetTick", "" +); + +void PikaStdTask_Task_run_foreverMethod(PikaObj *self, Args *args){ + PikaStdTask_Task_run_forever(self); +} +method_typedef( + PikaStdTask_Task_run_forever, + "run_forever", "" +); + +void PikaStdTask_Task_run_onceMethod(PikaObj *self, Args *args){ + PikaStdTask_Task_run_once(self); +} +method_typedef( + PikaStdTask_Task_run_once, + "run_once", "" +); + +void PikaStdTask_Task_run_until_msMethod(PikaObj *self, Args *args){ + int until_ms = args_getInt(args, "until_ms"); + PikaStdTask_Task_run_until_ms(self, until_ms); +} +method_typedef( + PikaStdTask_Task_run_until_ms, + "run_until_ms", "until_ms" +); + +class_def(PikaStdTask_Task){ + __BEFORE_MOETHOD_DEF + method_def(PikaStdTask_Task_run_forever, 408322738), + method_def(PikaStdTask_Task_run_until_ms, 854930212), + method_def(PikaStdTask_Task___init__, 904762485), + method_def(PikaStdTask_Task_call_always, 1368427953), + method_def(PikaStdTask_Task_call_period_ms, 1674236450), + method_def(PikaStdTask_Task_run_once, 1726949022), + method_def(PikaStdTask_Task_platformGetTick, 1897947957), + method_def(PikaStdTask_Task_call_when, 2141638002), +}; +class_inhert(PikaStdTask_Task, PikaStdLib_SysObj); + +PikaObj *New_PikaStdTask_Task(Args *args){ + PikaObj *self = New_PikaStdLib_SysObj(args); + obj_newObj(self, "calls", "PikaStdData_List", New_PikaStdData_List); + obj_setClass(self, PikaStdTask_Task); + return self; +} + +Arg *PikaStdTask_Task(PikaObj *self){ + return obj_newObjInPackage(New_PikaStdTask_Task); +} +#endif + diff --git a/examples/pikapython/pikapython/pikascript-api/main.py.o b/examples/pikapython/pikapython/pikascript-api/main.py.o new file mode 100644 index 00000000..fb89147f Binary files /dev/null and b/examples/pikapython/pikapython/pikascript-api/main.py.o differ diff --git a/examples/pikapython/pikapython/pikascript-api/pikaModules.py.a b/examples/pikapython/pikapython/pikascript-api/pikaModules.py.a new file mode 100644 index 00000000..2f7f6a2f Binary files /dev/null and b/examples/pikapython/pikapython/pikascript-api/pikaModules.py.a differ diff --git a/examples/pikapython/pikapython/pikascript-api/pikaScript.c b/examples/pikapython/pikapython/pikascript-api/pikaScript.c new file mode 100644 index 00000000..ab85744c --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/pikaScript.c @@ -0,0 +1,35 @@ +/* + * [Warning!] This file is auto-generated by pika compiler. + * Do not edit it manually. + * The source code is *.pyi file. + * More details: + * English Doc: + * https://pikadoc.readthedocs.io/en/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + * Chinese Doc: + * https://pikadoc.readthedocs.io/zh/latest/PikaScript%20%E6%A8%A1%E5%9D%97%E6%A6%82%E8%BF%B0.html + */ + +#include "PikaMain.h" +#include +#include + +volatile PikaObj *__pikaMain; +PikaObj *pikaScriptInit(void){ + __platform_printf("======[pikascript packages installed]======\r\n"); + pks_printVersion(); + __platform_printf("PikaStdLib==v1.12.0\r\n"); + __platform_printf("===========================================\r\n"); + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + __pikaMain = pikaMain; + extern unsigned char pikaModules_py_a[]; + obj_linkLibrary(pikaMain, pikaModules_py_a); +#if PIKA_INIT_STRING_ENABLE + obj_run(pikaMain, + "print('hello PikaPython!')\n" + "\n"); +#else + obj_runModule((PikaObj*)pikaMain, "main"); +#endif + return pikaMain; +} + diff --git a/examples/pikapython/pikapython/pikascript-api/pikaScript.h b/examples/pikapython/pikapython/pikascript-api/pikaScript.h new file mode 100644 index 00000000..3b5c169f --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-api/pikaScript.h @@ -0,0 +1,13 @@ +/* ******************************** */ +/* Warning! Don't modify this file! */ +/* ******************************** */ +#ifndef __pikaScript__H +#define __pikaScript__H +#include +#include +#include "PikaObj.h" +#include "PikaMain.h" + +PikaObj * pikaScriptInit(void); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/BaseObj.c b/examples/pikapython/pikapython/pikascript-core/BaseObj.c new file mode 100644 index 00000000..bf47a06c --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/BaseObj.c @@ -0,0 +1,43 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "BaseObj.h" +#include "PikaObj.h" +#include "TinyObj.h" +#include "dataMemory.h" +#include "dataString.h" +#include "dataStrs.h" + +extern const NativeProperty TinyObjNativeProp; +const NativeProperty BaseObjNativeProp = {.super = &TinyObjNativeProp, + .methodGroup = NULL, + .methodGroupCount = 0}; + +PikaObj* New_BaseObj(Args* args) { + PikaObj* self = New_TinyObj(args); + return self; +} diff --git a/examples/pikapython/pikapython/pikascript-core/BaseObj.h b/examples/pikapython/pikapython/pikascript-core/BaseObj.h new file mode 100644 index 00000000..dd954df4 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/BaseObj.h @@ -0,0 +1,38 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _PikaObj_baseObj__H +#define _PikaObj_baseObj__H +#include "PikaObj.h" +#include "PikaVM.h" +#include "TinyObj.h" +#include "dataMemory.h" + +PikaObj* New_BaseObj(Args* args); +void Baseobj_print(PikaObj* self, Args* args); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/CMakeLists.txt b/examples/pikapython/pikapython/pikascript-core/CMakeLists.txt new file mode 100644 index 00000000..287833f3 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/CMakeLists.txt @@ -0,0 +1,9 @@ +#设置 BINARY 为项目名IndexProject +set(BINARY ${CMAKE_PROJECT_NAME}) + +file(GLOB_RECURSE SOURCES LIST_DIRECTORIES true *.h *.c) +set(SOURCES ${SOURCES}) + +add_library(${BINARY}-core + STATIC + ${SOURCES}) diff --git a/examples/pikapython/pikapython/pikascript-core/PikaCompiler.c b/examples/pikapython/pikapython/pikascript-core/PikaCompiler.c new file mode 100644 index 00000000..212687fb --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/PikaCompiler.c @@ -0,0 +1,840 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "PikaCompiler.h" +#include "BaseObj.h" +#include "PikaObj.h" +#include "PikaParser.h" +#include "dataQueue.h" +#include "dataQueueObj.h" +#include "dataStack.h" +#include "dataStrs.h" + +const char magic_code_pyo[] = {0x0f, 'p', 'y', 'o'}; + +static PIKA_BOOL _check_magic_code_pyo(uint8_t* bytecode) { + char* data = (char*)bytecode; + if (data[0] == magic_code_pyo[0] && data[1] == magic_code_pyo[1] && + data[2] == magic_code_pyo[2] && data[3] == magic_code_pyo[3]) { + return PIKA_TRUE; + } + return PIKA_FALSE; +} + +static uint8_t* arg_getBytecode(Arg* self) { + uint8_t* bytecode_file = arg_getBytes(self); + if (_check_magic_code_pyo(bytecode_file)) { + return bytecode_file + sizeof(magic_code_pyo) + sizeof(uint32_t); + } + return bytecode_file; +} + +static size_t arg_getBytecodeSize(Arg* self) { + size_t size_all = arg_getBytesSize(self); + uint8_t* bytecode_file = arg_getBytes(self); + if (_check_magic_code_pyo(bytecode_file)) { + return size_all - sizeof(magic_code_pyo) - sizeof(uint32_t); + } + return size_all; +} + +/* const Pool output redirect */ +static void __handler_constPool_output_file(ConstPool* self, char* content) { + /* to ram */ + uint16_t size = strGetSize(content) + 1; + self->arg_buff = arg_append(self->arg_buff, content, size); + /* to flash */ + pika_platform_fwrite(content, 1, size, self->output_f); +} + +/* instruct array output redirect */ +static void __handler_instructArray_output_none(InstructArray* self, + InstructUnit* ins_unit) { + /* none */ +} + +static void __handler_instructArray_output_file(InstructArray* self, + InstructUnit* ins_unit) { + /* to flash */ + pika_platform_fwrite(ins_unit, 1, instructUnit_getSize(), self->output_f); +} + +/* + need implament : + pika_platform_fopen() + pika_platform_fwrite() + pika_platform_fclose() +*/ + +PIKA_RES pikaCompile(char* output_file_name, char* py_lines) { + PIKA_RES res = PIKA_RES_OK; + ByteCodeFrame bytecode_frame = {0}; + uint32_t const_pool_size = 0; + uint32_t instruct_array_size = 0; + uint32_t bytecode_size = 0; + char void_ = 0; + FILE* bytecode_f = pika_platform_fopen(output_file_name, "wb+"); + if (NULL == bytecode_f) { + pika_platform_printf("Error: open file %s failed.\r\n", output_file_name); + res = PIKA_RES_ERR_IO_ERROR; + goto exit; + } + /* main process */ + + /* step 1, get size of const pool and instruct array */ + byteCodeFrame_init(&bytecode_frame); + bytecode_frame.const_pool.output_f = bytecode_f; + bytecode_frame.instruct_array.output_f = bytecode_f; + bytecode_frame.instruct_array.output_redirect_fun = + __handler_instructArray_output_none; + res = Parser_linesToBytes(&bytecode_frame, py_lines); + if (PIKA_RES_OK != res) { + pika_platform_printf(" Error: Syntax error.\r\n"); + goto exit; + } + const_pool_size = bytecode_frame.const_pool.size; + instruct_array_size = bytecode_frame.instruct_array.size; + bytecode_size = const_pool_size + instruct_array_size + + sizeof(const_pool_size) + + sizeof(instruct_array_size); + byteCodeFrame_deinit(&bytecode_frame); + + /* step 2, write instruct array to file */ + /* write magic code */ + pika_platform_fwrite(magic_code_pyo, 1, sizeof(magic_code_pyo), bytecode_f); + /* write bytecode size */ + pika_platform_fwrite(&bytecode_size, 1, sizeof(bytecode_size), bytecode_f); + /* write ins array size */ + pika_platform_fwrite(&instruct_array_size, 1, sizeof(instruct_array_size), + bytecode_f); + byteCodeFrame_init(&bytecode_frame); + bytecode_frame.const_pool.output_f = bytecode_f; + bytecode_frame.instruct_array.output_f = bytecode_f; + /* instruct array to file */ + bytecode_frame.instruct_array.output_redirect_fun = + __handler_instructArray_output_file; + Parser_linesToBytes(&bytecode_frame, py_lines); + byteCodeFrame_deinit(&bytecode_frame); + + /* step 3, write const pool to file */ + pika_platform_fwrite(&const_pool_size, 1, sizeof(const_pool_size), bytecode_f); + void_ = 0; + /* add \0 at the start */ + pika_platform_fwrite(&void_, 1, 1, bytecode_f); + byteCodeFrame_init(&bytecode_frame); + bytecode_frame.const_pool.output_f = bytecode_f; + bytecode_frame.instruct_array.output_f = bytecode_f; + /* const pool to file */ + bytecode_frame.const_pool.output_redirect_fun = + __handler_constPool_output_file; + /* instruct array to none */ + bytecode_frame.instruct_array.output_redirect_fun = + __handler_instructArray_output_none; + Parser_linesToBytes(&bytecode_frame, py_lines); + + /* deinit */ +exit: + byteCodeFrame_deinit(&bytecode_frame); + if (NULL != bytecode_f) { + pika_platform_fclose(bytecode_f); + } + /* succeed */ + return res; +}; + +/* + need implament : + pika_platform_fopen() + pika_platform_fread() + pika_platform_fwrite() + pika_platform_fclose() +*/ +PIKA_RES pikaCompileFileWithOutputName(char* output_file_name, + char* input_file_name) { + Args buffs = {0}; + Arg* input_file_arg = arg_loadFile(NULL, input_file_name); + if (NULL == input_file_arg) { + return PIKA_RES_ERR_IO_ERROR; + } + char* lines = (char*)arg_getBytes(input_file_arg); + /* replace the "\r\n" to "\n" */ + lines = strsReplace(&buffs, lines, "\r\n", "\n"); + /* clear the void line */ + lines = strsReplace(&buffs, lines, "\n\n", "\n"); + /* add '\n' at the end */ + lines = strsAppend(&buffs, lines, "\n\n"); + PIKA_RES res = pikaCompile(output_file_name, lines); + arg_deinit(input_file_arg); + strsDeinit(&buffs); + return res; +} + +PIKA_RES pikaCompileFile(char* input_file_name) { + Args buffs = {0}; + char* output_file_name = strsGetFirstToken(&buffs, input_file_name, '.'); + output_file_name = strsAppend(&buffs, input_file_name, ".o"); + PIKA_RES res = + pikaCompileFileWithOutputName(output_file_name, input_file_name); + strsDeinit(&buffs); + return res; +} + +LibObj* New_LibObj(Args* args) { + LibObj* self = New_TinyObj(NULL); + return self; +} + +void LibObj_deinit(LibObj* self) { + obj_deinit(self); +} + +/* add bytecode to lib, not copy the bytecode */ +void LibObj_dynamicLink(LibObj* self, char* module_name, uint8_t* bytecode) { + if (strIsContain(module_name, '.')) { + /* skip file */ + return; + } + if (!obj_isArgExist(self, module_name)) { + obj_newObj(self, module_name, "", New_TinyObj); + } + PikaObj* module_obj = obj_getObj(self, module_name); + obj_setStr(module_obj, "name", module_name); + obj_setPtr(module_obj, "bytecode", bytecode); +} + +/* add bytecode to lib, and copy the bytecode to the buff in the lib */ +int LibObj_staticLink(LibObj* self, + char* module_name, + uint8_t* bytecode, + size_t size) { + if (!obj_isArgExist(self, module_name)) { + obj_newObj(self, module_name, "", New_TinyObj); + } + PikaObj* module_obj = obj_getObj(self, module_name); + /* copy bytecode to buff */ + obj_setBytes(module_obj, "buff", bytecode, size); + /* link to buff */ + LibObj_dynamicLink(self, module_name, obj_getBytes(module_obj, "buff")); + return 0; +} + +int LibObj_staticLinkFile(LibObj* self, char* input_file_name) { + Args buffs = {0}; + /* read file */ + Arg* input_file_arg = arg_loadFile(NULL, input_file_name); + if (NULL == input_file_arg) { + pika_platform_printf("error: can't open file %s\r\n", input_file_name); + return -1; + } + char* module_name = strsGetLastToken(&buffs, input_file_name, '/'); + + size_t module_name_len = strlen(module_name); + + /* cut off '.py.o' */ + if (module_name[module_name_len - 1] == 'o' && + module_name[module_name_len - 2] == '.' && + module_name[module_name_len - 3] == 'y' && + module_name[module_name_len - 4] == 'p' && + module_name[module_name_len - 5] == '.') { + module_name[module_name_len - 5] = 0; + } else { + // pika_platform_printf("linking raw %s:%s:%ld\r\n", input_file_name, + // module_name, arg_getBytecodeSize(input_file_arg)); + /* replace . to | */ + module_name = strsReplace(&buffs, module_name, ".", "|"); + } + + /* push bytecode */ + LibObj_staticLink(self, module_name, arg_getBytecode(input_file_arg), + arg_getBytecodeSize(input_file_arg)); + + /* deinit */ + strsDeinit(&buffs); + arg_deinit(input_file_arg); + return 0; +} + +static int32_t __foreach_handler_listModules(Arg* argEach, Args* context) { + if (argType_isObject(arg_getType(argEach))) { + PikaObj* module_obj = arg_getPtr(argEach); + pika_platform_printf("%s\r\n", obj_getStr(module_obj, "name")); + } + return 0; +} + +void LibObj_listModules(LibObj* self) { + args_foreach(self->list, __foreach_handler_listModules, NULL); +} + +static int32_t __foreach_handler_libWriteBytecode(Arg* argEach, Args* context) { + FILE* out_file = args_getPtr(context, "out_file"); + if (argType_isObject(arg_getType(argEach))) { + PikaObj* module_obj = arg_getPtr(argEach); + char* bytecode = obj_getPtr(module_obj, "bytecode"); + size_t bytecode_size = obj_getBytesSize(module_obj, "buff"); + size_t aline_size = + aline_by(bytecode_size, sizeof(uint32_t)) - bytecode_size; + char aline_buff[sizeof(uint32_t)] = {0}; + pika_platform_fwrite(bytecode, 1, bytecode_size, out_file); + pika_platform_fwrite(aline_buff, 1, aline_size, out_file); + } + return 0; +} + +static int32_t __foreach_handler_libWriteIndex(Arg* argEach, Args* context) { + FILE* out_file = args_getPtr(context, "out_file"); + Args buffs = {0}; + if (argType_isObject(arg_getType(argEach))) { + PikaObj* module_obj = arg_getPtr(argEach); + uint32_t bytecode_size = obj_getBytesSize(module_obj, "buff"); + char buff[LIB_INFO_BLOCK_SIZE - sizeof(uint32_t)] = {0}; + bytecode_size = aline_by(bytecode_size, sizeof(uint32_t)); + char* module_name = obj_getStr(module_obj, "name"); + module_name = strsReplace(&buffs, module_name, "|", "."); + // pika_platform_printf(" %s:%d\r\n", module_name, bytecode_size); + pika_platform_memcpy(buff, module_name, strGetSize(module_name)); + pika_platform_fwrite(buff, 1, LIB_INFO_BLOCK_SIZE - sizeof(bytecode_size), + out_file); + pika_platform_fwrite(&bytecode_size, 1, sizeof(bytecode_size), out_file); + } + strsDeinit(&buffs); + return 0; +} + +static int32_t __foreach_handler_getModuleNum(Arg* argEach, Args* context) { + if (argType_isObject(arg_getType(argEach))) { + args_setInt(context, "module_num", + args_getInt(context, "module_num") + 1); + } + return 0; +} + +int LibObj_saveLibraryFile(LibObj* self, char* output_file_name) { + FILE* out_file = pika_platform_fopen(output_file_name, "wb+"); + + Args context = {0}; + args_setPtr(&context, "out_file", out_file); + args_setInt(&context, "module_num", 0); + + /* write meta information */ + char buff[LIB_INFO_BLOCK_SIZE] = {0}; + args_foreach(self->list, __foreach_handler_getModuleNum, &context); + + /* meta info */ + char magic_code[] = {0x7f, 'p', 'y', 'a'}; + uint32_t version_num = LIB_VERSION_NUMBER; + uint32_t module_num = args_getInt(&context, "module_num"); + + /* write meta info */ + const uint32_t magic_code_offset = sizeof(uint32_t) * 0; + const uint32_t version_offset = sizeof(uint32_t) * 1; + const uint32_t module_num_offset = sizeof(uint32_t) * 2; + + pika_platform_memcpy(buff + magic_code_offset, &magic_code, sizeof(uint32_t)); + pika_platform_memcpy(buff + version_offset, &version_num, sizeof(uint32_t)); + /* write module_num to the file */ + pika_platform_memcpy(buff + module_num_offset, &module_num, sizeof(uint32_t)); + /* aline to 32 bytes */ + pika_platform_fwrite(buff, 1, LIB_INFO_BLOCK_SIZE, out_file); + /* write module index to file */ + args_foreach(self->list, __foreach_handler_libWriteIndex, &context); + /* write module bytecode to file */ + args_foreach(self->list, __foreach_handler_libWriteBytecode, &context); + args_deinit_stack(&context); + /* main process */ + /* deinit */ + pika_platform_fclose(out_file); + return 0; +} + +static int _getModuleNum(uint8_t* library_bytes) { + if (0 != ((intptr_t)library_bytes & 0x03)) { + return PIKA_RES_ERR_UNALIGNED_PTR; + } + + char* magic_code = (char*)library_bytes; + + uint32_t* library_info = (uint32_t*)library_bytes; + uint32_t version_num = library_info[1]; + uint32_t module_num = library_info[2]; + + /* check magic_code */ + if (!((magic_code[0] == 0x7f) && (magic_code[1] == 'p') && + (magic_code[2] == 'y') && (magic_code[3] == 'a'))) { + pika_platform_printf("Error: invalid magic code.\r\n"); + return PIKA_RES_ERR_ILLEGAL_MAGIC_CODE; + } + /* check version num */ + if (version_num != LIB_VERSION_NUMBER) { + pika_platform_printf( + "Error: invalid version number. Expected %d, got %d\r\n", + LIB_VERSION_NUMBER, version_num); + return PIKA_RES_ERR_INVALID_VERSION_NUMBER; + } + return module_num; +} + +static PIKA_RES _loadModuleDataWithIndex(uint8_t* library_bytes, + int module_num, + int module_index, + char** name_p, + uint8_t** addr_p, + size_t* size) { + uint8_t* bytecode_addr = + library_bytes + LIB_INFO_BLOCK_SIZE * (module_num + 1); + for (uint32_t i = 0; i < module_index + 1; i++) { + char* module_name = + (char*)(library_bytes + LIB_INFO_BLOCK_SIZE * (i + 1)); + // pika_platform_printf("loading module: %s\r\n", module_name); + *name_p = module_name; + *addr_p = bytecode_addr; + size_t module_size = + *(uint32_t*)(module_name + LIB_INFO_BLOCK_SIZE - sizeof(uint32_t)); + *size = module_size; + bytecode_addr += module_size; + } + return PIKA_RES_OK; +} + +PIKA_RES _loadModuleDataWithName(uint8_t* library_bytes, + char* module_name, + uint8_t** addr_p, + size_t* size_p) { + int module_num = _getModuleNum(library_bytes); + if (module_num < 0) { + return (PIKA_RES)module_num; + } + for (int i = 0; i < module_num; i++) { + char* name = NULL; + uint8_t* addr = NULL; + size_t size = 0; + _loadModuleDataWithIndex(library_bytes, module_num, i, &name, &addr, + &size); + if (strEqu(module_name, name)) { + *addr_p = addr; + *size_p = size; + return PIKA_RES_OK; + } + } + return PIKA_RES_ERR_ARG_NO_FOUND; +} + +int LibObj_loadLibrary(LibObj* self, uint8_t* library_bytes) { + int module_num = _getModuleNum(library_bytes); + if (module_num < 0) { + /* load error */ + return module_num; + } + for (uint32_t i = 0; i < module_num; i++) { + char* module_name = NULL; + uint8_t* bytecode_addr = NULL; + size_t bytecode_size = 0; + _loadModuleDataWithIndex(library_bytes, module_num, i, &module_name, + &bytecode_addr, &bytecode_size); + LibObj_dynamicLink(self, module_name, bytecode_addr); + } + return PIKA_RES_OK; +} + +int32_t __foreach_handler_printModule(Arg* argEach, Args* context) { + if (argType_isObject(arg_getType(argEach))) { + PikaObj* module_obj = arg_getPtr(argEach); + char* module_name = obj_getStr(module_obj, "name"); + if (NULL != module_name) { + pika_platform_printf(module_name); + pika_platform_printf("\r\n"); + } + } + return 0; +} + +void LibObj_printModules(LibObj* self) { + args_foreach(self->list, __foreach_handler_printModule, NULL); +} + +int LibObj_loadLibraryFile(LibObj* self, char* lib_file_name) { + Arg* file_arg = arg_loadFile(NULL, lib_file_name); + if (NULL == file_arg) { + pika_platform_printf("Error: Could not load library file '%s'\n", + lib_file_name); + return PIKA_RES_ERR_IO_ERROR; + } + /* save file_arg as @lib_buf to libObj */ + obj_setArg_noCopy(self, "@lib_buf", file_arg); + if (0 != LibObj_loadLibrary(self, arg_getBytes(file_arg))) { + pika_platform_printf("Error: Could not load library from '%s'\n", + lib_file_name); + return PIKA_RES_ERR_OPERATION_FAILED; + } + return PIKA_RES_OK; +} + +size_t pika_fputs(char* str, FILE* fp) { + size_t size = strGetSize(str); + return pika_platform_fwrite(str, 1, size, fp); +} + +int Lib_loadLibraryFileToArray(char* origin_file_name, char* out_folder) { + Args buffs = {0}; + Arg* file_arg = arg_loadFile(NULL, origin_file_name); + int res = 0; + if (NULL == file_arg) { + pika_platform_printf("Error: Could not load file '%s'\n", + origin_file_name); + return 1; + } + char* output_file_name = NULL; + output_file_name = strsGetLastToken(&buffs, origin_file_name, '/'); + output_file_name = strsAppend(&buffs, "__asset_", output_file_name); + output_file_name = strsReplace(&buffs, output_file_name, ".", "_"); + output_file_name = strsAppend(&buffs, output_file_name, ".c"); + + char* output_file_path = strsAppend(&buffs, out_folder, "/"); + output_file_path = strsAppend(&buffs, output_file_path, output_file_name); + + FILE* fp = pika_platform_fopen(output_file_path, "wb+"); + char* array_name = strsGetLastToken(&buffs, origin_file_name, '/'); + array_name = strsReplace(&buffs, array_name, ".", "_"); + pika_platform_printf(" loading %s[]...\n", array_name); + pika_fputs("#include \"PikaPlatform.h\"\n", fp); + pika_fputs("/* warning: auto generated file, please do not modify */\n", + fp); + pika_fputs("PIKA_BYTECODE_ALIGN const unsigned char ", fp); + pika_fputs(array_name, fp); + pika_fputs("[] = {", fp); + char byte_buff[32] = {0}; + uint8_t* array = arg_getBytes(file_arg); + for (size_t i = 0; i < arg_getBytesSize(file_arg); i++) { + if (i % 12 == 0) { + pika_fputs("\n ", fp); + } + pika_platform_sprintf(byte_buff, "0x%02x, ", array[i]); + pika_fputs(byte_buff, fp); + } + + pika_fputs("\n};\n", fp); + res = 0; + goto exit; + +exit: + pika_platform_fclose(fp); + strsDeinit(&buffs); + arg_deinit(file_arg); + return res; +} + +static PIKA_RES __Maker_compileModuleWithInfo(PikaMaker* self, + char* module_name) { + Args buffs = {0}; + char* input_file_name = strsAppend(&buffs, module_name, ".py"); + char* input_file_path = + strsAppend(&buffs, obj_getStr(self, "pwd"), input_file_name); + pika_platform_printf(" compiling %s...\r\n", input_file_name); + char* output_file_name = strsAppend(&buffs, module_name, ".py.o"); + char* output_file_path = NULL; + output_file_path = + strsAppend(&buffs, obj_getStr(self, "pwd"), "pikascript-api/"); + output_file_path = strsAppend(&buffs, output_file_path, output_file_name); + PIKA_RES res = + pikaCompileFileWithOutputName(output_file_path, input_file_path); + strsDeinit(&buffs); + return res; +} + +PikaMaker* New_PikaMaker(void) { + PikaMaker* self = New_TinyObj(NULL); + obj_setStr(self, "pwd", ""); + obj_setInt(self, "err", 0); + LibObj* lib = New_LibObj(NULL); + obj_setPtr(self, "lib", lib); + return self; +} + +void pikaMaker_deinit(PikaMaker* self) { + LibObj* lib = obj_getPtr(self, "lib"); + LibObj_deinit(lib); + obj_deinit(self); +} + +void pikaMaker_setPWD(PikaMaker* self, char* pwd) { + obj_setStr(self, "pwd", pwd); +} + +void pikaMaker_setState(PikaMaker* self, char* module_name, char* state) { + obj_newMetaObj(self, module_name, New_TinyObj); + PikaObj* module_obj = obj_getObj(self, module_name); + obj_setStr(module_obj, "name", module_name); + obj_setStr(module_obj, "state", state); +} + +PIKA_RES pikaMaker_compileModule(PikaMaker* self, char* module_name) { + PIKA_RES res = __Maker_compileModuleWithInfo(self, module_name); + /* update compile info */ + if (PIKA_RES_OK == res) { + pikaMaker_setState(self, module_name, "compiled"); + } else { + pikaMaker_setState(self, module_name, "failed"); + } + return res; +} + +int pikaMaker_getDependencies(PikaMaker* self, char* module_name) { + int res = 0; + ByteCodeFrame bf = {0}; + Args buffs = {0}; + byteCodeFrame_init(&bf); + ConstPool* const_pool = NULL; + InstructArray* ins_array = NULL; + char* module_path = + strsAppend(&buffs, obj_getStr(self, "pwd"), "pikascript-api/"); + module_path = strsAppend(&buffs, module_path, module_name); + char* file_path = strsAppend(&buffs, module_path, ".py.o"); + Arg* file_arg = arg_loadFile(NULL, file_path); + uint8_t offset_befor = 0; + if (NULL == file_arg) { + res = 1; + goto exit; + } + byteCodeFrame_loadByteCode(&bf, arg_getBytes(file_arg)); + const_pool = &bf.const_pool; + ins_array = &bf.instruct_array; + + offset_befor = ins_array->content_offset_now; + ins_array->content_offset_now = 0; + while (1) { + InstructUnit* ins_unit = instructArray_getNow(ins_array); + if (NULL == ins_unit) { + goto exit; + } + if (instructUnit_getInstruct(ins_unit) == IMP) { + char* imp_module_name = + constPool_getByOffset(const_pool, ins_unit->const_pool_index); + char* imp_module_path = + strsAppend(&buffs, obj_getStr(self, "pwd"), imp_module_name); + /* check if compiled the module */ + if (obj_isArgExist(self, imp_module_name)) { + /* module info is exist, do nothing */ + } else { + /* module info is not exist */ + /* set module to be compile */ + FILE* imp_file_py = pika_platform_fopen( + strsAppend(&buffs, imp_module_path, ".py"), "rb"); + FILE* imp_file_pyi = pika_platform_fopen( + strsAppend(&buffs, imp_module_path, ".pyi"), "rb"); + FILE* imp_file_pyo = pika_platform_fopen( + strsAppend(&buffs, imp_module_path, ".py.o"), "rb"); + if (NULL != imp_file_pyo) { + pika_platform_printf(" loading %s.py.o...\r\n", + imp_module_path); + /* found *.py.o, push to compiled list */ + pikaMaker_setState(self, imp_module_name, "compiled"); + char* imp_api_path = strsAppend( + &buffs, obj_getStr(self, "pwd"), "pikascript-api/"); + imp_api_path = + strsAppend(&buffs, imp_api_path, imp_module_name); + FILE* imp_file_pyo_api = pika_platform_fopen( + strsAppend(&buffs, imp_api_path, ".py.o"), "wb+"); + /* copy imp_file_pyo to imp_api_path */ + uint8_t* buff = (uint8_t*)pika_platform_malloc(128); + size_t read_size = 0; + while (1) { + read_size = + pika_platform_fread(buff, 1, 128, imp_file_pyo); + if (read_size > 0) { + pika_platform_fwrite(buff, 1, read_size, + imp_file_pyo_api); + } else { + break; + } + } + pika_platform_free(buff); + pika_platform_fclose(imp_file_pyo_api); + } else if (NULL != imp_file_py) { + /* found *.py, push to nocompiled list */ + pikaMaker_setState(self, imp_module_name, "nocompiled"); + } else if (NULL != imp_file_pyi) { + /* found *.py, push to nocompiled list */ + pikaMaker_setState(self, imp_module_name, "cmodule"); + } else { + pika_platform_printf( + " [warning]: file: '%s.pyi', '%s.py' or '%s.py.o' " + "no found\n", + imp_module_name, imp_module_name, imp_module_name); + } + if (NULL != imp_file_pyo) { + pika_platform_fclose(imp_file_pyo); + } + if (NULL != imp_file_pyi) { + pika_platform_fclose(imp_file_pyi); + } + if (NULL != imp_file_py) { + pika_platform_fclose(imp_file_py); + } + } + } + instructArray_getNext(ins_array); + } + +exit: + ins_array->content_offset_now = offset_befor; + if (NULL != file_arg) { + arg_deinit(file_arg); + } + strsDeinit(&buffs); + byteCodeFrame_deinit(&bf); + return res; +} + +int32_t __foreach_handler_printStates(Arg* argEach, Args* context) { + if (argType_isObject(arg_getType(argEach))) { + PikaObj* module_obj = arg_getPtr(argEach); + pika_platform_printf("%s: %s\r\n", obj_getStr(module_obj, "name"), + obj_getStr(module_obj, "state")); + } + return 0; +} + +void pikaMaker_printStates(PikaMaker* self) { + args_foreach(self->list, __foreach_handler_printStates, NULL); +} + +int32_t __foreach_handler_getFirstNocompiled(Arg* argEach, Args* context) { + if (argType_isObject(arg_getType(argEach))) { + PikaObj* module_obj = arg_getPtr(argEach); + char* state = obj_getStr(module_obj, "state"); + if (args_isArgExist(context, "res")) { + /* already get method */ + return 0; + } + if (strEqu("nocompiled", state)) { + /* push module */ + args_setStr(context, "res", obj_getStr(module_obj, "name")); + return 0; + } + } + return 0; +} + +char* pikaMaker_getFirstNocompiled(PikaMaker* self) { + Args context = {0}; + args_foreach(self->list, __foreach_handler_getFirstNocompiled, &context); + char* res = args_getStr(&context, "res"); + if (NULL == res) { + /* remove res in maker */ + obj_removeArg(self, "res"); + } else { + obj_setStr(self, "res", res); + } + args_deinit_stack(&context); + return obj_getStr(self, "res"); +} + +PIKA_RES pikaMaker_compileModuleWithDepends(PikaMaker* self, + char* module_name) { + PIKA_RES res = PIKA_RES_OK; + res = pikaMaker_compileModule(self, module_name); + if (PIKA_RES_OK != res) { + obj_setInt(self, "err", res); + return res; + } + pikaMaker_getDependencies(self, module_name); + while (1) { + char* uncompiled = pikaMaker_getFirstNocompiled(self); + /* compiled all modules */ + if (NULL == uncompiled) { + break; + } + res = pikaMaker_compileModule(self, uncompiled); + if (PIKA_RES_OK != res) { + obj_setInt(self, "err", res); + return res; + } + pikaMaker_getDependencies(self, uncompiled); + } + return PIKA_RES_OK; +} + +int32_t __foreach_handler_linkCompiledModules(Arg* argEach, Args* context) { + Args buffs = {0}; + if (argType_isObject(arg_getType(argEach))) { + LibObj* lib = args_getPtr(context, "@lib"); + PikaMaker* maker = args_getPtr(context, "__maker"); + PikaObj* module_obj = arg_getPtr(argEach); + char* module_name = obj_getStr(module_obj, "name"); + char* state = obj_getStr(module_obj, "state"); + if (strEqu(state, "compiled")) { + char* pwd = obj_getStr(maker, "pwd"); + char* folder_path = strsAppend(&buffs, pwd, "pikascript-api/"); + char* module_file_name = strsAppend(&buffs, module_name, ".py.o"); + char* module_file_path = + strsAppend(&buffs, folder_path, module_file_name); + LibObj_staticLinkFile(lib, module_file_path); + } + } + strsDeinit(&buffs); + return 0; +} + +PIKA_RES pikaMaker_linkCompiledModulesFullPath(PikaMaker* self, + char* lib_path) { + PIKA_RES compile_err = (PIKA_RES)obj_getInt(self, "err"); + if (PIKA_RES_OK != compile_err) { + pika_platform_printf(" Error: compile failed, link aborted.\r\n"); + return compile_err; + } + Args context = {0}; + Args buffs = {0}; + pika_platform_printf(" linking %s...\n", lib_path); + LibObj* lib = obj_getPtr(self, "lib"); + args_setPtr(&context, "@lib", lib); + args_setPtr(&context, "__maker", self); + args_foreach(self->list, __foreach_handler_linkCompiledModules, &context); + args_deinit_stack(&context); + char* pwd = obj_getStr(self, "pwd"); + char* lib_path_folder = strsCopy(&buffs, lib_path); + strPopLastToken(lib_path_folder, '/'); + char* folder_path = strsAppend(&buffs, pwd, lib_path_folder); + folder_path = strsAppend(&buffs, folder_path, "/"); + char* lib_file_path = strsAppend(&buffs, pwd, lib_path); + LibObj_saveLibraryFile(lib, lib_file_path); + Lib_loadLibraryFileToArray(lib_file_path, folder_path); + strsDeinit(&buffs); + return PIKA_RES_OK; +} + +PIKA_RES pikaMaker_linkCompiledModules(PikaMaker* self, char* lib_name) { + Args buffs = {0}; + char* lib_file_path = strsAppend(&buffs, "pikascript-api/", lib_name); + PIKA_RES res = pikaMaker_linkCompiledModulesFullPath(self, lib_file_path); + strsDeinit(&buffs); + return res; +} + +PIKA_RES pikaMaker_linkRaw(PikaMaker* self, char* file_path) { + LibObj* lib = obj_getPtr(self, "lib"); + LibObj_staticLinkFile(lib, file_path); + return PIKA_RES_OK; +} diff --git a/examples/pikapython/pikapython/pikascript-core/PikaCompiler.h b/examples/pikapython/pikapython/pikascript-core/PikaCompiler.h new file mode 100644 index 00000000..e84a03ce --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/PikaCompiler.h @@ -0,0 +1,44 @@ +#ifndef __PIKA_COMPILER__H +#define __PIKA_COMPILER__H +#include "PikaObj.h" +#include "stdint.h" + +PIKA_RES pikaCompileFile(char* input_file_name); +PIKA_RES pikaCompileFileWithOutputName(char* output_file_name, + char* input_file_name); +PIKA_RES pikaCompile(char* output_file_name, char* py_lines); + +LibObj* New_LibObj(Args* args); +void LibObj_deinit(LibObj* self); +void LibObj_dynamicLink(LibObj* self, char* module_name, uint8_t* bytecode); +int LibObj_staticLink(LibObj* self, + char* module_name, + uint8_t* bytecode, + size_t size); +int LibObj_staticLinkFile(LibObj* self, char* input_file_name); +void LibObj_listModules(LibObj* self); +int LibObj_saveLibraryFile(LibObj* self, char* output_file_name); +int LibObj_loadLibraryFile(LibObj* self, char* input_file_name); +int Lib_loadLibraryFileToArray(char* origin_file_name, char* pikascript_root); +PikaMaker* New_PikaMaker(void); +void pikaMaker_setPWD(PikaMaker* self, char* pwd); +PIKA_RES pikaMaker_compileModule(PikaMaker* self, char* module_name); +int pikaMaker_getDependencies(PikaMaker* self, char* module_name); +void pikaMaker_printStates(PikaMaker* self); +char* pikaMaker_getFirstNocompiled(PikaMaker* self); +PIKA_RES pikaMaker_compileModuleWithDepends(PikaMaker* self, char* module_name); +PIKA_RES pikaMaker_linkCompiledModulesFullPath(PikaMaker* self, char* lib_path); +PIKA_RES pikaMaker_linkCompiledModules(PikaMaker* self, char* lib_name); +int LibObj_loadLibrary(LibObj* self, uint8_t* library_bytes); +void LibObj_printModules(LibObj* self); +void pikaMaker_deinit(PikaMaker* self); +PIKA_RES pikaMaker_linkRaw(PikaMaker* self, char* file_path); +PIKA_RES _loadModuleDataWithName(uint8_t* library_bytes, + char* module_name, + uint8_t** addr_p, + size_t* size_p); + +#define LIB_VERSION_NUMBER 2 +#define LIB_INFO_BLOCK_SIZE 32 + +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/PikaObj.c b/examples/pikapython/pikapython/pikascript-core/PikaObj.c new file mode 100644 index 00000000..fe307806 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/PikaObj.c @@ -0,0 +1,1732 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "PikaObj.h" +#include +#include "BaseObj.h" +#include "PikaCompiler.h" +#include "PikaPlatform.h" +#include "dataArgs.h" +#include "dataMemory.h" +#include "dataString.h" +#include "dataStrs.h" + +static volatile Arg* _help_modules_cmodule = NULL; +static volatile PIKA_BOOL in_root_obj = PIKA_FALSE; + +static enum shellCTRL __obj_shellLineHandler_REPL(PikaObj* self, + char* input_line, + ShellConfig* shell); + +static const uint64_t __talbe_fast_atoi[][10] = { + {0, 1e0, 2e0, 3e0, 4e0, 5e0, 6e0, 7e0, 8e0, 9e0}, + {0, 1e1, 2e1, 3e1, 4e1, 5e1, 6e1, 7e1, 8e1, 9e1}, + {0, 1e2, 2e2, 3e2, 4e2, 5e2, 6e2, 7e2, 8e2, 9e2}, + {0, 1e3, 2e3, 3e3, 4e3, 5e3, 6e3, 7e3, 8e3, 9e3}, + {0, 1e4, 2e4, 3e4, 4e4, 5e4, 6e4, 7e4, 8e4, 9e4}, + {0, 1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5}, + {0, 1e6, 2e6, 3e6, 4e6, 5e6, 6e6, 7e6, 8e6, 9e6}, + {0, 1e7, 2e7, 3e7, 4e7, 5e7, 6e7, 7e7, 8e7, 9e7}, + {0, 1e8, 2e8, 3e8, 4e8, 5e8, 6e8, 7e8, 8e8, 9e8}, + {0, 1e9, 2e9, 3e9, 4e9, 5e9, 6e9, 7e9, 8e9, 9e9}, +}; + +int64_t fast_atoi(char* src) { + const char* p = src; + uint16_t size = strGetSize(src); + p = p + size - 1; + if (*p) { + int64_t s = 0; + const uint64_t* n = __talbe_fast_atoi[0]; + while (p != src) { + s += n[(*p - '0')]; + n += 10; + p--; + } + if (*p == '-') { + return -s; + } + return s + n[(*p - '0')]; + } + return 0; +} + +static uint16_t const str100p[100] = { + 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730, 0x3830, + 0x3930, 0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731, + 0x3831, 0x3931, 0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, + 0x3732, 0x3832, 0x3932, 0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, + 0x3633, 0x3733, 0x3833, 0x3933, 0x3034, 0x3134, 0x3234, 0x3334, 0x3434, + 0x3534, 0x3634, 0x3734, 0x3834, 0x3934, 0x3035, 0x3135, 0x3235, 0x3335, + 0x3435, 0x3535, 0x3635, 0x3735, 0x3835, 0x3935, 0x3036, 0x3136, 0x3236, + 0x3336, 0x3436, 0x3536, 0x3636, 0x3736, 0x3836, 0x3936, 0x3037, 0x3137, + 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737, 0x3837, 0x3937, 0x3038, + 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738, 0x3838, 0x3938, + 0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739, 0x3839, + 0x3939, +}; + +char* fast_itoa(char* buf, uint32_t val) { + char* p = &buf[10]; + *p = '\0'; + while (val >= 100) { + uint32_t const old = val; + p -= 2; + val /= 100; + pika_platform_memcpy(p, &str100p[old - (val * 100)], sizeof(uint16_t)); + } + p -= 2; + pika_platform_memcpy(p, &str100p[val], sizeof(uint16_t)); + return &p[val < 10]; +} + +static int32_t obj_deinit_no_del(PikaObj* self) { + /* free the list */ + args_deinit(self->list); + /* free the pointer */ + pikaFree(self, sizeof(PikaObj)); + self = NULL; + return 0; +} + +int32_t obj_deinit(PikaObj* self) { + Arg* del = obj_getMethodArg(self, "__del__"); + if (NULL != del) { + const uint8_t bytes[] = { + 0x04, 0x00, 0x00, 0x00, /* instruct array size */ + 0x00, 0x82, 0x01, 0x00, /* instruct array */ + 0x09, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x64, 0x65, + 0x6c, 0x5f, 0x5f, 0x00, /* const pool */ + }; + pikaVM_runByteCode(self, (uint8_t*)bytes); + arg_deinit(del); + } + extern volatile PikaObj* __pikaMain; + if (self == (PikaObj*)__pikaMain) { + void _mem_cache_deinit(void); + void _VMEvent_deinit(void); + _mem_cache_deinit(); +#if PIKA_EVENT_ENABLE + _VMEvent_deinit(); +#endif + if (NULL != _help_modules_cmodule) { + arg_deinit((Arg*)_help_modules_cmodule); + _help_modules_cmodule = NULL; + } + __pikaMain = NULL; + } + return obj_deinit_no_del(self); +} + +PIKA_RES obj_setInt(PikaObj* self, char* argPath, int64_t val) { + PikaObj* obj = obj_getHostObj(self, argPath); + if (NULL == obj) { + /* [error] object no found */ + return PIKA_RES_ERR_ARG_NO_FOUND; + } + char* name = strPointToLastToken(argPath, '.'); + args_setInt(obj->list, name, val); + return PIKA_RES_OK; +} + +PIKA_RES obj_setPtr(PikaObj* self, char* argPath, void* pointer) { + PikaObj* obj = obj_getHostObj(self, argPath); + if (NULL == obj) { + /* [error] object no found */ + return PIKA_RES_ERR_ARG_NO_FOUND; + } + char* name = strPointToLastToken(argPath, '.'); + args_setPtr(obj->list, name, pointer); + return PIKA_RES_OK; +} + +PIKA_RES obj_setRef(PikaObj* self, char* argPath, PikaObj* pointer) { + PikaObj* obj = obj_getHostObj(self, argPath); + if (NULL == obj) { + /* [error] object no found */ + return PIKA_RES_ERR_ARG_NO_FOUND; + } + char* name = strPointToLastToken(argPath, '.'); + args_setRef(obj->list, name, pointer); + return PIKA_RES_OK; +} + +PIKA_RES obj_setFloat(PikaObj* self, char* argPath, pika_float value) { + PikaObj* obj = obj_getHostObj(self, argPath); + if (NULL == obj) { + /* [error] object no found */ + return PIKA_RES_ERR_ARG_NO_FOUND; + } + char* name = strPointToLastToken(argPath, '.'); + args_setFloat(obj->list, name, value); + return PIKA_RES_OK; +} + +PIKA_RES obj_setStr(PikaObj* self, char* argPath, char* str) { + PikaObj* obj = obj_getHostObj(self, argPath); + if (NULL == obj) { + return PIKA_RES_ERR_ARG_NO_FOUND; + } + char* name = strPointToLastToken(argPath, '.'); + return args_setStr(obj->list, name, str); +} + +PIKA_RES obj_setNone(PikaObj* self, char* argPath) { + PikaObj* obj = obj_getHostObj(self, argPath); + if (NULL == obj) { + return PIKA_RES_ERR_ARG_NO_FOUND; + } + char* name = strPointToLastToken(argPath, '.'); + args_setNone(obj->list, name); + return PIKA_RES_OK; +} + +PIKA_RES obj_setBytes(PikaObj* self, char* argPath, uint8_t* src, size_t size) { + PikaObj* obj = obj_getHostObj(self, argPath); + if (NULL == obj) { + return PIKA_RES_ERR_ARG_NO_FOUND; + } + char* name = strPointToLastToken(argPath, '.'); + args_setBytes(obj->list, name, src, size); + return PIKA_RES_OK; +} + +int64_t obj_getInt(PikaObj* self, char* argPath) { + PikaObj* obj = obj_getHostObj(self, argPath); + if (NULL == obj) { + return -999999999; + } + char* argName = strPointToLastToken(argPath, '.'); + int64_t res = args_getInt(obj->list, argName); + return res; +} + +Arg* obj_getArg(PikaObj* self, char* argPath) { + PIKA_BOOL is_temp = PIKA_FALSE; + PikaObj* obj = obj_getHostObjWithIsTemp(self, argPath, &is_temp); + if (NULL == obj) { + return NULL; + } + Arg* res = NULL; + char* argName = strPointToLastToken(argPath, '.'); + res = args_getArg(obj->list, argName); + if (is_temp) { + obj_setArg(self, "_buf", res); + res = obj_getArg(self, "_buf"); + obj_deinit(obj); + } + return res; +} + +uint8_t* obj_getBytes(PikaObj* self, char* argPath) { + PikaObj* obj = obj_getHostObj(self, argPath); + if (NULL == obj) { + return NULL; + } + char* argName = strPointToLastToken(argPath, '.'); + return args_getBytes(obj->list, argName); +} + +size_t obj_getBytesSize(PikaObj* self, char* argPath) { + PikaObj* obj = obj_getHostObj(self, argPath); + if (NULL == obj) { + return 0; + } + char* argName = strPointToLastToken(argPath, '.'); + return args_getBytesSize(obj->list, argName); +} + +size_t obj_loadBytes(PikaObj* self, char* argPath, uint8_t* out_buff) { + size_t size_mem = obj_getBytesSize(self, argPath); + void* src = obj_getBytes(self, argPath); + if (0 == size_mem) { + return 0; + } + if (NULL == src) { + return 0; + } + pika_platform_memcpy(out_buff, src, size_mem); + return size_mem; +} + +static PIKA_RES __obj_setArg(PikaObj* self, + char* argPath, + Arg* arg, + uint8_t is_copy) { + /* setArg would copy arg */ + PikaObj* obj = obj_getHostObj(self, argPath); + if (NULL == obj) { + /* object no found */ + return PIKA_RES_ERR_ARG_NO_FOUND; + } + char* argName = strPointToLastToken(argPath, '.'); + Arg* newArg; + if (is_copy) { + newArg = arg_copy(arg); + } else { + newArg = arg; + } + newArg = arg_setName(newArg, argName); + args_setArg(obj->list, newArg); + return PIKA_RES_OK; +} + +PIKA_RES obj_setArg(PikaObj* self, char* argPath, Arg* arg) { + return __obj_setArg(self, argPath, arg, 1); +}; + +PIKA_RES obj_setArg_noCopy(PikaObj* self, char* argPath, Arg* arg) { + return __obj_setArg(self, argPath, arg, 0); +} + +void* obj_getPtr(PikaObj* self, char* argPath) { + PikaObj* obj = obj_getHostObj(self, argPath); + if (NULL == obj) { + return NULL; + } + char* argName = strPointToLastToken(argPath, '.'); + void* res = args_getPtr(obj->list, argName); + return res; +} + +pika_float obj_getFloat(PikaObj* self, char* argPath) { + PikaObj* obj = obj_getHostObj(self, argPath); + if (NULL == obj) { + return -999.999; + } + char* argName = strPointToLastToken(argPath, '.'); + pika_float res = args_getFloat(obj->list, argName); + return res; +} + +char* obj_getStr(PikaObj* self, char* argPath) { + PikaObj* obj = obj_getHostObj(self, argPath); + if (NULL == obj) { + return NULL; + } + char* argName = strPointToLastToken(argPath, '.'); + char* res = args_getStr(obj->list, argName); + return res; +} + +PikaObj* obj_getClassObjByNewFun(PikaObj* context, + char* name, + NewFun newClassFun) { + Args* initArgs = New_args(NULL); + PikaObj* thisClass = newClassFun(initArgs); + thisClass->constructor = newClassFun; + thisClass->refcnt = 0; + args_deinit(initArgs); + return thisClass; +} + +Arg* _obj_getProp(PikaObj* obj, char* name) { + NativeProperty* prop = obj_getPtr(obj, "@p"); + PikaObj* class_obj = NULL; + Arg* method = NULL; + if (NULL == prop) { + if (NULL != obj->constructor) { + class_obj = obj_getClassObj(obj); + prop = obj_getPtr(class_obj, "@p"); + } + } + Hash method_hash = hash_time33(name); + while (1) { + if (prop == NULL) { + break; + } + int size = prop->methodGroupCount; + /* binary search */ + if (size == 0) { + goto next; + } +#if !PIKA_NANO_ENABLE + if (size > 16) { + int left = 0; + int right = size - 1; + int mid = 0; + while (1) { + if (left > right) { + break; + } + mid = (right + left) >> 1; + Arg* prop_this = (Arg*)(prop->methodGroup + mid); + if (prop_this->name_hash == method_hash) { + method = prop_this; + goto exit; + } else if (prop_this->name_hash < method_hash) { + left = mid + 1; + } else { + right = mid - 1; + } + } + goto next; + } +#endif + for (int i = 0; i < (int)prop->methodGroupCount; i++) { + Arg* prop_this = (Arg*)(prop->methodGroup + i); + if (prop_this->name_hash == method_hash) { + method = prop_this; + goto exit; + } + } + goto next; + next: + prop = (NativeProperty*)prop->super; + } +exit: + if (NULL != class_obj) { + obj_deinit_no_del(class_obj); + } + return method; +} + +Arg* _obj_getMethodArg(PikaObj* obj, char* methodPath, Arg* arg_reg) { + Arg* method = NULL; + char* methodName = strPointToLastToken(methodPath, '.'); + method = obj_getArg(obj, methodName); + if (NULL != method) { + method = arg_copy_noalloc(method, arg_reg); + goto exit; + } + method = _obj_getProp(obj, methodName); + if (NULL != method) { + goto exit; + } +exit: + return method; +} + +Arg* obj_getMethodArg(PikaObj* obj, char* methodPath) { + return _obj_getMethodArg(obj, methodPath, NULL); +} + +Arg* obj_getMethodArg_noalloc(PikaObj* obj, char* methodPath, Arg* arg_reg) { + return _obj_getMethodArg(obj, methodPath, arg_reg); +} + +NewFun obj_getClass(PikaObj* obj) { + return (NewFun)obj->constructor; +} + +PikaObj* obj_getClassObj(PikaObj* obj) { + NewFun classPtr = obj_getClass(obj); + if (NULL == classPtr) { + return NULL; + } + PikaObj* classObj = obj_getClassObjByNewFun(obj, "", classPtr); + return classObj; +} + +void* getNewClassObjFunByName(PikaObj* obj, char* name) { + char* classPath = name; + /* init the subprocess */ + void* newClassObjFun = args_getPtr(obj->list, classPath); + return newClassObjFun; +} + +PikaObj* removeMethodInfo(PikaObj* thisClass) { +#if PIKA_METHOD_CACHE_ENABLE +#else + args_removeArg(thisClass->list, args_getArg(thisClass->list, "@p")); +#endif + return thisClass; +} + +PikaObj* newNormalObj(NewFun newObjFun) { + PikaObj* thisClass = obj_getClassObjByNewFun(NULL, "", newObjFun); + obj_refcntInc(thisClass); + obj_setFlag(thisClass, OBJ_FLAG_ALREADY_INIT); + return removeMethodInfo(thisClass); +} + +#ifdef __linux + +#include +#include +#include +#include +#define ECHOFLAGS (ECHO | ECHOE | ECHOK | ECHONL) +// 函数set_disp_mode用于控制是否开启输入回显功能 +// 如果option为0,则关闭回显,为1则打开回显 +static int set_disp_mode(int fd, int option) { + int err; + struct termios term; + if (tcgetattr(fd, &term) == -1) { + perror("Cannot get the attribution of the terminal"); + return 1; + } + if (option) + term.c_lflag |= ECHOFLAGS; + else + term.c_lflag &= ~ECHOFLAGS; + err = tcsetattr(fd, TCSAFLUSH, &term); + if (err == -1 && err == EINTR) { + perror("Cannot set the attribution of the terminal"); + return 1; + } + return 0; +} +#endif + +static volatile uint8_t logo_printed = 0; + +extern volatile PikaObj* __pikaMain; +PikaObj* newRootObj(char* name, NewFun newObjFun) { + in_root_obj = PIKA_TRUE; +#if PIKA_POOL_ENABLE + mem_pool_init(); +#endif +#if __linux + // set_disp_mode(STDIN_FILENO, 0); +#endif + PikaObj* newObj = newNormalObj(newObjFun); + if (!logo_printed) { + logo_printed = 1; + pika_platform_printf("\r\n"); + pika_platform_printf("~~~/ POWERED BY \\~~~\r\n"); + pika_platform_printf("~ pikascript.com ~\r\n"); + pika_platform_printf("~~~~~~~~~~~~~~~~~~~~\r\n"); + } + __pikaMain = newObj; + in_root_obj = PIKA_FALSE; + return newObj; +} + +Arg* arg_newMetaObj(NewFun new_obj_fun) { + Arg* arg_new = New_arg(NULL); + /* m means meta-object */ + arg_new = arg_setPtr(arg_new, "", ARG_TYPE_OBJECT_META, (void*)new_obj_fun); + return arg_new; +} + +Arg* arg_newDirectObj(NewFun new_obj_fun) { + PikaObj* newObj = newNormalObj(new_obj_fun); + Arg* arg_new = arg_newPtr(ARG_TYPE_OBJECT_NEW, newObj); + return arg_new; +} + +Arg* obj_newObjInPackage(NewFun new_obj_fun) { + return arg_newDirectObj(new_obj_fun); +} + +static PikaObj* __obj_initSubObj(PikaObj* obj, char* name) { + PikaObj* res = NULL; + NewFun constructor = (NewFun)getNewClassObjFunByName(obj, name); + Args buffs = {0}; + PikaObj* thisClass; + PikaObj* new_obj; + if (NULL == constructor) { + /* no such object */ + res = NULL; + goto exit; + } + thisClass = obj_getClassObjByNewFun(obj, name, constructor); + new_obj = removeMethodInfo(thisClass); + obj_refcntInc(new_obj); + obj_runNativeMethod(new_obj, "__init__", NULL); + args_setPtrWithType(obj->list, name, ARG_TYPE_OBJECT, new_obj); + res = obj_getPtr(obj, name); + goto exit; +exit: + strsDeinit(&buffs); + return res; +} + +PikaObj* _arg_to_obj(Arg* self, PIKA_BOOL* pIsTemp) { + if (NULL == self) { + return NULL; + } + if (argType_isObject(arg_getType(self))) { + return arg_getPtr(self); + } +#if !PIKA_NANO_ENABLE + if (arg_getType(self) == ARG_TYPE_STRING) { + PikaObj* New_PikaStdData_String(Args * args); + PikaObj* obj = newNormalObj(New_PikaStdData_String); + obj_setStr(obj, "str", arg_getStr(self)); + if (NULL != pIsTemp) { + *pIsTemp = PIKA_TRUE; + } + return obj; + } + if (arg_getType(self) == ARG_TYPE_BYTES) { + PikaObj* New_PikaStdData_ByteArray(Args * args); + PikaObj* obj = newNormalObj(New_PikaStdData_ByteArray); + obj_setArg(obj, "raw", self); + if (NULL != pIsTemp) { + *pIsTemp = PIKA_TRUE; + } + return obj; + } +#endif + return NULL; +} + +static PikaObj* __obj_getObjDirect(PikaObj* self, + char* name, + PIKA_BOOL* pIsTemp) { + *pIsTemp = PIKA_FALSE; + if (NULL == self) { + return NULL; + } + /* finded object, check type*/ + Arg* arg_obj = args_getArg(self->list, name); + ArgType type = ARG_TYPE_NONE; + if (NULL == arg_obj) { + arg_obj = _obj_getProp(self, name); + } + if (NULL == arg_obj) { + return NULL; + } + type = arg_getType(arg_obj); + /* found meta Object */ + if (type == ARG_TYPE_OBJECT_META) { + return __obj_initSubObj(self, name); + } + /* found Objcet */ + if (argType_isObject(type)) { + return arg_getPtr(arg_obj); + } +#if !PIKA_NANO_ENABLE + /* found class */ + if (type == ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR || + type == ARG_TYPE_METHOD_CONSTRUCTOR) { + *pIsTemp = PIKA_TRUE; + PikaObj* method_args_obj = New_TinyObj(NULL); + Arg* cls_obj_arg = obj_runMethodArg(self, method_args_obj, arg_obj); + obj_deinit(method_args_obj); + if (type == ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR) { + obj_runNativeMethod(arg_getPtr(cls_obj_arg), "__init__", NULL); + } + PikaObj* res = arg_getPtr(cls_obj_arg); + arg_deinit(cls_obj_arg); + return res; + } +#endif + return _arg_to_obj(arg_obj, pIsTemp); +} + +static PikaObj* __obj_getObjWithKeepDeepth(PikaObj* self, + char* objPath, + PIKA_BOOL* pIsTemp, + int32_t keepDeepth) { + char objPath_buff[PIKA_PATH_BUFF_SIZE]; + char* objPath_ptr = objPath_buff; + strcpy(objPath_buff, objPath); + int32_t token_num = strGetTokenNum(objPath, '.'); + PikaObj* obj = self; + for (int32_t i = 0; i < token_num - keepDeepth; i++) { + char* token = strPopFirstToken(&objPath_ptr, '.'); + obj = __obj_getObjDirect(obj, token, pIsTemp); + if (obj == NULL) { + goto exit; + } + } + goto exit; +exit: + return obj; +} + +PikaObj* obj_getObj(PikaObj* self, char* objPath) { + PIKA_BOOL is_temp = PIKA_FALSE; + return __obj_getObjWithKeepDeepth(self, objPath, &is_temp, 0); +} + +PikaObj* obj_getHostObj(PikaObj* self, char* objPath) { + PIKA_BOOL is_temp = PIKA_FALSE; + return __obj_getObjWithKeepDeepth(self, objPath, &is_temp, 1); +} + +PikaObj* obj_getHostObjWithIsTemp(PikaObj* self, + char* objPath, + PIKA_BOOL* pIsTemp) { + return __obj_getObjWithKeepDeepth(self, objPath, pIsTemp, 1); +} + +Method methodArg_getPtr(Arg* method_arg) { + MethodProp* method_store = (MethodProp*)arg_getContent(method_arg); + return (Method)method_store->ptr; +} + +char* methodArg_getTypeList(Arg* method_arg, char* buffs, size_t size) { + MethodProp* method_store = (MethodProp*)arg_getContent(method_arg); + if (NULL != method_store->type_list) { + return strcpy(buffs, method_store->type_list); + } + char* method_dec = methodArg_getDec(method_arg); + pika_assert(strGetSize(method_dec) <= size); + if (strGetSize(method_dec) > size) { + pika_platform_printf( + "OverFlowError: please use bigger PIKA_LINE_BUFF_SIZE\r\n"); + while (1) { + } + } + char* res = strCut(buffs, method_dec, '(', ')'); + pika_assert(NULL != res); + return res; +} + +char* methodArg_getName(Arg* method_arg, char* buffs, size_t size) { + MethodProp* method_store = (MethodProp*)arg_getContent(method_arg); + if (NULL != method_store->name) { + return strcpy(buffs, method_store->name); + } + char* method_dec = methodArg_getDec(method_arg); + pika_assert(strGetSize(method_dec) <= size); + char* res = strGetFirstToken(buffs, method_dec, '('); + return res; +} + +Method obj_getNativeMethod(PikaObj* self, char* method_name) { + Arg* method_arg = obj_getMethodArg(self, method_name); + if (NULL == method_arg) { + return NULL; + } + Method res = methodArg_getPtr(method_arg); + arg_deinit(method_arg); + return res; +} + +ByteCodeFrame* methodArg_getBytecodeFrame(Arg* method_arg) { + MethodProp* method_store = (MethodProp*)arg_getContent(method_arg); + return method_store->bytecode_frame; +} + +char* methodArg_getDec(Arg* method_arg) { + MethodProp* method_store = (MethodProp*)arg_getContent(method_arg); + return method_store->declareation; +} + +PikaObj* methodArg_getDefContext(Arg* method_arg) { + MethodProp* method_store = (MethodProp*)arg_getContent(method_arg); + return method_store->def_context; +} + +void _update_proxy(PikaObj* self, char* name) { +#if PIKA_NANO_ENABLE + return; +#endif + if (name[0] != '_' || name[1] != '_') { + return; + } + if (!obj_getFlag(self, OBJ_FLAG_PROXY_GETATTRIBUTE)) { + if (strEqu(name, "__getattribute__")) { + obj_setFlag(self, OBJ_FLAG_PROXY_GETATTRIBUTE); + return; + } + } + if (!obj_getFlag(self, OBJ_FLAG_PROXY_GETATTR)) { + if (strEqu(name, "__getattr__")) { + obj_setFlag(self, OBJ_FLAG_PROXY_GETATTR); + return; + } + } + if (!obj_getFlag(self, OBJ_FLAG_PROXY_SETATTR)) { + if (strEqu(name, "__setattr__")) { + obj_setFlag(self, OBJ_FLAG_PROXY_SETATTR); + return; + } + } +} + +static void obj_saveMethodInfo(PikaObj* self, MethodInfo* method_info) { + Arg* arg = New_arg(NULL); + MethodProp method_store = { + .ptr = method_info->ptr, + .type_list = method_info->typelist, + .name = method_info->name, + .bytecode_frame = method_info->bytecode_frame, + .def_context = method_info->def_context, + .declareation = method_info->dec, // const + }; + char* name = method_info->name; + if (NULL == method_info->name) { + char name_buff[PIKA_LINE_BUFF_SIZE / 2] = {0}; + name = strGetFirstToken(name_buff, method_info->dec, '('); + } + /* the first arg_value */ + arg = arg_setStruct(arg, name, &method_store, sizeof(method_store)); + pika_assert(NULL != arg); + arg_setType(arg, method_info->type); + _update_proxy(self, name); + args_setArg(self->list, arg); +} + +static int32_t __class_defineMethodWithType(PikaObj* self, + char* declareation, + char* name, + char* typelist, + Method method_ptr, + ArgType method_type, + PikaObj* def_context, + ByteCodeFrame* bytecode_frame) { + int32_t res = 0; + Args buffs = {0}; + PikaObj* method_host = self; + MethodInfo method_info = {0}; + if (NULL == method_host) { + /* no found method object */ + res = 1; + goto exit; + } + method_info.dec = declareation; + method_info.name = name; + method_info.ptr = (void*)method_ptr; + method_info.type = method_type; + method_info.def_context = def_context; + method_info.bytecode_frame = bytecode_frame; + method_info.typelist = typelist; + obj_saveMethodInfo(method_host, &method_info); + res = 0; + goto exit; +exit: + strsDeinit(&buffs); + return res; +} + +/* define a constructor method */ +int32_t class_defineConstructor(PikaObj* self, + char* name, + char* typelist, + Method methodPtr) { + return __class_defineMethodWithType(self, NULL, name, typelist, methodPtr, + ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR, + NULL, NULL); +} + +/* define a native method as default */ +int32_t class_defineMethod(PikaObj* self, + char* name, + char* typelist, + Method methodPtr) { + return __class_defineMethodWithType(self, NULL, name, typelist, methodPtr, + ARG_TYPE_METHOD_NATIVE, NULL, NULL); +} + +/* define object method, object method is which startwith (self) */ +int32_t class_defineRunTimeConstructor(PikaObj* self, + char* declareation, + Method methodPtr, + PikaObj* def_context, + ByteCodeFrame* bytecode_frame) { + return __class_defineMethodWithType(self, declareation, NULL, NULL, + methodPtr, ARG_TYPE_METHOD_CONSTRUCTOR, + def_context, bytecode_frame); +} + +/* define object method, object method is which startwith (self) */ +int32_t class_defineObjectMethod(PikaObj* self, + char* declareation, + Method methodPtr, + PikaObj* def_context, + ByteCodeFrame* bytecode_frame) { + return __class_defineMethodWithType(self, declareation, NULL, NULL, + methodPtr, ARG_TYPE_METHOD_OBJECT, + def_context, bytecode_frame); +} + +/* define a static method as default */ +int32_t class_defineStaticMethod(PikaObj* self, + char* declareation, + Method methodPtr, + PikaObj* def_context, + ByteCodeFrame* bytecode_frame) { + return __class_defineMethodWithType(self, declareation, NULL, NULL, + methodPtr, ARG_TYPE_METHOD_STATIC, + def_context, bytecode_frame); +} + +int32_t obj_removeArg(PikaObj* self, char* argPath) { + PikaObj* objHost = obj_getHostObj(self, argPath); + char* argName; + int32_t res; + int32_t err = 0; + if (NULL == objHost) { + /* [error] object no found */ + err = 1; + goto exit; + } + argName = strPointToLastToken(argPath, '.'); + res = args_removeArg(objHost->list, args_getArg(objHost->list, argName)); + if (1 == res) { + /*[error] not found arg*/ + err = 2; + goto exit; + } + goto exit; +exit: + return err; +} + +int32_t obj_isArgExist(PikaObj* self, char* argPath) { + PikaObj* obj_host = obj_getHostObj(self, argPath); + int32_t res = 0; + char* argName; + Arg* arg; + if (NULL == obj_host) { + /* [error] object no found */ + res = 1; + goto exit; + } + argName = strPointToLastToken(argPath, '.'); + arg = args_getArg(obj_host->list, argName); + if (NULL == arg) { + /* no found arg */ + res = 0; + goto exit; + } + /* found arg */ + res = 1; + goto exit; + +exit: + return res; +} + +VMParameters* obj_run(PikaObj* self, char* cmd) { + return pikaVM_run(self, cmd); +} + +PIKA_RES obj_runNativeMethod(PikaObj* self, char* method_name, Args* args) { + Method native_method = obj_getNativeMethod(self, method_name); + if (NULL == native_method) { + return PIKA_RES_ERR_ARG_NO_FOUND; + } + native_method(self, args); + return PIKA_RES_OK; +} + +static void __clearBuff(ShellConfig* shell) { + memset(shell->lineBuff, 0, PIKA_LINE_BUFF_SIZE); + shell->line_curpos = 0; + shell->line_position = 0; +} + +enum PIKA_SHELL_STATE { + PIKA_SHELL_STATE_NORMAL, + PIKA_SHELL_STATE_WAIT_SPEC_KEY, + PIKA_SHELL_STATE_WAIT_FUNC_KEY, +}; + +static void _obj_runChar_beforeRun(PikaObj* self, ShellConfig* shell) { + /* create the line buff for the first time */ + shell->inBlock = PIKA_FALSE; + shell->stat = PIKA_SHELL_STATE_NORMAL; + shell->line_position = 0; + shell->line_curpos = 0; + __clearBuff(shell); + pika_platform_printf("%s", shell->prefix); +} + +static void _putc_cmd(char KEY_POS, int pos) { + const char cmd[] = {0x1b, 0x5b, KEY_POS, 0x00}; + for (int i = 0; i < pos; i++) { + pika_platform_printf((char*)cmd); + } +} + +enum shellCTRL _do_obj_runChar(PikaObj* self, + char inputChar, + ShellConfig* shell) { + char* input_line = NULL; + enum shellCTRL ctrl = SHELL_CTRL_CONTINUE; +#if !(defined(__linux) || defined(_WIN32)) + pika_platform_printf("%c", inputChar); +#endif + if (inputChar == '\n' && shell->lastChar == '\r') { + ctrl = SHELL_CTRL_CONTINUE; + goto exit; + } + if (inputChar == 0x1b) { + shell->stat = PIKA_SHELL_STATE_WAIT_SPEC_KEY; + ctrl = SHELL_CTRL_CONTINUE; + goto exit; + } + if (shell->stat == PIKA_SHELL_STATE_WAIT_SPEC_KEY) { + if (inputChar == 0x5b) { + shell->stat = PIKA_SHELL_STATE_WAIT_FUNC_KEY; + ctrl = SHELL_CTRL_CONTINUE; + goto exit; + } + shell->stat = PIKA_SHELL_STATE_NORMAL; + } + if (shell->stat == PIKA_SHELL_STATE_WAIT_FUNC_KEY) { + if (inputChar == KEY_LEFT) { + if (shell->line_curpos) { + shell->line_curpos--; + } else { + pika_platform_printf(" "); + } + ctrl = SHELL_CTRL_CONTINUE; + goto exit; + } + if (inputChar == KEY_RIGHT) { + if (shell->line_curpos < shell->line_position) { + // pika_platform_printf("%c", + // shell->lineBuff[shell->line_curpos]); + shell->line_curpos++; + } else { + pika_platform_printf("\b"); + } + ctrl = SHELL_CTRL_CONTINUE; + goto exit; + } + if (inputChar == KEY_UP) { + _putc_cmd(KEY_DOWN, 1); + ctrl = SHELL_CTRL_CONTINUE; + goto exit; + } + if (inputChar == KEY_DOWN) { + ctrl = SHELL_CTRL_CONTINUE; + goto exit; + } + } + if ((inputChar == '\b') || (inputChar == 127)) { + if (shell->line_position == 0) { + pika_platform_printf(" "); + ctrl = SHELL_CTRL_CONTINUE; + goto exit; + } + pika_platform_printf(" \b"); + shell->line_position--; + shell->line_curpos--; + pika_platform_memmove(shell->lineBuff + shell->line_curpos, + shell->lineBuff + shell->line_curpos + 1, + shell->line_position - shell->line_curpos); + shell->lineBuff[shell->line_position] = 0; + if (shell->line_curpos != shell->line_position) { + /* update screen */ + pika_platform_printf(shell->lineBuff + shell->line_curpos); + pika_platform_printf(" "); + _putc_cmd(KEY_LEFT, shell->line_position - shell->line_curpos + 1); + } + ctrl = SHELL_CTRL_CONTINUE; + goto exit; + } + if ((inputChar != '\r') && (inputChar != '\n')) { + if (shell->line_position + 1 >= PIKA_LINE_BUFF_SIZE) { + pika_platform_printf( + "\r\nError: line buff overflow, please use bigger " + "'PIKA_LINE_BUFF_SIZE'\r\n"); + ctrl = SHELL_CTRL_EXIT; + __clearBuff(shell); + goto exit; + } + if ('\0' != inputChar) { + pika_platform_memmove(shell->lineBuff + shell->line_curpos + 1, + shell->lineBuff + shell->line_curpos, + shell->line_position - shell->line_curpos); + shell->lineBuff[shell->line_position + 1] = 0; + if (shell->line_curpos != shell->line_position) { + pika_platform_printf(shell->lineBuff + shell->line_curpos + 1); + _putc_cmd(KEY_LEFT, shell->line_position - shell->line_curpos); + } + shell->lineBuff[shell->line_curpos] = inputChar; + shell->line_position++; + shell->line_curpos++; + } + ctrl = SHELL_CTRL_CONTINUE; + goto exit; + } + if ((inputChar == '\r') || (inputChar == '\n')) { +#if !(defined(__linux) || defined(_WIN32)) + pika_platform_printf("\r\n"); +#endif + /* still in block */ + if (shell->blockBuffName != NULL && shell->inBlock) { + /* load new line into buff */ + Args buffs = {0}; + char _n = '\n'; + strAppendWithSize(shell->lineBuff, &_n, 1); + char* shell_buff_new = + strsAppend(&buffs, obj_getStr(self, shell->blockBuffName), + shell->lineBuff); + obj_setStr(self, shell->blockBuffName, shell_buff_new); + strsDeinit(&buffs); + /* go out from block */ + if ((shell->lineBuff[0] != ' ') && (shell->lineBuff[0] != '\t')) { + shell->inBlock = PIKA_FALSE; + input_line = obj_getStr(self, shell->blockBuffName); + ctrl = shell->handler(self, input_line, shell); + __clearBuff(shell); + pika_platform_printf(">>> "); + goto exit; + } else { + pika_platform_printf("... "); + } + __clearBuff(shell); + ctrl = SHELL_CTRL_CONTINUE; + goto exit; + } + /* go in block */ + if (shell->blockBuffName != NULL && 0 != strGetSize(shell->lineBuff)) { + if (shell->lineBuff[strGetSize(shell->lineBuff) - 1] == ':') { + shell->inBlock = PIKA_TRUE; + char _n = '\n'; + strAppendWithSize(shell->lineBuff, &_n, 1); + obj_setStr(self, shell->blockBuffName, shell->lineBuff); + __clearBuff(shell); + pika_platform_printf("... "); + ctrl = SHELL_CTRL_CONTINUE; + goto exit; + } + } + shell->lineBuff[shell->line_position] = '\0'; + ctrl = shell->handler(self, shell->lineBuff, shell); + pika_platform_printf("%s", shell->prefix); + __clearBuff(shell); + goto exit; + } +exit: + shell->lastChar = inputChar; + return ctrl; +} + +enum shellCTRL obj_runChar(PikaObj* self, char inputChar) { + ShellConfig* shell = args_getStruct(self->list, "@shcfg"); + if (NULL == shell) { + /* init the shell */ + ShellConfig newShell = { + .prefix = ">>> ", + .blockBuffName = "@sh1", + .handler = __obj_shellLineHandler_REPL, + }; + args_setStruct(self->list, "@shcfg", newShell); + shell = args_getStruct(self->list, "@shcfg"); + _obj_runChar_beforeRun(self, shell); + } + return _do_obj_runChar(self, inputChar, shell); +} + +void _do_pikaScriptShell(PikaObj* self, ShellConfig* cfg) { + /* init the shell */ + _obj_runChar_beforeRun(self, cfg); + + /* getchar and run */ + char inputChar[2] = {0}; + while (1) { + inputChar[1] = inputChar[0]; + inputChar[0] = cfg->fn_getchar(); +#if !PIKA_NANO_ENABLE + /* run python script */ + if (inputChar[0] == '!' && inputChar[1] == '#') { + /* #! xxx */ + /* start */ + char* buff = pikaMalloc(PIKA_READ_FILE_BUFF_SIZE); + char input[2] = {0}; + int buff_i = 0; + PIKA_BOOL is_exit = PIKA_FALSE; + PIKA_BOOL is_first_line = PIKA_TRUE; + while (1) { + input[1] = input[0]; + input[0] = cfg->fn_getchar(); + if (input[0] == '!' && input[1] == '#') { + buff[buff_i - 1] = 0; + for (int i = 0; i < 4; i++) { + /* eat 'pika' */ + cfg->fn_getchar(); + } + break; + } + if ('\r' == input[0]) { + continue; + } + if (is_first_line) { + if ('\n' == input[0]) { + is_first_line = PIKA_FALSE; + } + continue; + } + buff[buff_i++] = input[0]; + } + /* end */ + pika_platform_printf( + "\r\n=============== [Code] ===============\r\n"); + size_t len = strGetSize(buff); + for (size_t i = 0; i < len; i++) { + if (buff[i] == '\r') { + continue; + } + if (buff[i] == '\n') { + pika_platform_printf("\r\n"); + continue; + } + pika_platform_printf("%c", buff[i]); + } + pika_platform_printf("\r\n"); + pika_platform_printf("=============== [File] ===============\r\n"); + pika_platform_printf( + "[ Info] File buff used: %d/%d (%0.2f%%)\r\n", (int)len, + (int)PIKA_READ_FILE_BUFF_SIZE, + ((float)len / (float)PIKA_READ_FILE_BUFF_SIZE)); +#if PIKA_SHELL_SAVE_FILE_ENABLE + char* file_name = PIKA_SHELL_SAVE_FILE_NAME; + pika_platform_printf("[ Info] Saving file to '%s'...\r\n", + file_name); + FILE* fp = pika_platform_fopen(file_name, "w+"); + if (NULL == fp) { + pika_platform_printf("[ Error] Open file '%s' error!\r\n", + file_name); + pika_platform_fclose(fp); + } else { + pika_platform_fwrite(buff, 1, len, fp); + pika_platform_printf( + "[ Info] Writing %d bytes to '%s'...\r\n", (int)(len), + file_name); + pika_platform_fclose(fp); + pika_platform_printf("[ OK ] Writing to '%s' succeed!\r\n", + file_name); + } +#endif + pika_platform_printf("=============== [ Run] ===============\r\n"); + obj_run(self, (char*)buff); + if (NULL != strstr(buff, "exit()")) { + is_exit = PIKA_TRUE; + } + pikaFree(buff, PIKA_READ_FILE_BUFF_SIZE); + if (is_exit) { + return; + } + pika_platform_printf("%s", cfg->prefix); + continue; + } + + /* run xx.py.o */ + if (inputChar[0] == 'p' && inputChar[1] == 0x0f) { + for (int i = 0; i < 2; i++) { + /* eat 'yo' */ + cfg->fn_getchar(); + } + uint32_t size = 0; + for (int i = 0; i < 4; i++) { + uint8_t* size_byte = (uint8_t*)&size; + size_byte[i] = cfg->fn_getchar(); + } + uint8_t* buff = pikaMalloc(size); + for (uint32_t i = 0; i < size; i++) { + buff[i] = cfg->fn_getchar(); + } + pika_platform_printf( + "\r\n=============== [Code] ===============\r\n"); + pika_platform_printf("[ Info] Bytecode size: %d\r\n", size); + pika_platform_printf("=============== [ RUN] ===============\r\n"); + pikaVM_runByteCodeInconstant(self, buff); + pikaFree(buff, size); + return; + } +#endif + if (SHELL_CTRL_EXIT == _do_obj_runChar(self, inputChar[0], cfg)) { + break; + } + } +} + +void _temp__do_pikaScriptShell(PikaObj* self, ShellConfig* shell) { + /* init the shell */ + _obj_runChar_beforeRun(self, shell); + + /* getchar and run */ + while (1) { + char inputChar = shell->fn_getchar(); + if (SHELL_CTRL_EXIT == _do_obj_runChar(self, inputChar, shell)) { + break; + } + } +} + +static enum shellCTRL __obj_shellLineHandler_REPL(PikaObj* self, + char* input_line, + ShellConfig* shell) { + /* exit */ + if (strEqu("exit()", input_line)) { + /* exit pika shell */ + return SHELL_CTRL_EXIT; + } + /* run single line */ + obj_run(self, input_line); + return SHELL_CTRL_CONTINUE; +} + +static volatile ShellConfig g_repl_shell = { + .handler = __obj_shellLineHandler_REPL, + .prefix = ">>> ", + .blockBuffName = "@sh0", +}; + +void pikaScriptShell_withGetchar(PikaObj* self, sh_getchar getchar_fn) { + g_repl_shell.fn_getchar = getchar_fn; + _do_pikaScriptShell(self, (ShellConfig*)&g_repl_shell); +} + +void pikaScriptShell(PikaObj* self) { + pikaScriptShell_withGetchar(self, pika_platform_getchar); +} + +void obj_setErrorCode(PikaObj* self, int32_t errCode) { + obj_setInt(self, "__errCode", errCode); +} + +int32_t obj_getErrorCode(PikaObj* self) { + if (!obj_isArgExist(self, "__errCode")) { + return 0; + } + return obj_getInt(self, "__errCode"); +} + +int32_t args_getErrorCode(Args* args) { + if (!args_isArgExist(args, "__errCode")) { + return 0; + } + return args_getInt(args, "__errCode"); +} + +void obj_setSysOut(PikaObj* self, char* str) { + args_setSysOut(self->list, str); +} + +char* obj_getSysOut(PikaObj* self) { + return obj_getStr(self, "__sysOut"); +} + +void args_setSysOut(Args* args, char* str) { + // args_setStr(args, "__sysOut", str); + if (NULL == str) { + return; + } + if (strEqu("", str)) { + return; + } + pika_platform_printf("%s\r\n", str); +} + +void method_returnBytes(Args* args, uint8_t* val) { + args_pushArg_name(args, "@rt", arg_newBytes(val, PIKA_BYTES_DEFAULT_SIZE)); +} + +void method_returnStr(Args* args, char* val) { + args_pushArg_name(args, "@rt", arg_newStr(val)); +} + +void method_returnInt(Args* args, int64_t val) { + args_pushArg_name(args, "@rt", arg_newInt(val)); +} + +void method_returnFloat(Args* args, pika_float val) { + args_pushArg_name(args, "@rt", arg_newFloat(val)); +} + +void method_returnPtr(Args* args, void* val) { + args_pushArg_name(args, "@rt", arg_newPtr(ARG_TYPE_POINTER, val)); +} + +void method_returnObj(Args* args, void* val) { + if (NULL == val) { + args_pushArg_name(args, "@rt", arg_newNull()); + return; + } + ArgType type; + PikaObj* obj = (PikaObj*)val; + if (obj_getFlag(obj, OBJ_FLAG_ALREADY_INIT)) { + type = ARG_TYPE_OBJECT; + } else { + type = ARG_TYPE_OBJECT_NEW; + } + args_pushArg_name(args, "@rt", arg_newPtr(type, val)); +} + +void method_returnArg(Args* args, Arg* arg) { + args_pushArg_name(args, "@rt", arg); +} + +int64_t method_getInt(Args* args, char* argName) { + return args_getInt(args, argName); +} + +pika_float method_getFloat(Args* args, char* argName) { + return args_getFloat(args, argName); +} + +char* method_getStr(Args* args, char* argName) { + return args_getStr(args, argName); +} + +PikaObj* New_PikaObj(void) { + PikaObj* self = pikaMalloc(sizeof(PikaObj)); + /* List */ + self->list = New_args(NULL); + self->refcnt = 0; + self->constructor = NULL; + self->flag = 0; + return self; +} + +Arg* arg_setObj(Arg* self, char* name, PikaObj* obj) { + return arg_setPtr(self, name, ARG_TYPE_OBJECT, obj); +} + +Arg* arg_setRef(Arg* self, char* name, PikaObj* obj) { + pika_assert(NULL != obj); + obj_refcntInc(obj); + return arg_setObj(self, name, obj); +} + +int32_t obj_newDirectObj(PikaObj* self, char* objName, NewFun newFunPtr) { + Arg* new_obj = arg_newDirectObj(newFunPtr); + new_obj = arg_setName(new_obj, objName); + arg_setType(new_obj, ARG_TYPE_OBJECT); + args_setArg(self->list, new_obj); + return 0; +} + +int32_t obj_newMetaObj(PikaObj* self, char* objName, NewFun newFunPtr) { + /* add meta Obj, no inited */ + Arg* new_obj = arg_newMetaObj(newFunPtr); + new_obj = arg_setName(new_obj, objName); + args_setArg(self->list, new_obj); + return 0; +} + +static void _append_help(char* name) { + if (NULL == _help_modules_cmodule) { + _help_modules_cmodule = (volatile Arg*)arg_newStr(""); + } + Arg* _help = (Arg*)_help_modules_cmodule; + _help = arg_strAppend(_help, name); + _help = arg_strAppend(_help, "\r\n"); + _help_modules_cmodule = (volatile Arg*)_help; +} + +int32_t obj_newObj(PikaObj* self, + char* objName, + char* className, + NewFun newFunPtr) { + /* before init root object */ + if (in_root_obj) { + _append_help(objName); + } + return obj_newMetaObj(self, objName, newFunPtr); +} + +PikaObj* obj_importModuleWithByteCode(PikaObj* self, + char* name, + uint8_t* byteCode) { + PikaObj* New_PikaStdLib_SysObj(Args * args); + if (!obj_isArgExist((PikaObj*)__pikaMain, name)) { + obj_newDirectObj((PikaObj*)__pikaMain, name, New_PikaStdLib_SysObj); + pikaVM_runByteCode(obj_getObj((PikaObj*)__pikaMain, name), + (uint8_t*)byteCode); + } + if (self != (PikaObj*)__pikaMain) { + Arg* module_arg = obj_getArg((PikaObj*)__pikaMain, name); + PikaObj* module_obj = arg_getPtr(module_arg); + obj_setArg(self, name, module_arg); + arg_setIsWeakRef(obj_getArg(self, name), PIKA_TRUE); + pika_assert(argType_isObject(arg_getType(module_arg))); + /* decrase refcnt to avoid circle reference */ + obj_refcntDec(module_obj); + } + return self; +} + +PikaObj* obj_importModuleWithByteCodeFrame(PikaObj* self, + char* name, + ByteCodeFrame* byteCode_frame) { + PikaObj* New_PikaStdLib_SysObj(Args * args); + obj_newDirectObj(self, name, New_PikaStdLib_SysObj); + pikaVM_runByteCodeFrame(obj_getObj(self, name), byteCode_frame); + return self; +} + +PikaObj* obj_linkLibraryFile(PikaObj* self, char* input_file_name) { + obj_newMetaObj(self, "@lib", New_LibObj); + LibObj* lib = obj_getObj(self, "@lib"); + LibObj_loadLibraryFile(lib, input_file_name); + return self; +} + +PikaObj* obj_linkLibrary(PikaObj* self, uint8_t* library_bytes) { + obj_newMetaObj(self, "@lib", New_LibObj); + LibObj* lib = obj_getObj(self, "@lib"); + LibObj_loadLibrary(lib, library_bytes); + obj_setPtr(self, "@libraw", library_bytes); + return self; +} + +void obj_printModules(PikaObj* self) { + LibObj* lib = obj_getObj(self, "@lib"); + pika_platform_printf(arg_getStr((Arg*)_help_modules_cmodule)); + LibObj_printModules(lib); +} + +PikaObj* obj_linkLibObj(PikaObj* self, LibObj* library) { + obj_setPtr(self, "@lib", library); + return self; +} + +uint8_t* obj_getByteCodeFromModule(PikaObj* self, char* module_name) { + /* exit when no found '@lib' */ + if (!obj_isArgExist(self, "@lib")) { + return NULL; + } + /* find module from the library */ + LibObj* lib = obj_getPtr(self, "@lib"); + PikaObj* module = obj_getObj(lib, module_name); + /* exit when no module in '@lib' */ + if (NULL == module) { + return NULL; + } + return obj_getPtr(module, "bytecode"); +} + +int obj_runModule(PikaObj* self, char* module_name) { + uint8_t* bytecode = obj_getByteCodeFromModule(self, module_name); + if (NULL == bytecode) { + return 1; + } + pikaVM_runByteCode(self, bytecode); + return 0; +} + +int obj_importModule(PikaObj* self, char* module_name) { + /* import bytecode of the module */ + uint8_t* bytecode = + obj_getByteCodeFromModule((PikaObj*)__pikaMain, module_name); + if (NULL == bytecode) { + return 1; + } + obj_importModuleWithByteCode(self, module_name, bytecode); + return 0; +} + +char* obj_toStr(PikaObj* self) { + /* clang-format off */ + PIKA_PYTHON( + __res = __str__() + ) + /* clang-format on */ + + /* check method arg */ + Arg* method_arg = obj_getMethodArg(self, "__str__"); + if (NULL != method_arg) { + arg_deinit(method_arg); + const uint8_t bytes[] = { + 0x08, 0x00, 0x00, 0x00, /* instruct array size */ + 0x00, 0x82, 0x01, 0x00, 0x00, 0x04, 0x09, 0x00, /* instruct + array */ + 0x0f, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x73, 0x74, 0x72, 0x5f, 0x5f, 0x00, + 0x5f, 0x5f, 0x72, 0x65, 0x73, 0x00, /* const pool */ + }; + pikaVM_runByteCode(self, (uint8_t*)bytes); + char* str_res = obj_getStr(self, "__res"); + return str_res; + } + + /* normal object */ + Args buffs = {0}; + char* str_res = + strsFormat(&buffs, PIKA_SPRINTF_BUFF_SIZE, "", self); + obj_setStr(self, "__res", str_res); + strsDeinit(&buffs); + return obj_getStr(self, "__res"); +} + +void pks_eventListener_registEvent(PikaEventListener* self, + uint32_t eventId, + PikaObj* eventHandleObj) { + Args buffs = {0}; + char* event_name = + strsFormat(&buffs, PIKA_SPRINTF_BUFF_SIZE, "%ld", eventId); + obj_newDirectObj(self, event_name, New_TinyObj); + PikaObj* event_item = obj_getObj(self, event_name); + obj_setRef(event_item, "eventHandleObj", eventHandleObj); + strsDeinit(&buffs); +} + +void pks_eventListener_removeEvent(PikaEventListener* self, uint32_t eventId) { + Args buffs = {0}; + char* event_name = + strsFormat(&buffs, PIKA_SPRINTF_BUFF_SIZE, "%ld", eventId); + obj_removeArg(self, event_name); + strsDeinit(&buffs); +} + +PikaObj* pks_eventListener_getEventHandleObj(PikaEventListener* self, + uint32_t eventId) { + Args buffs = {0}; + char* event_name = + strsFormat(&buffs, PIKA_SPRINTF_BUFF_SIZE, "%ld", eventId); + PikaObj* event_item = obj_getObj(self, event_name); + PikaObj* eventHandleObj = obj_getPtr(event_item, "eventHandleObj"); + strsDeinit(&buffs); + return eventHandleObj; +} + +void pks_eventListener_init(PikaEventListener** p_self) { + *p_self = newNormalObj(New_TinyObj); +} + +void pks_eventListener_deinit(PikaEventListener** p_self) { + if (NULL != *p_self) { + obj_deinit(*p_self); + *p_self = NULL; + } +} + +Arg* __eventListener_runEvent(PikaEventListener* lisener, + uint32_t eventId, + Arg* eventData) { + PikaObj* handler = pks_eventListener_getEventHandleObj(lisener, eventId); + if (NULL == handler) { + pika_platform_printf( + "Error: can not find event handler by id: [0x%02x]\r\n", eventId); + return NULL; + } + obj_setArg(handler, "eventData", eventData); + /* clang-format off */ + PIKA_PYTHON( + _res = eventCallBack(eventData) + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x0c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x0b, 0x00, 0x00, 0x04, 0x19, 0x00, + /* instruct array */ + 0x1e, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x44, 0x61, 0x74, 0x61, 0x00, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x6c, 0x42, 0x61, 0x63, 0x6b, + 0x00, 0x5f, 0x72, 0x65, 0x73, 0x00, /* const pool */ + }; + pikaVM_runByteCode(handler, (uint8_t*)bytes); + Arg* res = obj_getArg(handler, "_res"); + res = arg_copy(res); + obj_removeArg(handler, "_res"); + return res; +} + +Arg* __eventListener_runEvent_dataInt(PikaEventListener* lisener, + uint32_t eventId, + int eventSignal) { + return __eventListener_runEvent(lisener, eventId, arg_newInt(eventSignal)); +} + +void _do_pks_eventListener_send(PikaEventListener* self, + uint32_t eventId, + Arg* eventData, + PIKA_BOOL pickupWhenNoVM) { +#if !PIKA_EVENT_ENABLE + pika_platform_printf("PIKA_EVENT_ENABLE is not enable"); + while (1) { + }; +#else + /* push event handler to vm event list */ + if (PIKA_RES_OK != __eventListener_pushEvent(self, eventId, eventData)) { + } + if (pickupWhenNoVM) { + if (0 == _VMEvent_getVMCnt()) { + /* no vm running, pick up event imediately */ + _VMEvent_pickupEvent(); + } + } +#endif +} + +void pks_eventListener_send(PikaEventListener* self, + uint32_t eventId, + Arg* eventData) { + _do_pks_eventListener_send(self, eventId, eventData, PIKA_TRUE); +} + +void pks_eventListener_sendSignal(PikaEventListener* self, + uint32_t eventId, + int eventSignal) { + pks_eventListener_send(self, eventId, arg_newInt(eventSignal)); +} + +Arg* pks_eventListener_sendSignalAwaitResult(PikaEventListener* self, + uint32_t eventId, + int eventSignal) { + /* + * Await result from event. + * need implement `pika_platform_thread_delay()` to support thread switch */ +#if !PIKA_EVENT_ENABLE + pika_platform_printf("PIKA_EVENT_ENABLE is not enable"); + while (1) { + }; +#else + extern volatile VMSignal PikaVMSignal; + int tail = PikaVMSignal.cq.tail; + pks_eventListener_sendSignal(self, eventId, eventSignal); + while (1) { + Arg* res = PikaVMSignal.cq.res[tail]; + pika_platform_thread_delay(); + if (NULL != res) { + return res; + } + } +#endif +} + +/* print major version info */ +void pks_printVersion(void) { + pika_platform_printf("pikascript-core==v%d.%d.%d (%s)\r\n", + PIKA_VERSION_MAJOR, PIKA_VERSION_MINOR, + PIKA_VERSION_MICRO, PIKA_EDIT_TIME); +} + +void pks_getVersion(char* buff) { + pika_platform_sprintf(buff, "%d.%d.%d", PIKA_VERSION_MAJOR, + PIKA_VERSION_MINOR, PIKA_VERSION_MICRO); +} + +void* obj_getStruct(PikaObj* self, char* name) { + return args_getStruct(self->list, name); +} + +char* obj_cacheStr(PikaObj* self, char* str) { + return args_cacheStr(self->list, str); +} + +void _obj_updateProxyFlag(PikaObj* self) { + if (!obj_getFlag(self, OBJ_FLAG_PROXY_GETATTRIBUTE)) { + if (NULL != _obj_getProp(self, "__getattribute__")) { + obj_setFlag(self, OBJ_FLAG_PROXY_GETATTRIBUTE); + } + } + if (!obj_getFlag(self, OBJ_FLAG_PROXY_GETATTR)) { + if (NULL != _obj_getProp(self, "__getattr__")) { + obj_setFlag(self, OBJ_FLAG_PROXY_GETATTR); + } + } + if (!obj_getFlag(self, OBJ_FLAG_PROXY_SETATTR)) { + if (NULL != _obj_getProp(self, "__setattr__")) { + obj_setFlag(self, OBJ_FLAG_PROXY_SETATTR); + } + } +}; diff --git a/examples/pikapython/pikapython/pikascript-core/PikaObj.h b/examples/pikapython/pikapython/pikascript-core/PikaObj.h new file mode 100644 index 00000000..fe4ecf2f --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/PikaObj.h @@ -0,0 +1,520 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _Process__H +#define _Process__H + +#include "dataArgs.h" +#include "dataLink.h" +#include "dataMemory.h" +#include "dataStrs.h" + +typedef struct InstructUnit InstructUnit; +struct InstructUnit { + uint8_t deepth; + uint8_t isNewLine_instruct; + uint16_t const_pool_index; +}; + +typedef struct ConstPool ConstPool; +struct ConstPool { + Arg* arg_buff; + uint32_t content_offset_now; + uint32_t size; + void* content_start; + void (*output_redirect_fun)(ConstPool* self, char* content); + FILE* output_f; +}; + +typedef struct InstructArray InstructArray; +struct InstructArray { + Arg* arg_buff; + uint32_t content_offset_now; + uint32_t size; + void* content_start; + void (*output_redirect_fun)(InstructArray* self, InstructUnit* ins_unit); + FILE* output_f; +}; + +typedef struct ByteCodeFrame ByteCodeFrame; +struct ByteCodeFrame { + ConstPool const_pool; + InstructArray instruct_array; +}; + +typedef struct NativeProperty NativeProperty; +struct NativeProperty { + const NativeProperty* super; + const Arg* methodGroup; + uint32_t methodGroupCount; +}; + +typedef struct PikaObj PikaObj; +struct PikaObj { + Args* list; + uint8_t refcnt; + void* constructor; + uint8_t flag; +}; + +typedef struct RangeData RangeData; +struct RangeData { + int64_t start; + int64_t end; + int64_t step; + int64_t i; +}; + +#define OBJ_FLAG_PROXY_GETATTRIBUTE 0x01 +#define OBJ_FLAG_PROXY_GETATTR 0x02 +#define OBJ_FLAG_PROXY_SETATTR 0x04 +#define OBJ_FLAG_ALREADY_INIT 0x08 +#define OBJ_FLAG_RUN_AS 0x16 +#define OBJ_FLAG_GLOBALS 0x32 + +#define KEY_UP 0x41 +#define KEY_DOWN 0x42 +#define KEY_RIGHT 0x43 +#define KEY_LEFT 0x44 + +static inline uint8_t obj_getFlag(PikaObj* self, uint8_t flag) { + return (self->flag & flag) == flag; +} + +static inline void obj_setFlag(PikaObj* self, uint8_t flag) { + self->flag |= flag; +} + +static inline void obj_clearFlag(PikaObj* self, uint8_t flag) { + self->flag &= ~flag; +} + +typedef PikaObj* (*NewFun)(Args* args); +typedef PikaObj* (*InitFun)(PikaObj* self, Args* args); +typedef PikaObj VMParameters; +typedef void (*Method)(PikaObj* self, Args* args); + +typedef struct MethodInfo MethodInfo; +struct MethodInfo { + char* name; + char* dec; + char* ptr; + char* typelist; + PikaObj* def_context; + ArgType type; + ByteCodeFrame* bytecode_frame; +}; + +typedef struct MethodProp { + void* ptr; + char* type_list; + char* name; + ByteCodeFrame* bytecode_frame; + PikaObj* def_context; + char* declareation; +} MethodProp; + +typedef struct MethodPropNative { + void* ptr; + char* type_list; +#if !PIKA_NANO_ENABLE + char* name; +#endif +} MethodPropNative; + +typedef PikaObj LibObj; +typedef PikaObj PikaMaker; + +/* operation */ +int32_t obj_deinit(PikaObj* self); +int32_t obj_init(PikaObj* self, Args* args); +int32_t obj_update(PikaObj* self); +int32_t obj_enable(PikaObj* self); +int32_t obj_disable(PikaObj* self); + +// arg type operations +PIKA_RES obj_setInt(PikaObj* self, char* argPath, int64_t val); +PIKA_RES obj_setRef(PikaObj* self, char* argPath, PikaObj* pointer); +PIKA_RES obj_setPtr(PikaObj* self, char* argPath, void* pointer); +PIKA_RES obj_setFloat(PikaObj* self, char* argPath, pika_float value); +PIKA_RES obj_setStr(PikaObj* self, char* argPath, char* str); +PIKA_RES obj_setNone(PikaObj* self, char* argPath); +PIKA_RES obj_setArg(PikaObj* self, char* argPath, Arg* arg); +PIKA_RES obj_setArg_noCopy(PikaObj* self, char* argPath, Arg* arg); +PIKA_RES obj_setBytes(PikaObj* self, char* argPath, uint8_t* src, size_t size); + +void* obj_getPtr(PikaObj* self, char* argPath); +pika_float obj_getFloat(PikaObj* self, char* argPath); +char* obj_getStr(PikaObj* self, char* argPath); +int64_t obj_getInt(PikaObj* self, char* argPath); +Arg* obj_getArg(PikaObj* self, char* argPath); +uint8_t* obj_getBytes(PikaObj* self, char* argPath); +size_t obj_getBytesSize(PikaObj* self, char* argPath); +size_t obj_loadBytes(PikaObj* self, char* argPath, uint8_t* out_buff); + +char* obj_print(PikaObj* self, char* name); + +// args operations +int32_t obj_load(PikaObj* self, Args* args, char* name); + +// subObject +int32_t obj_addOther(PikaObj* self, char* subObjectName, void* new_projcetFun); +PikaObj* obj_getObj(PikaObj* self, char* objPath); +PikaObj* obj_getHostObj(PikaObj* self, char* objPath); +PikaObj* obj_getHostObjWithIsTemp(PikaObj* self, + char* objPath, + PIKA_BOOL* pIsClass); + +// subProcess +int32_t obj_freeObj(PikaObj* self, char* subObjectName); + +/* method */ +int32_t class_defineMethod(PikaObj* self, + char* name, + char* typelist, + Method methodPtr); + +int32_t class_defineObjectMethod(PikaObj* self, + char* declareation, + Method methodPtr, + PikaObj* def_context, + ByteCodeFrame* bytecode_frame); + +int32_t class_defineStaticMethod(PikaObj* self, + char* declareation, + Method methodPtr, + PikaObj* def_context, + ByteCodeFrame* bytecode_frame); + +int32_t class_defineConstructor(PikaObj* self, + char* name, + char* typelist, + Method methodPtr); + +int32_t class_defineRunTimeConstructor(PikaObj* self, + char* declareation, + Method methodPtr, + PikaObj* def_context, + ByteCodeFrame* bytecode_frame); + +int32_t obj_removeArg(PikaObj* self, char* argPath); +int32_t obj_isArgExist(PikaObj* self, char* argPath); +PikaObj* obj_getClassObjByNewFun(PikaObj* self, char* name, NewFun newClassFun); +PikaObj* newRootObj(char* name, NewFun newObjFun); +PikaObj* obj_getClassObj(PikaObj* obj); +Arg* obj_getMethodArg(PikaObj* obj, char* methodPath); +Arg* obj_getMethodArg_noalloc(PikaObj* obj, char* methodPath, Arg* arg_reg); + +void obj_setErrorCode(PikaObj* self, int32_t errCode); +int32_t obj_getErrorCode(PikaObj* self); +void obj_setSysOut(PikaObj* self, char* str); +char* args_getSysOut(Args* args); +void args_setErrorCode(Args* args, int32_t errCode); +int32_t args_getErrorCode(Args* args); +void args_setSysOut(Args* args, char* str); +char* obj_getSysOut(PikaObj* self); +void obj_sysPrintf(PikaObj* self, char* fmt, ...); +uint8_t obj_getAnyArg(PikaObj* self, + char* targetArgName, + char* sourceArgPath, + Args* targetArgs); + +void method_returnStr(Args* args, char* val); +void method_returnInt(Args* args, int64_t val); +void method_returnFloat(Args* args, pika_float val); +void method_returnPtr(Args* args, void* val); +void method_returnObj(Args* args, void* val); +int64_t method_getInt(Args* args, char* argName); +pika_float method_getFloat(Args* args, char* argName); +char* method_getStr(Args* args, char* argName); +void method_returnArg(Args* args, Arg* arg); +char* methodArg_getDec(Arg* method_arg); +char* methodArg_getTypeList(Arg* method_arg, char* buffs, size_t size); +char* methodArg_getName(Arg* method_arg, char* buffs, size_t size); +ByteCodeFrame* methodArg_getBytecodeFrame(Arg* method_arg); +Method methodArg_getPtr(Arg* method_arg); + +VMParameters* obj_run(PikaObj* self, char* cmd); +PikaObj* New_PikaObj(void); + +/* tools */ +int64_t fast_atoi(char* src); +char* fast_itoa(char* buf, uint32_t val); + +/* shell */ +void pikaScriptShell(PikaObj* self); +enum shellCTRL { SHELL_CTRL_CONTINUE, SHELL_CTRL_EXIT }; + +typedef struct ShellConfig ShellConfig; +typedef enum shellCTRL (*sh_handler)(PikaObj*, char*, ShellConfig*); +typedef char (*sh_getchar)(void); + +struct ShellConfig { + char* prefix; + sh_handler handler; + void* context; + char lineBuff[PIKA_LINE_BUFF_SIZE]; + size_t line_position; + size_t line_curpos; + char* blockBuffName; + PIKA_BOOL inBlock; + char lastChar; + sh_getchar fn_getchar; + uint8_t stat; +}; + +void _do_pikaScriptShell(PikaObj* self, ShellConfig* cfg); + +void _temp__do_pikaScriptShell(PikaObj* self, ShellConfig* cfg); + +/* + need implament : + pika_platform_fopen() + pika_platform_fwrite() + pika_platform_fclose() +*/ +Method obj_getNativeMethod(PikaObj* self, char* method_name); +PIKA_RES obj_runNativeMethod(PikaObj* self, char* method_name, Args* args); +Arg* obj_newObjInPackage(NewFun newObjFun); + +PikaObj* newNormalObj(NewFun newObjFun); +Arg* arg_setRef(Arg* self, char* name, PikaObj* obj); +Arg* arg_setObj(Arg* self, char* name, PikaObj* obj); + +static inline Arg* arg_newObj(PikaObj* obj) { + return arg_setObj(NULL, "", (obj)); +} + +static inline Arg* arg_newRef(PikaObj* obj) { + return arg_setRef(NULL, "", (obj)); +} + +PikaObj* obj_importModuleWithByteCodeFrame(PikaObj* self, + char* name, + ByteCodeFrame* bytecode_frame); +PikaObj* obj_importModuleWithByteCode(PikaObj* self, + char* name, + uint8_t* byteCode); + +int32_t obj_newObj(PikaObj* self, + char* objName, + char* className, + NewFun newFunPtr); + +Arg* arg_newMetaObj(NewFun objPtr); +PikaObj* obj_linkLibObj(PikaObj* self, LibObj* library); +PikaObj* obj_linkLibrary(PikaObj* self, uint8_t* library_bytes); +int obj_importModule(PikaObj* self, char* module_name); +int32_t obj_newMetaObj(PikaObj* self, char* objName, NewFun newFunPtr); +int32_t obj_newDirectObj(PikaObj* self, char* objName, NewFun newFunPtr); +int obj_runModule(PikaObj* self, char* module_name); +char* obj_toStr(PikaObj* self); +Arg* arg_newDirectObj(NewFun new_obj_fun); +enum shellCTRL obj_runChar(PikaObj* self, char inputChar); + +#define PIKA_PYTHON_BEGIN +#define PIKA_PYTHON(x) +#define PIKA_PYTHON_END + +typedef PikaObj PikaEventListener; + +void pks_eventListener_registEvent(PikaEventListener* self, + uint32_t eventId, + PikaObj* eventHandleObj); + +void pks_eventListener_removeEvent(PikaEventListener* self, uint32_t eventId); + +void _do_pks_eventListener_send(PikaEventListener* self, + uint32_t eventId, + Arg* eventData, + PIKA_BOOL pickupWhenNoVM); + +void pks_eventListener_sendSignal(PikaEventListener* self, + uint32_t eventId, + int eventSignal); + +void pks_eventListener_send(PikaEventListener* self, + uint32_t eventId, + Arg* eventData); + +PikaObj* pks_eventListener_getEventHandleObj(PikaEventListener* self, + uint32_t eventId); + +void pks_eventListener_init(PikaEventListener** p_self); +void pks_eventListener_deinit(PikaEventListener** p_self); +PikaObj* methodArg_getDefContext(Arg* method_arg); +PikaObj* obj_linkLibraryFile(PikaObj* self, char* input_file_name); +NewFun obj_getClass(PikaObj* obj); + +void pks_printVersion(void); +void pks_getVersion(char* buff); +void* obj_getStruct(PikaObj* self, char* name); + +static inline void obj_refcntDec(PikaObj* self) { + self->refcnt--; +} + +static inline void obj_refcntInc(PikaObj* self) { + self->refcnt++; +} + +static inline uint8_t obj_refcntNow(PikaObj* self) { + return self->refcnt; +} + +#define obj_setStruct(PikaObj_p_self, char_p_name, struct_) \ + args_setStruct(((PikaObj_p_self)->list), char_p_name, struct_) + +#define ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(_) \ + obj_setErrorCode(self, 1); \ + pika_platform_printf("Error: abstract method `%s()` need override.\r\n", \ + __FUNCTION__) + +char* obj_cacheStr(PikaObj* self, char* str); +PikaObj* _arg_to_obj(Arg* self, PIKA_BOOL* pIsTemp); +char* __printBytes(PikaObj* self, Arg* arg); + +#define PIKASCRIPT_VERSION_TO_NUM(majer, minor, micro) \ + majer * 100 * 100 + minor * 100 + micro + +#define PIKASCRIPT_VERSION_NUM \ + PIKASCRIPT_VERSION_TO_NUM(PIKA_VERSION_MAJOR, PIKA_VERSION_MINOR, \ + PIKA_VERSION_MICRO) + +#define PIKASCRIPT_VERSION_REQUIRE_MINIMUN(majer, minor, micro) \ + (PIKASCRIPT_VERSION_NUM >= PIKASCRIPT_VERSION_TO_NUM(majer, minor, micro)) + +/* [example] +const MethodProp floatMethod = { + .ptr = (void*)PikaStdLib_SysObj_floatMethod, + .bytecode_frame = NULL, + .def_context = NULL, + .declareation = "float(arg)", + .type_list = "arg", + .name = "float", +}; +*/ + +#if !PIKA_NANO_ENABLE +#define method_typedef(_method, _name, _typelist) \ + const MethodPropNative _method##Prop = { \ + .ptr = (void*)_method##Method, \ + .type_list = _typelist, \ + .name = _name, \ + }; +#else +#define method_typedef(_method, _name, _typelist) \ + const MethodPropNative _method##Prop = { \ + .ptr = (void*)_method##Method, \ + .type_list = _typelist, \ + }; +#endif + +/* clang-format off */ +#if PIKA_ARG_CACHE_ENABLE +#define _method_def(_method, _hash, _type) \ + { \ + ._ = \ + { \ + .buffer = (uint8_t*)&_method##Prop \ + }, \ + .size = sizeof(MethodPropNative), \ + .heap_size = 0, \ + .type = _type, \ + .flag = 0, \ + .name_hash = _hash \ + } +#else +#define _method_def(_method, _hash, _type) \ + { \ + ._ = \ + { \ + .buffer = (uint8_t*)&_method##Prop \ + }, \ + .size = sizeof(MethodPropNative), \ + .type = _type, \ + .flag = 0, \ + .name_hash = _hash \ + } +#endif + +#if defined(_WIN32) || \ + (defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 6000000)) +#define __BEFORE_MOETHOD_DEF \ + { \ + ._ = \ + { \ + .buffer = NULL \ + }, \ + .size = 0, \ + .type = ARG_TYPE_NONE, \ + .flag = 0, \ + .name_hash = 0 \ + }, +#else +#define __BEFORE_MOETHOD_DEF +#endif +/* clang-format on */ + +#define method_def(_method, _hash) \ + _method_def(_method, _hash, ARG_TYPE_METHOD_NATIVE) +#define constructor_def(_method, _hash) \ + _method_def(_method, _hash, ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR) +#define class_def(_class) const ConstArg _class##Collect[] = + +#define class_inhert(_class, _super) \ + extern const NativeProperty _super##NativeProp; \ + const NativeProperty _class##NativeProp = { \ + .super = &_super##NativeProp, \ + .methodGroup = (Arg*)_class##Collect, \ + .methodGroupCount = \ + sizeof(_class##Collect) / sizeof(_class##Collect[0]), \ + } + +#define pika_class(_method) _method##NativeProp + +void _obj_updateProxyFlag(PikaObj* self); +#define obj_setClass(_self, _method) \ + obj_setPtr((_self), "@p", (void*)&pika_class(_method)); \ + _obj_updateProxyFlag((_self)) + +Arg* _obj_getProp(PikaObj* obj, char* name); +Arg* __eventListener_runEvent_dataInt(PikaEventListener* lisener, + uint32_t eventId, + int eventSignal); + +Arg* __eventListener_runEvent(PikaEventListener* lisener, + uint32_t eventId, + Arg* eventData); + +Arg* pks_eventListener_sendSignalAwaitResult(PikaEventListener* self, + uint32_t eventId, + int eventSignal); + +void obj_printModules(PikaObj* self); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/PikaParser.c b/examples/pikapython/pikapython/pikascript-core/PikaParser.c new file mode 100644 index 00000000..5e3ce0ab --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/PikaParser.c @@ -0,0 +1,3139 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "PikaParser.h" +#include "BaseObj.h" +#include "PikaObj.h" +#include "dataQueue.h" +#include "dataQueueObj.h" +#include "dataStack.h" +#include "dataStrs.h" + +/* local head */ +typedef QueueObj AST; +char* Lexer_getTokenStream(Args* outBuffs, char* stmt); +char* AST_genAsm(AST* ast, Args* outBuffs); +int32_t AST_deinit(AST* ast); + +uint8_t TokenStream_isContain(char* tokenStream, + enum TokenType token_type, + char* pyload); +char* TokenStream_pop(Args* buffs_p, char** tokenStream); + +/* Cursor preivilage */ +void _Cursor_init(struct Cursor* cs); +void _Cursor_parse(struct Cursor* cs, char* stmt); +void _Cursor_beforeIter(struct Cursor* cs); + +/* Cursor iter api */ +void Cursor_iterStart(struct Cursor* cs); +void Cursor_iterEnd(struct Cursor* cs); +void Cursor_deinit(struct Cursor* cs); + +/* Cursor high level api */ +char* Cursor_popToken(Args* buffs, char** stmt, char* devide); +PIKA_BOOL Cursor_isContain(char* stmt, TokenType type, char* pyload); + +char* Parser_linesToAsm(Args* outBuffs, char* multiLine); +uint16_t TokenStream_getSize(char* tokenStream) { + if (strEqu("", tokenStream)) { + return 0; + } + return strCountSign(tokenStream, 0x1F) + 1; +} + +char* strsPopTokenWithSkip_byStr(Args* outBuffs, + char* stmts, + char* str, + char skipStart, + char skipEnd) { + uint8_t divider_index = 0; + Arg* keeped_arg = arg_newStr(""); + Arg* poped_arg = arg_newStr(""); + Cursor_forEachToken(cs, stmts) { + Cursor_iterStart(&cs); + if (cs.branket_deepth == 0) { + if (strEqu(str, cs.token1.pyload)) { + divider_index = cs.iter_index; + } + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + Cursor_forEachTokenExistPs(cs, stmts) { + Cursor_iterStart(&cs); + if (cs.iter_index < divider_index) { + poped_arg = arg_strAppend(poped_arg, cs.token1.pyload); + } + if (cs.iter_index > divider_index) { + keeped_arg = arg_strAppend(keeped_arg, cs.token1.pyload); + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + char* keeped = arg_getStr(keeped_arg); + char* poped = strsCopy(outBuffs, arg_getStr(poped_arg)); + pika_platform_memcpy(stmts, keeped, strGetSize(keeped) + 1); + arg_deinit(poped_arg); + arg_deinit(keeped_arg); + return poped; +} + +char* strsGetCleanCmd(Args* outBuffs, char* cmd) { + pika_assert(cmd != NULL); + int32_t size = strGetSize(cmd); + /* lexer may generate more chars than input */ + char* strOut = args_getBuff(outBuffs, size * 2); + int32_t iOut = 0; + Cursor_forEachToken(cs, cmd) { + Cursor_iterStart(&cs); + for (uint16_t k = 0; k < strGetSize(cs.token1.pyload); k++) { + strOut[iOut] = cs.token1.pyload[k]; + iOut++; + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + /* add \0 */ + strOut[iOut] = 0; + return strOut; +} + +static uint8_t Lexer_isError(char* line) { + Args buffs = {0}; + uint8_t res = 0; /* not error */ + char* tokenStream = Lexer_getTokenStream(&buffs, line); + if (NULL == tokenStream) { + res = 1; /* lex error */ + goto exit; + } + goto exit; +exit: + strsDeinit(&buffs); + return res; +} + +static char* Cursor_removeTokensBetween(Args* outBuffs, + char* input, + char* token_pyload1, + char* token_pyload2) { + Args buffs = {0}; + uint8_t block_deepth = 0; + char* output = ""; + Cursor_forEachToken(cs, input) { + Cursor_iterStart(&cs); + if (strEqu(token_pyload1, cs.token1.pyload)) { + if (block_deepth == 0) { + output = strsAppend(&buffs, output, cs.token1.pyload); + } + block_deepth++; + } + if (strEqu(token_pyload2, cs.token1.pyload)) { + block_deepth--; + } + if (block_deepth == 0) { + output = strsAppend(&buffs, output, cs.token1.pyload); + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + output = strsCopy(outBuffs, output); + strsDeinit(&buffs); + return output; +} + +char* _remove_sub_stmt(Args* outBuffs, char* stmt) { + Args buffs = {0}; + stmt = strsCopy(&buffs, stmt); + stmt = Cursor_removeTokensBetween(&buffs, stmt, "(", ")"); + stmt = Cursor_removeTokensBetween(&buffs, stmt, "[", "]"); + stmt = Cursor_removeTokensBetween(&buffs, stmt, "{", "}"); + char* res = args_cacheStr(outBuffs, stmt); + strsDeinit(&buffs); + return res; +} + +static enum StmtType Lexer_matchStmtType(char* right) { + Args buffs = {0}; + enum StmtType stmtType = STMT_none; + char* rightWithoutSubStmt = _remove_sub_stmt(&buffs, right); + + PIKA_BOOL is_get_operator = PIKA_FALSE; + PIKA_BOOL is_get_method = PIKA_FALSE; + PIKA_BOOL is_get_string = PIKA_FALSE; + PIKA_BOOL is_get_bytes = PIKA_FALSE; + PIKA_BOOL is_get_number = PIKA_FALSE; + PIKA_BOOL is_get_symbol = PIKA_FALSE; + PIKA_BOOL is_get_list = PIKA_FALSE; + PIKA_BOOL is_get_slice = PIKA_FALSE; + PIKA_BOOL is_get_dict = PIKA_FALSE; + PIKA_BOOL is_get_import = PIKA_FALSE; + PIKA_BOOL is_get_chain = PIKA_FALSE; + Cursor_forEachToken(cs, rightWithoutSubStmt) { + Cursor_iterStart(&cs); + /* collect type */ + if (strEqu(cs.token1.pyload, " import ")) { + is_get_import = PIKA_TRUE; + goto iter_continue; + } + if (strEqu(cs.token2.pyload, "[")) { + /* (symble | iteral | <]> | <)>) + <[> */ + if (TOKEN_symbol == cs.token1.type || + TOKEN_literal == cs.token1.type || + strEqu(cs.token1.pyload, "]") || + strEqu(cs.token1.pyload, ")")) { + is_get_slice = PIKA_TRUE; + goto iter_continue; + } + /* ( <,> | <=> ) + <[> */ + is_get_list = PIKA_TRUE; + } + if (strEqu(cs.token1.pyload, "[") && cs.iter_index == 1) { + /* VOID + <[> */ + is_get_list = PIKA_TRUE; + goto iter_continue; + } + if (strEqu(cs.token1.pyload, "...")) { + goto iter_continue; + } + + if (strEqu(cs.token1.pyload, "pass")) { + goto iter_continue; + } + + if (strIsStartWith(cs.token1.pyload, ".")) { + if (cs.iter_index != 1) { + is_get_chain = PIKA_TRUE; + goto iter_continue; + } + } + if (strEqu(cs.token1.pyload, "{")) { + is_get_dict = PIKA_TRUE; + goto iter_continue; + } + if (cs.token1.type == TOKEN_operator) { + is_get_operator = PIKA_TRUE; + goto iter_continue; + } + /* <(> */ + if (strEqu(cs.token1.pyload, "(")) { + is_get_method = PIKA_TRUE; + goto iter_continue; + } + if (cs.token1.type == TOKEN_literal) { + if (cs.token1.pyload[0] == '\'' || cs.token1.pyload[0] == '"') { + is_get_string = PIKA_TRUE; + goto iter_continue; + } + if (cs.token1.pyload[1] == '\'' || cs.token1.pyload[1] == '"') { + if (cs.token1.pyload[0] == 'b') { + is_get_bytes = PIKA_TRUE; + goto iter_continue; + } + } + is_get_number = PIKA_TRUE; + goto iter_continue; + } + if (cs.token1.type == TOKEN_symbol) { + is_get_symbol = PIKA_TRUE; + goto iter_continue; + } + iter_continue: + Cursor_iterEnd(&cs); + } + if (is_get_import) { + stmtType = STMT_import; + goto exit; + } + if (is_get_operator) { + stmtType = STMT_operator; + goto exit; + } + if (is_get_chain) { + stmtType = STMT_chain; + goto exit; + } + if (is_get_slice) { + stmtType = STMT_slice; + goto exit; + } + if (is_get_list) { + stmtType = STMT_list; + goto exit; + } + if (is_get_dict) { + stmtType = STMT_dict; + goto exit; + } + if (is_get_method) { + stmtType = STMT_method; + goto exit; + } + if (is_get_string) { + /* support multi assign */ + if (Cursor_isContain(right, TOKEN_devider, ",")) { + stmtType = STMT_tuple; + goto exit; + } + stmtType = STMT_string; + goto exit; + } + if (is_get_bytes) { + /* support multi assign */ + if (Cursor_isContain(right, TOKEN_devider, ",")) { + stmtType = STMT_tuple; + goto exit; + } + stmtType = STMT_bytes; + goto exit; + } + if (is_get_number) { + /* support multi assign */ + if (Cursor_isContain(right, TOKEN_devider, ",")) { + stmtType = STMT_tuple; + goto exit; + } + stmtType = STMT_number; + goto exit; + } + if (is_get_symbol) { + /* support multi assign */ + if (Cursor_isContain(right, TOKEN_devider, ",")) { + stmtType = STMT_tuple; + goto exit; + } + stmtType = STMT_reference; + goto exit; + } +exit: + Cursor_deinit(&cs); + strsDeinit(&buffs); + return stmtType; +} + +char* Lexer_printTokenStream(Args* outBuffs, char* tokenStream) { + pika_assert(tokenStream); + /* init */ + Args buffs = {0}; + char* printOut = strsCopy(&buffs, ""); + + /* process */ + uint16_t token_size = TokenStream_getSize(tokenStream); + for (uint16_t i = 0; i < token_size; i++) { + char* token = TokenStream_pop(&buffs, &tokenStream); + if (token[0] == TOKEN_operator) { + printOut = strsAppend(&buffs, printOut, "{opt}"); + printOut = strsAppend(&buffs, printOut, token + 1); + } + if (token[0] == TOKEN_devider) { + printOut = strsAppend(&buffs, printOut, "{dvd}"); + printOut = strsAppend(&buffs, printOut, token + 1); + } + if (token[0] == TOKEN_symbol) { + printOut = strsAppend(&buffs, printOut, "{sym}"); + printOut = strsAppend(&buffs, printOut, token + 1); + } + if (token[0] == TOKEN_literal) { + printOut = strsAppend(&buffs, printOut, "{lit}"); + printOut = strsAppend(&buffs, printOut, token + 1); + } + } + /* out put */ + printOut = strsCopy(outBuffs, printOut); + strsDeinit(&buffs); + return printOut; +} + +uint8_t Parser_checkIsDirect(char* str) { + Args buffs = {0}; + uint8_t res = 0; + pika_assert(NULL != str); + if (Cursor_isContain(str, TOKEN_operator, "=")) { + res = 1; + goto exit; + } +exit: + strsDeinit(&buffs); + return res; +} + +Arg* Lexer_setToken(Arg* tokenStream_arg, + enum TokenType token_type, + char* + operator) { + Args buffs = {0}; + char token_type_buff[3] = {0}; + token_type_buff[0] = 0x1F; + token_type_buff[1] = token_type; + char* tokenStream = arg_getStr(tokenStream_arg); + tokenStream = strsAppend(&buffs, tokenStream, token_type_buff); + tokenStream = strsAppend(&buffs, tokenStream, operator); + Arg* new_tokenStream_arg = arg_newStr(tokenStream); + arg_deinit(tokenStream_arg); + strsDeinit(&buffs); + return new_tokenStream_arg; +} + +Arg* Lexer_setSymbel(Arg* tokenStream_arg, + char* stmt, + int32_t i, + int32_t* symbol_start_index) { + Args buffs = {0}; + char* symbol_buff = NULL; + if (-1 == *symbol_start_index) { + /* no found symbol start index */ + goto exit; + } + /* nothing to add symbel */ + if (i == *symbol_start_index) { + goto exit; + } + symbol_buff = args_getBuff(&buffs, i - *symbol_start_index); + pika_platform_memcpy(symbol_buff, stmt + *symbol_start_index, + i - *symbol_start_index); + /* literal */ + if ((symbol_buff[0] == '\'') || (symbol_buff[0] == '"')) { + /* "" or '' */ + tokenStream_arg = + Lexer_setToken(tokenStream_arg, TOKEN_literal, symbol_buff); + goto exit; + } + + if ((symbol_buff[0] >= '0') && (symbol_buff[0] <= '9')) { + /* number */ + tokenStream_arg = + Lexer_setToken(tokenStream_arg, TOKEN_literal, symbol_buff); + goto exit; + } + + if ((symbol_buff[0] == 'b') && + ((symbol_buff[1] == '\'') || (symbol_buff[1] == '"'))) { + /* b"" or b'' */ + tokenStream_arg = + Lexer_setToken(tokenStream_arg, TOKEN_literal, symbol_buff); + goto exit; + } + + /* symbol */ + tokenStream_arg = + Lexer_setToken(tokenStream_arg, TOKEN_symbol, symbol_buff); + goto exit; +exit: + *symbol_start_index = -1; + strsDeinit(&buffs); + return tokenStream_arg; +} + +/* tokenStream is devided by space */ +/* a token is [TOKENTYPE|(CONTENT)] */ +char* Lexer_getTokenStream(Args* outBuffs, char* stmt) { + /* init */ + Arg* tokenStream_arg = New_arg(NULL); + tokenStream_arg = arg_setStr(tokenStream_arg, "", ""); + int32_t size = strGetSize(stmt); + uint8_t bracket_deepth = 0; + uint8_t cn2 = 0; + uint8_t cn1 = 0; + uint8_t c0 = 0; + uint8_t c1 = 0; + uint8_t c2 = 0; + uint8_t c3 = 0; + uint8_t c4 = 0; + uint8_t c5 = 0; + uint8_t c6 = 0; + int32_t symbol_start_index = -1; + int is_in_string = 0; + int is_number = 0; + char* tokenStream; + + /* process */ + for (int32_t i = 0; i < size; i++) { + /* update char */ + cn2 = 0; + cn1 = 0; + c0 = stmt[i]; + c1 = 0; + c2 = 0; + c3 = 0; + c4 = 0; + c5 = 0; + c6 = 0; + if (i - 2 >= 0) { + cn2 = stmt[i - 2]; + } + if (i - 1 >= 0) { + cn1 = stmt[i - 1]; + } + if (i + 1 < size) { + c1 = stmt[i + 1]; + } + if (i + 2 < size) { + c2 = stmt[i + 2]; + } + if (i + 3 < size) { + c3 = stmt[i + 3]; + } + if (i + 4 < size) { + c4 = stmt[i + 4]; + } + if (i + 5 < size) { + c5 = stmt[i + 5]; + } + if (i + 6 < size) { + c6 = stmt[i + 6]; + } + if (-1 == symbol_start_index) { + is_number = 0; + if ((c0 >= '0') && (c0 <= '9')) { + is_number = 1; + } + symbol_start_index = i; + } + + /* solve string */ + if (0 == is_in_string) { + if ('\'' == c0) { + if ('\\' != cn1 || ('\\' == cn1 && '\\' == cn2)) { + /* in ' */ + is_in_string = 1; + continue; + } + } + if ('"' == c0) { + if ('\\' != cn1 || ('\\' == cn1 && '\\' == cn2)) { + /* in "" */ + is_in_string = 2; + continue; + } + } + } + + if (1 == is_in_string) { + if ('\'' == c0 && ('\\' != cn1 || ('\\' == cn1 && '\\' == cn2))) { + is_in_string = 0; + tokenStream_arg = Lexer_setSymbel(tokenStream_arg, stmt, i + 1, + &symbol_start_index); + } + continue; + } + if (2 == is_in_string) { + if ('"' == c0 && ('\\' != cn1 || ('\\' == cn1 && '\\' == cn2))) { + is_in_string = 0; + tokenStream_arg = Lexer_setSymbel(tokenStream_arg, stmt, i + 1, + &symbol_start_index); + } + continue; + } + + /* match annotation */ + if ('#' == c0) { + break; + } + + /* match devider*/ + if (('(' == c0) || (')' == c0) || (',' == c0) || ('[' == c0) || + (']' == c0) || (':' == c0) || ('{' == c0) || ('}' == c0)) { + tokenStream_arg = + Lexer_setSymbel(tokenStream_arg, stmt, i, &symbol_start_index); + char content[2] = {0}; + content[0] = c0; + tokenStream_arg = + Lexer_setToken(tokenStream_arg, TOKEN_devider, content); + if (c0 == '(') { + bracket_deepth++; + } + if (c0 == ')') { + bracket_deepth--; + } + continue; + } + /* match operator */ + if (('>' == c0) || ('<' == c0) || ('*' == c0) || ('/' == c0) || + ('+' == c0) || ('-' == c0) || ('!' == c0) || ('=' == c0) || + ('%' == c0) || ('&' == c0) || ('|' == c0) || ('^' == c0) || + ('~' == c0)) { + if ('-' == c0 && is_number) { + if ((cn1 == 'e') || (cn1 == 'E')) { + continue; + } + } + if (('*' == c0) || ('/' == c0)) { + /* + =, **=, // + */ + if ((c0 == c1) && ('=' == c2)) { + char content[4] = {0}; + content[0] = c0; + content[1] = c1; + content[2] = '='; + tokenStream_arg = Lexer_setSymbel(tokenStream_arg, stmt, i, + &symbol_start_index); + tokenStream_arg = Lexer_setToken(tokenStream_arg, + TOKEN_operator, content); + i = i + 2; + continue; + } + } + /* + >>, <<, **, // + */ + if (('>' == c0) || ('<' == c0) || ('*' == c0) || ('/' == c0)) { + if (c0 == c1) { + char content[3] = {0}; + content[0] = c0; + content[1] = c1; + tokenStream_arg = Lexer_setSymbel(tokenStream_arg, stmt, i, + &symbol_start_index); + tokenStream_arg = Lexer_setToken(tokenStream_arg, + TOKEN_operator, content); + i = i + 1; + continue; + } + } + /* + >=, <=, *=, /=, +=, -=, !=, ==, %= + */ + if (('>' == c0) || ('<' == c0) || ('*' == c0) || ('/' == c0) || + ('+' == c0) || ('-' == c0) || ('!' == c0) || ('=' == c0) || + ('%' == c0)) { + if ('=' == c1) { + char content[3] = {0}; + content[0] = c0; + content[1] = c1; + tokenStream_arg = Lexer_setSymbel(tokenStream_arg, stmt, i, + &symbol_start_index); + tokenStream_arg = Lexer_setToken(tokenStream_arg, + TOKEN_operator, content); + i = i + 1; + continue; + } + } + + /* single operator */ + /* + +, -, *, ... / + */ + char content[2] = {0}; + content[0] = c0; + tokenStream_arg = + Lexer_setSymbel(tokenStream_arg, stmt, i, &symbol_start_index); + tokenStream_arg = + Lexer_setToken(tokenStream_arg, TOKEN_operator, content); + continue; + } + + // not the string operator + if ((cn1 >= 'a' && cn1 <= 'z') || (cn1 >= 'A' && cn1 <= 'Z') || + (cn1 >= '0' && cn1 <= '9') || cn1 == '_' || cn1 == '.') { + goto after_match_string_operator; + } + /* not */ + if ('n' == c0) { + if (('o' == c1) && ('t' == c2) && (' ' == c3)) { + tokenStream_arg = Lexer_setSymbel(tokenStream_arg, stmt, i, + &symbol_start_index); + tokenStream_arg = + Lexer_setToken(tokenStream_arg, TOKEN_operator, " not "); + i = i + 3; + continue; + } + } + /* and */ + if ('a' == c0) { + if (('n' == c1) && ('d' == c2) && (' ' == c3)) { + tokenStream_arg = Lexer_setSymbel(tokenStream_arg, stmt, i, + &symbol_start_index); + tokenStream_arg = + Lexer_setToken(tokenStream_arg, TOKEN_operator, " and "); + i = i + 3; + continue; + } + } + /* or */ + if ('o' == c0) { + if (('r' == c1) && (' ' == c2)) { + tokenStream_arg = Lexer_setSymbel(tokenStream_arg, stmt, i, + &symbol_start_index); + tokenStream_arg = + Lexer_setToken(tokenStream_arg, TOKEN_operator, " or "); + i = i + 2; + continue; + } + } + /* is */ + if ('i' == c0) { + if (('s' == c1) && (' ' == c2)) { + tokenStream_arg = Lexer_setSymbel(tokenStream_arg, stmt, i, + &symbol_start_index); + tokenStream_arg = + Lexer_setToken(tokenStream_arg, TOKEN_operator, " is "); + i = i + 2; + continue; + } + } + /* in */ + if ('i' == c0) { + if (('n' == c1) && (' ' == c2)) { + tokenStream_arg = Lexer_setSymbel(tokenStream_arg, stmt, i, + &symbol_start_index); + tokenStream_arg = + Lexer_setToken(tokenStream_arg, TOKEN_operator, " in "); + i = i + 2; + continue; + } + } + /* as */ + if ('a' == c0) { + if (('s' == c1) && (' ' == c2)) { + tokenStream_arg = Lexer_setSymbel(tokenStream_arg, stmt, i, + &symbol_start_index); + tokenStream_arg = + Lexer_setToken(tokenStream_arg, TOKEN_operator, " as "); + i = i + 2; + continue; + } + } + /* import */ + if ('i' == c0) { + if (('m' == c1) && ('p' == c2) && ('o' == c3) && ('r' == c4) && + ('t' == c5) && (' ' == c6)) { + tokenStream_arg = Lexer_setSymbel(tokenStream_arg, stmt, i, + &symbol_start_index); + tokenStream_arg = + Lexer_setToken(tokenStream_arg, TOKEN_operator, " import "); + i = i + 5; + continue; + } + } + after_match_string_operator: + + /* skip spaces */ + if (' ' == c0) { + /* not get symbal */ + if (i == symbol_start_index) { + symbol_start_index = -1; + } else { + /* already get symbal */ + tokenStream_arg = Lexer_setSymbel(tokenStream_arg, stmt, i, + &symbol_start_index); + } + } + if (i == size - 1) { + /* last check symbel */ + // if('\n' == c0){ + // continue; + // } + tokenStream_arg = Lexer_setSymbel(tokenStream_arg, stmt, size, + &symbol_start_index); + } + } + /* output */ + tokenStream = arg_getStr(tokenStream_arg); + tokenStream = strsCopy(outBuffs, tokenStream); + arg_deinit(tokenStream_arg); + return tokenStream; +} + +char* TokenStream_pop(Args* buffs_p, char** tokenStream) { + return strsPopToken(buffs_p, tokenStream, 0x1F); +} + +enum TokenType Token_getType(char* token) { + return (enum TokenType)token[0]; +} + +char* Token_getPyload(char* token) { + return (char*)((uintptr_t)token + 1); +} + +uint8_t TokenStream_isContain(char* tokenStream, + enum TokenType token_type, + char* pyload) { + Args buffs = {0}; + char* tokenStream_buff = strsCopy(&buffs, tokenStream); + uint8_t res = 0; + uint16_t token_size = TokenStream_getSize(tokenStream); + for (int i = 0; i < token_size; i++) { + char* token = TokenStream_pop(&buffs, &tokenStream_buff); + if (token_type == Token_getType(token)) { + if (strEqu(Token_getPyload(token), pyload)) { + res = 1; + goto exit; + } + } + } +exit: + strsDeinit(&buffs); + return res; +} + +static char* _solveEqualLevelOperator(Args* buffs, + char* + operator, + char * op1, + char* op2, + char* stmt) { + if ((strEqu(operator, op1)) || (strEqu(operator, op2))) { + Cursor_forEachToken(cs, stmt) { + Cursor_iterStart(&cs); + if (strEqu(cs.token1.pyload, op1)) { + operator= strsCopy(buffs, op1); + } + if (strEqu(cs.token1.pyload, op2)) { + operator= strsCopy(buffs, op2); + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + } + return operator; +} + +static const char operators[][9] = { + "**", "~", "*", "/", "%", "//", "+", "-", + ">>", "<<", "&", "^", "|", "<", "<=", ">", + ">=", "!=", "==", " is ", " in ", "%=", "/=", "//=", + "-=", "+=", "*=", "**=", " not ", " and ", " or ", " import "}; + +char* Lexer_getOperator(Args* outBuffs, char* stmt) { + Args buffs = {0}; + char* operator= NULL; + char* tokenStream = Lexer_getTokenStream(&buffs, stmt); + + // use parse state foreach to get operator + for (uint32_t i = 0; i < sizeof(operators) / 9; i++) { + Cursor_forEachToken(cs, tokenStream) { + Cursor_iterStart(&cs); + // get operator + if (strEqu(cs.token2.pyload, (char*)operators[i])) { + // solve the iuuse of "~-1" + operator= strsCopy(&buffs, (char*)operators[i]); + Cursor_iterEnd(&cs); + break; + } + Cursor_iterEnd(&cs); + }; + Cursor_deinit(&cs); + } + + /* solve the iuuse of "~-1" */ + if (strEqu(operator, "-")) { + Cursor_forEachToken(cs, stmt) { + Cursor_iterStart(&cs); + if (strEqu(cs.token2.pyload, "-")) { + if (cs.token1.type == TOKEN_operator) { + operator= strsCopy(&buffs, cs.token1.pyload); + Cursor_iterEnd(&cs); + break; + } + } + Cursor_iterEnd(&cs); + }; + Cursor_deinit(&cs); + } + + /* match the last operator in equal level */ + operator= _solveEqualLevelOperator(&buffs, operator, "+", "-", stmt); + operator= _solveEqualLevelOperator(&buffs, operator, "*", "/", stmt); + /* out put */ + if (NULL == operator) { + return NULL; + } + operator= strsCopy(outBuffs, operator); + strsDeinit(&buffs); + return operator; +} + +const char void_str[] = ""; + +void LexToken_update(struct LexToken* lex_token) { + lex_token->type = Token_getType(lex_token->tokenStream); + if (lex_token->type == TOKEN_strEnd) { + lex_token->pyload = (char*)void_str; + } else { + lex_token->pyload = Token_getPyload(lex_token->tokenStream); + } +} + +void Cursor_iterStart(struct Cursor* cs) { + cs->iter_index++; + cs->iter_buffs = New_strBuff(); + /* token1 is the last token */ + cs->token1.tokenStream = + strsCopy(cs->iter_buffs, arg_getStr(cs->last_token)); + /* token2 is the next token */ + cs->token2.tokenStream = TokenStream_pop(cs->iter_buffs, &cs->tokenStream); + /* store last token */ + arg_deinit(cs->last_token); + cs->last_token = arg_newStr(cs->token2.tokenStream); + + LexToken_update(&cs->token1); + LexToken_update(&cs->token2); + if (strEqu(cs->token1.pyload, "(")) { + cs->branket_deepth++; + } + if (strEqu(cs->token1.pyload, ")")) { + cs->branket_deepth--; + } + if (strEqu(cs->token1.pyload, "[")) { + cs->branket_deepth++; + } + if (strEqu(cs->token1.pyload, "]")) { + cs->branket_deepth--; + } + if (strEqu(cs->token1.pyload, "{")) { + cs->branket_deepth++; + } + if (strEqu(cs->token1.pyload, "}")) { + cs->branket_deepth--; + } +} + +void LexToken_init(struct LexToken* lt) { + lt->pyload = NULL; + lt->tokenStream = NULL; + lt->type = TOKEN_strEnd; +} + +void _Cursor_init(struct Cursor* cs) { + cs->tokenStream = NULL; + cs->length = 0; + cs->iter_index = 0; + cs->branket_deepth = 0; + cs->last_token = NULL; + cs->iter_buffs = NULL; + cs->buffs_p = New_strBuff(); + cs->result = PIKA_RES_OK; + LexToken_init(&cs->token1); + LexToken_init(&cs->token2); +} + +void Cursor_iterEnd(struct Cursor* cs) { + args_deinit(cs->iter_buffs); +} + +void Cursor_deinit(struct Cursor* cs) { + if (NULL != cs->last_token) { + arg_deinit(cs->last_token); + } + args_deinit(cs->buffs_p); +} + +void _Cursor_parse(struct Cursor* cs, char* stmt) { + if (NULL == stmt) { + cs->result = PIKA_RES_ERR_SYNTAX_ERROR; + return; + } + cs->tokenStream = Lexer_getTokenStream(cs->buffs_p, stmt); + if (NULL == cs->tokenStream) { + cs->result = PIKA_RES_ERR_SYNTAX_ERROR; + return; + } + cs->length = TokenStream_getSize(cs->tokenStream); +} + +void _Cursor_beforeIter(struct Cursor* cs) { + /* clear first token */ + if (cs->result != PIKA_RES_OK) { + return; + } + TokenStream_pop(cs->buffs_p, &cs->tokenStream); + cs->last_token = arg_newStr(TokenStream_pop(cs->buffs_p, &cs->tokenStream)); +} + +PIKA_BOOL Cursor_isContain(char* stmt, TokenType type, char* pyload) { + /* fast return */ + if (!strstr(stmt, pyload)) { + return PIKA_FALSE; + } + Args buffs = {0}; + PIKA_BOOL res = PIKA_FALSE; + char* tokenStream = Lexer_getTokenStream(&buffs, stmt); + if (TokenStream_isContain(tokenStream, type, pyload)) { + res = PIKA_TRUE; + } + strsDeinit(&buffs); + return res; +} + +char* Cursor_popToken(Args* buffs, char** tokenStream, char* devide) { + Arg* out_item = arg_newStr(""); + Arg* tokenStream_after = arg_newStr(""); + PIKA_BOOL is_find_devide = PIKA_FALSE; + Cursor_forEachToken(cs, *tokenStream) { + Cursor_iterStart(&cs); + if (!is_find_devide) { + if ((cs.branket_deepth == 0 && strEqu(cs.token1.pyload, devide)) || + cs.iter_index == cs.length) { + is_find_devide = PIKA_TRUE; + Cursor_iterEnd(&cs); + continue; + } + } + if (!is_find_devide) { + out_item = arg_strAppend(out_item, cs.token1.pyload); + } else { + tokenStream_after = + arg_strAppend(tokenStream_after, cs.token1.pyload); + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + /* cache out item */ + char* out_item_str = strsCopy(buffs, arg_getStr(out_item)); + arg_deinit(out_item); + /* cache tokenStream after */ + char* token_after_str = strsCopy(buffs, arg_getStr(tokenStream_after)); + arg_deinit(tokenStream_after); + /* update tokenStream */ + *tokenStream = token_after_str; + return out_item_str; +} + +static void Slice_getPars(Args* outBuffs, + char* inner, + char** pStart, + char** pEnd, + char** pStep) { +#if PIKA_NANO_ENABLE + return; +#endif + Args buffs = {0}; + *pStart = ""; + *pEnd = ""; + *pStep = ""; + + /* slice */ + uint8_t colon_i = 0; + Cursor_forEachToken(cs, inner) { + Cursor_iterStart(&cs); + if (strEqu(cs.token1.pyload, ":") && cs.branket_deepth == 0) { + colon_i++; + goto iter_continue1; + } + if (colon_i == 0) { + *pStart = strsAppend(&buffs, *pStart, cs.token1.pyload); + } + if (colon_i == 1) { + *pEnd = strsAppend(&buffs, *pEnd, cs.token1.pyload); + } + if (colon_i == 2) { + *pStep = strsAppend(&buffs, *pStep, cs.token1.pyload); + } + iter_continue1: + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + if (colon_i == 1) { + *pStep = "1"; + if (strEqu(*pStart, "")) { + *pStart = "0"; + } + if (strEqu(*pEnd, "")) { + *pEnd = "-1"; + } + } + if (colon_i == 0) { + *pEnd = strsAppend(&buffs, *pStart, " + 1"); + *pStep = "1"; + } + + /* slice with step */ + + /* output */ + *pStart = strsCopy(outBuffs, *pStart); + *pEnd = strsCopy(outBuffs, *pEnd); + *pStep = strsCopy(outBuffs, *pStep); + /* clean */ + strsDeinit(&buffs); +} + +char* Suger_leftSlice(Args* outBuffs, char* right, char** left_p) { +#if !PIKA_SYNTAX_SLICE_ENABLE + return right; +#endif + /* init objects */ + Args buffs = {0}; + Arg* right_arg = arg_newStr(""); + char* left = *left_p; + uint8_t is_in_brancket = 0; + args_setStr(&buffs, "inner", ""); + uint8_t matched = 0; + char* right_res = NULL; + /* exit when NULL */ + if (NULL == left) { + arg_deinit(right_arg); + right_arg = arg_newStr(right); + goto exit; + } + /* exit when not match + (symble|iteral)'[' + */ + Cursor_forEachToken(cs, left) { + Cursor_iterStart(&cs); + if (strEqu(cs.token2.pyload, "[")) { + if (TOKEN_symbol == cs.token1.type || + TOKEN_literal == cs.token1.type) { + matched = 1; + Cursor_iterEnd(&cs); + break; + } + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + if (!matched) { + /* not contain '[', return origin */ + arg_deinit(right_arg); + right_arg = arg_newStr(right); + goto exit; + } + + /* matched [] */ + Cursor_forEachTokenExistPs(cs, left) { + Cursor_iterStart(&cs); + /* found '[' */ + if ((TOKEN_devider == cs.token2.type) && + (strEqu(cs.token2.pyload, "["))) { + /* get 'obj' from obj[] */ + args_setStr(&buffs, "obj", cs.token1.pyload); + is_in_brancket = 1; + /* fond ']' */ + } else if ((TOKEN_devider == cs.token2.type) && + (strEqu(cs.token2.pyload, "]"))) { + is_in_brancket = 0; + char* inner = args_getStr(&buffs, "inner"); + Arg* inner_arg = arg_newStr(inner); + inner_arg = arg_strAppend(inner_arg, cs.token1.pyload); + args_setStr(&buffs, "inner", arg_getStr(inner_arg)); + arg_deinit(inner_arg); + /* update inner pointer */ + inner = args_getStr(&buffs, "inner"); + char* start = NULL; + char* end = NULL; + char* step = NULL; + Slice_getPars(&buffs, inner, &start, &end, &step); + /* obj = __setitem__(obj, key, val) */ + right_arg = arg_strAppend(right_arg, "__setitem__("); + right_arg = arg_strAppend(right_arg, args_getStr(&buffs, "obj")); + right_arg = arg_strAppend(right_arg, ","); + right_arg = arg_strAppend(right_arg, start); + right_arg = arg_strAppend(right_arg, ","); + right_arg = arg_strAppend(right_arg, right); + right_arg = arg_strAppend(right_arg, ")"); + /* clean the inner */ + args_setStr(&buffs, "inner", ""); + /* in brancket and found '[' */ + } else if (is_in_brancket && (!strEqu(cs.token1.pyload, "["))) { + char* inner = args_getStr(&buffs, "inner"); + Arg* index_arg = arg_newStr(inner); + index_arg = arg_strAppend(index_arg, cs.token1.pyload); + args_setStr(&buffs, "inner", arg_getStr(index_arg)); + arg_deinit(index_arg); + /* out of brancket and not found ']' */ + } else if (!is_in_brancket && (!strEqu(cs.token1.pyload, "]"))) { + if (TOKEN_strEnd != cs.token1.type) { + right_arg = arg_strAppend(right_arg, cs.token1.pyload); + } + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + /* clean the left */ + for (size_t i = 0; i < strGetSize(left); i++) { + if (left[i] == '[') { + left[i] = '\0'; + break; + } + } +exit: + /* clean and return */ + right_res = strsCopy(outBuffs, arg_getStr(right_arg)); + arg_deinit(right_arg); + strsDeinit(&buffs); + return right_res; +} + +char* Suger_format(Args* outBuffs, char* right) { +#if !PIKA_SYNTAX_FORMAT_ENABLE + return right; +#endif + /* quick skip */ + if (!strIsContain(right, '%')) { + return right; + } + + PIKA_BOOL is_format = PIKA_FALSE; + Cursor_forEachToken(ps1, right) { + Cursor_iterStart(&ps1); + if (ps1.branket_deepth == 0 && strEqu(ps1.token1.pyload, "%")) { + is_format = PIKA_TRUE; + } + Cursor_iterEnd(&ps1); + } + Cursor_deinit(&ps1); + if (PIKA_FALSE == is_format) { + return right; + } + + char* res = right; + Arg* str_buf = arg_newStr(""); + Arg* var_buf = arg_newStr(""); + PIKA_BOOL is_in_format = PIKA_FALSE; + PIKA_BOOL is_tuple = PIKA_FALSE; + PIKA_BOOL is_out_vars = PIKA_FALSE; + Args buffs = {0}; + char* fmt = NULL; + Cursor_forEachToken(cs, right) { + char* item = ""; + Cursor_iterStart(&cs); + if (PIKA_FALSE == is_in_format) { + if (cs.token1.type != TOKEN_literal) { + item = cs.token1.pyload; + goto iter_continue; + } + if (cs.token1.pyload[0] != '\'' && cs.token1.pyload[0] != '"') { + item = cs.token1.pyload; + goto iter_continue; + } + if (!strEqu(cs.token2.pyload, "%")) { + item = cs.token1.pyload; + goto iter_continue; + } + /* found the format stmt */ + is_in_format = PIKA_TRUE; + fmt = strsCopy(&buffs, cs.token1.pyload); + goto iter_continue; + } + if (PIKA_TRUE == is_in_format) { + /* check the format vars */ + if (strEqu(cs.token1.pyload, "%")) { + /* is a tuple */ + if (strEqu(cs.token2.pyload, "(")) { + is_tuple = PIKA_TRUE; + } else { + var_buf = arg_strAppend(var_buf, cs.token2.pyload); + } + goto iter_continue; + } + /* found the end of tuple */ + if (cs.iter_index == cs.length) { + is_out_vars = PIKA_TRUE; + is_in_format = PIKA_FALSE; + } else { + /* push the vars inner the tuple */ + var_buf = arg_strAppend(var_buf, cs.token2.pyload); + } + if (is_out_vars) { + if (is_tuple) { + str_buf = arg_strAppend(str_buf, "cformat("); + str_buf = arg_strAppend(str_buf, fmt); + str_buf = arg_strAppend(str_buf, ","); + str_buf = arg_strAppend(str_buf, arg_getStr(var_buf)); + } else { + str_buf = arg_strAppend(str_buf, "cformat("); + str_buf = arg_strAppend(str_buf, fmt); + str_buf = arg_strAppend(str_buf, ","); + str_buf = arg_strAppend(str_buf, arg_getStr(var_buf)); + str_buf = arg_strAppend(str_buf, ")"); + } + } + } + iter_continue: + if (!is_in_format) { + str_buf = arg_strAppend(str_buf, item); + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + + res = strsCopy(outBuffs, arg_getStr(str_buf)); + arg_deinit(str_buf); + arg_deinit(var_buf); + strsDeinit(&buffs); + return res; +} + +uint8_t Suger_selfOperator(Args* outbuffs, + char* stmt, + char** right_p, + char** left_p) { + char* left_new = NULL; + char* right_new = NULL; + Arg* left_arg = arg_newStr(""); + Arg* right_arg = arg_newStr(""); + Arg* right_arg_new = arg_newStr(""); + uint8_t is_left_exist = 0; + + Args buffs = {0}; + char _operator[2] = {0}; + char* operator=(char*) _operator; + uint8_t is_right = 0; + if (Cursor_isContain(stmt, TOKEN_operator, "+=")) { + operator[0] = '+'; + } + if (Cursor_isContain(stmt, TOKEN_operator, "-=")) { + operator[0] = '-'; + } + if (Cursor_isContain(stmt, TOKEN_operator, "*=")) { + operator[0] = '*'; + } + if (Cursor_isContain(stmt, TOKEN_operator, "/=")) { + operator[0] = '/'; + } + /* not found self operator */ + if (operator[0] == 0) { + goto exit; + } + /* found self operator */ + is_left_exist = 1; + Cursor_forEachToken(cs, stmt) { + Cursor_iterStart(&cs); + if ((strEqu(cs.token1.pyload, "*=")) || + (strEqu(cs.token1.pyload, "/=")) || + (strEqu(cs.token1.pyload, "+=")) || + (strEqu(cs.token1.pyload, "-="))) { + is_right = 1; + goto iter_continue; + } + if (!is_right) { + left_arg = arg_strAppend(left_arg, cs.token1.pyload); + } else { + right_arg = arg_strAppend(right_arg, cs.token1.pyload); + } + iter_continue: + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + /* connect right */ + right_arg_new = arg_strAppend(right_arg_new, arg_getStr(left_arg)); + right_arg_new = arg_strAppend(right_arg_new, operator); + right_arg_new = arg_strAppend(right_arg_new, "("); + right_arg_new = arg_strAppend(right_arg_new, arg_getStr(right_arg)); + right_arg_new = arg_strAppend(right_arg_new, ")"); + + /* collect left_new and right_new */ + left_new = arg_getStr(left_arg); + right_new = arg_getStr(right_arg_new); + +exit: + strsDeinit(&buffs); + if (NULL != right_new) { + *(right_p) = strsCopy(outbuffs, right_new); + ; + } + if (NULL != left_new) { + *(left_p) = strsCopy(outbuffs, left_new); + } + arg_deinit(right_arg); + arg_deinit(left_arg); + arg_deinit(right_arg_new); + return is_left_exist; +} + +PIKA_RES AST_setNodeAttr(AST* ast, char* attr_name, char* attr_val) { + return obj_setStr(ast, attr_name, attr_val); +} + +char* AST_getNodeAttr(AST* ast, char* attr_name) { + return obj_getStr(ast, attr_name); +} + +PIKA_RES AST_setNodeBlock(AST* ast, char* node_content) { + return AST_setNodeAttr(ast, "block", node_content); +} + +char* AST_getThisBlock(AST* ast) { + return obj_getStr(ast, "block"); +} + +AST* AST_parseStmt(AST* ast, char* stmt); +PIKA_RES AST_parseSubStmt(AST* ast, char* node_content) { + queueObj_pushObj(ast, (char*)"stmt"); + AST_parseStmt(queueObj_getCurrentObj(ast), node_content); + return PIKA_RES_OK; +} + +char* Parser_popSubStmt(Args* outbuffs, char** stmt_p, char* delimiter) { + Arg* substmt_arg = arg_newStr(""); + Arg* newstmt_arg = arg_newStr(""); + char* stmt = *stmt_p; + PIKA_BOOL is_get_substmt = PIKA_FALSE; + Args buffs = {0}; + Cursor_forEachToken(cs, stmt) { + Cursor_iterStart(&cs); + if (is_get_substmt) { + /* get new stmt */ + newstmt_arg = arg_strAppend(newstmt_arg, cs.token1.pyload); + Cursor_iterEnd(&cs); + continue; + } + if (cs.branket_deepth > 0) { + /* ignore */ + substmt_arg = arg_strAppend(substmt_arg, cs.token1.pyload); + Cursor_iterEnd(&cs); + continue; + } + if (strEqu(cs.token1.pyload, delimiter)) { + /* found delimiter */ + is_get_substmt = PIKA_TRUE; + Cursor_iterEnd(&cs); + continue; + } + /* collect substmt */ + substmt_arg = arg_strAppend(substmt_arg, cs.token1.pyload); + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + + strsDeinit(&buffs); + + char* substmt = strsCacheArg(outbuffs, substmt_arg); + char* newstmt = strsCacheArg(outbuffs, newstmt_arg); + *stmt_p = newstmt; + return substmt; +} + +char* Parser_popLastSubStmt(Args* outbuffs, char** stmt_p, char* delimiter) { + uint8_t last_stmt_i = 0; + char* stmt = *stmt_p; + Cursor_forEachToken(cs, stmt) { + Cursor_iterStart(&cs); + if (strIsStartWith(cs.token1.pyload, delimiter)) { + /* found delimiter */ + if (!strEqu(delimiter, "[") && cs.branket_deepth > 0) { + /* ignore */ + Cursor_iterEnd(&cs); + continue; + } + + /* for "[" */ + if (cs.branket_deepth > 1) { + /* ignore */ + Cursor_iterEnd(&cs); + continue; + } + + last_stmt_i = cs.iter_index; + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + + Arg* mainStmt = arg_newStr(""); + Arg* lastStmt = arg_newStr(""); + { + Cursor_forEachToken(cs, stmt) { + Cursor_iterStart(&cs); + if (cs.iter_index < last_stmt_i) { + mainStmt = arg_strAppend(mainStmt, cs.token1.pyload); + } + if (cs.iter_index >= last_stmt_i) { + lastStmt = arg_strAppend(lastStmt, cs.token1.pyload); + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + } + + *stmt_p = strsCacheArg(outbuffs, mainStmt); + return strsCacheArg(outbuffs, lastStmt); +} + +static void _AST_parse_list(AST* ast, Args* buffs, char* stmt) { +#if !PIKA_BUILTIN_STRUCT_ENABLE + return; +#endif + AST_setNodeAttr(ast, (char*)"list", "list"); + char* subStmts = strsCut(buffs, stmt, '[', ']'); + subStmts = strsAppend(buffs, subStmts, ","); + while (1) { + char* subStmt = Parser_popSubStmt(buffs, &subStmts, ","); + AST_parseSubStmt(ast, subStmt); + if (strEqu(subStmts, "")) { + break; + } + } + return; +} + +static void _AST_parse_dict(AST* ast, Args* buffs, char* stmt) { +#if !PIKA_BUILTIN_STRUCT_ENABLE + return; +#endif + AST_setNodeAttr(ast, (char*)"dict", "dict"); + char* subStmts = strsCut(buffs, stmt, '{', '}'); + subStmts = strsAppend(buffs, subStmts, ","); + while (1) { + char* subStmt = Parser_popSubStmt(buffs, &subStmts, ","); + char* key = Parser_popSubStmt(buffs, &subStmt, ":"); + char* value = subStmt; + AST_parseSubStmt(ast, key); + AST_parseSubStmt(ast, value); + if (strEqu(subStmts, "")) { + break; + } + } +} + +static void _AST_parse_slice(AST* ast, Args* buffs, char* stmt) { +#if !PIKA_SYNTAX_SLICE_ENABLE + return; +#endif + AST_setNodeAttr(ast, (char*)"slice", "slice"); + stmt = strsCopy(buffs, stmt); + char* laststmt = Parser_popLastSubStmt(buffs, &stmt, "["); + AST_parseSubStmt(ast, stmt); + char* slice_list = strsCut(buffs, laststmt, '[', ']'); + pika_assert(slice_list != NULL); + slice_list = strsAppend(buffs, slice_list, ":"); + int index = 0; + while (1) { + char* slice_str = Parser_popSubStmt(buffs, &slice_list, ":"); + if (index == 0 && strEqu(slice_str, "")) { + AST_parseSubStmt(ast, "0"); + } else if (index == 1 && strEqu(slice_str, "")) { + AST_parseSubStmt(ast, "-99999"); + } else { + AST_parseSubStmt(ast, slice_str); + } + index++; + if (strEqu("", slice_list)) { + break; + } + } +} + +char* Suger_not_in(Args* out_buffs, char* line) { +#if PIKA_NANO_ENABLE + return line; +#endif + char* ret = line; + char* stmt1 = ""; + char* stmt2 = ""; + PIKA_BOOL got_not_in = PIKA_FALSE; + PIKA_BOOL skip = PIKA_FALSE; + Args buffs = {0}; + if (!Cursor_isContain(line, TOKEN_operator, " not ")) { + ret = line; + goto __exit; + } + if (!Cursor_isContain(line, TOKEN_operator, " in ")) { + ret = line; + goto __exit; + } + + /* stmt1 not in stmt2 => not stmt1 in stmt2 */ + Cursor_forEachToken(cs, line) { + Cursor_iterStart(&cs); + if (!got_not_in) { + if (strEqu(cs.token1.pyload, " not ") && + strEqu(cs.token2.pyload, " in ")) { + got_not_in = PIKA_TRUE; + Cursor_iterEnd(&cs); + continue; + } + stmt1 = strsAppend(&buffs, stmt1, cs.token1.pyload); + } else { + if (!skip) { + skip = PIKA_TRUE; + Cursor_iterEnd(&cs); + continue; + } + stmt2 = strsAppend(&buffs, stmt2, cs.token1.pyload); + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + if (!got_not_in) { + ret = line; + goto __exit; + } + ret = strsFormat(out_buffs, strGetSize(line) + 3, " not %s in %s", stmt1, + stmt2); + goto __exit; +__exit: + strsDeinit(&buffs); + return ret; +} + +AST* AST_parseStmt(AST* ast, char* stmt) { + Args buffs = {0}; + char* assignment = strsGetFirstToken(&buffs, stmt, '('); + char* method = NULL; + char* ref = NULL; + char* str = NULL; + char* num = NULL; + char* left = NULL; + char* right = NULL; + char* import = NULL; + PIKA_RES result = PIKA_RES_OK; + + right = stmt; + /* solve check direct */ + uint8_t isLeftExist = 0; + if (Parser_checkIsDirect(assignment)) { + isLeftExist = 1; + left = strsCopy(&buffs, ""); + right = strsCopy(&buffs, ""); + uint8_t is_meet_equ = 0; + Cursor_forEachToken(cs, stmt) { + Cursor_iterStart(&cs); + if (!is_meet_equ && strEqu(cs.token1.pyload, "=") && + cs.token1.type == TOKEN_operator) { + is_meet_equ = 1; + Cursor_iterEnd(&cs); + continue; + } + if (0 == is_meet_equ) { + left = strsAppend(&buffs, left, cs.token1.pyload); + } + if (1 == is_meet_equ) { + right = strsAppend(&buffs, right, cs.token1.pyload); + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + } + /* solve the += -= /= *= stmt */ + if (!isLeftExist) { + isLeftExist = Suger_selfOperator(&buffs, stmt, &right, &left); + } + + /* solve the [] stmt */ + right = Suger_leftSlice(&buffs, right, &left); + right = Suger_format(&buffs, right); + + /* set left */ + if (isLeftExist) { + AST_setNodeAttr(ast, (char*)"left", left); + } + /* match statment type */ + enum StmtType stmtType = Lexer_matchStmtType(right); + if (STMT_tuple == stmtType) { + right = strsFormat(&buffs, PIKA_LINE_BUFF_SIZE, "(%s)", right); + stmtType = STMT_method; + } + /* solve operator stmt */ + if (STMT_operator == stmtType) { + right = Suger_not_in(&buffs, right); + char* rightWithoutSubStmt = _remove_sub_stmt(&buffs, right); + char* operator= Lexer_getOperator(&buffs, rightWithoutSubStmt); + if (NULL == operator) { + result = PIKA_RES_ERR_SYNTAX_ERROR; + goto exit; + } + AST_setNodeAttr(ast, (char*)"operator", operator); + char* rightBuff = strsCopy(&buffs, right); + char* subStmt1 = + strsPopTokenWithSkip_byStr(&buffs, rightBuff, operator, '(', ')'); + char* subStmt2 = rightBuff; + AST_parseSubStmt(ast, subStmt1); + AST_parseSubStmt(ast, subStmt2); + goto exit; + } + + /* solve list stmt */ + if (STMT_list == stmtType) { + _AST_parse_list(ast, &buffs, right); + goto exit; + } + + /* solve dict stmt */ + if (STMT_dict == stmtType) { + _AST_parse_dict(ast, &buffs, right); + goto exit; + } + + /* solve method chain */ + if (STMT_chain == stmtType) { + char* stmt = strsCopy(&buffs, right); + char* lastStmt = Parser_popLastSubStmt(&buffs, &stmt, "."); + AST_parseSubStmt(ast, stmt); + AST_parseStmt(ast, lastStmt); + goto exit; + } + + if (STMT_slice == stmtType) { + /* solve slice stmt */ + _AST_parse_slice(ast, &buffs, right); + goto exit; + } + + /* solve method stmt */ + if (STMT_method == stmtType) { + method = strsGetFirstToken(&buffs, right, '('); + AST_setNodeAttr(ast, (char*)"method", method); + char* subStmts = strsCut(&buffs, right, '(', ')'); + pika_assert(NULL != subStmts); + /* add ',' at the end */ + subStmts = strsAppend(&buffs, subStmts, ","); + while (1) { + char* substmt = Parser_popSubStmt(&buffs, &subStmts, ","); + AST_parseSubStmt(ast, substmt); + if (strEqu("", subStmts)) { + break; + } + } + goto exit; + } + /* solve reference stmt */ + if (STMT_reference == stmtType) { + ref = right; + AST_setNodeAttr(ast, (char*)"ref", ref); + goto exit; + } + /* solve import stmt */ + if (STMT_import == stmtType) { + import = strsGetLastToken(&buffs, right, ' '); + AST_setNodeAttr(ast, (char*)"import", import); + goto exit; + } + /* solve str stmt */ + if (STMT_string == stmtType) { + str = strsCopy(&buffs, right); + /* remove the first char */ + str = str + 1; + /* remove the last char */ + str[strGetSize(str) - 1] = '\0'; + /* replace */ + if (strIsContain(str, '\\')) { + str = strsReplace(&buffs, str, "\\\"", "\""); + str = strsReplace(&buffs, str, "\\'", "'"); + } + AST_setNodeAttr(ast, (char*)"string", str); + goto exit; + } + /* solve bytes stmt */ + if (STMT_bytes == stmtType) { + str = right + 1; + str = strsDeleteChar(&buffs, str, '\''); + str = strsDeleteChar(&buffs, str, '\"'); + AST_setNodeAttr(ast, (char*)"bytes", str); + goto exit; + } + /* solve number stmt */ + if (STMT_number == stmtType) { + num = right; + AST_setNodeAttr(ast, (char*)"num", num); + goto exit; + } +exit: + strsDeinit(&buffs); + if (result != PIKA_RES_OK) { + AST_deinit(ast); + return NULL; + } + return ast; +} + +static int32_t Parser_getPyLineBlockDeepth(char* line) { + uint32_t size = strGetSize(line); + for (uint32_t i = 0; i < size; i++) { + if (line[i] != ' ') { + uint32_t spaceNum = i; + if (0 == spaceNum % 4) { + return spaceNum / 4; + } + /* space Num is not 4N, error*/ + return -1; + } + } + return 0; +} + +char* Parser_removeAnnotation(char* line) { + uint8_t is_annotation_exit = 0; + uint8_t is_in_single_quotes = 0; + uint8_t is_in_pika_float_quotes_deepth = 0; + for (uint32_t i = 0; i < strGetSize(line); i++) { + if ('\'' == line[i]) { + is_in_single_quotes = !is_in_single_quotes; + continue; + } + if ('"' == line[i]) { + is_in_pika_float_quotes_deepth = !is_in_pika_float_quotes_deepth; + continue; + } + if (!(is_in_single_quotes == 0 && + is_in_pika_float_quotes_deepth == 0)) { + continue; + } + if ('#' == line[i]) { + /* end the line */ + line[i] = 0; + is_annotation_exit = 1; + break; + } + } + /* no annotation, exit */ + if (!is_annotation_exit) { + return line; + } + /* check empty line */ + for (uint32_t i = 0; i < strGetSize(line); i++) { + if (' ' != line[i]) { + return line; + } + } + /* is an emply line */ + line = "@annontation"; + return line; +} + +char* _defGetDefault(Args* outBuffs, char** dec_out) { +#if PIKA_NANO_ENABLE + return ""; +#endif + Args buffs = {0}; + char* dec_str = strsCopy(&buffs, *dec_out); + char* fn_name = strsGetFirstToken(&buffs, dec_str, '('); + Arg* dec_arg = arg_strAppend(arg_newStr(fn_name), "("); + Arg* default_arg = arg_newStr(""); + char* arg_list = strsCut(&buffs, dec_str, '(', ')'); + char* default_out = NULL; + pika_assert(NULL != arg_list); + int arg_num = strCountSign(arg_list, ',') + 1; + for (int i = 0; i < arg_num; i++) { + char* arg_str = strsPopToken(&buffs, &arg_list, ','); + int is_default = 0; + if (strIsContain(arg_str, '=')) { + default_arg = arg_strAppend(default_arg, arg_str); + default_arg = arg_strAppend(default_arg, ","); + arg_str = strsPopToken(&buffs, &arg_str, '='); + is_default = 1; + } + dec_arg = arg_strAppend(dec_arg, arg_str); + if (is_default) { + dec_arg = arg_strAppend(dec_arg, "="); + } + dec_arg = arg_strAppend(dec_arg, ","); + } + strPopLastToken(arg_getStr(dec_arg), ','); + dec_arg = arg_strAppend(dec_arg, ")"); + *dec_out = strsCopy(outBuffs, arg_getStr(dec_arg)); + default_out = strsCopy(outBuffs, arg_getStr(default_arg)); + strPopLastToken(default_out, ','); + arg_deinit(dec_arg); + arg_deinit(default_arg); + strsDeinit(&buffs); + return default_out; +} + +static char* Suger_multiReturn(Args* out_buffs, char* line) { +#if PIKA_NANO_ENABLE + return line; +#endif + Cursor_forEachToken(cs, line) { + Cursor_iterStart(&cs); + if (cs.branket_deepth == 0 && strEqu(cs.token1.pyload, ",")) { + line = strsFormat(out_buffs, strGetSize(line) + 3, "(%s)", line); + Cursor_iterEnd(&cs); + break; + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + return line; +} + +/* match block start keywords */ +const char control_keywords[][9] = {"break", "continue"}; + +/* normal keyward */ +const char normal_keywords[][7] = {"while", "if", "elif"}; + +AST* AST_parseLine_withBlockStack_withBlockDeepth(char* line, + Stack* block_stack, + int block_deepth) { + Stack s; + stack_init(&s); + if (block_stack == NULL) { + block_stack = &s; + } + /* line is not exist */ + if (line == NULL) { + return NULL; + } + /* init data */ + AST* ast = New_queueObj(); + Args buffs = {0}; + int8_t block_deepth_now, block_deepth_last = -1; + char *line_start, *stmt; + /* get block deepth */ + block_deepth_now = Parser_getPyLineBlockDeepth(line); + /* set block deepth */ + if (block_deepth_now == -1) { + /* get block_deepth error */ + pika_platform_printf( + "IndentationError: unexpected indent, only support 4 " + "spaces\r\n"); + obj_deinit(ast); + ast = NULL; + goto exit; + } + block_deepth_now += block_deepth; + obj_setInt(ast, "blockDeepth", block_deepth_now); + + /* check if exit block */ + block_deepth_last = stack_getTop(block_stack) + block_deepth; + /* exit each block */ + for (int i = 0; i < block_deepth_last - block_deepth_now; i++) { + QueueObj* exit_block_queue = obj_getObj(ast, "exitBlock"); + /* create an exit_block queue */ + if (NULL == exit_block_queue) { + obj_newObj(ast, "exitBlock", "", New_TinyObj); + exit_block_queue = obj_getObj(ast, "exitBlock"); + queueObj_init(exit_block_queue); + } + char buff[10] = {0}; + char* block_type = stack_popStr(block_stack, buff); + /* push exit block type to exit_block queue */ + queueObj_pushStr(exit_block_queue, block_type); + } + + line_start = line + (block_deepth_now - block_deepth) * 4; + stmt = line_start; + + // "while" "if" "elif" + for (uint32_t i = 0; i < sizeof(normal_keywords) / 7; i++) { + char* keyword = (char*)normal_keywords[i]; + uint8_t keyword_len = strGetSize(keyword); + if (strIsStartWith(line_start, keyword) && + (line_start[keyword_len] == ' ')) { + stmt = strsCut(&buffs, line_start, ' ', ':'); + AST_setNodeBlock(ast, keyword); + stack_pushStr(block_stack, keyword); + goto block_matched; + } + } + + /* contral keyward */ + /* "break", "continue" */ + for (uint32_t i = 0; i < sizeof(control_keywords) / 8; i++) { + char* keyward = (char*)control_keywords[i]; + uint8_t keyward_size = strGetSize(keyward); + if ((strIsStartWith(line_start, keyward)) && + ((line_start[keyward_size] == ' ') || + (line_start[keyward_size] == 0))) { + AST_setNodeAttr(ast, keyward, ""); + stmt = ""; + goto block_matched; + } + } + + /* for */ + if (strIsStartWith(line_start, "for ")) { + Args* list_buffs = New_strBuff(); + char* line_buff = strsCopy(list_buffs, line_start + 4); + line_buff = strsGetCleanCmd(list_buffs, line_buff); + if (strCountSign(line_buff, ':') < 1) { + args_deinit(list_buffs); + obj_deinit(ast); + ast = NULL; + goto exit; + } + char* arg_in = strsPopToken(list_buffs, &line_buff, ' '); + AST_setNodeAttr(ast, "arg_in", arg_in); + strsPopToken(list_buffs, &line_buff, ' '); + char* list_in = strsPopToken(list_buffs, &line_buff, ':'); + list_in = strsAppend(list_buffs, "iter(", list_in); + list_in = strsAppend(list_buffs, list_in, ")"); + list_in = strsCopy(&buffs, list_in); + args_deinit(list_buffs); + AST_setNodeBlock(ast, "for"); + AST_setNodeAttr(ast, "list_in", list_in); + stack_pushStr(block_stack, "for"); + stmt = list_in; + goto block_matched; + } + + /* else */ + if (strIsStartWith(line_start, "else")) { + if ((line_start[4] == ' ') || (line_start[4] == ':')) { + stmt = ""; + AST_setNodeBlock(ast, "else"); + stack_pushStr(block_stack, "else"); + } + goto block_matched; + } + +#if PIKA_SYNTAX_EXCEPTION_ENABLE + /* try */ + if (strIsStartWith(line_start, "try")) { + if ((line_start[3] == ' ') || (line_start[3] == ':')) { + stmt = ""; + AST_setNodeBlock(ast, "try"); + stack_pushStr(block_stack, "try"); + } + goto block_matched; + } + + /* except */ + if (strIsStartWith(line_start, "except")) { + if ((line_start[6] == ' ') || (line_start[6] == ':')) { + stmt = ""; + AST_setNodeBlock(ast, "except"); + stack_pushStr(block_stack, "except"); + } + goto block_matched; + } +#endif + + if (strEqu(line_start, "return")) { + AST_setNodeAttr(ast, "return", ""); + stmt = ""; + goto block_matched; + } + if (strIsStartWith(line_start, "return ")) { + char* lineBuff = strsCopy(&buffs, line_start); + strsPopToken(&buffs, &lineBuff, ' '); + stmt = lineBuff; + stmt = Suger_multiReturn(&buffs, stmt); + AST_setNodeAttr(ast, "return", ""); + goto block_matched; + } + +#if PIKA_SYNTAX_EXCEPTION_ENABLE + if (strEqu(line_start, "raise")) { + AST_setNodeAttr(ast, "raise", ""); + stmt = "RuntimeError"; + goto block_matched; + } + if (strIsStartWith(line_start, "raise ")) { + AST_setNodeAttr(ast, "raise", ""); + char* lineBuff = strsCopy(&buffs, line_start); + strsPopToken(&buffs, &lineBuff, ' '); + stmt = lineBuff; + if (strEqu("", stmt)) { + stmt = "RuntimeError"; + } + goto block_matched; + } + /* assert */ + if (strIsStartWith(line_start, "assert ")) { + stmt = ""; + AST_setNodeAttr(ast, "assert", ""); + char* lineBuff = strsCopy(&buffs, line_start + 7); + /* assert expr [, msg] */ + while (1) { + char* subStmt = Parser_popSubStmt(&buffs, &lineBuff, ","); + AST_parseSubStmt(ast, subStmt); + if (strEqu(lineBuff, "")) { + break; + } + } + goto block_matched; + } +#endif + + if (strIsStartWith(line_start, "global ")) { + stmt = ""; + char* global_list = line_start + 7; + global_list = strsGetCleanCmd(&buffs, global_list); + AST_setNodeAttr(ast, "global", global_list); + goto block_matched; + } + if (strIsStartWith(line_start, "del ") || + strIsStartWith(line_start, "del(")) { + stmt = ""; + char* del_dir = NULL; + if (line_start[3] == '(') { + del_dir = strsCut(&buffs, line_start, '(', ')'); + } else { + del_dir = line_start + sizeof("del ") - 1; + } + del_dir = strsGetCleanCmd(&buffs, del_dir); + AST_setNodeAttr(ast, "del", del_dir); + goto block_matched; + } + if (strIsStartWith(line_start, (char*)"def ")) { + stmt = ""; + char* declare = strsCut(&buffs, line_start, ' ', ':'); + if (NULL == declare) { + obj_deinit(ast); + ast = NULL; + goto exit; + } + declare = strsGetCleanCmd(&buffs, declare); + if (!strIsContain(declare, '(') || !strIsContain(declare, ')')) { + obj_deinit(ast); + ast = NULL; + goto exit; + } + char* defaultStmt = _defGetDefault(&buffs, &declare); + AST_setNodeBlock(ast, "def"); + AST_setNodeAttr(ast, "declare", declare); + if (defaultStmt[0] != '\0') { + AST_setNodeAttr(ast, "default", defaultStmt); + } + stack_pushStr(block_stack, "def"); + goto block_matched; + } + if (strIsStartWith(line_start, (char*)"class ")) { + stmt = ""; + char* declare = strsCut(&buffs, line_start, ' ', ':'); + if (NULL == declare) { + obj_deinit(ast); + ast = NULL; + goto exit; + } + declare = strsGetCleanCmd(&buffs, declare); + AST_setNodeBlock(ast, "class"); + AST_setNodeAttr(ast, "declare", declare); + stack_pushStr(block_stack, "class"); + goto block_matched; + } + +block_matched: + if (NULL == stmt) { + AST_deinit(ast); + ast = NULL; + goto exit; + } + stmt = strsGetCleanCmd(&buffs, stmt); + ast = AST_parseStmt(ast, stmt); + goto exit; +exit: + stack_deinit(&s); + strsDeinit(&buffs); + return ast; +} + +static AST* AST_parseLine_withBlockStack(char* line, Stack* block_stack) { + return AST_parseLine_withBlockStack_withBlockDeepth(line, block_stack, 0); +} + +static AST* AST_parseLine_withBlockDeepth(char* line, int block_deepth) { + return AST_parseLine_withBlockStack_withBlockDeepth(line, NULL, + block_deepth); +} + +int AST_getBlockDeepthNow(AST* ast) { + return obj_getInt(ast, "blockDeepth"); +} + +AST* AST_parseLine(char* line) { + return AST_parseLine_withBlockStack(line, NULL); +} + +static char* Suger_import_as(Args* out_buffs, char* line) { +#if !PIKA_SYNTAX_IMPORT_EX_ENABLE + return line; +#endif + Args buffs = {0}; + char* line_out = line; + char* alias = NULL; + char* origin = NULL; + char* stmt = line + 7; + + /* not import, exit */ + if (!strIsStartWith(line, "import ")) { + line_out = line; + goto exit; + } + + if (!Cursor_isContain(stmt, TOKEN_operator, " as ")) { + line_out = line; + goto exit; + } + + /* {origin} as {alias} */ + origin = Cursor_popToken(&buffs, &stmt, " as "); + alias = stmt; + + /* 'import' and 'as' */ + line_out = strsFormat(&buffs, PIKA_LINE_BUFF_SIZE, "import %s\n%s = %s", + origin, alias, origin); +exit: + return strsReturnOut(&buffs, out_buffs, line_out); +} + +static PIKA_BOOL _check_is_multi_assign(char* arg_list) { +#if PIKA_NANO_ENABLE + return PIKA_FALSE; +#endif + PIKA_BOOL res = PIKA_FALSE; + Cursor_forEachToken(cs, arg_list) { + Cursor_iterStart(&cs); + if ((cs.branket_deepth == 0 && strEqu(cs.token1.pyload, ","))) { + res = PIKA_TRUE; + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + return res; +} + +static char* Suger_multiAssign(Args* out_buffs, char* line) { +#if PIKA_NANO_ENABLE + return line; +#endif + Args buffs = {0}; + char* line_out = line; + PIKA_BOOL is_assign = PIKA_FALSE; + Arg* stmt = arg_newStr(""); + Arg* out_list = arg_newStr(""); + Arg* out_item = arg_newStr(""); + Arg* line_out_arg = arg_newStr(""); + char* line_item = NULL; + char* out_list_str = NULL; + int out_num = 0; + Cursor_forEachToken(cs, line) { + Cursor_iterStart(&cs); + if (cs.branket_deepth == 0 && strEqu(cs.token1.pyload, "=")) { + is_assign = PIKA_TRUE; + Cursor_iterEnd(&cs); + continue; + } + if (is_assign) { + stmt = arg_strAppend(stmt, cs.token1.pyload); + } + if (!is_assign) { + out_list = arg_strAppend(out_list, cs.token1.pyload); + } + Cursor_iterEnd(&cs); + } + Cursor_deinit(&cs); + if (!is_assign) { + line_out = line; + goto exit; + } + + if (!_check_is_multi_assign(arg_getStr(out_list))) { + line_out = line; + goto exit; + } + + line_item = + strsFormat(&buffs, PIKA_LINE_BUFF_SIZE, "$tmp= %s\n", arg_getStr(stmt)); + line_out_arg = arg_strAppend(line_out_arg, line_item); + + out_list_str = arg_getStr(out_list); + while (1) { + char* item = Cursor_popToken(&buffs, &out_list_str, ","); + if (item[0] == '\0') { + break; + } + char* line_item = strsFormat(&buffs, PIKA_LINE_BUFF_SIZE, + "%s = $tmp[%d]\n", item, out_num); + line_out_arg = arg_strAppend(line_out_arg, line_item); + out_num++; + } + line_out_arg = arg_strAppend(line_out_arg, "del $tmp"); + + line_out = strsCopy(out_buffs, arg_getStr(line_out_arg)); +exit: + arg_deinit(stmt); + arg_deinit(out_list); + arg_deinit(out_item); + arg_deinit(line_out_arg); + strsDeinit(&buffs); + return line_out; +} + +static char* Suger_from_import_as(Args* buffs_p, char* line) { +#if !PIKA_SYNTAX_IMPORT_EX_ENABLE + return line; +#endif + Args buffs = {0}; + char* line_out = line; + char* class = NULL; + char* module = NULL; + char* alias = NULL; + char* stmt = line + 5; + char* class_after = ""; + + if (!strIsStartWith(line, "from ")) { + line_out = line; + goto exit; + } + + module = Cursor_popToken(&buffs, &stmt, " import "); + if (!Cursor_isContain(stmt, TOKEN_operator, " as ")) { + class = stmt; + } else { + class = Cursor_popToken(&buffs, &stmt, " as "); + alias = stmt; + } + + if (NULL == alias) { + alias = class; + } + + /* skip PikaObj */ + if (strEqu(module, "PikaObj")) { + line_out = strsCopy(buffs_p, ""); + goto exit; + } + + while (1) { + char* class_item = Cursor_popToken(&buffs, &class, ","); + if (class_item[0] == '\0') { + break; + } + class_item = strsFormat(&buffs, PIKA_LINE_BUFF_SIZE, "%s.%s,", module, + class_item); + class_after = strsAppend(&buffs, class_after, class_item); + } + class_after[strlen(class_after) - 1] = '\0'; + class = class_after; + + line_out = strsFormat(&buffs, PIKA_LINE_BUFF_SIZE, "import %s\n%s = %s", + module, alias, class); + line_out = strsCopy(buffs_p, line_out); +exit: + strsDeinit(&buffs); + return line_out; +} + +static char* Suger_import(Args* outbuffs, char* line) { +#if !PIKA_SYNTAX_IMPORT_EX_ENABLE + return line; +#endif + line = Suger_import_as(outbuffs, line); + line = Suger_from_import_as(outbuffs, line); + Arg* line_buff = arg_newStr(""); + while (1) { + char* single_line = strPopFirstToken(&line, '\n'); + if (single_line[0] == '\0') { + break; + } + if (strIsStartWith(single_line, "import ")) { + if (strIsContain(single_line, ',')) { + single_line = single_line + 7; + while (1) { + char* single_import = strPopFirstToken(&single_line, ','); + if (single_import[0] == '\0') { + break; + } + line_buff = arg_strAppend(line_buff, "import "); + line_buff = arg_strAppend(line_buff, single_import); + line_buff = arg_strAppend(line_buff, "\n"); + } + char* line_after = arg_getStr(line_buff); + line_after[strlen(line_after) - 1] = '\0'; + } + } + line_buff = arg_strAppend(line_buff, single_line); + line_buff = arg_strAppend(line_buff, "\n"); + } + char* line_after = arg_getStr(line_buff); + line_after[strlen(line_after) - 1] = '\0'; + line_after = strsCopy(outbuffs, line_after); + arg_deinit(line_buff); + return line_after; +} + +static char* Parser_linePreProcess(Args* outbuffs, char* line) { + line = Parser_removeAnnotation(line); + Arg* line_buff = NULL; + int line_num = 0; + /* check syntex error */ + if (Lexer_isError(line)) { + line = NULL; + goto exit; + } + /* process EOL */ + line = strsDeleteChar(outbuffs, line, '\r'); + /* process import */ + line = Suger_import(outbuffs, line); + + /* process multi assign */ + line_num = strCountSign(line, '\n') + 1; + line_buff = arg_newStr(""); + for (int i = 0; i < line_num; i++) { + if (i > 0) { + line_buff = arg_strAppend(line_buff, "\n"); + } + char* single_line = strsPopToken(outbuffs, &line, '\n'); + single_line = Suger_multiAssign(outbuffs, single_line); + line_buff = arg_strAppend(line_buff, single_line); + } + line = strsCopy(outbuffs, arg_getStr(line_buff)); +exit: + if (NULL != line_buff) { + arg_deinit(line_buff); + } + return line; +} + +char* Parser_LineToAsm(Args* buffs_p, char* line, Stack* blockStack) { + char* ASM = NULL; + AST* ast = NULL; + uint8_t line_num = 0; + /* pre process */ + line = Parser_linePreProcess(buffs_p, line); + if (NULL == line) { + /* preprocess error */ + goto exit; + } + if (strEqu("@annontation", line)) { + ASM = ""; + goto exit; + } + /* + solve more lines + preprocess may generate more lines + */ + line_num = strCountSign(line, '\n') + 1; + for (int i = 0; i < line_num; i++) { + char* single_line = strsPopToken(buffs_p, &line, '\n'); + /* parse line to AST */ + ast = AST_parseLine_withBlockStack(single_line, blockStack); + /* gen ASM from AST */ + if (ASM == NULL) { + ASM = AST_genAsm(ast, buffs_p); + } else { + ASM = strsAppend(buffs_p, ASM, AST_genAsm(ast, buffs_p)); + } + if (NULL != ast) { + AST_deinit(ast); + } + } +exit: + return ASM; +} + +static int Parser_isVoidLine(char* line) { + for (uint32_t i = 0; i < strGetSize(line); i++) { + if (line[i] != ' ') { + return 0; + } + } + return 1; +} + +static uint8_t Parser_checkIsMultiComment(char* line) { + for (uint32_t i = 0; i < strGetSize(line); i++) { + /* not match ' or " */ + if ((line[i] != '\'') && (line[i] != '"')) { + continue; + } + /* not match ''' or """ */ + if (!((line[i + 1] == line[i]) && (line[i + 2] == line[i]))) { + continue; + } + /* check char befor the ''' or """ */ + if (!((0 == i) || (line[i - 1] == ' '))) { + continue; + } + /* check char after the ''' or """ */ + if (!((line[i + 3] == ' ') || (line[i + 3] == 0))) { + continue; + } + /* mached */ + return 1; + } + /* not mached */ + return 0; +} + +static char* _Parser_linesToBytesOrAsm(Args* outBuffs, + ByteCodeFrame* bytecode_frame, + char* py_lines) { + Stack block_stack; + stack_init(&block_stack); + Arg* asm_buff = arg_newStr(""); + uint32_t lines_offset = 0; + uint16_t lines_num = strCountSign(py_lines, '\n') + 1; + uint16_t lines_index = 0; + uint8_t is_in_multi_comment = 0; + Arg* line_connection_arg = arg_newStr(""); + uint8_t is_line_connection = 0; + char* out_ASM = NULL; + char* single_ASM = NULL; + uint32_t line_size = 0; + /* parse each line */ + while (1) { + lines_index++; + Args buffs = {0}; + char* line_origin = NULL; + char* line = NULL; + + /* add void line to the end */ + if (lines_index >= lines_num + 1) { + line = ""; + goto parse_line; + } + + /* get single line by pop multiline */ + line_origin = strsGetFirstToken(&buffs, py_lines + lines_offset, '\n'); + + line = strsCopy(&buffs, line_origin); + /* line connection */ + if (is_line_connection) { + is_line_connection = 0; + line_connection_arg = arg_strAppend(line_connection_arg, line); + line = strsCopy(&buffs, arg_getStr(line_connection_arg)); + /* reflash the line_connection_arg */ + arg_deinit(line_connection_arg); + line_connection_arg = arg_newStr(""); + } + + /* check connection */ + if ('\\' == line[strGetSize(line) - 1]) { + /* remove the '\\' */ + line[strGetSize(line) - 1] = '\0'; + is_line_connection = 1; + line_connection_arg = arg_strAppend(line_connection_arg, line); + goto next_line; + } + Cursor_forEachToken(c, line) { + Cursor_iterStart(&c); + Cursor_iterEnd(&c); + } + Cursor_deinit(&c); + /* auto connection */ + if (lines_index < lines_num) { + if (c.branket_deepth > 0) { + line_connection_arg = arg_strAppend(line_connection_arg, line); + is_line_connection = 1; + goto next_line; + } + } + + /* branket match failed */ + if (c.branket_deepth != 0) { + single_ASM = NULL; + goto parse_after; + } + + /* support Tab */ + line = strsReplace(&buffs, line, "\t", " "); + /* remove \r */ + line = strsReplace(&buffs, line, "\r", ""); + + /* filter for not end \n */ + if (Parser_isVoidLine(line)) { + goto next_line; + } + + /* filter for multiline comment ''' or """ */ + if (Parser_checkIsMultiComment(line)) { + is_in_multi_comment = ~is_in_multi_comment; + goto next_line; + } + + /* skipe multiline comment */ + if (is_in_multi_comment) { + goto next_line; + } + + parse_line: + /* parse single Line to Asm */ + single_ASM = Parser_LineToAsm(&buffs, line, &block_stack); + parse_after: + if (NULL == single_ASM) { + out_ASM = NULL; + strsDeinit(&buffs); + goto exit; + } + + if (NULL == bytecode_frame) { + /* store ASM */ + asm_buff = arg_strAppend(asm_buff, single_ASM); + } else if (NULL == outBuffs) { + /* store ByteCode */ + byteCodeFrame_appendFromAsm(bytecode_frame, single_ASM); + } + + next_line: + if (lines_index < lines_num) { + line_size = strGetSize(line_origin); + lines_offset = lines_offset + line_size + 1; + } + strsDeinit(&buffs); + + /* exit when finished */ + if (lines_index >= lines_num + 1) { + break; + } + } + if (NULL != outBuffs) { + /* load stored ASM */ + out_ASM = strsCopy(outBuffs, arg_getStr(asm_buff)); + } else { + out_ASM = (char*)1; + } + goto exit; +exit: + if (NULL != asm_buff) { + arg_deinit(asm_buff); + } + if (NULL != line_connection_arg) { + arg_deinit(line_connection_arg); + } + stack_deinit(&block_stack); + return out_ASM; +}; + +PIKA_RES Parser_linesToBytes(ByteCodeFrame* bf, char* py_lines) { +#if PIKA_BYTECODE_ONLY_ENABLE + pika_platform_printf( + "Error: In bytecode-only mode, can not parse python script.\r\n"); + pika_platform_printf( + " Note: Please check PIKA_BYTECODE_ONLY_ENABLE config.\r\n"); + return PIKA_RES_ERR_SYNTAX_ERROR; +#else + if (1 == (uintptr_t)_Parser_linesToBytesOrAsm(NULL, bf, py_lines)) { + return PIKA_RES_OK; + } + return PIKA_RES_ERR_SYNTAX_ERROR; +#endif +} + +char* Parser_linesToAsm(Args* outBuffs, char* multi_line) { + return _Parser_linesToBytesOrAsm(outBuffs, NULL, multi_line); +} + +char* Parser_fileToAsm(Args* outBuffs, char* filename) { + Args buffs = {0}; + Arg* file_arg = arg_loadFile(NULL, filename); + pika_assert(NULL != file_arg); + if (NULL == file_arg) { + return NULL; + } + char* lines = (char*)arg_getBytes(file_arg); + /* replace the "\r\n" to "\n" */ + lines = strsReplace(&buffs, lines, "\r\n", "\n"); + /* clear the void line */ + lines = strsReplace(&buffs, lines, "\n\n", "\n"); + /* add '\n' at the end */ + lines = strsAppend(&buffs, lines, "\n\n"); + char* res = Parser_linesToAsm(&buffs, lines); + arg_deinit(file_arg); + res = strsCopy(outBuffs, res); + strsDeinit(&buffs); + return res; +} + +char* AST_genAsm_sub(AST* ast, AST* subAst, Args* outBuffs, char* pikaAsm) { + int deepth = obj_getInt(ast, "deepth"); + Args buffs = {0}; + /* append each queue item */ + while (1) { + QueueObj* subStmt = queueObj_popObj(subAst); + if (NULL == subStmt) { + break; + } + obj_setInt(ast, "deepth", deepth + 1); + pikaAsm = AST_genAsm_sub(ast, subStmt, &buffs, pikaAsm); + } + + /* Byte code generate rules */ + const GenRule rules_subAst[] = { + {.ins = "RUN", .type = VAL_DYNAMIC, .ast = "method"}, + {.ins = "OPT", .type = VAL_DYNAMIC, .ast = "operator"}, + {.ins = "BYT", .type = VAL_DYNAMIC, .ast = "bytes"}, + {.ins = "NUM", .type = VAL_DYNAMIC, .ast = "num"}, + {.ins = "IMP", .type = VAL_DYNAMIC, .ast = "import"}, + {.ins = "REF", .type = VAL_DYNAMIC, .ast = "ref"}, + {.ins = "STR", .type = VAL_DYNAMIC, .ast = "string"}, + {.ins = "SLC", .type = VAL_NONEVAL, .ast = "slice"}, + {.ins = "DCT", .type = VAL_NONEVAL, .ast = "dict"}, + {.ins = "LST", .type = VAL_NONEVAL, .ast = "list"}, + {.ins = "OUT", .type = VAL_DYNAMIC, .ast = "left"}}; + + char* buff = args_getBuff(&buffs, PIKA_SPRINTF_BUFF_SIZE); + + /* append the syntax item */ + for (size_t i = 0; i < sizeof(rules_subAst) / sizeof(GenRule); i++) { + GenRule rule = rules_subAst[i]; + char* astNodeVal = obj_getStr(subAst, rule.ast); + if (NULL != astNodeVal) { + /* e.g. "0 RUN print \n" */ + pika_platform_sprintf(buff, "%d %s ", deepth, rule.ins); + Arg* abuff = arg_newStr(buff); + if (rule.type == VAL_DYNAMIC) { + abuff = arg_strAppend(abuff, astNodeVal); + } + abuff = arg_strAppend(abuff, "\n"); + pikaAsm = strsAppend(&buffs, pikaAsm, arg_getStr(abuff)); + arg_deinit(abuff); + } + } + + obj_setInt(ast, "deepth", deepth - 1); + goto exit; +exit: + pikaAsm = strsCopy(outBuffs, pikaAsm); + strsDeinit(&buffs); + return pikaAsm; +} + +char* ASM_addBlockDeepth(AST* ast, + Args* buffs_p, + char* pikaAsm, + uint8_t deepthOffset) { + pikaAsm = strsAppend(buffs_p, pikaAsm, (char*)"B"); + char buff[11]; + pikaAsm = + strsAppend(buffs_p, pikaAsm, + fast_itoa(buff, AST_getBlockDeepthNow(ast) + deepthOffset)); + pikaAsm = strsAppend(buffs_p, pikaAsm, (char*)"\n"); + return pikaAsm; +} + +char* GenRule_toAsm(GenRule rule, + Args* buffs, + AST* ast, + char* pikaAsm, + int deepth) { + char* buff = args_getBuff(buffs, PIKA_SPRINTF_BUFF_SIZE); + /* parse stmt ast */ + pikaAsm = AST_genAsm_sub(ast, ast, buffs, pikaAsm); + /* e.g. "0 CTN \n" */ + pika_platform_sprintf(buff, "%d %s ", deepth, rule.ins); + Arg* abuff = arg_newStr(buff); + if (rule.type == VAL_DYNAMIC) { + abuff = arg_strAppend(abuff, obj_getStr(ast, rule.ast)); + } + if (rule.type == VAL_STATIC_) { + abuff = arg_strAppend(abuff, rule.val); + } + abuff = arg_strAppend(abuff, "\n"); + pikaAsm = strsAppend(buffs, pikaAsm, arg_getStr(abuff)); + arg_deinit(abuff); + return pikaAsm; +} + +char* AST_genAsm(AST* ast, Args* outBuffs) { + const GenRule rules_topAst[] = { + {.ins = "CTN", .type = VAL_NONEVAL, .ast = "continue"}, + {.ins = "BRK", .type = VAL_NONEVAL, .ast = "break"}, + {.ins = "DEL", .type = VAL_DYNAMIC, .ast = "del"}, + {.ins = "GLB", .type = VAL_DYNAMIC, .ast = "global"}, + {.ins = "RIS", .type = VAL_DYNAMIC, .ast = "raise"}, + {.ins = "ASS", .type = VAL_NONEVAL, .ast = "assert"}, + {.ins = "RET", .type = VAL_NONEVAL, .ast = "return"}}; + + /* generate code for block ast */ + const GenRule rules_block[] = { + {.ins = "TRY", .type = VAL_NONEVAL, .ast = "try"}, + {.ins = "EXP", .type = VAL_NONEVAL, .ast = "except"}, + {.ins = "NEL", .type = VAL_STATIC_, .ast = "else", .val = "1"}, + {.ins = "JEZ", .type = VAL_STATIC_, .ast = "if", .val = "1"}, + {.ins = "JEZ", .type = VAL_STATIC_, .ast = "while", .val = "2"}, + }; + + Args buffs = {0}; + char* pikaAsm = strsCopy(&buffs, ""); + QueueObj* exitBlock; + uint8_t is_block_matched; + if (NULL == ast) { + pikaAsm = NULL; + goto exit; + } + exitBlock = obj_getObj(ast, "exitBlock"); + /* exiting from block */ + if (exitBlock != NULL) { + while (1) { + uint8_t block_type_num = obj_getInt(exitBlock, "top") - + obj_getInt(exitBlock, "bottom") - 1; + char* block_type = queueObj_popStr(exitBlock); + if (NULL == block_type) { + break; + } + /* goto the while start when exit while block */ + if (strEqu(block_type, "while")) { + pikaAsm = + ASM_addBlockDeepth(ast, outBuffs, pikaAsm, block_type_num); + pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"0 JMP -1\n"); + } +#if PIKA_SYNTAX_EXCEPTION_ENABLE + /* goto the while start when exit while block */ + if (strEqu(block_type, "try")) { + pikaAsm = + ASM_addBlockDeepth(ast, outBuffs, pikaAsm, block_type_num); + pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"0 NTR \n"); + pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"0 GER \n"); + pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"0 JEZ 2\n"); + } + + if (strEqu(block_type, "except")) { + pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"0 SER 0\n"); + } +#endif + /* goto the while start when exit while block */ + if (strEqu(block_type, "for")) { + pikaAsm = + ASM_addBlockDeepth(ast, outBuffs, pikaAsm, block_type_num); + pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"0 JMP -1\n"); + /* garbage collect for the list */ + pikaAsm = + ASM_addBlockDeepth(ast, outBuffs, pikaAsm, block_type_num); + char _l_x[] = "$lx"; + char block_deepth_char = + AST_getBlockDeepthNow(ast) + block_type_num + '0'; + _l_x[sizeof(_l_x) - 2] = block_deepth_char; + pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"0 DEL "); + pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)_l_x); + pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"\n"); + } + /* return when exit method */ + if (strEqu(block_type, "def")) { + pikaAsm = ASM_addBlockDeepth(ast, outBuffs, pikaAsm, + block_type_num + 1); + pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"0 RET \n"); + } + /* return when exit class */ + if (strEqu(block_type, "class")) { + pikaAsm = ASM_addBlockDeepth(ast, outBuffs, pikaAsm, + block_type_num + 1); + pikaAsm = + strsAppend(outBuffs, pikaAsm, (char*)"0 RAS $origin\n"); + pikaAsm = ASM_addBlockDeepth(ast, outBuffs, pikaAsm, 1); + pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"0 NEW self\n"); + pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"0 RET \n"); + } + } + } + /* add block deepth */ + /* example: B0 */ + pikaAsm = ASM_addBlockDeepth(ast, outBuffs, pikaAsm, 0); + + /* "deepth" is invoke deepth, not the blockDeepth */ + obj_setInt(ast, "deepth", 0); + + /* match block */ + is_block_matched = 0; + if (strEqu(AST_getThisBlock(ast), "for")) { + /* for "for" iter */ + char* arg_in = obj_getStr(ast, "arg_in"); +#if !PIKA_NANO_ENABLE + char* arg_in_kv = NULL; +#endif + Arg* newAsm_arg = arg_newStr(""); + char _l_x[] = "$lx"; + char block_deepth_char = '0'; + block_deepth_char += AST_getBlockDeepthNow(ast); + _l_x[sizeof(_l_x) - 2] = block_deepth_char; + /* init iter */ + /* get the iter(_l) */ + pikaAsm = AST_genAsm_sub(ast, ast, &buffs, pikaAsm); + newAsm_arg = arg_strAppend(newAsm_arg, "0 OUT "); + newAsm_arg = arg_strAppend(newAsm_arg, _l_x); + newAsm_arg = arg_strAppend(newAsm_arg, "\n"); + pikaAsm = strsAppend(&buffs, pikaAsm, arg_getStr(newAsm_arg)); + arg_deinit(newAsm_arg); + newAsm_arg = arg_newStr(""); + /* get next */ + /* run next(_l) */ + /* check item is exist */ + /* + $n = $lx.next() + EST $n + k, v = $n + DEL $n + */ + +#if !PIKA_NANO_ENABLE + if (_check_is_multi_assign(arg_in)) { + arg_in_kv = arg_in; + arg_in = "$tmp"; + } +#endif + + pikaAsm = ASM_addBlockDeepth(ast, outBuffs, pikaAsm, 0); + newAsm_arg = arg_strAppend(newAsm_arg, "0 RUN "); + newAsm_arg = arg_strAppend(newAsm_arg, _l_x); + newAsm_arg = arg_strAppend(newAsm_arg, + ".__next__\n" + "0 OUT "); + newAsm_arg = arg_strAppend(newAsm_arg, arg_in); + newAsm_arg = arg_strAppend(newAsm_arg, + "\n" + "0 EST "); + newAsm_arg = arg_strAppend(newAsm_arg, arg_in); + newAsm_arg = arg_strAppend(newAsm_arg, "\n0 JEZ 2\n"); + pikaAsm = strsAppend(&buffs, pikaAsm, arg_getStr(newAsm_arg)); + arg_deinit(newAsm_arg); + +#if !PIKA_NANO_ENABLE + if (NULL != arg_in_kv) { + int out_num = 0; + while (1) { + char* item = Cursor_popToken(&buffs, &arg_in_kv, ","); + if (item[0] == '\0') { + break; + } + char* stmt = strsFormat(&buffs, PIKA_LINE_BUFF_SIZE, + "%s = $tmp[%d]\n", item, out_num); + + AST* ast_this = AST_parseLine_withBlockDeepth( + stmt, AST_getBlockDeepthNow(ast) + 1); + pikaAsm = + strsAppend(&buffs, pikaAsm, AST_genAsm(ast_this, &buffs)); + AST_deinit(ast_this); + out_num++; + } + pikaAsm = ASM_addBlockDeepth(ast, outBuffs, pikaAsm, 1); + pikaAsm = strsAppend(&buffs, pikaAsm, "0 DEL $tmp\n"); + } +#endif + + is_block_matched = 1; + goto exit; + } + if (strEqu(AST_getThisBlock(ast), "elif")) { + /* skip if __else is 0 */ + pikaAsm = strsAppend(&buffs, pikaAsm, "0 NEL 1\n"); + /* parse stmt ast */ + pikaAsm = AST_genAsm_sub(ast, ast, &buffs, pikaAsm); + /* skip if stmt is 0 */ + pikaAsm = strsAppend(&buffs, pikaAsm, "0 JEZ 1\n"); + is_block_matched = 1; + goto exit; + } + if (strEqu(AST_getThisBlock(ast), "def")) { +#if !PIKA_NANO_ENABLE + char* defaultStmts = AST_getNodeAttr(ast, "default"); +#endif + pikaAsm = strsAppend(&buffs, pikaAsm, "0 DEF "); + pikaAsm = strsAppend(&buffs, pikaAsm, AST_getNodeAttr(ast, "declare")); + pikaAsm = strsAppend(&buffs, pikaAsm, + "\n" + "0 JMP 1\n"); + +#if !PIKA_NANO_ENABLE + if (NULL != defaultStmts) { + int stmt_num = strGetTokenNum(defaultStmts, ','); + for (int i = 0; i < stmt_num; i++) { + char* stmt = strsPopToken(&buffs, &defaultStmts, ','); + char* arg_name = strsGetFirstToken(&buffs, stmt, '='); + pikaAsm = ASM_addBlockDeepth(ast, &buffs, pikaAsm, 1); + pikaAsm = strsAppend(&buffs, pikaAsm, "0 EST "); + pikaAsm = strsAppend(&buffs, pikaAsm, arg_name); + pikaAsm = strsAppend(&buffs, pikaAsm, "\n"); + pikaAsm = strsAppend(&buffs, pikaAsm, "0 JNZ 2\n"); + AST* ast_this = AST_parseLine_withBlockDeepth( + stmt, AST_getBlockDeepthNow(ast) + 1); + pikaAsm = + strsAppend(&buffs, pikaAsm, AST_genAsm(ast_this, &buffs)); + AST_deinit(ast_this); + } + } +#endif + + is_block_matched = 1; + goto exit; + } + + if (strEqu(AST_getThisBlock(ast), "class")) { + char* declare = obj_getStr(ast, "declare"); + char* thisClass = NULL; + char* superClass = NULL; + if (strIsContain(declare, '(')) { + thisClass = strsGetFirstToken(&buffs, declare, '('); + superClass = strsCut(&buffs, declare, '(', ')'); + } else { + thisClass = declare; + superClass = ""; + } + if (strEqu("", superClass)) { + /* default superClass */ + superClass = "TinyObj"; + } + if (strEqu("TinyObj", superClass)) { + /* default superClass */ + superClass = "TinyObj"; + } + pikaAsm = strsAppend(&buffs, pikaAsm, "0 CLS "); + pikaAsm = strsAppend(&buffs, pikaAsm, + strsAppend(&buffs, thisClass, + "()\n" + "0 JMP 1\n")); + char block_deepth_str[] = "B0\n"; + /* goto deeper block */ + block_deepth_str[1] += AST_getBlockDeepthNow(ast) + 1; + pikaAsm = strsAppend(&buffs, pikaAsm, block_deepth_str); + pikaAsm = strsAppend(&buffs, pikaAsm, "0 RUN "); + pikaAsm = strsAppend(&buffs, pikaAsm, superClass); + pikaAsm = strsAppend(&buffs, pikaAsm, "\n"); + pikaAsm = strsAppend(&buffs, pikaAsm, "0 OUT self\n"); + pikaAsm = strsAppend(&buffs, pikaAsm, block_deepth_str); + pikaAsm = strsAppend(&buffs, pikaAsm, "0 RAS self\n"); + is_block_matched = 1; + goto exit; + } + + for (size_t i = 0; i < sizeof(rules_block) / sizeof(GenRule); i++) { + GenRule rule = rules_block[i]; + if (strEqu(AST_getThisBlock(ast), rule.ast)) { + pikaAsm = GenRule_toAsm(rule, &buffs, ast, pikaAsm, 0); + is_block_matched = 1; + goto exit; + } + } + + /* generate code for top level ast */ + for (size_t i = 0; i < sizeof(rules_topAst) / sizeof(rules_topAst[0]); + i++) { + GenRule item = rules_topAst[i]; + if (obj_isArgExist(ast, item.ast)) { + pikaAsm = GenRule_toAsm(item, &buffs, ast, pikaAsm, 0); + is_block_matched = 1; + goto exit; + } + } +exit: + if (NULL == pikaAsm) { + strsDeinit(&buffs); + return NULL; + } + if (!is_block_matched) { + /* parse stmt ast */ + pikaAsm = AST_genAsm_sub(ast, ast, &buffs, pikaAsm); + } + + /* output pikaAsm */ + pikaAsm = strsCopy(outBuffs, pikaAsm); + strsDeinit(&buffs); + return pikaAsm; +} + +int32_t AST_deinit(AST* ast) { + return obj_deinit(ast); +} + +ByteCodeFrame* byteCodeFrame_appendFromAsm(ByteCodeFrame* self, char* pikaAsm) { + Asmer asmer = { + .asm_code = pikaAsm, + .block_deepth_now = 0, + .is_new_line = 0, + .line_pointer = pikaAsm, + }; + uint16_t const_pool_offset; + uint16_t exist_offset; + int invoke_deepth_int = 0; + for (int i = 0; i < strCountSign(pikaAsm, '\n'); i++) { + Args buffs = {0}; + char* line = strsGetLine(&buffs, asmer.line_pointer); + char* data = NULL; + char ins_str[4] = ""; + char invoke_deepth[3] = ""; + uint8_t space_num = 0; + uint8_t invoke_deepth_i = 0; + uint8_t ins_str_i = 0; + Arg* line_buff = arg_newStr(line); + strsDeinit(&buffs); + line = arg_getStr(line_buff); + InstructUnit ins_unit = {0}; + /* remove '\r' */ + if (line[strGetSize(line) - 1] == '\r') { + line[strGetSize(line) - 1] = 0; + } + /* process block deepth flag*/ + if ('B' == line[0]) { + asmer.block_deepth_now = fast_atoi(line + 1); + asmer.is_new_line = 1; + goto next_line; + } + + /* process each ins */ + + /* get constPool offset */ + const_pool_offset = 0; + + for (int i = 0; i < (int)strGetSize(line); i++) { + if (space_num < 2) { + if (line[i] == ' ') { + space_num++; + if (space_num == 2) { + data = line + i + 1; + break; + } + continue; + } + } + if (space_num == 0) { + invoke_deepth[invoke_deepth_i++] = line[i]; + continue; + } + if (space_num == 1) { + ins_str[ins_str_i++] = line[i]; + continue; + } + } + + exist_offset = constPool_getOffsetByData(&(self->const_pool), data); + + /* get const offset */ + if (strEqu(data, "")) { + /* not need const value */ + const_pool_offset = 0; + } else if (65535 == exist_offset) { + /* push new const value */ + const_pool_offset = constPool_getLastOffset(&(self->const_pool)); + /* load const to const pool buff */ + constPool_append(&(self->const_pool), data); + } else { + /* use exist const value */ + const_pool_offset = exist_offset; + } + + invoke_deepth_int = fast_atoi(invoke_deepth); + /* load Asm to byte code unit */ + instructUnit_setBlockDeepth(&ins_unit, asmer.block_deepth_now); + instructUnit_setInvokeDeepth(&ins_unit, invoke_deepth_int); + instructUnit_setConstPoolIndex(&ins_unit, const_pool_offset); + instructUnit_setInstruct(&ins_unit, pikaVM_getInstructFromAsm(ins_str)); + if (asmer.is_new_line) { + instructUnit_setIsNewLine(&ins_unit, 1); + asmer.is_new_line = 0; + } + + /* append instructUnit to instructArray */ + instructArray_append(&(self->instruct_array), &ins_unit); + + next_line: + /* point to next line */ + asmer.line_pointer += strGetLineSize(asmer.line_pointer) + 1; + arg_deinit(line_buff); + } + return self; +} + +char* Parser_linesToArray(char* lines) { + ByteCodeFrame bytecode_frame; + byteCodeFrame_init(&bytecode_frame); + Parser_linesToBytes(&bytecode_frame, lines); + /* do something */ + byteCodeFrame_print(&bytecode_frame); + + pika_platform_printf("\n\n/* clang-format off */\n"); + pika_platform_printf("PIKA_PYTHON(\n"); + pika_platform_printf("%s\n", lines); + pika_platform_printf(")\n"); + pika_platform_printf("/* clang-format on */\n"); + byteCodeFrame_printAsArray(&bytecode_frame); + /* deinit */ + byteCodeFrame_deinit(&bytecode_frame); + pika_platform_printf("\n\n"); + return NULL; +} diff --git a/examples/pikapython/pikapython/pikascript-core/PikaParser.h b/examples/pikapython/pikapython/pikascript-core/PikaParser.h new file mode 100644 index 00000000..6f5b0881 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/PikaParser.h @@ -0,0 +1,125 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __PIKA_PARSER__H +#define __PIKA_PARSER__H +#include "PikaVM.h" +#include "dataQueueObj.h" +#include "dataStack.h" + +typedef enum TokenType { + TOKEN_strEnd = 0, + TOKEN_symbol, + TOKEN_keyword, + TOKEN_operator, + TOKEN_devider, + TOKEN_literal, +} TokenType; + +enum StmtType { + STMT_reference, + STMT_tuple, + STMT_string, + STMT_bytes, + STMT_number, + STMT_method, + STMT_chain, + STMT_operator, + STMT_import, + STMT_list, + STMT_slice, + STMT_dict, + STMT_none, +}; + +typedef struct Asmer Asmer; +struct Asmer { + char* asm_code; + uint8_t block_deepth_now; + uint8_t is_new_line; + char* line_pointer; +}; + +typedef enum _GenRuleValType { + VAL_NONEVAL, + VAL_DYNAMIC, + VAL_STATIC_, +} GenRuleValType; + +typedef struct GenRule { + char* ins; + GenRuleValType type; + char* ast; + char* val; +} GenRule; + +typedef struct LexToken LexToken; +struct LexToken { + char* tokenStream; + enum TokenType type; + char* pyload; +}; + +typedef struct Cursor ParsetState; +struct Cursor { + char* tokenStream; + uint16_t length; + uint16_t iter_index; + int8_t branket_deepth; + struct LexToken token1; + struct LexToken token2; + Arg* last_token; + Args* iter_buffs; + Args* buffs_p; + PIKA_RES result; +}; + +char* Parser_fileToAsm(Args* outBuffs, char* filename); +char* Parser_linesToAsm(Args* outBuffs, char* multiLine); +PIKA_RES Parser_linesToBytes(ByteCodeFrame* bf, char* py_lines); +char* Parser_linesToArray(char* lines); + +char* instructUnit_fromAsmLine(Args* outBuffs, char* pikaAsm); +ByteCodeFrame* byteCodeFrame_appendFromAsm(ByteCodeFrame* bf, char* pikaAsm); + +#define Cursor_forEach(cursor) \ + _Cursor_beforeIter(&cursor); \ + for (int __i = 0; __i < cursor.length; __i++) + +#define Cursor_forEachTokenExistPs(cursor, tokenStream) \ + /* init parserStage */ \ + _Cursor_init(&cursor); \ + _Cursor_parse(&cursor, tokenStream); \ + Cursor_forEach(cursor) + +#define Cursor_forEachToken(cursor, tokenStream) \ + struct Cursor cursor; \ + Cursor_forEachTokenExistPs(cursor, tokenStream) + +uint16_t TokenStream_getSize(char* tokenStream); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/PikaPlatform.c b/examples/pikapython/pikapython/pikascript-core/PikaPlatform.c new file mode 100644 index 00000000..9325f837 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/PikaPlatform.c @@ -0,0 +1,538 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "PikaPlatform.h" +#include +#include + +PIKA_WEAK void pika_platform_disable_irq_handle(void) { + /* disable irq to support thread */ +} + +PIKA_WEAK void pika_platform_enable_irq_handle(void) { + /* disable irq to support thread */ +} + +PIKA_WEAK void* pika_platform_malloc(size_t size) { + return malloc(size); +} + +PIKA_WEAK void* pika_platform_realloc(void* ptr, size_t size) { + return realloc(ptr, size); +} + +PIKA_WEAK void* pika_platform_calloc(size_t num, size_t size) { + return calloc(num, size); +} + +PIKA_WEAK void pika_platform_free(void* ptr) { + free(ptr); +} + +PIKA_WEAK void* pika_user_malloc(size_t size) { + return pika_platform_malloc(size); +} + +PIKA_WEAK void pika_user_free(void* ptr, size_t size) { + pika_platform_free(ptr); +} + +PIKA_WEAK void pika_platform_error_handle() { + return; +} + +PIKA_WEAK void pika_platform_panic_handle() { + while (1) { + }; +} + +PIKA_WEAK uint8_t pika_is_locked_pikaMemory(void) { + return 0; +} + +PIKA_WEAK int64_t pika_platform_getTick(void) { + return -1; +} + +PIKA_WEAK int pika_platform_vsprintf(char* buff, char* fmt, va_list args) { + /* vsnprintf */ + return pika_platform_vsnprintf(buff, PIKA_SPRINTF_BUFF_SIZE, fmt, args); +} + +PIKA_WEAK int pika_platform_snprintf(char* buff, + size_t size, + const char* fmt, + ...) { + va_list args; + va_start(args, fmt); + int ret = pika_platform_vsnprintf(buff, size, fmt, args); + va_end(args); + return ret; +} + +PIKA_WEAK int pika_platform_putchar(char ch) { + return putchar(ch); +} + +PIKA_WEAK int pika_platform_vprintf(char* fmt, va_list args) { + /* vsprintf to vprintf */ + char buff[PIKA_SPRINTF_BUFF_SIZE]; + pika_platform_vsprintf(buff, fmt, args); + /* putchar */ + for (int i = 0; i < strlen(buff); i++) { + pika_platform_putchar(buff[i]); + } + return 0; +} + +#ifndef pika_platform_printf +PIKA_WEAK void pika_platform_printf(char* fmt, ...) { + va_list args; + va_start(args, fmt); + pika_platform_vprintf(fmt, args); + va_end(args); +} +#endif + +PIKA_WEAK char* pika_platform_strdup(const char* src) { + char* dst = (char*)pika_platform_malloc(strlen(src) + 1); + if (dst) { + strcpy(dst, src); + } + return dst; +} + +PIKA_WEAK size_t pika_platform_tick_from_millisecond(size_t ms) { + return ms; +} + +PIKA_WEAK int pika_platform_vsnprintf(char* buff, + size_t size, + const char* fmt, + va_list args) { + return vsnprintf(buff, size, fmt, args); +} + +PIKA_WEAK int pika_platform_sprintf(char* buff, char* fmt, ...) { + va_list args; + va_start(args, fmt); + int res = pika_platform_vsnprintf(buff, PIKA_SPRINTF_BUFF_SIZE, fmt, args); + va_end(args); + if (res >= PIKA_SPRINTF_BUFF_SIZE) { + pika_platform_printf( + "OverflowError: sprintf buff size overflow, please use bigger " + "PIKA_SPRINTF_BUFF_SIZE\r\n"); + pika_platform_printf("Info: buff size request: %d\r\n", res); + pika_platform_printf("Info: buff size now: %d\r\n", + PIKA_SPRINTF_BUFF_SIZE); + while (1) + ; + } + return res; +} + +PIKA_WEAK void pika_platform_wait(void) { + while (1) { + }; +} + +PIKA_WEAK void* pika_platform_memset(void* mem, int ch, size_t size) { + return memset(mem, ch, size); +} + +PIKA_WEAK void* pika_platform_memcpy(void* dir, const void* src, size_t size) { + return memcpy(dir, src, size); +} + +PIKA_WEAK int pika_platform_memcmp(const void* s1, const void* s2, size_t n) { + return memcmp(s1, s2, n); +} + +PIKA_WEAK void* pika_platform_memmove(void* s1, void* s2, size_t n) { + return memmove(s1, s2, n); +} + +PIKA_WEAK char pika_platform_getchar(void) { +#if defined(__linux) || defined(_WIN32) + return getchar(); +#else + pika_platform_printf( + "Error: pika_platform_getchar need implementation!\r\n"); + while (1) { + } +#endif +} + +/* fopen */ +PIKA_WEAK FILE* pika_platform_fopen(const char* filename, const char* modes) { +#if defined(__linux) || defined(_WIN32) + return fopen(filename, modes); +#else + pika_platform_printf("Error: pika_platform_fopen need implementation!\r\n"); + while (1) { + } +#endif +} + +/* fclose */ +PIKA_WEAK int pika_platform_fclose(FILE* stream) { +#if defined(__linux) || defined(_WIN32) + return fclose(stream); +#else + pika_platform_printf( + "Error: pika_platform_fclose need implementation!\r\n"); + while (1) { + } +#endif +} + +/* fwrite */ +PIKA_WEAK size_t pika_platform_fwrite(const void* ptr, + size_t size, + size_t n, + FILE* stream) { +#if defined(__linux) || defined(_WIN32) + return fwrite(ptr, size, n, stream); +#else + pika_platform_printf( + "Error: pika_platform_fwrite need implementation!\r\n"); + while (1) { + } +#endif +} + +/* fread */ +PIKA_WEAK size_t pika_platform_fread(void* ptr, + size_t size, + size_t n, + FILE* stream) { +#if defined(__linux) || defined(_WIN32) + return fread(ptr, size, n, stream); +#else + pika_platform_printf("Error: pika_platform_fread need implementation!\r\n"); + while (1) { + } +#endif +} + +/* fseek */ +PIKA_WEAK int pika_platform_fseek(FILE* stream, long offset, int whence) { +#if defined(__linux) || defined(_WIN32) + return fseek(stream, offset, whence); +#else + pika_platform_printf("Error: pika_platform_fseek need implementation!\r\n"); + while (1) { + } +#endif +} + +/* ftell */ +PIKA_WEAK long pika_platform_ftell(FILE* stream) { +#if defined(__linux) || defined(_WIN32) + return ftell(stream); +#else + pika_platform_printf("Error: pika_platform_ftell need implementation!\r\n"); + while (1) { + } +#endif +} + +PIKA_WEAK void pika_hook_instruct(void) { + return; +} + +PIKA_WEAK PIKA_BOOL pika_hook_arg_cache_filter(void* self) { + return PIKA_TRUE; +} + +PIKA_WEAK void pika_platform_thread_delay(void) { + return; +} + +PIKA_WEAK void pika_platform_sleep_ms(uint32_t ms) { + pika_platform_printf( + "Error: pika_platform_sleep_ms need implementation!\r\n"); + while (1) { + } +} + +PIKA_WEAK void pika_platform_sleep_s(uint32_t s) { + pika_platform_printf( + "Error: pika_platform_sleep_s need implementation!\r\n"); + while (1) { + } +} + +/* Thread Support */ +PIKA_WEAK pika_platform_thread_t* pika_platform_thread_init( + const char* name, + void (*entry)(void*), + void* const param, + unsigned int stack_size, + unsigned int priority, + unsigned int tick) { +#ifdef __linux + int res; + pika_platform_thread_t* thread; + void* (*thread_entry)(void*); + + thread_entry = (void* (*)(void*))entry; + thread = pika_platform_malloc(sizeof(pika_platform_thread_t)); + + res = pthread_create(&thread->thread, NULL, thread_entry, param); + if (res != 0) { + pika_platform_free(thread); + } + + thread->mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + thread->cond = (pthread_cond_t)PTHREAD_COND_INITIALIZER; + + return thread; +#elif PIKA_FREERTOS_ENABLE + BaseType_t err; + pika_platform_thread_t* thread; + + thread = pika_platform_malloc(sizeof(pika_platform_thread_t)); + + (void)tick; + + err = xTaskCreate(entry, name, stack_size, param, priority, thread->thread); + + if (pdPASS != err) { + pika_platform_free(thread); + return NULL; + } + + return thread; +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); + return NULL; +#endif +} + +PIKA_WEAK void pika_platform_thread_startup(pika_platform_thread_t* thread) { + (void)thread; +} + +PIKA_WEAK void pika_platform_thread_stop(pika_platform_thread_t* thread) { +#ifdef __linux + pthread_mutex_lock(&(thread->mutex)); + pthread_cond_wait(&(thread->cond), &(thread->mutex)); + pthread_mutex_unlock(&(thread->mutex)); +#elif PIKA_FREERTOS_ENABLE + vTaskSuspend(thread->thread); +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); +#endif +} + +PIKA_WEAK void pika_platform_thread_start(pika_platform_thread_t* thread) { +#ifdef __linux + pthread_mutex_lock(&(thread->mutex)); + pthread_cond_signal(&(thread->cond)); + pthread_mutex_unlock(&(thread->mutex)); +#elif PIKA_FREERTOS_ENABLE + vTaskResume(thread->thread); +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); +#endif +} + +PIKA_WEAK void pika_platform_thread_destroy(pika_platform_thread_t* thread) { +#ifdef __linux + if (NULL != thread) { + pthread_detach(thread->thread); + pika_platform_free(thread); + thread = NULL; + } +#elif PIKA_FREERTOS_ENABLE + if (NULL != thread) + vTaskDelete(thread->thread); + pika_platform_memory_free(thread); +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); +#endif +} + +PIKA_WEAK int pika_platform_thread_mutex_init(pika_platform_thread_mutex_t* m) { +#ifdef __linux + return pthread_mutex_init(&(m->mutex), NULL); +#elif PIKA_FREERTOS_ENABLE + m->mutex = xSemaphoreCreateMutex(); + return 0; +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); + return -1; +#endif +} + +PIKA_WEAK int pika_platform_thread_mutex_lock(pika_platform_thread_mutex_t* m) { +#ifdef __linux + return pthread_mutex_lock(&(m->mutex)); +#elif PIKA_FREERTOS_ENABLE + return xSemaphoreTake(m->mutex, portMAX_DELAY); +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); + return -1; +#endif +} + +PIKA_WEAK int pika_platform_thread_mutex_trylock( + pika_platform_thread_mutex_t* m) { +#ifdef __linux + return pthread_mutex_trylock(&(m->mutex)); +#elif PIKA_FREERTOS_ENABLE + return xSemaphoreTake(m->mutex, 0); +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); + return -1; +#endif +} + +PIKA_WEAK int pika_platform_thread_mutex_unlock( + pika_platform_thread_mutex_t* m) { +#ifdef __linux + return pthread_mutex_unlock(&(m->mutex)); +#elif PIKA_FREERTOS_ENABLE + return xSemaphoreGive(m->mutex); +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); + return -1; +#endif +} + +PIKA_WEAK int pika_platform_thread_mutex_destroy( + pika_platform_thread_mutex_t* m) { +#ifdef __linux + return pthread_mutex_destroy(&(m->mutex)); +#elif PIKA_FREERTOS_ENABLE + vSemaphoreDelete(m->mutex); + return 0; +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); + return -1; +#endif +} + +#if PIKA_FREERTOS_ENABLE +static uint32_t platform_uptime_ms(void) { +#if (configTICK_RATE_HZ == 1000) + return (uint32_t)xTaskGetTickCount(); +#else + TickType_t tick = 0u; + + tick = xTaskGetTickCount() * 1000; + return (uint32_t)((tick + configTICK_RATE_HZ - 1) / configTICK_RATE_HZ); +#endif +} +#endif + +PIKA_WEAK void pika_platform_timer_init(pika_platform_timer_t* timer) { +#ifdef __linux + timer->time = (struct timeval){0, 0}; +#elif PIKA_FREERTOS_ENABLE + timer->time = 0; +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); +#endif +} + +PIKA_WEAK void pika_platform_timer_cutdown(pika_platform_timer_t* timer, + unsigned int timeout) { +#ifdef __linux + struct timeval now; + gettimeofday(&now, NULL); + struct timeval interval = {timeout / 1000, (timeout % 1000) * 1000}; + timeradd(&now, &interval, &timer->time); +#elif PIKA_FREERTOS_ENABLE + timer->time = platform_uptime_ms(); + timer->time += timeout; +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); +#endif +} + +PIKA_WEAK char pika_platform_timer_is_expired(pika_platform_timer_t* timer) { +#ifdef __linux + struct timeval now, res; + gettimeofday(&now, NULL); + timersub(&timer->time, &now, &res); + return ((res.tv_sec < 0) || (res.tv_sec == 0 && res.tv_usec <= 0)); +#elif PIKA_FREERTOS_ENABLE + return platform_uptime_ms() > timer->time ? 1 : 0; +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); + return 1; +#endif +} + +PIKA_WEAK int pika_platform_timer_remain(pika_platform_timer_t* timer) { +#ifdef __linux + struct timeval now, res; + gettimeofday(&now, NULL); + timersub(&timer->time, &now, &res); + return (res.tv_sec < 0) ? 0 : res.tv_sec * 1000 + res.tv_usec / 1000; +#elif PIKA_FREERTOS_ENABLE + uint32_t now; + now = platform_uptime_ms(); + if (timer->time <= now) { + return 0; + } + return timer->time - now; +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); + return -1; +#endif +} + +PIKA_WEAK unsigned long pika_platform_timer_now(void) { +#ifdef __linux + return (unsigned long)time(NULL); +#elif PIKA_FREERTOS_ENABLE + return (unsigned long)platform_uptime_ms(); +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); + return 1; +#endif +} + +PIKA_WEAK void pika_platform_timer_usleep(unsigned long usec) { +#ifdef __linux + usleep(usec); +#elif PIKA_FREERTOS_ENABLE + TickType_t tick = 1; + if (usec != 0) { + tick = usec / portTICK_PERIOD_MS; + + if (tick == 0) + tick = 1; + } + vTaskDelay(tick); +#else + WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); +#endif +} diff --git a/examples/pikapython/pikapython/pikascript-core/PikaPlatform.h b/examples/pikapython/pikapython/pikascript-core/PikaPlatform.h new file mode 100644 index 00000000..4a8422d5 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/PikaPlatform.h @@ -0,0 +1,284 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* adapter for old api */ +#include "./pika_adapter_old_api.h" + +#ifndef __PIKA_PALTFORM__H +#define __PIKA_PALTFORM__H +#include +#include +#include +#include +#include +#include +#ifdef __linux +#include +#endif + +/* clang-format off */ +#if PIKA_ASSERT_ENABLE + #define pika_assert(expr) \ + if(!(expr)) { \ + pika_platform_printf("Assertion \"%s\" failed, in function: %s(). \r\n (at %s:%d)\n", #expr, __FUNCTION__, __FILE__, __LINE__); \ + abort(); \ + } +#else + #define pika_assert(...) +#endif +/* clang-format on */ + +/* Compiler */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 5000000) /* ARM Compiler \ + */ +#define PIKA_WEAK __attribute__((weak)) +#elif defined(__IAR_SYSTEMS_ICC__) /* for IAR Compiler */ +#define PIKA_WEAK __weak +#elif defined(__MINGW32__) /* MINGW32 Compiler */ +#define PIKA_WEAK +#elif defined(__GNUC__) /* GNU GCC Compiler */ +#define PIKA_WEAK __attribute__((weak)) +#endif +/* default PIKA_WEAK */ +#ifndef PIKA_WEAK +#define PIKA_WEAK +#endif + +/* align for bytecode */ +#if defined(_WIN32) +#define PIKA_BYTECODE_ALIGN +#else +#define PIKA_BYTECODE_ALIGN __attribute__((aligned(4))) +#endif + +/* OS */ +#ifdef __RTTHREAD__ +#include +#define pika_platform_printf(...) rt_kprintf(__VA_ARGS__) +#endif + +typedef enum { + PIKA_RES_OK = 0, + PIKA_RES_ERR_RUNTIME_ERROR = -1, + PIKA_RES_ERR_ARG_NO_FOUND = -2, + PIKA_RES_ERR_UNKNOWN_INSTRUCTION = -3, + PIKA_RES_ERR_OUT_OF_RANGE = -4, + PIKA_RES_ERR_IO_ERROR = -5, + PIKA_RES_ERR_INSUFFICIENT_RESOURCE = -6, + PIKA_RES_ERR_INVALID_PARAM = -7, + PIKA_RES_ERR_INVALID_PTR = -8, + PIKA_RES_ERR_UNALIGNED_PTR = -9, + PIKA_RES_ERR_INVALID_VERSION_NUMBER = -10, + PIKA_RES_ERR_ILLEGAL_MAGIC_CODE = -11, + PIKA_RES_ERR_OPERATION_FAILED = -12, + PIKA_RES_ERR_UNKNOWN = -13, + PIKA_RES_ERR_SYNTAX_ERROR = -14, + PIKA_RES_ERR_IO = -15, + PIKA_RES_ERR_ASSERT = -16, + PIKA_RES_ERR_SIGNAL_EVENT_FULL = -17, + PIKA_RES_ERR_SIGNAL_EVENT_EMPTY = -18, +} PIKA_RES; + +/* clang-format off */ + +/* pikascript bool type */ +typedef enum { + PIKA_TRUE = 1, + PIKA_FALSE = 0, +} PIKA_BOOL; + +/* clang-format on */ + +/* + [Note]: + Create a pika_config.c to override the following weak functions to config + PikaScript. [Example]: + 1. + https://gitee.com/Lyon1998/pikascript/blob/master/package/STM32G030Booter/pika_config.c + 2. + https://gitee.com/Lyon1998/pikascript/blob/master/package/pikaRTBooter/pika_config.c +*/ + +/* interrupt config */ +void pika_platform_enable_irq_handle(void); +void pika_platform_disable_irq_handle(void); + +/* printf family config */ +#ifndef pika_platform_printf +void pika_platform_printf(char* fmt, ...); +#endif +int pika_platform_sprintf(char* buff, char* fmt, ...); +int pika_platform_vsprintf(char* buff, char* fmt, va_list args); +int pika_platform_vsnprintf(char* buff, + size_t size, + const char* fmt, + va_list args); +int pika_platform_snprintf(char* buff, size_t size, const char* fmt, ...); +char* pika_platform_strdup(const char* src); +size_t pika_platform_tick_from_millisecond(size_t ms); + +/* libc config */ +void* pika_platform_malloc(size_t size); +void* pika_platform_realloc(void* ptr, size_t size); +void* pika_platform_calloc(size_t num, size_t size); +void pika_platform_free(void* ptr); +void* pika_platform_memset(void* mem, int ch, size_t size); +void* pika_platform_memcpy(void* dir, const void* src, size_t size); +int pika_platform_memcmp(const void* s1, const void* s2, size_t n); +void* pika_platform_memmove(void* s1, void* s2, size_t n); + +/* pika memory pool config */ +void pika_platform_wait(void); + +/* support shell */ +char pika_platform_getchar(void); +int pika_platform_putchar(char ch); + +/* file API */ +FILE* pika_platform_fopen(const char* filename, const char* modes); +int pika_platform_fclose(FILE* stream); +size_t pika_platform_fwrite(const void* ptr, + size_t size, + size_t n, + FILE* stream); +size_t pika_platform_fread(void* ptr, size_t size, size_t n, FILE* stream); +int pika_platform_fseek(FILE* stream, long offset, int whence); +long pika_platform_ftell(FILE* stream); + +/* error */ +void pika_platform_error_handle(void); + +/* panic */ +void pika_platform_panic_handle(void); + +void pika_platform_thread_delay(void); +int64_t pika_platform_getTick(void); + +void pika_platform_sleep_ms(uint32_t ms); +void pika_platform_sleep_s(uint32_t s); + +void pika_hook_instruct(void); +PIKA_BOOL pika_hook_arg_cache_filter(void* self); +void* pika_user_malloc(size_t size); +void pika_user_free(void* ptr, size_t size); +uint8_t pika_is_locked_pikaMemory(void); + +#if PIKA_FLOAT_TYPE_DOUBLE +#define pika_float double +#else +#define pika_float float +#endif + +#ifdef _WIN32 +#pragma warning(disable : 4996) +#endif + +/* Thread Platform */ +#ifdef __linux +#include +typedef struct pika_platform_thread { + pthread_t thread; + pthread_mutex_t mutex; + pthread_cond_t cond; +} pika_platform_thread_t; +#elif PIKA_FREERTOS_ENABLE +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +typedef struct pika_platform_thread { + TaskHandle_t thread; +} pika_platform_thread_t; +#else +typedef struct pika_platform_thread { + void* platform_data; +} pika_platform_thread_t; +#endif + +pika_platform_thread_t* pika_platform_thread_init(const char* name, + void (*entry)(void*), + void* const param, + unsigned int stack_size, + unsigned int priority, + unsigned int tick); +void pika_platform_thread_startup(pika_platform_thread_t* thread); +void pika_platform_thread_stop(pika_platform_thread_t* thread); +void pika_platform_thread_start(pika_platform_thread_t* thread); +void pika_platform_thread_destroy(pika_platform_thread_t* thread); + +#ifdef __linux +#include +typedef struct pika_platform_thread_mutex { + pthread_mutex_t mutex; +} pika_platform_thread_mutex_t; +#elif PIKA_FREERTOS_ENABLE +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +typedef struct pika_platform_thread_mutex { + SemaphoreHandle_t mutex; +} pika_platform_thread_mutex_t; +#else +typedef struct pika_platform_thread_mutex { + void* platform_data; +} pika_platform_thread_mutex_t; +#endif + +int pika_platform_thread_mutex_init(pika_platform_thread_mutex_t* m); +int pika_platform_thread_mutex_lock(pika_platform_thread_mutex_t* m); +int pika_platform_thread_mutex_trylock(pika_platform_thread_mutex_t* m); +int pika_platform_thread_mutex_unlock(pika_platform_thread_mutex_t* m); +int pika_platform_thread_mutex_destroy(pika_platform_thread_mutex_t* m); + +#ifdef __linux +#include +typedef struct pika_platform_timer { + struct timeval time; +} pika_platform_timer_t; +#elif PIKA_FREERTOS_ENABLE +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +typedef struct pika_platform_timer { + uint32_t time; +} pika_platform_timer_t; +#else +typedef struct pika_platform_timer { + void* platform_data; +} pika_platform_timer_t; +#endif + +void pika_platform_timer_init(pika_platform_timer_t* timer); +void pika_platform_timer_cutdown(pika_platform_timer_t* timer, + unsigned int timeout); +char pika_platform_timer_is_expired(pika_platform_timer_t* timer); +int pika_platform_timer_remain(pika_platform_timer_t* timer); +unsigned long pika_platform_timer_now(void); +void pika_platform_timer_usleep(unsigned long usec); + +#define WEAK_FUNCTION_NEED_OVERRIDE_ERROR(_) \ + pika_platform_printf("Error: weak function `%s()` need override.\r\n", \ + __FUNCTION__); \ + pika_platform_panic_handle(); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/PikaVM.c b/examples/pikapython/pikapython/pikascript-core/PikaVM.c new file mode 100644 index 00000000..6f24cbbb --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/PikaVM.c @@ -0,0 +1,3562 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "PikaVM.h" +#include "BaseObj.h" +#include "PikaCompiler.h" +#include "PikaObj.h" +#include "PikaParser.h" +#include "PikaPlatform.h" +#include "dataStrs.h" +#if PIKA_MATH_ENABLE +#include +#endif + +volatile VMSignal PikaVMSignal = {.signal_ctrl = VM_SIGNAL_CTRL_NONE, + .vm_cnt = 0, +#if PIKA_EVENT_ENABLE + .cq = + { + .head = 0, + .tail = 0, + .res = {0}, + } +#endif +}; + +int _VMEvent_getVMCnt(void) { + return PikaVMSignal.vm_cnt; +} + +#if PIKA_EVENT_ENABLE +static PIKA_BOOL _cq_isEmpty(volatile EventCQ* cq) { + return (PIKA_BOOL)(cq->head == cq->tail); +} + +static PIKA_BOOL _cq_isFull(volatile EventCQ* cq) { + return (PIKA_BOOL)((cq->tail + 1) % PIKA_EVENT_LIST_SIZE == cq->head); +} +#endif + +void _VMEvent_deinit(void) { +#if !PIKA_EVENT_ENABLE + pika_platform_printf("PIKA_EVENT_ENABLE is not enable"); + pika_platform_panic_handle(); +#else + for (int i = 0; i < PIKA_EVENT_LIST_SIZE; i++) { + if (NULL != PikaVMSignal.cq.res[i]) { + arg_deinit(PikaVMSignal.cq.res[i]); + PikaVMSignal.cq.res[i] = NULL; + } + if (NULL != PikaVMSignal.cq.data[i]) { + arg_deinit(PikaVMSignal.cq.data[i]); + PikaVMSignal.cq.data[i] = NULL; + } + } +#endif +} + +PIKA_RES __eventListener_pushEvent(PikaEventListener* lisener, + uint32_t eventId, + Arg* eventData) { +#if !PIKA_EVENT_ENABLE + pika_platform_printf("PIKA_EVENT_ENABLE is not enable"); + pika_platform_panic_handle(); +#else + /* push to event_cq_buff */ + if (_cq_isFull(&PikaVMSignal.cq)) { + arg_deinit(eventData); + return PIKA_RES_ERR_SIGNAL_EVENT_FULL; + } + if (arg_getType(eventData) == ARG_TYPE_OBJECT_NEW) { + arg_setType(eventData, ARG_TYPE_OBJECT); + } + if (PikaVMSignal.cq.res[PikaVMSignal.cq.tail] != NULL) { + arg_deinit(PikaVMSignal.cq.res[PikaVMSignal.cq.tail]); + PikaVMSignal.cq.res[PikaVMSignal.cq.tail] = NULL; + } + if (PikaVMSignal.cq.data[PikaVMSignal.cq.tail] != NULL) { + arg_deinit(PikaVMSignal.cq.data[PikaVMSignal.cq.tail]); + PikaVMSignal.cq.data[PikaVMSignal.cq.tail] = NULL; + } + PikaVMSignal.cq.id[PikaVMSignal.cq.tail] = eventId; + PikaVMSignal.cq.data[PikaVMSignal.cq.tail] = eventData; + PikaVMSignal.cq.lisener[PikaVMSignal.cq.tail] = lisener; + PikaVMSignal.cq.tail = (PikaVMSignal.cq.tail + 1) % PIKA_EVENT_LIST_SIZE; + return PIKA_RES_OK; +#endif +} + +PIKA_RES __eventListener_popEvent(PikaEventListener** lisener_p, + uint32_t* id, + Arg** data, + int* head) { +#if !PIKA_EVENT_ENABLE + pika_platform_printf("PIKA_EVENT_ENABLE is not enable"); + pika_platform_panic_handle(); +#else + /* pop from event_cq_buff */ + if (_cq_isEmpty(&PikaVMSignal.cq)) { + return PIKA_RES_ERR_SIGNAL_EVENT_EMPTY; + } + *id = PikaVMSignal.cq.id[PikaVMSignal.cq.head]; + *data = PikaVMSignal.cq.data[PikaVMSignal.cq.head]; + *lisener_p = PikaVMSignal.cq.lisener[PikaVMSignal.cq.head]; + *head = PikaVMSignal.cq.head; + PikaVMSignal.cq.head = (PikaVMSignal.cq.head + 1) % PIKA_EVENT_LIST_SIZE; + return PIKA_RES_OK; +#endif +} + +void _VMEvent_pickupEvent(void) { +#if !PIKA_EVENT_ENABLE + pika_platform_printf("PIKA_EVENT_ENABLE is not enable"); + pika_platform_panic_handle(); +#else + PikaObj* event_lisener; + uint32_t event_id; + Arg* event_data; + int head; + if (PIKA_RES_OK == __eventListener_popEvent(&event_lisener, &event_id, + &event_data, &head)) { + Arg* res = + __eventListener_runEvent(event_lisener, event_id, event_data); + PikaVMSignal.cq.res[head] = res; + } +#endif +} + +VM_SIGNAL_CTRL VMSignal_getCtrl(void) { + return PikaVMSignal.signal_ctrl; +} + +void pks_vm_exit(void) { + PikaVMSignal.signal_ctrl = VM_SIGNAL_CTRL_EXIT; +} + +void pks_vmSignal_setCtrlElear(void) { + PikaVMSignal.signal_ctrl = VM_SIGNAL_CTRL_NONE; +} + +/* head declare start */ +static uint8_t VMState_getInputArgNum(VMState* vm); +static VMParameters* __pikaVM_runByteCodeFrameWithState( + PikaObj* self, + VMParameters* locals, + VMParameters* globals, + ByteCodeFrame* bytecode_frame, + uint16_t pc, + RunState* run_state); + +/* head declare end */ + +static void VMState_setErrorCode(VMState* vm, int8_t error_code) { + vm->error_code = error_code; +} + +static enum Instruct VMstate_getInstructWithOffset(VMState* vm, + int32_t offset) { + return instructUnit_getInstruct( + VMState_getInstructUnitWithOffset(vm, offset)); +} + +static int VMState_getBlockDeepthNow(VMState* vm) { + /* support run byteCode */ + InstructUnit* ins_unit = VMState_getInstructNow(vm); + return instructUnit_getBlockDeepth(ins_unit); +} + +#if !PIKA_NANO_ENABLE +static char* VMState_getConstWithOffset(VMState* vm, int32_t offset) { + return VMState_getConstWithInstructUnit( + vm, VMState_getInstructUnitWithOffset(vm, offset)); +} +#endif + +static int VMState_getInvokeDeepthNow(VMState* vm) { + /* support run byteCode */ + InstructUnit* ins_unit = VMState_getInstructNow(vm); + return instructUnit_getInvokeDeepth(ins_unit); +} + +static int32_t VMState_getAddrOffsetOfJmpBack(VMState* vm) { + int offset = 0; + int loop_deepth = -1; + + /* find loop deepth */ + while (1) { + offset -= instructUnit_getSize(); + InstructUnit* ins_unit_now = + VMState_getInstructUnitWithOffset(vm, offset); + uint16_t invoke_deepth = instructUnit_getInvokeDeepth(ins_unit_now); + enum Instruct ins = instructUnit_getInstruct(ins_unit_now); + char* data = VMState_getConstWithInstructUnit(vm, ins_unit_now); + if ((0 == invoke_deepth) && (JEZ == ins) && data[0] == '2') { + loop_deepth = instructUnit_getBlockDeepth(ins_unit_now); + break; + } + } + + offset = 0; + while (1) { + offset += instructUnit_getSize(); + InstructUnit* ins_unit_now = + VMState_getInstructUnitWithOffset(vm, offset); + enum Instruct ins = instructUnit_getInstruct(ins_unit_now); + char* data = VMState_getConstWithInstructUnit(vm, ins_unit_now); + int block_deepth_now = instructUnit_getBlockDeepth(ins_unit_now); + if ((block_deepth_now == loop_deepth) && (JMP == ins) && + data[0] == '-' && data[1] == '1') { + return offset; + } + } +} + +static int32_t VMState_getAddrOffsetFromJmp(VMState* vm) { + int offset = 0; + /* run byte Code */ + InstructUnit* this_ins_unit = VMState_getInstructNow(vm); + int thisBlockDeepth = instructUnit_getBlockDeepth(this_ins_unit); + int8_t blockNum = 0; + int pc_max = (int)VMState_getInstructArraySize(vm); + if (vm->jmp > 0) { + offset = 0; + while (1) { + offset += instructUnit_getSize(); + /* reach the end */ + if (vm->pc + offset >= pc_max) { + break; + } + this_ins_unit = VMState_getInstructUnitWithOffset(vm, offset); + if (instructUnit_getIsNewLine(this_ins_unit)) { + uint8_t blockDeepth = + instructUnit_getBlockDeepth(this_ins_unit); + if (blockDeepth <= thisBlockDeepth) { + blockNum++; + } + } + if (blockNum >= vm->jmp) { + break; + } + } + } + if (vm->jmp < 0) { + while (1) { + offset -= instructUnit_getSize(); + this_ins_unit = VMState_getInstructUnitWithOffset(vm, offset); + if (instructUnit_getIsNewLine(this_ins_unit)) { + uint8_t blockDeepth = + instructUnit_getBlockDeepth(this_ins_unit); + if (blockDeepth == thisBlockDeepth) { + blockNum--; + } + } + if (blockNum <= vm->jmp) { + break; + } + } + } + return offset; +} + +static int32_t VMState_getAddrOffsetOfBreak(VMState* vm) { + int32_t offset = VMState_getAddrOffsetOfJmpBack(vm); + /* byteCode */ + offset += instructUnit_getSize(); + return offset; +} + +#if !PIKA_NANO_ENABLE +static int32_t VMState_getAddrOffsetOfRaise(VMState* vm) { + int offset = 0; + InstructUnit* ins_unit_now = VMState_getInstructNow(vm); + while (1) { + offset += instructUnit_getSize(); + if (vm->pc + offset >= (int)VMState_getInstructArraySize(vm)) { + return 0; + } + ins_unit_now = VMState_getInstructUnitWithOffset(vm, offset); + enum Instruct ins = instructUnit_getInstruct(ins_unit_now); + if (NTR == ins) { + return offset; + } + /* if not found except, return */ + if (RET == ins) { + return 0; + } + } +} +#endif + +static int32_t VMState_getAddrOffsetOfContinue(VMState* vm) { + int32_t offset = VMState_getAddrOffsetOfJmpBack(vm); + /* byteCode */ + return offset; +} + +static void VMState_delLReg(VMState* vm, uint8_t index) { + PikaObj* obj = vm->lreg[index]; + if (NULL != obj) { + obj_refcntDec(obj); + vm->lreg[index] = NULL; + if (0 == obj_refcntNow(obj)) { + obj_deinit(obj); + } + } +} + +static void VMState_initReg(VMState* vm) { + for (uint8_t i = 0; i < PIKA_REGIST_SIZE; i++) { + vm->lreg[i] = NULL; + vm->ireg[i] = PIKA_FALSE; + } +} + +static PIKA_BOOL _checkLReg(char* data) { + if ((data[0] == '$') && (data[1] == 'l') && (data[2] >= '0') && + (data[2] <= '9')) { + return PIKA_TRUE; + } + return PIKA_FALSE; +} + +static uint8_t _getLRegIndex(char* data) { + return data[2] - '0'; +} + +static void VMState_setLReg(VMState* vm, uint8_t index, PikaObj* obj) { + obj_refcntInc(obj); + vm->lreg[index] = obj; +} + +typedef Arg* (*VM_instruct_handler)(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg); + +static Arg* VM_instruction_handler_NON(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + return NULL; +} + +Arg* __vm_get(VMState* vm, PikaObj* self, Arg* key, Arg* obj) { + ArgType type = arg_getType(obj); + Arg* obj_new = NULL; + int index = 0; + if (ARG_TYPE_INT == arg_getType(key)) { + index = arg_getInt(key); + } + if (ARG_TYPE_STRING == type) { +#if PIKA_STRING_UTF8_ENABLE + PIKA_BOOL is_temp = PIKA_FALSE; + obj_new = arg_newObj(_arg_to_obj(obj, &is_temp)); + type = arg_getType(obj_new); +#else + char* str_pyload = arg_getStr(obj); + char char_buff[] = " "; + if (index < 0) { + index = strGetSize(str_pyload) + index; + } + char_buff[0] = str_pyload[index]; + return arg_newStr(char_buff); +#endif + } + if (ARG_TYPE_BYTES == type) { + uint8_t* bytes_pyload = arg_getBytes(obj); + uint8_t byte_buff[] = " "; + if (index < 0) { + index = arg_getBytesSize(obj) + index; + } + byte_buff[0] = bytes_pyload[index]; + return arg_newBytes(byte_buff, 1); + } + if (argType_isObject(type)) { + PikaObj* arg_obj = NULL; + if (obj_new != NULL) { + arg_obj = arg_getPtr(obj_new); + } else { + arg_obj = arg_getPtr(obj); + } + obj_setArg(arg_obj, "__key", key); + /* clang-format off */ + PIKA_PYTHON( + __res = __getitem__(__key) + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x0c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00, 0x04, 0x13, + 0x00, + /* instruct array */ + 0x19, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x5f, 0x5f, 0x67, 0x65, + 0x74, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x72, + 0x65, 0x73, 0x00, + /* const pool */ + }; + if (NULL != vm) { + _do_pikaVM_runByteCode(arg_obj, arg_obj, arg_obj, (uint8_t*)bytes, + vm->run_state, PIKA_TRUE); + } else { + pikaVM_runByteCode(arg_obj, (uint8_t*)bytes); + } + Arg* __res = args_getArg(arg_obj->list, "__res"); + Arg* res = NULL; + if (NULL != __res) { + res = arg_copy(__res); + } + if (NULL != obj_new) { + arg_deinit(obj_new); + } + if (NULL == res) { + if (NULL != vm) { + VMState_setErrorCode(vm, PIKA_RES_ERR_ARG_NO_FOUND); + } + return arg_newNull(); + } + return res; + } + return arg_newNull(); +} + +Arg* _vm_slice(VMState* vm, + PikaObj* self, + Arg* end, + Arg* obj, + Arg* start, + int step) { +#if PIKA_SYNTAX_SLICE_ENABLE + /* No interger index only support __getitem__ */ + if (!(arg_getType(start) == ARG_TYPE_INT && + arg_getType(end) == ARG_TYPE_INT)) { + return __vm_get(vm, self, start, obj); + } + + int start_i = arg_getInt(start); + int end_i = arg_getInt(end); + + /* __slice__ is equal to __getitem__ */ + if (end_i - start_i == 1) { + return __vm_get(vm, self, start, obj); + } + + if (ARG_TYPE_STRING == arg_getType(obj)) { + char* string_slice(Args * outBuffs, char* str, int start, int end); + Args buffs = {0}; + Arg* sliced_arg = NULL; + char* sliced_str = + string_slice(&buffs, arg_getStr(obj), start_i, end_i); + if (NULL != sliced_str) { + sliced_arg = arg_newStr(sliced_str); + } else { + sliced_arg = arg_newNull(); + } + strsDeinit(&buffs); + return sliced_arg; + } + + if (ARG_TYPE_BYTES == arg_getType(obj)) { + size_t len = arg_getBytesSize(obj); + if (start_i < 0) { + start_i += len; + } + /* magit code, to the end */ + if (end_i == -99999) { + end_i = len; + } + if (end_i < 0) { + end_i += len; + } + Arg* sliced_arg = arg_newBytes(NULL, 0); + for (int i = start_i; i < end_i; i++) { + Arg* i_arg = arg_newInt(i); + Arg* item_arg = __vm_get(vm, self, i_arg, obj); + uint8_t* bytes_origin = arg_getBytes(sliced_arg); + size_t size_origin = arg_getBytesSize(sliced_arg); + Arg* sliced_arg_new = arg_newBytes(NULL, size_origin + 1); + pika_platform_memcpy(arg_getBytes(sliced_arg_new), bytes_origin, + size_origin); + pika_platform_memcpy(arg_getBytes(sliced_arg_new) + size_origin, + arg_getBytes(item_arg), 1); + arg_deinit(sliced_arg); + sliced_arg = sliced_arg_new; + arg_deinit(item_arg); + arg_deinit(i_arg); + } + return sliced_arg; + } + + if (argType_isObject(arg_getType(obj))) { + PikaObj* arg_obj = arg_getPtr(obj); + PikaObj* New_PikaStdData_List(Args * args); + PikaObj* New_PikaStdData_Tuple(Args * args); + if (arg_obj->constructor == New_PikaStdData_List || + arg_obj->constructor == New_PikaStdData_Tuple) { + PikaObj* sliced_obj = newNormalObj((NewFun)arg_obj->constructor); + __vm_List___init__(sliced_obj); + for (int i = start_i; i < end_i; i++) { + Arg* i_arg = arg_newInt(i); + Arg* item_arg = __vm_get(vm, self, i_arg, obj); + __vm_List_append(sliced_obj, item_arg); + arg_deinit(item_arg); + arg_deinit(i_arg); + } + return arg_newObj(sliced_obj); + } + } + return arg_newNull(); +#else + return __vm_get(vm, self, start, obj); +#endif +} + +static Arg* VM_instruction_handler_SLC(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { +#if PIKA_SYNTAX_SLICE_ENABLE + int n_input = VMState_getInputArgNum(vm); + if (n_input < 2) { + return arg_newNull(); + } + if (n_input == 2) { + Arg* key = stack_popArg_alloc(&vm->stack); + Arg* obj = stack_popArg_alloc(&vm->stack); + Arg* res = __vm_get(vm, self, key, obj); + arg_deinit(key); + arg_deinit(obj); + return res; + } + if (n_input == 3) { + Arg* end = stack_popArg_alloc(&vm->stack); + Arg* start = stack_popArg_alloc(&vm->stack); + Arg* obj = stack_popArg_alloc(&vm->stack); + Arg* res = _vm_slice(vm, self, end, obj, start, 1); + arg_deinit(end); + arg_deinit(obj); + arg_deinit(start); + return res; + } + return arg_newNull(); +#else + Arg* key = stack_popArg_alloc(&vm->stack); + Arg* obj = stack_popArg_alloc(&vm->stack); + Arg* res = __vm_get(vm, self, key, obj); + arg_deinit(key); + arg_deinit(obj); + return res; +#endif +} + +static Arg* VM_instruction_handler_TRY(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + pika_assert(NULL != vm->run_state); + vm->run_state->try_state = TRY_STATE_INNER; + return NULL; +} + +static Arg* VM_instruction_handler_EXP(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + return NULL; +} + +static Arg* VM_instruction_handler_NTR(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + vm->run_state->try_state = TRY_STATE_NONE; + return NULL; +} + +static Arg* VM_instruction_handler_NEW(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + Arg* origin_arg = obj_getArg(vm->locals, data); + Arg* new_arg = arg_copy(origin_arg); + arg_setType(origin_arg, ARG_TYPE_OBJECT); + arg_setType(new_arg, ARG_TYPE_OBJECT_NEW); + return new_arg; +} + +static Arg* _proxy_getattribute(PikaObj* host, char* name) { +#if PIKA_NANO_ENABLE + return NULL; +#endif + if ('@' != name[0] && obj_getFlag(host, OBJ_FLAG_PROXY_GETATTRIBUTE)) { + args_setStr(host->list, "@name", name); + /* clang-format off */ + PIKA_PYTHON( + @res = __getattribute__(@name) + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x0c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00, 0x04, 0x18, + 0x00, + /* instruct array */ + 0x1d, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x40, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x5f, 0x5f, 0x67, 0x65, + 0x74, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, + 0x5f, 0x00, 0x40, 0x72, 0x65, 0x73, 0x00, /* const pool */ + }; + pikaVM_runByteCode(host, (uint8_t*)bytes); + return args_getArg(host->list, "@res"); + } + return NULL; +} + +static Arg* _proxy_getattr(PikaObj* host, char* name) { +#if PIKA_NANO_ENABLE + return NULL; +#endif + if ('@' != name[0] && obj_getFlag(host, OBJ_FLAG_PROXY_GETATTR)) { + args_setStr(host->list, "@name", name); + /* clang-format off */ + PIKA_PYTHON( + @res = __getattr__(@name) + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x0c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00, 0x04, 0x13, + 0x00, + /* instruct array */ + 0x18, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x40, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x5f, 0x5f, 0x67, 0x65, + 0x74, 0x61, 0x74, 0x74, 0x72, 0x5f, 0x5f, 0x00, 0x40, 0x72, 0x65, + 0x73, 0x00, /* const pool */ + }; + pikaVM_runByteCode(host, (uint8_t*)bytes); + return args_getArg(host->list, "@res"); + } + return NULL; +} + +static Arg* VM_instruction_handler_REF(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + PikaObj* host_object = NULL; + char* arg_path = data; + char* arg_name = strPointToLastToken(arg_path, '.'); + PIKA_BOOL is_temp = PIKA_FALSE; + + switch (data[0]) { + case 'T': + if (strEqu(arg_path, (char*)"True")) { + return arg_setInt(arg_ret_reg, "", 1); + } + break; + case 'F': + if (strEqu(arg_path, (char*)"False")) { + return arg_setInt(arg_ret_reg, "", 0); + } + break; + case 'N': + if (strEqu(arg_path, (char*)"None")) { + return arg_setNull(arg_ret_reg); + } + break; + case 'R': + if (strEqu(arg_path, (char*)"RuntimeError")) { + return arg_setInt(arg_ret_reg, "", PIKA_RES_ERR_RUNTIME_ERROR); + } + break; + } + + Arg* res = NULL; + if (arg_path[0] == '.') { + /* find host from stack */ + Arg* host_obj = stack_popArg_alloc(&(vm->stack)); + if (argType_isObject(arg_getType(host_obj))) { + host_object = arg_getPtr(host_obj); + res = arg_copy_noalloc(obj_getArg(host_object, arg_path + 1), + arg_ret_reg); + } + arg_deinit(host_obj); + goto exit; + } + + /* host_object is self */ + if (NULL == host_object) { + if (!strIsContain(arg_path, '.')) { + host_object = vm->locals; + } + } + + /* find in local list first */ + if (NULL == host_object) { + host_object = obj_getHostObjWithIsTemp(vm->locals, arg_path, &is_temp); + } + + /* find in global list */ + if (NULL == host_object) { + host_object = obj_getHostObjWithIsTemp(vm->globals, arg_path, &is_temp); + } + + /* error cannot found host_object */ + if (NULL == host_object) { + goto exit; + } + + /* proxy */ + if (NULL == res) { + res = _proxy_getattribute(host_object, arg_name); + } + + /* find res in host */ + if (NULL == res) { + res = args_getArg(host_object->list, arg_name); + } + + /* find res in host prop */ + if (NULL == res) { + res = _obj_getProp(host_object, arg_name); + } + + /* find res in globlas */ + if (NULL == res) { + res = args_getArg(vm->globals->list, arg_name); + } + + /* proxy */ + if (NULL == res) { + res = _proxy_getattr(host_object, arg_name); + } + +exit: + if (NULL == res) { + VMState_setErrorCode(vm, PIKA_RES_ERR_ARG_NO_FOUND); + pika_platform_printf("NameError: name '%s' is not defined\r\n", + arg_path); + } else { + res = arg_copy_noalloc(res, arg_ret_reg); + } + if (is_temp) { + obj_deinit(host_object); + } + return res; +} + +static Arg* VM_instruction_handler_GER(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + PIKA_RES err = (PIKA_RES)vm->try_error_code; + Arg* err_arg = arg_newInt(err); + return err_arg; +} + +Arg* _get_return_arg(PikaObj* locals) { + Arg* res = args_getArg(locals->list, (char*)"@rt"); + args_removeArg_notDeinitArg(locals->list, res); + return res; +} + +Arg* _obj_runMethodArgWithState(PikaObj* self, + PikaObj* locals, + Arg* method_arg, + RunState* run_state, + Arg* ret_arg_reg) { + pika_assert(NULL != run_state); + Arg* return_arg = NULL; + /* get method Ptr */ + Method method_ptr = methodArg_getPtr(method_arg); + /* get method type list */ + ArgType method_type = arg_getType(method_arg); + /* error */ + if (ARG_TYPE_NONE == method_type) { + return NULL; + } + ByteCodeFrame* method_bytecodeFrame = + methodArg_getBytecodeFrame(method_arg); + + /* redirect to def context */ + if (!argType_isNative(method_type)) { + self = methodArg_getDefContext(method_arg); + } + + obj_setErrorCode(self, PIKA_RES_OK); + + /* run method */ + if (method_type == ARG_TYPE_METHOD_NATIVE) { + /* native method */ + method_ptr(self, locals->list); + /* get method return */ + return_arg = _get_return_arg(locals); + } else if (method_type == ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR) { + /* native method */ + method_ptr(self, locals->list); + /* get method return */ + return_arg = _get_return_arg(locals); + } else { + /* static method and object method */ + /* byteCode */ + uintptr_t insturctArray_start = (uintptr_t)instructArray_getByOffset( + &(method_bytecodeFrame->instruct_array), 0); + uint16_t pc = (uintptr_t)method_ptr - insturctArray_start; + locals = __pikaVM_runByteCodeFrameWithState( + self, locals, self, method_bytecodeFrame, pc, run_state); + + /* get method return */ + return_arg = _get_return_arg(locals); + } + return return_arg; +} + +Arg* obj_runMethodArgWithState(PikaObj* self, + PikaObj* method_args_obj, + Arg* method_arg, + RunState* try_state) { + return _obj_runMethodArgWithState(self, method_args_obj, method_arg, + try_state, NULL); +} + +Arg* obj_runMethodArgWithState_noalloc(PikaObj* self, + PikaObj* locals, + Arg* method_arg, + RunState* run_state, + Arg* ret_arg_reg) { + return _obj_runMethodArgWithState(self, locals, method_arg, run_state, + ret_arg_reg); +} + +Arg* obj_runMethodArg(PikaObj* self, + PikaObj* method_args_obj, + Arg* method_arg) { + RunState run_state = {.try_state = TRY_STATE_NONE, + .try_result = TRY_RESULT_NONE}; + return obj_runMethodArgWithState(self, method_args_obj, method_arg, + &run_state); +} + +static char* _kw_to_default_all(FunctionArgsInfo* f, + char* arg_name, + int* argc, + Arg* argv[], + Arg* call_arg) { +#if PIKA_NANO + return arg_name; +#endif + while (strIsContain(arg_name, '=')) { + strPopLastToken(arg_name, '='); + Arg* default_arg = NULL; + /* load default arg from kws */ + if (f->kw != NULL) { + default_arg = pikaDict_getArg(f->kw, arg_name); + if (default_arg != NULL) { + Arg* arg_new = arg_copy(default_arg); + argv[(*argc)++] = arg_new; + pikaDict_removeArg(f->kw, default_arg); + } + } + if (f->kw == NULL || default_arg == NULL) { + /* can not load defalut from kw */ + if (NULL != call_arg && f->is_default) { + /* load default from pos */ + if (f->i_arg > f->n_positional) { + arg_setNameHash(call_arg, + hash_time33EndWith(arg_name, ':')); + argv[(*argc)++] = call_arg; + return (char*)1; + } + } + } + arg_name = strPopLastToken(f->type_list, ','); + } + return arg_name; +} + +static int _kw_to_pos_one(FunctionArgsInfo* f, + char* arg_name, + int* argc, + Arg* argv[]) { + if (f->kw == NULL) { + return 0; + } + Arg* pos_arg = pikaDict_getArg(f->kw, arg_name); + if (pos_arg == NULL) { + return 0; + } + argv[(*argc)++] = arg_copy(pos_arg); + pikaDict_removeArg(f->kw, pos_arg); + return 1; +} + +static void _kw_to_pos_all(FunctionArgsInfo* f, int* argc, Arg* argv[]) { + int arg_num_need = f->n_positional - f->n_positional_got; + if (0 == arg_num_need) { + return; + } + for (int i = 0; i < arg_num_need; i++) { + char* arg_name = strPopLastToken(f->type_list, ','); + pika_assert(f->kw != NULL); + Arg* pos_arg = pikaDict_getArg(f->kw, arg_name); + pika_assert(pos_arg != NULL); + argv[(*argc)++] = arg_copy(pos_arg); + pikaDict_removeArg(f->kw, pos_arg); + } +} + +static void _loadLocalsFromArgv(Args* locals, int argc, Arg* argv[]) { + for (int i = 0; i < argc; i++) { + Arg* arg = argv[i]; + args_setArg(locals, arg); + } +} + +static void _type_list_parse(FunctionArgsInfo* f) { + if (f->type_list[0] == 0) { + f->n_positional = 0; + return; + } + int8_t res = strCountSign(f->type_list, ',') + 1; + int8_t x = strCountSign(f->type_list, '*'); + int8_t y = strCountSign(f->type_list, '='); + /* default */ + if (y > 0) { + res -= y; + f->is_default = PIKA_TRUE; + f->n_default = y; + } + /* vars */ + if (x == 1) { + f->is_vars = PIKA_TRUE; + f->n_positional = res - 1; + return; + } + /* kw */ + if (x == 2) { + f->is_keys = PIKA_TRUE; + f->n_positional = res - 1; + return; + } + /* vars and kw */ + if (x == 3) { + f->is_vars = PIKA_TRUE; + f->is_keys = PIKA_TRUE; + f->n_positional = res - 2; + return; + } + f->n_positional = res; + return; +} + +static void _kw_push(FunctionArgsInfo* f, Arg* call_arg, int i) { + if (NULL == f->kw) { + f->kw = New_pikaDict(); + } + if (NULL == f->kw_keys) { + f->kw_keys = New_pikaDict(); + } + arg_setIsKeyword(call_arg, PIKA_FALSE); + pikaDict_setArg(f->kw, call_arg); + char kw_keys_index_buff[11] = {0}; + char* kw_keys_index = fast_itoa(kw_keys_index_buff, i); + pikaDict_setArg(f->kw_keys, + arg_setInt(NULL, kw_keys_index, arg_getNameHash(call_arg))); +} + +static void _load_call_arg(VMState* vm, + Arg* call_arg, + FunctionArgsInfo* f, + int* i, + int* argc, + Arg* argv[]) { + /* load the kw arg */ + if (call_arg != NULL && arg_getIsKeyword(call_arg)) { + _kw_push(f, call_arg, *i); + return; + } + /* load variable arg */ + if (f->i_arg > f->n_positional) { + if (f->is_vars) { + pikaList_append(&(f->tuple)->super, call_arg); + /* the append would copy the arg */ + if (NULL != call_arg) { + arg_deinit(call_arg); + } + return; + } + } + char* arg_name = strPopLastToken(f->type_list, ','); + /* load default from kw */ + arg_name = _kw_to_default_all(f, arg_name, argc, argv, call_arg); + if (((char*)1) == arg_name) { + /* load default from pos */ + return; + } + /* load position arg */ + if (_kw_to_pos_one(f, arg_name, argc, argv)) { + /* load pos from kw */ + (f->n_positional_got)++; + /* restore the stack */ + (*i)--; + stack_pushArg(&(vm->stack), call_arg); + return; + } + /*load pos from pos */ + arg_setNameHash(call_arg, hash_time33EndWith(arg_name, ':')); + argv[(*argc)++] = call_arg; + (f->n_positional_got)++; +} + +static int _get_n_input_with_unpack(VMState* vm) { +#if PIKA_NANO_ENABLE + return VMState_getInputArgNum(vm); +#else + int n_input = VMState_getInputArgNum(vm); + int get_star = 0; + int unpack_num = 0; + for (int i = 0; i < n_input; i++) { + Arg* arg_check = stack_checkArg(&(vm->stack), i); + if (NULL == arg_check) { + break; + } + if (arg_getIsDoubleStarred(arg_check) || arg_getIsStarred(arg_check)) { + get_star++; + } + } + if (0 == get_star) { + return n_input; + } + Stack stack_tmp = {0}; + stack_init(&stack_tmp); + for (int i = 0; i < n_input; i++) { + /* unpack starred arg */ + Arg* call_arg = stack_popArg_alloc(&(vm->stack)); + if (call_arg == NULL) { + break; + } + if (arg_getIsStarred(call_arg)) { + pika_assert(argType_isObject(arg_getType(call_arg))); + PikaObj* obj = arg_getPtr(call_arg); + /* clang-format off */ + PIKA_PYTHON( + @l = __len__() + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x08, 0x00, 0x00, 0x00, /* instruct array size */ + 0x00, 0x82, 0x01, 0x00, 0x00, 0x04, 0x09, 0x00, /* instruct + array */ + 0x0c, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x6c, 0x65, 0x6e, 0x5f, 0x5f, 0x00, + 0x40, 0x6c, 0x00, /* const pool */ + }; + pikaVM_runByteCode(obj, (uint8_t*)bytes); + int len = obj_getInt(obj, "@l"); + for (int i_star_arg = len - 1; i_star_arg >= 0; i_star_arg--) { + obj_setInt(obj, "@d", i_star_arg); + /* clang-format off */ + PIKA_PYTHON( + @a = __getitem__(@d) + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x0c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x04, + 0x10, 0x00, + /* instruct array */ + 0x13, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x40, 0x64, 0x00, 0x5f, 0x5f, 0x67, 0x65, 0x74, 0x69, + 0x74, 0x65, 0x6d, 0x5f, 0x5f, 0x00, 0x40, 0x61, + 0x00, /* const pool */ + }; + pikaVM_runByteCode(obj, (uint8_t*)bytes); + Arg* arg_a = obj_getArg(obj, "@a"); + stack_pushArg(&stack_tmp, arg_copy(arg_a)); + unpack_num++; + } + goto __continue; + } + if (arg_getIsDoubleStarred(call_arg)) { + pika_assert(argType_isObject(arg_getType(call_arg))); + PikaObj* New_PikaStdData_Dict(Args * args); + PikaObj* obj = arg_getPtr(call_arg); + pika_assert(obj->constructor == New_PikaStdData_Dict); + PikaDict* dict = obj_getPtr(obj, "dict"); + int i_item = 0; + while (PIKA_TRUE) { + Arg* item_val = args_getArgByIndex(&dict->super, i_item); + if (NULL == item_val) { + break; + } + /* unpack as keyword arg */ + arg_setIsKeyword(item_val, PIKA_TRUE); + stack_pushArg(&stack_tmp, arg_copy(item_val)); + i_item++; + } + goto __continue; + } + stack_pushArg(&stack_tmp, arg_copy(call_arg)); + __continue: + if (NULL != call_arg) { + arg_deinit(call_arg); + } + } + int n_input_new = stack_getTop(&stack_tmp); + for (int i = 0; i < n_input_new; i++) { + Arg* arg = stack_popArg_alloc(&stack_tmp); + stack_pushArg(&(vm->stack), arg); + } + stack_deinit(&stack_tmp); + return n_input_new; +#endif +} + +#define vars_or_keys_or_default (f.is_vars || f.is_keys || f.is_default) +static int VMState_loadArgsFromMethodArg(VMState* vm, + PikaObj* method_host_obj, + Args* locals, + Arg* method_arg, + char* method_name, + int n_used) { + Arg* argv[PIKA_ARG_NUM_MAX] = {0}; + int argc = 0; + char _buffs1[PIKA_LINE_BUFF_SIZE] = {0}; + char* buffs1 = (char*)_buffs1; + char _buffs2[PIKA_LINE_BUFF_SIZE] = {0}; + char* buffs2 = (char*)_buffs2; + FunctionArgsInfo f = {0}; + char* type_list_buff = NULL; + /* get method type list */ + f.type_list = methodArg_getTypeList(method_arg, buffs1, sizeof(_buffs1)); + if (NULL == f.type_list) { + pika_platform_printf( + "OverflowError: type list is too long, please use bigger " + "PIKA_LINE_BUFF_SIZE\r\n"); + pika_platform_panic_handle(); + } + f.method_type = arg_getType(method_arg); + + /* get arg_num_pos */ + _type_list_parse(&f); + if (f.method_type == ARG_TYPE_METHOD_OBJECT) { + /* delete the 'self' */ + f.n_positional--; + } + + f.n_input = _get_n_input_with_unpack(vm); + + /* check arg num */ + if (f.method_type == ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR || + f.method_type == ARG_TYPE_METHOD_CONSTRUCTOR || + f.is_vars == PIKA_TRUE || n_used != 0) { + /* skip for constrctor */ + /* skip for variable args */ + /* n_used != 0 means it is a factory method */ + } else { + /* check position arg num */ + if (!vars_or_keys_or_default) { + if (f.n_positional != f.n_input) { + VMState_setErrorCode(vm, PIKA_RES_ERR_INVALID_PARAM); + pika_platform_printf( + "TypeError: %s() takes %d positional argument but %d were " + "given\r\n", + method_name, f.n_positional, f.n_input); + goto exit; + } + } +#if !PIKA_NANO_ENABLE + if (f.is_default) { + int8_t n_min = f.n_positional; + int8_t n_max = f.n_positional + f.n_default; + if (f.n_input < n_min || f.n_input > n_max) { + VMState_setErrorCode(vm, PIKA_RES_ERR_INVALID_PARAM); + pika_platform_printf( + "TypeError: %s() takes from %d to %d positional arguments " + "but %d were given\r\n", + method_name, n_min, n_max, f.n_input); + goto exit; + } + } +#endif + } + + if (vars_or_keys_or_default) { + f.n_arg = f.n_input; + } else { + f.n_arg = f.n_positional; + } + + /* create tuple/dict for vars/keys */ + if (vars_or_keys_or_default) { + if (strGetSize(f.type_list) > sizeof(_buffs2)) { + pika_platform_printf( + "OverFlowError: please use bigger PIKA_LINE_BUFF_SIZE\r\n"); + while (1) { + } + } + type_list_buff = strCopy(buffs2, f.type_list); + uint8_t n_typelist = strCountSign(type_list_buff, ',') + 1; + for (int i = 0; i < n_typelist; i++) { + char* arg_def = strPopLastToken(type_list_buff, ','); + if (arg_def[0] == '*' && arg_def[1] != '*') { + /* get variable tuple name */ + /* skip the '*' */ + f.var_tuple_name = arg_def + 1; + /* create tuple */ + if (NULL == f.tuple) { + f.tuple = New_pikaTuple(); + /* remove the format arg */ + strPopLastToken(f.type_list, ','); + } + continue; + } + if (arg_def[0] == '*' && arg_def[1] == '*') { + /* get kw dict name */ + f.kw_dict_name = arg_def + 2; + f.kw = New_pikaDict(); + f.kw_keys = New_pikaDict(); + /* remove the format arg */ + strPopLastToken(f.type_list, ','); + continue; + } + } + } + + /* load args */ + for (int i = 0; i < f.n_arg; i++) { + f.i_arg = f.n_arg - i; + Arg* call_arg = stack_popArg_alloc(&(vm->stack)); + _load_call_arg(vm, call_arg, &f, &i, &argc, argv); + } + +/* only default */ +#if !PIKA_NANO_ENABLE + if (strIsContain(f.type_list, '=')) { + char* arg_name = strPopLastToken(f.type_list, ','); + _kw_to_default_all(&f, arg_name, &argc, argv, NULL); + } + /* load kw to pos */ + _kw_to_pos_all(&f, &argc, argv); +#endif + + if (f.tuple != NULL) { + pikaList_reverse(&(f.tuple)->super); + /* load variable tuple */ + PikaObj* New_PikaStdData_Tuple(Args * args); + PikaObj* tuple_obj = newNormalObj(New_PikaStdData_Tuple); + obj_setPtr(tuple_obj, "list", f.tuple); + Arg* argi = + arg_setPtr(NULL, f.var_tuple_name, ARG_TYPE_OBJECT, tuple_obj); + argv[argc++] = argi; + } + + if (f.kw != NULL) { + if (NULL == f.kw_dict_name) { + f.kw_dict_name = "__kwargs"; + } + /* load kw dict */ + PikaObj* New_PikaStdData_Dict(Args * args); + PikaObj* dict_obj = newNormalObj(New_PikaStdData_Dict); + obj_setPtr(dict_obj, "dict", f.kw); + obj_setPtr(dict_obj, "_keys", f.kw_keys); + Arg* argi = arg_setPtr(NULL, f.kw_dict_name, ARG_TYPE_OBJECT, dict_obj); + argv[argc++] = argi; + } + + /* load 'self' as the first arg when call object method */ + if (f.method_type == ARG_TYPE_METHOD_OBJECT) { + Arg* call_arg = arg_setRef(NULL, "self", method_host_obj); + argv[argc++] = call_arg; + } + _loadLocalsFromArgv(locals, argc, argv); +exit: + return f.n_arg; +} + +void __vm_List_append(PikaObj* self, Arg* arg) { + PikaList* list = obj_getPtr(self, "list"); + pikaList_append(list, arg); +} + +void __vm_List___init__(PikaObj* self) { + PikaList* list = New_pikaList(); + obj_setPtr(self, "list", list); +} + +#if PIKA_BUILTIN_STRUCT_ENABLE +PikaObj* New_PikaStdData_List(Args* args); +PikaObj* New_PikaStdData_Tuple(Args* args); +#endif + +static Arg* _vm_create_list_or_tuple(PikaObj* self, + VMState* vm, + PIKA_BOOL is_list) { +#if PIKA_BUILTIN_STRUCT_ENABLE + NewFun constructor = is_list ? New_PikaStdData_List : New_PikaStdData_Tuple; + uint8_t n_arg = VMState_getInputArgNum(vm); + PikaObj* list = newNormalObj(constructor); + __vm_List___init__(list); + Stack stack = {0}; + stack_init(&stack); + /* load to local stack to change sort */ + for (int i = 0; i < n_arg; i++) { + Arg* arg = stack_popArg_alloc(&(vm->stack)); + pika_assert(arg != NULL); + stack_pushArg(&stack, arg); + } + for (int i = 0; i < n_arg; i++) { + Arg* arg = stack_popArg_alloc(&stack); + pika_assert(arg != NULL); + __vm_List_append(list, arg); + arg_deinit(arg); + } + stack_deinit(&stack); + return arg_newObj(list); +#else + return VM_instruction_handler_NON(self, vm, "", NULL); +#endif +} + +static Arg* VM_instruction_handler_LST(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + return _vm_create_list_or_tuple(self, vm, PIKA_TRUE); +} + +void __vm_Dict___init__(PikaObj* self) { + PikaDict* dict = New_pikaDict(); + PikaDict* keys = New_pikaDict(); + obj_setPtr(self, "dict", dict); + obj_setPtr(self, "_keys", keys); +} + +void __vm_Dict_set(PikaObj* self, Arg* arg, char* key) { + PikaDict* dict = obj_getPtr(self, "dict"); + PikaDict* keys = obj_getPtr(self, "_keys"); + Arg* arg_key = arg_setStr(NULL, key, key); + Arg* arg_new = arg_copy(arg); + arg_setName(arg_new, key); + pikaDict_setArg(dict, arg_new); + pikaDict_setArg(keys, arg_key); +} + +#if PIKA_BUILTIN_STRUCT_ENABLE +PikaObj* New_PikaStdData_Dict(Args* args); +#endif + +static Arg* VM_instruction_handler_DCT(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { +#if PIKA_BUILTIN_STRUCT_ENABLE + uint8_t n_arg = VMState_getInputArgNum(vm); + PikaObj* dict = newNormalObj(New_PikaStdData_Dict); + __vm_Dict___init__(dict); + Stack stack = {0}; + stack_init(&stack); + /* load to local stack to change sort */ + for (int i = 0; i < n_arg; i++) { + Arg* arg = stack_popArg_alloc(&(vm->stack)); + stack_pushArg(&stack, arg); + } + for (int i = 0; i < n_arg / 2; i++) { + Arg* key_arg = stack_popArg_alloc(&stack); + Arg* val_arg = stack_popArg_alloc(&stack); + __vm_Dict_set(dict, val_arg, arg_getStr(key_arg)); + arg_deinit(key_arg); + arg_deinit(val_arg); + } + stack_deinit(&stack); + return arg_newObj(dict); +#else + return VM_instruction_handler_NON(self, vm, data, arg_ret_reg); +#endif +} + +static Arg* VM_instruction_handler_RET(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + /* exit jmp signal */ + vm->jmp = VM_JMP_EXIT; + Arg* return_arg = stack_popArg_alloc(&(vm->stack)); + method_returnArg(vm->locals->list, return_arg); + return NULL; +} + +#if !PIKA_NANO_ENABLE +static char* _find_super_class_name(VMState* vm) { + /* find super class */ + int offset = 0; + char* super_class_name = NULL; + while (1) { + offset -= instructUnit_getSize(); + if (vm->pc + offset >= (int)VMState_getInstructArraySize(vm)) { + return 0; + } + if ((CLS == VMstate_getInstructWithOffset(vm, offset))) { + break; + } + } + + while (1) { + offset += instructUnit_getSize(); + if (vm->pc + offset >= (int)VMState_getInstructArraySize(vm)) { + return 0; + } + if ((RUN == instructUnit_getInstruct( + VMState_getInstructUnitWithOffset(vm, offset)))) { + super_class_name = VMState_getConstWithOffset(vm, offset); + return super_class_name; + } + } +} +#endif + +#if !PIKA_NANO_ENABLE +static char* _find_self_name(VMState* vm) { + /* find super class */ + int offset = 0; + char* self_name = NULL; + while (1) { + offset -= instructUnit_getSize(); + if (vm->pc + offset >= (int)VMState_getInstructArraySize(vm)) { + return 0; + } + if ((CLS == VMstate_getInstructWithOffset(vm, offset))) { + break; + } + } + + while (1) { + offset += instructUnit_getSize(); + if (vm->pc + offset >= (int)VMState_getInstructArraySize(vm)) { + return 0; + } + if ((OUT == instructUnit_getInstruct( + VMState_getInstructUnitWithOffset(vm, offset)))) { + self_name = VMState_getConstWithOffset(vm, offset); + return self_name; + } + } +} +#endif + +static Arg* VM_instruction_handler_RUN(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + Arg* return_arg = NULL; + VMParameters* sub_locals = NULL; + char* run_path = data; + PikaObj* method_host = NULL; + PikaObj* obj_this = NULL; + Arg* method = NULL; + Arg* host_arg = NULL; + PIKA_BOOL is_temp = PIKA_FALSE; + PIKA_BOOL skip_init = PIKA_FALSE; + char* sys_out; + int n_used = 0; + arg_newReg(arg_reg1, 64); + RunState sub_run_state = {.try_state = vm->run_state->try_state, + .try_result = TRY_RESULT_NONE}; + pika_assert(NULL != vm->run_state); + + /* inhert */ + if (vm->pc - 2 * (int)instructUnit_getSize() >= 0) { + if (CLS == VMstate_getInstructWithOffset( + vm, -2 * (int)instructUnit_getSize())) { + skip_init = PIKA_TRUE; + } + } + + /* tuple or single arg */ + if (run_path[0] == 0) { + if (VMState_getInputArgNum(vm) < 2) { + /* return arg directly */ + return_arg = stack_popArg(&(vm->stack), arg_ret_reg); + goto exit; + } + /* create a tuple */ + return_arg = _vm_create_list_or_tuple(self, vm, PIKA_FALSE); + goto exit; + } + +#if !PIKA_NANO_ENABLE + /* support for super() */ + if (strEqu(run_path, "super")) { + run_path = _find_super_class_name(vm); + vm->in_super = PIKA_TRUE; + vm->super_invoke_deepth = VMState_getInvokeDeepthNow(vm); + skip_init = PIKA_TRUE; + } +#endif + + /* return tiny obj */ + if (strEqu(run_path, "TinyObj")) { + return_arg = arg_newMetaObj(New_TinyObj); + goto exit; + } + + if (strEqu(run_path, "object")) { + return_arg = arg_newMetaObj(New_TinyObj); + goto exit; + } + + /* get method host obj from reg */ + if (NULL == method_host && _checkLReg(run_path)) { + uint8_t reg_index = _getLRegIndex(run_path); + method_host = vm->lreg[reg_index]; + } + +#if !PIKA_NANO_ENABLE + /* get method host obj from stack */ + if (NULL == method_host && run_path[0] == '.') { + /* get method host obj from stack */ + Arg* stack_tmp[PIKA_ARG_NUM_MAX] = {0}; + int n_arg = VMState_getInputArgNum(vm); + if (n_arg > PIKA_ARG_NUM_MAX) { + pika_platform_printf( + "[ERROR] Too many args in RUN instruction, please use bigger " + "#define PIKA_ARG_NUM_MAX\n"); + pika_platform_panic_handle(); + } + for (int i = 0; i < n_arg; i++) { + stack_tmp[i] = stack_popArg_alloc(&(vm->stack)); + } + host_arg = stack_tmp[n_arg - 1]; + method_host = _arg_to_obj(host_arg, &is_temp); + if (NULL != method_host) { + n_used++; + } + /* push back other args to stack */ + for (int i = n_arg - 2; i >= 0; i--) { + stack_pushArg(&(vm->stack), stack_tmp[i]); + } + } +#endif + + /* get method host obj from local scope */ + if (NULL == method_host) { + method_host = obj_getHostObjWithIsTemp(vm->locals, run_path, &is_temp); + } + + /* get method host obj from local scope */ + if (NULL == method_host) { + method_host = obj_getHostObjWithIsTemp(vm->globals, run_path, &is_temp); + } + + /* method host obj is not found */ + if (NULL == method_host) { + /* error, not found object */ + VMState_setErrorCode(vm, PIKA_RES_ERR_ARG_NO_FOUND); + pika_platform_printf("Error: method '%s' no found.\r\n", run_path); + goto exit; + } + +#if !PIKA_NANO_ENABLE + if (!skip_init && vm->in_super && + VMState_getInvokeDeepthNow(vm) == vm->super_invoke_deepth - 1) { + vm->in_super = PIKA_FALSE; + obj_this = obj_getPtr(vm->locals, _find_self_name(vm)); + } +#endif + + /* get object this */ + if (NULL == obj_this) { + obj_this = method_host; + } + + /* get method in object */ + if (NULL == method) { + method = obj_getMethodArg_noalloc(method_host, run_path, &arg_reg1); + } + + /* get method in locals */ + if (NULL == method) { + method = obj_getMethodArg_noalloc(vm->locals, run_path, &arg_reg1); + } + + /* get method in global */ + if (NULL == method) { + method = obj_getMethodArg_noalloc(vm->globals, run_path, &arg_reg1); + } + + /* assert method exist */ + if (NULL == method || ARG_TYPE_NONE == arg_getType(method)) { + /* error, method no found */ + VMState_setErrorCode(vm, PIKA_RES_ERR_ARG_NO_FOUND); + pika_platform_printf("NameError: name '%s' is not defined\r\n", + run_path); + goto exit; + } + + /* assert methodd type */ + if (!argType_isCallable(arg_getType(method))) { + /* error, method no found */ + VMState_setErrorCode(vm, PIKA_RES_ERR_ARG_NO_FOUND); + pika_platform_printf("TypeError: '%s' object is not callable\r\n", + run_path); + goto exit; + } + + /* create sub local scope */ + sub_locals = New_PikaObj(); + + /* load args from vmState to sub_local->list */ + n_used += VMState_loadArgsFromMethodArg(vm, obj_this, sub_locals->list, + method, run_path, n_used); + + /* load args failed */ + if (vm->error_code != 0) { + goto exit; + } + + /* run method arg */ + return_arg = obj_runMethodArgWithState_noalloc(obj_this, sub_locals, method, + &sub_run_state, arg_ret_reg); + if (skip_init) { + if (arg_getType(return_arg) == ARG_TYPE_OBJECT_NEW) { + pika_assert(NULL != return_arg); + arg_setType(return_arg, ARG_TYPE_OBJECT); + } + } + + if (sub_run_state.try_result != TRY_RESULT_NONE) { + /* try result */ + vm->error_code = sub_run_state.try_result; + } + + /* __init__() */ + if (NULL != return_arg && ARG_TYPE_OBJECT_NEW == arg_getType(return_arg)) { + pika_assert(NULL != return_arg); + arg_setType(return_arg, ARG_TYPE_OBJECT); + /* init object */ + PikaObj* new_obj = arg_getPtr(return_arg); + Arg* method_arg = + obj_getMethodArg_noalloc(new_obj, "__init__", &arg_reg1); + PikaObj* sub_locals = New_PikaObj(); + Arg* return_arg_init = NULL; + if (NULL == method_arg) { + goto init_exit; + } + VMState_loadArgsFromMethodArg(vm, new_obj, sub_locals->list, method_arg, + "__init__", n_used); + /* load args failed */ + if (vm->error_code != 0) { + goto init_exit; + } + return_arg_init = obj_runMethodArgWithState(new_obj, sub_locals, + method_arg, &sub_run_state); + init_exit: + if (NULL != return_arg_init) { + arg_deinit(return_arg_init); + } + obj_deinit(sub_locals); + if (NULL != method_arg) { + arg_deinit(method_arg); + } + } + + /* transfer sysOut */ + sys_out = obj_getSysOut(obj_this); + if (NULL != sys_out) { + args_setSysOut(vm->locals->list, sys_out); + } + + /* transfer errCode */ + if (0 != obj_getErrorCode(obj_this)) { + /* method error */ + VMState_setErrorCode(vm, PIKA_RES_ERR_RUNTIME_ERROR); + } + + goto exit; +exit: + if (NULL != method) { + arg_deinit(method); + } + if (NULL != sub_locals) { + obj_deinit(sub_locals); + } + if (NULL != host_arg) { + arg_deinit(host_arg); + } + if (NULL != method_host && is_temp) { + /* class method */ + obj_deinit(method_host); + } + + return return_arg; +} + +static char* __get_transferd_str(Args* buffs, char* str, size_t* iout_p) { + char* transfered_str = args_getBuff(buffs, strGetSize(str)); + size_t i_out = 0; + size_t len = strGetSize(str); + for (size_t i = 0; i < len; i++) { + /* eg. replace '\x33' to '3' */ + if ((str[i] == '\\') && (str[i + 1] == 'x')) { + char hex_str[] = "0x00"; + hex_str[2] = str[i + 2]; + hex_str[3] = str[i + 3]; + char hex = (char)strtoll(hex_str, NULL, 0); + transfered_str[i_out++] = hex; + i += 3; + continue; + } + if (str[i] == '\\') { + switch (str[i + 1]) { + case 'r': + transfered_str[i_out++] = '\r'; + break; + case 'n': + transfered_str[i_out++] = '\n'; + break; + case 't': + transfered_str[i_out++] = '\t'; + break; + case 'b': + transfered_str[i_out++] = '\b'; + break; + case '\\': + transfered_str[i_out++] = '\\'; + break; + case '\'': + transfered_str[i_out++] = '\''; + break; + case '\"': + transfered_str[i_out++] = '\"'; + break; + case '?': + transfered_str[i_out++] = '\?'; + break; + default: + transfered_str[i_out++] = str[i]; + break; + } + i += 1; + continue; + } + /* normal char */ + transfered_str[i_out++] = str[i]; + } + *iout_p = i_out; + return transfered_str; +} + +static Arg* VM_instruction_handler_STR(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + if (strIsContain(data, '\\')) { + Args buffs = {0}; + size_t i_out = 0; + char* transfered_str = __get_transferd_str(&buffs, data, &i_out); + Arg* return_arg = arg_ret_reg; + return_arg = arg_setStr(return_arg, "", transfered_str); + strsDeinit(&buffs); + return return_arg; + } + return arg_setStr(arg_ret_reg, "", data); +} + +static Arg* VM_instruction_handler_BYT(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + if (strIsContain(data, '\\')) { + Args buffs = {0}; + size_t i_out = 0; + char* transfered_str = __get_transferd_str(&buffs, data, &i_out); + Arg* return_arg = New_arg(NULL); + return_arg = + arg_setBytes(return_arg, "", (uint8_t*)transfered_str, i_out); + strsDeinit(&buffs); + return return_arg; + } + return arg_newBytes((uint8_t*)data, strGetSize(data)); +} + +static PIKA_BOOL _proxy_setattr(PikaObj* self, char* name, Arg* arg) { +#if PIKA_NANO_ENABLE + return PIKA_FALSE; +#endif + if (obj_getFlag(self, OBJ_FLAG_PROXY_SETATTR)) { + obj_setStr(self, "@name", name); + obj_setArg(self, "@value", arg); + /* clang-format off */ + PIKA_PYTHON( + __setattr__(@name, @value) + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x0c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x10, 0x01, 0x07, 0x00, 0x00, 0x02, 0x0e, + 0x00, + /* instruct array */ + 0x1a, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x40, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x40, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x00, 0x5f, 0x5f, 0x73, 0x65, 0x74, 0x61, 0x74, 0x74, + 0x72, 0x5f, 0x5f, 0x00, /* const pool */ + }; + pikaVM_runByteCode(self, (uint8_t*)bytes); + return PIKA_TRUE; + } + return PIKA_FALSE; +} + +static Arg* VM_instruction_handler_OUT(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + char* arg_path = data; + char* arg_name = strPointToLastToken(arg_path, '.'); + PikaObj* host_obj = NULL; + PIKA_BOOL is_temp = PIKA_FALSE; + arg_newReg(outArg_reg, PIKA_ARG_BUFF_SIZE); + Arg* out_arg = stack_popArg(&vm->stack, &outArg_reg); + // Arg* outArg = stack_popArg_alloc(&vm->stack); + if (NULL == out_arg) { + return NULL; + } + ArgType outArg_type = arg_getType(out_arg); + if (VMState_getInvokeDeepthNow(vm) > 0) { + /* in block, is a kw arg */ + arg_setIsKeyword(out_arg, PIKA_TRUE); + arg_setName(out_arg, arg_path); + Arg* res = arg_copy_noalloc(out_arg, arg_ret_reg); + arg_deinit(out_arg); + return res; + } + + if (_checkLReg(arg_path)) { + uint8_t index = _getLRegIndex(arg_path); + if (argType_isObject(outArg_type)) { + PikaObj* obj = arg_getPtr(out_arg); + VMState_setLReg(vm, index, obj); + arg_deinit(out_arg); + } + return NULL; + } + + PikaObj* context = vm->locals; + /* match global_list */ + if (obj_getFlag(vm->locals, OBJ_FLAG_GLOBALS)) { + char* global_list = args_getStr(vm->locals->list, "@g"); + /* use a arg as buff */ + Arg* global_list_arg = arg_newStr(global_list); + char* global_list_buff = arg_getStr(global_list_arg); + /* for each arg arg in global_list */ + for (int i = 0; i < strCountSign(global_list, ',') + 1; i++) { + char* global_arg = strPopFirstToken(&global_list_buff, ','); + /* matched global arg, context set to global */ + if (strEqu(global_arg, arg_path)) { + context = vm->globals; + } + } + arg_deinit(global_list_arg); + } + /* use RunAs object */ + if (obj_getFlag(vm->locals, OBJ_FLAG_RUN_AS)) { + context = args_getPtr(vm->locals->list, "@r"); + } + /* set free object to nomal object */ + if (ARG_TYPE_OBJECT_NEW == outArg_type) { + pika_assert(NULL != out_arg); + arg_setType(out_arg, ARG_TYPE_OBJECT); + } + + /* ouput arg to context */ + if (arg_path == arg_name) { + obj_setArg_noCopy(context, arg_path, out_arg); + return NULL; + } + + host_obj = obj_getHostObjWithIsTemp(context, arg_path, &is_temp); + + if (NULL == host_obj) { + host_obj = obj_getHostObjWithIsTemp(vm->globals, arg_path, &is_temp); + } + + if (host_obj != NULL) { + if (_proxy_setattr(host_obj, arg_name, out_arg)) { + return NULL; + } + obj_setArg_noCopy(host_obj, arg_name, out_arg); + return NULL; + } + + obj_setArg_noCopy(context, arg_path, out_arg); + return NULL; +} + +/* run as */ +static Arg* VM_instruction_handler_RAS(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + if (strEqu(data, "$origin")) { + /* use origin object to run */ + obj_removeArg(vm->locals, "@r"); + obj_clearFlag(vm->locals, OBJ_FLAG_RUN_AS); + return NULL; + } + /* use "data" object to run */ + PikaObj* runAs = obj_getObj(vm->locals, data); + args_setRef(vm->locals->list, "@r", runAs); + obj_setFlag(vm->locals, OBJ_FLAG_RUN_AS); + return NULL; +} + +static Arg* VM_instruction_handler_NUM(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + /* fast return */ + if (data[1] == '\0') { + return arg_setInt(arg_ret_reg, "", data[0] - '0'); + } + /* hex */ + if (data[1] == 'x' || data[1] == 'X') { + return arg_setInt(arg_ret_reg, "", strtoll(data, NULL, 0)); + } + if (data[1] == 'o' || data[1] == 'O') { + char strtoll_buff[10] = {0}; + strtoll_buff[0] = '0'; + pika_platform_memcpy(strtoll_buff + 1, data + 2, strGetSize(data) - 2); + return arg_setInt(arg_ret_reg, "", strtoll(strtoll_buff, NULL, 0)); + } + if (data[1] == 'b' || data[1] == 'B') { + char strtoll_buff[10] = {0}; + pika_platform_memcpy(strtoll_buff, data + 2, strGetSize(data) - 2); + return arg_setInt(arg_ret_reg, "", strtoll(strtoll_buff, NULL, 2)); + } + /* float */ + if (strIsContain(data, '.') || + (strIsContain(data, 'e') || strIsContain(data, 'E'))) { + return arg_setFloat(arg_ret_reg, "", strtod(data, NULL)); + } + /* int */ + return arg_setInt(arg_ret_reg, "", fast_atoi(data)); +} + +static Arg* VM_instruction_handler_JMP(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + vm->jmp = fast_atoi(data); + return NULL; +} + +static Arg* VM_instruction_handler_SER(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + vm->try_error_code = fast_atoi(data); + return NULL; +} + +static Arg* _VM_JEZ(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg, + int pika_assert) { + int thisBlockDeepth = VMState_getBlockDeepthNow(vm); + int jmp_expect = fast_atoi(data); + vm->ireg[thisBlockDeepth] = (PIKA_BOOL)!pika_assert; + + if (0 == pika_assert) { + /* jump */ + vm->jmp = jmp_expect; + } + + /* restore loop deepth */ + if (2 == jmp_expect && 0 == pika_assert) { + int block_deepth_now = VMState_getBlockDeepthNow(vm); + vm->loop_deepth = block_deepth_now; + } + + return NULL; +} + +static Arg* VM_instruction_handler_JEZ(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + Arg* pika_assertArg = stack_popArg(&(vm->stack), arg_ret_reg); + int pika_assert = 0; + if (NULL != pika_assertArg) { + pika_assert = arg_getInt(pika_assertArg); + arg_deinit(pika_assertArg); + } + return _VM_JEZ(self, vm, data, arg_ret_reg, pika_assert); +} + +static Arg* VM_instruction_handler_JNZ(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + Arg* pika_assertArg = stack_popArg(&(vm->stack), arg_ret_reg); + int pika_assert = 0; + if (NULL != pika_assertArg) { + pika_assert = arg_getInt(pika_assertArg); + arg_deinit(pika_assertArg); + } + return _VM_JEZ(self, vm, data, arg_ret_reg, !pika_assert); +} + +static uint8_t VMState_getInputArgNum(VMState* vm) { + InstructUnit* ins_unit_now = VMState_getInstructNow(vm); + uint8_t invoke_deepth_this = instructUnit_getInvokeDeepth(ins_unit_now); + int32_t pc_this = vm->pc; + uint8_t num = 0; + while (1) { + ins_unit_now--; + pc_this -= instructUnit_getSize(); + uint8_t invode_deepth = instructUnit_getInvokeDeepth(ins_unit_now); + if (pc_this < 0) { + break; + } + if (invode_deepth == invoke_deepth_this + 1) { + if (instructUnit_getInstruct(ins_unit_now) == OUT) { + continue; + } + num++; + } + if (instructUnit_getIsNewLine(ins_unit_now)) { + break; + } + if (invode_deepth <= invoke_deepth_this) { + break; + } + } + return num; +} + +void operatorInfo_init(OperatorInfo* info, + PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + info->opt = data; + info->res = arg_ret_reg; + if (info->a1 != NULL) { + info->t1 = arg_getType(info->a1); + if (info->t1 == ARG_TYPE_INT) { + info->i1 = arg_getInt(info->a1); + info->f1 = (pika_float)info->i1; + } else if (info->t1 == ARG_TYPE_FLOAT) { + info->f1 = arg_getFloat(info->a1); + info->i1 = (int64_t)info->f1; + } + } + info->t2 = arg_getType(info->a2); + info->vm = vm; + if (info->t2 == ARG_TYPE_INT) { + info->i2 = arg_getInt(info->a2); + info->f2 = (pika_float)info->i2; + } else if (info->t2 == ARG_TYPE_FLOAT) { + info->f2 = arg_getFloat(info->a2); + info->i2 = (int64_t)info->f2; + } +} + +static void _OPT_ADD(OperatorInfo* op) { +#if !PIKA_NANO_ENABLE + if (argType_isObject(op->t1)) { + if (!argType_isObject(op->t2)) { + VMState_setErrorCode(op->vm, PIKA_RES_ERR_OPERATION_FAILED); + pika_platform_printf("TypeError: unsupported operand +\n"); + op->res = NULL; + return; + } + PikaObj* obj1 = arg_getPtr(op->a1); + Arg* method_add = obj_getMethodArg(obj1, "__add__"); + if (NULL == method_add) { + VMState_setErrorCode(op->vm, PIKA_RES_ERR_OPERATION_FAILED); + pika_platform_printf("TypeError: unsupported operand +\n"); + op->res = NULL; + return; + } + arg_deinit(method_add); + PikaObj* obj2 = arg_getPtr(op->a2); + obj_setPtr(obj1, "__others", obj2); + /* clang-format off */ + PIKA_PYTHON( + __res = __add__(__others) + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x0c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x04, 0x12, + 0x00, + /* instruct array */ + 0x18, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x00, 0x5f, + 0x5f, 0x61, 0x64, 0x64, 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65, + 0x73, 0x00, /* const pool */ + }; + pikaVM_runByteCode(obj1, (uint8_t*)bytes); + Arg* __res = arg_copy(obj_getArg(obj1, "__res")); + op->res = __res; + obj_removeArg(obj1, "__others"); + obj_removeArg(obj1, "__res"); + return; + } +#endif + + if ((op->t1 == ARG_TYPE_STRING) && (op->t2 == ARG_TYPE_STRING)) { + char* num1_s = NULL; + char* num2_s = NULL; + Args str_opt_buffs = {0}; + num1_s = arg_getStr(op->a1); + num2_s = arg_getStr(op->a2); + char* opt_str_out = strsAppend(&str_opt_buffs, num1_s, num2_s); + op->res = arg_setStr(op->res, "", opt_str_out); + strsDeinit(&str_opt_buffs); + return; + } +#if !PIKA_NANO_ENABLE + if ((op->t1 == ARG_TYPE_BYTES) && (op->t2 == ARG_TYPE_BYTES)) { + uint8_t* bytes1 = arg_getBytes(op->a1); + uint8_t* bytes2 = arg_getBytes(op->a2); + size_t size1 = arg_getBytesSize(op->a1); + size_t size2 = arg_getBytesSize(op->a2); + op->res = arg_setBytes(op->res, "", NULL, size1 + size2); + uint8_t* bytes_out = arg_getBytes(op->res); + pika_platform_memcpy(bytes_out, bytes1, size1); + pika_platform_memcpy(bytes_out + size1, bytes2, size2); + return; + } +#endif + /* match float */ + if ((op->t1 == ARG_TYPE_FLOAT) || op->t2 == ARG_TYPE_FLOAT) { + op->res = arg_setFloat(op->res, "", op->f1 + op->f2); + return; + } + /* int is default */ + op->res = arg_setInt(op->res, "", op->i1 + op->i2); + return; +} + +static void _OPT_SUB(OperatorInfo* op) { +#if !PIKA_NANO_ENABLE + if (argType_isObject(op->t1)) { + if (!argType_isObject(op->t2)) { + VMState_setErrorCode(op->vm, PIKA_RES_ERR_OPERATION_FAILED); + pika_platform_printf("TypeError: unsupported operand +\n"); + op->res = NULL; + return; + } + PikaObj* obj1 = arg_getPtr(op->a1); + Arg* method_sub = obj_getMethodArg(obj1, "__sub__"); + if (NULL == method_sub) { + VMState_setErrorCode(op->vm, PIKA_RES_ERR_OPERATION_FAILED); + pika_platform_printf("TypeError: unsupported operand +\n"); + op->res = NULL; + return; + } + arg_deinit(method_sub); + PikaObj* obj2 = arg_getPtr(op->a2); + obj_setPtr(obj1, "__others", obj2); + /* clang-format off */ + PIKA_PYTHON( + __res = __sub__(__others) + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x0c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x04, 0x12, + 0x00, + /* instruct array */ + 0x18, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x00, 0x5f, + 0x5f, 0x73, 0x75, 0x62, 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65, + 0x73, 0x00, /* const pool */ + }; + pikaVM_runByteCode(obj1, (uint8_t*)bytes); + Arg* __res = arg_copy(obj_getArg(obj1, "__res")); + op->res = __res; + obj_removeArg(obj1, "__others"); + obj_removeArg(obj1, "__res"); + return; + } +#endif + if (op->t2 == ARG_TYPE_NONE) { + if (op->t1 == ARG_TYPE_INT) { + op->res = arg_setInt(op->res, "", -op->i1); + return; + } + if (op->t1 == ARG_TYPE_FLOAT) { + op->res = arg_setFloat(op->res, "", -op->f1); + return; + } + } + if ((op->t1 == ARG_TYPE_FLOAT) || op->t2 == ARG_TYPE_FLOAT) { + op->res = arg_setFloat(op->res, "", op->f1 - op->f2); + return; + } + op->res = arg_setInt(op->res, "", op->i1 - op->i2); + return; +} + +static void _OPT_EQU(OperatorInfo* op) { + int8_t is_equ = -1; + if (op->t1 == ARG_TYPE_NONE && op->t2 == ARG_TYPE_NONE) { + is_equ = 1; + goto exit; + } + /* type not equl, and type is not int or float */ + if (op->t1 != op->t2) { + if ((op->t1 != ARG_TYPE_FLOAT) && (op->t1 != ARG_TYPE_INT)) { + is_equ = 0; + goto exit; + } + if ((op->t2 != ARG_TYPE_FLOAT) && (op->t2 != ARG_TYPE_INT)) { + is_equ = 0; + goto exit; + } + } + /* string compire */ + if (op->t1 == ARG_TYPE_STRING) { + is_equ = strEqu(arg_getStr(op->a1), arg_getStr(op->a2)); + goto exit; + } + /* bytes compire */ + if (op->t1 == ARG_TYPE_BYTES) { + if (arg_getBytesSize(op->a1) != arg_getBytesSize(op->a2)) { + is_equ = 0; + goto exit; + } + is_equ = 1; + for (size_t i = 0; i < arg_getBytesSize(op->a1); i++) { + if (arg_getBytes(op->a1)[i] != arg_getBytes(op->a2)[i]) { + is_equ = 0; + goto exit; + } + } + goto exit; + } + /* default: int and float */ + is_equ = ((op->f1 - op->f2) * (op->f1 - op->f2) < (pika_float)0.000001); + goto exit; +exit: + if (op->opt[0] == '=') { + op->res = arg_setInt(op->res, "", is_equ); + } else { + op->res = arg_setInt(op->res, "", !is_equ); + } + return; +} + +static void _OPT_POW(OperatorInfo* op) { + if (op->num == 1) { + op->res = arg_copy(op->a2); + arg_setIsDoubleStarred(op->res, 1); + return; + } + if (op->t1 == ARG_TYPE_INT && op->t2 == ARG_TYPE_INT) { + int res = 1; + for (int i = 0; i < op->i2; i++) { + res = res * op->i1; + } + op->res = arg_setInt(op->res, "", res); + return; + } else if (op->t1 == ARG_TYPE_FLOAT && op->t2 == ARG_TYPE_INT) { + float res = 1; + for (int i = 0; i < op->i2; i++) { + res = res * op->f1; + } + op->res = arg_setFloat(op->res, "", res); + return; + } else { +#if PIKA_MATH_ENABLE + float res = 1; + res = pow(op->f1, op->f2); + op->res = arg_setFloat(op->res, "", res); + return; +#else + VMState_setErrorCode(op->vm, PIKA_RES_ERR_OPERATION_FAILED); + pika_platform_printf( + "Operation float ** float is not enabled, please set " + "PIKA_MATH_ENABLE\n"); +#endif + } +} + +static Arg* VM_instruction_handler_OPT(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + OperatorInfo op = {0}; + op.num = VMState_getInputArgNum(vm); + arg_newReg(arg_reg1, PIKA_ARG_BUFF_SIZE); + arg_newReg(arg_reg2, PIKA_ARG_BUFF_SIZE); + if (op.num == 2) { + /* tow input */ + op.a2 = stack_popArg(&(vm->stack), &arg_reg2); + op.a1 = stack_popArg(&(vm->stack), &arg_reg1); + } else if (op.num == 1) { + /* only one input */ + op.a2 = stack_popArg(&(vm->stack), &arg_reg2); + op.a1 = NULL; + } + /* init operator info */ + operatorInfo_init(&op, self, vm, data, arg_ret_reg); + switch (data[0]) { + case '+': + _OPT_ADD(&op); + goto exit; + case '%': + if ((op.t1 == ARG_TYPE_INT) && (op.t2 == ARG_TYPE_INT)) { + op.res = arg_setInt(op.res, "", op.i1 % op.i2); + goto exit; + } + VMState_setErrorCode(vm, PIKA_RES_ERR_OPERATION_FAILED); + pika_platform_printf( + "TypeError: unsupported operand type(s) for %%: 'float'\n"); + op.res = NULL; + goto exit; + case '-': + _OPT_SUB(&op); + goto exit; + } + if (data[1] == '=' && (data[0] == '!' || data[0] == '=')) { + _OPT_EQU(&op); + goto exit; + } + if (data[1] == 0) { + switch (data[0]) { + case '<': + op.res = arg_setInt(op.res, "", op.f1 < op.f2); + goto exit; + case '*': + if (op.num == 1) { + op.res = arg_copy(op.a2); + arg_setIsStarred(op.res, 1); + goto exit; + } + if ((op.t1 == ARG_TYPE_FLOAT) || op.t2 == ARG_TYPE_FLOAT) { + op.res = arg_setFloat(op.res, "", op.f1 * op.f2); + goto exit; + } + op.res = arg_setInt(op.res, "", op.i1 * op.i2); + goto exit; + case '&': + if ((op.t1 == ARG_TYPE_INT) && (op.t2 == ARG_TYPE_INT)) { + op.res = arg_setInt(op.res, "", op.i1 & op.i2); + goto exit; + } + VMState_setErrorCode(vm, PIKA_RES_ERR_OPERATION_FAILED); + pika_platform_printf( + "TypeError: unsupported operand type(s) for &: 'float'\n"); + op.res = NULL; + goto exit; + case '|': + if ((op.t1 == ARG_TYPE_INT) && (op.t2 == ARG_TYPE_INT)) { + op.res = arg_setInt(op.res, "", op.i1 | op.i2); + goto exit; + } + VMState_setErrorCode(vm, PIKA_RES_ERR_OPERATION_FAILED); + pika_platform_printf( + "TypeError: unsupported operand type(s) for |: 'float'\n"); + op.res = NULL; + goto exit; + case '~': + if (op.t2 == ARG_TYPE_INT) { + op.res = arg_setInt(op.res, "", ~op.i2); + goto exit; + } + VMState_setErrorCode(vm, PIKA_RES_ERR_OPERATION_FAILED); + pika_platform_printf( + "TypeError: unsupported operand type(s) for ~: 'float'\n"); + op.res = NULL; + goto exit; + case '/': + if (0 == op.f2) { + VMState_setErrorCode(vm, PIKA_RES_ERR_OPERATION_FAILED); + args_setSysOut(vm->locals->list, + "ZeroDivisionError: division by zero"); + op.res = NULL; + goto exit; + } + op.res = arg_setFloat(op.res, "", op.f1 / op.f2); + goto exit; + case '>': + op.res = arg_setInt(op.res, "", op.f1 > op.f2); + goto exit; + } + } + if (data[1] == 'i' && data[2] == 'n') { + if (op.t1 == ARG_TYPE_STRING && op.t2 == ARG_TYPE_STRING) { + if (strstr(arg_getStr(op.a2), arg_getStr(op.a1))) { + op.res = arg_setInt(op.res, "", 1); + } else { + op.res = arg_setInt(op.res, "", 0); + } + goto exit; + } +#if !PIKA_NANO_ENABLE + if (argType_isObject(op.t2)) { + PikaObj* obj2 = arg_getPtr(op.a2); + Arg* __contains__ = obj_getMethodArg(obj2, "__contains__"); + if (NULL != __contains__) { + arg_deinit(__contains__); + /* clang-format off */ + PIKA_PYTHON( + __res = __contains__(__others) + ) + obj_setArg(obj2, "__others", op.a1); + /* clang-format on */ + const uint8_t bytes[] = { + 0x0c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x04, + 0x17, 0x00, + /* instruct array */ + 0x1d, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x00, + 0x5f, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, + 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, + 0x00, /* const pool */ + }; + pikaVM_runByteCode(obj2, (uint8_t*)bytes); + op.res = arg_setInt(op.res, "", obj_getInt(obj2, "__res")); + goto exit; + } + } +#endif + + VMState_setErrorCode(vm, PIKA_RES_ERR_OPERATION_FAILED); + args_setSysOut(vm->locals->list, + "Operation 'in' is not supported for this " + "type\n"); + op.res = NULL; + goto exit; + } + if (data[0] == '*' && data[1] == '*') { + _OPT_POW(&op); + goto exit; + } + if (data[0] == '/' && data[1] == '/') { + if ((op.t1 == ARG_TYPE_INT) && (op.t2 == ARG_TYPE_INT)) { + op.res = arg_setInt(op.res, "", op.i1 / op.i2); + goto exit; + } + VMState_setErrorCode(vm, PIKA_RES_ERR_OPERATION_FAILED); + pika_platform_printf( + "TypeError: unsupported operand type(s) for //: 'float'\n"); + op.res = NULL; + goto exit; + } + if (data[1] == 'i' && data[2] == 's') { +#if !PIKA_NANO_ENABLE + if (argType_isObject(op.t1) && argType_isObject(op.t2)) { + if (arg_getPtr(op.a1) == arg_getPtr(op.a2)) { + op.res = arg_setInt(op.res, "", 1); + } else { + op.res = arg_setInt(op.res, "", 0); + } + goto exit; + } +#endif + op.opt = "=="; + _OPT_EQU(&op); + goto exit; + } + if (data[0] == '>' && data[1] == '=') { + op.res = arg_setInt( + op.res, "", + (op.f1 > op.f2) || + ((op.f1 - op.f2) * (op.f1 - op.f2) < (pika_float)0.000001)); + goto exit; + } + if (data[0] == '<' && data[1] == '=') { + op.res = arg_setInt( + op.res, "", + (op.f1 < op.f2) || + ((op.f1 - op.f2) * (op.f1 - op.f2) < (pika_float)0.000001)); + goto exit; + } + if (data[0] == '>' && data[1] == '>') { + if ((op.t1 == ARG_TYPE_INT) && (op.t2 == ARG_TYPE_INT)) { + op.res = arg_setInt(op.res, "", op.i1 >> op.i2); + goto exit; + } + VMState_setErrorCode(vm, PIKA_RES_ERR_OPERATION_FAILED); + pika_platform_printf( + "TypeError: unsupported operand type(s) for >>: 'float'\n"); + op.res = NULL; + goto exit; + } + if (data[0] == '<' && data[1] == '<') { + if ((op.t1 == ARG_TYPE_INT) && (op.t2 == ARG_TYPE_INT)) { + op.res = arg_setInt(op.res, "", op.i1 << op.i2); + goto exit; + } + VMState_setErrorCode(vm, PIKA_RES_ERR_OPERATION_FAILED); + pika_platform_printf( + "TypeError: unsupported operand type(s) for <<: 'float'\n"); + op.res = NULL; + goto exit; + } + if (data[0] == ' ' && data[1] == 'a' && data[2] == 'n' && data[3] == 'd' && + data[4] == ' ') { + op.res = arg_setInt(op.res, "", op.i1 && op.i2); + goto exit; + } + if (data[0] == ' ' && data[1] == 'o' && data[2] == 'r' && data[3] == ' ' && + data[4] == 0) { + op.res = arg_setInt(op.res, "", op.i1 || op.i2); + goto exit; + } + if (data[0] == ' ' && data[1] == 'n' && data[2] == 'o' && data[3] == 't' && + data[4] == ' ' && data[5] == 0) { + op.res = arg_setInt(op.res, "", !op.i2); + goto exit; + } +exit: + if (NULL != op.a1) { + arg_deinit(op.a1); + } + if (NULL != op.a2) { + arg_deinit(op.a2); + } + if (NULL != op.res) { + return op.res; + } + return NULL; +} + +static Arg* __VM_instruction_handler_DEF(PikaObj* self, + VMState* vm, + char* data, + uint8_t is_class) { + int thisBlockDeepth = VMState_getBlockDeepthNow(vm); + + PikaObj* hostObj = vm->locals; + uint8_t is_in_class = 0; + /* use RunAs object */ + if (obj_getFlag(vm->locals, OBJ_FLAG_RUN_AS)) { + hostObj = args_getPtr(vm->locals->list, "@r"); + is_in_class = 1; + } + int offset = 0; + /* byteCode */ + while (1) { + InstructUnit* ins_unit_now = + VMState_getInstructUnitWithOffset(vm, offset); + if (!instructUnit_getIsNewLine(ins_unit_now)) { + offset += instructUnit_getSize(); + continue; + } + if (instructUnit_getBlockDeepth(ins_unit_now) == thisBlockDeepth + 1) { + if (is_in_class) { + class_defineObjectMethod(hostObj, data, (Method)ins_unit_now, + self, vm->bytecode_frame); + } else { + if (is_class) { + class_defineRunTimeConstructor(hostObj, data, + (Method)ins_unit_now, self, + vm->bytecode_frame); + } else { + class_defineStaticMethod(hostObj, data, + (Method)ins_unit_now, self, + vm->bytecode_frame); + } + } + break; + } + offset += instructUnit_getSize(); + } + + return NULL; +} + +static Arg* VM_instruction_handler_DEF(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + return __VM_instruction_handler_DEF(self, vm, data, 0); +} + +static Arg* VM_instruction_handler_CLS(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + return __VM_instruction_handler_DEF(self, vm, data, 1); +} + +static Arg* VM_instruction_handler_RIS(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { +#if PIKA_NANO_ENABLE + return NULL; +#endif + Arg* err_arg = stack_popArg_alloc(&(vm->stack)); + PIKA_RES err = (PIKA_RES)arg_getInt(err_arg); + VMState_setErrorCode(vm, err); + arg_deinit(err_arg); + return NULL; +} + +static Arg* VM_instruction_handler_ASS(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { +#if PIKA_NANO_ENABLE + return NULL; +#endif + arg_newReg(reg1, PIKA_ARG_BUFF_SIZE); + arg_newReg(reg2, PIKA_ARG_BUFF_SIZE); + Arg* arg1 = NULL; + Arg* arg2 = NULL; + Arg* res = NULL; + int n_arg = VMState_getInputArgNum(vm); + if (n_arg == 1) { + arg1 = stack_popArg(&vm->stack, ®1); + } + if (n_arg == 2) { + arg2 = stack_popArg(&vm->stack, ®2); + arg1 = stack_popArg(&vm->stack, ®1); + } + /* assert failed */ + if (arg_getType(arg1) == ARG_TYPE_INT && arg_getInt(arg1) == 0) { + stack_pushArg(&vm->stack, arg_newInt(PIKA_RES_ERR_ASSERT)); + res = VM_instruction_handler_RIS(self, vm, data, arg_ret_reg); + if (vm->run_state->try_state == TRY_STATE_NONE) { + if (n_arg == 1) { + pika_platform_printf("AssertionError\n"); + } + if (n_arg == 2) { + pika_platform_printf("AssertionError: %s\n", arg_getStr(arg2)); + } + } + goto exit; + } +exit: + arg_deinit(arg1); + if (NULL != arg2) { + arg_deinit(arg2); + } + return res; +} + +static Arg* VM_instruction_handler_NEL(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + int thisBlockDeepth = VMState_getBlockDeepthNow(vm); + if (0 == vm->ireg[thisBlockDeepth]) { + /* set __else flag */ + vm->jmp = fast_atoi(data); + } + return NULL; +} + +static Arg* VM_instruction_handler_DEL(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + if (_checkLReg(data)) { + uint8_t reg_index = _getLRegIndex(data); + VMState_delLReg(vm, reg_index); + return NULL; + } + if (obj_isArgExist(vm->locals, data)) { + obj_removeArg(vm->locals, data); + return NULL; + } + if (obj_isArgExist(vm->globals, data)) { + obj_removeArg(vm->globals, data); + return NULL; + } + VMState_setErrorCode(vm, PIKA_RES_ERR_OPERATION_FAILED); + pika_platform_printf("NameError: name '%s' is not defined\n", data); + return NULL; +} + +static Arg* VM_instruction_handler_EST(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + Arg* arg = obj_getArg(vm->locals, data); + if (arg == NULL) { + return arg_setInt(arg_ret_reg, "", 0); + } + if (ARG_TYPE_NONE == arg_getType(arg)) { + return arg_setInt(arg_ret_reg, "", 0); + } + return arg_setInt(arg_ret_reg, "", 1); +} + +static Arg* VM_instruction_handler_BRK(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + /* break jmp signal */ + vm->jmp = VM_JMP_BREAK; + return NULL; +} + +static Arg* VM_instruction_handler_CTN(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + /* continue jmp signal */ + vm->jmp = VM_JMP_CONTINUE; + return NULL; +} + +static Arg* VM_instruction_handler_GLB(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + Arg* global_list_buff = NULL; + char* global_list = args_getStr(vm->locals->list, "@g"); + /* create new global_list */ + if (NULL == global_list) { + args_setStr(vm->locals->list, "@g", data); + obj_setFlag(vm->locals, OBJ_FLAG_GLOBALS); + goto exit; + } + /* append to exist global_list */ + global_list_buff = arg_newStr(global_list); + global_list_buff = arg_strAppend(global_list_buff, ","); + global_list_buff = arg_strAppend(global_list_buff, data); + args_setStr(vm->locals->list, "@g", arg_getStr(global_list_buff)); + goto exit; +exit: + if (NULL != global_list_buff) { + arg_deinit(global_list_buff); + } + return NULL; +} + +static Arg* VM_instruction_handler_IMP(PikaObj* self, + VMState* vm, + char* data, + Arg* arg_ret_reg) { + /* the module is already imported, skip. */ + if (obj_isArgExist(self, data)) { + return NULL; + } + /* find cmodule in root object */ + extern volatile PikaObj* __pikaMain; + if (obj_isArgExist((PikaObj*)__pikaMain, data)) { + obj_setArg(self, data, obj_getArg((PikaObj*)__pikaMain, data)); + return NULL; + } + /* import module from '@lib' */ + if (0 == obj_importModule(self, data)) { + return NULL; + } + VMState_setErrorCode(vm, PIKA_RES_ERR_ARG_NO_FOUND); + pika_platform_printf("ModuleNotFoundError: No module named '%s'\r\n", data); + return NULL; +} + +const VM_instruct_handler VM_instruct_handler_table[__INSTRCUTION_CNT] = { +#define __INS_TABLE +#include "__instruction_table.cfg" +}; + +enum Instruct pikaVM_getInstructFromAsm(char* ins_str) { +#define __INS_COMPIRE +#include "__instruction_table.cfg" + return NON; +} + +static int pikaVM_runInstructUnit(PikaObj* self, + VMState* vm, + InstructUnit* ins_unit) { + enum Instruct instruct = instructUnit_getInstruct(ins_unit); + arg_newReg(ret_reg, PIKA_ARG_BUFF_SIZE); + Arg* return_arg = &ret_reg; + // char invode_deepth1_str[2] = {0}; + int32_t pc_next = vm->pc + instructUnit_getSize(); + char* data = VMState_getConstWithInstructUnit(vm, ins_unit); + /* run instruct */ + pika_assert(NULL != vm->run_state); + return_arg = VM_instruct_handler_table[instruct](self, vm, data, &ret_reg); + + if (vm->error_code != PIKA_RES_OK || + VMSignal_getCtrl() == VM_SIGNAL_CTRL_EXIT) { + /* raise jmp */ + if (vm->run_state->try_state == TRY_STATE_INNER) { + vm->jmp = VM_JMP_RAISE; + } else { + /* exit */ + vm->jmp = VM_JMP_EXIT; + } + } + + if (NULL != return_arg) { + stack_pushArg(&(vm->stack), return_arg); + } + goto nextLine; +nextLine: + /* exit */ + if (VM_JMP_EXIT == vm->jmp) { + pc_next = VM_PC_EXIT; + goto exit; + } + /* break */ + if (VM_JMP_BREAK == vm->jmp) { + pc_next = vm->pc + VMState_getAddrOffsetOfBreak(vm); + goto exit; + } + /* continue */ + if (VM_JMP_CONTINUE == vm->jmp) { + pc_next = vm->pc + VMState_getAddrOffsetOfContinue(vm); + goto exit; + } +/* raise */ +#if !PIKA_NANO_ENABLE + if (VM_JMP_RAISE == vm->jmp) { + int offset = VMState_getAddrOffsetOfRaise(vm); + if (0 == offset) { + /* can not found end of try, return */ + pc_next = VM_PC_EXIT; + vm->run_state->try_result = TRY_RESULT_RAISE; + goto exit; + } + pc_next = vm->pc + offset; + goto exit; + } +#endif + /* static jmp */ + if (vm->jmp != 0) { + pc_next = vm->pc + VMState_getAddrOffsetFromJmp(vm); + goto exit; + } + /* not jmp */ + pc_next = vm->pc + instructUnit_getSize(); + + /* jump to next line */ + if (vm->error_code != 0) { + while (1) { + if (pc_next >= (int)VMState_getInstructArraySize(vm)) { + pc_next = VM_PC_EXIT; + goto exit; + } + InstructUnit* ins_next = instructArray_getByOffset( + &vm->bytecode_frame->instruct_array, pc_next); + if (instructUnit_getIsNewLine(ins_next)) { + goto exit; + } + pc_next = pc_next + instructUnit_getSize(); + } + } + + goto exit; +exit: + vm->jmp = 0; + /* reach the end */ + if (pc_next >= (int)VMState_getInstructArraySize(vm)) { + return VM_PC_EXIT; + } + return pc_next; +} + +VMParameters* pikaVM_runAsm(PikaObj* self, char* pikaAsm) { + ByteCodeFrame bytecode_frame; + byteCodeFrame_init(&bytecode_frame); + byteCodeFrame_appendFromAsm(&bytecode_frame, pikaAsm); + VMParameters* res = pikaVM_runByteCodeFrame(self, &bytecode_frame); + byteCodeFrame_deinit(&bytecode_frame); + return res; +} + +static ByteCodeFrame* _cache_bytecodeframe(PikaObj* self) { + ByteCodeFrame bytecode_frame_stack = {0}; + ByteCodeFrame* res = NULL; + if (!obj_isArgExist(self, "@bcn")) { + /* start form @bc0 */ + obj_setInt(self, "@bcn", 0); + } + int bcn = obj_getInt(self, "@bcn"); + char bcn_str[] = "@bcx"; + bcn_str[3] = '0' + bcn; + /* load bytecode to heap */ + args_setHeapStruct(self->list, bcn_str, bytecode_frame_stack, + byteCodeFrame_deinit); + /* get bytecode_ptr from heap */ + res = args_getHeapStruct(self->list, bcn_str); + obj_setInt(self, "@bcn", bcn + 1); + return res; +} + +static ByteCodeFrame* _cache_bcf_fn(PikaObj* self, char* py_lines) { + /* cache 'def' and 'class' to heap */ + if ((NULL == strstr(py_lines, "def ")) && + (NULL == strstr(py_lines, "class "))) { + return NULL; + } + return _cache_bytecodeframe(self); +} + +static char* _get_data_from_bytecode2(uint8_t* bytecode, + enum Instruct ins1, + enum Instruct ins2) { + ByteCodeFrame bf = {0}; + char* res = NULL; + byteCodeFrame_init(&bf); + byteCodeFrame_loadByteCode(&bf, bytecode); + while (1) { + InstructUnit* ins_unit = instructArray_getNow(&bf.instruct_array); + if (NULL == ins_unit) { + goto __exit; + } + enum Instruct ins = instructUnit_getInstruct(ins_unit); + if (ins == ins1 || ins == ins2) { + res = constPool_getByOffset(&bf.const_pool, + ins_unit->const_pool_index); + goto __exit; + } + instructArray_getNext(&bf.instruct_array); + } +__exit: + byteCodeFrame_deinit(&bf); + return res; +} + +static ByteCodeFrame* _cache_bcf_fn_bc(PikaObj* self, uint8_t* bytecode) { + /* save 'def' and 'class' to heap */ + if (NULL == _get_data_from_bytecode2(bytecode, DEF, CLS)) { + return NULL; + } + return _cache_bytecodeframe(self); +} + +static VMParameters* __pikaVM_runPyLines(PikaObj* self, char* py_lines) { + VMParameters* globals = NULL; + ByteCodeFrame bytecode_frame_stack = {0}; + ByteCodeFrame* bytecode_frame_p = NULL; + uint8_t is_use_heap_bytecode = 0; + + /* + * the first obj_run, cache bytecode to heap, to support 'def' and + * 'class' + */ + bytecode_frame_p = _cache_bcf_fn(self, py_lines); + if (NULL == bytecode_frame_p) { + is_use_heap_bytecode = 0; + /* get bytecode_ptr from stack */ + bytecode_frame_p = &bytecode_frame_stack; + } + + /* load or generate byte code frame */ + /* generate byte code */ + byteCodeFrame_init(bytecode_frame_p); + if (PIKA_RES_OK != Parser_linesToBytes(bytecode_frame_p, py_lines)) { + pika_platform_printf("Error: Syntax error.\r\n"); + globals = NULL; + goto exit; + } + /* run byteCode */ + globals = pikaVM_runByteCodeFrame(self, bytecode_frame_p); + goto exit; +exit: + if (!is_use_heap_bytecode) { + byteCodeFrame_deinit(&bytecode_frame_stack); + } + return globals; +} + +VMParameters* _do_pikaVM_runByteCode(PikaObj* self, + VMParameters* locals, + VMParameters* globals, + uint8_t* bytecode, + RunState* run_state, + PIKA_BOOL is_const_bytecode) { + ByteCodeFrame bytecode_frame_stack = {0}; + ByteCodeFrame* bytecode_frame_p = NULL; + uint8_t is_use_heap_bytecode = 1; + /* + * the first obj_run, cache bytecode to heap, to support 'def' and + * 'class' + */ + bytecode_frame_p = _cache_bcf_fn_bc(self, bytecode); + if (NULL == bytecode_frame_p) { + is_use_heap_bytecode = 0; + /* get bytecode_ptr from stack */ + bytecode_frame_p = &bytecode_frame_stack; + /* no def/class ins, no need cache bytecode */ + is_const_bytecode = PIKA_TRUE; + } + + /* load or generate byte code frame */ + /* load bytecode */ + _do_byteCodeFrame_loadByteCode(bytecode_frame_p, bytecode, + is_const_bytecode); + + /* run byteCode */ + + globals = __pikaVM_runByteCodeFrameWithState( + self, locals, globals, bytecode_frame_p, 0, run_state); + goto exit; +exit: + if (!is_use_heap_bytecode) { + byteCodeFrame_deinit(&bytecode_frame_stack); + } + return globals; +} + +VMParameters* pikaVM_runByteCodeFile(PikaObj* self, char* filename) { + Args buffs = {0}; + Arg* file_arg = arg_loadFile(NULL, filename); + pika_assert(NULL != file_arg); + if (NULL == file_arg) { + return NULL; + } + uint8_t* lines = arg_getBytes(file_arg); + /* clear the void line */ + VMParameters* res = pikaVM_runByteCodeInconstant(self, lines); + arg_deinit(file_arg); + strsDeinit(&buffs); + return res; +} + +VMParameters* pikaVM_runSingleFile(PikaObj* self, char* filename) { + Args buffs = {0}; + Arg* file_arg = arg_loadFile(NULL, filename); + pika_assert(NULL != file_arg); + if (NULL == file_arg) { + return NULL; + } + char* lines = (char*)arg_getBytes(file_arg); + /* clear the void line */ + VMParameters* res = pikaVM_run(self, lines); + arg_deinit(file_arg); + strsDeinit(&buffs); + return res; +} + +VMParameters* pikaVM_run(PikaObj* self, char* py_lines) { + return __pikaVM_runPyLines(self, py_lines); +} + +VMParameters* pikaVM_runByteCode(PikaObj* self, const uint8_t* bytecode) { + RunState run_state = {.try_state = TRY_STATE_NONE, + .try_result = TRY_RESULT_NONE}; + return _do_pikaVM_runByteCode(self, self, self, (uint8_t*)bytecode, + &run_state, PIKA_TRUE); +} + +VMParameters* pikaVM_runByteCodeInconstant(PikaObj* self, uint8_t* bytecode) { + RunState run_state = {.try_state = TRY_STATE_NONE, + .try_result = TRY_RESULT_NONE}; + return _do_pikaVM_runByteCode(self, self, self, (uint8_t*)bytecode, + &run_state, PIKA_FALSE); +} + +void constPool_update(ConstPool* self) { + self->content_start = (void*)arg_getContent(self->arg_buff); +} + +void constPool_init(ConstPool* self) { + self->arg_buff = NULL; + self->content_start = NULL; + self->content_offset_now = 0; + self->size = 1; + self->output_redirect_fun = NULL; + self->output_f = NULL; +} + +void constPool_deinit(ConstPool* self) { + if (NULL != self->arg_buff) { + arg_deinit(self->arg_buff); + } +} + +void constPool_append(ConstPool* self, char* content) { + if (NULL == self->arg_buff) { + self->arg_buff = arg_newStr(""); + } + uint16_t size = strGetSize(content) + 1; + if (NULL == self->output_redirect_fun) { + self->arg_buff = arg_append(self->arg_buff, content, size); + } else { + self->output_redirect_fun(self, content); + }; + constPool_update(self); + self->size += size; +} + +char* constPool_getNow(ConstPool* self) { + if (self->content_offset_now >= self->size) { + /* is the end */ + return NULL; + } + return (char*)((uintptr_t)constPool_getStart(self) + + (uintptr_t)(self->content_offset_now)); +} + +uint16_t constPool_getOffsetByData(ConstPool* self, char* data) { + uint16_t ptr_befor = self->content_offset_now; + /* set ptr_now to begin */ + self->content_offset_now = 0; + uint16_t offset_out = 65535; + if (self->arg_buff == NULL) { + goto __exit; + } + while (1) { + if (NULL == constPool_getNext(self)) { + goto __exit; + } + if (strEqu(data, constPool_getNow(self))) { + offset_out = self->content_offset_now; + goto __exit; + } + } +__exit: + /* retore ptr_now */ + self->content_offset_now = ptr_befor; + return offset_out; +} + +char* constPool_getNext(ConstPool* self) { + self->content_offset_now += strGetSize(constPool_getNow(self)) + 1; + return constPool_getNow(self); +} + +char* constPool_getByIndex(ConstPool* self, uint16_t index) { + uint16_t ptr_befor = self->content_offset_now; + /* set ptr_now to begin */ + self->content_offset_now = 0; + for (uint16_t i = 0; i < index; i++) { + constPool_getNext(self); + } + char* res = constPool_getNow(self); + /* retore ptr_now */ + self->content_offset_now = ptr_befor; + return res; +} + +void constPool_print(ConstPool* self) { + uint16_t ptr_befor = self->content_offset_now; + /* set ptr_now to begin */ + self->content_offset_now = 0; + while (1) { + if (NULL == constPool_getNext(self)) { + goto exit; + } + uint16_t offset = self->content_offset_now; + pika_platform_printf("%d: %s\r\n", offset, constPool_getNow(self)); + } +exit: + /* retore ptr_now */ + self->content_offset_now = ptr_befor; + return; +} + +void byteCodeFrame_init(ByteCodeFrame* self) { + /* init to support append, + if only load static bytecode, + can not init */ + constPool_init(&(self->const_pool)); + instructArray_init(&(self->instruct_array)); +} + +extern const char magic_code_pyo[4]; +void _do_byteCodeFrame_loadByteCode(ByteCodeFrame* self, + uint8_t* bytes, + PIKA_BOOL is_const) { + if (bytes[0] == magic_code_pyo[0] && bytes[1] == magic_code_pyo[1] && + bytes[2] == magic_code_pyo[2] && bytes[3] == magic_code_pyo[3]) { + /* load from file, found magic code, skip head */ + bytes = bytes + sizeof(magic_code_pyo) + sizeof(uint32_t); + } + uint32_t* ins_size_p = (uint32_t*)bytes; + void* ins_start_p = (uint32_t*)((uintptr_t)bytes + sizeof(*ins_size_p)); + uint32_t* const_size_p = + (uint32_t*)((uintptr_t)ins_start_p + (uintptr_t)(*ins_size_p)); + self->instruct_array.size = *ins_size_p; + self->instruct_array.content_start = ins_start_p; + self->const_pool.size = *const_size_p; + self->const_pool.content_start = + (char*)((uintptr_t)const_size_p + sizeof(*const_size_p)); + if (!is_const) { + pika_assert(NULL == self->instruct_array.arg_buff); + pika_assert(NULL == self->instruct_array.arg_buff); + self->instruct_array.arg_buff = arg_newBytes(ins_start_p, *ins_size_p); + self->const_pool.arg_buff = + arg_newBytes(self->const_pool.content_start, *const_size_p); + self->instruct_array.content_start = + arg_getBytes(self->instruct_array.arg_buff); + self->const_pool.content_start = + arg_getBytes(self->const_pool.arg_buff); + } +} + +void byteCodeFrame_loadByteCode(ByteCodeFrame* self, uint8_t* bytes) { + _do_byteCodeFrame_loadByteCode(self, bytes, PIKA_TRUE); +} + +void byteCodeFrame_deinit(ByteCodeFrame* self) { + constPool_deinit(&(self->const_pool)); + instructArray_deinit(&(self->instruct_array)); +} + +void instructArray_init(InstructArray* self) { + self->arg_buff = NULL; + self->content_start = NULL; + self->size = 0; + self->content_offset_now = 0; + self->output_redirect_fun = NULL; + self->output_f = NULL; +} + +void instructArray_deinit(InstructArray* self) { + if (NULL != self->arg_buff) { + arg_deinit(self->arg_buff); + } +} + +void instructArray_append(InstructArray* self, InstructUnit* ins_unit) { + if (NULL == self->arg_buff) { + self->arg_buff = arg_newNull(); + } + if (NULL == self->output_redirect_fun) { + self->arg_buff = + arg_append(self->arg_buff, ins_unit, instructUnit_getSize()); + } else { + self->output_redirect_fun(self, ins_unit); + }; + instructArray_update(self); + self->size += instructUnit_getSize(); +} + +void instructUnit_init(InstructUnit* ins_unit) { + ins_unit->deepth = 0; + ins_unit->const_pool_index = 0; + ins_unit->isNewLine_instruct = 0; +} + +void instructArray_update(InstructArray* self) { + self->content_start = (void*)arg_getContent(self->arg_buff); +} + +InstructUnit* instructArray_getNow(InstructArray* self) { + if (self->content_offset_now >= self->size) { + /* is the end */ + return NULL; + } + return (InstructUnit*)((uintptr_t)instructArray_getStart(self) + + (uintptr_t)(self->content_offset_now)); +} + +InstructUnit* instructArray_getNext(InstructArray* self) { + self->content_offset_now += instructUnit_getSize(); + return instructArray_getNow(self); +} + +static char* instructUnit_getInstructStr(InstructUnit* self) { +#define __INS_GET_INS_STR +#include "__instruction_table.cfg" + return "NON"; +} + +void instructUnit_print(InstructUnit* self) { + if (instructUnit_getIsNewLine(self)) { + pika_platform_printf("B%d\r\n", instructUnit_getBlockDeepth(self)); + } + pika_platform_printf("%d %s #%d\r\n", instructUnit_getInvokeDeepth(self), + instructUnit_getInstructStr(self), + self->const_pool_index); +} + +static void instructUnit_printWithConst(InstructUnit* self, + ConstPool* const_pool) { + // if (instructUnit_getIsNewLine(self)) { + // pika_platform_printf("B%d\r\n", instructUnit_getBlockDeepth(self)); + // } + pika_platform_printf( + "%s %s \t\t(#%d)\r\n", instructUnit_getInstructStr(self), + constPool_getByOffset(const_pool, self->const_pool_index), + self->const_pool_index); +} + +void instructArray_printWithConst(InstructArray* self, ConstPool* const_pool) { + uint16_t offset_befor = self->content_offset_now; + self->content_offset_now = 0; + while (1) { + InstructUnit* ins_unit = instructArray_getNow(self); + if (NULL == ins_unit) { + goto exit; + } + instructUnit_printWithConst(ins_unit, const_pool); + instructArray_getNext(self); + } +exit: + self->content_offset_now = offset_befor; + return; +} + +void instructArray_print(InstructArray* self) { + uint16_t offset_befor = self->content_offset_now; + self->content_offset_now = 0; + while (1) { + InstructUnit* ins_unit = instructArray_getNow(self); + if (NULL == ins_unit) { + goto exit; + } + instructUnit_print(ins_unit); + instructArray_getNext(self); + } +exit: + self->content_offset_now = offset_befor; + return; +} + +void instructArray_printAsArray(InstructArray* self) { + uint16_t offset_befor = self->content_offset_now; + self->content_offset_now = 0; + uint8_t line_num = 12; + uint16_t g_i = 0; + uint8_t* ins_size_p = (uint8_t*)&self->size; + pika_platform_printf("0x%02x, ", *(ins_size_p)); + pika_platform_printf("0x%02x, ", *(ins_size_p + (uintptr_t)1)); + pika_platform_printf("0x%02x, ", *(ins_size_p + (uintptr_t)2)); + pika_platform_printf("0x%02x, ", *(ins_size_p + (uintptr_t)3)); + pika_platform_printf("/* instruct array size */\n"); + while (1) { + InstructUnit* ins_unit = instructArray_getNow(self); + if (NULL == ins_unit) { + goto exit; + } + for (int i = 0; i < (int)instructUnit_getSize(); i++) { + g_i++; + pika_platform_printf("0x%02x, ", + *((uint8_t*)ins_unit + (uintptr_t)i)); + if (g_i % line_num == 0) { + pika_platform_printf("\n"); + } + } + instructArray_getNext(self); + } +exit: + pika_platform_printf("/* instruct array */\n"); + self->content_offset_now = offset_befor; + return; +} + +size_t byteCodeFrame_getSize(ByteCodeFrame* bf) { + return bf->const_pool.size + bf->instruct_array.size; +} + +void byteCodeFrame_print(ByteCodeFrame* self) { + constPool_print(&(self->const_pool)); + instructArray_printWithConst(&(self->instruct_array), &(self->const_pool)); + pika_platform_printf("---------------\r\n"); + pika_platform_printf("byte code size: %d\r\n", + self->const_pool.size + self->instruct_array.size); +} + +void VMState_solveUnusedStack(VMState* vm) { + uint8_t top = stack_getTop(&(vm->stack)); + for (int i = 0; i < top; i++) { + Arg* arg = stack_popArg_alloc(&(vm->stack)); + ArgType type = arg_getType(arg); + if (type == ARG_TYPE_NONE) { + arg_deinit(arg); + continue; + } + if (vm->line_error_code != 0) { + arg_deinit(arg); + continue; + } + arg_singlePrint(arg, PIKA_TRUE, "\r\n"); + arg_deinit(arg); + } +} + +static VMParameters* __pikaVM_runByteCodeFrameWithState( + PikaObj* self, + VMParameters* locals, + VMParameters* globals, + ByteCodeFrame* bytecode_frame, + uint16_t pc, + RunState* run_state) { + pika_assert(NULL != run_state); + int size = bytecode_frame->instruct_array.size; + /* locals is the local scope */ + VMState vm = { + .bytecode_frame = bytecode_frame, + .locals = locals, + .globals = globals, + .jmp = 0, + .pc = pc, + .loop_deepth = 0, + .error_code = PIKA_RES_OK, + .line_error_code = PIKA_RES_OK, + .try_error_code = PIKA_RES_OK, + .run_state = run_state, + .ins_cnt = 0, + .in_super = PIKA_FALSE, + .super_invoke_deepth = 0, + }; + stack_init(&(vm.stack)); + VMState_initReg(&vm); + if (PikaVMSignal.vm_cnt == 0) { + pks_vmSignal_setCtrlElear(); + } + PikaVMSignal.vm_cnt++; + while (vm.pc < size) { + if (vm.pc == VM_PC_EXIT) { + break; + } + InstructUnit* this_ins_unit = VMState_getInstructNow(&vm); + uint8_t is_new_line = instructUnit_getIsNewLine(this_ins_unit); + if (is_new_line) { + VMState_solveUnusedStack(&vm); + stack_reset(&(vm.stack)); + vm.error_code = 0; + vm.line_error_code = 0; + } + vm.pc = pikaVM_runInstructUnit(self, &vm, this_ins_unit); + vm.ins_cnt++; +#if PIKA_INSTRUCT_HOOK_ENABLE + if (vm.ins_cnt % PIKA_INSTRUCT_HOOK_PERIOD == 0) { + pika_hook_instruct(); + } +#endif +#if PIKA_EVENT_ENABLE + _VMEvent_pickupEvent(); +#endif + if (0 != vm.error_code) { + vm.line_error_code = vm.error_code; + InstructUnit* head_ins_unit = this_ins_unit; + /* get first ins of a line */ + while (1) { + if (instructUnit_getIsNewLine(head_ins_unit)) { + break; + } + head_ins_unit--; + } + if (vm.run_state->try_state) { + vm.try_error_code = vm.error_code; + } + /* print inses of a line */ + if (!vm.run_state->try_state) { + while (1) { + if (head_ins_unit != this_ins_unit) { + pika_platform_printf(" "); + } else { + pika_platform_printf(" -> "); + } + instructUnit_printWithConst(head_ins_unit, + &(bytecode_frame->const_pool)); + head_ins_unit++; + if (head_ins_unit > this_ins_unit) { + break; + } + } + } + pika_platform_error_handle(); + vm.error_code = 0; + } + } + VMState_solveUnusedStack(&vm); + stack_deinit(&(vm.stack)); + PikaVMSignal.vm_cnt--; + return locals; +} + +VMParameters* pikaVM_runByteCodeFrame(PikaObj* self, + ByteCodeFrame* byteCode_frame) { + RunState run_state = {.try_state = TRY_STATE_NONE, + .try_result = TRY_RESULT_NONE}; + return __pikaVM_runByteCodeFrameWithState(self, self, self, byteCode_frame, + 0, &run_state); +} + +void constPool_printAsArray(ConstPool* self) { + uint8_t* const_size_str = (uint8_t*)&(self->size); + pika_platform_printf("0x%02x, ", *(const_size_str)); + pika_platform_printf("0x%02x, ", *(const_size_str + (uintptr_t)1)); + pika_platform_printf("0x%02x, ", *(const_size_str + (uintptr_t)2)); + pika_platform_printf("0x%02x, ", *(const_size_str + (uintptr_t)3)); + pika_platform_printf("/* const pool size */\n"); + uint16_t ptr_befor = self->content_offset_now; + uint8_t line_num = 12; + uint16_t g_i = 0; + /* set ptr_now to begin */ + self->content_offset_now = 0; + pika_platform_printf("0x00, "); + while (1) { + if (NULL == constPool_getNext(self)) { + goto exit; + } + char* data_each = constPool_getNow(self); + /* todo start */ + size_t len = strlen(data_each); + for (uint32_t i = 0; i < len + 1; i++) { + pika_platform_printf("0x%02x, ", *(data_each + (uintptr_t)i)); + g_i++; + if (g_i % line_num == 0) { + pika_platform_printf("\n"); + } + } + /* todo end */ + } +exit: + /* retore ptr_now */ + pika_platform_printf("/* const pool */\n"); + self->content_offset_now = ptr_befor; + return; +} + +void byteCodeFrame_printAsArray(ByteCodeFrame* self) { + pika_platform_printf("const uint8_t bytes[] = {\n"); + instructArray_printAsArray(&(self->instruct_array)); + constPool_printAsArray(&(self->const_pool)); + pika_platform_printf("};\n"); + pika_platform_printf("pikaVM_runByteCode(self, (uint8_t*)bytes);\n"); +} + +PikaObj* pikaVM_runFile(PikaObj* self, char* file_name) { + Args buffs = {0}; + char* module_name = strsCopy(&buffs, file_name); + strPopLastToken(module_name, '.'); + + pika_platform_printf("(pikascript) pika compiler:\r\n"); + PikaMaker* maker = New_PikaMaker(); + pikaMaker_compileModuleWithDepends(maker, module_name); + pikaMaker_linkCompiledModules(maker, "pikaModules_cache.py.a"); + pikaMaker_deinit(maker); + pika_platform_printf("(pikascript) all succeed.\r\n\r\n"); + + pikaMemMaxReset(); + obj_linkLibraryFile(self, "pikascript-api/pikaModules_cache.py.a"); + self = pikaVM_runSingleFile(self, file_name); + strsDeinit(&buffs); + return self; +} diff --git a/examples/pikapython/pikapython/pikascript-core/PikaVM.h b/examples/pikapython/pikapython/pikascript-core/PikaVM.h new file mode 100644 index 00000000..c267ae3b --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/PikaVM.h @@ -0,0 +1,316 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __PIKA_VM__H +#define __PIKA_VM__H +#include "PikaObj.h" +#include "dataQueue.h" +#include "dataQueueObj.h" +#include "dataStack.h" + +enum Instruct { +#define __INS_ENUM +#include "__instruction_table.cfg" + __INSTRCUTION_CNT, +}; + +typedef enum { + VM_JMP_EXIT = -999, + VM_JMP_CONTINUE = -997, + VM_JMP_BREAK = -998, + VM_JMP_RAISE = -996, +} VM_JMP; + +typedef enum { VM_PC_EXIT = -99999 } VM_PC; + +typedef enum { + TRY_STATE_NONE = 0, + TRY_STATE_INNER, +} TRY_STATE; + +typedef enum { + TRY_RESULT_NONE = 0, + TRY_RESULT_RAISE, +} TRY_RESULT; + +typedef struct RunState RunState; +struct RunState { + TRY_STATE try_state; + TRY_RESULT try_result; +}; + +typedef struct VMState VMState; +struct VMState { + VMParameters* locals; + VMParameters* globals; + Stack stack; + int32_t jmp; + int32_t pc; + ByteCodeFrame* bytecode_frame; + uint8_t loop_deepth; + int8_t error_code; + uint8_t line_error_code; + uint8_t try_error_code; + uint32_t ins_cnt; + PIKA_BOOL in_super; + uint8_t super_invoke_deepth; + PikaObj* lreg[PIKA_REGIST_SIZE]; + PIKA_BOOL ireg[PIKA_REGIST_SIZE]; + RunState* run_state; +}; + +typedef struct { + int8_t n_positional; + int8_t n_positional_got; + int8_t n_default; + int8_t n_arg; + int8_t i_arg; + int8_t n_input; + PIKA_BOOL is_vars; + PIKA_BOOL is_keys; + PIKA_BOOL is_default; + ArgType method_type; + PikaTuple* tuple; + PikaDict* kw; + PikaDict* kw_keys; + char* var_tuple_name; + char* kw_dict_name; + char* type_list; +} FunctionArgsInfo; + +typedef struct OperatorInfo OperatorInfo; +struct OperatorInfo { + char* opt; + ArgType t1; + ArgType t2; + Arg* a1; + Arg* a2; + pika_float f1; + pika_float f2; + int64_t i1; + int64_t i2; + Arg* res; + int num; + VMState* vm; +}; + +typedef enum VM_SIGNAL_CTRL { + VM_SIGNAL_CTRL_NONE = 0, + VM_SIGNAL_CTRL_EXIT, +} VM_SIGNAL_CTRL; + +typedef struct EventCQ { + uint32_t id[PIKA_EVENT_LIST_SIZE]; + Arg* data[PIKA_EVENT_LIST_SIZE]; + PikaEventListener* lisener[PIKA_EVENT_LIST_SIZE]; + Arg* res[PIKA_EVENT_LIST_SIZE]; + int head; + int tail; +} EventCQ; + +typedef struct VMSignal VMSignal; +struct VMSignal { + VM_SIGNAL_CTRL signal_ctrl; + int vm_cnt; +#if PIKA_EVENT_ENABLE + EventCQ cq; +#endif +}; + +VMParameters* pikaVM_run(PikaObj* self, char* pyLine); +VMParameters* pikaVM_runAsm(PikaObj* self, char* pikaAsm); +VMParameters* pikaVM_runByteCodeFrame(PikaObj* self, + ByteCodeFrame* byteCode_frame); + +static inline int instructUnit_getBlockDeepth(InstructUnit* self) { + return self->deepth & 0x0F; +} + +static inline int instructUnit_getInvokeDeepth(InstructUnit* self) { + return self->deepth >> 4; +} + +static inline enum Instruct instructUnit_getInstruct(InstructUnit* self) { + return (enum Instruct)(self->isNewLine_instruct & 0x7F); +} + +static inline int instructUnit_getConstPoolIndex(InstructUnit* self) { + return self->const_pool_index; +} + +static inline int instructUnit_getIsNewLine(InstructUnit* self) { + return self->isNewLine_instruct >> 7; +} + +static inline void instructUnit_setBlockDeepth(InstructUnit* self, int val) { + self->deepth |= (0x0F & val); +} + +static inline void instructUnit_setConstPoolIndex(InstructUnit* self, int val) { + self->const_pool_index = val; +} + +static inline void instructUnit_setInvokeDeepth(InstructUnit* self, int val) { + self->deepth |= ((0x0F & val) << 4); +} + +static inline void instructUnit_setInstruct(InstructUnit* self, int val) { + self->isNewLine_instruct |= (0x7F & val); +} + +static inline void instructUnit_setIsNewLine(InstructUnit* self, int val) { + self->isNewLine_instruct |= ((0x01 & val) << 7); +} + +InstructUnit* New_instructUnit(uint8_t data_size); +void instructUnit_deinit(InstructUnit* self); + +enum Instruct pikaVM_getInstructFromAsm(char* line); + +void constPool_init(ConstPool* self); +void constPool_deinit(ConstPool* self); +void constPool_append(ConstPool* self, char* content); + +static inline void* constPool_getStart(ConstPool* self) { + return self->content_start; +} + +static inline int constPool_getLastOffset(ConstPool* self) { + return self->size; +} + +static inline char* constPool_getByOffset(ConstPool* self, int offset) { + return (char*)((uintptr_t)constPool_getStart(self) + (uintptr_t)offset); +} + +static inline char* VMState_getConstWithInstructUnit(VMState* vm, + InstructUnit* ins_unit) { + return constPool_getByOffset(&(vm->bytecode_frame->const_pool), + instructUnit_getConstPoolIndex(ins_unit)); +} + +char* constPool_getNow(ConstPool* self); +char* constPool_getNext(ConstPool* self); +char* constPool_getByIndex(ConstPool* self, uint16_t index); +void constPool_print(ConstPool* self); + +void byteCodeFrame_init(ByteCodeFrame* bf); +void byteCodeFrame_deinit(ByteCodeFrame* bf); +size_t byteCodeFrame_getSize(ByteCodeFrame* bf); + +void instructArray_init(InstructArray* ins_array); +void instructArray_deinit(InstructArray* ins_array); +void instructArray_append(InstructArray* ins_array, InstructUnit* ins_unit); +void instructUnit_init(InstructUnit* ins_unit); +void instructUnit_print(InstructUnit* self); +void instructArray_print(InstructArray* self); + +static inline InstructUnit* instructArray_getStart(InstructArray* self) { + return (InstructUnit*)self->content_start; +} + +static inline size_t instructArray_getSize(InstructArray* self) { + return (size_t)self->size; +} + +static inline int VMState_getInstructArraySize(VMState* vm) { + return instructArray_getSize(&(vm->bytecode_frame->instruct_array)); +} + +static inline InstructUnit* instructArray_getByOffset(InstructArray* self, + int offset) { + return (InstructUnit*)((uintptr_t)instructArray_getStart(self) + + (uintptr_t)offset); +} + +static inline InstructUnit* VMState_getInstructUnitWithOffset(VMState* vm, + int offset) { + return instructArray_getByOffset(&(vm->bytecode_frame->instruct_array), + vm->pc + offset); +} + +static inline InstructUnit* VMState_getInstructNow(VMState* vm) { + return instructArray_getByOffset(&(vm->bytecode_frame->instruct_array), + vm->pc); +} + +void byteCodeFrame_print(ByteCodeFrame* self); + +static inline size_t instructUnit_getSize(void) { + return (size_t)sizeof(InstructUnit); +} + +uint16_t constPool_getOffsetByData(ConstPool* self, char* data); +void instructArray_printWithConst(InstructArray* self, ConstPool* const_pool); +void constPool_update(ConstPool* self); +void instructArray_update(InstructArray* self); +void constPool_printAsArray(ConstPool* self); +void instructArray_printAsArray(InstructArray* self); +void byteCodeFrame_loadByteCode(ByteCodeFrame* self, uint8_t* bytes); +void byteCodeFrame_printAsArray(ByteCodeFrame* self); +void byteCodeFrame_init(ByteCodeFrame* self); +VMParameters* pikaVM_runByteCode(PikaObj* self, const uint8_t* bytecode); +VMParameters* pikaVM_runByteCodeInconstant(PikaObj* self, uint8_t* bytecode); +InstructUnit* instructArray_getNow(InstructArray* self); +InstructUnit* instructArray_getNext(InstructArray* self); +VMParameters* pikaVM_runSingleFile(PikaObj* self, char* filename); +VMParameters* pikaVM_runByteCodeFile(PikaObj* self, char* filename); +Arg* obj_runMethodArg(PikaObj* self, PikaObj* method_args_obj, Arg* method_arg); +PikaObj* pikaVM_runFile(PikaObj* self, char* file_name); +Arg* _vm_slice(VMState* vm, + PikaObj* self, + Arg* end, + Arg* obj, + Arg* start, + int step); +VMParameters* _do_pikaVM_runByteCode(PikaObj* self, + VMParameters* locals, + VMParameters* globals, + uint8_t* bytecode, + RunState* run_state, + PIKA_BOOL is_const_bytecode); +void _do_byteCodeFrame_loadByteCode(ByteCodeFrame* self, + uint8_t* bytes, + PIKA_BOOL is_const); +Arg* __vm_get(VMState* vm, PikaObj* self, Arg* key, Arg* obj); +void __vm_List_append(PikaObj* self, Arg* arg); +void __vm_List___init__(PikaObj* self); +void __vm_Dict_set(PikaObj* self, Arg* arg, char* key); +void __vm_Dict___init__(PikaObj* self); +VM_SIGNAL_CTRL VMSignal_getCtrl(void); +void pks_vm_exit(void); +void pks_vmSignal_setCtrlElear(void); +PIKA_RES __eventListener_popEvent(PikaEventListener** lisener_p, + uint32_t* id, + Arg** signal, + int* head); +PIKA_RES __eventListener_pushEvent(PikaEventListener* lisener, + uint32_t eventId, + Arg* eventData); +int _VMEvent_getVMCnt(void); +void _VMEvent_pickupEvent(void); +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/PikaVersion.h b/examples/pikapython/pikapython/pikascript-core/PikaVersion.h new file mode 100644 index 00000000..0a961d53 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/PikaVersion.h @@ -0,0 +1,5 @@ +#define PIKA_VERSION_MAJOR 1 +#define PIKA_VERSION_MINOR 12 +#define PIKA_VERSION_MICRO 0 + +#define PIKA_EDIT_TIME "2022/12/29 18:05:17" diff --git a/examples/pikapython/pikapython/pikascript-core/README.md b/examples/pikapython/pikapython/pikascript-core/README.md new file mode 100644 index 00000000..ea47272d --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/README.md @@ -0,0 +1 @@ +# PikaScript 运行时内核 diff --git a/examples/pikapython/pikapython/pikascript-core/TinyObj.c b/examples/pikapython/pikapython/pikascript-core/TinyObj.c new file mode 100644 index 00000000..1e7c34c8 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/TinyObj.c @@ -0,0 +1,37 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "PikaObj.h" + +const NativeProperty TinyObjNativeProp = {.super = NULL, + .methodGroup = NULL, + .methodGroupCount = 0}; + +PikaObj* New_TinyObj(Args* args) { + PikaObj* self = New_PikaObj(); + return self; +} diff --git a/examples/pikapython/pikapython/pikascript-core/TinyObj.h b/examples/pikapython/pikapython/pikascript-core/TinyObj.h new file mode 100644 index 00000000..72d388ef --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/TinyObj.h @@ -0,0 +1,32 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __TYNYOBJ__H +#define __TYNYOBJ__H +#include "PikaObj.h" +PikaObj* New_TinyObj(Args* args); +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/__instruction_def.h b/examples/pikapython/pikapython/pikascript-core/__instruction_def.h new file mode 100644 index 00000000..b4e1d62d --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/__instruction_def.h @@ -0,0 +1,54 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 GorgonMeducer ?? embedded_zhuoran@hotmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#undef def_ins + +#if defined(__INS_ENUM) +#define def_ins(__INS_NAME) __INS_NAME, +#endif + +#if defined(__INS_TABLE) +#define def_ins(__INS_NAME) [__INS_NAME] = &VM_instruction_handler_##__INS_NAME, +#endif + +#if defined(__INS_COMPIRE) +#define def_ins(__INS_NAME) \ + if (0 == strncmp(ins_str, "" #__INS_NAME "", 3)) { \ + return __INS_NAME; \ + } +#endif + +#if defined(__INS_GET_INS_STR) +#define def_ins(__INS_NAME) \ + if (__INS_NAME == instructUnit_getInstruct(self)){ \ + return ""#__INS_NAME""; \ + } +#endif + +#undef __INS_ENUM +#undef __INS_TABLE +#undef __INS_COMPIRE diff --git a/examples/pikapython/pikapython/pikascript-core/__instruction_table.cfg b/examples/pikapython/pikapython/pikascript-core/__instruction_table.cfg new file mode 100644 index 00000000..e69baf28 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/__instruction_table.cfg @@ -0,0 +1,98 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 GorgonMeducer ?? embedded_zhuoran@hotmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "__instruction_def.h" + +//! just append ins to the end, insert ins would brake the pre-compiled +//! bytecode. + +/* none */ +def_ins(NON) +/* get referance */ +def_ins(REF) +/* run function */ +def_ins(RUN) +/* string */ +def_ins(STR) +/* output */ +def_ins(OUT) +/* number */ +def_ins(NUM) +/* jump */ +def_ins(JMP) +/* jump qual zero */ +def_ins(JEZ) +/* operator */ +def_ins(OPT) +/* define */ +def_ins(DEF) +/* return */ +def_ins(RET) +/* not equal */ +def_ins(NEL) +/* delete */ +def_ins(DEL) +/* exist */ +def_ins(EST) +/* break */ +def_ins(BRK) +/* continue */ +def_ins(CTN) +/* global */ +def_ins(GLB) +/* run as */ +def_ins(RAS) +/* new */ +def_ins(NEW) +/* class */ +def_ins(CLS) +/* bytes */ +def_ins(BYT) +/* list */ +def_ins(LST) +/* import */ +def_ins(IMP) +/* try */ +def_ins(TRY) +/* not try */ +def_ins(NTR) +/* raise */ +def_ins(RIS) +/* get error code */ +def_ins(GER) +/* set error code */ +def_ins(SER) +/* dict */ +def_ins(DCT) +/* slice */ +def_ins(SLC) +/* assert */ +def_ins(ASS) +/* expect */ +def_ins(EXP) +/* jump no zero */ +def_ins(JNZ) diff --git a/examples/pikapython/pikapython/pikascript-core/__pika_ooc.h b/examples/pikapython/pikapython/pikascript-core/__pika_ooc.h new file mode 100644 index 00000000..91c5c379 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/__pika_ooc.h @@ -0,0 +1,36 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon ?? liang6516@outlook.com + * Copyright (c) 2021 Gorgon Meducer ?? embedded_zhuoran@hotmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __PIKA_OOC_H__ +#define __PIKA_OOC_H__ + #if PIKA_PLOOC_ENABLE + #include "../pikascript-lib/PLOOC/plooc_class.h" + #else + #define private_member(X) X + #endif +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/dataArg.c b/examples/pikapython/pikapython/pikascript-core/dataArg.c new file mode 100644 index 00000000..35a0dcc7 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataArg.c @@ -0,0 +1,599 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "dataArg.h" +#include "PikaObj.h" +#include "dataArgs.h" +#include "dataMemory.h" +#include "dataString.h" +#include "stdlib.h" + +static PIKA_BOOL _arg_cache_push(Arg* self, uint32_t size) { +#if !PIKA_ARG_CACHE_ENABLE + return PIKA_FALSE; +#else + if (PIKA_FALSE == pika_hook_arg_cache_filter(self)) { + return PIKA_FALSE; + } + extern PikaMemInfo pikaMemInfo; + if (self->heap_size < PIKA_ARG_CACHE_SIZE || + self->heap_size > 2 * PIKA_ARG_CACHE_SIZE) { + return PIKA_FALSE; + } + if (PIKA_ARG_CACHE_POOL_SIZE <= pikaMemInfo.cache_pool_top) { + return PIKA_FALSE; + } + pikaMemInfo.cache_pool[pikaMemInfo.cache_pool_top++] = (uint8_t*)self; + pikaMemInfo.heapUsed -= mem_align(sizeof(Arg) + size); + return PIKA_TRUE; +#endif +} + +static Arg* _arg_cache_pop(uint32_t size) { +#if !PIKA_ARG_CACHE_ENABLE + return NULL; +#else + uint32_t req_heap_size = mem_align(sizeof(Arg) + size); + extern PikaMemInfo pikaMemInfo; + if (req_heap_size > PIKA_ARG_CACHE_SIZE) { + return NULL; + } + if (!(pikaMemInfo.cache_pool_top > 0)) { + return NULL; + } + --pikaMemInfo.cache_pool_top; + Arg* self = (Arg*)pikaMemInfo.cache_pool[pikaMemInfo.cache_pool_top]; + pikaMemInfo.heapUsed += mem_align(sizeof(Arg) + size); + return self; +#endif +} + +uint32_t arg_getTotleSize(Arg* self) { + return arg_totleSize(self); +} + +/** + * time33 hash + */ + +Hash hash_time33EndWith(char* str, char end) { + pika_assert(str != NULL); + if (*str == 0) { + return 5381; + } + Hash hash = 5381; + while (*str && *str != end) { + hash += (hash << 5) + (*str++); + } + return (hash & 0x7FFFFFFF); +} + +Hash hash_time33(char* str) { + pika_assert(str != NULL); + if (*str == 0) { + return 5381; + } + Hash hash = 5381; + while (*str) { + hash += (hash << 5) + (*str++); + } + return (hash & 0x7FFFFFFF); +} + +static Arg* _arg_set_hash(Arg* self, + Hash nameHash, + ArgType type, + uint8_t* content, + uint32_t size, + Arg* next) { + /* create arg if not exist */ + if (NULL == self || self->size < size) { + self = _arg_cache_pop(size); + uint32_t heap_size = sizeof(Arg) + size; +#if PIKA_ARG_CACHE_ENABLE + // if (heap_size < PIKA_ARG_CACHE_SIZE) { + // heap_size = PIKA_ARG_CACHE_SIZE; + // } + extern PikaMemInfo pikaMemInfo; + pikaMemInfo.alloc_times++; + pikaMemInfo.alloc_times_cache++; +#endif + if (NULL == self) { + self = (Arg*)pikaMalloc(heap_size); +#if PIKA_ARG_CACHE_ENABLE + extern PikaMemInfo pikaMemInfo; + pikaMemInfo.alloc_times_cache--; + self->heap_size = mem_align(heap_size); +#endif + } + self->size = size; + self->flag = 0; + arg_setSerialized(self, PIKA_TRUE); + // arg_setIsKeyword(self, PIKA_FALSE); + arg_setNext(self, next); + } + self->name_hash = nameHash; + self->type = type; + if (NULL != content) { + pika_platform_memcpy(arg_getContent(self), content, size); + } else { + pika_platform_memset(arg_getContent(self), 0, + aline_by(size, sizeof(uint32_t))); + } + pika_assert(self->flag < ARG_FLAG_MAX); + return self; +} + +static Arg* arg_create_hash(Hash nameHash, + ArgType type, + uint8_t* content, + uint32_t size, + Arg* next) { + return _arg_set_hash(NULL, nameHash, type, content, size, next); +} + +static Arg* arg_create(char* name, + ArgType type, + uint8_t* content, + uint32_t size, + Arg* next) { + Hash nameHash = hash_time33(name); + return arg_create_hash(nameHash, type, content, size, next); +} + +static Arg* arg_set(Arg* self, + char* name, + ArgType type, + uint8_t* content, + uint32_t size) { + Hash nameHash = hash_time33(name); + return _arg_set_hash(self, nameHash, type, content, size, NULL); +} + +void arg_init_stack(Arg* self, uint8_t* buffer, uint32_t size) { + self->_.buffer = buffer; + self->size = size; +} + +uint32_t arg_totleSize(Arg* self) { + return ((Arg*)self)->size + sizeof(Arg); +} + +void arg_freeContent(Arg* self) { + pika_assert(NULL != self); + if (_arg_cache_push(self, self->size)) { + return; + } + pikaFree(self, arg_totleSize(self)); + return; +} + +Arg* arg_setContent(Arg* self, uint8_t* content, uint32_t size) { + if (NULL == self) { + /* malloc */ + return arg_create("", ARG_TYPE_NONE, content, size, NULL); + } + + /* only copy */ + if (arg_getSize(self) >= size) { + pika_platform_memcpy(arg_getContent((Arg*)self), content, size); + return self; + } + + /* realloc */ + Hash nameHash = arg_getNameHash(self); + ArgType type = arg_getType(self); + Arg* next = arg_getNext(self); + Arg* newContent = arg_create_hash(nameHash, type, content, size, next); + arg_freeContent(self); + return newContent; +} + +Arg* arg_setNameHash(Arg* self, Hash nameHash) { + if (NULL == self) { + return arg_create_hash(nameHash, ARG_TYPE_NONE, NULL, 0, NULL); + } + Arg* arg = (Arg*)self; + arg->name_hash = nameHash; + return self; +} + +Arg* arg_setName(Arg* self, char* name) { + pika_assert(NULL != name); + return arg_setNameHash(self, hash_time33(name)); +} + +Arg* arg_setBytes(Arg* self, char* name, uint8_t* src, size_t size) { + self = arg_newContent(size + sizeof(size_t) + 1); + if (NULL == self) { + return NULL; + } + self = arg_setName(self, name); + pika_assert(NULL != self); + arg_setType(self, ARG_TYPE_BYTES); + void* dir = arg_getContent(self); + /* set content all to 0 */ + pika_platform_memset(dir, 0, size + sizeof(size_t) + 1); + /* setsize */ + pika_platform_memcpy(dir, &size, sizeof(size_t)); + + /* set init value */ + if (NULL != src) { + pika_platform_memcpy((void*)((uintptr_t)dir + sizeof(size_t)), src, size); + } + pika_assert(self->flag < ARG_FLAG_MAX); + return self; +} + +Arg* arg_newContent(uint32_t size) { + Arg* newContent = arg_create("", ARG_TYPE_NONE, NULL, size, NULL); + return newContent; +} + +uint8_t* arg_getBytes(Arg* self) { + return arg_getContent(self) + sizeof(size_t); +} + +char* __printBytes(PikaObj* self, Arg* arg) { + Args buffs = {0}; + size_t bytes_size = arg_getBytesSize(arg); + uint8_t* bytes = arg_getBytes(arg); + Arg* str_arg = arg_newStr("b\'"); + for (size_t i = 0; i < bytes_size; i++) { + char* str_item = strsFormat(&buffs, 16, "\\x%02x", bytes[i]); + str_arg = arg_strAppend(str_arg, str_item); + } + str_arg = arg_strAppend(str_arg, "\'"); + char* str_res = obj_cacheStr(self, arg_getStr(str_arg)); + strsDeinit(&buffs); + arg_deinit(str_arg); + return str_res; +} + +void arg_printBytes(Arg* self, char* end) { + PikaObj* obj = New_PikaObj(); + pika_platform_printf("%s%s", __printBytes(obj, self), end); + obj_deinit(obj); +} + +void arg_singlePrint(Arg* self, PIKA_BOOL in_REPL, char* end) { + ArgType type = arg_getType(self); + if (ARG_TYPE_NONE == type) { + pika_platform_printf("None%s", end); + return; + } + if (argType_isObject(type)) { + char* res = obj_toStr(arg_getPtr(self)); + pika_platform_printf("%s%s", res, end); + return; + } + if (type == ARG_TYPE_INT) { +#if PIKA_PRINT_LLD_ENABLE + pika_platform_printf("%lld%s", (long long int)arg_getInt(self), end); +#else + pika_platform_printf("%d%s", (int)arg_getInt(self), end); +#endif + return; + } + if (type == ARG_TYPE_FLOAT) { + pika_platform_printf("%f%s", arg_getFloat(self), end); + return; + } + if (type == ARG_TYPE_STRING) { + if (in_REPL) { + pika_platform_printf("'%s'%s", arg_getStr(self), end); + return; + } + pika_platform_printf("%s%s", arg_getStr(self), end); + return; + } + if (type == ARG_TYPE_BYTES) { + arg_printBytes(self, end); + return; + } + if (ARG_TYPE_POINTER == type || ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR) { + pika_platform_printf("%p%s", arg_getPtr(self), end); + return; + } + return; +} + +size_t arg_getBytesSize(Arg* self) { + size_t mem_size = 0; + void* content = (void*)arg_getContent(self); + if (NULL == content) { + return 0; + } + pika_platform_memcpy(&mem_size, content, sizeof(size_t)); + return mem_size; +} + +Arg* arg_setStruct(Arg* self, + char* name, + void* struct_ptr, + uint32_t struct_size) { + if (NULL == struct_ptr) { + return NULL; + } + return arg_set(self, name, ARG_TYPE_STRUCT, (uint8_t*)struct_ptr, + struct_size); +} + +Arg* arg_setHeapStruct(Arg* self, + char* name, + void* struct_ptr, + uint32_t struct_size, + void* struct_deinit_fun) { + if (NULL == struct_ptr) { + return NULL; + } + Arg* struct_arg = + arg_setContent(NULL, (uint8_t*)&struct_deinit_fun, sizeof(void*)); + struct_arg = arg_append(struct_arg, (uint8_t*)struct_ptr, struct_size); + pika_assert(NULL != struct_arg); + arg_setType(struct_arg, ARG_TYPE_STRUCT_HEAP); + struct_arg = arg_setName(struct_arg, name); + return struct_arg; +} + +void* arg_getHeapStructDeinitFun(Arg* self) { + void* deinit_fun = NULL; + pika_platform_memcpy(&deinit_fun, arg_getContent(self), sizeof(void*)); + return deinit_fun; +} + +Arg* arg_setInt(Arg* self, char* name, int64_t val) { + return arg_set(self, name, ARG_TYPE_INT, (uint8_t*)&val, sizeof(val)); +} + +Arg* arg_setNull(Arg* self) { + return arg_set(self, "", ARG_TYPE_NONE, NULL, 0); +} + +Arg* arg_setFloat(Arg* self, char* name, pika_float val) { + return arg_set(self, name, ARG_TYPE_FLOAT, (uint8_t*)&val, sizeof(val)); +} + +pika_float arg_getFloat(Arg* self) { + if (NULL == arg_getContent(self)) { + return -999.999; + } + + return *(pika_float*)arg_getContent(self); +} + +Arg* arg_setPtr(Arg* self, char* name, ArgType type, void* pointer) { + return arg_set(self, name, type, (uint8_t*)&pointer, sizeof(uintptr_t)); +} + +Arg* arg_setStr(Arg* self, char* name, char* string) { + if (NULL == string) { + return NULL; + } + return arg_set(self, name, ARG_TYPE_STRING, (uint8_t*)string, + strGetSize(string) + 1); +} + +int64_t arg_getInt(Arg* self) { + pika_assert(NULL != self); + if (NULL == arg_getContent(self)) { + return -999999; + } + return *(int64_t*)arg_getContent(self); +} + +void* arg_getPtr(Arg* self) { + if (arg_getType(self) == ARG_TYPE_NONE) { + return NULL; + } + if (NULL == arg_getContent(self)) { + return NULL; + } + return *(void**)arg_getContent(self); +} +char* arg_getStr(Arg* self) { + return (char*)arg_getContent(self); +} + +uint32_t arg_getContentSize(Arg* self) { + return arg_getSize(self); +} + +Arg* New_arg(void* voidPointer) { + return NULL; +} + +Arg* arg_copy(Arg* arg_src) { + if (NULL == arg_src) { + return NULL; + } + pika_assert(arg_src->flag < ARG_FLAG_MAX); + ArgType arg_type = arg_getType(arg_src); + if (ARG_TYPE_OBJECT == arg_type) { + obj_refcntInc((PikaObj*)arg_getPtr(arg_src)); + } + Arg* arg_dict = New_arg(NULL); + arg_dict = arg_setContent(arg_dict, arg_getContent(arg_src), + arg_getContentSize(arg_src)); + arg_dict = arg_setNameHash(arg_dict, arg_getNameHash(arg_src)); + pika_assert(NULL != arg_dict); + arg_setType(arg_dict, arg_getType(arg_src)); + arg_setIsKeyword(arg_dict, arg_getIsKeyword(arg_src)); + return arg_dict; +} + +Arg* arg_copy_noalloc(Arg* arg_src, Arg* arg_dict) { + if (NULL == arg_src) { + return NULL; + } + if (NULL == arg_dict) { + return arg_copy(arg_src); + } + /* size is too big to be copied by noalloc */ + if (arg_getSize(arg_src) > arg_getSize(arg_dict)) { + return arg_copy(arg_src); + } + ArgType arg_type = arg_getType(arg_src); + if (ARG_TYPE_OBJECT == arg_type) { + obj_refcntInc((PikaObj*)arg_getPtr(arg_src)); + } + arg_setSerialized(arg_dict, PIKA_FALSE); + arg_dict = arg_setContent(arg_dict, arg_getContent(arg_src), + arg_getContentSize(arg_src)); + arg_dict = arg_setNameHash(arg_dict, arg_getNameHash(arg_src)); + pika_assert(NULL != arg_dict); + arg_setType(arg_dict, arg_getType(arg_src)); + arg_setIsKeyword(arg_dict, arg_getIsKeyword(arg_src)); + return arg_dict; +} + +Arg* arg_append(Arg* self, void* new_content, size_t new_size) { + uint8_t* old_content = arg_getContent(self); + size_t old_size = arg_getContentSize(self); + Arg* new_arg = NULL; +#if PIKA_ARG_CACHE_ENABLE + /* create arg_out */ + if (self->heap_size > mem_align(sizeof(Arg) + old_size + new_size)) { + new_arg = self; + new_arg->size = old_size + new_size; + extern PikaMemInfo pikaMemInfo; + pikaMemInfo.heapUsed += mem_align(sizeof(Arg) + old_size + new_size) - + mem_align(sizeof(Arg) + old_size); + } +#endif + if (NULL == new_arg) { + new_arg = arg_setContent(NULL, NULL, old_size + new_size); + } + pika_assert(NULL != new_arg); + arg_setType(new_arg, arg_getType(self)); + arg_setNameHash(new_arg, arg_getNameHash(self)); + if (self != new_arg) { + /* copy old content */ + pika_platform_memcpy(arg_getContent(new_arg), old_content, old_size); + } + /* copy new content */ + pika_platform_memcpy(arg_getContent(new_arg) + old_size, new_content, + new_size); + if (self != new_arg) { + arg_deinit(self); + } + return new_arg; +} + +void* arg_getHeapStruct(Arg* self) { + return arg_getContent(self) + sizeof(void*); +} + +void arg_deinitHeap(Arg* self) { + if (arg_getIsWeakRef(self)) { + return; + } + ArgType type = arg_getType(self); + /* deinit heap struct */ + if (type == ARG_TYPE_STRUCT_HEAP) { + /* deinit heap strcut */ + StructDeinitFun struct_deinit_fun = + (StructDeinitFun)arg_getHeapStructDeinitFun(self); + struct_deinit_fun(arg_getHeapStruct(self)); + return; + } + /* deinit sub object */ + if (ARG_TYPE_OBJECT == type) { + PikaObj* subObj = arg_getPtr(self); + obj_refcntDec(subObj); + int ref_cnt = obj_refcntNow(subObj); + if (ref_cnt <= 0) { + obj_deinit(subObj); + } + return; + } +} + +/* load file as byte array */ +Arg* arg_loadFile(Arg* self, char* filename) { + size_t file_size = 0; + char* file_buff = pika_platform_malloc(PIKA_READ_FILE_BUFF_SIZE); + Arg* res = New_arg(NULL); + pika_platform_memset(file_buff, 0, PIKA_READ_FILE_BUFF_SIZE); + FILE* input_file = pika_platform_fopen(filename, "rb"); + if (NULL == input_file) { + pika_platform_printf("Error: Couldn't open file '%s'\n", filename); + res = NULL; + goto exit; + } + file_size = + pika_platform_fread(file_buff, 1, PIKA_READ_FILE_BUFF_SIZE, input_file); + + if (file_size >= PIKA_READ_FILE_BUFF_SIZE) { + pika_platform_printf("Error: Not enough buff for input file.\r\n"); + return NULL; + } + /* add '\0' to the end of the string */ + res = arg_setBytes(res, "", (uint8_t*)file_buff, file_size + 1); + +exit: + pika_platform_free(file_buff); + if (NULL != input_file) { + pika_platform_fclose(input_file); + } + return res; +} + +void arg_deinit(Arg* self) { + pika_assert(NULL != self); + /* deinit arg pointed heap */ + arg_deinitHeap(self); + if (!arg_isSerialized(self)) { + return; + } + /* free the ref */ + arg_freeContent(self); +} + +PIKA_BOOL arg_isEqual(Arg* self, Arg* other) { + if (NULL == self || NULL == other) { + return PIKA_FALSE; + } + if (arg_getType(self) != arg_getType(other)) { + return PIKA_FALSE; + } + if (arg_getType(self) == ARG_TYPE_OBJECT) { + if (arg_getPtr(self) != arg_getPtr(other)) { + return PIKA_FALSE; + } + } + if (arg_getType(self) == ARG_TYPE_STRING) { + if (strEqu(arg_getStr(self), arg_getStr(other))) { + return PIKA_TRUE; + } + } + if (0 != pika_platform_memcmp(arg_getContent(self), arg_getContent(other), + arg_getContentSize(self))) { + return PIKA_FALSE; + } + return PIKA_TRUE; +} diff --git a/examples/pikapython/pikapython/pikascript-core/dataArg.h b/examples/pikapython/pikapython/pikascript-core/dataArg.h new file mode 100644 index 00000000..c3d4c167 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataArg.h @@ -0,0 +1,277 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _arg__H +#define _arg__H + +#include "dataLink.h" +#include "dataMemory.h" + +typedef uint32_t Hash; +typedef enum { + ARG_TYPE_UNDEF = 0, + ARG_TYPE_NONE, + ARG_TYPE_INT, + ARG_TYPE_FLOAT, + ARG_TYPE_STRING, + ARG_TYPE_BYTES, + ARG_TYPE_POINTER, + ARG_TYPE_BIG_ARG_PTR, + ARG_TYPE_OBJECT, + ARG_TYPE_OBJECT_META, + ARG_TYPE_OBJECT_NEW, + ARG_TYPE_METHOD_NATIVE, + ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR, + ARG_TYPE_METHOD_CONSTRUCTOR, + ARG_TYPE_METHOD_OBJECT, + ARG_TYPE_METHOD_STATIC, + ARG_TYPE_STRUCT, + ARG_TYPE_STRUCT_HEAP, + ARG_TYPE_TUPLE, +} ArgType; + +typedef void (*StructDeinitFun)(void* struct_); + +typedef struct Arg Arg; + +typedef union { + Arg* next; + uint8_t* buffer; +} _arg_union; + +struct Arg { + _arg_union _; + uint32_t size; +#if PIKA_ARG_CACHE_ENABLE + uint32_t heap_size; +#endif + ArgType type; + uint8_t flag; + Hash name_hash; + uint8_t content[]; +}; + +typedef struct ConstArg { + _arg_union _; + uint32_t size; +#if PIKA_ARG_CACHE_ENABLE + uint32_t heap_size; +#endif + ArgType type; + uint8_t flag; + Hash name_hash; +} ConstArg; + +uint32_t arg_totleSize(Arg* self); +uint32_t arg_getTotleSize(Arg* self); +void arg_freeContent(Arg* self); + +Arg* arg_setName(Arg* self, char* name); +Arg* arg_setNameHash(Arg* self, Hash nameHash); +Arg* arg_setContent(Arg* self, uint8_t* content, uint32_t size); +Arg* arg_newContent(uint32_t size); + +static inline void arg_setType(Arg* self, ArgType type) { + self->type = type; +} + +static inline Hash arg_getNameHash(Arg* self) { + return self->name_hash; +} + +static inline ArgType arg_getType(Arg* self) { + return (ArgType)self->type; +} + +uint32_t arg_getContentSize(Arg* self); +Hash hash_time33(char* str); + +Arg* arg_setInt(Arg* self, char* name, int64_t val); +Arg* arg_setFloat(Arg* self, char* name, pika_float val); +Arg* arg_setPtr(Arg* self, char* name, ArgType type, void* pointer); +Arg* arg_setStr(Arg* self, char* name, char* string); +Arg* arg_setNull(Arg* self); +Arg* arg_setBytes(Arg* self, char* name, uint8_t* src, size_t size); + +static inline Arg* arg_newInt(int64_t val) { + return arg_setInt(NULL, "", (val)); +} + +static inline Arg* arg_newFloat(pika_float val) { + return arg_setFloat(NULL, "", (val)); +} + +static inline Arg* arg_newPtr(ArgType type, void* pointer) { + return arg_setPtr(NULL, "", (type), (pointer)); +} + +static inline Arg* arg_newStr(char* string) { + return arg_setStr(NULL, "", (string)); +} + +static inline Arg* arg_newNull() { + return arg_setNull(NULL); +} + +static inline Arg* arg_newBytes(uint8_t* src, size_t size) { + return arg_setBytes(NULL, "", (src), (size)); +} + +int64_t arg_getInt(Arg* self); +pika_float arg_getFloat(Arg* self); +void* arg_getPtr(Arg* self); +char* arg_getStr(Arg* self); +uint8_t* arg_getBytes(Arg* self); +size_t arg_getBytesSize(Arg* self); +Arg* arg_copy(Arg* argToBeCopy); +Arg* arg_copy_noalloc(Arg* argToBeCopy, Arg* argToBeCopyTo); + +void arg_deinit(Arg* self); + +Arg* New_arg(void* voidPointer); +Arg* arg_append(Arg* arg_in, void* new_content, size_t new_size); +Arg* arg_setStruct(Arg* self, + char* name, + void* struct_ptr, + uint32_t struct_size); +Arg* arg_setHeapStruct(Arg* self, + char* name, + void* struct_ptr, + uint32_t struct_size, + void* struct_deinit_fun); +void* arg_getHeapStruct(Arg* self); +void arg_deinitHeap(Arg* self); +void arg_printBytes(Arg* self, char* end); +void arg_singlePrint(Arg* self, PIKA_BOOL in_REPL, char* end); +Arg* arg_loadFile(Arg* self, char* filename); + +#define ARG_FLAG_SERIALIZED 0x01 +#define ARG_FLAG_KEYWORD 0x02 +#define ARG_FLAG_WEAK_REF 0x04 +#define ARG_FLAG_STARRED 0x08 +#define ARG_FLAG_DOUBLE_STARRED 0x10 +#define ARG_FLAG_MAX 0x18 + +static inline Arg* arg_getNext(Arg* self) { + return self->_.next; +} + +static inline void arg_setNext(Arg* self, Arg* next) { + pika_assert(NULL != self); + self->_.next = next; +} + +static inline uint32_t arg_getSize(Arg* self) { + pika_assert(NULL != self); + return self->size; +} + +static inline uint8_t arg_isSerialized(Arg* self) { + pika_assert(NULL != self); + pika_assert(self->flag <= ARG_FLAG_MAX); + return self->flag & ARG_FLAG_SERIALIZED; +} + +static inline void arg_setSerialized(Arg* self, uint8_t serialized) { + self->flag = (self->flag & ~ARG_FLAG_SERIALIZED) | + (serialized ? ARG_FLAG_SERIALIZED : 0); +} + +static inline uint8_t arg_getIsKeyword(Arg* self) { + pika_assert(self->flag <= ARG_FLAG_MAX); + return self->flag & ARG_FLAG_KEYWORD; +} + +static inline void arg_setIsKeyword(Arg* self, uint8_t isKeyword) { + self->flag = + (self->flag & ~ARG_FLAG_KEYWORD) | (isKeyword ? ARG_FLAG_KEYWORD : 0); +} + +static inline uint8_t arg_getIsWeakRef(Arg* self) { + pika_assert(self->flag <= ARG_FLAG_MAX); + return self->flag & ARG_FLAG_WEAK_REF; +} + +static inline void arg_setIsWeakRef(Arg* self, uint8_t isWeakRef) { + pika_assert(NULL != self); + self->flag = + (self->flag & ~ARG_FLAG_WEAK_REF) | (isWeakRef ? ARG_FLAG_WEAK_REF : 0); +} + +static inline void arg_setIsStarred(Arg* self, uint8_t isStarred) { + self->flag = + (self->flag & ~ARG_FLAG_STARRED) | (isStarred ? ARG_FLAG_STARRED : 0); +} + +static inline uint8_t arg_getIsStarred(Arg* self) { + pika_assert(self->flag <= ARG_FLAG_MAX); + return self->flag & ARG_FLAG_STARRED; +} + +static inline void arg_setIsDoubleStarred(Arg* self, uint8_t isDoubleStarred) { + self->flag = (self->flag & ~ARG_FLAG_DOUBLE_STARRED) | + (isDoubleStarred ? ARG_FLAG_DOUBLE_STARRED : 0); +} + +static inline uint8_t arg_getIsDoubleStarred(Arg* self) { + pika_assert(self->flag <= ARG_FLAG_MAX); + return self->flag & ARG_FLAG_DOUBLE_STARRED; +} + +static inline uint8_t* arg_getContent(Arg* self) { + pika_assert(self->flag <= ARG_FLAG_MAX); + pika_assert(NULL != self); + return (arg_isSerialized(self)) ? (self)->content : ((self)->_.buffer); +} + +static inline uint8_t argType_isObject(ArgType type) { + return ((type) == ARG_TYPE_OBJECT || (type) == ARG_TYPE_OBJECT_NEW); +} + +static inline uint8_t argType_isCallable(ArgType type) { + return ((type) == ARG_TYPE_METHOD_CONSTRUCTOR || + (type) == ARG_TYPE_METHOD_OBJECT || + (type) == ARG_TYPE_METHOD_STATIC || + (type) == ARG_TYPE_METHOD_NATIVE || + (type) == ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR); +} + +static inline uint8_t argType_isNative(ArgType type) { + return ((type) == ARG_TYPE_METHOD_NATIVE || + (type) == ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR); +} + +#define arg_newReg(__name, __size) \ + Arg __name = {0}; \ + uint8_t __##__name##_buff[__size] = {0}; \ + arg_init_stack(&__name, __##__name##_buff, __size) + +void arg_init_stack(Arg* self, uint8_t* buffer, uint32_t size); +PIKA_BOOL arg_isEqual(Arg* self, Arg* other); +Hash hash_time33EndWith(char* str, char end); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/dataArgs.c b/examples/pikapython/pikapython/pikascript-core/dataArgs.c new file mode 100644 index 00000000..64585c41 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataArgs.c @@ -0,0 +1,729 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "dataArgs.h" +#include "PikaObj.h" +#include "PikaPlatform.h" +#include "dataLink.h" +#include "dataMemory.h" +#include "dataString.h" +#include "dataStrs.h" + +void args_deinit(Args* self) { + pika_assert(self != NULL); + link_deinit(self); +} + +void args_deinit_stack(Args* self) { + link_deinit_stack(self); +} + +PIKA_RES args_setFloat(Args* self, char* name, pika_float argFloat) { + Arg* argNew = New_arg(NULL); + argNew = arg_setFloat(argNew, name, argFloat); + args_setArg(self, argNew); + return PIKA_RES_OK; +} + +void* args_getPtr(Args* self, char* name) { + void* pointer = NULL; + Arg* arg = args_getArg(self, name); + if (NULL == arg) { + return NULL; + } + + pointer = arg_getPtr(arg); + return pointer; +} + +PIKA_RES args_setPtrWithType(Args* self, char* name, ArgType type, void* val) { + Arg* arg = args_getArg(self, name); + if (NULL == arg) { + args_pushArg_name(self, name, arg_newPtr(type, val)); + return PIKA_RES_OK; + } + void** val_ptr = (void**)arg_getContent(arg); + *val_ptr = val; + arg_setType(arg, type); + return PIKA_RES_OK; +} + +PIKA_RES args_setPtr(Args* self, char* name, void* argPointer) { + return args_setPtrWithType(self, name, ARG_TYPE_POINTER, argPointer); +} + +PIKA_RES args_setRef(Args* self, char* name, void* argPointer) { + PIKA_RES errCode = PIKA_RES_OK; + Arg* argNew = New_arg(NULL); + argNew = arg_setRef(argNew, name, argPointer); + args_setArg(self, argNew); + return errCode; +} + +PIKA_RES args_setStr(Args* self, char* name, char* strIn) { + PIKA_RES errCode = PIKA_RES_OK; + Arg* argNew = New_arg(NULL); + argNew = arg_setStr(argNew, name, strIn); + if (NULL == argNew) { + return PIKA_RES_ERR_INVALID_PTR; + } + args_setArg(self, argNew); + return errCode; +} + +PIKA_RES args_setNone(Args* self, char* name) { + PIKA_RES errCode = PIKA_RES_OK; + Arg* argNew = arg_newNull(); + arg_setName(argNew, name); + args_setArg(self, argNew); + return errCode; +} + +PIKA_RES args_pushArg(Args* self, Arg* arg) { + Arg* new_arg = NULL; + if (!arg_isSerialized(arg)) { + new_arg = arg_copy(arg); + arg_deinit(arg); + } else { + new_arg = arg; + } + link_addNode(self, new_arg); + return PIKA_RES_OK; +} + +PIKA_RES args_pushArg_name(Args* self, char* name, Arg* arg) { + return args_pushArg(self, arg_setName(arg, name)); +} + +PIKA_RES args_setBytes(Args* self, char* name, uint8_t* src, size_t size) { + Arg* argNew = arg_setBytes(NULL, name, src, size); + args_setArg(self, argNew); + return PIKA_RES_OK; +} + +char* args_getBuff(Args* self, int32_t size) { + Arg* argNew = New_arg(NULL); + argNew = arg_newContent(size + 1); + args_pushArg(self, argNew); + return (char*)arg_getContent(argNew); +} + +char* args_getStr(Args* self, char* name) { + if (NULL == self) { + return NULL; + } + Arg* arg = args_getArg(self, name); + if (NULL == arg) { + return NULL; + } + if (NULL == arg_getContent(arg)) { + return NULL; + } + return (char*)arg_getContent(arg); +} + +uint8_t* args_getBytes(Args* self, char* name) { + if (NULL == self) { + return NULL; + } + Arg* arg = args_getArg(self, name); + if (NULL == arg) { + return NULL; + } + if (NULL == arg_getContent(arg)) { + return NULL; + } + return arg_getBytes(arg); +} + +size_t args_getBytesSize(Args* self, char* name) { + if (NULL == self) { + return 0; + } + Arg* arg = args_getArg(self, name); + if (NULL == arg) { + return 0; + } + if (NULL == arg_getContent(arg)) { + return 0; + } + return arg_getBytesSize(arg); +} + +PIKA_RES args_setInt(Args* self, char* name, int64_t val) { + Arg* arg = args_getArg(self, name); + if (NULL == arg || arg_getType(arg) != ARG_TYPE_INT) { + args_pushArg_name(self, name, arg_newInt(val)); + return PIKA_RES_OK; + } + int64_t* val_ptr = (int64_t*)arg_getContent(arg); + *val_ptr = val; + return PIKA_RES_OK; +} + +int64_t args_getInt(Args* self, char* name) { + Arg* arg = args_getArg(self, name); + if (NULL == arg) { + return -999999999; + } + ArgType arg_type = arg_getType(arg); + if (arg_type == ARG_TYPE_INT) { + return arg_getInt(arg); + } else if (arg_type == ARG_TYPE_FLOAT) { + return (int)arg_getFloat(arg); + } + return -999999999; +} + +int32_t args_getSize(Args* self) { + return link_getSize(self); +} + +ArgType args_getType(Args* self, char* name) { + Arg* arg = NULL; + arg = args_getArg(self, name); + if (NULL == arg) { + return ARG_TYPE_NONE; + } + return arg_getType(arg); +} + +pika_float args_getFloat(Args* self, char* name) { + Arg* arg = args_getArg(self, name); + if (NULL == arg) { + return -999999999.0; + } + ArgType arg_type = arg_getType(arg); + if (arg_type == ARG_TYPE_FLOAT) { + return arg_getFloat(arg); + } else if (arg_type == ARG_TYPE_INT) { + return (pika_float)arg_getInt(arg); + } + return -999999999.0; +} + +PIKA_RES args_copyArg(Args* self, Arg* argToBeCopy) { + if (NULL == argToBeCopy) { + return PIKA_RES_ERR_INVALID_PTR; + } + Arg* argCopied = arg_copy(argToBeCopy); + args_setArg(self, argCopied); + + return PIKA_RES_OK; +} + +PIKA_RES args_setStructWithSize(Args* self, + char* name, + void* struct_ptr, + uint32_t struct_size) { + Arg* struct_arg = arg_setStruct(NULL, name, struct_ptr, struct_size); + if (NULL == struct_arg) { + /* failed */ + return PIKA_RES_ERR_ARG_NO_FOUND; + } + args_setArg(self, struct_arg); + return PIKA_RES_OK; +} + +void* args_getStruct(Args* self, char* name) { + Arg* struct_arg = args_getArg(self, name); + if (NULL == struct_arg) { + return NULL; + } + return arg_getContent(struct_arg); +} + +void* args_getHeapStruct(Args* self, char* name) { + Arg* struct_arg = args_getArg(self, name); + return arg_getHeapStruct(struct_arg); +} + +PIKA_RES args_setHeapStructWithSize(Args* self, + char* name, + void* struct_ptr, + uint32_t struct_size, + void* struct_deinit_fun) { + Arg* struct_arg = arg_setHeapStruct(NULL, name, struct_ptr, struct_size, + struct_deinit_fun); + if (NULL == struct_arg) { + /* failed */ + return PIKA_RES_ERR_ARG_NO_FOUND; + } + args_setArg(self, struct_arg); + return PIKA_RES_OK; +} + +PIKA_RES args_copyArgByName(Args* self, char* name, Args* directArgs) { + Arg* argToBeCopy = args_getArg(self, name); + args_copyArg(directArgs, argToBeCopy); + return PIKA_RES_OK; +} + +int32_t args_isArgExist_hash(Args* self, Hash nameHash) { + if (NULL != args_getArg_hash(self, nameHash)) { + return 1; + } + return 0; +} + +int32_t args_isArgExist(Args* self, char* name) { + if (NULL != args_getArg(self, name)) { + return 1; + } + return 0; +} + +PIKA_RES __updateArg(Args* self, Arg* argNew) { + LinkNode* nodeToUpdate = NULL; + LinkNode* nodeNow = self->firstNode; + LinkNode* priorNode = NULL; + PIKA_RES res; + if (NULL == self->firstNode) { + return PIKA_RES_ERR_ARG_NO_FOUND; + } + Hash nameHash = arg_getNameHash(argNew); + while (1) { + if (arg_getNameHash((Arg*)nodeNow) == nameHash) { + nodeToUpdate = nodeNow; + break; + } + if (arg_getNext((Arg*)nodeNow) == NULL) { + // error, node no found + return PIKA_RES_ERR_ARG_NO_FOUND; + } + priorNode = nodeNow; + nodeNow = (LinkNode*)arg_getNext((Arg*)nodeNow); + } + + arg_deinitHeap((Arg*)nodeToUpdate); + + nodeToUpdate = (LinkNode*)arg_setContent( + (Arg*)nodeToUpdate, arg_getContent(argNew), arg_getSize(argNew)); + + pika_assert(NULL != nodeToUpdate); + arg_setType((Arg*)nodeToUpdate, arg_getType(argNew)); + // update privior link, because arg_getContent would free origin pointer + if (NULL == priorNode) { + self->firstNode = nodeToUpdate; + res = PIKA_RES_OK; + goto exit; + } + + arg_setNext((Arg*)priorNode, (Arg*)nodeToUpdate); + res = PIKA_RES_OK; + goto exit; +exit: + if (!arg_isSerialized(argNew)) { + return res; + } + arg_freeContent(argNew); + return res; +} + +PIKA_RES args_setArg(Args* self, Arg* arg) { + if (PIKA_RES_OK == __updateArg(self, arg)) { + return PIKA_RES_OK; + } + args_pushArg(self, arg); + return PIKA_RES_OK; +} + +#ifndef __PIKA_CFG_HASH_LIST_CACHE_SIZE +#define __PIKA_CFG_HASH_LIST_CACHE_SIZE 4 +#endif + +#define __USE_PIKA_HASH_LIST_CACHE 0 + +LinkNode* args_getNode_hash(Args* self, Hash nameHash) { + LinkNode* node = self->firstNode; +#if __USE_PIKA_HASH_LIST_CACHE + int_fast8_t n = 0; +#endif + while (NULL != node) { + Arg* arg = (Arg*)node; + Hash thisNameHash = arg_getNameHash(arg); +#if __USE_PIKA_HASH_LIST_CACHE + n++; +#endif + if (thisNameHash == nameHash) { +#if __USE_PIKA_HASH_LIST_CACHE + if (n > __PIKA_CFG_HASH_LIST_CACHE_SIZE) { + /* the first __PIKA_CFG_HASH_LIST_CACHE_SIZE items in the list + * is considered as a cache. + * Don't make __PIKA_CFG_HASH_LIST_CACHE_SIZE too big, otherwise + * this optimisation is useless. + */ + + /*! remove current node from the list */ + node = (LinkNode*)arg_getNext((Arg*)arg); + + /*! move the node to the cache */ + arg_setNext(arg, (Arg*)(self->firstNode)); + self->firstNode = (LinkNode*)arg; + } +#endif + return (LinkNode*)arg; + } + node = (LinkNode*)arg_getNext((Arg*)node); + } + return NULL; +} + +LinkNode* args_getNode(Args* self, char* name) { + return args_getNode_hash(self, hash_time33(name)); +} + +Arg* args_getArg_hash(Args* self, Hash nameHash) { + LinkNode* node = args_getNode_hash(self, nameHash); + if (NULL == node) { + return NULL; + } + return (Arg*)node; +} + +Arg* args_getArg(Args* self, char* name) { + pika_assert(NULL != self); + LinkNode* node = args_getNode(self, name); + return (Arg*)node; +} + +Arg* args_getArgByIndex(Args* self, int index) { + pika_assert(NULL != self); + LinkNode* nodeNow = self->firstNode; + if (NULL == nodeNow) { + return NULL; + } + for (int i = 0; i < index; i++) { + nodeNow = (LinkNode*)arg_getNext((Arg*)nodeNow); + } + return (Arg*)nodeNow; +} + +PIKA_RES args_foreach(Args* self, + int32_t (*eachHandle)(Arg* argEach, Args* context), + Args* context) { + if (NULL == self->firstNode) { + return PIKA_RES_OK; + } + LinkNode* nodeNow = self->firstNode; + while (1) { + Arg* argNow = (Arg*)nodeNow; + if (NULL == argNow) { + continue; + } + LinkNode* nextNode = (LinkNode*)arg_getNext((Arg*)nodeNow); + eachHandle(argNow, context); + + if (NULL == nextNode) { + break; + } + nodeNow = nextNode; + } + return PIKA_RES_OK; +} + +PIKA_RES args_removeArg(Args* self, Arg* argNow) { + if (NULL == argNow) { + return PIKA_RES_ERR_INVALID_PTR; + } + link_removeNode(self, argNow); + return PIKA_RES_OK; +} + +PIKA_RES args_removeArg_notDeinitArg(Args* self, Arg* argNow) { + if (NULL == argNow) { + return PIKA_RES_ERR_INVALID_PTR; + } + link_removeNode_notDeinitNode(self, argNow); + return PIKA_RES_OK; +} + +PIKA_RES args_moveArg(Args* self, Args* dict, Arg* argNow) { + if (NULL == argNow) { + return PIKA_RES_ERR_INVALID_PTR; + } + link_removeNode_notDeinitNode(self, argNow); + args_pushArg(dict, argNow); + return PIKA_RES_OK; +} + +Args* New_args(Args* args) { + Args* self = New_link(NULL); + return self; +} + +PikaDict* New_pikaDict(void) { + PikaDict* self = (PikaDict*)New_args(NULL); + return self; +} + +PikaList* New_pikaList(void) { + PikaList* self = (PikaList*)New_args(NULL); + /* set top index for append */ + args_pushArg_name(&self->super, "top", arg_newInt(0)); + return self; +} + +PIKA_RES pikaList_setArg(PikaList* self, int index, Arg* arg) { + char buff[11]; + char* i_str = fast_itoa(buff, index); + int top = args_getInt(&self->super, "top"); + if (index > top) { + return PIKA_RES_ERR_OUT_OF_RANGE; + } + Arg* new_arg = arg_copy(arg); + new_arg = arg_setName(new_arg, i_str); + args_setArg(&self->super, new_arg); + return PIKA_RES_OK; +} + +Arg* pikaList_getArg(PikaList* self, int index) { + pika_assert(NULL != self); + char buff[11]; + char* i_str = fast_itoa(buff, index); + return args_getArg(&self->super, i_str); +} + +int pikaList_getInt(PikaList* self, int index) { + Arg* arg = pikaList_getArg(self, index); + return arg_getInt(arg); +} + +pika_float pikaList_getFloat(PikaList* self, int index) { + Arg* arg = pikaList_getArg(self, index); + return arg_getFloat(arg); +} + +char* pikaList_getStr(PikaList* self, int index) { + Arg* arg = pikaList_getArg(self, index); + return arg_getStr(arg); +} + +void* pikaList_getPtr(PikaList* self, int index) { + Arg* arg = pikaList_getArg(self, index); + return arg_getPtr(arg); +} + +PIKA_RES pikaList_append(PikaList* self, Arg* arg) { + if (NULL == arg) { + return PIKA_RES_ERR_ARG_NO_FOUND; + } + int top = args_getInt(&self->super, "top"); + char buff[11]; + char* topStr = fast_itoa(buff, top); + Arg* arg_to_push = arg_copy(arg); + arg_setName(arg_to_push, topStr); + args_setArg(&self->super, arg_to_push); + /* top++ */ + return args_setInt(&self->super, "top", top + 1); +} + +Arg* pikaList_pop(PikaList* list) { + int top = args_getInt(&list->super, "top"); + if (top <= 0) { + return NULL; + } + Arg* arg = pikaList_getArg(list, top - 1); + Arg* res = arg_copy(arg); + args_removeArg(&list->super, arg); + args_setInt(&list->super, "top", top - 1); + return res; +} + +PIKA_RES pikaList_remove(PikaList* list, Arg* arg) { + int top = args_getInt(&list->super, "top"); + int i_remove = 0; + if (top <= 0) { + return PIKA_RES_ERR_OUT_OF_RANGE; + } + for (int i = 0; i < top; i++) { + Arg* arg_now = pikaList_getArg(list, i); + if (arg_isEqual(arg_now, arg)) { + i_remove = i; + args_removeArg(&list->super, arg_now); + break; + } + } + /* move args */ + for (int i = i_remove + 1; i < top; i++) { + char buff[11]; + char* i_str = fast_itoa(buff, i - 1); + Arg* arg_now = pikaList_getArg(list, i); + arg_setName(arg_now, i_str); + } + args_setInt(&list->super, "top", top - 1); + return PIKA_RES_OK; +} + +PIKA_RES pikaList_insert(PikaList* self, int index, Arg* arg) { + int top = args_getInt(&self->super, "top"); + if (index > top) { + return PIKA_RES_ERR_OUT_OF_RANGE; + } + /* move args */ + for (int i = top - 1; i >= index; i--) { + char buff[11]; + char* i_str = fast_itoa(buff, i + 1); + Arg* arg_now = pikaList_getArg(self, i); + arg_setName(arg_now, i_str); + } + char buff[11]; + char* i_str = fast_itoa(buff, index); + Arg* arg_to_push = arg_copy(arg); + arg_setName(arg_to_push, i_str); + args_setArg(&self->super, arg_to_push); + args_setInt(&self->super, "top", top + 1); + return PIKA_RES_OK; +} + +size_t pikaList_getSize(PikaList* self) { + pika_assert(NULL != self); + return args_getInt(&self->super, "top"); +} + +void pikaList_reverse(PikaList* self) { + pika_assert(NULL != self); + int top = pikaList_getSize(self); + for (int i = 0; i < top / 2; i++) { + Arg* arg_i = arg_copy(pikaList_getArg(self, i)); + Arg* arg_top = arg_copy(pikaList_getArg(self, top - i - 1)); + pikaList_setArg(self, i, arg_top); + pikaList_setArg(self, top - i - 1, arg_i); + arg_deinit(arg_i); + arg_deinit(arg_top); + } +} + +PikaTuple* New_pikaTuple(void) { + PikaTuple* self = (PikaTuple*)New_pikaList(); + return self; +} + +char* strsFormatArg(Args* out_buffs, char* fmt, Arg* arg) { + Args buffs = {0}; + char* res = NULL; + ArgType type = arg_getType(arg); + const char* syms[] = {"%s", "%r"}; + for (size_t i = 0; i < sizeof(syms) / sizeof(char*); i++) { + char* sym = (char*)syms[i]; + if (strstr(fmt, sym)) { + if (type == ARG_TYPE_STRING) { + fmt = strsReplace(&buffs, fmt, sym, "%s"); + break; + } + if (type == ARG_TYPE_INT) { + fmt = strsReplace(&buffs, fmt, sym, "%d"); + break; + } + if (type == ARG_TYPE_FLOAT) { + fmt = strsReplace(&buffs, fmt, sym, "%f"); + break; + } + if (type == ARG_TYPE_POINTER) { + fmt = strsReplace(&buffs, fmt, sym, "%p"); + break; + } + } + } + if (ARG_TYPE_INT == type) { + int val = arg_getInt(arg); + res = strsFormat(&buffs, PIKA_SPRINTF_BUFF_SIZE, fmt, val); + goto exit; + } + if (ARG_TYPE_FLOAT == type) { + pika_float val = arg_getFloat(arg); + res = strsFormat(&buffs, PIKA_SPRINTF_BUFF_SIZE, fmt, val); + goto exit; + } + if (ARG_TYPE_STRING == type) { + char* val = arg_getStr(arg); + res = strsFormat(&buffs, PIKA_SPRINTF_BUFF_SIZE, fmt, val); + goto exit; + } + if (ARG_TYPE_NONE == type) { + res = strsFormat(&buffs, PIKA_SPRINTF_BUFF_SIZE, fmt, "None"); + goto exit; + } +exit: + if (NULL != res) { + res = strsCopy(out_buffs, res); + } + strsDeinit(&buffs); + return res; +} + +char* strsFormatList(Args* out_buffs, char* fmt, PikaList* list) { + Args buffs = {0}; + char* res = NULL; + char* fmt_buff = strsCopy(&buffs, fmt); + char* fmt_item = strsPopToken(&buffs, &fmt_buff, '%'); + Arg* res_buff = arg_newStr(fmt_item); + + for (size_t i = 0; i < pikaList_getSize(list); i++) { + Args buffs_item = {0}; + Arg* arg = pikaList_getArg(list, i); + char* fmt_item = strsPopToken(&buffs_item, &fmt_buff, '%'); + fmt_item = strsAppend(&buffs_item, "%", fmt_item); + char* str_format = strsFormatArg(&buffs_item, fmt_item, arg); + if (NULL == str_format) { + strsDeinit(&buffs_item); + goto exit; + } + res_buff = arg_strAppend(res_buff, str_format); + strsDeinit(&buffs_item); + } + goto exit; + +exit: + res = strsCopy(out_buffs, arg_getStr(res_buff)); + strsDeinit(&buffs); + arg_deinit(res_buff); + return res; +} + +/* tuple */ +PikaTuple* args_getTuple(Args* self, char* name) { + if (NULL == self) { + return NULL; + } + PikaObj* tuple_obj = args_getPtr(self, name); + return obj_getPtr(tuple_obj, "list"); +} + +/* dict */ +PikaDict* args_getDict(Args* self, char* name) { + if (NULL == self) { + return NULL; + } + PikaObj* tuple_obj = args_getPtr(self, name); + return obj_getPtr(tuple_obj, "dict"); +} + +char* args_cacheStr(Args* self, char* str) { + args_setStr(self, "@sc", str); + return args_getStr(self, "@sc"); +} diff --git a/examples/pikapython/pikapython/pikascript-core/dataArgs.h b/examples/pikapython/pikapython/pikascript-core/dataArgs.h new file mode 100644 index 00000000..7239f955 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataArgs.h @@ -0,0 +1,277 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _dataArgs__H +#define _dataArgs__H +#include "dataArg.h" +#include "dataLink.h" +#include "dataMemory.h" +#include "dataString.h" + +typedef Link Args; + +/* operation */ +void args_deinit(Args* self); +void args_deinit_stack(Args* self); +void args_init(Args* self, Args* args); +int32_t args_getSize(Args* self); +LinkNode* args_getNode(Args* self, char* name); + +Arg* args_getArgByIndex(Args* self, int index); +Arg* args_getArg(Args* self, char* name); +PIKA_RES args_removeArg(Args* self, Arg* argNow); +PIKA_RES args_moveArg(Args* self, Args* dict, Arg* arg); +Arg* args_getArg_hash(Args* self, Hash nameHash); + +PIKA_RES args_setArg(Args* self, Arg* arg); + +PIKA_RES args_copyArgByName(Args* self, char* name, Args* directList); +PIKA_RES args_copyArg(Args* self, Arg* argToBeCopy); + +ArgType args_getType(Args* self, char* name); +int32_t args_isArgExist_hash(Args* self, Hash nameHash); +int32_t args_isArgExist(Args* self, char* name); + +PIKA_RES args_setStr(Args* self, char* name, char* strIn); +PIKA_RES args_setNone(Args* self, char* name); +PIKA_RES args_setStrWithDefaultName(Args* self, char* strIn); +char* args_getStr(Args* self, char* name); + +PIKA_RES args_setFloatWithDefaultName(Args* self, pika_float argFloat); +PIKA_RES args_setFloat(Args* self, char* name, pika_float argFloat); +pika_float args_getFloat(Args* self, char* name); + +PIKA_RES args_setRef(Args* self, char* name, void* argPointer); +PIKA_RES args_setPtr(Args* self, char* name, void* argPointer); +void* args_getPtr(Args* self, char* name); + +PIKA_RES args_setInt(Args* self, char* name, int64_t int64In); +int64_t args_getInt(Args* self, char* name); + +char* args_print(Args* self, char* name); + +PIKA_RES args_setStructWithSize(Args* self, + char* name, + void* struct_ptr, + uint32_t struct_size); + +PIKA_RES args_setHeapStructWithSize(Args* self, + char* name, + void* struct_ptr, + uint32_t struct_size, + void* struct_deinit_fun); + +#define args_setStruct(Args_p_self, char_p_name, struct_) \ + args_setStructWithSize((Args_p_self), (char_p_name), &(struct_), \ + sizeof(struct_)) + +#define args_setHeapStruct(Args_p_self, char_p_name, struct_, \ + struct_deinit_fun) \ + args_setHeapStructWithSize((Args_p_self), (char_p_name), &(struct_), \ + sizeof(struct_), (void*)struct_deinit_fun) + +void* args_getStruct(Args* self, char* name); + +PIKA_RES args_set(Args* self, char* name, char* valueStr); +PIKA_RES args_setObjectWithClass(Args* self, + char* objectName, + char* className, + void* objectPtr); +PIKA_RES args_setPtrWithType(Args* self, + char* name, + ArgType type, + void* objPtr); +PIKA_RES args_foreach(Args* self, + int32_t (*eachHandle)(Arg* argEach, Args* context), + Args* context); + +char* args_getBuff(Args* self, int32_t size); +PIKA_RES args_pushArg(Args* self, Arg* arg); +PIKA_RES args_pushArg_name(Args* self, char* name, Arg* arg); +void* args_getHeapStruct(Args* self, char* name); +PIKA_RES args_removeArg_notDeinitArg(Args* self, Arg* argNow); +uint8_t* args_getBytes(Args* self, char* name); +PIKA_RES args_setBytes(Args* self, char* name, uint8_t* src, size_t size); +size_t args_getBytesSize(Args* self, char* name); + +Args* New_args(Args* args); + +typedef struct PikaList PikaList; +struct PikaList { + Args super; +}; + +typedef struct PikaTuple PikaTuple; +struct PikaTuple { + PikaList super; +}; + +typedef struct PikaDict PikaDict; +struct PikaDict { + Args super; +}; + +/* dict api */ +PikaDict* New_pikaDict(void); + +static inline PIKA_RES pikaDict_setInt(PikaDict* self, + char* name, + int64_t val) { + return args_setInt((&((self)->super)), (name), (val)); +} +static inline PIKA_RES pikaDict_setFloat(PikaDict* self, + char* name, + pika_float val) { + return args_setFloat((&((self)->super)), (name), (val)); +} +static inline PIKA_RES pikaDict_setStr(PikaDict* self, char* name, char* val) { + return args_setStr((&((self)->super)), (name), (val)); +} +static inline PIKA_RES pikaDict_setPtr(PikaDict* self, char* name, void* val) { + return args_setPtr((&((self)->super)), (name), (val)); +} + +static inline PIKA_RES pikaDict_setArg(PikaDict* self, Arg* val) { + return args_setArg((&((self)->super)), (val)); +} + +static inline PIKA_RES pikaDict_removeArg(PikaDict* self, Arg* val) { + return args_removeArg((&((self)->super)), (val)); +} + +static inline PIKA_RES pikaDict_setBytes(PikaDict* self, + char* name, + uint8_t* val, + size_t size) { + return args_setBytes((&((self)->super)), (name), (val), (size)); +} + +static inline int64_t pikaDict_getInt(PikaDict* self, char* name) { + return args_getInt((&((self)->super)), (name)); +} + +static inline pika_float pikaDict_getFloat(PikaDict* self, char* name) { + return args_getFloat((&((self)->super)), (name)); +} + +static inline char* pikaDict_getStr(PikaDict* self, char* name) { + return args_getStr((&((self)->super)), (name)); +} + +static inline void* pikaDict_getPtr(PikaDict* self, char* name) { + return args_getPtr((&((self)->super)), (name)); +} + +static inline Arg* pikaDict_getArg(PikaDict* self, char* name) { + return args_getArg((&((self)->super)), (name)); +} + +static inline int32_t pikaDict_isArgExist(PikaDict* self, char* name) { + return args_isArgExist((&((self)->super)), (name)); +} + +static inline uint8_t* pikaDict_getBytes(PikaDict* self, char* name) { + return args_getBytes((&((self)->super)), (name)); +} + +static inline ArgType pikaDict_getType(PikaDict* self, char* name) { + return args_getType((&((self)->super)), (name)); +} + +static inline size_t pikaDict_getBytesSize(PikaDict* self, char* name) { + return args_getBytesSize((&((self)->super)), (name)); +} + +static inline void pikaDict_deinit(PikaDict* self) { + args_deinit((&((self)->super))); +} + +/* list api */ +PIKA_RES pikaList_append(PikaList* self, Arg* arg); +PIKA_RES pikaList_setArg(PikaList* self, int index, Arg* arg); +int pikaList_getInt(PikaList* self, int index); +pika_float pikaList_getFloat(PikaList* self, int index); +char* pikaList_getStr(PikaList* self, int index); +void* pikaList_getPtr(PikaList* self, int index); +Arg* pikaList_getArg(PikaList* self, int index); +size_t pikaList_getSize(PikaList* self); +void pikaList_reverse(PikaList* self); +PIKA_RES pikaList_insert(PikaList* self, int index, Arg* arg); +Arg* pikaList_pop(PikaList* list); +PIKA_RES pikaList_remove(PikaList* list, Arg* arg); +static inline void pikaList_deinit(PikaList* self) { + args_deinit((&((self)->super))); +} + +static inline ArgType pikaList_getType(PikaList* self, int index) { + Arg* arg = pikaList_getArg(self, index); + return arg_getType(arg); +} + +/* tuple api */ +static inline void pikaTuple_deinit(PikaTuple* self) { + pikaList_deinit((&((self)->super))); +} + +static inline Arg* pikaTuple_getArg(PikaTuple* self, int index) { + return pikaList_getArg((&((self)->super)), (index)); +} + +static inline size_t pikaTuple_getSize(PikaTuple* self) { + return pikaList_getSize((&((self)->super))); +} + +static inline int64_t pikaTuple_getInt(PikaTuple* self, int index) { + return pikaList_getInt((&((self)->super)), (index)); +} + +static inline pika_float pikaTuple_getFloat(PikaTuple* self, int index) { + return pikaList_getFloat((&((self)->super)), (index)); +} + +static inline char* pikaTuple_getStr(PikaTuple* self, int index) { + return pikaList_getStr((&((self)->super)), (index)); +} + +static inline void* pikaTuple_getPtr(PikaTuple* self, int index) { + return pikaList_getPtr((&((self)->super)), (index)); +} + +static inline ArgType pikaTuple_getType(PikaTuple* self, int index) { + return pikaList_getType((&((self)->super)), (index)); +} + +PikaList* New_pikaList(void); +PikaTuple* New_pikaTuple(void); +PikaTuple* args_getTuple(Args* self, char* name); +PikaDict* args_getDict(Args* self, char* name); + +char* strsFormatList(Args* out_buffs, char* fmt, PikaList* list); +char* args_cacheStr(Args* self, char* str); +char* strsFormatArg(Args* out_buffs, char* fmt, Arg* arg); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/dataLink.c b/examples/pikapython/pikapython/pikascript-core/dataLink.c new file mode 100644 index 00000000..52e9d3e9 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataLink.c @@ -0,0 +1,128 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "dataLink.h" +#include "dataArg.h" +#include "dataLinkNode.h" +#include "dataMemory.h" + +void __link_deinit_pyload(Link* self) { + LinkNode* nowNode = self->firstNode; + while (NULL != nowNode) { + LinkNode* nodeNext = (LinkNode*)arg_getNext((Arg*)nowNode); + linkNode_deinit(nowNode); + nowNode = nodeNext; + } + self = NULL; +} + +void link_deinit(Link* self) { + pika_assert(self != NULL); + __link_deinit_pyload(self); + pikaFree(self, sizeof(Link)); +} + +void link_deinit_stack(Link* self) { + __link_deinit_pyload(self); +} + +void link_addNode(Link* self, void* content) { + // old first node become new second node + LinkNode* secondNode = self->firstNode; + + self->firstNode = content; + // change the first node to new node + arg_setNext((Arg*)content, (Arg*)secondNode); +} + +static void __link_removeNode(Link* self, + void* content, + uint8_t is_deinit_node) { + LinkNode* nodeToDelete = NULL; + LinkNode* nodeNow = self->firstNode; + LinkNode* priorNode = NULL; + LinkNode* nextNode; + while (1) { + if (nodeNow == content) { + nodeToDelete = nodeNow; + break; + } + if (nodeNow == NULL) { + // error, node no found + goto exit; + } + priorNode = nodeNow; + nodeNow = (LinkNode*)arg_getNext((Arg*)nodeNow); + } + + nextNode = (LinkNode*)arg_getNext((Arg*)nodeToDelete); + if (nodeToDelete == self->firstNode) { + self->firstNode = (LinkNode*)arg_getNext((Arg*)nodeToDelete); + } + if (NULL == priorNode) { + self->firstNode = nextNode; + goto exit; + } + arg_setNext((Arg*)priorNode, (Arg*)nextNode); + goto exit; + +// deinit the node +exit: + if (is_deinit_node) { + linkNode_deinit(nodeToDelete); + } + return; +} + +void link_removeNode(Link* self, void* content) { + __link_removeNode(self, content, 1); +} + +void link_removeNode_notDeinitNode(Link* self, void* content) { + __link_removeNode(self, content, 0); +} + +int32_t link_getSize(Link* self) { + LinkNode* NowNode; + int32_t size = 0; + NowNode = self->firstNode; + while (NULL != NowNode) { + size++; + NowNode = (LinkNode*)arg_getNext((Arg*)NowNode); + } + return size; +} + +void link_init(Link* self, void* args) { + self->firstNode = NULL; +} + +Link* New_link(void* args) { + Link* self = pikaMalloc(sizeof(Link)); + link_init(self, args); + return self; +} diff --git a/examples/pikapython/pikapython/pikascript-core/dataLink.h b/examples/pikapython/pikapython/pikascript-core/dataLink.h new file mode 100644 index 00000000..1f1ede39 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataLink.h @@ -0,0 +1,52 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _link2__H +#define _link2__H +#include "dataLinkNode.h" +#include "dataMemory.h" + +enum LINK_IS_DEINIT_SELF { + LINK_IS_DEINIT_SELF_ENABLE, + LINK_IS_DEINIT_SELF_DISABLE, +}; + +typedef struct Link Link; +struct Link{ + LinkNode* firstNode; +}; + +void link_deinit(Link* self); +void link_deinit_stack(Link* self); +void link_init(Link* self, void* args); +void link_addNode(Link* self, void* content); +void link_removeNode(Link* self, void* content); +void link_removeNode_notDeinitNode(Link* self, void* content); +LinkNode* link_getNode(Link* self, int64_t id); +int32_t link_getSize(Link* self); +Link* New_link(void* args); +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/dataLinkNode.c b/examples/pikapython/pikapython/pikascript-core/dataLinkNode.c new file mode 100644 index 00000000..b6f0c4d5 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataLinkNode.c @@ -0,0 +1,34 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "dataLinkNode.h" +#include "dataArg.h" +#include "dataMemory.h" + +void linkNode_deinit(LinkNode* self) { + arg_deinit((Arg*)self); +} diff --git a/examples/pikapython/pikapython/pikascript-core/dataLinkNode.h b/examples/pikapython/pikapython/pikascript-core/dataLinkNode.h new file mode 100644 index 00000000..63b648f3 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataLinkNode.h @@ -0,0 +1,42 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _linkNode__H +#define _linkNode__H + +#include "dataMemory.h" + +typedef struct LinkNode LinkNode; +struct LinkNode { + void* __rsvd; +}; + +void linkNode_deinit(LinkNode* self); +void linkNode_init(LinkNode* self, void* args); + +LinkNode* New_linkNode(void* args); +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/dataMemory.c b/examples/pikapython/pikapython/pikascript-core/dataMemory.c new file mode 100644 index 00000000..c4af0750 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataMemory.c @@ -0,0 +1,322 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define __DATA_MEMORY_CLASS_IMPLEMENT__ +#include "dataMemory.h" +#include "PikaPlatform.h" + +volatile PikaMemInfo pikaMemInfo = {0}; + +void* pikaMalloc(uint32_t size) { + /* pika memory lock */ + if (0 != pika_is_locked_pikaMemory()) { + pika_platform_wait(); + } + +//! if you unsure about the __impl_pikaMalloc, uncomment this to force alignment +#if PIKA_ARG_ALIGN_ENABLE + /* force alignment to avoid unaligned access */ + size = mem_align(size); +#endif + + pikaMemInfo.heapUsed += size; + if (pikaMemInfo.heapUsedMax < pikaMemInfo.heapUsed) { + pikaMemInfo.heapUsedMax = pikaMemInfo.heapUsed; + } + pika_platform_disable_irq_handle(); + void* mem = pika_user_malloc(size); + pika_platform_enable_irq_handle(); + if (NULL == mem) { + pika_platform_printf("Error: No heap space! Please reset the device.\r\n"); + while (1) { + } + } + return mem; +} + +void pikaFree(void* mem, uint32_t size) { + if (0 != pika_is_locked_pikaMemory()) { + pika_platform_wait(); + } + +//! if you unsure about the __impl_pikaMalloc, uncomment this to force alignment +#if PIKA_ARG_ALIGN_ENABLE + /* force alignment to avoid unaligned access */ + size = mem_align(size); +#endif + + pika_platform_disable_irq_handle(); + pika_user_free(mem, size); + pika_platform_enable_irq_handle(); + pikaMemInfo.heapUsed -= size; +} + +uint32_t pikaMemNow(void) { + return pikaMemInfo.heapUsed; + // return 0; +} + +uint32_t pikaMemMax(void) { + return pikaMemInfo.heapUsedMax; +} + +void pikaMemMaxReset(void) { + pikaMemInfo.heapUsedMax = 0; +} + +uint32_t pool_getBlockIndex_byMemSize(Pool* pool, uint32_t size) { + if (0 == size) { + return 0; + } + return (size - 1) / pool->aline + 1; +} + +uint32_t pool_aline(Pool* pool, uint32_t size) { + return pool_getBlockIndex_byMemSize(pool, size) * pool->aline; +} + +Pool pool_init(uint32_t size, uint8_t aline) { + Pool pool; + pool.aline = aline; + uint32_t block_size = pool_getBlockIndex_byMemSize(&pool, size); + pool.size = pool_aline(&pool, size); + pool.bitmap = bitmap_init(block_size); + pool.mem = pika_platform_malloc(pool_aline(&pool, pool.size)); + pool.first_free_block = 0; + pool.purl_free_block_start = 0; + pool.inited = PIKA_TRUE; + return pool; +} + +void pool_deinit(Pool* pool) { + pika_platform_free(pool->mem); + pool->mem = NULL; + bitmap_deinit(pool->bitmap); +} + +void* pool_getBytes_byBlockIndex(Pool* pool, uint32_t block_index) { + return pool->mem + block_index * pool->aline; +} + +uint32_t pool_getBlockIndex_byMem(Pool* pool, void* mem) { + uint32_t mem_size = (uintptr_t)mem - (uintptr_t)pool->mem; + return pool_getBlockIndex_byMemSize(pool, mem_size); +} + +void pool_printBlocks(Pool* pool, uint32_t size_min, uint32_t size_max) { + uint32_t block_index_min = pool_getBlockIndex_byMemSize(pool, size_min); + uint32_t block_index_max = pool_getBlockIndex_byMemSize(pool, size_max); + pika_platform_printf("[bitmap]\r\n"); + uint8_t is_end = 0; + for (uint32_t i = block_index_min; i < block_index_max; i += 16) { + if (is_end) { + break; + } + pika_platform_printf("0x%x\t: 0x%d", i * pool->aline, + (i + 15) * pool->aline); + for (uint32_t j = i; j < i + 16; j += 4) { + if (is_end) { + break; + } + for (uint32_t k = j; k < j + 4; k++) { + if (k >= block_index_max) { + is_end = 1; + break; + } + pika_platform_printf("%d", bitmap_get(pool->bitmap, k)); + } + pika_platform_printf(" "); + } + pika_platform_printf("\r\n"); + } +} + +void* pool_malloc(Pool* pool, uint32_t size) { + uint32_t block_index_max = pool_getBlockIndex_byMemSize(pool, pool->size); + uint32_t block_num_need = pool_getBlockIndex_byMemSize(pool, size); + uint32_t block_num_found = 0; + uint8_t found_first_free = 0; + uint32_t block_index; + /* high speed malloc */ + block_index = pool->purl_free_block_start + block_num_need - 1; + if (block_index < block_index_max) { + goto found; + } + /* low speed malloc */ + for (block_index = pool->first_free_block; + block_index < pool->purl_free_block_start; block_index++) { + /* 8 bit is not free */ + uint8_t bitmap_byte = bitmap_getByte(pool->bitmap, block_index); + if (0xFF == bitmap_byte) { + block_index = 8 * (block_index / 8) + 7; + block_num_found = 0; + continue; + } + /* found a free block */ + if (0 == bitmap_get(pool->bitmap, block_index)) { + /* save the first free */ + if (!found_first_free) { + pool->first_free_block = block_index; + found_first_free = 1; + } + block_num_found++; + } else { + /* a used block appeared, find again */ + block_num_found = 0; + } + /* found all request blocks */ + if (block_num_found >= block_num_need) { + goto found; + } + } + /* malloc for purl free blocks */ + block_index = pool->purl_free_block_start + block_num_need - 1; + if (block_index < block_index_max) { + goto found; + } + + /* no found */ + return NULL; +found: + /* set 1 for found blocks */ + for (uint32_t i = 0; i < block_num_need; i++) { + bitmap_set(pool->bitmap, block_index - i, 1); + } + /* save last used block */ + if (block_index >= pool->purl_free_block_start) { + pool->purl_free_block_start = block_index + 1; + } + /* return mem by block index */ + return pool_getBytes_byBlockIndex(pool, block_index - block_num_need + 1); +} + +void pool_free(Pool* pool, void* mem, uint32_t size) { + uint32_t block_num = pool_getBlockIndex_byMemSize(pool, size); + uint32_t block_index = pool_getBlockIndex_byMem(pool, mem); + for (uint32_t i = 0; i < block_num; i++) { + bitmap_set(pool->bitmap, block_index + i, 0); + } + /* save min free block index to add speed */ + if (block_index < pool->first_free_block) { + pool->first_free_block = block_index; + } + /* save last free block index to add speed */ + uint32_t block_end = block_index + block_num - 1; + if (block_end == pool->purl_free_block_start - 1) { + uint32_t first_pure_free_block = block_index; + /* back to first used block */ + if (0 != first_pure_free_block) { + while (0 == bitmap_get(pool->bitmap, first_pure_free_block - 1)) { + first_pure_free_block--; + if (0 == first_pure_free_block) { + break; + } + } + } + pool->purl_free_block_start = first_pure_free_block; + } + return; +} + +BitMap bitmap_init(uint32_t size) { + BitMap mem_bit_map = + (BitMap)pika_platform_malloc(((size - 1) / 8 + 1) * sizeof(char)); + if (mem_bit_map == NULL) { + return NULL; + } + uint32_t size_mem_bit_map = (size - 1) / 8 + 1; + pika_platform_memset(mem_bit_map, 0x0, size_mem_bit_map); + return mem_bit_map; +} + +void bitmap_set(BitMap bitmap, uint32_t index, uint8_t bit) { + uint32_t index_byte = index / 8; + uint8_t index_bit = index % 8; + uint8_t x = (0x1 << index_bit); + /* set 1 */ + if (bit) { + bitmap[index_byte] |= x; + return; + } + /* set 0 */ + bitmap[index_byte] &= ~x; + return; +} + +uint8_t bitmap_getByte(BitMap bitmap, uint32_t index) { + uint32_t index_byte = (index) / 8; + uint8_t byte; + byte = bitmap[index_byte]; + return byte; +} + +uint8_t bitmap_get(BitMap bitmap, uint32_t index) { + uint32_t index_byte = (index) / 8; + uint8_t index_bit = (index) % 8; + uint8_t x = (0x1 << index_bit); + uint8_t bit; + bit = bitmap[index_byte] & x; + return bit > 0 ? 1 : 0; +} + +void bitmap_deinit(BitMap bitmap) { + pika_platform_free(bitmap); +} + +#if PIKA_POOL_ENABLE +Pool pikaPool = {0}; +void* pika_user_malloc(size_t size) { + return pool_malloc(&pikaPool, size); +} +void pika_user_free(void* ptrm, size_t size) { + pool_free(&pikaPool, ptrm, size); +} +#endif + +void mem_pool_init(void) { +#if PIKA_POOL_ENABLE + if (!pikaPool.inited) { + pikaPool = pool_init(PIKA_POOL_SIZE, PIKA_POOL_ALIGN); + } +#endif +} + +void _mem_cache_deinit(void) { +#if PIKA_ARG_CACHE_ENABLE + while (pikaMemInfo.cache_pool_top) { + pika_user_free(pikaMemInfo.cache_pool[pikaMemInfo.cache_pool_top - 1], 0); + pikaMemInfo.cache_pool_top--; + } +#endif +} + +void mem_pool_deinit(void) { + _mem_cache_deinit(); +#if PIKA_POOL_ENABLE + pool_deinit(&pikaPool); +#endif +} diff --git a/examples/pikapython/pikapython/pikascript-core/dataMemory.h b/examples/pikapython/pikapython/pikascript-core/dataMemory.h new file mode 100644 index 00000000..449bc32b --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataMemory.h @@ -0,0 +1,90 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __MEMORY_H__ +#define __MEMORY_H__ + +#include "PikaPlatform.h" +#include "PikaVersion.h" + +/*! \NOTE: Make sure #include "plooc_class.h" is close to the class definition + */ +#if defined(__DATA_MEMORY_CLASS_IMPLEMENT__) +#define __PLOOC_CLASS_IMPLEMENT__ +#endif +#include "__pika_ooc.h" + +typedef struct { + uint32_t heapUsed; + uint32_t heapUsedMax; +#if PIKA_ARG_CACHE_ENABLE + uint8_t* cache_pool[PIKA_ARG_CACHE_POOL_SIZE]; + uint32_t cache_pool_top; +#endif + uint32_t alloc_times; + uint32_t alloc_times_cache; +} PikaMemInfo; + +typedef uint8_t* BitMap; + +/* clang-format off */ +typedef struct Pool Pool; +struct Pool{ + private_member( + BitMap bitmap; + uint8_t* mem; + uint8_t aline; + uint32_t size; + uint32_t first_free_block; + uint32_t purl_free_block_start; + PIKA_BOOL inited; + ) +}; +/* clang-format on */ + +#define aline_by(size, aline) \ + (((size) == 0) ? 0 : (((size)-1) / (aline) + 1) * (aline)) + +void pikaFree(void* mem, uint32_t size); +void* pikaMalloc(uint32_t size); +uint32_t pikaMemNow(void); +uint32_t pikaMemMax(void); +void pikaMemMaxReset(void); + +BitMap bitmap_init(uint32_t size); +void bitmap_set(BitMap bitmap, uint32_t index, uint8_t bit); +uint8_t bitmap_get(BitMap bitmap, uint32_t index); +uint8_t bitmap_getByte(BitMap bitmap, uint32_t index); +void bitmap_deinit(BitMap bitmap); + +void mem_pool_deinit(void); +void mem_pool_init(void); + +#define mem_align(_size) ((((_size) + 4 - 1) & ~(4 - 1))) + +#undef __DATA_MEMORY_CLASS_IMPLEMENT__ +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/dataQueue.c b/examples/pikapython/pikapython/pikascript-core/dataQueue.c new file mode 100644 index 00000000..87a0cd49 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataQueue.c @@ -0,0 +1,96 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "dataQueue.h" +#include "PikaPlatform.h" +#include "dataArgs.h" + +void queue_init(Queue* queue) { + args_setInt(queue, "__t", 0); + args_setInt(queue, "__b", 0); +} + +Queue* New_queue(void) { + Args* args = New_args(NULL); + queue_init(args); + return (Queue*)args; +} + +int32_t queue_deinit(Queue* queue) { + Args* args = queue; + args_deinit(args); + return 0; +} + +int32_t queue_pushArg(Queue* queue, Arg* arg) { + Args* args = queue; + uint64_t top = args_getInt(args, "__t"); + /* add top */ + args_setInt(args, "__t", top + 1); + char buff[11]; + arg = arg_setName(arg, fast_itoa(buff, top)); + return args_setArg(args, arg); +} + +Arg* __queue_popArg_noRmoveArg(Queue* queue) { + Args* args = queue; + uint64_t top = args_getInt(args, "__t"); + uint64_t bottom = args_getInt(args, "__b"); + if (top - bottom < 1) { + return NULL; + } + /* add bottom */ + args_setInt(args, "__b", bottom + 1); + char buff[11]; + Arg* res = args_getArg(args, fast_itoa(buff, bottom)); + /* not deinit arg to keep str buff */ + return res; +} + +int32_t queue_pushInt(Queue* queue, int val) { + return queue_pushArg(queue, arg_newInt(val)); +} + +int64_t queue_popInt(Queue* queue) { + return arg_getInt(__queue_popArg_noRmoveArg(queue)); +} + +int32_t queue_pushFloat(Queue* queue, pika_float val) { + return queue_pushArg(queue, arg_newFloat(val)); +} + +pika_float queue_popFloat(Queue* queue) { + return arg_getFloat(__queue_popArg_noRmoveArg(queue)); +} + +int32_t queue_pushStr(Queue* queue, char* str) { + return queue_pushArg(queue, arg_newStr(str)); +} + +char* queue_popStr(Queue* queue) { + return arg_getStr(__queue_popArg_noRmoveArg(queue)); +} diff --git a/examples/pikapython/pikapython/pikascript-core/dataQueue.h b/examples/pikapython/pikapython/pikascript-core/dataQueue.h new file mode 100644 index 00000000..c32d1728 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataQueue.h @@ -0,0 +1,49 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __DATA_QUEUE__H +#define __DATA_QUEUE__H +#include "dataArgs.h" + +typedef Args Queue; +Queue* New_queue(void); + +int32_t queue_deinit(Queue* queue); +int32_t queue_pushInt(Queue* queue, int val); +int32_t queue_pushFloat(Queue* queue, pika_float val); +int32_t queue_pushStr(Queue* queue, char* str); +int32_t queue_pushArg(Queue* queue, Arg* arg); +char* fast_itoa(char* buf, uint32_t val); + +int64_t queue_popInt(Queue* queue); +pika_float queue_popFloat(Queue* queue); +char* queue_popStr(Queue* queue); +Arg* queue_popArg(Queue* queue); +Arg* queue_popArg_notDeinitArg(Queue* queue); +int32_t queue_deinit_stack(Queue* queue); +void queue_init(Queue* queue); +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/dataQueueObj.c b/examples/pikapython/pikapython/pikascript-core/dataQueueObj.c new file mode 100644 index 00000000..ec07f59f --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataQueueObj.c @@ -0,0 +1,125 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "dataQueueObj.h" +#include "BaseObj.h" +#include "dataQueue.h" +QueueObj* New_queueObj(void) { + PikaObj* self = New_PikaObj(); + queueObj_init(self); + return self; +} + +int32_t queueObj_init(QueueObj* self) { + obj_setInt(self, "top", 0); + obj_setInt(self, "bottom", 0); + return 0; +} + +int32_t queueObj_pushObj(QueueObj* self, char* className) { + uint64_t top = obj_getInt(self, "top"); + char buff[11]; + char* topStr = fast_itoa(buff, top); + /* add top */ + obj_setInt(self, "top", top + 1); + return obj_newObj(self, topStr, className, New_TinyObj); +} + +PikaObj* queueObj_getCurrentObj(QueueObj* self) { + uint64_t current = obj_getInt(self, "top") - 1; + char buff[11]; + char* currentStr = fast_itoa(buff, current); + return obj_getObj(self, currentStr); +} + +PikaObj* queueObj_popObj(QueueObj* self) { + uint64_t bottom = obj_getInt(self, "bottom"); + char buff[11]; + char* bottomStr = fast_itoa(buff, bottom); + /* add bottom */ + obj_setInt(self, "bottom", bottom + 1); + PikaObj* res = obj_getObj(self, bottomStr); + return res; +} + +int32_t queueObj_pushInt(QueueObj* self, int val) { + uint64_t top = obj_getInt(self, "top"); + char buff[11]; + char* topStr = fast_itoa(buff, top); + /* add top */ + obj_setInt(self, "top", top + 1); + return obj_setInt(self, topStr, val); +} + +int64_t queueObj_popInt(QueueObj* self) { + uint64_t bottom = obj_getInt(self, "bottom"); + char buff[11]; + char* bottomStr = fast_itoa(buff, bottom); + /* add bottom */ + obj_setInt(self, "bottom", bottom + 1); + int64_t res = obj_getInt(self, bottomStr); + obj_removeArg(self, bottomStr); + return res; +} + +int32_t queueObj_pushFloat(QueueObj* self, pika_float val) { + uint64_t top = obj_getInt(self, "top"); + char buff[11]; + char* topStr = fast_itoa(buff, top); + /* add top */ + obj_setInt(self, "top", top + 1); + return obj_setFloat(self, topStr, val); +} + +pika_float queueObj_popFloat(QueueObj* self) { + uint64_t bottom = obj_getInt(self, "bottom"); + char buff[11]; + char* bottomStr = fast_itoa(buff, bottom); + /* add bottom */ + obj_setInt(self, "bottom", bottom + 1); + pika_float res = obj_getFloat(self, bottomStr); + obj_removeArg(self, bottomStr); + return res; +} + +int32_t queueObj_pushStr(QueueObj* self, char* str) { + uint64_t top = obj_getInt(self, "top"); + char buff[11]; + char* topStr = fast_itoa(buff, top); + /* add top */ + obj_setInt(self, "top", top + 1); + return obj_setStr(self, topStr, str); +} + +char* queueObj_popStr(QueueObj* self) { + uint64_t bottom = obj_getInt(self, "bottom"); + char buff[11]; + char* bottomStr = fast_itoa(buff, bottom); + /* add bottom */ + obj_setInt(self, "bottom", bottom + 1); + return obj_getStr(self, bottomStr); +} diff --git a/examples/pikapython/pikapython/pikascript-core/dataQueueObj.h b/examples/pikapython/pikapython/pikascript-core/dataQueueObj.h new file mode 100644 index 00000000..78531602 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataQueueObj.h @@ -0,0 +1,48 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __DATA_QUEUE_OBJ__H +#define __DATA_QUEUE_OBJ__H +#include "PikaObj.h" +typedef PikaObj QueueObj; + +QueueObj* New_queueObj(void); +int32_t queueObj_init(QueueObj* self); + +int32_t queueObj_pushInt(QueueObj* self, int val); +int32_t queueObj_pushFloat(QueueObj* self, pika_float val); +int32_t queueObj_pushStr(QueueObj* self, char* str); +int32_t queueObj_pushObj(QueueObj* self, char* className); + +int64_t queueObj_popInt(QueueObj* self); +pika_float queueObj_popFloat(QueueObj* self); +char* queueObj_popStr(QueueObj* self); +PikaObj* queueObj_popObj(QueueObj* self); + +PikaObj* queueObj_getCurrentObj(QueueObj* self); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/dataStack.c b/examples/pikapython/pikapython/pikascript-core/dataStack.c new file mode 100644 index 00000000..cca22627 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataStack.c @@ -0,0 +1,231 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "dataStack.h" +#include "PikaObj.h" +#include "dataQueue.h" + +uint8_t* stack_popPyload(Stack* stack, int32_t size); + +void stack_reset(Stack* stack) { + stack->sp = (uint8_t*)arg_getContent(stack->stack_pyload); + stack->sp_size = (int32_t*)arg_getContent(stack->stack_size_array); + stack->top = 0; +} + +int32_t stack_init(Stack* stack) { + stack->stack_pyload = arg_setContent(NULL, NULL, PIKA_STACK_BUFF_SIZE); + stack->stack_size_array = + arg_setContent(NULL, NULL, PIKA_STACK_BUFF_SIZE / 4); + stack_reset(stack); + stack->stack_totle_size = PIKA_STACK_BUFF_SIZE; + return 0; +}; + +void stack_pushSize(Stack* stack, int32_t size) { + *(stack->sp_size) = size; + stack->sp_size++; +} + +int32_t stack_popSize(Stack* stack) { + stack->sp_size--; + return *(stack->sp_size); +} + +Arg* stack_checkArg(Stack* stack, int index) { + if (stack->top - index <= 0) { + return NULL; + } + int sp_offset = 0; + int32_t size = 0; + for (int i = 1; i <= index + 1; i++) { + size = stack->sp_size[-i]; + if (size == -1) { + sp_offset -= sizeof(Arg*); + } else { + sp_offset -= size; + } + } + if (size == -1) { + return *(Arg**)(stack->sp + sp_offset); + } + return (Arg*)(stack->sp + sp_offset); +} + +int32_t stack_deinit(Stack* stack) { + while (stack->top > 0) { + int32_t size = stack_popSize(stack); + uint8_t* pyload = stack_popPyload(stack, size); + stack->top--; + if (size == -1) { + arg_deinit(*(Arg**)pyload); + } + } + arg_deinit(stack->stack_pyload); + arg_deinit(stack->stack_size_array); + return 0; +} + +void stack_pushPyload(Stack* stack, + uint8_t* in, + size_t size, + PIKA_BOOL is_sample_copy) { + size_t stack_size_after_push = + size + (stack->sp - arg_getContent(stack->stack_pyload)); + if (stack_size_after_push > stack->stack_totle_size) { + pika_platform_printf( + "OverflowError: pika VM stack overflow, please use bigger " + "PIKA_STACK_BUFF_SIZE\r\n"); + pika_platform_printf("Info: stack size request: %d\r\n", + (int)stack_size_after_push); + pika_platform_printf("Info: stack size now: %d\r\n", + (int)stack->stack_totle_size); + while (1) { + } + } + Arg* top = (Arg*)stack->sp; + if (is_sample_copy) { + pika_platform_memcpy(top, in, size); + } else { + pika_platform_memcpy(top, in, sizeof(Arg)); + pika_platform_memcpy(top->content, ((Arg*)in)->_.buffer, + size - sizeof(Arg)); + /* transfer to serialized form */ + arg_setSerialized(top, PIKA_TRUE); + } + stack->sp += size; +} + +uint8_t* stack_popPyload(Stack* stack, int32_t size) { + if (size == -1) { + size = sizeof(void*); + } + stack->sp -= size; + return stack->sp; +} + +static int32_t _stack_pushArg(Stack* stack, Arg* arg, PIKA_BOOL is_alloc) { + PIKA_BOOL is_big_arg = PIKA_FALSE; + stack->top++; + size_t size = arg_getTotleSize(arg); +//! if you unsure about the __impl_pikaMalloc, uncomment this to force alignment +#if PIKA_ARG_ALIGN_ENABLE + /* force alignment to avoid unaligned access */ + size = (size + 4 - 1) & ~(4 - 1); +#endif + /* add ref_cnt to keep object in stack */ + if (argType_isObject(arg_getType(arg))) { + obj_refcntInc((PikaObj*)arg_getPtr(arg)); + } + + if (arg_isSerialized(arg)) { + is_big_arg = PIKA_TRUE; + } + + if (is_big_arg) { + /* push a pointer to this arg */ + stack_pushSize(stack, -1); + stack_pushPyload(stack, (uint8_t*)&arg, sizeof(Arg*), PIKA_TRUE); + } else { + stack_pushSize(stack, size); + stack_pushPyload(stack, (uint8_t*)arg, size, (PIKA_BOOL)arg_isSerialized(arg)); + } + + if (is_big_arg) { + return 0; + } + if (is_alloc) { + arg_deinit(arg); + return 0; + } + arg_deinitHeap(arg); + return 0; +} + +int32_t stack_pushArg(Stack* stack, Arg* arg) { + pika_assert(arg != NULL); + if (arg_isSerialized(arg)) { + return _stack_pushArg(stack, arg, PIKA_TRUE); + } + return _stack_pushArg(stack, arg, PIKA_FALSE); +} + +int32_t stack_pushStr(Stack* stack, char* str) { + Arg* newArg = arg_newStr(str); + return stack_pushArg(stack, newArg); +} + +Arg* _stack_popArg(Stack* stack, Arg* arg_dict, PIKA_BOOL is_alloc) { + PIKA_BOOL is_big_arg = PIKA_FALSE; + if (stack->top == 0) { + return NULL; + } + stack->top--; + int32_t size = stack_popSize(stack); + if (size == -1) { + is_big_arg = PIKA_TRUE; + size = sizeof(Arg*); + } + Arg* arg = NULL; + if (is_big_arg) { + arg = *(Arg**)stack_popPyload(stack, size); + } else { + arg = (Arg*)stack_popPyload(stack, size); + if (is_alloc) { + arg = arg_copy(arg); + } else { + arg = arg_copy_noalloc(arg, arg_dict); + } + } + + ArgType type = arg_getType(arg); + /* decrase ref_cnt */ + if (argType_isObject(type)) { + obj_refcntDec((PikaObj*)arg_getPtr(arg)); + } + pika_assert(arg->flag < ARG_FLAG_MAX); + return arg; +} + +Arg* stack_popArg_alloc(Stack* stack) { + return _stack_popArg(stack, NULL, PIKA_TRUE); +} + +Arg* stack_popArg(Stack* stack, Arg* arg_dict) { + return _stack_popArg(stack, arg_dict, PIKA_FALSE); +} + +char* stack_popStr(Stack* stack, char* outBuff) { + Arg* arg = stack_popArg_alloc(stack); + strcpy(outBuff, arg_getStr(arg)); + arg_deinit(arg); + return outBuff; +} + +int32_t stack_getTop(Stack* stack) { + return stack->top; +} diff --git a/examples/pikapython/pikapython/pikascript-core/dataStack.h b/examples/pikapython/pikapython/pikascript-core/dataStack.h new file mode 100644 index 00000000..4290cd0e --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataStack.h @@ -0,0 +1,54 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __DATA_STACK__H +#define __DATA_STACK__H +#include "dataArgs.h" + +typedef struct Stack_t { + Arg* stack_pyload; + Arg* stack_size_array; + uint8_t* sp; + int32_t* sp_size; + int32_t top; + size_t stack_totle_size; +} Stack; + +int32_t stack_deinit(Stack* stack); + +int32_t stack_pushStr(Stack* stack, char* str); +char* stack_popStr(Stack* stack, char* outBuff); +Arg* stack_checkArg(Stack* stack, int index); +int32_t stack_pushArg(Stack* stack, Arg* arg); +Arg* stack_popArg_alloc(Stack* stack); +Arg* stack_popArg(Stack* stack, Arg* arg_dict); +int32_t stack_getTop(Stack* stack); +int32_t stack_init(Stack* stack); +int32_t stack_popSize(Stack* stack); +void stack_pushSize(Stack* stack, int32_t size); +void stack_reset(Stack* stack); +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/dataString.c b/examples/pikapython/pikapython/pikascript-core/dataString.c new file mode 100644 index 00000000..206e2bce --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataString.c @@ -0,0 +1,282 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "dataString.h" +#include "PikaPlatform.h" + +char* strCut(char* strOut, char* strIn, char startSign, char endSign) { + int32_t Size = strGetSize(strIn); + int32_t iStart = 0; + int32_t iEnd = Size; + uint8_t isStart = 0; + uint8_t isEnd = 0; + for (int32_t i = 0; i < Size; i++) { + if (strIn[i] == startSign) { + iStart = i; + isStart = 1; + break; + } + } + for (int32_t i = Size - 1; i >= 0; i--) { + if (strIn[i] == endSign) { + iEnd = i; + isEnd = 1; + break; + } + } + int outi = 0; + for (int32_t i = iStart + 1; i < iEnd; i++) { + strOut[outi] = strIn[i]; + outi++; + } + /* add \0 */ + strOut[outi] = 0; + if (isStart && isEnd) { + /* succeed */ + return strOut; + } + /* failed */ + return NULL; +} + +char* strDeleteChar(char* strOut, char* strIn, char ch) { + int32_t iOut = 0; + uint32_t size = strGetSize(strIn); + for (uint32_t i = 0; i < size; i++) { + if (ch == strIn[i]) { + continue; + } + strOut[iOut] = strIn[i]; + iOut++; + } + /* add \0 */ + strOut[iOut] = 0; + return strOut; +} + +char* strAppendWithSize(char* strOut, char* pData, int32_t Size) { + int32_t strOut_i = strGetSize(strOut); + for (int32_t i = 0; i < Size; i++) { + strOut[strOut_i + i] = pData[i]; + } + strOut_i += Size; + // add \0 to the end of strOut + strOut[strOut_i] = 0; + + return strOut; +} + +int32_t strCountSign(char* strIn, char sign) { + pika_assert(NULL != strIn); + int count = 0; + while (*strIn) { + if (*strIn == sign) { + count++; + } + strIn++; + } + return count; +} + +char* strReplaceChar(char* strIn, char src, char dst) { + while (*strIn) { + if (*strIn == src) { + *strIn = dst; + } + strIn++; + } + return strIn; +} + +int32_t strGetTokenNum(char* strIn, char sign) { + return strCountSign(strIn, sign) + 1; +} + +size_t strGetSize(char* pData) { + pika_assert(pData != NULL); + return strlen(pData); +} + +char* strPointToLastToken(char* strIn, char sign) { + if (!strIsContain(strIn, sign)) { + return strIn; + } + int32_t size = strGetSize(strIn); + for (int32_t i = size - 1; i > -1; i--) { + if (strIn[i] == sign) { + return strIn + i + 1; + } + } + return strIn; +} + +char* strPopLastToken(char* strIn, char sign) { + char* last_token = strPointToLastToken(strIn, sign); + if (last_token != strIn) { + *(last_token - 1) = 0; + } + return last_token; +} + +char* strGetLastToken(char* strOut, char* strIn, char sign) { + int32_t size = strGetSize(strIn); + int32_t buffSize = 0; + for (int32_t i = size - 1; i > -1; i--) { + if (strIn[i] != sign) { + strOut[size - i - 1] = strIn[i]; + buffSize++; + } + if (strIn[i] == sign) { + break; + } + } + int32_t i = 0; + for (i = 0; i < buffSize / 2; i++) { + char buff = strOut[i]; + strOut[i] = strOut[buffSize - i - 1]; + strOut[buffSize - i - 1] = buff; + } + strOut[buffSize] = 0; + return strOut; +} + +char* strPopFirstToken(char** strIn, char sign) { + char* strIn_ = *strIn; + char* pos = strchr(strIn_, sign); + if (pos != NULL) { + /* found the first sign */ + *pos = 0; + *strIn = pos + 1; + return strIn_; + } + /* no found */ + *strIn = strchr(strIn_, 0); + return strIn_; +} + +char* strGetFirstToken(char* strOut, char* strIn, char sign) { + int32_t size = strGetSize(strIn); + for (int32_t i = 0; i < size; i++) { + if (strIn[i] != sign) { + strOut[i] = strIn[i]; + } + if (strIn[i] == sign) { + break; + } + } + return strOut; +} + +char* strAppend(char* strOut, char* pData) { + uint32_t Size = 0; + Size = strGetSize(pData); + return strAppendWithSize(strOut, pData, Size); +} + +int32_t strIsStartWith(char* str, char* strStart) { + if (NULL == str || NULL == strStart) { + /* input is null */ + return 0; + } + /* fast return */ + if (str[0] != strStart[0]) { + return 0; + } + uint32_t size = strGetSize(strStart); + if (0 == strncmp(str, strStart, size)) { + return 1; + } + return 0; +} + +int32_t strEqu(char* str1, char* str2) { + if (NULL == str1 || NULL == str2) { + return 0; + } + return !strcmp(str1, str2); +} + +char* strRemovePrefix(char* inputStr, char* prefix, char* outputStr) { + if (!strIsStartWith(inputStr, prefix)) { + return NULL; + } + size_t len = strGetSize(inputStr); + for (uint32_t i = strGetSize(prefix); i < len; i++) { + outputStr[i - strGetSize(prefix)] = inputStr[i]; + } + return outputStr; +} + +int32_t strIsContain(char* str, char ch) { + while (*str) { + if (*str == ch) { + return 1; + } + str++; + } + return 0; +} + +char* strCopy(char* strBuff, char* strIn) { + pika_platform_memcpy(strBuff, strIn, strGetSize(strIn) + 1); + return strBuff; +} + +int32_t strGetLineSize(char* str) { + int i = 0; + while (1) { + if (str[i] == '\n') { + return i; + } + i++; + } +} + +char* strGetLine(char* strOut, char* strIn) { + int32_t lineSize = strGetLineSize(strIn); + pika_platform_memcpy(strOut, strIn, lineSize); + strOut[lineSize] = 0; + return strOut; +} + +char* strGetLastLine(char* strOut, char* strIn) { + int32_t size = strGetSize(strIn); + char sign = '\n'; + uint32_t beginIndex = 0; + + /* skip the latest '\n' */ + for (int32_t i = size - 2; i > -1; i--) { + if (strIn[i] == sign) { + beginIndex = i + 1; + break; + } + } + + pika_platform_memcpy(strOut, strIn + beginIndex, size - beginIndex); + strOut[size - beginIndex + 1] = 0; + return strOut; +} diff --git a/examples/pikapython/pikapython/pikascript-core/dataString.h b/examples/pikapython/pikapython/pikascript-core/dataString.h new file mode 100644 index 00000000..d64984a2 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataString.h @@ -0,0 +1,66 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __MY_TEST_TOOLS_H +#define __MY_TEST_TOOLS_H +#include "PikaPlatform.h" + +/* size */ +size_t strGetSize(char* pData); +/* append */ +char* strAppend(char* strOut, char* pData); +char* strAppend_unlimited(char* strOut, char* pData); +char* strAppendWithSize(char* strOut, char* pData, int32_t Size); +/* cut */ +char* strCut(char* strOut, char* strIn, char startSign, char endSign); +/* pika_assert */ +int32_t strIsStartWith(char* str, char* strStart); +int32_t strEqu(char* str1, char* str2); +/* delete */ +char* strDeleteEnter(char* str); +char* strDeleteChar(char* strOut, char* strIn, char ch); +/* prefix */ +char* strRemovePrefix(char* inputStr, char* prefix, char* outputStr); +/* token */ +int32_t strGetToken(char* string, char** argv, char sign); +char* strPopFirstToken(char** strIn, char sign); +int32_t strCountSign(char* strIn, char sign); +int32_t strGetTokenNum(char* strIn, char sign); +char* strGetFirstToken(char* strOut, char* strIn, char sign); +char* strGetLastToken(char* strOut, char* strIn, char sign); +char* strClear(char* str); +int32_t strIsContain(char* str, char ch); +char* strCopy(char* strBuff, char* strIn); +char* strGetLastLine(char* strOut, char* strIn); +char* strPointToLastToken(char* strIn, char sign); +char* strGetLine(char* strOut, char* strIn); +int32_t strGetLineSize(char* str); +char* strPopLastToken(char* strIn, char sign); +char* strGetLastLine(char* strOut, char* strIn); +char* strReplaceChar(char* strIn, char src, char dst); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/dataStrs.c b/examples/pikapython/pikapython/pikascript-core/dataStrs.c new file mode 100644 index 00000000..3f940380 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataStrs.c @@ -0,0 +1,202 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "dataStrs.h" +#include "PikaPlatform.h" +#include "dataString.h" + +Args* New_strBuff(void) { + return New_args(NULL); +} + +char* strsRemovePrefix(Args* buffs_p, char* inputStr, char* prefix) { + int32_t size = strGetSize(inputStr); + char* buff = args_getBuff(buffs_p, size); + return strRemovePrefix(inputStr, prefix, buff); +} + +char* strsGetDirectStr(Args* buffs_p, char* argPath) { + char* directStr = NULL; + directStr = strsCut(buffs_p, argPath, '"', '"'); + if (NULL != directStr) { + return directStr; + } + directStr = strsCut(buffs_p, argPath, '\'', '\''); + if (NULL != directStr) { + return directStr; + } + return NULL; +} + +char* strsAppend(Args* buffs_p, char* strOrigin, char* strToAppend) { + pika_assert(NULL != strToAppend); + pika_assert(NULL != strOrigin); + int32_t size = strGetSize(strOrigin) + strGetSize(strToAppend); + char* buff = args_getBuff(buffs_p, size); + char* strOut = strCopy(buff, strOrigin); + strAppend(strOut, strToAppend); + return strOut; +} + +char* strsReturnOut(Args* buffs, Args* outbuffs, char* str) { + char* line_out = strsCopy(outbuffs, str); + strsDeinit(buffs); + return line_out; +} + +char* strsGetLastToken(Args* buffs_p, char* argPath, char sign) { + int32_t size = strGetSize(argPath); + char* buff = args_getBuff(buffs_p, size); + return strGetLastToken(buff, argPath, sign); +} + +char* strsCut(Args* buffs_p, char* strIn, char startSign, char endSign) { + int32_t size = strGetSize(strIn); + char* buff = args_getBuff(buffs_p, size); + return strCut(buff, strIn, startSign, endSign); +} + +char* strsDeleteChar(Args* buffs_p, char* strIn, char ch) { + int32_t size = strGetSize(strIn); + return strDeleteChar(args_getBuff(buffs_p, size), strIn, ch); +} + +static uint32_t getSizeOfFirstToken(char* str, char sign) { + uint32_t size = strGetSize(str); + for (uint32_t i = 0; i < size; i++) { + if (str[i] == sign) { + return i; + } + } + return size; +} + +char* strsGetFirstToken(Args* buffs_p, char* strIn, char sign) { + int32_t size = getSizeOfFirstToken(strIn, sign); + return strGetFirstToken(args_getBuff(buffs_p, size), strIn, sign); +} + +char* strsPopToken(Args* buffs_p, char** tokens, char sign) { + return strsCopy(buffs_p, strPopFirstToken(tokens, sign)); +} + +char* strsCopy(Args* buffs_p, char* source) { + pika_assert(source != NULL); + int32_t size = strGetSize(source); + char* buff = args_getBuff(buffs_p, size); + return strCopy(buff, source); +} + +char* strsCacheArg(Args* buffs_p, Arg* arg) { + pika_assert(arg != NULL); + char* res = strsCopy(buffs_p, arg_getStr(arg)); + arg_deinit(arg); + return res; +} + +char* strsFormat(Args* buffs_p, uint16_t buffSize, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + char* res = args_getBuff(buffs_p, buffSize); + pika_platform_vsnprintf(res, buffSize, fmt, args); + va_end(args); + return res; +} + +Arg* arg_strAppend(Arg* arg_in, char* str_to_append) { + pika_assert(NULL != str_to_append); + Args buffs = {0}; + char* str_out = strsAppend(&buffs, arg_getStr(arg_in), str_to_append); + Arg* arg_out = arg_newStr(str_out); + arg_deinit(arg_in); + strsDeinit(&buffs); + return arg_out; +} + +char* strsReplace(Args* buffs_p, char* orig, char* rep, char* with) { + char* result; // the return string + char* ins; // the next insert point + char* tmp; // varies + int len_rep; // length of rep (the string to remove) + int len_with; // length of with (the string to replace rep with) + int len_front; // distance between rep and end of last rep + int count; // number of replacements + + /* no need replace, skip */ + if (NULL == strstr(orig, rep)) { + return orig; + } + + // sanity checks and initialization + if (!orig || !rep) + return NULL; + len_rep = strlen(rep); + if (len_rep == 0) + return NULL; // empty rep causes infinite loop during count + if (!with) + with = ""; + len_with = strlen(with); + // count the number of replacements needed + ins = orig; + tmp = strstr(ins, rep); + count = 0; + while (tmp) { + count++; + ins = tmp + len_rep; + tmp = strstr(ins, rep); + } + tmp = + args_getBuff(buffs_p, strlen(orig) + (len_with - len_rep) * count + 1); + result = tmp; + if (NULL == result) { + return NULL; + } + // first time through the loop, all the variable are set correctly + // from here on, + // tmp points to the end of the result string + // ins points to the next occurrence of rep in orig + // orig points to the remainder of orig after "end of rep" + while (count--) { + ins = strstr(orig, rep); + len_front = ins - orig; + tmp = strncpy(tmp, orig, len_front) + len_front; + tmp = strcpy(tmp, with) + len_with; + orig += len_front + len_rep; // move to next "end of rep" + } + strcpy(tmp, orig); + return result; +} + +char* strsGetLine(Args* buffs_p, char* code) { + int32_t lineSize = strGetLineSize(code); + char* line_buff = args_getBuff(buffs_p, lineSize + 1); + return strGetLine(line_buff, code); +} + +void strsDeinit(Args* buffs_p) { + link_deinit_stack(buffs_p); +} diff --git a/examples/pikapython/pikapython/pikascript-core/dataStrs.h b/examples/pikapython/pikapython/pikascript-core/dataStrs.h new file mode 100644 index 00000000..1e2404a6 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/dataStrs.h @@ -0,0 +1,48 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __STR_ARGS__H +#define __STR_ARGS__H +#include "dataArgs.h" +Args* New_strBuff(void); +char* strsGetFirstToken(Args* buffs, char* strIn, char sign); +char* strsGetLastToken(Args* buffs, char* arg_Path, char sign); +char* strsPopToken(Args* buffs, char** tokens, char sign); +char* strsCopy(Args* buffs, char* source); +char* strsDeleteChar(Args* buff, char* strIn, char ch); +char* strsCut(Args* buffs, char* strIn, char startSign, char endSign); +char* strsRemovePrefix(Args* buffs, char* inputStr, char* prefix); +char* strsAppend(Args* buffs, char* strOrigin, char* strAppend); +char* strsFormat(Args* buffs, uint16_t buffSize, const char* fmt, ...); +char* strsGetDirectStr(Args* buffs, char* argPath); +Arg* arg_strAppend(Arg* arg_in, char* str_to_append); +char* strsReplace(Args* buffs, char* orig, char* rep, char* with); +char* strsGetLine(Args* buffs, char* code); +void strsDeinit(Args* buffs); +char* strsCacheArg(Args* buffs_p, Arg* arg); +char* strsReturnOut(Args* buffs, Args* outbuffs, char* str); +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/pika_adapter_mpy.h b/examples/pikapython/pikapython/pikascript-core/pika_adapter_mpy.h new file mode 100644 index 00000000..c60449a7 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/pika_adapter_mpy.h @@ -0,0 +1,337 @@ +#ifndef __PIKA_ADAPTER_MPY_H__ +#define __PIKA_ADAPTER_MPY_H__ +#include +#include "PikaObj.h" +#include "PikaStdData_List.h" +#define bool int +#define true 1 +#define false 0 +/* object type */ +#define mp_obj_t Arg* +/* type define*/ +#define STATIC static +#define NORETURN + +/* object API */ +#define MP_OBJ_NEW_SMALL_INT(...) arg_newInt(__VA_ARGS__) +#define mp_obj_new_bool(...) arg_newInt(__VA_ARGS__) +#define mp_obj_new_bytes(...) arg_newBytes(__VA_ARGS__) +#define mp_obj_new_float(...) arg_newFloat(__VA_ARGS__) +#define MP_OBJ_TO_PTR(...) arg_getPtr(__VA_ARGS__) +#define MP_OBJ_FROM_PTR(_p) arg_newPtr(ARG_TYPE_OBJECT, (_p)) +#define mp_obj_get_int(...) arg_getInt(__VA_ARGS__) +#define mp_obj_is_true(...) (bool)arg_getInt(__VA_ARGS__) +#define mp_const_true arg_newInt(1) +#define mp_const_false arg_newInt(0) +#define mp_const_none arg_newNull() + +/* module API */ +#define MP_DEFINE_CONST_DICT(...) +#define MP_DEFINE_CONST_FUN_OBJ_KW(...) +#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(...) +#define MP_DEFINE_CONST_FUN_OBJ_1(...) +#define MP_DEFINE_CONST_FUN_OBJ_2(...) +#define MP_DEFINE_CONST_FUN_OBJ_3(...) +#define MP_DEFINE_CONST_FUN_OBJ_4(...) +#define MP_DEFINE_CONST_FUN_OBJ_5(...) +#define MP_DEFINE_CONST_FUN_OBJ_6(...) +#define MP_DEFINE_CONST_FUN_OBJ_7(...) +#define MP_DEFINE_CONST_FUN_OBJ_8(...) + +/* gil */ +#define MP_THREAD_GIL_EXIT(...) +#define MP_THREAD_GIL_ENTER(...) + +/* raise */ +#define MP_ETIMEDOUT "timed out" +#define MP_ENOMEM "out of memory" +#define MP_BUFFER_READ "read" +#define MP_ERROR_TEXT(_s) _s +#define mp_raise_msg_varg(_, ...) pika_platform_printf(__VA_ARGS__) +#define mp_raise_msg(_, _s) mp_raise_msg_varg(_, _s) +#define mp_raise_TpyeXXX(_s) mp_raise_msg(NULL, _s) +#define mp_raise_ValueError mp_raise_TpyeXXX +#define mp_raise_TypeError mp_raise_TpyeXXX +#define mp_raise_OSError mp_raise_TpyeXXX + +/* utils */ +#define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) +#define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) + +/* list */ +typedef struct mp_obj_tuple_t { + size_t len; + mp_obj_t* items; +} mp_obj_tuple_t; + +#define mp_obj_str_get_str(...) arg_getStr(__VA_ARGS__) +#define mp_obj_get_float(...) arg_getFloat(__VA_ARGS__) + +typedef struct _mp_map_elem_t { + mp_obj_t key; + mp_obj_t value; +} mp_map_elem_t; + +typedef struct mp_map_t { + size_t all_keys_are_qstrs : 1; + size_t + is_fixed : 1; // if set, table is fixed/read-only and can't be modified + size_t is_ordered : 1; // if set, table is an ordered array, not a hash map + size_t used : (8 * sizeof(size_t) - 3); + size_t alloc; + mp_map_elem_t* table; +} mp_map_t; + +static inline bool mp_map_slot_is_filled(const mp_map_t* map, size_t pos) { + return (map)->table[pos].key != NULL; +} + +static inline int mp_obj_str_get_qstr(Arg* arg) { + return hash_time33(arg_getStr(arg)); +} + +#define mp_obj_new_str(str, len) arg_newStr(str) + +typedef struct _mp_buffer_info_t { + void* buf; // can be NULL if len == 0 + size_t len; // in bytes + int typecode; // as per binary.h +} mp_buffer_info_t; + +#define MP_QSTR(_str) hash_time33(#_str) + +static inline Arg* mp_obj_new_list(int n, Arg** items) { + PikaObj* list = newNormalObj(New_PikaStdData_List); + PikaStdData_List___init__(list); + return arg_newObj(list); +} + +static inline mp_obj_tuple_t* mp_obj_new_tuple(int n, Arg** items_in) { + mp_obj_tuple_t* tuple = (mp_obj_tuple_t*)malloc(sizeof(mp_obj_tuple_t)); + Arg** items = (Arg**)malloc(sizeof(Arg*) * n); + if (NULL == items_in) { + tuple->len = n; + tuple->items = items; + } + return tuple; +} + +static inline void mp_obj_list_append(Arg* list, mp_obj_tuple_t* tuple) { + PikaObj* list_obj = (PikaObj*)arg_getPtr(list); + for (int i = 0; i < tuple->len; i++) { + PikaStdData_List_append(list_obj, tuple->items[i]); + arg_deinit(tuple->items[i]); + } + free(tuple->items); + free(tuple); +} + +static inline char* mp_obj_str_get_data(Arg* self, size_t* len) { + char* str = arg_getStr(self); + *len = strGetSize(str); + return str; +} + +static inline size_t pks_load_mp_args(PikaTuple* tuple, + mp_obj_t mp_self, + mp_obj_t* args) { + size_t len = pikaTuple_getSize(tuple); + size_t i = 0; + if (NULL != mp_self) { + args[0] = mp_self; + i = 1; + } + for (i = 0; i < len; i++) { + args[i] = pikaTuple_getArg(tuple, i); + } + return len; +} + +static inline void pks_load_mp_map(PikaDict* kw, mp_map_t* map) { + size_t len = pikaDict_getSize(kw); + map->alloc = len; + map->used = len; + map->table = (mp_map_elem_t*)malloc(sizeof(mp_map_elem_t) * len); + for (int i = 0; i < len; i++) { + Arg* item = pikaDict_getArgByidex(kw, i); + map->table[i].key = arg_getNameHash(item); + map->table[i].value = item; + } +} + +static inline void mp_get_buffer_raise(mp_obj_t item, + mp_buffer_info_t* buf, + char* msg) { + buf->len = arg_getSize(item); + buf->buf = malloc(buf->len); + if (NULL == buf->buf) { + mp_raise_OSError(msg); + } + memcpy(buf->buf, arg_getBytes(item), buf->len); +} + +static const ArgType mp_type_tuple = ARG_TYPE_TUPLE; +static const ArgType mp_type_list = ARG_TYPE_TUPLE; +static const ArgType mp_type_str = ARG_TYPE_STRING; +static const ArgType mp_type_bytes = ARG_TYPE_BYTES; +static const ArgType mp_type_int = ARG_TYPE_INT; +static const ArgType mp_type_float = ARG_TYPE_FLOAT; +static const ArgType mp_type_bool = ARG_TYPE_INT; +static const ArgType mp_type_none = ARG_TYPE_NONE; + +static inline bool mp_obj_is_type(mp_obj_t self, ArgType* arg_type_ptr) { + if (arg_getType(self) == *arg_type_ptr) { + return true; + } + return false; +} + +#define mp_obj_is_integer(self) mp_obj_is_type(self, &mp_type_int) + +#define mp_uint_t size_t +#define mp_int_t int + +typedef void (*mp_print_strn_t)(void* data, const char* str, size_t len); + +typedef struct _mp_print_t { + void* data; + mp_print_strn_t print_strn; +} mp_print_t; + +static inline void mp_obj_get_array_fixed_n(mp_obj_t tuple, + size_t n, + mp_obj_t* arrray) { + for (int i = 0; i < n; i++) { + arrray[i] = pikaTuple_getArg((PikaTuple*)arg_getPtr(tuple), i); + } +} + +typedef const void* mp_const_obj_t; +typedef mp_const_obj_t mp_rom_obj_t; +typedef struct _mp_rom_map_elem_t { + mp_rom_obj_t key; + mp_rom_obj_t value; +} mp_rom_map_elem_t; + +#define MICROPY_OBJ_BASE_ALIGNMENT +typedef struct _mp_obj_type_t mp_obj_type_t; +struct _mp_obj_base_t { + const mp_obj_type_t* type MICROPY_OBJ_BASE_ALIGNMENT; +}; +typedef struct _mp_obj_base_t mp_obj_base_t; + +struct _mp_obj_type_t { + // A type is an object so must start with this entry, which points to + // mp_type_type. + mp_obj_base_t base; + + // Flags associated with this type. + uint16_t flags; + + // The name of this type, a qstr. + uint16_t name; + + // Slots: For the rest of the fields, the slot index points to the + // relevant function in the variable-length "slots" field. Ideally these + // would be only 4 bits, but the extra overhead of accessing them adds + // more code, and we also need to be able to take the address of them for + // mp_obj_class_lookup. + + // Corresponds to __new__ and __init__ special methods, to make an instance + // of the type. + uint8_t slot_index_make_new; + + // Corresponds to __repr__ and __str__ special methods. + uint8_t slot_index_print; + + // Corresponds to __call__ special method, ie T(...). + uint8_t slot_index_call; + + // Implements unary and binary operations. + // Can return MP_OBJ_NULL if the operation is not supported. + uint8_t slot_index_unary_op; + uint8_t slot_index_binary_op; + + // Implements load, store and delete attribute. + // + // dest[0] = MP_OBJ_NULL means load + // return: for fail, do nothing + // for fail but continue lookup in locals_dict, dest[1] = + // MP_OBJ_SENTINEL for attr, dest[0] = value for method, dest[0] = + // method, dest[1] = self + // + // dest[0,1] = {MP_OBJ_SENTINEL, MP_OBJ_NULL} means delete + // dest[0,1] = {MP_OBJ_SENTINEL, object} means store + // return: for fail, do nothing + // for success set dest[0] = MP_OBJ_NULL + uint8_t slot_index_attr; + + // Implements load, store and delete subscripting: + // - value = MP_OBJ_SENTINEL means load + // - value = MP_OBJ_NULL means delete + // - all other values mean store the value + // Can return MP_OBJ_NULL if operation not supported. + uint8_t slot_index_subscr; + + // This slot's behaviour depends on the MP_TYPE_FLAG_ITER_IS_* flags above. + // - If MP_TYPE_FLAG_ITER_IS_GETITER flag is set, then this corresponds to + // the __iter__ + // special method (of type mp_getiter_fun_t). Can use the given + // mp_obj_iter_buf_t to store the iterator object, otherwise can return a + // pointer to an object on the heap. + // - If MP_TYPE_FLAG_ITER_IS_ITERNEXT is set, then this corresponds to + // __next__ special method. + // May return MP_OBJ_STOP_ITERATION as an optimisation instead of raising + // StopIteration() with no args. The type will implicitly implement + // getiter as "return self". + // - If MP_TYPE_FLAG_ITER_IS_CUSTOM is set, then this slot must point to an + // mp_getiter_iternext_custom_t instance with both the getiter and + // iternext fields set. + // - If MP_TYPE_FLAG_ITER_IS_STREAM is set, this this slot should be unset. + uint8_t slot_index_iter; + + // Implements the buffer protocol if supported by this type. + uint8_t slot_index_buffer; + + // One of disjoint protocols (interfaces), like mp_stream_p_t, etc. + uint8_t slot_index_protocol; + + // A pointer to the parents of this type: + // - 0 parents: pointer is NULL (object is implicitly the single parent) + // - 1 parent: a pointer to the type of that parent + // - 2 or more parents: pointer to a tuple object containing the parent + // types + uint8_t slot_index_parent; + + // A dict mapping qstrs to objects local methods/constants/etc. + uint8_t slot_index_locals_dict; + + const void* slots[]; +}; + +typedef struct _mp_obj_dict_t { + mp_obj_base_t base; + mp_map_t map; +} mp_obj_dict_t; + +typedef struct _mp_obj_module_t { + mp_obj_base_t base; + mp_obj_dict_t* globals; +} mp_obj_module_t; + +typedef struct _vstr_t { + size_t alloc; + size_t len; + char *buf; + bool fixed_buf; +} vstr_t; + +typedef struct _mp_obj_list_t { + mp_obj_base_t base; + size_t alloc; + size_t len; + mp_obj_t *items; +} mp_obj_list_t; + + +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/pika_adapter_old_api.h b/examples/pikapython/pikapython/pikascript-core/pika_adapter_old_api.h new file mode 100644 index 00000000..bf76fcd7 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/pika_adapter_old_api.h @@ -0,0 +1,77 @@ +#ifndef __PIKA_ADAPTER_OLD_API_H__ +#define __PIKA_ADAPTER_OLD_API_H__ + +/* micro pika configuration */ +#include "./pika_config_valid.h" + +/* + * This file is used to support old api, it's not recommended to use it. + * In new project, please use new api instead. + */ + +#if PIKA_OLD_API_ENABLE +#define __platform_enable_irq_handle pika_platform_enable_irq_handle +#define __platform_disable_irq_handle pika_platform_disable_irq_handle +#define __platform_printf pika_platform_printf +#define __platform_sprintf pika_platform_sprintf +#define __platform_vsprintf pika_platform_vsprintf +#define __platform_vsnprintf pika_platform_vsnprintf +#define __platform_snprintf pika_platform_snprintf +#define __platform_strdup pika_platform_strdup +#define __platform_tick_from_millisecond pika_platform_tick_from_millisecond +#define __platform_malloc pika_platform_malloc +#define __platform_realloc pika_platform_realloc +#define __platform_calloc pika_platform_calloc +#define __platform_free pika_platform_free +#define __platform_memset pika_platform_memset +#define __platform_memcpy pika_platform_memcpy +#define __platform_memcmp pika_platform_memcmp +#define __platform_memmove pika_platform_memmove +#define __platform_wait pika_platform_wait +#define __platform_getchar pika_platform_getchar +#define __platform_putchar pika_platform_putchar +#define __platform_fopen pika_platform_fopen +#define __platform_fclose pika_platform_fclose +#define __platform_fwrite pika_platform_fwrite +#define __platform_fread pika_platform_fread +#define __platform_fseek pika_platform_fseek +#define __platform_ftell pika_platform_ftell +#define __platform_error_handle pika_platform_error_handle +#define __platform_panic_handle pika_platform_panic_handle +#define __platform_thread_delay pika_platform_thread_delay +#define __platform_getTick pika_platform_getTick +#define __platform_sleep_ms pika_platform_sleep_ms +#define __platform_sleep_s pika_platform_sleep_s + +#define __pks_hook_instruct pika_hook_instruct +#define __pks_hook_arg_cache_filter pika_hook_arg_cache_filter +#define __user_malloc pika_user_malloc +#define __user_free pika_user_free +#define __is_locked_pikaMemory pika_is_locked_pikaMemory + +/* old api */ +#define __platform_socket pika_platform_socket +#define __platform_bind pika_platform_bind +#define __platform_listen pika_platform_listen +#define __platform_accept pika_platform_accept +#define __platform_connect pika_platform_connect +#define __platform_send pika_platform_send +#define __platform_recv pika_platform_recv +#define __platform_gethostname pika_platform_gethostname +#define __platform_getaddrinfo pika_platform_getaddrinfo +#define __platform_freeaddrinfo pika_platform_freeaddrinfo +#define __platform_setsockopt pika_platform_setsockopt +#define __platform_close pika_platform_close +#define __platform_write pika_platform_write +#define __platform_fcntl pika_platform_fcntl + +#define pks_eventLicener_registEvent pks_eventListener_registEvent +#define pks_eventLisener_init pks_eventListener_init +#define pks_eventLisener_getEventHandleObj pks_eventListener_getEventHandleObj +#define pks_eventLisener_sendSignal pks_eventListener_sendSignal +#define pks_eventLisener_deinit pks_eventListener_deinit +#define pks_eventLicener_removeEvent pks_eventListener_removeEvent + +#endif + +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/pika_adapter_rtt.h b/examples/pikapython/pikapython/pikascript-core/pika_adapter_rtt.h new file mode 100644 index 00000000..a8c824c8 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/pika_adapter_rtt.h @@ -0,0 +1,54 @@ +#ifndef __PIKA_ADAPTER_RTT_H__ +#include +#include "PikaPlatform.h" +#define __PIKA_ADAPTER_RTT_H__ + +#define RT_NULL 0 +/* boolean type definitions */ +#define RT_TRUE 1 /**< boolean true */ +#define RT_FALSE 0 /**< boolean fails */ + +#define rt_malloc pika_platform_malloc +#define rt_calloc pika_platform_calloc +#define rt_realloc pika_platform_realloc +#define rt_free pika_platform_free +#define rt_memset pika_platform_memset +#define rt_memcpy pika_platform_memcpy +#define rt_memcmp pika_platform_memcmp +#define rt_kprintf pika_platform_printf +#define rt_snprintf pika_platform_snprintf +#define rt_vsnprintf pika_platform_vsnprintf +#define rt_strdup pika_platform_strdup +#define rt_tick_from_millisecond pika_platform_tick_from_millisecond + +#define rt_int32_t int32_t +#define rt_uint32_t uint32_t +#define rt_int16_t int16_t +#define rt_uint16_t uint16_t +#define rt_int8_t int8_t +#define rt_uint8_t uint8_t +#define rt_int64_t int64_t +#define rt_uint64_t uint64_t +#define rt_size_t size_t +#define rt_bool_t uint8_t + +/* RT-Thread error code definitions */ +#define RT_EOK 0 /**< There is no error */ +#define RT_ERROR 1 /**< A generic error happens */ +#define RT_ETIMEOUT 2 /**< Timed out */ +#define RT_EFULL 3 /**< The resource is full */ +#define RT_EEMPTY 4 /**< The resource is empty */ +#define RT_ENOMEM 5 /**< No memory */ +#define RT_ENOSYS 6 /**< No system */ +#define RT_EBUSY 7 /**< Busy */ +#define RT_EIO 8 /**< IO error */ +#define RT_EINTR 9 /**< Interrupted system call */ +#define RT_EINVAL 10 /**< Invalid argument */ + +#define LOG_E(fmt, ...) pika_platform_printf(fmt "\r\n", ##__VA_ARGS__) +#define LOG_W(...) +#define LOG_D(...) + +#define RT_ASSERT(...) pika_assert(__VA_ARGS__) + +#endif diff --git a/examples/pikapython/pikapython/pikascript-core/pika_config_valid.h b/examples/pikapython/pikapython/pikascript-core/pika_config_valid.h new file mode 100644 index 00000000..cb380317 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-core/pika_config_valid.h @@ -0,0 +1,357 @@ +/* + * This file is part of the PikaScript project. + * http://github.com/pikastech/pikascript + * + * MIT License + * + * Copyright (c) 2021 lyon 李昂 liang6516@outlook.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __PIKA_CFG_VALID_H__ +#define __PIKA_CFG_VALID_H__ + +/* clang-format off */ + +/* + * Don't modify the "pika_config_valid.h" file! + * If you want to change the config, create "pika_config.h", + * then #define PIKA_CONFIG_ENABLE in the Compiler Options. + * To see more: + * https://pikadoc.readthedocs.io/en/latest/%E4%BC%98%E5%8C%96%E5%86%85%E5%AD%98%E5%8D%A0%E7%94%A8%E3%80%81%E9%85%8D%E7%BD%AE%20libc.html + */ + + /* optimize options */ + #define PIKA_OPTIMIZE_SIZE 0 + #define PIKA_OPTIMIZE_SPEED 1 + + /* syntax support level */ + #define PIKA_SYNTAX_LEVEL_MINIMAL 0 + #define PIKA_SYNTAX_LEVEL_MAXIMAL 1 + + /* use user config */ + #ifdef PIKA_CONFIG_ENABLE + #include "pika_config.h" + #endif + + /* default pika_nano_enabled */ + #ifndef PIKA_NANO_ENABLE + #define PIKA_NANO_ENABLE 0 + #endif + + #if PIKA_NANO_ENABLE + #ifndef PIKA_OPTIMIZE + #define PIKA_OPTIMIZE PIKA_OPTIMIZE_SIZE + #endif + + /* default syntax support level */ + #ifndef PIKA_SYNTAX_LEVEL + #define PIKA_SYNTAX_LEVEL PIKA_SYNTAX_LEVEL_MINIMAL + #endif + + + #ifndef PIKA_STRING_UTF8_ENABLE + #define PIKA_STRING_UTF8_ENABLE 0 + #endif + + #endif + + /* default optimize */ + #ifndef PIKA_OPTIMIZE + #define PIKA_OPTIMIZE PIKA_OPTIMIZE_SIZE + #endif + + /* default syntax support level */ + #ifndef PIKA_SYNTAX_LEVEL + #define PIKA_SYNTAX_LEVEL PIKA_SYNTAX_LEVEL_MAXIMAL + #endif + + /* auto config for optimize */ + #if PIKA_OPTIMIZE == PIKA_OPTIMIZE_SIZE + #ifndef PIKA_METHOD_CACHE_ENABLE + #define PIKA_METHOD_CACHE_ENABLE 0 + #endif + + #elif PIKA_OPTIMIZE == PIKA_OPTIMIZE_SPEED + #ifndef PIKA_METHOD_CACHE_ENABLE + #define PIKA_METHOD_CACHE_ENABLE 1 + #endif + #ifndef PIKA_ARG_CACHE_ENABLE + #define PIKA_ARG_CACHE_ENABLE 1 + #endif + #endif + + /* auto config for syntax level */ + #if PIKA_SYNTAX_LEVEL == PIKA_SYNTAX_LEVEL_MINIMAL + #ifndef PIKA_SYNTAX_SLICE_ENABLE + #define PIKA_SYNTAX_SLICE_ENABLE 0 + #endif + + #ifndef PIKA_BUILTIN_STRUCT_ENABLE + #define PIKA_BUILTIN_STRUCT_ENABLE 0 + #endif + + #ifndef PIKA_SYNTAX_FORMAT_ENABLE + #define PIKA_SYNTAX_FORMAT_ENABLE 0 + #endif + + #ifndef PIKA_STD_DEVICE_UNIX_TIME_ENABLE + #define PIKA_STD_DEVICE_UNIX_TIME_ENABLE 0 + #endif + + #ifndef PIKA_SYNTAX_EXCEPTION_ENABLE + #define PIKA_SYNTAX_EXCEPTION_ENABLE 0 + #endif + + #ifndef PIKA_SYNTAX_IMPORT_EX_ENABLE + #define PIKA_SYNTAX_IMPORT_EX_ENABLE 0 + #endif + + #ifndef PIKA_EVENT_ENABLE + #define PIKA_EVENT_ENABLE 0 + #endif + + #ifndef PIKA_FILEIO_ENABLE + #define PIKA_FILEIO_ENABLE 0 + #endif + + #ifndef PIKA_EXEC_ENABLE + #define PIKA_EXEC_ENABLE 0 + #endif + + #elif PIKA_SYNTAX_LEVEL == PIKA_SYNTAX_LEVEL_MAXIMAL + #ifndef PIKA_SYNTAX_SLICE_ENABLE + #define PIKA_SYNTAX_SLICE_ENABLE 1 + #endif + + #ifndef PIKA_BUILTIN_STRUCT_ENABLE + #define PIKA_BUILTIN_STRUCT_ENABLE 1 + #endif + + #ifndef PIKA_SYNTAX_FORMAT_ENABLE + #define PIKA_SYNTAX_FORMAT_ENABLE 1 + #endif + + #ifndef PIKA_STD_DEVICE_UNIX_TIME_ENABLE + #define PIKA_STD_DEVICE_UNIX_TIME_ENABLE 1 + #endif + + #ifndef PIKA_SYNTAX_EXCEPTION_ENABLE + #define PIKA_SYNTAX_EXCEPTION_ENABLE 1 + #endif + + #ifndef PIKA_SYNTAX_IMPORT_EX_ENABLE + #define PIKA_SYNTAX_IMPORT_EX_ENABLE 1 + #endif + + #ifndef PIKA_EVENT_ENABLE + #define PIKA_EVENT_ENABLE 1 + #endif + + #ifndef PIKA_FILEIO_ENABLE + #define PIKA_FILEIO_ENABLE 1 + #endif + + #ifndef PIKA_EXEC_ENABLE + #define PIKA_EXEC_ENABLE 1 + #endif + + #endif + + /* default configuration */ + #ifndef PIKA_LINE_BUFF_SIZE + #define PIKA_LINE_BUFF_SIZE 128 + #endif + + #ifndef PIKA_SPRINTF_BUFF_SIZE + #define PIKA_SPRINTF_BUFF_SIZE 256 + #endif + + #ifndef PIKA_STACK_BUFF_SIZE + #define PIKA_STACK_BUFF_SIZE 256 + #endif + + #ifndef PIKA_NAME_BUFF_SIZE + #define PIKA_NAME_BUFF_SIZE 32 + #endif + + #ifndef PIKA_PATH_BUFF_SIZE + #define PIKA_PATH_BUFF_SIZE 96 + #endif + + #ifndef PIKA_BYTES_DEFAULT_SIZE + #define PIKA_BYTES_DEFAULT_SIZE 64 + #endif + + #ifndef PIKA_ARG_ALIGN_ENABLE + #define PIKA_ARG_ALIGN_ENABLE 1 + #endif + + #ifndef PIKA_METHOD_CACHE_ENABLE + #define PIKA_METHOD_CACHE_ENABLE 0 + #endif + + #ifndef PIKA_BUILTIN_STRUCT_ENABLE + #define PIKA_BUILTIN_STRUCT_ENABLE 0 + #endif + + #ifndef PIKA_READ_FILE_BUFF_SIZE + #define PIKA_READ_FILE_BUFF_SIZE 1024 * 10 + #endif + + #ifndef PIKA_INIT_STRING_ENABLE + #define PIKA_INIT_STRING_ENABLE 0 + #endif + + #ifndef PIKA_SYNTAX_SLICE_ENABLE + #define PIKA_SYNTAX_SLICE_ENABLE 1 + #endif + + #ifndef PIKA_SYNTAX_FORMAT_ENABLE + #define PIKA_SYNTAX_FORMAT_ENABLE 1 + #endif + + #ifndef PIKA_SYNTAX_EXCEPTION_ENABLE + #define PIKA_SYNTAX_EXCEPTION_ENABLE 1 + #endif + + #ifndef PIKA_SYNTAX_IMPORT_EX_ENABLE + #define PIKA_SYNTAX_IMPORT_EX_ENABLE 1 + #endif + + #ifndef PIKA_PLOOC_ENABLE + #define PIKA_PLOOC_ENABLE 0 + #endif + + #ifndef PIKA_STD_DEVICE_UNIX_TIME_ENABLE + #define PIKA_STD_DEVICE_UNIX_TIME_ENABLE 1 + #endif + + #ifndef PIKA_POOL_ENABLE + #define PIKA_POOL_ENABLE 0 + #endif + + #ifndef PIKA_POOL_SIZE + #define PIKA_POOL_SIZE 0x4000 + #endif + + #ifndef PIKA_POOL_ALIGN + #define PIKA_POOL_ALIGN 8 + #endif + + #ifndef PIKA_ASSERT_ENABLE + #define PIKA_ASSERT_ENABLE 0 + #endif + + #ifndef PIKA_EVENT_ENABLE + #define PIKA_EVENT_ENABLE 1 + #endif + + #ifndef PIKA_DEBUG_ENABLE + #define PIKA_DEBUG_ENABLE 0 + #endif + + #ifndef PIKA_FILEIO_ENABLE + #define PIKA_FILEIO_ENABLE 1 + #endif + + #ifndef PIKA_ARG_NUM_MAX + #define PIKA_ARG_NUM_MAX 16 + #endif + + #ifndef PIKA_MATH_ENABLE + #define PIKA_MATH_ENABLE 0 + #endif + + #ifndef PIKA_REGIST_SIZE + #define PIKA_REGIST_SIZE 10 + #endif + + #ifndef PIKA_ARG_BUFF_SIZE + #define PIKA_ARG_BUFF_SIZE 8 + #endif + + #ifndef PIKA_INSTRUCT_HOOK_ENABLE + #define PIKA_INSTRUCT_HOOK_ENABLE 0 + #endif + + #ifndef PIKA_INSTRUCT_HOOK_PERIOD + #define PIKA_INSTRUCT_HOOK_PERIOD 50 + #endif + + #ifndef PIKA_EXEC_ENABLE + #define PIKA_EXEC_ENABLE 1 + #endif + + /* support for UTF-8 in PikaStdData_String */ + #ifndef PIKA_STRING_UTF8_ENABLE + #define PIKA_STRING_UTF8_ENABLE 1 + #endif + + #ifndef PIKA_PRINT_LLD_ENABLE + #define PIKA_PRINT_LLD_ENABLE 1 + #endif + + #ifndef PIKA_FLOAT_TYPE_DOUBLE + #define PIKA_FLOAT_TYPE_DOUBLE 1 + #endif + + #ifndef PIKA_ARG_CACHE_ENABLE + #define PIKA_ARG_CACHE_ENABLE 0 + #endif + + #ifndef PIKA_ARG_CACHE_POOL_SIZE + #define PIKA_ARG_CACHE_POOL_SIZE 32 + #endif + + #ifndef PIKA_ARG_CACHE_SIZE + #define PIKA_ARG_CACHE_SIZE sizeof(Arg) + 16 + #endif + + #ifndef PIKA_SHELL_SAVE_FILE_ENABLE + #define PIKA_SHELL_SAVE_FILE_ENABLE 0 + #endif + + #ifndef PIKA_SHELL_SAVE_FILE_NAME + #define PIKA_SHELL_SAVE_FILE_NAME "pika_shell_save.py" + #endif + + #ifndef PIKA_EVENT_LIST_SIZE + #define PIKA_EVENT_LIST_SIZE 16 + #endif + + #ifndef PIKA_BYTECODE_ONLY_ENABLE + #define PIKA_BYTECODE_ONLY_ENABLE 0 + #endif + + #ifndef PIKA_OLD_API_ENABLE + #define PIKA_OLD_API_ENABLE 1 + #endif + + #ifndef PIKA_FREERTOS_ENABLE + #define PIKA_FREERTOS_ENABLE 0 + #endif + + #ifndef PIKA_LWIP_ENABLE + #define PIKA_LWIP_ENABLE 0 + #endif + + /* configuration validation */ + +#endif diff --git a/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaDebuger_Debuger.c b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaDebuger_Debuger.c new file mode 100644 index 00000000..c3fbd4c4 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaDebuger_Debuger.c @@ -0,0 +1,57 @@ +#include "PikaVM.h" +#include "dataStrs.h" + +extern volatile PikaObj* __pikaMain; +static enum shellCTRL __obj_shellLineHandler_debug( + PikaObj* self, + char* input_line, + struct ShellConfig* config) { + /* continue */ + if (strEqu("c", input_line)) { + return SHELL_CTRL_EXIT; + } + /* next */ + if (strEqu("n", input_line)) { + return SHELL_CTRL_EXIT; + } + /* launch shell */ + if (strEqu("sh", input_line)) { + /* exit pika shell */ + pikaScriptShell((PikaObj*)__pikaMain); + return SHELL_CTRL_CONTINUE; + } + /* quit */ + if (strEqu("q", input_line)) { + obj_setInt(self, "enable", 0); + return SHELL_CTRL_EXIT; + } + /* print */ + if (strIsStartWith(input_line, "p ")) { + char* path = input_line + 2; + Arg* asm_buff = arg_newStr("B0\n1 REF "); + asm_buff = arg_strAppend(asm_buff, path); + asm_buff = arg_strAppend(asm_buff, "\n0 RUN print\n"); + pikaVM_runAsm((PikaObj*)__pikaMain, arg_getStr(asm_buff)); + arg_deinit(asm_buff); + return SHELL_CTRL_CONTINUE; + } + obj_run((PikaObj*)__pikaMain, input_line); + return SHELL_CTRL_CONTINUE; +} + +void PikaDebug_Debuger___init__(PikaObj* self) { + /* global enable contral */ + obj_setInt(self, "enable", 1); +} + +void PikaDebug_Debuger_set_trace(PikaObj* self) { + if (!obj_getInt(self, "enable")) { + return; + } + struct ShellConfig cfg = { + .prefix = "(pika-debug) ", + .handler = __obj_shellLineHandler_debug, + .fn_getchar = __platform_getchar, + }; + _do_pikaScriptShell(self, &cfg); +} diff --git a/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_ByteArray.c b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_ByteArray.c new file mode 100644 index 00000000..585c1665 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_ByteArray.c @@ -0,0 +1,71 @@ +#include "PikaStdData_ByteArray.h" + +void PikaStdData_ByteArray___init__(PikaObj* self, Arg* bytes) { + obj_setArg(self, "raw", bytes); +} + +Arg* PikaStdData_ByteArray___iter__(PikaObj* self) { + obj_setInt(self, "__iter_i", 0); + return arg_newRef(self); +} + +Arg* PikaStdData_ByteArray___next__(PikaObj* self) { + int __iter_i = args_getInt(self->list, "__iter_i"); + uint8_t* data = obj_getBytes(self, "raw"); + uint16_t len = obj_getBytesSize(self, "raw"); + Arg* res = NULL; + char char_buff[] = " "; + if (__iter_i < len) { + char_buff[0] = data[__iter_i]; + res = arg_newInt(char_buff[0]); + } else { + return arg_newNull(); + } + args_setInt(self->list, "__iter_i", __iter_i + 1); + return res; +} + +int PikaStdData_ByteArray___getitem__(PikaObj* self, int __key) { + uint8_t* data = obj_getBytes(self, "raw"); + uint16_t len = obj_getBytesSize(self, "raw"); + if (__key < len) { + return data[__key]; + } else { + return 0; + } +} + +void PikaStdData_ByteArray___setitem__(PikaObj* self, int __key, int __val) { + uint8_t* data = obj_getBytes(self, "raw"); + uint16_t len = obj_getBytesSize(self, "raw"); + if (__key < len) { + data[__key] = __val; + } +} + +char* PikaStdData_ByteArray___str__(PikaObj* self) { + uint8_t* data = obj_getBytes(self, "raw"); + uint16_t len = obj_getBytesSize(self, "raw"); + Arg* str_arg = arg_newStr(""); + str_arg = arg_strAppend(str_arg, "bytearray(b'"); + for (int i = 0; i < len; i++) { + char u8_str[] = "\\x00"; + uint8_t u8 = data[i]; + __platform_sprintf(u8_str, "\\x%02x", u8); + str_arg = arg_strAppend(str_arg, u8_str); + } + str_arg = arg_strAppend(str_arg, "')"); + obj_removeArg(self, "_buf"); + obj_setStr(self, "_buf", arg_getStr(str_arg)); + arg_deinit(str_arg); + return obj_getStr(self, "_buf"); +} + +char* PikaStdData_ByteArray_decode(PikaObj* self) { + uint8_t* data = obj_getBytes(self, "raw"); + Arg* str_arg = arg_newStr((char*)data); + obj_removeArg(self, "_buf"); + obj_setStr(self, "_buf", arg_getStr(str_arg)); + arg_deinit(str_arg); + return obj_getStr(self, "_buf"); +} diff --git a/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_Dict.c b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_Dict.c new file mode 100644 index 00000000..63447c25 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_Dict.c @@ -0,0 +1,293 @@ +#include "PikaStdData_Dict.h" +#include "BaseObj.h" +#include "PikaObj.h" +#include "PikaStdData_Tuple.h" +#include "PikaStdData_dict_items.h" +#include "PikaStdData_dict_keys.h" +#include "PikaStdLib_SysObj.h" +#include "dataStrs.h" + +Arg* PikaStdData_Dict_get(PikaObj* self, char* key) { + PikaDict* dict = obj_getPtr(self, "dict"); + Arg* res = pikaDict_getArg(dict, key); + if (NULL == res) { + obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR); + __platform_printf("KeyError: %s\n", key); + } + return arg_copy(res); +} + +void PikaStdData_Dict___init__(PikaObj* self) { + __vm_Dict___init__(self); +} + +void PikaStdData_Dict_set(PikaObj* self, char* key, Arg* arg) { + __vm_Dict_set(self, arg, key); +} + +void PikaStdData_Dict_remove(PikaObj* self, char* key) { + PikaDict* dict = obj_getPtr(self, "dict"); + PikaDict* keys = obj_getPtr(self, "_keys"); + pikaDict_removeArg(dict, pikaDict_getArg(dict, key)); + pikaDict_removeArg(keys, pikaDict_getArg(keys, key)); +} + +Arg* PikaStdData_Dict___iter__(PikaObj* self) { + obj_setInt(self, "__iter_i", 0); + return arg_newRef(self); +} + +Arg* PikaStdData_Dict___next__(PikaObj* self) { + int __iter_i = args_getInt(self->list, "__iter_i"); + PikaDict* keys = obj_getPtr(self, "_keys"); + Arg* res = arg_copy(args_getArgByIndex(&keys->super, __iter_i)); + if (NULL == res) { + return arg_newNull(); + } + args_setInt(self->list, "__iter_i", __iter_i + 1); + return res; +} + +void PikaStdData_Dict___setitem__(PikaObj* self, Arg* __key, Arg* __val) { + PikaStdData_Dict_set(self, obj_getStr(self, "__key"), + obj_getArg(self, "__val")); +} + +Arg* PikaStdData_Dict___getitem__(PikaObj* self, Arg* __key) { + return PikaStdData_Dict_get(self, obj_getStr(self, "__key")); +} + +void PikaStdData_Dict___del__(PikaObj* self) { + PikaDict* dict = obj_getPtr(self, "dict"); + PikaDict* keys = obj_getPtr(self, "_keys"); + pikaDict_deinit(dict); + if (NULL != keys) { + pikaDict_deinit(keys); + } +} + +void PikaStdData_dict_keys___init__(PikaObj* self, PikaObj* dict) { + obj_setPtr(self, "dictptr", dict); +} + +PikaObj* PikaStdData_Dict_keys(PikaObj* self) { + PikaObj* dict_keys = newNormalObj(New_PikaStdData_dict_keys); + PikaStdData_dict_keys___init__(dict_keys, self); + return dict_keys; +} + +PikaObj* PikaStdData_Dict_items(PikaObj* self) { + PikaObj* dict_items = newNormalObj(New_PikaStdData_dict_items); + PikaStdData_dict_keys___init__(dict_items, self); + return dict_items; +} + +Arg* PikaStdData_dict_keys___iter__(PikaObj* self) { + obj_setInt(self, "__iter_i", 0); + return arg_newRef(self); +} + +Arg* PikaStdData_dict_keys___next__(PikaObj* self) { + int __iter_i = args_getInt(self->list, "__iter_i"); + PikaObj* dictptr = obj_getPtr(self, "dictptr"); + PikaDict* keys = obj_getPtr(dictptr, "_keys"); + Arg* res = arg_copy(args_getArgByIndex(&keys->super, __iter_i)); + if (NULL == res) { + return arg_newNull(); + } + args_setInt(self->list, "__iter_i", __iter_i + 1); + return res; +} + +char* PikaStdLib_SysObj_str(PikaObj* self, Arg* arg); +char* PikaStdData_dict_keys___str__(PikaObj* self) { + Arg* str_arg = arg_newStr("dict_keys(["); + PikaObj* dictptr = obj_getPtr(self, "dictptr"); + PikaDict* keys = obj_getPtr(dictptr, "_keys"); + + int i = 0; + while (PIKA_TRUE) { + Arg* item = args_getArgByIndex(&keys->super, i); + if (NULL == item) { + break; + } + if (i != 0) { + str_arg = arg_strAppend(str_arg, ", "); + } + char* item_str = PikaStdLib_SysObj_str(self, item); + if (arg_getType(item) == ARG_TYPE_STRING) { + str_arg = arg_strAppend(str_arg, "'"); + } + str_arg = arg_strAppend(str_arg, item_str); + if (arg_getType(item) == ARG_TYPE_STRING) { + str_arg = arg_strAppend(str_arg, "'"); + } + i++; + } + + str_arg = arg_strAppend(str_arg, "])"); + obj_setStr(self, "_buf", arg_getStr(str_arg)); + arg_deinit(str_arg); + return obj_getStr(self, "_buf"); +} + +char* PikaStdData_Dict___str__(PikaObj* self) { + Arg* str_arg = arg_newStr("{"); + + PikaDict* keys = obj_getPtr(self, "_keys"); + PikaDict* dict = obj_getPtr(self, "dict"); + pika_assert(NULL != dict); + pika_assert(NULL != keys); + + int i = 0; + while (PIKA_TRUE) { + Arg* item_key = args_getArgByIndex(&keys->super, i); + Arg* item_val = args_getArgByIndex(&dict->super, i); + if (NULL == item_key) { + break; + } + if (i != 0) { + str_arg = arg_strAppend(str_arg, ", "); + } + char* key_str = PikaStdLib_SysObj_str(self, item_key); + str_arg = arg_strAppend(str_arg, "'"); + str_arg = arg_strAppend(str_arg, key_str); + str_arg = arg_strAppend(str_arg, "'"); + str_arg = arg_strAppend(str_arg, ": "); + + char* val_str = PikaStdLib_SysObj_str(self, item_val); + if (arg_getType(item_val) == ARG_TYPE_STRING) { + str_arg = arg_strAppend(str_arg, "'"); + } + str_arg = arg_strAppend(str_arg, val_str); + if (arg_getType(item_val) == ARG_TYPE_STRING) { + str_arg = arg_strAppend(str_arg, "'"); + } + i++; + } + + str_arg = arg_strAppend(str_arg, "}"); + obj_setStr(self, "_buf", arg_getStr(str_arg)); + arg_deinit(str_arg); + return obj_getStr(self, "_buf"); +} + +int PikaStdData_Dict___len__(PikaObj* self) { + PikaDict* dict = obj_getPtr(self, "dict"); + return args_getSize(&dict->super); +} + +int PikaStdData_dict_keys___len__(PikaObj* self) { + PikaObj* dictptr = obj_getPtr(self, "dictptr"); + PikaDict* keys = obj_getPtr(dictptr, "_keys"); + return args_getSize(&keys->super); +} + +int dict_contains(PikaDict* dict, Arg* key) { + int i = 0; + while (PIKA_TRUE) { + Arg* item = args_getArgByIndex(&dict->super, i); + if (NULL == item) { + break; + } + if (arg_isEqual(item, key)) { + return PIKA_TRUE; + } + i++; + } + return PIKA_FALSE; +} + +int PikaStdData_Dict___contains__(PikaObj* self, Arg* val) { + PikaDict* dict = obj_getPtr(self, "_keys"); + return dict_contains(dict, val); +} + +Arg* PikaStdData_dict_items___iter__(PikaObj* self) { + obj_setInt(self, "__iter_i", 0); + return arg_newRef(self); +} + +int PikaStdData_dict_items___len__(PikaObj* self) { + PikaObj* dictptr = obj_getPtr(self, "dictptr"); + PikaDict* keys = obj_getPtr(dictptr, "_keys"); + return args_getSize(&keys->super); +} + +Arg* PikaStdData_dict_items___next__(PikaObj* self) { + int __iter_i = args_getInt(self->list, "__iter_i"); + PikaObj* dictptr = obj_getPtr(self, "dictptr"); + PikaDict* keys = obj_getPtr(dictptr, "_keys"); + PikaDict* dict = obj_getPtr(dictptr, "dict"); + Arg* key = args_getArgByIndex(&keys->super, __iter_i); + Arg* val = args_getArgByIndex(&dict->super, __iter_i); + if (NULL == key) { + return arg_newNull(); + } + PikaObj* tuple = newNormalObj(New_PikaStdData_Tuple); + PikaStdData_Tuple___init__(tuple); + PikaList* list = obj_getPtr(tuple, "list"); + pikaList_append(list, key); + pikaList_append(list, val); + args_setInt(self->list, "__iter_i", __iter_i + 1); + return arg_newObj(tuple); +} + +char* PikaStdData_dict_items___str__(PikaObj* self) { + Arg* str_arg = arg_newStr("dict_items(["); + int i = 0; + obj_setInt(self, "__iter_i", 0); + while (PIKA_TRUE) { + Arg* item = PikaStdData_dict_items___next__(self); + if (arg_getType(item) == ARG_TYPE_NONE) { + arg_deinit(item); + break; + } + if (i != 0) { + str_arg = arg_strAppend(str_arg, ", "); + } + char* item_str = PikaStdLib_SysObj_str(self, item); + str_arg = arg_strAppend(str_arg, item_str); + i++; + arg_deinit(item); + } + str_arg = arg_strAppend(str_arg, "])"); + obj_setStr(self, "_buf", arg_getStr(str_arg)); + arg_deinit(str_arg); + return obj_getStr(self, "_buf"); +} + +void PikaStdData_Dict_update(PikaObj* self, PikaObj* other) { + PikaObj* context = newNormalObj(New_PikaStdLib_SysObj); + obj_setRef(context, "@other", other); + obj_setRef(context, "@self", self); + /* clang-format off */ + PIKA_PYTHON( + for @item in @other: + @self[@item] = @other[@item] + + ) + /* clang-format on */ + const uint8_t + bytes[] = + { + 0x40, 0x00, 0x00, 0x00,/* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x04, + 0x0d, 0x00, 0x00, 0x82, 0x11, 0x00, 0x00, 0x04, 0x1e, 0x00, + 0x00, 0x0d, 0x1e, 0x00, 0x00, 0x07, 0x24, 0x00, 0x11, 0x81, + 0x26, 0x00, 0x11, 0x01, 0x1e, 0x00, 0x21, 0x01, 0x01, 0x00, + 0x21, 0x01, 0x1e, 0x00, 0x11, 0x1d, 0x00, 0x00, 0x01, 0x02, + 0x2c, 0x00, 0x01, 0x04, 0x26, 0x00, 0x00, 0x86, 0x38, 0x00, + 0x00, 0x8c, 0x0d, 0x00, /* instruct array */ + 0x3b, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x40, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x00, 0x69, 0x74, + 0x65, 0x72, 0x00, 0x24, 0x6c, 0x30, 0x00, 0x24, 0x6c, 0x30, + 0x2e, 0x5f, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x5f, 0x00, + 0x40, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x32, 0x00, 0x40, 0x73, + 0x65, 0x6c, 0x66, 0x00, 0x5f, 0x5f, 0x73, 0x65, 0x74, 0x69, + 0x74, 0x65, 0x6d, 0x5f, 0x5f, 0x00, 0x2d, 0x31, 0x00, /* const + pool */ + }; + pikaVM_runByteCode(context, (uint8_t*)bytes); + obj_deinit(context); +} diff --git a/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_FILEIO.c b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_FILEIO.c new file mode 100644 index 00000000..38b54a9f --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_FILEIO.c @@ -0,0 +1,247 @@ +#include "PikaStdData_FILEIO.h" +#include +#include "PikaCompiler.h" +#include "PikaStdData_List.h" + +typedef struct { + uint8_t* addr; + size_t size; + size_t pos; +} PIKAFS_FILE; + +int PikaStdData_FILEIO_init(PikaObj* self, char* path, char* mode) { + if (obj_isArgExist(self, "_f")) { + /* already initialized */ + return 0; + } + if (strIsStartWith(path, "pikafs/")) { + PIKAFS_FILE* f = (PIKAFS_FILE*)pikaMalloc(sizeof(PIKAFS_FILE)); + memset(f, 0, sizeof(PIKAFS_FILE)); + extern volatile PikaObj* __pikaMain; + uint8_t* library_bytes = obj_getPtr((PikaObj*)__pikaMain, "@libraw"); + if (NULL == library_bytes) { + return 1; + } + char* file_name = path + 7; + if (PIKA_RES_OK != _loadModuleDataWithName(library_bytes, file_name, + &f->addr, &f->size)) { + return 1; + } + obj_setInt(self, "pikafs", PIKA_TRUE); + obj_setPtr(self, "_f", f); + obj_setStr(self, "_mode", mode); + return 0; + } + FILE* f = __platform_fopen(path, mode); + if (f == NULL) { + return 1; + } + obj_setPtr(self, "_f", f); + obj_setStr(self, "_mode", mode); + return 0; +} + +void PikaStdData_FILEIO_close(PikaObj* self) { + if (PIKA_TRUE == obj_getInt(self, "pikafs")) { + PIKAFS_FILE* f = obj_getPtr(self, "_f"); + if (NULL == f) { + return; + } + pikaFree(f, sizeof(PIKAFS_FILE)); + obj_setPtr(self, "_f", NULL); + return; + } + FILE* f = obj_getPtr(self, "_f"); + if (NULL == f) { + return; + } + __platform_fclose(f); + obj_setPtr(self, "_f", NULL); +} + +size_t _pikafs_fread(void* buf, size_t size, size_t count, PIKAFS_FILE* f) { + if (f->pos >= f->size) { + return 0; + } + if (f->pos + size * count > f->size) { + count = (f->size - f->pos) / size; + } + __platform_memcpy(buf, f->addr + f->pos, size * count); + f->pos += size * count; + return count; +} + +Arg* PikaStdData_FILEIO_read(PikaObj* self, PikaTuple* size_) { + int size = 0; + if (pikaTuple_getSize(size_) == 0) { + size = -1; + } else { + size = pikaTuple_getInt(size_, 0); + } + if (size <= 0) { + /* read all */ + size = PIKA_READ_FILE_BUFF_SIZE; + } + Arg* buf_arg = arg_newBytes(NULL, size); + uint8_t* buf = arg_getBytes(buf_arg); + int n = 0; + /* read */ + if (PIKA_TRUE == obj_getInt(self, "pikafs")) { + PIKAFS_FILE* f = obj_getPtr(self, "_f"); + if (NULL == f) { + return NULL; + } + n = _pikafs_fread(buf, 1, size, f); + } else { + FILE* f = obj_getPtr(self, "_f"); + if (f == NULL) { + return NULL; + } + n = __platform_fread(buf, 1, size, f); + } + if (n < size) { + /* EOF */ + buf[n] = '\0'; + } + char* mode = obj_getStr(self, "_mode"); + if (strIsContain(mode, 'b')) { + /* binary */ + Arg* res = arg_newBytes(buf, n); + arg_deinit(buf_arg); + return res; + } else { + /* text */ + Arg* res = arg_newStr((char*)buf); + arg_deinit(buf_arg); + return res; + } +} + +int PikaStdData_FILEIO_write(PikaObj* self, Arg* s) { + if (PIKA_TRUE == obj_getInt(self, "pikafs")) { + return 1; + } + FILE* f = obj_getPtr(self, "_f"); + int res = -1; + if (f == NULL) { + obj_setErrorCode(self, PIKA_RES_ERR_IO); + __platform_printf("Error: can't write to file\n"); + return res; + } + char* mode = obj_getStr(self, "_mode"); + if (strIsContain(mode, 'b')) { + if (arg_getType(s) != ARG_TYPE_BYTES) { + __platform_printf( + "TypeError: a bytes-like object is required, not 'str'\r\n"); + obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM); + return -1; + } + /* binary */ + res = __platform_fwrite(arg_getBytes(s), 1, arg_getBytesSize(s), f); + } else { + /* text */ + char* str = arg_getStr(s); + res = __platform_fwrite(str, 1, strlen(str), f); + } + return res; +} + +int PikaStdData_FILEIO_seek(PikaObj* self, int offset, PikaTuple* fromwhere) { + FILE* f = obj_getPtr(self, "_f"); + if (f == NULL) { + obj_setErrorCode(self, PIKA_RES_ERR_IO); + __platform_printf("Error: can't seek in file\n"); + return -1; + } + if (pikaTuple_getSize(fromwhere) == 1) { + int whence = pikaTuple_getInt(fromwhere, 0); + __platform_fseek(f, offset, whence); + return __platform_ftell(f); + } + __platform_fseek(f, offset, 0); + return __platform_ftell(f); +} + +int PikaStdData_FILEIO_tell(PikaObj* self) { + FILE* f = obj_getPtr(self, "_f"); + if (f == NULL) { + obj_setErrorCode(self, PIKA_RES_ERR_IO); + __platform_printf("Error: can't tell in file\n"); + return -1; + } + return __platform_ftell(f); +} + +char* PikaStdData_FILEIO_readline(PikaObj* self) { + FILE* f = obj_getPtr(self, "_f"); + if (f == NULL) { + obj_setErrorCode(self, PIKA_RES_ERR_IO); + __platform_printf("Error: can't read line from file\n"); + return NULL; + } + obj_setBytes(self, "_line_buff", NULL, PIKA_LINE_BUFF_SIZE); + char* line_buff = (char*)obj_getBytes(self, "_line_buff"); + while (1) { + char char_buff[2] = {0}; + int n = __platform_fread(char_buff, 1, 1, f); + if (n == 0) { + /* EOF */ + return NULL; + } + if (char_buff[0] == '\n') { + /* end of line */ + strAppend(line_buff, char_buff); + return line_buff; + } + if (strGetSize(line_buff) >= PIKA_LINE_BUFF_SIZE) { + /* line too long */ + obj_setErrorCode(self, PIKA_RES_ERR_IO); + __platform_printf("Error: line too long\n"); + return NULL; + } + strAppend(line_buff, char_buff); + } +} + +PikaObj* PikaStdData_FILEIO_readlines(PikaObj* self) { + FILE* f = obj_getPtr(self, "_f"); + if (f == NULL) { + obj_setErrorCode(self, PIKA_RES_ERR_IO); + __platform_printf("Error: can't read lines from file\n"); + return NULL; + } + PikaObj* line_list = newNormalObj(New_PikaStdData_List); + PikaStdData_List___init__(line_list); + while (1) { + char* line = PikaStdData_FILEIO_readline(self); + if (line == NULL) { + break; + } + Arg* arg_str = arg_newStr(line); + PikaStdData_List_append(line_list, arg_str); + arg_deinit(arg_str); + } + return line_list; +} + +void PikaStdData_FILEIO_writelines(PikaObj* self, PikaObj* lines) { + FILE* f = obj_getPtr(self, "_f"); + if (f == NULL) { + obj_setErrorCode(self, PIKA_RES_ERR_IO); + __platform_printf("Error: can't write lines to file\n"); + return; + } + PikaList* list = obj_getPtr(lines, "list"); + if (list == NULL) { + obj_setErrorCode(self, PIKA_RES_ERR_IO); + __platform_printf("Error: can't write lines to file\n"); + return; + } + for (size_t i = 0; i < pikaList_getSize(list); i++) { + char* line = pikaList_getStr(list, i); + Arg* arg_str = arg_newStr(line); + PikaStdData_FILEIO_write(self, arg_str); + arg_deinit(arg_str); + } + return; +} diff --git a/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_List.c b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_List.c new file mode 100644 index 00000000..f5c10e98 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_List.c @@ -0,0 +1,98 @@ +#include "PikaStdData_List.h" +#include "BaseObj.h" +#include "PikaObj.h" +#include "PikaStdData_Tuple.h" +#include "dataStrs.h" + +void PikaStdData_List_append(PikaObj* self, Arg* arg) { + __vm_List_append(self, arg); +} + +void PikaStdData_List_set(PikaObj* self, int i, Arg* arg) { + PikaList* list = obj_getPtr(self, "list"); + if (PIKA_RES_OK != pikaList_setArg(list, i, arg)) { + obj_setErrorCode(self, 1); + obj_setSysOut(self, "Error: index exceeded lengh of list."); + } +} + +void PikaStdData_List___setitem__(PikaObj* self, Arg* __key, Arg* __val) { + PikaStdData_List_set(self, obj_getInt(self, "__key"), + obj_getArg(self, "__val")); +} + +void PikaStdData_List___init__(PikaObj* self) { + __vm_List___init__(self); +} + +char* PikaStdLib_SysObj_str(PikaObj* self, Arg* arg); +char* PikaStdData_List___str__(PikaObj* self) { + Arg* str_arg = arg_newStr("["); + PikaList* list = obj_getPtr(self, "list"); + + int i = 0; + while (PIKA_TRUE) { + Arg* item = pikaList_getArg(list, i); + if (NULL == item) { + break; + } + if (i != 0) { + str_arg = arg_strAppend(str_arg, ", "); + } + char* item_str = PikaStdLib_SysObj_str(self, item); + if (arg_getType(item) == ARG_TYPE_STRING) { + str_arg = arg_strAppend(str_arg, "'"); + } + str_arg = arg_strAppend(str_arg, item_str); + if (arg_getType(item) == ARG_TYPE_STRING) { + str_arg = arg_strAppend(str_arg, "'"); + } + i++; + } + + str_arg = arg_strAppend(str_arg, "]"); + obj_setStr(self, "_buf", arg_getStr(str_arg)); + arg_deinit(str_arg); + return obj_getStr(self, "_buf"); +} + +void PikaStdData_List_reverse(PikaObj* self) { + PikaList* list = obj_getPtr(self, "list"); + pikaList_reverse(list); +} + +PikaObj* PikaStdData_List___add__(PikaObj* self, PikaObj* others) { + PikaObj* res = newNormalObj(New_PikaStdData_List); + PikaStdData_List___init__(res); + PikaList* list_res = obj_getPtr(res, "list"); + PikaList* list1 = obj_getPtr(self, "list"); + PikaList* list2 = obj_getPtr(others, "list"); + for (size_t i = 0; i < pikaList_getSize(list1); i++) { + Arg* arg = pikaList_getArg(list1, i); + pikaList_append(list_res, arg); + } + for (size_t i = 0; i < pikaList_getSize(list2); i++) { + Arg* arg = pikaList_getArg(list2, i); + pikaList_append(list_res, arg); + } + return res; +} + +void PikaStdData_List_insert(PikaObj *self, int i, Arg* arg){ + PikaList* list = obj_getPtr(self, "list"); + if (PIKA_RES_OK != pikaList_insert(list, i, arg)) { + obj_setErrorCode(self, 1); + obj_setSysOut(self, "Error: index exceeded lengh of list."); + } +} + +Arg* PikaStdData_List_pop(PikaObj *self){ + PikaList* list = obj_getPtr(self, "list"); + return pikaList_pop(list); +} + +void PikaStdData_List_remove(PikaObj *self, Arg* val){ + PikaList* list = obj_getPtr(self, "list"); + pikaList_remove(list, val); +} + diff --git a/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_String.c b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_String.c new file mode 100644 index 00000000..6dc463ef --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_String.c @@ -0,0 +1,817 @@ +#include "PikaStdData_String.h" +#include "PikaStdData_List.h" +#include "PikaStdData_String_Util.h" +#include "dataStrs.h" + +char* _strlwr(char* str); +static int string_len(char* str); + +Arg* PikaStdData_String___iter__(PikaObj* self) { + obj_setInt(self, "__iter_i", 0); + return arg_newRef(self); +} + +void PikaStdData_String_set(PikaObj* self, char* s) { +#if PIKA_STRING_UTF8_ENABLE + int r = _valid_utf8(s, -1); + if (r >= 0) { + obj_setErrorCode(self, __LINE__); + __platform_printf("Error invaliad character %x\r\n", s[r]); + return; + } +#endif + obj_setStr(self, "str", s); +} + +void PikaStdData_String___init__(PikaObj* self, char* s) { +#if PIKA_STRING_UTF8_ENABLE + int r = _valid_utf8(s, -1); + if (r >= 0) { + obj_setErrorCode(self, __LINE__); + __platform_printf("Error invaliad character %x\r\n", s[r]); + return; + } +#endif + PikaStdData_String_set(self, s); +} + +char* PikaStdData_String_get(PikaObj* self) { + return obj_getStr(self, "str"); +} + +Arg* PikaStdData_String___next__(PikaObj* self) { + int __iter_i = args_getInt(self->list, "__iter_i"); + char* str = obj_getStr(self, "str"); + uint16_t len = strGetSize(str); +#if PIKA_STRING_UTF8_ENABLE + char char_buff[5]; + int r = _utf8_get(str, len, __iter_i, char_buff); + if (r < 0) { + return arg_newNull(); + } + args_setInt(self->list, "__iter_i", __iter_i + 1); + return arg_newStr((char*)char_buff); +#else + Arg* res = NULL; + char char_buff[] = " "; + if (__iter_i < len) { + char_buff[0] = str[__iter_i]; + res = arg_newStr((char*)char_buff); + } else { + return arg_newNull(); + } + args_setInt(self->list, "__iter_i", __iter_i + 1); + return res; +#endif +} + +static int _str_get(char* str, int key_i, char* char_buff) { + uint16_t len = strGetSize(str); + if (key_i < 0) { + key_i = string_len(str) + key_i; + } +#if PIKA_STRING_UTF8_ENABLE + return _utf8_get(str, len, key_i, char_buff); +#else + if (key_i < len) { + char_buff[0] = str[key_i]; + return 0; + } + return -1; +#endif +} + +char* string_slice(Args* outBuffs, char* str, int start, int end) { + char* res = args_getBuff(outBuffs, strGetSize(str)); + if (start < 0) { + start += string_len(str); + } + /* magic code, to the end */ + if (end == -99999) { + end = string_len(str); + } + if (end < 0) { + end += string_len(str); + } + for (int i = start; i < end; i++) { + char char_buff[5] = {0}; + int r = _str_get(str, i, char_buff); + if (r < 0) { + return NULL; + } + res = strAppend(res, char_buff); + } + return res; +} + +Arg* PikaStdData_String___getitem__(PikaObj* self, Arg* __key) { + int key_i = arg_getInt(__key); + char* str = obj_getStr(self, "str"); + char char_buff[5] = {0}; + int r = _str_get(str, key_i, char_buff); + if (r < 0) { + return arg_newNull(); + } + return arg_newStr((char*)char_buff); +} + +void PikaStdData_String___setitem__(PikaObj* self, Arg* __key, Arg* __val) { + int key_i = arg_getInt(__key); + char* str = obj_getStr(self, "str"); + char* val = arg_getStr(__val); + uint16_t len = strGetSize(str); +#if PIKA_STRING_UTF8_ENABLE + int len2 = strlen(val); + int is_invalid = _valid_utf8(val, len2); + if (is_invalid >= 0) { + obj_setErrorCode(self, __LINE__); + __platform_printf("Error String invalid\r\n"); + return; + } + int ulen_val = _utf8_strlen(val, len2); + if (ulen_val != 1) { + obj_setErrorCode(self, __LINE__); + __platform_printf("Error String invalid char\r\n"); + return; + } + int char_len; + int repl_at = _utf8_get_offset(str, len, key_i, &char_len); + if (repl_at < 0) { + obj_setErrorCode(self, __LINE__); + __platform_printf("Error String Overflow\r\n"); + return; + } + int ok = __str_repl(self, str, len, repl_at, char_len, val, len2); + if (ok < 0) { + obj_setErrorCode(self, __LINE__); + __platform_printf("Error. Internal error(-%d)\r\n", __LINE__); + return; + } +#else + if (key_i >= len) { + obj_setErrorCode(self, 1); + __platform_printf("Error String Overflow\r\n"); + return; + } + str[key_i] = val[0]; +#endif +} + +char* PikaStdData_String___str__(PikaObj* self) { + return obj_getStr(self, "str"); +} + +int PikaStdData_String_startswith(PikaObj* self, char* prefix) { + char* str = obj_getStr(self, "str"); + char* p = prefix; + int i = 0; + while (*p != '\0') { + if (*p != str[i]) + return 0; + p++; + i++; + } + return 1; +} + +int PikaStdData_String_endswith(PikaObj* self, char* suffix) { + char* str = obj_getStr(self, "str"); + int len1 = strlen(str); + int len2 = strlen(suffix); + while (len2 >= 1) { + if (suffix[len2 - 1] != str[len1 - 1]) + return 0; + len2--; + len1--; + } + return 1; +} + +int PikaStdData_String_isdigit(PikaObj* self) { + char* str = obj_getStr(self, "str"); + int i = 0; + while (str[i] != '\0') { + if (!isdigit((int)str[i])) + return 0; + i++; + } + return 1; +} + +int PikaStdData_String_islower(PikaObj* self) { + char* str = obj_getStr(self, "str"); + int i = 0; + while (str[i] != '\0') { + if (!islower((int)str[i])) + return 0; + i++; + } + return 1; +} + +int PikaStdData_String_isalnum(PikaObj* self) { + char* str = obj_getStr(self, "str"); + int i = 0; + while (str[i] != '\0') { + if (!isalnum((int)str[i])) + return 0; + i++; + } + return 1; +} + +int PikaStdData_String_isalpha(PikaObj* self) { + char* str = obj_getStr(self, "str"); + int i = 0; + while (str[i] != '\0') { + if (!isalpha((int)str[i])) + return 0; + i++; + } + return 1; +} + +int PikaStdData_String_isspace(PikaObj* self) { + char* str = obj_getStr(self, "str"); + int i = 0; + while (str[i] != '\0') { + if (!isspace((int)str[i])) + return 0; + i++; + } + return 1; +} + +PikaObj* PikaStdData_String_split(PikaObj* self, char* s) { + /* 创建 list 对象 */ + PikaObj* list = newNormalObj(New_PikaStdData_List); + /* 初始化 list */ + PikaStdData_List___init__(list); + + Args buffs = {0}; + char* str = strsCopy(&buffs, obj_getStr(self, "str")); + + char sign = s[0]; + int token_num = strCountSign(str, sign) + 1; + + for (int i = 0; i < token_num; i++) { + char* token = strsPopToken(&buffs, &str, sign); + /* 用 arg_set 的 api 创建 arg */ + Arg* token_arg = arg_newStr(token); + /* 添加到 list 对象 */ + PikaStdData_List_append(list, token_arg); + /* 销毁 arg */ + arg_deinit(token_arg); + } + + strsDeinit(&buffs); + return list; +} + +static int string_len(char* str) { +#if PIKA_STRING_UTF8_ENABLE + int n = _utf8_strlen(str, -1); + return n; +#else + return strGetSize(str); +#endif +} + +int PikaStdData_String___len__(PikaObj* self) { + char* str = obj_getStr(self, "str"); + int n = string_len(str); + if (n < 0) { + obj_setErrorCode(self, __LINE__); + __platform_printf("Error. Internal error(%d)\r\n", __LINE__); + } + return n; +} + +char* PikaStdData_String_strip(PikaObj* self, PikaTuple* chrs) { + Args buffs = {0}; + char to_strip = ' '; + if (pikaTuple_getSize(chrs) > 1) { + obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM); + obj_setSysOut(self, "Error. Invalid param"); + } + if (pikaTuple_getSize(chrs) == 1) { + char* ch_str = pikaTuple_getStr(chrs, 0); + to_strip = ch_str[0]; + } + char* str = strsCopy(&buffs, obj_getStr(self, "str")); + /* strip */ + char* str_start = str; + size_t len = strlen(str); + for (size_t i = 0; i < len; i++) { + if (str[i] != to_strip) { + str_start = (char*)(str + i); + break; + } + } + + len = strlen(str); + for (int i = len - 1; i >= 0; i--) { + if (str[i] != to_strip) { + str[i + 1] = '\0'; + break; + } + } + + obj_setStr(self, "_buf", str_start); + strsDeinit(&buffs); + return obj_getStr(self, "_buf"); +} + +char* PikaStdData_String_replace(PikaObj* self, char* old, char* new) { + Args buffs = {0}; + char* str = strsCopy(&buffs, obj_getStr(self, "str")); + str = strsReplace(&buffs, str, old, new); + obj_setStr(self, "_buf", str); + strsDeinit(&buffs); + return obj_getStr(self, "_buf"); +} + +Arg* PikaStdData_String_encode(PikaObj* self, PikaTuple* encoding) { + char* str = obj_getStr(self, "str"); + +#if PIKA_STRING_UTF8_ENABLE + char* to_code = NULL; + int argn = pikaTuple_getSize(encoding); + if (argn < 1) { + return arg_newBytes((uint8_t*)str, strGetSize(str)); + } + Arg* arg_i = pikaTuple_getArg(encoding, 0); + if (arg_getType(arg_i) != ARG_TYPE_STRING) { + obj_setErrorCode(self, __LINE__); + __platform_printf("Error invaliad arguments\r\n"); + return NULL; + } + to_code = arg_getStr(arg_i); + _strlwr(to_code); + Arg* res = _str_encode(str, to_code); + if (!res) { + obj_setErrorCode(self, __LINE__); + __platform_printf("Error internal error\r\n"); + return NULL; + } + return res; +#else + return arg_newBytes((uint8_t*)str, strGetSize(str)); +#endif +} + +#if PIKA_STRING_UTF8_ENABLE + +static const uint8_t _pcre_utf8_table4[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; + +const char mask1 = 0x80; +const char mask2 = 0xc0; +const char mask3 = 0xe0; +const char mask4 = 0xf0; + +const char nmask1 = 0x3f; +const char nmask2 = 0x1f; +const char nmask3 = 0x0f; +const char nmask4 = 0x07; + +int _valid_utf8(const char* string, int length) { + const uint8_t* p; + if (length < 0) { + length = strlen(string); + } + + for (p = (const uint8_t*)string; length-- > 0; p++) { + int ab; + int c = *p; + if (!(c & 0x80)) + continue; + if (c < 0xc0) + return (uintptr_t)p - (uintptr_t)string; + ab = _pcre_utf8_table4[c & 0x3f]; + if (length < ab || ab > 3) + return (uintptr_t)p - (uintptr_t)string; + length -= ab; + if ((*(++p) & 0xc0) != 0x80) + return (uintptr_t)p - (uintptr_t)string; + switch (ab) { + case 1: + if ((c & 0x3e) == 0) + return (uintptr_t)p - (uintptr_t)string; + continue; + case 2: + if ((c == 0xe0 && (*p & 0x20) == 0) || + (c == 0xed && *p >= 0xa0)) + return (uintptr_t)p - (uintptr_t)string; + break; + case 3: + if ((c == 0xf0 && (*p & 0x30) == 0) || (c > 0xf4) || + (c == 0xf4 && *p > 0x8f)) + return (uintptr_t)p - (uintptr_t)string; + break; + } + while (--ab > 0) { + if ((*(++p) & 0xc0) != 0x80) + return (uintptr_t)p - (uintptr_t)string; + } + } + return -1; +} +int _utf8_get(const char* string, int length, int at, char* out_buf) { + const uint8_t* p; + int ab, c; + if (length < 0) { + length = strlen(string); + } + if (at < 0 || at >= length) + return -1; + + for (p = (const uint8_t*)string; length > 0 && at; p++, at--) { + c = *p; + if (!(c & 0x80)) { + length--; + continue; + } + ab = _pcre_utf8_table4[c & 0x3f]; + p += ab++; + length -= ab; + } + if (at || length <= 0) + return -2; + c = *p; + if (!(c & 0x80)) { + *out_buf = c; + out_buf[1] = 0; + return 1; + }; + ab = _pcre_utf8_table4[c & 0x3f] + 1; + __platform_memcpy(out_buf, p, ab); + out_buf[ab] = '\0'; + return ab; +} +int _utf8_get_offset(const char* string, + int length, + int at, + int* out_char_len) { + const uint8_t* p; + int ab, c; + if (length < 0) { + length = strlen(string); + } + if (at < 0 || at >= length) + return -1; + + for (p = (const uint8_t*)string; length > 0 && at; p++, at--) { + c = *p; + if (!(c & 0x80)) { + length--; + continue; + } + ab = _pcre_utf8_table4[c & 0x3f]; + p += ab++; + length -= ab; + } + if (at) + return -2; + c = *p; + if (!(c & 0x80)) { + if (out_char_len) + *out_char_len = 1; + return (uintptr_t)p - (uintptr_t)string; + }; + ab = _pcre_utf8_table4[c & 0x3f] + 1; + if (out_char_len) + *out_char_len = ab; + return (uintptr_t)p - (uintptr_t)string; +} +int _utf8_strlen(const char* string, int length) { + const uint8_t* p; + int i, ab, c; + if (length < 0) { + length = strlen(string); + } + + for (i = 0, p = (const uint8_t*)string; length > 0; i++, p++) { + c = *p; + if (!(c & 0x80)) { + length--; + continue; + } + ab = _pcre_utf8_table4[c & 0x3f]; + p += ab++; + length -= ab; + } + if (length < 0) + return -1; + return i; +} + +int __str_repl(PikaObj* self, + char* str, + int str_len, + int repl_at, + int repl_len, + char* val, + int val_len) { + if (val_len > repl_len) { + str[repl_at] = 0; + Arg* s_new = arg_newStr(str); + if (!s_new) + return -1; + s_new = arg_strAppend(s_new, val); + s_new = arg_strAppend(s_new, str + repl_at + repl_len); + obj_removeArg(self, "str"); + int rs = obj_setArg(self, "str", s_new); + arg_deinit(s_new); + if (rs) + return -rs; + return 0; + } + char* s = str + repl_at; + __platform_memcpy(s, val, val_len); + __platform_memmove(s + val_len, s + repl_len, + str_len - repl_at - repl_len + 1); + return 0; +} + +int __utf8_to_utf32_char_LE(const char* utf8, char* out_buf) { + char c = *utf8; + if (!(c & mask1)) { + *out_buf = c; + out_buf[1] = 0; + out_buf[2] = 0; + out_buf[3] = 0; + return 1; + } + int left_length = _pcre_utf8_table4[c & 0x3f]; + char a, b, d; + switch (left_length) { + case 1: + a = c & nmask2; + b = utf8[1] & nmask1; + out_buf[0] = b | a << 6; + out_buf[1] = a >> 2; + out_buf[2] = 0; + out_buf[3] = 0; + return 2; + case 2: + a = c & nmask3; + b = utf8[1] & nmask1; + c = utf8[2] & nmask1; + out_buf[0] = c | b << 6; + out_buf[1] = b >> 2 | a << 4; + out_buf[2] = 0; + out_buf[3] = 0; + return 3; + case 3: + a = c & nmask4; + b = utf8[1] & nmask1; + c = utf8[2] & nmask1; + d = utf8[3] & nmask1; + out_buf[0] = d | c << 6; + out_buf[1] = c >> 2 | b << 4; + out_buf[2] = b >> 4 | a << 2; + out_buf[3] = 0; + return 4; + default: + return 0; + } +} +int __utf8_to_utf32_LE_noBOM_get_size(const char* utf8, int len) { + char* p = (char*)utf8; + char buf[4]; + int space_sum = 0; + while (len > 0) { + int size = __utf8_to_utf32_char_LE(p, buf); + if (!size) + return -1; + p += size; + len -= size; + space_sum++; + } + return space_sum * 4; +} +int __utf8_to_utf32_LE_noBOM(const char* utf8, int len, char* out_buf) { + char* q = out_buf; + char* p = (char*)utf8; + while (len > 0) { + int size = __utf8_to_utf32_char_LE(p, q); + if (!size) + return -1; + p += size; + len -= size; + q += 4; + } + return q - out_buf; +} +int __utf8_to_utf32_LE_withBOM(const char* utf8, int len, char* out_buf) { + int size = __utf8_to_utf32_LE_noBOM(utf8, len, out_buf + 4); + if (size < 0) { + return size; + } + out_buf[0] = '\xff'; + out_buf[1] = '\xfe'; + out_buf[2] = 0; + out_buf[3] = 0; + return size + 4; +} + +int32_t __utf8_decode(const char* utf8, int left_length) { + int ucode = -1; + char c = *utf8; + if (!(c & mask1)) { + return c; + } + char a, b, d; + switch (left_length) { + case 1: + a = c & nmask2; + b = utf8[1] & nmask1; + ucode = b | (a & 0x03) << 6; + ucode |= (a >> 2) << 8; + break; + case 2: + a = c & nmask3; + b = utf8[1] & nmask1; + c = utf8[2] & nmask1; + ucode = c | (b & 0x03) << 6; + ucode |= (b >> 2 | a << 4) << 8; + break; + case 3: + a = c & nmask4; + b = utf8[1] & nmask1; + c = utf8[2] & nmask1; + d = utf8[3] & nmask1; + ucode = d | (c & 0x03) << 6; + ucode |= (c >> 2 | (b & 0x0f) << 4) << 8; + ucode |= (b >> 4 | a << 2) << 16; + break; + default: + return -1; + } + return ucode; +} + +int __unicode_to_utf16_char_LE(int32_t u, char* out_buf) { + if (!(u & 0xffff0000)) { + out_buf[0] = u & 0xff; + out_buf[1] = (u & 0xff00) >> 8; + return 2; + } + int32_t d = u - 0x10000; + int32_t L = d & 0x3ff; + int32_t U = d >> 10; + L = L | 0xdc00; + U = U | 0xd800; + out_buf[0] = U & 0xff; + out_buf[1] = (U & 0xff00) >> 8; + out_buf[2] = L & 0xff; + out_buf[3] = (L & 0xff00) >> 8; + return 4; +} +int __utf8_to_utf16_LE_noBOM(const char* utf8, int len, char* out_buf) { + char* q = out_buf; + char* p = (char*)utf8; + while (len > 0) { + char c = *p; + int32_t ucode; + if (!(c & mask1)) { + ucode = c; + p++; + len--; + } else { + int left_size = _pcre_utf8_table4[c & 0x3f]; + ucode = __utf8_decode(p, left_size++); + if (ucode < 0) + return ucode; + p += left_size; + len -= left_size; + } + int size = __unicode_to_utf16_char_LE(ucode, q); + q += size; + } + return q - out_buf; +} +int __utf8_to_utf16_LE_noBOM_get_size(const char* utf8, int len) { + char out_buf[4]; + char* p = (char*)utf8; + int need_space = 0; + while (len > 0) { + char c = *p; + int32_t ucode; + if (!(c & mask1)) { + ucode = c; + p++; + len--; + } else { + int left_size = _pcre_utf8_table4[c & 0x3f]; + ucode = __utf8_decode(p, left_size++); + if (ucode < 0) + return ucode; + p += left_size; + len -= left_size; + } + int size = __unicode_to_utf16_char_LE(ucode, out_buf); + need_space += size; + } + return need_space; +} +int __utf8_to_utf16_LE_withBOM(const char* utf8, int len, char* out_buf) { + int size = __utf8_to_utf16_LE_noBOM(utf8, len, out_buf + 2); + if (size < 0) { + return size; + } + out_buf[0] = '\xff'; + out_buf[1] = '\xfe'; + return size + 2; +} +Arg* _str_encode(char* str, char* encoding) { + if (strEqu(encoding, "utf-8")) { + return arg_newBytes((uint8_t*)str, strGetSize(str)); + } + int len = strlen(str); + + if (strEqu(encoding, "ascii")) { + int ulen = _utf8_strlen(str, len); + if (ulen == len) { + return arg_newBytes((uint8_t*)str, strGetSize(str)); + } + __platform_printf("Warning there is non-ascii characters\r\n"); + char* b = (char*)pikaMalloc(len + 1); + if (!b) { + return NULL; + } + char* p = str; + char* q = b; + char c = *p++; + while (c) { + if (!(c & 0x80)) { + *q++ = c; + } + c = *p++; + } + *q = 0; + Arg* arg = arg_newBytes((uint8_t*)b, strGetSize(b)); + pikaFree(b, len + 1); + return arg; + } + + if (strEqu(encoding, "utf-16")) { + int size_needed = __utf8_to_utf16_LE_noBOM_get_size(str, len); + if (size_needed <= 0) { + return NULL; + } + size_needed += 2; + char* b = (char*)pikaMalloc(size_needed); + if (!b) { + return NULL; + } + int ok = __utf8_to_utf16_LE_withBOM(str, len, b); + if (ok < 0) { + pikaFree(b, size_needed); + return NULL; + } + Arg* arg = arg_newBytes((uint8_t*)b, size_needed); + pikaFree(b, size_needed); + return arg; + } + + if (strEqu(encoding, "utf-32")) { + int size_needed = __utf8_to_utf32_LE_noBOM_get_size(str, len); + if (size_needed <= 0) { + return NULL; + } + size_needed += 4; + char* b = (char*)pikaMalloc(size_needed); + if (!b) { + return NULL; + } + int ok = __utf8_to_utf32_LE_withBOM(str, len, b); + if (ok < 0) { + pikaFree(b, size_needed); + return NULL; + } + Arg* arg = arg_newBytes((uint8_t*)b, size_needed); + pikaFree(b, size_needed); + return arg; + } + return NULL; +} + +char* _strlwr(char* str) { + int i = 0; + while (str[i] != '\0') { + str[i] = tolower((int)str[i]); + i++; + } + return str; +} + +#endif + +char* PikaStdData_String_format(PikaObj* self, PikaTuple* vars) { + /* 'test{}'.format(123) */ + return NULL; +} diff --git a/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_String_Util.h b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_String_Util.h new file mode 100644 index 00000000..cd9815bf --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_String_Util.h @@ -0,0 +1,20 @@ +#include + +#if PIKA_STRING_UTF8_ENABLE + +int _valid_utf8(const char *string, int length); +int _utf8_get(const char *string, int length, int at, char *out_buf); +int _utf8_get_offset(const char *string, int length, int at, int *out_char_len); +int _utf8_strlen(const char *string, int length); +int __str_repl(PikaObj *self, char *str, int str_len, int repl_at, int repl_len, char *val, int val_len); + +int __utf8_to_utf32_LE_withBOM(const char *utf8, int len, char *out_buf); +int __utf8_to_utf32_LE_noBOM(const char *utf8, int len, char *out_buf); +int __utf8_to_utf32_LE_noBOM_get_size(const char *utf8, int len); + +int __utf8_to_utf16_LE_withBOM(const char *utf8, int len, char *out_buf); +int __utf8_to_utf16_LE_noBOM(const char *utf8, int len, char *out_buf); +int __utf8_to_utf16_LE_noBOM_get_size(const char *utf8, int len); +Arg* _str_encode(char*str, char*encoding); + +#endif diff --git a/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_Tuple.c b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_Tuple.c new file mode 100644 index 00000000..93f047cf --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_Tuple.c @@ -0,0 +1,87 @@ +#include "PikaStdData_Tuple.h" +#include "PikaVM.h" +#include "dataStrs.h" + +int PikaStdData_Tuple_len(PikaObj* self) { + PikaList* list = obj_getPtr(self, "list"); + return pikaList_getSize(list); +} + +Arg* PikaStdData_Tuple_get(PikaObj* self, int i) { + PikaList* list = obj_getPtr(self, "list"); + return arg_copy(pikaList_getArg(list, i)); +} + +void PikaStdData_Tuple___init__(PikaObj* self) { + __vm_List___init__(self); +} + +Arg* PikaStdData_Tuple___iter__(PikaObj* self) { + obj_setInt(self, "__iter_i", 0); + return arg_newRef(self); +} + +Arg* PikaStdData_Tuple___next__(PikaObj* self) { + int __iter_i = args_getInt(self->list, "__iter_i"); + Arg* res = PikaStdData_Tuple_get(self, __iter_i); + if (NULL == res) { + return arg_newNull(); + } + args_setInt(self->list, "__iter_i", __iter_i + 1); + return res; +} + +Arg* PikaStdData_Tuple___getitem__(PikaObj* self, Arg* __key) { + return PikaStdData_Tuple_get(self, arg_getInt(__key)); +} + +void PikaStdData_Tuple___del__(PikaObj* self) { + Args* list = obj_getPtr(self, "list"); + args_deinit(list); +} + +char* PikaStdLib_SysObj_str(PikaObj* self, Arg* arg); +char* PikaStdData_Tuple___str__(PikaObj* self) { + Arg* str_arg = arg_newStr("("); + PikaList* list = obj_getPtr(self, "list"); + + int i = 0; + while (PIKA_TRUE) { + Arg* item = pikaList_getArg(list, i); + if (NULL == item) { + break; + } + if (i != 0) { + str_arg = arg_strAppend(str_arg, ", "); + } + char* item_str = PikaStdLib_SysObj_str(self, item); + if (arg_getType(item) == ARG_TYPE_STRING) { + str_arg = arg_strAppend(str_arg, "'"); + } + str_arg = arg_strAppend(str_arg, item_str); + if (arg_getType(item) == ARG_TYPE_STRING) { + str_arg = arg_strAppend(str_arg, "'"); + } + i++; + } + + str_arg = arg_strAppend(str_arg, ")"); + obj_setStr(self, "_buf", arg_getStr(str_arg)); + arg_deinit(str_arg); + return obj_getStr(self, "_buf"); +} + +int PikaStdData_Tuple___len__(PikaObj* self) { + return PikaStdData_Tuple_len(self); +} + +int PikaStdData_Tuple___contains__(PikaObj* self, Arg* val) { + PikaList* list = obj_getPtr(self, "list"); + for (size_t i = 0; i < pikaList_getSize(list); i++) { + Arg* arg = pikaList_getArg(list, i); + if (arg_isEqual(arg, val)) { + return 1; + } + } + return 0; +} diff --git a/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_Utils.c b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_Utils.c new file mode 100644 index 00000000..be15c5d5 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdData_Utils.c @@ -0,0 +1,14 @@ +#include "PikaStdData_Utils.h" +#include "dataStrs.h" + +Arg* PikaStdData_Utils_int_to_bytes(PikaObj* self, int val) { + if (val > 0xFF) { + obj_setErrorCode(self, 1); + __platform_printf( + "OverflowError: cannot convert value larger than 0xFF to " + "bytes\r\n"); + return arg_newNull(); + } + uint8_t val_bytes = (uint8_t)val; + return arg_newBytes(&val_bytes, 1); +} diff --git a/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdLib_MemChecker.c b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdLib_MemChecker.c new file mode 100644 index 00000000..b395b105 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdLib_MemChecker.c @@ -0,0 +1,23 @@ +#include "PikaStdLib_MemChecker.h" +#include "BaseObj.h" +#include "dataStrs.h" + +void PikaStdLib_MemChecker_max(PikaObj* self) { + __platform_printf("%0.2f kB\r\n", pikaMemMax() / 1024.0); +} + +void PikaStdLib_MemChecker_now(PikaObj* self) { + __platform_printf("%0.2f kB\r\n", pikaMemNow() / 1024.0); +} + +void PikaStdLib_MemChecker_resetMax(PikaObj* self) { + pikaMemMaxReset(); +} + +pika_float PikaStdLib_MemChecker_getMax(PikaObj* self) { + return pikaMemMax() / 1024.0; +} + +pika_float PikaStdLib_MemChecker_getNow(PikaObj* self) { + return pikaMemNow() / 1024.0; +} diff --git a/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdLib_RangeObj.c b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdLib_RangeObj.c new file mode 100644 index 00000000..5c668e16 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdLib_RangeObj.c @@ -0,0 +1,14 @@ +#include "PikaObj.h" + +Arg* PikaStdLib_RangeObj___next__(PikaObj* self) { + RangeData* _ = (RangeData*)args_getStruct(self->list, "_"); + int end = _->end; + int step = _->step; + /* exit */ + if (_->i >= end) { + return arg_newNull(); + } + Arg* res = arg_newInt(_->i); + _->i += step; + return res; +} diff --git a/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdLib_StringObj.c b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdLib_StringObj.c new file mode 100644 index 00000000..ad15ee2a --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdLib_StringObj.c @@ -0,0 +1,5 @@ +#include "PikaObj.h" + +Arg* PikaStdLib_StringObj___next__(PikaObj* self) { + return arg_newNull(); +} diff --git a/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c new file mode 100644 index 00000000..e1f7e024 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c @@ -0,0 +1,684 @@ +#include "PikaStdLib_SysObj.h" +#include "PikaStdData_FILEIO.h" +#include "PikaStdLib_RangeObj.h" +#include "PikaStdLib_StringObj.h" +#include "PikaVM.h" +#include "dataStrs.h" + +void PikaStdLib_SysObj_remove(PikaObj* self, char* argPath) { + obj_setErrorCode(self, 0); + int32_t res = obj_removeArg(self, argPath); + if (1 == res) { + obj_setSysOut(self, "[error] del: object no found."); + obj_setErrorCode(self, 1); + return; + } + if (2 == res) { + obj_setSysOut(self, "[error] del: arg not match."); + obj_setErrorCode(self, 2); + return; + } +} + +Arg* PikaStdLib_SysObj_type(PikaObj* self, Arg* arg) { + if (NULL == arg) { + obj_setSysOut(self, "[error] type: arg no found."); + obj_setErrorCode(self, 1); + return arg_newNull(); + } + ArgType type = arg_getType(arg); + if (ARG_TYPE_INT == type) { + return arg_newStr(""); + } + if (ARG_TYPE_FLOAT == type) { + return arg_newStr(""); + } + if (ARG_TYPE_STRING == type) { + return arg_newStr(""); + } + if (argType_isObject(type)) { + PikaObj* obj = arg_getPtr(arg); + NewFun clsptr = obj_getClass(obj); + PikaObj* New_PikaStdData_List(Args * args); + if (clsptr == New_PikaStdData_List) { + return arg_newStr(""); + } + /* dict */ + PikaObj* New_PikaStdData_Dict(Args * args); + if (clsptr == New_PikaStdData_Dict) { + return arg_newStr(""); + } + return arg_newStr(""); + } + if (ARG_TYPE_OBJECT_META == type) { + return arg_newStr(""); + } + if (ARG_TYPE_BYTES == type) { + return arg_newStr(""); + } + if (ARG_TYPE_METHOD_NATIVE == type) { + return arg_newStr(""); + } + if (ARG_TYPE_METHOD_OBJECT == type) { + return arg_newStr(""); + } + if (ARG_TYPE_METHOD_STATIC == type) { + return arg_newStr(""); + } + if (ARG_TYPE_NONE == type) { + return arg_newStr(""); + } + return arg_newNull(); +} + +pika_float PikaStdLib_SysObj_float(PikaObj* self, Arg* arg) { + ArgType type = arg_getType(arg); + if (ARG_TYPE_INT == type) { + return (float)arg_getInt(arg); + } + if (ARG_TYPE_FLOAT == type) { + return (float)arg_getFloat(arg); + } + if (ARG_TYPE_STRING == type) { + return strtod(arg_getStr(arg), NULL); + } + obj_setSysOut(self, "[error] convert to pika_float type failed."); + obj_setErrorCode(self, 1); + return -99999.99999; +} + +int PikaStdLib_SysObj_int(PikaObj* self, Arg* arg) { + ArgType type = arg_getType(arg); + if (ARG_TYPE_INT == type) { + return (int)arg_getInt(arg); + } + if (ARG_TYPE_FLOAT == type) { + return (int)arg_getFloat(arg); + } + if (ARG_TYPE_STRING == type) { + return (int)fast_atoi(arg_getStr(arg)); + } + if (ARG_TYPE_BYTES == type) { + size_t size = arg_getBytesSize(arg); + if (size != 1) { + obj_setSysOut(self, "ValueError: invalid literal for int()"); + obj_setErrorCode(self, 1); + return -999999999; + } + uint8_t val = *arg_getBytes(arg); + return val; + } + obj_setSysOut(self, "[error] convert to int type failed."); + obj_setErrorCode(self, 1); + return -999999999; +} + +char* PikaStdLib_SysObj_str(PikaObj* self, Arg* arg) { + obj_removeArg(self, "__buf"); + ArgType type = arg_getType(arg); + Args buffs = {0}; + char* res = ""; + if (ARG_TYPE_INT == type) { + int val = arg_getInt(arg); + res = strsFormat(&buffs, 11, "%d", val); + goto exit; + } + if (ARG_TYPE_FLOAT == type) { + pika_float val = arg_getFloat(arg); + res = strsFormat(&buffs, 11, "%f", val); + goto exit; + } + if (ARG_TYPE_BYTES == type) { + res = (char*)arg_getBytes(arg); + goto exit; + } + if (ARG_TYPE_STRING == type) { + res = arg_getStr(arg); + } + if (ARG_TYPE_NONE == type) { + res = "None"; + } + if (argType_isObject(type)) { + res = obj_toStr(arg_getPtr(arg)); + if (NULL != res) { + goto exit; + } + } +exit: + obj_setStr(self, "__buf", res); + strsDeinit(&buffs); + return obj_getStr(self, "__buf"); +} + +Arg* PikaStdLib_SysObj_iter(PikaObj* self, Arg* arg) { + /* object */ + PIKA_BOOL is_temp = 0; + PikaObj* arg_obj = _arg_to_obj(arg, &is_temp); + NewFun _clsptr = (NewFun)arg_obj->constructor; + if (_clsptr == New_PikaStdLib_RangeObj) { + /* found RangeObj, return directly */ + return arg_copy(arg); + } + // pikaVM_runAsm(arg_obj, + // "B0\n" + // "0 RUN __iter__\n" + // "0 OUT __res\n"); + const uint8_t bytes[] = { + 0x08, 0x00, 0x00, 0x00, /* instruct array size */ + 0x00, 0x82, 0x01, 0x00, 0x00, 0x04, 0x0a, 0x00, /* instruct array */ + 0x10, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x69, 0x74, 0x65, 0x72, 0x5f, + 0x5f, 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, 0x00, /* const pool */ + }; + pikaVM_runByteCode(arg_obj, (uint8_t*)bytes); + Arg* res = arg_copy(args_getArg(arg_obj->list, "__res")); + obj_removeArg(arg_obj, "__res"); + if (is_temp) { + obj_refcntDec(arg_obj); + } + return res; +} + +Arg* PikaStdLib_SysObj_range(PikaObj* self, PikaTuple* ax) { + /* set template arg to create rangeObj */ + Arg* obj_arg = arg_newDirectObj(New_PikaStdLib_RangeObj); + PikaObj* range_obj = arg_getPtr(obj_arg); + RangeData range_data = {0}; + if (pikaTuple_getSize(ax) == 1) { + int start = 0; + int end = arg_getInt(pikaTuple_getArg(ax, 0)); + range_data.start = start; + range_data.end = end; + range_data.step = 1; + } else if (pikaTuple_getSize(ax) == 2) { + int start = arg_getInt(pikaTuple_getArg(ax, 0)); + int end = arg_getInt(pikaTuple_getArg(ax, 1)); + range_data.start = start; + range_data.end = end; + range_data.step = 1; + } else if (pikaTuple_getSize(ax) == 3) { + int start = arg_getInt(pikaTuple_getArg(ax, 0)); + int end = arg_getInt(pikaTuple_getArg(ax, 1)); + int step = arg_getInt(pikaTuple_getArg(ax, 2)); + range_data.start = start; + range_data.end = end; + range_data.step = step; + } + range_data.i = range_data.start; + obj_setStruct(range_obj, "_", range_data); + return obj_arg; +} + +Arg* PikaStdLib_SysObj___getitem__(PikaObj* self, Arg* obj, Arg* key) { + return __vm_get(NULL, self, key, obj); +} + +Arg* PikaStdLib_SysObj___setitem__(PikaObj* self, + Arg* obj, + Arg* key, + Arg* val) { + ArgType obj_type = arg_getType(obj); + if (ARG_TYPE_STRING == obj_type) { + int index = arg_getInt(key); + char* str_val = arg_getStr(val); + char* str_pyload = arg_getStr(obj); + str_pyload[index] = str_val[0]; + return arg_newStr(str_pyload); + } + if (ARG_TYPE_BYTES == obj_type) { + int index = arg_getInt(key); + uint8_t byte_val = 0; + if (ARG_TYPE_BYTES == arg_getType(val)) { + uint8_t* bytes_val = arg_getBytes(val); + byte_val = bytes_val[0]; + } + if (ARG_TYPE_INT == arg_getType(val)) { + byte_val = arg_getInt(val); + } + uint8_t* bytes_pyload = arg_getBytes(obj); + size_t bytes_len = arg_getBytesSize(obj); + bytes_pyload[index] = byte_val; + return arg_newBytes(bytes_pyload, bytes_len); + } + if (argType_isObject(obj_type)) { + PikaObj* arg_obj = arg_getPtr(obj); + obj_setArg(arg_obj, "__key", key); + obj_setArg(arg_obj, "__val", val); + /* clang-format off */ + PIKA_PYTHON( + __setitem__(__key, __val) + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x0c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x10, 0x81, 0x01, 0x00, 0x10, 0x01, 0x07, 0x00, 0x00, 0x02, 0x0d, + 0x00, + /* instruct array */ + 0x19, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x6b, 0x65, 0x79, 0x00, 0x5f, 0x5f, 0x76, 0x61, + 0x6c, 0x00, 0x5f, 0x5f, 0x73, 0x65, 0x74, 0x69, 0x74, 0x65, 0x6d, + 0x5f, 0x5f, 0x00, + /* const pool */ + }; + pikaVM_runByteCode(arg_obj, (uint8_t*)bytes); + return arg_newRef(arg_obj); + } + return NULL; +} + +int PikaStdLib_SysObj_len(PikaObj* self, Arg* arg) { + if (ARG_TYPE_STRING == arg_getType(arg)) { + return strGetSize(arg_getStr(arg)); + } + if (ARG_TYPE_BYTES == arg_getType(arg)) { + return arg_getBytesSize(arg); + } + + if (argType_isObject(arg_getType(arg))) { + PikaObj* arg_obj = arg_getPtr(arg); + Arg* method_arg = obj_getMethodArg(arg_obj, "__len__"); + if (NULL != method_arg) { + arg_deinit(method_arg); + + /* clang-format off */ + PIKA_PYTHON( + __res = __len__() + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x08, 0x00, 0x00, 0x00, /* instruct array size */ + 0x00, 0x82, 0x01, 0x00, 0x00, 0x04, 0x09, 0x00, /* instruct + array */ + 0x0f, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x6c, 0x65, 0x6e, 0x5f, 0x5f, 0x00, + 0x5f, 0x5f, 0x72, 0x65, 0x73, 0x00, /* const pool */ + }; + pikaVM_runByteCode(arg_obj, (uint8_t*)bytes); + return obj_getInt(arg_obj, "__res"); + } + } + + obj_setErrorCode(self, 1); + __platform_printf("[Error] len: arg type not support\r\n"); + return -1; +} + +Arg* PikaStdLib_SysObj_list(PikaObj* self, PikaTuple* val) { +#if PIKA_BUILTIN_STRUCT_ENABLE + if (1 == pikaTuple_getSize(val)) { + Arg* in = pikaTuple_getArg(val, 0); + obj_setArg(self, "__list", in); + /* clang-format off */ + PIKA_PYTHON( + __res = [] + for __item in __list: + __res.append(__item) + del __item + del __list + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x3c, 0x00, 0x00, 0x00, /* instruct array size */ + 0x00, 0x95, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x10, 0x81, 0x07, + 0x00, 0x00, 0x02, 0x0e, 0x00, 0x00, 0x04, 0x13, 0x00, 0x00, 0x82, + 0x17, 0x00, 0x00, 0x04, 0x24, 0x00, 0x00, 0x0d, 0x24, 0x00, 0x00, + 0x07, 0x2b, 0x00, 0x11, 0x81, 0x24, 0x00, 0x01, 0x02, 0x2d, 0x00, + 0x00, 0x86, 0x3a, 0x00, 0x00, 0x8c, 0x13, 0x00, 0x00, 0x8c, 0x24, + 0x00, 0x00, 0x8c, 0x07, 0x00, + /* instruct array */ + 0x3d, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, 0x00, 0x5f, 0x5f, 0x6c, 0x69, + 0x73, 0x74, 0x00, 0x69, 0x74, 0x65, 0x72, 0x00, 0x24, 0x6c, 0x30, + 0x00, 0x24, 0x6c, 0x30, 0x2e, 0x5f, 0x5f, 0x6e, 0x65, 0x78, 0x74, + 0x5f, 0x5f, 0x00, 0x5f, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x32, + 0x00, 0x5f, 0x5f, 0x72, 0x65, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x65, + 0x6e, 0x64, 0x00, 0x2d, 0x31, 0x00, + /* const pool */ + }; + pikaVM_runByteCode(self, (uint8_t*)bytes); + return arg_copy(obj_getArg(self, "__res")); + } + PikaObj* New_PikaStdData_List(Args * args); + return arg_newDirectObj(New_PikaStdData_List); +#else + obj_setErrorCode(self, 1); + __platform_printf("[Error] built-in list is not enabled.\r\n"); +#endif + return arg_newNull(); +} + +Arg* PikaStdLib_SysObj_dict(PikaObj* self, PikaTuple* val) { +#if PIKA_BUILTIN_STRUCT_ENABLE + PikaObj* New_PikaStdData_Dict(Args * args); + return arg_newDirectObj(New_PikaStdData_Dict); +#else + obj_setErrorCode(self, 1); + __platform_printf("[Error] built-in dist is not enabled.\r\n"); + return arg_newNull(); +#endif +} + +char* PikaStdLib_SysObj_hex(PikaObj* self, int val) { + char buff[PIKA_SPRINTF_BUFF_SIZE] = {0}; + if (val >= 0) { + __platform_sprintf(buff, "0x%02x", val); + } else { + __platform_sprintf(buff, "-0x%02x", -val); + } + /* load the string from stack to heap */ + obj_setStr(self, "__buf", buff); + return obj_getStr(self, "__buf"); +} + +int PikaStdLib_SysObj_ord(PikaObj* self, char* val) { + return (int)val[0]; +} + +char* PikaStdLib_SysObj_chr(PikaObj* self, int val) { + char buff[PIKA_SPRINTF_BUFF_SIZE] = {0}; + char to_str[] = "0"; + to_str[0] = val; + __platform_sprintf(buff, "%s", to_str); + /* load the string from stack to heap */ + obj_setStr(self, "__buf", buff); + return obj_getStr(self, "__buf"); +} + +Arg* PikaStdLib_SysObj_bytes(PikaObj* self, Arg* val) { + ArgType type = arg_getType(val); + if (ARG_TYPE_INT == type) { + int size = arg_getInt(val); + /* src is NULL so the bytes are all '\0' */ + Arg* bytes = arg_newBytes(NULL, size); + return bytes; + } + if (ARG_TYPE_BYTES == type) { + return arg_copy(val); + } + if (ARG_TYPE_STRING == type) { + int size = strGetSize(arg_getStr(val)); + Arg* bytes = arg_newBytes((uint8_t*)arg_getStr(val), size); + return bytes; + } +#if !PIKA_NANO_ENABLE + if (argType_isObject(type)) { + PikaObj* obj = arg_getPtr(val); + PikaObj* New_PikaStdData_List(Args * args); + PikaObj* New_PikaStdData_Tuple(Args * args); + if (obj->constructor == New_PikaStdData_List || + obj->constructor == New_PikaStdData_Tuple) { + PikaList* list = obj_getPtr(obj, "list"); + Arg* bytes = arg_newBytes(NULL, pikaList_getSize(list)); + uint8_t* bytes_raw = arg_getBytes(bytes); + for (size_t i = 0; i < pikaList_getSize(list); i++) { + bytes_raw[i] = (uint8_t)pikaList_getInt(list, i); + } + return bytes; + } + } +#endif + obj_setErrorCode(self, 1); + __platform_printf("Error: input arg type not supported.\r\n"); + return arg_newNull(); +} + +static char* __print_arg(PikaObj* self, Arg* val) { + Args buffs = {0}; + char* res = NULL; + if (NULL == val) { + goto __exit; + } + ArgType arg_type = arg_getType(val); + if (arg_type == ARG_TYPE_BYTES) { + res = __printBytes(self, val); + goto __exit; + } + if (arg_type == ARG_TYPE_STRING) { + res = arg_getStr(val); + goto __exit; + } + if (arg_type == ARG_TYPE_NONE) { + res = "None"; + goto __exit; + } + if (arg_type == ARG_TYPE_INT) { + int64_t value = arg_getInt(val); +#if PIKA_PRINT_LLD_ENABLE + res = strsFormat(&buffs, 32, "%lld", value); +#else + res = strsFormat(&buffs, 32, "%d", value); +#endif + goto __exit; + } + if (arg_type == ARG_TYPE_FLOAT) { + pika_float value = arg_getFloat(val); + res = strsFormat(&buffs, 32, "%f", value); + goto __exit; + } + if (arg_type == ARG_TYPE_POINTER || + arg_type == ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR) { + void* value = arg_getPtr(val); + res = strsFormat(&buffs, 32, "%p", value); + goto __exit; + } + if (argType_isObject(arg_type)) { + res = obj_toStr(arg_getPtr(val)); + goto __exit; + } +__exit: + if (NULL == res) { + obj_setSysOut(self, "Error: can not print val"); + obj_setErrorCode(self, 1); + } + if (NULL != res) { + res = obj_cacheStr(self, res); + } + strsDeinit(&buffs); + return res; +} + +void PikaStdLib_SysObj_print(PikaObj* self, PikaTuple* val, PikaDict* ops) { + int arg_size = pikaTuple_getSize(val); + char* end = pikaDict_getStr(ops, "end"); + if (NULL == end) { + /* default */ + end = "\r\n"; + } + if (arg_size == 1) { + arg_singlePrint(pikaTuple_getArg(val, 0), PIKA_FALSE, end); + return; + } + Arg* print_out_arg = NULL; + PIKA_BOOL is_get_print = PIKA_FALSE; + for (int i = 0; i < arg_size; i++) { + Arg* arg = pikaTuple_getArg(val, i); + char* item = __print_arg(self, arg); + if (NULL != item) { + is_get_print = PIKA_TRUE; + if (NULL == print_out_arg) { + print_out_arg = arg_newStr(""); + } + print_out_arg = arg_strAppend(print_out_arg, item); + if (i < arg_size - 1) { + print_out_arg = arg_strAppend(print_out_arg, " "); + } + } + } + if (PIKA_TRUE == is_get_print) { + __platform_printf("%s%s", arg_getStr(print_out_arg), end); + } + if (NULL != print_out_arg) { + arg_deinit(print_out_arg); + } +} + +char* PikaStdLib_SysObj_cformat(PikaObj* self, char* fmt, PikaTuple* var) { +#if PIKA_SYNTAX_FORMAT_ENABLE + Args buffs = {0}; + pikaMemMaxReset(); + char* res = strsFormatList(&buffs, fmt, &var->super); + obj_setStr(self, "_buf", res); + res = obj_getStr(self, "_buf"); + strsDeinit(&buffs); + return res; +#else + obj_setErrorCode(self, 1); + __platform_printf("[Error] PIKA_SYNTAX_FORMAT_ENABLE is not enabled.\r\n"); + return NULL; +#endif +} + +int PikaStdLib_SysObj_id(PikaObj* self, Arg* obj) { + uintptr_t ptr = 0; + if (argType_isObject(arg_getType(obj))) { + ptr = (uintptr_t)arg_getPtr(obj); + } else { + ptr = (uintptr_t)obj; + } + return ptr & (0x7FFFFFFF); +} + +PikaObj* PikaStdLib_SysObj_open(PikaObj* self, char* path, char* mode) { +#if PIKA_FILEIO_ENABLE + PikaObj* file = newNormalObj(New_PikaStdData_FILEIO); + if (0 != PikaStdData_FILEIO_init(file, path, mode)) { + obj_setErrorCode(self, 1); + __platform_printf("[Error] open: can not open file.\r\n"); + obj_deinit(file); + return NULL; + } + return file; +#else + obj_setErrorCode(self, 1); + __platform_printf("[Error] PIKA_FILEIO_ENABLE is not enabled.\r\n"); + return NULL; +#endif +} + +/* __dir_each */ +int32_t __dir_each(Arg* argEach, Args* context) { + PikaObj* list = args_getPtr(context, "list"); + if (argType_isCallable(arg_getType(argEach))) { + char name_buff[PIKA_LINE_BUFF_SIZE / 2] = {0}; + char* method_name = + methodArg_getName(argEach, name_buff, sizeof(name_buff)); + Arg* arg_str = arg_newStr(method_name); + __vm_List_append(list, arg_str); + arg_deinit(arg_str); + } + return 0; +} + +PikaObj* PikaStdLib_SysObj_dir(PikaObj* self, PikaObj* obj) { + PikaObj* New_PikaStdData_List(Args * args); + PikaObj* list = newNormalObj(New_PikaStdData_List); + __vm_List___init__(list); + Args* context = New_args(NULL); + args_setPtr(context, "list", list); + args_foreach(obj->list, __dir_each, context); + args_deinit(context); + return list; +} + +void PikaStdLib_SysObj_exec(PikaObj* self, char* code) { +#if PIKA_EXEC_ENABLE + obj_run(self, code); +#else + obj_setErrorCode(self, 1); + __platform_printf("[Error] PIKA_EXEC_ENABLE is not enabled.\r\n"); +#endif +} + +Arg* PikaStdLib_SysObj_getattr(PikaObj* self, PikaObj* obj, char* name) { + Arg* res = NULL; + if (NULL == obj) { + obj_setErrorCode(self, 1); + __platform_printf("[Error] getattr: can not get attr of NULL.\r\n"); + return NULL; + } + Arg* arg = obj_getArg(obj, name); + if (NULL == arg) { + arg = obj_getMethodArg(obj, name); + return arg_copy(arg); + } + if (NULL != arg) { + res = arg_copy(arg); + return res; + } + return NULL; +} + +void PikaStdLib_SysObj_setattr(PikaObj* self, + PikaObj* obj, + char* name, + Arg* val) { + if (NULL == obj) { + obj_setErrorCode(self, 1); + __platform_printf("[Error] setattr: obj is null.\r\n"); + goto exit; + } + obj_setArg(obj, name, val); +exit: + return; +} + +void PikaStdLib_SysObj_exit(PikaObj* self) { + pks_vm_exit(); +} + +int PikaStdLib_SysObj_hasattr(PikaObj* self, PikaObj* obj, char* name) { + if (NULL == obj) { + obj_setErrorCode(self, 1); + __platform_printf("[Error] hasattr: obj is null.\r\n"); + return 0; + } + if (obj_isArgExist(obj, name)) { + return 1; + } + Arg* method = obj_getMethodArg(obj, name); + if (NULL != method) { + arg_deinit(method); + return 1; + } + return 0; +} + +Arg* PikaStdLib_SysObj_eval(PikaObj* self, char* code) { + Args buffs = {0}; + char* cmd = strsAppend(&buffs, "@res = ", code); + obj_run(self, cmd); + Arg* res = arg_copy(obj_getArg(self, "@res")); + strsDeinit(&buffs); + obj_removeArg(self, "@res"); + return res; +} + +static enum shellCTRL __obj_shellLineHandler_input(PikaObj* self, + char* input_line, + struct ShellConfig* cfg) { + cfg->context = arg_newStr(input_line); + return SHELL_CTRL_EXIT; +} + +char* PikaStdLib_SysObj_input(PikaObj* self, PikaTuple* info) { + struct ShellConfig cfg = { + .prefix = "", + .context = NULL, + .handler = __obj_shellLineHandler_input, + .fn_getchar = __platform_getchar, + }; + if (pikaTuple_getSize(info) > 0) { + __platform_printf("%s", pikaTuple_getStr(info, 0)); + } + _temp__do_pikaScriptShell(self, &cfg); + char* res = obj_cacheStr(self, arg_getStr(cfg.context)); + arg_deinit(cfg.context); + return res; +} + +extern volatile PikaObj* __pikaMain; +void PikaStdLib_SysObj_help(PikaObj* self, char* name) { + if (strEqu(name, "modules")) { + obj_printModules((PikaObj*)__pikaMain); + } +} diff --git a/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdTask_Task.c b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdTask_Task.c new file mode 100644 index 00000000..cdaee7c3 --- /dev/null +++ b/examples/pikapython/pikapython/pikascript-lib/PikaStdLib/PikaStdTask_Task.c @@ -0,0 +1,217 @@ +#include "BaseObj.h" +#include "PikaVM.h" + +void PikaStdTask_Task___init__(PikaObj* self) { + obj_setInt(self, "is_period", 0); +} + +void PikaStdTask_Task_call_always(PikaObj* self, Arg* fun_todo) { + obj_setArg(self, "fun_todo", fun_todo); + PIKA_PYTHON_BEGIN + /* clang-format off */ + PIKA_PYTHON( + calls.append('always') + calls.append(fun_todo) + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x10, 0x00, 0x00, 0x00,/* instruct array size */ + 0x10, 0x83, 0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x10, 0x81, 0x15, + 0x00, 0x00, 0x02, 0x08, 0x00, /* instruct array */ + 0x1e, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x00, 0x63, 0x61, 0x6c, + 0x6c, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x00, 0x66, + 0x75, 0x6e, 0x5f, 0x74, 0x6f, 0x64, 0x6f, 0x00, /* const pool */ + }; + PIKA_PYTHON_END + pikaVM_runByteCode(self, (uint8_t*)bytes); +} + +void PikaStdTask_Task_call_when(PikaObj* self, Arg* fun_todo, Arg* fun_when) { + obj_setArg(self, "fun_todo", fun_todo); + obj_setArg(self, "fun_when", fun_when); + PIKA_PYTHON_BEGIN + /* clang-format off */ + PIKA_PYTHON( + calls.append('when') + calls.append(fun_when) + calls.append(fun_todo) + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0x18, 0x00, 0x00, 0x00,/* instruct array size */ + 0x10, 0x83, 0x01, 0x00, 0x00, 0x02, 0x06, 0x00, 0x10, 0x81, 0x13, 0x00, + 0x00, 0x02, 0x06, 0x00, 0x10, 0x81, 0x1c, 0x00, 0x00, 0x02, 0x06, 0x00, + /* instruct array */ + 0x25, 0x00, 0x00, 0x00,/* const pool size */ + 0x00, 0x77, 0x68, 0x65, 0x6e, 0x00, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x2e, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x00, 0x66, 0x75, 0x6e, 0x5f, 0x77, + 0x68, 0x65, 0x6e, 0x00, 0x66, 0x75, 0x6e, 0x5f, 0x74, 0x6f, 0x64, 0x6f, + 0x00, + /* const pool */ + }; + PIKA_PYTHON_END + pikaVM_runByteCode(self, (uint8_t*)bytes); +} + +void PikaStdTask_Task_call_period_ms(PikaObj* self, + Arg* fun_todo, + int period_ms) { + obj_setArg(self, "fun_todo", fun_todo); + obj_setInt(self, "period_ms", period_ms); + PIKA_PYTHON_BEGIN + /* clang-format off */ + PIKA_PYTHON( + calls.append('period_ms') + calls.append(period_ms) + calls.append(fun_todo) + calls.append(0) + is_period = 1 + ) + /* clang-format on */ + const uint8_t bytes[] = + { + 0x28, 0x00, 0x00, 0x00,/* instruct array size */ + 0x10, 0x83, 0x01, 0x00, 0x00, 0x02, 0x0b, 0x00, 0x10, 0x81, 0x01, + 0x00, 0x00, 0x02, 0x0b, 0x00, 0x10, 0x81, 0x18, 0x00, 0x00, 0x02, + 0x0b, 0x00, 0x10, 0x85, 0x21, 0x00, 0x00, 0x02, 0x0b, 0x00, 0x00, + 0x85, 0x23, 0x00, 0x00, 0x04, 0x25, 0x00, /* instruct array */ + 0x2f, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x00, + 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, + 0x64, 0x00, 0x66, 0x75, 0x6e, 0x5f, 0x74, 0x6f, 0x64, 0x6f, 0x00, + 0x30, 0x00, 0x31, 0x00, 0x69, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x69, + 0x6f, 0x64, 0x00, /* const pool */ + }; + PIKA_PYTHON_END + pikaVM_runByteCode(self, (uint8_t*)bytes); +} + +void PikaStdTask_Task_run_once(PikaObj* self) { + /* clang-format off */ + PIKA_PYTHON( + len = calls.len() + mode = 'none' + info_index = 0 + for i in range(0, len): + if len == 0: + break + if info_index == 0: + mode = calls[i] + info_index = 1 + elif info_index == 1: + if mode == 'always': + todo = calls[i] + todo() + info_index = 0 + elif mode == 'when': + when = calls[i] + info_index = 2 + elif mode == 'period_ms': + period_ms = calls[i] + info_index = 2 + elif info_index == 2: + if mode == 'when': + if when(): + todo = calls[i] + todo() + info_index = 0 + elif mode == 'period_ms': + todo = calls[i] + info_index = 3 + elif info_index == 3: + if mode == 'period_ms': + if tick > calls[i]: + todo() + calls[i] = tick + period_ms + info_index = 0 + ) + /* clang-format on */ + const uint8_t bytes[] = { + 0xf0, 0x01, 0x00, 0x00,/* instruct array size */ + 0x00, 0x82, 0x01, 0x00, 0x00, 0x04, 0x0b, 0x00, 0x00, 0x83, 0x0f, 0x00, + 0x00, 0x04, 0x14, 0x00, 0x00, 0x85, 0x19, 0x00, 0x00, 0x04, 0x1b, 0x00, + 0x20, 0x85, 0x19, 0x00, 0x20, 0x01, 0x0b, 0x00, 0x10, 0x02, 0x26, 0x00, + 0x00, 0x02, 0x2c, 0x00, 0x00, 0x04, 0x31, 0x00, 0x00, 0x82, 0x35, 0x00, + 0x00, 0x04, 0x42, 0x00, 0x00, 0x0d, 0x42, 0x00, 0x00, 0x07, 0x44, 0x00, + 0x11, 0x81, 0x0b, 0x00, 0x11, 0x05, 0x19, 0x00, 0x01, 0x08, 0x46, 0x00, + 0x01, 0x07, 0x49, 0x00, 0x02, 0x8e, 0x00, 0x00, 0x11, 0x81, 0x1b, 0x00, + 0x11, 0x05, 0x19, 0x00, 0x01, 0x08, 0x46, 0x00, 0x01, 0x07, 0x49, 0x00, + 0x12, 0x81, 0x4b, 0x00, 0x12, 0x01, 0x42, 0x00, 0x02, 0x1d, 0x00, 0x00, + 0x02, 0x04, 0x14, 0x00, 0x02, 0x85, 0x49, 0x00, 0x02, 0x04, 0x1b, 0x00, + 0x01, 0x8b, 0x49, 0x00, 0x11, 0x01, 0x1b, 0x00, 0x11, 0x05, 0x49, 0x00, + 0x01, 0x08, 0x46, 0x00, 0x01, 0x07, 0x49, 0x00, 0x12, 0x81, 0x14, 0x00, + 0x12, 0x03, 0x51, 0x00, 0x02, 0x08, 0x46, 0x00, 0x02, 0x07, 0x49, 0x00, + 0x13, 0x81, 0x4b, 0x00, 0x13, 0x01, 0x42, 0x00, 0x03, 0x1d, 0x00, 0x00, + 0x03, 0x04, 0x58, 0x00, 0x03, 0x82, 0x58, 0x00, 0x03, 0x85, 0x19, 0x00, + 0x03, 0x04, 0x1b, 0x00, 0x02, 0x8b, 0x49, 0x00, 0x12, 0x01, 0x14, 0x00, + 0x12, 0x03, 0x5d, 0x00, 0x02, 0x08, 0x46, 0x00, 0x02, 0x07, 0x49, 0x00, + 0x13, 0x81, 0x4b, 0x00, 0x13, 0x01, 0x42, 0x00, 0x03, 0x1d, 0x00, 0x00, + 0x03, 0x04, 0x5d, 0x00, 0x03, 0x85, 0x44, 0x00, 0x03, 0x04, 0x1b, 0x00, + 0x02, 0x8b, 0x49, 0x00, 0x12, 0x01, 0x14, 0x00, 0x12, 0x03, 0x62, 0x00, + 0x02, 0x08, 0x46, 0x00, 0x02, 0x07, 0x49, 0x00, 0x13, 0x81, 0x4b, 0x00, + 0x13, 0x01, 0x42, 0x00, 0x03, 0x1d, 0x00, 0x00, 0x03, 0x04, 0x62, 0x00, + 0x03, 0x85, 0x44, 0x00, 0x03, 0x04, 0x1b, 0x00, 0x01, 0x8b, 0x49, 0x00, + 0x11, 0x01, 0x1b, 0x00, 0x11, 0x05, 0x44, 0x00, 0x01, 0x08, 0x46, 0x00, + 0x01, 0x07, 0x49, 0x00, 0x12, 0x81, 0x14, 0x00, 0x12, 0x03, 0x5d, 0x00, + 0x02, 0x08, 0x46, 0x00, 0x02, 0x07, 0x49, 0x00, 0x03, 0x82, 0x5d, 0x00, + 0x03, 0x07, 0x49, 0x00, 0x14, 0x81, 0x4b, 0x00, 0x14, 0x01, 0x42, 0x00, + 0x04, 0x1d, 0x00, 0x00, 0x04, 0x04, 0x58, 0x00, 0x04, 0x82, 0x58, 0x00, + 0x03, 0x85, 0x19, 0x00, 0x03, 0x04, 0x1b, 0x00, 0x02, 0x8b, 0x49, 0x00, + 0x12, 0x01, 0x14, 0x00, 0x12, 0x03, 0x62, 0x00, 0x02, 0x08, 0x46, 0x00, + 0x02, 0x07, 0x49, 0x00, 0x13, 0x81, 0x4b, 0x00, 0x13, 0x01, 0x42, 0x00, + 0x03, 0x1d, 0x00, 0x00, 0x03, 0x04, 0x58, 0x00, 0x03, 0x85, 0x6c, 0x00, + 0x03, 0x04, 0x1b, 0x00, 0x01, 0x8b, 0x49, 0x00, 0x11, 0x01, 0x1b, 0x00, + 0x11, 0x05, 0x6c, 0x00, 0x01, 0x08, 0x46, 0x00, 0x01, 0x07, 0x49, 0x00, + 0x12, 0x81, 0x14, 0x00, 0x12, 0x03, 0x62, 0x00, 0x02, 0x08, 0x46, 0x00, + 0x02, 0x07, 0x49, 0x00, 0x13, 0x81, 0x6e, 0x00, 0x23, 0x01, 0x4b, 0x00, + 0x23, 0x01, 0x42, 0x00, 0x13, 0x1d, 0x00, 0x00, 0x03, 0x08, 0x73, 0x00, + 0x03, 0x07, 0x49, 0x00, 0x04, 0x82, 0x58, 0x00, 0x14, 0x81, 0x4b, 0x00, + 0x14, 0x01, 0x42, 0x00, 0x24, 0x01, 0x6e, 0x00, 0x24, 0x01, 0x62, 0x00, + 0x14, 0x08, 0x75, 0x00, 0x04, 0x02, 0x77, 0x00, 0x04, 0x04, 0x4b, 0x00, + 0x03, 0x85, 0x19, 0x00, 0x03, 0x04, 0x1b, 0x00, 0x00, 0x86, 0x83, 0x00, + 0x00, 0x8c, 0x31, 0x00, /* instruct array */ + 0x86, 0x00, 0x00, 0x00, /* const pool size */ + 0x00, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x00, 0x6c, + 0x65, 0x6e, 0x00, 0x6e, 0x6f, 0x6e, 0x65, 0x00, 0x6d, 0x6f, 0x64, 0x65, + 0x00, 0x30, 0x00, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x69, 0x74, 0x65, 0x72, + 0x00, 0x5f, 0x6c, 0x30, 0x00, 0x5f, 0x6c, 0x30, 0x2e, 0x5f, 0x5f, 0x6e, + 0x65, 0x78, 0x74, 0x5f, 0x5f, 0x00, 0x69, 0x00, 0x32, 0x00, 0x3d, 0x3d, + 0x00, 0x31, 0x00, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x00, 0x61, 0x6c, 0x77, + 0x61, 0x79, 0x73, 0x00, 0x74, 0x6f, 0x64, 0x6f, 0x00, 0x77, 0x68, 0x65, + 0x6e, 0x00, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x6d, 0x73, 0x00, + 0x33, 0x00, 0x74, 0x69, 0x63, 0x6b, 0x00, 0x3e, 0x00, 0x2b, 0x00, 0x5f, + 0x5f, 0x73, 0x65, 0x74, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x5f, 0x00, 0x2d, + 0x31, 0x00, /* const pool */ + }; + pikaVM_runByteCode(self, (uint8_t*)bytes); +} + +void __Task_update_tick(PikaObj* self) { + if (obj_getInt(self, "is_perod")) { + obj_runNativeMethod(self, "platformGetTick", NULL); + } +} + +void PikaStdTask_Task_run_forever(PikaObj* self) { + while (1) { + __Task_update_tick(self); + PikaStdTask_Task_run_once(self); + } +} + +void PikaStdTask_Task_run_until_ms(PikaObj* self, int until_ms) { + while (1) { + __Task_update_tick(self); + PikaStdTask_Task_run_once(self); + if (obj_getInt(self, "tick") > until_ms) { + return; + } + } +} + +void PikaStdTask_Task_platformGetTick(PikaObj* self) { + obj_setErrorCode(self, 1); + __platform_printf("Error: abstract method %s need implament", __FUNCTION__); +} diff --git a/examples/pikapython/pikapython/requestment.txt b/examples/pikapython/pikapython/requestment.txt new file mode 100644 index 00000000..cc568171 --- /dev/null +++ b/examples/pikapython/pikapython/requestment.txt @@ -0,0 +1,2 @@ +pikascript-core==v1.12.0 +PikaStdLib==v1.12.0 \ No newline at end of file diff --git a/examples/pikapython/pikapython/rust-msc-latest-win10.exe b/examples/pikapython/pikapython/rust-msc-latest-win10.exe new file mode 100755 index 00000000..e9d36d4d Binary files /dev/null and b/examples/pikapython/pikapython/rust-msc-latest-win10.exe differ diff --git a/examples/pikapython/proj.conf b/examples/pikapython/proj.conf new file mode 100644 index 00000000..38cabb5f --- /dev/null +++ b/examples/pikapython/proj.conf @@ -0,0 +1,8 @@ +set(CONFIG_VLIBC 1) +set(CONFIG_VLIBC_FATFS 1) + +set(CONFIG_BFLOG 1) +set(CONFIG_FATFS 1) + +set(CONFIG_BSP_SDH_SDCARD 1) +set(CONFIG_BSP_FATFS_SDH_SDCARD 1) \ No newline at end of file