44 Commits

Author SHA1 Message Date
Ed_
2ad164dc39 CodeSpecifiers fixes 2025-04-02 21:19:15 -04:00
Ed_
878bc4c8ae Merge pull request #72 from Ed94/dev
Changes involved with getting gencpp-odin setup
2025-02-04 22:43:18 -05:00
Ed_
ec8dd1e9cd missing delete specifier (gen_unreal_engine) 2025-02-04 22:37:28 -05:00
Ed_
c0ea2ce3ff fix for edge case (running out of tokens while parsing assignment expression 2025-02-04 22:05:24 -05:00
Ed_
b5652a4dad if on c11 segmented (parsing spec defines were mising!) 2025-02-04 21:42:01 -05:00
Ed_
dda70fce36 can't use static globals on static libs 2025-02-04 21:23:51 -05:00
Ed_
3bce2e9b8a rename GEN_INTELLISENSE_DIRECTIVES -> INTELLISENSE_DIRECTIVES 2025-02-04 18:33:07 -05:00
Ed_
f3f8f2fff2 update readme with related repos 2025-02-04 17:24:03 -05:00
Ed_
c600a3e0dc add missing defines 2025-02-04 17:04:33 -05:00
Ed_
372cda734e fixes for generated c11 segemented 2025-02-04 16:17:29 -05:00
Ed_
6481313969 Various fixes and adjustments
* moved constants to components/constants.hpp (adjsuted generators accordingly)
* parser accepts include & defineas parameter identifiers (will add more flags for keywords when necessary
2025-02-04 15:35:28 -05:00
Ed_
5c17983a73 move more strbuilder functions to cpp 2025-02-04 14:53:26 -05:00
Ed_
b6d95e8d70 move strbuilder_make_space_for to strings.cpp (not inlined) 2025-02-04 14:17:15 -05:00
Ed_
6f2d81434e fixes 2025-02-04 12:57:42 -05:00
Ed_
b8695a33db added missing asserts to serialization functions 2025-02-04 11:50:15 -05:00
Ed_
1f958e121c more adjustments based on odin binding drafting 2025-02-04 01:57:23 -05:00
Ed_
e457191f5d moved seiralization inlines to inlines.hpp, more adjustments 2025-02-03 18:53:35 -05:00
Ed_
0d8f30b25c adjustments based on odin bindings drafting 2025-02-03 11:26:03 -05:00
Ed_
d08efcb5ef Corrections while implementing odin bindings 2025-02-03 09:42:31 -05:00
Ed_
13ebd105c4 Fix for convert_cpp_enum_to_c for gen_c_library
It wasn't generating correct typedefs for when underlying type was used over the enum name.
2025-01-30 14:14:53 -05:00
Ed_
bdd9c9bcdf Fixes for building all library types 2025-01-30 13:57:42 -05:00
Ed_
16bc66c80e Backporting changes done on UnrealGencpp repo
Commits:
ec77e8b - Fixes while parsing EditorEngine.h
5017429 - parse_complicated_definition fix when parsing Controller.h
aac0dd5 - Add  IRISCORE_API
049b59c - Support for attributes retated to an operator or function between the return type and the identifier/op (Thanks World.h...)
97d7e6d - Fix for attributes after name in using statements
9f204e7 - Support for final specifier on class & struct definitions
f0698cc - Added support for Spec_Delete (= delete on functions and operators) [Part 3]
1f6650a - Added support for Spec_Delete (= delete on functions and operators) [Part 2]
06ac8da - Added support for Spec_Delete (= delete on functions and operators)
2025-01-30 13:25:56 -05:00
Ed_
f8c42a53c6 Fix for parse_function_after_name suffix specifier macro 2025-01-29 02:35:55 -05:00
Ed_
eca538c6af Fixes for GEN_API symbol exports necessary for dynamic linking 2025-01-29 02:04:50 -05:00
Ed_
ce2be411d7 Add support for non Specifier enum SuffixSpecs in AST_Fn and parsing (Thanks Unreal) 2025-01-29 01:29:55 -05:00
Ed_
16fc3fa379 Separate ifndef for bitfield_is_set 2025-01-28 21:09:35 -05:00
Ed_
62b36ec8bb misc changes to clang format spacing 2025-01-28 14:49:19 -05:00
Ed_
b6b246fb38 Added refactor.exe binary 2024-12-19 09:40:41 -05:00
Ed_
d91d3c6b6f typo in _Generic psuedo 2024-12-17 13:30:41 -05:00
Ed_
3ab2673fd3 gen_c_library doc update 2024-12-17 13:29:38 -05:00
Ed_
ca7ff99a79 Code type coercion for builder_print in C11 library using generic selector. 2024-12-17 10:03:50 -05:00
Ed_
177820cd6e remove .vscode 2024-12-16 22:24:18 -05:00
Ed_
d254d3aec4 removed custom attribute form gen_unreal_engine (mistake) 2024-12-16 22:00:56 -05:00
Ed_
299f1b1ef7 more proofing 2024-12-16 21:50:59 -05:00
Ed_
9c968967e2 Proofing 2024-12-16 21:48:01 -05:00
Ed_
04ae75c698 Update main readme (old example code) 2024-12-16 21:19:19 -05:00
Ed_
6d551e95b9 Add GEN_PARSER_TYPENAME_ALLOWED_SUFFIX_SPECIFIER_CASES to gen_urneal_engine's case macros 2024-12-16 21:02:16 -05:00
Ed_
a7cb7b0411 adjustment to test_cuik.c 2024-12-16 20:54:19 -05:00
Ed_
46e816d7ce Add restrict specifier support for C 2024-12-16 20:53:56 -05:00
Ed_
28aa2c4dec remove tok_to_str, fix for parsing inpalce dfinitions that don't have an identifier for the type. 2024-12-16 20:53:56 -05:00
Ed_
d410590a86 Update Readme.md 2024-12-16 20:52:15 -05:00
Ed_
e271fa39e4 remove vod 2024-12-16 18:34:50 -05:00
Ed_
08dcc3152f Testing c-library with Cuik parsing... 2024-12-16 18:28:26 -05:00
Ed_
0829603262 Finished updating Parer_Algo.md 2024-12-16 17:59:30 -05:00
100 changed files with 2700 additions and 2012 deletions

5
.gitignore vendored
View File

@ -1,3 +1,4 @@
.vscode
.idea
**/build/*
@ -27,7 +28,7 @@ release/**
**/Unreal/*.h
**/Unreal/*.cpp
! **/Unreal/validate.unreal.cpp
project/auxillary/vis_ast/dependencies/temp
project/auxiliary/vis_ast/dependencies/temp
test/gen/original
singleheader/gen/scratch.hpp
test/gen/scratch.cpp
@ -41,3 +42,5 @@ gen_c_library/gen
**/*.vcxproj.user
test/c_library/gen
test/cpp_library/gen
!scripts/helpers/refactor.exe

View File

@ -1,99 +0,0 @@
{
"configurations": [
{
"name": "Bootstrap",
"includePath": [
"${workspaceFolder}/base/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE",
"GEN_TIME",
"GEN_IMPLEMENTATION",
// "GEN_DONT_USE_NAMESPACE"
"GEN_INTELLISENSE_DIRECTIVES",
"INTELLISENSE_DIRECTIVES"
],
"cStandard": "c11",
"cppStandard": "c++17",
"windowsSdkVersion": "10.0.19041.0",
"compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.29.30133/bin/HostX64/x64/cl.exe",
"intelliSenseMode": "msvc-x64",
"compileCommands": "${workspaceFolder}/.vscode/tasks.json",
"compilerArgs": [
"/EHsc-",
"/GR-",
"/Zc:preprocessor",
"/FC"
]
},
{
"name": "Win32 clang",
"includePath": [
"${workspaceFolder}/base/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE",
"GEN_TIME",
"GEN_IMPLEMENTATION",
// "GEN_DONT_USE_NAMESPACE"
"GEN_INTELLISENSE_DIRECTIVES",
"INTELLISENSE_DIRECTIVES"
],
"cStandard": "c11",
"cppStandard": "c++17",
"windowsSdkVersion": "10.0.19041.0",
"compilerPath": "clang++.exe",
"intelliSenseMode": "windows-clang-x64",
"compileCommands": "${workspaceFolder}/.vscode/tasks.json"
},
{
"name": "Win32 msvc c_library",
"includePath": [
"${workspaceFolder}/gen_c_library/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE",
"GEN_TIME",
"GEN_IMPLEMENTATION",
// "GEN_DONT_USE_NAMESPACE"
"GEN_INTELLISENSE_DIRECTIVES",
"INTELLISENSE_DIRECTIVES"
],
"cStandard": "c11",
"cppStandard": "c++17",
"windowsSdkVersion": "10.0.19041.0",
"compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.29.30133/bin/HostX64/x64/cl.exe",
"intelliSenseMode": "msvc-x64",
"compileCommands": "${workspaceFolder}/.vscode/tasks.json"
},
{
"name": "Win32 msvc c_library test",
"includePath": [
"${workspaceFolder}/test/c_library/**",
"${workspaceFolder}/gen_c_library/gen/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE",
"GEN_TIME",
"GEN_IMPLEMENTATION",
// "GEN_DONT_USE_NAMESPACE"
"GEN_INTELLISENSE_DIRECTIVES",
"INTELLISENSE_DIRECTIVES"
],
"cStandard": "c11",
"windowsSdkVersion": "10.0.19041.0",
"compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.29.30133/bin/HostX64/x64/cl.exe",
"intelliSenseMode": "msvc-x64",
"compileCommands": "${workspaceFolder}/.vscode/tasks.json"
}
],
"version": 4
}

35
.vscode/launch.json vendored
View File

@ -1,35 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "cppvsdbg",
"request": "launch",
"name": "Debug base vsdbg",
"program": "${workspaceFolder}/base/build/base.exe",
"args": [],
"cwd": "${workspaceFolder}/base/",
"visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis"
},
{
"type": "cppvsdbg",
"request": "launch",
"name": "Debug singleheader vsdbg",
"program": "${workspaceFolder}/singleheader/build/singleheader.exe",
"args": [],
"cwd": "${workspaceFolder}/singleheader/",
"visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis"
},
{
"type": "cppvsdbg",
"request": "launch",
"name": "Debug unreal vsdbg",
"program": "${workspaceFolder}/unreal_engine/build/unreal.exe",
"args": [],
"cwd": "${workspaceFolder}/unreal_engine/",
"visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis"
}
]
}

97
.vscode/settings.json vendored
View File

@ -1,97 +0,0 @@
{
"files.associations": {
"*.rmd": "markdown",
"array": "cpp",
"compare": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"xtr1common": "cpp",
"xutility": "cpp",
"initializer_list": "cpp",
"table.h": "c",
"iterator": "cpp",
"memory": "cpp",
"exception": "cpp",
"optional": "cpp",
"tuple": "cpp",
"xmemory": "cpp",
"algorithm": "cpp",
"limits": "cpp",
"concepts": "cpp",
"*.rh": "cpp",
"chrono": "cpp",
"string": "cpp",
"filesystem": "cpp",
"format": "cpp",
"ratio": "cpp",
"xstring": "cpp",
"functional": "cpp",
"vector": "cpp",
"list": "cpp",
"xhash": "cpp",
"glfw3.h": "c",
"stdbool.h": "c",
"objbase.h": "c",
"mmreg.h": "c",
"mmsystem.h": "c",
"propidl.h": "c",
"android_native_app_glue.h": "c",
"raylib.h": "c",
"*.m": "cpp",
"atomic": "cpp",
"gen.h": "c",
"string_ops.hpp": "c",
"assert.h": "c",
"intrin.h": "c",
"bit": "cpp",
"cmath": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"iosfwd": "cpp",
"new": "cpp",
"typeinfo": "cpp",
"unordered_map": "cpp",
"xstddef": "cpp",
"gen_singleheader.h": "c"
},
"C_Cpp.intelliSenseEngineFallback": "disabled",
"mesonbuild.configureOnOpen": true,
"C_Cpp.errorSquiggles": "disabled", // This doesn't work well with how the headers are included.
"godot_tools.scene_file_config": "",
"C_Cpp.default.compilerPath": "cl.exe",
"C_Cpp.exclusionPolicy": "checkFilesAndFolders",
"C_Cpp.files.exclude": {
"**/.vscode": true,
"**/.vs": true,
"**/sanity.gen.hpp": true,
"test/**":true,
},
"autoHide.autoHidePanel": false,
"autoHide.autoHideSideBar": false,
"dimmer.enabled": false,
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#fa1b49",
"activityBar.background": "#fa1b49",
"activityBar.foreground": "#e7e7e7",
"activityBar.inactiveForeground": "#e7e7e799",
"activityBarBadge.background": "#155e02",
"activityBarBadge.foreground": "#e7e7e7",
"commandCenter.border": "#e7e7e799",
"sash.hoverBorder": "#fa1b49",
"statusBar.background": "#dd0531",
"statusBar.foreground": "#e7e7e7",
"statusBarItem.hoverBackground": "#fa1b49",
"statusBarItem.remoteBackground": "#dd0531",
"statusBarItem.remoteForeground": "#e7e7e7",
"titleBar.activeBackground": "#dd0531",
"titleBar.activeForeground": "#e7e7e7",
"titleBar.inactiveBackground": "#dd053199",
"titleBar.inactiveForeground": "#e7e7e799"
},
"peacock.color": "#dd0531"
}

144
.vscode/tasks.json vendored
View File

@ -1,144 +0,0 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Build Bootstrap",
"type": "shell",
"command": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
"args": [
"-ExecutionPolicy",
"Bypass",
"-File",
"${workspaceFolder}/scripts/build.ci.ps1",
"bootstrap",
"msvc"
],
"group": "build",
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*)\\((\\d+)\\)\\s*:\\s*(warning|error)\\s*(\\w+)\\s*:\\s*(.*)$",
"file": 1,
"line": 2,
"severity": 3,
"code": 4,
"message": 5
}
},
"presentation": {
"reveal": "always",
"panel": "shared",
"clear": true
}
},
{
"label": "Build C Library",
"type": "shell",
"command": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
"args": [
"-ExecutionPolicy",
"Bypass",
"-File",
"${workspaceFolder}/scripts/build.ci.ps1",
"c_library",
"msvc"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*)\\((\\d+)\\)\\s*:\\s*(warning|error)\\s*(\\w+)\\s*:\\s*(.*)$",
"file": 1,
"line": 2,
"severity": 3,
"code": 4,
"message": 5
}
},
"presentation": {
"reveal": "always",
"panel": "shared",
"clear": true
}
},
{
"label": "Build Singleheader (MSVC)",
"type": "shell",
"command": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
"args": [
"-ExecutionPolicy",
"Bypass",
"-File",
"${workspaceFolder}/scripts/build.ci.ps1",
"singleheader",
"msvc",
"debug"
],
"group": "build",
"problemMatcher": {
"owner": "cpp",
"fileLocation": ["relative", "${workspaceFolder}"],
"pattern": [
{
"regexp": "^(.*)\\((\\d+)\\)\\s*:\\s*(error|warning|info|note)\\s+(\\w{1,2}\\d+)\\s*:\\s*(.*)$",
"file": 1,
"line": 2,
"severity": 3,
"code": 4,
"message": 5
}
]
},
"presentation": {
"reveal": "always",
"panel": "shared",
"clear": true
}
},
{
"label": "Build Unreal (MSVC)",
"type": "shell",
"command": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
"args": [
"-ExecutionPolicy",
"Bypass",
"-File",
"${workspaceFolder}/scripts/build.ci.ps1",
"unreal",
"msvc",
"debug"
],
"group": "build",
"problemMatcher": {
"owner": "cpp",
"fileLocation": ["relative", "${workspaceFolder}"],
"pattern": [
{
"regexp": "^(.*)\\((\\d+)\\)\\s*:\\s*(error|warning|info|note)\\s+(\\w{1,2}\\d+)\\s*:\\s*(.*)$",
"file": 1,
"line": 2,
"severity": 3,
"code": 4,
"message": 5
}
]
},
"presentation": {
"reveal": "always",
"panel": "shared",
"clear": true
}
}
]
}

View File

@ -11,6 +11,14 @@ These build up a code AST to then serialize with a file builder, or can be trave
This code base attempts follow the [handmade philosophy](https://handmade.network/manifesto).
Its not meant to be a black box metaprogramming utility, it should be easy to integrate into a user's project domain.
## Langauge Bindings
* [gencpp-odin](https://github.com/Ed94/gencpp-odin): Bindings for the odin programming language.
## Utility Libraries
* [UnrealGencpp](https://github.com/Ed94/UnrealGencpp): Setup as a plugin to integrate into Unreal Engine or Unreal Projects.
## Documentation
* [docs - General](./docs/Readme.md): Overview and additional docs
@ -79,18 +87,18 @@ Example using each construction interface:
Validation and construction through a functional interface.
```cpp
Code t_uw = def_type( name(usize) );
Code t_allocator = def_type( name(allocator) );
Code t_string_const = def_type( name(char), def_specifiers( args( ESpecifier::Const, ESpecifier::Ptr ) ));
CodeTypename t_uw = def_type( name(usize) );
CodeTypename t_allocator = def_type( name(allocator) );
CodeTypename t_string_const = def_type( name(char), def_specifiers( args( ESpecifier::Const, ESpecifier::Ptr ) ));
Code header;
CodeStruct header;
{
Code num = def_variable( t_uw, name(Num) );
Code cap = def_variable( t_uw, name(Capacity) );
Code mem_alloc = def_variable( t_allocator, name(Allocator) );
Code body = def_struct_body( args( num, cap, mem_alloc ) );
CodeVar num = def_variable( t_uw, name(Num) );
CodeVar cap = def_variable( t_uw, name(Capacity) );
CodeVar mem_alloc = def_variable( t_allocator, name(Allocator) );
CodeBody body = def_struct_body( args( num, cap, mem_alloc ) );
header = def_struct( name(ArrayHeader), __, __, body );
header = def_struct( name(ArrayHeader), { body });
}
```
@ -99,7 +107,7 @@ Code header;
Validation through ast construction.
```cpp
Code header = parse_struct( code(
CodeStruct header = parse_struct( code(
struct ArrayHeader
{
usize Num;
@ -152,7 +160,7 @@ See the [scripts directory](scripts/).
### Listing definitions in the Cuik Compiler
https://github.com/user-attachments/assets/2302240c-01f1-4e1b-a4b5-292eb3186648
### Unreal: Generating a UAttributeSet from a UDataTable

View File

@ -24,16 +24,16 @@ If using the library's provided build scripts:
* `<push/pop>.<name>.inline.<hpp>`: macros that are meant to be injected at specific locations of the library file/s.
* `misc.hpp`: Misc functionality used by the library generation metaprograms.
* `undef.macros.h`: Undefines all macros from library.
* **auxillary**: Non-essential tooling:
* **auxiliary**: Non-essential tooling:
* `Builder`: Similar conceptually to Jai programming language's *builder*, just opens a file and prepares a string buffer to serialize code into (`builder_print`, `builder_print_fmt`). Then write & close the file when completed (`builder_write`).
* **`Scanner`**: Interface to load up `Code` from files two basic funcctions are currently provided.
* **`Scanner`**: Interface to load up `Code` from files two basic functions are currently provided.
* `scan_file`: Used mainly by the library format generators to directly scan files into untyped `Code` (raw string content, pre-formatted no AST parsed).
* `parse_file`: Used to read file and then parsed to populate a `CodeBody` AST.
* CSV parsing via one or two columns simplified.
* **gen_segemetned**: Dependencies go into gen.dep.{hpp/cpp} and components into gen.{hpp/cpp}
* **gen_singleheader**: Everything into a single file: gen.hpp
* **gen_unreal_engine**: Like gen_segemented but the library is modified slightly to compile as a thirdparty library within an Unreal Engine plugin or module.
* **gen_c_library**: The library is heavily modifed into C11 compliant code. A segemented and single-header set of variants are generated.
* **gen_unreal_engine**: Like gen_segmented but the library is modified slightly to compile as a thirdparty library within an Unreal Engine plugin or module.
* **gen_c_library**: The library is heavily modifed into C11 compliant code. A segmented and single-header set of variants are generated.
Code not making up the core library is located in `auxiliary/<auxiliary_name>.<hpp/cpp>`. These are optional extensions or tools for the library.
@ -108,7 +108,7 @@ Any large macros used implementing the gen interface or parser are going to be p
The vast majority of macros should be single-line subsitutions that either add:
* Improvements to searching
* Inteniality of keyword usage
* Intentionality of keyword usage
* A feature that only the preprocessor has (ex: function name reflection or stringifying)
* Compatibility of statements or expressions bewteen C & C++ that cannot be parsed by gencpp itself.
* Masking highly verbose syntax (the latter is getting phased out).
@ -123,7 +123,7 @@ The vast majority of macros should be single-line subsitutions that either add:
There are ***five*** header files which are automatically generated using [base_codegen.hpp](./helpers/base_codegen.hpp) by [base.cpp](./base.cpp). They are all located in [components/gen](./components/gen/).
* [ecodetypes.hpp](./components/gen/ecode.hpp): `CodeType` enum definition and related implementaiton. Generation is based off of [ECodeType.csv](./enums/ECodeTypes.csv).
* [ecodetypes.hpp](./components/gen/ecode.hpp): `CodeType` enum definition and related implementation. Generation is based off of [ECodeType.csv](./enums/ECodeTypes.csv).
* [especifier.hpp](./components/gen/especifier.hpp): `Specifier` enum definition, etc. Generated using [ESpecifier.csv](./enums/ESpecifier.csv).
* [eoperator.hpp](./components/gen/eoperator.hpp): `Operator` enum definition, etc. Generated using [EOperator.hpp](./enums/EOperator.csv).
* [etoktype.cpp](./components/gen/etoktype.cpp): `TokType` enum defininition, etc. Used by the lexer and parser backend. Uses two csvs:
@ -191,7 +191,7 @@ These require the following to be handled to the equivalent extent as the other
4. [ast.cpp](./components/ast.cpp): Need to review
* `code_debug_str`
* `code_is_equal`
* `code_to_strbuilder_ptr`
* `code_to_strbuilder_ref`
* `code_validate_body`
5. [code_serialization.cpp](./components/code_serialization.cpp): Define serialization here.
6. [inlines.hpp](./components/inlines.hpp): Any inline definitions for the `struct Code<Name>` are defined here.

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# include "builder.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "helpers/push_ignores.inline.hpp"
# include "components/header_start.hpp"
@ -21,11 +21,11 @@ using namespace gen;
struct Builder;
typedef struct Builder Builder;
Builder builder_open ( char const* path );
void builder_pad_lines ( Builder* builder, s32 num );
void builder_print ( Builder* builder, Code code );
void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va );
void builder_write ( Builder* builder );
GEN_API Builder builder_open ( char const* path );
GEN_API void builder_pad_lines ( Builder* builder, s32 num );
GEN_API void builder_print ( Builder* builder, Code code );
GEN_API void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va );
GEN_API void builder_write ( Builder* builder );
forceinline void builder_print_fmt ( Builder* builder, char const* fmt, ... ) {
va_list va;

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "helpers/push_ignores.inline.hpp"
# include "components/header_start.hpp"

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# include "scanner.hpp"
#endif
@ -24,7 +24,7 @@ Code scan_file( char const* path )
file_read( & file, str, fsize );
strbuilder_get_header(str)->Length = fsize;
// Skip GEN_INTELLISENSE_DIRECTIVES preprocessor blocks
// Skip INTELLISENSE_DIRECTIVES preprocessor blocks
// Its designed so that the directive should be the first thing in the file.
// Anything that comes before it will also be omitted.
{
@ -33,7 +33,7 @@ Code scan_file( char const* path )
#define move_fwd() do { ++ scanner; -- left; } while (0)
const Str directive_start = txt( "ifdef" );
const Str directive_end = txt( "endif" );
const Str def_intellisense = txt("GEN_INTELLISENSE_DIRECTIVES" );
const Str def_intellisense = txt("INTELLISENSE_DIRECTIVES" );
bool found_directive = false;
char const* scanner = (char const*)str;

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "helpers/push_ignores.inline.hpp"
# include "components/header_start.hpp"
@ -20,9 +20,9 @@
// This is a simple file reader that reads the entire file into memory.
// It has an extra option to skip the first few lines for undesired includes.
// This is done so that includes can be kept in dependency and component files so that intellisense works.
Code scan_file( char const* path );
GEN_API Code scan_file( char const* path );
CodeBody parse_file( const char* path );
GEN_API CodeBody parse_file( const char* path );
// The follow is basic support for light csv parsing (use it as an example)
// Make something robust if its more serious.
@ -40,7 +40,7 @@ struct CSV_Columns2 {
Array(ADT_Node) Col_2;
};
CSV_Column parse_csv_one_column(AllocatorInfo allocator, char const* path);
CSV_Columns2 parse_csv_two_columns(AllocatorInfo allocator, char const* path);
GEN_API CSV_Column parse_csv_one_column (AllocatorInfo allocator, char const* path);
GEN_API CSV_Columns2 parse_csv_two_columns(AllocatorInfo allocator, char const* path);
#pragma endregion Scanner

View File

@ -30,7 +30,7 @@ int gen_main()
gen::init( & ctx);
CodeBody gen_component_header = def_global_body( args(
def_preprocess_cond( PreprocessCond_IfDef, txt("GEN_INTELLISENSE_DIRECTIVES") ),
def_preprocess_cond( PreprocessCond_IfDef, txt("INTELLISENSE_DIRECTIVES") ),
pragma_once,
def_include(txt("components/types.hpp")),
preprocess_endif,

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "static_data.cpp"
#endif
@ -379,11 +379,11 @@ Code code_duplicate(Code self)
StrBuilder code_to_strbuilder(Code self)
{
StrBuilder result = strbuilder_make_str( _ctx->Allocator_Temp, txt("") );
code_to_strbuilder_ptr( self, & result );
code_to_strbuilder_ref( self, & result );
return result;
}
void code_to_strbuilder_ptr( Code self, StrBuilder* result )
void code_to_strbuilder_ref( Code self, StrBuilder* result )
{
GEN_ASSERT(self != nullptr);
local_persist thread_local

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "types.hpp"
#include "gen/ecode.hpp"
@ -193,6 +193,7 @@ typedef AST_Stmt_If* CodeStmt_If;
typedef AST_Stmt_For* CodeStmt_For;
typedef AST_Stmt_Goto* CodeStmt_Goto;
typedef AST_Stmt_Label* CodeStmt_Label;
typedef AST_Stmt_Lambda* CodeStmt_Lambda;
typedef AST_Stmt_Switch* CodeStmt_Switch;
typedef AST_Stmt_While* CodeStmt_While;
#else
@ -208,6 +209,7 @@ struct CodeStmt_If;
struct CodeStmt_For;
struct CodeStmt_Goto;
struct CodeStmt_Label;
struct CodeStmt_Lambda;
struct CodeStmt_Switch;
struct CodeStmt_While;
#endif
@ -239,18 +241,18 @@ template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast(
#pragma region Code C-Interface
GEN_API void code_append (Code code, Code other );
void code_append (Code code, Code other );
GEN_API Str code_debug_str (Code code);
GEN_API Code code_duplicate (Code code);
GEN_API Code* code_entry (Code code, u32 idx );
GEN_API bool code_has_entries (Code code);
GEN_API bool code_is_body (Code code);
Code* code_entry (Code code, u32 idx );
bool code_has_entries (Code code);
bool code_is_body (Code code);
GEN_API bool code_is_equal (Code code, Code other);
GEN_API bool code_is_valid (Code code);
GEN_API void code_set_global (Code code);
bool code_is_valid (Code code);
void code_set_global (Code code);
GEN_API StrBuilder code_to_strbuilder (Code self );
GEN_API void code_to_strbuilder_ptr(Code self, StrBuilder* result );
GEN_API Str code_type_str (Code self );
GEN_API void code_to_strbuilder_ref(Code self, StrBuilder* result );
Str code_type_str (Code self );
GEN_API bool code_validate_body (Code self );
#pragma endregion Code C-Interface
@ -287,7 +289,7 @@ struct Code
forceinline Code* entry(u32 idx) { return code_entry(* this, idx); }
forceinline bool has_entries() { return code_has_entries(* this); }
forceinline StrBuilder to_strbuilder() { return code_to_strbuilder(* this); }
forceinline void to_strbuilder(StrBuilder& result) { return code_to_strbuilder_ptr(* this, & result); }
forceinline void to_strbuilder(StrBuilder& result) { return code_to_strbuilder_ref(* this, & result); }
forceinline Str type_str() { return code_type_str(* this); }
forceinline bool validate_body() { return code_validate_body(*this); }
#endif
@ -337,10 +339,10 @@ struct Code
#pragma region Statics
// Used to identify ASTs that should always be duplicated. (Global constant ASTs)
extern Code Code_Global;
GEN_API extern Code Code_Global;
// Used to identify invalid generated code.
extern Code Code_Invalid;
GEN_API extern Code Code_Invalid;
#pragma endregion Statics
struct Code_POD
@ -378,7 +380,7 @@ struct AST
{
Code InlineCmt; // Class, Constructor, Destructor, Enum, Friend, Functon, Operator, OpCast, Struct, Typedef, Using, Variable
Code Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable // TODO(Ed): Parameters can have attributes
Code Specs; // Destructor, Function, Operator, Typename, Variable
Code Specs; // Class, Destructor, Function, Operator, Struct, Typename, Variable
union {
Code InitializerList; // Constructor
Code ParentType; // Class, Struct, ParentType->Next has a possible list of interfaces.
@ -399,8 +401,8 @@ struct AST
Code Value; // Parameter, Variable
};
union {
Code NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
Code SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
Code NextVar; // Variable
Code SuffixSpecs; // Typename, Function (Thanks Unreal)
Code PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
};
};
@ -420,7 +422,7 @@ struct AST
Code Next;
Code Back;
};
Token* Token; // Reference to starting token, only avaialble if it was derived from parsing.
Token* Token; // Reference to starting token, only available if it was derived from parsing.
Code Parent;
CodeType Type;
// CodeFlag CodeFlags;

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "code_types.hpp"
#endif
@ -100,7 +100,7 @@ struct AST_Class
{
CodeComment InlineCmt; // Only supported by forward declarations
CodeAttributes Attributes;
char _PAD_SPECS_ [ sizeof(AST*) ];
CodeSpecifiers Specs; // Support for final
CodeTypename ParentType;
char _PAD_PARAMS_[ sizeof(AST*) ];
CodeBody Body;
@ -227,7 +227,7 @@ struct AST_Enum
Code Parent;
CodeType Type;
ModuleFlag ModuleFlags;
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
char _PAD_UNUSED_[ sizeof(u32) ];
};
static_assert( sizeof(AST_Enum) == sizeof(AST), "ERROR: AST_Enum is not the same size as AST");
@ -575,7 +575,7 @@ struct AST_Fn
CodeTypename ReturnType;
CodeParams Params;
CodeBody Body;
char _PAD_PROPERTIES_ [ sizeof(AST*) ];
Code SuffixSpecs; // Thanks Unreal
};
};
StrCached Name;
@ -738,8 +738,8 @@ static_assert( sizeof(AST_PreprocessCond) == sizeof(AST), "ERROR: AST_Preprocess
struct AST_Specifiers
{
Specifier ArrSpecs[ AST_ArrSpecs_Cap ];
StrCached Name;
CodeSpecifiers NextSpecs;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
@ -970,7 +970,7 @@ struct AST_Struct
{
CodeComment InlineCmt;
CodeAttributes Attributes;
char _PAD_SPECS_ [ sizeof(AST*) ];
CodeSpecifiers Specs; // Support for final
CodeTypename ParentType;
char _PAD_PARAMS_[ sizeof(AST*) ];
CodeBody Body;
@ -1056,7 +1056,7 @@ struct AST_Typename
CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures
};
};
StrCached Name;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
@ -1082,7 +1082,7 @@ struct AST_Typedef
char _PAD_PROPERTIES_2_[ sizeof(AST*) * 3 ];
};
};
StrCached Name;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;

View File

@ -1,23 +1,8 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "ast.cpp"
#endif
inline
StrBuilder attributes_to_strbuilder(CodeAttributes attributes) {
GEN_ASSERT(attributes);
char* raw = ccast(char*, str_duplicate( attributes->Content, _ctx->Allocator_Temp ).Ptr);
StrBuilder result = { raw };
return result;
}
inline
void attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result) {
GEN_ASSERT(attributes);
GEN_ASSERT(result);
strbuilder_append_str(result, attributes->Content);
}
StrBuilder body_to_strbuilder(CodeBody body)
{
GEN_ASSERT(body);
@ -47,20 +32,6 @@ StrBuilder body_to_strbuilder(CodeBody body)
return result;
}
void body_to_strbuilder_ref( CodeBody body, StrBuilder* result )
{
GEN_ASSERT(body != nullptr);
GEN_ASSERT(result != nullptr);
Code curr = body->Front;
s32 left = body->NumEntries;
while ( left -- )
{
code_to_strbuilder_ptr(curr, result);
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
++curr;
}
}
void body_to_strbuilder_export( CodeBody body, StrBuilder* result )
{
GEN_ASSERT(body != nullptr);
@ -71,7 +42,7 @@ void body_to_strbuilder_export( CodeBody body, StrBuilder* result )
s32 left = body->NumEntries;
while ( left-- )
{
code_to_strbuilder_ptr(curr, result);
code_to_strbuilder_ref(curr, result);
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
++curr;
}
@ -79,23 +50,9 @@ void body_to_strbuilder_export( CodeBody body, StrBuilder* result )
strbuilder_append_fmt( result, "};\n" );
}
inline
StrBuilder comment_to_strbuilder(CodeComment comment) {
GEN_ASSERT(comment);
char* raw = ccast(char*, str_duplicate( comment->Content, _ctx->Allocator_Temp ).Ptr);
StrBuilder result = { raw };
return result;
}
inline
void comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result) {
GEN_ASSERT(comment);
GEN_ASSERT(result);
strbuilder_append_str(result, comment->Content);
}
StrBuilder constructor_to_strbuilder(CodeConstructor self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
switch (self->Type)
{
@ -111,6 +68,8 @@ StrBuilder constructor_to_strbuilder(CodeConstructor self)
void constructor_to_strbuilder_def(CodeConstructor self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
Code ClassStructParent = self->Parent->Parent;
if (ClassStructParent) {
strbuilder_append_str( result, ClassStructParent->Name );
@ -135,6 +94,8 @@ void constructor_to_strbuilder_def(CodeConstructor self, StrBuilder* result )
void constructor_to_strbuilder_fwd(CodeConstructor self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
Code ClassStructParent = self->Parent->Parent;
if (ClassStructParent) {
strbuilder_append_str( result, ClassStructParent->Name );
@ -159,6 +120,7 @@ void constructor_to_strbuilder_fwd(CodeConstructor self, StrBuilder* result )
StrBuilder class_to_strbuilder( CodeClass self )
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
switch ( self->Type )
{
@ -175,6 +137,7 @@ StrBuilder class_to_strbuilder( CodeClass self )
void class_to_strbuilder_def( CodeClass self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -186,10 +149,16 @@ void class_to_strbuilder_def( CodeClass self, StrBuilder* result )
strbuilder_append_fmt( result, "%SB ", attributes_to_strbuilder(self->Attributes) );
}
if ( self->Name.Len )
strbuilder_append_str( result, self->Name );
if (self->Specs && specifiers_has(self->Specs, Spec_Final))
strbuilder_append_str(result, txt(" final"));
if ( self->ParentType )
{
Str access_level = access_spec_to_str( self->ParentAccess );
strbuilder_append_fmt( result, "%S : %S %SB", self->Name, access_level, typename_to_strbuilder(self->ParentType) );
strbuilder_append_fmt( result, " : %S %SB", self->Name, access_level, typename_to_strbuilder(self->ParentType) );
CodeTypename interface = cast(CodeTypename, self->ParentType->Next);
if ( interface )
@ -201,10 +170,6 @@ void class_to_strbuilder_def( CodeClass self, StrBuilder* result )
interface = interface->Next ? cast(CodeTypename, interface->Next) : NullCode;
}
}
else if ( self->Name.Len )
{
strbuilder_append_str( result, self->Name );
}
if ( self->InlineCmt )
{
@ -220,6 +185,7 @@ void class_to_strbuilder_def( CodeClass self, StrBuilder* result )
void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -239,13 +205,6 @@ void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result )
}
}
StrBuilder define_to_strbuilder(CodeDefine define)
{
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
define_to_strbuilder_ref(define, & result);
return result;
}
void define_to_strbuilder_ref(CodeDefine define, StrBuilder* result )
{
GEN_ASSERT(define);
@ -260,14 +219,6 @@ void define_to_strbuilder_ref(CodeDefine define, StrBuilder* result )
}
}
StrBuilder define_params_to_strbuilder(CodeDefineParams params)
{
GEN_ASSERT(params);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
define_params_to_strbuilder_ref( params, & result );
return result;
}
void define_params_to_strbuilder_ref(CodeDefineParams self, StrBuilder* result)
{
GEN_ASSERT(self);
@ -287,6 +238,7 @@ void define_params_to_strbuilder_ref(CodeDefineParams self, StrBuilder* result)
StrBuilder destructor_to_strbuilder(CodeDestructor self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
switch ( self->Type )
{
@ -302,6 +254,8 @@ StrBuilder destructor_to_strbuilder(CodeDestructor self)
void destructor_to_strbuilder_def(CodeDestructor self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->Name.Len )
{
strbuilder_append_fmt( result, "%S()", self->Name );
@ -321,6 +275,8 @@ void destructor_to_strbuilder_def(CodeDestructor self, StrBuilder* result )
void destructor_to_strbuilder_fwd(CodeDestructor self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->Specs )
{
if ( specifiers_has(self->Specs, Spec_Virtual ) )
@ -344,6 +300,7 @@ void destructor_to_strbuilder_fwd(CodeDestructor self, StrBuilder* result )
StrBuilder enum_to_strbuilder(CodeEnum self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
switch ( self->Type )
{
@ -365,6 +322,8 @@ StrBuilder enum_to_strbuilder(CodeEnum self)
void enum_to_strbuilder_def(CodeEnum self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -398,6 +357,8 @@ void enum_to_strbuilder_def(CodeEnum self, StrBuilder* result )
void enum_to_strbuilder_fwd(CodeEnum self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -425,6 +386,8 @@ void enum_to_strbuilder_fwd(CodeEnum self, StrBuilder* result )
void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -457,6 +420,8 @@ void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result )
void enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -476,56 +441,9 @@ void enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result )
}
}
StrBuilder exec_to_strbuilder(CodeExec exec)
{
GEN_ASSERT(exec);
char* raw = ccast(char*, str_duplicate( exec->Content, _ctx->Allocator_Temp ).Ptr);
StrBuilder result = { raw };
return result;
}
void extern_to_strbuilder(CodeExtern self, StrBuilder* result )
{
if ( self->Body )
strbuilder_append_fmt( result, "extern \"%S\"\n{\n%SB\n}\n", self->Name, body_to_strbuilder(self->Body) );
else
strbuilder_append_fmt( result, "extern \"%S\"\n{}\n", self->Name );
}
StrBuilder include_to_strbuilder(CodeInclude include)
{
return strbuilder_fmt_buf( _ctx->Allocator_Temp, "#include %S\n", include->Content );
}
void include_to_strbuilder_ref( CodeInclude include, StrBuilder* result )
{
strbuilder_append_fmt( result, "#include %S\n", include->Content );
}
StrBuilder friend_to_strbuilder(CodeFriend self)
{
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
friend_to_strbuilder_ref( self, & result );
return result;
}
void friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result )
{
strbuilder_append_fmt( result, "friend %SB", code_to_strbuilder(self->Declaration) );
if ( self->Declaration->Type != CT_Function && self->Declaration->Type != CT_Operator && (* result)[ strbuilder_length(* result) - 1 ] != ';' )
{
strbuilder_append_str( result, txt(";") );
}
if ( self->InlineCmt )
strbuilder_append_fmt( result, " %S", self->InlineCmt->Content );
else
strbuilder_append_str( result, txt("\n"));
}
StrBuilder fn_to_strbuilder(CodeFn self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
switch ( self->Type )
{
@ -541,6 +459,8 @@ StrBuilder fn_to_strbuilder(CodeFn self)
void fn_to_strbuilder_def(CodeFn self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export") );
@ -589,11 +509,17 @@ void fn_to_strbuilder_def(CodeFn self, StrBuilder* result )
}
}
// This is bodged in for now SOLEY for Unreal's PURE_VIRTUAL functional macro
if ( self->SuffixSpecs )
strbuilder_append_fmt( result, " %SB", code_to_strbuilder(self->SuffixSpecs) );
strbuilder_append_fmt( result, "\n{\n%SB\n}\n", body_to_strbuilder(self->Body) );
}
void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -642,11 +568,18 @@ void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result )
strbuilder_append_fmt( result, " %.*s", spec_str.Len, spec_str.Ptr );
}
}
if ( specifiers_has(self->Specs, Spec_Pure ) )
strbuilder_append_str( result, txt(" = 0") );
else if ( specifiers_has(self->Specs, Spec_Delete ) )
strbuilder_append_str( result, txt(" = delete") );
}
if ( self->Specs && specifiers_has(self->Specs, Spec_Pure ) >= 0 )
strbuilder_append_str( result, txt(" = 0;") );
else if (self->Body)
// This is bodged in for now SOLEY for Unreal's PURE_VIRTUAL functional macro (I kept it open ended for other jank)
if ( self->SuffixSpecs )
strbuilder_append_fmt( result, " %SB", code_to_strbuilder(self->SuffixSpecs) );
if (self->Body)
strbuilder_append_fmt( result, " = %SB;", body_to_strbuilder(self->Body) );
if ( self->InlineCmt )
@ -655,15 +588,10 @@ void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result )
strbuilder_append_str( result, txt(";\n") );
}
StrBuilder module_to_strbuilder(CodeModule self)
{
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 64 );
module_to_strbuilder_ref( self, & result );
return result;
}
void module_to_strbuilder_ref(CodeModule self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if (((scast(u32, ModuleFlag_Export) & scast(u32, self->ModuleFlags)) == scast(u32, ModuleFlag_Export)))
strbuilder_append_str( result, txt("export "));
@ -673,23 +601,9 @@ void module_to_strbuilder_ref(CodeModule self, StrBuilder* result )
strbuilder_append_fmt( result, "%S;\n", self->Name );
}
StrBuilder namespace_to_strbuilder(CodeNS self)
{
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
namespace_to_strbuilder_ref( self, & result );
return result;
}
void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result )
{
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
strbuilder_append_fmt( result, "namespace %S\n{\n%SB\n}\n", self->Name, body_to_strbuilder(self->Body) );
}
StrBuilder code_op_to_strbuilder(CodeOperator self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
switch ( self->Type )
{
@ -707,6 +621,8 @@ StrBuilder code_op_to_strbuilder(CodeOperator self)
void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -761,6 +677,8 @@ void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result )
void code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -812,6 +730,7 @@ void code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result )
StrBuilder opcast_to_strbuilder(CodeOpCast self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
switch ( self->Type )
{
@ -827,6 +746,8 @@ StrBuilder opcast_to_strbuilder(CodeOpCast self)
void opcast_to_strbuilder_def(CodeOpCast self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->Specs )
{
for ( Specifier* spec = begin_CodeSpecifiers(self->Specs); spec != end_CodeSpecifiers(self->Specs); spec = next_CodeSpecifiers(self->Specs, spec) )
@ -864,6 +785,8 @@ void opcast_to_strbuilder_def(CodeOpCast self, StrBuilder* result )
void opcast_to_strbuilder_fwd(CodeOpCast self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->Specs )
{
for ( Specifier* spec = begin_CodeSpecifiers(self->Specs); spec != end_CodeSpecifiers(self->Specs); spec = next_CodeSpecifiers(self->Specs, spec) )
@ -899,14 +822,6 @@ void opcast_to_strbuilder_fwd(CodeOpCast self, StrBuilder* result )
strbuilder_append_fmt( result, "operator %SB();\n", typename_to_strbuilder(self->ValueType) );
}
StrBuilder params_to_strbuilder(CodeParams self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
params_to_strbuilder_ref( self, & result );
return result;
}
void params_to_strbuilder_ref( CodeParams self, StrBuilder* result )
{
GEN_ASSERT(self);
@ -974,62 +889,6 @@ StrBuilder preprocess_to_strbuilder(CodePreprocessCond self)
return result;
}
void preprocess_to_strbuilder_if(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
strbuilder_append_fmt( result, "#if %S", cond->Content );
}
void preprocess_to_strbuilder_ifdef(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
strbuilder_append_fmt( result, "#ifdef %S\n", cond->Content );
}
void preprocess_to_strbuilder_ifndef(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
strbuilder_append_fmt( result, "#ifndef %S", cond->Content );
}
void preprocess_to_strbuilder_elif(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
strbuilder_append_fmt( result, "#elif %S\n", cond->Content );
}
void preprocess_to_strbuilder_else(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
strbuilder_append_str( result, txt("#else\n") );
}
void preprocess_to_strbuilder_endif(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
strbuilder_append_str( result, txt("#endif\n") );
}
StrBuilder pragma_to_strbuilder(CodePragma self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
pragma_to_strbuilder_ref( self, & result );
return result;
}
void pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result )
{
strbuilder_append_fmt( result, "#pragma %S\n", self->Content );
}
StrBuilder specifiers_to_strbuilder(CodeSpecifiers self)
{
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 64 );
specifiers_to_strbuilder_ref( self, & result );
return result;
}
void specifiers_to_strbuilder_ref( CodeSpecifiers self, StrBuilder* result )
{
GEN_ASSERT(self);
@ -1087,11 +946,17 @@ void struct_to_strbuilder_def( CodeStruct self, StrBuilder* result )
strbuilder_append_fmt( result, "%SB ", attributes_to_strbuilder(self->Attributes) );
}
if ( self->Name.Len )
strbuilder_append_str( result, self->Name );
if (self->Specs && specifiers_has(self->Specs, Spec_Final))
strbuilder_append_str( result, txt(" final"));
if ( self->ParentType )
{
Str access_level = access_spec_to_str( self->ParentAccess );
strbuilder_append_fmt( result, "%S : %S %SB", self->Name, access_level, typename_to_strbuilder(self->ParentType) );
strbuilder_append_fmt( result, " : %S %SB", access_level, typename_to_strbuilder(self->ParentType) );
CodeTypename interface = cast(CodeTypename, self->ParentType->Next);
if ( interface )
@ -1103,10 +968,6 @@ void struct_to_strbuilder_def( CodeStruct self, StrBuilder* result )
interface = interface->Next ? cast( CodeTypename, interface->Next) : NullCode;
}
}
else if ( self->Name.Len )
{
strbuilder_append_str( result, self->Name );
}
if ( self->InlineCmt )
{
@ -1140,14 +1001,6 @@ void struct_to_strbuilder_fwd( CodeStruct self, StrBuilder* result )
}
}
StrBuilder template_to_strbuilder(CodeTemplate self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 1024 );
template_to_strbuilder_ref( self, & result );
return result;
}
void template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result )
{
GEN_ASSERT(self);
@ -1161,15 +1014,10 @@ void template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result )
strbuilder_append_fmt( result, "template<>\n%SB", code_to_strbuilder(self->Declaration) );
}
StrBuilder typedef_to_strbuilder(CodeTypedef self)
{
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
typedef_to_strbuilder_ref( self, & result );
return result;
}
void typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -1203,15 +1051,10 @@ void typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result )
strbuilder_append_str( result, txt("\n"));
}
StrBuilder typename_to_strbuilder(CodeTypename self)
{
StrBuilder result = strbuilder_make_str( _ctx->Allocator_Temp, txt("") );
typename_to_strbuilder_ref( self, & result );
return result;
}
void typename_to_strbuilder_ref(CodeTypename self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
#if defined(GEN_USE_NEW_TYPENAME_PARSING)
if ( self->ReturnType && self->Params )
{
@ -1268,6 +1111,7 @@ void typename_to_strbuilder_ref(CodeTypename self, StrBuilder* result )
StrBuilder union_to_strbuilder(CodeUnion self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
switch ( self->Type )
{
@ -1283,6 +1127,8 @@ StrBuilder union_to_strbuilder(CodeUnion self)
void union_to_strbuilder_def(CodeUnion self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -1331,22 +1177,6 @@ void union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result )
strbuilder_append_str( result, txt(";\n"));
}
StrBuilder using_to_strbuilder(CodeUsing self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
switch ( self->Type )
{
case CT_Using:
using_to_strbuilder_ref( self, & result );
break;
case CT_Using_Namespace:
using_to_strbuilder_ns( self, & result );
break;
}
return result;
}
void using_to_strbuilder_ref(CodeUsing self, StrBuilder* result )
{
GEN_ASSERT(self);
@ -1384,26 +1214,6 @@ void using_to_strbuilder_ref(CodeUsing self, StrBuilder* result )
strbuilder_append_str( result, txt("\n"));
}
inline
void using_to_strbuilder_ns(CodeUsing self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->InlineCmt )
strbuilder_append_fmt( result, "using namespace $SC; %S", self->Name, self->InlineCmt->Content );
else
strbuilder_append_fmt( result, "using namespace %S;\n", self->Name );
}
inline
StrBuilder var_to_strbuilder(CodeVar self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
var_to_strbuilder_ref( self, & result );
return result;
}
neverinline
void var_to_strbuilder_ref(CodeVar self, StrBuilder* result )
{

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "ast.hpp"
#endif
@ -20,58 +20,59 @@
GEN_API void body_append ( CodeBody body, Code other );
GEN_API void body_append_body ( CodeBody body, CodeBody other );
GEN_API StrBuilder body_to_strbuilder ( CodeBody body );
GEN_API void body_to_strbuilder_ref ( CodeBody body, StrBuilder* result );
void body_to_strbuilder_ref ( CodeBody body, StrBuilder* result );
GEN_API void body_to_strbuilder_export( CodeBody body, StrBuilder* result );
GEN_API Code begin_CodeBody( CodeBody body);
GEN_API Code end_CodeBody ( CodeBody body );
GEN_API Code next_CodeBody ( CodeBody body, Code entry_iter );
Code begin_CodeBody( CodeBody body);
Code end_CodeBody ( CodeBody body );
Code next_CodeBody ( CodeBody body, Code entry_iter );
GEN_API void class_add_interface ( CodeClass self, CodeTypename interface );
void class_add_interface ( CodeClass self, CodeTypename interface );
GEN_API StrBuilder class_to_strbuilder ( CodeClass self );
GEN_API void class_to_strbuilder_def( CodeClass self, StrBuilder* result );
GEN_API void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result );
GEN_API void define_params_append (CodeDefineParams appendee, CodeDefineParams other );
GEN_API CodeDefineParams define_params_get (CodeDefineParams params, s32 idx);
GEN_API bool define_params_has_entries (CodeDefineParams params );
GEN_API StrBuilder define_params_to_strbuilder (CodeDefineParams params );
void define_params_append (CodeDefineParams appendee, CodeDefineParams other );
CodeDefineParams define_params_get (CodeDefineParams params, s32 idx);
bool define_params_has_entries (CodeDefineParams params );
StrBuilder define_params_to_strbuilder (CodeDefineParams params );
GEN_API void define_params_to_strbuilder_ref(CodeDefineParams params, StrBuilder* result );
GEN_API CodeDefineParams begin_CodeDefineParams(CodeDefineParams params);
GEN_API CodeDefineParams end_CodeDefineParams (CodeDefineParams params);
GEN_API CodeDefineParams next_CodeDefineParams (CodeDefineParams params, CodeDefineParams entry_iter);
CodeDefineParams begin_CodeDefineParams(CodeDefineParams params);
CodeDefineParams end_CodeDefineParams (CodeDefineParams params);
CodeDefineParams next_CodeDefineParams (CodeDefineParams params, CodeDefineParams entry_iter);
GEN_API void params_append (CodeParams appendee, CodeParams other );
GEN_API CodeParams params_get (CodeParams params, s32 idx);
GEN_API bool params_has_entries (CodeParams params );
GEN_API StrBuilder params_to_strbuilder (CodeParams params );
void params_append (CodeParams appendee, CodeParams other );
CodeParams params_get (CodeParams params, s32 idx);
bool params_has_entries (CodeParams params );
StrBuilder params_to_strbuilder (CodeParams params );
GEN_API void params_to_strbuilder_ref(CodeParams params, StrBuilder* result );
GEN_API CodeParams begin_CodeParams(CodeParams params);
GEN_API CodeParams end_CodeParams (CodeParams params);
GEN_API CodeParams next_CodeParams (CodeParams params, CodeParams entry_iter);
CodeParams begin_CodeParams(CodeParams params);
CodeParams end_CodeParams (CodeParams params);
CodeParams next_CodeParams (CodeParams params, CodeParams entry_iter);
GEN_API bool specifiers_append (CodeSpecifiers specifiers, Specifier spec);
GEN_API s32 specifiers_has (CodeSpecifiers specifiers, Specifier spec);
GEN_API s32 specifiers_remove (CodeSpecifiers specifiers, Specifier to_remove );
GEN_API StrBuilder specifiers_to_strbuilder (CodeSpecifiers specifiers);
bool specifiers_append (CodeSpecifiers specifiers, Specifier spec);
bool specifiers_has (CodeSpecifiers specifiers, Specifier spec);
s32 specifiers_index_of (CodeSpecifiers specifiers, Specifier spec);
s32 specifiers_remove (CodeSpecifiers specifiers, Specifier to_remove );
StrBuilder specifiers_to_strbuilder (CodeSpecifiers specifiers);
GEN_API void specifiers_to_strbuilder_ref(CodeSpecifiers specifiers, StrBuilder* result);
GEN_API Specifier* begin_CodeSpecifiers(CodeSpecifiers specifiers);
GEN_API Specifier* end_CodeSpecifiers (CodeSpecifiers specifiers);
GEN_API Specifier* next_CodeSpecifiers (CodeSpecifiers specifiers, Specifier* spec_iter);
Specifier* begin_CodeSpecifiers(CodeSpecifiers specifiers);
Specifier* end_CodeSpecifiers (CodeSpecifiers specifiers);
Specifier* next_CodeSpecifiers (CodeSpecifiers specifiers, Specifier* spec_iter);
GEN_API void struct_add_interface (CodeStruct self, CodeTypename interface);
void struct_add_interface (CodeStruct self, CodeTypename interface);
GEN_API StrBuilder struct_to_strbuilder (CodeStruct self);
GEN_API void struct_to_strbuilder_fwd(CodeStruct self, StrBuilder* result);
GEN_API void struct_to_strbuilder_def(CodeStruct self, StrBuilder* result);
GEN_API StrBuilder attributes_to_strbuilder (CodeAttributes attributes);
GEN_API void attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result);
StrBuilder attributes_to_strbuilder (CodeAttributes attributes);
void attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result);
GEN_API StrBuilder comment_to_strbuilder (CodeComment comment );
GEN_API void comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result );
StrBuilder comment_to_strbuilder (CodeComment comment );
void comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result );
GEN_API StrBuilder constructor_to_strbuilder (CodeConstructor constructor);
GEN_API void constructor_to_strbuilder_def(CodeConstructor constructor, StrBuilder* result );
@ -90,66 +91,68 @@ GEN_API void enum_to_strbuilder_fwd (CodeEnum self, StrBuilder* resul
GEN_API void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result );
GEN_API void enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result );
GEN_API StrBuilder exec_to_strbuilder (CodeExec exec);
GEN_API void exec_to_strbuilder_ref(CodeExec exec, StrBuilder* result);
StrBuilder exec_to_strbuilder (CodeExec exec);
void exec_to_strbuilder_ref(CodeExec exec, StrBuilder* result);
GEN_API void extern_to_strbuilder(CodeExtern self, StrBuilder* result);
void extern_to_strbuilder(CodeExtern self, StrBuilder* result);
GEN_API StrBuilder include_to_strbuilder (CodeInclude self);
GEN_API void include_to_strbuilder_ref(CodeInclude self, StrBuilder* result);
StrBuilder include_to_strbuilder (CodeInclude self);
void include_to_strbuilder_ref(CodeInclude self, StrBuilder* result);
GEN_API StrBuilder friend_to_strbuilder (CodeFriend self);
GEN_API void friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result);
StrBuilder friend_to_strbuilder (CodeFriend self);
void friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result);
GEN_API StrBuilder fn_to_strbuilder (CodeFn self);
GEN_API void fn_to_strbuilder_def(CodeFn self, StrBuilder* result);
GEN_API void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result);
GEN_API StrBuilder module_to_strbuilder (CodeModule self);
StrBuilder module_to_strbuilder (CodeModule self);
GEN_API void module_to_strbuilder_ref(CodeModule self, StrBuilder* result);
GEN_API StrBuilder namespace_to_strbuilder (CodeNS self);
GEN_API void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result);
StrBuilder namespace_to_strbuilder (CodeNS self);
void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result);
GEN_API StrBuilder code_op_to_strbuilder (CodeOperator self);
GEN_API void code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result );
GEN_API void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result );
GEN_API StrBuilder opcast_to_strbuilder (CodeOpCast op_cast );
GEN_API StrBuilder opcast_to_strbuilder (CodeOpCast op_cast );
GEN_API void opcast_to_strbuilder_def(CodeOpCast op_cast, StrBuilder* result );
GEN_API void opcast_to_strbuilder_fwd(CodeOpCast op_cast, StrBuilder* result );
GEN_API StrBuilder pragma_to_strbuilder (CodePragma self);
GEN_API void pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result);
StrBuilder pragma_to_strbuilder (CodePragma self);
void pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result);
GEN_API StrBuilder preprocess_to_strbuilder (CodePreprocessCond cond);
GEN_API void preprocess_to_strbuilder_if (CodePreprocessCond cond, StrBuilder* result );
GEN_API void preprocess_to_strbuilder_ifdef (CodePreprocessCond cond, StrBuilder* result );
GEN_API void preprocess_to_strbuilder_ifndef(CodePreprocessCond cond, StrBuilder* result );
GEN_API void preprocess_to_strbuilder_elif (CodePreprocessCond cond, StrBuilder* result );
GEN_API void preprocess_to_strbuilder_else (CodePreprocessCond cond, StrBuilder* result );
GEN_API void preprocess_to_strbuilder_endif (CodePreprocessCond cond, StrBuilder* result );
void preprocess_to_strbuilder_if (CodePreprocessCond cond, StrBuilder* result );
void preprocess_to_strbuilder_ifdef (CodePreprocessCond cond, StrBuilder* result );
void preprocess_to_strbuilder_ifndef(CodePreprocessCond cond, StrBuilder* result );
void preprocess_to_strbuilder_elif (CodePreprocessCond cond, StrBuilder* result );
void preprocess_to_strbuilder_else (CodePreprocessCond cond, StrBuilder* result );
void preprocess_to_strbuilder_endif (CodePreprocessCond cond, StrBuilder* result );
GEN_API StrBuilder template_to_strbuilder (CodeTemplate self);
StrBuilder template_to_strbuilder (CodeTemplate self);
GEN_API void template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result);
GEN_API StrBuilder typename_to_strbuilder (CodeTypename self);
GEN_API void typename_to_strbuilder_ref(CodeTypename self, StrBuilder* result);
GEN_API StrBuilder typedef_to_strbuilder (CodeTypedef self);
StrBuilder typedef_to_strbuilder (CodeTypedef self);
GEN_API void typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result );
StrBuilder typename_to_strbuilder (CodeTypename self);
GEN_API void typename_to_strbuilder_ref(CodeTypename self, StrBuilder* result);
GEN_API StrBuilder union_to_strbuilder (CodeUnion self);
GEN_API void union_to_strbuilder_def(CodeUnion self, StrBuilder* result);
GEN_API void union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result);
GEN_API StrBuilder using_to_strbuilder (CodeUsing op_cast );
StrBuilder using_to_strbuilder (CodeUsing op_cast );
GEN_API void using_to_strbuilder_ref(CodeUsing op_cast, StrBuilder* result );
GEN_API void using_to_strbuilder_ns (CodeUsing op_cast, StrBuilder* result );
void using_to_strbuilder_ns (CodeUsing op_cast, StrBuilder* result );
GEN_API StrBuilder var_to_strbuilder (CodeVar self);
StrBuilder var_to_strbuilder (CodeVar self);
GEN_API void var_to_strbuilder_ref(CodeVar self, StrBuilder* result);
// TODO(Ed): Move C-Interface inlines here...
#pragma endregion Code Type C-Interface
#if GEN_COMPILER_CPP
@ -249,7 +252,8 @@ struct CodeSpecifiers
#if ! GEN_C_LIKE_CPP
Using_Code( CodeSpecifiers );
bool append( Specifier spec ) { return specifiers_append(* this, spec); }
s32 has( Specifier spec ) { return specifiers_has(* this, spec); }
bool has( Specifier spec ) { return specifiers_has(* this, spec); }
s32 index_of(Specifier spec) { return specifiers_index_of(* this, spec); }
s32 remove( Specifier to_remove ) { return specifiers_remove(* this, to_remove); }
StrBuilder to_strbuilder() { return specifiers_to_strbuilder(* this ); }
void to_strbuilder( StrBuilder& result ) { return specifiers_to_strbuilder_ref(* this, & result); }
@ -1071,7 +1075,8 @@ forceinline StrBuilder to_strbuilder(CodeParams params ) {
forceinline void to_strbuilder(CodeParams params, StrBuilder& result ) { return params_to_strbuilder_ref(params, & result); }
forceinline bool append (CodeSpecifiers specifiers, Specifier spec) { return specifiers_append(specifiers, spec); }
forceinline s32 has (CodeSpecifiers specifiers, Specifier spec) { return specifiers_has(specifiers, spec); }
forceinline bool has (CodeSpecifiers specifiers, Specifier spec) { return specifiers_has(specifiers, spec); }
forceinline s32 index_of (CodeSpecifiers specifiers, Specifier spec) { return specifiers_index_of(specifiers, spec); }
forceinline s32 remove (CodeSpecifiers specifiers, Specifier to_remove ) { return specifiers_remove(specifiers, to_remove); }
forceinline StrBuilder to_strbuilder(CodeSpecifiers specifiers) { return specifiers_to_strbuilder(specifiers); }
forceinline void to_strbuilder(CodeSpecifiers specifiers, StrBuilder& result) { return specifiers_to_strbuilder_ref(specifiers, & result); }

View File

@ -0,0 +1,85 @@
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "interface.hpp"
#endif
#pragma region Constants
// Predefined typename codes. Are set to readonly and are setup during gen::init()
GEN_API extern Macro enum_underlying_macro;
GEN_API extern Code access_public;
GEN_API extern Code access_protected;
GEN_API extern Code access_private;
GEN_API extern CodeAttributes attrib_api_export;
GEN_API extern CodeAttributes attrib_api_import;
GEN_API extern Code module_global_fragment;
GEN_API extern Code module_private_fragment;
GEN_API extern Code fmt_newline;
GEN_API extern CodePragma pragma_once;
GEN_API extern CodeParams param_varadic;
GEN_API extern CodePreprocessCond preprocess_else;
GEN_API extern CodePreprocessCond preprocess_endif;
GEN_API extern CodeSpecifiers spec_const;
GEN_API extern CodeSpecifiers spec_consteval;
GEN_API extern CodeSpecifiers spec_constexpr;
GEN_API extern CodeSpecifiers spec_constinit;
GEN_API extern CodeSpecifiers spec_extern_linkage;
GEN_API extern CodeSpecifiers spec_final;
GEN_API extern CodeSpecifiers spec_forceinline;
GEN_API extern CodeSpecifiers spec_global;
GEN_API extern CodeSpecifiers spec_inline;
GEN_API extern CodeSpecifiers spec_internal_linkage;
GEN_API extern CodeSpecifiers spec_local_persist;
GEN_API extern CodeSpecifiers spec_mutable;
GEN_API extern CodeSpecifiers spec_neverinline;
GEN_API extern CodeSpecifiers spec_noexcept;
GEN_API extern CodeSpecifiers spec_override;
GEN_API extern CodeSpecifiers spec_ptr;
GEN_API extern CodeSpecifiers spec_pure;
GEN_API extern CodeSpecifiers spec_ref;
GEN_API extern CodeSpecifiers spec_register;
GEN_API extern CodeSpecifiers spec_rvalue;
GEN_API extern CodeSpecifiers spec_static_member;
GEN_API extern CodeSpecifiers spec_thread_local;
GEN_API extern CodeSpecifiers spec_virtual;
GEN_API extern CodeSpecifiers spec_volatile;
GEN_API extern CodeTypename t_empty; // Used with varaidc parameters. (Exposing just in case its useful for another circumstance)
GEN_API extern CodeTypename t_auto;
GEN_API extern CodeTypename t_void;
GEN_API extern CodeTypename t_int;
GEN_API extern CodeTypename t_bool;
GEN_API extern CodeTypename t_char;
GEN_API extern CodeTypename t_wchar_t;
GEN_API extern CodeTypename t_class;
GEN_API extern CodeTypename t_typename;
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
GEN_API extern CodeTypename t_b32;
GEN_API extern CodeTypename t_s8;
GEN_API extern CodeTypename t_s16;
GEN_API extern CodeTypename t_s32;
GEN_API extern CodeTypename t_s64;
GEN_API extern CodeTypename t_u8;
GEN_API extern CodeTypename t_u16;
GEN_API extern CodeTypename t_u32;
GEN_API extern CodeTypename t_u64;
GEN_API extern CodeTypename t_ssize;
GEN_API extern CodeTypename t_usize;
GEN_API extern CodeTypename t_f32;
GEN_API extern CodeTypename t_f64;
#endif
#pragma endregion Constants

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "components/types.hpp"
#endif
@ -7,14 +7,14 @@
#pragma region generated code inline implementation
inline Code& Code::operator=( Code other )
inline Code& Code::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -23,14 +23,14 @@ inline Code::operator bool()
return ast != nullptr;
}
inline CodeBody& CodeBody::operator=( Code other )
inline CodeBody& CodeBody::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -39,14 +39,14 @@ inline CodeBody::operator bool()
return ast != nullptr;
}
inline CodeAttributes& CodeAttributes::operator=( Code other )
inline CodeAttributes& CodeAttributes::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -57,27 +57,27 @@ inline CodeAttributes::operator bool()
inline CodeAttributes::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Attributes* CodeAttributes::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeComment& CodeComment::operator=( Code other )
inline CodeComment& CodeComment::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -88,27 +88,27 @@ inline CodeComment::operator bool()
inline CodeComment::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Comment* CodeComment::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeConstructor& CodeConstructor::operator=( Code other )
inline CodeConstructor& CodeConstructor::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -119,27 +119,27 @@ inline CodeConstructor::operator bool()
inline CodeConstructor::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Constructor* CodeConstructor::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeClass& CodeClass::operator=( Code other )
inline CodeClass& CodeClass::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -148,14 +148,14 @@ inline CodeClass::operator bool()
return ast != nullptr;
}
inline CodeDefine& CodeDefine::operator=( Code other )
inline CodeDefine& CodeDefine::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -166,27 +166,27 @@ inline CodeDefine::operator bool()
inline CodeDefine::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Define* CodeDefine::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeDefineParams& CodeDefineParams::operator=( Code other )
inline CodeDefineParams& CodeDefineParams::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -195,14 +195,14 @@ inline CodeDefineParams::operator bool()
return ast != nullptr;
}
inline CodeDestructor& CodeDestructor::operator=( Code other )
inline CodeDestructor& CodeDestructor::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -213,27 +213,27 @@ inline CodeDestructor::operator bool()
inline CodeDestructor::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Destructor* CodeDestructor::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeEnum& CodeEnum::operator=( Code other )
inline CodeEnum& CodeEnum::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -244,27 +244,27 @@ inline CodeEnum::operator bool()
inline CodeEnum::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Enum* CodeEnum::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeExec& CodeExec::operator=( Code other )
inline CodeExec& CodeExec::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -275,27 +275,27 @@ inline CodeExec::operator bool()
inline CodeExec::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Exec* CodeExec::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeExtern& CodeExtern::operator=( Code other )
inline CodeExtern& CodeExtern::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -306,27 +306,27 @@ inline CodeExtern::operator bool()
inline CodeExtern::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Extern* CodeExtern::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeFriend& CodeFriend::operator=( Code other )
inline CodeFriend& CodeFriend::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -337,27 +337,27 @@ inline CodeFriend::operator bool()
inline CodeFriend::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Friend* CodeFriend::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeFn& CodeFn::operator=( Code other )
inline CodeFn& CodeFn::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -368,27 +368,27 @@ inline CodeFn::operator bool()
inline CodeFn::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Fn* CodeFn::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeInclude& CodeInclude::operator=( Code other )
inline CodeInclude& CodeInclude::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -399,27 +399,27 @@ inline CodeInclude::operator bool()
inline CodeInclude::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Include* CodeInclude::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeModule& CodeModule::operator=( Code other )
inline CodeModule& CodeModule::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -430,27 +430,27 @@ inline CodeModule::operator bool()
inline CodeModule::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Module* CodeModule::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeNS& CodeNS::operator=( Code other )
inline CodeNS& CodeNS::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -461,27 +461,27 @@ inline CodeNS::operator bool()
inline CodeNS::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_NS* CodeNS::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeOperator& CodeOperator::operator=( Code other )
inline CodeOperator& CodeOperator::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -492,27 +492,27 @@ inline CodeOperator::operator bool()
inline CodeOperator::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Operator* CodeOperator::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeOpCast& CodeOpCast::operator=( Code other )
inline CodeOpCast& CodeOpCast::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -523,27 +523,27 @@ inline CodeOpCast::operator bool()
inline CodeOpCast::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_OpCast* CodeOpCast::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeParams& CodeParams::operator=( Code other )
inline CodeParams& CodeParams::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -552,14 +552,14 @@ inline CodeParams::operator bool()
return ast != nullptr;
}
inline CodePragma& CodePragma::operator=( Code other )
inline CodePragma& CodePragma::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -570,27 +570,27 @@ inline CodePragma::operator bool()
inline CodePragma::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Pragma* CodePragma::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodePreprocessCond& CodePreprocessCond::operator=( Code other )
inline CodePreprocessCond& CodePreprocessCond::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -601,27 +601,27 @@ inline CodePreprocessCond::operator bool()
inline CodePreprocessCond::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_PreprocessCond* CodePreprocessCond::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeSpecifiers& CodeSpecifiers::operator=( Code other )
inline CodeSpecifiers& CodeSpecifiers::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -630,14 +630,14 @@ inline CodeSpecifiers::operator bool()
return ast != nullptr;
}
inline CodeStruct& CodeStruct::operator=( Code other )
inline CodeStruct& CodeStruct::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -646,14 +646,14 @@ inline CodeStruct::operator bool()
return ast != nullptr;
}
inline CodeTemplate& CodeTemplate::operator=( Code other )
inline CodeTemplate& CodeTemplate::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -664,27 +664,27 @@ inline CodeTemplate::operator bool()
inline CodeTemplate::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Template* CodeTemplate::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeTypename& CodeTypename::operator=( Code other )
inline CodeTypename& CodeTypename::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -695,27 +695,27 @@ inline CodeTypename::operator bool()
inline CodeTypename::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Typename* CodeTypename::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeTypedef& CodeTypedef::operator=( Code other )
inline CodeTypedef& CodeTypedef::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -726,27 +726,27 @@ inline CodeTypedef::operator bool()
inline CodeTypedef::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Typedef* CodeTypedef::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeUnion& CodeUnion::operator=( Code other )
inline CodeUnion& CodeUnion::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -757,27 +757,27 @@ inline CodeUnion::operator bool()
inline CodeUnion::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Union* CodeUnion::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeUsing& CodeUsing::operator=( Code other )
inline CodeUsing& CodeUsing::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -788,27 +788,27 @@ inline CodeUsing::operator bool()
inline CodeUsing::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Using* CodeUsing::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;
}
inline CodeVar& CodeVar::operator=( Code other )
inline CodeVar& CodeVar::operator=(Code other)
{
if ( other.ast != nullptr && other->Parent != nullptr )
if (other.ast != nullptr && other->Parent != nullptr)
{
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr };
}
ast = rcast( decltype( ast ), other.ast );
ast = rcast(decltype(ast), other.ast);
return *this;
}
@ -819,14 +819,14 @@ inline CodeVar::operator bool()
inline CodeVar::operator Code()
{
return *rcast( Code*, this );
return *rcast(Code*, this);
}
inline AST_Var* CodeVar::operator->()
{
if ( ast == nullptr )
if (ast == nullptr)
{
log_failure( "Attempt to dereference a nullptr!\n" );
log_failure("Attempt to dereference a nullptr!\n");
return nullptr;
}
return ast;

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "components/types.hpp"
#endif
@ -73,150 +73,150 @@ enum CodeType : u32
CT_UnderlyingType = GEN_U32_MAX
};
inline Str codetype_to_str( CodeType type )
inline Str codetype_to_str(CodeType type)
{
local_persist Str lookup[] = {
{ "Invalid", sizeof( "Invalid" ) - 1 },
{ "Untyped", sizeof( "Untyped" ) - 1 },
{ "NewLine", sizeof( "NewLine" ) - 1 },
{ "Comment", sizeof( "Comment" ) - 1 },
{ "Access_Private", sizeof( "Access_Private" ) - 1 },
{ "Access_Protected", sizeof( "Access_Protected" ) - 1 },
{ "Access_Public", sizeof( "Access_Public" ) - 1 },
{ "PlatformAttributes", sizeof( "PlatformAttributes" ) - 1 },
{ "Class", sizeof( "Class" ) - 1 },
{ "Class_Fwd", sizeof( "Class_Fwd" ) - 1 },
{ "Class_Body", sizeof( "Class_Body" ) - 1 },
{ "Constructor", sizeof( "Constructor" ) - 1 },
{ "Constructor_Fwd", sizeof( "Constructor_Fwd" ) - 1 },
{ "Destructor", sizeof( "Destructor" ) - 1 },
{ "Destructor_Fwd", sizeof( "Destructor_Fwd" ) - 1 },
{ "Enum", sizeof( "Enum" ) - 1 },
{ "Enum_Fwd", sizeof( "Enum_Fwd" ) - 1 },
{ "Enum_Body", sizeof( "Enum_Body" ) - 1 },
{ "Enum_Class", sizeof( "Enum_Class" ) - 1 },
{ "Enum_Class_Fwd", sizeof( "Enum_Class_Fwd" ) - 1 },
{ "Execution", sizeof( "Execution" ) - 1 },
{ "Export_Body", sizeof( "Export_Body" ) - 1 },
{ "Extern_Linkage", sizeof( "Extern_Linkage" ) - 1 },
{ "Extern_Linkage_Body", sizeof( "Extern_Linkage_Body" ) - 1 },
{ "Friend", sizeof( "Friend" ) - 1 },
{ "Function", sizeof( "Function" ) - 1 },
{ "Function_Fwd", sizeof( "Function_Fwd" ) - 1 },
{ "Function_Body", sizeof( "Function_Body" ) - 1 },
{ "Global_Body", sizeof( "Global_Body" ) - 1 },
{ "Module", sizeof( "Module" ) - 1 },
{ "Namespace", sizeof( "Namespace" ) - 1 },
{ "Namespace_Body", sizeof( "Namespace_Body" ) - 1 },
{ "Operator", sizeof( "Operator" ) - 1 },
{ "Operator_Fwd", sizeof( "Operator_Fwd" ) - 1 },
{ "Operator_Member", sizeof( "Operator_Member" ) - 1 },
{ "Operator_Member_Fwd", sizeof( "Operator_Member_Fwd" ) - 1 },
{ "Operator_Cast", sizeof( "Operator_Cast" ) - 1 },
{ "Operator_Cast_Fwd", sizeof( "Operator_Cast_Fwd" ) - 1 },
{ "Parameters", sizeof( "Parameters" ) - 1 },
{ "Parameters_Define", sizeof( "Parameters_Define" ) - 1 },
{ "Preprocess_Define", sizeof( "Preprocess_Define" ) - 1 },
{ "Preprocess_Include", sizeof( "Preprocess_Include" ) - 1 },
{ "Preprocess_If", sizeof( "Preprocess_If" ) - 1 },
{ "Preprocess_IfDef", sizeof( "Preprocess_IfDef" ) - 1 },
{ "Preprocess_IfNotDef", sizeof( "Preprocess_IfNotDef" ) - 1 },
{ "Preprocess_ElIf", sizeof( "Preprocess_ElIf" ) - 1 },
{ "Preprocess_Else", sizeof( "Preprocess_Else" ) - 1 },
{ "Preprocess_EndIf", sizeof( "Preprocess_EndIf" ) - 1 },
{ "Preprocess_Pragma", sizeof( "Preprocess_Pragma" ) - 1 },
{ "Specifiers", sizeof( "Specifiers" ) - 1 },
{ "Struct", sizeof( "Struct" ) - 1 },
{ "Struct_Fwd", sizeof( "Struct_Fwd" ) - 1 },
{ "Struct_Body", sizeof( "Struct_Body" ) - 1 },
{ "Template", sizeof( "Template" ) - 1 },
{ "Typedef", sizeof( "Typedef" ) - 1 },
{ "Typename", sizeof( "Typename" ) - 1 },
{ "Union", sizeof( "Union" ) - 1 },
{ "Union_Fwd", sizeof( "Union_Fwd" ) - 1 },
{ "Union_Body", sizeof( "Union_Body" ) - 1 },
{ "Using", sizeof( "Using" ) - 1 },
{ "Using_Namespace", sizeof( "Using_Namespace" ) - 1 },
{ "Variable", sizeof( "Variable" ) - 1 },
{ "Invalid", sizeof("Invalid") - 1 },
{ "Untyped", sizeof("Untyped") - 1 },
{ "NewLine", sizeof("NewLine") - 1 },
{ "Comment", sizeof("Comment") - 1 },
{ "Access_Private", sizeof("Access_Private") - 1 },
{ "Access_Protected", sizeof("Access_Protected") - 1 },
{ "Access_Public", sizeof("Access_Public") - 1 },
{ "PlatformAttributes", sizeof("PlatformAttributes") - 1 },
{ "Class", sizeof("Class") - 1 },
{ "Class_Fwd", sizeof("Class_Fwd") - 1 },
{ "Class_Body", sizeof("Class_Body") - 1 },
{ "Constructor", sizeof("Constructor") - 1 },
{ "Constructor_Fwd", sizeof("Constructor_Fwd") - 1 },
{ "Destructor", sizeof("Destructor") - 1 },
{ "Destructor_Fwd", sizeof("Destructor_Fwd") - 1 },
{ "Enum", sizeof("Enum") - 1 },
{ "Enum_Fwd", sizeof("Enum_Fwd") - 1 },
{ "Enum_Body", sizeof("Enum_Body") - 1 },
{ "Enum_Class", sizeof("Enum_Class") - 1 },
{ "Enum_Class_Fwd", sizeof("Enum_Class_Fwd") - 1 },
{ "Execution", sizeof("Execution") - 1 },
{ "Export_Body", sizeof("Export_Body") - 1 },
{ "Extern_Linkage", sizeof("Extern_Linkage") - 1 },
{ "Extern_Linkage_Body", sizeof("Extern_Linkage_Body") - 1 },
{ "Friend", sizeof("Friend") - 1 },
{ "Function", sizeof("Function") - 1 },
{ "Function_Fwd", sizeof("Function_Fwd") - 1 },
{ "Function_Body", sizeof("Function_Body") - 1 },
{ "Global_Body", sizeof("Global_Body") - 1 },
{ "Module", sizeof("Module") - 1 },
{ "Namespace", sizeof("Namespace") - 1 },
{ "Namespace_Body", sizeof("Namespace_Body") - 1 },
{ "Operator", sizeof("Operator") - 1 },
{ "Operator_Fwd", sizeof("Operator_Fwd") - 1 },
{ "Operator_Member", sizeof("Operator_Member") - 1 },
{ "Operator_Member_Fwd", sizeof("Operator_Member_Fwd") - 1 },
{ "Operator_Cast", sizeof("Operator_Cast") - 1 },
{ "Operator_Cast_Fwd", sizeof("Operator_Cast_Fwd") - 1 },
{ "Parameters", sizeof("Parameters") - 1 },
{ "Parameters_Define", sizeof("Parameters_Define") - 1 },
{ "Preprocess_Define", sizeof("Preprocess_Define") - 1 },
{ "Preprocess_Include", sizeof("Preprocess_Include") - 1 },
{ "Preprocess_If", sizeof("Preprocess_If") - 1 },
{ "Preprocess_IfDef", sizeof("Preprocess_IfDef") - 1 },
{ "Preprocess_IfNotDef", sizeof("Preprocess_IfNotDef") - 1 },
{ "Preprocess_ElIf", sizeof("Preprocess_ElIf") - 1 },
{ "Preprocess_Else", sizeof("Preprocess_Else") - 1 },
{ "Preprocess_EndIf", sizeof("Preprocess_EndIf") - 1 },
{ "Preprocess_Pragma", sizeof("Preprocess_Pragma") - 1 },
{ "Specifiers", sizeof("Specifiers") - 1 },
{ "Struct", sizeof("Struct") - 1 },
{ "Struct_Fwd", sizeof("Struct_Fwd") - 1 },
{ "Struct_Body", sizeof("Struct_Body") - 1 },
{ "Template", sizeof("Template") - 1 },
{ "Typedef", sizeof("Typedef") - 1 },
{ "Typename", sizeof("Typename") - 1 },
{ "Union", sizeof("Union") - 1 },
{ "Union_Fwd", sizeof("Union_Fwd") - 1 },
{ "Union_Body", sizeof("Union_Body") - 1 },
{ "Using", sizeof("Using") - 1 },
{ "Using_Namespace", sizeof("Using_Namespace") - 1 },
{ "Variable", sizeof("Variable") - 1 },
};
return lookup[type];
}
inline Str codetype_to_keyword_str( CodeType type )
inline Str codetype_to_keyword_str(CodeType type)
{
local_persist Str lookup[] = {
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "//", sizeof( "//" ) - 1 },
{ "private", sizeof( "private" ) - 1 },
{ "protected", sizeof( "protected" ) - 1 },
{ "public", sizeof( "public" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "class", sizeof( "class" ) - 1 },
{ "clsss", sizeof( "clsss" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "enum", sizeof( "enum" ) - 1 },
{ "enum", sizeof( "enum" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "enum class", sizeof( "enum class" ) - 1 },
{ "enum class", sizeof( "enum class" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "extern", sizeof( "extern" ) - 1 },
{ "extern", sizeof( "extern" ) - 1 },
{ "friend", sizeof( "friend" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "module", sizeof( "module" ) - 1 },
{ "namespace", sizeof( "namespace" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "define", sizeof( "define" ) - 1 },
{ "include", sizeof( "include" ) - 1 },
{ "if", sizeof( "if" ) - 1 },
{ "ifdef", sizeof( "ifdef" ) - 1 },
{ "ifndef", sizeof( "ifndef" ) - 1 },
{ "elif", sizeof( "elif" ) - 1 },
{ "else", sizeof( "else" ) - 1 },
{ "endif", sizeof( "endif" ) - 1 },
{ "pragma", sizeof( "pragma" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "struct", sizeof( "struct" ) - 1 },
{ "struct", sizeof( "struct" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "template", sizeof( "template" ) - 1 },
{ "typedef", sizeof( "typedef" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "union", sizeof( "union" ) - 1 },
{ "union", sizeof( "union" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "using", sizeof( "using" ) - 1 },
{ "using namespace", sizeof( "using namespace" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "//", sizeof("//") - 1 },
{ "private", sizeof("private") - 1 },
{ "protected", sizeof("protected") - 1 },
{ "public", sizeof("public") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "class", sizeof("class") - 1 },
{ "clsss", sizeof("clsss") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "enum", sizeof("enum") - 1 },
{ "enum", sizeof("enum") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "enum class", sizeof("enum class") - 1 },
{ "enum class", sizeof("enum class") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "extern", sizeof("extern") - 1 },
{ "extern", sizeof("extern") - 1 },
{ "friend", sizeof("friend") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "module", sizeof("module") - 1 },
{ "namespace", sizeof("namespace") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "operator", sizeof("operator") - 1 },
{ "operator", sizeof("operator") - 1 },
{ "operator", sizeof("operator") - 1 },
{ "operator", sizeof("operator") - 1 },
{ "operator", sizeof("operator") - 1 },
{ "operator", sizeof("operator") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "define", sizeof("define") - 1 },
{ "include", sizeof("include") - 1 },
{ "if", sizeof("if") - 1 },
{ "ifdef", sizeof("ifdef") - 1 },
{ "ifndef", sizeof("ifndef") - 1 },
{ "elif", sizeof("elif") - 1 },
{ "else", sizeof("else") - 1 },
{ "endif", sizeof("endif") - 1 },
{ "pragma", sizeof("pragma") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "struct", sizeof("struct") - 1 },
{ "struct", sizeof("struct") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "template", sizeof("template") - 1 },
{ "typedef", sizeof("typedef") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "union", sizeof("union") - 1 },
{ "union", sizeof("union") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
{ "using", sizeof("using") - 1 },
{ "using namespace", sizeof("using namespace") - 1 },
{ "__NA__", sizeof("__NA__") - 1 },
};
return lookup[type];
}
forceinline Str to_str( CodeType type )
forceinline Str to_str(CodeType type)
{
return codetype_to_str( type );
return codetype_to_str(type);
}
forceinline Str to_keyword_str( CodeType type )
forceinline Str to_keyword_str(CodeType type)
{
return codetype_to_keyword_str( type );
return codetype_to_keyword_str(type);
}

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "components/types.hpp"
#endif
@ -58,61 +58,61 @@ enum Operator : u32
Op_UnderlyingType = 0xffffffffu
};
inline Str operator_to_str( Operator op )
inline Str operator_to_str(Operator op)
{
local_persist Str lookup[] = {
{ "INVALID", sizeof( "INVALID" ) - 1 },
{ "=", sizeof( "=" ) - 1 },
{ "+=", sizeof( "+=" ) - 1 },
{ "-=", sizeof( "-=" ) - 1 },
{ "*=", sizeof( "*=" ) - 1 },
{ "/=", sizeof( "/=" ) - 1 },
{ "%=", sizeof( "%=" ) - 1 },
{ "&=", sizeof( "&=" ) - 1 },
{ "|=", sizeof( "|=" ) - 1 },
{ "^=", sizeof( "^=" ) - 1 },
{ "<<=", sizeof( "<<=" ) - 1 },
{ ">>=", sizeof( ">>=" ) - 1 },
{ "++", sizeof( "++" ) - 1 },
{ "--", sizeof( "--" ) - 1 },
{ "+", sizeof( "+" ) - 1 },
{ "-", sizeof( "-" ) - 1 },
{ "!", sizeof( "!" ) - 1 },
{ "+", sizeof( "+" ) - 1 },
{ "-", sizeof( "-" ) - 1 },
{ "*", sizeof( "*" ) - 1 },
{ "/", sizeof( "/" ) - 1 },
{ "%", sizeof( "%" ) - 1 },
{ "~", sizeof( "~" ) - 1 },
{ "&", sizeof( "&" ) - 1 },
{ "|", sizeof( "|" ) - 1 },
{ "^", sizeof( "^" ) - 1 },
{ "<<", sizeof( "<<" ) - 1 },
{ ">>", sizeof( ">>" ) - 1 },
{ "&&", sizeof( "&&" ) - 1 },
{ "||", sizeof( "||" ) - 1 },
{ "==", sizeof( "==" ) - 1 },
{ "!=", sizeof( "!=" ) - 1 },
{ "<", sizeof( "<" ) - 1 },
{ ">", sizeof( ">" ) - 1 },
{ "<=", sizeof( "<=" ) - 1 },
{ ">=", sizeof( ">=" ) - 1 },
{ "[]", sizeof( "[]" ) - 1 },
{ "*", sizeof( "*" ) - 1 },
{ "&", sizeof( "&" ) - 1 },
{ "->", sizeof( "->" ) - 1 },
{ "->*", sizeof( "->*" ) - 1 },
{ "()", sizeof( "()" ) - 1 },
{ ",", sizeof( "," ) - 1 },
{ "new", sizeof( "new" ) - 1 },
{ "new[]", sizeof( "new[]" ) - 1 },
{ "delete", sizeof( "delete" ) - 1 },
{ "delete[]", sizeof( "delete[]" ) - 1 },
{ "INVALID", sizeof("INVALID") - 1 },
{ "=", sizeof("=") - 1 },
{ "+=", sizeof("+=") - 1 },
{ "-=", sizeof("-=") - 1 },
{ "*=", sizeof("*=") - 1 },
{ "/=", sizeof("/=") - 1 },
{ "%=", sizeof("%=") - 1 },
{ "&=", sizeof("&=") - 1 },
{ "|=", sizeof("|=") - 1 },
{ "^=", sizeof("^=") - 1 },
{ "<<=", sizeof("<<=") - 1 },
{ ">>=", sizeof(">>=") - 1 },
{ "++", sizeof("++") - 1 },
{ "--", sizeof("--") - 1 },
{ "+", sizeof("+") - 1 },
{ "-", sizeof("-") - 1 },
{ "!", sizeof("!") - 1 },
{ "+", sizeof("+") - 1 },
{ "-", sizeof("-") - 1 },
{ "*", sizeof("*") - 1 },
{ "/", sizeof("/") - 1 },
{ "%", sizeof("%") - 1 },
{ "~", sizeof("~") - 1 },
{ "&", sizeof("&") - 1 },
{ "|", sizeof("|") - 1 },
{ "^", sizeof("^") - 1 },
{ "<<", sizeof("<<") - 1 },
{ ">>", sizeof(">>") - 1 },
{ "&&", sizeof("&&") - 1 },
{ "||", sizeof("||") - 1 },
{ "==", sizeof("==") - 1 },
{ "!=", sizeof("!=") - 1 },
{ "<", sizeof("<") - 1 },
{ ">", sizeof(">") - 1 },
{ "<=", sizeof("<=") - 1 },
{ ">=", sizeof(">=") - 1 },
{ "[]", sizeof("[]") - 1 },
{ "*", sizeof("*") - 1 },
{ "&", sizeof("&") - 1 },
{ "->", sizeof("->") - 1 },
{ "->*", sizeof("->*") - 1 },
{ "()", sizeof("()") - 1 },
{ ",", sizeof(",") - 1 },
{ "new", sizeof("new") - 1 },
{ "new[]", sizeof("new[]") - 1 },
{ "delete", sizeof("delete") - 1 },
{ "delete[]", sizeof("delete[]") - 1 },
};
return lookup[op];
}
forceinline Str to_str( Operator op )
forceinline Str to_str(Operator op)
{
return operator_to_str( op );
return operator_to_str(op);
}

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "components/types.hpp"
#endif
@ -23,6 +23,7 @@ enum Specifier : u32
Spec_Ptr,
Spec_Ref,
Spec_Register,
Spec_Restrict,
Spec_RValue,
Spec_Static,
Spec_Thread_Local,
@ -32,88 +33,92 @@ enum Specifier : u32
Spec_NoExceptions,
Spec_Override,
Spec_Pure,
Spec_Delete,
Spec_Volatile,
Spec_NumSpecifiers,
Spec_UnderlyingType = 0xffffffffu
};
inline Str spec_to_str( Specifier type )
inline Str spec_to_str(Specifier type)
{
local_persist Str lookup[] = {
{ "INVALID", sizeof( "INVALID" ) - 1 },
{ "consteval", sizeof( "consteval" ) - 1 },
{ "constexpr", sizeof( "constexpr" ) - 1 },
{ "constinit", sizeof( "constinit" ) - 1 },
{ "explicit", sizeof( "explicit" ) - 1 },
{ "extern", sizeof( "extern" ) - 1 },
{ "forceinline", sizeof( "forceinline" ) - 1 },
{ "global", sizeof( "global" ) - 1 },
{ "inline", sizeof( "inline" ) - 1 },
{ "internal", sizeof( "internal" ) - 1 },
{ "local_persist", sizeof( "local_persist" ) - 1 },
{ "mutable", sizeof( "mutable" ) - 1 },
{ "neverinline", sizeof( "neverinline" ) - 1 },
{ "*", sizeof( "*" ) - 1 },
{ "&", sizeof( "&" ) - 1 },
{ "register", sizeof( "register" ) - 1 },
{ "&&", sizeof( "&&" ) - 1 },
{ "static", sizeof( "static" ) - 1 },
{ "thread_local", sizeof( "thread_local" ) - 1 },
{ "virtual", sizeof( "virtual" ) - 1 },
{ "const", sizeof( "const" ) - 1 },
{ "final", sizeof( "final" ) - 1 },
{ "noexcept", sizeof( "noexcept" ) - 1 },
{ "override", sizeof( "override" ) - 1 },
{ "= 0", sizeof( "= 0" ) - 1 },
{ "volatile", sizeof( "volatile" ) - 1 },
{ "INVALID", sizeof("INVALID") - 1 },
{ "consteval", sizeof("consteval") - 1 },
{ "constexpr", sizeof("constexpr") - 1 },
{ "constinit", sizeof("constinit") - 1 },
{ "explicit", sizeof("explicit") - 1 },
{ "extern", sizeof("extern") - 1 },
{ "forceinline", sizeof("forceinline") - 1 },
{ "global", sizeof("global") - 1 },
{ "inline", sizeof("inline") - 1 },
{ "internal", sizeof("internal") - 1 },
{ "local_persist", sizeof("local_persist") - 1 },
{ "mutable", sizeof("mutable") - 1 },
{ "neverinline", sizeof("neverinline") - 1 },
{ "*", sizeof("*") - 1 },
{ "&", sizeof("&") - 1 },
{ "register", sizeof("register") - 1 },
{ "restrict", sizeof("restrict") - 1 },
{ "&&", sizeof("&&") - 1 },
{ "static", sizeof("static") - 1 },
{ "thread_local", sizeof("thread_local") - 1 },
{ "virtual", sizeof("virtual") - 1 },
{ "const", sizeof("const") - 1 },
{ "final", sizeof("final") - 1 },
{ "noexcept", sizeof("noexcept") - 1 },
{ "override", sizeof("override") - 1 },
{ "= 0", sizeof("= 0") - 1 },
{ "= delete", sizeof("= delete") - 1 },
{ "volatile", sizeof("volatile") - 1 },
};
return lookup[type];
}
inline bool spec_is_trailing( Specifier specifier )
inline bool spec_is_trailing(Specifier specifier)
{
switch ( specifier )
switch (specifier)
{
case Spec_Const :
case Spec_Final :
case Spec_NoExceptions :
case Spec_Override :
case Spec_Pure :
case Spec_Volatile :
case Spec_Const:
case Spec_Final:
case Spec_NoExceptions:
case Spec_Override:
case Spec_Pure:
case Spec_Delete:
case Spec_Volatile:
return true;
default :
default:
return false;
}
}
inline Specifier str_to_specifier( Str str )
inline Specifier str_to_specifier(Str str)
{
local_persist u32 keymap[Spec_NumSpecifiers];
do_once_start for ( u32 index = 0; index < Spec_NumSpecifiers; index++ )
do_once_start for (u32 index = 0; index < Spec_NumSpecifiers; index++)
{
Str enum_str = spec_to_str( (Specifier)index );
keymap[index] = crc32( enum_str.Ptr, enum_str.Len );
Str enum_str = spec_to_str((Specifier)index);
keymap[index] = crc32(enum_str.Ptr, enum_str.Len);
}
do_once_end u32 hash = crc32( str.Ptr, str.Len );
for ( u32 index = 0; index < Spec_NumSpecifiers; index++ )
do_once_end u32 hash = crc32(str.Ptr, str.Len);
for (u32 index = 0; index < Spec_NumSpecifiers; index++)
{
if ( keymap[index] == hash )
if (keymap[index] == hash)
return (Specifier)index;
}
return Spec_Invalid;
}
forceinline Str to_str( Specifier spec )
forceinline Str to_str(Specifier spec)
{
return spec_to_str( spec );
return spec_to_str(spec);
}
forceinline Specifier to_type( Str str )
forceinline Specifier to_type(Str str)
{
return str_to_specifier( str );
return str_to_specifier(str);
}
forceinline bool is_trailing( Specifier specifier )
forceinline bool is_trailing(Specifier specifier)
{
return spec_is_trailing( specifier );
return spec_is_trailing(specifier);
}

View File

@ -1,11 +1,11 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "components/types.hpp"
#endif
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
#define GEN_DEFINE_ATTRIBUTE_TOKENS Entry( Tok_Attribute_GEN_API, "GEN_API" )
#define GEN_DEFINE_ATTRIBUTE_TOKENS Entry(Tok_Attribute_GEN_API, "GEN_API")
enum TokType : u32
{
@ -83,6 +83,7 @@ enum TokType : u32
Tok_Spec_Mutable,
Tok_Spec_NeverInline,
Tok_Spec_Override,
Tok_Spec_Restrict,
Tok_Spec_Static,
Tok_Spec_ThreadLocal,
Tok_Spec_Volatile,
@ -111,124 +112,125 @@ enum TokType : u32
Tok_NumTokens
};
inline Str toktype_to_str( TokType type )
inline Str toktype_to_str(TokType type)
{
local_persist Str lookup[] = {
{ "__invalid__", sizeof( "__invalid__" ) - 1 },
{ "private", sizeof( "private" ) - 1 },
{ "protected", sizeof( "protected" ) - 1 },
{ "public", sizeof( "public" ) - 1 },
{ ".", sizeof( "." ) - 1 },
{ "::", sizeof( "::" ) - 1 },
{ "&", sizeof( "&" ) - 1 },
{ "&&", sizeof( "&&" ) - 1 },
{ ":", sizeof( ":" ) - 1 },
{ "[[", sizeof( "[[" ) - 1 },
{ "]]", sizeof( "]]" ) - 1 },
{ "{", sizeof( "{" ) - 1 },
{ "}", sizeof( "}" ) - 1 },
{ "[", sizeof( "[" ) - 1 },
{ "]", sizeof( "]" ) - 1 },
{ "(", sizeof( "(" ) - 1 },
{ ")", sizeof( ")" ) - 1 },
{ "__comment__", sizeof( "__comment__" ) - 1 },
{ "__comment_end__", sizeof( "__comment_end__" ) - 1 },
{ "__comment_start__", sizeof( "__comment_start__" ) - 1 },
{ "__character__", sizeof( "__character__" ) - 1 },
{ ",", sizeof( "," ) - 1 },
{ "class", sizeof( "class" ) - 1 },
{ "__attribute__", sizeof( "__attribute__" ) - 1 },
{ "__declspec", sizeof( "__declspec" ) - 1 },
{ "enum", sizeof( "enum" ) - 1 },
{ "extern", sizeof( "extern" ) - 1 },
{ "friend", sizeof( "friend" ) - 1 },
{ "module", sizeof( "module" ) - 1 },
{ "namespace", sizeof( "namespace" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 },
{ "struct", sizeof( "struct" ) - 1 },
{ "template", sizeof( "template" ) - 1 },
{ "typedef", sizeof( "typedef" ) - 1 },
{ "using", sizeof( "using" ) - 1 },
{ "union", sizeof( "union" ) - 1 },
{ "__identifier__", sizeof( "__identifier__" ) - 1 },
{ "import", sizeof( "import" ) - 1 },
{ "export", sizeof( "export" ) - 1 },
{ "__new_line__", sizeof( "__new_line__" ) - 1 },
{ "__number__", sizeof( "__number__" ) - 1 },
{ "__operator__", sizeof( "__operator__" ) - 1 },
{ "#", sizeof( "#" ) - 1 },
{ "define", sizeof( "define" ) - 1 },
{ "__define_param__", sizeof( "__define_param__" ) - 1 },
{ "if", sizeof( "if" ) - 1 },
{ "ifdef", sizeof( "ifdef" ) - 1 },
{ "ifndef", sizeof( "ifndef" ) - 1 },
{ "elif", sizeof( "elif" ) - 1 },
{ "else", sizeof( "else" ) - 1 },
{ "endif", sizeof( "endif" ) - 1 },
{ "include", sizeof( "include" ) - 1 },
{ "pragma", sizeof( "pragma" ) - 1 },
{ "__macro_content__", sizeof( "__macro_content__" ) - 1 },
{ "__macro_expression__", sizeof( "__macro_expression__" ) - 1 },
{ "__macro_statment__", sizeof( "__macro_statment__" ) - 1 },
{ "__macro_typename__", sizeof( "__macro_typename__" ) - 1 },
{ "__unsupported__", sizeof( "__unsupported__" ) - 1 },
{ "alignas", sizeof( "alignas" ) - 1 },
{ "const", sizeof( "const" ) - 1 },
{ "consteval", sizeof( "consteval" ) - 1 },
{ "constexpr", sizeof( "constexpr" ) - 1 },
{ "constinit", sizeof( "constinit" ) - 1 },
{ "explicit", sizeof( "explicit" ) - 1 },
{ "extern", sizeof( "extern" ) - 1 },
{ "final", sizeof( "final" ) - 1 },
{ "forceinline", sizeof( "forceinline" ) - 1 },
{ "global", sizeof( "global" ) - 1 },
{ "inline", sizeof( "inline" ) - 1 },
{ "internal", sizeof( "internal" ) - 1 },
{ "local_persist", sizeof( "local_persist" ) - 1 },
{ "mutable", sizeof( "mutable" ) - 1 },
{ "neverinline", sizeof( "neverinline" ) - 1 },
{ "override", sizeof( "override" ) - 1 },
{ "static", sizeof( "static" ) - 1 },
{ "thread_local", sizeof( "thread_local" ) - 1 },
{ "volatile", sizeof( "volatile" ) - 1 },
{ "virtual", sizeof( "virtual" ) - 1 },
{ "*", sizeof( "*" ) - 1 },
{ ";", sizeof( ";" ) - 1 },
{ "static_assert", sizeof( "static_assert" ) - 1 },
{ "__string__", sizeof( "__string__" ) - 1 },
{ "typename", sizeof( "typename" ) - 1 },
{ "unsigned", sizeof( "unsigned" ) - 1 },
{ "signed", sizeof( "signed" ) - 1 },
{ "short", sizeof( "short" ) - 1 },
{ "long", sizeof( "long" ) - 1 },
{ "bool", sizeof( "bool" ) - 1 },
{ "char", sizeof( "char" ) - 1 },
{ "int", sizeof( "int" ) - 1 },
{ "double", sizeof( "double" ) - 1 },
{ "__int8", sizeof( "__int8" ) - 1 },
{ "__int16", sizeof( "__int16" ) - 1 },
{ "__int32", sizeof( "__int32" ) - 1 },
{ "__int64", sizeof( "__int64" ) - 1 },
{ "_W64", sizeof( "_W64" ) - 1 },
{ "...", sizeof( "..." ) - 1 },
{ "__attrib_start__", sizeof( "__attrib_start__" ) - 1 },
{ "GEN_API", sizeof( "GEN_API" ) - 1 },
{ "__invalid__", sizeof("__invalid__") - 1 },
{ "private", sizeof("private") - 1 },
{ "protected", sizeof("protected") - 1 },
{ "public", sizeof("public") - 1 },
{ ".", sizeof(".") - 1 },
{ "::", sizeof("::") - 1 },
{ "&", sizeof("&") - 1 },
{ "&&", sizeof("&&") - 1 },
{ ":", sizeof(":") - 1 },
{ "[[", sizeof("[[") - 1 },
{ "]]", sizeof("]]") - 1 },
{ "{", sizeof("{") - 1 },
{ "}", sizeof("}") - 1 },
{ "[", sizeof("[") - 1 },
{ "]", sizeof("]") - 1 },
{ "(", sizeof("(") - 1 },
{ ")", sizeof(")") - 1 },
{ "__comment__", sizeof("__comment__") - 1 },
{ "__comment_end__", sizeof("__comment_end__") - 1 },
{ "__comment_start__", sizeof("__comment_start__") - 1 },
{ "__character__", sizeof("__character__") - 1 },
{ ",", sizeof(",") - 1 },
{ "class", sizeof("class") - 1 },
{ "__attribute__", sizeof("__attribute__") - 1 },
{ "__declspec", sizeof("__declspec") - 1 },
{ "enum", sizeof("enum") - 1 },
{ "extern", sizeof("extern") - 1 },
{ "friend", sizeof("friend") - 1 },
{ "module", sizeof("module") - 1 },
{ "namespace", sizeof("namespace") - 1 },
{ "operator", sizeof("operator") - 1 },
{ "struct", sizeof("struct") - 1 },
{ "template", sizeof("template") - 1 },
{ "typedef", sizeof("typedef") - 1 },
{ "using", sizeof("using") - 1 },
{ "union", sizeof("union") - 1 },
{ "__identifier__", sizeof("__identifier__") - 1 },
{ "import", sizeof("import") - 1 },
{ "export", sizeof("export") - 1 },
{ "__new_line__", sizeof("__new_line__") - 1 },
{ "__number__", sizeof("__number__") - 1 },
{ "__operator__", sizeof("__operator__") - 1 },
{ "#", sizeof("#") - 1 },
{ "define", sizeof("define") - 1 },
{ "__define_param__", sizeof("__define_param__") - 1 },
{ "if", sizeof("if") - 1 },
{ "ifdef", sizeof("ifdef") - 1 },
{ "ifndef", sizeof("ifndef") - 1 },
{ "elif", sizeof("elif") - 1 },
{ "else", sizeof("else") - 1 },
{ "endif", sizeof("endif") - 1 },
{ "include", sizeof("include") - 1 },
{ "pragma", sizeof("pragma") - 1 },
{ "__macro_content__", sizeof("__macro_content__") - 1 },
{ "__macro_expression__", sizeof("__macro_expression__") - 1 },
{ "__macro_statment__", sizeof("__macro_statment__") - 1 },
{ "__macro_typename__", sizeof("__macro_typename__") - 1 },
{ "__unsupported__", sizeof("__unsupported__") - 1 },
{ "alignas", sizeof("alignas") - 1 },
{ "const", sizeof("const") - 1 },
{ "consteval", sizeof("consteval") - 1 },
{ "constexpr", sizeof("constexpr") - 1 },
{ "constinit", sizeof("constinit") - 1 },
{ "explicit", sizeof("explicit") - 1 },
{ "extern", sizeof("extern") - 1 },
{ "final", sizeof("final") - 1 },
{ "forceinline", sizeof("forceinline") - 1 },
{ "global", sizeof("global") - 1 },
{ "inline", sizeof("inline") - 1 },
{ "internal", sizeof("internal") - 1 },
{ "local_persist", sizeof("local_persist") - 1 },
{ "mutable", sizeof("mutable") - 1 },
{ "neverinline", sizeof("neverinline") - 1 },
{ "override", sizeof("override") - 1 },
{ "restrict", sizeof("restrict") - 1 },
{ "static", sizeof("static") - 1 },
{ "thread_local", sizeof("thread_local") - 1 },
{ "volatile", sizeof("volatile") - 1 },
{ "virtual", sizeof("virtual") - 1 },
{ "*", sizeof("*") - 1 },
{ ";", sizeof(";") - 1 },
{ "static_assert", sizeof("static_assert") - 1 },
{ "__string__", sizeof("__string__") - 1 },
{ "typename", sizeof("typename") - 1 },
{ "unsigned", sizeof("unsigned") - 1 },
{ "signed", sizeof("signed") - 1 },
{ "short", sizeof("short") - 1 },
{ "long", sizeof("long") - 1 },
{ "bool", sizeof("bool") - 1 },
{ "char", sizeof("char") - 1 },
{ "int", sizeof("int") - 1 },
{ "double", sizeof("double") - 1 },
{ "__int8", sizeof("__int8") - 1 },
{ "__int16", sizeof("__int16") - 1 },
{ "__int32", sizeof("__int32") - 1 },
{ "__int64", sizeof("__int64") - 1 },
{ "_W64", sizeof("_W64") - 1 },
{ "...", sizeof("...") - 1 },
{ "__attrib_start__", sizeof("__attrib_start__") - 1 },
{ "GEN_API", sizeof("GEN_API") - 1 },
};
return lookup[type];
}
inline TokType str_to_toktype( Str str )
inline TokType str_to_toktype(Str str)
{
local_persist u32 keymap[Tok_NumTokens];
do_once_start for ( u32 index = 0; index < Tok_NumTokens; index++ )
do_once_start for (u32 index = 0; index < Tok_NumTokens; index++)
{
Str enum_str = toktype_to_str( (TokType)index );
keymap[index] = crc32( enum_str.Ptr, enum_str.Len );
Str enum_str = toktype_to_str((TokType)index);
keymap[index] = crc32(enum_str.Ptr, enum_str.Len);
}
do_once_end u32 hash = crc32( str.Ptr, str.Len );
for ( u32 index = 0; index < Tok_NumTokens; index++ )
do_once_end u32 hash = crc32(str.Ptr, str.Len);
for (u32 index = 0; index < Tok_NumTokens; index++)
{
if ( keymap[index] == hash )
if (keymap[index] == hash)
return (TokType)index;
}
return Tok_Invalid;

View File

@ -1,88 +0,0 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#pragma once
#include "inlines.hpp"
#include "gen/ast_inlines.hpp"
#endif
#pragma region Constants
extern Macro enum_underlying_macro;
extern Code access_public;
extern Code access_protected;
extern Code access_private;
extern CodeAttributes attrib_api_export;
extern CodeAttributes attrib_api_import;
extern Code module_global_fragment;
extern Code module_private_fragment;
extern Code fmt_newline;
extern CodePragma pragma_once;
extern CodeParams param_varadic;
extern CodePreprocessCond preprocess_else;
extern CodePreprocessCond preprocess_endif;
extern CodeSpecifiers spec_const;
extern CodeSpecifiers spec_consteval;
extern CodeSpecifiers spec_constexpr;
extern CodeSpecifiers spec_constinit;
extern CodeSpecifiers spec_extern_linkage;
extern CodeSpecifiers spec_final;
extern CodeSpecifiers spec_forceinline;
extern CodeSpecifiers spec_global;
extern CodeSpecifiers spec_inline;
extern CodeSpecifiers spec_internal_linkage;
extern CodeSpecifiers spec_local_persist;
extern CodeSpecifiers spec_mutable;
extern CodeSpecifiers spec_neverinline;
extern CodeSpecifiers spec_noexcept;
extern CodeSpecifiers spec_override;
extern CodeSpecifiers spec_ptr;
extern CodeSpecifiers spec_pure;
extern CodeSpecifiers spec_ref;
extern CodeSpecifiers spec_register;
extern CodeSpecifiers spec_rvalue;
extern CodeSpecifiers spec_static_member;
extern CodeSpecifiers spec_thread_local;
extern CodeSpecifiers spec_virtual;
extern CodeSpecifiers spec_volatile;
extern CodeTypename t_empty; // Used with varaidc parameters. (Exposing just in case its useful for another circumstance)
extern CodeTypename t_auto;
extern CodeTypename t_void;
extern CodeTypename t_int;
extern CodeTypename t_bool;
extern CodeTypename t_char;
extern CodeTypename t_wchar_t;
extern CodeTypename t_class;
extern CodeTypename t_typename;
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
// Predefined typename codes. Are set to readonly and are setup during gen::init()
extern Context* _ctx;
extern CodeTypename t_b32;
extern CodeTypename t_s8;
extern CodeTypename t_s16;
extern CodeTypename t_s32;
extern CodeTypename t_s64;
extern CodeTypename t_u8;
extern CodeTypename t_u16;
extern CodeTypename t_u32;
extern CodeTypename t_u64;
extern CodeTypename t_ssize;
extern CodeTypename t_usize;
extern CodeTypename t_f32;
extern CodeTypename t_f64;
#endif
#pragma endregion Constants

View File

@ -15,7 +15,7 @@
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
| | | | | __} | |
| l_l l_l {___/ |
! ----------------------------------------------------------------------- VERSION: v0.23-Alpha |
! ----------------------------------------------------------------------- VERSION: v0.25-Alpha |
! ============================================================================================ |
! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION |
! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL |

View File

@ -1,8 +1,318 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "interface.hpp"
#endif
#pragma region Serialization
inline
StrBuilder attributes_to_strbuilder(CodeAttributes attributes) {
GEN_ASSERT(attributes);
char* raw = ccast(char*, str_duplicate( attributes->Content, get_context()->Allocator_Temp ).Ptr);
StrBuilder result = { raw };
return result;
}
inline
void attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result) {
GEN_ASSERT(attributes);
GEN_ASSERT(result);
strbuilder_append_str(result, attributes->Content);
}
inline
StrBuilder comment_to_strbuilder(CodeComment comment) {
GEN_ASSERT(comment);
char* raw = ccast(char*, str_duplicate( comment->Content, get_context()->Allocator_Temp ).Ptr);
StrBuilder result = { raw };
return result;
}
inline
void body_to_strbuilder_ref( CodeBody body, StrBuilder* result )
{
GEN_ASSERT(body != nullptr);
GEN_ASSERT(result != nullptr);
Code curr = body->Front;
s32 left = body->NumEntries;
while ( left -- )
{
code_to_strbuilder_ref(curr, result);
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
++curr;
}
}
inline
void comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result) {
GEN_ASSERT(comment);
GEN_ASSERT(result);
strbuilder_append_str(result, comment->Content);
}
inline
StrBuilder define_to_strbuilder(CodeDefine define)
{
GEN_ASSERT(define);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
define_to_strbuilder_ref(define, & result);
return result;
}
inline
StrBuilder define_params_to_strbuilder(CodeDefineParams params)
{
GEN_ASSERT(params);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
define_params_to_strbuilder_ref( params, & result );
return result;
}
inline
StrBuilder exec_to_strbuilder(CodeExec exec)
{
GEN_ASSERT(exec);
char* raw = ccast(char*, str_duplicate( exec->Content, _ctx->Allocator_Temp ).Ptr);
StrBuilder result = { raw };
return result;
}
inline
void exec_to_strbuilder_ref(CodeExec exec, StrBuilder* result) {
GEN_ASSERT(exec);
GEN_ASSERT(result);
strbuilder_append_str(result, exec->Content);
}
inline
void extern_to_strbuilder(CodeExtern self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->Body )
strbuilder_append_fmt( result, "extern \"%S\"\n{\n%SB\n}\n", self->Name, body_to_strbuilder(self->Body) );
else
strbuilder_append_fmt( result, "extern \"%S\"\n{}\n", self->Name );
}
inline
StrBuilder friend_to_strbuilder(CodeFriend self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
friend_to_strbuilder_ref( self, & result );
return result;
}
inline
void friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
strbuilder_append_fmt( result, "friend %SB", code_to_strbuilder(self->Declaration) );
if ( self->Declaration->Type != CT_Function && self->Declaration->Type != CT_Operator && (* result)[ strbuilder_length(* result) - 1 ] != ';' )
{
strbuilder_append_str( result, txt(";") );
}
if ( self->InlineCmt )
strbuilder_append_fmt( result, " %S", self->InlineCmt->Content );
else
strbuilder_append_str( result, txt("\n"));
}
inline
StrBuilder include_to_strbuilder(CodeInclude include)
{
GEN_ASSERT(include);
return strbuilder_fmt_buf( _ctx->Allocator_Temp, "#include %S\n", include->Content );
}
inline
void include_to_strbuilder_ref( CodeInclude include, StrBuilder* result )
{
GEN_ASSERT(include);
GEN_ASSERT(result);
strbuilder_append_fmt( result, "#include %S\n", include->Content );
}
inline
StrBuilder module_to_strbuilder(CodeModule self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 64 );
module_to_strbuilder_ref( self, & result );
return result;
}
inline
StrBuilder namespace_to_strbuilder(CodeNS self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
namespace_to_strbuilder_ref( self, & result );
return result;
}
inline
void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
strbuilder_append_fmt( result, "namespace %S\n{\n%SB\n}\n", self->Name, body_to_strbuilder(self->Body) );
}
inline
StrBuilder params_to_strbuilder(CodeParams self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
params_to_strbuilder_ref( self, & result );
return result;
}
inline
StrBuilder pragma_to_strbuilder(CodePragma self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
pragma_to_strbuilder_ref( self, & result );
return result;
}
inline
void pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
strbuilder_append_fmt( result, "#pragma %S\n", self->Content );
}
inline
void preprocess_to_strbuilder_if(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
GEN_ASSERT(result);
strbuilder_append_fmt( result, "#if %S", cond->Content );
}
inline
void preprocess_to_strbuilder_ifdef(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
GEN_ASSERT(result);
strbuilder_append_fmt( result, "#ifdef %S\n", cond->Content );
}
inline
void preprocess_to_strbuilder_ifndef(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
GEN_ASSERT(result);
strbuilder_append_fmt( result, "#ifndef %S", cond->Content );
}
inline
void preprocess_to_strbuilder_elif(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
GEN_ASSERT(result);
strbuilder_append_fmt( result, "#elif %S\n", cond->Content );
}
inline
void preprocess_to_strbuilder_else(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
GEN_ASSERT(result);
strbuilder_append_str( result, txt("#else\n") );
}
inline
void preprocess_to_strbuilder_endif(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
GEN_ASSERT(result);
strbuilder_append_str( result, txt("#endif\n") );
}
inline
StrBuilder specifiers_to_strbuilder(CodeSpecifiers self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 64 );
specifiers_to_strbuilder_ref( self, & result );
return result;
}
inline
StrBuilder template_to_strbuilder(CodeTemplate self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 1024 );
template_to_strbuilder_ref( self, & result );
return result;
}
inline
StrBuilder typedef_to_strbuilder(CodeTypedef self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
typedef_to_strbuilder_ref( self, & result );
return result;
}
inline
StrBuilder typename_to_strbuilder(CodeTypename self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_str( _ctx->Allocator_Temp, txt("") );
typename_to_strbuilder_ref( self, & result );
return result;
}
inline
StrBuilder using_to_strbuilder(CodeUsing self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
switch ( self->Type )
{
case CT_Using:
using_to_strbuilder_ref( self, & result );
break;
case CT_Using_Namespace:
using_to_strbuilder_ns( self, & result );
break;
}
return result;
}
inline
void using_to_strbuilder_ns(CodeUsing self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->InlineCmt )
strbuilder_append_fmt( result, "using namespace $S; %S", self->Name, self->InlineCmt->Content );
else
strbuilder_append_fmt( result, "using namespace %S;\n", self->Name );
}
inline
StrBuilder var_to_strbuilder(CodeVar self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( get_context()->Allocator_Temp, 256 );
var_to_strbuilder_ref( self, & result );
return result;
}
#pragma endregion Serialization
#pragma region Code
inline
void code_append( Code self, Code other )
@ -74,7 +384,7 @@ bool code_is_valid(Code self)
return self != nullptr && self->Type != CT_Invalid;
}
forceinline
bool code_has_entries(AST* self)
bool code_has_entries(Code self)
{
GEN_ASSERT(self);
return self->NumEntries > 0;
@ -169,12 +479,12 @@ void class_add_interface( CodeClass self, CodeTypename type )
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
}
while ( possible_slot != nullptr )
while ( possible_slot->Next != nullptr )
{
possible_slot = cast(CodeTypename, possible_slot->Next);
}
possible_slot = type;
possible_slot->Next = cast(Code, type);
}
#pragma endregion CodeClass
@ -296,7 +606,17 @@ bool specifiers_append(CodeSpecifiers self, Specifier spec )
return true;
}
inline
s32 specifiers_has(CodeSpecifiers self, Specifier spec)
bool specifiers_has(CodeSpecifiers self, Specifier spec)
{
GEN_ASSERT(self != nullptr);
for ( s32 idx = 0; idx < self->NumEntries; idx++ ) {
if ( self->ArrSpecs[ idx ] == spec )
return true;
}
return false;
}
inline
s32 specifiers_index_of(CodeSpecifiers self, Specifier spec)
{
GEN_ASSERT(self != nullptr);
for ( s32 idx = 0; idx < self->NumEntries; idx++ ) {
@ -378,12 +698,12 @@ void struct_add_interface(CodeStruct self, CodeTypename type )
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
}
while ( possible_slot != nullptr )
while ( possible_slot->Next != nullptr )
{
possible_slot = cast(CodeTypename, possible_slot->Next);
}
possible_slot = type;
possible_slot->Next = cast(Code, type);
}
#pragma endregion Code

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "code_serialization.cpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "ast_types.hpp"
#endif
@ -50,6 +50,7 @@ struct Context
// LoggerCallaback* log_callback; // TODO(Ed): Impl user logger callback as an option.
// Initalization config
u32 Max_CommentLineLength; // Used by def_comment
u32 Max_StrCacheLength; // Any cached string longer than this is always allocated again.
@ -98,6 +99,11 @@ struct Context
s32 temp_serialize_indent;
};
// TODO(Ed): Eventually this library should opt out of an implicit context for baseline implementation
// This would automatically make it viable for multi-threaded purposes among other things
// An implicit context interface will be provided instead as wrapper procedures as convience.
GEN_API extern Context* _ctx;
// Initialize the library. There first ctx initialized must exist for lifetime of other contextes that come after as its the one that
GEN_API void init(Context* ctx);
@ -155,6 +161,7 @@ struct Opts_def_struct {
CodeAttributes attributes;
CodeTypename* interfaces;
s32 num_interfaces;
CodeSpecifiers specifiers; // Only used for final specifier for now.
ModuleFlag mflags;
};
GEN_API CodeClass def_class( Str name, Opts_def_struct opts GEN_PARAM_DEFAULT );
@ -192,7 +199,7 @@ GEN_API CodeEnum def_enum( Str name, Opts_def_enum opts GEN_PARAM_DEFAULT );
GEN_API CodeExec def_execution ( Str content );
GEN_API CodeExtern def_extern_link( Str name, CodeBody body );
GEN_API CodeFriend def_friend ( Code symbol );
GEN_API CodeFriend def_friend ( Code code );
struct Opts_def_function {
CodeParams params;
@ -228,7 +235,7 @@ struct Opts_def_operator_cast {
GEN_API CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opts GEN_PARAM_DEFAULT );
struct Opts_def_param { Code value; };
GEN_API CodeParams def_param ( CodeTypename type, Str name, Opts_def_param opts GEN_PARAM_DEFAULT );
GEN_API CodeParams def_param ( CodeTypename type, Str name, Opts_def_param opts GEN_PARAM_DEFAULT );
GEN_API CodePragma def_pragma( Str directive );
GEN_API CodePreprocessCond def_preprocess_cond( EPreprocessCond type, Str content );
@ -242,7 +249,7 @@ GEN_API CodeTemplate def_template( CodeParams params, Code definition, Opts_def_
struct Opts_def_type {
ETypenameTag type_tag;
Code arrayexpr;
Code array_expr;
CodeSpecifiers specifiers;
CodeAttributes attributes;
};
@ -278,7 +285,7 @@ struct Opts_def_variable
GEN_API CodeVar def_variable( CodeTypename type, Str name, Opts_def_variable opts GEN_PARAM_DEFAULT );
// Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries.
GEN_API CodeBody def_body( CodeType type );
CodeBody def_body( CodeType type );
// There are two options for defining a struct body, either varadically provided with the args macro to auto-deduce the arg num,
/// or provide as an array of Code objects.
@ -386,7 +393,7 @@ GEN_API CodeVar parse_variable ( Str var_def );
GEN_API ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va );
//! Do not use directly. Use the token_fmt macro instead.
GEN_API Str token_fmt_impl( ssize, ... );
Str token_fmt_impl( ssize, ... );
GEN_API Code untyped_str( Str content);
GEN_API Code untyped_fmt ( char const* fmt, ... );

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "gen/etoktype.cpp"
#include "interface.upfront.cpp"
@ -39,7 +39,7 @@ CodeConstructor parse_constructor( Str def )
while ( left && tok_is_specifier(currtok) )
{
Specifier spec = str_to_specifier( tok_to_str(currtok) );
Specifier spec = str_to_specifier( currtok.Text );
b32 ignore_spec = false;

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "interface.parsing.cpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "interface.cpp"
#endif
@ -402,7 +402,7 @@ bool null__check( char const* context, char const* code_id, Code code ) {
#define null_check( context, code ) null__check( #context, #code, cast(Code, code) )
/*
The implementaiton of the upfront constructors involves doing three things:
The implementation of the upfront constructors involves doing three things:
* Validate the arguments given to construct the intended type of AST is valid.
* Construct said AST type.
* Lock the AST (set to readonly) and return the valid object.
@ -532,6 +532,7 @@ CodeClass def_class( Str name, Opts_def_struct p )
result->Name = cache_str( name );
result->ModuleFlags = p.mflags;
result->Attributes = p.attributes;
result->Specs = p.specifiers;
result->ParentAccess = p.parent_access;
result->ParentType = p.parent;
if ( p.body )
@ -1065,6 +1066,7 @@ CodeStruct def_struct( Str name, Opts_def_struct p )
result->Type = CT_Struct_Fwd;
}
result->Attributes = p.attributes;
result->Specs = p.specifiers;
result->ParentAccess = p.parent_access;
result->ParentType = p.parent;
@ -1112,7 +1114,7 @@ CodeTypename def_type( Str name, Opts_def_type p )
GEN_DEBUG_TRAP();
return InvalidCode;
}
Code arrayexpr = p.arrayexpr;
Code array_expr = p.array_expr;
CodeSpecifiers specifiers = p.specifiers;
CodeAttributes attributes = p.attributes;
if ( p.attributes && p.attributes->Type != CT_PlatformAttributes ) {
@ -1125,8 +1127,8 @@ CodeTypename def_type( Str name, Opts_def_type p )
GEN_DEBUG_TRAP();
return InvalidCode;
}
if ( p.arrayexpr && p.arrayexpr->Type != CT_Untyped ) {
log_failure( "gen::def_type: arrayexpr is not of untyped type - %s", code_debug_str((Code)p.arrayexpr) );
if ( p.array_expr && p.array_expr->Type != CT_Untyped ) {
log_failure( "gen::def_type: arrayexpr is not of untyped type - %s", code_debug_str((Code)p.array_expr) );
GEN_DEBUG_TRAP();
return InvalidCode;
}
@ -1136,7 +1138,7 @@ CodeTypename def_type( Str name, Opts_def_type p )
result->Type = CT_Typename;
result->Attributes = p.attributes;
result->Specs = p.specifiers;
result->ArrExpr = p.arrayexpr;
result->ArrExpr = p.array_expr;
result->TypeTag = p.type_tag;
return result;
}

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "interface.upfront.cpp"
#include "gen/etoktype.cpp"
@ -264,7 +264,6 @@ s32 lex_preprocessor_define( LexContext* ctx )
}
// TODO(Ed): We need to to attempt to recover from a lex failure?
forceinline
s32 lex_preprocessor_directive( LexContext* ctx )
{
char const* hash = ctx->scanner;
@ -281,7 +280,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
ctx->token.Text.Len++;
}
ctx->token.Type = str_to_toktype( tok_to_str(ctx->token) );
ctx->token.Type = str_to_toktype( ctx->token.Text );
bool is_preprocessor = ctx->token.Type >= Tok_Preprocess_Define && ctx->token.Type <= Tok_Preprocess_Pragma;
if ( ! is_preprocessor )
@ -480,7 +479,6 @@ s32 lex_preprocessor_directive( LexContext* ctx )
return Lex_Continue; // Skip found token, its all handled here.
}
forceinline
void lex_found_token( LexContext* ctx )
{
if ( ctx->token.Type != Tok_Invalid ) {
@ -488,7 +486,11 @@ void lex_found_token( LexContext* ctx )
return;
}
TokType type = str_to_toktype( tok_to_str(ctx->token) );
TokType type = str_to_toktype( ctx->token.Text );
if (type == Tok_Preprocess_Define || type == Tok_Preprocess_Include) {
ctx->token.Flags |= TF_Identifier;
}
if (type <= Tok_Access_Public && type >= Tok_Access_Private ) {
ctx->token.Flags |= TF_AccessSpecifier;
@ -550,6 +552,9 @@ void lex_found_token( LexContext* ctx )
if ( bitfield_is_set(MacroFlags, macro->Flags, MF_Allow_As_Attribute) ) {
ctx->token.Flags |= TF_Attribute;
}
if ( bitfield_is_set(MacroFlags, macro->Flags, MF_Allow_As_Specifier ) ) {
ctx->token.Flags |= TF_Specifier;
}
}
else
{

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "gen/etoktype.cpp"
#include "parser_case_macros.cpp"
@ -533,7 +533,7 @@ Code parse_array_decl()
untyped_tok.Text.Len = ( (sptr)prevtok.Text.Ptr + prevtok.Text.Len ) - (sptr)untyped_tok.Text.Ptr;
Code array_expr = untyped_str( tok_to_str(untyped_tok) );
Code array_expr = untyped_str( untyped_tok.Text );
// [ <Content>
if ( left == 0 )
@ -717,6 +717,13 @@ Code parse_class_struct( TokType which, bool inplace_def )
}
// <ModuleFlags> <class/struct> <Attributes> <Name>
CodeSpecifiers specifiers = NullCode;
if ( check(Tok_Spec_Final)) {
specifiers = def_specifier(Spec_Final);
eat(Tok_Spec_Final);
}
// <ModuleFlags> <class/struct> <Attributes> <Name> <final>
local_persist
char interface_arr_mem[ kilobytes(4) ] = {0};
Array(CodeTypename) interfaces; {
@ -728,55 +735,55 @@ Code parse_class_struct( TokType which, bool inplace_def )
if ( check( Tok_Assign_Classifer ) )
{
eat( Tok_Assign_Classifer );
// <ModuleFlags> <class/struct> <Attributes> <Name> :
// <ModuleFlags> <class/struct> <Attributes> <Name> <final> :
if ( tok_is_access_specifier(currtok) ) {
access = tok_to_access_specifier(currtok);
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier>
// <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier>
eat( currtok.Type );
}
Token parent_tok = parse_identifier(nullptr);
parent = def_type( tok_to_str(parent_tok) );
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Parent/Interface Name>
parent = def_type( parent_tok.Text );
// <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Parent/Interface Name>
while ( check(Tok_Comma) )
{
eat( Tok_Comma );
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>,
// <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>,
if ( tok_is_access_specifier(currtok) ) {
eat(currtok.Type);
}
Token interface_tok = parse_identifier(nullptr);
array_append( interfaces, def_type( tok_to_str(interface_tok) ) );
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ...
array_append( interfaces, def_type( interface_tok.Text ) );
// <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>, ...
}
}
if ( check( Tok_BraceCurly_Open ) ) {
body = parse_class_struct_body( which, name );
}
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ... { <Body> }
// <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>, ... { <Body> }
CodeComment inline_cmt = NullCode;
if ( ! inplace_def )
{
Token stmt_end = currtok;
eat( Tok_Statement_End );
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ... { <Body> };
// <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>, ... { <Body> };
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
inline_cmt = parse_comment();
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ... { <Body> }; <InlineCmt>
// <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>, ... { <Body> }; <InlineCmt>
}
if ( which == Tok_Decl_Class )
result = cast(Code, def_class( tok_to_str(name), def_assign( body, parent, access, attributes, interfaces, scast(s32, array_num(interfaces)), mflags ) ));
result = cast(Code, def_class( name.Text, def_assign( body, parent, access, attributes, interfaces, scast(s32, array_num(interfaces)), specifiers, mflags ) ));
else
result = cast(Code, def_struct( tok_to_str(name), def_assign( body, (CodeTypename)parent, access, attributes, interfaces, scast(s32, array_num(interfaces)), mflags ) ));
result = cast(Code, def_struct( name.Text, def_assign( body, (CodeTypename)parent, access, attributes, interfaces, scast(s32, array_num(interfaces)), specifiers, mflags ) ));
if ( inline_cmt )
result->InlineCmt = cast(Code, inline_cmt);
@ -947,10 +954,6 @@ CodeBody parse_class_struct_body( TokType which, Token name )
member = cast(Code, parse_simple_preprocess( Tok_Preprocess_Macro_Stmt ));
break;
}
case Tok_Preprocess_Macro_Expr: {
log_failure("Unbounded macro expression residing in class/struct body\n%S", parser_to_strbuilder(_ctx->parser));
return InvalidCode;
}
// case Tok_Preprocess_Macro:
// // <Macro>
@ -976,6 +979,15 @@ CodeBody parse_class_struct_body( TokType which, Token name )
break;
}
case Tok_Preprocess_Macro_Expr:
{
if ( ! tok_is_attribute(currtok))
{
log_failure("Unbounded macro expression residing in class/struct body\n%S", parser_to_strbuilder(_ctx->parser));
return InvalidCode;
}
}
//! Fallthrough intended
case Tok_Attribute_Open:
case Tok_Decl_GNU_Attribute:
case Tok_Decl_MSVC_Attribute:
@ -994,7 +1006,7 @@ CodeBody parse_class_struct_body( TokType which, Token name )
while ( left && tok_is_specifier(currtok) )
{
Specifier spec = str_to_specifier( tok_to_str(currtok) );
Specifier spec = str_to_specifier( currtok.Text );
b32 ignore_spec = false;
@ -1102,7 +1114,7 @@ CodeBody parse_class_struct_body( TokType which, Token name )
untyped_tok.Text.Len = ( (sptr)currtok.Text.Ptr + currtok.Text.Len ) - (sptr)untyped_tok.Text.Ptr;
eat( currtok.Type );
}
member = untyped_str( tok_to_str(untyped_tok) );
member = untyped_str( untyped_tok.Text );
// Something unknown
break;
}
@ -1130,7 +1142,7 @@ CodeComment parse_comment()
CodeComment
result = (CodeComment) make_code();
result->Type = CT_Comment;
result->Content = cache_str( tok_to_str(currtok_noskip) );
result->Content = cache_str( currtok_noskip.Text );
// result->Token = currtok_noskip;
eat( Tok_Comment );
@ -1143,27 +1155,44 @@ Code parse_complicated_definition( TokType which )
{
push_scope();
bool is_inplace = false;
b32 is_inplace = false;
b32 is_fn_def = false;
TokArray tokens = _ctx->parser.Tokens;
s32 idx = tokens.Idx;
s32 level = 0;
b32 had_def = false;
b32 had_paren = false;
for ( ; idx < array_num(tokens.Arr); idx++ )
{
if ( tokens.Arr[ idx ].Type == Tok_BraceCurly_Open )
level++;
if ( tokens.Arr[ idx ].Type == Tok_BraceCurly_Close )
if ( tokens.Arr[ idx ].Type == Tok_BraceCurly_Close ) {
level--;
had_def = level == 0;
}
if ( level == 0 && tokens.Arr[ idx ].Type == Tok_Statement_End )
b32 found_fn_def = had_def && had_paren;
if ( level == 0 && (tokens.Arr[ idx ].Type == Tok_Statement_End || found_fn_def) )
break;
}
is_fn_def = had_def && had_paren;
if (is_fn_def)
{
// Function definition with <which> on return type
Code result = parse_operator_function_or_variable(false, NullCode, NullCode);
// <which> <typename>(...) ... { ... }
parser_pop(& _ctx->parser);
return result;
}
if ( ( idx - 2 ) == tokens.Idx )
{
// Its a forward declaration only
// It's a forward declaration only
Code result = parse_forward_or_definition( which, is_inplace );
// <class, enum, struct, or union> <Name>;
parser_pop(& _ctx->parser);
@ -1171,13 +1200,13 @@ Code parse_complicated_definition( TokType which )
}
Token tok = tokens.Arr[ idx - 1 ];
if ( tok_is_specifier(tok) && spec_is_trailing( str_to_specifier( tok_to_str(tok))) )
if ( tok_is_specifier(tok) && spec_is_trailing( str_to_specifier( tok.Text)) )
{
// <which> <type_identifier>(...) <specifier> ...;
s32 spec_idx = idx - 1;
Token spec = tokens.Arr[spec_idx];
while ( tok_is_specifier(spec) && spec_is_trailing( str_to_specifier( tok_to_str(spec))) )
while ( tok_is_specifier(spec) && spec_is_trailing( str_to_specifier( spec.Text)) )
{
-- spec_idx;
spec = tokens.Arr[spec_idx];
@ -1207,9 +1236,19 @@ Code parse_complicated_definition( TokType which )
if ( tok.Type == Tok_BraceCurly_Close )
{
// Its an inplace definition
// <which> <type_identifier> { ... } <identifier>;
// <which> <type_identifier ?> { ... } <identifier>;
ok_to_parse = true;
is_inplace = true;
CodeTypename type = cast(CodeTypename, parse_forward_or_definition(which, is_inplace));
// Should be a name right after the type.
Token name = parse_identifier(nullptr);
_ctx->parser.Scope->Name = name.Text;
CodeVar result = parse_variable_after_name(ModuleFlag_None, NullCode, NullCode, type, name.Text);
parser_pop(& _ctx->parser);
return (Code) result;
}
else if ( tok.Type == Tok_Identifier && tokens.Arr[ idx - 3 ].Type == which )
{
@ -1326,8 +1365,10 @@ Code parse_assignment_expression()
eat( currtok.Type );
}
expr_tok.Text.Len = ( ( sptr )currtok.Text.Ptr + currtok.Text.Len ) - ( sptr )expr_tok.Text.Ptr - 1;
expr = untyped_str( tok_to_str(expr_tok) );
if (left) {
expr_tok.Text.Len = ( ( sptr )currtok.Text.Ptr + currtok.Text.Len ) - ( sptr )expr_tok.Text.Ptr - 1;
}
expr = untyped_str( expr_tok.Text );
// = <Expression>
return expr;
}
@ -1378,17 +1419,26 @@ CodeFn parse_function_after_name(
CodeParams params = parse_params(parser_use_parenthesis);
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Parameters> )
Code suffix_specs = NullCode;
// TODO(Ed), Review old comment : These have to be kept separate from the return type's specifiers.
while ( left && tok_is_specifier(currtok) )
{
// For Unreal's PURE_VIRTUAL Support
Macro* macro = lookup_macro( currtok.Text );
if (macro && tok_is_specifier(currtok))
{
suffix_specs = parse_simple_preprocess(Tok_Preprocess_Macro_Expr);
continue;
}
if ( specifiers == nullptr )
{
specifiers = def_specifier( str_to_specifier( tok_to_str(currtok)) );
specifiers = def_specifier( str_to_specifier( currtok.Text) );
eat( currtok.Type );
continue;
}
specifiers_append(specifiers, str_to_specifier( tok_to_str(currtok)) );
specifiers_append(specifiers, str_to_specifier( currtok.Text) );
eat( currtok.Type );
}
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers>
@ -1408,13 +1458,27 @@ CodeFn parse_function_after_name(
else if ( check(Tok_Operator) && currtok.Text.Ptr[0] == '=' )
{
eat(Tok_Operator);
specifiers_append(specifiers, Spec_Pure );
if ( specifiers == nullptr )
{
specifiers = (CodeSpecifiers) make_code();
specifiers->Type = CT_Specifiers;
}
if ( str_are_equal(nexttok.Text, txt("delete")))
{
specifiers_append(specifiers, Spec_Delete);
eat(currtok.Type);
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> = delete
}
else
{
specifiers_append(specifiers, Spec_Pure );
eat( Tok_Number);
eat( Tok_Number);
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> = 0
}
Token stmt_end = currtok;
eat( Tok_Statement_End );
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> = 0;
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
inline_cmt = parse_comment();
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers>; <InlineCmt>
@ -1431,7 +1495,7 @@ CodeFn parse_function_after_name(
}
StrBuilder
name_stripped = strbuilder_make_str( _ctx->Allocator_Temp, tok_to_str(name) );
name_stripped = strbuilder_make_str( _ctx->Allocator_Temp, name.Text );
strbuilder_strip_space(name_stripped);
CodeFn
@ -1469,6 +1533,9 @@ CodeFn parse_function_after_name(
if ( specifiers )
result->Specs = specifiers;
if ( suffix_specs )
result->SuffixSpecs = suffix_specs;
result->ReturnType = ret_type;
if ( params )
@ -1662,10 +1729,6 @@ CodeBody parse_global_nspace( CodeType which )
member = cast(Code, parse_simple_preprocess( Tok_Preprocess_Macro_Stmt ));
break;
}
case Tok_Preprocess_Macro_Expr: {
log_failure("Unbounded macro expression residing in class/struct body\n%S", parser_to_strbuilder(_ctx->parser));
return InvalidCode;
}
case Tok_Preprocess_Pragma: {
member = cast(Code, parse_pragma());
@ -1699,6 +1762,16 @@ CodeBody parse_global_nspace( CodeType which )
log_failure( "gen::%s: This function is not implemented" );
return InvalidCode;
}
break;
case Tok_Preprocess_Macro_Expr:
{
if (tok_is_attribute(currtok))
{
log_failure("Unbounded macro expression residing in class/struct body\n%S", parser_to_strbuilder(_ctx->parser));
return InvalidCode;
}
}
//! Fallthrough intentional
case Tok_Attribute_Open:
case Tok_Decl_GNU_Attribute:
@ -1718,7 +1791,7 @@ CodeBody parse_global_nspace( CodeType which )
while ( left && tok_is_specifier(currtok) )
{
Specifier spec = str_to_specifier( tok_to_str(currtok) );
Specifier spec = str_to_specifier( currtok.Text );
bool ignore_spec = false;
@ -1973,7 +2046,14 @@ Token parse_identifier( bool* possible_member_function )
Token name = currtok;
_ctx->parser.Scope->Name = name.Text;
eat( Tok_Identifier );
Macro* macro = lookup_macro(currtok.Text);
b32 accept_as_identifier = macro && bitfield_is_set(MacroFlags, macro->Flags, MF_Allow_As_Identifier );
// Typename can be: '::' <name>
// If that is the case first option will be Tok_Access_StaticSymbol below
if (check(Tok_Identifier) || accept_as_identifier)
eat( Tok_Identifier );
// <Name>
parse_template_args( & name );
@ -2059,7 +2139,7 @@ CodeInclude parse_include()
}
_ctx->parser.Scope->Name = currtok.Text;
include->Content = cache_str( tok_to_str(currtok) );
include->Content = cache_str( currtok.Text );
eat( Tok_String );
// #include <Path> or "Path"
@ -2384,15 +2464,34 @@ CodeOperator parse_operator_after_ret_type(
{
if ( specifiers == nullptr )
{
specifiers = def_specifier( str_to_specifier( tok_to_str(currtok)) );
specifiers = def_specifier( str_to_specifier( currtok.Text) );
eat( currtok.Type );
continue;
}
specifiers_append(specifiers, str_to_specifier( tok_to_str(currtok)) );
specifiers_append(specifiers, str_to_specifier( currtok.Text) );
eat( currtok.Type );
}
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers>
// TODO(Ed): Add proper "delete" and "new" awareness
// We're dealing with either a "= delete" or operator deletion
if (check(Tok_Operator) && currtok.Text.Ptr[0] == '=')
{
eat(currtok.Type);
if ( ! str_are_equal(currtok.Text, txt("delete")))
{
log_failure("Expected delete after = in operator forward instead found \"%S\"\n%SB", currtok.Text, parser_to_strbuilder(_ctx->parser));
parser_pop(& _ctx->parser);
return InvalidCode;
}
if (specifiers == nullptr)
specifiers = def_specifier( Spec_Delete );
else
specifiers_append(specifiers, Spec_Delete);
eat(currtok.Type);
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers> = delete
}
// Parse Body
CodeBody body = { nullptr };
@ -2419,7 +2518,7 @@ CodeOperator parse_operator_after_ret_type(
}
// OpValidateResult check_result = operator__validate( op, params, ret_type, specifiers );
CodeOperator result = def_operator( op, tok_to_str(nspace), def_assign( params, ret_type, body, specifiers, attributes, mflags ) );
CodeOperator result = def_operator( op, nspace.Text, def_assign( params, ret_type, body, specifiers, attributes, mflags ) );
if ( inline_cmt )
result->InlineCmt = inline_cmt;
@ -2444,6 +2543,24 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
CodeTypename type = parser_parse_type( parser_not_from_template, nullptr );
// <Attributes> <Specifiers> <ReturnType/ValueType>
// Thanks Unreal
CodeAttributes post_rt_attributes = parse_attributes();
if (post_rt_attributes)
{
if (attributes)
{
StrBuilder merged = strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S %S", attributes->Content, post_rt_attributes->Content);
attributes->Content = cache_str(strbuilder_to_str(merged));
}
else
{
attributes = post_rt_attributes;
}
// <Attributes> <Specifiers> <ReturnType/ValueType> <Attributes>
// CONVERTED TO:
// <Attributes> <Specifiers> <ReturnType/ValueType>
}
if ( type == InvalidCode ) {
parser_pop(& _ctx->parser);
return InvalidCode;
@ -2537,7 +2654,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
return InvalidCode;
}
// Dealing with a variable
result = cast(Code, parse_variable_after_name( ModuleFlag_None, attributes, specifiers, type, tok_to_str(name) ));
result = cast(Code, parse_variable_after_name( ModuleFlag_None, attributes, specifiers, type, name.Text ));
// <Attributes> <Specifiers> <ValueType> <Name> ...
}
}
@ -2595,7 +2712,7 @@ CodePragma parse_pragma()
_ctx->parser.Scope->Name = currtok.Text;
pragma->Content = cache_str( tok_to_str(currtok) );
pragma->Content = cache_str( currtok.Text );
eat( Tok_Preprocess_Content );
// #pragma <Content>
@ -2673,10 +2790,10 @@ CodeParams parse_params( bool use_template_capture )
}
// ( <Macro> <ValueType>
if ( check( Tok_Identifier ) )
if ( check( Tok_Identifier ) || bitfield_is_set(u32, currtok.Flags, TF_Identifier) )
{
name = currtok;
eat( Tok_Identifier );
eat( currtok.Type );
// ( <Macro> <ValueType> <Name>
}
@ -2691,10 +2808,8 @@ CodeParams parse_params( bool use_template_capture )
// ( <Macro> <ValueType> <Name> <PostNameMacro>
}
// In template captures you can have a typename have direct assignment without a name
// typename = typename ...
// Which would result in a static value type from a struct expansion (traditionally)
if ( ( name.Text.Ptr || use_template_capture ) && bitfield_is_set( u32, currtok.Flags, TF_Assign ) )
// C++ allows typename = expression... so anything goes....
if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ) )
{
eat( Tok_Operator );
// ( <Macro> <ValueType> <Name> =
@ -2729,7 +2844,7 @@ CodeParams parse_params( bool use_template_capture )
eat( currtok.Type );
}
value = untyped_str( strbuilder_to_str(parser_strip_formatting( tok_to_str(value_tok), parser_strip_formatting_dont_preserve_newlines )) );
value = untyped_str( strbuilder_to_str(parser_strip_formatting( value_tok.Text, parser_strip_formatting_dont_preserve_newlines )) );
// ( <Macro> <ValueType> <Name> = <Expression>
}
}
@ -2740,7 +2855,7 @@ CodeParams parse_params( bool use_template_capture )
result->Macro = macro;
if ( name.Text.Len > 0 )
result->Name = cache_str( tok_to_str(name) );
result->Name = cache_str( name.Text );
result->ValueType = type;
@ -2786,10 +2901,10 @@ CodeParams parse_params( bool use_template_capture )
name = NullToken;
if ( check( Tok_Identifier ) )
if ( check( Tok_Identifier ) || bitfield_is_set(u32, currtok.Flags, TF_Identifier) )
{
name = currtok;
eat( Tok_Identifier );
eat( currtok.Type );
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name>
}
@ -2802,10 +2917,8 @@ CodeParams parse_params( bool use_template_capture )
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <PostNameMacro>
}
// In template captures you can have a typename have direct assignment without a name
// typename = typename ...
// Which would result in a static value type from a struct expansion (traditionally)
if ( ( name.Text.Ptr || use_template_capture ) && bitfield_is_set( u32, currtok.Flags, TF_Assign ) )
/// C++ allows typename = expression... so anything goes....
if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ) )
{
eat( Tok_Operator );
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> <PostNameMacro> =
@ -2843,7 +2956,7 @@ CodeParams parse_params( bool use_template_capture )
eat( currtok.Type );
}
value = untyped_str( strbuilder_to_str(parser_strip_formatting( tok_to_str(value_tok), parser_strip_formatting_dont_preserve_newlines )) );
value = untyped_str( strbuilder_to_str(parser_strip_formatting( value_tok.Text, parser_strip_formatting_dont_preserve_newlines )) );
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> <PostNameMacro> = <Expression>
}
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> <PostNameMacro> = <Expression>, ..
@ -2855,7 +2968,7 @@ CodeParams parse_params( bool use_template_capture )
param->Macro = macro;
if ( name.Text.Len > 0 )
param->Name = cache_str( tok_to_str(name) );
param->Name = cache_str( name.Text );
param->PostNameMacro = post_name_macro;
param->ValueType = cast(CodeTypename, type);
@ -2912,7 +3025,7 @@ CodePreprocessCond parse_preprocess_cond()
}
_ctx->parser.Scope->Name = currtok.Text;
cond->Content = cache_str( tok_to_str(currtok) );
cond->Content = cache_str( currtok.Text );
eat( Tok_Preprocess_Content );
// #<Conditiona> <Content>
@ -3179,7 +3292,7 @@ CodeVar parse_variable_after_name(
eat( Tok_BraceCurly_Close );
expr_tok.Text.Len = ( (sptr)prevtok.Text.Ptr + prevtok.Text.Len ) - (sptr)expr_tok.Text.Ptr;
expr = untyped_str( tok_to_str(expr_tok) );
expr = untyped_str( expr_tok.Text );
// <Attributes> <Specifiers> <ValueType> <Name> = { <Expression> }
}
@ -3205,7 +3318,7 @@ CodeVar parse_variable_after_name(
}
expr_token.Text.Len = ( (sptr)prevtok.Text.Ptr + prevtok.Text.Len ) - (sptr)expr_token.Text.Ptr;
expr = untyped_str( tok_to_str(expr_token) );
expr = untyped_str( expr_token.Text );
eat( Tok_Paren_Close );
// <Attributes> <Specifiers> <ValueType> <Name> ( <Expression> )
}
@ -3228,7 +3341,7 @@ CodeVar parse_variable_after_name(
}
expr_tok.Text.Len = ( (sptr)prevtok.Text.Ptr + prevtok.Text.Len ) - (sptr)expr_tok.Text.Ptr;
bitfield_expr = untyped_str( tok_to_str(expr_tok) );
bitfield_expr = untyped_str( expr_tok.Text );
// <Attributes> <Specifiers> <ValueType> <Name> : <Expression>
}
@ -3309,7 +3422,7 @@ CodeVar parse_variable_declaration_list()
while ( left && tok_is_specifier(currtok) )
{
Specifier spec = str_to_specifier( tok_to_str(currtok) );
Specifier spec = str_to_specifier( currtok.Text );
switch ( spec )
{
@ -3333,7 +3446,7 @@ CodeVar parse_variable_declaration_list()
{
log_failure( "Error, invalid specifier '%S' proceeding comma\n"
"(Parser will add and continue to specifiers, but will most likely fail to compile)\n%S"
, tok_to_str(currtok), strbuilder_to_str( parser_to_strbuilder(_ctx->parser)) );
, currtok.Text, strbuilder_to_str( parser_to_strbuilder(_ctx->parser)) );
continue;
}
break;
@ -3348,7 +3461,7 @@ CodeVar parse_variable_declaration_list()
}
// , <Specifiers>
Str name = tok_to_str(currtok);
Str name = currtok.Text;
eat( Tok_Identifier );
// , <Specifiers> <Name>
@ -3417,7 +3530,7 @@ CodeConstructor parser_parse_constructor( CodeSpecifiers specifiers )
initializer_list_tok.Text.Len = ( ( sptr )prevtok.Text.Ptr + prevtok.Text.Len ) - ( sptr )initializer_list_tok.Text.Ptr;
// <Name> ( <Parameters> ) : <InitializerList>
initializer_list = untyped_str( tok_to_str(initializer_list_tok) );
initializer_list = untyped_str( initializer_list_tok.Text );
// TODO(Ed): Constructors can have post-fix specifiers
@ -3429,6 +3542,7 @@ CodeConstructor parser_parse_constructor( CodeSpecifiers specifiers )
body = cast(CodeBody, parse_function_body());
// <Name> ( <Parameters> ) { <Body> }
}
// TODO(Ed): Add support for detecting constructor deletion
else if ( check( Tok_Operator) && currtok.Text.Ptr[ 0 ] == '=' )
{
body = cast(CodeBody, parse_assignment_expression());
@ -3446,7 +3560,7 @@ CodeConstructor parser_parse_constructor( CodeSpecifiers specifiers )
CodeConstructor result = ( CodeConstructor )make_code();
result->Name = cache_str( tok_to_str(identifier));
result->Name = cache_str( identifier.Text );
result->Specs = specifiers;
@ -3492,7 +3606,7 @@ CodeDefine parser_parse_define()
return InvalidCode;
}
_ctx->parser.Scope->Name = currtok.Text;
define->Name = cache_str( tok_to_str(currtok) );
define->Name = cache_str( currtok.Text );
eat( Tok_Identifier );
// #define <Name>
@ -3550,7 +3664,7 @@ CodeDefine parser_parse_define()
return define;
}
define->Body = untyped_str( strbuilder_to_str( parser_strip_formatting( tok_to_str(currtok), parser_strip_formatting_dont_preserve_newlines )) );
define->Body = untyped_str( strbuilder_to_str( parser_strip_formatting( currtok.Text, parser_strip_formatting_dont_preserve_newlines )) );
eat( Tok_Preprocess_Content );
// #define <Name> ( <params> ) <Content>
@ -3650,7 +3764,7 @@ CodeDestructor parser_parse_destructor( CodeSpecifiers specifiers )
if ( tok_is_valid(prefix_identifier) ) {
prefix_identifier.Text.Len += 1 + identifier.Text.Len;
result->Name = cache_str( tok_to_str(prefix_identifier) );
result->Name = cache_str( prefix_identifier.Text );
}
if ( specifiers )
@ -3726,7 +3840,7 @@ CodeEnum parser_parse_enum( bool inplace_def )
else if ( currtok.Type == Tok_Preprocess_Macro_Expr )
{
// We'll support the enum_underlying macro
if ( str_contains( tok_to_str(currtok), enum_underlying_macro.Name) )
if ( str_contains( currtok.Text, enum_underlying_macro.Name) )
{
use_macro_underlying = true;
underlying_macro = parse_simple_preprocess( Tok_Preprocess_Macro_Expr );
@ -3761,7 +3875,7 @@ CodeEnum parser_parse_enum( bool inplace_def )
switch ( currtok_noskip.Type )
{
case Tok_NewLine:
member = untyped_str( tok_to_str(currtok_noskip) );
member = untyped_str( currtok_noskip.Text );
eat( Tok_NewLine );
break;
@ -3854,7 +3968,7 @@ CodeEnum parser_parse_enum( bool inplace_def )
Token prev = * lex_previous(_ctx->parser.Tokens, lex_dont_skip_formatting);
entry.Text.Len = ( (sptr)prev.Text.Ptr + prev.Text.Len ) - (sptr)entry.Text.Ptr;
member = untyped_str( tok_to_str(entry) );
member = untyped_str( entry.Text );
}
break;
}
@ -3898,7 +4012,7 @@ CodeEnum parser_parse_enum( bool inplace_def )
result->Type = is_enum_class ? CT_Enum_Class_Fwd : CT_Enum_Fwd;
}
result->Name = cache_str( tok_to_str(name) );
result->Name = cache_str( name.Text );
if ( attributes )
result->Attributes = attributes;
@ -3950,7 +4064,7 @@ CodeExtern parser_parse_extern_link()
CodeExtern
result = (CodeExtern) make_code();
result->Type = CT_Extern_Linkage;
result->Name = cache_str( tok_to_str(name) );
result->Name = cache_str( name.Text );
CodeBody entry = parser_parse_extern_link_body();
if ( cast(Code, entry) == Code_Invalid )
@ -3986,7 +4100,7 @@ CodeFriend parser_parse_friend()
while ( left && tok_is_specifier(currtok) )
{
Specifier spec = str_to_specifier( tok_to_str(currtok) );
Specifier spec = str_to_specifier( currtok.Text );
switch ( spec )
{
@ -4104,7 +4218,7 @@ CodeFn parser_parse_function()
while ( left && tok_is_specifier(currtok) )
{
Specifier spec = str_to_specifier( tok_to_str(currtok) );
Specifier spec = str_to_specifier( currtok.Text );
switch ( spec )
{
@ -4174,7 +4288,7 @@ CodeNS parser_parse_namespace()
CodeNS
result = (CodeNS) make_code();
result->Type = CT_Namespace;
result->Name = cache_str( tok_to_str(name) );
result->Name = cache_str( name.Text );
result->Body = body;
@ -4205,7 +4319,7 @@ CodeOperator parser_parse_operator()
while ( left && tok_is_specifier(currtok) )
{
Specifier spec = str_to_specifier( tok_to_str(currtok) );
Specifier spec = str_to_specifier( currtok.Text );
switch ( spec )
{
@ -4319,7 +4433,7 @@ CodeOpCast parser_parse_operator_cast( CodeSpecifiers specifiers )
eat( Tok_BraceCurly_Close );
// <Specifiers> <Qualifier> :: ... operator <UnderlyingType>() <const> { <Body> }
body = untyped_str( tok_to_str(body_str) );
body = untyped_str( body_str.Text );
}
else
{
@ -4335,7 +4449,7 @@ CodeOpCast parser_parse_operator_cast( CodeSpecifiers specifiers )
CodeOpCast result = (CodeOpCast) make_code();
if ( tok_is_valid(name) )
result->Name = cache_str( tok_to_str(name) );
result->Name = cache_str( name.Text );
if (body) {
result->Type = CT_Operator_Cast;
@ -4438,7 +4552,7 @@ CodeTemplate parser_parse_template()
{
while ( left && tok_is_specifier(currtok) )
{
Specifier spec = str_to_specifier( tok_to_str(currtok) );
Specifier spec = str_to_specifier( currtok.Text );
switch ( spec )
{
@ -4568,10 +4682,10 @@ CodeTypename parser_parse_type( bool from_template, bool* typedef_is_function )
// Prefix specifiers
while ( left && tok_is_specifier(currtok) )
{
Specifier spec = str_to_specifier( tok_to_str(currtok) );
Specifier spec = str_to_specifier( currtok.Text );
if ( spec != Spec_Const ) {
log_failure( "Error, invalid specifier used in type definition: %S\n%SB", tok_to_str(currtok), parser_to_strbuilder(_ctx->parser) );
log_failure( "Error, invalid specifier used in type definition: %S\n%SB", currtok.Text, parser_to_strbuilder(_ctx->parser) );
parser_pop(& _ctx->parser);
return InvalidCode;
}
@ -4619,7 +4733,7 @@ CodeTypename parser_parse_type( bool from_template, bool* typedef_is_function )
// <Attributes> <Specifiers> <class, enum, struct, union> <Name>
}
// Decltype draft implementaiton
// Decltype draft implementation
#if 0
else if ( currtok.Type == Tok_DeclType )
{
@ -4707,15 +4821,18 @@ else if ( currtok.Type == Tok_DeclType )
// Suffix specifiers for typename.
while ( left && tok_is_specifier(currtok) )
{
Specifier spec = str_to_specifier( tok_to_str(currtok) );
Specifier spec = str_to_specifier( currtok.Text );
if ( spec != Spec_Const && spec != Spec_Ptr && spec != Spec_Ref && spec != Spec_RValue )
{
log_failure( "Error, invalid specifier used in type definition: %S\n%SB", tok_to_str(currtok), parser_to_strbuilder(_ctx->parser) );
parser_pop(& _ctx->parser);
return InvalidCode;
switch (spec ) {
GEN_PARSER_TYPENAME_ALLOWED_SUFFIX_SPECIFIER_CASES:
break;
default: {
log_failure( "Error, invalid specifier used in type definition: %S\n%SB", currtok.Text, parser_to_strbuilder(_ctx->parser) );
parser_pop(& _ctx->parser);
return InvalidCode;
}
}
specs_found[ NumSpecifiers ] = spec;
NumSpecifiers++;
eat( currtok.Type );
@ -4793,7 +4910,7 @@ else if ( currtok.Type == Tok_DeclType )
// StrBuilder
// name_stripped = StrBuilder::make( FallbackAllocator, name );
// name_stripped.strip_space();
return_type->Name = cache_str( tok_to_str(name) );
return_type->Name = cache_str( name.Text );
#ifdef GEN_USE_NEW_TYPENAME_PARSING
if ( specifiers )
@ -4906,14 +5023,14 @@ else if ( currtok.Type == Tok_DeclType )
// Look for suffix specifiers for the function
while ( left && tok_is_specifier(currtok) )
{
Specifier spec = str_to_specifier( tok_to_str(currtok) );
Specifier spec = str_to_specifier( currtok.Text );
if ( spec != Spec_Const
// TODO : Add support for NoExcept, l-value, volatile, l-value, etc
// && spec != Spec_NoExcept
&& spec != Spec_RValue )
{
log_failure( "Error, invalid specifier used in type definition: %S\n%S", tok_to_str(currtok), strbuilder_to_str( parser_to_strbuilder(_ctx->parser)) );
log_failure( "Error, invalid specifier used in type definition: %S\n%S", currtok.Text, strbuilder_to_str( parser_to_strbuilder(_ctx->parser)) );
parser_pop(& _ctx->parser);
return InvalidCode;
}
@ -4947,7 +5064,7 @@ else if ( currtok.Type == Tok_DeclType )
// result->Token = _ctx->parser.Scope->Start;
// Need to wait until were using the new parsing method to do this.
StrBuilder name_stripped = parser_strip_formatting( tok_to_str(name), parser_strip_formatting_dont_preserve_newlines );
StrBuilder name_stripped = parser_strip_formatting( name.Text, parser_strip_formatting_dont_preserve_newlines );
// name_stripped.strip_space();
@ -5206,7 +5323,7 @@ CodeTypedef parser_parse_typedef()
}
else
{
result->Name = cache_str( tok_to_str(name) );
result->Name = cache_str( name.Text );
result->IsFunction = false;
}
@ -5250,7 +5367,7 @@ CodeUnion parser_parse_union( bool inplace_def )
Str name = { nullptr, 0 };
if ( check( Tok_Identifier ) )
{
name = tok_to_str(currtok);
name = currtok.Text;
_ctx->parser.Scope->Name = currtok.Text;
eat( Tok_Identifier );
}
@ -5413,7 +5530,10 @@ CodeUsing parser_parse_using()
if ( ! is_namespace )
{
if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ) )
attributes = parse_attributes();
// <ModuleFlags> using <Name> <Attributes>
if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ))
{
attributes = parse_attributes();
// <ModuleFlags> using <Name> <Attributes>
@ -5441,7 +5561,7 @@ CodeUsing parser_parse_using()
CodeUsing
result = (CodeUsing) make_code();
result->Name = cache_str( tok_to_str(name) );
result->Name = cache_str( name.Text );
result->ModuleFlags = mflags;
if ( is_namespace)
@ -5492,7 +5612,7 @@ CodeVar parser_parse_variable()
while ( left && tok_is_specifier(currtok) )
{
Specifier spec = str_to_specifier( tok_to_str(currtok) );
Specifier spec = str_to_specifier( currtok.Text );
switch ( spec )
{
GEN_PARSER_VARIABLE_ALLOWED_SPECIFIER_CASES:
@ -5518,13 +5638,6 @@ CodeVar parser_parse_variable()
}
// <ModuleFlags> <Attributes> <Specifiers>
// Note(Ed): We're enforcing that using this codepath requires non-macro jank.
// Code macro_stmt = parse_macro_as_definiton(attributes, specifiers);
// if (macro_stmt) {
// parser_pop(& _ctx->parser);
// return macro_stmt;
// }
CodeTypename type = parser_parse_type(parser_not_from_template, nullptr);
// <ModuleFlags> <Attributes> <Specifiers> <ValueType>

View File

@ -97,9 +97,16 @@ case Spec_Global: \
case Spec_Inline: \
case Spec_Local_Persist: \
case Spec_Mutable: \
case Spec_Restrict: \
case Spec_Static: \
case Spec_Thread_Local: \
case Spec_Volatile
#define GEN_PARSER_TYPENAME_ALLOWED_SUFFIX_SPECIFIER_CASES \
case Spec_Const: \
case Spec_Ptr: \
case Spec_Restrict: \
case Spec_Ref: \
case Spec_RValue

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "types.hpp"
#include "gen/ecode.hpp"
@ -11,17 +11,18 @@ enum TokFlags : u32
{
TF_Operator = bit(0),
TF_Assign = bit(1),
TF_Preprocess = bit(2),
TF_Preprocess_Cond = bit(3),
TF_Attribute = bit(6),
TF_AccessOperator = bit(7),
TF_AccessSpecifier = bit(8),
TF_Specifier = bit(9),
TF_EndDefinition = bit(10), // Either ; or }
TF_Formatting = bit(11),
TF_Literal = bit(12),
TF_Macro_Functional = bit(13),
TF_Macro_Expects_Body = bit(14),
TF_Identifier = bit(2),
TF_Preprocess = bit(3),
TF_Preprocess_Cond = bit(4),
TF_Attribute = bit(5),
TF_AccessOperator = bit(6),
TF_AccessSpecifier = bit(7),
TF_Specifier = bit(8),
TF_EndDefinition = bit(9), // Either ; or }
TF_Formatting = bit(10),
TF_Literal = bit(11),
TF_Macro_Functional = bit(12),
TF_Macro_Expects_Body = bit(13),
TF_Null = 0,
TF_UnderlyingType = GEN_U32_MAX,
@ -43,11 +44,6 @@ AccessSpec tok_to_access_specifier(Token tok) {
return scast(AccessSpec, tok.Type);
}
forceinline
Str tok_to_str(Token tok) {
return tok.Text;
}
forceinline
bool tok_is_valid( Token tok ) {
return tok.Text.Ptr && tok.Text.Len && tok.Type != Tok_Invalid;
@ -183,14 +179,16 @@ enum EMacroFlags : u16
// ^^^ This a kludge because unreal has a macro that behaves as both a 'statement' and an attribute (UE_DEPRECATED, PRAGMA_ENABLE_DEPRECATION_WARNINGS, etc)
// TODO(Ed): We can keep the MF_Allow_As_Attribute flag for macros, however, we need to add the ability of AST_Attributes to chain themselves.
// Its thats already a thing in the standard language anyway
// & it would allow UE_DEPRECATED, (UE_PROPERTY / UE_FUNCTION) to chain themselves as attributes of a resolved member function/varaible definition
// & it would allow UE_DEPRECATED, (UE_PROPERTY / UE_FUNCTION) to chain themselves as attributes of a resolved member function/variable definition
MF_Allow_As_Attribute = bit(3),
// When a macro is encountered after attributs and specifiers while parsing a function, or variable:
// When a macro is encountered after attributes and specifiers while parsing a function, or variable:
// It will consume the macro and treat it as resolving the definition. (Yes this is for Unreal Engine)
// (MUST BE OF MT_Statement TYPE)
MF_Allow_As_Definition = bit(4),
MF_Allow_As_Specifier = bit(5), // Created for Unreal's PURE_VIRTUAL
MF_Null = 0,
MF_UnderlyingType = GEN_U16_MAX,
};

View File

@ -1,90 +1,90 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "../gen.hpp"
#endif
#pragma region StaticData
global Context* _ctx;
global u32 context_counter;
GEN_API global Context* _ctx;
GEN_API global u32 context_counter;
#pragma region Constants
global Macro enum_underlying_macro;
GEN_API global Macro enum_underlying_macro;
global Code Code_Global;
global Code Code_Invalid;
GEN_API global Code Code_Global;
GEN_API global Code Code_Invalid;
global Code access_public;
global Code access_protected;
global Code access_private;
GEN_API global Code access_public;
GEN_API global Code access_protected;
GEN_API global Code access_private;
global CodeAttributes attrib_api_export;
global CodeAttributes attrib_api_import;
GEN_API global CodeAttributes attrib_api_export;
GEN_API global CodeAttributes attrib_api_import;
global Code module_global_fragment;
global Code module_private_fragment;
GEN_API global Code module_global_fragment;
GEN_API global Code module_private_fragment;
global Code fmt_newline;
GEN_API global Code fmt_newline;
global CodeParams param_varadic;
GEN_API global CodeParams param_varadic;
global CodePragma pragma_once;
GEN_API global CodePragma pragma_once;
global CodePreprocessCond preprocess_else;
global CodePreprocessCond preprocess_endif;
GEN_API global CodePreprocessCond preprocess_else;
GEN_API global CodePreprocessCond preprocess_endif;
global CodeSpecifiers spec_const;
global CodeSpecifiers spec_consteval;
global CodeSpecifiers spec_constexpr;
global CodeSpecifiers spec_constinit;
global CodeSpecifiers spec_extern_linkage;
global CodeSpecifiers spec_final;
global CodeSpecifiers spec_forceinline;
global CodeSpecifiers spec_global;
global CodeSpecifiers spec_inline;
global CodeSpecifiers spec_internal_linkage;
global CodeSpecifiers spec_local_persist;
global CodeSpecifiers spec_mutable;
global CodeSpecifiers spec_noexcept;
global CodeSpecifiers spec_neverinline;
global CodeSpecifiers spec_override;
global CodeSpecifiers spec_ptr;
global CodeSpecifiers spec_pure;
global CodeSpecifiers spec_ref;
global CodeSpecifiers spec_register;
global CodeSpecifiers spec_rvalue;
global CodeSpecifiers spec_static_member;
global CodeSpecifiers spec_thread_local;
global CodeSpecifiers spec_virtual;
global CodeSpecifiers spec_volatile;
GEN_API global CodeSpecifiers spec_const;
GEN_API global CodeSpecifiers spec_consteval;
GEN_API global CodeSpecifiers spec_constexpr;
GEN_API global CodeSpecifiers spec_constinit;
GEN_API global CodeSpecifiers spec_extern_linkage;
GEN_API global CodeSpecifiers spec_final;
GEN_API global CodeSpecifiers spec_forceinline;
GEN_API global CodeSpecifiers spec_global;
GEN_API global CodeSpecifiers spec_inline;
GEN_API global CodeSpecifiers spec_internal_linkage;
GEN_API global CodeSpecifiers spec_local_persist;
GEN_API global CodeSpecifiers spec_mutable;
GEN_API global CodeSpecifiers spec_noexcept;
GEN_API global CodeSpecifiers spec_neverinline;
GEN_API global CodeSpecifiers spec_override;
GEN_API global CodeSpecifiers spec_ptr;
GEN_API global CodeSpecifiers spec_pure;
GEN_API global CodeSpecifiers spec_ref;
GEN_API global CodeSpecifiers spec_register;
GEN_API global CodeSpecifiers spec_rvalue;
GEN_API global CodeSpecifiers spec_static_member;
GEN_API global CodeSpecifiers spec_thread_local;
GEN_API global CodeSpecifiers spec_virtual;
GEN_API global CodeSpecifiers spec_volatile;
global CodeTypename t_empty;
global CodeTypename t_auto;
global CodeTypename t_void;
global CodeTypename t_int;
global CodeTypename t_bool;
global CodeTypename t_char;
global CodeTypename t_wchar_t;
global CodeTypename t_class;
global CodeTypename t_typename;
GEN_API global CodeTypename t_empty;
GEN_API global CodeTypename t_auto;
GEN_API global CodeTypename t_void;
GEN_API global CodeTypename t_int;
GEN_API global CodeTypename t_bool;
GEN_API global CodeTypename t_char;
GEN_API global CodeTypename t_wchar_t;
GEN_API global CodeTypename t_class;
GEN_API global CodeTypename t_typename;
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
global CodeTypename t_b32;
GEN_API global CodeTypename t_b32;
global CodeTypename t_s8;
global CodeTypename t_s16;
global CodeTypename t_s32;
global CodeTypename t_s64;
GEN_API global CodeTypename t_s8;
GEN_API global CodeTypename t_s16;
GEN_API global CodeTypename t_s32;
GEN_API global CodeTypename t_s64;
global CodeTypename t_u8;
global CodeTypename t_u16;
global CodeTypename t_u32;
global CodeTypename t_u64;
GEN_API global CodeTypename t_u8;
GEN_API global CodeTypename t_u16;
GEN_API global CodeTypename t_u32;
GEN_API global CodeTypename t_u64;
global CodeTypename t_ssize;
global CodeTypename t_usize;
GEN_API global CodeTypename t_ssize;
GEN_API global CodeTypename t_usize;
global CodeTypename t_f32;
global CodeTypename t_f64;
GEN_API global CodeTypename t_f32;
GEN_API global CodeTypename t_f64;
#endif
#pragma endregion Constants

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "header_start.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "macros.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "printing.hpp"
#endif
@ -309,6 +309,7 @@ ArrayHeader* array_get_header(Array<Type> array) {
using NonConstType = TRemoveConst<Type>;
return rcast(ArrayHeader*, const_cast<NonConstType*>(Data)) - 1;
}
template<class Type> forceinline
bool array_grow(Array<Type>* array, usize min_capacity)
{
@ -415,7 +416,7 @@ bool array_set_capacity(Array<Type>* array, usize new_capacity)
// These are intended for use in the base library of gencpp and the C-variant of the library
// It provides a interoperability between the C++ and C implementation of arrays. (not letting these do any crazy substiution though)
// They are undefined in gen.hpp and gen.cpp at the end of the files.
// We cpp library expects the user to use the regular calls as they can resolve the type fine.
// The cpp library expects the user to use the regular calls as they can resolve the type fine.
#define array_init(type, allocator) array_init <type> (allocator )
#define array_init_reserve(type, allocator, cap) array_init_reserve <type> (allocator, cap)

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "src_start.cpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "dependencies/platform.hpp"
# include "dependencies/macros.hpp"
@ -67,8 +67,8 @@
while (0)
#endif
void assert_handler( char const* condition, char const* file, char const* function, s32 line, char const* msg, ... );
s32 assert_crash( char const* condition );
void process_exit( u32 code );
GEN_API void assert_handler( char const* condition, char const* file, char const* function, s32 line, char const* msg, ... );
GEN_API s32 assert_crash( char const* condition );
GEN_API void process_exit( u32 code );
#pragma endregion Debug

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "strings.cpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "strings.hpp"
#endif
@ -121,20 +121,20 @@ enum FileStandardType
* @param std Check zpl_file_standard_type
* @return File handle to standard I/O
*/
FileInfo* file_get_standard( FileStandardType std );
GEN_API FileInfo* file_get_standard( FileStandardType std );
/**
* Closes the file
* @param file
*/
FileError file_close( FileInfo* file );
GEN_API FileError file_close( FileInfo* file );
/**
* Returns the currently opened file's name
* @param file
*/
inline
char const* file_name( FileInfo* file )
char const* file_name( FileInfo* file )
{
return file->filename ? file->filename : "";
}
@ -144,7 +144,7 @@ inline
* @param file
* @param filename
*/
FileError file_open( FileInfo* file, char const* filename );
GEN_API FileError file_open( FileInfo* file, char const* filename );
/**
* Opens a file using a specified mode
@ -152,7 +152,7 @@ FileError file_open( FileInfo* file, char const* filename );
* @param mode Access mode to use
* @param filename
*/
FileError file_open_mode( FileInfo* file, FileMode mode, char const* filename );
GEN_API FileError file_open_mode( FileInfo* file, FileMode mode, char const* filename );
/**
* Reads from a file
@ -200,14 +200,14 @@ constexpr b32 file_no_zero_terminate = false;
* @param filepath Path to the file
* @return File contents data
*/
FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const* filepath );
GEN_API FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const* filepath );
/**
* Returns a size of the file
* @param file
* @return File size
*/
s64 file_size( FileInfo* file );
GEN_API s64 file_size( FileInfo* file );
/**
* Seeks the file cursor from the beginning of file to a specific position
@ -274,7 +274,7 @@ enum FileStreamFlags : u32
* @param file
* @param allocator
*/
b8 file_stream_new( FileInfo* file, AllocatorInfo allocator );
GEN_API b8 file_stream_new( FileInfo* file, AllocatorInfo allocator );
/**
* Opens a memory stream over an existing buffer
@ -284,14 +284,14 @@ b8 file_stream_new( FileInfo* file, AllocatorInfo allocator );
* @param size Buffer's size
* @param flags
*/
b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize size, FileStreamFlags flags );
GEN_API b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize size, FileStreamFlags flags );
/**
* Retrieves the stream's underlying buffer and buffer size.
* @param file memory stream
* @param size (Optional) buffer size
*/
u8* file_stream_buf( FileInfo* file, ssize* size );
GEN_API u8* file_stream_buf( FileInfo* file, ssize* size );
extern FileOperations const memory_file_operations;

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "memory.cpp"
#endif

View File

@ -1,11 +1,11 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "containers.hpp"
#endif
#pragma region Hashing
u32 crc32( void const* data, ssize len );
u64 crc64( void const* data, ssize len );
GEN_API u32 crc32( void const* data, ssize len );
GEN_API u64 crc64( void const* data, ssize len );
#pragma endregion Hashing

View File

@ -1,10 +1,11 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "platform.hpp"
#endif
#pragma region Macros
#ifndef GEN_API
#if GEN_COMPILER_MSVC
#ifdef GEN_DYN_LINK
#ifdef GEN_DYN_EXPORT
@ -22,9 +23,14 @@
#define GEN_API // Empty for static builds
#endif
#endif
#endif // GEN_API
#ifndef global
#define global static // Global variables
#ifndef global // Global variables
# if defined(GEN_STATIC_LINK) || defined(GEN_DYN_LINK)
# define global
# else
# define global static
# endif
#endif
#ifndef internal
#define internal static // Internal linkage
@ -35,6 +41,9 @@
#ifndef bit
#define bit( Value ) ( 1 << Value )
#endif
#ifndef bitfield_is_set
#define bitfield_is_set( Type, Field, Mask ) ( (scast(Type, Mask) & scast(Type, Field)) == scast(Type, Mask) )
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "printing.cpp"
#endif
@ -84,13 +84,13 @@ void heap_stats_check( void )
typedef struct _heap_alloc_info _heap_alloc_info;
struct _heap_alloc_info
{
ssize size;
ssize size;
void* physical_start;
};
void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
{
void* ptr = NULL;
void* ptr = nullptr;
// unused( allocator_data );
// unused( old_size );
if ( ! alignment )

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "debug.hpp"
#endif
@ -41,10 +41,10 @@ void const* pointer_add_const( void const* ptr, ssize bytes );
ssize pointer_diff( void const* begin, void const* end );
//! Copy non-overlapping memory from source to destination.
void* mem_copy( void* dest, void const* source, ssize size );
GEN_API void* mem_copy( void* dest, void const* source, ssize size );
//! Search for a constant value within the size limit at memory location.
void const* mem_find( void const* data, u8 byte_value, ssize size );
GEN_API void const* mem_find( void const* data, u8 byte_value, ssize size );
//! Copy memory from source to destination.
void* mem_move( void* dest, void const* source, ssize size );
@ -119,17 +119,17 @@ void* resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size,
/* define GEN_HEAP_ANALYSIS to enable this feature */
/* call zpl_heap_stats_init at the beginning of the entry point */
/* you can call zpl_heap_stats_check near the end of the execution to validate any possible leaks */
void heap_stats_init( void );
ssize heap_stats_used_memory( void );
ssize heap_stats_alloc_count( void );
void heap_stats_check( void );
GEN_API void heap_stats_init( void );
GEN_API ssize heap_stats_used_memory( void );
GEN_API ssize heap_stats_alloc_count( void );
GEN_API void heap_stats_check( void );
//! Allocate/Resize memory using default options.
//! Use this if you don't need a "fancy" resize allocation
void* default_resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size, ssize alignment );
void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
GEN_API void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
//! The heap allocator backed by operating system's memory manager.
constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; }
@ -147,25 +147,25 @@ struct VirtualMemory
};
//! Initialize virtual memory from existing data.
VirtualMemory vm_from_memory( void* data, ssize size );
GEN_API VirtualMemory vm_from_memory( void* data, ssize size );
//! Allocate virtual memory at address with size.
//! @param addr The starting address of the region to reserve. If NULL, it lets operating system to decide where to allocate it.
//! @param size The size to serve.
VirtualMemory vm_alloc( void* addr, ssize size );
GEN_API VirtualMemory vm_alloc( void* addr, ssize size );
//! Release the virtual memory.
b32 vm_free( VirtualMemory vm );
GEN_API b32 vm_free( VirtualMemory vm );
//! Trim virtual memory.
VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size );
GEN_API VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size );
//! Purge virtual memory.
b32 vm_purge( VirtualMemory vm );
GEN_API b32 vm_purge( VirtualMemory vm );
//! Retrieve VM's page size and alignment.
ssize virtual_memory_page_size( ssize* alignment_out );
GEN_API ssize virtual_memory_page_size( ssize* alignment_out );
#pragma region Arena
struct Arena;
@ -173,7 +173,7 @@ struct Arena;
AllocatorInfo arena_allocator_info( Arena* arena );
// Remove static keyword and rename allocator_proc
void* arena_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags);
GEN_API void* arena_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags);
// Add these declarations after the Arena struct
Arena arena_init_from_allocator(AllocatorInfo backing, ssize size);
@ -382,13 +382,13 @@ using FixedArena_4MB = FixedArena< megabytes( 4 ) >;
#pragma region Pool
struct Pool;
void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags);
GEN_API void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags);
Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size);
Pool pool_init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align);
AllocatorInfo pool_allocator_info(Pool* pool);
void pool_clear(Pool* pool);
void pool_free(Pool* pool);
Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size);
Pool pool_init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align);
AllocatorInfo pool_allocator_info(Pool* pool);
GEN_API void pool_clear(Pool* pool);
void pool_free(Pool* pool);
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
forceinline AllocatorInfo allocator_info(Pool& pool) { return pool_allocator_info(& pool); }

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "parsing.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "timing.hpp"
#endif
@ -122,7 +122,7 @@ struct ADT_Node
* @param is_array
* @return error code
*/
u8 adt_make_branch( ADT_Node* node, AllocatorInfo backing, char const* name, b32 is_array );
GEN_API u8 adt_make_branch( ADT_Node* node, AllocatorInfo backing, char const* name, b32 is_array );
/**
* @brief Destroy an ADT branch and its descendants
@ -130,7 +130,7 @@ u8 adt_make_branch( ADT_Node* node, AllocatorInfo backing, char const* name, b32
* @param node
* @return error code
*/
u8 adt_destroy_branch( ADT_Node* node );
GEN_API u8 adt_destroy_branch( ADT_Node* node );
/**
* @brief Initialise an ADT leaf
@ -140,7 +140,7 @@ u8 adt_destroy_branch( ADT_Node* node );
* @param type Node's type (use zpl_adt_make_branch for container nodes)
* @return error code
*/
u8 adt_make_leaf( ADT_Node* node, char const* name, ADT_Type type );
GEN_API u8 adt_make_leaf( ADT_Node* node, char const* name, ADT_Type type );
/**
@ -160,7 +160,7 @@ u8 adt_make_leaf( ADT_Node* node, char const* name, ADT_Type type );
*
* @see code/apps/examples/json_get.c
*/
ADT_Node* adt_query( ADT_Node* node, char const* uri );
GEN_API ADT_Node* adt_query( ADT_Node* node, char const* uri );
/**
* @brief Find a field node within an object by the given name.
@ -170,7 +170,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri );
* @param deep_search Perform search recursively
* @return zpl_adt_node * node
*/
ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search );
GEN_API ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search );
/**
* @brief Allocate an unitialised node within a container at a specified index.
@ -179,7 +179,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search );
* @param index
* @return zpl_adt_node * node
*/
ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index );
GEN_API ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index );
/**
* @brief Allocate an unitialised node within a container.
@ -187,7 +187,7 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index );
* @param parent
* @return zpl_adt_node * node
*/
ADT_Node* adt_alloc( ADT_Node* parent );
GEN_API ADT_Node* adt_alloc( ADT_Node* parent );
/**
* @brief Move an existing node to a new container at a specified index.
@ -197,7 +197,7 @@ ADT_Node* adt_alloc( ADT_Node* parent );
* @param index
* @return zpl_adt_node * node
*/
ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index );
GEN_API ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index );
/**
* @brief Move an existing node to a new container.
@ -206,7 +206,7 @@ ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index );
* @param new_parent
* @return zpl_adt_node * node
*/
ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent );
GEN_API ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent );
/**
* @brief Swap two nodes.
@ -215,7 +215,7 @@ ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent );
* @param other_node
* @return
*/
void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node );
GEN_API void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node );
/**
* @brief Remove node from container.
@ -223,7 +223,7 @@ void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node );
* @param node
* @return
*/
void adt_remove_node( ADT_Node* node );
GEN_API void adt_remove_node( ADT_Node* node );
/**
* @brief Initialise a node as an object
@ -233,7 +233,7 @@ void adt_remove_node( ADT_Node* node );
* @param backing
* @return
*/
b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing );
GEN_API b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing );
/**
* @brief Initialise a node as an array
@ -243,7 +243,7 @@ b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing );
* @param backing
* @return
*/
b8 adt_set_arr( ADT_Node* obj, char const* name, AllocatorInfo backing );
GEN_API b8 adt_set_arr( ADT_Node* obj, char const* name, AllocatorInfo backing );
/**
* @brief Initialise a node as a string
@ -253,7 +253,7 @@ b8 adt_set_arr( ADT_Node* obj, char const* name, AllocatorInfo backing );
* @param value
* @return
*/
b8 adt_set_str( ADT_Node* obj, char const* name, char const* value );
GEN_API b8 adt_set_str( ADT_Node* obj, char const* name, char const* value );
/**
* @brief Initialise a node as a float
@ -263,7 +263,7 @@ b8 adt_set_str( ADT_Node* obj, char const* name, char const* value );
* @param value
* @return
*/
b8 adt_set_flt( ADT_Node* obj, char const* name, f64 value );
GEN_API b8 adt_set_flt( ADT_Node* obj, char const* name, f64 value );
/**
* @brief Initialise a node as a signed integer
@ -273,7 +273,7 @@ b8 adt_set_flt( ADT_Node* obj, char const* name, f64 value );
* @param value
* @return
*/
b8 adt_set_int( ADT_Node* obj, char const* name, s64 value );
GEN_API b8 adt_set_int( ADT_Node* obj, char const* name, s64 value );
/**
* @brief Append a new node to a container as an object
@ -282,7 +282,7 @@ b8 adt_set_int( ADT_Node* obj, char const* name, s64 value );
* @param name
* @return*
*/
ADT_Node* adt_append_obj( ADT_Node* parent, char const* name );
GEN_API ADT_Node* adt_append_obj( ADT_Node* parent, char const* name );
/**
* @brief Append a new node to a container as an array
@ -291,7 +291,7 @@ ADT_Node* adt_append_obj( ADT_Node* parent, char const* name );
* @param name
* @return*
*/
ADT_Node* adt_append_arr( ADT_Node* parent, char const* name );
GEN_API ADT_Node* adt_append_arr( ADT_Node* parent, char const* name );
/**
* @brief Append a new node to a container as a string
@ -301,7 +301,7 @@ ADT_Node* adt_append_arr( ADT_Node* parent, char const* name );
* @param value
* @return*
*/
ADT_Node* adt_append_str( ADT_Node* parent, char const* name, char const* value );
GEN_API ADT_Node* adt_append_str( ADT_Node* parent, char const* name, char const* value );
/**
* @brief Append a new node to a container as a float
@ -311,7 +311,7 @@ ADT_Node* adt_append_str( ADT_Node* parent, char const* name, char const* value
* @param value
* @return*
*/
ADT_Node* adt_append_flt( ADT_Node* parent, char const* name, f64 value );
GEN_API ADT_Node* adt_append_flt( ADT_Node* parent, char const* name, f64 value );
/**
* @brief Append a new node to a container as a signed integer
@ -321,7 +321,7 @@ ADT_Node* adt_append_flt( ADT_Node* parent, char const* name, f64 value );
* @param value
* @return*
*/
ADT_Node* adt_append_int( ADT_Node* parent, char const* name, s64 value );
GEN_API ADT_Node* adt_append_int( ADT_Node* parent, char const* name, s64 value );
/* parser helpers */
@ -332,7 +332,7 @@ ADT_Node* adt_append_int( ADT_Node* parent, char const* name, s64 value );
* @param base
* @return*
*/
char* adt_parse_number( ADT_Node* node, char* base );
GEN_API char* adt_parse_number( ADT_Node* node, char* base );
/**
* @brief Parses a text and stores the result into an unitialised node.
@ -342,7 +342,7 @@ char* adt_parse_number( ADT_Node* node, char* base );
* @param base
* @return*
*/
char* adt_parse_number_strict( ADT_Node* node, char* base_str );
GEN_API char* adt_parse_number_strict( ADT_Node* node, char* base_str );
/**
* @brief Parses and converts an existing string node into a number.
@ -350,7 +350,7 @@ char* adt_parse_number_strict( ADT_Node* node, char* base_str );
* @param node
* @return
*/
ADT_Error adt_c_str_to_number( ADT_Node* node );
GEN_API ADT_Error adt_c_str_to_number( ADT_Node* node );
/**
* @brief Parses and converts an existing string node into a number.
@ -359,7 +359,7 @@ ADT_Error adt_c_str_to_number( ADT_Node* node );
* @param node
* @return
*/
ADT_Error adt_c_str_to_number_strict( ADT_Node* node );
GEN_API ADT_Error adt_c_str_to_number_strict( ADT_Node* node );
/**
* @brief Prints a number into a file stream.
@ -371,7 +371,7 @@ ADT_Error adt_c_str_to_number_strict( ADT_Node* node );
* @param node
* @return
*/
ADT_Error adt_print_number( FileInfo* file, ADT_Node* node );
GEN_API ADT_Error adt_print_number( FileInfo* file, ADT_Node* node );
/**
* @brief Prints a string into a file stream.
@ -385,7 +385,7 @@ ADT_Error adt_print_number( FileInfo* file, ADT_Node* node );
* @param escape_symbol
* @return
*/
ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_chars, char const* escape_symbol );
GEN_API ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_chars, char const* escape_symbol );
#pragma endregion ADT
@ -401,14 +401,14 @@ enum CSV_Error : u32
typedef ADT_Node CSV_Object;
u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header );
u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim );
void csv_free( CSV_Object* obj );
u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header );
GEN_API u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim );
void csv_free( CSV_Object* obj );
void csv_write( FileInfo* file, CSV_Object* obj );
StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj );
void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
void csv_write( FileInfo* file, CSV_Object* obj );
StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj );
GEN_API void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
GEN_API StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
/* inline */

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "strbuilder_ops.cpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "strbuilder_ops.hpp"
#endif
@ -13,15 +13,15 @@ typedef struct FileInfo FileInfo;
typedef char PrintF_Buffer[GEN_PRINTF_MAXLEN];
// NOTE: A locally persisting buffer is used internally
char* c_str_fmt_buf ( char const* fmt, ... );
char* c_str_fmt_buf_va ( char const* fmt, va_list va );
ssize c_str_fmt ( char* str, ssize n, char const* fmt, ... );
ssize c_str_fmt_va ( char* str, ssize n, char const* fmt, va_list va );
ssize c_str_fmt_out_va ( char const* fmt, va_list va );
ssize c_str_fmt_out_err ( char const* fmt, ... );
ssize c_str_fmt_out_err_va( char const* fmt, va_list va );
ssize c_str_fmt_file ( FileInfo* f, char const* fmt, ... );
ssize c_str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va );
GEN_API char* c_str_fmt_buf ( char const* fmt, ... );
GEN_API char* c_str_fmt_buf_va ( char const* fmt, va_list va );
GEN_API ssize c_str_fmt ( char* str, ssize n, char const* fmt, ... );
GEN_API ssize c_str_fmt_va ( char* str, ssize n, char const* fmt, va_list va );
GEN_API ssize c_str_fmt_out_va ( char const* fmt, va_list va );
GEN_API ssize c_str_fmt_out_err ( char const* fmt, ... );
GEN_API ssize c_str_fmt_out_err_va( char const* fmt, va_list va );
GEN_API ssize c_str_fmt_file ( FileInfo* f, char const* fmt, ... );
GEN_API ssize c_str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va );
constexpr
char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "header_start.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "debug.cpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "memory.hpp"
#endif
@ -33,10 +33,10 @@ char const* c_str_trim( char const* str, b32 catch_newline );
void c_str_to_lower( char* str );
void c_str_to_upper( char* str );
s64 c_str_to_i64( const char* str, char** end_ptr, s32 base );
void i64_to_str( s64 value, char* string, s32 base );
void u64_to_str( u64 value, char* string, s32 base );
f64 c_str_to_f64( const char* str, char** end_ptr );
GEN_API s64 c_str_to_i64( const char* str, char** end_ptr, s32 base );
GEN_API void i64_to_str( s64 value, char* string, s32 base );
GEN_API void u64_to_str( u64 value, char* string, s32 base );
GEN_API f64 c_str_to_f64( const char* str, char** end_ptr );
inline
const char* char_first_occurence( const char* s, char c )

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "hashing.cpp"
#endif
@ -58,4 +58,120 @@ StrBuilder strbuilder_make_reserve( AllocatorInfo allocator, ssize capacity )
return result;
}
bool strbuilder_make_space_for(StrBuilder* str, char const* to_append, ssize add_len)
{
ssize available = strbuilder_avail_space(* str);
if (available >= add_len) {
return true;
}
else
{
ssize new_len, old_size, new_size;
void* ptr;
void* new_ptr;
AllocatorInfo allocator = strbuilder_get_header(* str)->Allocator;
StrBuilderHeader* header = nullptr;
new_len = strbuilder_grow_formula(strbuilder_length(* str) + add_len);
ptr = strbuilder_get_header(* str);
old_size = size_of(StrBuilderHeader) + strbuilder_length(* str) + 1;
new_size = size_of(StrBuilderHeader) + new_len + 1;
new_ptr = resize(allocator, ptr, old_size, new_size);
if (new_ptr == nullptr)
return false;
header = rcast(StrBuilderHeader*, new_ptr);
header->Allocator = allocator;
header->Capacity = new_len;
char** Data = rcast(char**, str);
* Data = rcast(char*, header + 1);
return true;
}
}
bool strbuilder_append_c_str_len(StrBuilder* str, char const* c_str_to_append, ssize append_length)
{
GEN_ASSERT(str != nullptr);
if ( rcast(sptr, c_str_to_append) > 0)
{
ssize curr_len = strbuilder_length(* str);
if ( ! strbuilder_make_space_for(str, c_str_to_append, append_length))
return false;
StrBuilderHeader* header = strbuilder_get_header(* str);
char* Data = * str;
mem_copy( Data + curr_len, c_str_to_append, append_length);
Data[curr_len + append_length] = '\0';
header->Length = curr_len + append_length;
}
return c_str_to_append != nullptr;
}
void strbuilder_trim(StrBuilder str, char const* cut_set)
{
ssize len = 0;
char* start_pos = str;
char* end_pos = scast(char*, str) + strbuilder_length(str) - 1;
while (start_pos <= end_pos && char_first_occurence(cut_set, *start_pos))
start_pos++;
while (end_pos > start_pos && char_first_occurence(cut_set, *end_pos))
end_pos--;
len = scast(ssize, (start_pos > end_pos) ? 0 : ((end_pos - start_pos) + 1));
if (str != start_pos)
mem_move(str, start_pos, len);
str[len] = '\0';
strbuilder_get_header(str)->Length = len;
}
StrBuilder strbuilder_visualize_whitespace(StrBuilder const str)
{
StrBuilderHeader* header = (StrBuilderHeader*)(scast(char const*, str) - sizeof(StrBuilderHeader));
StrBuilder result = strbuilder_make_reserve(header->Allocator, strbuilder_length(str) * 2); // Assume worst case for space requirements.
for (char const* c = strbuilder_begin(str); c != strbuilder_end(str); c = strbuilder_next(str, c))
switch ( * c )
{
case ' ':
strbuilder_append_str(& result, txt("·"));
break;
case '\t':
strbuilder_append_str(& result, txt(""));
break;
case '\n':
strbuilder_append_str(& result, txt(""));
break;
case '\r':
strbuilder_append_str(& result, txt(""));
break;
case '\v':
strbuilder_append_str(& result, txt(""));
break;
case '\f':
strbuilder_append_str(& result, txt(""));
break;
default:
strbuilder_append_char(& result, * c);
break;
}
return result;
}
#pragma endregion StrBuilder

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "hashing.hpp"
#endif
@ -122,19 +122,22 @@ struct StrBuilder;
forceinline usize strbuilder_grow_formula(usize value);
GEN_API StrBuilder strbuilder_make_reserve (AllocatorInfo allocator, ssize capacity);
GEN_API StrBuilder strbuilder_make_length (AllocatorInfo allocator, char const* str, ssize length);
GEN_API bool strbuilder_make_space_for (StrBuilder* str, char const* to_append, ssize add_len);
GEN_API bool strbuilder_append_c_str_len (StrBuilder* str, char const* c_str_to_append, ssize length);
GEN_API void strbuilder_trim (StrBuilder str, char const* cut_set);
GEN_API StrBuilder strbuilder_visualize_whitespace(StrBuilder const str);
StrBuilder strbuilder_make_c_str (AllocatorInfo allocator, char const* str);
StrBuilder strbuilder_make_str (AllocatorInfo allocator, Str str);
StrBuilder strbuilder_make_reserve (AllocatorInfo allocator, ssize capacity);
StrBuilder strbuilder_make_length (AllocatorInfo allocator, char const* str, ssize length);
StrBuilder strbuilder_fmt (AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...);
StrBuilder strbuilder_fmt_buf (AllocatorInfo allocator, char const* fmt, ...);
StrBuilder strbuilder_join (AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue);
bool strbuilder_are_equal (StrBuilder const lhs, StrBuilder const rhs);
bool strbuilder_are_equal_str (StrBuilder const lhs, Str rhs);
bool strbuilder_make_space_for (StrBuilder* str, char const* to_append, ssize add_len);
bool strbuilder_append_char (StrBuilder* str, char c);
bool strbuilder_append_c_str (StrBuilder* str, char const* c_str_to_append);
bool strbuilder_append_c_str_len (StrBuilder* str, char const* c_str_to_append, ssize length);
bool strbuilder_append_str (StrBuilder* str, Str c_str_to_append);
bool strbuilder_append_string (StrBuilder* str, StrBuilder const other);
bool strbuilder_append_fmt (StrBuilder* str, char const* fmt, ...);
@ -153,9 +156,7 @@ b32 strbuilder_starts_with_string (StrBuilder const str, StrBuild
void strbuilder_skip_line (StrBuilder str);
void strbuilder_strip_space (StrBuilder str);
Str strbuilder_to_str (StrBuilder str);
void strbuilder_trim (StrBuilder str, char const* cut_set);
void strbuilder_trim_space (StrBuilder str);
StrBuilder strbuilder_visualize_whitespace(StrBuilder const str);
struct StrBuilderHeader {
AllocatorInfo Allocator;
@ -357,29 +358,6 @@ bool strbuilder_append_c_str(StrBuilder* str, char const* c_str_to_append) {
return strbuilder_append_c_str_len(str, c_str_to_append, c_str_len(c_str_to_append));
}
inline
bool strbuilder_append_c_str_len(StrBuilder* str, char const* c_str_to_append, ssize append_length)
{
GEN_ASSERT(str != nullptr);
if ( rcast(sptr, c_str_to_append) > 0)
{
ssize curr_len = strbuilder_length(* str);
if ( ! strbuilder_make_space_for(str, c_str_to_append, append_length))
return false;
StrBuilderHeader* header = strbuilder_get_header(* str);
char* Data = * str;
mem_copy( Data + curr_len, c_str_to_append, append_length);
Data[curr_len + append_length] = '\0';
header->Length = curr_len + append_length;
}
return c_str_to_append != nullptr;
}
forceinline
bool strbuilder_append_str(StrBuilder* str, Str c_str_to_append) {
GEN_ASSERT(str != nullptr);
@ -521,44 +499,6 @@ ssize strbuilder_length(StrBuilder const str)
return header->Length;
}
inline
bool strbuilder_make_space_for(StrBuilder* str, char const* to_append, ssize add_len)
{
ssize available = strbuilder_avail_space(* str);
if (available >= add_len) {
return true;
}
else
{
ssize new_len, old_size, new_size;
void* ptr;
void* new_ptr;
AllocatorInfo allocator = strbuilder_get_header(* str)->Allocator;
StrBuilderHeader* header = nullptr;
new_len = strbuilder_grow_formula(strbuilder_length(* str) + add_len);
ptr = strbuilder_get_header(* str);
old_size = size_of(StrBuilderHeader) + strbuilder_length(* str) + 1;
new_size = size_of(StrBuilderHeader) + new_len + 1;
new_ptr = resize(allocator, ptr, old_size, new_size);
if (new_ptr == nullptr)
return false;
header = rcast(StrBuilderHeader*, new_ptr);
header->Allocator = allocator;
header->Capacity = new_len;
char** Data = rcast(char**, str);
* Data = rcast(char*, header + 1);
return true;
}
}
forceinline
b32 strbuilder_starts_with_str(StrBuilder const str, Str substring) {
if (substring.Len > strbuilder_length(str))
@ -626,69 +566,11 @@ Str strbuilder_to_str(StrBuilder str) {
return result;
}
inline
void strbuilder_trim(StrBuilder str, char const* cut_set)
{
ssize len = 0;
char* start_pos = str;
char* end_pos = scast(char*, str) + strbuilder_length(str) - 1;
while (start_pos <= end_pos && char_first_occurence(cut_set, *start_pos))
start_pos++;
while (end_pos > start_pos && char_first_occurence(cut_set, *end_pos))
end_pos--;
len = scast(ssize, (start_pos > end_pos) ? 0 : ((end_pos - start_pos) + 1));
if (str != start_pos)
mem_move(str, start_pos, len);
str[len] = '\0';
strbuilder_get_header(str)->Length = len;
}
forceinline
void strbuilder_trim_space(StrBuilder str) {
strbuilder_trim(str, " \t\r\n\v\f");
}
inline
StrBuilder strbuilder_visualize_whitespace(StrBuilder const str)
{
StrBuilderHeader* header = (StrBuilderHeader*)(scast(char const*, str) - sizeof(StrBuilderHeader));
StrBuilder result = strbuilder_make_reserve(header->Allocator, strbuilder_length(str) * 2); // Assume worst case for space requirements.
for (char const* c = strbuilder_begin(str); c != strbuilder_end(str); c = strbuilder_next(str, c))
switch ( * c )
{
case ' ':
strbuilder_append_str(& result, txt("·"));
break;
case '\t':
strbuilder_append_str(& result, txt(""));
break;
case '\n':
strbuilder_append_str(& result, txt(""));
break;
case '\r':
strbuilder_append_str(& result, txt(""));
break;
case '\v':
strbuilder_append_str(& result, txt(""));
break;
case '\f':
strbuilder_append_str(& result, txt(""));
break;
default:
strbuilder_append_char(& result, * c);
break;
}
return result;
}
#pragma endregion StrBuilder
#if GEN_COMPILER_CPP

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "filesystem.cpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "filesystem.hpp"
#endif
@ -7,13 +7,13 @@
#ifdef GEN_BENCHMARK
//! Return CPU timestamp.
u64 read_cpu_time_stamp_counter( void );
GEN_API u64 read_cpu_time_stamp_counter( void );
//! Return relative time (in seconds) since the application start.
f64 time_rel( void );
GEN_API f64 time_rel( void );
//! Return relative time since the application start.
u64 time_rel_ms( void );
GEN_API u64 time_rel_ms( void );
#endif
#pragma endregion Timing

View File

@ -14,6 +14,7 @@ NeverInline, neverinline
Ptr, *
Ref, &
Register, register
Restrict, restrict
RValue, &&
Static, static
Thread_Local, thread_local
@ -23,4 +24,5 @@ Final, final
NoExceptions, noexcept
Override, override
Pure, = 0
Delete, = delete
Volatile, volatile

1 Invalid INVALID
14 Ptr *
15 Ref &
16 Register register
17 Restrict restrict
18 RValue &&
19 Static static
20 Thread_Local thread_local
24 NoExceptions noexcept
25 Override override
26 Pure = 0
27 Delete = delete
28 Volatile volatile

View File

@ -72,6 +72,7 @@ Spec_LocalPersist, "local_persist"
Spec_Mutable, "mutable"
Spec_NeverInline, "neverinline"
Spec_Override, "override"
Spec_Restrict, "restrict"
Spec_Static, "static"
Spec_ThreadLocal, "thread_local"
Spec_Volatile, "volatile"

1 Invalid __invalid__
72 Spec_Mutable mutable
73 Spec_NeverInline neverinline
74 Spec_Override override
75 Spec_Restrict restrict
76 Spec_Static static
77 Spec_ThreadLocal thread_local
78 Spec_Volatile volatile

View File

@ -37,8 +37,8 @@ GEN_NS_BEGIN
#include "components/interface.parsing.cpp"
#include "components/interface.untyped.cpp"
#include "auxillary/builder.cpp"
#include "auxillary/scanner.cpp"
#include "auxiliary/builder.cpp"
#include "auxiliary/scanner.cpp"
GEN_NS_END

View File

@ -29,12 +29,12 @@ GEN_NS_BEGIN
#include "components/interface.hpp"
#include "components/constants.hpp"
#include "components/inlines.hpp"
#include "components/gen/ast_inlines.hpp"
#include "components/header_end.hpp"
#include "auxillary/builder.hpp"
#include "auxillary/scanner.hpp"
#include "auxiliary/builder.hpp"
#include "auxiliary/scanner.hpp"
GEN_NS_END

View File

@ -1,6 +1,6 @@
#pragma once
#if GEN_INTELLISENSE_DIRECTIVES
#if INTELLISENSE_DIRECTIVES
# include "../gen.hpp"
# include "misc.hpp"
@ -220,6 +220,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
case Spec_NoExceptions:
case Spec_Override:
case Spec_Pure:
case Spec_Delete:
case Spec_Volatile:
return true;

View File

@ -1,15 +1,15 @@
#pragma once
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
# define GEN_ENFORCE_STRONG_CODE_TYPES
# define GEN_EXPOSE_BACKEND
# include "gen.hpp"
# include "helpers/push_ignores.inline.hpp"
# include "helpers/helper.hpp"
# include "auxillary/builder.hpp"
# include "auxillary/builder.cpp"
# include "auxillary/scanner.hpp"
# include "auxiliary/builder.hpp"
# include "auxiliary/builder.cpp"
# include "auxiliary/scanner.hpp"
#include <stdlib.h>

View File

@ -15,7 +15,7 @@ In order to abstract away constant use of `AST*` its wrapped in a Code type whic
When its the [C generated variant of the library](../gen_c_library/)
```c
typedef AST* Code;
tyepdef AST_<name>* Code<name>;
typedef AST_<name>* Code<name>;
...
```
@ -53,7 +53,7 @@ StrBuilder <prefix>_to_strbuilder(Code code);
Where the first generates strings allocated using Allocator_StringArena and the other appends an existing strings with their backed allocator.
Serialization of for the AST is defined for `Code` in [`ast.cpp`](../base/components/ast.cpp) with `code_to_strbuilder_ptr` & `code_to_strbuilder`.
Serialization of for the AST is defined for `Code` in [`ast.cpp`](../base/components/ast.cpp) with `code_to_strbuilder_ref` & `code_to_strbuilder`.
Serializtion for the rest of the code types is within [`code_serialization.cpp`](../base/components/code_serialization.cpp).
Gencpp's serialization does not provide coherent formatting of the code. The user should use a formatter after serializing.

View File

@ -6,7 +6,7 @@
# AST Types Documentation
While the Readme for docs covers the data layout per AST, this will focus on the AST types avaialble, and their nuances.
While the Readme for docs covers the data layout per AST, this will focus on the AST types available, and their nuances.
## Body
@ -37,7 +37,7 @@ s32 NumEntries;
The `Front` member represents the start of the link list and `Back` the end.
NumEntries is the number of entries in the body.
Parent should have a compatible CodeType type for the type of defintion used.
Parent should have a compatible CodeType type for the type of definition used.
Serialization:
@ -95,7 +95,7 @@ Serialization:
<Content>
```
The parser will perserve comments found if residing with a body or in accepted inline-to-definition locations.
The parser will preserve comments found if residing with a body or in accepted inline-to-definition locations.
Otherwise they will be skipped by the TokArray::__eat and TokArray::current( skip foramtting enabled ) functions.
The upfront constructor: `def_comment` expects to recieve a comment without the `//` or `/* */` parts. It will add them during construction.
@ -289,7 +289,7 @@ Serialization:
## Execution
Just represents an execution body. Equivalent to an untyped body.
Will be obsolute when function body parsing is implemented.
Will be obsolete when function body parsing is implemented.
Fields:

View File

@ -4,7 +4,7 @@
<- [docs - General](Readme.md)
# Parser's Algorithim
# Parser's Algorithm
gencpp uses a hand-written recursive descent parser. Both the lexer and parser currently handle a full C/C++ file in a single pass.
@ -399,7 +399,7 @@ Below is an outline of the general alogirithim used for these internal procedure
## `parse_function_after_name`
This is needed as a function defintion is not easily resolvable early on, as such this function handles resolving a function
This is needed as a function definition is not easily resolvable early on, as such this function handles resolving a function
after its been made ceratin that the type of declaration or definition is indeed for a function signature.
By the point this function is called the following are known : export module flag, attributes, specifiers, return type, & name
@ -548,7 +548,7 @@ In the future statements and expressions will be parsed.
### Implementation Constraints
* Cannot definitively distinguish nested namespaces with identical names
* Cannot distinguish nested namespaces with identical names
* Return type detection requires parser enhancement
* Template parameter validation is syntax-based only
* Future enhancement: Implement type parsing with rollback capability
@ -595,7 +595,7 @@ Notes:
## `parse_operator_after_ret_type`
This is needed as a operator defintion is not easily resolvable early on, as such this function handles resolving a operator after its been made ceratin that the type of declaration or definition is indeed for a operator signature.
This is needed as a operator definition is not easily resolvable early on, as such this function handles resolving a operator after its been made ceratin that the type of declaration or definition is indeed for a operator signature.
By the point this function is called the following are known : export module flag, attributes, specifiers, and return type
@ -639,7 +639,7 @@ By the point this function is called the following are known : export module fla
## `parse_operator_function_or_variable`
When this function is called, attribute and specifiers may have been resolved, however what comes next can still be either an operator, function, or varaible.
When this function is called, attribute and specifiers may have been resolved, however what comes next can still be either an operator, function, or variable.
1. Initial Type Resolution
1. Push parsing scope
@ -792,7 +792,7 @@ This will get changed heavily once we have better support for typename expressio
## `parse_variable_after_name`
This is needed as a variable defintion is not easily resolvable early on, it takes a long evaluation period before its known that the declaration or definition is a variable. As such this function handles resolving a variable.
This is needed as a variable definition is not easily resolvable early on, it takes a long evaluation period before its known that the declaration or definition is a variable. As such this function handles resolving a variable.
By the point this function is called the following are known : export module flag, attributes, specifiers, value type, name
1. Initialization Processing
@ -1090,7 +1090,7 @@ Limitations:
This implementatin will be updated in the future to properly handle functional typename signatures.
### Current Algorithim
### Current Algorithm
Anything that is in the qualifier capture of the function typename is treated as an expression abstracted as an untyped string
@ -1101,7 +1101,8 @@ Anything that is in the qualifier capture of the function typename is treated as
1. If its an in-place definition of a class, enum, struct, or union:
2. If its a decltype (Not supported yet but draft impl there)
3. If its a compound native type expression (unsigned, char, short, long, int, float, dobule, etc )
4. Ends up being a regular type alias of an identifier
4. If its a typename amcro
5. A regular type alias of an identifier
5. Parse specifiers (postfix)
6. We need to now look ahead to see If we're dealing with a function typename
7. If wer're dealing with a function typename:
@ -1118,7 +1119,7 @@ Anything that is in the qualifier capture of the function typename is treated as
8. Check for varaidic argument (param pack) token:
1. Consume varadic argument token
### WIP - Alternative Algorithim
### WIP - Alternative Algorithm
Currently wrapped up via macro: `GEN_USE_NEW_TYPENAME_PARSING`
Anything that is in the qualifier capture of the function typename is treated as an expression abstracted as an untyped string
@ -1129,7 +1130,8 @@ Anything that is in the qualifier capture of the function typename is treated as
1. If its an in-place definition of a class, enum, struct, or union:
2. If its a decltype (Not supported yet but draft impl there)
3. If its a compound native type expression (unsigned, char, short, long, int, float, dobule, etc )
4. Ends up being a regular type alias of an identifier
4. If its a typename amcro
5. A regular type alias of an identifier
4. Parse specifiers (postfix)
1. If any specifiers are found populate specifiers code with them.
5. We need to now look ahead to see If we're dealing with a function typename
@ -1150,7 +1152,7 @@ Anything that is in the qualifier capture of the function typename is treated as
7. Check for varaidic argument (param pack) token:
1. Consume varadic argument token
### **Later: Algorithim based on typename expressions**
### **Later: Algorithm based on typename expressions**
## `parse_typedef`
@ -1190,7 +1192,7 @@ Anything that is in the qualifier capture of the function typename is treated as
6. Decl_Union
7. Preprocess_Define
8. Preprocess_Conditional (if, ifdef, ifndef, elif, else, endif)
9. Preprocess_Macro
9. Preprocess_Macro (`MT_Statement` or `MT_Typename`)
10. Preprocess_Pragma
11. Unsupported preprocess directive
12. Variable

View File

@ -10,7 +10,7 @@ The library features a naive single-pass parser, tailored for only what the libr
This parser does not, and should not do the compiler's job. By only supporting this minimal set of features, the parser is kept (so far) around ~7000 loc. I hope to keep it under 10-15k loc worst case.
You can think of this parser as *frontend parser* vs a *semantic parser*. Its intuitively similar to WYSIWYG. What you ***precerive*** as the syntax from the user-side before the compiler gets a hold of it, is what you get.
You can think of this parser as *frontend parser* vs a *semantic parser*. Its intuitively similar to WYSIWYG. What you ***perceive*** as the syntax from the user-side before the compiler gets a hold of it, is what you get.
User exposed interface:
@ -63,7 +63,7 @@ The preprocessor lines are stored as members of their associated scope they are
Any preprocessor definition abuse that changes the syntax of the core language is unsupported and will fail to parse if not kept within an execution scope (function body, or expression assignment).
Exceptions:
* varaible definitions are allowed for a preprocessed macro `extern MACRO();`
* variable definitions are allowed for a preprocessed macro `extern MACRO();`
* function definitions are allowed for a preprocessed macro: `neverinline MACRO() { ... }`
* Disable with: `#define GEN_PARSER_DISABLE_MACRO_FUNCTION_SIGNATURES`
* typedefs allow for a preprocessed macro: `typedef MACRO();`

View File

@ -260,7 +260,7 @@ def_global_body( args( ht_entry, array_ht_entry, hashtable ));
def_global_body( 3, ht_entry, array_ht_entry, hashtable );
```
If a more incremental approach is desired for the body ASTs, `Code def_body( CodeT type )` can be used to create an empty body.
If a more incremental approach is desired for the body ASTs, `Code def_body( CodeT type )` can be used to create an empty bodyss
When the members have been populated use: `code_validate_body` to verify that the members are valid entires for that type.
### Parse construction
@ -432,7 +432,7 @@ and have the desired specifiers assigned to them beforehand.
## Code generation and modification
There are two provided auxillary interfaces:
There are two provided auxiliary interfaces:
* Builder
* Scanner
@ -444,7 +444,7 @@ There are two provided auxillary interfaces:
* The code is provided via print( code ) function will be serialized to its buffer.
* When all serialization is finished, use the write() command to write the buffer to the file.
### Scanner Auxillary Interface
### Scanner
* The purpose is to scan or parse files
* Some with two basic functions to convert a fil to code: `scan_file` and `parse_file`

View File

@ -21,7 +21,7 @@ To generate a static or dynamic library:
```ps1
.\build.ps1 <compiler> <debug or omit> c_lib_static c_lib_dyn
```
.
All free from tag identifiers will be prefixed with `gen_` or `GEN_` as the namespace. This can either be changed after generation with a `.refactor` script (or your preferred subst method), OR by modifying [c_library.refactor](./c_library.refactor).
**If c_library.refactor is modified you may need to modify c_library.cpp and its [components](./components/). As some of the container generation relies on that prefix.**
@ -29,10 +29,10 @@ All free from tag identifiers will be prefixed with `gen_` or `GEN_` as the name
## Generation structure
1. Files are scanned in or parsed.
* If they are parsed, its dude to requiring some changes to either naming, or adding additonal definitions (container generation, typedefs, etc).
* If they are parsed, its due to requiring some changes to either naming, or adding additonal definitions (container generation, typedefs, etc).
2. All scanned or parsed code is refactored (identifiers substs) and/or formatted.
3. Singleheader generated.
4. Segemented headers and source generated.
4. Segmented headers and source generated.
## Templated container generation
@ -43,7 +43,7 @@ The array and hashtable containers used across this library are generated using
These are functionally (and interface wise) equivalent to the library's `Array<Type>` `HashTable<Type>` within [containers.hpp](../base/dependencies/containers.hpp)
Both files follow the same patter of providing three procedures:
Both files follow the same pattern of providing three procedures:
* `gen_<container>_base` : Intended to be called once, defines universal "base" definitions.
* `gen_<container>` : Called per instatiation of the container for a given set of dependent args.
@ -54,11 +54,13 @@ A simple `<container>_DefinitionCounter` is used to know how many instantiations
## Macro Usage
For the most part macros are kept minimal with exception to `_Generic`...
*(I will be explaining this thing for the rest of this seciton along with gencpp c library's usage of it)*
The `_Generic` macro plays a key role in reducing direct need of the user to wrangle with mangled definition identifiers of 'templated' containers or for type coercion to map distinct data types to a common code path.
Because of its lack of use in many C11 libraries.. and, of those that do; they usually end up obfuscating it with excessive preprocessor abuse; Effort was put into minimizing how much of these macros are handled by the preprocessor vs gencpp itself.
Many C11 libraries don't use it.. and, of those that do. they usually end up obfuscate it with excessive preprocessor abuse; Effort was put into minimizing how much of these macros are handled by the preprocessor vs gencpp itself.
*(I will be explaining this thing for the rest of this seciton along with gencpp c library's usage of it)*
The usual presentation (done bare) is the following:
@ -95,7 +97,7 @@ For this library's purposes we'll be using the functional macro equivalent *(if
```c
#define macro_that_uses_selector_arg_for_resolving_a_fucntion( selecting_exp) \
_Generic( (arg), \
_Generic( (selecting_exp), \
int : func_use_int, \
double : func_use_double, \
struct Whatnot : func_use_Whatnot, \

View File

@ -306,7 +306,7 @@ do \
break;
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_memory, header_memory );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_header_memory, header_memory );
if (found) break;
header_memory.append(entry);
@ -334,7 +334,7 @@ do \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_printing, header_printing );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_header_printing, header_printing );
if (found) break;
header_printing.append(entry);
@ -391,7 +391,7 @@ do \
case CT_Preprocess_IfDef:
{
ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings );
ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings );
}
break;
@ -472,7 +472,7 @@ do \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_filesystem, header_filesystem );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_header_filesystem, header_filesystem );
if (found) break;
header_filesystem.append(entry);
@ -509,7 +509,7 @@ do \
case CT_Variable:
{
CodeVar var = cast(CodeVar, entry);
if (var->Specs.has(Spec_Constexpr) > -1)
if (var->Specs.has(Spec_Constexpr))
{
Opts_def_define opts = { {}, entry->Value->Content };
CodeDefine define = def_define(entry->Name, MT_Expression, opts);
@ -532,7 +532,7 @@ do \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_parsing, header_parsing );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_header_parsing, header_parsing );
if (found) break;
header_parsing.append(entry);
@ -640,7 +640,7 @@ do \
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_types, types );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_types, types );
if (found) break;
types.append(entry);
@ -702,7 +702,7 @@ do \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_parser_types, parser_types );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_parser_types, parser_types );
if (found) break;
parser_types.append(entry);
@ -769,7 +769,7 @@ do \
case CT_Variable:
{
CodeVar var = cast(CodeVar, entry);
if (var->Specs && var->Specs.has(Spec_Constexpr) > -1) {
if (var->Specs && var->Specs.has(Spec_Constexpr)) {
Code define_ver = untyped_str(token_fmt(
"name", var->Name
, "value", var->Value->Content
@ -797,7 +797,7 @@ do \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_ast, ast );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_ast, ast );
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_EXECUTION_EXPRESSION_SUPPORT"), entry, parsed_ast, ast );
@ -978,7 +978,7 @@ R"(#define AST_ArrSpecs_Cap \
++ entry; // Skip a newline...
break;
}
found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types );
found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types );
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_EXECUTION_EXPRESSION_SUPPORT"), entry, parsed_code_types, code_types);
@ -995,7 +995,7 @@ R"(#define AST_ArrSpecs_Cap \
/*
This thing makes a:
#define code_<interface_name>( code, ... ) _Generic( (code), \
<slots> of defintions that look like: <typeof(code)>: code__<interface_name>, \
<slots> of definitions that look like: <typeof(code)>: code__<interface_name>, \
default: gen_generic_selection (Fail case) \
) GEN_RESOLVED_FUNCTION_CALL( code, ... ) \
*/
@ -1078,7 +1078,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
case CT_Preprocess_If:
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_ast_types, ast_types );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_ast_types, ast_types );
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_EXECUTION_EXPRESSION_SUPPORT"), entry, parsed_ast_types, ast_types);
@ -1132,7 +1132,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
case CT_Preprocess_If:
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_interface, interface );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_interface, interface );
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_interface, interface);
@ -1221,7 +1221,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
case CT_Preprocess_If:
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_inlines, inlines );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_inlines, inlines );
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_interface, interface);
@ -1256,13 +1256,53 @@ R"(#define <interface_name>( code ) _Generic( (code), \
break;
}
CodeBody parsed_header_builder = parse_file( path_base "auxillary/builder.hpp" );
CodeBody header_builder = def_body(CT_Global_Body);
s32 idx = 0;
CodeBody parsed_constants = parse_file( path_base "components/constants.hpp" );
CodeBody constants = def_body(CT_Global_Body);
for ( Code entry = parsed_constants.begin(); entry != parsed_constants.end(); ++ entry, ++ idx ) switch( entry->Type )
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_constants, constants );
if (found) break;
constants.append(entry);
}
break;
case CT_Variable:
{
CodeVar var = cast(CodeVar, entry);
if (var->Specs)
{
s32 constexpr_found = var->Specs.remove( Spec_Constexpr );
if (constexpr_found > -1)
{
Opts_def_define opts = { {}, entry->Value->Content };
CodeDefine define = def_define(entry->Name, MT_Expression, opts );
constants.append(define);
continue;
}
}
constants.append(entry);
}
break;
default:
constants.append(entry);
break;
}
#pragma endregion Resolve Components
#pragma region Resolve Aux
CodeDefine gsel_builder_print = NullCode;
CodeBody parsed_header_builder = parse_file( path_base "auxiliary/builder.hpp" );
CodeBody header_builder = def_body(CT_Global_Body);
for ( Code entry = parsed_header_builder.begin(); entry != parsed_header_builder.end(); ++ entry ) switch( entry->Type )
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_builder, header_builder );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_header_builder, header_builder );
if (found) break;
header_builder.append(entry);
@ -1281,6 +1321,51 @@ R"(#define <interface_name>( code ) _Generic( (code), \
}
break;
case CT_Function_Fwd:
{
CodeFn fn = cast(CodeFn, entry);
if (! fn->Name.is_equal(txt("builder_print")) ) {
header_builder.append(fn);
continue;
}
fn->Name = cache_str(txt("builder__print"));
StrBuilder generic_selector = StrBuilder::make(_ctx->Allocator_Temp,
"#define builder_print(builder, code) _Generic( (code), \\\n"
);
// Append slots
for(Str type : code_typenames ) {
generic_selector.append_fmt("%S : %S,\\\n", type, fn->Name );
}
generic_selector.append(txt("default: gen_generic_selection_fail \\\n"));
generic_selector.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( builder, (Code)code )"));
// We need to register this as an identifier macro now sot that parsing the source wont break.
register_macro({ txt("builder_print"), MT_Statement, MF_Functional | MF_Allow_As_Identifier });
// We'll be adding this selector after builder_print_fmt
gsel_builder_print = parse_define(generic_selector);
header_builder.append(fn);
}
break;
case CT_Function:
{
CodeFn fn = cast(CodeFn, entry);
if ( fn->Name.is_equal(txt("builder_print_fmt")) ) {
header_builder.append(fn);
// Add the selector right after
header_builder.append(fmt_newline);
header_builder.append(gsel_builder_print);
}
}
break;
case CT_Struct:
{
CodeBody body = cast(CodeBody, entry->Body);
@ -1312,44 +1397,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header_builder.append(entry);
break;
}
s32 idx = 0;
CodeBody parsed_header_end = parse_file( path_base "components/header_end.hpp" );
CodeBody header_end = def_body(CT_Global_Body);
for ( Code entry = parsed_header_end.begin(); entry != parsed_header_end.end(); ++ entry, ++ idx ) switch( entry->Type )
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_end, header_end );
if (found) break;
header_end.append(entry);
}
break;
case CT_Variable:
{
CodeVar var = cast(CodeVar, entry);
if (var->Specs)
{
s32 constexpr_found = var->Specs.remove( Spec_Constexpr );
if (constexpr_found > -1)
{
Opts_def_define opts = { {}, entry->Value->Content };
CodeDefine define = def_define(entry->Name, MT_Expression, opts );
header_end.append(define);
continue;
}
}
header_end.append(entry);
}
break;
default:
header_end.append(entry);
break;
}
#pragma endregion Resolve Components
#pragma endregion Aux
// Source Content : Reflection and Generation
@ -1398,7 +1446,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_ast, src_ast );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_src_ast, src_ast );
if (found) break;
src_ast.append(entry);
@ -1433,7 +1481,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_upfront, src_upfront );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_src_upfront, src_upfront );
if (found) break;
src_upfront.append(entry);
@ -1472,7 +1520,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_lexer, src_lexer );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_src_lexer, src_lexer );
if (found) break;
src_lexer.append(entry);
@ -1494,7 +1542,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
case CT_Variable:
{
CodeVar var = cast(CodeVar, entry);
if (var->Specs && var->Specs.has(Spec_Constexpr) > -1) {
if (var->Specs && var->Specs.has(Spec_Constexpr)) {
Code define_ver = untyped_str(token_fmt(
"name", var->Name
, "value", var->Value->Content
@ -1521,7 +1569,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_parser, src_parser );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_src_parser, src_parser );
if (found) break;
src_parser.append(entry);
@ -1539,7 +1587,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
case CT_Variable:
{
CodeVar var = cast(CodeVar, entry);
if (var->Specs && var->Specs.has(Spec_Constexpr) > -1) {
if (var->Specs && var->Specs.has(Spec_Constexpr)) {
Code define_ver = untyped_str(token_fmt(
"name", var->Name
, "value", var->Value->Content
@ -1559,7 +1607,27 @@ R"(#define <interface_name>( code ) _Generic( (code), \
}
#pragma endregion Resolve Components
// THERE SHOULD BE NO NEW GENERIC CONTAINER DEFINTIONS PAST THIS POINT (It will not have slots for the generic selection generated macros)
#pragma region Resolve Aux
CodeBody parsed_src_builder = parse_file( path_base "auxiliary/builder.cpp" );
CodeBody src_builder = def_body(CT_Global_Body);
for ( Code entry = parsed_src_builder.begin(); entry != parsed_src_builder.end(); ++ entry ) switch( entry->Type )
{
case CT_Function:
{
if (entry->Name.is_equal(txt("builder_print"))) {
entry->Name = cache_str(txt("builder__print"));
}
src_builder.append(entry);
}
break;
default:
src_builder.append(entry);
break;
}
#pragma endregion ResolveAux
// THERE SHOULD BE NO NEW GENERIC CONTAINER DEFINITIONS PAST THIS POINT (It will not have slots for the generic selection generated macros)
CodeBody containers = def_body(CT_Global_Body);
{
containers.append( def_pragma(code(region Containers)));
@ -1605,13 +1673,13 @@ R"(#define <interface_name>( code ) _Generic( (code), \
Code rf_ast_types = refactor_and_format(ast_types);
Code rf_interface = refactor_and_format(interface);
Code rf_constants = refactor_and_format(constants);
Code rf_inlines = refactor_and_format(inlines);
Code rf_ht_preprocessor_macro = refactor_and_format(ht_preprocessor_macro);
Code rf_array_string_cached = refactor_and_format(array_string_cached);
Code rf_header_end = refactor_and_format(header_end);
Code rf_header_builder = refactor_and_format(header_builder);
Code rf_header_scanner = refactor_and_format( scan_file( path_base "auxillary/scanner.hpp" ));
Code rf_header_scanner = refactor_and_format( scan_file( path_base "auxiliary/scanner.hpp" ));
Code r_src_dep_start = refactor(src_dep_start);
Code r_src_debug = refactor(src_debug);
@ -1644,8 +1712,8 @@ R"(#define <interface_name>( code ) _Generic( (code), \
CodeBody etoktype = gen_etoktype( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv", helper_use_c_definition );
Code rf_etoktype = refactor_and_format(etoktype);
Code rf_src_builder = refactor_and_format( scan_file( path_base "auxillary/builder.cpp" ));
Code rf_src_scanner = refactor_and_format( scan_file( path_base "auxillary/scanner.cpp" ));
Code rf_src_builder = refactor_and_format( src_builder );
Code rf_src_scanner = refactor_and_format( scan_file( path_base "auxiliary/scanner.cpp" ));
#pragma endregion Refactored / Formatted
#pragma region Singleheader
@ -1720,6 +1788,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print( rf_ht_preprocessor_macro );
header.print( rf_interface );
header.print( rf_constants );
header.print(fmt_newline);
header.print_fmt("#pragma region Inlines\n");
@ -1728,7 +1797,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print(fmt_newline);
header.print( rf_header_end );
header.print( rf_header_builder );
header.print( rf_header_scanner );
@ -1814,6 +1882,9 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print( r_header_macros );
header.print( header_generic_macros );
header.print_fmt( "\nGEN_API_C_BEGIN\n" );
header.print( r_header_basic_types );
header.print( r_header_debug );
header.print( rf_header_memory );
@ -1827,6 +1898,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print( r_header_timing );
header.print(rf_header_parsing );
header.print_fmt( "\nGEN_API_C_END\n" );
header.print_fmt( "\nGEN_NS_END\n" );
header.write();
}
@ -1881,7 +1953,17 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print( rf_ast_types );
header.print_fmt("\n#pragma endregion AST\n");
header.print( fmt_newline);
header.print( rf_array_arena );
header.print( fmt_newline);
header.print( rf_array_pool);
header.print( fmt_newline);
header.print( rf_array_string_cached );
header.print( fmt_newline);
header.print( rf_ht_preprocessor_macro );
header.print( rf_interface );
header.print( rf_constants );
header.print(fmt_newline);
header.print_fmt("#pragma region Inlines\n");
@ -1889,9 +1971,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print_fmt("#pragma endregion Inlines\n");
header.print(fmt_newline);
header.print( rf_array_string_cached );
header.print( rf_header_end );
header.print( rf_header_builder );
header.print( rf_header_scanner );
@ -1908,11 +1988,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
builder_print( src, src_start );
src.print_fmt( "\nGEN_NS_BEGIN\n");
src.print( fmt_newline);
src.print( rf_array_arena );
src.print( fmt_newline);
src.print( rf_array_pool);
src.print( r_src_static_data );
src.print( fmt_newline);
@ -1930,6 +2005,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
src.print( fmt_newline);
src.print( rf_array_code_typename );
src.print( fmt_newline);
src.print( r_src_parser_case_macros );
src.print( rf_src_parser );
src.print( r_src_parsing );
src.print_fmt( "\n#pragma endregion Parsing\n" );

View File

@ -420,6 +420,10 @@ word make_code, gen_make_code
namespace set_allocator_, gen_set_allocator_
word register_macro, gen_register_macro
word register_macros, gen_register_macros
word register_macros_arr, gen_register_macros_arr
namespace Opts_, gen_Opts_
namespace def_, gen_def_

View File

@ -13,7 +13,7 @@
| \_____|\___}_l |_|\___} .__/| .__/ {_____/ \__\__/_l\__. |\___/\__,_l \____}{_____}{_____} |
| | | | | __} | |
| l_l l_l {___/ |
! ----------------------------------------------------------------------- VERSION: v0.23-Alpha |
! ----------------------------------------------------------------------- VERSION: v0.25-Alpha |
! ============================================================================================= |
! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION |
! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL |

View File

@ -7,8 +7,19 @@ void convert_cpp_enum_to_c( CodeEnum to_convert, CodeBody to_append )
{
#pragma push_macro("enum_underlying")
#undef enum_underlying
StrCached type = to_convert->UnderlyingType ? to_convert->UnderlyingType.to_strbuilder().to_str() : to_convert->Name;
CodeTypedef tdef = parse_typedef(token_fmt("type", type, "name", to_convert->Name, stringize( typedef enum <type> <name>; )));
StrCached type;
CodeTypedef tdef;
if (to_convert->UnderlyingType)
{
type = to_convert->UnderlyingType.to_strbuilder().to_str();
tdef = parse_typedef(token_fmt("type", type, "name", to_convert->Name, stringize( typedef <type> <name>; )));
}
else
{
type = to_convert->Name;
tdef = parse_typedef(token_fmt("type", type, "name", to_convert->Name, stringize( typedef enum <type> <name>; )));
}
if (to_convert->UnderlyingType)
{
to_convert->UnderlyingTypeMacro = untyped_str(token_fmt("type", to_convert->UnderlyingType->Name, stringize(enum_underlying(<type>))));

View File

@ -1,3 +1,6 @@
#define GEN_IMPLEMENTATION
#define GEN_DONT_ENFORCE_GEN_TIME_GUARD
#define GEN_DEFINE_LIBRARY_CORE_CONSTANTS
#define GEN_ENFORCE_STRONG_CODE_TYPES
#define GEN_EXPOSE_BACKEND
#include "gen/gen_singleheader.h"

View File

@ -6,15 +6,15 @@
* [docs](../docs/Readme.md)
# Segemented Library Generation
# segmented Library Generation
Create a segemented library using `segemented.cpp`
Create a segmented library using `segmented.cpp`
The principal (user) files are `gen.hpp` and `gen.cpp`.
They contain includes for its various components: `components/<component_name>.<hpp/cpp>`
Dependencies are bundled into `gen.dep.<hpp/cpp>`. They are included in `gen.<hpp/cpp>` before component includes.
Just like the `gen.<hpp/cpp>` they include their components: `dependencies/<dependency_name>.<hpp/cpp>`. The auxillary content (builder & scanner) is given their own files.
Just like the `gen.<hpp/cpp>` they include their components: `dependencies/<dependency_name>.<hpp/cpp>`. The auxiliary content (builder & scanner) is given their own files.
If using the library's provided build scripts:

View File

@ -114,7 +114,7 @@ int gen_main()
}
CodeBody gen_component_header = def_global_body( args(
def_preprocess_cond( PreprocessCond_IfDef, txt("GEN_INTELLISENSE_DIRECTIVES") ),
def_preprocess_cond( PreprocessCond_IfDef, txt("INTELLISENSE_DIRECTIVES") ),
pragma_once,
def_include(txt("components/types.hpp")),
preprocess_endif,
@ -131,8 +131,8 @@ int gen_main()
Code ast_types = scan_file( path_base "components/ast_types.hpp" );
Code code_types = scan_file( path_base "components/code_types.hpp" );
Code interface = scan_file( path_base "components/interface.hpp" );
Code constants = scan_file( path_base "components/constants.hpp");
Code inlines = scan_file( path_base "components/inlines.hpp" );
Code header_end = scan_file( path_base "components/header_end.hpp" );
CodeBody ecode = gen_ecode ( path_base "enums/ECodeTypes.csv" );
CodeBody eoperator = gen_eoperator ( path_base "enums/EOperator.csv" );
@ -168,6 +168,7 @@ int gen_main()
builder_print_fmt( header, "\n#pragma endregion AST\n" );
builder_print( header, interface );
builder_print( header, constants );
builder_print_fmt( header, "\n#pragma region Inlines\n" );
builder_print( header, inlines );
@ -176,7 +177,6 @@ int gen_main()
builder_print( header, fmt_newline );
builder_print_fmt( header, "#pragma endregion Inlines\n" );
builder_print( header, header_end );
builder_print_fmt( header, "\nGEN_NS_END\n\n" );
builder_print( header, pop_ignores );
builder_write(header);
@ -231,7 +231,7 @@ int gen_main()
// gen_builder.hpp
{
Code builder = scan_file( path_base "auxillary/builder.hpp" );
Code builder = scan_file( path_base "auxiliary/builder.hpp" );
Builder header = builder_open( "gen/gen.builder.hpp" );
builder_print_fmt( & header, generation_notice );
@ -245,7 +245,7 @@ int gen_main()
// gen_builder.cpp
{
Code builder = scan_file( path_base "auxillary/builder.cpp" );
Code builder = scan_file( path_base "auxiliary/builder.cpp" );
Builder src = builder_open( "gen/gen.builder.cpp" );
builder_print_fmt( & src, generation_notice );
@ -258,7 +258,7 @@ int gen_main()
// gen_scanner.hpp
{
Code scanner = scan_file( path_base "auxillary/scanner.hpp" );
Code scanner = scan_file( path_base "auxiliary/scanner.hpp" );
Builder header = builder_open( "gen/gen.scanner.hpp" );
builder_print_fmt( & header, generation_notice );
@ -272,7 +272,7 @@ int gen_main()
// gen_scanner.cpp
{
Code scanner = scan_file( path_base "auxillary/scanner.cpp" );
Code scanner = scan_file( path_base "auxiliary/scanner.cpp" );
Builder src = builder_open( "gen/gen.scanner.cpp" );
builder_print_fmt( & src, generation_notice );

View File

@ -15,7 +15,7 @@
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
| Singleheader | | | | __} | |
| l_l l_l {___/ |
! ----------------------------------------------------------------------- VERSION: v0.23-Alpha |
! ----------------------------------------------------------------------- VERSION: v0.25-Alpha |
! ============================================================================================ |
! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION |
! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL |

View File

@ -117,8 +117,8 @@ int gen_main()
Code ast_types = scan_file( path_base "components/ast_types.hpp" );
Code code_types = scan_file( path_base "components/code_types.hpp" );
Code interface = scan_file( path_base "components/interface.hpp" );
Code constants = scan_file( path_base "components/constants.hpp" );
Code inlines = scan_file( path_base "components/inlines.hpp" );
Code header_end = scan_file( path_base "components/header_end.hpp" );
CodeBody ecode = gen_ecode ( path_base "enums/ECodeTypes.csv" );
CodeBody eoperator = gen_eoperator ( path_base "enums/EOperator.csv" );
@ -149,6 +149,7 @@ int gen_main()
header.print_fmt("\n#pragma endregion AST\n");
header.print( interface );
header.print( constants );
header.print_fmt( "\n#pragma region Inlines\n" );
header.print( inlines );
@ -156,13 +157,11 @@ int gen_main()
header.print( fmt_newline );
header.print_fmt( "#pragma endregion Inlines\n" );
header.print( header_end );
if ( generate_builder ) {
header.print( scan_file( path_base "auxillary/builder.hpp" ) );
header.print( scan_file( path_base "auxiliary/builder.hpp" ) );
}
if ( generate_scanner ) {
header.print( scan_file( path_base "auxillary/scanner.hpp" ) );
header.print( scan_file( path_base "auxiliary/scanner.hpp" ) );
}
header.print(fmt_newline);
@ -246,11 +245,11 @@ int gen_main()
header.print_fmt( "\n#pragma endregion Interface\n");
if ( generate_builder ) {
header.print( scan_file( path_base "auxillary/builder.cpp" ) );
header.print( scan_file( path_base "auxiliary/builder.cpp" ) );
}
if ( generate_scanner ) {
header.print( scan_file( path_base "auxillary/scanner.cpp" ) );
header.print( scan_file( path_base "auxiliary/scanner.cpp" ) );
}
header.print( fmt_newline);

View File

@ -16,7 +16,7 @@
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
| Unreal Engine | | | | __} | |
| l_l l_l {___/ |
! ----------------------------------------------------------------------- VERSION: v0.23-Alpha |
! ----------------------------------------------------------------------- VERSION: v0.25-Alpha |
! ============================================================================================ |
! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION |
! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL |

View File

@ -106,3 +106,9 @@ case Spec_Mutable: \
case Spec_Static: \
case Spec_Thread_Local: \
case Spec_Volatile
#define GEN_PARSER_TYPENAME_ALLOWED_SUFFIX_SPECIFIER_CASES \
case Spec_Const: \
case Spec_Ptr: \
case Spec_Ref: \
case Spec_RValue

View File

@ -4,4 +4,3 @@ COREUOBJECT_API, COREUOBJECT_API
ENGINE_API, ENGINE_API
GAMEPLAYABILITIES_API, GAMEPLAYABILITIES_API
UMG_API, UMG_API
GASA_API, GASA_API
1 API_Export GEN_API_Export_Code
4 ENGINE_API ENGINE_API
5 GAMEPLAYABILITIES_API GAMEPLAYABILITIES_API
6 UMG_API UMG_API
GASA_API GASA_API

View File

@ -24,4 +24,5 @@ Final, final
NoExceptions, noexcept
Override, override
Pure, = 0
Delete, = delete
Volatile, volatile

1 Invalid INVALID
24 NoExceptions noexcept
25 Override override
26 Pure = 0
27 Delete = delete
28 Volatile volatile

View File

@ -224,8 +224,8 @@ int gen_main()
Code ast_types = scan_file( path_base "components/ast_types.hpp" );
Code code_types = scan_file( path_base "components/code_types.hpp" );
Code interface = scan_file( path_base "components/interface.hpp" );
Code constants = scan_file( path_base "components/constants.hpp" );
Code inlines = scan_file( path_base "components/inlines.hpp" );
Code header_end = scan_file( path_base "components/header_end.hpp" );
CodeBody ecode = gen_ecode ( path_base "enums/ECodeTypes.csv" );
CodeBody eoperator = gen_eoperator ( path_base "enums/EOperator.csv" );
@ -266,6 +266,7 @@ int gen_main()
header.print_fmt( "\n#pragma endregion AST\n" );
header.print( interface );
header.print( constants );
header.print_fmt( "\n#pragma region Inlines\n" );
header.print( inlines );
@ -274,7 +275,6 @@ int gen_main()
header.print( fmt_newline );
header.print_fmt( "#pragma endregion Inlines\n" );
header.print( header_end );
header.print_fmt( "\nGEN_NS_END\n\n" );
header.print( pop_ignores );
header.write();
@ -337,7 +337,7 @@ int gen_main()
// gen_builder.hpp
{
Code builder = scan_file( path_base "auxillary/builder.hpp" );
Code builder = scan_file( path_base "auxiliary/builder.hpp" );
Builder
header = Builder::open( "gen/gen.builder.hpp" );
@ -356,7 +356,7 @@ int gen_main()
// gen_builder.cpp
{
Code builder = scan_file( path_base "auxillary/builder.cpp" );
Code builder = scan_file( path_base "auxiliary/builder.cpp" );
Builder
src = Builder::open( "gen/gen.builder.cpp" );
@ -374,7 +374,7 @@ int gen_main()
// gen_scanner.hpp
{
Code scanner = scan_file( path_base "auxillary/scanner.hpp" );
Code scanner = scan_file( path_base "auxiliary/scanner.hpp" );
Builder
header = Builder::open( "gen/gen.scanner.hpp" );
@ -393,7 +393,7 @@ int gen_main()
// gen.scanner.cpp
{
Code scanner = scan_file( path_base "auxillary/scanner.cpp" );
Code scanner = scan_file( path_base "auxiliary/scanner.cpp" );
Builder
src = Builder::open( "gen/gen.scanner.cpp" );

View File

@ -146,7 +146,7 @@ QualifierAlignment: Leave
ReferenceAlignment: Left
ReflowComments: true
ReflowComments: false
# RequiresExpressionIndentation: OuterScope
@ -164,7 +164,7 @@ SpaceAfterTemplateKeyword: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
@ -182,7 +182,7 @@ SpacesInContainerLiterals: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: 20
SpacesInParentheses: true
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: c++17

View File

@ -22,7 +22,7 @@ args:
c_lib : Build c11 library (singleheader & segmented)
c_lib_static : Build static c11 library
c_lib_dyn : Buidl dyanmic c11
segemented
segmented
singleheader
unreal
clang

View File

@ -172,7 +172,7 @@ if ( $segmented )
write-host `t $_ -ForegroundColor Green
}
}
write-host "`nBootstrap completed in $($time_taken.TotalMilliseconds) ms"
write-host "`nSegmented completed in $($time_taken.TotalMilliseconds) ms"
}
Pop-Location
}
@ -263,6 +263,7 @@ if ( $c_lib_static )
$compiler_args += $flag_all_c
$compiler_args += $flag_updated_cpp_macro
$compiler_args += $flag_c11
$compiler_args += ($flag_define + 'GEN_STATIC_LINK')
$linker_args = @()
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $path_lib
@ -280,6 +281,7 @@ if ( $c_lib_dyn )
$compiler_args += $flag_c11
$compiler_args += ( $flag_define + 'GEN_DYN_LINK' )
$compiler_args += ( $flag_define + 'GEN_DYN_EXPORT' )
$compiler_args += ( $flag_define + 'GEN_DEFINE_LIBRARY_CODE_CONSTANTS' )
$linker_args = @()
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $path_dll
@ -368,7 +370,49 @@ if ( $test -and $true )
Pop-Location
}
if ($test -and $true)
if ( $test -and $false )
{
$path_test_c = join-path $path_test c_library
$path_build = join-path $path_test_c build
$path_gen = join-path $path_test_c gen
if ( -not(Test-Path($path_build) )) {
New-Item -ItemType Directory -Path $path_build
}
if ( -not(Test-Path($path_gen) )) {
New-Item -ItemType Directory -Path $path_gen
}
$path_singleheader_include = join-path $path_c_library gen
$includes = @( $path_singleheader_include )
$unit = join-path $path_test_c "test_cuik.c"
$executable = join-path $path_build "test_cuik.exe"
$compiler_args = @()
$compiler_args += ( $flag_define + 'GEN_TIME' )
$compiler_args += $flag_all_c
$compiler_args += $flag_updated_cpp_macro
$compiler_args += $flag_c11
$linker_args = @(
$flag_link_win_subsystem_console
)
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
Push-Location $path_test_c
if ( Test-Path( $executable ) ) {
write-host "`nRunning c_library test"
$time_taken = Measure-Command { & $executable
| ForEach-Object {
write-host `t $_ -ForegroundColor Green
}
}
write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms"
}
Pop-Location
}
if ($test -and $false)
{
$path_test_cpp = join-path $path_test cpp_library
$path_build = join-path $path_test_cpp build

Binary file not shown.

View File

@ -344,15 +344,17 @@ if ( $vendor -match "clang" )
}
# Check if output is a static library
# if ( $binary -match '\.lib$' )
# {
# $lib_args = @()
if ( $binary -match '\.lib$' )
{
$lib_args = @()
# $lib_args += $flag_nologo
# $lib_args += $flag_link_win_machine_64
# $lib_args += ( $flag_link_win_path_output + $binary )
# $lib_args += $object
# return run-archiver $archiver $binary $lib_args
# }
# $lib_args += '--format=windows'
# $lib_args += '-X64'
$lib_args += $object
return run-archiver $archiver $binary $lib_args
}
$linker_args += $object
return run-linker $linker $binary $linker_args
@ -562,6 +564,7 @@ if ( $vendor -match "msvc" )
# Check if output is a static library
if ( $binary -match '\.lib$' )
{
write-host "Running archiver for $binary"
$lib_args = @()
$lib_args += $flag_nologo
$lib_args += $flag_link_win_machine_64

View File

@ -106,10 +106,10 @@ Copy-Item -Verbose -Path $path_base\gen.hpp -Destination $path_rel
Copy-Item -Verbose -Path $path_base\gen.cpp -Destination $path_release_content
Copy-Item -Verbose -Path $path_base\gen.dep.hpp -Destination $path_release_content
Copy-Item -Verbose -Path $path_base\gen.dep.cpp -Destination $path_release_content
Copy-Item -Verbose -Path $path_base\auxillary\builder.hpp -Destination $path_release_content\auxillary
Copy-Item -Verbose -Path $path_base\auxillary\builder.cpp -Destination $path_release_content\auxillary
Copy-Item -Verbose -Path $path_base\auxillary\scanner.hpp -Destination $path_release_content\auxillary
Copy-Item -Verbose -Path $path_base\auxillary\scanner.cpp -Destination $path_release_content\auxillary
Copy-Item -Verbose -Path $path_base\auxiliary\builder.hpp -Destination $path_release_content\auxiliary
Copy-Item -Verbose -Path $path_base\auxiliary\builder.cpp -Destination $path_release_content\auxiliary
Copy-Item -Verbose -Path $path_base\auxiliary\scanner.hpp -Destination $path_release_content\auxiliary
Copy-Item -Verbose -Path $path_base\auxiliary\scanner.cpp -Destination $path_release_content\auxiliary
New-Item -ItemType Directory -Force -Path "$path_release_content\components"
New-Item -ItemType Directory -Force -Path "$path_release_content\components\gen"

90
scripts/uncrustify.cfg Normal file
View File

@ -0,0 +1,90 @@
# Basic indentation settings
indent_columns = 4
indent_with_tabs = 1
indent_case_brace = 0
indent_switch_case = 4
indent_col1_comment = true
indent_namespace = true
indent_class = true
indent_extern = true
# Alignment settings
align_assign_span = 1
align_assign_thresh = 0
align_enum_equ_span = 1
align_var_def_span = 1
align_var_def_thresh = 0
align_var_def_inline = true
align_right_cmt_span = 1
align_pp_define_span = 1
align_typedef_span = 1
align_typedef_gap = 0
# Spacing settings
sp_before_square = remove
sp_inside_square = remove
sp_after_comma = force
sp_before_comma = remove
sp_after_cast = remove
sp_inside_paren = remove
sp_inside_fparen = remove
sp_inside_sparen = remove
sp_before_sparen = force
sp_after_operator = remove
sp_after_operator_sym = remove
sp_after_ptr_star = remove
sp_before_ptr_star = force
sp_between_ptr_star = remove
# Code style settings
mod_full_brace_do = force
mod_full_brace_for = force
mod_full_brace_if = force
mod_full_brace_while = force
mod_paren_on_return = remove
mod_full_brace_nl = 1
mod_remove_extra_semicolon = true
# Line breaking
nl_after_brace_open = true
nl_after_brace_close = true
nl_after_return = true
nl_before_case = true
nl_fcall_brace = force
nl_enum_brace = force
nl_struct_brace = force
nl_union_brace = force
nl_if_brace = force
nl_brace_else = force
nl_elseif_brace = force
nl_else_brace = force
nl_else_if = remove
nl_while_brace = force
nl_do_brace = force
nl_for_brace = force
nl_max = 4
nl_after_func_proto = 2
nl_after_func_body = 2
# Template settings
sp_inside_angle = remove
sp_after_angle = force
sp_angle_paren = remove
sp_angle_word = force
# Other settings
cmt_indent_multi = true
cmt_c_group = false
cmt_cpp_group = false
indent_func_call_param = true
indent_func_def_param = true
indent_func_proto_param = true
indent_template_param = true
indent_relative_single_line_comments = true
# Preprocessor settings
pp_indent = remove
pp_space = remove
# Column limit
code_width = 160

View File

@ -1,3 +1,3 @@
# Test
The implementaiton here has been gutted and will be rewritten...
The implementation here has been gutted and will be rewritten...

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Yasser Arguelles Snape
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.

View File

@ -0,0 +1,454 @@
#pragma once
#include "../tb_internal.h"
#include <arena_array.h>
#include <limits.h>
enum {
INT_WIDEN_LIMIT = 3,
FAST_IDOM_LIMIT = 20
};
#if TB_PACKED_USERS
#define USERN(u) ((TB_Node*) ((u)->_n)) // node
#define USERI(u) ((int) ((u)->_slot)) // index
#else
#define USERN(u) ((u)->_n) // node
#define USERI(u) ((u)->_slot) // index
#endif
#define FOR_USERS(u, n) for (TB_User *u = (n)->users, *_end_ = &u[(n)->user_count]; u != _end_; u++)
////////////////////////////////
// Constant prop
////////////////////////////////
typedef struct {
int64_t min, max;
// for known bit analysis
uint64_t known_zeros, known_ones;
// we really don't wanna widen 18 quintillion times, it's never worth it
uint64_t widen;
} LatticeInt;
// Represents the fancier type system within the optimizer, it's
// all backed by my shitty understanding of lattice theory
struct Lattice {
enum {
LATTICE_BOT, // bot ^ x = bot
LATTICE_TOP, // top ^ x = x
LATTICE_INT,
LATTICE_TUPLE,
// float (each float type has it's own separate set of these btw):
//
// top
// / \
// / \
// / \
// / \
// /|\ /|\
// / | \ / | \
// N N N 0.0 1.5 ... # fltcon
// \ | / \ | /
// \|/ \|/
// nan ~nan
// \ /
// \ /
// \ /
// \ /
// flt
//
// N means NaN it's just too long to write in the diagram
LATTICE_FLT32, LATTICE_FLT64, // bottom types for floats
LATTICE_NAN32, LATTICE_NAN64,
LATTICE_XNAN32, LATTICE_XNAN64,
LATTICE_FLTCON32, LATTICE_FLTCON64, // _f32 and _f64
// pointers:
// anyptr
// / \
// / \
// / /|\
// | / | \
// null a b ... # ptrcon
// | \ | /
// \ ~null
// \ /
// allptr
LATTICE_ALLPTR,
LATTICE_ANYPTR,
LATTICE_NULL,
LATTICE_XNULL,
LATTICE_PTRCON,
// memory types
LATTICE_MEMORY,
// control tokens:
// top
// |
// dead
// |
// live
// |
// bot
LATTICE_LIVE,
LATTICE_DEAD,
} tag;
union {
size_t _elem_count; // LATTICE_TUPLE
LatticeInt _int; // LATTICE_INT
TB_Symbol* _ptr; // LATTICE_PTRCON
float _f32; // LATTICE_FLTCON32
double _f64; // LATTICE_FLTCON64
};
union {
Lattice* elems[0];
};
};
////////////////////////////////
// Cool properties
////////////////////////////////
uint32_t cfg_flags(TB_Node* n);
bool cfg_is_region(TB_Node* n);
bool cfg_is_natural_loop(TB_Node* n);
bool cfg_is_branch(TB_Node* n);
bool cfg_is_fork(TB_Node* n);
bool cfg_is_terminator(TB_Node* n);
bool cfg_is_endpoint(TB_Node* n);
bool tb_node_is_safepoint(TB_Node* n);
bool tb_node_has_mem_out(TB_Node* n);
TB_Node* tb_node_mem_in(TB_Node* n);
////////////////////////////////
// CFG
////////////////////////////////
typedef struct {
TB_Node *phi, *n;
int dst, src;
} PhiVal;
////////////////////////////////
// Core optimizer
////////////////////////////////
typedef struct {
TB_Module* mod;
NL_HashSet visited;
size_t ws_cap;
size_t ws_cnt;
TB_Function** ws;
} IPOSolver;
static bool cant_signed_overflow(TB_Node* n) {
return TB_NODE_GET_EXTRA_T(n, TB_NodeBinopInt)->ab & TB_ARITHMATIC_NSW;
}
static bool is_proj(TB_Node* n) {
return n->type == TB_PROJ || n->type == TB_MACH_PROJ || n->type == TB_BRANCH_PROJ;
}
static uint64_t tb__mask(uint64_t bits) {
return ~UINT64_C(0) >> (64 - bits);
}
static bool cfg_is_cproj(TB_Node* n) {
return is_proj(n) && n->dt.type == TB_TAG_CONTROL;
}
static bool cfg_is_mproj(TB_Node* n) {
return n->type == TB_PROJ && n->dt.type == TB_TAG_MEMORY;
}
// includes tuples which have control flow
static bool cfg_is_control(TB_Node* n) {
if (n->dt.type == TB_TAG_CONTROL) { return true; }
if (n->dt.type == TB_TAG_TUPLE) {
FOR_USERS(u, n) {
if (cfg_is_cproj(USERN(u))) { return true; }
}
}
return false;
}
static bool cfg_is_bb_entry(TB_Node* n) {
if (cfg_is_region(n)) {
return true;
} else if (cfg_is_cproj(n) && (n->inputs[0]->type == TB_ROOT || cfg_is_fork(n->inputs[0]))) {
// Start's control proj or a branch target
return true;
} else {
return false;
}
}
// returns a BranchProj's falsey proj, if it's an if-like TB_BRANCH
static TB_NodeBranchProj* cfg_if_branch(TB_Node* n) {
size_t succ_count = 0;
if (n->type == TB_BRANCH || n->type == TB_AFFINE_LATCH) {
TB_NodeBranch* br = TB_NODE_GET_EXTRA(n);
succ_count = br->succ_count;
} else if (cfg_is_branch(n)) {
FOR_USERS(u, n) {
if (USERN(u)->type == TB_BRANCH_PROJ) { succ_count++; }
}
} else {
tb_todo();
}
if (succ_count != 2) { return NULL; }
FOR_USERS(u, n) {
if (USERN(u)->type == TB_BRANCH_PROJ) {
TB_NodeBranchProj* proj = TB_NODE_GET_EXTRA(USERN(u));
if (proj->index == 1) { return proj; }
}
}
// shouldn't be reached wtf?
return NULL;
}
static bool is_mem_out_op(TB_Node* n) {
return n->dt.type == TB_TAG_MEMORY || (n->type >= TB_STORE && n->type <= TB_ATOMIC_CAS) || (n->type >= TB_CALL && n->type <= TB_TAILCALL) || n->type == TB_SPLITMEM || n->type == TB_MERGEMEM || n->type == TB_DEBUG_LOCATION;
}
static bool is_mem_end_op(TB_Node* n) {
return n->type == TB_RETURN || n->type == TB_TRAP || n->type == TB_UNREACHABLE;
}
static bool is_mem_in_op(TB_Node* n) {
return is_mem_out_op(n) || n->type == TB_SAFEPOINT || n->type == TB_LOAD;
}
static bool is_mem_only_in_op(TB_Node* n) {
return n->type == TB_SAFEPOINT || n->type == TB_LOAD;
}
static bool single_use(TB_Node* n) {
return n->user_count == 1;
}
static TB_User* get_single_use(TB_Node* n) {
return n->user_count == 1 ? &n->users[0] : NULL;
}
static bool tb_node_is_pinned(TB_Node* n) {
if ((n->type >= TB_ROOT && n->type <= TB_SAFEPOINT) || is_proj(n) || cfg_is_control(n)) {
return true;
}
return cfg_flags(n) & NODE_PINNED;
}
////////////////////////////////
// CFG analysis
////////////////////////////////
// if we see a branch projection, it may either be a BB itself
// or if it enters a REGION directly, then that region is the BB.
static TB_Node* cfg_next_bb_after_cproj(TB_Node* proj) {
return proj;
}
static TB_User* proj_with_index(TB_Node* n, int i) {
FOR_USERS(u, n) if (is_proj(USERN(u))) {
TB_NodeProj* p = TB_NODE_GET_EXTRA(USERN(u));
if (p->index == i) { return u; }
}
return NULL;
}
static TB_User* cfg_next_user(TB_Node* n) {
FOR_USERS(u, n) {
if (cfg_is_control(USERN(u))) { return u; }
}
return NULL;
}
static bool cfg_has_phis(TB_Node* n) {
if (!cfg_is_region(n)) { return false; }
FOR_USERS(u, n) {
if (USERN(u)->type == TB_PHI) { return true; }
}
return false;
}
static bool cfg_is_unreachable(TB_Node* n) {
FOR_USERS(u, n) {
if (USERN(u)->type == TB_UNREACHABLE) { return true; }
}
return false;
}
static TB_Node* cfg_next_control(TB_Node* n) {
FOR_USERS(u, n) {
if (cfg_is_control(USERN(u))) { return USERN(u); }
}
return NULL;
}
static TB_Node* cfg_get_pred(TB_CFG* cfg, TB_Node* n, int i) {
n = n->inputs[i];
for (;;) {
ptrdiff_t search = nl_map_get(cfg->node_to_block, n);
if (search >= 0 || n->type == TB_DEAD || cfg_is_region(n)) {
return n;
}
n = n->inputs[0];
}
}
static TB_BasicBlock* cfg_get_pred_bb(TB_CFG* cfg, TB_Node* n, int i) {
n = n->inputs[i];
for (;;) {
ptrdiff_t search = nl_map_get(cfg->node_to_block, n);
if (search >= 0) {
return cfg->node_to_block[search].v;
} else if (n->type == TB_DEAD || cfg_is_region(n)) {
return NULL;
}
n = n->inputs[0];
}
}
// shorthand because we use it a lot
static TB_Node* idom(TB_CFG* cfg, TB_Node* n) {
TB_ASSERT(cfg->node_to_block == NULL);
ptrdiff_t search = nl_map_get(cfg->node_to_block, n);
if (search < 0) {
return NULL;
}
TB_BasicBlock* dom = cfg->node_to_block[search].v->dom;
return dom ? dom->start : NULL;
}
static int dom_depth(TB_CFG* cfg, TB_Node* n) {
return nl_map_get_checked(cfg->node_to_block, n)->dom_depth;
}
static bool slow_dommy2(TB_BasicBlock* expected_dom, TB_BasicBlock* bb) {
while (bb->dom_depth > expected_dom->dom_depth) {
bb = bb->dom;
}
return bb == expected_dom;
}
static bool slow_dommy(TB_CFG* cfg, TB_Node* expected_dom, TB_Node* bb) {
TB_BasicBlock* a = nl_map_get_checked(cfg->node_to_block, expected_dom);
TB_BasicBlock* b = nl_map_get_checked(cfg->node_to_block, bb);
return slow_dommy2(a, b);
}
////////////////////////////////
// Unordered SoN successor iterator
////////////////////////////////
#define FOR_SUCC(it, n) for (SuccIter it = succ_iter(n); succ_iter_next(&it);)
typedef struct {
TB_Node* n;
TB_Node* succ;
int index; // -1 if we're not walking CProjs
} SuccIter;
static SuccIter succ_iter(TB_Node* n) {
if (n->dt.type == TB_TAG_TUPLE) {
return (SuccIter){ n, NULL, 0 };
} else if (!cfg_is_endpoint(n)) {
return (SuccIter){ n, NULL, -1 };
} else {
return (SuccIter){ n, NULL, n->user_count };
}
}
static bool succ_iter_next(SuccIter* restrict it) {
TB_Node* n = it->n;
// not branching? ok pick single next control
if (it->index == -1) {
it->index = n->user_count; // terminate
it->succ = cfg_next_control(n);
return true;
}
// if we're in this loop, we know we're scanning for CProjs
while (it->index < n->user_count) {
TB_Node* un = USERN(&n->users[it->index++]);
if (cfg_is_cproj(un)) {
it->succ = un;
return true;
}
}
return false;
}
// lovely properties
bool cfg_is_region(TB_Node* n);
bool cfg_is_natural_loop(TB_Node* n);
bool cfg_is_terminator(TB_Node* n);
bool cfg_is_endpoint(TB_Node* n);
// internal debugging mostly
void tb_print_dumb_node(Lattice** types, TB_Node* n);
// computes basic blocks but also dominators and loop nests if necessary.
TB_CFG tb_compute_cfg(TB_Function* f, TB_Worklist* ws, TB_Arena* tmp_arena, bool dominators);
void tb_free_cfg(TB_CFG* cfg);
// TB_Worklist API
void worklist_alloc(TB_Worklist* restrict ws, size_t initial_cap);
void worklist_free(TB_Worklist* restrict ws);
void worklist_clear(TB_Worklist* restrict ws);
void worklist_clear_visited(TB_Worklist* restrict ws);
bool worklist_test(TB_Worklist* restrict ws, TB_Node* n);
bool worklist_test_n_set(TB_Worklist* restrict ws, TB_Node* n);
void worklist_push(TB_Worklist* restrict ws, TB_Node* restrict n);
int worklist_count(TB_Worklist* ws);
TB_Node* worklist_pop(TB_Worklist* ws);
void subsume_node(TB_Function* f, TB_Node* n, TB_Node* new_n);
void subsume_node2(TB_Function* f, TB_Node* n, TB_Node* new_n);
void subsume_node_without_phis(TB_Function* f, TB_Node* n, TB_Node* new_n);
void tb__gvn_remove(TB_Function* f, TB_Node* n);
// Scheduler's cost model crap (talk about these in codegen_impl.h)
typedef int (*TB_GetLatency)(TB_Function* f, TB_Node* n, TB_Node* end);
typedef uint64_t (*TB_GetUnitMask)(TB_Function* f, TB_Node* n);
// Local scheduler
void tb_list_scheduler(TB_Function* f, TB_CFG* cfg, TB_Worklist* ws, DynArray(PhiVal*) phi_vals, TB_BasicBlock* bb, TB_GetLatency get_lat, TB_GetUnitMask get_unit_mask, int unit_count);
void tb_greedy_scheduler(TB_Function* f, TB_CFG* cfg, TB_Worklist* ws, DynArray(PhiVal*) phi_vals, TB_BasicBlock* bb);
void tb_dataflow(TB_Function* f, TB_Arena* arena, TB_CFG cfg);
// Global scheduler
void tb_clear_anti_deps(TB_Function* f, TB_Worklist* ws);
void tb_renumber_nodes(TB_Function* f, TB_Worklist* ws);
void tb_compact_nodes(TB_Function* f, TB_Worklist* ws);
void tb_global_schedule(TB_Function* f, TB_Worklist* ws, TB_CFG cfg, bool early_only, bool dataflow, TB_GetLatency get_lat);
void tb_compute_synthetic_loop_freq(TB_Function* f, TB_CFG* cfg);
// BB placement
int bb_placement_rpo(TB_Arena* arena, TB_CFG* cfg, int* dst_order);
int bb_placement_trace(TB_Arena* arena, TB_CFG* cfg, int* dst_order);
// makes arch-friendly IR
void tb_opt_legalize(TB_Function* f, TB_Arch arch);
int tb_opt_peeps(TB_Function* f);
int tb_opt_locals(TB_Function* f);
// Integrated IR debugger
void tb_integrated_dbg(TB_Function* f, TB_Node* n);
Lattice* latuni_get(TB_Function* f, TB_Node* n);
void tb__print_regmask(RegMask* mask);

View File

@ -1,3 +1,7 @@
#if INTELLISENSE_DIRECTIVES
#include "../../gen_c_library/gen/gen_singleheader.h"
#endif
#define GEN_IMPLEMENTATION
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
#include "gen_singleheader.h"
@ -16,7 +20,7 @@ int main()
gen_CodeVar hello_var = gen_parse_variable(code(
char const* hello_gencpp_str = "HELLO GENCPP C11 !";
));
gen_builder_print( & src_hello, (gen_Code)hello_var );
gen_builder_print( & src_hello, hello_var );
gen_builder_write(& src_hello);
gen_CodeBody body = gen_parse_file("gen/hello.c");

View File

@ -0,0 +1,48 @@
#define GEN_IMPLEMENTATION
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
#include "gen_singleheader.h"
#define gen_iterator( Type, container, iter ) \
gen_begin_ ## Type(container); \
iter != gen_end_ ## Type(container); \
code = gen_next_ ## Type(container, iter)
int main()
{
gen_Context ctx = {0};
gen_init(& ctx);
gen_register_macros( args(
((gen_Macro){ txt("USERN"), MT_Expression, MF_Functional }),
((gen_Macro){ txt("USERI"), MT_Expression, MF_Functional }),
((gen_Macro){ txt("USERI"), MT_Expression, MF_Functional }),
((gen_Macro){ txt("FOR_USERS"), MT_Statement, MF_Functional }),
((gen_Macro){ txt("FOR_SUCC"), MT_Statement, MF_Functional })
));
gen_CodeBody h_passes = gen_parse_file("Cuik/tb/opt/passes.h");
for (gen_Code code = gen_iterator(CodeBody, h_passes, code)) switch (code->Type) {
case CT_Function_Fwd:
case CT_Function:
gen_log_fmt("%S:\t%S RETURN_TYPE: %S PARAMS:%S\n"
, gen_codetype_to_str(code->Type)
, code->Name
, gen_strbuilder_to_str( gen_typename_to_strbuilder((gen_CodeTypename) code->ReturnType))
, gen_strbuilder_to_str( gen_params_to_strbuilder( (gen_CodeParams) code->Params))
);
break;
case CT_Variable:
gen_log_fmt("%S:\t%S Type:%S\n", gen_codetype_to_str(code->Type), code->Name, code->ValueType);
break;
case CT_Struct_Fwd:
case CT_Struct:
case CT_Typedef:
gen_log_fmt("%S: %S\n", gen_codetype_to_str(code->Type), code->Name);
break;
}
gen_deinit(& ctx);
return 0;
}