mirror of
https://github.com/Ed94/gencpp.git
synced 2025-06-14 18:51:47 -07:00
Compare commits
78 Commits
3c249d2fae
...
main
Author | SHA1 | Date | |
---|---|---|---|
2ad164dc39 | |||
878bc4c8ae | |||
ec8dd1e9cd | |||
c0ea2ce3ff | |||
b5652a4dad | |||
dda70fce36 | |||
3bce2e9b8a | |||
f3f8f2fff2 | |||
c600a3e0dc | |||
372cda734e | |||
6481313969 | |||
5c17983a73 | |||
b6d95e8d70 | |||
6f2d81434e | |||
b8695a33db | |||
1f958e121c | |||
e457191f5d | |||
0d8f30b25c | |||
d08efcb5ef | |||
13ebd105c4 | |||
bdd9c9bcdf | |||
16bc66c80e | |||
f8c42a53c6 | |||
eca538c6af | |||
ce2be411d7 | |||
16fc3fa379 | |||
62b36ec8bb | |||
b6b246fb38 | |||
d91d3c6b6f | |||
3ab2673fd3 | |||
ca7ff99a79 | |||
177820cd6e | |||
d254d3aec4 | |||
299f1b1ef7 | |||
9c968967e2 | |||
04ae75c698 | |||
6d551e95b9 | |||
a7cb7b0411 | |||
46e816d7ce | |||
28aa2c4dec | |||
d410590a86 | |||
e271fa39e4 | |||
08dcc3152f | |||
0829603262 | |||
3133977b0f | |||
e4088185af | |||
c55151886f | |||
6689235691 | |||
6533a3be29 | |||
adbcb2a83b | |||
15847f10b9 | |||
8952cf5f1b | |||
2bdd49fd19 | |||
0f95c916dd | |||
527fb3b132 | |||
abffa74ad8 | |||
772d0de5c1 | |||
cb50f93af5 | |||
e4f564b165 | |||
0b78b74fbc | |||
5d8883ec45 | |||
c90c210e04 | |||
980d1d7134 | |||
b027778328 | |||
a6143e12b4 | |||
868b93cdd0 | |||
0b03b3cd92 | |||
572e957c17 | |||
63bc3bebed | |||
70872c29d1 | |||
e9752cb906 | |||
7946954017 | |||
4fe1a4da65 | |||
956ab73130 | |||
f93250da07 | |||
1b4f9a2e77 | |||
c8cf55403b | |||
76257123da |
7
.gitignore
vendored
7
.gitignore
vendored
@ -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
|
||||
@ -39,3 +40,7 @@ gen_c_library/gen
|
||||
**/*.vcxproj
|
||||
**/*.vcxproj.filters
|
||||
**/*.vcxproj.user
|
||||
test/c_library/gen
|
||||
test/cpp_library/gen
|
||||
|
||||
!scripts/helpers/refactor.exe
|
||||
|
74
.vscode/c_cpp_properties.json
vendored
74
.vscode/c_cpp_properties.json
vendored
@ -1,74 +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 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"
|
||||
],
|
||||
"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 clang",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/base/**"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE",
|
||||
"GEN_TIME",
|
||||
"GEN_IMPLEMENTATION",
|
||||
// "GEN_DONT_USE_NAMESPACE"
|
||||
"GEN_INTELLISENSE_DIRECTIVES",
|
||||
"INTELLISENSE_DIRECTIVES"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.19041.0",
|
||||
"compilerPath": "clang++.exe",
|
||||
"intelliSenseMode": "windows-clang-x64",
|
||||
"compileCommands": "${workspaceFolder}/.vscode/tasks.json"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
35
.vscode/launch.json
vendored
35
.vscode/launch.json
vendored
@ -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
97
.vscode/settings.json
vendored
@ -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
144
.vscode/tasks.json
vendored
@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
16
LICENSE
16
LICENSE
@ -26,3 +26,19 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Source URL: https://github.com/Ed94/gencpp
|
||||
|
||||
Acknowledgements
|
||||
|
||||
* The dependencies for gencpp source are derived from the zpl library: https://github.com/zpl-c/zpl
|
||||
|
||||
Special thanks to:
|
||||
|
||||
* The Handmade Community.
|
||||
|
||||
* Casey Muratori, Ginger Bill (Bill Hall), Mr. 4th (Allen Webster), Ryan Fluery: Influnced conceptually how to handle staged metaprograming.
|
||||
|
||||
* Jonathan Blow: Jai's metaprogramming influenced the design of this library.
|
||||
|
||||
* My friends for putting up with discord spam on this library.
|
||||
|
47
Readme.md
47
Readme.md
@ -1,6 +1,9 @@
|
||||
# gencpp
|
||||
|
||||
An attempt at simple staged metaprogramming for C/C++.
|
||||
An attempt at simple staged metaprogramming for C/C++. Reflect and generate code for your codebase at runtime!
|
||||
|
||||

|
||||

|
||||
|
||||
The library API is a composition of code element constructors, and a non-standards-compliant single-pass C/C++ parser.
|
||||
These build up a code AST to then serialize with a file builder, or can be traversed for staged-reflection of C/C++ code.
|
||||
@ -8,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
|
||||
@ -49,7 +60,11 @@ Within `program.cpp` :
|
||||
|
||||
u32 gen_main()
|
||||
{
|
||||
gen::Context ctx;
|
||||
gen::init(& ctx);
|
||||
...
|
||||
gen::deinit(& ctx);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -72,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 });
|
||||
}
|
||||
```
|
||||
|
||||
@ -92,7 +107,7 @@ Code header;
|
||||
Validation through ast construction.
|
||||
|
||||
```cpp
|
||||
Code header = parse_struct( code(
|
||||
CodeStruct header = parse_struct( code(
|
||||
struct ArrayHeader
|
||||
{
|
||||
usize Num;
|
||||
@ -140,3 +155,13 @@ struct ArrayHeader
|
||||
## Building
|
||||
|
||||
See the [scripts directory](scripts/).
|
||||
|
||||
## Gallery
|
||||
|
||||
### Listing definitions in the Cuik Compiler
|
||||
|
||||
https://github.com/user-attachments/assets/2302240c-01f1-4e1b-a4b5-292eb3186648
|
||||
|
||||
### Unreal: Generating a UAttributeSet from a UDataTable
|
||||
|
||||
https://github.com/user-attachments/assets/2a07b743-825d-4f9f-beaf-3559e8748a4d
|
||||
|
@ -8,7 +8,13 @@
|
||||
|
||||
The library is fragmented into a series of headers and source files meant to be scanned in and then generated to a standard target format, or a user's desires.
|
||||
|
||||
Standard formats:
|
||||
If using the library's provided build scripts:
|
||||
|
||||
```ps1
|
||||
.\build.ps1 <compiler> <debug or omit> base
|
||||
```
|
||||
|
||||
## Content Overview
|
||||
|
||||
* **base**: Files are in granular pieces separated into four directories:
|
||||
* **dependencies**: Originally from the c-zpl library and modified thereafter.
|
||||
@ -18,16 +24,16 @@ Standard formats:
|
||||
* `<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 generatd.
|
||||
* **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.
|
||||
|
||||
@ -102,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).
|
||||
@ -117,15 +123,15 @@ 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).
|
||||
* [`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:
|
||||
* [`ETokType.csv`](./enums/ETokType.csv): Provides the enum entries and their strinng ids.
|
||||
* [`AttributeTokens.csv`](./enums/AttributeTokens.csv): Provides tokens entries that should be considered as attributes by the lexer and parser. Sspecfiically macro attributes such as those use for exporting symbols.
|
||||
* [`ast_inlines.hpp`](./components/gen/ast_inlines.hpp): Member trivial `operator` definitions for C++ code types. Does not use a 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:
|
||||
* [ETokType.csv](./enums/ETokType.csv): Provides the enum entries and their strinng ids.
|
||||
* [AttributeTokens.csv](./enums/AttributeTokens.csv): Provides tokens entries that should be considered as attributes by the lexer and parser. Sspecfiically macro attributes such as those use for exporting symbols.
|
||||
* [ast_inlines.hpp](./components/gen/ast_inlines.hpp): Member trivial `operator` definitions for C++ code types. Does not use a csv.
|
||||
|
||||
[`misc.hpp`](./helpers/misc.hpp): Has shared functions used by the library generation meta-programs throughout this codebase.
|
||||
[misc.hpp](./helpers/misc.hpp): Has shared functions used by the library generation meta-programs throughout this codebase.
|
||||
|
||||
If using the library's provided build scripts:
|
||||
|
||||
@ -154,9 +160,53 @@ Names or Content fields are interned strings and thus showed be cached using `ca
|
||||
|
||||
`def_operator` is the most sophisticated upfront constructor as it has multiple permutations of definitions that could be created that are not trivial to determine if valid.
|
||||
|
||||
The parser is documented under [`docs/Parsing.md`](../docs/Parsing.md) and [`docs/Parser_Algo.md`](../docs/Parser_Algo.md).
|
||||
The parser is documented under [`docs/Parsing.md`](../docs/Parsing.md) and [`docs/Parser_Algo.md`](../docs/Parser_Algo.md). Read that and the entire library if you want to extend it.
|
||||
|
||||
### Attributes
|
||||
|
||||
To add additional macro attributes, all that has to be done is modifying [`AttributeTokens.csv`](./enums/AttributeTokens.csv).
|
||||
|
||||
### Specifiers
|
||||
|
||||
To add additional macro specifiers, the following needs to be done:
|
||||
|
||||
1. Adjust [especifier.hpp](./components/gen/especifier.hpp)
|
||||
2. Adjust [etoktype.cpp](./components/gen/etoktype.cpp)
|
||||
3. Adjust [parser_case_macros.cpp](./components/parser_case_macros.cpp)
|
||||
|
||||
If the specifier is a new trailing specifier on function definitions:
|
||||
|
||||
Head into [base_codegen.hpp](./helpers/base_codegen.hpp): `gen_especifier`. There will be an `is_trailing` function that needs to be adjusted with an additional case for the user's new trailing specifier.
|
||||
|
||||
### Code Types
|
||||
|
||||
These require the following to be handled to the equivalent extent as the other types:
|
||||
|
||||
1. Adjust [ECodeTypes.csv](./enums/ECodeTypes.csv) with the new types
|
||||
2. Define a new `AST_<Name>` and `Code<Name>`. See
|
||||
* [ast.hpp](./components/ast.hpp): Initial forwards and user defined conversion for Code.
|
||||
* [ast_types.hpp](./components/ast_types.hpp): Define the `AST_<Name>` struct.
|
||||
* [code_types.hpp](./components/code_types.hpp): Defne the `CodeType` struct. If its needs an iterator see: `struct CodeBody` & `struct CodeParams`.
|
||||
3. [ast_case_macros.cpp](./components/ast_case_macros.cpp): Review cases here if the new code type needs to be considered.
|
||||
4. [ast.cpp](./components/ast.cpp): Need to review
|
||||
* `code_debug_str`
|
||||
* `code_is_equal`
|
||||
* `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.
|
||||
7. [interface.cpp](./components/interface.hpp): Define the `Code<Name>` upfront and parsing interface.
|
||||
8. [interface.upfront.cpp](./components/interface.upfront.cpp): Define the upfront constructor implementation.
|
||||
9. [interface.parsing.cpp](./components/interface.parsing.cpp): Define the parsing interface implementation.
|
||||
10. [lexer.cpp](./components/lexer.cpp): Adjust the lexer as needed.
|
||||
11. [parser.cpp](./components/parser.cpp): Adjust the parser as needed.
|
||||
|
||||
## A note on compilation and runtime generation speed
|
||||
|
||||
The library is designed to be fast to compile and generate code at runtime as fast as resonable possible on a debug build.
|
||||
The library is designed to be fast to compile and generate code at runtime as fast as possible on a debug build.
|
||||
Its recommended that your metaprogam be compiled using a single translation unit (unity build).
|
||||
|
||||
## Whats with the expression / executions support #ifd and enums?
|
||||
|
||||
The library is a *work in progress* and those are unfinished hypotheticals for adding the ability to manage or parse the AST of expresions or execution scope code.
|
||||
They are entirely untested and not meant to be used yet, futher there is no parsing support or an upfront interface for what CodeTypes are defined so far.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# include "builder.hpp"
|
||||
#endif
|
||||
|
||||
@ -15,7 +15,9 @@ Builder builder_open( char const* path )
|
||||
return result;
|
||||
}
|
||||
|
||||
result.Buffer = strbuilder_make_reserve( _ctx->Allocator_Temp, _ctx->InitSize_BuilderBuffer );
|
||||
Context* ctx = get_context();
|
||||
GEN_ASSERT_NOT_NULL(ctx);
|
||||
result.Buffer = strbuilder_make_reserve( ctx->Allocator_Temp, ctx->InitSize_BuilderBuffer );
|
||||
|
||||
// log_fmt("$Builder - Opened file: %s\n", result.File.filename );
|
||||
return result;
|
@ -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,17 +21,18 @@ 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_print_fmt ( Builder* builder, char const* fmt, ... ) {
|
||||
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;
|
||||
va_start( va, fmt );
|
||||
builder_print_fmt_va( builder, fmt, va );
|
||||
va_end( va );
|
||||
}
|
||||
void builder_write( Builder* builder );
|
||||
|
||||
struct Builder
|
||||
{
|
||||
@ -56,10 +57,10 @@ struct Builder
|
||||
};
|
||||
|
||||
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
|
||||
void builder_pad_lines( Builder& builder, s32 num ) { return builder_pad_lines(& builder, num); }
|
||||
void builder_print ( Builder& builder, Code code ) { return builder_print(& builder, code); }
|
||||
void builder_write ( Builder& builder ) { return builder_write(& builder ); }
|
||||
void builder_print_fmt( Builder& builder, char const* fmt, ...) {
|
||||
forceinline void builder_pad_lines( Builder& builder, s32 num ) { return builder_pad_lines(& builder, num); }
|
||||
forceinline void builder_print ( Builder& builder, Code code ) { return builder_print(& builder, code); }
|
||||
forceinline void builder_write ( Builder& builder ) { return builder_write(& builder ); }
|
||||
forceinline void builder_print_fmt( Builder& builder, char const* fmt, ...) {
|
||||
va_list va;
|
||||
va_start( va, fmt );
|
||||
builder_print_fmt_va( & builder, fmt, va );
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "helpers/push_ignores.inline.hpp"
|
||||
# include "components/header_start.hpp"
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# include "scanner.hpp"
|
||||
#endif
|
||||
|
||||
@ -20,11 +20,11 @@ Code scan_file( char const* path )
|
||||
GEN_FATAL("scan_file: %s is empty", path );
|
||||
}
|
||||
|
||||
StrBuilder str = strbuilder_make_reserve( _ctx->Allocator_Temp, fsize );
|
||||
StrBuilder str = strbuilder_make_reserve( get_context()->Allocator_Temp, fsize );
|
||||
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;
|
||||
@ -117,7 +117,7 @@ Code scan_file( char const* path )
|
||||
}
|
||||
|
||||
CodeBody parse_file( const char* path ) {
|
||||
FileContents file = file_read_contents( _ctx->Allocator_Temp, true, path );
|
||||
FileContents file = file_read_contents( get_context()->Allocator_Temp, true, path );
|
||||
Str content = { (char const*)file.data, file.size };
|
||||
CodeBody code = parse_global_body( content );
|
||||
log_fmt("\nParsed: %s\n", path);
|
@ -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
|
@ -1,6 +1,5 @@
|
||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||
#define GEN_EXPOSE_BACKEND
|
||||
#define GEN_C_LIKE_CPP 1
|
||||
#include "gen.cpp"
|
||||
#include "helpers/push_ignores.inline.hpp"
|
||||
@ -31,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,
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "static_data.cpp"
|
||||
#endif
|
||||
@ -36,7 +36,6 @@ Str code_debug_str(Code self)
|
||||
case CT_Execution:
|
||||
case CT_Comment:
|
||||
case CT_PlatformAttributes:
|
||||
case CT_Preprocess_Define:
|
||||
case CT_Preprocess_Include:
|
||||
case CT_Preprocess_Pragma:
|
||||
case CT_Preprocess_If:
|
||||
@ -52,6 +51,11 @@ Str code_debug_str(Code self)
|
||||
strbuilder_append_fmt( result, "\n\tContent: %S", self->Content );
|
||||
break;
|
||||
|
||||
case CT_Preprocess_Define:
|
||||
// TODO(ED): Needs implementaton
|
||||
log_failure("code_debug_str: NOT IMPLEMENTED for CT_Preprocess_Define");
|
||||
break;
|
||||
|
||||
case CT_Class:
|
||||
case CT_Struct:
|
||||
if ( self->Prev )
|
||||
@ -259,6 +263,11 @@ Str code_debug_str(Code self)
|
||||
strbuilder_append_fmt( result, "\n\tValue : %S", self->Value ? strbuilder_to_str( code_to_strbuilder(self->Value)) : txt("Null") );
|
||||
break;
|
||||
|
||||
case CT_Parameters_Define:
|
||||
// TODO(ED): Needs implementaton
|
||||
log_failure("code_debug_str: NOT IMPLEMENTED for CT_Parameters_Define");
|
||||
break;
|
||||
|
||||
case CT_Specifiers:
|
||||
{
|
||||
strbuilder_append_fmt( result, "\n\tNumEntries: %d", self->NumEntries );
|
||||
@ -370,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
|
||||
@ -497,6 +506,10 @@ void code_to_strbuilder_ptr( Code self, StrBuilder* result )
|
||||
params_to_strbuilder_ref(cast(CodeParams, self), result );
|
||||
break;
|
||||
|
||||
case CT_Parameters_Define:
|
||||
define_params_to_strbuilder_ref(cast(CodeDefineParams, self), result);
|
||||
break;
|
||||
|
||||
case CT_Preprocess_Define:
|
||||
define_to_strbuilder_ref(cast(CodeDefine, self), result );
|
||||
break;
|
||||
@ -987,11 +1000,17 @@ bool code_is_equal( Code self, Code other )
|
||||
return true;
|
||||
}
|
||||
|
||||
case CT_Parameters_Define:
|
||||
{
|
||||
// TODO(ED): Needs implementaton
|
||||
log_failure("code_is_equal: NOT IMPLEMENTED for CT_Parameters_Define");
|
||||
return false;
|
||||
}
|
||||
|
||||
case CT_Preprocess_Define:
|
||||
{
|
||||
check_member_str( Name );
|
||||
check_member_content( Content );
|
||||
|
||||
check_member_content( Body->Content );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "types.hpp"
|
||||
#include "gen/ecode.hpp"
|
||||
@ -26,6 +26,7 @@ struct AST_Constructor;
|
||||
// struct AST_BaseClass;
|
||||
struct AST_Class;
|
||||
struct AST_Define;
|
||||
struct AST_DefineParams;
|
||||
struct AST_Destructor;
|
||||
struct AST_Enum;
|
||||
struct AST_Exec;
|
||||
@ -42,7 +43,7 @@ struct AST_Pragma;
|
||||
struct AST_PreprocessCond;
|
||||
struct AST_Specifiers;
|
||||
|
||||
#if GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
#ifdef GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
struct AST_Expr;
|
||||
struct AST_Expr_Assign;
|
||||
struct AST_Expr_Alignof;
|
||||
@ -98,6 +99,7 @@ typedef AST_Comment* CodeComment;
|
||||
typedef AST_Class* CodeClass;
|
||||
typedef AST_Constructor* CodeConstructor;
|
||||
typedef AST_Define* CodeDefine;
|
||||
typedef AST_DefineParams* CodeDefineParams;
|
||||
typedef AST_Destructor* CodeDestructor;
|
||||
typedef AST_Enum* CodeEnum;
|
||||
typedef AST_Exec* CodeExec;
|
||||
@ -120,6 +122,7 @@ struct CodeComment;
|
||||
struct CodeClass;
|
||||
struct CodeConstructor;
|
||||
struct CodeDefine;
|
||||
struct CodeDefineParams;
|
||||
struct CodeDestructor;
|
||||
struct CodeEnum;
|
||||
struct CodeExec;
|
||||
@ -137,7 +140,7 @@ struct CodePragma;
|
||||
struct CodeSpecifiers;
|
||||
#endif
|
||||
|
||||
#if GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
#ifdef GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
|
||||
#if GEN_COMPILER_C
|
||||
typedef AST_Expr* CodeExpr;
|
||||
@ -190,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
|
||||
@ -205,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
|
||||
@ -236,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
|
||||
@ -284,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
|
||||
@ -305,6 +310,7 @@ struct Code
|
||||
operator CodeClass() const;
|
||||
operator CodeConstructor() const;
|
||||
operator CodeDefine() const;
|
||||
operator CodeDefineParams() const;
|
||||
operator CodeDestructor() const;
|
||||
operator CodeExec() const;
|
||||
operator CodeEnum() const;
|
||||
@ -333,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
|
||||
@ -365,6 +371,7 @@ int AST_ArrSpecs_Cap =
|
||||
|
||||
/*
|
||||
Simple AST POD with functionality to seralize into C++ syntax.
|
||||
TODO(Ed): Eventually haven't a transparent AST like this will longer be viable once statements & expressions are in (most likely....)
|
||||
*/
|
||||
struct AST
|
||||
{
|
||||
@ -372,8 +379,8 @@ struct AST
|
||||
struct
|
||||
{
|
||||
Code InlineCmt; // Class, Constructor, Destructor, Enum, Friend, Functon, Operator, OpCast, Struct, Typedef, Using, Variable
|
||||
Code Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable
|
||||
Code Specs; // Destructor, Function, Operator, Typename, Variable
|
||||
Code Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable // TODO(Ed): Parameters can have attributes
|
||||
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.
|
||||
@ -384,18 +391,18 @@ struct AST
|
||||
union {
|
||||
Code Macro; // Parameter
|
||||
Code BitfieldSize; // Variable (Class/Struct Data Member)
|
||||
Code Params; // Constructor, Function, Operator, Template, Typename
|
||||
Code Params; // Constructor, Define, Function, Operator, Template, Typename
|
||||
Code UnderlyingTypeMacro; // Enum
|
||||
};
|
||||
union {
|
||||
Code ArrExpr; // Typename
|
||||
Code Body; // Class, Constructor, Destructor, Enum, Friend, Function, Namespace, Struct, Union
|
||||
Code Body; // Class, Constructor, Define, Destructor, Enum, Friend, Function, Namespace, Struct, Union
|
||||
Code Declaration; // Friend, Template
|
||||
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)
|
||||
};
|
||||
};
|
||||
@ -415,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;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "code_types.hpp"
|
||||
#endif
|
||||
@ -29,26 +29,27 @@
|
||||
struct AST_Body
|
||||
{
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
Code Front;
|
||||
Code Back;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||
s32 NumEntries;
|
||||
StrCached Name;
|
||||
Code Front;
|
||||
Code Back;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||
s32 NumEntries;
|
||||
};
|
||||
static_assert( sizeof(AST_Body) == sizeof(AST), "ERROR: AST_Body is not the same size as AST");
|
||||
|
||||
// TODO(Ed): Support chaining attributes (Use parameter linkage pattern)
|
||||
struct AST_Attributes
|
||||
{
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
StrCached Content;
|
||||
StrCached Content;
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
@ -64,7 +65,7 @@ struct AST_BaseClass
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
@ -81,7 +82,7 @@ struct AST_Comment
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
StrCached Content;
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
@ -99,14 +100,14 @@ 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*) ];
|
||||
char _PAD_PARAMS_[ sizeof(AST*) ];
|
||||
CodeBody Body;
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeTypename Prev;
|
||||
CodeTypename Next;
|
||||
Token* Tok;
|
||||
@ -129,10 +130,10 @@ struct AST_Constructor
|
||||
Code InitializerList;
|
||||
CodeParams Params;
|
||||
Code Body;
|
||||
char _PAD_PROPERTIES_2_ [ sizeof(AST*) * 2 ];
|
||||
char _PAD_PROPERTIES_2_ [ sizeof(AST*) * 2 ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
@ -146,17 +147,39 @@ struct AST_Define
|
||||
{
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
StrCached Content;
|
||||
struct
|
||||
{
|
||||
char _PAD_PROPERTIES_ [ sizeof(AST*) * 4 ];
|
||||
CodeDefineParams Params;
|
||||
Code Body; // Should be completely serialized for now to a: StrCached Content.
|
||||
char _PAD_PROPERTIES_2_ [ sizeof(AST*) * 1 ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||
};
|
||||
static_assert( sizeof(AST_Define) == sizeof(AST), "ERROR: AST_Define is not the same size as AST");
|
||||
|
||||
struct AST_DefineParams
|
||||
{
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
CodeDefineParams Last;
|
||||
CodeDefineParams Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||
s32 NumEntries;
|
||||
};
|
||||
static_assert( sizeof(AST_Define) == sizeof(AST), "ERROR: AST_Define is not the same size as AST");
|
||||
static_assert( sizeof(AST_DefineParams) == sizeof(AST), "ERROR: AST_DefineParams is not the same size as AST");
|
||||
|
||||
struct AST_Destructor
|
||||
{
|
||||
@ -169,10 +192,10 @@ struct AST_Destructor
|
||||
CodeSpecifiers Specs;
|
||||
char _PAD_PROPERTIES_2_ [ sizeof(AST*) * 2 ];
|
||||
Code Body;
|
||||
char _PAD_PROPERTIES_3_ [ sizeof(AST*) ];
|
||||
char _PAD_PROPERTIES_3_ [ sizeof(AST*) ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
@ -194,17 +217,17 @@ struct AST_Enum
|
||||
CodeTypename UnderlyingType;
|
||||
Code UnderlyingTypeMacro;
|
||||
CodeBody Body;
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
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");
|
||||
|
||||
@ -214,7 +237,7 @@ struct AST_Exec
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
StrCached Content;
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
@ -224,7 +247,7 @@ struct AST_Exec
|
||||
};
|
||||
static_assert( sizeof(AST_Exec) == sizeof(AST), "ERROR: AST_Exec is not the same size as AST");
|
||||
|
||||
#if GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
#ifdef GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
struct AST_Expr
|
||||
{
|
||||
union {
|
||||
@ -492,13 +515,13 @@ struct AST_Extern
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||
};
|
||||
static_assert( sizeof(AST_Extern) == sizeof(AST), "ERROR: AST_Extern is not the same size as AST");
|
||||
|
||||
@ -508,13 +531,13 @@ struct AST_Include
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
StrCached Content;
|
||||
};
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||
};
|
||||
static_assert( sizeof(AST_Include) == sizeof(AST), "ERROR: AST_Include is not the same size as AST");
|
||||
|
||||
@ -527,16 +550,16 @@ struct AST_Friend
|
||||
CodeComment InlineCmt;
|
||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ];
|
||||
Code Declaration;
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||
};
|
||||
static_assert( sizeof(AST_Friend) == sizeof(AST), "ERROR: AST_Friend is not the same size as AST");
|
||||
|
||||
@ -550,19 +573,19 @@ struct AST_Fn
|
||||
CodeAttributes Attributes;
|
||||
CodeSpecifiers Specs;
|
||||
CodeTypename ReturnType;
|
||||
CodeParams Params;
|
||||
CodeParams Params;
|
||||
CodeBody Body;
|
||||
char _PAD_PROPERTIES_ [ sizeof(AST*) ];
|
||||
Code SuffixSpecs; // Thanks Unreal
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||
};
|
||||
static_assert( sizeof(AST_Fn) == sizeof(AST), "ERROR: AST_Fn is not the same size as AST");
|
||||
|
||||
@ -571,14 +594,14 @@ struct AST_Module
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||
};
|
||||
static_assert( sizeof(AST_Module) == sizeof(AST), "ERROR: AST_Module is not the same size as AST");
|
||||
|
||||
@ -587,45 +610,45 @@ struct AST_NS
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
struct {
|
||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 5 ];
|
||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 5 ];
|
||||
CodeBody Body;
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||
};
|
||||
static_assert( sizeof(AST_NS) == sizeof(AST), "ERROR: AST_NS is not the same size as AST");
|
||||
|
||||
struct AST_Operator
|
||||
{
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
struct
|
||||
{
|
||||
CodeComment InlineCmt;
|
||||
CodeAttributes Attributes;
|
||||
CodeSpecifiers Specs;
|
||||
CodeTypename ReturnType;
|
||||
CodeParams Params;
|
||||
CodeBody Body;
|
||||
char _PAD_PROPERTIES_ [ sizeof(AST*) ];
|
||||
CodeComment InlineCmt;
|
||||
CodeAttributes Attributes;
|
||||
CodeSpecifiers Specs;
|
||||
CodeTypename ReturnType;
|
||||
CodeParams Params;
|
||||
CodeBody Body;
|
||||
char _PAD_PROPERTIES_ [ sizeof(AST*) ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
Operator Op;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
Operator Op;
|
||||
};
|
||||
static_assert( sizeof(AST_Operator) == sizeof(AST), "ERROR: AST_Operator is not the same size as AST");
|
||||
|
||||
@ -635,22 +658,22 @@ struct AST_OpCast
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
struct
|
||||
{
|
||||
CodeComment InlineCmt;
|
||||
char _PAD_PROPERTIES_[ sizeof(AST*) ];
|
||||
CodeSpecifiers Specs;
|
||||
CodeTypename ValueType;
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
CodeBody Body;
|
||||
char _PAD_PROPERTIES_3_[ sizeof(AST*) ];
|
||||
CodeComment InlineCmt;
|
||||
char _PAD_PROPERTIES_[ sizeof(AST*) ];
|
||||
CodeSpecifiers Specs;
|
||||
CodeTypename ValueType;
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
CodeBody Body;
|
||||
char _PAD_PROPERTIES_3_[ sizeof(AST*) ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||
};
|
||||
static_assert( sizeof(AST_OpCast) == sizeof(AST), "ERROR: AST_OpCast is not the same size as AST");
|
||||
|
||||
@ -660,7 +683,8 @@ struct AST_Params
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
struct
|
||||
{
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) * 3 ];
|
||||
// TODO(Ed): Support attributes for parameters (Some prefix macros can be converted to that...)
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) * 3 ];
|
||||
CodeTypename ValueType;
|
||||
Code Macro;
|
||||
Code Value;
|
||||
@ -668,14 +692,14 @@ struct AST_Params
|
||||
// char _PAD_PROPERTIES_3_[sizeof( AST* )];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
CodeParams Last;
|
||||
CodeParams Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||
s32 NumEntries;
|
||||
StrCached Name;
|
||||
CodeParams Last;
|
||||
CodeParams Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||
s32 NumEntries;
|
||||
};
|
||||
static_assert( sizeof(AST_Params) == sizeof(AST), "ERROR: AST_Params is not the same size as AST");
|
||||
|
||||
@ -685,13 +709,13 @@ struct AST_Pragma
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
StrCached Content;
|
||||
};
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||
};
|
||||
static_assert( sizeof(AST_Pragma) == sizeof(AST), "ERROR: AST_Pragma is not the same size as AST");
|
||||
|
||||
@ -699,40 +723,40 @@ struct AST_PreprocessCond
|
||||
{
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
StrCached Content;
|
||||
StrCached Content;
|
||||
};
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||
};
|
||||
static_assert( sizeof(AST_PreprocessCond) == sizeof(AST), "ERROR: AST_PreprocessCond is not the same size as AST");
|
||||
|
||||
struct AST_Specifiers
|
||||
{
|
||||
Specifier ArrSpecs[ AST_ArrSpecs_Cap ];
|
||||
Specifier ArrSpecs[ AST_ArrSpecs_Cap ];
|
||||
CodeSpecifiers NextSpecs;
|
||||
StrCached Name;
|
||||
CodeSpecifiers NextSpecs;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||
s32 NumEntries;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||
s32 NumEntries;
|
||||
};
|
||||
static_assert( sizeof(AST_Specifiers) == sizeof(AST), "ERROR: AST_Specifier is not the same size as AST");
|
||||
|
||||
#if GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
#ifdef GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
struct AST_Stmt
|
||||
{
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeExpr Prev;
|
||||
CodeExpr Next;
|
||||
Token* Tok;
|
||||
@ -747,7 +771,7 @@ struct AST_Stmt_Break
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeExpr Prev;
|
||||
CodeExpr Next;
|
||||
Token* Tok;
|
||||
@ -762,7 +786,7 @@ struct AST_Stmt_Case
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeExpr Prev;
|
||||
CodeExpr Next;
|
||||
Token* Tok;
|
||||
@ -777,7 +801,7 @@ struct AST_Stmt_Continue
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeExpr Prev;
|
||||
CodeExpr Next;
|
||||
Token* Tok;
|
||||
@ -792,7 +816,7 @@ struct AST_Stmt_Decl
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeExpr Prev;
|
||||
CodeExpr Next;
|
||||
Token* Tok;
|
||||
@ -807,7 +831,7 @@ struct AST_Stmt_Do
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeExpr Prev;
|
||||
CodeExpr Next;
|
||||
Token* Tok;
|
||||
@ -822,7 +846,7 @@ struct AST_Stmt_Expr
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeExpr Prev;
|
||||
CodeExpr Next;
|
||||
Token* Tok;
|
||||
@ -837,7 +861,7 @@ struct AST_Stmt_Else
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeExpr Prev;
|
||||
CodeExpr Next;
|
||||
Token* Tok;
|
||||
@ -852,7 +876,7 @@ struct AST_Stmt_If
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeExpr Prev;
|
||||
CodeExpr Next;
|
||||
Token* Tok;
|
||||
@ -867,7 +891,7 @@ struct AST_Stmt_For
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeExpr Prev;
|
||||
CodeExpr Next;
|
||||
Token* Tok;
|
||||
@ -882,7 +906,7 @@ struct AST_Stmt_Goto
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeExpr Prev;
|
||||
CodeExpr Next;
|
||||
Token* Tok;
|
||||
@ -897,7 +921,7 @@ struct AST_Stmt_Label
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeExpr Prev;
|
||||
CodeExpr Next;
|
||||
Token* Tok;
|
||||
@ -912,7 +936,7 @@ struct AST_Stmt_Switch
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeExpr Prev;
|
||||
CodeExpr Next;
|
||||
Token* Tok;
|
||||
@ -927,7 +951,7 @@ struct AST_Stmt_While
|
||||
union {
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeExpr Prev;
|
||||
CodeExpr Next;
|
||||
Token* Tok;
|
||||
@ -946,14 +970,14 @@ struct AST_Struct
|
||||
{
|
||||
CodeComment InlineCmt;
|
||||
CodeAttributes Attributes;
|
||||
char _PAD_SPECS_ [ sizeof(AST*) ];
|
||||
CodeSpecifiers Specs; // Support for final
|
||||
CodeTypename ParentType;
|
||||
char _PAD_PARAMS_[ sizeof(AST*) ];
|
||||
char _PAD_PARAMS_[ sizeof(AST*) ];
|
||||
CodeBody Body;
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeTypename Prev;
|
||||
CodeTypename Next;
|
||||
Token* Tok;
|
||||
@ -970,20 +994,20 @@ struct AST_Template
|
||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||
struct
|
||||
{
|
||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ];
|
||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ];
|
||||
CodeParams Params;
|
||||
Code Declaration;
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||
};
|
||||
static_assert( sizeof(AST_Template) == sizeof(AST), "ERROR: AST_Template is not the same size as AST");
|
||||
|
||||
@ -1005,13 +1029,13 @@ struct AST_Type
|
||||
// CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||
b32 IsParamPack;
|
||||
};
|
||||
static_assert( sizeof(AST_Type) == sizeof(AST), "ERROR: AST_Type is not the same size as AST");
|
||||
@ -1032,13 +1056,13 @@ struct AST_Typename
|
||||
CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||
struct {
|
||||
b16 IsParamPack; // Used by typename to know if type should be considered a parameter pack.
|
||||
ETypenameTag TypeTag; // Used by typename to keep track of explicitly declared tags for the identifier (enum, struct, union)
|
||||
@ -1053,12 +1077,12 @@ struct AST_Typedef
|
||||
struct
|
||||
{
|
||||
CodeComment InlineCmt;
|
||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 2 ];
|
||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 2 ];
|
||||
Code UnderlyingType;
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) * 3 ];
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) * 3 ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
@ -1077,19 +1101,19 @@ struct AST_Union
|
||||
{
|
||||
char _PAD_INLINE_CMT_[ sizeof(AST*) ];
|
||||
CodeAttributes Attributes;
|
||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 3 ];
|
||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 3 ];
|
||||
CodeBody Body;
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||
};
|
||||
static_assert( sizeof(AST_Union) == sizeof(AST), "ERROR: AST_Union is not the same size as AST");
|
||||
|
||||
@ -1101,19 +1125,19 @@ struct AST_Using
|
||||
{
|
||||
CodeComment InlineCmt;
|
||||
CodeAttributes Attributes;
|
||||
char _PAD_SPECS_ [ sizeof(AST*) ];
|
||||
char _PAD_SPECS_ [ sizeof(AST*) ];
|
||||
CodeTypename UnderlyingType;
|
||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 3 ];
|
||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 3 ];
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||
};
|
||||
static_assert( sizeof(AST_Using) == sizeof(AST), "ERROR: AST_Using is not the same size as AST");
|
||||
|
||||
@ -1129,17 +1153,17 @@ struct AST_Var
|
||||
CodeTypename ValueType;
|
||||
Code BitfieldSize;
|
||||
Code Value;
|
||||
CodeVar NextVar;
|
||||
CodeVar NextVar;
|
||||
};
|
||||
};
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
s32 VarParenthesizedInit;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
s32 VarParenthesizedInit;
|
||||
};
|
||||
static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST");
|
||||
|
||||
|
@ -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,8 +137,9 @@ StrBuilder class_to_strbuilder( CodeClass self )
|
||||
void class_to_strbuilder_def( CodeClass self, StrBuilder* result )
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
strbuilder_append_str( result, txt("class ") );
|
||||
@ -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,8 +185,9 @@ 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_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
if ( self->Attributes )
|
||||
@ -239,18 +205,40 @@ void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result )
|
||||
}
|
||||
}
|
||||
|
||||
StrBuilder define_to_strbuilder(CodeDefine define)
|
||||
{
|
||||
return strbuilder_fmt_buf( _ctx->Allocator_Temp, "#define %S %S", define->Name, define->Content );
|
||||
}
|
||||
|
||||
void define_to_strbuilder_ref(CodeDefine define, StrBuilder* result )
|
||||
{
|
||||
strbuilder_append_fmt( result, "#define %S %S", define->Name, define->Content );
|
||||
GEN_ASSERT(define);
|
||||
GEN_ASSERT(define->Body);
|
||||
GEN_ASSERT(define->Body->Content.Ptr && define->Body->Content.Len > 0);
|
||||
if (define->Params) {
|
||||
StrBuilder params_builder = define_params_to_strbuilder(define->Params);
|
||||
strbuilder_append_fmt( result, "#define %S(%S) %S", define->Name, strbuilder_to_str(params_builder), define->Body->Content );
|
||||
}
|
||||
else {
|
||||
strbuilder_append_fmt( result, "#define %S %S", define->Name, define->Body->Content );
|
||||
}
|
||||
}
|
||||
|
||||
void define_params_to_strbuilder_ref(CodeDefineParams self, StrBuilder* result)
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
if ( self->Name.Ptr && self->Name.Len )
|
||||
{
|
||||
strbuilder_append_fmt( result, " %S", self->Name );
|
||||
}
|
||||
if ( self->NumEntries - 1 > 0 )
|
||||
{
|
||||
for ( CodeDefineParams param = begin_CodeDefineParams(self->Next); param != end_CodeDefineParams(self->Next); param = next_CodeDefineParams(self->Next, param) )
|
||||
{
|
||||
strbuilder_append_fmt( result, ", %SB", define_params_to_strbuilder(param) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StrBuilder destructor_to_strbuilder(CodeDestructor self)
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
|
||||
switch ( self->Type )
|
||||
{
|
||||
@ -266,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 );
|
||||
@ -285,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 ) )
|
||||
@ -308,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 )
|
||||
{
|
||||
@ -329,7 +322,9 @@ StrBuilder enum_to_strbuilder(CodeEnum self)
|
||||
|
||||
void enum_to_strbuilder_def(CodeEnum self, StrBuilder* result )
|
||||
{
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
if ( self->Attributes || self->UnderlyingType || self->UnderlyingTypeMacro )
|
||||
@ -362,7 +357,9 @@ void enum_to_strbuilder_def(CodeEnum self, StrBuilder* result )
|
||||
|
||||
void enum_to_strbuilder_fwd(CodeEnum self, StrBuilder* result )
|
||||
{
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
if ( self->Attributes )
|
||||
@ -389,7 +386,9 @@ void enum_to_strbuilder_fwd(CodeEnum self, StrBuilder* result )
|
||||
|
||||
void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result )
|
||||
{
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
if ( self->Attributes || self->UnderlyingType )
|
||||
@ -421,7 +420,9 @@ void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result )
|
||||
|
||||
void enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result )
|
||||
{
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
strbuilder_append_str( result, txt("enum class ") );
|
||||
@ -440,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 )
|
||||
{
|
||||
@ -505,7 +459,9 @@ StrBuilder fn_to_strbuilder(CodeFn self)
|
||||
|
||||
void fn_to_strbuilder_def(CodeFn self, StrBuilder* result )
|
||||
{
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export") );
|
||||
|
||||
if ( self->Attributes )
|
||||
@ -553,12 +509,18 @@ 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 )
|
||||
{
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
if ( self->Attributes )
|
||||
@ -606,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 )
|
||||
@ -619,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 "));
|
||||
|
||||
@ -637,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_equal( 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 )
|
||||
{
|
||||
@ -671,7 +621,9 @@ StrBuilder code_op_to_strbuilder(CodeOperator self)
|
||||
|
||||
void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result )
|
||||
{
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
if ( self->Attributes )
|
||||
@ -725,7 +677,9 @@ void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result )
|
||||
|
||||
void code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result )
|
||||
{
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
if ( self->Attributes )
|
||||
@ -776,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 )
|
||||
{
|
||||
@ -791,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) )
|
||||
@ -828,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) )
|
||||
@ -863,15 +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);
|
||||
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);
|
||||
@ -939,74 +889,30 @@ 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);
|
||||
GEN_ASSERT(result);
|
||||
s32 idx = 0;
|
||||
s32 left = self->NumEntries;
|
||||
while ( left-- )
|
||||
while ( left -- )
|
||||
{
|
||||
Str spec = spec_to_str( self->ArrSpecs[idx] );
|
||||
strbuilder_append_fmt( result, "%.*s ", spec.Len, spec.Ptr );
|
||||
Specifier spec = self->ArrSpecs[idx];
|
||||
Str spec_str = spec_to_str( spec );
|
||||
if ( idx > 0 ) switch (spec) {
|
||||
case Spec_Ptr:
|
||||
case Spec_Ref:
|
||||
case Spec_RValue:
|
||||
break;
|
||||
|
||||
default:
|
||||
strbuilder_append_str(result, txt(" "));
|
||||
break;
|
||||
}
|
||||
strbuilder_append_fmt( result, "%S", spec_str );
|
||||
idx++;
|
||||
}
|
||||
strbuilder_append_str(result, txt(" "));
|
||||
}
|
||||
|
||||
StrBuilder struct_to_strbuilder(CodeStruct self)
|
||||
@ -1030,7 +936,7 @@ void struct_to_strbuilder_def( CodeStruct self, StrBuilder* result )
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
strbuilder_append_str( result, txt("struct ") );
|
||||
@ -1040,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 )
|
||||
@ -1056,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 )
|
||||
{
|
||||
@ -1076,7 +984,7 @@ void struct_to_strbuilder_fwd( CodeStruct self, StrBuilder* result )
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
if ( self->Attributes )
|
||||
@ -1093,19 +1001,11 @@ 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);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
if ( self->Params )
|
||||
@ -1114,16 +1014,11 @@ 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 )
|
||||
{
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
strbuilder_append_str( result, txt("typedef "));
|
||||
@ -1156,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 )
|
||||
{
|
||||
@ -1221,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 )
|
||||
{
|
||||
@ -1236,7 +1127,9 @@ StrBuilder union_to_strbuilder(CodeUnion self)
|
||||
|
||||
void union_to_strbuilder_def(CodeUnion self, StrBuilder* result )
|
||||
{
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
strbuilder_append_str( result, txt("union ") );
|
||||
@ -1267,7 +1160,7 @@ void union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result )
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
strbuilder_append_str( result, txt("union ") );
|
||||
@ -1284,27 +1177,11 @@ 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);
|
||||
GEN_ASSERT(result);
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
if ( self->Attributes )
|
||||
@ -1337,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 )
|
||||
{
|
||||
@ -1401,7 +1258,7 @@ void var_to_strbuilder_ref(CodeVar self, StrBuilder* result )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
|
||||
strbuilder_append_str( result, txt("export ") );
|
||||
|
||||
if ( self->Attributes || self->Specs )
|
||||
@ -1410,7 +1267,7 @@ void var_to_strbuilder_ref(CodeVar self, StrBuilder* result )
|
||||
strbuilder_append_fmt( result, "%SB ", attributes_to_strbuilder(self->Attributes) );
|
||||
|
||||
if ( self->Specs )
|
||||
strbuilder_append_fmt( result, "%SB\n", specifiers_to_strbuilder(self->Specs) );
|
||||
strbuilder_append_fmt( result, "%SB", specifiers_to_strbuilder(self->Specs) );
|
||||
|
||||
strbuilder_append_fmt( result, "%SB %S", typename_to_strbuilder(self->ValueType), self->Name );
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "ast.hpp"
|
||||
#endif
|
||||
@ -20,48 +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 params_append (CodeParams params, CodeParams param );
|
||||
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 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 );
|
||||
|
||||
CodeDefineParams begin_CodeDefineParams(CodeDefineParams params);
|
||||
CodeDefineParams end_CodeDefineParams (CodeDefineParams params);
|
||||
CodeDefineParams next_CodeDefineParams (CodeDefineParams params, CodeDefineParams entry_iter);
|
||||
|
||||
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 );
|
||||
@ -80,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
|
||||
@ -192,12 +205,11 @@ struct CodeParams
|
||||
{
|
||||
#if ! GEN_C_LIKE_CPP
|
||||
Using_Code( CodeParams );
|
||||
forceinline void append( CodeParams other );
|
||||
forceinline CodeParams get( s32 idx );
|
||||
forceinline bool has_entries();
|
||||
forceinline StrBuilder to_strbuilder();
|
||||
forceinline void to_strbuilder( StrBuilder& result );
|
||||
|
||||
forceinline void append( CodeParams other ) { return params_append(* this, other); }
|
||||
forceinline CodeParams get( s32 idx ) { return params_get( * this, idx); }
|
||||
forceinline bool has_entries() { return params_has_entries(* this); }
|
||||
forceinline StrBuilder to_strbuilder() { return params_to_strbuilder(* this); }
|
||||
forceinline void to_strbuilder( StrBuilder& result ) { return params_to_strbuilder_ref(*this, & result); }
|
||||
#endif
|
||||
Using_CodeOps( CodeParams );
|
||||
forceinline CodeParams begin() { return begin_CodeParams(* this); }
|
||||
@ -212,12 +224,36 @@ struct CodeParams
|
||||
AST_Params* ast;
|
||||
};
|
||||
|
||||
struct CodeDefineParams
|
||||
{
|
||||
#if ! GEN_C_LIKE_CPP
|
||||
Using_Code( CodeDefineParams );
|
||||
forceinline void append( CodeDefineParams other ) { return params_append( cast(CodeParams, * this), cast(CodeParams, other)); }
|
||||
forceinline CodeDefineParams get( s32 idx ) { return (CodeDefineParams) (Code) params_get( cast(CodeParams, * this), idx); }
|
||||
forceinline bool has_entries() { return params_has_entries( cast(CodeParams, * this)); }
|
||||
forceinline StrBuilder to_strbuilder() { return define_params_to_strbuilder(* this); }
|
||||
forceinline void to_strbuilder( StrBuilder& result ) { return define_params_to_strbuilder_ref(* this, & result); }
|
||||
#endif
|
||||
Using_CodeOps( CodeDefineParams );
|
||||
forceinline CodeDefineParams begin() { return (CodeDefineParams) (Code) begin_CodeParams( cast(CodeParams, * this)); }
|
||||
forceinline CodeDefineParams end() { return (CodeDefineParams) (Code) end_CodeParams( cast(CodeParams, * this)); }
|
||||
forceinline operator Code() { return { (AST*)ast }; }
|
||||
forceinline CodeDefineParams operator *() { return * this; } // Required to support for-range iteration.
|
||||
forceinline AST_DefineParams* operator->() {
|
||||
GEN_ASSERT(ast);
|
||||
return ast;
|
||||
}
|
||||
forceinline CodeDefineParams& operator++();
|
||||
AST_DefineParams* ast;
|
||||
};
|
||||
|
||||
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); }
|
||||
@ -330,7 +366,7 @@ struct CodeExec
|
||||
AST_Exec *ast;
|
||||
};
|
||||
|
||||
#if GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
#ifdef GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
struct CodeExpr
|
||||
{
|
||||
#if ! GEN_C_LIKE_CPP
|
||||
@ -657,7 +693,7 @@ struct CodePreprocessCond
|
||||
AST_PreprocessCond* ast;
|
||||
};
|
||||
|
||||
#if GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
#ifdef GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
struct CodeStmt
|
||||
{
|
||||
#if ! GEN_C_LIKE_CPP
|
||||
@ -941,6 +977,7 @@ struct InvalidCode_ImplictCaster
|
||||
operator CodeClass () const { return cast(CodeClass, Code_Invalid); }
|
||||
operator CodeConstructor () const { return cast(CodeConstructor, Code_Invalid); }
|
||||
operator CodeDefine () const { return cast(CodeDefine, Code_Invalid); }
|
||||
operator CodeDefineParams () const { return cast(CodeDefineParams, Code_Invalid); }
|
||||
operator CodeDestructor () const { return cast(CodeDestructor, Code_Invalid); }
|
||||
operator CodeExec () const { return cast(CodeExec, Code_Invalid); }
|
||||
operator CodeEnum () const { return cast(CodeEnum, Code_Invalid); }
|
||||
@ -974,6 +1011,7 @@ struct NullCode_ImplicitCaster
|
||||
operator CodeClass () const { return {nullptr}; }
|
||||
operator CodeConstructor () const { return {nullptr}; }
|
||||
operator CodeDefine () const { return {nullptr}; }
|
||||
operator CodeDefineParams () const { return {nullptr}; }
|
||||
operator CodeDestructor () const { return {nullptr}; }
|
||||
operator CodeExec () const { return {nullptr}; }
|
||||
operator CodeEnum () const { return {nullptr}; }
|
||||
@ -1024,17 +1062,24 @@ forceinline StrBuilder to_strbuilder ( CodeClass self )
|
||||
forceinline void to_strbuilder_def( CodeClass self, StrBuilder& result ) { return class_to_strbuilder_def(self, & result); }
|
||||
forceinline void to_strbuilder_fwd( CodeClass self, StrBuilder& result ) { return class_to_strbuilder_fwd(self, & result); }
|
||||
|
||||
forceinline void append (CodeParams params, CodeParams param ) { return params_append(params, param); }
|
||||
forceinline CodeParams get (CodeParams params, s32 idx) { return params_get(params, idx); }
|
||||
forceinline bool has_entries (CodeParams params ) { return params_has_entries(params); }
|
||||
forceinline StrBuilder to_strbuilder(CodeParams params ) { return params_to_strbuilder(params); }
|
||||
forceinline void to_strbuilder(CodeParams params, StrBuilder& result ) { return params_to_strbuilder_ref(params, & result); }
|
||||
forceinline void append (CodeDefineParams appendee, CodeDefineParams other ) { params_append(cast(CodeParams, appendee), cast(CodeParams, other)); }
|
||||
forceinline CodeDefineParams get (CodeDefineParams params, s32 idx) { return (CodeDefineParams) (Code) params_get(cast(CodeParams, params), idx); }
|
||||
forceinline bool has_entries (CodeDefineParams params ) { return params_has_entries(cast(CodeParams, params)); }
|
||||
forceinline StrBuilder to_strbuilder(CodeDefineParams params ) { return define_params_to_strbuilder(params); }
|
||||
forceinline void to_strbuilder(CodeDefineParams params, StrBuilder& result ) { return define_params_to_strbuilder_ref(params, & result); }
|
||||
|
||||
forceinline void append (CodeParams appendee, CodeParams other ) { return params_append(appendee, other); }
|
||||
forceinline CodeParams get (CodeParams params, s32 idx) { return params_get(params, idx); }
|
||||
forceinline bool has_entries (CodeParams params ) { return params_has_entries(params); }
|
||||
forceinline StrBuilder to_strbuilder(CodeParams params ) { return params_to_strbuilder(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); }
|
||||
forceinline void to_strbuilder(CodeSpecifiers specifiers, StrBuilder& result) { return specifiers_to_strbuilder_ref(specifiers, & result); }
|
||||
|
||||
forceinline void add_interface (CodeStruct self, CodeTypename interface) { return struct_add_interface(self, interface); }
|
||||
forceinline StrBuilder to_strbuilder (CodeStruct self) { return struct_to_strbuilder(self); }
|
||||
|
85
base/components/constants.hpp
Normal file
85
base/components/constants.hpp
Normal 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
|
@ -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,43 @@ 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 CodeDestructor& CodeDestructor::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;
|
||||
}
|
||||
|
||||
inline CodeDefineParams::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeDestructor& CodeDestructor::operator=(Code other)
|
||||
{
|
||||
if (other.ast != nullptr && other->Parent != nullptr)
|
||||
{
|
||||
ast = rcast(decltype(ast), code_duplicate(other).ast);
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast(decltype(ast), other.ast);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -197,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;
|
||||
}
|
||||
|
||||
@ -228,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;
|
||||
}
|
||||
|
||||
@ -259,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;
|
||||
}
|
||||
|
||||
@ -290,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;
|
||||
}
|
||||
|
||||
@ -321,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;
|
||||
}
|
||||
|
||||
@ -352,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;
|
||||
}
|
||||
|
||||
@ -383,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;
|
||||
}
|
||||
|
||||
@ -414,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;
|
||||
}
|
||||
|
||||
@ -445,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;
|
||||
}
|
||||
|
||||
@ -476,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;
|
||||
}
|
||||
|
||||
@ -507,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;
|
||||
}
|
||||
|
||||
@ -536,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;
|
||||
}
|
||||
|
||||
@ -554,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;
|
||||
}
|
||||
|
||||
@ -585,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;
|
||||
}
|
||||
|
||||
@ -614,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;
|
||||
}
|
||||
|
||||
@ -630,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;
|
||||
}
|
||||
|
||||
@ -648,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;
|
||||
}
|
||||
|
||||
@ -679,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;
|
||||
}
|
||||
|
||||
@ -710,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;
|
||||
}
|
||||
|
||||
@ -741,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;
|
||||
}
|
||||
|
||||
@ -772,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;
|
||||
}
|
||||
|
||||
@ -803,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;
|
||||
@ -851,6 +867,11 @@ forceinline Code::operator CodeDefine() const
|
||||
return { (AST_Define*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeDefineParams() const
|
||||
{
|
||||
return { (AST_DefineParams*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeDestructor() const
|
||||
{
|
||||
return { (AST_Destructor*)ast };
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "components/types.hpp"
|
||||
#endif
|
||||
@ -46,6 +46,7 @@ enum CodeType : u32
|
||||
CT_Operator_Cast,
|
||||
CT_Operator_Cast_Fwd,
|
||||
CT_Parameters,
|
||||
CT_Parameters_Define,
|
||||
CT_Preprocess_Define,
|
||||
CT_Preprocess_Include,
|
||||
CT_Preprocess_If,
|
||||
@ -72,148 +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[61] = {
|
||||
{ "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 },
|
||||
{ "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 },
|
||||
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 },
|
||||
};
|
||||
return lookup[type];
|
||||
}
|
||||
|
||||
inline Str codetype_to_keyword_str( CodeType type )
|
||||
inline Str codetype_to_keyword_str(CodeType type)
|
||||
{
|
||||
local_persist Str lookup[61] = {
|
||||
{ "__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 },
|
||||
{ "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 },
|
||||
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 },
|
||||
};
|
||||
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);
|
||||
}
|
||||
|
@ -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[47] = {
|
||||
{ "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 },
|
||||
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 },
|
||||
};
|
||||
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);
|
||||
}
|
||||
|
@ -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,77 +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[26] = {
|
||||
{ "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 },
|
||||
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 },
|
||||
{ "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)
|
||||
{
|
||||
return specifier > Spec_Virtual;
|
||||
switch (specifier)
|
||||
{
|
||||
case Spec_Const:
|
||||
case Spec_Final:
|
||||
case Spec_NoExceptions:
|
||||
case Spec_Override:
|
||||
case Spec_Pure:
|
||||
case Spec_Delete:
|
||||
case Spec_Volatile:
|
||||
return true;
|
||||
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);
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
@ -24,8 +24,8 @@ enum TokType : u32
|
||||
Tok_BraceCurly_Close,
|
||||
Tok_BraceSquare_Open,
|
||||
Tok_BraceSquare_Close,
|
||||
Tok_Capture_Start,
|
||||
Tok_Capture_End,
|
||||
Tok_Paren_Open,
|
||||
Tok_Paren_Close,
|
||||
Tok_Comment,
|
||||
Tok_Comment_End,
|
||||
Tok_Comment_Start,
|
||||
@ -53,6 +53,7 @@ enum TokType : u32
|
||||
Tok_Operator,
|
||||
Tok_Preprocess_Hash,
|
||||
Tok_Preprocess_Define,
|
||||
Tok_Preprocess_Define_Param,
|
||||
Tok_Preprocess_If,
|
||||
Tok_Preprocess_IfDef,
|
||||
Tok_Preprocess_IfNotDef,
|
||||
@ -62,7 +63,9 @@ enum TokType : u32
|
||||
Tok_Preprocess_Include,
|
||||
Tok_Preprocess_Pragma,
|
||||
Tok_Preprocess_Content,
|
||||
Tok_Preprocess_Macro,
|
||||
Tok_Preprocess_Macro_Expr,
|
||||
Tok_Preprocess_Macro_Stmt,
|
||||
Tok_Preprocess_Macro_Typename,
|
||||
Tok_Preprocess_Unsupported,
|
||||
Tok_Spec_Alignas,
|
||||
Tok_Spec_Const,
|
||||
@ -80,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,
|
||||
@ -108,121 +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 },
|
||||
{ "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__", sizeof( "__macro__" ) - 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;
|
||||
|
@ -1,88 +0,0 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "inlines.hpp"
|
||||
#include "gen/ast_inlines.hpp"
|
||||
#endif
|
||||
|
||||
#pragma region Constants
|
||||
|
||||
extern Str enum_underlying_sig;
|
||||
|
||||
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
|
||||
|
@ -15,7 +15,7 @@
|
||||
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
|
||||
| | | | | __} | |
|
||||
| l_l l_l {___/ |
|
||||
! ----------------------------------------------------------------------- VERSION: v0.20-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 |
|
||||
|
@ -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
|
||||
|
||||
@ -257,6 +567,25 @@ CodeParams next_CodeParams(CodeParams params, CodeParams param_iter)
|
||||
}
|
||||
#pragma endregion CodeParams
|
||||
|
||||
#pragma region CodeDefineParams
|
||||
forceinline void define_params_append (CodeDefineParams appendee, CodeDefineParams other ) { params_append( cast(CodeParams, appendee), cast(CodeParams, other) ); }
|
||||
forceinline CodeDefineParams define_params_get (CodeDefineParams self, s32 idx ) { return (CodeDefineParams) (Code) params_get( cast(CodeParams, self), idx); }
|
||||
forceinline bool define_params_has_entries(CodeDefineParams self) { return params_has_entries( cast(CodeParams, self)); }
|
||||
|
||||
forceinline CodeDefineParams begin_CodeDefineParams(CodeDefineParams params) { return (CodeDefineParams) (Code) begin_CodeParams( cast(CodeParams, (Code)params)); }
|
||||
forceinline CodeDefineParams end_CodeDefineParams (CodeDefineParams params) { return (CodeDefineParams) (Code) end_CodeParams ( cast(CodeParams, (Code)params)); }
|
||||
forceinline CodeDefineParams next_CodeDefineParams (CodeDefineParams params, CodeDefineParams entry_iter) { return (CodeDefineParams) (Code) next_CodeParams ( cast(CodeParams, (Code)params), cast(CodeParams, (Code)entry_iter)); }
|
||||
|
||||
#if GEN_COMPILER_CPP
|
||||
forceinline
|
||||
CodeDefineParams& CodeDefineParams::operator ++()
|
||||
{
|
||||
* this = ast->Next;
|
||||
return * this;
|
||||
}
|
||||
#endif
|
||||
#pragma endregion CodeDefineParams
|
||||
|
||||
#pragma region CodeSpecifiers
|
||||
inline
|
||||
bool specifiers_append(CodeSpecifiers self, Specifier spec )
|
||||
@ -277,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++ ) {
|
||||
@ -359,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
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "code_serialization.cpp"
|
||||
#endif
|
||||
@ -179,37 +179,39 @@ void define_constants()
|
||||
#endif
|
||||
|
||||
spec_const = def_specifier( Spec_Const); code_set_global( cast(Code, spec_const ));
|
||||
spec_consteval = def_specifier( Spec_Consteval); code_set_global( cast(Code, spec_consteval ));;
|
||||
spec_constexpr = def_specifier( Spec_Constexpr); code_set_global( cast(Code, spec_constexpr ));;
|
||||
spec_constinit = def_specifier( Spec_Constinit); code_set_global( cast(Code, spec_constinit ));;
|
||||
spec_extern_linkage = def_specifier( Spec_External_Linkage); code_set_global( cast(Code, spec_extern_linkage ));;
|
||||
spec_final = def_specifier( Spec_Final); code_set_global( cast(Code, spec_final ));;
|
||||
spec_forceinline = def_specifier( Spec_ForceInline); code_set_global( cast(Code, spec_forceinline ));;
|
||||
spec_global = def_specifier( Spec_Global); code_set_global( cast(Code, spec_global ));;
|
||||
spec_inline = def_specifier( Spec_Inline); code_set_global( cast(Code, spec_inline ));;
|
||||
spec_internal_linkage = def_specifier( Spec_Internal_Linkage); code_set_global( cast(Code, spec_internal_linkage ));;
|
||||
spec_local_persist = def_specifier( Spec_Local_Persist); code_set_global( cast(Code, spec_local_persist ));;
|
||||
spec_mutable = def_specifier( Spec_Mutable); code_set_global( cast(Code, spec_mutable ));;
|
||||
spec_neverinline = def_specifier( Spec_NeverInline); code_set_global( cast(Code, spec_neverinline ));;
|
||||
spec_noexcept = def_specifier( Spec_NoExceptions); code_set_global( cast(Code, spec_noexcept ));;
|
||||
spec_override = def_specifier( Spec_Override); code_set_global( cast(Code, spec_override ));;
|
||||
spec_ptr = def_specifier( Spec_Ptr); code_set_global( cast(Code, spec_ptr ));;
|
||||
spec_consteval = def_specifier( Spec_Consteval); code_set_global( cast(Code, spec_consteval ));
|
||||
spec_constexpr = def_specifier( Spec_Constexpr); code_set_global( cast(Code, spec_constexpr ));
|
||||
spec_constinit = def_specifier( Spec_Constinit); code_set_global( cast(Code, spec_constinit ));
|
||||
spec_extern_linkage = def_specifier( Spec_External_Linkage); code_set_global( cast(Code, spec_extern_linkage ));
|
||||
spec_final = def_specifier( Spec_Final); code_set_global( cast(Code, spec_final ));
|
||||
spec_forceinline = def_specifier( Spec_ForceInline); code_set_global( cast(Code, spec_forceinline ));
|
||||
spec_global = def_specifier( Spec_Global); code_set_global( cast(Code, spec_global ));
|
||||
spec_inline = def_specifier( Spec_Inline); code_set_global( cast(Code, spec_inline ));
|
||||
spec_internal_linkage = def_specifier( Spec_Internal_Linkage); code_set_global( cast(Code, spec_internal_linkage ));
|
||||
spec_local_persist = def_specifier( Spec_Local_Persist); code_set_global( cast(Code, spec_local_persist ));
|
||||
spec_mutable = def_specifier( Spec_Mutable); code_set_global( cast(Code, spec_mutable ));
|
||||
spec_neverinline = def_specifier( Spec_NeverInline); code_set_global( cast(Code, spec_neverinline ));
|
||||
spec_noexcept = def_specifier( Spec_NoExceptions); code_set_global( cast(Code, spec_noexcept ));
|
||||
spec_override = def_specifier( Spec_Override); code_set_global( cast(Code, spec_override ));
|
||||
spec_ptr = def_specifier( Spec_Ptr); code_set_global( cast(Code, spec_ptr ));
|
||||
spec_pure = def_specifier( Spec_Pure); code_set_global( cast(Code, spec_pure ));
|
||||
spec_ref = def_specifier( Spec_Ref); code_set_global( cast(Code, spec_ref ));;
|
||||
spec_register = def_specifier( Spec_Register); code_set_global( cast(Code, spec_register ));;
|
||||
spec_rvalue = def_specifier( Spec_RValue); code_set_global( cast(Code, spec_rvalue ));;
|
||||
spec_static_member = def_specifier( Spec_Static); code_set_global( cast(Code, spec_static_member ));;
|
||||
spec_thread_local = def_specifier( Spec_Thread_Local); code_set_global( cast(Code, spec_thread_local ));;
|
||||
spec_virtual = def_specifier( Spec_Virtual); code_set_global( cast(Code, spec_virtual ));;
|
||||
spec_ref = def_specifier( Spec_Ref); code_set_global( cast(Code, spec_ref ));
|
||||
spec_register = def_specifier( Spec_Register); code_set_global( cast(Code, spec_register ));
|
||||
spec_rvalue = def_specifier( Spec_RValue); code_set_global( cast(Code, spec_rvalue ));
|
||||
spec_static_member = def_specifier( Spec_Static); code_set_global( cast(Code, spec_static_member ));
|
||||
spec_thread_local = def_specifier( Spec_Thread_Local); code_set_global( cast(Code, spec_thread_local ));
|
||||
spec_virtual = def_specifier( Spec_Virtual); code_set_global( cast(Code, spec_virtual ));
|
||||
spec_volatile = def_specifier( Spec_Volatile); code_set_global( cast(Code, spec_volatile ));
|
||||
|
||||
spec_local_persist = def_specifiers( 1, Spec_Local_Persist );
|
||||
code_set_global(cast(Code, spec_local_persist));
|
||||
|
||||
if (enum_underlying_sig.Len == 0) {
|
||||
enum_underlying_sig = txt("enum_underlying(");
|
||||
if (enum_underlying_macro.Name.Len == 0) {
|
||||
enum_underlying_macro.Name = txt("enum_underlying");
|
||||
enum_underlying_macro.Type = MT_Expression;
|
||||
enum_underlying_macro.Flags = MF_Functional;
|
||||
}
|
||||
array_append( _ctx->PreprocessorDefines, enum_underlying_sig);
|
||||
register_macro(enum_underlying_macro);
|
||||
}
|
||||
|
||||
void init(Context* ctx)
|
||||
@ -270,8 +272,8 @@ void init(Context* ctx)
|
||||
ctx->CodePool_NumBlocks = kilobytes(16);
|
||||
}
|
||||
|
||||
if (ctx->InitSize_LexArena == 0 ) {
|
||||
ctx->InitSize_LexArena = megabytes(4);
|
||||
if (ctx->InitSize_LexerTokens == 0 ) {
|
||||
ctx->InitSize_LexerTokens = kilobytes(64);
|
||||
}
|
||||
if (ctx->SizePer_StringArena == 0) {
|
||||
ctx->SizePer_StringArena = megabytes(1);
|
||||
@ -301,9 +303,6 @@ void init(Context* ctx)
|
||||
GEN_FATAL( "gen::init: Failed to initialize the code pool" );
|
||||
array_append( ctx->CodePools, code_pool );
|
||||
|
||||
// TODO(Ed): This is going to be phased out most likely.
|
||||
ctx->LexArena = arena_init_from_allocator( ctx->Allocator_DyanmicContainers, ctx->InitSize_LexArena );
|
||||
|
||||
// TODO(Ed): Eventually the string arenas needs to be phased out for a dedicated string slab allocator
|
||||
Arena strbuilder_arena = arena_init_from_allocator( ctx->Allocator_StrCache, ctx->SizePer_StringArena );
|
||||
if ( strbuilder_arena.PhysicalStart == nullptr )
|
||||
@ -315,9 +314,12 @@ void init(Context* ctx)
|
||||
ctx->StrCache = hashtable_init(StrCached, ctx->Allocator_DyanmicContainers);
|
||||
if ( ctx->StrCache.Entries == nullptr )
|
||||
GEN_FATAL( "gen::init: Failed to initialize the StringCache");
|
||||
|
||||
ctx->Macros = hashtable_init(Macro, ctx->Allocator_DyanmicContainers);
|
||||
if (ctx->Macros.Hashes == nullptr || ctx->Macros.Entries == nullptr) {
|
||||
GEN_FATAL( "gen::init: Failed to initialize the PreprocessMacros table" );
|
||||
}
|
||||
}
|
||||
// Preprocessor Defines
|
||||
ctx->PreprocessorDefines = array_init_reserve(StrCached, ctx->Allocator_DyanmicContainers, kilobytes(1) );
|
||||
|
||||
define_constants();
|
||||
parser_init();
|
||||
@ -354,9 +356,7 @@ void deinit(Context* ctx)
|
||||
array_free( ctx->CodePools);
|
||||
array_free( ctx->StringArenas);
|
||||
|
||||
arena_free(& ctx->LexArena);
|
||||
|
||||
array_free(ctx->PreprocessorDefines);
|
||||
hashtable_destroy(ctx->Macros);
|
||||
|
||||
left = array_num( ctx->Fallback_AllocatorBuckets);
|
||||
if (left)
|
||||
@ -376,6 +376,13 @@ void deinit(Context* ctx)
|
||||
if (_ctx == ctx)
|
||||
_ctx = nullptr;
|
||||
-- context_counter;
|
||||
|
||||
Context wipe = {};
|
||||
* ctx = wipe;
|
||||
}
|
||||
|
||||
Context* get_context() {
|
||||
return _ctx;
|
||||
}
|
||||
|
||||
void reset(Context* ctx)
|
||||
@ -401,6 +408,7 @@ void reset(Context* ctx)
|
||||
while ( left--, left );
|
||||
|
||||
hashtable_clear(ctx->StrCache);
|
||||
hashtable_clear(ctx->Macros);
|
||||
define_constants();
|
||||
}
|
||||
|
||||
@ -463,10 +471,51 @@ Code make_code()
|
||||
return result;
|
||||
}
|
||||
|
||||
void set_preprocess_define( Str id, b32 is_functional ) {
|
||||
StrBuilder builder = strbuilder_make_str( _ctx->Allocator_Temp, id );
|
||||
if (is_functional) {
|
||||
strbuilder_append_char( & builder, '(' );
|
||||
}
|
||||
array_append( _ctx->PreprocessorDefines, cache_str( strbuilder_to_str(builder)) );
|
||||
Macro* lookup_macro( Str name ) {
|
||||
u32 key = crc32( name.Ptr, name.Len );
|
||||
return hashtable_get( _ctx->Macros, key );
|
||||
}
|
||||
|
||||
void register_macro( Macro macro ) {
|
||||
GEN_ASSERT_NOT_NULL(macro.Name.Ptr);
|
||||
GEN_ASSERT(macro.Name.Len > 0);
|
||||
u32 key = crc32( macro.Name.Ptr, macro.Name.Len );
|
||||
macro.Name = cache_str(macro.Name);
|
||||
hashtable_set( _ctx->Macros, key, macro );
|
||||
}
|
||||
|
||||
void register_macros( s32 num, ... )
|
||||
{
|
||||
GEN_ASSERT(num > 0);
|
||||
va_list va;
|
||||
va_start(va, num);
|
||||
do
|
||||
{
|
||||
Macro macro = va_arg(va, Macro);
|
||||
GEN_ASSERT_NOT_NULL(macro.Name.Ptr);
|
||||
GEN_ASSERT(macro.Name.Len > 0);
|
||||
macro.Name = cache_str(macro.Name);
|
||||
|
||||
u32 key = crc32( macro.Name.Ptr, macro.Name.Len );
|
||||
hashtable_set( _ctx->Macros, key, macro );
|
||||
}
|
||||
while (num--, num > 0);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void register_macros_arr( s32 num, Macro* macros )
|
||||
{
|
||||
GEN_ASSERT(num > 0);
|
||||
do
|
||||
{
|
||||
Macro macro = * macros;
|
||||
GEN_ASSERT_NOT_NULL(macro.Name.Ptr);
|
||||
GEN_ASSERT(macro.Name.Len > 0);
|
||||
macro.Name = cache_str(macro.Name);
|
||||
|
||||
u32 key = crc32( macro.Name.Ptr, macro.Name.Len );
|
||||
hashtable_set( _ctx->Macros, key, macro );
|
||||
++ macros;
|
||||
}
|
||||
while (num--, num > 0);
|
||||
}
|
||||
|
@ -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.
|
||||
|
||||
@ -60,7 +61,7 @@ struct Context
|
||||
u32 CodePool_NumBlocks;
|
||||
|
||||
// TODO(Ed): Review these... (No longer needed if using the proper allocation strategy)
|
||||
u32 InitSize_LexArena;
|
||||
u32 InitSize_LexerTokens;
|
||||
u32 SizePer_StringArena;
|
||||
|
||||
// TODO(Ed): Symbol Table
|
||||
@ -71,7 +72,7 @@ struct Context
|
||||
// Used by the lexer to persistently treat all these identifiers as preprocessor defines.
|
||||
// Populate with strings via gen::cache_str.
|
||||
// Functional defines must have format: id( ;at minimum to indicate that the define is only valid with arguments.
|
||||
Array(StrCached) PreprocessorDefines;
|
||||
MacroTable Macros;
|
||||
|
||||
// Backend
|
||||
|
||||
@ -79,6 +80,8 @@ struct Context
|
||||
u32 InitSize_Fallback_Allocator_Bucket_Size;
|
||||
Array(Arena) Fallback_AllocatorBuckets;
|
||||
|
||||
StringTable token_fmt_map;
|
||||
|
||||
// Array(Token) LexerTokens;
|
||||
|
||||
Array(Pool) CodePools;
|
||||
@ -87,15 +90,20 @@ struct Context
|
||||
StringTable StrCache;
|
||||
|
||||
// TODO(Ed): This needs to be just handled by a parser context
|
||||
|
||||
Arena LexArena;
|
||||
StringTable Lexer_defines;
|
||||
Array(Token) Lexer_Tokens;
|
||||
|
||||
// TODO(Ed): Active parse context vs a parse result need to be separated conceptually
|
||||
ParseContext parser;
|
||||
|
||||
// TODO(Ed): Formatting - This will eventually be in a separate struct when in the process of serialization of the builder.
|
||||
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);
|
||||
|
||||
@ -103,15 +111,30 @@ GEN_API void init(Context* ctx);
|
||||
// However on Windows at least, it doesn't need to occur as the OS will clean up after the process.
|
||||
GEN_API void deinit(Context* ctx);
|
||||
|
||||
// Retrieves the active context (not usually needed, but here in case...)
|
||||
GEN_API Context* get_context();
|
||||
|
||||
// Clears the allocations, but doesn't free the memoery, then calls init() again.
|
||||
// Ease of use.
|
||||
GEN_API void reset(Context* ctx);
|
||||
|
||||
GEN_API void set_context(Context* ctx);
|
||||
|
||||
// Mostly intended for the parser
|
||||
GEN_API Macro* lookup_macro( Str Name );
|
||||
|
||||
// Alternative way to add a preprocess define entry for the lexer & parser to utilize
|
||||
// if the user doesn't want to use def_define
|
||||
GEN_API void set_preprocess_define( Str id, b32 is_functional );
|
||||
// Macros are tracked by name so if the name already exists the entry will be overwritten.
|
||||
GEN_API void register_macro( Macro macro );
|
||||
|
||||
// Ease of use batch registration
|
||||
GEN_API void register_macros( s32 num, ... );
|
||||
GEN_API void register_macros_arr( s32 num, Macro* macros );
|
||||
|
||||
#if GEN_COMPILER_CPP
|
||||
forceinline void register_macros( s32 num, Macro* macros ) { return register_macros_arr(num, macros); }
|
||||
#endif
|
||||
|
||||
// Used internally to retrive or make string allocations.
|
||||
// Strings are stored in a series of string arenas of fixed size (SizePer_StringArena)
|
||||
@ -138,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 );
|
||||
@ -150,9 +174,12 @@ struct Opts_def_constructor {
|
||||
GEN_API CodeConstructor def_constructor( Opts_def_constructor opts GEN_PARAM_DEFAULT );
|
||||
|
||||
struct Opts_def_define {
|
||||
b32 dont_append_preprocess_defines;
|
||||
CodeDefineParams params;
|
||||
Str content;
|
||||
MacroFlags flags;
|
||||
b32 dont_register_to_preprocess_macros;
|
||||
};
|
||||
GEN_API CodeDefine def_define( Str name, Str content, Opts_def_define opts GEN_PARAM_DEFAULT );
|
||||
GEN_API CodeDefine def_define( Str name, MacroType type, Opts_def_define opts GEN_PARAM_DEFAULT );
|
||||
|
||||
struct Opts_def_destructor {
|
||||
Code body;
|
||||
@ -172,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;
|
||||
@ -208,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 );
|
||||
@ -222,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;
|
||||
};
|
||||
@ -258,40 +285,55 @@ 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.
|
||||
|
||||
GEN_API CodeBody def_class_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_class_body ( s32 num, Code* codes );
|
||||
GEN_API CodeBody def_enum_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_enum_body ( s32 num, Code* codes );
|
||||
GEN_API CodeBody def_export_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_export_body ( s32 num, Code* codes);
|
||||
GEN_API CodeBody def_extern_link_body( s32 num, ... );
|
||||
GEN_API CodeBody def_extern_link_body( s32 num, Code* codes );
|
||||
GEN_API CodeBody def_function_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_function_body ( s32 num, Code* codes );
|
||||
GEN_API CodeBody def_global_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_global_body ( s32 num, Code* codes );
|
||||
GEN_API CodeBody def_namespace_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_namespace_body ( s32 num, Code* codes );
|
||||
GEN_API CodeParams def_params ( s32 num, ... );
|
||||
GEN_API CodeParams def_params ( s32 num, CodeParams* params );
|
||||
GEN_API CodeSpecifiers def_specifiers ( s32 num, ... );
|
||||
GEN_API CodeSpecifiers def_specifiers ( s32 num, Specifier* specs );
|
||||
GEN_API CodeBody def_struct_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_struct_body ( s32 num, Code* codes );
|
||||
GEN_API CodeBody def_union_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_union_body ( s32 num, Code* codes );
|
||||
GEN_API CodeBody def_class_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_class_body_arr ( s32 num, Code* codes );
|
||||
GEN_API CodeDefineParams def_define_params ( s32 num, ... );
|
||||
GEN_API CodeDefineParams def_define_params_arr ( s32 num, CodeDefineParams* codes );
|
||||
GEN_API CodeBody def_enum_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_enum_body_arr ( s32 num, Code* codes );
|
||||
GEN_API CodeBody def_export_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_export_body_arr ( s32 num, Code* codes);
|
||||
GEN_API CodeBody def_extern_link_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_extern_link_body_arr ( s32 num, Code* codes );
|
||||
GEN_API CodeBody def_function_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_function_body_arr ( s32 num, Code* codes );
|
||||
GEN_API CodeBody def_global_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_global_body_arr ( s32 num, Code* codes );
|
||||
GEN_API CodeBody def_namespace_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_namespace_body_arr ( s32 num, Code* codes );
|
||||
GEN_API CodeParams def_params ( s32 num, ... );
|
||||
GEN_API CodeParams def_params_arr ( s32 num, CodeParams* params );
|
||||
GEN_API CodeSpecifiers def_specifiers ( s32 num, ... );
|
||||
GEN_API CodeSpecifiers def_specifiers_arr ( s32 num, Specifier* specs );
|
||||
GEN_API CodeBody def_struct_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_struct_body_arr ( s32 num, Code* codes );
|
||||
GEN_API CodeBody def_union_body ( s32 num, ... );
|
||||
GEN_API CodeBody def_union_body_arr ( s32 num, Code* codes );
|
||||
|
||||
#if GEN_COMPILER_CPP
|
||||
forceinline CodeBody def_class_body ( s32 num, Code* codes ) { return def_class_body_arr(num, codes); }
|
||||
forceinline CodeDefineParams def_define_params ( s32 num, CodeDefineParams* codes ) { return def_define_params_arr(num, codes); }
|
||||
forceinline CodeBody def_enum_body ( s32 num, Code* codes ) { return def_enum_body_arr(num, codes); }
|
||||
forceinline CodeBody def_export_body ( s32 num, Code* codes) { return def_export_body_arr(num, codes); }
|
||||
forceinline CodeBody def_extern_link_body( s32 num, Code* codes ) { return def_extern_link_body_arr(num, codes); }
|
||||
forceinline CodeBody def_function_body ( s32 num, Code* codes ) { return def_function_body_arr(num, codes); }
|
||||
forceinline CodeBody def_global_body ( s32 num, Code* codes ) { return def_global_body_arr(num, codes); }
|
||||
forceinline CodeBody def_namespace_body ( s32 num, Code* codes ) { return def_namespace_body_arr(num, codes); }
|
||||
forceinline CodeParams def_params ( s32 num, CodeParams* params ) { return def_params_arr(num, params); }
|
||||
forceinline CodeSpecifiers def_specifiers ( s32 num, Specifier* specs ) { return def_specifiers_arr(num, specs); }
|
||||
forceinline CodeBody def_struct_body ( s32 num, Code* codes ) { return def_struct_body_arr(num, codes); }
|
||||
forceinline CodeBody def_union_body ( s32 num, Code* codes ) { return def_union_body_arr(num, codes); }
|
||||
#endif
|
||||
|
||||
#pragma endregion Upfront
|
||||
|
||||
#pragma region Parsing
|
||||
|
||||
// TODO(Ed) : Implmeent the new parser API design.
|
||||
|
||||
#if 0
|
||||
struct StackNode
|
||||
{
|
||||
@ -326,6 +368,7 @@ CodeBody parse_file( Str path );
|
||||
|
||||
GEN_API CodeClass parse_class ( Str class_def );
|
||||
GEN_API CodeConstructor parse_constructor ( Str constructor_def );
|
||||
GEN_API CodeDefine parse_define ( Str define_def );
|
||||
GEN_API CodeDestructor parse_destructor ( Str destructor_def );
|
||||
GEN_API CodeEnum parse_enum ( Str enum_def );
|
||||
GEN_API CodeBody parse_export_body ( Str export_def );
|
||||
@ -350,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, ... );
|
||||
@ -367,12 +410,20 @@ GEN_API Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );
|
||||
#ifndef name
|
||||
// Convienence for defining any name used with the gen api.
|
||||
// Lets you provide the length and string literal to the functions without the need for the DSL.
|
||||
#define name( Id_ ) { stringize(Id_), sizeof(stringize( Id_ )) - 1 }
|
||||
# if GEN_COMPILER_C
|
||||
# define name( Id_ ) (Str){ stringize(Id_), sizeof(stringize( Id_ )) - 1 }
|
||||
# else
|
||||
# define name( Id_ ) Str { stringize(Id_), sizeof(stringize( Id_ )) - 1 }
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef code
|
||||
// Same as name just used to indicate intention of literal for code instead of names.
|
||||
#define code( ... ) { stringize( __VA_ARGS__ ), sizeof(stringize(__VA_ARGS__)) - 1 }
|
||||
# if GEN_COMPILER_C
|
||||
# define code( ... ) (Str){ stringize( __VA_ARGS__ ), sizeof(stringize(__VA_ARGS__)) - 1 }
|
||||
# else
|
||||
# define code( ... ) Str { stringize( __VA_ARGS__ ), sizeof(stringize(__VA_ARGS__)) - 1 }
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef args
|
||||
|
@ -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;
|
||||
|
||||
@ -73,7 +73,7 @@ CodeConstructor parse_constructor( Str def )
|
||||
|
||||
if ( NumSpecifiers )
|
||||
{
|
||||
specifiers = def_specifiers( NumSpecifiers, specs_found );
|
||||
specifiers = def_specifiers_arr( NumSpecifiers, specs_found );
|
||||
// <specifiers> ...
|
||||
}
|
||||
|
||||
@ -82,6 +82,21 @@ CodeConstructor parse_constructor( Str def )
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeDefine parse_define( Str def )
|
||||
{
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
_ctx->parser.Tokens = toks;
|
||||
push_scope();
|
||||
CodeDefine result = parser_parse_define();
|
||||
parser_pop(& _ctx->parser);
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeDestructor parse_destructor( Str def )
|
||||
{
|
||||
check_parse_args( def );
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "interface.parsing.cpp"
|
||||
#endif
|
||||
@ -8,9 +8,8 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
||||
char const* buf_begin = buf;
|
||||
ssize remaining = buf_size;
|
||||
|
||||
local_persist StringTable tok_map;
|
||||
do_once() {
|
||||
tok_map = hashtable_init(Str, _ctx->Allocator_DyanmicContainers );
|
||||
if (_ctx->token_fmt_map.Hashes == nullptr) {
|
||||
_ctx->token_fmt_map = hashtable_init(Str, _ctx->Allocator_DyanmicContainers );
|
||||
}
|
||||
// Populate token pairs
|
||||
{
|
||||
@ -22,7 +21,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
||||
Str value = va_arg( va, Str );
|
||||
|
||||
u32 key = crc32( token, c_str_len(token) );
|
||||
hashtable_set( tok_map, key, value );
|
||||
hashtable_set( _ctx->token_fmt_map, key, value );
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,8 +56,8 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
||||
|
||||
char const* token = fmt + 1;
|
||||
|
||||
u32 key = crc32( token, tok_len );
|
||||
Str* value = hashtable_get(tok_map, key );
|
||||
u32 key = crc32( token, tok_len );
|
||||
Str* value = hashtable_get(_ctx->token_fmt_map, key );
|
||||
|
||||
if ( value )
|
||||
{
|
||||
@ -87,7 +86,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
||||
current = * fmt;
|
||||
}
|
||||
}
|
||||
hashtable_clear(tok_map);
|
||||
hashtable_clear(_ctx->token_fmt_map);
|
||||
ssize result = buf_size - remaining;
|
||||
return result;
|
||||
}
|
||||
|
@ -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.
|
||||
@ -516,7 +516,6 @@ CodeClass def_class( Str name, Opts_def_struct p )
|
||||
GEN_DEBUG_TRAP();
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
if ( p.attributes && p.attributes->Type != CT_PlatformAttributes ) {
|
||||
log_failure( "gen::def_class: attributes was not a 'PlatformAttributes' type: %s", code_debug_str(p.attributes) );
|
||||
GEN_DEBUG_TRAP();
|
||||
@ -529,9 +528,13 @@ CodeClass def_class( Str name, Opts_def_struct p )
|
||||
}
|
||||
|
||||
CodeClass
|
||||
result = (CodeClass) make_code();
|
||||
result->Name = cache_str( name );
|
||||
result->ModuleFlags = p.mflags;
|
||||
result = (CodeClass) make_code();
|
||||
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 )
|
||||
{
|
||||
switch ( p.body->Type )
|
||||
@ -552,44 +555,32 @@ CodeClass def_class( Str name, Opts_def_struct p )
|
||||
else {
|
||||
result->Type = CT_Class_Fwd;
|
||||
}
|
||||
|
||||
result->Attributes = p.attributes;
|
||||
result->ParentAccess = p.parent_access;
|
||||
result->ParentType = p.parent;
|
||||
|
||||
for (s32 idx = 0; idx < p.num_interfaces; idx++ ) {
|
||||
class_add_interface(result, p.interfaces[idx] );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeDefine def_define( Str name, Str content, Opts_def_define p )
|
||||
CodeDefine def_define( Str name, MacroType type, Opts_def_define p )
|
||||
{
|
||||
if ( ! name_check( def_define, name ) ) {
|
||||
GEN_DEBUG_TRAP();
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
CodeDefine
|
||||
result = (CodeDefine) make_code();
|
||||
result->Type = CT_Preprocess_Define;
|
||||
result->Name = cache_str( name );
|
||||
|
||||
if ( content.Len <= 0 || content.Ptr == nullptr )
|
||||
result->Content = cache_str( txt("") );
|
||||
result->Params = p.params;
|
||||
if ( p.content.Len <= 0 || p.content.Ptr == nullptr )
|
||||
result->Body = untyped_str( txt("\n") );
|
||||
else
|
||||
result->Content = cache_str( strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S\n", content)) );
|
||||
result->Body = untyped_str( strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S\n", p.content)) );
|
||||
|
||||
b32 append_preprocess_defines = ! p.dont_append_preprocess_defines;
|
||||
if ( append_preprocess_defines ) {
|
||||
// Add the define to PreprocessorDefines for usage in parsing
|
||||
s32 lex_id_len = 0;
|
||||
for (; lex_id_len < result->Name.Len; ++ lex_id_len ) {
|
||||
if ( result->Name.Ptr[lex_id_len] == '(' )
|
||||
break;
|
||||
}
|
||||
Str lex_id = { result->Name.Ptr, lex_id_len };
|
||||
array_append(_ctx->PreprocessorDefines, cache_str(lex_id) );
|
||||
b32 register_define = ! p.dont_register_to_preprocess_macros;
|
||||
if ( register_define ) {
|
||||
Macro macro_entry = { result->Name, type, p.flags };
|
||||
register_macro(macro_entry);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1075,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;
|
||||
|
||||
@ -1122,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 ) {
|
||||
@ -1135,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;
|
||||
}
|
||||
@ -1146,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;
|
||||
}
|
||||
@ -1284,7 +1276,7 @@ CodeUsing def_using_namespace( Str name )
|
||||
|
||||
CodeVar def_variable( CodeTypename type, Str name, Opts_def_variable p )
|
||||
{
|
||||
if ( ! name_check( def_variable, name ) || null_check( def_variable, type ) ) {
|
||||
if ( ! name_check( def_variable, name ) || ! null_check( def_variable, type ) ) {
|
||||
GEN_DEBUG_TRAP();
|
||||
return InvalidCode;
|
||||
}
|
||||
@ -1379,7 +1371,7 @@ CodeBody def_class_body( s32 num, ... )
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeBody def_class_body( s32 num, Code* codes )
|
||||
CodeBody def_class_body_arr( s32 num, Code* codes )
|
||||
{
|
||||
def_body_code_array_start( def_class_body );
|
||||
|
||||
@ -1410,6 +1402,67 @@ CodeBody def_class_body( s32 num, Code* codes )
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeDefineParams def_define_params( s32 num, ... )
|
||||
{
|
||||
def_body_start( def_define_params );
|
||||
|
||||
va_list va;
|
||||
va_start(va, num);
|
||||
|
||||
Code_POD pod = va_arg(va, Code_POD);
|
||||
CodeDefineParams param = pcast( CodeDefineParams, pod );
|
||||
|
||||
null_check( def_define_params, param );
|
||||
if ( param->Type != CT_Parameters_Define ) {
|
||||
log_failure( "gen::def_define_params: param %d is not a parameter for a preprocessor define", num - num + 1 );
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
CodeDefineParams result = (CodeDefineParams) code_duplicate(param);
|
||||
while ( -- num )
|
||||
{
|
||||
pod = va_arg(va, Code_POD);
|
||||
param = pcast( CodeDefineParams, pod );
|
||||
if ( param->Type != CT_Parameters_Define ) {
|
||||
log_failure( "gen::def_define_params: param %d is not a parameter for a preprocessor define", num - num + 1 );
|
||||
return InvalidCode;
|
||||
}
|
||||
define_params_append(result, param );
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeDefineParams def_define_params_arr( s32 num, CodeDefineParams* codes )
|
||||
{
|
||||
def_body_code_array_start( def_define_params );
|
||||
|
||||
# define check_current(current) \
|
||||
if ( current == nullptr ) { \
|
||||
log_failure("gen::def_define_params: Provide a null code in codes array"); \
|
||||
return InvalidCode; \
|
||||
} \
|
||||
if (current->Type != CT_Parameters_Define ) { \
|
||||
log_failure("gen::def_define_params: Code in coes array is not of paramter for preprocessor define type - %s", code_debug_str(current) ); \
|
||||
return InvalidCode; \
|
||||
}
|
||||
CodeDefineParams current = (CodeDefineParams)code_duplicate(* codes);
|
||||
check_current(current);
|
||||
|
||||
CodeDefineParams
|
||||
result = (CodeDefineParams) make_code();
|
||||
result->Name = current->Name;
|
||||
result->Type = current->Type;
|
||||
while( codes++, current = * codes, num--, num > 0 ) {
|
||||
check_current(current);
|
||||
define_params_append(result, current );
|
||||
}
|
||||
# undef check_current
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeBody def_enum_body( s32 num, ... )
|
||||
{
|
||||
def_body_start( def_enum_body );
|
||||
@ -1440,7 +1493,7 @@ CodeBody def_enum_body( s32 num, ... )
|
||||
return (CodeBody) result;
|
||||
}
|
||||
|
||||
CodeBody def_enum_body( s32 num, Code* codes )
|
||||
CodeBody def_enum_body_arr( s32 num, Code* codes )
|
||||
{
|
||||
def_body_code_array_start( def_enum_body );
|
||||
|
||||
@ -1501,7 +1554,7 @@ CodeBody def_export_body( s32 num, ... )
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeBody def_export_body( s32 num, Code* codes )
|
||||
CodeBody def_export_body_arr( s32 num, Code* codes )
|
||||
{
|
||||
def_body_code_array_start( def_export_body );
|
||||
|
||||
@ -1567,7 +1620,7 @@ CodeBody def_extern_link_body( s32 num, ... )
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeBody def_extern_link_body( s32 num, Code* codes )
|
||||
CodeBody def_extern_link_body_arr( s32 num, Code* codes )
|
||||
{
|
||||
def_body_code_array_start( def_extern_linkage_body );
|
||||
|
||||
@ -1634,7 +1687,7 @@ CodeBody def_function_body( s32 num, ... )
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeBody def_function_body( s32 num, Code* codes )
|
||||
CodeBody def_function_body_arr( s32 num, Code* codes )
|
||||
{
|
||||
def_body_code_array_start( def_function_body );
|
||||
|
||||
@ -1705,7 +1758,7 @@ CodeBody def_global_body( s32 num, ... )
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeBody def_global_body( s32 num, Code* codes )
|
||||
CodeBody def_global_body_arr( s32 num, Code* codes )
|
||||
{
|
||||
def_body_code_array_start( def_global_body );
|
||||
|
||||
@ -1776,7 +1829,7 @@ CodeBody def_namespace_body( s32 num, ... )
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeBody def_namespace_body( s32 num, Code* codes )
|
||||
CodeBody def_namespace_body_arr( s32 num, Code* codes )
|
||||
{
|
||||
def_body_code_array_start( def_namespace_body );
|
||||
|
||||
@ -1838,7 +1891,7 @@ CodeParams def_params( s32 num, ... )
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeParams def_params( s32 num, CodeParams* codes )
|
||||
CodeParams def_params_arr( s32 num, CodeParams* codes )
|
||||
{
|
||||
def_body_code_array_start( def_params );
|
||||
|
||||
@ -1894,7 +1947,7 @@ CodeSpecifiers def_specifiers( s32 num, ... )
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeSpecifiers def_specifiers( s32 num, Specifier* specs )
|
||||
CodeSpecifiers def_specifiers_arr( s32 num, Specifier* specs )
|
||||
{
|
||||
if ( num <= 0 ) {
|
||||
log_failure("gen::def_specifiers: num cannot be zero or less");
|
||||
@ -1953,7 +2006,7 @@ CodeBody def_struct_body( s32 num, ... )
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeBody def_struct_body( s32 num, Code* codes )
|
||||
CodeBody def_struct_body_arr( s32 num, Code* codes )
|
||||
{
|
||||
def_body_code_array_start( def_struct_body );
|
||||
|
||||
@ -2014,7 +2067,7 @@ CodeBody def_union_body( s32 num, ... )
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeBody def_union_body( s32 num, Code* codes )
|
||||
CodeBody def_union_body_arr( s32 num, Code* codes )
|
||||
{
|
||||
def_body_code_array_start( def_union_body );
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "interface.upfront.cpp"
|
||||
#include "gen/etoktype.cpp"
|
||||
@ -112,7 +112,158 @@ void lexer_end_line( LexContext* ctx )
|
||||
}
|
||||
#define end_line() lexer_end_line(ctx)
|
||||
|
||||
forceinline
|
||||
// TODO(Ed): We need to to attempt to recover from a lex failure?
|
||||
s32 lex_preprocessor_define( LexContext* ctx )
|
||||
{
|
||||
Token name = { { ctx->scanner, 1 }, Tok_Identifier, ctx->line, ctx->column, TF_Preprocess };
|
||||
move_forward();
|
||||
|
||||
while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) ) {
|
||||
move_forward();
|
||||
name.Text.Len++;
|
||||
}
|
||||
|
||||
Specifier spec = str_to_specifier( name.Text );
|
||||
TokType attrib = str_to_toktype( name.Text );
|
||||
b32 not_specifier = spec == Spec_Invalid;
|
||||
b32 not_attribute = attrib <= Tok___Attributes_Start;
|
||||
|
||||
Macro macro = { name.Text, MT_Expression, (MacroFlags)0 };
|
||||
Macro* registered_macro = lookup_macro(name.Text);
|
||||
|
||||
if ( registered_macro == nullptr && not_specifier && not_attribute ) {
|
||||
log_fmt("Warning: '%S' was not registered before the lexer processed its #define directive, it will be registered as a expression macro\n"
|
||||
, name.Text
|
||||
);
|
||||
// GEN_DEBUG_TRAP();
|
||||
}
|
||||
array_append( _ctx->Lexer_Tokens, name );
|
||||
|
||||
if ( ctx->left && (* ctx->scanner) == '(' )
|
||||
{
|
||||
if (registered_macro && ! macro_is_functional(* registered_macro)) {
|
||||
log_fmt("Warning: %S registered macro is not flagged as functional yet the definition detects opening parenthesis '(' for arguments\n"
|
||||
, name.Text
|
||||
);
|
||||
// GEN_DEBUG_TRAP();
|
||||
}
|
||||
else {
|
||||
macro.Flags |= MF_Functional;
|
||||
}
|
||||
|
||||
Token opening_paren = { { ctx->scanner, 1 }, Tok_Paren_Open, ctx->line, ctx->column, TF_Preprocess };
|
||||
array_append( _ctx->Lexer_Tokens, opening_paren );
|
||||
move_forward();
|
||||
|
||||
Token last_parameter = {};
|
||||
// We need to tokenize the define's arguments now:
|
||||
while( ctx->left && * ctx->scanner != ')')
|
||||
{
|
||||
skip_whitespace();
|
||||
|
||||
Str possible_varadic = { ctx->scanner, 3 };
|
||||
if ( ctx->left > 3 && str_are_equal( txt("..."), possible_varadic ) ) {
|
||||
Token parameter = { { ctx->scanner, 3 }, Tok_Preprocess_Define_Param, ctx->line, ctx->column, TF_Preprocess };
|
||||
move_forward();
|
||||
move_forward();
|
||||
move_forward();
|
||||
|
||||
array_append(_ctx->Lexer_Tokens, parameter);
|
||||
skip_whitespace();
|
||||
last_parameter = parameter;
|
||||
|
||||
while ( (* ctx->scanner) == '\\' ) {
|
||||
move_forward();
|
||||
skip_whitespace();
|
||||
}
|
||||
if (* ctx->scanner != ')' )
|
||||
{
|
||||
log_failure("lex_preprocessor_define(%d, %d): Expected a ')' after '...' (varaidc macro param) %S\n"
|
||||
, ctx->line
|
||||
, ctx->column
|
||||
, name.Text
|
||||
);
|
||||
return Lex_ReturnNull;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if ( (* ctx->scanner) == '\\' ) {
|
||||
move_forward();
|
||||
skip_whitespace();
|
||||
continue;
|
||||
}
|
||||
else if ( char_is_alpha( (* ctx->scanner) ) || (* ctx->scanner) == '_' )
|
||||
{
|
||||
Token parameter = { { ctx->scanner, 1 }, Tok_Preprocess_Define_Param, ctx->line, ctx->column, TF_Preprocess };
|
||||
move_forward();
|
||||
|
||||
while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) )
|
||||
{
|
||||
move_forward();
|
||||
parameter.Text.Len++;
|
||||
}
|
||||
array_append(_ctx->Lexer_Tokens, parameter);
|
||||
skip_whitespace();
|
||||
last_parameter = parameter;
|
||||
}
|
||||
else {
|
||||
log_failure("lex_preprocessor_define(%d, %d): Expected a '_' or alpha character for a parameter name for %S\n"
|
||||
, ctx->line
|
||||
, ctx->column
|
||||
, name.Text
|
||||
);
|
||||
return Lex_ReturnNull;
|
||||
}
|
||||
|
||||
if (* ctx->scanner == ')' )
|
||||
break;
|
||||
|
||||
// There should be a comma
|
||||
if ( * ctx->scanner != ',' ) {
|
||||
log_failure("lex_preprocessor_define(%d, %d): Expected a comma after parameter %S for %S\n"
|
||||
, ctx->line
|
||||
, ctx->column
|
||||
, last_parameter.Text
|
||||
, name.Text
|
||||
);
|
||||
return Lex_ReturnNull;
|
||||
}
|
||||
Token comma = { { ctx->scanner, 1 }, Tok_Comma, ctx->line, ctx->column, TF_Preprocess };
|
||||
array_append(_ctx->Lexer_Tokens, comma);
|
||||
move_forward();
|
||||
}
|
||||
|
||||
if ( * ctx->scanner != ')' ) {
|
||||
log_failure("lex_preprocessor_define(%d, %d): Expected a ')' after last_parameter %S for %S (ran out of characters...)\n"
|
||||
, ctx->line
|
||||
, ctx->column
|
||||
, last_parameter.Text
|
||||
, name.Text
|
||||
);
|
||||
return Lex_ReturnNull;
|
||||
}
|
||||
Token closing_paren = { { ctx->scanner, 1 }, Tok_Paren_Close, ctx->line, ctx->column, TF_Preprocess };
|
||||
array_append(_ctx->Lexer_Tokens, closing_paren);
|
||||
move_forward();
|
||||
}
|
||||
else if ( registered_macro && macro_is_functional( * registered_macro) ) {
|
||||
if (registered_macro && ! macro_is_functional(* registered_macro)) {
|
||||
log_fmt("Warning: %S registered macro is flagged as functional yet the definition detects no opening parenthesis '(' for arguments\n"
|
||||
, name.Text
|
||||
);
|
||||
GEN_DEBUG_TRAP();
|
||||
}
|
||||
}
|
||||
|
||||
if ( registered_macro == nullptr ) {
|
||||
register_macro(macro);
|
||||
}
|
||||
|
||||
// Define's content handled by lex_preprocessor_directive (the original caller of this)
|
||||
return Lex_Continue;
|
||||
}
|
||||
|
||||
// TODO(Ed): We need to to attempt to recover from a lex failure?
|
||||
s32 lex_preprocessor_directive( LexContext* ctx )
|
||||
{
|
||||
char const* hash = ctx->scanner;
|
||||
@ -129,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 )
|
||||
@ -215,28 +366,9 @@ s32 lex_preprocessor_directive( LexContext* ctx )
|
||||
|
||||
if ( ctx->token.Type == Tok_Preprocess_Define )
|
||||
{
|
||||
Token name = { { ctx->scanner, 0 }, Tok_Identifier, ctx->line, ctx->column, TF_Preprocess };
|
||||
|
||||
name.Text.Ptr = ctx->scanner;
|
||||
name.Text.Len = 1;
|
||||
move_forward();
|
||||
|
||||
while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) )
|
||||
{
|
||||
move_forward();
|
||||
name.Text.Len++;
|
||||
}
|
||||
|
||||
if ( ctx->left && (* ctx->scanner) == '(' )
|
||||
{
|
||||
move_forward();
|
||||
name.Text.Len++;
|
||||
}
|
||||
|
||||
array_append( _ctx->Lexer_Tokens, name );
|
||||
|
||||
u64 key = crc32( name.Text.Ptr, name.Text.Len );
|
||||
hashtable_set(ctx->defines, key, tok_to_str(name) );
|
||||
u32 result = lex_preprocessor_define(ctx); // handles: #define <name>( <params> ) - define's content handled later on within this scope.
|
||||
if (result != Lex_Continue)
|
||||
return Lex_ReturnNull;
|
||||
}
|
||||
|
||||
Token preprocess_content = { { ctx->scanner, 0 }, Tok_Preprocess_Content, ctx->line, ctx->column, TF_Preprocess };
|
||||
@ -286,7 +418,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
|
||||
s32 within_string = false;
|
||||
s32 within_char = false;
|
||||
|
||||
// SkipWhitespace();
|
||||
// Consume preprocess content
|
||||
while ( ctx->left )
|
||||
{
|
||||
if ( (* ctx->scanner) == '"' && ! within_char )
|
||||
@ -322,6 +454,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
|
||||
, (* ctx->scanner), ctx->line, ctx->column
|
||||
, directive_str, preprocess_content.Line, preprocess_content.Column
|
||||
, content_str );
|
||||
return Lex_ReturnNull;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -346,33 +479,30 @@ 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 )
|
||||
{
|
||||
if ( ctx->token.Type != Tok_Invalid ) {
|
||||
array_append( _ctx->Lexer_Tokens, ctx->token );
|
||||
return;
|
||||
}
|
||||
|
||||
TokType type = str_to_toktype( tok_to_str(ctx->token) );
|
||||
TokType type = str_to_toktype( ctx->token.Text );
|
||||
|
||||
if (type <= Tok_Access_Public && type >= Tok_Access_Private )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if ( type > Tok___Attributes_Start )
|
||||
{
|
||||
if ( type > Tok___Attributes_Start ) {
|
||||
ctx->token.Flags |= TF_Attribute;
|
||||
}
|
||||
|
||||
if ( type == Tok_Decl_Extern_Linkage )
|
||||
{
|
||||
skip_whitespace();
|
||||
|
||||
if ( (* ctx->scanner) != '"' )
|
||||
{
|
||||
if ( (* ctx->scanner) != '"' ) {
|
||||
type = Tok_Spec_Extern;
|
||||
ctx->token.Flags |= TF_Specifier;
|
||||
}
|
||||
@ -381,7 +511,6 @@ void lex_found_token( LexContext* ctx )
|
||||
array_append( _ctx->Lexer_Tokens, ctx->token );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ( type <= Tok_Star && type >= Tok_Spec_Alignas)
|
||||
|| type == Tok_Ampersand
|
||||
|| type == Tok_Ampersand_DBL )
|
||||
@ -391,8 +520,6 @@ void lex_found_token( LexContext* ctx )
|
||||
array_append( _ctx->Lexer_Tokens, ctx->token );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ( type != Tok_Invalid )
|
||||
{
|
||||
ctx->token.Type = type;
|
||||
@ -400,50 +527,34 @@ void lex_found_token( LexContext* ctx )
|
||||
return;
|
||||
}
|
||||
|
||||
u64 key = 0;
|
||||
if ( (* ctx->scanner) == '(')
|
||||
key = crc32( ctx->token.Text.Ptr, ctx->token.Text.Len + 1 );
|
||||
else
|
||||
key = crc32( ctx->token.Text.Ptr, ctx->token.Text.Len );
|
||||
|
||||
Str* define = hashtable_get(ctx->defines, key );
|
||||
if ( define )
|
||||
{
|
||||
ctx->token.Type = Tok_Preprocess_Macro;
|
||||
|
||||
// Want to ignore any arguments the define may have as they can be execution expressions.
|
||||
if ( ctx->left && (* ctx->scanner) == '(' )
|
||||
{
|
||||
move_forward();
|
||||
ctx->token.Text.Len++;
|
||||
|
||||
s32 level = 0;
|
||||
while ( ctx->left && ((* ctx->scanner) != ')' || level > 0) )
|
||||
{
|
||||
if ( (* ctx->scanner) == '(' )
|
||||
level++;
|
||||
|
||||
else if ( (* ctx->scanner) == ')' && level > 0 )
|
||||
level--;
|
||||
|
||||
move_forward();
|
||||
ctx->token.Text.Len++;
|
||||
}
|
||||
|
||||
move_forward();
|
||||
ctx->token.Text.Len++;
|
||||
Macro* macro = lookup_macro( ctx->token.Text );
|
||||
b32 has_args = ctx->left && (* ctx->scanner) == '(';
|
||||
b32 resolved_to_macro = false;
|
||||
if (macro) {
|
||||
ctx->token.Type = macrotype_to_toktype(macro->Type);
|
||||
b32 is_functional = macro_is_functional(* macro);
|
||||
resolved_to_macro = has_args ? is_functional : ! is_functional;
|
||||
if ( ! resolved_to_macro && GEN_BUILD_DEBUG ) {
|
||||
log_fmt("Info(%d, %d): %S identified as a macro but usage here does not resolve to one (interpreting as identifier)\n"
|
||||
, ctx->token.Line
|
||||
, ctx->token.Line
|
||||
, macro->Name
|
||||
);
|
||||
}
|
||||
}
|
||||
if ( resolved_to_macro )
|
||||
{
|
||||
// TODO(Ed): When we introduce a macro AST (and expression support), we'll properly lex this section.
|
||||
// Want to ignore any arguments the define may have as they can be execution expressions.
|
||||
if ( has_args ) {
|
||||
ctx->token.Flags |= TF_Macro_Functional;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
//if ( (* ctx->scanner) == '\r' && ctx->scanner[1] == '\n' )
|
||||
//{
|
||||
// move_forward();
|
||||
// ctx->token..Text.Length++;
|
||||
//}
|
||||
//else if ( (* ctx->scanner) == '\n' )
|
||||
//{
|
||||
// move_forward();
|
||||
// ctx->token..Text.Length++;
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -453,6 +564,7 @@ void lex_found_token( LexContext* ctx )
|
||||
array_append( _ctx->Lexer_Tokens, ctx->token );
|
||||
}
|
||||
|
||||
// TODO(Ed): We need to to attempt to recover from a lex failure?
|
||||
neverinline
|
||||
// TokArray lex( Array<Token> tokens, Str content )
|
||||
TokArray lex( Str content )
|
||||
@ -461,7 +573,6 @@ TokArray lex( Str content )
|
||||
c.content = content;
|
||||
c.left = content.Len;
|
||||
c.scanner = content.Ptr;
|
||||
c.defines = _ctx->Lexer_defines;
|
||||
|
||||
char const* word = c.scanner;
|
||||
s32 word_length = 0;
|
||||
@ -477,26 +588,10 @@ TokArray lex( Str content )
|
||||
return null_array;
|
||||
}
|
||||
|
||||
for ( StrCached* entry = array_begin(_ctx->PreprocessorDefines); entry != array_end(_ctx->PreprocessorDefines); entry = array_next(_ctx->PreprocessorDefines, entry))
|
||||
{
|
||||
s32 length = 0;
|
||||
char const* entry_scanner = (*entry).Ptr;
|
||||
while ( entry->Len > length && (char_is_alphanumeric( *entry_scanner ) || *entry_scanner == '_') )
|
||||
{
|
||||
entry_scanner++;
|
||||
length ++;
|
||||
}
|
||||
if ( entry_scanner[0] == '(' )
|
||||
{
|
||||
length++;
|
||||
}
|
||||
|
||||
u64 key = crc32( entry->Ptr, length );
|
||||
hashtable_set(c.defines, key, * entry );
|
||||
}
|
||||
|
||||
array_clear(_ctx->Lexer_Tokens);
|
||||
|
||||
b32 preprocess_args = true;
|
||||
|
||||
while (c.left )
|
||||
{
|
||||
#if 0
|
||||
@ -707,7 +802,7 @@ TokArray lex( Str content )
|
||||
{
|
||||
Str text = { c.scanner, 1 };
|
||||
c.token.Text = text;
|
||||
c.token.Type = Tok_Capture_Start;
|
||||
c.token.Type = Tok_Paren_Open;
|
||||
|
||||
if (c.left)
|
||||
move_forward();
|
||||
@ -717,7 +812,7 @@ TokArray lex( Str content )
|
||||
{
|
||||
Str text = { c.scanner, 1 };
|
||||
c.token.Text = text;
|
||||
c.token.Type = Tok_Capture_End;
|
||||
c.token.Type = Tok_Paren_Close;
|
||||
|
||||
if (c.left)
|
||||
move_forward();
|
||||
@ -938,7 +1033,7 @@ TokArray lex( Str content )
|
||||
goto FoundToken;
|
||||
}
|
||||
|
||||
// Dash is unfortunatlly a bit more complicated...
|
||||
// Dash is unfortunately a bit more complicated...
|
||||
case '-':
|
||||
{
|
||||
Str text = { c.scanner, 1 };
|
||||
@ -1075,8 +1170,7 @@ TokArray lex( Str content )
|
||||
c.token.Text = text;
|
||||
move_forward();
|
||||
|
||||
while ( c.left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) )
|
||||
{
|
||||
while ( c.left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) ) {
|
||||
move_forward();
|
||||
c.token.Text.Len++;
|
||||
}
|
||||
@ -1102,8 +1196,7 @@ TokArray lex( Str content )
|
||||
move_forward();
|
||||
c.token.Text.Len++;
|
||||
|
||||
while ( c.left && char_is_hex_digit((* ctx->scanner)) )
|
||||
{
|
||||
while ( c.left && char_is_hex_digit((* ctx->scanner)) ) {
|
||||
move_forward();
|
||||
c.token.Text.Len++;
|
||||
}
|
||||
@ -1111,8 +1204,7 @@ TokArray lex( Str content )
|
||||
goto FoundToken;
|
||||
}
|
||||
|
||||
while ( c.left && char_is_digit((* ctx->scanner)) )
|
||||
{
|
||||
while ( c.left && char_is_digit((* ctx->scanner)) ) {
|
||||
move_forward();
|
||||
c.token.Text.Len++;
|
||||
}
|
||||
@ -1122,8 +1214,7 @@ TokArray lex( Str content )
|
||||
move_forward();
|
||||
c.token.Text.Len++;
|
||||
|
||||
while ( c.left && char_is_digit((* ctx->scanner)) )
|
||||
{
|
||||
while ( c.left && char_is_digit((* ctx->scanner)) ) {
|
||||
move_forward();
|
||||
c.token.Text.Len++;
|
||||
}
|
||||
@ -1141,8 +1232,7 @@ TokArray lex( Str content )
|
||||
c.token.Text.Len++;
|
||||
|
||||
// Handle 'll'/'LL' as a special case when we just processed an 'l'/'L'
|
||||
if (c.left && (prev == 'l' || prev == 'L') && ((* ctx->scanner) == 'l' || (* ctx->scanner) == 'L'))
|
||||
{
|
||||
if (c.left && (prev == 'l' || prev == 'L') && ((* ctx->scanner) == 'l' || (* ctx->scanner) == 'L')) {
|
||||
move_forward();
|
||||
c.token.Text.Len++;
|
||||
}
|
||||
@ -1168,8 +1258,7 @@ TokArray lex( Str content )
|
||||
log_failure( "Failed to lex token '%c' (%d, %d)\n%s", (* ctx->scanner), c.line, c.column, context_str );
|
||||
|
||||
// Skip to next whitespace since we can't know if anything else is valid until then.
|
||||
while ( c.left && ! char_is_space( (* ctx->scanner) ) )
|
||||
{
|
||||
while ( c.left && ! char_is_space( (* ctx->scanner) ) ) {
|
||||
move_forward();
|
||||
}
|
||||
}
|
||||
@ -1178,17 +1267,15 @@ TokArray lex( Str content )
|
||||
{
|
||||
lex_found_token( ctx );
|
||||
TokType last_type = array_back(_ctx->Lexer_Tokens)->Type;
|
||||
if ( last_type == Tok_Preprocess_Macro )
|
||||
if ( last_type == Tok_Preprocess_Macro_Stmt || last_type == Tok_Preprocess_Macro_Expr )
|
||||
{
|
||||
Token thanks_c = { { c.scanner, 0 }, Tok_Invalid, c.line, c.column, TF_Null };
|
||||
c.token = thanks_c;
|
||||
if ( (* ctx->scanner) == '\r')
|
||||
{
|
||||
if ( (* ctx->scanner) == '\r') {
|
||||
move_forward();
|
||||
c.token.Text.Len = 1;
|
||||
}
|
||||
|
||||
if ( (* ctx->scanner) == '\n' )
|
||||
if ( (* ctx->scanner) == '\n' )
|
||||
{
|
||||
c.token.Type = Tok_NewLine;
|
||||
c.token.Text.Len++;
|
||||
@ -1201,20 +1288,16 @@ TokArray lex( Str content )
|
||||
}
|
||||
}
|
||||
|
||||
if ( array_num(_ctx->Lexer_Tokens) == 0 )
|
||||
{
|
||||
if ( array_num(_ctx->Lexer_Tokens) == 0 ) {
|
||||
log_failure( "Failed to lex any tokens" );
|
||||
{
|
||||
TokArray tok_array = {};
|
||||
return tok_array;
|
||||
}
|
||||
TokArray tok_array = {};
|
||||
return tok_array;
|
||||
}
|
||||
|
||||
hashtable_clear(_ctx->Lexer_defines);
|
||||
// defines_map_arena.free();
|
||||
TokArray result = { _ctx->Lexer_Tokens, 0 };
|
||||
return result;
|
||||
}
|
||||
|
||||
#undef move_forward
|
||||
#undef skip_whitespace
|
||||
#undef end_line
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
// These macros are used in the swtich cases within parser.cpp
|
||||
|
||||
#define GEN_PARSER_CLASS_STRUCT_BODY_ALLOWED_MEMBER_TOK_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_CLASS_STRUCT_BODY_ALLOWED_MEMBER_TOK_SPECIFIER_CASES \
|
||||
case Tok_Spec_Consteval: \
|
||||
case Tok_Spec_Constexpr: \
|
||||
case Tok_Spec_Constinit: \
|
||||
@ -13,7 +13,7 @@ case Tok_Spec_Static: \
|
||||
case Tok_Spec_Volatile: \
|
||||
case Tok_Spec_Virtual
|
||||
|
||||
#define GEN_PARSER_CLASS_STRUCT_BODY_ALLOWED_MEMBER_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_CLASS_STRUCT_BODY_ALLOWED_MEMBER_SPECIFIER_CASES \
|
||||
case Spec_Constexpr: \
|
||||
case Spec_Constinit: \
|
||||
case Spec_Explicit: \
|
||||
@ -25,7 +25,7 @@ case Spec_Static: \
|
||||
case Spec_Volatile: \
|
||||
case Spec_Virtual
|
||||
|
||||
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_TOK_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_TOK_SPECIFIER_CASES \
|
||||
case Tok_Spec_Consteval: \
|
||||
case Tok_Spec_Constexpr: \
|
||||
case Tok_Spec_Constinit: \
|
||||
@ -37,7 +37,7 @@ case Tok_Spec_Internal_Linkage: \
|
||||
case Tok_Spec_NeverInline: \
|
||||
case Tok_Spec_Static
|
||||
|
||||
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_SPECIFIER_CASES \
|
||||
case Spec_Constexpr: \
|
||||
case Spec_Constinit: \
|
||||
case Spec_ForceInline: \
|
||||
@ -50,12 +50,12 @@ case Spec_NeverInline: \
|
||||
case Spec_Static: \
|
||||
case Spec_Volatile
|
||||
|
||||
#define GEN_PARSER_FRIEND_ALLOWED_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_FRIEND_ALLOWED_SPECIFIER_CASES \
|
||||
case Spec_Const: \
|
||||
case Spec_Inline: \
|
||||
case Spec_ForceInline
|
||||
|
||||
#define GEN_PARSER_FUNCTION_ALLOWED_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_FUNCTION_ALLOWED_SPECIFIER_CASES \
|
||||
case Spec_Const: \
|
||||
case Spec_Consteval: \
|
||||
case Spec_Constexpr: \
|
||||
@ -66,7 +66,7 @@ case Spec_Inline: \
|
||||
case Spec_NeverInline: \
|
||||
case Spec_Static
|
||||
|
||||
#define GEN_PARSER_OPERATOR_ALLOWED_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_OPERATOR_ALLOWED_SPECIFIER_CASES \
|
||||
case Spec_Const: \
|
||||
case Spec_Constexpr: \
|
||||
case Spec_ForceInline: \
|
||||
@ -74,7 +74,7 @@ case Spec_Inline: \
|
||||
case Spec_NeverInline: \
|
||||
case Spec_Static
|
||||
|
||||
#define GEN_PARSER_TEMPLATE_ALLOWED_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_TEMPLATE_ALLOWED_SPECIFIER_CASES \
|
||||
case Spec_Const: \
|
||||
case Spec_Constexpr: \
|
||||
case Spec_Constinit: \
|
||||
@ -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
|
||||
|
||||
|
||||
|
@ -1,42 +1,28 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "types.hpp"
|
||||
#include "gen/ecode.hpp"
|
||||
#include "gen/eoperator.hpp"
|
||||
#include "gen/especifier.hpp"
|
||||
#include "gen/etoktype.hpp"
|
||||
#endif
|
||||
|
||||
enum MacroFlags : u32
|
||||
{
|
||||
// Can only be one of these at a time (required)
|
||||
MF_Block_Start = bit(0), // Start of a "block" scope
|
||||
MF_Block_End = bit(1), // End of a "block" scope
|
||||
MF_Case_Statement = bit(2), // Used as a case statement (not utilized by the parser yet)
|
||||
MF_Expression = bit(3), // Used as an expresssion (not utilized by the parser yet)
|
||||
MF_Statement = bit(4), // Used a statement (will expect to be a lone macro)
|
||||
MF_Expects_Body = bit(5), // Expects to consume a braced scope
|
||||
MF_Typename = bit(6), // Behaves as a typename
|
||||
|
||||
// Optional
|
||||
MF_Functional = bit(7),
|
||||
|
||||
MF_Null = 0,
|
||||
MF_UnderlyingType = GEN_U32_MAX,
|
||||
};
|
||||
|
||||
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_Operator = bit(0),
|
||||
TF_Assign = bit(1),
|
||||
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,
|
||||
@ -58,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;
|
||||
@ -70,42 +51,42 @@ bool tok_is_valid( Token tok ) {
|
||||
|
||||
forceinline
|
||||
bool tok_is_access_operator(Token tok) {
|
||||
return bitfield_is_equal( u32, tok.Flags, TF_AccessOperator );
|
||||
return bitfield_is_set( u32, tok.Flags, TF_AccessOperator );
|
||||
}
|
||||
|
||||
forceinline
|
||||
bool tok_is_access_specifier(Token tok) {
|
||||
return bitfield_is_equal( u32, tok.Flags, TF_AccessSpecifier );
|
||||
return bitfield_is_set( u32, tok.Flags, TF_AccessSpecifier );
|
||||
}
|
||||
|
||||
forceinline
|
||||
bool tok_is_attribute(Token tok) {
|
||||
return bitfield_is_equal( u32, tok.Flags, TF_Attribute );
|
||||
return bitfield_is_set( u32, tok.Flags, TF_Attribute );
|
||||
}
|
||||
|
||||
forceinline
|
||||
bool tok_is_operator(Token tok) {
|
||||
return bitfield_is_equal( u32, tok.Flags, TF_Operator );
|
||||
return bitfield_is_set( u32, tok.Flags, TF_Operator );
|
||||
}
|
||||
|
||||
forceinline
|
||||
bool tok_is_preprocessor(Token tok) {
|
||||
return bitfield_is_equal( u32, tok.Flags, TF_Preprocess );
|
||||
return bitfield_is_set( u32, tok.Flags, TF_Preprocess );
|
||||
}
|
||||
|
||||
forceinline
|
||||
bool tok_is_preprocess_cond(Token tok) {
|
||||
return bitfield_is_equal( u32, tok.Flags, TF_Preprocess_Cond );
|
||||
return bitfield_is_set( u32, tok.Flags, TF_Preprocess_Cond );
|
||||
}
|
||||
|
||||
forceinline
|
||||
bool tok_is_specifier(Token tok) {
|
||||
return bitfield_is_equal( u32, tok.Flags, TF_Specifier );
|
||||
return bitfield_is_set( u32, tok.Flags, TF_Specifier );
|
||||
}
|
||||
|
||||
forceinline
|
||||
bool tok_is_end_definition(Token tok) {
|
||||
return bitfield_is_equal( u32, tok.Flags, TF_EndDefinition );
|
||||
return bitfield_is_set( u32, tok.Flags, TF_EndDefinition );
|
||||
}
|
||||
|
||||
StrBuilder tok_to_strbuilder(Token tok);
|
||||
@ -123,7 +104,7 @@ struct LexContext
|
||||
char const* scanner;
|
||||
s32 line;
|
||||
s32 column;
|
||||
StringTable defines;
|
||||
// StringTable defines;
|
||||
Token token;
|
||||
};
|
||||
|
||||
@ -141,3 +122,98 @@ struct ParseContext
|
||||
TokArray Tokens;
|
||||
StackNode* Scope;
|
||||
};
|
||||
|
||||
enum MacroType : u16
|
||||
{
|
||||
MT_Expression, // A macro is assumed to be a expression if not resolved.
|
||||
MT_Statement,
|
||||
MT_Typename,
|
||||
MT_Block_Start, // Not Supported yet
|
||||
MT_Block_End, // Not Supported yet
|
||||
MT_Case_Statement, // Not Supported yet
|
||||
|
||||
MT_UnderlyingType = GEN_U16_MAX,
|
||||
};
|
||||
|
||||
forceinline
|
||||
TokType macrotype_to_toktype( MacroType type ) {
|
||||
switch ( type ) {
|
||||
case MT_Statement : return Tok_Preprocess_Macro_Stmt;
|
||||
case MT_Expression : return Tok_Preprocess_Macro_Expr;
|
||||
case MT_Typename : return Tok_Preprocess_Macro_Typename;
|
||||
}
|
||||
// All others unsupported for now.
|
||||
return Tok_Invalid;
|
||||
}
|
||||
|
||||
inline
|
||||
Str macrotype_to_str( MacroType type )
|
||||
{
|
||||
local_persist
|
||||
Str lookup[] = {
|
||||
{ "Statement", sizeof("Statement") - 1 },
|
||||
{ "Expression", sizeof("Expression") - 1 },
|
||||
{ "Typename", sizeof("Typename") - 1 },
|
||||
{ "Block_Start", sizeof("Block_Start") - 1 },
|
||||
{ "Block_End", sizeof("Block_End") - 1 },
|
||||
{ "Case_Statement", sizeof("Case_Statement") - 1 },
|
||||
};
|
||||
local_persist
|
||||
Str invalid = { "Invalid", sizeof("Invalid") };
|
||||
if ( type > MT_Case_Statement )
|
||||
return invalid;
|
||||
|
||||
return lookup[ type ];
|
||||
}
|
||||
|
||||
enum EMacroFlags : u16
|
||||
{
|
||||
MF_Functional = bit(0), // Macro has parameters (args expected to be passed)
|
||||
MF_Expects_Body = bit(1), // Expects to assign a braced scope to its body.
|
||||
|
||||
// lex__eat wil treat this macro as an identifier if the parser attempts to consume it as one.
|
||||
// ^^^ This is a kludge because we don't support push/pop macro pragmas rn.
|
||||
MF_Allow_As_Identifier = bit(2),
|
||||
|
||||
// lex__eat wil treat this macro as an attribute if the parser attempts to consume it as one.
|
||||
// ^^^ 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/variable definition
|
||||
MF_Allow_As_Attribute = bit(3),
|
||||
|
||||
// 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,
|
||||
};
|
||||
typedef u16 MacroFlags;
|
||||
|
||||
struct Macro
|
||||
{
|
||||
StrCached Name;
|
||||
MacroType Type;
|
||||
MacroFlags Flags;
|
||||
};
|
||||
|
||||
forceinline
|
||||
b32 macro_is_functional( Macro macro ) {
|
||||
return bitfield_is_set( b16, macro.Flags, MF_Functional );
|
||||
}
|
||||
|
||||
forceinline
|
||||
b32 macro_expects_body( Macro macro ) {
|
||||
return bitfield_is_set( b16, macro.Flags, MF_Expects_Body );
|
||||
}
|
||||
|
||||
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
|
||||
forceinline b32 is_functional( Macro macro ) { return bitfield_is_set( b16, macro.Flags, MF_Functional ); }
|
||||
forceinline b32 expects_body ( Macro macro ) { return bitfield_is_set( b16, macro.Flags, MF_Expects_Body ); }
|
||||
#endif
|
||||
|
||||
typedef HashTable(Macro) MacroTable;
|
||||
|
@ -1,91 +1,90 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "../gen.hpp"
|
||||
#endif
|
||||
|
||||
#pragma region StaticData
|
||||
global Context* _ctx;
|
||||
GEN_API global Context* _ctx;
|
||||
GEN_API global u32 context_counter;
|
||||
|
||||
#pragma region Constants
|
||||
global u32 context_counter;
|
||||
GEN_API global Macro enum_underlying_macro;
|
||||
|
||||
global Str enum_underlying_sig;
|
||||
GEN_API global Code Code_Global;
|
||||
GEN_API global Code Code_Invalid;
|
||||
|
||||
global Code Code_Global;
|
||||
global Code Code_Invalid;
|
||||
GEN_API global Code access_public;
|
||||
GEN_API global Code access_protected;
|
||||
GEN_API global Code access_private;
|
||||
|
||||
global Code access_public;
|
||||
global Code access_protected;
|
||||
global Code access_private;
|
||||
GEN_API global CodeAttributes attrib_api_export;
|
||||
GEN_API global CodeAttributes attrib_api_import;
|
||||
|
||||
global CodeAttributes attrib_api_export;
|
||||
global CodeAttributes attrib_api_import;
|
||||
GEN_API global Code module_global_fragment;
|
||||
GEN_API global Code module_private_fragment;
|
||||
|
||||
global Code module_global_fragment;
|
||||
global Code module_private_fragment;
|
||||
GEN_API global Code fmt_newline;
|
||||
|
||||
global Code fmt_newline;
|
||||
GEN_API global CodeParams param_varadic;
|
||||
|
||||
global CodeParams param_varadic;
|
||||
GEN_API global CodePragma pragma_once;
|
||||
|
||||
global CodePragma pragma_once;
|
||||
GEN_API global CodePreprocessCond preprocess_else;
|
||||
GEN_API global CodePreprocessCond preprocess_endif;
|
||||
|
||||
global CodePreprocessCond preprocess_else;
|
||||
global CodePreprocessCond preprocess_endif;
|
||||
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 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;
|
||||
|
||||
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
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "header_start.hpp"
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "macros.hpp"
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "printing.hpp"
|
||||
#endif
|
||||
@ -143,6 +143,7 @@ Array<Type> array_init_reserve(AllocatorInfo allocator, ssize capacity)
|
||||
return {rcast(Type*, header + 1)};
|
||||
}
|
||||
|
||||
forceinline
|
||||
usize array_grow_formula(ssize value) {
|
||||
return 2 * value + 8;
|
||||
}
|
||||
@ -202,7 +203,7 @@ bool array_append_at(Array<Type>* array, Type item, usize idx)
|
||||
ArrayHeader* header = array_get_header(* array);
|
||||
|
||||
ssize slot = idx;
|
||||
if (slot >= header->Num)
|
||||
if (slot >= (ssize)(header->Num))
|
||||
slot = header->Num - 1;
|
||||
|
||||
if (slot < 0)
|
||||
@ -281,10 +282,9 @@ bool array_fill(Array<Type> array, usize begin, usize end, Type value)
|
||||
ArrayHeader* header = array_get_header(array);
|
||||
|
||||
if (begin < 0 || end > header->Num)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
for (ssize idx = ssize(begin); idx < ssize(end); idx++)
|
||||
{
|
||||
for (ssize idx = ssize(begin); idx < ssize(end); idx++) {
|
||||
array[idx] = value;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
@ -354,7 +355,6 @@ bool array_reserve(Array<Type>* array, usize new_capacity)
|
||||
{
|
||||
GEN_ASSERT( array != nullptr);
|
||||
GEN_ASSERT(* array != nullptr);
|
||||
GEN_ASSERT(num > 0)
|
||||
ArrayHeader* header = array_get_header(array);
|
||||
|
||||
if (header->Capacity < new_capacity)
|
||||
@ -416,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)
|
||||
@ -754,7 +754,7 @@ HashTableFindResult hashtable__find(HashTable<Type> table, u64 key)
|
||||
if (table.Entries[result.EntryIndex].Key == key)
|
||||
break;
|
||||
|
||||
result.PrevIndex = result.EntryIndex;
|
||||
result.PrevIndex = result.EntryIndex;
|
||||
result.EntryIndex = table.Entries[result.EntryIndex].Next;
|
||||
}
|
||||
}
|
||||
@ -763,7 +763,7 @@ HashTableFindResult hashtable__find(HashTable<Type> table, u64 key)
|
||||
}
|
||||
|
||||
template<typename Type> forceinline
|
||||
bool hashtable_full(HashTable<Type> table) {
|
||||
b32 hashtable_full(HashTable<Type> table) {
|
||||
GEN_ASSERT_NOT_NULL(table.Hashes);
|
||||
GEN_ASSERT_NOT_NULL(table.Entries);
|
||||
usize critical_load = usize(HashTable_CriticalLoadScale * f32(array_num(table.Hashes)));
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "src_start.cpp"
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "dependencies/platform.hpp"
|
||||
# include "dependencies/macros.hpp"
|
||||
@ -11,10 +11,10 @@
|
||||
#if GEN_BUILD_DEBUG
|
||||
# if defined( GEN_COMPILER_MSVC )
|
||||
# if _MSC_VER < 1300
|
||||
#pragma message("GEN_BUILD_DEBUG: __asm int 3")
|
||||
// #pragma message("GEN_BUILD_DEBUG: __asm int 3")
|
||||
# define GEN_DEBUG_TRAP() __asm int 3 /* Trap to debugger! */
|
||||
# else
|
||||
#pragma message("GEN_BUILD_DEBUG: __debugbreak()")
|
||||
// #pragma message("GEN_BUILD_DEBUG: __debugbreak()")
|
||||
# define GEN_DEBUG_TRAP() __debugbreak()
|
||||
# endif
|
||||
# elif defined( GEN_COMPILER_TINYC )
|
||||
@ -23,7 +23,7 @@
|
||||
# define GEN_DEBUG_TRAP() __builtin_trap()
|
||||
# endif
|
||||
#else
|
||||
#pragma message("GEN_BUILD_DEBUG: omitted")
|
||||
// #pragma message("GEN_BUILD_DEBUG: omitted")
|
||||
# define GEN_DEBUG_TRAP()
|
||||
#endif
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
// NOTE: Things that shouldn't happen with a message!
|
||||
#define GEN_PANIC( msg, ... ) GEN_ASSERT_MSG( 0, msg, ##__VA_ARGS__ )
|
||||
|
||||
#if GEN_BULD_DEBUG
|
||||
#if GEN_BUILD_DEBUG
|
||||
#define GEN_FATAL( ... ) \
|
||||
do \
|
||||
{ \
|
||||
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "strings.cpp"
|
||||
#endif
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "memory.cpp"
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -34,8 +40,11 @@
|
||||
#endif
|
||||
|
||||
#ifndef bit
|
||||
#define bit( Value ) ( 1 << Value )
|
||||
#define bitfield_is_equal( Type, Field, Mask ) ( (scast(Type, Mask) & scast(Type, Field)) == scast(Type, Mask) )
|
||||
#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
|
||||
|
||||
// Mainly intended for forcing the base library to utilize only C-valid constructs or type coercion
|
||||
@ -86,14 +95,16 @@
|
||||
#define stringize( ... ) stringize_va( __VA_ARGS__ )
|
||||
#endif
|
||||
|
||||
#ifndef do_once
|
||||
#define do_once() \
|
||||
static int __do_once_counter_##__LINE__ = 0; \
|
||||
for(; __do_once_counter_##__LINE__ != 1; __do_once_counter_##__LINE__ = 1 ) \
|
||||
#define src_line_str stringize(__LINE__)
|
||||
|
||||
#define do_once_defer( expression ) \
|
||||
static int __do_once_counter_##__LINE__ = 0; \
|
||||
for(; __do_once_counter_##__LINE__ != 1; __do_once_counter_##__LINE__ = 1, (expression)) \
|
||||
#ifndef do_once
|
||||
#define do_once() \
|
||||
local_persist int __do_once_counter_##src_line_str = 0; \
|
||||
for(; __do_once_counter_##src_line_str != 1; __do_once_counter_##src_line_str = 1 ) \
|
||||
|
||||
#define do_once_defer( expression ) \
|
||||
local_persist int __do_once_counter_##src_line_str = 0; \
|
||||
for(;__do_once_counter_##src_line_str != 1; __do_once_counter_##src_line_str = 1, (expression)) \
|
||||
|
||||
#define do_once_start \
|
||||
do \
|
||||
@ -248,9 +259,9 @@
|
||||
# if ! GEN_COMPILER_C
|
||||
# define typeof decltype
|
||||
# elif defined(_MSC_VER)
|
||||
# define typeof(x) __typeof__(x)
|
||||
# define typeof __typeof__
|
||||
# elif defined(__GNUC__) || defined(__clang__)
|
||||
# define typeof(x) __typeof__(x)
|
||||
# define typeof __typeof__
|
||||
# else
|
||||
# error "Compiler not supported"
|
||||
# endif
|
||||
|
@ -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 )
|
||||
@ -346,25 +346,25 @@ void* arena_allocator_proc( void* allocator_data, AllocType type, ssize size, ss
|
||||
switch ( type )
|
||||
{
|
||||
case EAllocation_ALLOC :
|
||||
{
|
||||
void* end = pointer_add( arena->PhysicalStart, arena->TotalUsed );
|
||||
ssize total_size = align_forward_s64( size, alignment );
|
||||
|
||||
// NOTE: Out of memory
|
||||
if ( arena->TotalUsed + total_size > (ssize) arena->TotalSize )
|
||||
{
|
||||
void* end = pointer_add( arena->PhysicalStart, arena->TotalUsed );
|
||||
ssize total_size = align_forward_s64( size, alignment );
|
||||
|
||||
// NOTE: Out of memory
|
||||
if ( arena->TotalUsed + total_size > (ssize) arena->TotalSize )
|
||||
{
|
||||
// zpl__printf_err("%s", "Arena out of memory\n");
|
||||
GEN_FATAL("Arena out of memory! (Possibly could not fit for the largest size Arena!!)");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ptr = align_forward( end, alignment );
|
||||
arena->TotalUsed += total_size;
|
||||
|
||||
if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
|
||||
zero_size( ptr, size );
|
||||
// zpl__printf_err("%s", "Arena out of memory\n");
|
||||
GEN_FATAL("Arena out of memory! (Possibly could not fit for the largest size Arena!!)");
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
ptr = align_forward( end, alignment );
|
||||
arena->TotalUsed += total_size;
|
||||
|
||||
if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
|
||||
zero_size( ptr, size );
|
||||
}
|
||||
break;
|
||||
|
||||
case EAllocation_FREE :
|
||||
// NOTE: Free all at once
|
||||
|
@ -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);
|
||||
@ -225,11 +225,10 @@ forceinline ssize size_remaining(Arena& arena, ssize alignment) { return
|
||||
// This id is defined by Unreal for asserts
|
||||
#pragma push_macro("check")
|
||||
#undef check
|
||||
forceinline void check(Arena& arena) { return arena_check(& arena); };
|
||||
forceinline void check(Arena& arena) { return arena_check(& arena); }
|
||||
#pragma pop_macro("check")
|
||||
#endif
|
||||
|
||||
|
||||
inline
|
||||
AllocatorInfo arena_allocator_info( Arena* arena ) {
|
||||
GEN_ASSERT(arena != nullptr);
|
||||
@ -383,18 +382,18 @@ 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
|
||||
AllocatorInfo allocator_info(Pool& pool) { return pool_allocator_info(& pool); }
|
||||
void clear(Pool& pool) { return pool_clear(& pool); }
|
||||
void free(Pool& pool) { return pool_free(& pool); }
|
||||
forceinline AllocatorInfo allocator_info(Pool& pool) { return pool_allocator_info(& pool); }
|
||||
forceinline void clear(Pool& pool) { return pool_clear(& pool); }
|
||||
forceinline void free(Pool& pool) { return pool_free(& pool); }
|
||||
#endif
|
||||
|
||||
struct Pool
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "parsing.hpp"
|
||||
#endif
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "strbuilder_ops.cpp"
|
||||
#endif
|
||||
|
@ -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";
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "header_start.hpp"
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "debug.cpp"
|
||||
#endif
|
||||
|
@ -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 )
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "hashing.hpp"
|
||||
#endif
|
||||
@ -40,9 +40,9 @@ struct Str
|
||||
|
||||
#ifndef txt
|
||||
# if GEN_COMPILER_CPP
|
||||
# define txt( text ) Str { ( text ), sizeof( text ) - 1 }
|
||||
# define txt( text ) GEN_NS Str { ( text ), sizeof( text ) - 1 }
|
||||
# else
|
||||
# define txt( text ) (Str){ ( text ), sizeof( text ) - 1 }
|
||||
# define txt( text ) (GEN_NS Str){ ( text ), sizeof( text ) - 1 }
|
||||
# endif
|
||||
#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);
|
||||
@ -392,6 +370,7 @@ bool strbuilder_append_string(StrBuilder* str, StrBuilder const other) {
|
||||
return strbuilder_append_c_str_len(str, (char const*)other, strbuilder_length(other));
|
||||
}
|
||||
|
||||
inline
|
||||
bool strbuilder_append_fmt(StrBuilder* str, char const* fmt, ...) {
|
||||
GEN_ASSERT(str != nullptr);
|
||||
ssize res;
|
||||
@ -520,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))
|
||||
@ -625,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
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#ifdef INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "filesystem.cpp"
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -37,6 +37,7 @@ Operator_Member_Fwd, "operator"
|
||||
Operator_Cast, "operator"
|
||||
Operator_Cast_Fwd, "operator"
|
||||
Parameters, "__NA__"
|
||||
Parameters_Define, "__NA__"
|
||||
Preprocess_Define, "define"
|
||||
Preprocess_Include, "include"
|
||||
Preprocess_If, "if"
|
||||
|
|
@ -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,95 +1,99 @@
|
||||
Invalid, "__invalid__"
|
||||
Access_Private, "private"
|
||||
Access_Protected, "protected"
|
||||
Access_Public, "public"
|
||||
Access_MemberSymbol, "."
|
||||
Access_StaticSymbol, "::"
|
||||
Ampersand, "&"
|
||||
Ampersand_DBL, "&&"
|
||||
Assign_Classifer, ":"
|
||||
Attribute_Open, "[["
|
||||
Attribute_Close, "]]"
|
||||
BraceCurly_Open, "{"
|
||||
BraceCurly_Close, "}"
|
||||
BraceSquare_Open, "["
|
||||
BraceSquare_Close, "]"
|
||||
Capture_Start, "("
|
||||
Capture_End, ")"
|
||||
Comment, "__comment__"
|
||||
Comment_End, "__comment_end__"
|
||||
Comment_Start, "__comment_start__"
|
||||
Char, "__character__"
|
||||
Comma, ","
|
||||
Decl_Class, "class"
|
||||
Decl_GNU_Attribute, "__attribute__"
|
||||
Decl_MSVC_Attribute, "__declspec"
|
||||
Decl_Enum, "enum"
|
||||
Decl_Extern_Linkage, "extern"
|
||||
Decl_Friend, "friend"
|
||||
Decl_Module, "module"
|
||||
Decl_Namespace, "namespace"
|
||||
Decl_Operator, "operator"
|
||||
Decl_Struct, "struct"
|
||||
Decl_Template, "template"
|
||||
Decl_Typedef, "typedef"
|
||||
Decl_Using, "using"
|
||||
Decl_Union, "union"
|
||||
Identifier, "__identifier__"
|
||||
Module_Import, "import"
|
||||
Module_Export, "export"
|
||||
NewLine, "__new_line__"
|
||||
Number, "__number__"
|
||||
Operator, "__operator__"
|
||||
Preprocess_Hash, "#"
|
||||
Preprocess_Define, "define"
|
||||
Preprocess_If, "if"
|
||||
Preprocess_IfDef, "ifdef"
|
||||
Preprocess_IfNotDef, "ifndef"
|
||||
Preprocess_ElIf, "elif"
|
||||
Preprocess_Else, "else"
|
||||
Preprocess_EndIf, "endif"
|
||||
Preprocess_Include, "include"
|
||||
Preprocess_Pragma, "pragma"
|
||||
Preprocess_Content, "__macro_content__"
|
||||
Preprocess_Macro, "__macro__"
|
||||
Preprocess_Unsupported, "__unsupported__"
|
||||
Spec_Alignas, "alignas"
|
||||
Spec_Const, "const"
|
||||
Spec_Consteval, "consteval"
|
||||
Spec_Constexpr, "constexpr"
|
||||
Spec_Constinit, "constinit"
|
||||
Spec_Explicit, "explicit"
|
||||
Spec_Extern, "extern"
|
||||
Spec_Final, "final"
|
||||
Spec_ForceInline, "forceinline"
|
||||
Spec_Global, "global"
|
||||
Spec_Inline, "inline"
|
||||
Spec_Internal_Linkage, "internal"
|
||||
Spec_LocalPersist, "local_persist"
|
||||
Spec_Mutable, "mutable"
|
||||
Spec_NeverInline, "neverinline"
|
||||
Spec_Override, "override"
|
||||
Spec_Static, "static"
|
||||
Spec_ThreadLocal, "thread_local"
|
||||
Spec_Volatile, "volatile"
|
||||
Spec_Virtual, "virtual"
|
||||
Star, "*"
|
||||
Statement_End, ";"
|
||||
StaticAssert, "static_assert"
|
||||
String, "__string__"
|
||||
Type_Typename, "typename"
|
||||
Type_Unsigned, "unsigned"
|
||||
Type_Signed, "signed"
|
||||
Type_Short, "short"
|
||||
Type_Long, "long"
|
||||
Type_bool, "bool"
|
||||
Type_char, "char"
|
||||
Type_int, "int"
|
||||
Type_double, "double"
|
||||
Type_MS_int8, "__int8"
|
||||
Type_MS_int16, "__int16"
|
||||
Type_MS_int32, "__int32"
|
||||
Type_MS_int64, "__int64"
|
||||
Type_MS_W64, "_W64"
|
||||
Varadic_Argument, "..."
|
||||
__Attributes_Start, "__attrib_start__"
|
||||
Invalid, "__invalid__"
|
||||
Access_Private, "private"
|
||||
Access_Protected, "protected"
|
||||
Access_Public, "public"
|
||||
Access_MemberSymbol, "."
|
||||
Access_StaticSymbol, "::"
|
||||
Ampersand, "&"
|
||||
Ampersand_DBL, "&&"
|
||||
Assign_Classifer, ":"
|
||||
Attribute_Open, "[["
|
||||
Attribute_Close, "]]"
|
||||
BraceCurly_Open, "{"
|
||||
BraceCurly_Close, "}"
|
||||
BraceSquare_Open, "["
|
||||
BraceSquare_Close, "]"
|
||||
Paren_Open, "("
|
||||
Paren_Close, ")"
|
||||
Comment, "__comment__"
|
||||
Comment_End, "__comment_end__"
|
||||
Comment_Start, "__comment_start__"
|
||||
Char, "__character__"
|
||||
Comma, ","
|
||||
Decl_Class, "class"
|
||||
Decl_GNU_Attribute, "__attribute__"
|
||||
Decl_MSVC_Attribute, "__declspec"
|
||||
Decl_Enum, "enum"
|
||||
Decl_Extern_Linkage, "extern"
|
||||
Decl_Friend, "friend"
|
||||
Decl_Module, "module"
|
||||
Decl_Namespace, "namespace"
|
||||
Decl_Operator, "operator"
|
||||
Decl_Struct, "struct"
|
||||
Decl_Template, "template"
|
||||
Decl_Typedef, "typedef"
|
||||
Decl_Using, "using"
|
||||
Decl_Union, "union"
|
||||
Identifier, "__identifier__"
|
||||
Module_Import, "import"
|
||||
Module_Export, "export"
|
||||
NewLine, "__new_line__"
|
||||
Number, "__number__"
|
||||
Operator, "__operator__"
|
||||
Preprocess_Hash, "#"
|
||||
Preprocess_Define, "define"
|
||||
Preprocess_Define_Param, "__define_param__"
|
||||
Preprocess_If, "if"
|
||||
Preprocess_IfDef, "ifdef"
|
||||
Preprocess_IfNotDef, "ifndef"
|
||||
Preprocess_ElIf, "elif"
|
||||
Preprocess_Else, "else"
|
||||
Preprocess_EndIf, "endif"
|
||||
Preprocess_Include, "include"
|
||||
Preprocess_Pragma, "pragma"
|
||||
Preprocess_Content, "__macro_content__"
|
||||
Preprocess_Macro_Expr, "__macro_expression__"
|
||||
Preprocess_Macro_Stmt, "__macro_statment__"
|
||||
Preprocess_Macro_Typename, "__macro_typename__"
|
||||
Preprocess_Unsupported, "__unsupported__"
|
||||
Spec_Alignas, "alignas"
|
||||
Spec_Const, "const"
|
||||
Spec_Consteval, "consteval"
|
||||
Spec_Constexpr, "constexpr"
|
||||
Spec_Constinit, "constinit"
|
||||
Spec_Explicit, "explicit"
|
||||
Spec_Extern, "extern"
|
||||
Spec_Final, "final"
|
||||
Spec_ForceInline, "forceinline"
|
||||
Spec_Global, "global"
|
||||
Spec_Inline, "inline"
|
||||
Spec_Internal_Linkage, "internal"
|
||||
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"
|
||||
Spec_Virtual, "virtual"
|
||||
Star, "*"
|
||||
Statement_End, ";"
|
||||
StaticAssert, "static_assert"
|
||||
String, "__string__"
|
||||
Type_Typename, "typename"
|
||||
Type_Unsigned, "unsigned"
|
||||
Type_Signed, "signed"
|
||||
Type_Short, "short"
|
||||
Type_Long, "long"
|
||||
Type_bool, "bool"
|
||||
Type_char, "char"
|
||||
Type_int, "int"
|
||||
Type_double, "double"
|
||||
Type_MS_int8, "__int8"
|
||||
Type_MS_int16, "__int16"
|
||||
Type_MS_int32, "__int32"
|
||||
Type_MS_int64, "__int64"
|
||||
Type_MS_W64, "_W64"
|
||||
Varadic_Argument, "..."
|
||||
__Attributes_Start, "__attrib_start__"
|
||||
|
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#if GEN_INTELLISENSE_DIRECTIVES
|
||||
#if INTELLISENSE_DIRECTIVES
|
||||
# include "../gen.hpp"
|
||||
# include "misc.hpp"
|
||||
|
||||
@ -47,7 +47,7 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false )
|
||||
Str codetype_to_str( CodeType type )
|
||||
{
|
||||
local_persist
|
||||
Str lookup[<num>] = {
|
||||
Str lookup[] = {
|
||||
<entries>
|
||||
};
|
||||
return lookup[ type ];
|
||||
@ -57,7 +57,7 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false )
|
||||
Str codetype_to_keyword_str( CodeType type )
|
||||
{
|
||||
local_persist
|
||||
Str lookup[ <num> ] = {
|
||||
Str lookup[] = {
|
||||
<keywords>
|
||||
};
|
||||
return lookup[ type ];
|
||||
@ -139,7 +139,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
|
||||
Str operator_to_str( Operator op )
|
||||
{
|
||||
local_persist
|
||||
Str lookup[<num>] = {
|
||||
Str lookup[] = {
|
||||
<entries>
|
||||
};
|
||||
|
||||
@ -214,7 +214,19 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
|
||||
inline
|
||||
bool spec_is_trailing( Specifier specifier )
|
||||
{
|
||||
return specifier > Spec_Virtual;
|
||||
switch (specifier) {
|
||||
case Spec_Const:
|
||||
case Spec_Final:
|
||||
case Spec_NoExceptions:
|
||||
case Spec_Override:
|
||||
case Spec_Pure:
|
||||
case Spec_Delete:
|
||||
case Spec_Volatile:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
)));
|
||||
|
||||
@ -237,7 +249,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
|
||||
Str spec_to_str( Specifier type )
|
||||
{
|
||||
local_persist
|
||||
Str lookup[<num>] = {
|
||||
Str lookup[] = {
|
||||
<entries>
|
||||
};
|
||||
|
||||
@ -283,7 +295,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
|
||||
body_append(result, enum_code);
|
||||
if (use_c_definition)
|
||||
{
|
||||
CodeTypedef specifier_t = parse_typedef( code(typedef u32 Specifier; ));
|
||||
CodeTypedef specifier_t = parse_typedef( code(typedef enum Specifier Specifier; ));
|
||||
body_append(result, specifier_t);
|
||||
}
|
||||
|
||||
@ -353,7 +365,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_
|
||||
|
||||
#pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
|
||||
#undef GEN_DEFINE_ATTRIBUTE_TOKENS
|
||||
CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), strbuilder_to_str(attribute_define_entries) );
|
||||
CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), MT_Statement, { {}, strbuilder_to_str(attribute_define_entries) } );
|
||||
#pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
|
||||
|
||||
// We cannot parse this enum, it has Attribute names as enums
|
||||
@ -499,59 +511,60 @@ CodeBody gen_ast_inlines()
|
||||
#pragma pop_macro("GEN_NS")
|
||||
#pragma pop_macro("CodeInvalid")
|
||||
|
||||
CodeBody impl_code = parse_global_body( token_fmt( "typename", Str name(Code), code_impl_tmpl ));
|
||||
CodeBody impl_code_body = parse_global_body( token_fmt( "typename", Str name(CodeBody), code_impl_tmpl ));
|
||||
CodeBody impl_code_attr = parse_global_body( token_fmt( "typename", Str name(CodeAttributes), code_impl_tmpl ));
|
||||
CodeBody impl_code_cmt = parse_global_body( token_fmt( "typename", Str name(CodeComment), code_impl_tmpl ));
|
||||
CodeBody impl_code_constr = parse_global_body( token_fmt( "typename", Str name(CodeConstructor), code_impl_tmpl ));
|
||||
CodeBody impl_code_class = parse_global_body( token_fmt( "typename", Str name(CodeClass), code_impl_tmpl ));
|
||||
CodeBody impl_code_define = parse_global_body( token_fmt( "typename", Str name(CodeDefine), code_impl_tmpl ));
|
||||
CodeBody impl_code_destruct = parse_global_body( token_fmt( "typename", Str name(CodeDestructor), code_impl_tmpl ));
|
||||
CodeBody impl_code_enum = parse_global_body( token_fmt( "typename", Str name(CodeEnum), code_impl_tmpl ));
|
||||
CodeBody impl_code_exec = parse_global_body( token_fmt( "typename", Str name(CodeExec), code_impl_tmpl ));
|
||||
CodeBody impl_code_extern = parse_global_body( token_fmt( "typename", Str name(CodeExtern), code_impl_tmpl ));
|
||||
CodeBody impl_code_include = parse_global_body( token_fmt( "typename", Str name(CodeInclude), code_impl_tmpl ));
|
||||
CodeBody impl_code_friend = parse_global_body( token_fmt( "typename", Str name(CodeFriend), code_impl_tmpl ));
|
||||
CodeBody impl_code_fn = parse_global_body( token_fmt( "typename", Str name(CodeFn), code_impl_tmpl ));
|
||||
CodeBody impl_code_module = parse_global_body( token_fmt( "typename", Str name(CodeModule), code_impl_tmpl ));
|
||||
CodeBody impl_code_ns = parse_global_body( token_fmt( "typename", Str name(CodeNS), code_impl_tmpl ));
|
||||
CodeBody impl_code_op = parse_global_body( token_fmt( "typename", Str name(CodeOperator), code_impl_tmpl ));
|
||||
CodeBody impl_code_opcast = parse_global_body( token_fmt( "typename", Str name(CodeOpCast), code_impl_tmpl ));
|
||||
CodeBody impl_code_params = parse_global_body( token_fmt( "typename", Str name(CodeParams), code_impl_tmpl ));
|
||||
CodeBody impl_code_pragma = parse_global_body( token_fmt( "typename", Str name(CodePragma), code_impl_tmpl ));
|
||||
CodeBody impl_code_precond = parse_global_body( token_fmt( "typename", Str name(CodePreprocessCond), code_impl_tmpl ));
|
||||
CodeBody impl_code_specs = parse_global_body( token_fmt( "typename", Str name(CodeSpecifiers), code_impl_tmpl ));
|
||||
CodeBody impl_code_struct = parse_global_body( token_fmt( "typename", Str name(CodeStruct), code_impl_tmpl ));
|
||||
CodeBody impl_code_tmpl = parse_global_body( token_fmt( "typename", Str name(CodeTemplate), code_impl_tmpl ));
|
||||
CodeBody impl_code_type = parse_global_body( token_fmt( "typename", Str name(CodeTypename), code_impl_tmpl ));
|
||||
CodeBody impl_code_typedef = parse_global_body( token_fmt( "typename", Str name(CodeTypedef), code_impl_tmpl ));
|
||||
CodeBody impl_code_union = parse_global_body( token_fmt( "typename", Str name(CodeUnion), code_impl_tmpl ));
|
||||
CodeBody impl_code_using = parse_global_body( token_fmt( "typename", Str name(CodeUsing), code_impl_tmpl ));
|
||||
CodeBody impl_code_var = parse_global_body( token_fmt( "typename", Str name(CodeVar), code_impl_tmpl ));
|
||||
CodeBody impl_code = parse_global_body( token_fmt( "typename", name(Code), code_impl_tmpl ));
|
||||
CodeBody impl_code_body = parse_global_body( token_fmt( "typename", name(CodeBody), code_impl_tmpl ));
|
||||
CodeBody impl_code_attr = parse_global_body( token_fmt( "typename", name(CodeAttributes), code_impl_tmpl ));
|
||||
CodeBody impl_code_cmt = parse_global_body( token_fmt( "typename", name(CodeComment), code_impl_tmpl ));
|
||||
CodeBody impl_code_constr = parse_global_body( token_fmt( "typename", name(CodeConstructor), code_impl_tmpl ));
|
||||
CodeBody impl_code_class = parse_global_body( token_fmt( "typename", name(CodeClass), code_impl_tmpl ));
|
||||
CodeBody impl_code_define = parse_global_body( token_fmt( "typename", name(CodeDefine), code_impl_tmpl ));
|
||||
CodeBody impl_code_define_params = parse_global_body( token_fmt( "typename", name(CodeDefineParams), code_impl_tmpl ));
|
||||
CodeBody impl_code_destruct = parse_global_body( token_fmt( "typename", name(CodeDestructor), code_impl_tmpl ));
|
||||
CodeBody impl_code_enum = parse_global_body( token_fmt( "typename", name(CodeEnum), code_impl_tmpl ));
|
||||
CodeBody impl_code_exec = parse_global_body( token_fmt( "typename", name(CodeExec), code_impl_tmpl ));
|
||||
CodeBody impl_code_extern = parse_global_body( token_fmt( "typename", name(CodeExtern), code_impl_tmpl ));
|
||||
CodeBody impl_code_include = parse_global_body( token_fmt( "typename", name(CodeInclude), code_impl_tmpl ));
|
||||
CodeBody impl_code_friend = parse_global_body( token_fmt( "typename", name(CodeFriend), code_impl_tmpl ));
|
||||
CodeBody impl_code_fn = parse_global_body( token_fmt( "typename", name(CodeFn), code_impl_tmpl ));
|
||||
CodeBody impl_code_module = parse_global_body( token_fmt( "typename", name(CodeModule), code_impl_tmpl ));
|
||||
CodeBody impl_code_ns = parse_global_body( token_fmt( "typename", name(CodeNS), code_impl_tmpl ));
|
||||
CodeBody impl_code_op = parse_global_body( token_fmt( "typename", name(CodeOperator), code_impl_tmpl ));
|
||||
CodeBody impl_code_opcast = parse_global_body( token_fmt( "typename", name(CodeOpCast), code_impl_tmpl ));
|
||||
CodeBody impl_code_params = parse_global_body( token_fmt( "typename", name(CodeParams), code_impl_tmpl ));
|
||||
CodeBody impl_code_pragma = parse_global_body( token_fmt( "typename", name(CodePragma), code_impl_tmpl ));
|
||||
CodeBody impl_code_precond = parse_global_body( token_fmt( "typename", name(CodePreprocessCond), code_impl_tmpl ));
|
||||
CodeBody impl_code_specs = parse_global_body( token_fmt( "typename", name(CodeSpecifiers), code_impl_tmpl ));
|
||||
CodeBody impl_code_struct = parse_global_body( token_fmt( "typename", name(CodeStruct), code_impl_tmpl ));
|
||||
CodeBody impl_code_tmpl = parse_global_body( token_fmt( "typename", name(CodeTemplate), code_impl_tmpl ));
|
||||
CodeBody impl_code_type = parse_global_body( token_fmt( "typename", name(CodeTypename), code_impl_tmpl ));
|
||||
CodeBody impl_code_typedef = parse_global_body( token_fmt( "typename", name(CodeTypedef), code_impl_tmpl ));
|
||||
CodeBody impl_code_union = parse_global_body( token_fmt( "typename", name(CodeUnion), code_impl_tmpl ));
|
||||
CodeBody impl_code_using = parse_global_body( token_fmt( "typename", name(CodeUsing), code_impl_tmpl ));
|
||||
CodeBody impl_code_var = parse_global_body( token_fmt( "typename", name(CodeVar), code_impl_tmpl ));
|
||||
|
||||
body_append(impl_code_attr, parse_global_body( token_fmt( "typename", Str name(Attributes), codetype_impl_tmpl )));
|
||||
body_append(impl_code_cmt, parse_global_body( token_fmt( "typename", Str name(Comment), codetype_impl_tmpl )));
|
||||
body_append(impl_code_constr, parse_global_body( token_fmt( "typename", Str name(Constructor), codetype_impl_tmpl )));
|
||||
body_append(impl_code_define, parse_global_body( token_fmt( "typename", Str name(Define), codetype_impl_tmpl )));
|
||||
body_append(impl_code_destruct, parse_global_body( token_fmt( "typename", Str name(Destructor), codetype_impl_tmpl )));
|
||||
body_append(impl_code_enum, parse_global_body( token_fmt( "typename", Str name(Enum), codetype_impl_tmpl )));
|
||||
body_append(impl_code_exec, parse_global_body( token_fmt( "typename", Str name(Exec), codetype_impl_tmpl )));
|
||||
body_append(impl_code_extern, parse_global_body( token_fmt( "typename", Str name(Extern), codetype_impl_tmpl )));
|
||||
body_append(impl_code_include, parse_global_body( token_fmt( "typename", Str name(Include), codetype_impl_tmpl )));
|
||||
body_append(impl_code_friend, parse_global_body( token_fmt( "typename", Str name(Friend), codetype_impl_tmpl )));
|
||||
body_append(impl_code_fn, parse_global_body( token_fmt( "typename", Str name(Fn), codetype_impl_tmpl )));
|
||||
body_append(impl_code_module, parse_global_body( token_fmt( "typename", Str name(Module), codetype_impl_tmpl )));
|
||||
body_append(impl_code_ns, parse_global_body( token_fmt( "typename", Str name(NS), codetype_impl_tmpl )));
|
||||
body_append(impl_code_op, parse_global_body( token_fmt( "typename", Str name(Operator), codetype_impl_tmpl )));
|
||||
body_append(impl_code_opcast, parse_global_body( token_fmt( "typename", Str name(OpCast), codetype_impl_tmpl )));
|
||||
body_append(impl_code_pragma, parse_global_body( token_fmt( "typename", Str name(Pragma), codetype_impl_tmpl )));
|
||||
body_append(impl_code_precond, parse_global_body( token_fmt( "typename", Str name(PreprocessCond), codetype_impl_tmpl )));
|
||||
body_append(impl_code_tmpl, parse_global_body( token_fmt( "typename", Str name(Template), codetype_impl_tmpl )));
|
||||
body_append(impl_code_type, parse_global_body( token_fmt( "typename", Str name(Typename), codetype_impl_tmpl )));
|
||||
body_append(impl_code_typedef, parse_global_body( token_fmt( "typename", Str name(Typedef), codetype_impl_tmpl )));
|
||||
body_append(impl_code_union, parse_global_body( token_fmt( "typename", Str name(Union), codetype_impl_tmpl )));
|
||||
body_append(impl_code_using, parse_global_body( token_fmt( "typename", Str name(Using), codetype_impl_tmpl )));
|
||||
body_append(impl_code_var, parse_global_body( token_fmt( "typename", Str name(Var), codetype_impl_tmpl )));
|
||||
body_append(impl_code_attr, parse_global_body( token_fmt( "typename", name(Attributes), codetype_impl_tmpl )));
|
||||
body_append(impl_code_cmt, parse_global_body( token_fmt( "typename", name(Comment), codetype_impl_tmpl )));
|
||||
body_append(impl_code_constr, parse_global_body( token_fmt( "typename", name(Constructor), codetype_impl_tmpl )));
|
||||
body_append(impl_code_define, parse_global_body( token_fmt( "typename", name(Define), codetype_impl_tmpl )));
|
||||
body_append(impl_code_destruct, parse_global_body( token_fmt( "typename", name(Destructor), codetype_impl_tmpl )));
|
||||
body_append(impl_code_enum, parse_global_body( token_fmt( "typename", name(Enum), codetype_impl_tmpl )));
|
||||
body_append(impl_code_exec, parse_global_body( token_fmt( "typename", name(Exec), codetype_impl_tmpl )));
|
||||
body_append(impl_code_extern, parse_global_body( token_fmt( "typename", name(Extern), codetype_impl_tmpl )));
|
||||
body_append(impl_code_include, parse_global_body( token_fmt( "typename", name(Include), codetype_impl_tmpl )));
|
||||
body_append(impl_code_friend, parse_global_body( token_fmt( "typename", name(Friend), codetype_impl_tmpl )));
|
||||
body_append(impl_code_fn, parse_global_body( token_fmt( "typename", name(Fn), codetype_impl_tmpl )));
|
||||
body_append(impl_code_module, parse_global_body( token_fmt( "typename", name(Module), codetype_impl_tmpl )));
|
||||
body_append(impl_code_ns, parse_global_body( token_fmt( "typename", name(NS), codetype_impl_tmpl )));
|
||||
body_append(impl_code_op, parse_global_body( token_fmt( "typename", name(Operator), codetype_impl_tmpl )));
|
||||
body_append(impl_code_opcast, parse_global_body( token_fmt( "typename", name(OpCast), codetype_impl_tmpl )));
|
||||
body_append(impl_code_pragma, parse_global_body( token_fmt( "typename", name(Pragma), codetype_impl_tmpl )));
|
||||
body_append(impl_code_precond, parse_global_body( token_fmt( "typename", name(PreprocessCond), codetype_impl_tmpl )));
|
||||
body_append(impl_code_tmpl, parse_global_body( token_fmt( "typename", name(Template), codetype_impl_tmpl )));
|
||||
body_append(impl_code_type, parse_global_body( token_fmt( "typename", name(Typename), codetype_impl_tmpl )));
|
||||
body_append(impl_code_typedef, parse_global_body( token_fmt( "typename", name(Typedef), codetype_impl_tmpl )));
|
||||
body_append(impl_code_union, parse_global_body( token_fmt( "typename", name(Union), codetype_impl_tmpl )));
|
||||
body_append(impl_code_using, parse_global_body( token_fmt( "typename", name(Using), codetype_impl_tmpl )));
|
||||
body_append(impl_code_var, parse_global_body( token_fmt( "typename", name(Var), codetype_impl_tmpl )));
|
||||
|
||||
#pragma push_macro("forceinline")
|
||||
#undef forceinline
|
||||
@ -563,34 +576,35 @@ CodeBody gen_ast_inlines()
|
||||
);
|
||||
#pragma pop_macro("forceinline")
|
||||
|
||||
CodeBody impl_cast_body = parse_global_body( token_fmt( "typename", Str name(Body), cast_tmpl ));
|
||||
CodeBody impl_cast_attribute = parse_global_body( token_fmt( "typename", Str name(Attributes), cast_tmpl ));
|
||||
CodeBody impl_cast_cmt = parse_global_body( token_fmt( "typename", Str name(Comment), cast_tmpl ));
|
||||
CodeBody impl_cast_constr = parse_global_body( token_fmt( "typename", Str name(Constructor), cast_tmpl ));
|
||||
CodeBody impl_cast_class = parse_global_body( token_fmt( "typename", Str name(Class), cast_tmpl ));
|
||||
CodeBody impl_cast_define = parse_global_body( token_fmt( "typename", Str name(Define), cast_tmpl ));
|
||||
CodeBody impl_cast_destruct = parse_global_body( token_fmt( "typename", Str name(Destructor), cast_tmpl ));
|
||||
CodeBody impl_cast_enum = parse_global_body( token_fmt( "typename", Str name(Enum), cast_tmpl ));
|
||||
CodeBody impl_cast_exec = parse_global_body( token_fmt( "typename", Str name(Exec), cast_tmpl ));
|
||||
CodeBody impl_cast_extern = parse_global_body( token_fmt( "typename", Str name(Extern), cast_tmpl ));
|
||||
CodeBody impl_cast_friend = parse_global_body( token_fmt( "typename", Str name(Friend), cast_tmpl ));
|
||||
CodeBody impl_cast_fn = parse_global_body( token_fmt( "typename", Str name(Fn), cast_tmpl ));
|
||||
CodeBody impl_cast_include = parse_global_body( token_fmt( "typename", Str name(Include), cast_tmpl ));
|
||||
CodeBody impl_cast_module = parse_global_body( token_fmt( "typename", Str name(Module), cast_tmpl ));
|
||||
CodeBody impl_cast_ns = parse_global_body( token_fmt( "typename", Str name(NS), cast_tmpl ));
|
||||
CodeBody impl_cast_op = parse_global_body( token_fmt( "typename", Str name(Operator), cast_tmpl ));
|
||||
CodeBody impl_cast_opcast = parse_global_body( token_fmt( "typename", Str name(OpCast), cast_tmpl ));
|
||||
CodeBody impl_cast_params = parse_global_body( token_fmt( "typename", Str name(Params), cast_tmpl ));
|
||||
CodeBody impl_cast_pragma = parse_global_body( token_fmt( "typename", Str name(Pragma), cast_tmpl ));
|
||||
CodeBody impl_cast_precond = parse_global_body( token_fmt( "typename", Str name(PreprocessCond), cast_tmpl ));
|
||||
CodeBody impl_cast_specs = parse_global_body( token_fmt( "typename", Str name(Specifiers), cast_tmpl ));
|
||||
CodeBody impl_cast_struct = parse_global_body( token_fmt( "typename", Str name(Struct), cast_tmpl ));
|
||||
CodeBody impl_cast_tmpl = parse_global_body( token_fmt( "typename", Str name(Template), cast_tmpl ));
|
||||
CodeBody impl_cast_type = parse_global_body( token_fmt( "typename", Str name(Typename), cast_tmpl ));
|
||||
CodeBody impl_cast_typedef = parse_global_body( token_fmt( "typename", Str name(Typedef), cast_tmpl ));
|
||||
CodeBody impl_cast_union = parse_global_body( token_fmt( "typename", Str name(Union), cast_tmpl ));
|
||||
CodeBody impl_cast_using = parse_global_body( token_fmt( "typename", Str name(Using), cast_tmpl ));
|
||||
CodeBody impl_cast_var = parse_global_body( token_fmt( "typename", Str name(Var), cast_tmpl ));
|
||||
CodeBody impl_cast_body = parse_global_body( token_fmt( "typename", name(Body), cast_tmpl ));
|
||||
CodeBody impl_cast_attribute = parse_global_body( token_fmt( "typename", name(Attributes), cast_tmpl ));
|
||||
CodeBody impl_cast_cmt = parse_global_body( token_fmt( "typename", name(Comment), cast_tmpl ));
|
||||
CodeBody impl_cast_constr = parse_global_body( token_fmt( "typename", name(Constructor), cast_tmpl ));
|
||||
CodeBody impl_cast_class = parse_global_body( token_fmt( "typename", name(Class), cast_tmpl ));
|
||||
CodeBody impl_cast_define = parse_global_body( token_fmt( "typename", name(Define), cast_tmpl ));
|
||||
CodeBody impl_cast_define_params = parse_global_body( token_fmt( "typename", name(DefineParams), cast_tmpl ));
|
||||
CodeBody impl_cast_destruct = parse_global_body( token_fmt( "typename", name(Destructor), cast_tmpl ));
|
||||
CodeBody impl_cast_enum = parse_global_body( token_fmt( "typename", name(Enum), cast_tmpl ));
|
||||
CodeBody impl_cast_exec = parse_global_body( token_fmt( "typename", name(Exec), cast_tmpl ));
|
||||
CodeBody impl_cast_extern = parse_global_body( token_fmt( "typename", name(Extern), cast_tmpl ));
|
||||
CodeBody impl_cast_friend = parse_global_body( token_fmt( "typename", name(Friend), cast_tmpl ));
|
||||
CodeBody impl_cast_fn = parse_global_body( token_fmt( "typename", name(Fn), cast_tmpl ));
|
||||
CodeBody impl_cast_include = parse_global_body( token_fmt( "typename", name(Include), cast_tmpl ));
|
||||
CodeBody impl_cast_module = parse_global_body( token_fmt( "typename", name(Module), cast_tmpl ));
|
||||
CodeBody impl_cast_ns = parse_global_body( token_fmt( "typename", name(NS), cast_tmpl ));
|
||||
CodeBody impl_cast_op = parse_global_body( token_fmt( "typename", name(Operator), cast_tmpl ));
|
||||
CodeBody impl_cast_opcast = parse_global_body( token_fmt( "typename", name(OpCast), cast_tmpl ));
|
||||
CodeBody impl_cast_params = parse_global_body( token_fmt( "typename", name(Params), cast_tmpl ));
|
||||
CodeBody impl_cast_pragma = parse_global_body( token_fmt( "typename", name(Pragma), cast_tmpl ));
|
||||
CodeBody impl_cast_precond = parse_global_body( token_fmt( "typename", name(PreprocessCond), cast_tmpl ));
|
||||
CodeBody impl_cast_specs = parse_global_body( token_fmt( "typename", name(Specifiers), cast_tmpl ));
|
||||
CodeBody impl_cast_struct = parse_global_body( token_fmt( "typename", name(Struct), cast_tmpl ));
|
||||
CodeBody impl_cast_tmpl = parse_global_body( token_fmt( "typename", name(Template), cast_tmpl ));
|
||||
CodeBody impl_cast_type = parse_global_body( token_fmt( "typename", name(Typename), cast_tmpl ));
|
||||
CodeBody impl_cast_typedef = parse_global_body( token_fmt( "typename", name(Typedef), cast_tmpl ));
|
||||
CodeBody impl_cast_union = parse_global_body( token_fmt( "typename", name(Union), cast_tmpl ));
|
||||
CodeBody impl_cast_using = parse_global_body( token_fmt( "typename", name(Using), cast_tmpl ));
|
||||
CodeBody impl_cast_var = parse_global_body( token_fmt( "typename", name(Var), cast_tmpl ));
|
||||
|
||||
CodeBody result = def_global_body( args(
|
||||
def_pragma( txt("region generated code inline implementation")),
|
||||
@ -602,6 +616,7 @@ CodeBody gen_ast_inlines()
|
||||
impl_code_constr,
|
||||
impl_code_class,
|
||||
impl_code_define,
|
||||
impl_code_define_params,
|
||||
impl_code_destruct,
|
||||
impl_code_enum,
|
||||
impl_code_exec,
|
||||
@ -636,6 +651,7 @@ CodeBody gen_ast_inlines()
|
||||
impl_cast_constr,
|
||||
impl_cast_class,
|
||||
impl_cast_define,
|
||||
impl_cast_define_params,
|
||||
impl_cast_destruct,
|
||||
impl_cast_enum,
|
||||
impl_cast_exec,
|
||||
|
@ -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>
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
#undef local_persist
|
||||
|
||||
#undef bit
|
||||
#undef bitfield_is_equal
|
||||
#undef bitfield_is_set
|
||||
|
||||
#undef cast
|
||||
|
||||
|
@ -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,6 +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.chpp`](../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.
|
||||
|
@ -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
|
||||
|
||||
@ -25,19 +25,19 @@ These are containers representing a scope body of a definition that can be of th
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Name;
|
||||
Code Front;
|
||||
Code Back;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
s32 NumEntries;
|
||||
StrCached Name;
|
||||
Code Front;
|
||||
Code Back;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
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:
|
||||
|
||||
@ -56,13 +56,13 @@ Represent standard or vendor specific C/C++ attributes.
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -80,13 +80,13 @@ Stores a comment.
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
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.
|
||||
@ -109,12 +109,12 @@ CodeComment InlineCmt; // Only supported by forward declarations
|
||||
CodeAttributes Attributes;
|
||||
CodeType ParentType;
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeType Prev;
|
||||
CodeType Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
AccessSpec ParentAccess;
|
||||
```
|
||||
@ -139,16 +139,16 @@ You'll notice that only one parent type is supported only with parent access. Th
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeComment InlineCmt; // Only supported by forward declarations
|
||||
Code InitializerList;
|
||||
CodeParams Params;
|
||||
Code Body;
|
||||
CodeComment InlineCmt; // Only supported by forward declarations
|
||||
Code InitializerList;
|
||||
CodeParams Params;
|
||||
Code Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -178,13 +178,14 @@ Represents a preprocessor define
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
CodeDefineParams Params;
|
||||
Code Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -193,6 +194,28 @@ Serialization:
|
||||
#define <Name> <Content>
|
||||
```
|
||||
|
||||
## DefineParams
|
||||
|
||||
Preprocessor define's parameters.
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Name;
|
||||
Code Last;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
s32 NumEntries;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
|
||||
```cpp
|
||||
<Name>, <Next> ...
|
||||
```
|
||||
|
||||
## Destructor
|
||||
|
||||
Fields:
|
||||
@ -201,12 +224,12 @@ Fields:
|
||||
CodeComment InlineCmt;
|
||||
CodeSpecifiers Specs;
|
||||
Code Body;
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -242,8 +265,8 @@ Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
StrCached Name;
|
||||
CodeT Type;
|
||||
StrCached Name;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
```
|
||||
|
||||
@ -266,18 +289,18 @@ 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:
|
||||
|
||||
```cpp
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -286,18 +309,18 @@ Serialization:
|
||||
<Content>
|
||||
```
|
||||
|
||||
## External Linkage
|
||||
## External Linkage (Extern)
|
||||
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -314,13 +337,13 @@ extern "<Name>"
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Code Parent;
|
||||
Token* Tok;
|
||||
CodeT Type;
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Code Parent;
|
||||
Token* Tok;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -336,14 +359,14 @@ This library (until its necessary become some third-party library to do otherwis
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeComment InlineCmt;
|
||||
Code Declaration;
|
||||
CodeComment InlineCmt;
|
||||
Code Declaration;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -363,12 +386,12 @@ CodeSpecifiers Specs;
|
||||
CodeType ReturnType;
|
||||
CodeParams Params;
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
```
|
||||
|
||||
@ -390,13 +413,13 @@ Serialization:
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -410,14 +433,14 @@ Serialization:
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -440,12 +463,12 @@ CodeSpecifiers Specs;
|
||||
CodeType ReturnType;
|
||||
CodeParams Params;
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
OperatorT Op;
|
||||
```
|
||||
@ -472,12 +495,12 @@ CodeComment InlineCmt;
|
||||
CodeSpecifiers Specs;
|
||||
CodeType ValueType;
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -498,17 +521,17 @@ Serialization:
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeType ValueType;
|
||||
Code Macro;
|
||||
Code Value;
|
||||
Code PostNameMacro;
|
||||
StrCached Name;
|
||||
CodeParams Last;
|
||||
CodeParams Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
s32 NumEntries;
|
||||
CodeType ValueType;
|
||||
Code Macro;
|
||||
Code Value;
|
||||
Code PostNameMacro;
|
||||
StrCached Name;
|
||||
CodeParams Last;
|
||||
CodeParams Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
s32 NumEntries;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -524,13 +547,13 @@ Serialization:
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -544,13 +567,13 @@ Serialization:
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
StrCached Content;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -566,12 +589,12 @@ Fields:
|
||||
```cpp
|
||||
SpecifierT ArrSpecs[ AST_ArrSpecs_Cap ];
|
||||
CodeSpecifiers NextSpecs;
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
CodeType Type;
|
||||
s32 NumEntries;
|
||||
```
|
||||
|
||||
@ -586,15 +609,15 @@ Serialization:
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeParams Params;
|
||||
Code Declaration;
|
||||
CodeParams Params;
|
||||
Code Declaration;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -621,8 +644,8 @@ Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
StrCached Name;
|
||||
CodeT Type;
|
||||
StrCached Name;
|
||||
CodeType Type;
|
||||
b32 IsParamPack;
|
||||
ETypenameTag TypeTag;
|
||||
```
|
||||
@ -647,16 +670,16 @@ Those (macros) don't use the underlying type field as everything was serialized
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
CodeComment InlineCmt;
|
||||
Code UnderlyingType;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
b32 IsFunction;
|
||||
CodeComment InlineCmt;
|
||||
Code UnderlyingType;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
b32 IsFunction;
|
||||
```
|
||||
|
||||
Serialization:
|
||||
@ -682,12 +705,12 @@ Fields:
|
||||
```cpp
|
||||
CodeAttributes Attributes;
|
||||
CodeBody Body;
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
```
|
||||
|
||||
@ -708,12 +731,12 @@ Fields:
|
||||
CodeComment InlineCmt;
|
||||
CodeAttributes Attributes;
|
||||
CodeType UnderlyingType;
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
```
|
||||
|
||||
@ -740,13 +763,13 @@ CodeSpecifiers Specs;
|
||||
CodeType ValueType;
|
||||
Code BitfieldSize;
|
||||
Code Value;
|
||||
StrCached Name;
|
||||
StrCached Name;
|
||||
CodeVar NextVar;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
Token* Tok;
|
||||
Code Parent;
|
||||
CodeT Type;
|
||||
CodeType Type;
|
||||
ModuleFlag ModuleFlags;
|
||||
s32 VarParenthesizedInit;
|
||||
```
|
||||
|
1179
docs/Parser_Algo.md
1179
docs/Parser_Algo.md
File diff suppressed because it is too large
Load Diff
@ -6,17 +6,18 @@
|
||||
|
||||
# Parsing
|
||||
|
||||
The library features a naive single-pass parser tailored for only what the library needs to construct the supported syntax of C++ into its AST for *"front-end"* meta-programming purposes.
|
||||
The library features a naive single-pass parser, tailored for only what the library needs; for construction of C++ code into gencpp's AST for *"front-end"* meta-programming purposes.
|
||||
|
||||
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 10k loc worst case.
|
||||
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:
|
||||
|
||||
```cpp
|
||||
CodeClass parse_class ( Str class_def );
|
||||
CodeConstructor parse_constructor ( Str constructor_def );
|
||||
CodeDefine parse_define ( Str define_def );
|
||||
CodeDestructor parse_destructor ( Str destructor_def );
|
||||
CodeEnum parse_enum ( Str enum_def );
|
||||
CodeBody parse_export_body ( Str export_def );
|
||||
@ -53,38 +54,98 @@ The keywords supported for the preprocessor are:
|
||||
* endif
|
||||
* pragma
|
||||
|
||||
Each directive `#` line is considered one preproecessor unit, and will be treated as one Preprocessor AST.
|
||||
Each directive `#` line is considered one preproecessor unit, and will be treated as one Preprocessor AST node.
|
||||
If a directive is used with an unsupported keyword its will be processed as an untyped AST.
|
||||
|
||||
The preprocessor lines are stored as members of their associated scope they are parsed within. ( Global, Namespace, Class/Struct )
|
||||
***Again (Its not standard): These ASTs will be considered members or entries of braced scope they reside within***
|
||||
The preprocessor lines are stored as members of their associated scope they are parsed within ( Global, Namespace, Class/Struct ).
|
||||
***Again: These ASTs will be considered members or entries of braced scope they reside within***
|
||||
|
||||
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:
|
||||
|
||||
* function signatures are allowed for a preprocessed macro: `neverinline 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();`
|
||||
* Disable with: `#define GEN_PARSER_DISABLE_MACRO_TYPEDEF`
|
||||
* Macros can behave as typenames
|
||||
* There is some macro support in paramters for functions or templates *(Specifically added to support parsing Unreal Engine source)*.
|
||||
* There is some macro support in parameters for functions or templates *(Specifically added to support parsing Unreal Engine source)*.
|
||||
|
||||
*(Exceptions are added on an on-demand basis)*
|
||||
*(See functions `parse_operator_function_or_variable` and `parse_typedef` )*
|
||||
|
||||
Adding your own exceptions is possible by simply modifying the parser to allow for the syntax you need.
|
||||
|
||||
*Note: You could interpret this strictness as a feature. This would allow the user to see if their codebase or a third-party's codebase some some egregious preprocessor abuse.*
|
||||
*Note: You could interpret this strictness as a feature. This would allow the user to see if their codebase or a third-party's codebase contains some egregious preprocessor abuse.*
|
||||
|
||||
If a macro is not defined withint e scope of parsing a set of files, it can be defined beforehand by:
|
||||
Macros used within a file should be registered by the user before parsing. This can be done two ways:
|
||||
|
||||
* Appending the [`PreprocessorDefines`](https://github.com/Ed94/gencpp/blob/a18b5b97aa5cfd20242065cbf53462a623cd18fa/base/components/header_end.hpp#L137) array.
|
||||
* For functional macros a "(" just needs to be added after the name like: `<name>(` so that it will tokenize its arguments as part of the token during lexing.
|
||||
* Defining a CodeDefine using `def_define`. The definition will be processed by the interface for user into `PreprocessorDefines`.
|
||||
* This can be prevented by setting the optional prameter `dont_append_preprocess_defines`.
|
||||
1. The register macro interface within [interface.hpp](../base/components/interface.hpp).
|
||||
2. Using `def_define` to create a CodeDefine and making sure to not set `opts.dont_register_to_preprocess_macros` to `true`.
|
||||
|
||||
The lexing and parsing takes shortcuts from whats expected in the standard.
|
||||
## Registering macros
|
||||
|
||||
While the registeration of macros in the meta-program's side for parsing can be considered tedius, its necessary for the parser to accurately resolve the macros intent in one pass (and it provides some hygenics by verifying that they are used as intended).
|
||||
|
||||
The following can be used to register a macro:
|
||||
|
||||
```c
|
||||
GEN_API void register_macro( Macro macro );
|
||||
GEN_API void register_macros( s32 num, ... );
|
||||
GEN_API void register_macros_arr( s32 num, Macro* macros );
|
||||
```
|
||||
|
||||
The Macro typename is defined with the following in [parser_types.hpp](../base/components/parser_types.hpp):
|
||||
|
||||
```c
|
||||
struct Macro
|
||||
{
|
||||
StrCached Name;
|
||||
MacroType Type;
|
||||
MacroFlags Flags;
|
||||
};
|
||||
```
|
||||
|
||||
The macro can be designated one of the following types:
|
||||
|
||||
* `MT_Expression`: Intended to resolve to an expression expansion.
|
||||
* `MT_Statement`: Intended to resolve an statement expansion.
|
||||
* `MT_Typename`: Intended to resolve to a typename.
|
||||
|
||||
Additioonally tthe following flags may be set:
|
||||
|
||||
* `MF_Functional`: The macro intended to be passed arguments are at least have the calling `()` as part of its usage.
|
||||
* `MF_Expects_Body`: The parser should expect a braced-body `{ ... }` after the macro signature `<name> <params>`
|
||||
* `MF_Allow_As_Identifier`: Will allow the macro to be an acceptable token/s when an `Tok_Identifier` is expected.
|
||||
* `MF_Allow_As_Attribute`: Will allow the macro to be an acceptable token/s when an attribute token/s is expected.
|
||||
* `MF_Allow_As_Definition`: Will allow the macro be an acceptable token/s when the parser expects a declartion or definition to resolve after attributes or specifiers have been identified beforehand.
|
||||
* This flag requires that the macro is of type `MT_Statement` to make any sense of usage.
|
||||
|
||||
If a macro is not defined the following warning will be issued if `GEN_BUILD_DEBUG=1` during lexing within [lexer.cpp](../base/components/lexer.cpp) - `lex_preprocessor_define`:
|
||||
|
||||
```c
|
||||
log_fmt("Warning: '%S' was not registered before the lexer processed its #define directive, it will be registered as a expression macro\n"
|
||||
, name.Text
|
||||
);
|
||||
```
|
||||
|
||||
Further within the same scope, the lexer will issue a warning if it detects a macro was not flagged as function but has an open parenthesis `(` token right after is name with no whitespace:
|
||||
|
||||
```c
|
||||
log_fmt("Warning: %S registered macro is not flagged as functional yet the definition detects opening parenthesis '(' for arguments\n"
|
||||
, name.Text
|
||||
);
|
||||
```
|
||||
|
||||
Macros are tracked using a `MacroTable Macros;` defined as a member of the library's `Context`.
|
||||
|
||||
```c
|
||||
typedef HashTable(Macro) MacroTable;
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
* Empty lines used throughout the file are preserved for formatting purposes during ast serialization (they have a dedicated Token: `Tok_NewLine`).
|
||||
* Numeric literals are not checked for validity.
|
||||
* The parse API treats any execution scope definitions with no validation and are turned into untyped Code ASTs. (There is a [todo](https://github.com/Ed94/gencpp/issues/49) to add support)
|
||||
* *This includes the assignment of variables.*
|
||||
@ -95,4 +156,4 @@ The lexing and parsing takes shortcuts from whats expected in the standard.
|
||||
* Parsing attributes can be extended to support user defined macros by defining `GEN_DEFINE_ATTRIBUTE_TOKENS` (see `gen.hpp` for the formatting)
|
||||
* This is useful for example: parsing Unreal `Module_API` macros.
|
||||
|
||||
Empty lines used throughout the file are preserved for formatting purposes during ast serialization.
|
||||
**The lexer & parser do not gracefully attempt to continue when it comes across incorrect code, and doesn't properly track errors into a listing (yet).**
|
||||
|
116
docs/Readme.md
116
docs/Readme.md
@ -26,7 +26,7 @@ This means that the typename entry for the parameter AST would be either:
|
||||
***Concepts and Constraints are not supported***
|
||||
Its a [todo](https://github.com/Ed94/gencpp/issues/21)
|
||||
|
||||
### Feature Macros:
|
||||
### Feature Macros
|
||||
|
||||
* `GEN_DEFINE_ATTRIBUTE_TOKENS` : Allows user to define their own attribute macros for use in parsing.
|
||||
* This can be generated using base.cpp.
|
||||
@ -36,10 +36,41 @@ Its a [todo](https://github.com/Ed94/gencpp/issues/21)
|
||||
* `GEN_EXPOSE_BACKEND` : Will expose symbols meant for internal use only.
|
||||
* `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves.
|
||||
* `GEN_DONT_ALLOW_INVALID_CODE` (Not implemented yet) : Will fail when an invalid code is constructed, parsed, or serialized.
|
||||
* `GEN_C_LIKE_PP` : Setting to `<true or 1>` Will prevent usage of function defnitions using references and structs with member functions. Structs will still have user-defined operator conversions, for-range support, and other operator overloads
|
||||
* `GEN_C_LIKE_CPP` : Setting to `<true or 1>` Will prevent usage of function defnitions using references and structs with member functions. Structs will still have user-defined operator conversions, for-range support, and other operator overloads
|
||||
|
||||
### The Data & Interface
|
||||
|
||||
The library's persistent state is managed tracked by a context struct: `global Context* _ctx;` defined within [static_data.cpp](../base/components/static_data.cpp)
|
||||
|
||||
https://github.com/Ed94/gencpp/blob/967a044637f1615c709cb723dc61118fcc08dcdb/base/components/interface.hpp#L39-L97
|
||||
|
||||
The interface for the context:
|
||||
|
||||
* `init`: Initializtion
|
||||
* `deinit`: De-initialization.
|
||||
* `reset`: Clears the allocations, but doesn't free the memoery, then calls `init()` on `_ctx` again.
|
||||
* `get_context`: Retreive the currently tracked context.
|
||||
* `set_context`: Swap out the current tracked context.
|
||||
|
||||
|
||||
#### Allocato usage
|
||||
|
||||
* `Allocator_DyanmicContainers`: Growing arrays, hash tables. (Unbounded sized containers)
|
||||
* `Allocator_Pool`: Fixed-sized object allocations (ASTs, etc)
|
||||
* `Allocator_StrCache`: StrCached allocations
|
||||
* `Allocator_Temp`: Temporary alloations mostly intended for StrBuilder usage. Manually cleared by the user by their own discretion.
|
||||
|
||||
The allocator definitions used are exposed to the user incase they want to dictate memory usage
|
||||
|
||||
* Allocators are defined with the `AllocatorInfo` structure found in [`memory.hpp`](../base/dependencies/memory.hpp)
|
||||
* Most of the work is just defining the allocation procedure:
|
||||
|
||||
```cpp
|
||||
void* ( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
|
||||
```
|
||||
|
||||
For any allocator above that the user does not define before `init`, a fallback allocator will be assigned that utiizes the `fallback_allocator_proc` wtihin [interface.cpp](../base/components/interface.cpp).
|
||||
|
||||
As mentioned in root readme, the user is provided Code objects by calling the constructor's functions to generate them or find existing matches.
|
||||
|
||||
The AST is managed by the library and provided to the user via its interface.
|
||||
@ -47,14 +78,14 @@ However, the user may specifiy memory configuration.
|
||||
|
||||
[Data layout of AST struct (Subject to heavily change with upcoming todos)](../base/components/ast.hpp#L396-461)
|
||||
|
||||
https://github.com/Ed94/gencpp/blob/eea4ebf5c40d5d87baa465abfb1be30845b2377e/base/components/ast.hpp#L396-L461
|
||||
https://github.com/Ed94/gencpp/blob/967a044637f1615c709cb723dc61118fcc08dcdb/base/components/ast.hpp#L369-L435
|
||||
|
||||
*`StringCahced` is a typedef for `Str` (a string slice), to denote it is an interned string*
|
||||
*`CodeType` is enum taggin the type of code. Has an underlying type of `u32`*
|
||||
*`OperatorT` is a typedef for `EOperator::Type` which has an underlying type of `u32`*
|
||||
*`StrBuilder` is the dynamically allocated string type for the library*
|
||||
*`StrBuilder` is the dynamically allocating string builder type for the library*
|
||||
|
||||
AST widths are setup to be AST_POD_Size.
|
||||
AST widths are setup to be AST_POD_Size (128 bytes by default).
|
||||
The width dictates how much the static array can hold before it must give way to using an allocated array:
|
||||
|
||||
```cpp
|
||||
@ -73,41 +104,16 @@ int AST_ArrSpecs_Cap =
|
||||
)
|
||||
/ sizeof(Specifier) - 1;
|
||||
```
|
||||
|
||||
*Ex: If the AST_POD_Size is 128 the capacity of the static array is 20.*
|
||||
|
||||
Data Notes:
|
||||
|
||||
* The allocator definitions used are exposed to the user incase they want to dictate memory usage
|
||||
* You'll find the memory handling in `init`, `deinit`, `reset`, `gen_strbuilder_allocator`, `cache_str`, `make_code`.
|
||||
* Allocators are defined with the `AllocatorInfo` structure found in [`memory.hpp`](../base/dependencies/memory.hpp)
|
||||
* Most of the work is just defining the allocation procedure:
|
||||
|
||||
```cpp
|
||||
void* ( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
|
||||
```
|
||||
|
||||
* ASTs are wrapped for the user in a Code struct which is a wrapper for a AST* type.
|
||||
* Code types have member symbols but their data layout is enforced to be POD types.
|
||||
* This library treats memory failures as fatal.
|
||||
* Cached Strings are stored in their own set of arenas. AST constructors use cached strings for names, and content.
|
||||
* `StringArenas`, `StringCache`, `Allocator_StringArena`, and `Allocator_StringTable` are the associated containers or allocators.
|
||||
* Strings used for serialization and file buffers are not contained by those used for cached strings.
|
||||
* They are currently using `FallbackAllocator`, which are tracked array of arenas that grows as needed (adds buckets when one runs out).
|
||||
* Memory within the buckets is not reused, so its inherently wasteful.
|
||||
* I will be augmenting the default allocator with virtual memory & a slab allocator in the [future](https://github.com/Ed94/gencpp/issues/12)
|
||||
* Intrusive linked lists used children nodes on bodies, and parameters.
|
||||
* `_ctx->Allocator_Temp` is used.
|
||||
* Its intended to generate the AST in one go and serialize after. The constructors and serializer are designed to be a "one pass, front to back" setup.
|
||||
* Allocations can be tuned by defining the folloiwng macros (will be moved to runtime configuration in the future):
|
||||
* `GEN_GLOBAL_BUCKET_SIZE` : Size of each bucket area for the global allocator
|
||||
* `GEN_CODEPOOL_NUM_BLOCKS` : Number of blocks per code pool in the code allocator
|
||||
* `GEN_SIZE_PER_STRING_ARENA` : Size per arena used with string caching.
|
||||
* `GEN_MAX_COMMENT_LINE_LENGTH` : Longest length a comment can have per line.
|
||||
* `GEN_MAX_NAME_LENGTH` : Max length of any identifier.
|
||||
* `GEN_MAX_UNTYPED_STR_LENGTH` : Max content length for any untyped code.
|
||||
* `TokenMap_FixedArena` : token_fmt_va uses local_persit memory of this arena type for the hashtable.
|
||||
* `GEN_LEX_ALLOCATOR_SIZE`
|
||||
* `GEN_BUILDER_STR_BUFFER_RESERVE`
|
||||
* Any modifcations to an existing AST should be to just construct another with the modifications done on-demand while traversing the AST (non-destructive).
|
||||
|
||||
The following CodeTypes are used which the user may optionally use strong typing with if they enable: `GEN_ENFORCE_STRONG_CODE_TYPES`
|
||||
|
||||
@ -117,6 +123,7 @@ The following CodeTypes are used which the user may optionally use strong typing
|
||||
* CodeClass
|
||||
* CodeConstructor
|
||||
* CodeDefine
|
||||
* CodeDefineParams
|
||||
* CodeDestructor
|
||||
* CodeEnum
|
||||
* CodeExec
|
||||
@ -127,7 +134,7 @@ The following CodeTypes are used which the user may optionally use strong typing
|
||||
* CodeModule
|
||||
* CodeNS
|
||||
* CodeOperator
|
||||
* CodeOpCast
|
||||
* CodeOpCast : User defined member operator conversion
|
||||
* CodeParams : Has support for `for : range` iterating across parameters.
|
||||
* CodePreprocessCond
|
||||
* CodePragma
|
||||
@ -140,11 +147,15 @@ The following CodeTypes are used which the user may optionally use strong typing
|
||||
* CodeUsing
|
||||
* CodeVar
|
||||
|
||||
Each Code boy has an associated "filtered AST" with the naming convention: `AST_<CodeName>`
|
||||
Each `struct Code<Name>` has an associated "filtered AST" with the naming convention: `AST_<CodeName>`
|
||||
Unrelated fields of the AST for that node type are omitted and only necessary padding members are defined otherwise.
|
||||
Retrieving a raw version of the ast can be done using the `raw()` function defined in each AST.
|
||||
|
||||
## There are three sets of interfaces for Code AST generation the library provides
|
||||
For the interface related to these code types see:
|
||||
|
||||
* [ast.hpp](../base/components/ast.hpp): Under the region pragma `Code C-Interface`
|
||||
* [code_types.hpp](../base/components/code_types.hpp): Under the region pragma `Code C-Interface`. Additional functionlity for c++ will be within the struct definitions or at the end of the file.
|
||||
|
||||
## There are three categories of interfaces for Code AST generation & reflection
|
||||
|
||||
* Upfront
|
||||
* Parsing
|
||||
@ -164,6 +175,7 @@ Interface :``
|
||||
* def_class
|
||||
* def_constructor
|
||||
* def_define
|
||||
* def_define_params
|
||||
* def_destructor
|
||||
* def_enum
|
||||
* def_execution
|
||||
@ -218,6 +230,27 @@ Code <name>
|
||||
|
||||
```
|
||||
|
||||
All optional parmeters are defined within `struct Opts_def_<functon name>`. This was done to setup a [macro trick](https://x.com/vkrajacic/status/1749816169736073295) for default optional parameers in the C library:
|
||||
|
||||
```cpp
|
||||
struct gen_Opts_def_struct
|
||||
{
|
||||
gen_CodeBody body;
|
||||
gen_CodeTypename parent;
|
||||
gen_AccessSpec parent_access;
|
||||
gen_CodeAttributes attributes;
|
||||
gen_CodeTypename* interfaces;
|
||||
gen_s32 num_interfaces;
|
||||
gen_ModuleFlag mflags;
|
||||
};
|
||||
typedef struct gen_Opts_def_struct gen_Opts_def_struct;
|
||||
|
||||
GEN_API gen_CodeClass gen_def__struct( gen_Str name, gen_Opts_def_struct opts GEN_PARAM_DEFAULT );
|
||||
#define gen_def_struct( name, ... ) gen_def__struct( name, ( gen_Opts_def_struct ) { __VA_ARGS__ } )
|
||||
```
|
||||
|
||||
In the C++ library, the `def_<funtion name>` is not wrapped in a macro.
|
||||
|
||||
When using the body functions, its recommended to use the args macro to auto determine the number of arguments for the varadic:
|
||||
|
||||
```cpp
|
||||
@ -227,8 +260,8 @@ 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.
|
||||
When the members have been populated use: `AST::validate_body` to verify that the members are valid entires for that type.
|
||||
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
|
||||
|
||||
@ -238,12 +271,12 @@ Interface :
|
||||
|
||||
* parse_class
|
||||
* parse_constructor
|
||||
* parse_define
|
||||
* parse_destructor
|
||||
* parse_enum
|
||||
* parse_export_body
|
||||
* parse_extern_link
|
||||
* parse_friend
|
||||
* Purposefully are only support forward declares with this constructor.
|
||||
* parse_function
|
||||
* parse_global_body
|
||||
* parse_namespace
|
||||
@ -322,6 +355,7 @@ Code <name> = parse_<function name>( gen_code_str );
|
||||
|
||||
The following are provided predefined by the library as they are commonly used:
|
||||
|
||||
* `enum_underlying_macro`
|
||||
* `access_public`
|
||||
* `access_protected`
|
||||
* `access_private`
|
||||
@ -398,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
|
||||
@ -410,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`
|
||||
|
BIN
docs/assets/Code_-_Insiders_2024-12-15_22-52-13.gif
Normal file
BIN
docs/assets/Code_-_Insiders_2024-12-15_22-52-13.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 150 KiB |
BIN
docs/assets/Code_-_Insiders_2024-12-15_22-57-58.gif
Normal file
BIN
docs/assets/Code_-_Insiders_2024-12-15_22-57-58.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 250 KiB |
BIN
docs/assets/Code_-_Insiders_2024-12-15_23-04-07.gif
Normal file
BIN
docs/assets/Code_-_Insiders_2024-12-15_23-04-07.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 175 KiB |
@ -1,7 +1,5 @@
|
||||
## Navigation
|
||||
|
||||
# base
|
||||
|
||||
[Top](../Readme.md)
|
||||
|
||||
* [docs](../docs/Readme.md)
|
||||
@ -15,9 +13,135 @@ The output will be in the `gen_segmented/gen` directory (if the directory does n
|
||||
If using the library's provided build scripts:
|
||||
|
||||
```ps1
|
||||
.\build.ps1 <compiler> <debug or omit> c_library
|
||||
.\build.ps1 <compiler> <debug or omit> c_lib
|
||||
```
|
||||
|
||||
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.**
|
||||
|
||||
## Generation structure
|
||||
|
||||
1. Files are scanned in or parsed.
|
||||
* 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. Segmented headers and source generated.
|
||||
|
||||
## Templated container generation
|
||||
|
||||
The array and hashtable containers used across this library are generated using the following implementatioon:
|
||||
|
||||
* [containers.array.hpp](./components/containers.array.hpp)
|
||||
* [containers.hashtable.hpp](./components/containers.hashtable.hpp)
|
||||
|
||||
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 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.
|
||||
* `gen_<container>_generic_selection_interface` : Intended to be called once after all of the instantiated containers have finished generating. It will generate a set of generic selection macros as described by Macro Usage section below.
|
||||
|
||||
A simple `<container>_DefinitionCounter` is used to know how many instantiations of the template have occured. This is used to determine how to define `GENERIC_SLOT_<ID>_<functionID>` for the generic interface along with how many slots the `_Generic` macro will need to have generated.
|
||||
|
||||
## Macro Usage
|
||||
|
||||
For the most part macros are kept minimal with exception to `_Generic`...
|
||||
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
```c
|
||||
#define macro_that_selects_typeof_arg(arg, y) \
|
||||
_Generic( (arg), \
|
||||
int : some expression, \
|
||||
double : some other expression, \
|
||||
struct Whatnot : something else again, \
|
||||
default : fallback expression \
|
||||
)
|
||||
```
|
||||
|
||||
Where `_Generic` can be considered the follwoing (psuedo-C):
|
||||
|
||||
```c
|
||||
#define type_expr_pair(type, expr) type: expr
|
||||
|
||||
C_Expression _Generic( selector_arg, a_type_expr_pair, ... ) {
|
||||
switch( typeof(selector_arg)) {
|
||||
case a_type_expr_pair:
|
||||
return a_type_expr_pari.expr;
|
||||
...
|
||||
default:
|
||||
return default.expr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The first `arg` of _Generic behaves as the "controlling expression" or the expression that resolves to a type which will dictate which of the following expressions provided after to `_Generic` will be resolved as the one used inline for the implemenation.
|
||||
|
||||
|
||||
For this library's purposes we'll be using the functional macro equivalent *(if there is an exception I'll link it at the end of this section)*:
|
||||
|
||||
```c
|
||||
#define macro_that_uses_selector_arg_for_resolving_a_fucntion( selecting_exp) \
|
||||
_Generic( (selecting_exp), \
|
||||
int : func_use_int, \
|
||||
double : func_use_double, \
|
||||
struct Whatnot : func_use_Whatnot, \
|
||||
default : struct SIGNALS_FAILURE \
|
||||
) (selecting_exp)
|
||||
```
|
||||
|
||||
In this case, we directly added `(selecting_exp)` to the end there.. as we want to directly have the macro resolve to calling a resolved procedure. A default has been set to a struct as that leads to a neat compiler message that would otherwise be impossible beause static_assert is a statement and thus cannot be used within a slot.
|
||||
|
||||
Now, even with gencpp generating this type-expression table, we still need wrapper macros to achieve function 'overloading' for the templated containers as _Generic has a [significant drawback](https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/c11-generic/):
|
||||
|
||||
> Discarded expressions still have to be semantically valid.
|
||||
|
||||
The only way to absolve this issue [(without resorting to nasty preprocessor hacks)](https://github.com/JacksonAllan/CC/blob/main/articles/Better_C_Generics_Part_1_The_Extendible_Generic.md) is with wrapping expressions in 'slot' resolving macros that do not expand if the slot is not defined:
|
||||
|
||||
```c
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1__function_sig )
|
||||
```
|
||||
|
||||
`GENERIC_SLOT_1__function_sig` is our warpper of a "`int, func_use_int`" pair. The `GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT` is a verbse named macro to indicate that that pair will be expanded ***ONLY IF*** its defined.
|
||||
|
||||
So for any given templated container interface. Expect the follwoing (taken straight from generation, and just cleaned up formatting):
|
||||
|
||||
```c
|
||||
#define gen_array_append( selector_arg, ... ) _Generic( \
|
||||
(selector_arg ), \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_1__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_2__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_3__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_4__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_5__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_6__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_7__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_8__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_9__array_append ) \
|
||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_10__array_append ) \
|
||||
default: gen_generic_selection_fail \
|
||||
) GEN_RESOLVED_FUNCTION_CALL( &selector_arg, __VA_ARGS__ )
|
||||
|
||||
```
|
||||
|
||||
*Note(Ed): Unfortunately I cannot get clang-format to output these macros sanely like the above..*
|
||||
*Eventually I'll add some basic builtin formatting but if the user has suggestions for something better I'm open ears...*
|
||||
|
||||
`GEN_RESOLVED_FUNCTION_CALL` is an empty define, its just to indicate that its intended to expand to a function call.
|
||||
|
||||
To see the the actual macro definitions used - see: [generic_macros.h](./components/generic_macros.h). They'll be injected right after the usual macros in the generated header file.
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||
#define GEN_EXPOSE_BACKEND
|
||||
#include "gen.cpp"
|
||||
#include "helpers/push_ignores.inline.hpp"
|
||||
|
||||
@ -65,19 +64,123 @@ int gen_main()
|
||||
Context ctx {};
|
||||
gen::init(& ctx);
|
||||
|
||||
ctx.PreprocessorDefines.append(txt("GEN_API_C_BEGIN"));
|
||||
ctx.PreprocessorDefines.append(txt("GEN_API_C_END"));
|
||||
ctx.PreprocessorDefines.append(txt("Array("));
|
||||
ctx.PreprocessorDefines.append(txt("HashTable("));
|
||||
ctx.PreprocessorDefines.append(txt("GEN_NS_PARSER"));
|
||||
ctx.PreprocessorDefines.append(txt("GEN_NS_PARSER_BEGIN"));
|
||||
ctx.PreprocessorDefines.append(txt("GEN_NS_PARSER_END"));
|
||||
ctx.PreprocessorDefines.append(txt("Using_Code("));
|
||||
ctx.PreprocessorDefines.append(txt("Using_CodeOps("));
|
||||
ctx.PreprocessorDefines.append(txt("GEN_OPTIMIZE_MAPPINGS_BEGIN"));
|
||||
ctx.PreprocessorDefines.append(txt("GEN_OPITMIZE_MAPPINGS_END"));
|
||||
ctx.PreprocessorDefines.append(txt("GEN_PARAM_DEFAULT"));
|
||||
//PreprocessorDefines.append(txt("GEN_EXECUTION_EXPRESSION_SUPPORT"));
|
||||
register_macros( args(
|
||||
(Macro { txt("bit"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("bitfield_is_set"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("GEN_C_LIKE_CPP"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("cast"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("ccast"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("rcast"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("pcast"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("scast"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("stringize_va"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("stringize"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("do_once"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("do_once_defer"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("do_once_start"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("do_once_end"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("labeled_scope_start"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("labeled_scope_end"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("compiler_decorated_func_name"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("num_args_impl"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("num_args"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("count_of"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("clamp"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("is_between"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("size_of"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("min"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("max"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("offset_of"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("static_assert"), MT_Statement, MF_Functional }),
|
||||
(Macro { txt("typeof"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("GEN_API_C_BEGIN"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("GEN_API_C_END"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("nullptr"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("GEN_REMOVE_PTR"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("GEN_PARAM_DEFAULT"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("struct_init"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("GEN_OPTIMIZE_MAPPINGS_BEGIN"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("GEN_OPITMIZE_MAPPINGS_END"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("Array"), MT_Typename, MF_Functional }),
|
||||
(Macro { txt("HashTable"), MT_Typename, MF_Functional }),
|
||||
(Macro { txt("Using_Code"), MT_Statement, MF_Functional }),
|
||||
(Macro { txt("Using_CodeOps"), MT_Statement, MF_Functional }),
|
||||
(Macro { txt("kilobytes"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("megabytes"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("gigabytes"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("terabytes"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("GEN__ONES"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("GEN__HIGHS"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("GEN__HAS_ZERO"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("zero_item"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("zero_array"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("GEN_DEFAULT_MEMORY_ALIGNMENT"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("GEN_DEFAULT_ALLOCATOR_FLAGS"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("alloc_item"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("alloc_array"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("malloc"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("mfree"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("GEN_PRINTF_MAXLEN"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("cast_to_str"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("current"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("txt"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("GEN_FILE_OPEN_PROC"), MT_Statement, MF_Functional | MF_Expects_Body }),
|
||||
(Macro { txt("GEN_FILE_READ_AT_PROC"), MT_Statement, MF_Functional | MF_Expects_Body }),
|
||||
(Macro { txt("GEN_FILE_WRITE_AT_PROC"), MT_Statement, MF_Functional | MF_Expects_Body }),
|
||||
(Macro { txt("GEN_FILE_SEEK_PROC"), MT_Statement, MF_Functional | MF_Expects_Body }),
|
||||
(Macro { txt("GEN_FILE_CLOSE_PROC"), MT_Statement, MF_Functional | MF_Expects_Body }),
|
||||
(Macro { txt("log_failure"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("operator"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("InvalidCode"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("NullCode"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("Verify_POD"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("gen_main"), MT_Statement, MF_Null })
|
||||
));
|
||||
register_macros( args(
|
||||
(Macro { txt("name"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("code"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("args"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("code_str"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("code_fmt"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("parse_fmt"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("token_fmt"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("check_member_val"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("check_member_str"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("check_member_content"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("check_member_ast"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("check_params"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("check_param_eq_ret"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("specs"), MT_Expression, MF_Functional | MF_Allow_As_Identifier }),
|
||||
(Macro { txt("name_check"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("null_check"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("def_body_start"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("def_body_code_array_start"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("move_forward"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("skip_whitespace"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("end_line"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("check_parse_args"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("currtok_noskip"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("currtok"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("peektok"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("prevtok"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("nexttok"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("nexttok_noskip"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("eat"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("left"), MT_Expression, MF_Null | MF_Allow_As_Identifier }),
|
||||
(Macro { txt("def_assign"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("CHECK_WAS_DEFINED"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("check_noskip"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("check"), MT_Expression, MF_Functional | MF_Allow_As_Identifier }),
|
||||
(Macro { txt("push_scope"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("cut_length"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("cut_ptr"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("pos"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("move_fwd"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("Entry"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("CheckEndParams"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("UseTemplateCapture"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("check_current"), MT_Expression, MF_Functional })
|
||||
));
|
||||
|
||||
Code push_ignores = scan_file( path_base "helpers/push_ignores.inline.hpp" );
|
||||
Code pop_ignores = scan_file( path_base "helpers/pop_ignores.inline.hpp" );
|
||||
@ -139,8 +242,8 @@ int gen_main()
|
||||
CodeTemplate tmpl = cast(CodeTemplate, entry);
|
||||
if ( tmpl->Declaration->Name.contains(txt("swap")))
|
||||
{
|
||||
log_fmt("SWAPPED");
|
||||
CodeBody macro_swap = parse_global_body( txt(R"(
|
||||
register_macro({ txt("swap"), MT_Expression, MF_Functional });
|
||||
CodeDefine macro_swap = parse_define( txt(R"(
|
||||
#define swap( a, b ) \
|
||||
do \
|
||||
{ \
|
||||
@ -203,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);
|
||||
@ -231,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);
|
||||
@ -241,7 +344,8 @@ do \
|
||||
{
|
||||
if ( str_contains(entry->Name, txt("Msg_Invalid_Value")))
|
||||
{
|
||||
CodeDefine define = def_define(entry->Name, entry->Value->Content);
|
||||
Opts_def_define opts = { {}, entry->Value->Content };
|
||||
CodeDefine define = def_define(entry->Name, MT_Expression, opts );
|
||||
header_printing.append(define);
|
||||
continue;
|
||||
}
|
||||
@ -287,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;
|
||||
|
||||
@ -368,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);
|
||||
@ -405,9 +509,10 @@ do \
|
||||
case CT_Variable:
|
||||
{
|
||||
CodeVar var = cast(CodeVar, entry);
|
||||
if (var->Specs.has(Spec_Constexpr) > -1)
|
||||
if (var->Specs.has(Spec_Constexpr))
|
||||
{
|
||||
CodeDefine define = def_define(entry->Name, entry->Value->Content);
|
||||
Opts_def_define opts = { {}, entry->Value->Content };
|
||||
CodeDefine define = def_define(entry->Name, MT_Expression, opts);
|
||||
header_filesystem.append(define);
|
||||
continue;
|
||||
}
|
||||
@ -427,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);
|
||||
@ -535,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);
|
||||
@ -597,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);
|
||||
@ -664,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
|
||||
@ -692,7 +797,10 @@ 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 );
|
||||
if (found) break;
|
||||
|
||||
ast.append(entry);
|
||||
@ -811,7 +919,8 @@ R"(#define AST_ArrSpecs_Cap \
|
||||
ast.append(def);
|
||||
break;
|
||||
}
|
||||
CodeDefine def = def_define(var->Name, var->Value.to_strbuilder());
|
||||
Opts_def_define opts = { {}, var->Value.to_strbuilder() };
|
||||
CodeDefine def = def_define(var->Name, MT_Expression, opts );
|
||||
ast.append(def);
|
||||
break;
|
||||
}
|
||||
@ -832,6 +941,7 @@ R"(#define AST_ArrSpecs_Cap \
|
||||
txt("CodeClass"),
|
||||
txt("CodeConstructor"),
|
||||
txt("CodeDefine"),
|
||||
txt("CodeDefineParams"),
|
||||
txt("CodeDestructor"),
|
||||
txt("CodeEnum"),
|
||||
txt("CodeExec"),
|
||||
@ -868,7 +978,10 @@ 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);
|
||||
if (found) break;
|
||||
|
||||
code_types.append(entry);
|
||||
@ -882,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, ... ) \
|
||||
*/
|
||||
@ -965,7 +1078,10 @@ 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_code_types, code_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);
|
||||
if (found) break;
|
||||
|
||||
ast_types.append(entry);
|
||||
@ -1005,16 +1121,24 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
||||
break;
|
||||
}
|
||||
|
||||
CodeBody array_arena = gen_array(txt("gen_Arena"), txt("Array_gen_Arena"));
|
||||
CodeBody array_pool = gen_array(txt("gen_Pool"), txt("Array_gen_Pool"));
|
||||
CodeBody array_arena = gen_array(txt("gen_Arena"), txt("Array_gen_Arena"));
|
||||
CodeBody array_pool = gen_array(txt("gen_Pool"), txt("Array_gen_Pool"));
|
||||
CodeBody ht_preprocessor_macro = gen_hashtable(txt("gen_Macro"), txt("MacroTable"));
|
||||
|
||||
CodeBody parsed_interface = parse_file( path_base "components/interface.hpp" );
|
||||
CodeBody interface = def_body(CT_Global_Body);
|
||||
for ( Code entry = parsed_interface.begin(); entry != parsed_interface.end(); ++ entry ) switch( entry->Type )
|
||||
{
|
||||
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);
|
||||
if (found) break;
|
||||
|
||||
found = ignore_preprocess_cond_block(txt("0"), entry, parsed_interface, interface);
|
||||
if (found) break;
|
||||
|
||||
interface.append(entry);
|
||||
@ -1027,13 +1151,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
||||
CodeFn fn = cast(CodeFn, entry);
|
||||
Code prev = entry->Prev;
|
||||
|
||||
if (prev && prev->Name.is_equal(entry->Name)) {
|
||||
// rename second definition so there isn't a symbol conflict
|
||||
StrBuilder postfix_arr = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "%S_arr", entry->Name);
|
||||
entry->Name = cache_str(postfix_arr.to_str());
|
||||
postfix_arr.free();
|
||||
}
|
||||
|
||||
b32 handled= false;
|
||||
for ( CodeParams opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_")))
|
||||
{
|
||||
@ -1101,9 +1218,16 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
||||
CodeBody inlines = def_body(CT_Global_Body);
|
||||
for ( Code entry = parsed_inlines.begin(); entry != parsed_inlines.end(); ++ entry ) switch( entry->Type )
|
||||
{
|
||||
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);
|
||||
if (found) break;
|
||||
|
||||
found = ignore_preprocess_cond_block(txt("0"), entry, parsed_interface, interface);
|
||||
if (found) break;
|
||||
|
||||
inlines.append(entry);
|
||||
@ -1132,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);
|
||||
@ -1157,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);
|
||||
@ -1188,42 +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) {
|
||||
CodeDefine define = def_define(entry->Name, entry->Value->Content);
|
||||
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
|
||||
|
||||
@ -1244,18 +1418,35 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
||||
Code src_static_data = scan_file( path_base "components/static_data.cpp" );
|
||||
Code src_ast_case_macros = scan_file( path_base "components/ast_case_macros.cpp" );
|
||||
Code src_code_serialization = scan_file( path_base "components/code_serialization.cpp" );
|
||||
Code src_interface = scan_file( path_base "components/interface.cpp" );
|
||||
|
||||
Code src_parsing_interface = scan_file( path_base "components/interface.parsing.cpp" );
|
||||
Code src_untyped = scan_file( path_base "components/interface.untyped.cpp" );
|
||||
Code src_parser_case_macros = scan_file( path_base "components/parser_case_macros.cpp" );
|
||||
|
||||
CodeBody parsed_src_interface = parse_file( path_base "components/interface.cpp" );
|
||||
CodeBody src_interface = def_body(CT_Global_Body);
|
||||
for ( Code entry = parsed_src_interface.begin(); entry != parsed_src_interface.end(); ++ entry ) switch( entry ->Type )
|
||||
{
|
||||
case CT_Function:
|
||||
{
|
||||
CodeFn fn = cast(CodeFn, entry);
|
||||
Code prev = entry->Prev;
|
||||
src_interface.append(fn);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
src_interface.append(entry);
|
||||
break;
|
||||
}
|
||||
|
||||
CodeBody parsed_src_ast = parse_file( path_base "components/ast.cpp" );
|
||||
CodeBody src_ast = def_body(CT_Global_Body);
|
||||
for ( Code entry = parsed_src_ast.begin(); entry != parsed_src_ast.end(); ++ entry ) switch( entry ->Type )
|
||||
{
|
||||
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);
|
||||
@ -1290,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);
|
||||
@ -1306,28 +1497,14 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
||||
{
|
||||
CodeFn fn = cast(CodeFn, entry);
|
||||
Code prev = entry->Prev;
|
||||
|
||||
for ( CodeParams arr_param : fn->Params )
|
||||
if ( fn->Name.starts_with(txt("def_"))
|
||||
&& ( (arr_param->ValueType->Name.starts_with(txt("Specifier")) && fn->Params->NumEntries > 1)
|
||||
|| arr_param->ValueType->Name.starts_with(txt("Code")) )
|
||||
)
|
||||
{
|
||||
// rename second definition so there isn't a symbol conflict
|
||||
StrBuilder postfix_arr = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "%S_arr", fn->Name);
|
||||
fn->Name = cache_str(postfix_arr.to_str());
|
||||
postfix_arr.free();
|
||||
}
|
||||
|
||||
for ( CodeParams opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_")))
|
||||
{
|
||||
// The frontend names are warapped in macros so we need to give it the intenral symbol name
|
||||
Str prefix = txt("def_");
|
||||
Str actual_name = { fn->Name.Ptr + prefix.Len, fn->Name.Len - prefix.Len };
|
||||
Str new_name = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "def__%S", actual_name ).to_str();
|
||||
|
||||
fn->Name = cache_str(new_name);
|
||||
}
|
||||
|
||||
src_upfront.append(fn);
|
||||
}
|
||||
break;
|
||||
@ -1343,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);
|
||||
@ -1365,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
|
||||
@ -1392,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);
|
||||
@ -1410,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
|
||||
@ -1430,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)));
|
||||
@ -1476,12 +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_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_ht_preprocessor_macro = refactor_and_format(ht_preprocessor_macro);
|
||||
Code rf_array_string_cached = refactor_and_format(array_string_cached);
|
||||
Code rf_header_builder = refactor_and_format(header_builder);
|
||||
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);
|
||||
@ -1503,7 +1701,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
||||
Code r_src_code_serialization = refactor(src_code_serialization);
|
||||
Code r_src_parser_case_macros = refactor(src_parser_case_macros);
|
||||
|
||||
Code r_src_interface = refactor(src_interface);
|
||||
Code r_src_interface = refactor_and_format(src_interface);
|
||||
Code r_src_upfront = refactor_and_format(src_upfront);
|
||||
Code r_src_lexer = refactor_and_format(src_lexer);
|
||||
Code rf_array_code_typename = refactor_and_format(array_code_typename);
|
||||
@ -1514,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
|
||||
@ -1586,8 +1784,11 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
||||
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");
|
||||
@ -1596,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 );
|
||||
|
||||
@ -1682,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 );
|
||||
@ -1695,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();
|
||||
}
|
||||
@ -1749,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");
|
||||
@ -1757,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 );
|
||||
|
||||
@ -1776,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);
|
||||
|
||||
@ -1798,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" );
|
||||
|
@ -21,7 +21,7 @@ word global, gen_global
|
||||
word internal, gen_internal
|
||||
word local_persist, gen_local_persist
|
||||
word bit, gen_bit
|
||||
word bitfield_is_equal, gen_bitfield_is_equal
|
||||
word bitfield_is_set, gen_bitfield_is_set
|
||||
word cast, gen_cast
|
||||
word ccast, gen_ccast
|
||||
word pcast, gen_pcast
|
||||
@ -310,6 +310,14 @@ word spec_to_str, gen_spec_to_str
|
||||
word spec_is_trailing, gen_spec_is_trailing
|
||||
// word str_to_specifier, gen_str_to_specifier
|
||||
|
||||
word MacroType, gen_MacroType
|
||||
word EMacroFlags, gen_EMacroFlags
|
||||
word MacroFlags, gen_MacroFlags
|
||||
word Macro, gen_Macro
|
||||
|
||||
namespace macro_, gen_macro_
|
||||
namespace macrotype, gen_macrotype_
|
||||
|
||||
// AST
|
||||
|
||||
word AST, gen_AST
|
||||
@ -325,6 +333,7 @@ word CodeComment, gen_CodeComment
|
||||
word CodeClass, gen_CodeClass
|
||||
word CodeConstructor, gen_CodeConstructor
|
||||
word CodeDefine, gen_CodeDefine
|
||||
word CodeDefineParams, gen_CodeDefineParams
|
||||
word CodeDestructor, gen_CodeDestructor
|
||||
word CodeEnum, gen_CodeEnum
|
||||
word CodeExec, gen_CodeExec
|
||||
@ -399,6 +408,8 @@ namespace var_, gen_var_
|
||||
|
||||
// Gen Interface
|
||||
|
||||
word _ctx, gen__ctx
|
||||
|
||||
word init, gen_init
|
||||
word deinit, gen_deinit
|
||||
word reset, gen_reset
|
||||
@ -409,6 +420,12 @@ 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_
|
||||
namespace parse_, gen_parse_
|
||||
namespace token_, gen_token_
|
||||
|
@ -22,9 +22,9 @@ CodeBody gen_array_base()
|
||||
Code get_header = untyped_str( txt( "#define array_get_header( self ) ( (ArrayHeader*)( self ) - 1)\n" ));
|
||||
Code type_define = untyped_str( txt( "#define Array(Type) gen_Array_##Type\n"));
|
||||
|
||||
Code array_begin = def_define(txt("array_begin(array)"), code( (array) ));
|
||||
Code array_end = def_define(txt("array_end(array)"), code( (array + array_get_header(array)->Num ) ));
|
||||
Code array_next = def_define(txt("array_next(array, entry)"), code( (entry + 1) ));
|
||||
Code array_begin = def_define(txt("array_begin(array)"), MT_Expression, { {}, code( (array) ) } );
|
||||
Code array_end = def_define(txt("array_end(array)"), MT_Expression, { {}, code( (array + array_get_header(array)->Num ) ) } );
|
||||
Code array_next = def_define(txt("array_next(array, entry)"), MT_Expression, { {}, code( (entry + 1) ) } );
|
||||
|
||||
return def_global_body( args(
|
||||
fmt_newline,
|
||||
@ -238,10 +238,10 @@ CodeBody gen_array( Str type, Str array_name )
|
||||
GEN_ASSERT(begin <= end);
|
||||
ArrayHeader* header = array_get_header( self );
|
||||
|
||||
if ( begin < 0 || end >= header->Num )
|
||||
if ( begin < 0 || end > header->Num )
|
||||
return false;
|
||||
|
||||
for ( ssize idx = begin; idx < end; idx ++ )
|
||||
for ( ssize idx = (ssize)begin; idx < (ssize)end; idx ++ )
|
||||
self[ idx ] = value;
|
||||
|
||||
return true;
|
||||
|
@ -19,7 +19,7 @@ CodeBody gen_hashtable_base()
|
||||
));
|
||||
|
||||
Code define_type = untyped_str(txt(
|
||||
R"(#define HashTable(_type) struct _type
|
||||
R"(#define HashTable(_type) struct gen_HashTable_##_type
|
||||
)"
|
||||
));
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
| \_____|\___}_l |_|\___} .__/| .__/ {_____/ \__\__/_l\__. |\___/\__,_l \____}{_____}{_____} |
|
||||
| | | | | __} | |
|
||||
| l_l l_l {___/ |
|
||||
! ----------------------------------------------------------------------- VERSION: v0.20-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 |
|
||||
|
@ -89,7 +89,14 @@ CodeBody gen_fixed_arenas()
|
||||
result.append(arena_interface_2mb);
|
||||
result.append(arena_interface_4mb);
|
||||
|
||||
CodeDefine def = def_define(txt("fixed_arena_allocator_info(fixed_arena)"), txt("( (AllocatorInfo) { arena_allocator_proc, & (fixed_arena)->arena } )"));
|
||||
register_macros( args(
|
||||
( Macro { txt("fixed_arena_allocator_info"), MT_Expression, MF_Functional }),
|
||||
( Macro { txt("fixed_arena_init"), MT_Expression, MF_Functional }),
|
||||
( Macro { txt("fixed_arena_free"), MT_Expression, MF_Functional }),
|
||||
( Macro { txt("fixed_arena_size_remaining"), MT_Expression, MF_Functional })
|
||||
));
|
||||
|
||||
CodeDefine def = parse_define(txt("#define fixed_arena_allocator_info(fixed_arena) ( (AllocatorInfo) { arena_allocator_proc, & (fixed_arena)->arena } )\n"));
|
||||
result.append(def);
|
||||
result.append(fmt_newline);
|
||||
|
||||
|
@ -7,12 +7,24 @@ void convert_cpp_enum_to_c( CodeEnum to_convert, CodeBody to_append )
|
||||
{
|
||||
#pragma push_macro("enum_underlying")
|
||||
#undef enum_underlying
|
||||
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>))));
|
||||
to_convert->UnderlyingType = CodeTypename{nullptr};
|
||||
}
|
||||
CodeTypedef tdef = parse_typedef(token_fmt("name", to_convert->Name, stringize( typedef enum <name> <name>; )));
|
||||
to_append.append(to_convert);
|
||||
to_append.append(tdef);
|
||||
#pragma pop_macro("enum_underlying")
|
||||
@ -27,10 +39,9 @@ b32 ignore_preprocess_cond_block( Str cond_sig, Code& entry_iter, CodeBody& pars
|
||||
//log_fmt("Preprocess cond found: %S\n", cond->Content);
|
||||
found = true;
|
||||
|
||||
s32 depth = 1;
|
||||
++ entry_iter;
|
||||
for(b32 continue_for = true; continue_for && entry_iter != parsed_body.end(); ) switch
|
||||
(entry_iter->Type) {
|
||||
s32 depth = 0;
|
||||
for(b32 continue_for = true; continue_for && entry_iter != parsed_body.end(); ) switch (entry_iter->Type)
|
||||
{
|
||||
case CT_Preprocess_If:
|
||||
case CT_Preprocess_IfDef:
|
||||
case CT_Preprocess_IfNotDef:
|
||||
@ -40,20 +51,18 @@ b32 ignore_preprocess_cond_block( Str cond_sig, Code& entry_iter, CodeBody& pars
|
||||
|
||||
case CT_Preprocess_Else:
|
||||
++ entry_iter;
|
||||
for(; continue_for && entry_iter != parsed_body.end(); ++ entry_iter)
|
||||
if (depth == 1) for(; entry_iter != parsed_body.end(); ++ entry_iter)
|
||||
{
|
||||
if (entry_iter->Type == CT_Preprocess_EndIf)
|
||||
{
|
||||
continue_for = false;
|
||||
if ( entry_iter->Type == CT_Preprocess_EndIf)
|
||||
break;
|
||||
}
|
||||
|
||||
body.append(entry_iter);
|
||||
}
|
||||
break;
|
||||
|
||||
case CT_Preprocess_EndIf:
|
||||
{
|
||||
depth --;
|
||||
-- depth;
|
||||
if (depth == 0) {
|
||||
continue_for = false;
|
||||
break;
|
||||
|
@ -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"
|
||||
|
@ -6,13 +6,15 @@
|
||||
|
||||
* [docs](../docs/Readme.md)
|
||||
|
||||
# Segemented Library Generation
|
||||
# segmented Library Generation
|
||||
|
||||
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>`
|
||||
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:
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||
#define GEN_EXPOSE_BACKEND
|
||||
#define GEN_C_LIKE_CPP 1
|
||||
#include "gen.cpp"
|
||||
#include "helpers/push_ignores.inline.hpp"
|
||||
@ -115,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,
|
||||
@ -132,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" );
|
||||
@ -169,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 );
|
||||
@ -177,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);
|
||||
@ -232,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 );
|
||||
@ -246,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 );
|
||||
@ -259,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 );
|
||||
@ -273,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 );
|
||||
|
@ -15,7 +15,7 @@
|
||||
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
|
||||
| Singleheader | | | | __} | |
|
||||
| l_l l_l {___/ |
|
||||
! ----------------------------------------------------------------------- VERSION: v0.20-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 |
|
||||
|
@ -1,6 +1,5 @@
|
||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||
#define GEN_EXPOSE_BACKEND
|
||||
#include "gen.cpp"
|
||||
#include "helpers/push_ignores.inline.hpp"
|
||||
|
||||
@ -118,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" );
|
||||
@ -150,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 );
|
||||
@ -157,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);
|
||||
@ -247,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);
|
||||
|
@ -15,3 +15,20 @@ If using the library's provided build scripts:
|
||||
```ps1
|
||||
.\build.ps1 <compiler> <debug or omit> unreal
|
||||
```
|
||||
|
||||
## Notables
|
||||
|
||||
For the most part this follows the same conventions as `gen_segmented`.
|
||||
|
||||
This generator uses a separate enumeration definitions for the following:
|
||||
|
||||
* [AttributeTokens.csv](./enums/AttributeTokens.csv) : Add your own <MODULE>_API attributes, etc here that are encountered within the Engine.
|
||||
* [ESpecifier.csv](./enums/ESpecifier.csv) : Adds the `FORCEINLINE` & `FORCEINLINE_DEBUGGABLE` specfiers (additions are made as they are encountered)
|
||||
* [ETokType.csv](./enums/ETokType.csv) : Same modifications as ESpecifier.csv.
|
||||
|
||||
A separate [parser_case_macros.cpp](./components/parser_case_macros.cpp) is used to accomodate for the new forceinline specifiers.
|
||||
|
||||
The `global` macro the library uses is redefined as an empty substiution.
|
||||
|
||||
|
||||
The expected usage of this library is to put into into a third-party plugin module to then use either in editor modules or in shell script done in some stage of hot-reloading or building the Unreal Engine or Project.
|
||||
|
@ -16,7 +16,7 @@
|
||||
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
|
||||
| Unreal Engine | | | | __} | |
|
||||
| l_l l_l {___/ |
|
||||
! ----------------------------------------------------------------------- VERSION: v0.20-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 |
|
||||
|
@ -1,6 +1,6 @@
|
||||
// These macros are used in the swtich cases within parser.cpp
|
||||
|
||||
#define GEN_PARSER_CLASS_STRUCT_BODY_ALLOWED_MEMBER_TOK_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_CLASS_STRUCT_BODY_ALLOWED_MEMBER_TOK_SPECIFIER_CASES \
|
||||
case Tok_Spec_Consteval: \
|
||||
case Tok_Spec_Constexpr: \
|
||||
case Tok_Spec_Constinit: \
|
||||
@ -14,7 +14,7 @@ case Tok_Spec_Static: \
|
||||
case Tok_Spec_Volatile: \
|
||||
case Tok_Spec_Virtual
|
||||
|
||||
#define GEN_PARSER_CLASS_STRUCT_BODY_ALLOWED_MEMBER_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_CLASS_STRUCT_BODY_ALLOWED_MEMBER_SPECIFIER_CASES \
|
||||
case Spec_Constexpr: \
|
||||
case Spec_Constinit: \
|
||||
case Spec_Explicit: \
|
||||
@ -27,7 +27,7 @@ case Spec_Static: \
|
||||
case Spec_Volatile: \
|
||||
case Spec_Virtual
|
||||
|
||||
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_TOK_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_TOK_SPECIFIER_CASES \
|
||||
case Tok_Spec_Consteval: \
|
||||
case Tok_Spec_Constexpr: \
|
||||
case Tok_Spec_Constinit: \
|
||||
@ -40,7 +40,7 @@ case Tok_Spec_Internal_Linkage: \
|
||||
case Tok_Spec_NeverInline: \
|
||||
case Tok_Spec_Static
|
||||
|
||||
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_SPECIFIER_CASES \
|
||||
case Spec_Constexpr: \
|
||||
case Spec_Constinit: \
|
||||
case Spec_ForceInline: \
|
||||
@ -54,12 +54,12 @@ case Spec_NeverInline: \
|
||||
case Spec_Static: \
|
||||
case Spec_Volatile
|
||||
|
||||
#define GEN_PARSER_FRIEND_ALLOWED_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_FRIEND_ALLOWED_SPECIFIER_CASES \
|
||||
case Spec_Const: \
|
||||
case Spec_Inline: \
|
||||
case Spec_ForceInline
|
||||
|
||||
#define GEN_PARSER_FUNCTION_ALLOWED_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_FUNCTION_ALLOWED_SPECIFIER_CASES \
|
||||
case Spec_Const: \
|
||||
case Spec_Consteval: \
|
||||
case Spec_Constexpr: \
|
||||
@ -71,7 +71,7 @@ case Spec_Inline: \
|
||||
case Spec_NeverInline: \
|
||||
case Spec_Static
|
||||
|
||||
#define GEN_PARSER_OPERATOR_ALLOWED_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_OPERATOR_ALLOWED_SPECIFIER_CASES \
|
||||
case Spec_Const: \
|
||||
case Spec_Constexpr: \
|
||||
case Spec_ForceInline: \
|
||||
@ -79,7 +79,7 @@ case Spec_Inline: \
|
||||
case Spec_NeverInline: \
|
||||
case Spec_Static
|
||||
|
||||
#define GEN_PARSER_TEMPLATE_ALLOWED_SPECIFIERS_CASES \
|
||||
#define GEN_PARSER_TEMPLATE_ALLOWED_SPECIFIER_CASES \
|
||||
case Spec_Const: \
|
||||
case Spec_Constexpr: \
|
||||
case Spec_Constinit: \
|
||||
@ -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
|
||||
|
@ -4,4 +4,3 @@ COREUOBJECT_API, COREUOBJECT_API
|
||||
ENGINE_API, ENGINE_API
|
||||
GAMEPLAYABILITIES_API, GAMEPLAYABILITIES_API
|
||||
UMG_API, UMG_API
|
||||
UE_DEPRECATED, UE_DEPRECATED
|
||||
|
|
@ -24,4 +24,5 @@ Final, final
|
||||
NoExceptions, noexcept
|
||||
Override, override
|
||||
Pure, = 0
|
||||
Delete, = delete
|
||||
Volatile, volatile
|
||||
|
|
@ -13,8 +13,8 @@ BraceCurly_Open, "{"
|
||||
BraceCurly_Close, "}"
|
||||
BraceSquare_Open, "["
|
||||
BraceSquare_Close, "]"
|
||||
Capture_Start, "("
|
||||
Capture_End, ")"
|
||||
Paren_Open, "("
|
||||
Paren_Close, ")"
|
||||
Comment, "__comment__"
|
||||
Comment_End, "__comment_end__"
|
||||
Comment_Start, "__comment_start__"
|
||||
@ -42,6 +42,7 @@ Number, "__number__"
|
||||
Operator, "__operator__"
|
||||
Preprocess_Hash, "#"
|
||||
Preprocess_Define, "define"
|
||||
Preprocess_Define_Param, "__define_param__"
|
||||
Preprocess_If, "if"
|
||||
Preprocess_IfDef, "ifdef"
|
||||
Preprocess_IfNotDef, "ifndef"
|
||||
@ -51,7 +52,9 @@ Preprocess_EndIf, "endif"
|
||||
Preprocess_Include, "include"
|
||||
Preprocess_Pragma, "pragma"
|
||||
Preprocess_Content, "__macro_content__"
|
||||
Preprocess_Macro, "__macro__"
|
||||
Preprocess_Macro_Expr, "__macro_expression__"
|
||||
Preprocess_Macro_Stmt, "__macro_statment__"
|
||||
Preprocess_Macro_Typename, "__macro_typename__"
|
||||
Preprocess_Unsupported, "__unsupported__"
|
||||
Spec_Alignas, "alignas"
|
||||
Spec_Const, "const"
|
||||
|
|
@ -1,6 +1,5 @@
|
||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||
#define GEN_EXPOSE_BACKEND
|
||||
#include "gen.cpp"
|
||||
#include "helpers/push_ignores.inline.hpp"
|
||||
|
||||
@ -64,6 +63,46 @@ int gen_main()
|
||||
Code ue_forceinline = code_str(FORCEINLINE);
|
||||
// Code
|
||||
|
||||
register_macros( args(
|
||||
(Macro { txt("bit"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("bitfield_is_set"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("GEN_C_LIKE_CPP"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("cast"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("ccast"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("rcast"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("pcast"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("scast"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("stringize_va"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("stringize"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("do_once"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("do_once_defer"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("do_once_start"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("do_once_end"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("labeled_scope_start"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("labeled_scope_end"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("compiler_decorated_func_name"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("num_args_impl"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("num_args"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("count_of"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("clamp"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("is_between"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("size_of"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("min"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("max"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("offset_of"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("static_assert"), MT_Statement, MF_Functional }),
|
||||
(Macro { txt("typeof"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("GEN_API_C_BEGIN"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("GEN_API_C_END"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("nullptr"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("GEN_REMOVE_PTR"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("GEN_PARAM_DEFAULT"), MT_Expression, MF_Null }),
|
||||
(Macro { txt("struct_init"), MT_Expression, MF_Functional }),
|
||||
(Macro { txt("GEN_OPTIMIZE_MAPPINGS_BEGIN"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("GEN_OPITMIZE_MAPPINGS_END"), MT_Statement, MF_Null }),
|
||||
(Macro { txt("src_line_str"), MT_Expression, MF_Null })
|
||||
));
|
||||
|
||||
// gen_dep.hpp
|
||||
{
|
||||
CodeBody macros = def_body( CT_Global_Body );
|
||||
@ -108,6 +147,7 @@ int gen_main()
|
||||
Code strings = scan_file( path_base "dependencies/strings.hpp" );
|
||||
Code filesystem = scan_file( path_base "dependencies/filesystem.hpp" );
|
||||
Code timing = scan_file( path_base "dependencies/timing.hpp" );
|
||||
Code parsing = scan_file( path_base "dependencies/parsing.hpp" );
|
||||
|
||||
Builder
|
||||
header = Builder::open("gen/gen.dep.hpp");
|
||||
@ -129,6 +169,7 @@ int gen_main()
|
||||
header.print( strings );
|
||||
header.print( filesystem );
|
||||
header.print( timing );
|
||||
header.print(parsing);
|
||||
|
||||
header.print_fmt( "\nGEN_NS_END\n" );
|
||||
header.print( fmt_newline );
|
||||
@ -147,6 +188,7 @@ int gen_main()
|
||||
Code strings = scan_file( path_base "dependencies/strings.cpp" );
|
||||
Code filesystem = scan_file( path_base "dependencies/filesystem.cpp" );
|
||||
Code timing = scan_file( path_base "dependencies/timing.cpp" );
|
||||
Code parsing = scan_file( path_base "dependencies/parsing.cpp" );
|
||||
|
||||
Builder
|
||||
src = Builder::open( "gen/gen.dep.cpp" );
|
||||
@ -165,6 +207,7 @@ int gen_main()
|
||||
src.print( strings );
|
||||
src.print( filesystem );
|
||||
src.print( timing );
|
||||
src.print( parsing );
|
||||
|
||||
src.print_fmt( "\nGEN_NS_END\n" );
|
||||
src.print( fmt_newline );
|
||||
@ -181,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" );
|
||||
@ -223,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 );
|
||||
@ -231,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();
|
||||
@ -271,14 +314,20 @@ int gen_main()
|
||||
|
||||
src.print_fmt( "\n#pragma region Interface\n" );
|
||||
src.print( interface );
|
||||
|
||||
src.print( upfront );
|
||||
|
||||
src.print_fmt( "\n#pragma region Parsing\n\n" );
|
||||
src.print( lexer );
|
||||
src.print( parser_case_macros );
|
||||
src.print( parser );
|
||||
src.print( parsing_interface );
|
||||
src.print( untyped );
|
||||
src.print_fmt( "\n#pragma endregion Parsing\n\n" );
|
||||
|
||||
src.print_fmt( "\n#pragma region Untyped\n\n" );
|
||||
src.print( untyped );
|
||||
src.print_fmt( "#pragma endregion \n\n" );
|
||||
|
||||
src.print_fmt( "#pragma endregion Interface\n\n" );
|
||||
|
||||
src.print_fmt( "GEN_NS_END\n\n");
|
||||
@ -288,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" );
|
||||
@ -307,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" );
|
||||
@ -325,8 +374,7 @@ int gen_main()
|
||||
|
||||
// gen_scanner.hpp
|
||||
{
|
||||
Code parsing = scan_file( path_base "dependencies/parsing.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" );
|
||||
@ -336,7 +384,6 @@ int gen_main()
|
||||
header.print( fmt_newline );
|
||||
header.print( def_include( txt("gen.hpp") ) );
|
||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||
header.print( parsing );
|
||||
header.print( scanner );
|
||||
header.print_fmt( "\nGEN_NS_END\n" );
|
||||
header.print( fmt_newline );
|
||||
@ -346,8 +393,7 @@ int gen_main()
|
||||
|
||||
// gen.scanner.cpp
|
||||
{
|
||||
Code parsing = scan_file( path_base "dependencies/parsing.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" );
|
||||
@ -356,8 +402,7 @@ int gen_main()
|
||||
src.print( fmt_newline );
|
||||
src.print( def_include( txt("gen.scanner.hpp") ) );
|
||||
src.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||
src.print( parsing );
|
||||
// src.print( scanner );
|
||||
src.print( scanner );
|
||||
src.print_fmt( "\nGEN_NS_END\n" );
|
||||
src.print( fmt_newline );
|
||||
src.print( pop_ignores );
|
||||
|
@ -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
|
||||
|
@ -15,12 +15,14 @@ Its main uage is the [c_library generation](../gen_c_library/).
|
||||
Remove any generated content from the repository.
|
||||
|
||||
**`build.ps1`**
|
||||
Build c_library, segmented, singleheader, unreal. Supports msvc or clang, release or debug.
|
||||
Build c library (segmented, singleheader, static, or dynamic), cpp library (segmented, singleheader, or unreal). Supports msvc or clang, release or debug.
|
||||
|
||||
```
|
||||
```erlang
|
||||
args:
|
||||
c_library
|
||||
segemented
|
||||
c_lib : Build c11 library (singleheader & segmented)
|
||||
c_lib_static : Build static c11 library
|
||||
c_lib_dyn : Buidl dyanmic c11
|
||||
segmented
|
||||
singleheader
|
||||
unreal
|
||||
clang
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user