diff --git a/Makefile b/Makefile index 306b40b..dc87d42 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: help full base os prng testing uuid all clean builddir build-test run-test codegen install build-lib ccodegen +.PHONY: help full base os prng testing uuid all clean builddir build-test run-test install build-lib ccodegen # External variables CC = clang @@ -7,7 +7,6 @@ AR = ar BUILD_TYPE = Debug BUILD_DIR = libwapp-build/$(PLATFORM)-$(BUILD_TYPE) INSTALL_PREFIX = dist -CODEGEN_INPUT = "" RUNTIME_ASSERT = true # Internal variables @@ -95,7 +94,7 @@ ifeq ($(KERNEL), Darwin) ECHO_E = echo endif -all: clean builddir codegen run-c-test full run-cc-test +all: clean builddir run-c-test full run-cc-test help: @$(ECHO_E) "$(BOLD)$(BLUE)Available build variables:$(RESET)" @@ -105,7 +104,6 @@ help: @$(ECHO_E) " $(GREEN)BUILD_TYPE$(RESET) Build type $(MAGENTA)[Debug | RelWithDebInfo | Release] $(YELLOW)(Default: Debug)$(RESET)." @$(ECHO_E) " $(GREEN)BUILD_DIR$(RESET) Directory where build files will be written." @$(ECHO_E) " $(GREEN)INSTALL_PREFIX$(RESET) Prefix where library and include files will be installed." - @$(ECHO_E) " $(GREEN)CODEGEN_INPUT$(RESET) Input file for code generation (See $(CYAN)codegen_custom_data_example.json$(RESET) for an example)." @$(ECHO_E) " $(GREEN)RUNTIME_ASSERT$(RESET) Whether runtime asserts are enabled $(MAGENTA)[true | false] $(YELLOW)(Default: true)$(RESET)." @$(ECHO_E) " $(GREEN)$(RESET) $(BOLD)$(BG_RED)DISCLAIMER:$(RESET) Using this flag is not recommended as it disables safety checks" @$(ECHO_E) " $(GREEN)$(RESET) potentially leading to Undefined Behaviour." @@ -167,10 +165,7 @@ run-cc-test: build-cc-test @export LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:"$(BUILD_DIR)" && "$(TEST_CXX_OUT)" @rm "$(TEST_CXX_OUT)" -codegen: - python3 -m codegen -f $(CODEGEN_INPUT) - -install: codegen build-lib +install: build-lib @mkdir -p "$(LIB_INSTALL)" @cp -v "$(LIB_OUT)" "$(LIB_INSTALL)" @mkdir -p "$(INCLUDE_INSTALL)" diff --git a/codegen/__main__.py b/codegen/__main__.py deleted file mode 100644 index abf015d..0000000 --- a/codegen/__main__.py +++ /dev/null @@ -1,47 +0,0 @@ -import json -from typing import Dict -from pathlib import Path -from codegen.datatypes import CDataType, CStruct -from codegen.constants import WAPP_REPO_ROOT, DBL_LIST_DATA -from codegen.dbl_list.make_dbl_list import DblListData, make_dbl_list - - -def main(types_file: Path | None): - dbl_list_datatypes: Dict[CDataType, DblListData] = {} - - if types_file is not None and types_file.is_file() and "json" in types_file.suffix.lower(): - with types_file.open("r") as infile: - datatypes = json.load(infile) - dbl_list_data = datatypes.get(DBL_LIST_DATA) - - if dbl_list_data is not None and isinstance(dbl_list_data, dict): - dbl_list_datatypes = {k: DblListData.from_dict(v) for k, v in dbl_list_data.items()} - - make_dbl_list(dbl_list_datatypes) - - # Save example types file - custom_struct = CStruct(name="custom_type", cargs=[], typedef_name="CustomType") - example = { - DBL_LIST_DATA: { - "CustomType": DblListData( - node_typename="CustomTypeNode", - list_typename="CustomTypeList", - hdr_decl_types=[custom_struct], - ).to_dict() - }, - } - - example_file = WAPP_REPO_ROOT / "codegen_custom_data_example.json" - with example_file.open("w") as outfile: - json.dump(example, outfile, indent=2) - - -if __name__ == "__main__": - from argparse import ArgumentParser - - parser = ArgumentParser() - parser.add_argument("-f", "--types-file", type=Path, help="JSON file containing custom types for codegen") - - args = parser.parse_args() - - main(args.types_file) diff --git a/codegen/constants.py b/codegen/constants.py deleted file mode 100644 index 3647b1a..0000000 --- a/codegen/constants.py +++ /dev/null @@ -1,9 +0,0 @@ -from pathlib import Path - -# Paths -PACKAGE_DIR = Path(__file__).parent.resolve() -WAPP_REPO_ROOT = PACKAGE_DIR.parent -WAPP_SRC_ROOT = WAPP_REPO_ROOT / "src" - -# Dictionary Keys -DBL_LIST_DATA = "dbl_list_data" diff --git a/codegen/datatypes.py b/codegen/datatypes.py deleted file mode 100644 index b98eda3..0000000 --- a/codegen/datatypes.py +++ /dev/null @@ -1,503 +0,0 @@ -from enum import Enum -from pathlib import Path -from typing import Optional, Union, List, Dict, Type, Any, TypeVar, cast -from dataclasses import dataclass, asdict, field, fields - -from codegen.constants import WAPP_SRC_ROOT -from codegen.utils import convert_to_relative - -E = TypeVar("E", bound="Enum") -S = TypeVar("S", bound="SerialisableDataclass") -F = TypeVar("F", bound="CFile") - -@dataclass -class SerialisableDataclass: - def to_dict(self) -> Dict[str, Any]: - d = asdict(self) - for f in fields(self): - member = getattr(self, f.name) - - if isinstance(member, list): - d[f.name] = [self.__serialise_member(i) for i in member] - else: - d[f.name] = self.__serialise_member(member) - - return d - - def __serialise_member(self, member: Any) -> Any: - if isinstance(member, Enum): - return member.value - elif isinstance(member, SerialisableDataclass): - return member.to_dict() - - return member - - @staticmethod - def to_enum_value(value: Any, _type: Type[E]) -> "E": - if isinstance(value, _type): - return value - - return _type(value) - - @staticmethod - def to_c_usertype(value: dict[str, Any]) -> "CUserType": - try: - output = CStruct.from_dict(value) - except TypeError: - output = CEnum.from_dict(value) - - return output - - @staticmethod - def to_cdatatype(value: Any) -> "CDataType": - if isinstance(value, dict): - output = SerialisableDataclass.to_c_usertype(value) - else: - try: - output = CType(value) - except ValueError: - output = value - - return output - - @classmethod - def from_dict(cls: Type[S], d: Dict[str, Any]) -> "S": - return cls(**d) - - -class CType(Enum): - VOID = "void" - BOOL = "b8" - CHAR = "char" - C8 = "c8" - C16 = "c16" - C32 = "c32" - I8 = "i8" - I16 = "i16" - I32 = "i32" - I64 = "i64" - U8 = "u8" - U16 = "u16" - U32 = "u32" - U64 = "u64" - F32 = "f32" - F64 = "f64" - F128 = "f128" - IPTR = "iptr" - UPTR = "uptr" - - def __str__(self) -> str: - return self.value - - -class CQualifier(Enum): - NONE = "" - CONST = "const " - EXTERNAL = "wapp_extern " - INTERNAL = "wapp_intern " - PERSISTENT = "wapp_persist " - - def __str__(self) -> str: - return self.value - - -class CPointerType(Enum): - NONE = "" - SINGLE = "*" - DOUBLE = "**" - - def __str__(self) -> str: - return self.value - - -@dataclass -class CPointer(SerialisableDataclass): - _type: CPointerType = CPointerType.NONE - qualifier: CQualifier = CQualifier.NONE - - def __str__(self) -> str: - return str(self._type) + str(self.qualifier) - - @classmethod - def from_dict(cls: Type["CPointer"], d: Dict[str, Any]) -> "CPointer": - ptr = CPointer(**d) - ptr._type = CPointer.to_enum_value(ptr._type, CPointerType) - ptr.qualifier = CPointer.to_enum_value(ptr.qualifier, CQualifier) - return ptr - - -@dataclass -class CEnumVal(SerialisableDataclass): - name: str - value: Optional[int] = None - - def __str__(self) -> str: - return self.name + "" if self.value is None else f" = {self.value}" - - -@dataclass -class CEnum(SerialisableDataclass): - name: str - values: List[CEnumVal] - typedef: bool = False - - def __str__(self) -> str: - if self.typedef: - header = "typedef enum {\n" - footer = f"}} {self.name};\n" - else: - header = f"enum {self.name} {{\n" - footer = "};\n" - - values = "" - for value in self.values: - values += f" {str(value)},\n" - - return header + values + footer - - @classmethod - def from_dict(cls: Type["CEnum"], d: Dict[str, Any]) -> "CEnum": - e = CEnum(**d) - e.values = [CEnumVal.from_dict(v) for v in e.values if isinstance(v, dict)] - return e - - -@dataclass -class CMacro(SerialisableDataclass): - name: str - value: str - - def __str__(self) -> str: - return f"#define {self.name} {self.value}\n" - - -@dataclass -class CStruct(SerialisableDataclass): - name: str - cargs: List["CArg"] - typedef_name: Optional[str] = None - - def __str__(self) -> str: - return self.declare() + self.define() - - def declare(self) -> str: - declaration = f"typedef struct {self.name} {self.typedef_name if self.typedef_name is not None else self.name};\n" - return declaration - - def define(self): - definition = f"struct {self.name} {{\n" - args = "" - for arg in self.cargs: - args += f" {str(arg)};\n" - footer = "};\n" - - return definition + args + footer; - - @classmethod - def from_dict(cls: Type["CStruct"], d: Dict[str, Any]) -> "CStruct": - s = CStruct(**d) - s.cargs = [CArg.from_dict(v) for v in s.cargs if isinstance(v, dict)] - return s - - -CUserType = Union[CStruct, CEnum] -CDataType = Union[CType, CUserType, str] - - -@dataclass -class CArg(SerialisableDataclass): - name: str - _type: CDataType - array: bool = False - pointer: CPointer = field(default_factory=CPointer) - qualifier: CQualifier = CQualifier.NONE - - def __str__(self) -> str: - qualifier = str(self.qualifier) - _type = get_datatype_string(self._type) + " " - pointer = str(self.pointer) - array = "[]" if self.array else "" - - return qualifier + _type + pointer + self.name + array - - @classmethod - def from_dict(cls: Type["CArg"], d: Dict[str, Any]) -> "CArg": - arg = CArg(**d) - arg._type = CArg.to_cdatatype(arg._type) - - if isinstance(arg.pointer, dict): - arg.pointer = CPointer.from_dict(arg.pointer) - - arg.qualifier = CArg.to_enum_value(arg.qualifier, CQualifier) - - return arg - - -@dataclass -class CFunc(SerialisableDataclass): - name: str - ret_type: CDataType - args: List[CArg] - body: str - pointer: CPointer = field(default_factory=CPointer) - qualifiers: List[CQualifier] = field(default_factory=list) - - def __str__(self) -> str: - qualifiers = "" - for qualifier in self.qualifiers: - if qualifier == CQualifier.NONE: - continue - if len(qualifiers) > 0: - qualifiers += " " - qualifiers += f"{str(qualifier)}" - - args = "" - for i, arg in enumerate(self.args): - args += f"{str(arg)}" - if i + 1 < len(self.args): - args += ", " - - return qualifiers + get_datatype_string(self.ret_type) + " " + str(self.pointer) + self.name + f"({args})" - - def declare(self) -> str: - return f"{str(self)};\n" - - def define(self) -> str: - return f"{str(self)} {{\n{self.body}\n}}\n\n" - - @classmethod - def from_dict(cls: Type["CFunc"], d: Dict[str, Any]) -> "CFunc": - f = CFunc(**d) - f.ret_type = CFunc.to_cdatatype(f.ret_type) - f.args = [CArg.from_dict(v) for v in f.args if isinstance(v, dict)] - f.qualifiers = [CFunc.to_enum_value(v, CQualifier) for v in f.qualifiers] - - if isinstance(f.pointer, dict): - f.pointer = CPointer.from_dict(f.pointer) - - return f - - -@dataclass -class CInclude(SerialisableDataclass): - header: Union[str, "CHeader"] - local: bool = False - same_dir: bool = False - - def __str__(self) -> str: - if isinstance(self.header, CHeader): - name = f"{self.header.name}.{self.header.extension}" - else: - name = self.header - - if self.local: - open_symbol = '"' - close_symbol = '"' - - if self.same_dir: - name = f"./{name}" - else: - open_symbol = '<' - close_symbol = '>' - - return f"#include {open_symbol}{name}{close_symbol}\n" - - @classmethod - def from_dict(cls: Type["CInclude"], d: Dict[str, Any]) -> "CInclude": - inc = CInclude(**d) - - if isinstance(inc.header, dict): - inc.header = CHeader.from_dict(inc.header) - - return inc - - -@dataclass -class CFile(SerialisableDataclass): - name: str - extension: str - includes: List[CInclude] = field(default_factory=list) - types: List[CUserType] = field(default_factory=list) - funcs: List[CFunc] = field(default_factory=list) - decl_types: List[CStruct] = field(default_factory=list) - macros: List[CMacro] = field(default_factory=list) - c_macros: List[CMacro] = field(default_factory=list) - cpp_macros: List[CMacro] = field(default_factory=list) - - def save(self, output_dir: Path): - self.includes.extend( - [ - CInclude( - header=str(convert_to_relative(WAPP_SRC_ROOT / "common" / "aliases" / "aliases.h", output_dir)).replace("\\", "/"), - local=True, - ), - CInclude( - header=str(convert_to_relative(WAPP_SRC_ROOT / "common" / "platform" / "platform.h", output_dir)).replace("\\", "/"), - local=True, - ) - ] - ) - output_file = output_dir / f"{self.name}.{self.extension}" - with open(output_file, "w+") as outfile: - outfile.write(str(self)) - - def __str__(self) -> str: - return """\ -/** - * THIS FILE IS AUTOMATICALLY GENERATED. ANY MODIFICATIONS TO IT WILL BE OVERWRITTEN. - */ - -""" - - @classmethod - def from_dict(cls: Type["CFile"], d: Dict[str, Any]) -> "CFile": - f = CFile(**d) - f.deserialise_c_file_data() - - return f - - def deserialise_c_file_data(self) -> None: - self.includes = [CInclude.from_dict(v) for v in self.includes if isinstance(v, dict)] - self.types = [CFile.to_c_usertype(v) for v in self.types if isinstance(v, dict)] - self.funcs = [CFunc.from_dict(v) for v in self.funcs if isinstance(v, dict)] - self.decl_types = [CStruct.from_dict(v) for v in self.decl_types if isinstance(v, dict)] - self.macros = [CMacro.from_dict(v) for v in self.macros if isinstance(v, dict)] - self.c_macros = [CMacro.from_dict(v) for v in self.c_macros if isinstance(v, dict)] - self.cpp_macros = [CMacro.from_dict(v) for v in self.cpp_macros if isinstance(v, dict)] - - -@dataclass -class CHeader(CFile): - extension: str = "h" - - def __str__(self) -> str: - name_upper = self.name.upper() - header_guard_name = f"{name_upper}_H" - header_guard_open = f"#ifndef {header_guard_name}\n#define {header_guard_name}\n\n" - header_guard_close = f"#endif // !{header_guard_name}\n" - - c_linkage_open = "#ifdef WAPP_PLATFORM_CPP\nBEGIN_C_LINKAGE\n#endif // !WAPP_PLATFORM_CPP\n\n" - c_linkage_close = "\n#ifdef WAPP_PLATFORM_CPP\nEND_C_LINKAGE\n#endif // !WAPP_PLATFORM_CPP\n\n" - - includes = _get_includes_string(self.includes) - - macros = "" - for macro in self.macros: - macros += str(macro) - if len(macros) > 0: - macros += "\n" - - if len(self.cpp_macros) > 0: - macros += "#ifdef WAPP_PLATFORM_CPP\n" - for macro in self.cpp_macros: - macros += str(macro) - macros += "#else\n" - for macro in self.c_macros: - macros += str(macro) - macros += "#endif // !WAPP_PLATFORM_CPP\n\n" - - forward_declarations = "" - for _type in self.decl_types: - forward_declarations += _type.declare() - if len(forward_declarations) > 0: - forward_declarations += "\n" - - types = "" - for _type in self.types: - types += str(_type) + "\n" - - funcs = "" - for func in self.funcs: - funcs += func.declare() - - return ( - super().__str__() + - header_guard_open + - includes + - c_linkage_open + - macros + - forward_declarations + - types + - funcs + - c_linkage_close + - header_guard_close - ) - - @classmethod - def from_dict(cls: Type["CHeader"], d: Dict[str, Any]) -> "CHeader": - return cast("CHeader", super().from_dict(d)) - - -@dataclass -class CSource(CFile): - extension: str = "c" - internal_funcs: List[CFunc] = field(default_factory=list) - - def __str__(self) -> str: - includes = _get_includes_string(self.includes) - - macros = "" - for macro in self.macros: - macros += str(macro) - if len(macros) > 0: - macros += "\n" - - forward_declarations = "" - for _type in self.decl_types: - forward_declarations += _type.declare() - if len(forward_declarations) > 0: - forward_declarations += "\n" - - types = "" - for _type in self.types: - types += str(_type) + "\n" - - internal_funcs_decl = "" - internal_funcs_def = "" - for func in self.internal_funcs: - internal_funcs_decl += func.declare() - internal_funcs_def += func.define() - - if len(internal_funcs_decl) > 0: - internal_funcs_decl += "\n" - - funcs = "" - for func in self.funcs: - funcs += func.define() - - return ( - super().__str__() + - includes + - macros + - forward_declarations + - types + - internal_funcs_decl + - funcs + - internal_funcs_def - ) - - @classmethod - def from_dict(cls: Type["CSource"], d: Dict[str, Any]) -> "CSource": - s = CSource(**d) - s.deserialise_c_file_data() - s.internal_funcs = [CFunc.from_dict(v) for v in s.funcs if isinstance(v, dict)] - return s - - -def get_datatype_string(_type: CDataType) -> str: - if isinstance(_type, CType): - return str(_type) - elif isinstance(_type, CStruct) or isinstance(_type, CEnum): - return _type.name - elif isinstance(_type, str): - return _type - - -def _get_includes_string(includes: List[CInclude]) -> str: - output = "" - for include in sorted(includes, key=lambda inc: inc.local, reverse=True): - output += str(include) - if len(output) > 0: - output += "\n" - - return output diff --git a/codegen/dbl_list/make_dbl_list.py b/codegen/dbl_list/make_dbl_list.py deleted file mode 100644 index 775d313..0000000 --- a/codegen/dbl_list/make_dbl_list.py +++ /dev/null @@ -1,339 +0,0 @@ -from pathlib import Path -from dataclasses import dataclass, field -from typing import List, Dict, Any, Type -from codegen.constants import WAPP_SRC_ROOT -from codegen.utils import load_func_body_from_file, convert_to_relative -from codegen.datatypes import ( - CDataType, - CMacro, - CStruct, - CFunc, - CHeader, - CSource, - CArg, - CType, - CPointer, - CPointerType, - CQualifier, - CInclude, - SerialisableDataclass, - get_datatype_string, -) - - -@dataclass -class DblListData(SerialisableDataclass): - node_typename: str - list_typename: str - hdr_decl_types: List[CStruct] = field(default_factory=list) - src_decl_types: List[CStruct] = field(default_factory=list) - - @classmethod - def from_dict(cls: Type["DblListData"], d: Dict[str, Any]) -> "DblListData": - data = DblListData(**d) - data.hdr_decl_types = [CStruct.from_dict(v) for v in data.hdr_decl_types if isinstance(v, dict)] - data.src_decl_types = [CStruct.from_dict(v) for v in data.src_decl_types if isinstance(v, dict)] - return data - - -def make_dbl_list(user_datatypes: Dict[CDataType, DblListData] = {}): - def __format_func_body( - filename: Path, - type_string: str, - type_string_upper: str, - type_string_lower: str, - node_typename: str, - list_typename: str - ): - return load_func_body_from_file(filename).format( - T=type_string, - NodeType=node_typename, - ListType=list_typename, - Tupper=type_string_upper, - Tlower=type_string_lower, - ) - - out_dir = WAPP_SRC_ROOT / "base" / "dbl_list" - out_dir.mkdir(parents=True, exist_ok=True) - - common_decl_types: List[CStruct] = [] - - datatypes: dict[CDataType, DblListData] = { - CType.VOID: DblListData(node_typename="GenericNode", list_typename="GenericList"), - "void *": DblListData(node_typename="VoidPNode", list_typename="VoidPList"), - "Str8": DblListData( - node_typename="Str8Node", - list_typename="Str8List", - hdr_decl_types=[ - CStruct(name="str8", cargs=[], typedef_name="Str8"), - ], - ), - } - - for _type in CType: - if _type == CType.VOID: - continue - - type_title = _type.value.title() - datatypes[_type] = DblListData( - node_typename=f"{type_title}Node", - list_typename=f"{type_title}List", - ) - - datatypes.update(user_datatypes) - - snippets_dir = Path(__file__).parent / "snippets" - - header = CHeader( - name="dbl_list", - decl_types=[*common_decl_types], - includes=[], - types=[], - funcs=[] - ) - - source = CSource( - name=header.name, - decl_types=[*common_decl_types], - includes=[ - CInclude(header, local=True, same_dir=True), - CInclude( - header=str(convert_to_relative(WAPP_SRC_ROOT / "common" / "assert" / "assert.h", out_dir)).replace("\\", "/"), - local=True - ), - CInclude(header="stddef.h"), - ], - internal_funcs=[], - funcs=header.funcs - ) - - for _type, dbl_list_data in datatypes.items(): - type_string = get_datatype_string(_type) - clean_type_string = type_string.replace(" ", "").replace("*", "_ptr") - type_string_upper = clean_type_string.upper() - type_string_lower = clean_type_string.lower() - - node = CStruct( - name=dbl_list_data.node_typename, - cargs=[ - CArg(name="item", _type=type_string, pointer=CPointer(_type=CPointerType.SINGLE)), - ], - ) - node.cargs.extend([ - CArg(name="prev", _type=node, pointer=CPointer(_type=CPointerType.SINGLE)), - CArg(name="next", _type=node, pointer=CPointer(_type=CPointerType.SINGLE)), - ]) - - dl_list = CStruct( - name=dbl_list_data.list_typename, - cargs=[ - CArg(name="first", _type=node, pointer=CPointer(_type=CPointerType.SINGLE)), - CArg(name="last", _type=node, pointer=CPointer(_type=CPointerType.SINGLE)), - CArg(name="node_count", _type=CType.U64), - ], - ) - - header.types.extend([node, dl_list]) - header.decl_types.extend(dbl_list_data.hdr_decl_types) - source.decl_types.extend(dbl_list_data.src_decl_types) - if isinstance(_type, CType) and _type == CType.VOID: - # Don't define any functions for the generic node and list - continue - - node_cmacro = CMacro( - name=f"wapp_{type_string_lower}_list_node(ITEM_PTR)", - value=__format_func_body( - filename=snippets_dir / "list_node", - type_string=type_string, - type_string_upper=type_string_upper, - type_string_lower=type_string_lower, - node_typename=dbl_list_data.node_typename, - list_typename=dbl_list_data.list_typename - ), - ) - - node_cppmacro = CMacro( - name=f"wapp_{type_string_lower}_list_node(ITEM_PTR)", - value=__format_func_body( - filename=snippets_dir / "list_node_cpp", - type_string=type_string, - type_string_upper=type_string_upper, - type_string_lower=type_string_lower, - node_typename=dbl_list_data.node_typename, - list_typename=dbl_list_data.list_typename - ), - ) - - get_func = CFunc( - name=f"wapp_{type_string_lower}_list_get", - ret_type=node, - args=[ - CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE), qualifier=CQualifier.CONST), - CArg(name="index", _type=CType.U64), - ], - body=__format_func_body( - filename=snippets_dir / "list_get", - type_string=type_string, - type_string_upper=type_string_upper, - type_string_lower=type_string_lower, - node_typename=dbl_list_data.node_typename, - list_typename=dbl_list_data.list_typename - ), - pointer=CPointer(CPointerType.SINGLE), - ) - - push_front_func = CFunc( - name=f"wapp_{type_string_lower}_list_push_front", - ret_type=CType.VOID, - args=[ - CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)), - CArg(name="node", _type=node, pointer=CPointer(CPointerType.SINGLE)), - ], - body=__format_func_body( - filename=snippets_dir / "list_push_front", - type_string=type_string, - type_string_upper=type_string_upper, - type_string_lower=type_string_lower, - node_typename=dbl_list_data.node_typename, - list_typename=dbl_list_data.list_typename - ), - ) - - push_back_func = CFunc( - name=f"wapp_{type_string_lower}_list_push_back", - ret_type=CType.VOID, - args=[ - CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)), - CArg(name="node", _type=node, pointer=CPointer(CPointerType.SINGLE)), - ], - body=__format_func_body( - filename=snippets_dir / "list_push_back", - type_string=type_string, - type_string_upper=type_string_upper, - type_string_lower=type_string_lower, - node_typename=dbl_list_data.node_typename, - list_typename=dbl_list_data.list_typename - ), - ) - - insert_func = CFunc( - name=f"wapp_{type_string_lower}_list_insert", - ret_type=CType.VOID, - args=[ - CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)), - CArg(name="node", _type=node, pointer=CPointer(CPointerType.SINGLE)), - CArg(name="index", _type=CType.U64), - ], - body=__format_func_body( - filename=snippets_dir / "list_insert", - type_string=type_string, - type_string_upper=type_string_upper, - type_string_lower=type_string_lower, - node_typename=dbl_list_data.node_typename, - list_typename=dbl_list_data.list_typename - ), - ) - - pop_front_func = CFunc( - name=f"wapp_{type_string_lower}_list_pop_front", - ret_type=node, - args=[ - CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)), - ], - body=__format_func_body( - filename=snippets_dir / "list_pop_front", - type_string=type_string, - type_string_upper=type_string_upper, - type_string_lower=type_string_lower, - node_typename=dbl_list_data.node_typename, - list_typename=dbl_list_data.list_typename - ), - pointer=CPointer(CPointerType.SINGLE), - ) - - pop_back_func = CFunc( - name=f"wapp_{type_string_lower}_list_pop_back", - ret_type=node, - args=[ - CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)), - ], - body=__format_func_body( - filename=snippets_dir / "list_pop_back", - type_string=type_string, - type_string_upper=type_string_upper, - type_string_lower=type_string_lower, - node_typename=dbl_list_data.node_typename, - list_typename=dbl_list_data.list_typename - ), - pointer=CPointer(CPointerType.SINGLE), - ) - - remove_func = CFunc( - name=f"wapp_{type_string_lower}_list_remove", - ret_type=node, - args=[ - CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)), - CArg(name="index", _type=CType.U64), - ], - body=__format_func_body( - filename=snippets_dir / "list_remove", - type_string=type_string, - type_string_upper=type_string_upper, - type_string_lower=type_string_lower, - node_typename=dbl_list_data.node_typename, - list_typename=dbl_list_data.list_typename - ), - pointer=CPointer(CPointerType.SINGLE), - ) - - empty_func = CFunc( - name=f"wapp_{type_string_lower}_list_empty", - ret_type=CType.VOID, - args=[ - CArg(name="list", _type=dl_list, pointer=CPointer(CPointerType.SINGLE)), - ], - body=__format_func_body( - filename=snippets_dir / "list_empty", - type_string=type_string, - type_string_upper=type_string_upper, - type_string_lower=type_string_lower, - node_typename=dbl_list_data.node_typename, - list_typename=dbl_list_data.list_typename - ), - ) - - node_to_list_func = CFunc( - name=f"{type_string_lower}_node_to_list", - ret_type=dl_list, - args=[ - CArg(name="node", _type=node, pointer=CPointer(CPointerType.SINGLE)), - ], - body=__format_func_body( - filename=snippets_dir / "node_to_list", - type_string=type_string, - type_string_upper=type_string_upper, - type_string_lower=type_string_lower, - node_typename=dbl_list_data.node_typename, - list_typename=dbl_list_data.list_typename - ), - qualifiers=[CQualifier.INTERNAL], - ) - - header.c_macros.append(node_cmacro) - header.cpp_macros.append(node_cppmacro) - header.funcs.extend([ - get_func, - push_front_func, - push_back_func, - insert_func, - pop_front_func, - pop_back_func, - remove_func, - empty_func, - ]) - - source.internal_funcs.append(node_to_list_func) - source.funcs = header.funcs - - header.save(out_dir) - source.save(out_dir) diff --git a/codegen/dbl_list/snippets/list_empty b/codegen/dbl_list/snippets/list_empty deleted file mode 100644 index 11802cb..0000000 --- a/codegen/dbl_list/snippets/list_empty +++ /dev/null @@ -1,6 +0,0 @@ - wapp_debug_assert(list != NULL, "`list` should not be NULL"); - - u64 count = list->node_count; - for (u64 i = 0; i < count; ++i) {{ - wapp_{Tlower}_list_pop_back(list); - }} diff --git a/codegen/dbl_list/snippets/list_get b/codegen/dbl_list/snippets/list_get deleted file mode 100644 index c5733cf..0000000 --- a/codegen/dbl_list/snippets/list_get +++ /dev/null @@ -1,11 +0,0 @@ - wapp_runtime_assert(index < list->node_count, "`index` is out of bounds"); - - {NodeType} *output = NULL; - {NodeType} *current = list->first; - for (u64 i = 1; i <= index; ++i) {{ - current = current->next; - }} - - output = current; - - return output; diff --git a/codegen/dbl_list/snippets/list_insert b/codegen/dbl_list/snippets/list_insert deleted file mode 100644 index c4e1d5f..0000000 --- a/codegen/dbl_list/snippets/list_insert +++ /dev/null @@ -1,26 +0,0 @@ - wapp_debug_assert(list != NULL && node != NULL && (node->item) != NULL, "`list`, `node` and `node->item` should not be NULL"); - - if (index == 0) {{ - wapp_{Tlower}_list_push_front(list, node); - return; - }} else if (index == list->node_count) {{ - wapp_{Tlower}_list_push_back(list, node); - return; - }} - - {NodeType} *dst_node = wapp_{Tlower}_list_get(list, index); - if (!dst_node) {{ - return; - }} - - {ListType} node_list = {Tlower}_node_to_list(node); - - list->node_count += node_list.node_count; - - {NodeType} *prev = dst_node->prev; - - dst_node->prev = node_list.last; - prev->next = node_list.first; - - node_list.first->prev = prev; - node_list.last->next = dst_node; diff --git a/codegen/dbl_list/snippets/list_node b/codegen/dbl_list/snippets/list_node deleted file mode 100644 index 3eec148..0000000 --- a/codegen/dbl_list/snippets/list_node +++ /dev/null @@ -1 +0,0 @@ -(({NodeType}){{.item = ITEM_PTR}}) diff --git a/codegen/dbl_list/snippets/list_node_cpp b/codegen/dbl_list/snippets/list_node_cpp deleted file mode 100644 index c753803..0000000 --- a/codegen/dbl_list/snippets/list_node_cpp +++ /dev/null @@ -1 +0,0 @@ -{NodeType}{{ITEM_PTR, nullptr, nullptr}} diff --git a/codegen/dbl_list/snippets/list_pop_back b/codegen/dbl_list/snippets/list_pop_back deleted file mode 100644 index 0bf82f0..0000000 --- a/codegen/dbl_list/snippets/list_pop_back +++ /dev/null @@ -1,22 +0,0 @@ - wapp_debug_assert(list != NULL, "`list` should not be NULL"); - - {NodeType} *output = NULL; - - if (list->node_count == 0) {{ - goto RETURN_{Tupper}_LIST_POP_BACK; - }} - - output = list->last; - - if (list->node_count == 1) {{ - *list = ({ListType}){{0}}; - goto RETURN_{Tupper}_LIST_POP_BACK; - }} - - --(list->node_count); - list->last = output->prev; - - output->prev = output->next = NULL; - -RETURN_{Tupper}_LIST_POP_BACK: - return output; diff --git a/codegen/dbl_list/snippets/list_pop_front b/codegen/dbl_list/snippets/list_pop_front deleted file mode 100644 index c4a868e..0000000 --- a/codegen/dbl_list/snippets/list_pop_front +++ /dev/null @@ -1,22 +0,0 @@ - wapp_debug_assert(list != NULL, "`list` should not be NULL"); - - {NodeType} *output = NULL; - - if (list->node_count == 0) {{ - goto RETURN_{Tupper}_LIST_POP_FRONT; - }} - - output = list->first; - - if (list->node_count == 1) {{ - *list = ({ListType}){{0}}; - goto RETURN_{Tupper}_LIST_POP_FRONT; - }} - - --(list->node_count); - list->first = output->next; - - output->prev = output->next = NULL; - -RETURN_{Tupper}_LIST_POP_FRONT: - return output; diff --git a/codegen/dbl_list/snippets/list_push_back b/codegen/dbl_list/snippets/list_push_back deleted file mode 100644 index a042ba8..0000000 --- a/codegen/dbl_list/snippets/list_push_back +++ /dev/null @@ -1,18 +0,0 @@ - wapp_debug_assert(list != NULL && node != NULL && (node->item) != NULL, "`list`, `node` and `node->item` should not be NULL"); - - {ListType} node_list = {Tlower}_node_to_list(node); - - if (list->node_count == 0) {{ - *list = node_list; - return; - }} - - list->node_count += node_list.node_count; - - {NodeType} *last = list->last; - if (last) {{ - last->next = node_list.first; - }} - - list->last = node_list.last; - node_list.first->prev = last; diff --git a/codegen/dbl_list/snippets/list_push_front b/codegen/dbl_list/snippets/list_push_front deleted file mode 100644 index cacabbc..0000000 --- a/codegen/dbl_list/snippets/list_push_front +++ /dev/null @@ -1,18 +0,0 @@ - wapp_debug_assert(list != NULL && node != NULL && (node->item) != NULL, "`list`, `node` and `node->item` should not be NULL"); - - {ListType} node_list = {Tlower}_node_to_list(node); - - if (list->node_count == 0) {{ - *list = node_list; - return; - }} - - list->node_count += node_list.node_count; - - {NodeType} *first = list->first; - if (first) {{ - first->prev = node_list.last; - }} - - list->first = node_list.first; - node_list.last->next = first; diff --git a/codegen/dbl_list/snippets/list_remove b/codegen/dbl_list/snippets/list_remove deleted file mode 100644 index b044868..0000000 --- a/codegen/dbl_list/snippets/list_remove +++ /dev/null @@ -1,26 +0,0 @@ - wapp_debug_assert(list != NULL, "`list` should not be NULL"); - - {NodeType} *output = NULL; - - if (index == 0) {{ - output = wapp_{Tlower}_list_pop_front(list); - goto RETURN_{Tupper}_LIST_REMOVE; - }} else if (index == list->node_count) {{ - output = wapp_{Tlower}_list_pop_back(list); - goto RETURN_{Tupper}_LIST_REMOVE; - }} - - output = wapp_{Tlower}_list_get(list, index); - if (!output) {{ - goto RETURN_{Tupper}_LIST_REMOVE; - }} - - output->prev->next = output->next; - output->next->prev = output->prev; - - --(list->node_count); - - output->prev = output->next = NULL; - -RETURN_{Tupper}_LIST_REMOVE: - return output; diff --git a/codegen/dbl_list/snippets/node_to_list b/codegen/dbl_list/snippets/node_to_list deleted file mode 100644 index bc8ed05..0000000 --- a/codegen/dbl_list/snippets/node_to_list +++ /dev/null @@ -1,13 +0,0 @@ - {ListType} output = {{.first = node, .last = node, .node_count = 1}}; - - while (output.first->prev != NULL) {{ - output.first = output.first->prev; - ++(output.node_count); - }} - - while (output.last->next != NULL) {{ - output.last = output.last->next; - ++(output.node_count); - }} - - return output; diff --git a/codegen/utils.py b/codegen/utils.py deleted file mode 100644 index e6d82f0..0000000 --- a/codegen/utils.py +++ /dev/null @@ -1,18 +0,0 @@ -import os -import sys -from pathlib import Path - - -def load_func_body_from_file(filename: Path) -> str: - with open(filename, "r") as infile: - return infile.read().rstrip() - - -def convert_to_relative(path: Path, target: Path) -> Path: - major = sys.version_info.major - minor = sys.version_info.minor - - if major >= 3 and minor >= 12: - return path.relative_to(target, walk_up=True) - else: - return Path(os.path.relpath(str(path), start=str(target))) \ No newline at end of file diff --git a/codegen_custom_data_example.json b/codegen_custom_data_example.json deleted file mode 100644 index 93a07e5..0000000 --- a/codegen_custom_data_example.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "dbl_list_data": { - "CustomType": { - "node_typename": "CustomTypeNode", - "list_typename": "CustomTypeList", - "hdr_decl_types": [ - { - "name": "custom_type", - "cargs": [], - "typedef_name": "CustomType" - } - ], - "src_decl_types": [] - } - } -} \ No newline at end of file