mirror of
https://github.com/Ed94/gencpp.git
synced 2025-03-13 21:54:40 -07:00
Compare commits
106 Commits
v0.20-Alph
...
main
Author | SHA1 | Date | |
---|---|---|---|
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 | |||
3c249d2fae | |||
683f13deab | |||
a7da5f2060 | |||
db88979b75 | |||
e04f72ddca | |||
e8bb381520 | |||
a33b3644d9 | |||
96ffca3094 | |||
967a044637 | |||
b5cf633e98 | |||
16d0e0834f | |||
76ac3a0f93 | |||
78bcc21130 | |||
a125653448 | |||
aa2170ba80 | |||
5705196710 | |||
cf0d787196 | |||
8d436fe546 | |||
e15ac22132 | |||
bac57a5872 | |||
012fcb6bd5 | |||
6ffdca8595 | |||
e3172057d3 | |||
8d48da0b9e | |||
30dea2e9fd | |||
633879d35f | |||
831b52129d | |||
55427822a0 | |||
71b7320e1c |
14
.gitignore
vendored
14
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
|
.vscode
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
**/build/*
|
**/build/*
|
||||||
@ -27,8 +28,19 @@ release/**
|
|||||||
**/Unreal/*.h
|
**/Unreal/*.h
|
||||||
**/Unreal/*.cpp
|
**/Unreal/*.cpp
|
||||||
! **/Unreal/validate.unreal.cpp
|
! **/Unreal/validate.unreal.cpp
|
||||||
project/auxillary/vis_ast/dependencies/temp
|
project/auxiliary/vis_ast/dependencies/temp
|
||||||
test/gen/original
|
test/gen/original
|
||||||
singleheader/gen/scratch.hpp
|
singleheader/gen/scratch.hpp
|
||||||
test/gen/scratch.cpp
|
test/gen/scratch.cpp
|
||||||
gen_c_library/gen
|
gen_c_library/gen
|
||||||
|
|
||||||
|
**/*.sln
|
||||||
|
**/*.sln.DotSettings.user
|
||||||
|
**/*.10x
|
||||||
|
**/*.vcxproj
|
||||||
|
**/*.vcxproj.filters
|
||||||
|
**/*.vcxproj.user
|
||||||
|
test/c_library/gen
|
||||||
|
test/cpp_library/gen
|
||||||
|
|
||||||
|
!scripts/helpers/refactor.exe
|
||||||
|
0
.vscode/bookmarks.json
vendored
0
.vscode/bookmarks.json
vendored
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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
76
.vscode/settings.json
vendored
76
.vscode/settings.json
vendored
@ -1,76 +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"
|
|
||||||
},
|
|
||||||
"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
|
|
||||||
}
|
|
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,
|
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
|
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.
|
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.
|
||||||
|
82
Readme.md
82
Readme.md
@ -1,44 +1,52 @@
|
|||||||
# gencpp
|
# 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.
|
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.
|
These build up a code AST to then serialize with a file builder, or can be traversed for staged-reflection of C/C++ code.
|
||||||
|
|
||||||
This code base attempts follow the [handmade philosophy](https://handmade.network/manifesto).
|
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 intergrate into a user's project domain.
|
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
|
## Documentation
|
||||||
|
|
||||||
* [docs - General](./docs/Readme.md): Overview and additional docs
|
* [docs - General](./docs/Readme.md): Overview and additional docs
|
||||||
* [AST_Design](./docs/AST_Design.md): Overvie of ASTs
|
* [AST_Design](./docs/AST_Design.md): Overview of ASTs
|
||||||
* [AST Types](./docs/AST_Types.md): Listing of all AST types along with their Code type interface.
|
* [AST Types](./docs/AST_Types.md): Listing of all AST types along with their Code type interface.
|
||||||
* [Parsing](./docs/Parsing.md): Overview of the parsing interface.
|
* [Parsing](./docs/Parsing.md): Overview of the parsing interface.
|
||||||
* [Parser Algo](./docs/Parser_Algo.md): In-depth breakdown of the parser's implementation.
|
* [Parser Algo](./docs/Parser_Algo.md): In-depth breakdown of the parser's implementation.
|
||||||
* [base](./base/Readme.md): Essential (base) library.
|
* [base](./base/Readme.md): Essential (base) library.
|
||||||
* [gen_c_library](./gen_c_library/): C11 library variant generation (single header and segmeented).
|
* [gen_c_library](./gen_c_library/): C11 library variant generation (single header and segmented).
|
||||||
* [gen_segmented](./gen_segmented/): Segemented C++ (`gen.<hpp/cpp>`, `gen.dep.<hpp/cpp>`) generation
|
* [gen_segmented](./gen_segmented/): Segmented C++ (`gen.<hpp/cpp>`, `gen.dep.<hpp/cpp>`) generation
|
||||||
* [gen_singleheader](./gen_singleheader/): Singlehader C++ generation `gen.hpp`
|
* [gen_singleheader](./gen_singleheader/): Singlehader C++ generation `gen.hpp`
|
||||||
* [gen_unreal_engine](./gen_unreal_engine/): Unreal Engine thirdparty code generation.
|
* [gen_unreal_engine](./gen_unreal_engine/): Unreal Engine thirdparty code generation.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
**On Partial Hiatus: Life has got me tackling other issues..**
|
|
||||||
I will be passively updating the library with bug fixes and minor improvements as I use it for my personal projects.
|
|
||||||
There won't be any major reworks or features to this thing for a while.
|
|
||||||
|
|
||||||
This project is still in development (very much an alpha state), so expect bugs and missing features.
|
This project is still in development (very much an alpha state), so expect bugs and missing features.
|
||||||
See [issues](https://github.com/Ed94/gencpp/issues) for a list of known bugs or todos.
|
See [issues](https://github.com/Ed94/gencpp/issues) for a list of known bugs or todos.
|
||||||
|
|
||||||
The library can already be used to generate code just fine, but the parser is where the most work is needed. If your C++ isn't "down to earth" expect issues.
|
The library can already be used to generate code just fine, but the parser is where the most work is needed. If your C++ isn't "down to earth" expect issues.
|
||||||
|
|
||||||
A `natvis` and `natstepfilter` are provided in the scripts directory (its outdated, I'll update this readme when its not).
|
A `natvis` and `natstepfilter` are provided in the scripts directory (its outdated, I'll update this readme when its not).
|
||||||
|
*Minor update: I've been using [RAD Debugger](https://github.com/EpicGamesExt/raddebugger) with this and the code structures should be easy to debug even without natvis.*
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
A metaprogram is built to generate files before the main program is built. We'll term runtime for this program as `GEN_TIME`. The metaprogram's core implementation are within `gen.hpp` and `gen.cpp` in the project directory.
|
A metaprogram is built to generate files before the main program is built. We'll term runtime for this program as `GEN_TIME`. The metaprogram's core implementation are within `gen.hpp` and `gen.cpp` in the project directory.
|
||||||
|
|
||||||
`gen.cpp` \`s `main()` is defined as `gen_main()` which the user will have to define once for their program. There they will dictate everything that should be generated.
|
`gen.cpp` \`s `main()` is defined as `gen_main()` which the user will have to define once for their program. There they may reflect and/or generate code.
|
||||||
|
|
||||||
In order to keep the locality of this code within the same files the following pattern may be used (although this pattern isn't the best to use):
|
In order to keep the locality of this code within the same files the following pattern may be used (although this pattern isn't the best to use):
|
||||||
|
|
||||||
@ -52,7 +60,11 @@ Within `program.cpp` :
|
|||||||
|
|
||||||
u32 gen_main()
|
u32 gen_main()
|
||||||
{
|
{
|
||||||
|
gen::Context ctx;
|
||||||
|
gen::init(& ctx);
|
||||||
...
|
...
|
||||||
|
gen::deinit(& ctx);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -75,18 +87,18 @@ Example using each construction interface:
|
|||||||
Validation and construction through a functional interface.
|
Validation and construction through a functional interface.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
Code t_uw = def_type( name(usize) );
|
CodeTypename t_uw = def_type( name(usize) );
|
||||||
Code t_allocator = def_type( name(allocator) );
|
CodeTypename t_allocator = def_type( name(allocator) );
|
||||||
Code t_string_const = def_type( name(char), def_specifiers( args( ESpecifier::Const, ESpecifier::Ptr ) ));
|
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) );
|
CodeVar num = def_variable( t_uw, name(Num) );
|
||||||
Code cap = def_variable( t_uw, name(Capacity) );
|
CodeVar cap = def_variable( t_uw, name(Capacity) );
|
||||||
Code mem_alloc = def_variable( t_allocator, name(Allocator) );
|
CodeVar mem_alloc = def_variable( t_allocator, name(Allocator) );
|
||||||
Code body = def_struct_body( args( num, cap, mem_alloc ) );
|
CodeBody body = def_struct_body( args( num, cap, mem_alloc ) );
|
||||||
|
|
||||||
header = def_struct( name(ArrayHeader), __, __, body );
|
header = def_struct( name(ArrayHeader), { body });
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -95,11 +107,11 @@ Code header;
|
|||||||
Validation through ast construction.
|
Validation through ast construction.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
Code header = parse_struct( code(
|
CodeStruct header = parse_struct( code(
|
||||||
struct ArrayHeader
|
struct ArrayHeader
|
||||||
{
|
{
|
||||||
usize Num;
|
usize Num;
|
||||||
usize Capacity;
|
usize Capacity;
|
||||||
allocator Allocator;
|
allocator Allocator;
|
||||||
};
|
};
|
||||||
));
|
));
|
||||||
@ -114,8 +126,8 @@ No validation, just glorified text injection.
|
|||||||
Code header = code_str(
|
Code header = code_str(
|
||||||
struct ArrayHeader
|
struct ArrayHeader
|
||||||
{
|
{
|
||||||
usize Num;
|
usize Num;
|
||||||
usize Capacity;
|
usize Capacity;
|
||||||
allocator Allocator;
|
allocator Allocator;
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
@ -124,15 +136,15 @@ Code header = code_str(
|
|||||||
`name` is a helper macro for providing a string literal with its size, intended for the name parameter of functions.
|
`name` is a helper macro for providing a string literal with its size, intended for the name parameter of functions.
|
||||||
`code` is a helper macro for providing a string literal with its size, but intended for code string parameters.
|
`code` is a helper macro for providing a string literal with its size, but intended for code string parameters.
|
||||||
`args` is a helper macro for providing the number of arguments to varadic constructors.
|
`args` is a helper macro for providing the number of arguments to varadic constructors.
|
||||||
`code_str` is a helper macro for writting `untyped_str( code( <content> ))`
|
`code_str` is a helper macro for writing `untyped_str( code( <content> ))`
|
||||||
|
|
||||||
All three constrcuton interfaces will generate the following C code:
|
All three construction interfaces will generate the following C code:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
struct ArrayHeader
|
struct ArrayHeader
|
||||||
{
|
{
|
||||||
usize Num;
|
usize Num;
|
||||||
usize Capacity;
|
usize Capacity;
|
||||||
allocator Allocator;
|
allocator Allocator;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
@ -143,3 +155,13 @@ struct ArrayHeader
|
|||||||
## Building
|
## Building
|
||||||
|
|
||||||
See the [scripts directory](scripts/).
|
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
|
||||||
|
100
base/Readme.md
100
base/Readme.md
@ -8,26 +8,32 @@
|
|||||||
|
|
||||||
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.
|
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:
|
* **base**: Files are in granular pieces separated into four directories:
|
||||||
* **dependencies**: Originally from the c-zpl library and modified thereafter.
|
* **dependencies**: Originally from the c-zpl library and modified thereafter.
|
||||||
* **components**: The essential definitions of the library.
|
* **components**: The essential definitions of the library.
|
||||||
* **helpers**: Contains helper functionality used by base and other libraries to regenerate or generate the other library formats.
|
* **helpers**: Contains helper functionality used by base and the variant library generators.
|
||||||
* `base_codegen.hpp`: Helps with self-hosted code generation of enums, and operator overload inlines of the code types.
|
* `base_codegen.hpp`: Helps with self-hosted code generation of enums, and operator overload inlines of the code types.
|
||||||
* `<push/pop>.<name>.inline.<hpp>`: macros that are meant to be injected at specific locations of the library.
|
* `<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.
|
* `misc.hpp`: Misc functionality used by the library generation metaprograms.
|
||||||
* `undef.macros.h`: Undefines all macros from library that original were intended to leak into user code.
|
* `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`).
|
* `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).
|
* `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.
|
* `parse_file`: Used to read file and then parsed to populate a `CodeBody` AST.
|
||||||
* CSV parsing via one or two columns simplified.
|
* CSV parsing via one or two columns simplified.
|
||||||
* **gen_segemetned**: Dependencies go into gen.dep.{hpp/cpp} and components into gen.{hpp/cpp}
|
* **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_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_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 segemented and single-header set of variants are generatd.
|
* **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.
|
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:
|
The vast majority of macros should be single-line subsitutions that either add:
|
||||||
|
|
||||||
* Improvements to searching
|
* Improvements to searching
|
||||||
* Inteniality of keyword usage
|
* Intentionality of keyword usage
|
||||||
* A feature that only the preprocessor has (ex: function name reflection or stringifying)
|
* 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.
|
* 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).
|
* Masking highly verbose syntax (the latter is getting phased out).
|
||||||
@ -117,15 +123,23 @@ 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/).
|
There are ***five*** header files which are automatically generated using [base_codegen.hpp](./helpers/base_codegen.hpp) by [base.cpp](./base.cpp). They are all located in [components/gen](./components/gen/).
|
||||||
|
|
||||||
* [`ecodetypes.hpp`](./components/gen/ecode.hpp): `CodeType` enum definition and related implementaiton. Generation is based off of [`ECodeType.csv](./enums/ECodeTypes.csv).
|
* [ecodetypes.hpp](./components/gen/ecode.hpp): `CodeType` enum definition and related implementation. Generation is based off of [ECodeType.csv](./enums/ECodeTypes.csv).
|
||||||
* [`especifier.hpp`](./components/gen/especifier.hpp): `Specifier` enum definition, etc. Generated using [`ESpecifier.csv`](./enums/ESpecifier.csv).
|
* [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).
|
* [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.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.
|
* [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.
|
* [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.
|
* [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:
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
.\build.ps1 <compiler> <debug or omit> base
|
||||||
|
```
|
||||||
|
|
||||||
|
Will refresh those files.
|
||||||
|
|
||||||
## On multi-threading
|
## On multi-threading
|
||||||
|
|
||||||
@ -140,15 +154,59 @@ The convention you'll see used throughout the upfront interface of the library i
|
|||||||
1. Check name or parameters to make sure they are valid for the construction requested
|
1. Check name or parameters to make sure they are valid for the construction requested
|
||||||
2. Create a code object using `make_code`.
|
2. Create a code object using `make_code`.
|
||||||
3. Populate immediate fields (Name, Type, ModuleFlags, etc)
|
3. Populate immediate fields (Name, Type, ModuleFlags, etc)
|
||||||
4. Populate sub-entires using `add_entry`. If using the default serialization function `to_string`, follow the order at which entires are expected to appear (there is a strong ordering expected).
|
4. Populate sub-entires using `add_entry`. If using the default serialization function `to_strbuilder`, follow the order at which entires are expected to appear (there is a strong ordering expected).
|
||||||
|
|
||||||
Names or Content fields are interned strings and thus showed be cached using `get_cached_string` if its desired to preserve that behavior.
|
Names or Content fields are interned strings and thus showed be cached using `cache_str` if its desired to preserve that behavior.
|
||||||
|
|
||||||
`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.
|
`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). Extending it is more serious.
|
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
|
## 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).
|
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"
|
# include "builder.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -15,7 +15,9 @@ Builder builder_open( char const* path )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Buffer = string_make_reserve( GlobalAllocator, Builder_StrBufferReserve );
|
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 );
|
// log_fmt("$Builder - Opened file: %s\n", result.File.filename );
|
||||||
return result;
|
return result;
|
||||||
@ -23,15 +25,15 @@ Builder builder_open( char const* path )
|
|||||||
|
|
||||||
void builder_pad_lines( Builder* builder, s32 num )
|
void builder_pad_lines( Builder* builder, s32 num )
|
||||||
{
|
{
|
||||||
string_append_strc( & builder->Buffer, txt("\n") );
|
strbuilder_append_str( & builder->Buffer, txt("\n") );
|
||||||
}
|
}
|
||||||
|
|
||||||
void builder_print( Builder* builder, Code code )
|
void builder_print( Builder* builder, Code code )
|
||||||
{
|
{
|
||||||
String str = code_to_string(code);
|
StrBuilder str = code_to_strbuilder(code);
|
||||||
// const ssize len = str.length();
|
// const ssize len = str.length();
|
||||||
// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data );
|
// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data );
|
||||||
string_append_string( & builder->Buffer, str );
|
strbuilder_append_string( & builder->Buffer, str );
|
||||||
}
|
}
|
||||||
|
|
||||||
void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va )
|
void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va )
|
||||||
@ -39,21 +41,21 @@ void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va )
|
|||||||
ssize res;
|
ssize res;
|
||||||
char buf[ GEN_PRINTF_MAXLEN ] = { 0 };
|
char buf[ GEN_PRINTF_MAXLEN ] = { 0 };
|
||||||
|
|
||||||
res = str_fmt_va( buf, count_of( buf ) - 1, fmt, va ) - 1;
|
res = c_str_fmt_va( buf, count_of( buf ) - 1, fmt, va ) - 1;
|
||||||
|
|
||||||
string_append_c_str_len( (String*) & (builder->Buffer), (char const*)buf, res);
|
strbuilder_append_c_str_len( (StrBuilder*) & (builder->Buffer), (char const*)buf, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void builder_write(Builder* builder)
|
void builder_write(Builder* builder)
|
||||||
{
|
{
|
||||||
b32 result = file_write( & builder->File, builder->Buffer, string_length(builder->Buffer) );
|
b32 result = file_write( & builder->File, builder->Buffer, strbuilder_length(builder->Buffer) );
|
||||||
|
|
||||||
if ( result == false )
|
if ( result == false )
|
||||||
log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & builder->File ) );
|
log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & builder->File ) );
|
||||||
|
|
||||||
log_fmt( "Generated: %s\n", builder->File.filename );
|
log_fmt( "Generated: %s\n", builder->File.filename );
|
||||||
file_close( & builder->File );
|
file_close( & builder->File );
|
||||||
string_free(& builder->Buffer);
|
strbuilder_free(& builder->Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion Builder
|
#pragma endregion Builder
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "helpers/push_ignores.inline.hpp"
|
# include "helpers/push_ignores.inline.hpp"
|
||||||
# include "components/header_start.hpp"
|
# include "components/header_start.hpp"
|
||||||
@ -21,22 +21,23 @@ using namespace gen;
|
|||||||
struct Builder;
|
struct Builder;
|
||||||
typedef struct Builder Builder;
|
typedef struct Builder Builder;
|
||||||
|
|
||||||
Builder builder_open ( char const* path );
|
GEN_API Builder builder_open ( char const* path );
|
||||||
void builder_pad_lines ( Builder* builder, s32 num );
|
GEN_API void builder_pad_lines ( Builder* builder, s32 num );
|
||||||
void builder_print ( Builder* builder, Code code );
|
GEN_API void builder_print ( Builder* builder, Code code );
|
||||||
void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va );
|
GEN_API void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va );
|
||||||
void builder_print_fmt ( Builder* builder, char const* fmt, ... ) {
|
GEN_API void builder_write ( Builder* builder );
|
||||||
|
|
||||||
|
forceinline void builder_print_fmt ( Builder* builder, char const* fmt, ... ) {
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start( va, fmt );
|
va_start( va, fmt );
|
||||||
builder_print_fmt_va( builder, fmt, va );
|
builder_print_fmt_va( builder, fmt, va );
|
||||||
va_end( va );
|
va_end( va );
|
||||||
}
|
}
|
||||||
void builder_write( Builder* builder );
|
|
||||||
|
|
||||||
struct Builder
|
struct Builder
|
||||||
{
|
{
|
||||||
FileInfo File;
|
FileInfo File;
|
||||||
String Buffer;
|
StrBuilder Buffer;
|
||||||
|
|
||||||
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
|
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
|
||||||
forceinline static Builder open( char const* path ) { return builder_open(path); }
|
forceinline static Builder open( char const* path ) { return builder_open(path); }
|
||||||
@ -56,10 +57,10 @@ struct Builder
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
|
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
|
||||||
void builder_pad_lines( Builder& builder, s32 num ) { return builder_pad_lines(& builder, num); }
|
forceinline 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); }
|
forceinline void builder_print ( Builder& builder, Code code ) { return builder_print(& builder, code); }
|
||||||
void builder_write ( Builder& builder ) { return builder_write(& builder ); }
|
forceinline void builder_write ( Builder& builder ) { return builder_write(& builder ); }
|
||||||
void builder_print_fmt( Builder& builder, char const* fmt, ...) {
|
forceinline void builder_print_fmt( Builder& builder, char const* fmt, ...) {
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start( va, fmt );
|
va_start( va, fmt );
|
||||||
builder_print_fmt_va( & builder, fmt, va );
|
builder_print_fmt_va( & builder, fmt, va );
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "helpers/push_ignores.inline.hpp"
|
# include "helpers/push_ignores.inline.hpp"
|
||||||
# include "components/header_start.hpp"
|
# include "components/header_start.hpp"
|
||||||
@ -32,4 +32,4 @@ CodeFn gen_func_template( CodeTemplate template, ... );
|
|||||||
Code gen_class_struct_template( CodeTemplate template, ... );
|
Code gen_class_struct_template( CodeTemplate template, ... );
|
||||||
|
|
||||||
Code gen_template( CodeTemplate template, ... );
|
Code gen_template( CodeTemplate template, ... );
|
||||||
Code gen_template( StrC template, StrC instantiation );
|
Code gen_template( Str template, Str instantiation );
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# include "scanner.hpp"
|
# include "scanner.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -20,20 +20,20 @@ Code scan_file( char const* path )
|
|||||||
GEN_FATAL("scan_file: %s is empty", path );
|
GEN_FATAL("scan_file: %s is empty", path );
|
||||||
}
|
}
|
||||||
|
|
||||||
String str = string_make_reserve( GlobalAllocator, fsize );
|
StrBuilder str = strbuilder_make_reserve( get_context()->Allocator_Temp, fsize );
|
||||||
file_read( & file, str, fsize );
|
file_read( & file, str, fsize );
|
||||||
string_get_header(str)->Length = 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.
|
// Its designed so that the directive should be the first thing in the file.
|
||||||
// Anything that comes before it will also be omitted.
|
// Anything that comes before it will also be omitted.
|
||||||
{
|
{
|
||||||
#define current (*scanner)
|
#define current (*scanner)
|
||||||
#define matched 0
|
#define matched 0
|
||||||
#define move_fwd() do { ++ scanner; -- left; } while (0)
|
#define move_fwd() do { ++ scanner; -- left; } while (0)
|
||||||
const StrC directive_start = txt( "ifdef" );
|
const Str directive_start = txt( "ifdef" );
|
||||||
const StrC directive_end = txt( "endif" );
|
const Str directive_end = txt( "endif" );
|
||||||
const StrC def_intellisense = txt("GEN_INTELLISENSE_DIRECTIVES" );
|
const Str def_intellisense = txt("INTELLISENSE_DIRECTIVES" );
|
||||||
|
|
||||||
bool found_directive = false;
|
bool found_directive = false;
|
||||||
char const* scanner = (char const*)str;
|
char const* scanner = (char const*)str;
|
||||||
@ -49,7 +49,7 @@ Code scan_file( char const* path )
|
|||||||
|
|
||||||
if ( ! found_directive )
|
if ( ! found_directive )
|
||||||
{
|
{
|
||||||
if ( left && str_compare_len( scanner, directive_start.Ptr, directive_start.Len ) == matched )
|
if ( left && c_str_compare_len( scanner, directive_start.Ptr, directive_start.Len ) == matched )
|
||||||
{
|
{
|
||||||
scanner += directive_start.Len;
|
scanner += directive_start.Len;
|
||||||
left -= directive_start.Len;
|
left -= directive_start.Len;
|
||||||
@ -57,7 +57,7 @@ Code scan_file( char const* path )
|
|||||||
while ( left && char_is_space( current ) )
|
while ( left && char_is_space( current ) )
|
||||||
move_fwd();
|
move_fwd();
|
||||||
|
|
||||||
if ( left && str_compare_len( scanner, def_intellisense.Ptr, def_intellisense.Len ) == matched )
|
if ( left && c_str_compare_len( scanner, def_intellisense.Ptr, def_intellisense.Len ) == matched )
|
||||||
{
|
{
|
||||||
scanner += def_intellisense.Len;
|
scanner += def_intellisense.Len;
|
||||||
left -= def_intellisense.Len;
|
left -= def_intellisense.Len;
|
||||||
@ -77,7 +77,7 @@ Code scan_file( char const* path )
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( left && str_compare_len( scanner, directive_end.Ptr, directive_end.Len ) == matched )
|
if ( left && c_str_compare_len( scanner, directive_end.Ptr, directive_end.Len ) == matched )
|
||||||
{
|
{
|
||||||
scanner += directive_end.Len;
|
scanner += directive_end.Len;
|
||||||
left -= directive_end.Len;
|
left -= directive_end.Len;
|
||||||
@ -94,12 +94,12 @@ Code scan_file( char const* path )
|
|||||||
if ( (scanner + 2) >= ( (char const*) str + fsize ) )
|
if ( (scanner + 2) >= ( (char const*) str + fsize ) )
|
||||||
{
|
{
|
||||||
mem_move( str, scanner, left );
|
mem_move( str, scanner, left );
|
||||||
string_get_header(str)->Length = left;
|
strbuilder_get_header(str)->Length = left;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_move( str, scanner, left );
|
mem_move( str, scanner, left );
|
||||||
string_get_header(str)->Length = left;
|
strbuilder_get_header(str)->Length = left;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -113,12 +113,12 @@ Code scan_file( char const* path )
|
|||||||
}
|
}
|
||||||
|
|
||||||
file_close( & file );
|
file_close( & file );
|
||||||
return untyped_str( string_to_strc(str) );
|
return untyped_str( strbuilder_to_str(str) );
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeBody parse_file( const char* path ) {
|
CodeBody parse_file( const char* path ) {
|
||||||
FileContents file = file_read_contents( GlobalAllocator, true, path );
|
FileContents file = file_read_contents( get_context()->Allocator_Temp, true, path );
|
||||||
StrC content = { file.size, (char const*)file.data };
|
Str content = { (char const*)file.data, file.size };
|
||||||
CodeBody code = parse_global_body( content );
|
CodeBody code = parse_global_body( content );
|
||||||
log_fmt("\nParsed: %s\n", path);
|
log_fmt("\nParsed: %s\n", path);
|
||||||
return code;
|
return code;
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "helpers/push_ignores.inline.hpp"
|
# include "helpers/push_ignores.inline.hpp"
|
||||||
# include "components/header_start.hpp"
|
# include "components/header_start.hpp"
|
||||||
@ -20,9 +20,9 @@
|
|||||||
// This is a simple file reader that reads the entire file into memory.
|
// 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.
|
// 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.
|
// 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)
|
// The follow is basic support for light csv parsing (use it as an example)
|
||||||
// Make something robust if its more serious.
|
// Make something robust if its more serious.
|
||||||
@ -40,7 +40,7 @@ struct CSV_Columns2 {
|
|||||||
Array(ADT_Node) Col_2;
|
Array(ADT_Node) Col_2;
|
||||||
};
|
};
|
||||||
|
|
||||||
CSV_Column parse_csv_one_column(AllocatorInfo allocator, char const* path);
|
GEN_API 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_Columns2 parse_csv_two_columns(AllocatorInfo allocator, char const* path);
|
||||||
|
|
||||||
#pragma endregion Scanner
|
#pragma endregion Scanner
|
@ -1,6 +1,5 @@
|
|||||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||||
#define GEN_EXPOSE_BACKEND
|
|
||||||
#define GEN_C_LIKE_CPP 1
|
#define GEN_C_LIKE_CPP 1
|
||||||
#include "gen.cpp"
|
#include "gen.cpp"
|
||||||
#include "helpers/push_ignores.inline.hpp"
|
#include "helpers/push_ignores.inline.hpp"
|
||||||
@ -27,20 +26,22 @@ constexpr char const* generation_notice =
|
|||||||
|
|
||||||
int gen_main()
|
int gen_main()
|
||||||
{
|
{
|
||||||
gen::init();
|
gen::Context ctx {};
|
||||||
|
gen::init( & ctx);
|
||||||
|
|
||||||
CodeBody gen_component_header = def_global_body( args(
|
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,
|
pragma_once,
|
||||||
def_include(txt("components/types.hpp")),
|
def_include(txt("components/types.hpp")),
|
||||||
preprocess_endif,
|
preprocess_endif,
|
||||||
fmt_newline,
|
fmt_newline,
|
||||||
untyped_str( to_strc_from_c_str(generation_notice) )
|
untyped_str( to_str_from_c_str(generation_notice) )
|
||||||
));
|
));
|
||||||
|
|
||||||
CodeBody ecode = gen_ecode ( "enums/ECodeTypes.csv" );
|
CodeBody ecode = gen_ecode ( "enums/ECodeTypes.csv" );
|
||||||
CodeBody eoperator = gen_eoperator ( "enums/EOperator.csv" );
|
CodeBody eoperator = gen_eoperator ( "enums/EOperator.csv" );
|
||||||
CodeBody especifier = gen_especifier( "enums/ESpecifier.csv" );
|
CodeBody especifier = gen_especifier( "enums/ESpecifier.csv" );
|
||||||
|
CodeBody etoktype = gen_etoktype ( "enums/ETokType.csv", "enums/AttributeTokens.csv" );
|
||||||
CodeBody ast_inlines = gen_ast_inlines();
|
CodeBody ast_inlines = gen_ast_inlines();
|
||||||
|
|
||||||
Builder header_ecode = builder_open( "components/gen/ecodetypes.hpp" );
|
Builder header_ecode = builder_open( "components/gen/ecodetypes.hpp" );
|
||||||
@ -57,12 +58,17 @@ int gen_main()
|
|||||||
builder_print( & header_especifier, gen_component_header );
|
builder_print( & header_especifier, gen_component_header );
|
||||||
builder_print( & header_especifier, format(especifier) );
|
builder_print( & header_especifier, format(especifier) );
|
||||||
builder_write( & header_especifier);
|
builder_write( & header_especifier);
|
||||||
|
|
||||||
|
Builder header_etoktype = builder_open( "components/gen/etoktype.hpp" );
|
||||||
|
builder_print( & header_etoktype, gen_component_header );
|
||||||
|
builder_print( & header_etoktype, format(etoktype) );
|
||||||
|
builder_write( & header_etoktype);
|
||||||
|
|
||||||
Builder header_ast_inlines = builder_open( "components/gen/ast_inlines.hpp" );
|
Builder header_ast_inlines = builder_open( "components/gen/ast_inlines.hpp" );
|
||||||
builder_print( & header_ast_inlines, gen_component_header );
|
builder_print( & header_ast_inlines, gen_component_header );
|
||||||
builder_print( & header_ast_inlines, format(ast_inlines) );
|
builder_print( & header_ast_inlines, format(ast_inlines) );
|
||||||
builder_write( & header_ast_inlines);
|
builder_write( & header_ast_inlines);
|
||||||
|
|
||||||
gen::deinit();
|
gen::deinit(& ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
#include "gen/ecode.hpp"
|
#include "gen/ecode.hpp"
|
||||||
@ -26,6 +26,7 @@ struct AST_Constructor;
|
|||||||
// struct AST_BaseClass;
|
// struct AST_BaseClass;
|
||||||
struct AST_Class;
|
struct AST_Class;
|
||||||
struct AST_Define;
|
struct AST_Define;
|
||||||
|
struct AST_DefineParams;
|
||||||
struct AST_Destructor;
|
struct AST_Destructor;
|
||||||
struct AST_Enum;
|
struct AST_Enum;
|
||||||
struct AST_Exec;
|
struct AST_Exec;
|
||||||
@ -42,7 +43,7 @@ struct AST_Pragma;
|
|||||||
struct AST_PreprocessCond;
|
struct AST_PreprocessCond;
|
||||||
struct AST_Specifiers;
|
struct AST_Specifiers;
|
||||||
|
|
||||||
#if GEN_EXECUTION_EXPRESSION_SUPPORT
|
#ifdef GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||||
struct AST_Expr;
|
struct AST_Expr;
|
||||||
struct AST_Expr_Assign;
|
struct AST_Expr_Assign;
|
||||||
struct AST_Expr_Alignof;
|
struct AST_Expr_Alignof;
|
||||||
@ -98,6 +99,7 @@ typedef AST_Comment* CodeComment;
|
|||||||
typedef AST_Class* CodeClass;
|
typedef AST_Class* CodeClass;
|
||||||
typedef AST_Constructor* CodeConstructor;
|
typedef AST_Constructor* CodeConstructor;
|
||||||
typedef AST_Define* CodeDefine;
|
typedef AST_Define* CodeDefine;
|
||||||
|
typedef AST_DefineParams* CodeDefineParams;
|
||||||
typedef AST_Destructor* CodeDestructor;
|
typedef AST_Destructor* CodeDestructor;
|
||||||
typedef AST_Enum* CodeEnum;
|
typedef AST_Enum* CodeEnum;
|
||||||
typedef AST_Exec* CodeExec;
|
typedef AST_Exec* CodeExec;
|
||||||
@ -120,6 +122,7 @@ struct CodeComment;
|
|||||||
struct CodeClass;
|
struct CodeClass;
|
||||||
struct CodeConstructor;
|
struct CodeConstructor;
|
||||||
struct CodeDefine;
|
struct CodeDefine;
|
||||||
|
struct CodeDefineParams;
|
||||||
struct CodeDestructor;
|
struct CodeDestructor;
|
||||||
struct CodeEnum;
|
struct CodeEnum;
|
||||||
struct CodeExec;
|
struct CodeExec;
|
||||||
@ -137,7 +140,7 @@ struct CodePragma;
|
|||||||
struct CodeSpecifiers;
|
struct CodeSpecifiers;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GEN_EXECUTION_EXPRESSION_SUPPORT
|
#ifdef GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||||
|
|
||||||
#if GEN_COMPILER_C
|
#if GEN_COMPILER_C
|
||||||
typedef AST_Expr* CodeExpr;
|
typedef AST_Expr* CodeExpr;
|
||||||
@ -190,6 +193,7 @@ typedef AST_Stmt_If* CodeStmt_If;
|
|||||||
typedef AST_Stmt_For* CodeStmt_For;
|
typedef AST_Stmt_For* CodeStmt_For;
|
||||||
typedef AST_Stmt_Goto* CodeStmt_Goto;
|
typedef AST_Stmt_Goto* CodeStmt_Goto;
|
||||||
typedef AST_Stmt_Label* CodeStmt_Label;
|
typedef AST_Stmt_Label* CodeStmt_Label;
|
||||||
|
typedef AST_Stmt_Lambda* CodeStmt_Lambda;
|
||||||
typedef AST_Stmt_Switch* CodeStmt_Switch;
|
typedef AST_Stmt_Switch* CodeStmt_Switch;
|
||||||
typedef AST_Stmt_While* CodeStmt_While;
|
typedef AST_Stmt_While* CodeStmt_While;
|
||||||
#else
|
#else
|
||||||
@ -205,6 +209,7 @@ struct CodeStmt_If;
|
|||||||
struct CodeStmt_For;
|
struct CodeStmt_For;
|
||||||
struct CodeStmt_Goto;
|
struct CodeStmt_Goto;
|
||||||
struct CodeStmt_Label;
|
struct CodeStmt_Label;
|
||||||
|
struct CodeStmt_Lambda;
|
||||||
struct CodeStmt_Switch;
|
struct CodeStmt_Switch;
|
||||||
struct CodeStmt_While;
|
struct CodeStmt_While;
|
||||||
#endif
|
#endif
|
||||||
@ -230,40 +235,25 @@ struct CodeUsing;
|
|||||||
struct CodeVar;
|
struct CodeVar;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GEN_NS_PARSER_BEGIN
|
|
||||||
|
|
||||||
struct Token;
|
|
||||||
|
|
||||||
GEN_NS_PARSER_END
|
|
||||||
|
|
||||||
#if GEN_COMPILER_CPP
|
|
||||||
// Note(Ed): This is to alleviate an edge case with parsing usings or typedefs where I don't really have it setup
|
|
||||||
// to parse a 'namespace' macro or a type with a macro.
|
|
||||||
// I have ideas for ways to pack that into the typedef/using ast, but for now just keeping it like this
|
|
||||||
#define ParserTokenType GEN_NS_PARSER Token
|
|
||||||
typedef ParserTokenType Token;
|
|
||||||
#undef ParserTokenType
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GEN_COMPILER_CPP
|
#if GEN_COMPILER_CPP
|
||||||
template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast( Type*, & self ); }
|
template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast( Type*, & self ); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region Code C-Interface
|
#pragma region Code C-Interface
|
||||||
|
|
||||||
void code_append (Code code, Code other );
|
void code_append (Code code, Code other );
|
||||||
StrC code_debug_str (Code code);
|
GEN_API Str code_debug_str (Code code);
|
||||||
Code code_duplicate (Code code);
|
GEN_API Code code_duplicate (Code code);
|
||||||
Code* code_entry (Code code, u32 idx );
|
Code* code_entry (Code code, u32 idx );
|
||||||
bool code_has_entries (Code code);
|
bool code_has_entries (Code code);
|
||||||
bool code_is_body (Code code);
|
bool code_is_body (Code code);
|
||||||
bool code_is_equal (Code code, Code other);
|
GEN_API bool code_is_equal (Code code, Code other);
|
||||||
bool code_is_valid (Code code);
|
bool code_is_valid (Code code);
|
||||||
void code_set_global (Code code);
|
void code_set_global (Code code);
|
||||||
String code_to_string (Code self );
|
GEN_API StrBuilder code_to_strbuilder (Code self );
|
||||||
void code_to_string_ptr(Code self, String* result );
|
GEN_API void code_to_strbuilder_ref(Code self, StrBuilder* result );
|
||||||
StrC code_type_str (Code self );
|
Str code_type_str (Code self );
|
||||||
bool code_validate_body(Code self );
|
GEN_API bool code_validate_body (Code self );
|
||||||
|
|
||||||
#pragma endregion Code C-Interface
|
#pragma endregion Code C-Interface
|
||||||
|
|
||||||
@ -278,7 +268,7 @@ struct Code
|
|||||||
AST* ast;
|
AST* ast;
|
||||||
|
|
||||||
# define Using_Code( Typename ) \
|
# define Using_Code( Typename ) \
|
||||||
forceinline StrC debug_str() { return code_debug_str(* this); } \
|
forceinline Str debug_str() { return code_debug_str(* this); } \
|
||||||
forceinline Code duplicate() { return code_duplicate(* this); } \
|
forceinline Code duplicate() { return code_duplicate(* this); } \
|
||||||
forceinline bool is_equal( Code other ) { return code_is_equal(* this, other); } \
|
forceinline bool is_equal( Code other ) { return code_is_equal(* this, other); } \
|
||||||
forceinline bool is_body() { return code_is_body(* this); } \
|
forceinline bool is_body() { return code_is_body(* this); } \
|
||||||
@ -295,16 +285,17 @@ struct Code
|
|||||||
|
|
||||||
#if ! GEN_C_LIKE_CPP
|
#if ! GEN_C_LIKE_CPP
|
||||||
Using_Code( Code );
|
Using_Code( Code );
|
||||||
forceinline void append(Code other) { return code_append(* this, other); }
|
forceinline void append(Code other) { return code_append(* this, other); }
|
||||||
forceinline Code* entry(u32 idx) { return code_entry(* this, idx); }
|
forceinline Code* entry(u32 idx) { return code_entry(* this, idx); }
|
||||||
forceinline bool has_entries() { return code_has_entries(* this); }
|
forceinline bool has_entries() { return code_has_entries(* this); }
|
||||||
forceinline String to_string() { return code_to_string(* this); }
|
forceinline StrBuilder to_strbuilder() { return code_to_strbuilder(* this); }
|
||||||
forceinline void to_string(String& result) { return code_to_string_ptr(* this, & result); }
|
forceinline void to_strbuilder(StrBuilder& result) { return code_to_strbuilder_ref(* this, & result); }
|
||||||
forceinline StrC type_str() { return code_type_str(* this); }
|
forceinline Str type_str() { return code_type_str(* this); }
|
||||||
forceinline bool validate_body() { return code_validate_body(*this); }
|
forceinline bool validate_body() { return code_validate_body(*this); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Using_CodeOps( Code );
|
Using_CodeOps( Code );
|
||||||
|
forceinline Code operator *() { return * this; } // Required to support for-range iteration.
|
||||||
forceinline AST* operator ->() { return ast; }
|
forceinline AST* operator ->() { return ast; }
|
||||||
|
|
||||||
Code& operator ++();
|
Code& operator ++();
|
||||||
@ -319,6 +310,7 @@ struct Code
|
|||||||
operator CodeClass() const;
|
operator CodeClass() const;
|
||||||
operator CodeConstructor() const;
|
operator CodeConstructor() const;
|
||||||
operator CodeDefine() const;
|
operator CodeDefine() const;
|
||||||
|
operator CodeDefineParams() const;
|
||||||
operator CodeDestructor() const;
|
operator CodeDestructor() const;
|
||||||
operator CodeExec() const;
|
operator CodeExec() const;
|
||||||
operator CodeEnum() const;
|
operator CodeEnum() const;
|
||||||
@ -347,10 +339,10 @@ struct Code
|
|||||||
|
|
||||||
#pragma region Statics
|
#pragma region Statics
|
||||||
// Used to identify ASTs that should always be duplicated. (Global constant ASTs)
|
// 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.
|
// Used to identify invalid generated code.
|
||||||
extern Code Code_Invalid;
|
GEN_API extern Code Code_Invalid;
|
||||||
#pragma endregion Statics
|
#pragma endregion Statics
|
||||||
|
|
||||||
struct Code_POD
|
struct Code_POD
|
||||||
@ -367,7 +359,7 @@ int AST_ArrSpecs_Cap =
|
|||||||
(
|
(
|
||||||
AST_POD_Size
|
AST_POD_Size
|
||||||
- sizeof(Code)
|
- sizeof(Code)
|
||||||
- sizeof(StringCached)
|
- sizeof(StrCached)
|
||||||
- sizeof(Code) * 2
|
- sizeof(Code) * 2
|
||||||
- sizeof(Token*)
|
- sizeof(Token*)
|
||||||
- sizeof(Code)
|
- sizeof(Code)
|
||||||
@ -379,6 +371,7 @@ int AST_ArrSpecs_Cap =
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Simple AST POD with functionality to seralize into C++ syntax.
|
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
|
struct AST
|
||||||
{
|
{
|
||||||
@ -386,8 +379,8 @@ struct AST
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
Code InlineCmt; // Class, Constructor, Destructor, Enum, Friend, Functon, Operator, OpCast, Struct, Typedef, Using, Variable
|
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 Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable // TODO(Ed): Parameters can have attributes
|
||||||
Code Specs; // Destructor, Function, Operator, Typename, Variable
|
Code Specs; // Class, Destructor, Function, Operator, Struct, Typename, Variable
|
||||||
union {
|
union {
|
||||||
Code InitializerList; // Constructor
|
Code InitializerList; // Constructor
|
||||||
Code ParentType; // Class, Struct, ParentType->Next has a possible list of interfaces.
|
Code ParentType; // Class, Struct, ParentType->Next has a possible list of interfaces.
|
||||||
@ -398,28 +391,28 @@ struct AST
|
|||||||
union {
|
union {
|
||||||
Code Macro; // Parameter
|
Code Macro; // Parameter
|
||||||
Code BitfieldSize; // Variable (Class/Struct Data Member)
|
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
|
Code UnderlyingTypeMacro; // Enum
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
Code ArrExpr; // Typename
|
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 Declaration; // Friend, Template
|
||||||
Code Value; // Parameter, Variable
|
Code Value; // Parameter, Variable
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
Code NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
|
Code NextVar; // Variable
|
||||||
Code SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
|
Code SuffixSpecs; // Typename, Function (Thanks Unreal)
|
||||||
Code PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
|
Code PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Content; // Attributes, Comment, Execution, Include
|
StrCached Content; // Attributes, Comment, Execution, Include
|
||||||
struct {
|
struct {
|
||||||
Specifier ArrSpecs[AST_ArrSpecs_Cap]; // Specifiers
|
Specifier ArrSpecs[AST_ArrSpecs_Cap]; // Specifiers
|
||||||
Code NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
|
Code NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
union {
|
union {
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Front;
|
Code Front;
|
||||||
@ -429,7 +422,7 @@ struct AST
|
|||||||
Code Next;
|
Code Next;
|
||||||
Code Back;
|
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;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
// CodeFlag CodeFlags;
|
// CodeFlag CodeFlags;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
# define GEN_AST_BODY_CLASS_UNALLOWED_TYPES \
|
// These macros are used in the swtich cases within ast.cpp, inteface.upfront.cpp, parser.cpp
|
||||||
|
|
||||||
|
# define GEN_AST_BODY_CLASS_UNALLOWED_TYPES_CASES \
|
||||||
case CT_PlatformAttributes: \
|
case CT_PlatformAttributes: \
|
||||||
case CT_Class_Body: \
|
case CT_Class_Body: \
|
||||||
case CT_Enum_Body: \
|
case CT_Enum_Body: \
|
||||||
@ -13,10 +15,10 @@
|
|||||||
case CT_Parameters: \
|
case CT_Parameters: \
|
||||||
case CT_Specifiers: \
|
case CT_Specifiers: \
|
||||||
case CT_Struct_Body: \
|
case CT_Struct_Body: \
|
||||||
case CT_Typename:
|
case CT_Typename
|
||||||
# define GEN_AST_BODY_STRUCT_UNALLOWED_TYPES GEN_AST_BODY_CLASS_UNALLOWED_TYPES
|
# define GEN_AST_BODY_STRUCT_UNALLOWED_TYPES_CASES GEN_AST_BODY_CLASS_UNALLOWED_TYPES_CASES
|
||||||
|
|
||||||
# define GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES \
|
# define GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES_CASES \
|
||||||
case CT_Access_Public: \
|
case CT_Access_Public: \
|
||||||
case CT_Access_Protected: \
|
case CT_Access_Protected: \
|
||||||
case CT_Access_Private: \
|
case CT_Access_Private: \
|
||||||
@ -37,9 +39,9 @@
|
|||||||
case CT_Parameters: \
|
case CT_Parameters: \
|
||||||
case CT_Specifiers: \
|
case CT_Specifiers: \
|
||||||
case CT_Struct_Body: \
|
case CT_Struct_Body: \
|
||||||
case CT_Typename:
|
case CT_Typename
|
||||||
|
|
||||||
# define GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES \
|
# define GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES_CASES \
|
||||||
case CT_Access_Public: \
|
case CT_Access_Public: \
|
||||||
case CT_Access_Protected: \
|
case CT_Access_Protected: \
|
||||||
case CT_Access_Private: \
|
case CT_Access_Private: \
|
||||||
@ -55,11 +57,11 @@
|
|||||||
case CT_Parameters: \
|
case CT_Parameters: \
|
||||||
case CT_Specifiers: \
|
case CT_Specifiers: \
|
||||||
case CT_Struct_Body: \
|
case CT_Struct_Body: \
|
||||||
case CT_Typename:
|
case CT_Typename
|
||||||
# define GEN_AST_BODY_EXPORT_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
|
# define GEN_AST_BODY_EXPORT_UNALLOWED_TYPES_CASES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES_CASES
|
||||||
# define GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
|
# define GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES_CASES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES_CASES
|
||||||
|
|
||||||
# define GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES \
|
# define GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES_CASES \
|
||||||
case CT_Access_Public: \
|
case CT_Access_Public: \
|
||||||
case CT_Access_Protected: \
|
case CT_Access_Protected: \
|
||||||
case CT_Access_Private: \
|
case CT_Access_Private: \
|
||||||
@ -75,4 +77,4 @@
|
|||||||
case CT_Parameters: \
|
case CT_Parameters: \
|
||||||
case CT_Specifiers: \
|
case CT_Specifiers: \
|
||||||
case CT_Struct_Body: \
|
case CT_Struct_Body: \
|
||||||
case CT_Typename:
|
case CT_Typename
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "code_types.hpp"
|
# include "code_types.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -29,26 +29,27 @@
|
|||||||
struct AST_Body
|
struct AST_Body
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Front;
|
Code Front;
|
||||||
Code Back;
|
Code Back;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Body) == sizeof(AST), "ERROR: AST_Body is not the same size as AST");
|
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
|
struct AST_Attributes
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
StringCached Content;
|
StrCached Content;
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -64,7 +65,7 @@ struct AST_BaseClass
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -79,9 +80,9 @@ struct AST_Comment
|
|||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
StringCached Content;
|
StrCached Content;
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -99,14 +100,14 @@ struct AST_Class
|
|||||||
{
|
{
|
||||||
CodeComment InlineCmt; // Only supported by forward declarations
|
CodeComment InlineCmt; // Only supported by forward declarations
|
||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
char _PAD_SPECS_ [ sizeof(AST*) ];
|
CodeSpecifiers Specs; // Support for final
|
||||||
CodeTypename ParentType;
|
CodeTypename ParentType;
|
||||||
char _PAD_PARAMS_[ sizeof(AST*) ];
|
char _PAD_PARAMS_[ sizeof(AST*) ];
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeTypename Prev;
|
CodeTypename Prev;
|
||||||
CodeTypename Next;
|
CodeTypename Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -129,10 +130,10 @@ struct AST_Constructor
|
|||||||
Code InitializerList;
|
Code InitializerList;
|
||||||
CodeParams Params;
|
CodeParams Params;
|
||||||
Code Body;
|
Code Body;
|
||||||
char _PAD_PROPERTIES_2_ [ sizeof(AST*) * 2 ];
|
char _PAD_PROPERTIES_2_ [ sizeof(AST*) * 2 ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -146,17 +147,39 @@ struct AST_Define
|
|||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
StringCached 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 ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
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;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
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
|
struct AST_Destructor
|
||||||
{
|
{
|
||||||
@ -169,10 +192,10 @@ struct AST_Destructor
|
|||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
char _PAD_PROPERTIES_2_ [ sizeof(AST*) * 2 ];
|
char _PAD_PROPERTIES_2_ [ sizeof(AST*) * 2 ];
|
||||||
Code Body;
|
Code Body;
|
||||||
char _PAD_PROPERTIES_3_ [ sizeof(AST*) ];
|
char _PAD_PROPERTIES_3_ [ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -194,17 +217,17 @@ struct AST_Enum
|
|||||||
CodeTypename UnderlyingType;
|
CodeTypename UnderlyingType;
|
||||||
Code UnderlyingTypeMacro;
|
Code UnderlyingTypeMacro;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
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");
|
static_assert( sizeof(AST_Enum) == sizeof(AST), "ERROR: AST_Enum is not the same size as AST");
|
||||||
|
|
||||||
@ -212,9 +235,9 @@ struct AST_Exec
|
|||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
StringCached Content;
|
StrCached Content;
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -224,13 +247,13 @@ struct AST_Exec
|
|||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Exec) == sizeof(AST), "ERROR: AST_Exec is not the same size as AST");
|
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
|
struct AST_Expr
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -245,7 +268,7 @@ struct AST_Expr_Assign
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -260,7 +283,7 @@ struct AST_Expr_Alignof
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -275,7 +298,7 @@ struct AST_Expr_Binary
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -290,7 +313,7 @@ struct AST_Expr_CStyleCast
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -305,7 +328,7 @@ struct AST_Expr_FunctionalCast
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -320,7 +343,7 @@ struct AST_Expr_CppCast
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -335,7 +358,7 @@ struct AST_Expr_ProcCall
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -350,7 +373,7 @@ struct AST_Expr_Decltype
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -365,7 +388,7 @@ struct AST_Expr_Comma
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -380,7 +403,7 @@ struct AST_Expr_AMS
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -395,7 +418,7 @@ struct AST_Expr_Sizeof
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -410,7 +433,7 @@ struct AST_Expr_Subscript
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -425,7 +448,7 @@ struct AST_Expr_Ternary
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -440,7 +463,7 @@ struct AST_Expr_UnaryPrefix
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -455,7 +478,7 @@ struct AST_Expr_UnaryPostfix
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -470,7 +493,7 @@ struct AST_Expr_Element
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -492,13 +515,13 @@ struct AST_Extern
|
|||||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
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");
|
static_assert( sizeof(AST_Extern) == sizeof(AST), "ERROR: AST_Extern is not the same size as AST");
|
||||||
|
|
||||||
@ -506,15 +529,15 @@ struct AST_Include
|
|||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
StringCached Content;
|
StrCached Content;
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Include) == sizeof(AST), "ERROR: AST_Include is not the same size as AST");
|
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;
|
CodeComment InlineCmt;
|
||||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ];
|
char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ];
|
||||||
Code Declaration;
|
Code Declaration;
|
||||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Friend) == sizeof(AST), "ERROR: AST_Friend is not the same size as AST");
|
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;
|
CodeAttributes Attributes;
|
||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
CodeTypename ReturnType;
|
CodeTypename ReturnType;
|
||||||
CodeParams Params;
|
CodeParams Params;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
char _PAD_PROPERTIES_ [ sizeof(AST*) ];
|
Code SuffixSpecs; // Thanks Unreal
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Fn) == sizeof(AST), "ERROR: AST_Fn is not the same size as AST");
|
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 {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
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");
|
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 {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
struct {
|
struct {
|
||||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 5 ];
|
char _PAD_PROPERTIES_[ sizeof(AST*) * 5 ];
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_NS) == sizeof(AST), "ERROR: AST_NS is not the same size as AST");
|
static_assert( sizeof(AST_NS) == sizeof(AST), "ERROR: AST_NS is not the same size as AST");
|
||||||
|
|
||||||
struct AST_Operator
|
struct AST_Operator
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
CodeComment InlineCmt;
|
CodeComment InlineCmt;
|
||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
CodeTypename ReturnType;
|
CodeTypename ReturnType;
|
||||||
CodeParams Params;
|
CodeParams Params;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
char _PAD_PROPERTIES_ [ sizeof(AST*) ];
|
char _PAD_PROPERTIES_ [ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
Operator Op;
|
Operator Op;
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Operator) == sizeof(AST), "ERROR: AST_Operator is not the same size as AST");
|
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*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
CodeComment InlineCmt;
|
CodeComment InlineCmt;
|
||||||
char _PAD_PROPERTIES_[ sizeof(AST*) ];
|
char _PAD_PROPERTIES_[ sizeof(AST*) ];
|
||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
CodeTypename ValueType;
|
CodeTypename ValueType;
|
||||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
char _PAD_PROPERTIES_3_[ sizeof(AST*) ];
|
char _PAD_PROPERTIES_3_[ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_OpCast) == sizeof(AST), "ERROR: AST_OpCast is not the same size as AST");
|
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*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
struct
|
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;
|
CodeTypename ValueType;
|
||||||
Code Macro;
|
Code Macro;
|
||||||
Code Value;
|
Code Value;
|
||||||
@ -668,14 +692,14 @@ struct AST_Params
|
|||||||
// char _PAD_PROPERTIES_3_[sizeof( AST* )];
|
// char _PAD_PROPERTIES_3_[sizeof( AST* )];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeParams Last;
|
CodeParams Last;
|
||||||
CodeParams Next;
|
CodeParams Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Params) == sizeof(AST), "ERROR: AST_Params is not the same size as AST");
|
static_assert( sizeof(AST_Params) == sizeof(AST), "ERROR: AST_Params is not the same size as AST");
|
||||||
|
|
||||||
@ -683,15 +707,15 @@ struct AST_Pragma
|
|||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
StringCached Content;
|
StrCached Content;
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Pragma) == sizeof(AST), "ERROR: AST_Pragma is not the same size as AST");
|
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 {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
StringCached Content;
|
StrCached Content;
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_PreprocessCond) == sizeof(AST), "ERROR: AST_PreprocessCond is not the same size as AST");
|
static_assert( sizeof(AST_PreprocessCond) == sizeof(AST), "ERROR: AST_PreprocessCond is not the same size as AST");
|
||||||
|
|
||||||
struct AST_Specifiers
|
struct AST_Specifiers
|
||||||
{
|
{
|
||||||
Specifier ArrSpecs[ AST_ArrSpecs_Cap ];
|
Specifier ArrSpecs[ AST_ArrSpecs_Cap ];
|
||||||
StringCached Name;
|
CodeSpecifiers NextSpecs;
|
||||||
CodeSpecifiers NextSpecs;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Specifiers) == sizeof(AST), "ERROR: AST_Specifier is not the same size as AST");
|
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
|
struct AST_Stmt
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -747,7 +771,7 @@ struct AST_Stmt_Break
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -762,7 +786,7 @@ struct AST_Stmt_Case
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -777,7 +801,7 @@ struct AST_Stmt_Continue
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -792,7 +816,7 @@ struct AST_Stmt_Decl
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -807,7 +831,7 @@ struct AST_Stmt_Do
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -822,7 +846,7 @@ struct AST_Stmt_Expr
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -837,7 +861,7 @@ struct AST_Stmt_Else
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -852,7 +876,7 @@ struct AST_Stmt_If
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -867,7 +891,7 @@ struct AST_Stmt_For
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -882,7 +906,7 @@ struct AST_Stmt_Goto
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -897,7 +921,7 @@ struct AST_Stmt_Label
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -912,7 +936,7 @@ struct AST_Stmt_Switch
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -927,7 +951,7 @@ struct AST_Stmt_While
|
|||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeExpr Prev;
|
CodeExpr Prev;
|
||||||
CodeExpr Next;
|
CodeExpr Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -946,14 +970,14 @@ struct AST_Struct
|
|||||||
{
|
{
|
||||||
CodeComment InlineCmt;
|
CodeComment InlineCmt;
|
||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
char _PAD_SPECS_ [ sizeof(AST*) ];
|
CodeSpecifiers Specs; // Support for final
|
||||||
CodeTypename ParentType;
|
CodeTypename ParentType;
|
||||||
char _PAD_PARAMS_[ sizeof(AST*) ];
|
char _PAD_PARAMS_[ sizeof(AST*) ];
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeTypename Prev;
|
CodeTypename Prev;
|
||||||
CodeTypename Next;
|
CodeTypename Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -970,20 +994,20 @@ struct AST_Template
|
|||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ];
|
char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ];
|
||||||
CodeParams Params;
|
CodeParams Params;
|
||||||
Code Declaration;
|
Code Declaration;
|
||||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Template) == sizeof(AST), "ERROR: AST_Template is not the same size as AST");
|
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
|
// CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||||
b32 IsParamPack;
|
b32 IsParamPack;
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Type) == sizeof(AST), "ERROR: AST_Type is not the same size as AST");
|
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
|
CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||||
struct {
|
struct {
|
||||||
b16 IsParamPack; // Used by typename to know if type should be considered a parameter pack.
|
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)
|
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
|
struct
|
||||||
{
|
{
|
||||||
CodeComment InlineCmt;
|
CodeComment InlineCmt;
|
||||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 2 ];
|
char _PAD_PROPERTIES_[ sizeof(AST*) * 2 ];
|
||||||
Code UnderlyingType;
|
Code UnderlyingType;
|
||||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) * 3 ];
|
char _PAD_PROPERTIES_2_[ sizeof(AST*) * 3 ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
@ -1077,19 +1101,19 @@ struct AST_Union
|
|||||||
{
|
{
|
||||||
char _PAD_INLINE_CMT_[ sizeof(AST*) ];
|
char _PAD_INLINE_CMT_[ sizeof(AST*) ];
|
||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 3 ];
|
char _PAD_PROPERTIES_[ sizeof(AST*) * 3 ];
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Union) == sizeof(AST), "ERROR: AST_Union is not the same size as AST");
|
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;
|
CodeComment InlineCmt;
|
||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
char _PAD_SPECS_ [ sizeof(AST*) ];
|
char _PAD_SPECS_ [ sizeof(AST*) ];
|
||||||
CodeTypename UnderlyingType;
|
CodeTypename UnderlyingType;
|
||||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 3 ];
|
char _PAD_PROPERTIES_[ sizeof(AST*) * 3 ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Using) == sizeof(AST), "ERROR: AST_Using is not the same size as AST");
|
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;
|
CodeTypename ValueType;
|
||||||
Code BitfieldSize;
|
Code BitfieldSize;
|
||||||
Code Value;
|
Code Value;
|
||||||
CodeVar NextVar;
|
CodeVar NextVar;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
s32 VarParenthesizedInit;
|
s32 VarParenthesizedInit;
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST");
|
static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST");
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
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
|
#pragma once
|
||||||
#include "components/types.hpp"
|
#include "components/types.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -7,14 +7,14 @@
|
|||||||
|
|
||||||
#pragma region generated code inline implementation
|
#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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,14 +23,14 @@ inline Code::operator bool()
|
|||||||
return ast != nullptr;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,14 +39,14 @@ inline CodeBody::operator bool()
|
|||||||
return ast != nullptr;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,27 +57,27 @@ inline CodeAttributes::operator bool()
|
|||||||
|
|
||||||
inline CodeAttributes::operator Code()
|
inline CodeAttributes::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Attributes* CodeAttributes::operator->()
|
inline AST_Attributes* CodeAttributes::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,27 +88,27 @@ inline CodeComment::operator bool()
|
|||||||
|
|
||||||
inline CodeComment::operator Code()
|
inline CodeComment::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Comment* CodeComment::operator->()
|
inline AST_Comment* CodeComment::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,27 +119,27 @@ inline CodeConstructor::operator bool()
|
|||||||
|
|
||||||
inline CodeConstructor::operator Code()
|
inline CodeConstructor::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Constructor* CodeConstructor::operator->()
|
inline AST_Constructor* CodeConstructor::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,14 +148,14 @@ inline CodeClass::operator bool()
|
|||||||
return ast != nullptr;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,27 +166,43 @@ inline CodeDefine::operator bool()
|
|||||||
|
|
||||||
inline CodeDefine::operator Code()
|
inline CodeDefine::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Define* CodeDefine::operator->()
|
inline AST_Define* CodeDefine::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,27 +213,27 @@ inline CodeDestructor::operator bool()
|
|||||||
|
|
||||||
inline CodeDestructor::operator Code()
|
inline CodeDestructor::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Destructor* CodeDestructor::operator->()
|
inline AST_Destructor* CodeDestructor::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,27 +244,27 @@ inline CodeEnum::operator bool()
|
|||||||
|
|
||||||
inline CodeEnum::operator Code()
|
inline CodeEnum::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Enum* CodeEnum::operator->()
|
inline AST_Enum* CodeEnum::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,27 +275,27 @@ inline CodeExec::operator bool()
|
|||||||
|
|
||||||
inline CodeExec::operator Code()
|
inline CodeExec::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Exec* CodeExec::operator->()
|
inline AST_Exec* CodeExec::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,27 +306,27 @@ inline CodeExtern::operator bool()
|
|||||||
|
|
||||||
inline CodeExtern::operator Code()
|
inline CodeExtern::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Extern* CodeExtern::operator->()
|
inline AST_Extern* CodeExtern::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,27 +337,27 @@ inline CodeFriend::operator bool()
|
|||||||
|
|
||||||
inline CodeFriend::operator Code()
|
inline CodeFriend::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Friend* CodeFriend::operator->()
|
inline AST_Friend* CodeFriend::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,27 +368,27 @@ inline CodeFn::operator bool()
|
|||||||
|
|
||||||
inline CodeFn::operator Code()
|
inline CodeFn::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Fn* CodeFn::operator->()
|
inline AST_Fn* CodeFn::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,27 +399,27 @@ inline CodeInclude::operator bool()
|
|||||||
|
|
||||||
inline CodeInclude::operator Code()
|
inline CodeInclude::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Include* CodeInclude::operator->()
|
inline AST_Include* CodeInclude::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,27 +430,27 @@ inline CodeModule::operator bool()
|
|||||||
|
|
||||||
inline CodeModule::operator Code()
|
inline CodeModule::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Module* CodeModule::operator->()
|
inline AST_Module* CodeModule::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,27 +461,27 @@ inline CodeNS::operator bool()
|
|||||||
|
|
||||||
inline CodeNS::operator Code()
|
inline CodeNS::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_NS* CodeNS::operator->()
|
inline AST_NS* CodeNS::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,27 +492,27 @@ inline CodeOperator::operator bool()
|
|||||||
|
|
||||||
inline CodeOperator::operator Code()
|
inline CodeOperator::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Operator* CodeOperator::operator->()
|
inline AST_Operator* CodeOperator::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,27 +523,27 @@ inline CodeOpCast::operator bool()
|
|||||||
|
|
||||||
inline CodeOpCast::operator Code()
|
inline CodeOpCast::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_OpCast* CodeOpCast::operator->()
|
inline AST_OpCast* CodeOpCast::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,14 +552,14 @@ inline CodeParams::operator bool()
|
|||||||
return ast != nullptr;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,27 +570,27 @@ inline CodePragma::operator bool()
|
|||||||
|
|
||||||
inline CodePragma::operator Code()
|
inline CodePragma::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Pragma* CodePragma::operator->()
|
inline AST_Pragma* CodePragma::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,27 +601,27 @@ inline CodePreprocessCond::operator bool()
|
|||||||
|
|
||||||
inline CodePreprocessCond::operator Code()
|
inline CodePreprocessCond::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_PreprocessCond* CodePreprocessCond::operator->()
|
inline AST_PreprocessCond* CodePreprocessCond::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,14 +630,14 @@ inline CodeSpecifiers::operator bool()
|
|||||||
return ast != nullptr;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,14 +646,14 @@ inline CodeStruct::operator bool()
|
|||||||
return ast != nullptr;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -648,27 +664,27 @@ inline CodeTemplate::operator bool()
|
|||||||
|
|
||||||
inline CodeTemplate::operator Code()
|
inline CodeTemplate::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Template* CodeTemplate::operator->()
|
inline AST_Template* CodeTemplate::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -679,27 +695,27 @@ inline CodeTypename::operator bool()
|
|||||||
|
|
||||||
inline CodeTypename::operator Code()
|
inline CodeTypename::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Typename* CodeTypename::operator->()
|
inline AST_Typename* CodeTypename::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,27 +726,27 @@ inline CodeTypedef::operator bool()
|
|||||||
|
|
||||||
inline CodeTypedef::operator Code()
|
inline CodeTypedef::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Typedef* CodeTypedef::operator->()
|
inline AST_Typedef* CodeTypedef::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,27 +757,27 @@ inline CodeUnion::operator bool()
|
|||||||
|
|
||||||
inline CodeUnion::operator Code()
|
inline CodeUnion::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Union* CodeUnion::operator->()
|
inline AST_Union* CodeUnion::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -772,27 +788,27 @@ inline CodeUsing::operator bool()
|
|||||||
|
|
||||||
inline CodeUsing::operator Code()
|
inline CodeUsing::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Using* CodeUsing::operator->()
|
inline AST_Using* CodeUsing::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
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->Parent = { nullptr };
|
||||||
}
|
}
|
||||||
ast = rcast( decltype( ast ), other.ast );
|
ast = rcast(decltype(ast), other.ast);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -803,14 +819,14 @@ inline CodeVar::operator bool()
|
|||||||
|
|
||||||
inline CodeVar::operator Code()
|
inline CodeVar::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast(Code*, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AST_Var* CodeVar::operator->()
|
inline AST_Var* CodeVar::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if (ast == nullptr)
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure("Attempt to dereference a nullptr!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
return ast;
|
||||||
@ -851,6 +867,11 @@ forceinline Code::operator CodeDefine() const
|
|||||||
return { (AST_Define*)ast };
|
return { (AST_Define*)ast };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forceinline Code::operator CodeDefineParams() const
|
||||||
|
{
|
||||||
|
return { (AST_DefineParams*)ast };
|
||||||
|
}
|
||||||
|
|
||||||
forceinline Code::operator CodeDestructor() const
|
forceinline Code::operator CodeDestructor() const
|
||||||
{
|
{
|
||||||
return { (AST_Destructor*)ast };
|
return { (AST_Destructor*)ast };
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "components/types.hpp"
|
#include "components/types.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -46,6 +46,7 @@ enum CodeType : u32
|
|||||||
CT_Operator_Cast,
|
CT_Operator_Cast,
|
||||||
CT_Operator_Cast_Fwd,
|
CT_Operator_Cast_Fwd,
|
||||||
CT_Parameters,
|
CT_Parameters,
|
||||||
|
CT_Parameters_Define,
|
||||||
CT_Preprocess_Define,
|
CT_Preprocess_Define,
|
||||||
CT_Preprocess_Include,
|
CT_Preprocess_Include,
|
||||||
CT_Preprocess_If,
|
CT_Preprocess_If,
|
||||||
@ -72,148 +73,150 @@ enum CodeType : u32
|
|||||||
CT_UnderlyingType = GEN_U32_MAX
|
CT_UnderlyingType = GEN_U32_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
inline StrC codetype_to_str( CodeType type )
|
inline Str codetype_to_str(CodeType type)
|
||||||
{
|
{
|
||||||
local_persist StrC lookup[61] = {
|
local_persist Str lookup[] = {
|
||||||
{ sizeof( "Invalid" ), "Invalid" },
|
{ "Invalid", sizeof("Invalid") - 1 },
|
||||||
{ sizeof( "Untyped" ), "Untyped" },
|
{ "Untyped", sizeof("Untyped") - 1 },
|
||||||
{ sizeof( "NewLine" ), "NewLine" },
|
{ "NewLine", sizeof("NewLine") - 1 },
|
||||||
{ sizeof( "Comment" ), "Comment" },
|
{ "Comment", sizeof("Comment") - 1 },
|
||||||
{ sizeof( "Access_Private" ), "Access_Private" },
|
{ "Access_Private", sizeof("Access_Private") - 1 },
|
||||||
{ sizeof( "Access_Protected" ), "Access_Protected" },
|
{ "Access_Protected", sizeof("Access_Protected") - 1 },
|
||||||
{ sizeof( "Access_Public" ), "Access_Public" },
|
{ "Access_Public", sizeof("Access_Public") - 1 },
|
||||||
{ sizeof( "PlatformAttributes" ), "PlatformAttributes" },
|
{ "PlatformAttributes", sizeof("PlatformAttributes") - 1 },
|
||||||
{ sizeof( "Class" ), "Class" },
|
{ "Class", sizeof("Class") - 1 },
|
||||||
{ sizeof( "Class_Fwd" ), "Class_Fwd" },
|
{ "Class_Fwd", sizeof("Class_Fwd") - 1 },
|
||||||
{ sizeof( "Class_Body" ), "Class_Body" },
|
{ "Class_Body", sizeof("Class_Body") - 1 },
|
||||||
{ sizeof( "Constructor" ), "Constructor" },
|
{ "Constructor", sizeof("Constructor") - 1 },
|
||||||
{ sizeof( "Constructor_Fwd" ), "Constructor_Fwd" },
|
{ "Constructor_Fwd", sizeof("Constructor_Fwd") - 1 },
|
||||||
{ sizeof( "Destructor" ), "Destructor" },
|
{ "Destructor", sizeof("Destructor") - 1 },
|
||||||
{ sizeof( "Destructor_Fwd" ), "Destructor_Fwd" },
|
{ "Destructor_Fwd", sizeof("Destructor_Fwd") - 1 },
|
||||||
{ sizeof( "Enum" ), "Enum" },
|
{ "Enum", sizeof("Enum") - 1 },
|
||||||
{ sizeof( "Enum_Fwd" ), "Enum_Fwd" },
|
{ "Enum_Fwd", sizeof("Enum_Fwd") - 1 },
|
||||||
{ sizeof( "Enum_Body" ), "Enum_Body" },
|
{ "Enum_Body", sizeof("Enum_Body") - 1 },
|
||||||
{ sizeof( "Enum_Class" ), "Enum_Class" },
|
{ "Enum_Class", sizeof("Enum_Class") - 1 },
|
||||||
{ sizeof( "Enum_Class_Fwd" ), "Enum_Class_Fwd" },
|
{ "Enum_Class_Fwd", sizeof("Enum_Class_Fwd") - 1 },
|
||||||
{ sizeof( "Execution" ), "Execution" },
|
{ "Execution", sizeof("Execution") - 1 },
|
||||||
{ sizeof( "Export_Body" ), "Export_Body" },
|
{ "Export_Body", sizeof("Export_Body") - 1 },
|
||||||
{ sizeof( "Extern_Linkage" ), "Extern_Linkage" },
|
{ "Extern_Linkage", sizeof("Extern_Linkage") - 1 },
|
||||||
{ sizeof( "Extern_Linkage_Body" ), "Extern_Linkage_Body" },
|
{ "Extern_Linkage_Body", sizeof("Extern_Linkage_Body") - 1 },
|
||||||
{ sizeof( "Friend" ), "Friend" },
|
{ "Friend", sizeof("Friend") - 1 },
|
||||||
{ sizeof( "Function" ), "Function" },
|
{ "Function", sizeof("Function") - 1 },
|
||||||
{ sizeof( "Function_Fwd" ), "Function_Fwd" },
|
{ "Function_Fwd", sizeof("Function_Fwd") - 1 },
|
||||||
{ sizeof( "Function_Body" ), "Function_Body" },
|
{ "Function_Body", sizeof("Function_Body") - 1 },
|
||||||
{ sizeof( "Global_Body" ), "Global_Body" },
|
{ "Global_Body", sizeof("Global_Body") - 1 },
|
||||||
{ sizeof( "Module" ), "Module" },
|
{ "Module", sizeof("Module") - 1 },
|
||||||
{ sizeof( "Namespace" ), "Namespace" },
|
{ "Namespace", sizeof("Namespace") - 1 },
|
||||||
{ sizeof( "Namespace_Body" ), "Namespace_Body" },
|
{ "Namespace_Body", sizeof("Namespace_Body") - 1 },
|
||||||
{ sizeof( "Operator" ), "Operator" },
|
{ "Operator", sizeof("Operator") - 1 },
|
||||||
{ sizeof( "Operator_Fwd" ), "Operator_Fwd" },
|
{ "Operator_Fwd", sizeof("Operator_Fwd") - 1 },
|
||||||
{ sizeof( "Operator_Member" ), "Operator_Member" },
|
{ "Operator_Member", sizeof("Operator_Member") - 1 },
|
||||||
{ sizeof( "Operator_Member_Fwd" ), "Operator_Member_Fwd" },
|
{ "Operator_Member_Fwd", sizeof("Operator_Member_Fwd") - 1 },
|
||||||
{ sizeof( "Operator_Cast" ), "Operator_Cast" },
|
{ "Operator_Cast", sizeof("Operator_Cast") - 1 },
|
||||||
{ sizeof( "Operator_Cast_Fwd" ), "Operator_Cast_Fwd" },
|
{ "Operator_Cast_Fwd", sizeof("Operator_Cast_Fwd") - 1 },
|
||||||
{ sizeof( "Parameters" ), "Parameters" },
|
{ "Parameters", sizeof("Parameters") - 1 },
|
||||||
{ sizeof( "Preprocess_Define" ), "Preprocess_Define" },
|
{ "Parameters_Define", sizeof("Parameters_Define") - 1 },
|
||||||
{ sizeof( "Preprocess_Include" ), "Preprocess_Include" },
|
{ "Preprocess_Define", sizeof("Preprocess_Define") - 1 },
|
||||||
{ sizeof( "Preprocess_If" ), "Preprocess_If" },
|
{ "Preprocess_Include", sizeof("Preprocess_Include") - 1 },
|
||||||
{ sizeof( "Preprocess_IfDef" ), "Preprocess_IfDef" },
|
{ "Preprocess_If", sizeof("Preprocess_If") - 1 },
|
||||||
{ sizeof( "Preprocess_IfNotDef" ), "Preprocess_IfNotDef" },
|
{ "Preprocess_IfDef", sizeof("Preprocess_IfDef") - 1 },
|
||||||
{ sizeof( "Preprocess_ElIf" ), "Preprocess_ElIf" },
|
{ "Preprocess_IfNotDef", sizeof("Preprocess_IfNotDef") - 1 },
|
||||||
{ sizeof( "Preprocess_Else" ), "Preprocess_Else" },
|
{ "Preprocess_ElIf", sizeof("Preprocess_ElIf") - 1 },
|
||||||
{ sizeof( "Preprocess_EndIf" ), "Preprocess_EndIf" },
|
{ "Preprocess_Else", sizeof("Preprocess_Else") - 1 },
|
||||||
{ sizeof( "Preprocess_Pragma" ), "Preprocess_Pragma" },
|
{ "Preprocess_EndIf", sizeof("Preprocess_EndIf") - 1 },
|
||||||
{ sizeof( "Specifiers" ), "Specifiers" },
|
{ "Preprocess_Pragma", sizeof("Preprocess_Pragma") - 1 },
|
||||||
{ sizeof( "Struct" ), "Struct" },
|
{ "Specifiers", sizeof("Specifiers") - 1 },
|
||||||
{ sizeof( "Struct_Fwd" ), "Struct_Fwd" },
|
{ "Struct", sizeof("Struct") - 1 },
|
||||||
{ sizeof( "Struct_Body" ), "Struct_Body" },
|
{ "Struct_Fwd", sizeof("Struct_Fwd") - 1 },
|
||||||
{ sizeof( "Template" ), "Template" },
|
{ "Struct_Body", sizeof("Struct_Body") - 1 },
|
||||||
{ sizeof( "Typedef" ), "Typedef" },
|
{ "Template", sizeof("Template") - 1 },
|
||||||
{ sizeof( "Typename" ), "Typename" },
|
{ "Typedef", sizeof("Typedef") - 1 },
|
||||||
{ sizeof( "Union" ), "Union" },
|
{ "Typename", sizeof("Typename") - 1 },
|
||||||
{ sizeof( "Union_Fwd" ), "Union_Fwd" },
|
{ "Union", sizeof("Union") - 1 },
|
||||||
{ sizeof( "Union_Body" ), "Union_Body" },
|
{ "Union_Fwd", sizeof("Union_Fwd") - 1 },
|
||||||
{ sizeof( "Using" ), "Using" },
|
{ "Union_Body", sizeof("Union_Body") - 1 },
|
||||||
{ sizeof( "Using_Namespace" ), "Using_Namespace" },
|
{ "Using", sizeof("Using") - 1 },
|
||||||
{ sizeof( "Variable" ), "Variable" },
|
{ "Using_Namespace", sizeof("Using_Namespace") - 1 },
|
||||||
|
{ "Variable", sizeof("Variable") - 1 },
|
||||||
};
|
};
|
||||||
return lookup[type];
|
return lookup[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline StrC codetype_to_keyword_str( CodeType type )
|
inline Str codetype_to_keyword_str(CodeType type)
|
||||||
{
|
{
|
||||||
local_persist StrC lookup[61] = {
|
local_persist Str lookup[] = {
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "//" ) - 1, "//" },
|
{ "//", sizeof("//") - 1 },
|
||||||
{ sizeof( "private" ) - 1, "private" },
|
{ "private", sizeof("private") - 1 },
|
||||||
{ sizeof( "protected" ) - 1, "protected" },
|
{ "protected", sizeof("protected") - 1 },
|
||||||
{ sizeof( "public" ) - 1, "public" },
|
{ "public", sizeof("public") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "class" ) - 1, "class" },
|
{ "class", sizeof("class") - 1 },
|
||||||
{ sizeof( "clsss" ) - 1, "clsss" },
|
{ "clsss", sizeof("clsss") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "enum" ) - 1, "enum" },
|
{ "enum", sizeof("enum") - 1 },
|
||||||
{ sizeof( "enum" ) - 1, "enum" },
|
{ "enum", sizeof("enum") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "enum class" ) - 1, "enum class" },
|
{ "enum class", sizeof("enum class") - 1 },
|
||||||
{ sizeof( "enum class" ) - 1, "enum class" },
|
{ "enum class", sizeof("enum class") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "extern" ) - 1, "extern" },
|
{ "extern", sizeof("extern") - 1 },
|
||||||
{ sizeof( "extern" ) - 1, "extern" },
|
{ "extern", sizeof("extern") - 1 },
|
||||||
{ sizeof( "friend" ) - 1, "friend" },
|
{ "friend", sizeof("friend") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "module" ) - 1, "module" },
|
{ "module", sizeof("module") - 1 },
|
||||||
{ sizeof( "namespace" ) - 1, "namespace" },
|
{ "namespace", sizeof("namespace") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "operator" ) - 1, "operator" },
|
{ "operator", sizeof("operator") - 1 },
|
||||||
{ sizeof( "operator" ) - 1, "operator" },
|
{ "operator", sizeof("operator") - 1 },
|
||||||
{ sizeof( "operator" ) - 1, "operator" },
|
{ "operator", sizeof("operator") - 1 },
|
||||||
{ sizeof( "operator" ) - 1, "operator" },
|
{ "operator", sizeof("operator") - 1 },
|
||||||
{ sizeof( "operator" ) - 1, "operator" },
|
{ "operator", sizeof("operator") - 1 },
|
||||||
{ sizeof( "operator" ) - 1, "operator" },
|
{ "operator", sizeof("operator") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "define" ) - 1, "define" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "include" ) - 1, "include" },
|
{ "define", sizeof("define") - 1 },
|
||||||
{ sizeof( "if" ) - 1, "if" },
|
{ "include", sizeof("include") - 1 },
|
||||||
{ sizeof( "ifdef" ) - 1, "ifdef" },
|
{ "if", sizeof("if") - 1 },
|
||||||
{ sizeof( "ifndef" ) - 1, "ifndef" },
|
{ "ifdef", sizeof("ifdef") - 1 },
|
||||||
{ sizeof( "elif" ) - 1, "elif" },
|
{ "ifndef", sizeof("ifndef") - 1 },
|
||||||
{ sizeof( "else" ) - 1, "else" },
|
{ "elif", sizeof("elif") - 1 },
|
||||||
{ sizeof( "endif" ) - 1, "endif" },
|
{ "else", sizeof("else") - 1 },
|
||||||
{ sizeof( "pragma" ) - 1, "pragma" },
|
{ "endif", sizeof("endif") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "pragma", sizeof("pragma") - 1 },
|
||||||
{ sizeof( "struct" ) - 1, "struct" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "struct" ) - 1, "struct" },
|
{ "struct", sizeof("struct") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "struct", sizeof("struct") - 1 },
|
||||||
{ sizeof( "template" ) - 1, "template" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "typedef" ) - 1, "typedef" },
|
{ "template", sizeof("template") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "typedef", sizeof("typedef") - 1 },
|
||||||
{ sizeof( "union" ) - 1, "union" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "union" ) - 1, "union" },
|
{ "union", sizeof("union") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "union", sizeof("union") - 1 },
|
||||||
{ sizeof( "using" ) - 1, "using" },
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
{ sizeof( "using namespace" ) - 1, "using namespace" },
|
{ "using", sizeof("using") - 1 },
|
||||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
{ "using namespace", sizeof("using namespace") - 1 },
|
||||||
|
{ "__NA__", sizeof("__NA__") - 1 },
|
||||||
};
|
};
|
||||||
return lookup[type];
|
return lookup[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline StrC to_str( CodeType type )
|
forceinline Str to_str(CodeType type)
|
||||||
{
|
{
|
||||||
return codetype_to_str( type );
|
return codetype_to_str(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline StrC 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
|
#pragma once
|
||||||
#include "components/types.hpp"
|
#include "components/types.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -58,61 +58,61 @@ enum Operator : u32
|
|||||||
Op_UnderlyingType = 0xffffffffu
|
Op_UnderlyingType = 0xffffffffu
|
||||||
};
|
};
|
||||||
|
|
||||||
inline StrC operator_to_str( Operator op )
|
inline Str operator_to_str(Operator op)
|
||||||
{
|
{
|
||||||
local_persist StrC lookup[47] = {
|
local_persist Str lookup[] = {
|
||||||
{ sizeof( "INVALID" ), "INVALID" },
|
{ "INVALID", sizeof("INVALID") - 1 },
|
||||||
{ sizeof( "=" ), "=" },
|
{ "=", sizeof("=") - 1 },
|
||||||
{ sizeof( "+=" ), "+=" },
|
{ "+=", sizeof("+=") - 1 },
|
||||||
{ sizeof( "-=" ), "-=" },
|
{ "-=", sizeof("-=") - 1 },
|
||||||
{ sizeof( "*=" ), "*=" },
|
{ "*=", sizeof("*=") - 1 },
|
||||||
{ sizeof( "/=" ), "/=" },
|
{ "/=", sizeof("/=") - 1 },
|
||||||
{ sizeof( "%=" ), "%=" },
|
{ "%=", sizeof("%=") - 1 },
|
||||||
{ sizeof( "&=" ), "&=" },
|
{ "&=", sizeof("&=") - 1 },
|
||||||
{ sizeof( "|=" ), "|=" },
|
{ "|=", sizeof("|=") - 1 },
|
||||||
{ sizeof( "^=" ), "^=" },
|
{ "^=", sizeof("^=") - 1 },
|
||||||
{ sizeof( "<<=" ), "<<=" },
|
{ "<<=", sizeof("<<=") - 1 },
|
||||||
{ sizeof( ">>=" ), ">>=" },
|
{ ">>=", sizeof(">>=") - 1 },
|
||||||
{ sizeof( "++" ), "++" },
|
{ "++", sizeof("++") - 1 },
|
||||||
{ sizeof( "--" ), "--" },
|
{ "--", sizeof("--") - 1 },
|
||||||
{ sizeof( "+" ), "+" },
|
{ "+", sizeof("+") - 1 },
|
||||||
{ sizeof( "-" ), "-" },
|
{ "-", sizeof("-") - 1 },
|
||||||
{ sizeof( "!" ), "!" },
|
{ "!", sizeof("!") - 1 },
|
||||||
{ sizeof( "+" ), "+" },
|
{ "+", sizeof("+") - 1 },
|
||||||
{ sizeof( "-" ), "-" },
|
{ "-", sizeof("-") - 1 },
|
||||||
{ sizeof( "*" ), "*" },
|
{ "*", sizeof("*") - 1 },
|
||||||
{ sizeof( "/" ), "/" },
|
{ "/", sizeof("/") - 1 },
|
||||||
{ sizeof( "%" ), "%" },
|
{ "%", sizeof("%") - 1 },
|
||||||
{ sizeof( "~" ), "~" },
|
{ "~", sizeof("~") - 1 },
|
||||||
{ sizeof( "&" ), "&" },
|
{ "&", sizeof("&") - 1 },
|
||||||
{ sizeof( "|" ), "|" },
|
{ "|", sizeof("|") - 1 },
|
||||||
{ sizeof( "^" ), "^" },
|
{ "^", sizeof("^") - 1 },
|
||||||
{ sizeof( "<<" ), "<<" },
|
{ "<<", sizeof("<<") - 1 },
|
||||||
{ sizeof( ">>" ), ">>" },
|
{ ">>", sizeof(">>") - 1 },
|
||||||
{ sizeof( "&&" ), "&&" },
|
{ "&&", sizeof("&&") - 1 },
|
||||||
{ sizeof( "||" ), "||" },
|
{ "||", sizeof("||") - 1 },
|
||||||
{ sizeof( "==" ), "==" },
|
{ "==", sizeof("==") - 1 },
|
||||||
{ sizeof( "!=" ), "!=" },
|
{ "!=", sizeof("!=") - 1 },
|
||||||
{ sizeof( "<" ), "<" },
|
{ "<", sizeof("<") - 1 },
|
||||||
{ sizeof( ">" ), ">" },
|
{ ">", sizeof(">") - 1 },
|
||||||
{ sizeof( "<=" ), "<=" },
|
{ "<=", sizeof("<=") - 1 },
|
||||||
{ sizeof( ">=" ), ">=" },
|
{ ">=", sizeof(">=") - 1 },
|
||||||
{ sizeof( "[]" ), "[]" },
|
{ "[]", sizeof("[]") - 1 },
|
||||||
{ sizeof( "*" ), "*" },
|
{ "*", sizeof("*") - 1 },
|
||||||
{ sizeof( "&" ), "&" },
|
{ "&", sizeof("&") - 1 },
|
||||||
{ sizeof( "->" ), "->" },
|
{ "->", sizeof("->") - 1 },
|
||||||
{ sizeof( "->*" ), "->*" },
|
{ "->*", sizeof("->*") - 1 },
|
||||||
{ sizeof( "()" ), "()" },
|
{ "()", sizeof("()") - 1 },
|
||||||
{ sizeof( "," ), "," },
|
{ ",", sizeof(",") - 1 },
|
||||||
{ sizeof( "new" ), "new" },
|
{ "new", sizeof("new") - 1 },
|
||||||
{ sizeof( "new[]" ), "new[]" },
|
{ "new[]", sizeof("new[]") - 1 },
|
||||||
{ sizeof( "delete" ), "delete" },
|
{ "delete", sizeof("delete") - 1 },
|
||||||
{ sizeof( "delete[]" ), "delete[]" },
|
{ "delete[]", sizeof("delete[]") - 1 },
|
||||||
};
|
};
|
||||||
return lookup[op];
|
return lookup[op];
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline StrC 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
|
#pragma once
|
||||||
#include "components/types.hpp"
|
#include "components/types.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -23,6 +23,7 @@ enum Specifier : u32
|
|||||||
Spec_Ptr,
|
Spec_Ptr,
|
||||||
Spec_Ref,
|
Spec_Ref,
|
||||||
Spec_Register,
|
Spec_Register,
|
||||||
|
Spec_Restrict,
|
||||||
Spec_RValue,
|
Spec_RValue,
|
||||||
Spec_Static,
|
Spec_Static,
|
||||||
Spec_Thread_Local,
|
Spec_Thread_Local,
|
||||||
@ -32,77 +33,92 @@ enum Specifier : u32
|
|||||||
Spec_NoExceptions,
|
Spec_NoExceptions,
|
||||||
Spec_Override,
|
Spec_Override,
|
||||||
Spec_Pure,
|
Spec_Pure,
|
||||||
|
Spec_Delete,
|
||||||
Spec_Volatile,
|
Spec_Volatile,
|
||||||
Spec_NumSpecifiers,
|
Spec_NumSpecifiers,
|
||||||
Spec_UnderlyingType = 0xffffffffu
|
Spec_UnderlyingType = 0xffffffffu
|
||||||
};
|
};
|
||||||
|
|
||||||
inline StrC spec_to_str( Specifier type )
|
inline Str spec_to_str(Specifier type)
|
||||||
{
|
{
|
||||||
local_persist StrC lookup[26] = {
|
local_persist Str lookup[] = {
|
||||||
{ sizeof( "INVALID" ), "INVALID" },
|
{ "INVALID", sizeof("INVALID") - 1 },
|
||||||
{ sizeof( "consteval" ), "consteval" },
|
{ "consteval", sizeof("consteval") - 1 },
|
||||||
{ sizeof( "constexpr" ), "constexpr" },
|
{ "constexpr", sizeof("constexpr") - 1 },
|
||||||
{ sizeof( "constinit" ), "constinit" },
|
{ "constinit", sizeof("constinit") - 1 },
|
||||||
{ sizeof( "explicit" ), "explicit" },
|
{ "explicit", sizeof("explicit") - 1 },
|
||||||
{ sizeof( "extern" ), "extern" },
|
{ "extern", sizeof("extern") - 1 },
|
||||||
{ sizeof( "forceinline" ), "forceinline" },
|
{ "forceinline", sizeof("forceinline") - 1 },
|
||||||
{ sizeof( "global" ), "global" },
|
{ "global", sizeof("global") - 1 },
|
||||||
{ sizeof( "inline" ), "inline" },
|
{ "inline", sizeof("inline") - 1 },
|
||||||
{ sizeof( "internal" ), "internal" },
|
{ "internal", sizeof("internal") - 1 },
|
||||||
{ sizeof( "local_persist" ), "local_persist" },
|
{ "local_persist", sizeof("local_persist") - 1 },
|
||||||
{ sizeof( "mutable" ), "mutable" },
|
{ "mutable", sizeof("mutable") - 1 },
|
||||||
{ sizeof( "neverinline" ), "neverinline" },
|
{ "neverinline", sizeof("neverinline") - 1 },
|
||||||
{ sizeof( "*" ), "*" },
|
{ "*", sizeof("*") - 1 },
|
||||||
{ sizeof( "&" ), "&" },
|
{ "&", sizeof("&") - 1 },
|
||||||
{ sizeof( "register" ), "register" },
|
{ "register", sizeof("register") - 1 },
|
||||||
{ sizeof( "&&" ), "&&" },
|
{ "restrict", sizeof("restrict") - 1 },
|
||||||
{ sizeof( "static" ), "static" },
|
{ "&&", sizeof("&&") - 1 },
|
||||||
{ sizeof( "thread_local" ), "thread_local" },
|
{ "static", sizeof("static") - 1 },
|
||||||
{ sizeof( "virtual" ), "virtual" },
|
{ "thread_local", sizeof("thread_local") - 1 },
|
||||||
{ sizeof( "const" ), "const" },
|
{ "virtual", sizeof("virtual") - 1 },
|
||||||
{ sizeof( "final" ), "final" },
|
{ "const", sizeof("const") - 1 },
|
||||||
{ sizeof( "noexcept" ), "noexcept" },
|
{ "final", sizeof("final") - 1 },
|
||||||
{ sizeof( "override" ), "override" },
|
{ "noexcept", sizeof("noexcept") - 1 },
|
||||||
{ sizeof( "= 0" ), "= 0" },
|
{ "override", sizeof("override") - 1 },
|
||||||
{ sizeof( "volatile" ), "volatile" },
|
{ "= 0", sizeof("= 0") - 1 },
|
||||||
|
{ "= delete", sizeof("= delete") - 1 },
|
||||||
|
{ "volatile", sizeof("volatile") - 1 },
|
||||||
};
|
};
|
||||||
return lookup[type];
|
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 strc_to_specifier( StrC str )
|
inline Specifier str_to_specifier(Str str)
|
||||||
{
|
{
|
||||||
local_persist u32 keymap[Spec_NumSpecifiers];
|
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++)
|
||||||
{
|
{
|
||||||
StrC enum_str = spec_to_str( (Specifier)index );
|
Str enum_str = spec_to_str((Specifier)index);
|
||||||
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 );
|
keymap[index] = crc32(enum_str.Ptr, enum_str.Len);
|
||||||
}
|
}
|
||||||
do_once_end u32 hash = crc32( str.Ptr, str.Len );
|
do_once_end u32 hash = crc32(str.Ptr, str.Len);
|
||||||
for ( u32 index = 0; index < Spec_NumSpecifiers; index++ )
|
for (u32 index = 0; index < Spec_NumSpecifiers; index++)
|
||||||
{
|
{
|
||||||
if ( keymap[index] == hash )
|
if (keymap[index] == hash)
|
||||||
return (Specifier)index;
|
return (Specifier)index;
|
||||||
}
|
}
|
||||||
return Spec_Invalid;
|
return Spec_Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline StrC to_str( Specifier spec )
|
forceinline Str to_str(Specifier spec)
|
||||||
{
|
{
|
||||||
return spec_to_str( spec );
|
return spec_to_str(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline Specifier to_type( StrC str )
|
forceinline Specifier to_type(Str str)
|
||||||
{
|
{
|
||||||
return strc_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,235 +0,0 @@
|
|||||||
#ifdef GEN_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)
|
|
||||||
|
|
||||||
GEN_NS_PARSER_BEGIN
|
|
||||||
|
|
||||||
#define GEN_DEFINE_ATTRIBUTE_TOKENS Entry( Tok_Attribute_API_Export, "GEN_API_Export_Code" ) Entry( Tok_Attribute_API_Import, "GEN_API_Import_Code" )
|
|
||||||
|
|
||||||
enum TokType : u32
|
|
||||||
{
|
|
||||||
Tok_Invalid,
|
|
||||||
Tok_Access_Private,
|
|
||||||
Tok_Access_Protected,
|
|
||||||
Tok_Access_Public,
|
|
||||||
Tok_Access_MemberSymbol,
|
|
||||||
Tok_Access_StaticSymbol,
|
|
||||||
Tok_Ampersand,
|
|
||||||
Tok_Ampersand_DBL,
|
|
||||||
Tok_Assign_Classifer,
|
|
||||||
Tok_Attribute_Open,
|
|
||||||
Tok_Attribute_Close,
|
|
||||||
Tok_BraceCurly_Open,
|
|
||||||
Tok_BraceCurly_Close,
|
|
||||||
Tok_BraceSquare_Open,
|
|
||||||
Tok_BraceSquare_Close,
|
|
||||||
Tok_Capture_Start,
|
|
||||||
Tok_Capture_End,
|
|
||||||
Tok_Comment,
|
|
||||||
Tok_Comment_End,
|
|
||||||
Tok_Comment_Start,
|
|
||||||
Tok_Char,
|
|
||||||
Tok_Comma,
|
|
||||||
Tok_Decl_Class,
|
|
||||||
Tok_Decl_GNU_Attribute,
|
|
||||||
Tok_Decl_MSVC_Attribute,
|
|
||||||
Tok_Decl_Enum,
|
|
||||||
Tok_Decl_Extern_Linkage,
|
|
||||||
Tok_Decl_Friend,
|
|
||||||
Tok_Decl_Module,
|
|
||||||
Tok_Decl_Namespace,
|
|
||||||
Tok_Decl_Operator,
|
|
||||||
Tok_Decl_Struct,
|
|
||||||
Tok_Decl_Template,
|
|
||||||
Tok_Decl_Typedef,
|
|
||||||
Tok_Decl_Using,
|
|
||||||
Tok_Decl_Union,
|
|
||||||
Tok_Identifier,
|
|
||||||
Tok_Module_Import,
|
|
||||||
Tok_Module_Export,
|
|
||||||
Tok_NewLine,
|
|
||||||
Tok_Number,
|
|
||||||
Tok_Operator,
|
|
||||||
Tok_Preprocess_Hash,
|
|
||||||
Tok_Preprocess_Define,
|
|
||||||
Tok_Preprocess_If,
|
|
||||||
Tok_Preprocess_IfDef,
|
|
||||||
Tok_Preprocess_IfNotDef,
|
|
||||||
Tok_Preprocess_ElIf,
|
|
||||||
Tok_Preprocess_Else,
|
|
||||||
Tok_Preprocess_EndIf,
|
|
||||||
Tok_Preprocess_Include,
|
|
||||||
Tok_Preprocess_Pragma,
|
|
||||||
Tok_Preprocess_Content,
|
|
||||||
Tok_Preprocess_Macro,
|
|
||||||
Tok_Preprocess_Unsupported,
|
|
||||||
Tok_Spec_Alignas,
|
|
||||||
Tok_Spec_Const,
|
|
||||||
Tok_Spec_Consteval,
|
|
||||||
Tok_Spec_Constexpr,
|
|
||||||
Tok_Spec_Constinit,
|
|
||||||
Tok_Spec_Explicit,
|
|
||||||
Tok_Spec_Extern,
|
|
||||||
Tok_Spec_Final,
|
|
||||||
Tok_Spec_ForceInline,
|
|
||||||
Tok_Spec_Global,
|
|
||||||
Tok_Spec_Inline,
|
|
||||||
Tok_Spec_Internal_Linkage,
|
|
||||||
Tok_Spec_LocalPersist,
|
|
||||||
Tok_Spec_Mutable,
|
|
||||||
Tok_Spec_NeverInline,
|
|
||||||
Tok_Spec_Override,
|
|
||||||
Tok_Spec_Static,
|
|
||||||
Tok_Spec_ThreadLocal,
|
|
||||||
Tok_Spec_Volatile,
|
|
||||||
Tok_Spec_Virtual,
|
|
||||||
Tok_Star,
|
|
||||||
Tok_Statement_End,
|
|
||||||
Tok_StaticAssert,
|
|
||||||
Tok_String,
|
|
||||||
Tok_Type_Typename,
|
|
||||||
Tok_Type_Unsigned,
|
|
||||||
Tok_Type_Signed,
|
|
||||||
Tok_Type_Short,
|
|
||||||
Tok_Type_Long,
|
|
||||||
Tok_Type_bool,
|
|
||||||
Tok_Type_char,
|
|
||||||
Tok_Type_int,
|
|
||||||
Tok_Type_double,
|
|
||||||
Tok_Type_MS_int8,
|
|
||||||
Tok_Type_MS_int16,
|
|
||||||
Tok_Type_MS_int32,
|
|
||||||
Tok_Type_MS_int64,
|
|
||||||
Tok_Type_MS_W64,
|
|
||||||
Tok_Varadic_Argument,
|
|
||||||
Tok___Attributes_Start,
|
|
||||||
Tok_Attribute_API_Export,
|
|
||||||
Tok_Attribute_API_Import,
|
|
||||||
Tok_NumTokens
|
|
||||||
};
|
|
||||||
|
|
||||||
inline StrC toktype_to_str( TokType type )
|
|
||||||
{
|
|
||||||
local_persist StrC lookup[] = {
|
|
||||||
{ sizeof( "__invalid__" ), "__invalid__" },
|
|
||||||
{ sizeof( "private" ), "private" },
|
|
||||||
{ sizeof( "protected" ), "protected" },
|
|
||||||
{ sizeof( "public" ), "public" },
|
|
||||||
{ sizeof( "." ), "." },
|
|
||||||
{ sizeof( "::" ), "::" },
|
|
||||||
{ sizeof( "&" ), "&" },
|
|
||||||
{ sizeof( "&&" ), "&&" },
|
|
||||||
{ sizeof( ":" ), ":" },
|
|
||||||
{ sizeof( "[[" ), "[[" },
|
|
||||||
{ sizeof( "]]" ), "]]" },
|
|
||||||
{ sizeof( "{" ), "{" },
|
|
||||||
{ sizeof( "}" ), "}" },
|
|
||||||
{ sizeof( "[" ), "[" },
|
|
||||||
{ sizeof( "]" ), "]" },
|
|
||||||
{ sizeof( "(" ), "(" },
|
|
||||||
{ sizeof( ")" ), ")" },
|
|
||||||
{ sizeof( "__comment__" ), "__comment__" },
|
|
||||||
{ sizeof( "__comment_end__" ), "__comment_end__" },
|
|
||||||
{ sizeof( "__comment_start__" ), "__comment_start__" },
|
|
||||||
{ sizeof( "__character__" ), "__character__" },
|
|
||||||
{ sizeof( "," ), "," },
|
|
||||||
{ sizeof( "class" ), "class" },
|
|
||||||
{ sizeof( "__attribute__" ), "__attribute__" },
|
|
||||||
{ sizeof( "__declspec" ), "__declspec" },
|
|
||||||
{ sizeof( "enum" ), "enum" },
|
|
||||||
{ sizeof( "extern" ), "extern" },
|
|
||||||
{ sizeof( "friend" ), "friend" },
|
|
||||||
{ sizeof( "module" ), "module" },
|
|
||||||
{ sizeof( "namespace" ), "namespace" },
|
|
||||||
{ sizeof( "operator" ), "operator" },
|
|
||||||
{ sizeof( "struct" ), "struct" },
|
|
||||||
{ sizeof( "template" ), "template" },
|
|
||||||
{ sizeof( "typedef" ), "typedef" },
|
|
||||||
{ sizeof( "using" ), "using" },
|
|
||||||
{ sizeof( "union" ), "union" },
|
|
||||||
{ sizeof( "__identifier__" ), "__identifier__" },
|
|
||||||
{ sizeof( "import" ), "import" },
|
|
||||||
{ sizeof( "export" ), "export" },
|
|
||||||
{ sizeof( "__new_line__" ), "__new_line__" },
|
|
||||||
{ sizeof( "__number__" ), "__number__" },
|
|
||||||
{ sizeof( "__operator__" ), "__operator__" },
|
|
||||||
{ sizeof( "#" ), "#" },
|
|
||||||
{ sizeof( "define" ), "define" },
|
|
||||||
{ sizeof( "if" ), "if" },
|
|
||||||
{ sizeof( "ifdef" ), "ifdef" },
|
|
||||||
{ sizeof( "ifndef" ), "ifndef" },
|
|
||||||
{ sizeof( "elif" ), "elif" },
|
|
||||||
{ sizeof( "else" ), "else" },
|
|
||||||
{ sizeof( "endif" ), "endif" },
|
|
||||||
{ sizeof( "include" ), "include" },
|
|
||||||
{ sizeof( "pragma" ), "pragma" },
|
|
||||||
{ sizeof( "__macro_content__" ), "__macro_content__" },
|
|
||||||
{ sizeof( "__macro__" ), "__macro__" },
|
|
||||||
{ sizeof( "__unsupported__" ), "__unsupported__" },
|
|
||||||
{ sizeof( "alignas" ), "alignas" },
|
|
||||||
{ sizeof( "const" ), "const" },
|
|
||||||
{ sizeof( "consteval" ), "consteval" },
|
|
||||||
{ sizeof( "constexpr" ), "constexpr" },
|
|
||||||
{ sizeof( "constinit" ), "constinit" },
|
|
||||||
{ sizeof( "explicit" ), "explicit" },
|
|
||||||
{ sizeof( "extern" ), "extern" },
|
|
||||||
{ sizeof( "final" ), "final" },
|
|
||||||
{ sizeof( "forceinline" ), "forceinline" },
|
|
||||||
{ sizeof( "global" ), "global" },
|
|
||||||
{ sizeof( "inline" ), "inline" },
|
|
||||||
{ sizeof( "internal" ), "internal" },
|
|
||||||
{ sizeof( "local_persist" ), "local_persist" },
|
|
||||||
{ sizeof( "mutable" ), "mutable" },
|
|
||||||
{ sizeof( "neverinline" ), "neverinline" },
|
|
||||||
{ sizeof( "override" ), "override" },
|
|
||||||
{ sizeof( "static" ), "static" },
|
|
||||||
{ sizeof( "thread_local" ), "thread_local" },
|
|
||||||
{ sizeof( "volatile" ), "volatile" },
|
|
||||||
{ sizeof( "virtual" ), "virtual" },
|
|
||||||
{ sizeof( "*" ), "*" },
|
|
||||||
{ sizeof( ";" ), ";" },
|
|
||||||
{ sizeof( "static_assert" ), "static_assert" },
|
|
||||||
{ sizeof( "__string__" ), "__string__" },
|
|
||||||
{ sizeof( "typename" ), "typename" },
|
|
||||||
{ sizeof( "unsigned" ), "unsigned" },
|
|
||||||
{ sizeof( "signed" ), "signed" },
|
|
||||||
{ sizeof( "short" ), "short" },
|
|
||||||
{ sizeof( "long" ), "long" },
|
|
||||||
{ sizeof( "bool" ), "bool" },
|
|
||||||
{ sizeof( "char" ), "char" },
|
|
||||||
{ sizeof( "int" ), "int" },
|
|
||||||
{ sizeof( "double" ), "double" },
|
|
||||||
{ sizeof( "__int8" ), "__int8" },
|
|
||||||
{ sizeof( "__int16" ), "__int16" },
|
|
||||||
{ sizeof( "__int32" ), "__int32" },
|
|
||||||
{ sizeof( "__int64" ), "__int64" },
|
|
||||||
{ sizeof( "_W64" ), "_W64" },
|
|
||||||
{ sizeof( "..." ), "..." },
|
|
||||||
{ sizeof( "__attrib_start__" ), "__attrib_start__" },
|
|
||||||
{ sizeof( "GEN_API_Export_Code" ), "GEN_API_Export_Code" },
|
|
||||||
{ sizeof( "GEN_API_Import_Code" ), "GEN_API_Import_Code" },
|
|
||||||
};
|
|
||||||
return lookup[type];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline TokType strc_to_toktype( StrC str )
|
|
||||||
{
|
|
||||||
local_persist u32 keymap[Tok_NumTokens];
|
|
||||||
do_once_start for ( u32 index = 0; index < Tok_NumTokens; index++ )
|
|
||||||
{
|
|
||||||
StrC enum_str = toktype_to_str( (TokType)index );
|
|
||||||
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 );
|
|
||||||
}
|
|
||||||
do_once_end u32 hash = crc32( str.Ptr, str.Len );
|
|
||||||
for ( u32 index = 0; index < Tok_NumTokens; index++ )
|
|
||||||
{
|
|
||||||
if ( keymap[index] == hash )
|
|
||||||
return (TokType)index;
|
|
||||||
}
|
|
||||||
return Tok_Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
GEN_NS_PARSER_END
|
|
237
base/components/gen/etoktype.hpp
Normal file
237
base/components/gen/etoktype.hpp
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
#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")
|
||||||
|
|
||||||
|
enum TokType : u32
|
||||||
|
{
|
||||||
|
Tok_Invalid,
|
||||||
|
Tok_Access_Private,
|
||||||
|
Tok_Access_Protected,
|
||||||
|
Tok_Access_Public,
|
||||||
|
Tok_Access_MemberSymbol,
|
||||||
|
Tok_Access_StaticSymbol,
|
||||||
|
Tok_Ampersand,
|
||||||
|
Tok_Ampersand_DBL,
|
||||||
|
Tok_Assign_Classifer,
|
||||||
|
Tok_Attribute_Open,
|
||||||
|
Tok_Attribute_Close,
|
||||||
|
Tok_BraceCurly_Open,
|
||||||
|
Tok_BraceCurly_Close,
|
||||||
|
Tok_BraceSquare_Open,
|
||||||
|
Tok_BraceSquare_Close,
|
||||||
|
Tok_Paren_Open,
|
||||||
|
Tok_Paren_Close,
|
||||||
|
Tok_Comment,
|
||||||
|
Tok_Comment_End,
|
||||||
|
Tok_Comment_Start,
|
||||||
|
Tok_Char,
|
||||||
|
Tok_Comma,
|
||||||
|
Tok_Decl_Class,
|
||||||
|
Tok_Decl_GNU_Attribute,
|
||||||
|
Tok_Decl_MSVC_Attribute,
|
||||||
|
Tok_Decl_Enum,
|
||||||
|
Tok_Decl_Extern_Linkage,
|
||||||
|
Tok_Decl_Friend,
|
||||||
|
Tok_Decl_Module,
|
||||||
|
Tok_Decl_Namespace,
|
||||||
|
Tok_Decl_Operator,
|
||||||
|
Tok_Decl_Struct,
|
||||||
|
Tok_Decl_Template,
|
||||||
|
Tok_Decl_Typedef,
|
||||||
|
Tok_Decl_Using,
|
||||||
|
Tok_Decl_Union,
|
||||||
|
Tok_Identifier,
|
||||||
|
Tok_Module_Import,
|
||||||
|
Tok_Module_Export,
|
||||||
|
Tok_NewLine,
|
||||||
|
Tok_Number,
|
||||||
|
Tok_Operator,
|
||||||
|
Tok_Preprocess_Hash,
|
||||||
|
Tok_Preprocess_Define,
|
||||||
|
Tok_Preprocess_Define_Param,
|
||||||
|
Tok_Preprocess_If,
|
||||||
|
Tok_Preprocess_IfDef,
|
||||||
|
Tok_Preprocess_IfNotDef,
|
||||||
|
Tok_Preprocess_ElIf,
|
||||||
|
Tok_Preprocess_Else,
|
||||||
|
Tok_Preprocess_EndIf,
|
||||||
|
Tok_Preprocess_Include,
|
||||||
|
Tok_Preprocess_Pragma,
|
||||||
|
Tok_Preprocess_Content,
|
||||||
|
Tok_Preprocess_Macro_Expr,
|
||||||
|
Tok_Preprocess_Macro_Stmt,
|
||||||
|
Tok_Preprocess_Macro_Typename,
|
||||||
|
Tok_Preprocess_Unsupported,
|
||||||
|
Tok_Spec_Alignas,
|
||||||
|
Tok_Spec_Const,
|
||||||
|
Tok_Spec_Consteval,
|
||||||
|
Tok_Spec_Constexpr,
|
||||||
|
Tok_Spec_Constinit,
|
||||||
|
Tok_Spec_Explicit,
|
||||||
|
Tok_Spec_Extern,
|
||||||
|
Tok_Spec_Final,
|
||||||
|
Tok_Spec_ForceInline,
|
||||||
|
Tok_Spec_Global,
|
||||||
|
Tok_Spec_Inline,
|
||||||
|
Tok_Spec_Internal_Linkage,
|
||||||
|
Tok_Spec_LocalPersist,
|
||||||
|
Tok_Spec_Mutable,
|
||||||
|
Tok_Spec_NeverInline,
|
||||||
|
Tok_Spec_Override,
|
||||||
|
Tok_Spec_Restrict,
|
||||||
|
Tok_Spec_Static,
|
||||||
|
Tok_Spec_ThreadLocal,
|
||||||
|
Tok_Spec_Volatile,
|
||||||
|
Tok_Spec_Virtual,
|
||||||
|
Tok_Star,
|
||||||
|
Tok_Statement_End,
|
||||||
|
Tok_StaticAssert,
|
||||||
|
Tok_String,
|
||||||
|
Tok_Type_Typename,
|
||||||
|
Tok_Type_Unsigned,
|
||||||
|
Tok_Type_Signed,
|
||||||
|
Tok_Type_Short,
|
||||||
|
Tok_Type_Long,
|
||||||
|
Tok_Type_bool,
|
||||||
|
Tok_Type_char,
|
||||||
|
Tok_Type_int,
|
||||||
|
Tok_Type_double,
|
||||||
|
Tok_Type_MS_int8,
|
||||||
|
Tok_Type_MS_int16,
|
||||||
|
Tok_Type_MS_int32,
|
||||||
|
Tok_Type_MS_int64,
|
||||||
|
Tok_Type_MS_W64,
|
||||||
|
Tok_Varadic_Argument,
|
||||||
|
Tok___Attributes_Start,
|
||||||
|
Tok_Attribute_GEN_API,
|
||||||
|
Tok_NumTokens
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Str toktype_to_str(TokType type)
|
||||||
|
{
|
||||||
|
local_persist Str lookup[] = {
|
||||||
|
{ "__invalid__", sizeof("__invalid__") - 1 },
|
||||||
|
{ "private", sizeof("private") - 1 },
|
||||||
|
{ "protected", sizeof("protected") - 1 },
|
||||||
|
{ "public", sizeof("public") - 1 },
|
||||||
|
{ ".", sizeof(".") - 1 },
|
||||||
|
{ "::", sizeof("::") - 1 },
|
||||||
|
{ "&", sizeof("&") - 1 },
|
||||||
|
{ "&&", sizeof("&&") - 1 },
|
||||||
|
{ ":", sizeof(":") - 1 },
|
||||||
|
{ "[[", sizeof("[[") - 1 },
|
||||||
|
{ "]]", sizeof("]]") - 1 },
|
||||||
|
{ "{", sizeof("{") - 1 },
|
||||||
|
{ "}", sizeof("}") - 1 },
|
||||||
|
{ "[", sizeof("[") - 1 },
|
||||||
|
{ "]", sizeof("]") - 1 },
|
||||||
|
{ "(", sizeof("(") - 1 },
|
||||||
|
{ ")", sizeof(")") - 1 },
|
||||||
|
{ "__comment__", sizeof("__comment__") - 1 },
|
||||||
|
{ "__comment_end__", sizeof("__comment_end__") - 1 },
|
||||||
|
{ "__comment_start__", sizeof("__comment_start__") - 1 },
|
||||||
|
{ "__character__", sizeof("__character__") - 1 },
|
||||||
|
{ ",", sizeof(",") - 1 },
|
||||||
|
{ "class", sizeof("class") - 1 },
|
||||||
|
{ "__attribute__", sizeof("__attribute__") - 1 },
|
||||||
|
{ "__declspec", sizeof("__declspec") - 1 },
|
||||||
|
{ "enum", sizeof("enum") - 1 },
|
||||||
|
{ "extern", sizeof("extern") - 1 },
|
||||||
|
{ "friend", sizeof("friend") - 1 },
|
||||||
|
{ "module", sizeof("module") - 1 },
|
||||||
|
{ "namespace", sizeof("namespace") - 1 },
|
||||||
|
{ "operator", sizeof("operator") - 1 },
|
||||||
|
{ "struct", sizeof("struct") - 1 },
|
||||||
|
{ "template", sizeof("template") - 1 },
|
||||||
|
{ "typedef", sizeof("typedef") - 1 },
|
||||||
|
{ "using", sizeof("using") - 1 },
|
||||||
|
{ "union", sizeof("union") - 1 },
|
||||||
|
{ "__identifier__", sizeof("__identifier__") - 1 },
|
||||||
|
{ "import", sizeof("import") - 1 },
|
||||||
|
{ "export", sizeof("export") - 1 },
|
||||||
|
{ "__new_line__", sizeof("__new_line__") - 1 },
|
||||||
|
{ "__number__", sizeof("__number__") - 1 },
|
||||||
|
{ "__operator__", sizeof("__operator__") - 1 },
|
||||||
|
{ "#", sizeof("#") - 1 },
|
||||||
|
{ "define", sizeof("define") - 1 },
|
||||||
|
{ "__define_param__", sizeof("__define_param__") - 1 },
|
||||||
|
{ "if", sizeof("if") - 1 },
|
||||||
|
{ "ifdef", sizeof("ifdef") - 1 },
|
||||||
|
{ "ifndef", sizeof("ifndef") - 1 },
|
||||||
|
{ "elif", sizeof("elif") - 1 },
|
||||||
|
{ "else", sizeof("else") - 1 },
|
||||||
|
{ "endif", sizeof("endif") - 1 },
|
||||||
|
{ "include", sizeof("include") - 1 },
|
||||||
|
{ "pragma", sizeof("pragma") - 1 },
|
||||||
|
{ "__macro_content__", sizeof("__macro_content__") - 1 },
|
||||||
|
{ "__macro_expression__", sizeof("__macro_expression__") - 1 },
|
||||||
|
{ "__macro_statment__", sizeof("__macro_statment__") - 1 },
|
||||||
|
{ "__macro_typename__", sizeof("__macro_typename__") - 1 },
|
||||||
|
{ "__unsupported__", sizeof("__unsupported__") - 1 },
|
||||||
|
{ "alignas", sizeof("alignas") - 1 },
|
||||||
|
{ "const", sizeof("const") - 1 },
|
||||||
|
{ "consteval", sizeof("consteval") - 1 },
|
||||||
|
{ "constexpr", sizeof("constexpr") - 1 },
|
||||||
|
{ "constinit", sizeof("constinit") - 1 },
|
||||||
|
{ "explicit", sizeof("explicit") - 1 },
|
||||||
|
{ "extern", sizeof("extern") - 1 },
|
||||||
|
{ "final", sizeof("final") - 1 },
|
||||||
|
{ "forceinline", sizeof("forceinline") - 1 },
|
||||||
|
{ "global", sizeof("global") - 1 },
|
||||||
|
{ "inline", sizeof("inline") - 1 },
|
||||||
|
{ "internal", sizeof("internal") - 1 },
|
||||||
|
{ "local_persist", sizeof("local_persist") - 1 },
|
||||||
|
{ "mutable", sizeof("mutable") - 1 },
|
||||||
|
{ "neverinline", sizeof("neverinline") - 1 },
|
||||||
|
{ "override", sizeof("override") - 1 },
|
||||||
|
{ "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)
|
||||||
|
{
|
||||||
|
local_persist u32 keymap[Tok_NumTokens];
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
do_once_end u32 hash = crc32(str.Ptr, str.Len);
|
||||||
|
for (u32 index = 0; index < Tok_NumTokens; index++)
|
||||||
|
{
|
||||||
|
if (keymap[index] == hash)
|
||||||
|
return (TokType)index;
|
||||||
|
}
|
||||||
|
return Tok_Invalid;
|
||||||
|
}
|
@ -1,159 +0,0 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
|
||||||
#pragma once
|
|
||||||
#include "inlines.hpp"
|
|
||||||
#include "gen/ast_inlines.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#pragma region Constants
|
|
||||||
|
|
||||||
#ifndef GEN_GLOBAL_BUCKET_SIZE
|
|
||||||
# define GEN_GLOBAL_BUCKET_SIZE megabytes(8)
|
|
||||||
#endif
|
|
||||||
#ifndef GEN_CODEPOOL_NUM_BLOCKS
|
|
||||||
# define GEN_CODEPOOL_NUM_BLOCKS kilobytes(16)
|
|
||||||
#endif
|
|
||||||
#ifndef GEN_SIZE_PER_STRING_ARENA
|
|
||||||
# define GEN_SIZE_PER_STRING_ARENA megabytes(1)
|
|
||||||
#endif
|
|
||||||
#ifndef GEN_MAX_COMMENT_LINE_LENGTH
|
|
||||||
# define GEN_MAX_COMMENT_LINE_LENGTH 1024
|
|
||||||
#endif
|
|
||||||
#ifndef GEN_MAX_NAME_LENGTH
|
|
||||||
# define GEN_MAX_NAME_LENGTH 128
|
|
||||||
#endif
|
|
||||||
#ifndef GEN_MAX_UNTYPED_STR_LENGTH
|
|
||||||
# define GEN_MAX_UNTYPED_STR_LENGTH megabytes(1)
|
|
||||||
#endif
|
|
||||||
#ifndef TokenMap_FixedArena
|
|
||||||
# define TokenMap_FixedArena FixedArena_8KB
|
|
||||||
#endif
|
|
||||||
#ifndef GEN_LEX_ALLOCATOR_SIZE
|
|
||||||
# define GEN_LEX_ALLOCATOR_SIZE megabytes(4)
|
|
||||||
#endif
|
|
||||||
#ifndef GEN_BUILDER_STR_BUFFER_RESERVE
|
|
||||||
# define GEN_BUILDER_STR_BUFFER_RESERVE megabytes(2)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// These constexprs are used for allocation behavior of data structures
|
|
||||||
// or string handling while constructing or serializing.
|
|
||||||
// Change them to suit your needs.
|
|
||||||
|
|
||||||
constexpr s32 InitSize_DataArrays = 16;
|
|
||||||
|
|
||||||
// NOTE: This limits the maximum size of an allocation
|
|
||||||
// If you are generating a string larger than this, increase the size of the bucket here.
|
|
||||||
constexpr usize Global_BucketSize = GEN_GLOBAL_BUCKET_SIZE;
|
|
||||||
constexpr s32 CodePool_NumBlocks = GEN_CODEPOOL_NUM_BLOCKS;
|
|
||||||
constexpr s32 SizePer_StringArena = GEN_SIZE_PER_STRING_ARENA;
|
|
||||||
|
|
||||||
constexpr s32 MaxCommentLineLength = GEN_MAX_COMMENT_LINE_LENGTH;
|
|
||||||
constexpr s32 MaxNameLength = GEN_MAX_NAME_LENGTH;
|
|
||||||
constexpr s32 MaxUntypedStrLength = GEN_MAX_UNTYPED_STR_LENGTH;
|
|
||||||
// constexpr s32 TokenFmt_TokenMap_MemSize = GEN_TOKEN_FMT_TOKEN_MAP_MEM_SIZE;
|
|
||||||
constexpr s32 LexAllocator_Size = GEN_LEX_ALLOCATOR_SIZE;
|
|
||||||
constexpr s32 Builder_StrBufferReserve = GEN_BUILDER_STR_BUFFER_RESERVE;
|
|
||||||
|
|
||||||
extern StrC 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 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
|
|
||||||
|
|
||||||
// Used by the lexer to persistently treat all these identifiers as preprocessor defines.
|
|
||||||
// Populate with strings via gen::get_cached_string.
|
|
||||||
// Functional defines must have format: id( ;at minimum to indicate that the define is only valid with arguments.
|
|
||||||
extern Array(StringCached) PreprocessorDefines;
|
|
||||||
|
|
||||||
#ifdef GEN_EXPOSE_BACKEND
|
|
||||||
// Global allocator used for data with process lifetime.
|
|
||||||
extern AllocatorInfo GlobalAllocator;
|
|
||||||
extern Array(Arena) Global_AllocatorBuckets;
|
|
||||||
|
|
||||||
extern Array(Pool) CodePools;
|
|
||||||
extern Array(Arena) StringArenas;
|
|
||||||
|
|
||||||
extern StringTable StringCache;
|
|
||||||
|
|
||||||
extern Arena LexArena;
|
|
||||||
|
|
||||||
extern AllocatorInfo Allocator_DataArrays;
|
|
||||||
extern AllocatorInfo Allocator_CodePool;
|
|
||||||
extern AllocatorInfo Allocator_Lexer;
|
|
||||||
extern AllocatorInfo Allocator_StringArena;
|
|
||||||
extern AllocatorInfo Allocator_StringTable;
|
|
||||||
extern AllocatorInfo Allocator_TypeTable;
|
|
||||||
#endif
|
|
@ -15,7 +15,7 @@
|
|||||||
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
|
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
|
||||||
| | | | | __} | |
|
| | | | | __} | |
|
||||||
| l_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 |
|
! 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 |
|
! 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
|
#pragma once
|
||||||
#include "interface.hpp"
|
#include "interface.hpp"
|
||||||
#endif
|
#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
|
#pragma region Code
|
||||||
inline
|
inline
|
||||||
void code_append( Code self, Code other )
|
void code_append( Code self, Code other )
|
||||||
@ -74,7 +384,7 @@ bool code_is_valid(Code self)
|
|||||||
return self != nullptr && self->Type != CT_Invalid;
|
return self != nullptr && self->Type != CT_Invalid;
|
||||||
}
|
}
|
||||||
forceinline
|
forceinline
|
||||||
bool code_has_entries(AST* self)
|
bool code_has_entries(Code self)
|
||||||
{
|
{
|
||||||
GEN_ASSERT(self);
|
GEN_ASSERT(self);
|
||||||
return self->NumEntries > 0;
|
return self->NumEntries > 0;
|
||||||
@ -101,7 +411,7 @@ Code& Code::operator ++()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
forceinline
|
forceinline
|
||||||
StrC code_type_str(Code self)
|
Str code_type_str(Code self)
|
||||||
{
|
{
|
||||||
GEN_ASSERT(self != nullptr);
|
GEN_ASSERT(self != nullptr);
|
||||||
return codetype_to_str( self->Type );
|
return codetype_to_str( self->Type );
|
||||||
@ -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.
|
// 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 = cast(CodeTypename, possible_slot->Next);
|
||||||
}
|
}
|
||||||
|
|
||||||
possible_slot = type;
|
possible_slot->Next = cast(Code, type);
|
||||||
}
|
}
|
||||||
#pragma endregion CodeClass
|
#pragma endregion CodeClass
|
||||||
|
|
||||||
@ -257,6 +567,25 @@ CodeParams next_CodeParams(CodeParams params, CodeParams param_iter)
|
|||||||
}
|
}
|
||||||
#pragma endregion CodeParams
|
#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
|
#pragma region CodeSpecifiers
|
||||||
inline
|
inline
|
||||||
bool specifiers_append(CodeSpecifiers self, Specifier spec )
|
bool specifiers_append(CodeSpecifiers self, Specifier spec )
|
||||||
@ -277,7 +606,17 @@ bool specifiers_append(CodeSpecifiers self, Specifier spec )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
inline
|
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);
|
GEN_ASSERT(self != nullptr);
|
||||||
for ( s32 idx = 0; idx < self->NumEntries; idx++ ) {
|
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.
|
// 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 = cast(CodeTypename, possible_slot->Next);
|
||||||
}
|
}
|
||||||
|
|
||||||
possible_slot = type;
|
possible_slot->Next = cast(Code, type);
|
||||||
}
|
}
|
||||||
#pragma endregion Code
|
#pragma endregion Code
|
||||||
|
|
||||||
@ -397,7 +736,7 @@ CodeBody def_body( CodeType type )
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
StrC token_fmt_impl( ssize num, ... )
|
Str token_fmt_impl( ssize num, ... )
|
||||||
{
|
{
|
||||||
local_persist thread_local
|
local_persist thread_local
|
||||||
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
||||||
@ -408,7 +747,7 @@ StrC token_fmt_impl( ssize num, ... )
|
|||||||
ssize result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va);
|
ssize result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
StrC str = { result, buf };
|
Str str = { buf, result };
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
#pragma endregion Interface
|
#pragma endregion Interface
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "code_serialization.cpp"
|
#include "code_serialization.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GEN_NS_PARSER_BEGIN
|
|
||||||
internal void parser_init();
|
internal void parser_init();
|
||||||
internal void parser_deinit();
|
internal void parser_deinit();
|
||||||
GEN_NS_PARSER_END
|
|
||||||
|
|
||||||
internal
|
internal
|
||||||
void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
|
void* fallback_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
|
||||||
{
|
{
|
||||||
Arena* last = array_back(Global_AllocatorBuckets);
|
GEN_ASSERT(_ctx);
|
||||||
|
GEN_ASSERT(_ctx->Fallback_AllocatorBuckets);
|
||||||
|
Arena* last = array_back(_ctx->Fallback_AllocatorBuckets);
|
||||||
|
|
||||||
switch ( type )
|
switch ( type )
|
||||||
{
|
{
|
||||||
@ -19,15 +19,15 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s
|
|||||||
{
|
{
|
||||||
if ( ( last->TotalUsed + size ) > last->TotalSize )
|
if ( ( last->TotalUsed + size ) > last->TotalSize )
|
||||||
{
|
{
|
||||||
Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
|
Arena bucket = arena_init_from_allocator( heap(), _ctx->InitSize_Fallback_Allocator_Bucket_Size );
|
||||||
|
|
||||||
if ( bucket.PhysicalStart == nullptr )
|
if ( bucket.PhysicalStart == nullptr )
|
||||||
GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
|
GEN_FATAL( "Failed to create bucket for Fallback_AllocatorBuckets");
|
||||||
|
|
||||||
if ( ! array_append( Global_AllocatorBuckets, bucket ) )
|
if ( ! array_append( _ctx->Fallback_AllocatorBuckets, bucket ) )
|
||||||
GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
|
GEN_FATAL( "Failed to append bucket to Fallback_AllocatorBuckets");
|
||||||
|
|
||||||
last = array_back(Global_AllocatorBuckets);
|
last = array_back(_ctx->Fallback_AllocatorBuckets);
|
||||||
}
|
}
|
||||||
|
|
||||||
return alloc_align( arena_allocator_info(last), size, alignment );
|
return alloc_align( arena_allocator_info(last), size, alignment );
|
||||||
@ -46,15 +46,15 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s
|
|||||||
{
|
{
|
||||||
if ( last->TotalUsed + size > last->TotalSize )
|
if ( last->TotalUsed + size > last->TotalSize )
|
||||||
{
|
{
|
||||||
Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
|
Arena bucket = arena_init_from_allocator( heap(), _ctx->InitSize_Fallback_Allocator_Bucket_Size );
|
||||||
|
|
||||||
if ( bucket.PhysicalStart == nullptr )
|
if ( bucket.PhysicalStart == nullptr )
|
||||||
GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
|
GEN_FATAL( "Failed to create bucket for Fallback_AllocatorBuckets");
|
||||||
|
|
||||||
if ( ! array_append( Global_AllocatorBuckets, bucket ) )
|
if ( ! array_append( _ctx->Fallback_AllocatorBuckets, bucket ) )
|
||||||
GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
|
GEN_FATAL( "Failed to append bucket to Fallback_AllocatorBuckets");
|
||||||
|
|
||||||
last = array_back(Global_AllocatorBuckets);
|
last = array_back( _ctx->Fallback_AllocatorBuckets);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* result = alloc_align( last->Backing, size, alignment );
|
void* result = alloc_align( last->Backing, size, alignment );
|
||||||
@ -74,8 +74,12 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s
|
|||||||
internal
|
internal
|
||||||
void define_constants()
|
void define_constants()
|
||||||
{
|
{
|
||||||
|
// We only initalize these if there is no base context.
|
||||||
|
if ( context_counter > 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
Code_Global = make_code();
|
Code_Global = make_code();
|
||||||
Code_Global->Name = get_cached_string( txt("Global Code") );
|
Code_Global->Name = cache_str( txt("Global Code") );
|
||||||
Code_Global->Content = Code_Global->Name;
|
Code_Global->Content = Code_Global->Name;
|
||||||
|
|
||||||
Code_Invalid = make_code();
|
Code_Invalid = make_code();
|
||||||
@ -83,41 +87,41 @@ void define_constants()
|
|||||||
|
|
||||||
t_empty = (CodeTypename) make_code();
|
t_empty = (CodeTypename) make_code();
|
||||||
t_empty->Type = CT_Typename;
|
t_empty->Type = CT_Typename;
|
||||||
t_empty->Name = get_cached_string( txt("") );
|
t_empty->Name = cache_str( txt("") );
|
||||||
code_set_global(cast(Code, t_empty));
|
code_set_global(cast(Code, t_empty));
|
||||||
|
|
||||||
access_private = make_code();
|
access_private = make_code();
|
||||||
access_private->Type = CT_Access_Private;
|
access_private->Type = CT_Access_Private;
|
||||||
access_private->Name = get_cached_string( txt("private:\n") );
|
access_private->Name = cache_str( txt("private:\n") );
|
||||||
code_set_global(cast(Code, access_private));
|
code_set_global(cast(Code, access_private));
|
||||||
|
|
||||||
access_protected = make_code();
|
access_protected = make_code();
|
||||||
access_protected->Type = CT_Access_Protected;
|
access_protected->Type = CT_Access_Protected;
|
||||||
access_protected->Name = get_cached_string( txt("protected:\n") );
|
access_protected->Name = cache_str( txt("protected:\n") );
|
||||||
code_set_global(access_protected);
|
code_set_global(access_protected);
|
||||||
|
|
||||||
access_public = make_code();
|
access_public = make_code();
|
||||||
access_public->Type = CT_Access_Public;
|
access_public->Type = CT_Access_Public;
|
||||||
access_public->Name = get_cached_string( txt("public:\n") );
|
access_public->Name = cache_str( txt("public:\n") );
|
||||||
code_set_global(access_public);
|
code_set_global(access_public);
|
||||||
|
|
||||||
StrC api_export_str = code(GEN_API_Export_Code);
|
Str api_export_str = code(GEN_API_Export_Code);
|
||||||
attrib_api_export = def_attributes( api_export_str );
|
attrib_api_export = def_attributes( api_export_str );
|
||||||
code_set_global(cast(Code, attrib_api_export));
|
code_set_global(cast(Code, attrib_api_export));
|
||||||
|
|
||||||
StrC api_import_str = code(GEN_API_Import_Code);
|
Str api_import_str = code(GEN_API_Import_Code);
|
||||||
attrib_api_import = def_attributes( api_import_str );
|
attrib_api_import = def_attributes( api_import_str );
|
||||||
code_set_global(cast(Code, attrib_api_import));
|
code_set_global(cast(Code, attrib_api_import));
|
||||||
|
|
||||||
module_global_fragment = make_code();
|
module_global_fragment = make_code();
|
||||||
module_global_fragment->Type = CT_Untyped;
|
module_global_fragment->Type = CT_Untyped;
|
||||||
module_global_fragment->Name = get_cached_string( txt("module;") );
|
module_global_fragment->Name = cache_str( txt("module;") );
|
||||||
module_global_fragment->Content = module_global_fragment->Name;
|
module_global_fragment->Content = module_global_fragment->Name;
|
||||||
code_set_global(cast(Code, module_global_fragment));
|
code_set_global(cast(Code, module_global_fragment));
|
||||||
|
|
||||||
module_private_fragment = make_code();
|
module_private_fragment = make_code();
|
||||||
module_private_fragment->Type = CT_Untyped;
|
module_private_fragment->Type = CT_Untyped;
|
||||||
module_private_fragment->Name = get_cached_string( txt("module : private;") );
|
module_private_fragment->Name = cache_str( txt("module : private;") );
|
||||||
module_private_fragment->Content = module_private_fragment->Name;
|
module_private_fragment->Content = module_private_fragment->Name;
|
||||||
code_set_global(cast(Code, module_private_fragment));
|
code_set_global(cast(Code, module_private_fragment));
|
||||||
|
|
||||||
@ -127,13 +131,13 @@ void define_constants()
|
|||||||
|
|
||||||
pragma_once = (CodePragma) make_code();
|
pragma_once = (CodePragma) make_code();
|
||||||
pragma_once->Type = CT_Preprocess_Pragma;
|
pragma_once->Type = CT_Preprocess_Pragma;
|
||||||
pragma_once->Name = get_cached_string( txt("once") );
|
pragma_once->Name = cache_str( txt("once") );
|
||||||
pragma_once->Content = pragma_once->Name;
|
pragma_once->Content = pragma_once->Name;
|
||||||
code_set_global((Code)pragma_once);
|
code_set_global((Code)pragma_once);
|
||||||
|
|
||||||
param_varadic = (CodeParams) make_code();
|
param_varadic = (CodeParams) make_code();
|
||||||
param_varadic->Type = CT_Parameters;
|
param_varadic->Type = CT_Parameters;
|
||||||
param_varadic->Name = get_cached_string( txt("...") );
|
param_varadic->Name = cache_str( txt("...") );
|
||||||
param_varadic->ValueType = t_empty;
|
param_varadic->ValueType = t_empty;
|
||||||
code_set_global((Code)param_varadic);
|
code_set_global((Code)param_varadic);
|
||||||
|
|
||||||
@ -145,318 +149,373 @@ void define_constants()
|
|||||||
preprocess_endif->Type = CT_Preprocess_EndIf;
|
preprocess_endif->Type = CT_Preprocess_EndIf;
|
||||||
code_set_global((Code)preprocess_endif);
|
code_set_global((Code)preprocess_endif);
|
||||||
|
|
||||||
# define def_constant_code_type( Type_ ) \
|
Str auto_str = txt("auto"); t_auto = def_type( auto_str ); code_set_global( t_auto );
|
||||||
do \
|
Str void_str = txt("void"); t_void = def_type( void_str ); code_set_global( t_void );
|
||||||
{ \
|
Str int_str = txt("int"); t_int = def_type( int_str ); code_set_global( t_int );
|
||||||
StrC name_str = name(Type_); \
|
Str bool_str = txt("bool"); t_bool = def_type( bool_str ); code_set_global( t_bool );
|
||||||
t_##Type_ = def_type( name_str ); \
|
Str char_str = txt("char"); t_char = def_type( char_str ); code_set_global( t_char );
|
||||||
code_set_global( cast(Code, t_##Type_)); \
|
Str wchar_str = txt("wchar_t"); t_wchar_t = def_type( wchar_str ); code_set_global( t_wchar_t );
|
||||||
} while(0)
|
Str class_str = txt("class"); t_class = def_type( class_str ); code_set_global( t_class );
|
||||||
|
Str typename_str = txt("typename"); t_typename = def_type( typename_str ); code_set_global( t_typename );
|
||||||
def_constant_code_type( auto );
|
|
||||||
def_constant_code_type( void );
|
|
||||||
def_constant_code_type( int );
|
|
||||||
def_constant_code_type( bool );
|
|
||||||
def_constant_code_type( char );
|
|
||||||
def_constant_code_type( wchar_t );
|
|
||||||
def_constant_code_type( class );
|
|
||||||
def_constant_code_type( typename );
|
|
||||||
|
|
||||||
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||||
t_b32 = def_type( name(b32) );
|
t_b32 = def_type( name(b32) ); code_set_global( t_b32 );
|
||||||
|
|
||||||
def_constant_code_type( s8 );
|
Str s8_str = txt("s8"); t_s8 = def_type( s8_str ); code_set_global( t_s8 );
|
||||||
def_constant_code_type( s16 );
|
Str s16_str = txt("s16"); t_s16 = def_type( s16_str ); code_set_global( t_s16 );
|
||||||
def_constant_code_type( s32 );
|
Str s32_str = txt("s32"); t_s32 = def_type( s32_str ); code_set_global( t_s32 );
|
||||||
def_constant_code_type( s64 );
|
Str s64_str = txt("s64"); t_s64 = def_type( s64_str ); code_set_global( t_s64 );
|
||||||
|
|
||||||
def_constant_code_type( u8 );
|
Str u8_str = txt("u8"); t_u8 = def_type( u8_str ); code_set_global( t_u8 );
|
||||||
def_constant_code_type( u16 );
|
Str u16_str = txt("u16"); t_u16 = def_type( u16_str ); code_set_global( t_u16 );
|
||||||
def_constant_code_type( u32 );
|
Str u32_str = txt("u32"); t_u32 = def_type( u32_str ); code_set_global( t_u32 );
|
||||||
def_constant_code_type( u64 );
|
Str u64_str = txt("u64"); t_u64 = def_type( u64_str ); code_set_global( t_u64 );
|
||||||
|
|
||||||
def_constant_code_type( ssize );
|
Str ssize_str = txt("ssize"); t_ssize = def_type( ssize_str ); code_set_global( t_ssize );
|
||||||
def_constant_code_type( usize );
|
Str usize_str = txt("usize"); t_usize = def_type( usize_str ); code_set_global( t_usize );
|
||||||
|
|
||||||
def_constant_code_type( f32 );
|
Str f32_str = txt("f32"); t_f32 = def_type( f32_str ); code_set_global( t_f32 );
|
||||||
def_constant_code_type( f64 );
|
Str f64_str = txt("f64"); t_f64 = def_type( f64_str ); code_set_global( t_f64 );
|
||||||
#endif
|
#endif
|
||||||
# undef def_constant_code_type
|
|
||||||
|
|
||||||
spec_const = def_specifier( Spec_Const); code_set_global( cast(Code, spec_const ));
|
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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_volatile = def_specifier( Spec_Volatile); code_set_global( cast(Code, spec_volatile ));
|
||||||
|
|
||||||
spec_local_persist = def_specifiers( 1, Spec_Local_Persist );
|
spec_local_persist = def_specifiers( 1, Spec_Local_Persist );
|
||||||
code_set_global(cast(Code, spec_local_persist));
|
code_set_global(cast(Code, spec_local_persist));
|
||||||
|
|
||||||
if (enum_underlying_sig.Len == 0) {
|
if (enum_underlying_macro.Name.Len == 0) {
|
||||||
enum_underlying_sig = txt("enum_underlying(");
|
enum_underlying_macro.Name = txt("enum_underlying");
|
||||||
|
enum_underlying_macro.Type = MT_Expression;
|
||||||
|
enum_underlying_macro.Flags = MF_Functional;
|
||||||
}
|
}
|
||||||
array_append(PreprocessorDefines, enum_underlying_sig);
|
register_macro(enum_underlying_macro);
|
||||||
|
|
||||||
# undef def_constant_spec
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init()
|
void init(Context* ctx)
|
||||||
{
|
{
|
||||||
// Setup global allocator
|
do_once() {
|
||||||
|
context_counter = 0;
|
||||||
|
}
|
||||||
|
AllocatorInfo fallback_allocator = { & fallback_allocator_proc, nullptr };
|
||||||
|
|
||||||
|
b32 using_fallback_allocator = false;
|
||||||
|
if (ctx->Allocator_DyanmicContainers.Proc == nullptr) {
|
||||||
|
ctx->Allocator_DyanmicContainers = fallback_allocator;
|
||||||
|
using_fallback_allocator = true;
|
||||||
|
}
|
||||||
|
if (ctx->Allocator_Pool.Proc == nullptr ) {
|
||||||
|
ctx->Allocator_Pool = fallback_allocator;
|
||||||
|
using_fallback_allocator = true;
|
||||||
|
}
|
||||||
|
if (ctx->Allocator_StrCache.Proc == nullptr) {
|
||||||
|
ctx->Allocator_StrCache = fallback_allocator;
|
||||||
|
using_fallback_allocator = true;
|
||||||
|
}
|
||||||
|
if (ctx->Allocator_Temp.Proc == nullptr) {
|
||||||
|
ctx->Allocator_Temp = fallback_allocator;
|
||||||
|
using_fallback_allocator = true;
|
||||||
|
}
|
||||||
|
// Setup fallback allocator
|
||||||
|
if (using_fallback_allocator)
|
||||||
{
|
{
|
||||||
AllocatorInfo becasue_C = { & Global_Allocator_Proc, nullptr };
|
ctx->Fallback_AllocatorBuckets = array_init_reserve(Arena, heap(), 128 );
|
||||||
GlobalAllocator = becasue_C;
|
if ( ctx->Fallback_AllocatorBuckets == nullptr )
|
||||||
|
GEN_FATAL( "Failed to reserve memory for Fallback_AllocatorBuckets");
|
||||||
Global_AllocatorBuckets = array_init_reserve(Arena, heap(), 128 );
|
|
||||||
|
|
||||||
if ( Global_AllocatorBuckets == nullptr )
|
|
||||||
GEN_FATAL( "Failed to reserve memory for Global_AllocatorBuckets");
|
|
||||||
|
|
||||||
Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
|
|
||||||
|
|
||||||
|
Arena bucket = arena_init_from_allocator( heap(), ctx->InitSize_Fallback_Allocator_Bucket_Size );
|
||||||
if ( bucket.PhysicalStart == nullptr )
|
if ( bucket.PhysicalStart == nullptr )
|
||||||
GEN_FATAL( "Failed to create first bucket for Global_AllocatorBuckets");
|
GEN_FATAL( "Failed to create first bucket for Fallback_AllocatorBuckets");
|
||||||
|
|
||||||
array_append( Global_AllocatorBuckets, bucket );
|
array_append( ctx->Fallback_AllocatorBuckets, bucket );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Allocator_DataArrays.Proc == nullptr) {
|
if (ctx->Max_CommentLineLength == 0) {
|
||||||
Allocator_DataArrays = GlobalAllocator;
|
ctx->Max_CommentLineLength = 1024;
|
||||||
}
|
}
|
||||||
if (Allocator_CodePool.Proc == nullptr ) {
|
if (ctx->Max_StrCacheLength == 0) {
|
||||||
Allocator_CodePool = GlobalAllocator;
|
ctx->Max_StrCacheLength = kilobytes(512);
|
||||||
}
|
}
|
||||||
if (Allocator_Lexer.Proc == nullptr) {
|
|
||||||
Allocator_Lexer = GlobalAllocator;
|
if (ctx->InitSize_BuilderBuffer == 0) {
|
||||||
|
ctx->InitSize_BuilderBuffer = megabytes(2);
|
||||||
}
|
}
|
||||||
if (Allocator_StringArena.Proc == nullptr) {
|
if (ctx->InitSize_CodePoolsArray == 0) {
|
||||||
Allocator_StringArena = GlobalAllocator;
|
ctx->InitSize_CodePoolsArray = 16;
|
||||||
}
|
}
|
||||||
if (Allocator_StringTable.Proc == nullptr) {
|
if (ctx->InitSize_StringArenasArray == 0) {
|
||||||
Allocator_StringTable = GlobalAllocator;
|
ctx->InitSize_StringArenasArray = 16;
|
||||||
}
|
}
|
||||||
if (Allocator_TypeTable.Proc == nullptr) {
|
if (ctx->CodePool_NumBlocks == 0) {
|
||||||
Allocator_TypeTable = GlobalAllocator;
|
ctx->CodePool_NumBlocks = kilobytes(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->InitSize_LexerTokens == 0 ) {
|
||||||
|
ctx->InitSize_LexerTokens = kilobytes(64);
|
||||||
|
}
|
||||||
|
if (ctx->SizePer_StringArena == 0) {
|
||||||
|
ctx->SizePer_StringArena = megabytes(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->InitSize_Fallback_Allocator_Bucket_Size == 0) {
|
||||||
|
ctx->InitSize_Fallback_Allocator_Bucket_Size = megabytes(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override the current context (user has to put it back if unwanted).
|
||||||
|
_ctx = ctx;
|
||||||
|
|
||||||
// Setup the arrays
|
// Setup the arrays
|
||||||
{
|
{
|
||||||
CodePools = array_init_reserve(Pool, Allocator_DataArrays, InitSize_DataArrays );
|
ctx->CodePools = array_init_reserve(Pool, ctx->Allocator_DyanmicContainers, ctx->InitSize_CodePoolsArray );
|
||||||
|
if ( ctx->CodePools == nullptr )
|
||||||
if ( CodePools == nullptr )
|
|
||||||
GEN_FATAL( "gen::init: Failed to initialize the CodePools array" );
|
GEN_FATAL( "gen::init: Failed to initialize the CodePools array" );
|
||||||
|
|
||||||
StringArenas = array_init_reserve(Arena, Allocator_DataArrays, InitSize_DataArrays );
|
ctx->StringArenas = array_init_reserve(Arena, ctx->Allocator_DyanmicContainers, ctx->InitSize_StringArenasArray );
|
||||||
|
if ( ctx->StringArenas == nullptr )
|
||||||
if ( StringArenas == nullptr )
|
|
||||||
GEN_FATAL( "gen::init: Failed to initialize the StringArenas array" );
|
GEN_FATAL( "gen::init: Failed to initialize the StringArenas array" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the code pool and code entries arena.
|
// Setup the code pool and code entries arena.
|
||||||
{
|
{
|
||||||
Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
|
Pool code_pool = pool_init( ctx->Allocator_Pool, ctx->CodePool_NumBlocks, sizeof(AST) );
|
||||||
|
|
||||||
if ( code_pool.PhysicalStart == nullptr )
|
if ( code_pool.PhysicalStart == nullptr )
|
||||||
GEN_FATAL( "gen::init: Failed to initialize the code pool" );
|
GEN_FATAL( "gen::init: Failed to initialize the code pool" );
|
||||||
|
array_append( ctx->CodePools, code_pool );
|
||||||
|
|
||||||
array_append( CodePools, code_pool );
|
// 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 );
|
||||||
LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size );
|
if ( strbuilder_arena.PhysicalStart == nullptr )
|
||||||
|
|
||||||
Arena string_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
|
|
||||||
|
|
||||||
if ( string_arena.PhysicalStart == nullptr )
|
|
||||||
GEN_FATAL( "gen::init: Failed to initialize the string arena" );
|
GEN_FATAL( "gen::init: Failed to initialize the string arena" );
|
||||||
|
array_append( ctx->StringArenas, strbuilder_arena );
|
||||||
array_append( StringArenas, string_arena );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the hash tables
|
// Setup the hash tables
|
||||||
{
|
{
|
||||||
StringCache = hashtable_init(StringCached, Allocator_StringTable);
|
ctx->StrCache = hashtable_init(StrCached, ctx->Allocator_DyanmicContainers);
|
||||||
|
if ( ctx->StrCache.Entries == nullptr )
|
||||||
if ( StringCache.Entries == nullptr )
|
|
||||||
GEN_FATAL( "gen::init: Failed to initialize the StringCache");
|
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
|
|
||||||
PreprocessorDefines = array_init_reserve(StringCached, GlobalAllocator, kilobytes(1) );
|
|
||||||
|
|
||||||
define_constants();
|
define_constants();
|
||||||
GEN_NS_PARSER parser_init();
|
parser_init();
|
||||||
|
|
||||||
|
++ context_counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deinit()
|
void deinit(Context* ctx)
|
||||||
{
|
{
|
||||||
|
GEN_ASSERT(context_counter);
|
||||||
|
GEN_ASSERT_MSG(context_counter > 0, "Attempted to deinit a context that for some reason wan't accounted for!");
|
||||||
usize index = 0;
|
usize index = 0;
|
||||||
usize left = array_num(CodePools);
|
usize left = array_num(ctx->CodePools);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Pool* code_pool = & CodePools[index];
|
Pool* code_pool = & ctx->CodePools[index];
|
||||||
pool_free(code_pool);
|
pool_free(code_pool);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
while ( left--, left );
|
while ( left--, left );
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
left = array_num(StringArenas);
|
left = array_num(ctx->StringArenas);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Arena* string_arena = & StringArenas[index];
|
Arena* strbuilder_arena = & ctx->StringArenas[index];
|
||||||
arena_free(string_arena);
|
arena_free(strbuilder_arena);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
while ( left--, left );
|
while ( left--, left );
|
||||||
|
|
||||||
hashtable_destroy(StringCache);
|
hashtable_destroy(ctx->StrCache);
|
||||||
|
|
||||||
array_free( CodePools);
|
array_free( ctx->CodePools);
|
||||||
array_free( StringArenas);
|
array_free( ctx->StringArenas);
|
||||||
|
|
||||||
arena_free(& LexArena);
|
hashtable_destroy(ctx->Macros);
|
||||||
|
|
||||||
array_free(PreprocessorDefines);
|
left = array_num( ctx->Fallback_AllocatorBuckets);
|
||||||
|
if (left)
|
||||||
index = 0;
|
|
||||||
left = array_num(Global_AllocatorBuckets);
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
Arena* bucket = & Global_AllocatorBuckets[ index ];
|
index = 0;
|
||||||
arena_free(bucket);
|
do
|
||||||
index++;
|
{
|
||||||
|
Arena* bucket = & ctx->Fallback_AllocatorBuckets[ index ];
|
||||||
|
arena_free(bucket);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
while ( left--, left );
|
||||||
|
array_free( ctx->Fallback_AllocatorBuckets);
|
||||||
}
|
}
|
||||||
while ( left--, left );
|
parser_deinit();
|
||||||
|
|
||||||
array_free(Global_AllocatorBuckets);
|
if (_ctx == ctx)
|
||||||
GEN_NS_PARSER parser_deinit();
|
_ctx = nullptr;
|
||||||
|
-- context_counter;
|
||||||
|
|
||||||
|
Context wipe = {};
|
||||||
|
* ctx = wipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
Context* get_context() {
|
||||||
|
return _ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(Context* ctx)
|
||||||
{
|
{
|
||||||
s32 index = 0;
|
s32 index = 0;
|
||||||
s32 left = array_num(CodePools);
|
s32 left = array_num(ctx->CodePools);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Pool* code_pool = & CodePools[index];
|
Pool* code_pool = & ctx->CodePools[index];
|
||||||
pool_clear(code_pool);
|
pool_clear(code_pool);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
while ( left--, left );
|
while ( left--, left );
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
left = array_num(StringArenas);
|
left = array_num(ctx->StringArenas);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Arena* string_arena = & StringArenas[index];
|
Arena* strbuilder_arena = & ctx->StringArenas[index];
|
||||||
string_arena->TotalUsed = 0;;
|
strbuilder_arena->TotalUsed = 0;;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
while ( left--, left );
|
while ( left--, left );
|
||||||
|
|
||||||
hashtable_clear(StringCache);
|
hashtable_clear(ctx->StrCache);
|
||||||
|
hashtable_clear(ctx->Macros);
|
||||||
define_constants();
|
define_constants();
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocatorInfo get_string_allocator( s32 str_length )
|
void set_context(Context* new_ctx) {
|
||||||
|
GEN_ASSERT(new_ctx);
|
||||||
|
_ctx = new_ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
AllocatorInfo get_cached_str_allocator( s32 str_length )
|
||||||
{
|
{
|
||||||
Arena* last = array_back(StringArenas);
|
Arena* last = array_back(_ctx->StringArenas);
|
||||||
|
usize size_req = str_length + sizeof(StrBuilderHeader) + sizeof(char*);
|
||||||
usize size_req = str_length + sizeof(StringHeader) + sizeof(char*);
|
|
||||||
|
|
||||||
if ( last->TotalUsed + scast(ssize, size_req) > last->TotalSize )
|
if ( last->TotalUsed + scast(ssize, size_req) > last->TotalSize )
|
||||||
{
|
{
|
||||||
Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
|
Arena new_arena = arena_init_from_allocator( _ctx->Allocator_StrCache, _ctx->SizePer_StringArena );
|
||||||
|
if ( ! array_append( _ctx->StringArenas, new_arena ) )
|
||||||
|
GEN_FATAL( "gen::get_cached_str_allocator: Failed to allocate a new string arena" );
|
||||||
|
|
||||||
if ( ! array_append( StringArenas, new_arena ) )
|
last = array_back( _ctx->StringArenas);
|
||||||
GEN_FATAL( "gen::get_string_allocator: Failed to allocate a new string arena" );
|
|
||||||
|
|
||||||
last = array_back(StringArenas);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return arena_allocator_info(last);
|
return arena_allocator_info(last);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Will either make or retrive a code string.
|
// Will either make or retrive a code string.
|
||||||
StringCached get_cached_string( StrC str )
|
StrCached cache_str( Str str )
|
||||||
{
|
{
|
||||||
s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len;
|
if (str.Len > _ctx->Max_StrCacheLength) {
|
||||||
u64 key = crc32( str.Ptr, hash_length );
|
// Do not cache the string, just shove into the arena and and return it.
|
||||||
{
|
Str result = strbuilder_to_str( strbuilder_make_str( get_cached_str_allocator( str.Len ), str ));
|
||||||
StringCached* result = hashtable_get(StringCache, key );
|
return result;
|
||||||
|
}
|
||||||
|
u64 key = crc32( str.Ptr, str.Len ); {
|
||||||
|
StrCached* result = hashtable_get( _ctx->StrCache, key );
|
||||||
if ( result )
|
if ( result )
|
||||||
return * result;
|
return * result;
|
||||||
}
|
}
|
||||||
|
Str result = strbuilder_to_str( strbuilder_make_str( get_cached_str_allocator( str.Len ), str ));
|
||||||
StrC result = string_to_strc( string_make_strc( get_string_allocator( str.Len ), str ));
|
hashtable_set( _ctx->StrCache, key, result );
|
||||||
hashtable_set(StringCache, key, result );
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used internally to retireve a Code object form the CodePool.
|
// Used internally to retireve a Code object form the CodePool.
|
||||||
Code make_code()
|
Code make_code()
|
||||||
{
|
{
|
||||||
Pool* allocator = array_back( CodePools);
|
Pool* allocator = array_back( _ctx->CodePools);
|
||||||
if ( allocator->FreeList == nullptr )
|
if ( allocator->FreeList == nullptr )
|
||||||
{
|
{
|
||||||
Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
|
Pool code_pool = pool_init( _ctx->Allocator_Pool, _ctx->CodePool_NumBlocks, sizeof(AST) );
|
||||||
|
|
||||||
if ( code_pool.PhysicalStart == nullptr )
|
if ( code_pool.PhysicalStart == nullptr )
|
||||||
GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." );
|
GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." );
|
||||||
|
|
||||||
if ( ! array_append( CodePools, code_pool ) )
|
if ( ! array_append( _ctx->CodePools, code_pool ) )
|
||||||
GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." );
|
GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." );
|
||||||
|
|
||||||
allocator = array_back( CodePools);
|
allocator = array_back( _ctx->CodePools);
|
||||||
}
|
}
|
||||||
|
|
||||||
Code result = { rcast( AST*, alloc( pool_allocator_info(allocator), sizeof(AST) )) };
|
Code result = { rcast( AST*, alloc( pool_allocator_info(allocator), sizeof(AST) )) };
|
||||||
mem_set( rcast(void*, cast(AST*, result)), 0, sizeof(AST) );
|
mem_set( rcast(void*, cast(AST*, result)), 0, sizeof(AST) );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_allocator_data_arrays( AllocatorInfo allocator )
|
Macro* lookup_macro( Str name ) {
|
||||||
{
|
u32 key = crc32( name.Ptr, name.Len );
|
||||||
Allocator_DataArrays = allocator;
|
return hashtable_get( _ctx->Macros, key );
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_allocator_code_pool( AllocatorInfo allocator )
|
void register_macro( Macro macro ) {
|
||||||
{
|
GEN_ASSERT_NOT_NULL(macro.Name.Ptr);
|
||||||
Allocator_CodePool = allocator;
|
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 set_allocator_lexer( AllocatorInfo allocator )
|
void register_macros( s32 num, ... )
|
||||||
{
|
{
|
||||||
Allocator_Lexer = allocator;
|
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 set_allocator_string_arena( AllocatorInfo allocator )
|
void register_macros_arr( s32 num, Macro* macros )
|
||||||
{
|
{
|
||||||
Allocator_StringArena = allocator;
|
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);
|
||||||
|
|
||||||
void set_allocator_string_table( AllocatorInfo allocator )
|
u32 key = crc32( macro.Name.Ptr, macro.Name.Len );
|
||||||
{
|
hashtable_set( _ctx->Macros, key, macro );
|
||||||
Allocator_StringArena = allocator;
|
++ macros;
|
||||||
|
}
|
||||||
|
while (num--, num > 0);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "ast_types.hpp"
|
#include "ast_types.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -15,41 +15,144 @@
|
|||||||
\▓▓▓▓▓▓ \▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓ \▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓
|
\▓▓▓▓▓▓ \▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓ \▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Initialize the library.
|
#if 0
|
||||||
void init();
|
enum LogLevel : u32
|
||||||
|
{
|
||||||
|
Info,
|
||||||
|
Warning,
|
||||||
|
Panic,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LogEntry
|
||||||
|
{
|
||||||
|
Str msg;
|
||||||
|
u32 line_num;
|
||||||
|
void* data;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void LoggerCallback(LogEntry entry);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Note(Ed): This is subject to heavily change
|
||||||
|
// with upcoming changes to the library's fallback (default) allocations strategy;
|
||||||
|
// and major changes to lexer/parser context usage.
|
||||||
|
struct Context
|
||||||
|
{
|
||||||
|
// User Configuration
|
||||||
|
|
||||||
|
// Persistent Data Allocation
|
||||||
|
AllocatorInfo Allocator_DyanmicContainers; // By default will use a genral slab allocator (TODO(Ed): Currently does not)
|
||||||
|
AllocatorInfo Allocator_Pool; // By default will use the growing vmem reserve (TODO(Ed): Currently does not)
|
||||||
|
AllocatorInfo Allocator_StrCache; // By default will use a dedicated slab allocator (TODO(Ed): Currently does not)
|
||||||
|
|
||||||
|
// Temporary Allocation
|
||||||
|
AllocatorInfo Allocator_Temp;
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
u32 InitSize_BuilderBuffer;
|
||||||
|
u32 InitSize_CodePoolsArray;
|
||||||
|
u32 InitSize_StringArenasArray;
|
||||||
|
|
||||||
|
u32 CodePool_NumBlocks;
|
||||||
|
|
||||||
|
// TODO(Ed): Review these... (No longer needed if using the proper allocation strategy)
|
||||||
|
u32 InitSize_LexerTokens;
|
||||||
|
u32 SizePer_StringArena;
|
||||||
|
|
||||||
|
// TODO(Ed): Symbol Table
|
||||||
|
// Keep track of all resolved symbols (naemspaced identifiers)
|
||||||
|
|
||||||
|
// Parser
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
MacroTable Macros;
|
||||||
|
|
||||||
|
// Backend
|
||||||
|
|
||||||
|
// The fallback allocator is utilized if any fo the three above allocators is not specified by the user.
|
||||||
|
u32 InitSize_Fallback_Allocator_Bucket_Size;
|
||||||
|
Array(Arena) Fallback_AllocatorBuckets;
|
||||||
|
|
||||||
|
StringTable token_fmt_map;
|
||||||
|
|
||||||
|
// Array(Token) LexerTokens;
|
||||||
|
|
||||||
|
Array(Pool) CodePools;
|
||||||
|
Array(Arena) StringArenas;
|
||||||
|
|
||||||
|
StringTable StrCache;
|
||||||
|
|
||||||
|
// TODO(Ed): This needs to be just handled by a parser context
|
||||||
|
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);
|
||||||
|
|
||||||
// Currently manually free's the arenas, code for checking for leaks.
|
// Currently manually free's the arenas, code for checking for leaks.
|
||||||
// However on Windows at least, it doesn't need to occur as the OS will clean up after the process.
|
// However on Windows at least, it doesn't need to occur as the OS will clean up after the process.
|
||||||
void deinit();
|
GEN_API void deinit(Context* ctx);
|
||||||
|
|
||||||
// Clears the allocations, but doesn't return to the heap, the calls init() again.
|
// 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.
|
// Ease of use.
|
||||||
void reset();
|
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
|
||||||
|
// 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.
|
// Used internally to retrive or make string allocations.
|
||||||
// Strings are stored in a series of string arenas of fixed size (SizePer_StringArena)
|
// Strings are stored in a series of string arenas of fixed size (SizePer_StringArena)
|
||||||
StringCached get_cached_string( StrC str );
|
GEN_API StrCached cache_str( Str str );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This provides a fresh Code AST.
|
This provides a fresh Code AST.
|
||||||
The gen interface use this as their method from getting a new AST object from the CodePool.
|
The gen interface use this as their method from getting a new AST object from the CodePool.
|
||||||
Use this if you want to make your own API for formatting the supported Code Types.
|
Use this if you want to make your own API for formatting the supported Code Types.
|
||||||
*/
|
*/
|
||||||
Code make_code();
|
GEN_API Code make_code();
|
||||||
|
|
||||||
// Set these before calling gen's init() procedure.
|
// Set these before calling gen's init() procedure.
|
||||||
|
|
||||||
void set_allocator_data_arrays ( AllocatorInfo data_array_allocator );
|
|
||||||
void set_allocator_code_pool ( AllocatorInfo pool_allocator );
|
|
||||||
void set_allocator_lexer ( AllocatorInfo lex_allocator );
|
|
||||||
void set_allocator_string_arena( AllocatorInfo string_allocator );
|
|
||||||
void set_allocator_string_table( AllocatorInfo string_allocator );
|
|
||||||
void set_allocator_type_table ( AllocatorInfo type_reg_allocator );
|
|
||||||
|
|
||||||
#pragma region Upfront
|
#pragma region Upfront
|
||||||
|
|
||||||
CodeAttributes def_attributes( StrC content );
|
GEN_API CodeAttributes def_attributes( Str content );
|
||||||
CodeComment def_comment ( StrC content );
|
GEN_API CodeComment def_comment ( Str content );
|
||||||
|
|
||||||
struct Opts_def_struct {
|
struct Opts_def_struct {
|
||||||
CodeBody body;
|
CodeBody body;
|
||||||
@ -58,27 +161,31 @@ struct Opts_def_struct {
|
|||||||
CodeAttributes attributes;
|
CodeAttributes attributes;
|
||||||
CodeTypename* interfaces;
|
CodeTypename* interfaces;
|
||||||
s32 num_interfaces;
|
s32 num_interfaces;
|
||||||
|
CodeSpecifiers specifiers; // Only used for final specifier for now.
|
||||||
ModuleFlag mflags;
|
ModuleFlag mflags;
|
||||||
};
|
};
|
||||||
CodeClass def_class( StrC name, Opts_def_struct opts GEN_PARAM_DEFAULT );
|
GEN_API CodeClass def_class( Str name, Opts_def_struct opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_constructor {
|
struct Opts_def_constructor {
|
||||||
CodeParams params;
|
CodeParams params;
|
||||||
Code initializer_list;
|
Code initializer_list;
|
||||||
Code body;
|
Code body;
|
||||||
};
|
};
|
||||||
CodeConstructor def_constructor( Opts_def_constructor opts GEN_PARAM_DEFAULT );
|
GEN_API CodeConstructor def_constructor( Opts_def_constructor opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_define {
|
struct Opts_def_define {
|
||||||
b32 dont_append_preprocess_defines;
|
CodeDefineParams params;
|
||||||
|
Str content;
|
||||||
|
MacroFlags flags;
|
||||||
|
b32 dont_register_to_preprocess_macros;
|
||||||
};
|
};
|
||||||
CodeDefine def_define( StrC name, StrC 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 {
|
struct Opts_def_destructor {
|
||||||
Code body;
|
Code body;
|
||||||
CodeSpecifiers specifiers;
|
CodeSpecifiers specifiers;
|
||||||
};
|
};
|
||||||
CodeDestructor def_destructor( Opts_def_destructor opts GEN_PARAM_DEFAULT );
|
GEN_API CodeDestructor def_destructor( Opts_def_destructor opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_enum {
|
struct Opts_def_enum {
|
||||||
CodeBody body;
|
CodeBody body;
|
||||||
@ -88,11 +195,11 @@ struct Opts_def_enum {
|
|||||||
ModuleFlag mflags;
|
ModuleFlag mflags;
|
||||||
Code type_macro;
|
Code type_macro;
|
||||||
};
|
};
|
||||||
CodeEnum def_enum( StrC name, Opts_def_enum opts GEN_PARAM_DEFAULT );
|
GEN_API CodeEnum def_enum( Str name, Opts_def_enum opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
CodeExec def_execution ( StrC content );
|
GEN_API CodeExec def_execution ( Str content );
|
||||||
CodeExtern def_extern_link( StrC name, CodeBody body );
|
GEN_API CodeExtern def_extern_link( Str name, CodeBody body );
|
||||||
CodeFriend def_friend ( Code symbol );
|
GEN_API CodeFriend def_friend ( Code code );
|
||||||
|
|
||||||
struct Opts_def_function {
|
struct Opts_def_function {
|
||||||
CodeParams params;
|
CodeParams params;
|
||||||
@ -102,14 +209,14 @@ struct Opts_def_function {
|
|||||||
CodeAttributes attrs;
|
CodeAttributes attrs;
|
||||||
ModuleFlag mflags;
|
ModuleFlag mflags;
|
||||||
};
|
};
|
||||||
CodeFn def_function( StrC name, Opts_def_function opts GEN_PARAM_DEFAULT );
|
GEN_API CodeFn def_function( Str name, Opts_def_function opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_include { b32 foreign; };
|
struct Opts_def_include { b32 foreign; };
|
||||||
struct Opts_def_module { ModuleFlag mflags; };
|
struct Opts_def_module { ModuleFlag mflags; };
|
||||||
struct Opts_def_namespace { ModuleFlag mflags; };
|
struct Opts_def_namespace { ModuleFlag mflags; };
|
||||||
CodeInclude def_include ( StrC content, Opts_def_include opts GEN_PARAM_DEFAULT );
|
GEN_API CodeInclude def_include ( Str content, Opts_def_include opts GEN_PARAM_DEFAULT );
|
||||||
CodeModule def_module ( StrC name, Opts_def_module opts GEN_PARAM_DEFAULT );
|
GEN_API CodeModule def_module ( Str name, Opts_def_module opts GEN_PARAM_DEFAULT );
|
||||||
CodeNS def_namespace( StrC name, CodeBody body, Opts_def_namespace opts GEN_PARAM_DEFAULT );
|
GEN_API CodeNS def_namespace( Str name, CodeBody body, Opts_def_namespace opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_operator {
|
struct Opts_def_operator {
|
||||||
CodeParams params;
|
CodeParams params;
|
||||||
@ -119,54 +226,54 @@ struct Opts_def_operator {
|
|||||||
CodeAttributes attributes;
|
CodeAttributes attributes;
|
||||||
ModuleFlag mflags;
|
ModuleFlag mflags;
|
||||||
};
|
};
|
||||||
CodeOperator def_operator( Operator op, StrC nspace, Opts_def_operator opts GEN_PARAM_DEFAULT );
|
GEN_API CodeOperator def_operator( Operator op, Str nspace, Opts_def_operator opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_operator_cast {
|
struct Opts_def_operator_cast {
|
||||||
CodeBody body;
|
CodeBody body;
|
||||||
CodeSpecifiers specs;
|
CodeSpecifiers specs;
|
||||||
};
|
};
|
||||||
CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opts GEN_PARAM_DEFAULT );
|
GEN_API CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_param { Code value; };
|
struct Opts_def_param { Code value; };
|
||||||
CodeParams def_param ( CodeTypename type, StrC name, Opts_def_param opts GEN_PARAM_DEFAULT );
|
GEN_API CodeParams def_param ( CodeTypename type, Str name, Opts_def_param opts GEN_PARAM_DEFAULT );
|
||||||
CodePragma def_pragma( StrC directive );
|
GEN_API CodePragma def_pragma( Str directive );
|
||||||
|
|
||||||
CodePreprocessCond def_preprocess_cond( EPreprocessCond type, StrC content );
|
GEN_API CodePreprocessCond def_preprocess_cond( EPreprocessCond type, Str content );
|
||||||
|
|
||||||
CodeSpecifiers def_specifier( Specifier specifier );
|
GEN_API CodeSpecifiers def_specifier( Specifier specifier );
|
||||||
|
|
||||||
CodeStruct def_struct( StrC name, Opts_def_struct opts GEN_PARAM_DEFAULT );
|
GEN_API CodeStruct def_struct( Str name, Opts_def_struct opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_template { ModuleFlag mflags; };
|
struct Opts_def_template { ModuleFlag mflags; };
|
||||||
CodeTemplate def_template( CodeParams params, Code definition, Opts_def_template opts GEN_PARAM_DEFAULT );
|
GEN_API CodeTemplate def_template( CodeParams params, Code definition, Opts_def_template opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_type {
|
struct Opts_def_type {
|
||||||
ETypenameTag type_tag;
|
ETypenameTag type_tag;
|
||||||
Code arrayexpr;
|
Code array_expr;
|
||||||
CodeSpecifiers specifiers;
|
CodeSpecifiers specifiers;
|
||||||
CodeAttributes attributes;
|
CodeAttributes attributes;
|
||||||
};
|
};
|
||||||
CodeTypename def_type( StrC name, Opts_def_type opts GEN_PARAM_DEFAULT );
|
GEN_API CodeTypename def_type( Str name, Opts_def_type opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_typedef {
|
struct Opts_def_typedef {
|
||||||
CodeAttributes attributes;
|
CodeAttributes attributes;
|
||||||
ModuleFlag mflags;
|
ModuleFlag mflags;
|
||||||
};
|
};
|
||||||
CodeTypedef def_typedef( StrC name, Code type, Opts_def_typedef opts GEN_PARAM_DEFAULT );
|
GEN_API CodeTypedef def_typedef( Str name, Code type, Opts_def_typedef opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_union {
|
struct Opts_def_union {
|
||||||
CodeAttributes attributes;
|
CodeAttributes attributes;
|
||||||
ModuleFlag mflags;
|
ModuleFlag mflags;
|
||||||
};
|
};
|
||||||
CodeUnion def_union( StrC name, CodeBody body, Opts_def_union opts GEN_PARAM_DEFAULT );
|
GEN_API CodeUnion def_union( Str name, CodeBody body, Opts_def_union opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_using {
|
struct Opts_def_using {
|
||||||
CodeAttributes attributes;
|
CodeAttributes attributes;
|
||||||
ModuleFlag mflags;
|
ModuleFlag mflags;
|
||||||
};
|
};
|
||||||
CodeUsing def_using( StrC name, CodeTypename type, Opts_def_using opts GEN_PARAM_DEFAULT );
|
GEN_API CodeUsing def_using( Str name, CodeTypename type, Opts_def_using opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
CodeUsing def_using_namespace( StrC name );
|
GEN_API CodeUsing def_using_namespace( Str name );
|
||||||
|
|
||||||
struct Opts_def_variable
|
struct Opts_def_variable
|
||||||
{
|
{
|
||||||
@ -175,7 +282,7 @@ struct Opts_def_variable
|
|||||||
CodeAttributes attributes;
|
CodeAttributes attributes;
|
||||||
ModuleFlag mflags;
|
ModuleFlag mflags;
|
||||||
};
|
};
|
||||||
CodeVar def_variable( CodeTypename type, StrC name, Opts_def_variable opts GEN_PARAM_DEFAULT );
|
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.
|
// Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries.
|
||||||
CodeBody def_body( CodeType type );
|
CodeBody def_body( CodeType type );
|
||||||
@ -183,53 +290,66 @@ 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,
|
// 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.
|
/// or provide as an array of Code objects.
|
||||||
|
|
||||||
CodeBody def_class_body ( s32 num, ... );
|
GEN_API CodeBody def_class_body ( s32 num, ... );
|
||||||
CodeBody def_class_body ( s32 num, Code* codes );
|
GEN_API CodeBody def_class_body_arr ( s32 num, Code* codes );
|
||||||
CodeBody def_enum_body ( s32 num, ... );
|
GEN_API CodeDefineParams def_define_params ( s32 num, ... );
|
||||||
CodeBody def_enum_body ( s32 num, Code* codes );
|
GEN_API CodeDefineParams def_define_params_arr ( s32 num, CodeDefineParams* codes );
|
||||||
CodeBody def_export_body ( s32 num, ... );
|
GEN_API CodeBody def_enum_body ( s32 num, ... );
|
||||||
CodeBody def_export_body ( s32 num, Code* codes);
|
GEN_API CodeBody def_enum_body_arr ( s32 num, Code* codes );
|
||||||
CodeBody def_extern_link_body( s32 num, ... );
|
GEN_API CodeBody def_export_body ( s32 num, ... );
|
||||||
CodeBody def_extern_link_body( s32 num, Code* codes );
|
GEN_API CodeBody def_export_body_arr ( s32 num, Code* codes);
|
||||||
CodeBody def_function_body ( s32 num, ... );
|
GEN_API CodeBody def_extern_link_body ( s32 num, ... );
|
||||||
CodeBody def_function_body ( s32 num, Code* codes );
|
GEN_API CodeBody def_extern_link_body_arr ( s32 num, Code* codes );
|
||||||
CodeBody def_global_body ( s32 num, ... );
|
GEN_API CodeBody def_function_body ( s32 num, ... );
|
||||||
CodeBody def_global_body ( s32 num, Code* codes );
|
GEN_API CodeBody def_function_body_arr ( s32 num, Code* codes );
|
||||||
CodeBody def_namespace_body ( s32 num, ... );
|
GEN_API CodeBody def_global_body ( s32 num, ... );
|
||||||
CodeBody def_namespace_body ( s32 num, Code* codes );
|
GEN_API CodeBody def_global_body_arr ( s32 num, Code* codes );
|
||||||
CodeParams def_params ( s32 num, ... );
|
GEN_API CodeBody def_namespace_body ( s32 num, ... );
|
||||||
CodeParams def_params ( s32 num, CodeParams* params );
|
GEN_API CodeBody def_namespace_body_arr ( s32 num, Code* codes );
|
||||||
CodeSpecifiers def_specifiers ( s32 num, ... );
|
GEN_API CodeParams def_params ( s32 num, ... );
|
||||||
CodeSpecifiers def_specifiers ( s32 num, Specifier* specs );
|
GEN_API CodeParams def_params_arr ( s32 num, CodeParams* params );
|
||||||
CodeBody def_struct_body ( s32 num, ... );
|
GEN_API CodeSpecifiers def_specifiers ( s32 num, ... );
|
||||||
CodeBody def_struct_body ( s32 num, Code* codes );
|
GEN_API CodeSpecifiers def_specifiers_arr ( s32 num, Specifier* specs );
|
||||||
CodeBody def_union_body ( s32 num, ... );
|
GEN_API CodeBody def_struct_body ( s32 num, ... );
|
||||||
CodeBody def_union_body ( s32 num, Code* codes );
|
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 endregion Upfront
|
||||||
|
|
||||||
#pragma region Parsing
|
#pragma region Parsing
|
||||||
|
|
||||||
// TODO(Ed) : Implmeent the new parser API design.
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
GEN_NS_PARSER_BEGIN
|
|
||||||
struct StackNode
|
struct StackNode
|
||||||
{
|
{
|
||||||
StackNode* Prev;
|
StackNode* Prev;
|
||||||
|
|
||||||
Token Start;
|
Token Start;
|
||||||
Token Name; // The name of the AST node (if parsed)
|
Token Name; // The name of the AST node (if parsed)
|
||||||
StrC FailedProc; // The name of the procedure that failed
|
Str FailedProc; // The name of the procedure that failed
|
||||||
};
|
};
|
||||||
// Stack nodes are allocated the error's allocator
|
// Stack nodes are allocated the error's allocator
|
||||||
|
|
||||||
struct Error
|
struct Error
|
||||||
{
|
{
|
||||||
String message;
|
StrBuilder message;
|
||||||
StackNode* context_stack;
|
StackNode* context_stack;
|
||||||
};
|
};
|
||||||
GEN_NS_PARSER_END
|
|
||||||
|
|
||||||
struct ParseInfo
|
struct ParseInfo
|
||||||
{
|
{
|
||||||
@ -243,40 +363,41 @@ struct ParseInfo
|
|||||||
// Errors are allocated to a dedicated general arena.
|
// Errors are allocated to a dedicated general arena.
|
||||||
};
|
};
|
||||||
|
|
||||||
CodeBody parse_file( StrC path );
|
CodeBody parse_file( Str path );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CodeClass parse_class ( StrC class_def );
|
GEN_API CodeClass parse_class ( Str class_def );
|
||||||
CodeConstructor parse_constructor ( StrC constructor_def );
|
GEN_API CodeConstructor parse_constructor ( Str constructor_def );
|
||||||
CodeDestructor parse_destructor ( StrC destructor_def );
|
GEN_API CodeDefine parse_define ( Str define_def );
|
||||||
CodeEnum parse_enum ( StrC enum_def );
|
GEN_API CodeDestructor parse_destructor ( Str destructor_def );
|
||||||
CodeBody parse_export_body ( StrC export_def );
|
GEN_API CodeEnum parse_enum ( Str enum_def );
|
||||||
CodeExtern parse_extern_link ( StrC exten_link_def );
|
GEN_API CodeBody parse_export_body ( Str export_def );
|
||||||
CodeFriend parse_friend ( StrC friend_def );
|
GEN_API CodeExtern parse_extern_link ( Str exten_link_def );
|
||||||
CodeFn parse_function ( StrC fn_def );
|
GEN_API CodeFriend parse_friend ( Str friend_def );
|
||||||
CodeBody parse_global_body ( StrC body_def );
|
GEN_API CodeFn parse_function ( Str fn_def );
|
||||||
CodeNS parse_namespace ( StrC namespace_def );
|
GEN_API CodeBody parse_global_body ( Str body_def );
|
||||||
CodeOperator parse_operator ( StrC operator_def );
|
GEN_API CodeNS parse_namespace ( Str namespace_def );
|
||||||
CodeOpCast parse_operator_cast( StrC operator_def );
|
GEN_API CodeOperator parse_operator ( Str operator_def );
|
||||||
CodeStruct parse_struct ( StrC struct_def );
|
GEN_API CodeOpCast parse_operator_cast( Str operator_def );
|
||||||
CodeTemplate parse_template ( StrC template_def );
|
GEN_API CodeStruct parse_struct ( Str struct_def );
|
||||||
CodeTypename parse_type ( StrC type_def );
|
GEN_API CodeTemplate parse_template ( Str template_def );
|
||||||
CodeTypedef parse_typedef ( StrC typedef_def );
|
GEN_API CodeTypename parse_type ( Str type_def );
|
||||||
CodeUnion parse_union ( StrC union_def );
|
GEN_API CodeTypedef parse_typedef ( Str typedef_def );
|
||||||
CodeUsing parse_using ( StrC using_def );
|
GEN_API CodeUnion parse_union ( Str union_def );
|
||||||
CodeVar parse_variable ( StrC var_def );
|
GEN_API CodeUsing parse_using ( Str using_def );
|
||||||
|
GEN_API CodeVar parse_variable ( Str var_def );
|
||||||
|
|
||||||
#pragma endregion Parsing
|
#pragma endregion Parsing
|
||||||
|
|
||||||
#pragma region Untyped text
|
#pragma region Untyped text
|
||||||
|
|
||||||
ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va );
|
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.
|
//! Do not use directly. Use the token_fmt macro instead.
|
||||||
StrC token_fmt_impl( ssize, ... );
|
Str token_fmt_impl( ssize, ... );
|
||||||
|
|
||||||
Code untyped_str ( StrC content);
|
GEN_API Code untyped_str( Str content);
|
||||||
Code untyped_fmt ( char const* fmt, ... );
|
GEN_API Code untyped_fmt ( char const* fmt, ... );
|
||||||
Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );
|
GEN_API Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );
|
||||||
|
|
||||||
#pragma endregion Untyped text
|
#pragma endregion Untyped text
|
||||||
|
|
||||||
@ -289,12 +410,20 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );
|
|||||||
#ifndef name
|
#ifndef name
|
||||||
// Convienence for defining any name used with the gen api.
|
// 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.
|
// Lets you provide the length and string literal to the functions without the need for the DSL.
|
||||||
#define name( Id_ ) { sizeof(stringize( Id_ )) - 1, stringize(Id_) }
|
# 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
|
#endif
|
||||||
|
|
||||||
#ifndef code
|
#ifndef code
|
||||||
// Same as name just used to indicate intention of literal for code instead of names.
|
// Same as name just used to indicate intention of literal for code instead of names.
|
||||||
#define code( ... ) { sizeof(stringize(__VA_ARGS__)) - 1, stringize( __VA_ARGS__ ) }
|
# 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
|
#endif
|
||||||
|
|
||||||
#ifndef args
|
#ifndef args
|
||||||
@ -317,21 +446,21 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );
|
|||||||
|
|
||||||
#ifndef token_fmt
|
#ifndef token_fmt
|
||||||
/*
|
/*
|
||||||
Takes a format string (char const*) and a list of tokens (StrC) and returns a StrC of the formatted string.
|
Takes a format string (char const*) and a list of tokens (Str) and returns a Str of the formatted string.
|
||||||
Tokens are provided in '<'identifier'>' format where '<' '>' are just angle brackets (you can change it in token_fmt_va)
|
Tokens are provided in '<'identifier'>' format where '<' '>' are just angle brackets (you can change it in token_fmt_va)
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
Example - A string with:
|
Example - A string with:
|
||||||
typedef <type> <name> <name>;
|
typedef <type> <name> <name>;
|
||||||
Will have a token_fmt arguments populated with:
|
Will have a token_fmt arguments populated with:
|
||||||
"type", strc_for_type,
|
"type", str_for_type,
|
||||||
"name", strc_for_name,
|
"name", str_for_name,
|
||||||
and:
|
and:
|
||||||
stringize( typedef <type> <name> <name>; )
|
stringize( typedef <type> <name> <name>; )
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
So the full call for this example would be:
|
So the full call for this example would be:
|
||||||
token_fmt(
|
token_fmt(
|
||||||
"type", strc_for_type
|
"type", str_for_type
|
||||||
, "name", strc_for_name
|
, "name", str_for_name
|
||||||
, stringize(
|
, stringize(
|
||||||
typedef <type> <name> <name>
|
typedef <type> <name> <name>
|
||||||
));
|
));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "gen/etoktype.cpp"
|
#include "gen/etoktype.cpp"
|
||||||
#include "interface.upfront.cpp"
|
#include "interface.upfront.cpp"
|
||||||
@ -8,25 +8,23 @@
|
|||||||
|
|
||||||
// Publically Exposed Interface
|
// Publically Exposed Interface
|
||||||
|
|
||||||
CodeClass parse_class( StrC def )
|
CodeClass parse_class( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
push_scope();
|
push_scope();
|
||||||
CodeClass result = (CodeClass) parse_class_struct( Tok_Decl_Class, parser_not_inplace_def );
|
CodeClass result = (CodeClass) parse_class_struct( Tok_Decl_Class, parser_not_inplace_def );
|
||||||
parser_pop(& Context);
|
parser_pop(& _ctx->parser);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeConstructor parse_constructor( StrC def )
|
CodeConstructor parse_constructor( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
@ -41,7 +39,7 @@ CodeConstructor parse_constructor( StrC def )
|
|||||||
|
|
||||||
while ( left && tok_is_specifier(currtok) )
|
while ( left && tok_is_specifier(currtok) )
|
||||||
{
|
{
|
||||||
Specifier spec = strc_to_specifier( tok_to_str(currtok) );
|
Specifier spec = str_to_specifier( currtok.Text );
|
||||||
|
|
||||||
b32 ignore_spec = false;
|
b32 ignore_spec = false;
|
||||||
|
|
||||||
@ -59,8 +57,8 @@ CodeConstructor parse_constructor( StrC def )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
log_failure( "Invalid specifier %s for variable\n%s", spec_to_str( spec ), parser_to_string(Context) );
|
log_failure( "Invalid specifier %s for variable\n%S", spec_to_str( spec ), parser_to_strbuilder(_ctx->parser) );
|
||||||
parser_pop(& Context);
|
parser_pop(& _ctx->parser);
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,18 +73,32 @@ CodeConstructor parse_constructor( StrC def )
|
|||||||
|
|
||||||
if ( NumSpecifiers )
|
if ( NumSpecifiers )
|
||||||
{
|
{
|
||||||
specifiers = def_specifiers( NumSpecifiers, specs_found );
|
specifiers = def_specifiers_arr( NumSpecifiers, specs_found );
|
||||||
// <specifiers> ...
|
// <specifiers> ...
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
CodeConstructor result = parser_parse_constructor( specifiers );
|
CodeConstructor result = parser_parse_constructor( specifiers );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeDestructor parse_destructor( StrC def )
|
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 )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
@ -96,225 +108,209 @@ CodeDestructor parse_destructor( StrC def )
|
|||||||
// TODO(Ed): Destructors can have prefix attributes
|
// TODO(Ed): Destructors can have prefix attributes
|
||||||
// TODO(Ed): Destructors can have virtual
|
// TODO(Ed): Destructors can have virtual
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
CodeDestructor result = parser_parse_destructor(NullCode);
|
CodeDestructor result = parser_parse_destructor(NullCode);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeEnum parse_enum( StrC def )
|
CodeEnum parse_enum( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
{
|
{
|
||||||
parser_pop(& Context);
|
parser_pop(& _ctx->parser);
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
return parser_parse_enum( parser_not_inplace_def);
|
return parser_parse_enum( parser_not_inplace_def);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeBody parse_export_body( StrC def )
|
CodeBody parse_export_body( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
return parser_parse_export_body();
|
return parser_parse_export_body();
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeExtern parse_extern_link( StrC def )
|
CodeExtern parse_extern_link( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
return parser_parse_extern_link();
|
return parser_parse_extern_link();
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeFriend parse_friend( StrC def )
|
CodeFriend parse_friend( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
return parser_parse_friend();
|
return parser_parse_friend();
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeFn parse_function( StrC def )
|
CodeFn parse_function( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
return (CodeFn) parser_parse_function();
|
return (CodeFn) parser_parse_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeBody parse_global_body( StrC def )
|
CodeBody parse_global_body( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
push_scope();
|
push_scope();
|
||||||
CodeBody result = parse_global_nspace( CT_Global_Body );
|
CodeBody result = parse_global_nspace( CT_Global_Body );
|
||||||
parser_pop(& Context);
|
parser_pop(& _ctx->parser);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeNS parse_namespace( StrC def )
|
CodeNS parse_namespace( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
return parser_parse_namespace();
|
return parser_parse_namespace();
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeOperator parse_operator( StrC def )
|
CodeOperator parse_operator( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
return (CodeOperator) parser_parse_operator();
|
return (CodeOperator) parser_parse_operator();
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeOpCast parse_operator_cast( StrC def )
|
CodeOpCast parse_operator_cast( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
return parser_parse_operator_cast(NullCode);
|
return parser_parse_operator_cast(NullCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeStruct parse_struct( StrC def )
|
CodeStruct parse_struct( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
push_scope();
|
push_scope();
|
||||||
CodeStruct result = (CodeStruct) parse_class_struct( Tok_Decl_Struct, parser_not_inplace_def );
|
CodeStruct result = (CodeStruct) parse_class_struct( Tok_Decl_Struct, parser_not_inplace_def );
|
||||||
parser_pop(& Context);
|
parser_pop(& _ctx->parser);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeTemplate parse_template( StrC def )
|
CodeTemplate parse_template( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
return parser_parse_template();
|
return parser_parse_template();
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeTypename parse_type( StrC def )
|
CodeTypename parse_type( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
return parser_parse_type( parser_not_from_template, nullptr);
|
return parser_parse_type( parser_not_from_template, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeTypedef parse_typedef( StrC def )
|
CodeTypedef parse_typedef( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
return parser_parse_typedef();
|
return parser_parse_typedef();
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeUnion parse_union( StrC def )
|
CodeUnion parse_union( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
return parser_parse_union( parser_not_inplace_def);
|
return parser_parse_union( parser_not_inplace_def);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeUsing parse_using( StrC def )
|
CodeUsing parse_using( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
return parser_parse_using();
|
return parser_parse_using();
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeVar parse_variable( StrC def )
|
CodeVar parse_variable( Str def )
|
||||||
{
|
{
|
||||||
GEN_USING_NS_PARSER;
|
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
_ctx->parser.Tokens = toks;
|
||||||
return parser_parse_variable();
|
return parser_parse_variable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "interface.parsing.cpp"
|
#include "interface.parsing.cpp"
|
||||||
#endif
|
#endif
|
||||||
@ -8,24 +8,20 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
|||||||
char const* buf_begin = buf;
|
char const* buf_begin = buf;
|
||||||
ssize remaining = buf_size;
|
ssize remaining = buf_size;
|
||||||
|
|
||||||
local_persist
|
if (_ctx->token_fmt_map.Hashes == nullptr) {
|
||||||
TokenMap_FixedArena tok_map_arena;
|
_ctx->token_fmt_map = hashtable_init(Str, _ctx->Allocator_DyanmicContainers );
|
||||||
fixed_arena_init( & tok_map_arena);
|
}
|
||||||
|
// Populate token pairs
|
||||||
local_persist
|
|
||||||
StringTable tok_map;
|
|
||||||
{
|
{
|
||||||
tok_map = hashtable_init(StrC, fixed_arena_allocator_info(& tok_map_arena) );
|
|
||||||
|
|
||||||
s32 left = num_tokens - 1;
|
s32 left = num_tokens - 1;
|
||||||
|
|
||||||
while ( left-- )
|
while ( left-- )
|
||||||
{
|
{
|
||||||
char const* token = va_arg( va, char const* );
|
char const* token = va_arg( va, char const* );
|
||||||
StrC value = va_arg( va, StrC );
|
Str value = va_arg( va, Str );
|
||||||
|
|
||||||
u32 key = crc32( token, str_len(token) );
|
u32 key = crc32( token, c_str_len(token) );
|
||||||
hashtable_set( tok_map, key, value );
|
hashtable_set( _ctx->token_fmt_map, key, value );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,8 +56,8 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
|||||||
|
|
||||||
char const* token = fmt + 1;
|
char const* token = fmt + 1;
|
||||||
|
|
||||||
u32 key = crc32( token, tok_len );
|
u32 key = crc32( token, tok_len );
|
||||||
StrC* value = hashtable_get(tok_map, key );
|
Str* value = hashtable_get(_ctx->token_fmt_map, key );
|
||||||
|
|
||||||
if ( value )
|
if ( value )
|
||||||
{
|
{
|
||||||
@ -90,16 +86,12 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
|||||||
current = * fmt;
|
current = * fmt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hashtable_clear(_ctx->token_fmt_map);
|
||||||
hashtable_clear(tok_map);
|
|
||||||
fixed_arena_free(& tok_map_arena);
|
|
||||||
|
|
||||||
ssize result = buf_size - remaining;
|
ssize result = buf_size - remaining;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code untyped_str( StrC content )
|
Code untyped_str( Str content )
|
||||||
{
|
{
|
||||||
if ( content.Len == 0 )
|
if ( content.Len == 0 )
|
||||||
{
|
{
|
||||||
@ -109,7 +101,7 @@ Code untyped_str( StrC content )
|
|||||||
|
|
||||||
Code
|
Code
|
||||||
result = make_code();
|
result = make_code();
|
||||||
result->Name = get_cached_string( content );
|
result->Name = cache_str( content );
|
||||||
result->Type = CT_Untyped;
|
result->Type = CT_Untyped;
|
||||||
result->Content = result->Name;
|
result->Content = result->Name;
|
||||||
|
|
||||||
@ -135,17 +127,14 @@ Code untyped_fmt( char const* fmt, ...)
|
|||||||
|
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
ssize length = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
|
ssize length = c_str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
Str content = { buf, length };
|
||||||
StrC buf_str = { str_len_capped(fmt, MaxNameLength), fmt };
|
|
||||||
StrC uncapped_str = { length, buf };
|
|
||||||
|
|
||||||
Code
|
Code
|
||||||
result = make_code();
|
result = make_code();
|
||||||
result->Name = get_cached_string( buf_str );
|
|
||||||
result->Type = CT_Untyped;
|
result->Type = CT_Untyped;
|
||||||
result->Content = get_cached_string( uncapped_str );
|
result->Content = cache_str( content );
|
||||||
|
|
||||||
if ( result->Name.Len == 0 )
|
if ( result->Name.Len == 0 )
|
||||||
{
|
{
|
||||||
@ -172,13 +161,12 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... )
|
|||||||
ssize length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va);
|
ssize length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
StrC buf_str = { length, buf };
|
Str buf_str = { buf, length };
|
||||||
|
|
||||||
Code
|
Code
|
||||||
result = make_code();
|
result = make_code();
|
||||||
result->Name = get_cached_string( buf_str );
|
|
||||||
result->Type = CT_Untyped;
|
result->Type = CT_Untyped;
|
||||||
result->Content = result->Name;
|
result->Content = cache_str( buf_str );
|
||||||
|
|
||||||
if ( result->Name.Len == 0 )
|
if ( result->Name.Len == 0 )
|
||||||
{
|
{
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
112
base/components/parser_case_macros.cpp
Normal file
112
base/components/parser_case_macros.cpp
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// These macros are used in the swtich cases within parser.cpp
|
||||||
|
|
||||||
|
#define GEN_PARSER_CLASS_STRUCT_BODY_ALLOWED_MEMBER_TOK_SPECIFIER_CASES \
|
||||||
|
case Tok_Spec_Consteval: \
|
||||||
|
case Tok_Spec_Constexpr: \
|
||||||
|
case Tok_Spec_Constinit: \
|
||||||
|
case Tok_Spec_Explicit: \
|
||||||
|
case Tok_Spec_ForceInline: \
|
||||||
|
case Tok_Spec_Inline: \
|
||||||
|
case Tok_Spec_Mutable: \
|
||||||
|
case Tok_Spec_NeverInline: \
|
||||||
|
case Tok_Spec_Static: \
|
||||||
|
case Tok_Spec_Volatile: \
|
||||||
|
case Tok_Spec_Virtual
|
||||||
|
|
||||||
|
#define GEN_PARSER_CLASS_STRUCT_BODY_ALLOWED_MEMBER_SPECIFIER_CASES \
|
||||||
|
case Spec_Constexpr: \
|
||||||
|
case Spec_Constinit: \
|
||||||
|
case Spec_Explicit: \
|
||||||
|
case Spec_Inline: \
|
||||||
|
case Spec_ForceInline: \
|
||||||
|
case Spec_Mutable: \
|
||||||
|
case Spec_NeverInline: \
|
||||||
|
case Spec_Static: \
|
||||||
|
case Spec_Volatile: \
|
||||||
|
case Spec_Virtual
|
||||||
|
|
||||||
|
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_TOK_SPECIFIER_CASES \
|
||||||
|
case Tok_Spec_Consteval: \
|
||||||
|
case Tok_Spec_Constexpr: \
|
||||||
|
case Tok_Spec_Constinit: \
|
||||||
|
case Tok_Spec_Extern: \
|
||||||
|
case Tok_Spec_ForceInline: \
|
||||||
|
case Tok_Spec_Global: \
|
||||||
|
case Tok_Spec_Inline: \
|
||||||
|
case Tok_Spec_Internal_Linkage: \
|
||||||
|
case Tok_Spec_NeverInline: \
|
||||||
|
case Tok_Spec_Static
|
||||||
|
|
||||||
|
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_SPECIFIER_CASES \
|
||||||
|
case Spec_Constexpr: \
|
||||||
|
case Spec_Constinit: \
|
||||||
|
case Spec_ForceInline: \
|
||||||
|
case Spec_Global: \
|
||||||
|
case Spec_External_Linkage: \
|
||||||
|
case Spec_Internal_Linkage: \
|
||||||
|
case Spec_Inline: \
|
||||||
|
case Spec_Mutable: \
|
||||||
|
case Spec_NeverInline: \
|
||||||
|
case Spec_Static: \
|
||||||
|
case Spec_Volatile
|
||||||
|
|
||||||
|
#define GEN_PARSER_FRIEND_ALLOWED_SPECIFIER_CASES \
|
||||||
|
case Spec_Const: \
|
||||||
|
case Spec_Inline: \
|
||||||
|
case Spec_ForceInline
|
||||||
|
|
||||||
|
#define GEN_PARSER_FUNCTION_ALLOWED_SPECIFIER_CASES \
|
||||||
|
case Spec_Const: \
|
||||||
|
case Spec_Consteval: \
|
||||||
|
case Spec_Constexpr: \
|
||||||
|
case Spec_External_Linkage: \
|
||||||
|
case Spec_Internal_Linkage: \
|
||||||
|
case Spec_ForceInline: \
|
||||||
|
case Spec_Inline: \
|
||||||
|
case Spec_NeverInline: \
|
||||||
|
case Spec_Static
|
||||||
|
|
||||||
|
#define GEN_PARSER_OPERATOR_ALLOWED_SPECIFIER_CASES \
|
||||||
|
case Spec_Const: \
|
||||||
|
case Spec_Constexpr: \
|
||||||
|
case Spec_ForceInline: \
|
||||||
|
case Spec_Inline: \
|
||||||
|
case Spec_NeverInline: \
|
||||||
|
case Spec_Static
|
||||||
|
|
||||||
|
#define GEN_PARSER_TEMPLATE_ALLOWED_SPECIFIER_CASES \
|
||||||
|
case Spec_Const: \
|
||||||
|
case Spec_Constexpr: \
|
||||||
|
case Spec_Constinit: \
|
||||||
|
case Spec_External_Linkage: \
|
||||||
|
case Spec_Global: \
|
||||||
|
case Spec_Inline: \
|
||||||
|
case Spec_ForceInline: \
|
||||||
|
case Spec_Local_Persist: \
|
||||||
|
case Spec_Mutable: \
|
||||||
|
case Spec_Static: \
|
||||||
|
case Spec_Thread_Local: \
|
||||||
|
case Spec_Volatile
|
||||||
|
|
||||||
|
#define GEN_PARSER_VARIABLE_ALLOWED_SPECIFIER_CASES \
|
||||||
|
case Spec_Const: \
|
||||||
|
case Spec_Constexpr: \
|
||||||
|
case Spec_Constinit: \
|
||||||
|
case Spec_External_Linkage: \
|
||||||
|
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
|
||||||
|
|
||||||
|
|
219
base/components/parser_types.hpp
Normal file
219
base/components/parser_types.hpp
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
#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 TokFlags : u32
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Token
|
||||||
|
{
|
||||||
|
Str Text;
|
||||||
|
TokType Type;
|
||||||
|
s32 Line;
|
||||||
|
s32 Column;
|
||||||
|
u32 Flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr Token NullToken { {}, Tok_Invalid, 0, 0, TF_Null };
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
AccessSpec tok_to_access_specifier(Token tok) {
|
||||||
|
return scast(AccessSpec, tok.Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
bool tok_is_valid( Token tok ) {
|
||||||
|
return tok.Text.Ptr && tok.Text.Len && tok.Type != Tok_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
bool tok_is_access_operator(Token tok) {
|
||||||
|
return bitfield_is_set( u32, tok.Flags, TF_AccessOperator );
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
bool tok_is_access_specifier(Token tok) {
|
||||||
|
return bitfield_is_set( u32, tok.Flags, TF_AccessSpecifier );
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
bool tok_is_attribute(Token tok) {
|
||||||
|
return bitfield_is_set( u32, tok.Flags, TF_Attribute );
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
bool tok_is_operator(Token tok) {
|
||||||
|
return bitfield_is_set( u32, tok.Flags, TF_Operator );
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
bool tok_is_preprocessor(Token tok) {
|
||||||
|
return bitfield_is_set( u32, tok.Flags, TF_Preprocess );
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
bool tok_is_preprocess_cond(Token tok) {
|
||||||
|
return bitfield_is_set( u32, tok.Flags, TF_Preprocess_Cond );
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
bool tok_is_specifier(Token tok) {
|
||||||
|
return bitfield_is_set( u32, tok.Flags, TF_Specifier );
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
bool tok_is_end_definition(Token tok) {
|
||||||
|
return bitfield_is_set( u32, tok.Flags, TF_EndDefinition );
|
||||||
|
}
|
||||||
|
|
||||||
|
StrBuilder tok_to_strbuilder(Token tok);
|
||||||
|
|
||||||
|
struct TokArray
|
||||||
|
{
|
||||||
|
Array(Token) Arr;
|
||||||
|
s32 Idx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LexContext
|
||||||
|
{
|
||||||
|
Str content;
|
||||||
|
s32 left;
|
||||||
|
char const* scanner;
|
||||||
|
s32 line;
|
||||||
|
s32 column;
|
||||||
|
// StringTable defines;
|
||||||
|
Token token;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StackNode
|
||||||
|
{
|
||||||
|
StackNode* Prev;
|
||||||
|
|
||||||
|
Token* Start;
|
||||||
|
Str Name; // The name of the AST node (if parsed)
|
||||||
|
Str ProcName; // The name of the procedure
|
||||||
|
};
|
||||||
|
|
||||||
|
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,109 +1,92 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../gen.hpp"
|
#include "../gen.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region StaticData
|
#pragma region StaticData
|
||||||
|
GEN_API global Context* _ctx;
|
||||||
// TODO : Convert global allocation strategy to use a slab allocation strategy.
|
GEN_API global u32 context_counter;
|
||||||
global AllocatorInfo GlobalAllocator;
|
|
||||||
global Array( Arena ) Global_AllocatorBuckets;
|
|
||||||
|
|
||||||
// TODO(Ed) : Make the code pool a dynamic arena
|
|
||||||
global Array( Pool ) CodePools = { nullptr };
|
|
||||||
global Array( Arena ) StringArenas = { nullptr };
|
|
||||||
|
|
||||||
global StringTable StringCache;
|
|
||||||
|
|
||||||
global Arena LexArena;
|
|
||||||
|
|
||||||
global AllocatorInfo Allocator_DataArrays = {0};
|
|
||||||
global AllocatorInfo Allocator_CodePool = {0};
|
|
||||||
global AllocatorInfo Allocator_Lexer = {0};
|
|
||||||
global AllocatorInfo Allocator_StringArena = {0};
|
|
||||||
global AllocatorInfo Allocator_StringTable = {0};
|
|
||||||
global AllocatorInfo Allocator_TypeTable = {0};
|
|
||||||
|
|
||||||
#pragma endregion StaticData
|
|
||||||
|
|
||||||
#pragma region Constants
|
#pragma region Constants
|
||||||
|
GEN_API global Macro enum_underlying_macro;
|
||||||
|
|
||||||
global StrC enum_underlying_sig;
|
GEN_API global Code Code_Global;
|
||||||
|
GEN_API global Code Code_Invalid;
|
||||||
|
|
||||||
global Code access_public;
|
GEN_API global Code access_public;
|
||||||
global Code access_protected;
|
GEN_API global Code access_protected;
|
||||||
global Code access_private;
|
GEN_API global Code access_private;
|
||||||
|
|
||||||
global CodeAttributes attrib_api_export;
|
GEN_API global CodeAttributes attrib_api_export;
|
||||||
global CodeAttributes attrib_api_import;
|
GEN_API global CodeAttributes attrib_api_import;
|
||||||
|
|
||||||
global Code module_global_fragment;
|
GEN_API global Code module_global_fragment;
|
||||||
global Code module_private_fragment;
|
GEN_API global Code module_private_fragment;
|
||||||
|
|
||||||
global Code fmt_newline;
|
GEN_API global Code fmt_newline;
|
||||||
|
|
||||||
global CodeParams param_varadic;
|
GEN_API global CodeParams param_varadic;
|
||||||
|
|
||||||
global CodePragma pragma_once;
|
GEN_API global CodePragma pragma_once;
|
||||||
|
|
||||||
global CodePreprocessCond preprocess_else;
|
GEN_API global CodePreprocessCond preprocess_else;
|
||||||
global CodePreprocessCond preprocess_endif;
|
GEN_API global CodePreprocessCond preprocess_endif;
|
||||||
|
|
||||||
global CodeSpecifiers spec_const;
|
GEN_API global CodeSpecifiers spec_const;
|
||||||
global CodeSpecifiers spec_consteval;
|
GEN_API global CodeSpecifiers spec_consteval;
|
||||||
global CodeSpecifiers spec_constexpr;
|
GEN_API global CodeSpecifiers spec_constexpr;
|
||||||
global CodeSpecifiers spec_constinit;
|
GEN_API global CodeSpecifiers spec_constinit;
|
||||||
global CodeSpecifiers spec_extern_linkage;
|
GEN_API global CodeSpecifiers spec_extern_linkage;
|
||||||
global CodeSpecifiers spec_final;
|
GEN_API global CodeSpecifiers spec_final;
|
||||||
global CodeSpecifiers spec_forceinline;
|
GEN_API global CodeSpecifiers spec_forceinline;
|
||||||
global CodeSpecifiers spec_global;
|
GEN_API global CodeSpecifiers spec_global;
|
||||||
global CodeSpecifiers spec_inline;
|
GEN_API global CodeSpecifiers spec_inline;
|
||||||
global CodeSpecifiers spec_internal_linkage;
|
GEN_API global CodeSpecifiers spec_internal_linkage;
|
||||||
global CodeSpecifiers spec_local_persist;
|
GEN_API global CodeSpecifiers spec_local_persist;
|
||||||
global CodeSpecifiers spec_mutable;
|
GEN_API global CodeSpecifiers spec_mutable;
|
||||||
global CodeSpecifiers spec_noexcept;
|
GEN_API global CodeSpecifiers spec_noexcept;
|
||||||
global CodeSpecifiers spec_neverinline;
|
GEN_API global CodeSpecifiers spec_neverinline;
|
||||||
global CodeSpecifiers spec_override;
|
GEN_API global CodeSpecifiers spec_override;
|
||||||
global CodeSpecifiers spec_ptr;
|
GEN_API global CodeSpecifiers spec_ptr;
|
||||||
global CodeSpecifiers spec_pure;
|
GEN_API global CodeSpecifiers spec_pure;
|
||||||
global CodeSpecifiers spec_ref;
|
GEN_API global CodeSpecifiers spec_ref;
|
||||||
global CodeSpecifiers spec_register;
|
GEN_API global CodeSpecifiers spec_register;
|
||||||
global CodeSpecifiers spec_rvalue;
|
GEN_API global CodeSpecifiers spec_rvalue;
|
||||||
global CodeSpecifiers spec_static_member;
|
GEN_API global CodeSpecifiers spec_static_member;
|
||||||
global CodeSpecifiers spec_thread_local;
|
GEN_API global CodeSpecifiers spec_thread_local;
|
||||||
global CodeSpecifiers spec_virtual;
|
GEN_API global CodeSpecifiers spec_virtual;
|
||||||
global CodeSpecifiers spec_volatile;
|
GEN_API global CodeSpecifiers spec_volatile;
|
||||||
|
|
||||||
global CodeTypename t_empty;
|
GEN_API global CodeTypename t_empty;
|
||||||
global CodeTypename t_auto;
|
GEN_API global CodeTypename t_auto;
|
||||||
global CodeTypename t_void;
|
GEN_API global CodeTypename t_void;
|
||||||
global CodeTypename t_int;
|
GEN_API global CodeTypename t_int;
|
||||||
global CodeTypename t_bool;
|
GEN_API global CodeTypename t_bool;
|
||||||
global CodeTypename t_char;
|
GEN_API global CodeTypename t_char;
|
||||||
global CodeTypename t_wchar_t;
|
GEN_API global CodeTypename t_wchar_t;
|
||||||
global CodeTypename t_class;
|
GEN_API global CodeTypename t_class;
|
||||||
global CodeTypename t_typename;
|
GEN_API global CodeTypename t_typename;
|
||||||
|
|
||||||
global Array(StringCached) PreprocessorDefines;
|
|
||||||
|
|
||||||
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||||
global CodeTypename t_b32;
|
GEN_API global CodeTypename t_b32;
|
||||||
|
|
||||||
global CodeTypename t_s8;
|
GEN_API global CodeTypename t_s8;
|
||||||
global CodeTypename t_s16;
|
GEN_API global CodeTypename t_s16;
|
||||||
global CodeTypename t_s32;
|
GEN_API global CodeTypename t_s32;
|
||||||
global CodeTypename t_s64;
|
GEN_API global CodeTypename t_s64;
|
||||||
|
|
||||||
global CodeTypename t_u8;
|
GEN_API global CodeTypename t_u8;
|
||||||
global CodeTypename t_u16;
|
GEN_API global CodeTypename t_u16;
|
||||||
global CodeTypename t_u32;
|
GEN_API global CodeTypename t_u32;
|
||||||
global CodeTypename t_u64;
|
GEN_API global CodeTypename t_u64;
|
||||||
|
|
||||||
global CodeTypename t_ssize;
|
GEN_API global CodeTypename t_ssize;
|
||||||
global CodeTypename t_usize;
|
GEN_API global CodeTypename t_usize;
|
||||||
|
|
||||||
global CodeTypename t_f32;
|
GEN_API global CodeTypename t_f32;
|
||||||
global CodeTypename t_f64;
|
GEN_API global CodeTypename t_f64;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma endregion Constants
|
#pragma endregion Constants
|
||||||
|
|
||||||
|
#pragma endregion StaticData
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "header_start.hpp"
|
#include "header_start.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -44,17 +44,17 @@ enum AccessSpec : u32
|
|||||||
static_assert( size_of(AccessSpec) == size_of(u32), "AccessSpec not u32 size" );
|
static_assert( size_of(AccessSpec) == size_of(u32), "AccessSpec not u32 size" );
|
||||||
|
|
||||||
inline
|
inline
|
||||||
StrC access_spec_to_str( AccessSpec type )
|
Str access_spec_to_str( AccessSpec type )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
StrC lookup[ (u32)AccessSpec_Num_AccessSpec ] = {
|
Str lookup[ (u32)AccessSpec_Num_AccessSpec ] = {
|
||||||
{ sizeof("") - 1, "" },
|
{ "", sizeof( "" ) - 1 },
|
||||||
{ sizeof("prviate") - 1, "private" },
|
{ "private", sizeof("prviate") - 1 },
|
||||||
{ sizeof("protected") - 1, "private" },
|
{ "private", sizeof("protected") - 1 },
|
||||||
{ sizeof("public") - 1, "public" },
|
{ "public", sizeof("public") - 1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
StrC invalid = { sizeof("Invalid") - 1, "Invalid" };
|
Str invalid = { "Invalid", sizeof("Invalid") - 1 };
|
||||||
if ( type > AccessSpec_Public )
|
if ( type > AccessSpec_Public )
|
||||||
return invalid;
|
return invalid;
|
||||||
|
|
||||||
@ -97,17 +97,17 @@ enum ModuleFlag : u32
|
|||||||
static_assert( size_of(ModuleFlag) == size_of(u32), "ModuleFlag not u32 size" );
|
static_assert( size_of(ModuleFlag) == size_of(u32), "ModuleFlag not u32 size" );
|
||||||
|
|
||||||
inline
|
inline
|
||||||
StrC module_flag_to_str( ModuleFlag flag )
|
Str module_flag_to_str( ModuleFlag flag )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
StrC lookup[ (u32)Num_ModuleFlags ] = {
|
Str lookup[ (u32)Num_ModuleFlags ] = {
|
||||||
{ sizeof("__none__"), "__none__" },
|
{ "__none__", sizeof("__none__") - 1 },
|
||||||
{ sizeof("export"), "export" },
|
{ "export", sizeof("export") - 1 },
|
||||||
{ sizeof("import"), "import" },
|
{ "import", sizeof("import") - 1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
local_persist
|
local_persist
|
||||||
StrC invalid_flag = { sizeof("invalid"), "invalid" };
|
Str invalid_flag = { "invalid", sizeof("invalid") };
|
||||||
if ( flag > ModuleFlag_Import )
|
if ( flag > ModuleFlag_Import )
|
||||||
return invalid_flag;
|
return invalid_flag;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "macros.hpp"
|
# include "macros.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "printing.hpp"
|
# include "printing.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -102,16 +102,16 @@ struct Array
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GEN_COMPILER_CPP && 0
|
#if GEN_COMPILER_CPP && 0
|
||||||
template<class Type> bool append(Array<Type>& array, Array<Type> other) { return append( & array, other ); }
|
template<class Type> bool append(Array<Type>& array, Array<Type> other) { return append( & array, other ); }
|
||||||
template<class Type> bool append(Array<Type>& array, Type value) { return append( & array, value ); }
|
template<class Type> bool append(Array<Type>& array, Type value) { return append( & array, value ); }
|
||||||
template<class Type> bool append(Array<Type>& array, Type* items, usize item_num) { return append( & array, items, item_num ); }
|
template<class Type> bool append(Array<Type>& array, Type* items, usize item_num) { return append( & array, items, item_num ); }
|
||||||
template<class Type> bool append_at(Array<Type>& array, Type item, usize idx) { return append_at( & array, item, idx ); }
|
template<class Type> bool append_at(Array<Type>& array, Type item, usize idx) { return append_at( & array, item, idx ); }
|
||||||
template<class Type> bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx) { return append_at( & array, items, item_num, idx ); }
|
template<class Type> bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx) { return append_at( & array, items, item_num, idx ); }
|
||||||
template<class Type> void free(Array<Type>& array) { return free( & array ); }
|
template<class Type> void free(Array<Type>& array) { return free( & array ); }
|
||||||
template<class Type> bool grow(Array<Type>& array, usize min_capacity) { return grow( & array, min_capacity); }
|
template<class Type> bool grow(Array<Type>& array, usize min_capacity) { return grow( & array, min_capacity); }
|
||||||
template<class Type> bool reserve(Array<Type>& array, usize new_capacity) { return reserve( & array, new_capacity); }
|
template<class Type> bool reserve(Array<Type>& array, usize new_capacity) { return reserve( & array, new_capacity); }
|
||||||
template<class Type> bool resize(Array<Type>& array, usize num) { return resize( & array, num); }
|
template<class Type> bool resize(Array<Type>& array, usize num) { return resize( & array, num); }
|
||||||
template<class Type> bool set_capacity(Array<Type>& array, usize new_capacity) { return set_capacity( & array, new_capacity); }
|
template<class Type> bool set_capacity(Array<Type>& array, usize new_capacity) { return set_capacity( & array, new_capacity); }
|
||||||
|
|
||||||
template<class Type> forceinline Type* begin(Array<Type>& array) { return array; }
|
template<class Type> forceinline Type* begin(Array<Type>& array) { return array; }
|
||||||
template<class Type> forceinline Type* end(Array<Type>& array) { return array + array_get_header(array)->Num; }
|
template<class Type> forceinline Type* end(Array<Type>& array) { return array + array_get_header(array)->Num; }
|
||||||
@ -143,13 +143,14 @@ Array<Type> array_init_reserve(AllocatorInfo allocator, ssize capacity)
|
|||||||
return {rcast(Type*, header + 1)};
|
return {rcast(Type*, header + 1)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
usize array_grow_formula(ssize value) {
|
usize array_grow_formula(ssize value) {
|
||||||
return 2 * value + 8;
|
return 2 * value + 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
bool array_append_array(Array<Type>* array, Array<Type> other) {
|
bool array_append_array(Array<Type>* array, Array<Type> other) {
|
||||||
return array_append_items(array, (Type*)other, num(other));
|
return array_append_items(array, (Type*)other, array_num(other));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
@ -179,13 +180,13 @@ bool array_append_items(Array<Type>* array, Type* items, usize item_num)
|
|||||||
GEN_ASSERT(* array != nullptr);
|
GEN_ASSERT(* array != nullptr);
|
||||||
GEN_ASSERT(items != nullptr);
|
GEN_ASSERT(items != nullptr);
|
||||||
GEN_ASSERT(item_num > 0);
|
GEN_ASSERT(item_num > 0);
|
||||||
ArrayHeader* header = array_get_header(array);
|
ArrayHeader* header = array_get_header(* array);
|
||||||
|
|
||||||
if (header->Num + item_num > header->Capacity)
|
if (header->Num + item_num > header->Capacity)
|
||||||
{
|
{
|
||||||
if ( ! grow(array, header->Capacity + item_num))
|
if ( ! array_grow(array, header->Capacity + item_num))
|
||||||
return false;
|
return false;
|
||||||
header = array_get_header(array);
|
header = array_get_header(* array);
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_copy((Type*)array + header->Num, items, item_num * sizeof(Type));
|
mem_copy((Type*)array + header->Num, items, item_num * sizeof(Type));
|
||||||
@ -202,7 +203,7 @@ bool array_append_at(Array<Type>* array, Type item, usize idx)
|
|||||||
ArrayHeader* header = array_get_header(* array);
|
ArrayHeader* header = array_get_header(* array);
|
||||||
|
|
||||||
ssize slot = idx;
|
ssize slot = idx;
|
||||||
if (slot >= header->Num)
|
if (slot >= (ssize)(header->Num))
|
||||||
slot = header->Num - 1;
|
slot = header->Num - 1;
|
||||||
|
|
||||||
if (slot < 0)
|
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);
|
ArrayHeader* header = array_get_header(array);
|
||||||
|
|
||||||
if (begin < 0 || end > header->Num)
|
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;
|
array[idx] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,6 +309,7 @@ ArrayHeader* array_get_header(Array<Type> array) {
|
|||||||
using NonConstType = TRemoveConst<Type>;
|
using NonConstType = TRemoveConst<Type>;
|
||||||
return rcast(ArrayHeader*, const_cast<NonConstType*>(Data)) - 1;
|
return rcast(ArrayHeader*, const_cast<NonConstType*>(Data)) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> forceinline
|
template<class Type> forceinline
|
||||||
bool array_grow(Array<Type>* array, usize min_capacity)
|
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(* array != nullptr);
|
GEN_ASSERT(* array != nullptr);
|
||||||
GEN_ASSERT(num > 0)
|
|
||||||
ArrayHeader* header = array_get_header(array);
|
ArrayHeader* header = array_get_header(array);
|
||||||
|
|
||||||
if (header->Capacity < new_capacity)
|
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
|
// 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)
|
// 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.
|
// 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(type, allocator) array_init <type> (allocator )
|
||||||
#define array_init_reserve(type, allocator, cap) array_init_reserve <type> (allocator, cap)
|
#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)
|
if (table.Entries[result.EntryIndex].Key == key)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
result.PrevIndex = result.EntryIndex;
|
result.PrevIndex = result.EntryIndex;
|
||||||
result.EntryIndex = table.Entries[result.EntryIndex].Next;
|
result.EntryIndex = table.Entries[result.EntryIndex].Next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -763,7 +763,7 @@ HashTableFindResult hashtable__find(HashTable<Type> table, u64 key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> forceinline
|
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.Hashes);
|
||||||
GEN_ASSERT_NOT_NULL(table.Entries);
|
GEN_ASSERT_NOT_NULL(table.Entries);
|
||||||
usize critical_load = usize(HashTable_CriticalLoadScale * f32(array_num(table.Hashes)));
|
usize critical_load = usize(HashTable_CriticalLoadScale * f32(array_num(table.Hashes)));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "src_start.cpp"
|
# include "src_start.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "dependencies/platform.hpp"
|
# include "dependencies/platform.hpp"
|
||||||
# include "dependencies/macros.hpp"
|
# include "dependencies/macros.hpp"
|
||||||
@ -8,16 +8,23 @@
|
|||||||
|
|
||||||
#pragma region Debug
|
#pragma region Debug
|
||||||
|
|
||||||
#if defined( _MSC_VER )
|
#if GEN_BUILD_DEBUG
|
||||||
# if _MSC_VER < 1300
|
# if defined( GEN_COMPILER_MSVC )
|
||||||
# define GEN_DEBUG_TRAP() __asm int 3 /* Trap to debugger! */
|
# if _MSC_VER < 1300
|
||||||
|
// #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()")
|
||||||
|
# define GEN_DEBUG_TRAP() __debugbreak()
|
||||||
|
# endif
|
||||||
|
# elif defined( GEN_COMPILER_TINYC )
|
||||||
|
# define GEN_DEBUG_TRAP() process_exit( 1 )
|
||||||
# else
|
# else
|
||||||
# define GEN_DEBUG_TRAP() __debugbreak()
|
# define GEN_DEBUG_TRAP() __builtin_trap()
|
||||||
# endif
|
# endif
|
||||||
#elif defined( GEN_COMPILER_TINYC )
|
|
||||||
# define GEN_DEBUG_TRAP() process_exit( 1 )
|
|
||||||
#else
|
#else
|
||||||
# define GEN_DEBUG_TRAP() __builtin_trap()
|
// #pragma message("GEN_BUILD_DEBUG: omitted")
|
||||||
|
# define GEN_DEBUG_TRAP()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GEN_ASSERT( cond ) GEN_ASSERT_MSG( cond, NULL )
|
#define GEN_ASSERT( cond ) GEN_ASSERT_MSG( cond, NULL )
|
||||||
@ -37,14 +44,14 @@
|
|||||||
// NOTE: Things that shouldn't happen with a message!
|
// NOTE: Things that shouldn't happen with a message!
|
||||||
#define GEN_PANIC( msg, ... ) GEN_ASSERT_MSG( 0, msg, ##__VA_ARGS__ )
|
#define GEN_PANIC( msg, ... ) GEN_ASSERT_MSG( 0, msg, ##__VA_ARGS__ )
|
||||||
|
|
||||||
#if Build_Debug
|
#if GEN_BUILD_DEBUG
|
||||||
#define GEN_FATAL( ... ) \
|
#define GEN_FATAL( ... ) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
local_persist thread_local \
|
local_persist thread_local \
|
||||||
char buf[GEN_PRINTF_MAXLEN] = { 0 }; \
|
char buf[GEN_PRINTF_MAXLEN] = { 0 }; \
|
||||||
\
|
\
|
||||||
str_fmt(buf, GEN_PRINTF_MAXLEN, __VA_ARGS__); \
|
c_str_fmt(buf, GEN_PRINTF_MAXLEN, __VA_ARGS__); \
|
||||||
GEN_PANIC(buf); \
|
GEN_PANIC(buf); \
|
||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
@ -53,14 +60,15 @@
|
|||||||
# define GEN_FATAL( ... ) \
|
# define GEN_FATAL( ... ) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
str_fmt_out_err( __VA_ARGS__ ); \
|
c_str_fmt_out_err( __VA_ARGS__ ); \
|
||||||
|
GEN_DEBUG_TRAP(); \
|
||||||
process_exit(1); \
|
process_exit(1); \
|
||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void assert_handler( char const* condition, char const* file, char const* function, s32 line, char const* msg, ... );
|
GEN_API void assert_handler( char const* condition, char const* file, char const* function, s32 line, char const* msg, ... );
|
||||||
s32 assert_crash( char const* condition );
|
GEN_API s32 assert_crash( char const* condition );
|
||||||
void process_exit( u32 code );
|
GEN_API void process_exit( u32 code );
|
||||||
|
|
||||||
#pragma endregion Debug
|
#pragma endregion Debug
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "strings.cpp"
|
# include "strings.cpp"
|
||||||
#endif
|
#endif
|
||||||
@ -18,7 +18,7 @@ wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, ssize* w_len_ )
|
|||||||
*w_len_ = w_len;
|
*w_len_ = w_len;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
len = str_len( text );
|
len = c_str_len( text );
|
||||||
if ( len == 0 )
|
if ( len == 0 )
|
||||||
{
|
{
|
||||||
if ( w_len_ )
|
if ( w_len_ )
|
||||||
@ -284,7 +284,7 @@ GEN_FILE_OPEN_PROC( _posix_file_open )
|
|||||||
|
|
||||||
internal void _dirinfo_free_entry( DirEntry* entry );
|
internal void _dirinfo_free_entry( DirEntry* entry );
|
||||||
|
|
||||||
// TODO : Is this a bad idea?
|
// TODO(zpl) : Is this a bad idea?
|
||||||
global b32 _std_file_set = false;
|
global b32 _std_file_set = false;
|
||||||
global FileInfo _std_files[ EFileStandard_COUNT ] = {
|
global FileInfo _std_files[ EFileStandard_COUNT ] = {
|
||||||
{
|
{
|
||||||
@ -375,7 +375,7 @@ FileError file_close( FileInfo* f )
|
|||||||
FileError file_new( FileInfo* f, FileDescriptor fd, FileOperations ops, char const* filename )
|
FileError file_new( FileInfo* f, FileDescriptor fd, FileOperations ops, char const* filename )
|
||||||
{
|
{
|
||||||
FileError err = EFileError_NONE;
|
FileError err = EFileError_NONE;
|
||||||
ssize len = str_len( filename );
|
ssize len = c_str_len( filename );
|
||||||
|
|
||||||
f->ops = ops;
|
f->ops = ops;
|
||||||
f->fd = fd;
|
f->fd = fd;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "strings.hpp"
|
# include "strings.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -93,7 +93,7 @@ struct DirInfo
|
|||||||
|
|
||||||
// Internals
|
// Internals
|
||||||
char** filenames; // zpl_array
|
char** filenames; // zpl_array
|
||||||
String buf;
|
StrBuilder buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FileInfo
|
struct FileInfo
|
||||||
@ -121,20 +121,20 @@ enum FileStandardType
|
|||||||
* @param std Check zpl_file_standard_type
|
* @param std Check zpl_file_standard_type
|
||||||
* @return File handle to standard I/O
|
* @return File handle to standard I/O
|
||||||
*/
|
*/
|
||||||
FileInfo* file_get_standard( FileStandardType std );
|
GEN_API FileInfo* file_get_standard( FileStandardType std );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the file
|
* Closes the file
|
||||||
* @param file
|
* @param file
|
||||||
*/
|
*/
|
||||||
FileError file_close( FileInfo* file );
|
GEN_API FileError file_close( FileInfo* file );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the currently opened file's name
|
* Returns the currently opened file's name
|
||||||
* @param file
|
* @param file
|
||||||
*/
|
*/
|
||||||
inline
|
inline
|
||||||
char const* file_name( FileInfo* file )
|
char const* file_name( FileInfo* file )
|
||||||
{
|
{
|
||||||
return file->filename ? file->filename : "";
|
return file->filename ? file->filename : "";
|
||||||
}
|
}
|
||||||
@ -144,7 +144,7 @@ inline
|
|||||||
* @param file
|
* @param file
|
||||||
* @param filename
|
* @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
|
* 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 mode Access mode to use
|
||||||
* @param filename
|
* @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
|
* Reads from a file
|
||||||
@ -200,14 +200,14 @@ constexpr b32 file_no_zero_terminate = false;
|
|||||||
* @param filepath Path to the file
|
* @param filepath Path to the file
|
||||||
* @return File contents data
|
* @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
|
* Returns a size of the file
|
||||||
* @param file
|
* @param file
|
||||||
* @return File size
|
* @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
|
* Seeks the file cursor from the beginning of file to a specific position
|
||||||
@ -274,7 +274,7 @@ enum FileStreamFlags : u32
|
|||||||
* @param file
|
* @param file
|
||||||
* @param allocator
|
* @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
|
* 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 size Buffer's size
|
||||||
* @param flags
|
* @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.
|
* Retrieves the stream's underlying buffer and buffer size.
|
||||||
* @param file memory stream
|
* @param file memory stream
|
||||||
* @param size (Optional) buffer size
|
* @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;
|
extern FileOperations const memory_file_operations;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "memory.cpp"
|
# include "memory.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "containers.hpp"
|
#include "containers.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region Hashing
|
#pragma region Hashing
|
||||||
|
|
||||||
u32 crc32( void const* data, ssize len );
|
GEN_API u32 crc32( void const* data, ssize len );
|
||||||
u64 crc64( void const* data, ssize len );
|
GEN_API u64 crc64( void const* data, ssize len );
|
||||||
|
|
||||||
#pragma endregion Hashing
|
#pragma endregion Hashing
|
||||||
|
@ -1,12 +1,36 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "platform.hpp"
|
# include "platform.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region Macros
|
#pragma region Macros
|
||||||
|
|
||||||
#ifndef global
|
#ifndef GEN_API
|
||||||
#define global static // Global variables
|
#if GEN_COMPILER_MSVC
|
||||||
|
#ifdef GEN_DYN_LINK
|
||||||
|
#ifdef GEN_DYN_EXPORT
|
||||||
|
#define GEN_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define GEN_API __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define GEN_API // Empty for static builds
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef GEN_DYN_LINK
|
||||||
|
#define GEN_API __attribute__((visibility("default")))
|
||||||
|
#else
|
||||||
|
#define GEN_API // Empty for static builds
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif // GEN_API
|
||||||
|
|
||||||
|
#ifndef global // Global variables
|
||||||
|
# if defined(GEN_STATIC_LINK) || defined(GEN_DYN_LINK)
|
||||||
|
# define global
|
||||||
|
# else
|
||||||
|
# define global static
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef internal
|
#ifndef internal
|
||||||
#define internal static // Internal linkage
|
#define internal static // Internal linkage
|
||||||
@ -16,8 +40,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef bit
|
#ifndef bit
|
||||||
#define bit( Value ) ( 1 << Value )
|
#define bit( Value ) ( 1 << Value )
|
||||||
#define bitfield_is_equal( Type, Field, Mask ) ( (scast(Type, Mask) & scast(Type, Field)) == scast(Type, Mask) )
|
#endif
|
||||||
|
|
||||||
|
#ifndef bitfield_is_set
|
||||||
|
#define bitfield_is_set( Type, Field, Mask ) ( (scast(Type, Mask) & scast(Type, Field)) == scast(Type, Mask) )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Mainly intended for forcing the base library to utilize only C-valid constructs or type coercion
|
// Mainly intended for forcing the base library to utilize only C-valid constructs or type coercion
|
||||||
@ -68,8 +95,16 @@
|
|||||||
#define stringize( ... ) stringize_va( __VA_ARGS__ )
|
#define stringize( ... ) stringize_va( __VA_ARGS__ )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define src_line_str stringize(__LINE__)
|
||||||
|
|
||||||
#ifndef do_once
|
#ifndef do_once
|
||||||
#define do_once( statement ) for ( local_persist b32 once = true; once; once = false, (statement) )
|
#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 \
|
#define do_once_start \
|
||||||
do \
|
do \
|
||||||
@ -224,9 +259,9 @@
|
|||||||
# if ! GEN_COMPILER_C
|
# if ! GEN_COMPILER_C
|
||||||
# define typeof decltype
|
# define typeof decltype
|
||||||
# elif defined(_MSC_VER)
|
# elif defined(_MSC_VER)
|
||||||
# define typeof(x) __typeof__(x)
|
# define typeof __typeof__
|
||||||
# elif defined(__GNUC__) || defined(__clang__)
|
# elif defined(__GNUC__) || defined(__clang__)
|
||||||
# define typeof(x) __typeof__(x)
|
# define typeof __typeof__
|
||||||
# else
|
# else
|
||||||
# error "Compiler not supported"
|
# error "Compiler not supported"
|
||||||
# endif
|
# endif
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "printing.cpp"
|
# include "printing.cpp"
|
||||||
#endif
|
#endif
|
||||||
@ -84,13 +84,13 @@ void heap_stats_check( void )
|
|||||||
typedef struct _heap_alloc_info _heap_alloc_info;
|
typedef struct _heap_alloc_info _heap_alloc_info;
|
||||||
struct _heap_alloc_info
|
struct _heap_alloc_info
|
||||||
{
|
{
|
||||||
ssize size;
|
ssize size;
|
||||||
void* physical_start;
|
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* 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( allocator_data );
|
||||||
// unused( old_size );
|
// unused( old_size );
|
||||||
if ( ! alignment )
|
if ( ! alignment )
|
||||||
@ -346,25 +346,25 @@ void* arena_allocator_proc( void* allocator_data, AllocType type, ssize size, ss
|
|||||||
switch ( type )
|
switch ( type )
|
||||||
{
|
{
|
||||||
case EAllocation_ALLOC :
|
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 );
|
// zpl__printf_err("%s", "Arena out of memory\n");
|
||||||
ssize total_size = align_forward_s64( size, alignment );
|
GEN_FATAL("Arena out of memory! (Possibly could not fit for the largest size Arena!!)");
|
||||||
|
|
||||||
// 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 );
|
|
||||||
}
|
}
|
||||||
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 :
|
case EAllocation_FREE :
|
||||||
// NOTE: Free all at once
|
// NOTE: Free all at once
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "debug.hpp"
|
# include "debug.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -41,10 +41,10 @@ void const* pointer_add_const( void const* ptr, ssize bytes );
|
|||||||
ssize pointer_diff( void const* begin, void const* end );
|
ssize pointer_diff( void const* begin, void const* end );
|
||||||
|
|
||||||
//! Copy non-overlapping memory from source to destination.
|
//! 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.
|
//! 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.
|
//! Copy memory from source to destination.
|
||||||
void* mem_move( void* dest, void const* source, ssize size );
|
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 */
|
/* define GEN_HEAP_ANALYSIS to enable this feature */
|
||||||
/* call zpl_heap_stats_init at the beginning of the entry point */
|
/* 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 */
|
/* you can call zpl_heap_stats_check near the end of the execution to validate any possible leaks */
|
||||||
void heap_stats_init( void );
|
GEN_API void heap_stats_init( void );
|
||||||
ssize heap_stats_used_memory( void );
|
GEN_API ssize heap_stats_used_memory( void );
|
||||||
ssize heap_stats_alloc_count( void );
|
GEN_API ssize heap_stats_alloc_count( void );
|
||||||
void heap_stats_check( void );
|
GEN_API void heap_stats_check( void );
|
||||||
|
|
||||||
//! Allocate/Resize memory using default options.
|
//! Allocate/Resize memory using default options.
|
||||||
|
|
||||||
//! Use this if you don't need a "fancy" resize allocation
|
//! 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* 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.
|
//! The heap allocator backed by operating system's memory manager.
|
||||||
constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; }
|
constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; }
|
||||||
@ -147,25 +147,25 @@ struct VirtualMemory
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! Initialize virtual memory from existing data.
|
//! 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.
|
//! 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 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.
|
//! @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.
|
//! Release the virtual memory.
|
||||||
b32 vm_free( VirtualMemory vm );
|
GEN_API b32 vm_free( VirtualMemory vm );
|
||||||
|
|
||||||
//! Trim virtual memory.
|
//! 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.
|
//! Purge virtual memory.
|
||||||
b32 vm_purge( VirtualMemory vm );
|
GEN_API b32 vm_purge( VirtualMemory vm );
|
||||||
|
|
||||||
//! Retrieve VM's page size and alignment.
|
//! 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
|
#pragma region Arena
|
||||||
struct Arena;
|
struct Arena;
|
||||||
@ -173,7 +173,7 @@ struct Arena;
|
|||||||
AllocatorInfo arena_allocator_info( Arena* arena );
|
AllocatorInfo arena_allocator_info( Arena* arena );
|
||||||
|
|
||||||
// Remove static keyword and rename allocator_proc
|
// 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
|
// Add these declarations after the Arena struct
|
||||||
Arena arena_init_from_allocator(AllocatorInfo backing, ssize size);
|
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
|
// This id is defined by Unreal for asserts
|
||||||
#pragma push_macro("check")
|
#pragma push_macro("check")
|
||||||
#undef 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")
|
#pragma pop_macro("check")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
inline
|
inline
|
||||||
AllocatorInfo arena_allocator_info( Arena* arena ) {
|
AllocatorInfo arena_allocator_info( Arena* arena ) {
|
||||||
GEN_ASSERT(arena != nullptr);
|
GEN_ASSERT(arena != nullptr);
|
||||||
@ -383,18 +382,18 @@ using FixedArena_4MB = FixedArena< megabytes( 4 ) >;
|
|||||||
#pragma region Pool
|
#pragma region Pool
|
||||||
struct 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(AllocatorInfo backing, ssize num_blocks, ssize block_size);
|
||||||
Pool pool_init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align);
|
Pool pool_init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align);
|
||||||
AllocatorInfo pool_allocator_info(Pool* pool);
|
AllocatorInfo pool_allocator_info(Pool* pool);
|
||||||
void pool_clear(Pool* pool);
|
GEN_API void pool_clear(Pool* pool);
|
||||||
void pool_free(Pool* pool);
|
void pool_free(Pool* pool);
|
||||||
|
|
||||||
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
|
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
|
||||||
AllocatorInfo allocator_info(Pool& pool) { return pool_allocator_info(& pool); }
|
forceinline AllocatorInfo allocator_info(Pool& pool) { return pool_allocator_info(& pool); }
|
||||||
void clear(Pool& pool) { return pool_clear(& pool); }
|
forceinline void clear(Pool& pool) { return pool_clear(& pool); }
|
||||||
void free(Pool& pool) { return pool_free(& pool); }
|
forceinline void free(Pool& pool) { return pool_free(& pool); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct Pool
|
struct Pool
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "parsing.hpp"
|
# include "parsing.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -8,7 +8,7 @@
|
|||||||
#define _adt_fprintf( s_, fmt_, ... ) \
|
#define _adt_fprintf( s_, fmt_, ... ) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
if ( str_fmt_file( s_, fmt_, ##__VA_ARGS__ ) < 0 ) \
|
if ( c_str_fmt_file( s_, fmt_, ##__VA_ARGS__ ) < 0 ) \
|
||||||
return EADT_ERROR_OUT_OF_MEMORY; \
|
return EADT_ERROR_OUT_OF_MEMORY; \
|
||||||
} while ( 0 )
|
} while ( 0 )
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search )
|
|||||||
|
|
||||||
for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
|
for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
|
||||||
{
|
{
|
||||||
if ( ! str_compare( node->nodes[ i ].name, name ) )
|
if ( ! c_str_compare( node->nodes[ i ].name, name ) )
|
||||||
{
|
{
|
||||||
return ( node->nodes + i );
|
return ( node->nodes + i );
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value )
|
|||||||
case EADT_TYPE_MULTISTRING :
|
case EADT_TYPE_MULTISTRING :
|
||||||
case EADT_TYPE_STRING :
|
case EADT_TYPE_STRING :
|
||||||
{
|
{
|
||||||
if ( node->string && ! str_compare( node->string, value ) )
|
if ( node->string && ! c_str_compare( node->string, value ) )
|
||||||
{
|
{
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value )
|
|||||||
ssize fsize = 0;
|
ssize fsize = 0;
|
||||||
u8* buf = file_stream_buf( &tmp, &fsize );
|
u8* buf = file_stream_buf( &tmp, &fsize );
|
||||||
|
|
||||||
if ( ! str_compare( ( char const* )buf, value ) )
|
if ( ! c_str_compare( ( char const* )buf, value ) )
|
||||||
{
|
{
|
||||||
file_close( &tmp );
|
file_close( &tmp );
|
||||||
return node;
|
return node;
|
||||||
@ -135,7 +135,7 @@ internal ADT_Node* _adt_get_field( ADT_Node* node, char* name, char* value )
|
|||||||
{
|
{
|
||||||
for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
|
for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
|
||||||
{
|
{
|
||||||
if ( ! str_compare( node->nodes[ i ].name, name ) )
|
if ( ! c_str_compare( node->nodes[ i ].name, name ) )
|
||||||
{
|
{
|
||||||
ADT_Node* child = &node->nodes[ i ];
|
ADT_Node* child = &node->nodes[ i ];
|
||||||
if ( _adt_get_value( child, value ) )
|
if ( _adt_get_value( child, value ) )
|
||||||
@ -168,22 +168,22 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined EADT_URI_DEBUG || 0
|
#if defined EADT_URI_DEBUG || 0
|
||||||
str_fmt_out( "uri: %s\n", uri );
|
c_str_fmt_out( "uri: %s\n", uri );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char * p = ( char* )uri, *b = p, *e = p;
|
char * p = ( char* )uri, *b = p, *e = p;
|
||||||
ADT_Node* found_node = NULL;
|
ADT_Node* found_node = NULL;
|
||||||
|
|
||||||
b = p;
|
b = p;
|
||||||
p = e = ( char* )str_skip( p, '/' );
|
p = e = ( char* )c_str_skip( p, '/' );
|
||||||
char* buf = str_fmt_buf( "%.*s", ( int )( e - b ), b );
|
char* buf = c_str_fmt_buf( "%.*s", ( int )( e - b ), b );
|
||||||
|
|
||||||
/* handle field value lookup */
|
/* handle field value lookup */
|
||||||
if ( *b == '[' )
|
if ( *b == '[' )
|
||||||
{
|
{
|
||||||
char *l_p = buf + 1, *l_b = l_p, *l_e = l_p, *l_b2 = l_p, *l_e2 = l_p;
|
char *l_p = buf + 1, *l_b = l_p, *l_e = l_p, *l_b2 = l_p, *l_e2 = l_p;
|
||||||
l_e = ( char* )str_skip( l_p, '=' );
|
l_e = ( char* )c_str_skip( l_p, '=' );
|
||||||
l_e2 = ( char* )str_skip( l_p, ']' );
|
l_e2 = ( char* )c_str_skip( l_p, ']' );
|
||||||
|
|
||||||
if ( ( ! *l_e && node->type != EADT_TYPE_ARRAY ) || ! *l_e2 )
|
if ( ( ! *l_e && node->type != EADT_TYPE_ARRAY ) || ! *l_e2 )
|
||||||
{
|
{
|
||||||
@ -257,7 +257,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
|
|||||||
/* handle array index lookup */
|
/* handle array index lookup */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ssize idx = ( ssize )str_to_i64( buf, NULL, 10 );
|
ssize idx = ( ssize )c_str_to_i64( buf, NULL, 10 );
|
||||||
if ( idx >= 0 && idx < scast(ssize, array_num(node->nodes)) )
|
if ( idx >= 0 && idx < scast(ssize, array_num(node->nodes)) )
|
||||||
{
|
{
|
||||||
found_node = &node->nodes[ idx ];
|
found_node = &node->nodes[ idx ];
|
||||||
@ -511,7 +511,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( ! str_compare_len( e, "0x", 2 ) || ! str_compare_len( e, "0X", 2 ) )
|
if ( ! c_str_compare_len( e, "0x", 2 ) || ! c_str_compare_len( e, "0X", 2 ) )
|
||||||
{
|
{
|
||||||
node_props = EADT_PROPS_IS_HEX;
|
node_props = EADT_PROPS_IS_HEX;
|
||||||
}
|
}
|
||||||
@ -575,12 +575,12 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
orig_exp = exp = ( u8 )str_to_i64( expbuf, NULL, 10 );
|
orig_exp = exp = ( u8 )c_str_to_i64( expbuf, NULL, 10 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( node_type == EADT_TYPE_INTEGER )
|
if ( node_type == EADT_TYPE_INTEGER )
|
||||||
{
|
{
|
||||||
node->integer = str_to_i64( buf, 0, 0 );
|
node->integer = c_str_to_i64( buf, 0, 0 );
|
||||||
#ifndef GEN_PARSER_DISABLE_ANALYSIS
|
#ifndef GEN_PARSER_DISABLE_ANALYSIS
|
||||||
/* special case: negative zero */
|
/* special case: negative zero */
|
||||||
if ( node->integer == 0 && buf[ 0 ] == '-' )
|
if ( node->integer == 0 && buf[ 0 ] == '-' )
|
||||||
@ -595,19 +595,19 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
node->real = str_to_f64( buf, 0 );
|
node->real = c_str_to_f64( buf, 0 );
|
||||||
|
|
||||||
#ifndef GEN_PARSER_DISABLE_ANALYSIS
|
#ifndef GEN_PARSER_DISABLE_ANALYSIS
|
||||||
char *q = buf, *base_string = q, *base_string2 = q;
|
char *q = buf, *base_string = q, *base_string2 = q;
|
||||||
base_string = ccast( char*, str_skip( base_string, '.' ));
|
base_string = ccast( char*, c_str_skip( base_string, '.' ));
|
||||||
*base_string = '\0';
|
*base_string = '\0';
|
||||||
base_string2 = base_string + 1;
|
base_string2 = base_string + 1;
|
||||||
char* base_string_off = base_string2;
|
char* base_strbuilder_off = base_string2;
|
||||||
while ( *base_string_off++ == '0' )
|
while ( *base_strbuilder_off++ == '0' )
|
||||||
base2_offset++;
|
base2_offset++;
|
||||||
|
|
||||||
base = ( s32 )str_to_i64( q, 0, 0 );
|
base = ( s32 )c_str_to_i64( q, 0, 0 );
|
||||||
base2 = ( s32 )str_to_i64( base_string2, 0, 0 );
|
base2 = ( s32 )c_str_to_i64( base_string2, 0, 0 );
|
||||||
if ( exp )
|
if ( exp )
|
||||||
{
|
{
|
||||||
exp = exp * ( ! ( eb == 10.0f ) ? -1 : 1 );
|
exp = exp * ( ! ( eb == 10.0f ) ? -1 : 1 );
|
||||||
@ -750,7 +750,7 @@ ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
p = str_skip_any( p, escaped_chars );
|
p = c_str_skip_any( p, escaped_chars );
|
||||||
_adt_fprintf( file, "%.*s", pointer_diff( b, p ), b );
|
_adt_fprintf( file, "%.*s", pointer_diff( b, p ), b );
|
||||||
if ( *p && ! ! char_first_occurence( escaped_chars, *p ) )
|
if ( *p && ! ! char_first_occurence( escaped_chars, *p ) )
|
||||||
{
|
{
|
||||||
@ -763,7 +763,7 @@ ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_
|
|||||||
return EADT_ERROR_NONE;
|
return EADT_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADT_Error adt_str_to_number( ADT_Node* node )
|
ADT_Error adt_c_str_to_number( ADT_Node* node )
|
||||||
{
|
{
|
||||||
GEN_ASSERT( node );
|
GEN_ASSERT( node );
|
||||||
|
|
||||||
@ -779,7 +779,7 @@ ADT_Error adt_str_to_number( ADT_Node* node )
|
|||||||
return EADT_ERROR_NONE;
|
return EADT_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADT_Error adt_str_to_number_strict( ADT_Node* node )
|
ADT_Error adt_c_str_to_number_strict( ADT_Node* node )
|
||||||
{
|
{
|
||||||
GEN_ASSERT( node );
|
GEN_ASSERT( node );
|
||||||
|
|
||||||
@ -826,7 +826,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
char delimiter = 0;
|
char delimiter = 0;
|
||||||
currentChar = ccast( char*, str_trim( currentChar, false ));
|
currentChar = ccast( char*, c_str_trim( currentChar, false ));
|
||||||
|
|
||||||
if ( *currentChar == 0 )
|
if ( *currentChar == 0 )
|
||||||
break;
|
break;
|
||||||
@ -850,7 +850,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
|||||||
#endif
|
#endif
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
endChar = ccast( char*, str_skip( endChar, '"' ));
|
endChar = ccast( char*, c_str_skip( endChar, '"' ));
|
||||||
|
|
||||||
if ( *endChar && *( endChar + 1 ) == '"' )
|
if ( *endChar && *( endChar + 1 ) == '"' )
|
||||||
{
|
{
|
||||||
@ -869,7 +869,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
|||||||
}
|
}
|
||||||
|
|
||||||
*endChar = 0;
|
*endChar = 0;
|
||||||
currentChar = ccast( char*, str_trim( endChar + 1, true ));
|
currentChar = ccast( char*, c_str_trim( endChar + 1, true ));
|
||||||
delimiter = * currentChar;
|
delimiter = * currentChar;
|
||||||
|
|
||||||
/* unescape escaped quotes (so that unescaped text escapes :) */
|
/* unescape escaped quotes (so that unescaped text escapes :) */
|
||||||
@ -879,7 +879,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
|||||||
{
|
{
|
||||||
if ( *escapedChar == '"' && *( escapedChar + 1 ) == '"' )
|
if ( *escapedChar == '"' && *( escapedChar + 1 ) == '"' )
|
||||||
{
|
{
|
||||||
mem_move( escapedChar, escapedChar + 1, str_len( escapedChar ) );
|
mem_move( escapedChar, escapedChar + 1, c_str_len( escapedChar ) );
|
||||||
}
|
}
|
||||||
escapedChar++;
|
escapedChar++;
|
||||||
}
|
}
|
||||||
@ -906,7 +906,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
|||||||
|
|
||||||
if ( * endChar )
|
if ( * endChar )
|
||||||
{
|
{
|
||||||
currentChar = ccast( char*, str_trim( endChar, true ));
|
currentChar = ccast( char*, c_str_trim( endChar, true ));
|
||||||
|
|
||||||
while ( char_is_space( *( endChar - 1 ) ) )
|
while ( char_is_space( *( endChar - 1 ) ) )
|
||||||
{
|
{
|
||||||
@ -927,7 +927,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
|||||||
char* num_p = beginChar;
|
char* num_p = beginChar;
|
||||||
|
|
||||||
// We only consider hexadecimal values if they start with 0x
|
// We only consider hexadecimal values if they start with 0x
|
||||||
if ( str_len(num_p) > 2 && num_p[0] == '0' && (num_p[1] == 'x' || num_p[1] == 'X') )
|
if ( c_str_len(num_p) > 2 && num_p[0] == '0' && (num_p[1] == 'x' || num_p[1] == 'X') )
|
||||||
{
|
{
|
||||||
num_p += 2; // skip '0x' prefix
|
num_p += 2; // skip '0x' prefix
|
||||||
do
|
do
|
||||||
@ -946,7 +946,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
|||||||
|
|
||||||
if (!skip_number)
|
if (!skip_number)
|
||||||
{
|
{
|
||||||
adt_str_to_number(&rowItem);
|
adt_c_str_to_number(&rowItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1021,16 +1021,16 @@ void _csv_write_record( FileInfo* file, CSV_Object* node )
|
|||||||
{
|
{
|
||||||
case EADT_NAME_STYLE_DOUBLE_QUOTE :
|
case EADT_NAME_STYLE_DOUBLE_QUOTE :
|
||||||
{
|
{
|
||||||
str_fmt_file( file, "\"" );
|
c_str_fmt_file( file, "\"" );
|
||||||
adt_print_string( file, node, "\"", "\"" );
|
adt_print_string( file, node, "\"", "\"" );
|
||||||
str_fmt_file( file, "\"" );
|
c_str_fmt_file( file, "\"" );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EADT_NAME_STYLE_NO_QUOTES :
|
case EADT_NAME_STYLE_NO_QUOTES :
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
str_fmt_file( file, "%s", node->string );
|
c_str_fmt_file( file, "%s", node->string );
|
||||||
#ifndef GEN_PARSER_DISABLE_ANALYSIS
|
#ifndef GEN_PARSER_DISABLE_ANALYSIS
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1078,10 +1078,10 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter )
|
|||||||
_csv_write_header( file, &obj->nodes[ i ] );
|
_csv_write_header( file, &obj->nodes[ i ] );
|
||||||
if ( i + 1 != cols )
|
if ( i + 1 != cols )
|
||||||
{
|
{
|
||||||
str_fmt_file( file, "%c", delimiter );
|
c_str_fmt_file( file, "%c", delimiter );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
str_fmt_file( file, "\n" );
|
c_str_fmt_file( file, "\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( ssize r = 0; r < rows; r++ )
|
for ( ssize r = 0; r < rows; r++ )
|
||||||
@ -1091,14 +1091,14 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter )
|
|||||||
_csv_write_record( file, &obj->nodes[ i ].nodes[ r ] );
|
_csv_write_record( file, &obj->nodes[ i ].nodes[ r ] );
|
||||||
if ( i + 1 != cols )
|
if ( i + 1 != cols )
|
||||||
{
|
{
|
||||||
str_fmt_file( file, "%c", delimiter );
|
c_str_fmt_file( file, "%c", delimiter );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
str_fmt_file( file, "\n" );
|
c_str_fmt_file( file, "\n" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimiter )
|
StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delimiter )
|
||||||
{
|
{
|
||||||
FileInfo tmp;
|
FileInfo tmp;
|
||||||
file_stream_new( &tmp, a );
|
file_stream_new( &tmp, a );
|
||||||
@ -1106,7 +1106,7 @@ String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimi
|
|||||||
|
|
||||||
ssize fsize;
|
ssize fsize;
|
||||||
u8* buf = file_stream_buf( &tmp, &fsize );
|
u8* buf = file_stream_buf( &tmp, &fsize );
|
||||||
String output = string_make_length( a, ( char* )buf, fsize );
|
StrBuilder output = strbuilder_make_length( a, ( char* )buf, fsize );
|
||||||
file_close( &tmp );
|
file_close( &tmp );
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "timing.hpp"
|
# include "timing.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -122,7 +122,7 @@ struct ADT_Node
|
|||||||
* @param is_array
|
* @param is_array
|
||||||
* @return error code
|
* @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
|
* @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
|
* @param node
|
||||||
* @return error code
|
* @return error code
|
||||||
*/
|
*/
|
||||||
u8 adt_destroy_branch( ADT_Node* node );
|
GEN_API u8 adt_destroy_branch( ADT_Node* node );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialise an ADT leaf
|
* @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)
|
* @param type Node's type (use zpl_adt_make_branch for container nodes)
|
||||||
* @return error code
|
* @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
|
* @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.
|
* @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
|
* @param deep_search Perform search recursively
|
||||||
* @return zpl_adt_node * node
|
* @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.
|
* @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
|
* @param index
|
||||||
* @return zpl_adt_node * node
|
* @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.
|
* @brief Allocate an unitialised node within a container.
|
||||||
@ -187,7 +187,7 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index );
|
|||||||
* @param parent
|
* @param parent
|
||||||
* @return zpl_adt_node * node
|
* @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.
|
* @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
|
* @param index
|
||||||
* @return zpl_adt_node * node
|
* @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.
|
* @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
|
* @param new_parent
|
||||||
* @return zpl_adt_node * node
|
* @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.
|
* @brief Swap two nodes.
|
||||||
@ -215,7 +215,7 @@ ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent );
|
|||||||
* @param other_node
|
* @param other_node
|
||||||
* @return
|
* @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.
|
* @brief Remove node from container.
|
||||||
@ -223,7 +223,7 @@ void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node );
|
|||||||
* @param node
|
* @param node
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
void adt_remove_node( ADT_Node* node );
|
GEN_API void adt_remove_node( ADT_Node* node );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialise a node as an object
|
* @brief Initialise a node as an object
|
||||||
@ -233,7 +233,7 @@ void adt_remove_node( ADT_Node* node );
|
|||||||
* @param backing
|
* @param backing
|
||||||
* @return
|
* @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
|
* @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
|
* @param backing
|
||||||
* @return
|
* @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
|
* @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
|
* @param value
|
||||||
* @return
|
* @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
|
* @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
|
* @param value
|
||||||
* @return
|
* @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
|
* @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
|
* @param value
|
||||||
* @return
|
* @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
|
* @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
|
* @param name
|
||||||
* @return*
|
* @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
|
* @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
|
* @param name
|
||||||
* @return*
|
* @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
|
* @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
|
* @param value
|
||||||
* @return*
|
* @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
|
* @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
|
* @param value
|
||||||
* @return*
|
* @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
|
* @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
|
* @param value
|
||||||
* @return*
|
* @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 */
|
/* parser helpers */
|
||||||
|
|
||||||
@ -332,7 +332,7 @@ ADT_Node* adt_append_int( ADT_Node* parent, char const* name, s64 value );
|
|||||||
* @param base
|
* @param base
|
||||||
* @return*
|
* @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.
|
* @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
|
* @param base
|
||||||
* @return*
|
* @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.
|
* @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
|
* @param node
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ADT_Error adt_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.
|
* @brief Parses and converts an existing string node into a number.
|
||||||
@ -359,7 +359,7 @@ ADT_Error adt_str_to_number( ADT_Node* node );
|
|||||||
* @param node
|
* @param node
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ADT_Error adt_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.
|
* @brief Prints a number into a file stream.
|
||||||
@ -371,7 +371,7 @@ ADT_Error adt_str_to_number_strict( ADT_Node* node );
|
|||||||
* @param node
|
* @param node
|
||||||
* @return
|
* @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.
|
* @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
|
* @param escape_symbol
|
||||||
* @return
|
* @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
|
#pragma endregion ADT
|
||||||
|
|
||||||
@ -401,14 +401,14 @@ enum CSV_Error : u32
|
|||||||
|
|
||||||
typedef ADT_Node CSV_Object;
|
typedef ADT_Node CSV_Object;
|
||||||
|
|
||||||
u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header );
|
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 );
|
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_free( CSV_Object* obj );
|
||||||
|
|
||||||
void csv_write( FileInfo* file, CSV_Object* obj );
|
void csv_write( FileInfo* file, CSV_Object* obj );
|
||||||
String csv_write_string( AllocatorInfo a, CSV_Object* obj );
|
StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj );
|
||||||
void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
|
GEN_API void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
|
||||||
String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
|
GEN_API StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
|
||||||
|
|
||||||
/* inline */
|
/* inline */
|
||||||
|
|
||||||
@ -425,9 +425,9 @@ void csv_write( FileInfo* file, CSV_Object* obj )
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
String csv_write_string( AllocatorInfo a, CSV_Object* obj )
|
StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj )
|
||||||
{
|
{
|
||||||
return csv_write_string_delimiter( a, obj, ',' );
|
return csv_write_strbuilder_delimiter( a, obj, ',' );
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion CSV
|
#pragma endregion CSV
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -143,27 +143,15 @@
|
|||||||
|
|
||||||
#if GEN_DONT_USE_NAMESPACE || GEN_COMPILER_C
|
#if GEN_DONT_USE_NAMESPACE || GEN_COMPILER_C
|
||||||
# if GEN_COMPILER_C
|
# if GEN_COMPILER_C
|
||||||
# define GEN_NS_PARSER_BEGIN
|
|
||||||
# define GEN_NS_PARSER_END
|
|
||||||
# define GEN_USING_NS_PARSER
|
|
||||||
# define GEN_NS_PARSER
|
|
||||||
# define GEN_NS
|
# define GEN_NS
|
||||||
# define GEN_NS_BEGIN
|
# define GEN_NS_BEGIN
|
||||||
# define GEN_NS_END
|
# define GEN_NS_END
|
||||||
# else
|
# else
|
||||||
# define GEN_NS_PARSER_BEGIN namespace parser {
|
|
||||||
# define GEN_NS_PARSER_END }
|
|
||||||
# define GEN_USING_NS_PARSER using namespace parser
|
|
||||||
# define GEN_NS_PARSER parser::
|
|
||||||
# define GEN_NS ::
|
# define GEN_NS ::
|
||||||
# define GEN_NS_BEGIN
|
# define GEN_NS_BEGIN
|
||||||
# define GEN_NS_END
|
# define GEN_NS_END
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# define GEN_NS_PARSER_BEGIN namespace parser {
|
|
||||||
# define GEN_NS_PARSER_END }
|
|
||||||
# define GEN_NS_PARSER parser::
|
|
||||||
# define GEN_USING_NS_PARSER using namespace parser
|
|
||||||
# define GEN_NS gen::
|
# define GEN_NS gen::
|
||||||
# define GEN_NS_BEGIN namespace gen {
|
# define GEN_NS_BEGIN namespace gen {
|
||||||
# define GEN_NS_END }
|
# define GEN_NS_END }
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "string_ops.cpp"
|
# include "strbuilder_ops.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region Printing
|
#pragma region Printing
|
||||||
@ -48,7 +48,7 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha
|
|||||||
|
|
||||||
if ( str == NULL && max_len >= 6 )
|
if ( str == NULL && max_len >= 6 )
|
||||||
{
|
{
|
||||||
res += str_copy_nulpad( text, "(null)", 6 );
|
res += c_str_copy_nulpad( text, "(null)", 6 );
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha
|
|||||||
// Made the design decision for this library that precision is the length of the string.
|
// Made the design decision for this library that precision is the length of the string.
|
||||||
len = info->precision;
|
len = info->precision;
|
||||||
else
|
else
|
||||||
len = str_len( str );
|
len = c_str_len( str );
|
||||||
|
|
||||||
if ( info && ( info->width == 0 && info->flags & GEN_FMT_WIDTH ) )
|
if ( info && ( info->width == 0 && info->flags & GEN_FMT_WIDTH ) )
|
||||||
{
|
{
|
||||||
@ -69,7 +69,7 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha
|
|||||||
len = info->precision < len ? info->precision : len;
|
len = info->precision < len ? info->precision : len;
|
||||||
if ( res + len > max_len )
|
if ( res + len > max_len )
|
||||||
return res;
|
return res;
|
||||||
res += str_copy_nulpad( text, str, len );
|
res += c_str_copy_nulpad( text, str, len );
|
||||||
text += res;
|
text += res;
|
||||||
|
|
||||||
if ( info->width > res )
|
if ( info->width > res )
|
||||||
@ -93,15 +93,15 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha
|
|||||||
|
|
||||||
if ( res + len > max_len )
|
if ( res + len > max_len )
|
||||||
return res;
|
return res;
|
||||||
res += str_copy_nulpad( text, str, len );
|
res += c_str_copy_nulpad( text, str, len );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( info )
|
if ( info )
|
||||||
{
|
{
|
||||||
if ( info->flags & GEN_FMT_UPPER )
|
if ( info->flags & GEN_FMT_UPPER )
|
||||||
str_to_upper( begin );
|
c_str_to_upper( begin );
|
||||||
else if ( info->flags & GEN_FMT_LOWER )
|
else if ( info->flags & GEN_FMT_LOWER )
|
||||||
str_to_lower( begin );
|
c_str_to_lower( begin );
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@ -238,7 +238,7 @@ internal ssize _print_f64( char* text, ssize max_len, _format_info* info, b32 is
|
|||||||
return ( text - text_begin );
|
return ( text - text_begin );
|
||||||
}
|
}
|
||||||
|
|
||||||
neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_list va )
|
neverinline ssize c_str_fmt_va( char* text, ssize max_len, char const* fmt, va_list va )
|
||||||
{
|
{
|
||||||
char const* text_begin = text;
|
char const* text_begin = text;
|
||||||
ssize remaining = max_len, res;
|
ssize remaining = max_len, res;
|
||||||
@ -310,7 +310,7 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info.width = scast( s32, str_to_i64( fmt, ccast( char**, & fmt), 10 ));
|
info.width = scast( s32, c_str_to_i64( fmt, ccast( char**, & fmt), 10 ));
|
||||||
if ( info.width != 0 )
|
if ( info.width != 0 )
|
||||||
{
|
{
|
||||||
info.flags |= GEN_FMT_WIDTH;
|
info.flags |= GEN_FMT_WIDTH;
|
||||||
@ -328,7 +328,7 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info.precision = scast( s32, str_to_i64( fmt, ccast( char**, & fmt), 10 ));
|
info.precision = scast( s32, c_str_to_i64( fmt, ccast( char**, & fmt), 10 ));
|
||||||
}
|
}
|
||||||
info.flags &= ~GEN_FMT_ZERO;
|
info.flags &= ~GEN_FMT_ZERO;
|
||||||
}
|
}
|
||||||
@ -419,19 +419,20 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis
|
|||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
{
|
{
|
||||||
if ( *(fmt + 1) == 'C' )
|
if ( *(fmt + 1) == 'B' )
|
||||||
{
|
{
|
||||||
|
|
||||||
++ fmt;
|
++ fmt;
|
||||||
StrC gen_str = va_arg( va, StrC);
|
StrBuilder gen_str = { va_arg( va, char*) };
|
||||||
info.precision = gen_str.Len;
|
|
||||||
len = _print_string( text, remaining, &info, gen_str.Ptr );
|
info.precision = strbuilder_length(gen_str);
|
||||||
|
len = _print_string( text, remaining, &info, gen_str );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
String gen_str = { va_arg( va, char*) };
|
Str gen_str = va_arg( va, Str);
|
||||||
|
info.precision = gen_str.Len;
|
||||||
info.precision = string_length(gen_str);
|
len = _print_string( text, remaining, &info, gen_str.Ptr );
|
||||||
len = _print_string( text, remaining, &info, gen_str );
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -531,67 +532,67 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis
|
|||||||
return ( res >= max_len || res < 0 ) ? -1 : res;
|
return ( res >= max_len || res < 0 ) ? -1 : res;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* str_fmt_buf_va( char const* fmt, va_list va )
|
char* c_str_fmt_buf_va( char const* fmt, va_list va )
|
||||||
{
|
{
|
||||||
local_persist thread_local char buffer[ GEN_PRINTF_MAXLEN ];
|
local_persist thread_local char buffer[ GEN_PRINTF_MAXLEN ];
|
||||||
str_fmt_va( buffer, size_of( buffer ), fmt, va );
|
c_str_fmt_va( buffer, size_of( buffer ), fmt, va );
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* str_fmt_buf( char const* fmt, ... )
|
char* c_str_fmt_buf( char const* fmt, ... )
|
||||||
{
|
{
|
||||||
va_list va;
|
va_list va;
|
||||||
char* str;
|
char* str;
|
||||||
va_start( va, fmt );
|
va_start( va, fmt );
|
||||||
str = str_fmt_buf_va( fmt, va );
|
str = c_str_fmt_buf_va( fmt, va );
|
||||||
va_end( va );
|
va_end( va );
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize str_fmt_file_va( FileInfo* f, char const* fmt, va_list va )
|
ssize c_str_fmt_file_va( FileInfo* f, char const* fmt, va_list va )
|
||||||
{
|
{
|
||||||
local_persist thread_local char buf[ GEN_PRINTF_MAXLEN ];
|
local_persist thread_local char buf[ GEN_PRINTF_MAXLEN ];
|
||||||
ssize len = str_fmt_va( buf, size_of( buf ), fmt, va );
|
ssize len = c_str_fmt_va( buf, size_of( buf ), fmt, va );
|
||||||
b32 res = file_write( f, buf, len - 1 ); // NOTE: prevent extra whitespace
|
b32 res = file_write( f, buf, len - 1 ); // NOTE: prevent extra whitespace
|
||||||
return res ? len : -1;
|
return res ? len : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize str_fmt_file( FileInfo* f, char const* fmt, ... )
|
ssize c_str_fmt_file( FileInfo* f, char const* fmt, ... )
|
||||||
{
|
{
|
||||||
ssize res;
|
ssize res;
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start( va, fmt );
|
va_start( va, fmt );
|
||||||
res = str_fmt_file_va( f, fmt, va );
|
res = c_str_fmt_file_va( f, fmt, va );
|
||||||
va_end( va );
|
va_end( va );
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize str_fmt( char* str, ssize n, char const* fmt, ... )
|
ssize c_str_fmt( char* str, ssize n, char const* fmt, ... )
|
||||||
{
|
{
|
||||||
ssize res;
|
ssize res;
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start( va, fmt );
|
va_start( va, fmt );
|
||||||
res = str_fmt_va( str, n, fmt, va );
|
res = c_str_fmt_va( str, n, fmt, va );
|
||||||
va_end( va );
|
va_end( va );
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize str_fmt_out_va( char const* fmt, va_list va )
|
ssize c_str_fmt_out_va( char const* fmt, va_list va )
|
||||||
{
|
{
|
||||||
return str_fmt_file_va( file_get_standard( EFileStandard_OUTPUT ), fmt, va );
|
return c_str_fmt_file_va( file_get_standard( EFileStandard_OUTPUT ), fmt, va );
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize str_fmt_out_err_va( char const* fmt, va_list va )
|
ssize c_str_fmt_out_err_va( char const* fmt, va_list va )
|
||||||
{
|
{
|
||||||
return str_fmt_file_va( file_get_standard( EFileStandard_ERROR ), fmt, va );
|
return c_str_fmt_file_va( file_get_standard( EFileStandard_ERROR ), fmt, va );
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize str_fmt_out_err( char const* fmt, ... )
|
ssize c_str_fmt_out_err( char const* fmt, ... )
|
||||||
{
|
{
|
||||||
ssize res;
|
ssize res;
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start( va, fmt );
|
va_start( va, fmt );
|
||||||
res = str_fmt_out_err_va( fmt, va );
|
res = c_str_fmt_out_err_va( fmt, va );
|
||||||
va_end( va );
|
va_end( va );
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "string_ops.hpp"
|
# include "strbuilder_ops.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region Printing
|
#pragma region Printing
|
||||||
@ -13,15 +13,15 @@ typedef struct FileInfo FileInfo;
|
|||||||
typedef char PrintF_Buffer[GEN_PRINTF_MAXLEN];
|
typedef char PrintF_Buffer[GEN_PRINTF_MAXLEN];
|
||||||
|
|
||||||
// NOTE: A locally persisting buffer is used internally
|
// NOTE: A locally persisting buffer is used internally
|
||||||
char* str_fmt_buf ( char const* fmt, ... );
|
GEN_API char* c_str_fmt_buf ( char const* fmt, ... );
|
||||||
char* str_fmt_buf_va ( char const* fmt, va_list va );
|
GEN_API char* c_str_fmt_buf_va ( char const* fmt, va_list va );
|
||||||
ssize str_fmt ( char* str, ssize n, char const* fmt, ... );
|
GEN_API ssize c_str_fmt ( char* str, ssize n, char const* fmt, ... );
|
||||||
ssize str_fmt_va ( char* str, ssize n, char const* fmt, va_list va );
|
GEN_API ssize c_str_fmt_va ( char* str, ssize n, char const* fmt, va_list va );
|
||||||
ssize str_fmt_out_va ( char const* fmt, va_list va );
|
GEN_API ssize c_str_fmt_out_va ( char const* fmt, va_list va );
|
||||||
ssize str_fmt_out_err ( char const* fmt, ... );
|
GEN_API ssize c_str_fmt_out_err ( char const* fmt, ... );
|
||||||
ssize str_fmt_out_err_va( char const* fmt, va_list va );
|
GEN_API ssize c_str_fmt_out_err_va( char const* fmt, va_list va );
|
||||||
ssize str_fmt_file ( FileInfo* f, char const* fmt, ... );
|
GEN_API ssize c_str_fmt_file ( FileInfo* f, char const* fmt, ... );
|
||||||
ssize str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va );
|
GEN_API ssize c_str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va );
|
||||||
|
|
||||||
constexpr
|
constexpr
|
||||||
char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
|
char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
|
||||||
@ -33,7 +33,7 @@ ssize log_fmt(char const* fmt, ...)
|
|||||||
va_list va;
|
va_list va;
|
||||||
|
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
res = str_fmt_out_va(fmt, va);
|
res = c_str_fmt_out_va(fmt, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "header_start.hpp"
|
# include "header_start.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -13,9 +13,9 @@
|
|||||||
# define _printf_err( fmt, ... ) fprintf( stderr, fmt, __VA_ARGS__ )
|
# define _printf_err( fmt, ... ) fprintf( stderr, fmt, __VA_ARGS__ )
|
||||||
# define _printf_err_va( fmt, va ) vfprintf( stderr, fmt, va )
|
# define _printf_err_va( fmt, va ) vfprintf( stderr, fmt, va )
|
||||||
# else
|
# else
|
||||||
# define _strlen str_len
|
# define _strlen c_str_len
|
||||||
# define _printf_err( fmt, ... ) str_fmt_out_err( fmt, __VA_ARGS__ )
|
# define _printf_err( fmt, ... ) c_str_fmt_out_err( fmt, __VA_ARGS__ )
|
||||||
# define _printf_err_va( fmt, va ) str_fmt_out_err_va( fmt, va )
|
# define _printf_err_va( fmt, va ) c_str_fmt_out_err_va( fmt, va )
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#
|
#
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "debug.cpp"
|
# include "debug.cpp"
|
||||||
#endif
|
#endif
|
||||||
@ -18,7 +18,7 @@ ssize _scan_zpl_i64( const char* text, s32 base, s64* value )
|
|||||||
text++;
|
text++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( base == 16 && str_compare_len( text, "0x", 2 ) == 0 )
|
if ( base == 16 && c_str_compare_len( text, "0x", 2 ) == 0 )
|
||||||
text += 2;
|
text += 2;
|
||||||
|
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
@ -53,14 +53,14 @@ global const char _num_to_char_table[] =
|
|||||||
"abcdefghijklmnopqrstuvwxyz"
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
"@$";
|
"@$";
|
||||||
|
|
||||||
s64 str_to_i64( const char* str, char** end_ptr, s32 base )
|
s64 c_str_to_i64( const char* str, char** end_ptr, s32 base )
|
||||||
{
|
{
|
||||||
ssize len;
|
ssize len;
|
||||||
s64 value;
|
s64 value;
|
||||||
|
|
||||||
if ( ! base )
|
if ( ! base )
|
||||||
{
|
{
|
||||||
if ( ( str_len( str ) > 2 ) && ( str_compare_len( str, "0x", 2 ) == 0 ) )
|
if ( ( c_str_len( str ) > 2 ) && ( c_str_compare_len( str, "0x", 2 ) == 0 ) )
|
||||||
base = 16;
|
base = 16;
|
||||||
else
|
else
|
||||||
base = 10;
|
base = 10;
|
||||||
@ -100,7 +100,7 @@ void i64_to_str( s64 value, char* string, s32 base )
|
|||||||
if ( negative )
|
if ( negative )
|
||||||
*buf++ = '-';
|
*buf++ = '-';
|
||||||
*buf = '\0';
|
*buf = '\0';
|
||||||
str_reverse( string );
|
c_str_reverse( string );
|
||||||
}
|
}
|
||||||
|
|
||||||
void u64_to_str( u64 value, char* string, s32 base )
|
void u64_to_str( u64 value, char* string, s32 base )
|
||||||
@ -121,10 +121,10 @@ void u64_to_str( u64 value, char* string, s32 base )
|
|||||||
}
|
}
|
||||||
*buf = '\0';
|
*buf = '\0';
|
||||||
|
|
||||||
str_reverse( string );
|
c_str_reverse( string );
|
||||||
}
|
}
|
||||||
|
|
||||||
f64 str_to_f64( const char* str, char** end_ptr )
|
f64 c_str_to_f64( const char* str, char** end_ptr )
|
||||||
{
|
{
|
||||||
f64 result, value, sign, scale;
|
f64 result, value, sign, scale;
|
||||||
s32 frac;
|
s32 frac;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "memory.hpp"
|
# include "memory.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -18,25 +18,25 @@ char char_to_upper( char c );
|
|||||||
s32 digit_to_int( char c );
|
s32 digit_to_int( char c );
|
||||||
s32 hex_digit_to_int( char c );
|
s32 hex_digit_to_int( char c );
|
||||||
|
|
||||||
s32 str_compare( const char* s1, const char* s2 );
|
s32 c_str_compare( const char* s1, const char* s2 );
|
||||||
s32 str_compare_len( const char* s1, const char* s2, ssize len );
|
s32 c_str_compare_len( const char* s1, const char* s2, ssize len );
|
||||||
char* str_copy( char* dest, const char* source, ssize len );
|
char* c_str_copy( char* dest, const char* source, ssize len );
|
||||||
ssize str_copy_nulpad( char* dest, const char* source, ssize len );
|
ssize c_str_copy_nulpad( char* dest, const char* source, ssize len );
|
||||||
ssize str_len( const char* str );
|
ssize c_str_len( const char* str );
|
||||||
ssize str_len_capped( const char* str, ssize max_len );
|
ssize c_str_len_capped( const char* str, ssize max_len );
|
||||||
char* str_reverse( char* str ); // NOTE: ASCII only
|
char* c_str_reverse( char* str ); // NOTE: ASCII only
|
||||||
char const* str_skip( char const* str, char c );
|
char const* c_str_skip( char const* str, char c );
|
||||||
char const* str_skip_any( char const* str, char const* char_list );
|
char const* c_str_skip_any( char const* str, char const* char_list );
|
||||||
char const* str_trim( char const* str, b32 catch_newline );
|
char const* c_str_trim( char const* str, b32 catch_newline );
|
||||||
|
|
||||||
// NOTE: ASCII only
|
// NOTE: ASCII only
|
||||||
void str_to_lower( char* str );
|
void c_str_to_lower( char* str );
|
||||||
void str_to_upper( char* str );
|
void c_str_to_upper( char* str );
|
||||||
|
|
||||||
s64 str_to_i64( const char* str, char** end_ptr, s32 base );
|
GEN_API s64 c_str_to_i64( const char* str, char** end_ptr, s32 base );
|
||||||
void i64_to_str( s64 value, char* string, s32 base );
|
GEN_API void i64_to_str( s64 value, char* string, s32 base );
|
||||||
void u64_to_str( u64 value, char* string, s32 base );
|
GEN_API void u64_to_str( u64 value, char* string, s32 base );
|
||||||
f64 str_to_f64( const char* str, char** end_ptr );
|
GEN_API f64 c_str_to_f64( const char* str, char** end_ptr );
|
||||||
|
|
||||||
inline
|
inline
|
||||||
const char* char_first_occurence( const char* s, char c )
|
const char* char_first_occurence( const char* s, char c )
|
||||||
@ -122,7 +122,7 @@ s32 hex_digit_to_int( char c )
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
s32 str_compare( const char* s1, const char* s2 )
|
s32 c_str_compare( const char* s1, const char* s2 )
|
||||||
{
|
{
|
||||||
while ( *s1 && ( *s1 == *s2 ) )
|
while ( *s1 && ( *s1 == *s2 ) )
|
||||||
{
|
{
|
||||||
@ -132,7 +132,7 @@ s32 str_compare( const char* s1, const char* s2 )
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
s32 str_compare_len( const char* s1, const char* s2, ssize len )
|
s32 c_str_compare_len( const char* s1, const char* s2, ssize len )
|
||||||
{
|
{
|
||||||
for ( ; len > 0; s1++, s2++, len-- )
|
for ( ; len > 0; s1++, s2++, len-- )
|
||||||
{
|
{
|
||||||
@ -145,7 +145,7 @@ s32 str_compare_len( const char* s1, const char* s2, ssize len )
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
char* str_copy( char* dest, const char* source, ssize len )
|
char* c_str_copy( char* dest, const char* source, ssize len )
|
||||||
{
|
{
|
||||||
GEN_ASSERT_NOT_NULL( dest );
|
GEN_ASSERT_NOT_NULL( dest );
|
||||||
if ( source )
|
if ( source )
|
||||||
@ -166,7 +166,7 @@ char* str_copy( char* dest, const char* source, ssize len )
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
ssize str_copy_nulpad( char* dest, const char* source, ssize len )
|
ssize c_str_copy_nulpad( char* dest, const char* source, ssize len )
|
||||||
{
|
{
|
||||||
ssize result = 0;
|
ssize result = 0;
|
||||||
GEN_ASSERT_NOT_NULL( dest );
|
GEN_ASSERT_NOT_NULL( dest );
|
||||||
@ -191,7 +191,7 @@ ssize str_copy_nulpad( char* dest, const char* source, ssize len )
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
ssize str_len( const char* str )
|
ssize c_str_len( const char* str )
|
||||||
{
|
{
|
||||||
if ( str == NULL )
|
if ( str == NULL )
|
||||||
{
|
{
|
||||||
@ -204,7 +204,7 @@ ssize str_len( const char* str )
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
ssize str_len_capped( const char* str, ssize max_len )
|
ssize c_str_len_capped( const char* str, ssize max_len )
|
||||||
{
|
{
|
||||||
const char* end = rcast(const char*, mem_find( str, 0, max_len ));
|
const char* end = rcast(const char*, mem_find( str, 0, max_len ));
|
||||||
if ( end )
|
if ( end )
|
||||||
@ -213,9 +213,9 @@ ssize str_len_capped( const char* str, ssize max_len )
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
char* str_reverse( char* str )
|
char* c_str_reverse( char* str )
|
||||||
{
|
{
|
||||||
ssize len = str_len( str );
|
ssize len = c_str_len( str );
|
||||||
char* a = str + 0;
|
char* a = str + 0;
|
||||||
char* b = str + len - 1;
|
char* b = str + len - 1;
|
||||||
len /= 2;
|
len /= 2;
|
||||||
@ -228,7 +228,7 @@ char* str_reverse( char* str )
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
char const* str_skip( char const* str, char c )
|
char const* c_str_skip( char const* str, char c )
|
||||||
{
|
{
|
||||||
while ( *str && *str != c )
|
while ( *str && *str != c )
|
||||||
{
|
{
|
||||||
@ -238,20 +238,20 @@ char const* str_skip( char const* str, char c )
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
char const* str_skip_any( char const* str, char const* char_list )
|
char const* c_str_skip_any( char const* str, char const* char_list )
|
||||||
{
|
{
|
||||||
char const* closest_ptr = rcast( char const*, pointer_add_const( rcast(mem_ptr_const, str), str_len( str ) ));
|
char const* closest_ptr = rcast( char const*, pointer_add_const( rcast(mem_ptr_const, str), c_str_len( str ) ));
|
||||||
ssize char_list_count = str_len( char_list );
|
ssize char_list_count = c_str_len( char_list );
|
||||||
for ( ssize i = 0; i < char_list_count; i++ )
|
for ( ssize i = 0; i < char_list_count; i++ )
|
||||||
{
|
{
|
||||||
char const* p = str_skip( str, char_list[ i ] );
|
char const* p = c_str_skip( str, char_list[ i ] );
|
||||||
closest_ptr = min( closest_ptr, p );
|
closest_ptr = min( closest_ptr, p );
|
||||||
}
|
}
|
||||||
return closest_ptr;
|
return closest_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
char const* str_trim( char const* str, b32 catch_newline )
|
char const* c_str_trim( char const* str, b32 catch_newline )
|
||||||
{
|
{
|
||||||
while ( *str && char_is_space( *str ) && ( ! catch_newline || ( catch_newline && *str != '\n' ) ) )
|
while ( *str && char_is_space( *str ) && ( ! catch_newline || ( catch_newline && *str != '\n' ) ) )
|
||||||
{
|
{
|
||||||
@ -261,7 +261,7 @@ char const* str_trim( char const* str, b32 catch_newline )
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void str_to_lower( char* str )
|
void c_str_to_lower( char* str )
|
||||||
{
|
{
|
||||||
if ( ! str )
|
if ( ! str )
|
||||||
return;
|
return;
|
||||||
@ -273,7 +273,7 @@ void str_to_lower( char* str )
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void str_to_upper( char* str )
|
void c_str_to_upper( char* str )
|
||||||
{
|
{
|
||||||
if ( ! str )
|
if ( ! str )
|
||||||
return;
|
return;
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "hashing.cpp"
|
# include "hashing.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region String
|
#pragma region StrBuilder
|
||||||
|
|
||||||
String string_make_length( AllocatorInfo allocator, char const* str, ssize length )
|
StrBuilder strbuilder_make_length( AllocatorInfo allocator, char const* str, ssize length )
|
||||||
{
|
{
|
||||||
ssize const header_size = sizeof( StringHeader );
|
ssize const header_size = sizeof( StrBuilderHeader );
|
||||||
|
|
||||||
s32 alloc_size = header_size + length + 1;
|
s32 alloc_size = header_size + length + 1;
|
||||||
void* allocation = alloc( allocator, alloc_size );
|
void* allocation = alloc( allocator, alloc_size );
|
||||||
|
|
||||||
if ( allocation == nullptr ) {
|
if ( allocation == nullptr ) {
|
||||||
String null_string = {nullptr};
|
StrBuilder null_string = {nullptr};
|
||||||
return null_string;
|
return null_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringHeader*
|
StrBuilderHeader*
|
||||||
header = rcast(StringHeader*, allocation);
|
header = rcast(StrBuilderHeader*, allocation);
|
||||||
header->Allocator = allocator;
|
header->Allocator = allocator;
|
||||||
header->Capacity = length;
|
header->Capacity = length;
|
||||||
header->Length = length;
|
header->Length = length;
|
||||||
|
|
||||||
String result = { rcast( char*, allocation) + header_size };
|
StrBuilder result = { rcast( char*, allocation) + header_size };
|
||||||
|
|
||||||
if ( length && str )
|
if ( length && str )
|
||||||
mem_copy( result, str, length );
|
mem_copy( result, str, length );
|
||||||
@ -35,27 +35,143 @@ String string_make_length( AllocatorInfo allocator, char const* str, ssize lengt
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
String string_make_reserve( AllocatorInfo allocator, ssize capacity )
|
StrBuilder strbuilder_make_reserve( AllocatorInfo allocator, ssize capacity )
|
||||||
{
|
{
|
||||||
ssize const header_size = sizeof( StringHeader );
|
ssize const header_size = sizeof( StrBuilderHeader );
|
||||||
|
|
||||||
s32 alloc_size = header_size + capacity + 1;
|
s32 alloc_size = header_size + capacity + 1;
|
||||||
void* allocation = alloc( allocator, alloc_size );
|
void* allocation = alloc( allocator, alloc_size );
|
||||||
|
|
||||||
if ( allocation == nullptr ) {
|
if ( allocation == nullptr ) {
|
||||||
String null_string = {nullptr};
|
StrBuilder null_string = {nullptr};
|
||||||
return null_string;
|
return null_string;
|
||||||
}
|
}
|
||||||
mem_set( allocation, 0, alloc_size );
|
mem_set( allocation, 0, alloc_size );
|
||||||
|
|
||||||
StringHeader*
|
StrBuilderHeader*
|
||||||
header = rcast(StringHeader*, allocation);
|
header = rcast(StrBuilderHeader*, allocation);
|
||||||
header->Allocator = allocator;
|
header->Allocator = allocator;
|
||||||
header->Capacity = capacity;
|
header->Capacity = capacity;
|
||||||
header->Length = 0;
|
header->Length = 0;
|
||||||
|
|
||||||
String result = { rcast(char*, allocation) + header_size };
|
StrBuilder result = { rcast(char*, allocation) + header_size };
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion String
|
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,65 +1,65 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "hashing.hpp"
|
# include "hashing.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region Strings
|
#pragma region Strings
|
||||||
|
|
||||||
struct StrC;
|
struct Str;
|
||||||
|
|
||||||
StrC to_strc_from_c_str (char const* bad_string);
|
Str to_str_from_c_str (char const* bad_string);
|
||||||
bool strc_are_equal (StrC lhs, StrC rhs);
|
bool str_are_equal (Str lhs, Str rhs);
|
||||||
char const* strc_back (StrC str);
|
char const* str_back (Str str);
|
||||||
bool strc_contains (StrC str, StrC substring);
|
bool str_contains (Str str, Str substring);
|
||||||
StrC strc_duplicate (StrC str, AllocatorInfo allocator);
|
Str str_duplicate (Str str, AllocatorInfo allocator);
|
||||||
b32 strc_starts_with (StrC str, StrC substring);
|
b32 str_starts_with (Str str, Str substring);
|
||||||
StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator);
|
Str str_visualize_whitespace(Str str, AllocatorInfo allocator);
|
||||||
|
|
||||||
// Constant string with length.
|
// Constant string with length.
|
||||||
struct StrC
|
struct Str
|
||||||
{
|
{
|
||||||
ssize Len;
|
|
||||||
char const* Ptr;
|
char const* Ptr;
|
||||||
|
ssize Len;
|
||||||
|
|
||||||
#if GEN_COMPILER_CPP
|
#if GEN_COMPILER_CPP
|
||||||
forceinline operator char const* () const { return Ptr; }
|
forceinline operator char const* () const { return Ptr; }
|
||||||
forceinline char const& operator[]( ssize index ) const { return Ptr[index]; }
|
forceinline char const& operator[]( ssize index ) const { return Ptr[index]; }
|
||||||
|
|
||||||
#if ! GEN_C_LIKE_CPP
|
#if ! GEN_C_LIKE_CPP
|
||||||
forceinline bool is_equal (StrC rhs) const { return strc_are_equal(* this, rhs); }
|
forceinline bool is_equal (Str rhs) const { return str_are_equal(* this, rhs); }
|
||||||
forceinline char const* back () const { return strc_back(* this); }
|
forceinline char const* back () const { return str_back(* this); }
|
||||||
forceinline bool contains (StrC substring) const { return strc_contains(* this, substring); }
|
forceinline bool contains (Str substring) const { return str_contains(* this, substring); }
|
||||||
forceinline StrC duplicate (AllocatorInfo allocator) const { return strc_duplicate(* this, allocator); }
|
forceinline Str duplicate (AllocatorInfo allocator) const { return str_duplicate(* this, allocator); }
|
||||||
forceinline b32 starts_with (StrC substring) const { return strc_starts_with(* this, substring); }
|
forceinline b32 starts_with (Str substring) const { return str_starts_with(* this, substring); }
|
||||||
forceinline StrC visualize_whitespace(AllocatorInfo allocator) const { return strc_visualize_whitespace(* this, allocator); }
|
forceinline Str visualize_whitespace(AllocatorInfo allocator) const { return str_visualize_whitespace(* this, allocator); }
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(ssize) )
|
#define cast_to_str( str ) * rcast( Str*, (str) - sizeof(ssize) )
|
||||||
|
|
||||||
#ifndef txt
|
#ifndef txt
|
||||||
# if GEN_COMPILER_CPP
|
# if GEN_COMPILER_CPP
|
||||||
# define txt( text ) StrC { sizeof( text ) - 1, ( text ) }
|
# define txt( text ) GEN_NS Str { ( text ), sizeof( text ) - 1 }
|
||||||
# else
|
# else
|
||||||
# define txt( text ) (StrC){ sizeof( text ) - 1, ( text ) }
|
# define txt( text ) (GEN_NS Str){ ( text ), sizeof( text ) - 1 }
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GEN_API_C_BEGIN
|
GEN_API_C_BEGIN
|
||||||
forceinline char const* strc_begin(StrC str) { return str.Ptr; }
|
forceinline char const* str_begin(Str str) { return str.Ptr; }
|
||||||
forceinline char const* strc_end (StrC str) { return str.Ptr + str.Len; }
|
forceinline char const* str_end (Str str) { return str.Ptr + str.Len; }
|
||||||
forceinline char const* strc_next (StrC str, char const* iter) { return iter + 1; }
|
forceinline char const* str_next (Str str, char const* iter) { return iter + 1; }
|
||||||
GEN_API_C_END
|
GEN_API_C_END
|
||||||
|
|
||||||
#if GEN_COMPILER_CPP
|
#if GEN_COMPILER_CPP
|
||||||
forceinline char const* begin(StrC str) { return str.Ptr; }
|
forceinline char const* begin(Str str) { return str.Ptr; }
|
||||||
forceinline char const* end (StrC str) { return str.Ptr + str.Len; }
|
forceinline char const* end (Str str) { return str.Ptr + str.Len; }
|
||||||
forceinline char const* next (StrC str, char const* iter) { return iter + 1; }
|
forceinline char const* next (Str str, char const* iter) { return iter + 1; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool strc_are_equal(StrC lhs, StrC rhs)
|
bool str_are_equal(Str lhs, Str rhs)
|
||||||
{
|
{
|
||||||
if (lhs.Len != rhs.Len)
|
if (lhs.Len != rhs.Len)
|
||||||
return false;
|
return false;
|
||||||
@ -72,12 +72,12 @@ bool strc_are_equal(StrC lhs, StrC rhs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
char const* strc_back(StrC str) {
|
char const* str_back(Str str) {
|
||||||
return & str.Ptr[str.Len - 1];
|
return & str.Ptr[str.Len - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool strc_contains(StrC str, StrC substring)
|
bool str_contains(Str str, Str substring)
|
||||||
{
|
{
|
||||||
if (substring.Len > str.Len)
|
if (substring.Len > str.Len)
|
||||||
return false;
|
return false;
|
||||||
@ -86,97 +86,98 @@ bool strc_contains(StrC str, StrC substring)
|
|||||||
ssize sub_len = substring.Len;
|
ssize sub_len = substring.Len;
|
||||||
for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
|
for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
|
||||||
{
|
{
|
||||||
if (str_compare_len(str.Ptr + idx, substring.Ptr, sub_len) == 0)
|
if (c_str_compare_len(str.Ptr + idx, substring.Ptr, sub_len) == 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
b32 strc_starts_with(StrC str, StrC substring) {
|
b32 str_starts_with(Str str, Str substring) {
|
||||||
if (substring.Len > str.Len)
|
if (substring.Len > str.Len)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
b32 result = str_compare_len(str.Ptr, substring.Ptr, substring.Len) == 0;
|
b32 result = c_str_compare_len(str.Ptr, substring.Ptr, substring.Len) == 0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
StrC to_strc_from_c_str( char const* bad_str ) {
|
Str to_str_from_c_str( char const* bad_str ) {
|
||||||
StrC result = { str_len( bad_str ), bad_str };
|
Str result = { bad_str, c_str_len( bad_str ) };
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dynamic String
|
// Dynamic StrBuilder
|
||||||
// This is directly based off the ZPL string api.
|
// This is directly based off the ZPL string api.
|
||||||
// They used a header pattern
|
// They used a header pattern
|
||||||
// I kept it for simplicty of porting but its not necessary to keep it that way.
|
// I kept it for simplicty of porting but its not necessary to keep it that way.
|
||||||
#pragma region String
|
#pragma region StrBuilder
|
||||||
struct StringHeader;
|
struct StrBuilderHeader;
|
||||||
|
|
||||||
#if GEN_COMPILER_C
|
#if GEN_COMPILER_C
|
||||||
typedef char* String;
|
typedef char* StrBuilder;
|
||||||
#else
|
#else
|
||||||
struct String;
|
struct StrBuilder;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
forceinline usize string_grow_formula(usize value);
|
forceinline usize strbuilder_grow_formula(usize value);
|
||||||
|
|
||||||
String string_make_c_str (AllocatorInfo allocator, char const* str);
|
GEN_API StrBuilder strbuilder_make_reserve (AllocatorInfo allocator, ssize capacity);
|
||||||
String string_make_strc (AllocatorInfo allocator, StrC str);
|
GEN_API StrBuilder strbuilder_make_length (AllocatorInfo allocator, char const* str, ssize length);
|
||||||
String string_make_reserve (AllocatorInfo allocator, ssize capacity);
|
GEN_API bool strbuilder_make_space_for (StrBuilder* str, char const* to_append, ssize add_len);
|
||||||
String string_make_length (AllocatorInfo allocator, char const* str, ssize length);
|
GEN_API bool strbuilder_append_c_str_len (StrBuilder* str, char const* c_str_to_append, ssize length);
|
||||||
String string_fmt (AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...);
|
GEN_API void strbuilder_trim (StrBuilder str, char const* cut_set);
|
||||||
String string_fmt_buf (AllocatorInfo allocator, char const* fmt, ...);
|
GEN_API StrBuilder strbuilder_visualize_whitespace(StrBuilder const str);
|
||||||
String string_join (AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue);
|
|
||||||
bool string_are_equal (String const lhs, String const rhs);
|
|
||||||
bool string_are_equal_strc (String const lhs, StrC rhs);
|
|
||||||
bool string_make_space_for (String* str, char const* to_append, ssize add_len);
|
|
||||||
bool string_append_char (String* str, char c);
|
|
||||||
bool string_append_c_str (String* str, char const* str_to_append);
|
|
||||||
bool string_append_c_str_len (String* str, char const* str_to_append, ssize length);
|
|
||||||
bool string_append_strc (String* str, StrC str_to_append);
|
|
||||||
bool string_append_string (String* str, String const other);
|
|
||||||
bool string_append_fmt (String* str, char const* fmt, ...);
|
|
||||||
ssize string_avail_space (String const str);
|
|
||||||
char* string_back (String str);
|
|
||||||
bool string_contains_strc (String const str, StrC substring);
|
|
||||||
bool string_contains_string (String const str, String const substring);
|
|
||||||
ssize string_capacity (String const str);
|
|
||||||
void string_clear (String str);
|
|
||||||
String string_duplicate (String const str, AllocatorInfo allocator);
|
|
||||||
void string_free (String* str);
|
|
||||||
StringHeader* string_get_header (String str);
|
|
||||||
ssize string_length (String const str);
|
|
||||||
b32 string_starts_with_strc (String const str, StrC substring);
|
|
||||||
b32 string_starts_with_string (String const str, String substring);
|
|
||||||
void string_skip_line (String str);
|
|
||||||
void string_strip_space (String str);
|
|
||||||
StrC string_to_strc (String str);
|
|
||||||
void string_trim (String str, char const* cut_set);
|
|
||||||
void string_trim_space (String str);
|
|
||||||
String string_visualize_whitespace(String const str);
|
|
||||||
|
|
||||||
struct StringHeader {
|
StrBuilder strbuilder_make_c_str (AllocatorInfo allocator, char const* str);
|
||||||
|
StrBuilder strbuilder_make_str (AllocatorInfo allocator, Str str);
|
||||||
|
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_append_char (StrBuilder* str, char c);
|
||||||
|
bool strbuilder_append_c_str (StrBuilder* str, char const* c_str_to_append);
|
||||||
|
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, ...);
|
||||||
|
ssize strbuilder_avail_space (StrBuilder const str);
|
||||||
|
char* strbuilder_back (StrBuilder str);
|
||||||
|
bool strbuilder_contains_str (StrBuilder const str, Str substring);
|
||||||
|
bool strbuilder_contains_string (StrBuilder const str, StrBuilder const substring);
|
||||||
|
ssize strbuilder_capacity (StrBuilder const str);
|
||||||
|
void strbuilder_clear (StrBuilder str);
|
||||||
|
StrBuilder strbuilder_duplicate (StrBuilder const str, AllocatorInfo allocator);
|
||||||
|
void strbuilder_free (StrBuilder* str);
|
||||||
|
StrBuilderHeader* strbuilder_get_header (StrBuilder str);
|
||||||
|
ssize strbuilder_length (StrBuilder const str);
|
||||||
|
b32 strbuilder_starts_with_str (StrBuilder const str, Str substring);
|
||||||
|
b32 strbuilder_starts_with_string (StrBuilder const str, StrBuilder substring);
|
||||||
|
void strbuilder_skip_line (StrBuilder str);
|
||||||
|
void strbuilder_strip_space (StrBuilder str);
|
||||||
|
Str strbuilder_to_str (StrBuilder str);
|
||||||
|
void strbuilder_trim_space (StrBuilder str);
|
||||||
|
|
||||||
|
struct StrBuilderHeader {
|
||||||
AllocatorInfo Allocator;
|
AllocatorInfo Allocator;
|
||||||
ssize Capacity;
|
ssize Capacity;
|
||||||
ssize Length;
|
ssize Length;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if GEN_COMPILER_CPP
|
#if GEN_COMPILER_CPP
|
||||||
struct String
|
struct StrBuilder
|
||||||
{
|
{
|
||||||
char* Data;
|
char* Data;
|
||||||
|
|
||||||
forceinline operator char*() { return Data; }
|
forceinline operator char*() { return Data; }
|
||||||
forceinline operator char const*() const { return Data; }
|
forceinline operator char const*() const { return Data; }
|
||||||
forceinline operator StrC() const { return { string_length(* this), Data }; }
|
forceinline operator Str() const { return { Data, strbuilder_length(* this) }; }
|
||||||
|
|
||||||
String const& operator=(String const& other) const {
|
StrBuilder const& operator=(StrBuilder const& other) const {
|
||||||
if (this == &other)
|
if (this == &other)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
String* this_ = ccast(String*, this);
|
StrBuilder* this_ = ccast(StrBuilder*, this);
|
||||||
this_->Data = other.Data;
|
this_->Data = other.Data;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@ -185,69 +186,69 @@ struct String
|
|||||||
forceinline char& operator[](ssize index) { return Data[index]; }
|
forceinline char& operator[](ssize index) { return Data[index]; }
|
||||||
forceinline char const& operator[](ssize index) const { return Data[index]; }
|
forceinline char const& operator[](ssize index) const { return Data[index]; }
|
||||||
|
|
||||||
forceinline bool operator==(std::nullptr_t) const { return Data == nullptr; }
|
forceinline bool operator==(std::nullptr_t) const { return Data == nullptr; }
|
||||||
forceinline bool operator!=(std::nullptr_t) const { return Data != nullptr; }
|
forceinline bool operator!=(std::nullptr_t) const { return Data != nullptr; }
|
||||||
friend forceinline bool operator==(std::nullptr_t, const String str) { return str.Data == nullptr; }
|
friend forceinline bool operator==(std::nullptr_t, const StrBuilder str) { return str.Data == nullptr; }
|
||||||
friend forceinline bool operator!=(std::nullptr_t, const String str) { return str.Data != nullptr; }
|
friend forceinline bool operator!=(std::nullptr_t, const StrBuilder str) { return str.Data != nullptr; }
|
||||||
|
|
||||||
#if ! GEN_C_LIKE_CPP
|
#if ! GEN_C_LIKE_CPP
|
||||||
forceinline char* begin() const { return Data; }
|
forceinline char* begin() const { return Data; }
|
||||||
forceinline char* end() const { return Data + string_length(* this); }
|
forceinline char* end() const { return Data + strbuilder_length(* this); }
|
||||||
|
|
||||||
#pragma region Member Mapping
|
#pragma region Member Mapping
|
||||||
forceinline static String make(AllocatorInfo allocator, char const* str) { return string_make_c_str(allocator, str); }
|
forceinline static StrBuilder make(AllocatorInfo allocator, char const* str) { return strbuilder_make_c_str(allocator, str); }
|
||||||
forceinline static String make(AllocatorInfo allocator, StrC str) { return string_make_strc(allocator, str); }
|
forceinline static StrBuilder make(AllocatorInfo allocator, Str str) { return strbuilder_make_str(allocator, str); }
|
||||||
forceinline static String make_reserve(AllocatorInfo allocator, ssize cap) { return string_make_reserve(allocator, cap); }
|
forceinline static StrBuilder make_reserve(AllocatorInfo allocator, ssize cap) { return strbuilder_make_reserve(allocator, cap); }
|
||||||
forceinline static String make_length(AllocatorInfo a, char const* s, ssize l) { return string_make_length(a, s, l); }
|
forceinline static StrBuilder make_length(AllocatorInfo a, char const* s, ssize l) { return strbuilder_make_length(a, s, l); }
|
||||||
forceinline static String join(AllocatorInfo a, char const** p, ssize n, char const* g) { return string_join(a, p, n, g); }
|
forceinline static StrBuilder join(AllocatorInfo a, char const** p, ssize n, char const* g) { return strbuilder_join(a, p, n, g); }
|
||||||
forceinline static usize grow_formula(usize value) { return string_grow_formula(value); }
|
forceinline static usize grow_formula(usize value) { return strbuilder_grow_formula(value); }
|
||||||
|
|
||||||
static
|
static
|
||||||
String fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) {
|
StrBuilder fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) {
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
ssize res = str_fmt_va(buf, buf_size, fmt, va) - 1;
|
ssize res = c_str_fmt_va(buf, buf_size, fmt, va) - 1;
|
||||||
va_end(va);
|
va_end(va);
|
||||||
return string_make_length(allocator, buf, res);
|
return strbuilder_make_length(allocator, buf, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
String fmt_buf(AllocatorInfo allocator, char const* fmt, ...) {
|
StrBuilder fmt_buf(AllocatorInfo allocator, char const* fmt, ...) {
|
||||||
local_persist thread_local
|
local_persist thread_local
|
||||||
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
ssize res = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) - 1;
|
ssize res = c_str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) - 1;
|
||||||
va_end(va);
|
va_end(va);
|
||||||
return string_make_length(allocator, buf, res);
|
return strbuilder_make_length(allocator, buf, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline bool make_space_for(char const* str, ssize add_len) { return string_make_space_for(this, str, add_len); }
|
forceinline bool make_space_for(char const* str, ssize add_len) { return strbuilder_make_space_for(this, str, add_len); }
|
||||||
forceinline bool append(char c) { return string_append_char(this, c); }
|
forceinline bool append(char c) { return strbuilder_append_char(this, c); }
|
||||||
forceinline bool append(char const* str) { return string_append_c_str(this, str); }
|
forceinline bool append(char const* str) { return strbuilder_append_c_str(this, str); }
|
||||||
forceinline bool append(char const* str, ssize length) { return string_append_c_str_len(this, str, length); }
|
forceinline bool append(char const* str, ssize length) { return strbuilder_append_c_str_len(this, str, length); }
|
||||||
forceinline bool append(StrC str) { return string_append_strc(this, str); }
|
forceinline bool append(Str str) { return strbuilder_append_str(this, str); }
|
||||||
forceinline bool append(const String other) { return string_append_string(this, other); }
|
forceinline bool append(const StrBuilder other) { return strbuilder_append_string(this, other); }
|
||||||
forceinline ssize avail_space() const { return string_avail_space(* this); }
|
forceinline ssize avail_space() const { return strbuilder_avail_space(* this); }
|
||||||
forceinline char* back() { return string_back(* this); }
|
forceinline char* back() { return strbuilder_back(* this); }
|
||||||
forceinline bool contains(StrC substring) const { return string_contains_strc(* this, substring); }
|
forceinline bool contains(Str substring) const { return strbuilder_contains_str(* this, substring); }
|
||||||
forceinline bool contains(String const& substring) const { return string_contains_string(* this, substring); }
|
forceinline bool contains(StrBuilder const& substring) const { return strbuilder_contains_string(* this, substring); }
|
||||||
forceinline ssize capacity() const { return string_capacity(* this); }
|
forceinline ssize capacity() const { return strbuilder_capacity(* this); }
|
||||||
forceinline void clear() { string_clear(* this); }
|
forceinline void clear() { strbuilder_clear(* this); }
|
||||||
forceinline String duplicate(AllocatorInfo allocator) const { return string_duplicate(* this, allocator); }
|
forceinline StrBuilder duplicate(AllocatorInfo allocator) const { return strbuilder_duplicate(* this, allocator); }
|
||||||
forceinline void free() { string_free(this); }
|
forceinline void free() { strbuilder_free(this); }
|
||||||
forceinline bool is_equal(String const& other) const { return string_are_equal(* this, other); }
|
forceinline bool is_equal(StrBuilder const& other) const { return strbuilder_are_equal(* this, other); }
|
||||||
forceinline bool is_equal(StrC other) const { return string_are_equal_strc(* this, other); }
|
forceinline bool is_equal(Str other) const { return strbuilder_are_equal_str(* this, other); }
|
||||||
forceinline ssize length() const { return string_length(* this); }
|
forceinline ssize length() const { return strbuilder_length(* this); }
|
||||||
forceinline b32 starts_with(StrC substring) const { return string_starts_with_strc(* this, substring); }
|
forceinline b32 starts_with(Str substring) const { return strbuilder_starts_with_str(* this, substring); }
|
||||||
forceinline b32 starts_with(String substring) const { return string_starts_with_string(* this, substring); }
|
forceinline b32 starts_with(StrBuilder substring) const { return strbuilder_starts_with_string(* this, substring); }
|
||||||
forceinline void skip_line() { string_skip_line(* this); }
|
forceinline void skip_line() { strbuilder_skip_line(* this); }
|
||||||
forceinline void strip_space() { string_strip_space(* this); }
|
forceinline void strip_space() { strbuilder_strip_space(* this); }
|
||||||
forceinline StrC to_strc() { return { string_length(*this), Data}; }
|
forceinline Str to_str() { return { Data, strbuilder_length(*this) }; }
|
||||||
forceinline void trim(char const* cut_set) { string_trim(* this, cut_set); }
|
forceinline void trim(char const* cut_set) { strbuilder_trim(* this, cut_set); }
|
||||||
forceinline void trim_space() { string_trim_space(* this); }
|
forceinline void trim_space() { strbuilder_trim_space(* this); }
|
||||||
forceinline String visualize_whitespace() const { return string_visualize_whitespace(* this); }
|
forceinline StrBuilder visualize_whitespace() const { return strbuilder_visualize_whitespace(* this); }
|
||||||
forceinline StringHeader& get_header() { return * string_get_header(* this); }
|
forceinline StrBuilderHeader& get_header() { return * strbuilder_get_header(* this); }
|
||||||
|
|
||||||
bool append_fmt(char const* fmt, ...) {
|
bool append_fmt(char const* fmt, ...) {
|
||||||
ssize res;
|
ssize res;
|
||||||
@ -255,163 +256,141 @@ struct String
|
|||||||
|
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
res = str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1;
|
res = c_str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1;
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
return string_append_c_str_len(this, buf, res);
|
return strbuilder_append_c_str_len(this, buf, res);
|
||||||
}
|
}
|
||||||
#pragma endregion Member Mapping
|
#pragma endregion Member Mapping
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
forceinline char* string_begin(String str) { return ((char*) str); }
|
forceinline char* strbuilder_begin(StrBuilder str) { return ((char*) str); }
|
||||||
forceinline char* string_end (String str) { return ((char*) str + string_length(str)); }
|
forceinline char* strbuilder_end (StrBuilder str) { return ((char*) str + strbuilder_length(str)); }
|
||||||
forceinline char* string_next (String str, char const* iter) { return ((char*) iter + 1); }
|
forceinline char* strbuilder_next (StrBuilder str, char const* iter) { return ((char*) iter + 1); }
|
||||||
|
|
||||||
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
|
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
|
||||||
forceinline char* begin(String str) { return ((char*) str); }
|
forceinline char* begin(StrBuilder str) { return ((char*) str); }
|
||||||
forceinline char* end (String str) { return ((char*) str + string_length(str)); }
|
forceinline char* end (StrBuilder str) { return ((char*) str + strbuilder_length(str)); }
|
||||||
forceinline char* next (String str, char* iter) { return ((char*) iter + 1); }
|
forceinline char* next (StrBuilder str, char* iter) { return ((char*) iter + 1); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
|
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
|
||||||
forceinline bool make_space_for(String& str, char const* to_append, ssize add_len);
|
forceinline bool make_space_for(StrBuilder& str, char const* to_append, ssize add_len);
|
||||||
forceinline bool append(String& str, char c);
|
forceinline bool append(StrBuilder& str, char c);
|
||||||
forceinline bool append(String& str, char const* str_to_append);
|
forceinline bool append(StrBuilder& str, char const* c_str_to_append);
|
||||||
forceinline bool append(String& str, char const* str_to_append, ssize length);
|
forceinline bool append(StrBuilder& str, char const* c_str_to_append, ssize length);
|
||||||
forceinline bool append(String& str, StrC str_to_append);
|
forceinline bool append(StrBuilder& str, Str c_str_to_append);
|
||||||
forceinline bool append(String& str, const String other);
|
forceinline bool append(StrBuilder& str, const StrBuilder other);
|
||||||
forceinline bool append_fmt(String& str, char const* fmt, ...);
|
forceinline bool append_fmt(StrBuilder& str, char const* fmt, ...);
|
||||||
forceinline char& back(String& str);
|
forceinline char& back(StrBuilder& str);
|
||||||
forceinline void clear(String& str);
|
forceinline void clear(StrBuilder& str);
|
||||||
forceinline void free(String& str);
|
forceinline void free(StrBuilder& str);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
usize string_grow_formula(usize value) {
|
usize strbuilder_grow_formula(usize value) {
|
||||||
// Using a very aggressive growth formula to reduce time mem_copying with recursive calls to append in this library.
|
// Using a very aggressive growth formula to reduce time mem_copying with recursive calls to append in this library.
|
||||||
return 4 * value + 8;
|
return 4 * value + 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
String string_make_c_str(AllocatorInfo allocator, char const* str) {
|
StrBuilder strbuilder_make_c_str(AllocatorInfo allocator, char const* str) {
|
||||||
ssize length = str ? str_len(str) : 0;
|
ssize length = str ? c_str_len(str) : 0;
|
||||||
return string_make_length(allocator, str, length);
|
return strbuilder_make_length(allocator, str, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
String string_make_strc(AllocatorInfo allocator, StrC str) {
|
StrBuilder strbuilder_make_str(AllocatorInfo allocator, Str str) {
|
||||||
return string_make_length(allocator, str.Ptr, str.Len);
|
return strbuilder_make_length(allocator, str.Ptr, str.Len);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
String string_fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) {
|
StrBuilder strbuilder_fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) {
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
ssize res = str_fmt_va(buf, buf_size, fmt, va) - 1;
|
ssize res = c_str_fmt_va(buf, buf_size, fmt, va) - 1;
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
return string_make_length(allocator, buf, res);
|
return strbuilder_make_length(allocator, buf, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
String string_fmt_buf(AllocatorInfo allocator, char const* fmt, ...)
|
StrBuilder strbuilder_fmt_buf(AllocatorInfo allocator, char const* fmt, ...)
|
||||||
{
|
{
|
||||||
local_persist thread_local
|
local_persist thread_local
|
||||||
PrintF_Buffer buf = struct_init(PrintF_Buffer, {0});
|
PrintF_Buffer buf = struct_init(PrintF_Buffer, {0});
|
||||||
|
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
ssize res = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) -1;
|
ssize res = c_str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) -1;
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
return string_make_length(allocator, buf, res);
|
return strbuilder_make_length(allocator, buf, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
String string_join(AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue)
|
StrBuilder strbuilder_join(AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue)
|
||||||
{
|
{
|
||||||
String result = string_make_c_str(allocator, "");
|
StrBuilder result = strbuilder_make_c_str(allocator, "");
|
||||||
|
|
||||||
for (ssize idx = 0; idx < num_parts; ++idx)
|
for (ssize idx = 0; idx < num_parts; ++idx)
|
||||||
{
|
{
|
||||||
string_append_c_str(& result, parts[idx]);
|
strbuilder_append_c_str(& result, parts[idx]);
|
||||||
|
|
||||||
if (idx < num_parts - 1)
|
if (idx < num_parts - 1)
|
||||||
string_append_c_str(& result, glue);
|
strbuilder_append_c_str(& result, glue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
bool string_append_char(String* str, char c) {
|
bool strbuilder_append_char(StrBuilder* str, char c) {
|
||||||
GEN_ASSERT(str != nullptr);
|
GEN_ASSERT(str != nullptr);
|
||||||
return string_append_c_str_len( str, (char const*)& c, (ssize)1);
|
return strbuilder_append_c_str_len( str, (char const*)& c, (ssize)1);
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
bool string_append_c_str(String* str, char const* str_to_append) {
|
bool strbuilder_append_c_str(StrBuilder* str, char const* c_str_to_append) {
|
||||||
GEN_ASSERT(str != nullptr);
|
GEN_ASSERT(str != nullptr);
|
||||||
return string_append_c_str_len(str, str_to_append, str_len(str_to_append));
|
return strbuilder_append_c_str_len(str, c_str_to_append, c_str_len(c_str_to_append));
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
bool strbuilder_append_str(StrBuilder* str, Str c_str_to_append) {
|
||||||
|
GEN_ASSERT(str != nullptr);
|
||||||
|
return strbuilder_append_c_str_len(str, c_str_to_append.Ptr, c_str_to_append.Len);
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
bool strbuilder_append_string(StrBuilder* str, StrBuilder const other) {
|
||||||
|
GEN_ASSERT(str != nullptr);
|
||||||
|
return strbuilder_append_c_str_len(str, (char const*)other, strbuilder_length(other));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool string_append_c_str_len(String* str, char const* str_to_append, ssize append_length)
|
bool strbuilder_append_fmt(StrBuilder* str, char const* fmt, ...) {
|
||||||
{
|
|
||||||
GEN_ASSERT(str != nullptr);
|
|
||||||
if ( rcast(sptr, str_to_append) > 0)
|
|
||||||
{
|
|
||||||
ssize curr_len = string_length(* str);
|
|
||||||
|
|
||||||
if ( ! string_make_space_for(str, str_to_append, append_length))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
StringHeader* header = string_get_header(* str);
|
|
||||||
|
|
||||||
char* Data = * str;
|
|
||||||
mem_copy( Data + curr_len, str_to_append, append_length);
|
|
||||||
|
|
||||||
Data[curr_len + append_length] = '\0';
|
|
||||||
|
|
||||||
header->Length = curr_len + append_length;
|
|
||||||
}
|
|
||||||
return str_to_append != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
forceinline
|
|
||||||
bool string_append_strc(String* str, StrC str_to_append) {
|
|
||||||
GEN_ASSERT(str != nullptr);
|
|
||||||
return string_append_c_str_len(str, str_to_append.Ptr, str_to_append.Len);
|
|
||||||
}
|
|
||||||
|
|
||||||
forceinline
|
|
||||||
bool string_append_string(String* str, String const other) {
|
|
||||||
GEN_ASSERT(str != nullptr);
|
|
||||||
return string_append_c_str_len(str, (char const*)other, string_length(other));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool string_append_fmt(String* str, char const* fmt, ...) {
|
|
||||||
GEN_ASSERT(str != nullptr);
|
GEN_ASSERT(str != nullptr);
|
||||||
ssize res;
|
ssize res;
|
||||||
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
||||||
|
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
res = str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1;
|
res = c_str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1;
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
return string_append_c_str_len(str, (char const*)buf, res);
|
return strbuilder_append_c_str_len(str, (char const*)buf, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool string_are_equal_string(String const lhs, String const rhs)
|
bool strbuilder_are_equal_string(StrBuilder const lhs, StrBuilder const rhs)
|
||||||
{
|
{
|
||||||
if (string_length(lhs) != string_length(rhs))
|
if (strbuilder_length(lhs) != strbuilder_length(rhs))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (ssize idx = 0; idx < string_length(lhs); ++idx)
|
for (ssize idx = 0; idx < strbuilder_length(lhs); ++idx)
|
||||||
if (lhs[idx] != rhs[idx])
|
if (lhs[idx] != rhs[idx])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -419,12 +398,12 @@ bool string_are_equal_string(String const lhs, String const rhs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool string_are_equal_strc(String const lhs, StrC rhs)
|
bool strbuilder_are_equal_str(StrBuilder const lhs, Str rhs)
|
||||||
{
|
{
|
||||||
if (string_length(lhs) != (rhs.Len))
|
if (strbuilder_length(lhs) != (rhs.Len))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (ssize idx = 0; idx < string_length(lhs); ++idx)
|
for (ssize idx = 0; idx < strbuilder_length(lhs); ++idx)
|
||||||
if (lhs[idx] != rhs.Ptr[idx])
|
if (lhs[idx] != rhs.Ptr[idx])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -432,20 +411,20 @@ bool string_are_equal_strc(String const lhs, StrC rhs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
ssize string_avail_space(String const str) {
|
ssize strbuilder_avail_space(StrBuilder const str) {
|
||||||
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader));
|
||||||
return header->Capacity - header->Length;
|
return header->Capacity - header->Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
char* string_back(String str) {
|
char* strbuilder_back(StrBuilder str) {
|
||||||
return & (str)[string_length(str) - 1];
|
return & (str)[strbuilder_length(str) - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool string_contains_StrC(String const str, StrC substring)
|
bool strbuilder_contains_StrC(StrBuilder const str, Str substring)
|
||||||
{
|
{
|
||||||
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader));
|
||||||
|
|
||||||
if (substring.Len > header->Length)
|
if (substring.Len > header->Length)
|
||||||
return false;
|
return false;
|
||||||
@ -455,7 +434,7 @@ bool string_contains_StrC(String const str, StrC substring)
|
|||||||
|
|
||||||
for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
|
for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
|
||||||
{
|
{
|
||||||
if (str_compare_len(str + idx, substring.Ptr, sub_len) == 0)
|
if (c_str_compare_len(str + idx, substring.Ptr, sub_len) == 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,19 +442,19 @@ bool string_contains_StrC(String const str, StrC substring)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool string_contains_string(String const str, String const substring)
|
bool strbuilder_contains_string(StrBuilder const str, StrBuilder const substring)
|
||||||
{
|
{
|
||||||
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader));
|
||||||
|
|
||||||
if (string_length(substring) > header->Length)
|
if (strbuilder_length(substring) > header->Length)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ssize main_len = header->Length;
|
ssize main_len = header->Length;
|
||||||
ssize sub_len = string_length(substring);
|
ssize sub_len = strbuilder_length(substring);
|
||||||
|
|
||||||
for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
|
for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
|
||||||
{
|
{
|
||||||
if (str_compare_len(str + idx, substring, sub_len) == 0)
|
if (c_str_compare_len(str + idx, substring, sub_len) == 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,101 +462,63 @@ bool string_contains_string(String const str, String const substring)
|
|||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
ssize string_capacity(String const str) {
|
ssize strbuilder_capacity(StrBuilder const str) {
|
||||||
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader));
|
||||||
return header->Capacity;
|
return header->Capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
void string_clear(String str) {
|
void strbuilder_clear(StrBuilder str) {
|
||||||
string_get_header(str)->Length = 0;
|
strbuilder_get_header(str)->Length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
String string_duplicate(String const str, AllocatorInfo allocator) {
|
StrBuilder strbuilder_duplicate(StrBuilder const str, AllocatorInfo allocator) {
|
||||||
return string_make_length(allocator, str, string_length(str));
|
return strbuilder_make_length(allocator, str, strbuilder_length(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
void string_free(String* str) {
|
void strbuilder_free(StrBuilder* str) {
|
||||||
GEN_ASSERT(str != nullptr);
|
GEN_ASSERT(str != nullptr);
|
||||||
if (! (* str))
|
if (! (* str))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
StringHeader* header = string_get_header(* str);
|
StrBuilderHeader* header = strbuilder_get_header(* str);
|
||||||
allocator_free(header->Allocator, header);
|
allocator_free(header->Allocator, header);
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
StringHeader* string_get_header(String str) {
|
StrBuilderHeader* strbuilder_get_header(StrBuilder str) {
|
||||||
return (StringHeader*)(scast(char*, str) - sizeof(StringHeader));
|
return (StrBuilderHeader*)(scast(char*, str) - sizeof(StrBuilderHeader));
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
ssize string_length(String const str)
|
ssize strbuilder_length(StrBuilder const str)
|
||||||
{
|
{
|
||||||
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader));
|
||||||
return header->Length;
|
return header->Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
bool string_make_space_for(String* str, char const* to_append, ssize add_len)
|
|
||||||
{
|
|
||||||
ssize available = string_avail_space(* str);
|
|
||||||
|
|
||||||
if (available >= add_len) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ssize new_len, old_size, new_size;
|
|
||||||
void* ptr;
|
|
||||||
void* new_ptr;
|
|
||||||
|
|
||||||
AllocatorInfo allocator = string_get_header(* str)->Allocator;
|
|
||||||
StringHeader* header = nullptr;
|
|
||||||
|
|
||||||
new_len = string_grow_formula(string_length(* str) + add_len);
|
|
||||||
ptr = string_get_header(* str);
|
|
||||||
old_size = size_of(StringHeader) + string_length(* str) + 1;
|
|
||||||
new_size = size_of(StringHeader) + new_len + 1;
|
|
||||||
|
|
||||||
new_ptr = resize(allocator, ptr, old_size, new_size);
|
|
||||||
|
|
||||||
if (new_ptr == nullptr)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
header = rcast(StringHeader*, new_ptr);
|
|
||||||
header->Allocator = allocator;
|
|
||||||
header->Capacity = new_len;
|
|
||||||
|
|
||||||
char** Data = rcast(char**, str);
|
|
||||||
* Data = rcast(char*, header + 1);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
b32 string_starts_with_strc(String const str, StrC substring) {
|
b32 strbuilder_starts_with_str(StrBuilder const str, Str substring) {
|
||||||
if (substring.Len > string_length(str))
|
if (substring.Len > strbuilder_length(str))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
b32 result = str_compare_len(str, substring.Ptr, substring.Len) == 0;
|
b32 result = c_str_compare_len(str, substring.Ptr, substring.Len) == 0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
b32 string_starts_with_string(String const str, String substring) {
|
b32 strbuilder_starts_with_string(StrBuilder const str, StrBuilder substring) {
|
||||||
if (string_length(substring) > string_length(str))
|
if (strbuilder_length(substring) > strbuilder_length(str))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
b32 result = str_compare_len(str, substring, string_length(substring) - 1) == 0;
|
b32 result = c_str_compare_len(str, substring, strbuilder_length(substring) - 1) == 0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void string_skip_line(String str)
|
void strbuilder_skip_line(StrBuilder str)
|
||||||
{
|
{
|
||||||
#define current (*scanner)
|
#define current (*scanner)
|
||||||
char* scanner = str;
|
char* scanner = str;
|
||||||
@ -593,13 +534,13 @@ void string_skip_line(String str)
|
|||||||
|
|
||||||
mem_move((char*)str, scanner, new_length);
|
mem_move((char*)str, scanner, new_length);
|
||||||
|
|
||||||
StringHeader* header = string_get_header(str);
|
StrBuilderHeader* header = strbuilder_get_header(str);
|
||||||
header->Length = new_length;
|
header->Length = new_length;
|
||||||
#undef current
|
#undef current
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void strip_space(String str)
|
void strbuilder_strip_space(StrBuilder str)
|
||||||
{
|
{
|
||||||
char* write_pos = str;
|
char* write_pos = str;
|
||||||
char* read_pos = str;
|
char* read_pos = str;
|
||||||
@ -616,129 +557,71 @@ void strip_space(String str)
|
|||||||
write_pos[0] = '\0'; // Null-terminate the modified string
|
write_pos[0] = '\0'; // Null-terminate the modified string
|
||||||
|
|
||||||
// Update the length if needed
|
// Update the length if needed
|
||||||
string_get_header(str)->Length = write_pos - str;
|
strbuilder_get_header(str)->Length = write_pos - str;
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
StrC string_to_strc(String str) {
|
Str strbuilder_to_str(StrBuilder str) {
|
||||||
StrC result = { string_length(str), (char const*)str };
|
Str result = { (char const*)str, strbuilder_length(str) };
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
void string_trim(String str, char const* cut_set)
|
|
||||||
{
|
|
||||||
ssize len = 0;
|
|
||||||
|
|
||||||
char* start_pos = str;
|
|
||||||
char* end_pos = scast(char*, str) + string_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';
|
|
||||||
|
|
||||||
string_get_header(str)->Length = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
void string_trim_space(String str) {
|
void strbuilder_trim_space(StrBuilder str) {
|
||||||
string_trim(str, " \t\r\n\v\f");
|
strbuilder_trim(str, " \t\r\n\v\f");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
#pragma endregion StrBuilder
|
||||||
String string_visualize_whitespace(String const str)
|
|
||||||
{
|
|
||||||
StringHeader* header = (StringHeader*)(scast(char const*, str) - sizeof(StringHeader));
|
|
||||||
String result = string_make_reserve(header->Allocator, string_length(str) * 2); // Assume worst case for space requirements.
|
|
||||||
|
|
||||||
for (char const* c = string_begin(str); c != string_end(str); c = string_next(str, c))
|
|
||||||
switch ( * c )
|
|
||||||
{
|
|
||||||
case ' ':
|
|
||||||
string_append_strc(& result, txt("·"));
|
|
||||||
break;
|
|
||||||
case '\t':
|
|
||||||
string_append_strc(& result, txt("→"));
|
|
||||||
break;
|
|
||||||
case '\n':
|
|
||||||
string_append_strc(& result, txt("↵"));
|
|
||||||
break;
|
|
||||||
case '\r':
|
|
||||||
string_append_strc(& result, txt("⏎"));
|
|
||||||
break;
|
|
||||||
case '\v':
|
|
||||||
string_append_strc(& result, txt("⇕"));
|
|
||||||
break;
|
|
||||||
case '\f':
|
|
||||||
string_append_strc(& result, txt("⌂"));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
string_append_char(& result, * c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#pragma endregion String
|
|
||||||
|
|
||||||
#if GEN_COMPILER_CPP
|
#if GEN_COMPILER_CPP
|
||||||
struct String_POD {
|
struct StrBuilder_POD {
|
||||||
char* Data;
|
char* Data;
|
||||||
};
|
};
|
||||||
static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" );
|
static_assert( sizeof( StrBuilder_POD ) == sizeof( StrBuilder ), "StrBuilder is not a POD" );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
StrC strc_duplicate(StrC str, AllocatorInfo allocator) {
|
Str str_duplicate(Str str, AllocatorInfo allocator) {
|
||||||
StrC result = string_to_strc( string_make_length(allocator, str.Ptr, str.Len));
|
Str result = strbuilder_to_str( strbuilder_make_length(allocator, str.Ptr, str.Len));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator)
|
Str str_visualize_whitespace(Str str, AllocatorInfo allocator)
|
||||||
{
|
{
|
||||||
String result = string_make_reserve(allocator, str.Len * 2); // Assume worst case for space requirements.
|
StrBuilder result = strbuilder_make_reserve(allocator, str.Len * 2); // Assume worst case for space requirements.
|
||||||
for (char const* c = strc_begin(str); c != strc_end(str); c = strc_next(str, c))
|
for (char const* c = str_begin(str); c != str_end(str); c = str_next(str, c))
|
||||||
switch ( * c )
|
switch ( * c )
|
||||||
{
|
{
|
||||||
case ' ':
|
case ' ':
|
||||||
string_append_strc(& result, txt("·"));
|
strbuilder_append_str(& result, txt("·"));
|
||||||
break;
|
break;
|
||||||
case '\t':
|
case '\t':
|
||||||
string_append_strc(& result, txt("→"));
|
strbuilder_append_str(& result, txt("→"));
|
||||||
break;
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
string_append_strc(& result, txt("↵"));
|
strbuilder_append_str(& result, txt("↵"));
|
||||||
break;
|
break;
|
||||||
case '\r':
|
case '\r':
|
||||||
string_append_strc(& result, txt("⏎"));
|
strbuilder_append_str(& result, txt("⏎"));
|
||||||
break;
|
break;
|
||||||
case '\v':
|
case '\v':
|
||||||
string_append_strc(& result, txt("⇕"));
|
strbuilder_append_str(& result, txt("⇕"));
|
||||||
break;
|
break;
|
||||||
case '\f':
|
case '\f':
|
||||||
string_append_strc(& result, txt("⌂"));
|
strbuilder_append_str(& result, txt("⌂"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
string_append_char(& result, * c);
|
strbuilder_append_char(& result, * c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return string_to_strc(result);
|
return strbuilder_to_str(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Represents strings cached with the string table.
|
// Represents strings cached with the string table.
|
||||||
// Should never be modified, if changed string is desired, cache_string( str ) another.
|
// Should never be modified, if changed string is desired, cache_string( str ) another.
|
||||||
typedef StrC StringCached;
|
typedef Str StrCached;
|
||||||
|
|
||||||
// Implements basic string interning. Data structure is based off the ZPL Hashtable.
|
// Implements basic string interning. Data structure is based off the ZPL Hashtable.
|
||||||
typedef HashTable(StringCached) StringTable;
|
typedef HashTable(StrCached) StringTable;
|
||||||
#pragma endregion Strings
|
#pragma endregion Strings
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "filesystem.cpp"
|
# include "filesystem.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "filesystem.hpp"
|
# include "filesystem.hpp"
|
||||||
#endif
|
#endif
|
||||||
@ -7,13 +7,13 @@
|
|||||||
|
|
||||||
#ifdef GEN_BENCHMARK
|
#ifdef GEN_BENCHMARK
|
||||||
//! Return CPU timestamp.
|
//! 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.
|
//! 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.
|
//! Return relative time since the application start.
|
||||||
u64 time_rel_ms( void );
|
GEN_API u64 time_rel_ms( void );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma endregion Timing
|
#pragma endregion Timing
|
||||||
|
@ -1,2 +1 @@
|
|||||||
API_Export, GEN_API_Export_Code
|
GEN_API, GEN_API
|
||||||
API_Import, GEN_API_Import_Code
|
|
||||||
|
|
@ -37,6 +37,7 @@ Operator_Member_Fwd, "operator"
|
|||||||
Operator_Cast, "operator"
|
Operator_Cast, "operator"
|
||||||
Operator_Cast_Fwd, "operator"
|
Operator_Cast_Fwd, "operator"
|
||||||
Parameters, "__NA__"
|
Parameters, "__NA__"
|
||||||
|
Parameters_Define, "__NA__"
|
||||||
Preprocess_Define, "define"
|
Preprocess_Define, "define"
|
||||||
Preprocess_Include, "include"
|
Preprocess_Include, "include"
|
||||||
Preprocess_If, "if"
|
Preprocess_If, "if"
|
||||||
|
|
@ -14,6 +14,7 @@ NeverInline, neverinline
|
|||||||
Ptr, *
|
Ptr, *
|
||||||
Ref, &
|
Ref, &
|
||||||
Register, register
|
Register, register
|
||||||
|
Restrict, restrict
|
||||||
RValue, &&
|
RValue, &&
|
||||||
Static, static
|
Static, static
|
||||||
Thread_Local, thread_local
|
Thread_Local, thread_local
|
||||||
@ -23,4 +24,5 @@ Final, final
|
|||||||
NoExceptions, noexcept
|
NoExceptions, noexcept
|
||||||
Override, override
|
Override, override
|
||||||
Pure, = 0
|
Pure, = 0
|
||||||
|
Delete, = delete
|
||||||
Volatile, volatile
|
Volatile, volatile
|
||||||
|
|
@ -1,95 +1,99 @@
|
|||||||
Invalid, "__invalid__"
|
Invalid, "__invalid__"
|
||||||
Access_Private, "private"
|
Access_Private, "private"
|
||||||
Access_Protected, "protected"
|
Access_Protected, "protected"
|
||||||
Access_Public, "public"
|
Access_Public, "public"
|
||||||
Access_MemberSymbol, "."
|
Access_MemberSymbol, "."
|
||||||
Access_StaticSymbol, "::"
|
Access_StaticSymbol, "::"
|
||||||
Ampersand, "&"
|
Ampersand, "&"
|
||||||
Ampersand_DBL, "&&"
|
Ampersand_DBL, "&&"
|
||||||
Assign_Classifer, ":"
|
Assign_Classifer, ":"
|
||||||
Attribute_Open, "[["
|
Attribute_Open, "[["
|
||||||
Attribute_Close, "]]"
|
Attribute_Close, "]]"
|
||||||
BraceCurly_Open, "{"
|
BraceCurly_Open, "{"
|
||||||
BraceCurly_Close, "}"
|
BraceCurly_Close, "}"
|
||||||
BraceSquare_Open, "["
|
BraceSquare_Open, "["
|
||||||
BraceSquare_Close, "]"
|
BraceSquare_Close, "]"
|
||||||
Capture_Start, "("
|
Paren_Open, "("
|
||||||
Capture_End, ")"
|
Paren_Close, ")"
|
||||||
Comment, "__comment__"
|
Comment, "__comment__"
|
||||||
Comment_End, "__comment_end__"
|
Comment_End, "__comment_end__"
|
||||||
Comment_Start, "__comment_start__"
|
Comment_Start, "__comment_start__"
|
||||||
Char, "__character__"
|
Char, "__character__"
|
||||||
Comma, ","
|
Comma, ","
|
||||||
Decl_Class, "class"
|
Decl_Class, "class"
|
||||||
Decl_GNU_Attribute, "__attribute__"
|
Decl_GNU_Attribute, "__attribute__"
|
||||||
Decl_MSVC_Attribute, "__declspec"
|
Decl_MSVC_Attribute, "__declspec"
|
||||||
Decl_Enum, "enum"
|
Decl_Enum, "enum"
|
||||||
Decl_Extern_Linkage, "extern"
|
Decl_Extern_Linkage, "extern"
|
||||||
Decl_Friend, "friend"
|
Decl_Friend, "friend"
|
||||||
Decl_Module, "module"
|
Decl_Module, "module"
|
||||||
Decl_Namespace, "namespace"
|
Decl_Namespace, "namespace"
|
||||||
Decl_Operator, "operator"
|
Decl_Operator, "operator"
|
||||||
Decl_Struct, "struct"
|
Decl_Struct, "struct"
|
||||||
Decl_Template, "template"
|
Decl_Template, "template"
|
||||||
Decl_Typedef, "typedef"
|
Decl_Typedef, "typedef"
|
||||||
Decl_Using, "using"
|
Decl_Using, "using"
|
||||||
Decl_Union, "union"
|
Decl_Union, "union"
|
||||||
Identifier, "__identifier__"
|
Identifier, "__identifier__"
|
||||||
Module_Import, "import"
|
Module_Import, "import"
|
||||||
Module_Export, "export"
|
Module_Export, "export"
|
||||||
NewLine, "__new_line__"
|
NewLine, "__new_line__"
|
||||||
Number, "__number__"
|
Number, "__number__"
|
||||||
Operator, "__operator__"
|
Operator, "__operator__"
|
||||||
Preprocess_Hash, "#"
|
Preprocess_Hash, "#"
|
||||||
Preprocess_Define, "define"
|
Preprocess_Define, "define"
|
||||||
Preprocess_If, "if"
|
Preprocess_Define_Param, "__define_param__"
|
||||||
Preprocess_IfDef, "ifdef"
|
Preprocess_If, "if"
|
||||||
Preprocess_IfNotDef, "ifndef"
|
Preprocess_IfDef, "ifdef"
|
||||||
Preprocess_ElIf, "elif"
|
Preprocess_IfNotDef, "ifndef"
|
||||||
Preprocess_Else, "else"
|
Preprocess_ElIf, "elif"
|
||||||
Preprocess_EndIf, "endif"
|
Preprocess_Else, "else"
|
||||||
Preprocess_Include, "include"
|
Preprocess_EndIf, "endif"
|
||||||
Preprocess_Pragma, "pragma"
|
Preprocess_Include, "include"
|
||||||
Preprocess_Content, "__macro_content__"
|
Preprocess_Pragma, "pragma"
|
||||||
Preprocess_Macro, "__macro__"
|
Preprocess_Content, "__macro_content__"
|
||||||
Preprocess_Unsupported, "__unsupported__"
|
Preprocess_Macro_Expr, "__macro_expression__"
|
||||||
Spec_Alignas, "alignas"
|
Preprocess_Macro_Stmt, "__macro_statment__"
|
||||||
Spec_Const, "const"
|
Preprocess_Macro_Typename, "__macro_typename__"
|
||||||
Spec_Consteval, "consteval"
|
Preprocess_Unsupported, "__unsupported__"
|
||||||
Spec_Constexpr, "constexpr"
|
Spec_Alignas, "alignas"
|
||||||
Spec_Constinit, "constinit"
|
Spec_Const, "const"
|
||||||
Spec_Explicit, "explicit"
|
Spec_Consteval, "consteval"
|
||||||
Spec_Extern, "extern"
|
Spec_Constexpr, "constexpr"
|
||||||
Spec_Final, "final"
|
Spec_Constinit, "constinit"
|
||||||
Spec_ForceInline, "forceinline"
|
Spec_Explicit, "explicit"
|
||||||
Spec_Global, "global"
|
Spec_Extern, "extern"
|
||||||
Spec_Inline, "inline"
|
Spec_Final, "final"
|
||||||
Spec_Internal_Linkage, "internal"
|
Spec_ForceInline, "forceinline"
|
||||||
Spec_LocalPersist, "local_persist"
|
Spec_Global, "global"
|
||||||
Spec_Mutable, "mutable"
|
Spec_Inline, "inline"
|
||||||
Spec_NeverInline, "neverinline"
|
Spec_Internal_Linkage, "internal"
|
||||||
Spec_Override, "override"
|
Spec_LocalPersist, "local_persist"
|
||||||
Spec_Static, "static"
|
Spec_Mutable, "mutable"
|
||||||
Spec_ThreadLocal, "thread_local"
|
Spec_NeverInline, "neverinline"
|
||||||
Spec_Volatile, "volatile"
|
Spec_Override, "override"
|
||||||
Spec_Virtual, "virtual"
|
Spec_Restrict, "restrict"
|
||||||
Star, "*"
|
Spec_Static, "static"
|
||||||
Statement_End, ";"
|
Spec_ThreadLocal, "thread_local"
|
||||||
StaticAssert, "static_assert"
|
Spec_Volatile, "volatile"
|
||||||
String, "__string__"
|
Spec_Virtual, "virtual"
|
||||||
Type_Typename, "typename"
|
Star, "*"
|
||||||
Type_Unsigned, "unsigned"
|
Statement_End, ";"
|
||||||
Type_Signed, "signed"
|
StaticAssert, "static_assert"
|
||||||
Type_Short, "short"
|
String, "__string__"
|
||||||
Type_Long, "long"
|
Type_Typename, "typename"
|
||||||
Type_bool, "bool"
|
Type_Unsigned, "unsigned"
|
||||||
Type_char, "char"
|
Type_Signed, "signed"
|
||||||
Type_int, "int"
|
Type_Short, "short"
|
||||||
Type_double, "double"
|
Type_Long, "long"
|
||||||
Type_MS_int8, "__int8"
|
Type_bool, "bool"
|
||||||
Type_MS_int16, "__int16"
|
Type_char, "char"
|
||||||
Type_MS_int32, "__int32"
|
Type_int, "int"
|
||||||
Type_MS_int64, "__int64"
|
Type_double, "double"
|
||||||
Type_MS_W64, "_W64"
|
Type_MS_int8, "__int8"
|
||||||
Varadic_Argument, "..."
|
Type_MS_int16, "__int16"
|
||||||
__Attributes_Start, "__attrib_start__"
|
Type_MS_int32, "__int32"
|
||||||
|
Type_MS_int64, "__int64"
|
||||||
|
Type_MS_W64, "_W64"
|
||||||
|
Varadic_Argument, "..."
|
||||||
|
__Attributes_Start, "__attrib_start__"
|
||||||
|
|
@ -31,14 +31,14 @@ GEN_NS_BEGIN
|
|||||||
|
|
||||||
#include "components/interface.cpp"
|
#include "components/interface.cpp"
|
||||||
#include "components/interface.upfront.cpp"
|
#include "components/interface.upfront.cpp"
|
||||||
#include "components/gen/etoktype.cpp"
|
|
||||||
#include "components/lexer.cpp"
|
#include "components/lexer.cpp"
|
||||||
|
#include "components/parser_case_macros.cpp"
|
||||||
#include "components/parser.cpp"
|
#include "components/parser.cpp"
|
||||||
#include "components/interface.parsing.cpp"
|
#include "components/interface.parsing.cpp"
|
||||||
#include "components/interface.untyped.cpp"
|
#include "components/interface.untyped.cpp"
|
||||||
|
|
||||||
#include "auxillary/builder.cpp"
|
#include "auxiliary/builder.cpp"
|
||||||
#include "auxillary/scanner.cpp"
|
#include "auxiliary/scanner.cpp"
|
||||||
|
|
||||||
GEN_NS_END
|
GEN_NS_END
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@ GEN_NS_BEGIN
|
|||||||
#include "components/gen/ecodetypes.hpp"
|
#include "components/gen/ecodetypes.hpp"
|
||||||
#include "components/gen/eoperator.hpp"
|
#include "components/gen/eoperator.hpp"
|
||||||
#include "components/gen/especifier.hpp"
|
#include "components/gen/especifier.hpp"
|
||||||
|
#include "components/gen/etoktype.hpp"
|
||||||
|
#include "components/parser_types.hpp"
|
||||||
|
|
||||||
#include "components/ast.hpp"
|
#include "components/ast.hpp"
|
||||||
#include "components/code_types.hpp"
|
#include "components/code_types.hpp"
|
||||||
@ -27,12 +29,12 @@ GEN_NS_BEGIN
|
|||||||
|
|
||||||
#include "components/interface.hpp"
|
#include "components/interface.hpp"
|
||||||
|
|
||||||
|
#include "components/constants.hpp"
|
||||||
#include "components/inlines.hpp"
|
#include "components/inlines.hpp"
|
||||||
#include "components/gen/ast_inlines.hpp"
|
#include "components/gen/ast_inlines.hpp"
|
||||||
#include "components/header_end.hpp"
|
|
||||||
|
|
||||||
#include "auxillary/builder.hpp"
|
#include "auxiliary/builder.hpp"
|
||||||
#include "auxillary/scanner.hpp"
|
#include "auxiliary/scanner.hpp"
|
||||||
|
|
||||||
GEN_NS_END
|
GEN_NS_END
|
||||||
|
|
||||||
|
@ -1,423 +0,0 @@
|
|||||||
__VERSION 1
|
|
||||||
|
|
||||||
// This is a example template to be used with the refactor program
|
|
||||||
// Use it to refactor the naming convention of this library to your own.
|
|
||||||
// Can be used as an aid to help use use your project's implementation if it fullfills the dependencies of this project.
|
|
||||||
// Example: Most likely have a memory and string library already, just rename the functions and make sure the args are the same.
|
|
||||||
// Program: https://github.com/Ed94/refactor
|
|
||||||
|
|
||||||
// NOTE: Due to the current limitations of the program, not every symbol in the library can be renamed.
|
|
||||||
// This is due to the program not actually parsing C/C++.
|
|
||||||
|
|
||||||
// not : Ignore
|
|
||||||
// include : #includes
|
|
||||||
// word : Alphanumeric or underscore
|
|
||||||
// namespace : Prefix search and replace (c-namspaces).
|
|
||||||
// regex : Unavailable in __VERSION 1.
|
|
||||||
|
|
||||||
// Precedence (highest to lowest):
|
|
||||||
// word, namespace, regex
|
|
||||||
|
|
||||||
// TODO(ED): THIS IS VERY OUTDATED
|
|
||||||
|
|
||||||
// Gen Macro namespace
|
|
||||||
// namespace GEN_, new_namespace_
|
|
||||||
|
|
||||||
// ---------- Dependency Macros
|
|
||||||
// Platform
|
|
||||||
// word GEN_ARCH_64_BIT, new_name
|
|
||||||
// word GEN_ARCH_32_BIT, new_name
|
|
||||||
|
|
||||||
// word GEN_SYSTEM_ANDROID, new_name
|
|
||||||
// word GEN_SYSTEM_CYGWIN, new_name
|
|
||||||
// word GEN_SYSTEM_EMSCRIPTEN, new_name
|
|
||||||
// word GEN_SYSTEM_FREEBSD, new_name
|
|
||||||
// word GEN_SYSTEM_IOS, new_name
|
|
||||||
// word GEN_SYSTEM_LINUX, new_name
|
|
||||||
// word GEN_SYSTEM_MACOS, new_name
|
|
||||||
// word GEN_SYSTEM_OPENBSD, new_name
|
|
||||||
// word GEN_SYSTEM_OSX, new_name
|
|
||||||
// word GEN_SYSTEM_UNIX, new_name
|
|
||||||
// word GEN_SYSTEM_WINDOWS, new_name
|
|
||||||
|
|
||||||
// word GEN_COMPILER_CLANG, new_name
|
|
||||||
// word GEN_COMPILER_GCC, new_name
|
|
||||||
// word GEN_COMPILER_MINGW, new_name
|
|
||||||
// word GEN_COMPILER_MSVC, new_name
|
|
||||||
|
|
||||||
// word global, new_name
|
|
||||||
// word internal, new_name
|
|
||||||
// word local_persist, new_name
|
|
||||||
// word forceinline, new_name
|
|
||||||
// word neverinline, new_name
|
|
||||||
|
|
||||||
// word bit, new_name
|
|
||||||
// word bitfield_is_equal, new_name
|
|
||||||
|
|
||||||
// word ccast, new_name
|
|
||||||
// word pcast, new_name
|
|
||||||
// word rcast, new_name
|
|
||||||
// word scast, new_name
|
|
||||||
|
|
||||||
// word num_args, new_name
|
|
||||||
// word num_args_impl, new_name
|
|
||||||
|
|
||||||
// word stringize, new_name
|
|
||||||
// word stringize_va, new_name
|
|
||||||
|
|
||||||
// word do_once, new_name
|
|
||||||
// word do_once_start, new_name
|
|
||||||
// word do_once_end, new_name
|
|
||||||
// word label_scope_start, new_name
|
|
||||||
// word label_scope_end, new_name
|
|
||||||
|
|
||||||
// word count_of, new_name
|
|
||||||
// word is_between, new_name
|
|
||||||
// word min, new_name
|
|
||||||
// word size_of, new_name
|
|
||||||
// word offset_of, new_name
|
|
||||||
// word swap, new_name
|
|
||||||
|
|
||||||
// Basic Types
|
|
||||||
// word GEN_U8_MIN, new_name
|
|
||||||
// word GEN_U8_MAX, new_name
|
|
||||||
// word GEN_I8_MIN, new_name
|
|
||||||
// word GEN_I8_MAX, new_name
|
|
||||||
|
|
||||||
// word GEN_U16_MIN, new_name
|
|
||||||
// word GEN_U16_MAX, new_name
|
|
||||||
// word GEN_I16_MIN, new_name
|
|
||||||
// word GEN_I16_MAX, new_name
|
|
||||||
|
|
||||||
// word GEN_U32_MIN, new_name
|
|
||||||
// word GEN_U32_MAX, new_name
|
|
||||||
// word GEN_I32_MIN, new_name
|
|
||||||
// word GEN_I32_MAX, new_name
|
|
||||||
|
|
||||||
// word GEN_U64_MIN, new_name
|
|
||||||
// word GEN_U64_MAX, new_name
|
|
||||||
// word GEN_I64_MIN, new_name
|
|
||||||
// word GEN_I64_MAX, new_name
|
|
||||||
|
|
||||||
// word GEN_USIZE_MIN, new_name
|
|
||||||
// word GEN_USIZE_MAX, new_name
|
|
||||||
// word GEN_ISIZE_MIN, new_name
|
|
||||||
// word GEN_ISIZE_MAX, new_name
|
|
||||||
|
|
||||||
// word GEN_F32_MIN, new_name
|
|
||||||
// word GEN_F32_MAX, new_name
|
|
||||||
// word GEN_F64_MIN, new_name
|
|
||||||
// word GEN_F64_MAX, new_name
|
|
||||||
|
|
||||||
// Debug
|
|
||||||
// word GEN_DEBUG_TRAP, new_name
|
|
||||||
// word GEN_ASSERT, new_name
|
|
||||||
// word GEN_ASSERT_MSG, new_name
|
|
||||||
// word GEN_ASSERT_NOT_NULL, new_name
|
|
||||||
// word GEN_PANIC, new_name
|
|
||||||
// word GEN_FATAL, new_name
|
|
||||||
|
|
||||||
// Memory
|
|
||||||
// word kilobytes, new_name
|
|
||||||
// word megabytes, new_name
|
|
||||||
// word gigabytes, new_name
|
|
||||||
// word terabytes, new_name
|
|
||||||
|
|
||||||
// word zero_item, new_name
|
|
||||||
// word zero_array, new_name
|
|
||||||
|
|
||||||
// word alloc_item, new_name
|
|
||||||
// word alloc_array, new_name
|
|
||||||
|
|
||||||
// word malloc, new_name
|
|
||||||
// word mfree, new_name
|
|
||||||
|
|
||||||
// Strings
|
|
||||||
// word txt, new_name
|
|
||||||
// word cast_to_strc, new_name
|
|
||||||
|
|
||||||
// ---------- Dependency Types
|
|
||||||
|
|
||||||
// word b8, new_name
|
|
||||||
// word b16, new_name
|
|
||||||
// word b32, new_name
|
|
||||||
// word s8, new_name
|
|
||||||
// word s16, new_name
|
|
||||||
// word s32, new_name
|
|
||||||
// word s64, new_name
|
|
||||||
// word u8, new_name
|
|
||||||
// word u16, new_name
|
|
||||||
// word u32, new_name
|
|
||||||
// word u64, new_name
|
|
||||||
// word usize, new_name
|
|
||||||
// word ssize, new_name
|
|
||||||
// word sptr, new_name
|
|
||||||
// word uptr, new_name
|
|
||||||
// word f32, new_name
|
|
||||||
// word f64, new_name
|
|
||||||
|
|
||||||
// namespace EAllocator_, new_namespace_
|
|
||||||
// namespace EFileMode_, new_namespace_
|
|
||||||
// namespace EFileError_, new_namespace_
|
|
||||||
|
|
||||||
// word AllocatorInfo, new_name
|
|
||||||
// word AllocatorProc, new_name
|
|
||||||
// word AllocFlag, new_name
|
|
||||||
// word AllocType, new_name
|
|
||||||
// word ArrayHeader, new_name
|
|
||||||
// word DirEntry, new_name
|
|
||||||
// word DirInfo, new_name
|
|
||||||
// word DirType, new_name
|
|
||||||
// word FileDescriptor, new_name
|
|
||||||
// word FileError, new_name
|
|
||||||
// word FileInfo, new_name
|
|
||||||
// word FileTime, new_name
|
|
||||||
// word FileModeFlag, new_name
|
|
||||||
// word FileOperations, new_name
|
|
||||||
// word FileStandardType, new_name
|
|
||||||
// word SeekWhenceType, new_name
|
|
||||||
|
|
||||||
// ---------- Dependency Data
|
|
||||||
|
|
||||||
// word default_file_operations, new_name
|
|
||||||
|
|
||||||
// ---------- Dependency Procedures
|
|
||||||
|
|
||||||
// word align_forward, new_name
|
|
||||||
// word align_fordward_i64, new_name
|
|
||||||
// word alloc, new_name
|
|
||||||
// word alloc_align, new_name
|
|
||||||
// word assert_handler, new_name
|
|
||||||
// word assert_crash, new_name
|
|
||||||
// word char_first_occurence, new_name
|
|
||||||
// word char_is_alpha, new_name
|
|
||||||
// word char_is_alphanumeric, new_name
|
|
||||||
// word char_is_digit, new_name
|
|
||||||
// word char_is_hex_digit, new_name
|
|
||||||
// word char_is_space, new_name
|
|
||||||
// word char_to_lower, new_name
|
|
||||||
// word char_to_upper, new_name
|
|
||||||
// word crc32, new_name
|
|
||||||
// word default_resize_align, new_name
|
|
||||||
// word digit_to_int, new_name
|
|
||||||
// word file_close, new_name
|
|
||||||
// word file_get_standard, new_name
|
|
||||||
// word file_name, new_name
|
|
||||||
// word file_open, new_name
|
|
||||||
// word file_open_mode, new_name
|
|
||||||
// word file_seek, new_name
|
|
||||||
// word file_tell, new_name
|
|
||||||
// word file_write, new_name
|
|
||||||
// word file_write_at, new_name
|
|
||||||
// word file_write_at_check, new_name
|
|
||||||
// word free, new_name
|
|
||||||
// word free_all, new_name
|
|
||||||
// word heap, new_name
|
|
||||||
// word heap_allocator_proc, new_name
|
|
||||||
// word heap_stats_check, new_name
|
|
||||||
// word heap_stats_alloc_count, new_name
|
|
||||||
// word heap_stats_init, new_name
|
|
||||||
// word heap_stats_used_memory, new_name
|
|
||||||
// word hex_digit_to_int, new_name
|
|
||||||
// word i64_to_str, new_name
|
|
||||||
// word is_power_of_two, new_name
|
|
||||||
// word log_fmt, new_name
|
|
||||||
// word mem_copy, new_name
|
|
||||||
// word mem_move, new_name
|
|
||||||
// word mem_set, new_name
|
|
||||||
// word pointer_add, new_name
|
|
||||||
// word mem_copy, new_name
|
|
||||||
// word mem_find, new_name
|
|
||||||
// word mem_move, new_name
|
|
||||||
// word mem_set, new_name
|
|
||||||
// word resize, new_name
|
|
||||||
// word resize_align, new_name
|
|
||||||
// word process_exit, new_name
|
|
||||||
// word str_compare, new_name
|
|
||||||
// word str_copy, new_name
|
|
||||||
// word str_copy_nulpad, new_name
|
|
||||||
// word str_fmt_buf, new_name
|
|
||||||
// word str_fmt_buf_va, new_name
|
|
||||||
// word str_fmt_file_va, new_name
|
|
||||||
// word str_fmt_out_va, new_name
|
|
||||||
// word str_fmt_out_err, new_name
|
|
||||||
// word str_fmt_out_err_va, new_name
|
|
||||||
// word str_fmt_va, new_name
|
|
||||||
// word str_len, new_name
|
|
||||||
// word str_reverse, new_name
|
|
||||||
// word str_to_i64, new_name
|
|
||||||
// word str_to_lower, new_name
|
|
||||||
// word str_to_upper, new_name
|
|
||||||
// word u64_to_str, new_name
|
|
||||||
// word zero_size, new_name
|
|
||||||
|
|
||||||
// ---------- gencpp Macros
|
|
||||||
|
|
||||||
// word log_failure, new_name
|
|
||||||
|
|
||||||
// word NullCode, new_name
|
|
||||||
// word CodeInvalid, new_name
|
|
||||||
|
|
||||||
// ------------ gencpp common
|
|
||||||
|
|
||||||
// word Arena, new_name
|
|
||||||
// word Array, new_name
|
|
||||||
// word HashTable, new_name
|
|
||||||
// word Pool, new_name
|
|
||||||
// word StrC, new_name
|
|
||||||
// word String, new_name
|
|
||||||
|
|
||||||
// word to_str, new_name
|
|
||||||
// word to_str, new_name
|
|
||||||
// word to_type, new_name
|
|
||||||
|
|
||||||
// ------------ gencpp Types & Constants
|
|
||||||
|
|
||||||
// word LogFailType, new_name
|
|
||||||
|
|
||||||
// word AccessSpec, new_name
|
|
||||||
// word ECode, new_name
|
|
||||||
// word EnumClass, new_name
|
|
||||||
// word EnumRegular, new_name
|
|
||||||
// word EnumT, new_name
|
|
||||||
// word EOperator, new_name
|
|
||||||
// word ESpecifier, new_name
|
|
||||||
// word OperatorT, new_name
|
|
||||||
// word ModuleFlag, new_name
|
|
||||||
// word SpecifierT, new_name
|
|
||||||
// word StringCached, new_name
|
|
||||||
// word StringTable, new_name
|
|
||||||
// word UsingRegular, new_name
|
|
||||||
// word UsingNamespace, new_name
|
|
||||||
|
|
||||||
// ------------ gencpp Data
|
|
||||||
|
|
||||||
// word API_Export, new_name
|
|
||||||
// word API_Import, new_name
|
|
||||||
// word AST_POD_Size, new_name
|
|
||||||
// word AST, new_name
|
|
||||||
// word AST_POD, new_name
|
|
||||||
// word Code, new_name
|
|
||||||
// word Code_POD, new_name
|
|
||||||
// word Keyword, new_name
|
|
||||||
|
|
||||||
// ------------ gencpp API
|
|
||||||
|
|
||||||
// word init, new_name
|
|
||||||
// word deinit, new_name
|
|
||||||
|
|
||||||
// word get_cached_string, new_name
|
|
||||||
// word make_code, new_name
|
|
||||||
// word make_code_entries, new_name
|
|
||||||
|
|
||||||
// word set_allocator_data_arrays, new_name
|
|
||||||
// word set_allocator_code_pool, new_name
|
|
||||||
// word set_allocator_code_entries_arena, new_name
|
|
||||||
// word set_allocator_string_arena, new_name
|
|
||||||
// word set_allocator_string_table, new_name
|
|
||||||
// word set_allocator_type_table, new_name
|
|
||||||
|
|
||||||
// ------------ upfront constructor namespace
|
|
||||||
// namespace def_ new_namespace_
|
|
||||||
|
|
||||||
// ------------ upfront constructor individual
|
|
||||||
|
|
||||||
// word def_attributes, new_name
|
|
||||||
// word def_comment, new_name
|
|
||||||
// word def_class, new_name
|
|
||||||
// word def_constructor, new_name
|
|
||||||
// word def_destructor, new_name
|
|
||||||
// word def_define, new_name
|
|
||||||
// word def_enum, new_name
|
|
||||||
// word def_execution, new_name
|
|
||||||
// word def_extern_link, new_name
|
|
||||||
// word def_friend, new_name
|
|
||||||
// word def_function, new_name
|
|
||||||
// word def_include, new_name
|
|
||||||
// word def_module, new_name
|
|
||||||
// word def_namespace, new_name
|
|
||||||
// word def_operator, new_name
|
|
||||||
// word def_operator_cast, new_name
|
|
||||||
// word def_param, new_name
|
|
||||||
// word def_pargma, new_name
|
|
||||||
// word def_preprocess_cond, new_name
|
|
||||||
// word def_specifier, new_name
|
|
||||||
// word def_struct, new_name
|
|
||||||
// word def_template, new_name
|
|
||||||
// word def_type, new_name
|
|
||||||
// word def_typedef, new_name
|
|
||||||
// word def_union, new_name
|
|
||||||
// word def_using, new_name
|
|
||||||
// word def_using_namespace, new_name
|
|
||||||
// word def_variable, new_name
|
|
||||||
|
|
||||||
// word def_body, new_name
|
|
||||||
// word def_class_body, new_name
|
|
||||||
// word def_enum_body, new_name
|
|
||||||
// word def_export_body, new_name
|
|
||||||
// word def_extern_link_body, new_name
|
|
||||||
// word def_function_body, new_name
|
|
||||||
// word def_global_body, new_name
|
|
||||||
// word def_namespace_body, new_name
|
|
||||||
// word def_params, new_name
|
|
||||||
// word def_specifiers, new_name
|
|
||||||
// word def_struct_body, new_name
|
|
||||||
// word def_union_body, new_name
|
|
||||||
|
|
||||||
// ------------ parse constructor namespace
|
|
||||||
// namespace parse_, new_namespace_
|
|
||||||
|
|
||||||
// ------------ parse constructor individual
|
|
||||||
|
|
||||||
// word parse_class, new_name
|
|
||||||
// word parse_enum, new_name
|
|
||||||
// word parse_export_body, new_name
|
|
||||||
// word parse_extern_link, new_name
|
|
||||||
// word parse_friend, new_name
|
|
||||||
// word parse_function, new_name
|
|
||||||
// word parse_global_body, new_name
|
|
||||||
// word parse_namespace, new_name
|
|
||||||
// word parse_operator, new_name
|
|
||||||
// word parse_struct, new_name
|
|
||||||
// word parse_template, new_name
|
|
||||||
// word parse_type, new_name
|
|
||||||
// word parse_typedef, new_name
|
|
||||||
// word parse_union, new_name
|
|
||||||
// word parse_using, new_name
|
|
||||||
// word parse_variable, new_name
|
|
||||||
|
|
||||||
// ------------ untyped constructor namespace
|
|
||||||
// namespace untyped_, new_namespace_
|
|
||||||
|
|
||||||
// ------------ untyped constructor individual
|
|
||||||
|
|
||||||
// word token_fmt_impl, new_name
|
|
||||||
// word token_fmt_va, new_name
|
|
||||||
// word untyped_str, new_name
|
|
||||||
// word untyped_fmt, new_name
|
|
||||||
// word untyped_token_fmt, new_name
|
|
||||||
|
|
||||||
// ------------ File Ops
|
|
||||||
|
|
||||||
// word Builder, new_name
|
|
||||||
// word Editor, new_name
|
|
||||||
// word Scanner, new_name
|
|
||||||
|
|
||||||
// ------------ gencpp user macros
|
|
||||||
|
|
||||||
// word gen_main, new_name
|
|
||||||
// word GEN_TIME, new_name
|
|
||||||
|
|
||||||
// word __, new_name
|
|
||||||
// word name, new_name
|
|
||||||
// word code, new_name
|
|
||||||
// word args, new_name
|
|
||||||
// word code_str, new_name
|
|
||||||
// word code_fmt, new_name
|
|
||||||
// word token_fmt, new_name
|
|
||||||
|
|
||||||
// ------------ Type AST namespace
|
|
||||||
// namespace t_, new_namespace_
|
|
||||||
|
|
||||||
// ------------ Specifier AST namespace
|
|
||||||
// namespace spec_, new_namespace_
|
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if GEN_INTELLISENSE_DIRECTIVES
|
#if INTELLISENSE_DIRECTIVES
|
||||||
# include "../gen.hpp"
|
# include "../gen.hpp"
|
||||||
# include "misc.hpp"
|
# include "misc.hpp"
|
||||||
|
|
||||||
@ -9,58 +9,55 @@ using namespace gen;
|
|||||||
|
|
||||||
CodeBody gen_ecode( char const* path, bool use_c_definition = false )
|
CodeBody gen_ecode( char const* path, bool use_c_definition = false )
|
||||||
{
|
{
|
||||||
FixedArena_32KB scratch; fixed_arena_init(& scratch);
|
CSV_Columns2 csv_enum = parse_csv_two_columns( _ctx->Allocator_Temp, path );
|
||||||
AllocatorInfo scratch_info = fixed_arena_allocator_info(& scratch);
|
StrBuilder enum_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(1) );
|
||||||
|
StrBuilder to_c_str_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(1) );
|
||||||
CSV_Columns2 csv_enum = parse_csv_two_columns( scratch_info, path );
|
StrBuilder to_keyword_c_str_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(1) );
|
||||||
String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
|
||||||
String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
|
||||||
String to_keyword_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
|
||||||
|
|
||||||
for ( ssize idx = 0; idx < array_num(csv_enum.Col_1); ++ idx ) {
|
for ( ssize idx = 0; idx < array_num(csv_enum.Col_1); ++ idx ) {
|
||||||
char const* code = csv_enum.Col_1[idx].string;
|
char const* code = csv_enum.Col_1[idx].string;
|
||||||
char const* keyword = csv_enum.Col_2[idx].string;
|
char const* keyword = csv_enum.Col_2[idx].string;
|
||||||
// TODO(Ed): to_str_entries and the others in here didn't have proper sizing of the StrC slice.
|
// TODO(Ed): to_c_str_entries and the others in here didn't have proper sizing of the Str slice.
|
||||||
string_append_fmt( & enum_entries, "CT_%s,\n", code );
|
strbuilder_append_fmt( & enum_entries, "CT_%s,\n", code );
|
||||||
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code );
|
strbuilder_append_fmt( & to_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", code, code );
|
||||||
string_append_fmt( & to_keyword_str_entries, "{ sizeof(\"%s\") - 1, \"%s\" },\n", keyword, keyword );
|
strbuilder_append_fmt( & to_keyword_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", keyword, keyword );
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeEnum enum_code;
|
CodeEnum enum_code;
|
||||||
if (use_c_definition) {
|
if (use_c_definition) {
|
||||||
enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", string_to_strc(enum_entries),
|
enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", strbuilder_to_str(enum_entries),
|
||||||
"enum CodeType enum_underlying(u32) { <entries> CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };"
|
"enum CodeType enum_underlying(u32) { <entries> CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", string_to_strc(enum_entries),
|
enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", strbuilder_to_str(enum_entries),
|
||||||
"enum CodeType : u32 { <entries> CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };"
|
"enum CodeType : u32 { <entries> CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma push_macro("local_persist")
|
#pragma push_macro("local_persist")
|
||||||
#undef local_persist
|
#undef local_persist
|
||||||
StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) ));
|
Str lookup_size = strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%d", array_num(csv_enum.Col_1) ));
|
||||||
CodeBody to_str_fns = parse_global_body( token_fmt(
|
CodeBody to_c_str_fns = parse_global_body( token_fmt(
|
||||||
"entries", string_to_strc(to_str_entries)
|
"entries", strbuilder_to_str(to_c_str_entries)
|
||||||
, "keywords", string_to_strc(to_keyword_str_entries)
|
, "keywords", strbuilder_to_str(to_keyword_c_str_entries)
|
||||||
, "num", lookup_size
|
, "num", lookup_size
|
||||||
, stringize(
|
, stringize(
|
||||||
inline
|
inline
|
||||||
StrC codetype_to_str( CodeType type )
|
Str codetype_to_str( CodeType type )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
StrC lookup[<num>] = {
|
Str lookup[] = {
|
||||||
<entries>
|
<entries>
|
||||||
};
|
};
|
||||||
return lookup[ type ];
|
return lookup[ type ];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
StrC codetype_to_keyword_str( CodeType type )
|
Str codetype_to_keyword_str( CodeType type )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
StrC lookup[ <num> ] = {
|
Str lookup[] = {
|
||||||
<keywords>
|
<keywords>
|
||||||
};
|
};
|
||||||
return lookup[ type ];
|
return lookup[ type ];
|
||||||
@ -76,14 +73,14 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false )
|
|||||||
body_append(result, code_t);
|
body_append(result, code_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
body_append(result, to_str_fns);
|
body_append(result, to_c_str_fns);
|
||||||
|
|
||||||
if (! use_c_definition) {
|
if (! use_c_definition) {
|
||||||
#pragma push_macro("forceinline")
|
#pragma push_macro("forceinline")
|
||||||
#undef forceinline
|
#undef forceinline
|
||||||
CodeBody alias_mappings = parse_global_body(code(
|
CodeBody alias_mappings = parse_global_body(code(
|
||||||
forceinline StrC to_str (CodeType type) { return codetype_to_str(type); }
|
forceinline Str to_str (CodeType type) { return codetype_to_str(type); }
|
||||||
forceinline StrC to_keyword_str(CodeType type) { return codetype_to_keyword_str(type); }
|
forceinline Str to_keyword_str(CodeType type) { return codetype_to_keyword_str(type); }
|
||||||
));
|
));
|
||||||
#pragma pop_macro("forceinline")
|
#pragma pop_macro("forceinline")
|
||||||
body_append(result, alias_mappings);
|
body_append(result, alias_mappings);
|
||||||
@ -93,19 +90,15 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false )
|
|||||||
|
|
||||||
CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
|
CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
|
||||||
{
|
{
|
||||||
FixedArena_16KB scratch; fixed_arena_init(& scratch);
|
CSV_Columns2 csv_enum = parse_csv_two_columns( _ctx->Allocator_Temp, path );
|
||||||
AllocatorInfo scratch_info = fixed_arena_allocator_info(& scratch);
|
StrBuilder enum_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, 32 );
|
||||||
|
StrBuilder to_c_str_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, 32 );
|
||||||
CSV_Columns2 csv_enum = parse_csv_two_columns( scratch_info, path );
|
|
||||||
String enum_entries = string_make_reserve( GlobalAllocator, 32 );
|
|
||||||
String to_str_entries = string_make_reserve( GlobalAllocator, 32 );
|
|
||||||
|
|
||||||
for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++) {
|
for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++) {
|
||||||
char const* enum_str = csv_enum.Col_1[idx].string;
|
char const* enum_str = csv_enum.Col_1[idx].string;
|
||||||
char const* entry_to_str = csv_enum.Col_2[idx].string;
|
char const* entry_to_str = csv_enum.Col_2[idx].string;
|
||||||
|
strbuilder_append_fmt( & enum_entries, "Op_%s,\n", enum_str );
|
||||||
string_append_fmt( & enum_entries, "Op_%s,\n", enum_str );
|
strbuilder_append_fmt( & to_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str);
|
||||||
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeEnum enum_code;
|
CodeEnum enum_code;
|
||||||
@ -113,7 +106,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
|
|||||||
{
|
{
|
||||||
#pragma push_macro("enum_underlying")
|
#pragma push_macro("enum_underlying")
|
||||||
#undef enum_underlying
|
#undef enum_underlying
|
||||||
enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize(
|
enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), stringize(
|
||||||
enum Operator enum_underlying(u32)
|
enum Operator enum_underlying(u32)
|
||||||
{
|
{
|
||||||
<entries>
|
<entries>
|
||||||
@ -125,7 +118,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize(
|
enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), stringize(
|
||||||
enum Operator : u32
|
enum Operator : u32
|
||||||
{
|
{
|
||||||
<entries>
|
<entries>
|
||||||
@ -137,16 +130,16 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
|
|||||||
|
|
||||||
#pragma push_macro("local_persist")
|
#pragma push_macro("local_persist")
|
||||||
#undef local_persist
|
#undef local_persist
|
||||||
StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) ));
|
Str lookup_size = strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%d", array_num(csv_enum.Col_1) ));
|
||||||
CodeFn to_str = parse_function(token_fmt(
|
CodeFn to_str = parse_function(token_fmt(
|
||||||
"entries", string_to_strc(to_str_entries)
|
"entries", strbuilder_to_str(to_c_str_entries)
|
||||||
, "num", lookup_size
|
, "num", lookup_size
|
||||||
, stringize(
|
, stringize(
|
||||||
inline
|
inline
|
||||||
StrC operator_to_str( Operator op )
|
Str operator_to_str( Operator op )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
StrC lookup[<num>] = {
|
Str lookup[] = {
|
||||||
<entries>
|
<entries>
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -169,7 +162,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
|
|||||||
#pragma push_macro("forceinline")
|
#pragma push_macro("forceinline")
|
||||||
#undef forceinline
|
#undef forceinline
|
||||||
CodeBody alias_mappings = parse_global_body(code(
|
CodeBody alias_mappings = parse_global_body(code(
|
||||||
forceinline StrC to_str(Operator op) { return operator_to_str(op); }
|
forceinline Str to_str(Operator op) { return operator_to_str(op); }
|
||||||
));
|
));
|
||||||
#pragma pop_macro("forceinline")
|
#pragma pop_macro("forceinline")
|
||||||
body_append(result, alias_mappings);
|
body_append(result, alias_mappings);
|
||||||
@ -179,20 +172,16 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
|
|||||||
|
|
||||||
CodeBody gen_especifier( char const* path, bool use_c_definition = false )
|
CodeBody gen_especifier( char const* path, bool use_c_definition = false )
|
||||||
{
|
{
|
||||||
FixedArena_16KB scratch; fixed_arena_init(& scratch);
|
CSV_Columns2 csv_enum = parse_csv_two_columns( _ctx->Allocator_Temp, path );
|
||||||
AllocatorInfo scratch_info = fixed_arena_allocator_info(& scratch);
|
StrBuilder enum_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(1) );
|
||||||
|
StrBuilder to_c_str_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(1) );
|
||||||
CSV_Columns2 csv_enum = parse_csv_two_columns( scratch_info, path );
|
|
||||||
String enum_entries = string_make_reserve( scratch_info, kilobytes(1) );
|
|
||||||
String to_str_entries = string_make_reserve( scratch_info, kilobytes(1) );
|
|
||||||
|
|
||||||
for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++)
|
for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++)
|
||||||
{
|
{
|
||||||
char const* enum_str = csv_enum.Col_1[idx].string;
|
char const* enum_str = csv_enum.Col_1[idx].string;
|
||||||
char const* entry_to_str = csv_enum.Col_2[idx].string;
|
char const* entry_to_str = csv_enum.Col_2[idx].string;
|
||||||
|
strbuilder_append_fmt( & enum_entries, "Spec_%s,\n", enum_str );
|
||||||
string_append_fmt( & enum_entries, "Spec_%s,\n", enum_str );
|
strbuilder_append_fmt( & to_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str);
|
||||||
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeEnum enum_code;
|
CodeEnum enum_code;
|
||||||
@ -200,7 +189,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
|
|||||||
{
|
{
|
||||||
#pragma push_macro("enum_underlying")
|
#pragma push_macro("enum_underlying")
|
||||||
#undef enum_underlying
|
#undef enum_underlying
|
||||||
enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize(
|
enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), stringize(
|
||||||
enum Specifier enum_underlying(u32)
|
enum Specifier enum_underlying(u32)
|
||||||
{
|
{
|
||||||
<entries>
|
<entries>
|
||||||
@ -212,7 +201,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize(
|
enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), stringize(
|
||||||
enum Specifier : u32
|
enum Specifier : u32
|
||||||
{
|
{
|
||||||
<entries>
|
<entries>
|
||||||
@ -221,12 +210,23 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
|
|||||||
};
|
};
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
CodeFn is_trailing = parse_function(token_fmt("specifier", strbuilder_to_str(to_c_str_entries), stringize(
|
||||||
CodeFn is_trailing = parse_function(token_fmt("specifier", string_to_strc(to_str_entries), stringize(
|
|
||||||
inline
|
inline
|
||||||
bool spec_is_trailing( Specifier specifier )
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)));
|
)));
|
||||||
|
|
||||||
@ -240,16 +240,16 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
|
|||||||
#undef do_once_end
|
#undef do_once_end
|
||||||
#undef forceinline
|
#undef forceinline
|
||||||
#undef neverinline
|
#undef neverinline
|
||||||
StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) ));
|
Str lookup_size = strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%d", array_num(csv_enum.Col_1) ));
|
||||||
CodeFn to_str = parse_function(token_fmt(
|
CodeFn to_str = parse_function(token_fmt(
|
||||||
"entries", string_to_strc(to_str_entries)
|
"entries", strbuilder_to_str(to_c_str_entries)
|
||||||
, "num", lookup_size
|
, "num", lookup_size
|
||||||
, stringize(
|
, stringize(
|
||||||
inline
|
inline
|
||||||
StrC spec_to_str( Specifier type )
|
Str spec_to_str( Specifier type )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
StrC lookup[<num>] = {
|
Str lookup[] = {
|
||||||
<entries>
|
<entries>
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -257,20 +257,20 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
|
|||||||
}
|
}
|
||||||
)));
|
)));
|
||||||
|
|
||||||
CodeFn to_type = parse_function( token_fmt( "entries", string_to_strc(to_str_entries), stringize(
|
CodeFn to_type = parse_function( token_fmt( "entries", strbuilder_to_str(to_c_str_entries), stringize(
|
||||||
inline
|
inline
|
||||||
Specifier strc_to_specifier( StrC str )
|
Specifier str_to_specifier( Str str )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
u32 keymap[ Spec_NumSpecifiers ];
|
u32 keymap[ Spec_NumSpecifiers ];
|
||||||
do_once_start
|
do_once_start
|
||||||
for ( u32 index = 0; index < Spec_NumSpecifiers; index++ )
|
for ( u32 index = 0; index < Spec_NumSpecifiers; index++ )
|
||||||
{
|
{
|
||||||
StrC enum_str = spec_to_str( (Specifier)index );
|
Str enum_str = spec_to_str( (Specifier)index );
|
||||||
|
|
||||||
// We subtract 1 to remove the null terminator
|
// We subtract 1 to remove the null terminator
|
||||||
// This is because the tokens lexed are not null terminated.
|
// This is because the tokens lexed are not null terminated.
|
||||||
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1);
|
keymap[index] = crc32( enum_str.Ptr, enum_str.Len );
|
||||||
}
|
}
|
||||||
do_once_end
|
do_once_end
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
|
|||||||
body_append(result, enum_code);
|
body_append(result, enum_code);
|
||||||
if (use_c_definition)
|
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);
|
body_append(result, specifier_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,8 +308,8 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
|
|||||||
#pragma push_macro("forceinline")
|
#pragma push_macro("forceinline")
|
||||||
#undef forceinline
|
#undef forceinline
|
||||||
CodeBody alias_mappings = parse_global_body(code(
|
CodeBody alias_mappings = parse_global_body(code(
|
||||||
forceinline StrC to_str (Specifier spec) { return spec_to_str(spec); }
|
forceinline Str to_str (Specifier spec) { return spec_to_str(spec); }
|
||||||
forceinline Specifier to_type( StrC str ) { return strc_to_specifier(str); }
|
forceinline Specifier to_type( Str str ) { return str_to_specifier(str); }
|
||||||
forceinline bool is_trailing( Specifier specifier ) { return spec_is_trailing(specifier); }
|
forceinline bool is_trailing( Specifier specifier ) { return spec_is_trailing(specifier); }
|
||||||
));
|
));
|
||||||
#pragma pop_macro("forceinline")
|
#pragma pop_macro("forceinline")
|
||||||
@ -320,64 +320,59 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
|
|||||||
|
|
||||||
CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_definition = false )
|
CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_definition = false )
|
||||||
{
|
{
|
||||||
FixedArena_64KB scratch; fixed_arena_init(& scratch);
|
FileContents enum_content = file_read_contents( _ctx->Allocator_Temp, file_zero_terminate, etok_path );
|
||||||
AllocatorInfo scratch_info = fixed_arena_allocator_info(& scratch);
|
|
||||||
|
|
||||||
FileContents enum_content = file_read_contents( scratch_info, file_zero_terminate, etok_path );
|
|
||||||
|
|
||||||
CSV_Object csv_enum_nodes;
|
CSV_Object csv_enum_nodes;
|
||||||
csv_parse( &csv_enum_nodes, rcast(char*, enum_content.data), scratch_info, false );
|
csv_parse( &csv_enum_nodes, rcast(char*, enum_content.data), _ctx->Allocator_Temp, false );
|
||||||
|
|
||||||
FileContents attrib_content = file_read_contents( scratch_info, file_zero_terminate, attr_path );
|
|
||||||
|
|
||||||
|
FileContents attrib_content = file_read_contents( _ctx->Allocator_Temp, file_zero_terminate, attr_path );
|
||||||
CSV_Object csv_attr_nodes;
|
CSV_Object csv_attr_nodes;
|
||||||
csv_parse( &csv_attr_nodes, rcast(char*, attrib_content.data), scratch_info, false );
|
csv_parse( &csv_attr_nodes, rcast(char*, attrib_content.data), _ctx->Allocator_Temp, false );
|
||||||
|
|
||||||
Array<ADT_Node> enum_strs = csv_enum_nodes.nodes[0].nodes;
|
Array<ADT_Node> enum_strs = csv_enum_nodes.nodes[0].nodes;
|
||||||
Array<ADT_Node> enum_str_strs = csv_enum_nodes.nodes[1].nodes;
|
Array<ADT_Node> enum_c_str_strs = csv_enum_nodes.nodes[1].nodes;
|
||||||
Array<ADT_Node> attribute_strs = csv_attr_nodes.nodes[0].nodes;
|
Array<ADT_Node> attribute_strs = csv_attr_nodes.nodes[0].nodes;
|
||||||
Array<ADT_Node> attribute_str_strs = csv_attr_nodes.nodes[1].nodes;
|
Array<ADT_Node> attribute_c_str_strs = csv_attr_nodes.nodes[1].nodes;
|
||||||
|
|
||||||
String enum_entries = string_make_reserve( scratch_info, kilobytes(2) );
|
StrBuilder enum_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(2) );
|
||||||
String to_str_entries = string_make_reserve( scratch_info, kilobytes(4) );
|
StrBuilder to_c_str_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(4) );
|
||||||
String attribute_entries = string_make_reserve( scratch_info, kilobytes(2) );
|
StrBuilder attribute_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(2) );
|
||||||
String to_str_attributes = string_make_reserve( scratch_info, kilobytes(4) );
|
StrBuilder to_c_str_attributes = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(4) );
|
||||||
String attribute_define_entries = string_make_reserve( scratch_info, kilobytes(4) );
|
StrBuilder attribute_define_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(4) );
|
||||||
|
|
||||||
for (usize idx = 0; idx < array_num(enum_strs); idx++)
|
for (usize idx = 0; idx < array_num(enum_strs); idx++)
|
||||||
{
|
{
|
||||||
char const* enum_str = enum_strs[idx].string;
|
char const* enum_str = enum_strs[idx].string;
|
||||||
char const* entry_to_str = enum_str_strs [idx].string;
|
char const* entry_to_str = enum_c_str_strs [idx].string;
|
||||||
|
|
||||||
string_append_fmt( & enum_entries, "Tok_%s,\n", enum_str );
|
strbuilder_append_fmt( & enum_entries, "Tok_%s,\n", enum_str );
|
||||||
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
strbuilder_append_fmt( & to_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( usize idx = 0; idx < array_num(attribute_strs); idx++ )
|
for ( usize idx = 0; idx < array_num(attribute_strs); idx++ )
|
||||||
{
|
{
|
||||||
char const* attribute_str = attribute_strs[idx].string;
|
char const* attribute_str = attribute_strs[idx].string;
|
||||||
char const* entry_to_str = attribute_str_strs [idx].string;
|
char const* entry_to_str = attribute_c_str_strs [idx].string;
|
||||||
|
|
||||||
string_append_fmt( & attribute_entries, "Tok_Attribute_%s,\n", attribute_str );
|
strbuilder_append_fmt( & attribute_entries, "Tok_Attribute_%s,\n", attribute_str );
|
||||||
string_append_fmt( & to_str_attributes, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
strbuilder_append_fmt( & to_c_str_attributes, "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str);
|
||||||
string_append_fmt( & attribute_define_entries, "Entry( Tok_Attribute_%s, \"%s\" )", attribute_str, entry_to_str );
|
strbuilder_append_fmt( & attribute_define_entries, "Entry( Tok_Attribute_%s, \"%s\" )", attribute_str, entry_to_str );
|
||||||
|
|
||||||
if ( idx < array_num(attribute_strs) - 1 )
|
if ( idx < array_num(attribute_strs) - 1 )
|
||||||
string_append_strc( & attribute_define_entries, txt(" \\\n"));
|
strbuilder_append_str( & attribute_define_entries, txt(" \\\n"));
|
||||||
else
|
else
|
||||||
string_append_strc( & attribute_define_entries, txt("\n"));
|
strbuilder_append_str( & attribute_define_entries, txt("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
|
#pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
|
||||||
#undef GEN_DEFINE_ATTRIBUTE_TOKENS
|
#undef GEN_DEFINE_ATTRIBUTE_TOKENS
|
||||||
CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), string_to_strc(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")
|
#pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
|
||||||
|
|
||||||
// We cannot parse this enum, it has Attribute names as enums
|
// We cannot parse this enum, it has Attribute names as enums
|
||||||
CodeEnum enum_code;
|
CodeEnum enum_code;
|
||||||
if (use_c_definition)
|
if (use_c_definition)
|
||||||
{
|
{
|
||||||
enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), "attribute_toks", string_to_strc(attribute_entries), stringize(
|
enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), "attribute_toks", strbuilder_to_str(attribute_entries), stringize(
|
||||||
enum TokType
|
enum TokType
|
||||||
{
|
{
|
||||||
<entries>
|
<entries>
|
||||||
@ -389,7 +384,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), "attribute_toks", string_to_strc(attribute_entries), stringize(
|
enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), "attribute_toks", strbuilder_to_str(attribute_entries), stringize(
|
||||||
enum TokType : u32
|
enum TokType : u32
|
||||||
{
|
{
|
||||||
<entries>
|
<entries>
|
||||||
@ -405,12 +400,12 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_
|
|||||||
#undef local_persist
|
#undef local_persist
|
||||||
#undef do_once_start
|
#undef do_once_start
|
||||||
#undef do_once_end
|
#undef do_once_end
|
||||||
CodeFn to_str = parse_function(token_fmt("entries", string_to_strc(to_str_entries), "attribute_toks", string_to_strc(to_str_attributes), stringize(
|
CodeFn to_str = parse_function(token_fmt("entries", strbuilder_to_str(to_c_str_entries), "attribute_toks", strbuilder_to_str(to_c_str_attributes), stringize(
|
||||||
inline
|
inline
|
||||||
StrC toktype_to_str( TokType type )
|
Str toktype_to_str( TokType type )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
StrC lookup[] = {
|
Str lookup[] = {
|
||||||
<entries>
|
<entries>
|
||||||
<attribute_toks>
|
<attribute_toks>
|
||||||
};
|
};
|
||||||
@ -419,20 +414,20 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_
|
|||||||
}
|
}
|
||||||
)));
|
)));
|
||||||
|
|
||||||
CodeFn to_type = parse_function( token_fmt( "entries", string_to_strc(to_str_entries), stringize(
|
CodeFn to_type = parse_function( token_fmt( "entries", strbuilder_to_str(to_c_str_entries), stringize(
|
||||||
inline
|
inline
|
||||||
TokType strc_to_toktype( StrC str )
|
TokType str_to_toktype( Str str )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
u32 keymap[ Tok_NumTokens ];
|
u32 keymap[ Tok_NumTokens ];
|
||||||
do_once_start
|
do_once_start
|
||||||
for ( u32 index = 0; index < Tok_NumTokens; index++ )
|
for ( u32 index = 0; index < Tok_NumTokens; index++ )
|
||||||
{
|
{
|
||||||
StrC enum_str = toktype_to_str( (TokType)index );
|
Str enum_str = toktype_to_str( (TokType)index );
|
||||||
|
|
||||||
// We subtract 1 to remove the null terminator
|
// We subtract 1 to remove the null terminator
|
||||||
// This is because the tokens lexed are not null terminated.
|
// This is because the tokens lexed are not null terminated.
|
||||||
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1);
|
keymap[index] = crc32( enum_str.Ptr, enum_str.Len);
|
||||||
}
|
}
|
||||||
do_once_end
|
do_once_end
|
||||||
|
|
||||||
@ -452,7 +447,6 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_
|
|||||||
#pragma pop_macro("do_once_end")
|
#pragma pop_macro("do_once_end")
|
||||||
|
|
||||||
CodeBody result = def_body(CT_Global_Body);
|
CodeBody result = def_body(CT_Global_Body);
|
||||||
body_append(result, untyped_str(txt("GEN_NS_PARSER_BEGIN\n\n")));
|
|
||||||
body_append(result, attribute_entires_def);
|
body_append(result, attribute_entires_def);
|
||||||
body_append(result, enum_code);
|
body_append(result, enum_code);
|
||||||
if (use_c_definition)
|
if (use_c_definition)
|
||||||
@ -462,7 +456,6 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_
|
|||||||
}
|
}
|
||||||
body_append(result, to_str);
|
body_append(result, to_str);
|
||||||
body_append(result, to_type);
|
body_append(result, to_type);
|
||||||
body_append(result, untyped_str(txt("\nGEN_NS_PARSER_END\n\n")));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,7 +501,7 @@ CodeBody gen_ast_inlines()
|
|||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if ( ast == nullptr )
|
||||||
{
|
{
|
||||||
log_failure( "Attempt to dereference a nullptr!" );
|
log_failure( "Attempt to dereference a nullptr!\n" );
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return ast;
|
return ast;
|
||||||
@ -518,59 +511,60 @@ CodeBody gen_ast_inlines()
|
|||||||
#pragma pop_macro("GEN_NS")
|
#pragma pop_macro("GEN_NS")
|
||||||
#pragma pop_macro("CodeInvalid")
|
#pragma pop_macro("CodeInvalid")
|
||||||
|
|
||||||
CodeBody impl_code = parse_global_body( token_fmt( "typename", StrC name(Code), 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", StrC name(CodeBody), 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", StrC name(CodeAttributes), 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", StrC name(CodeComment), 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", StrC name(CodeConstructor), 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", StrC name(CodeClass), 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", StrC name(CodeDefine), code_impl_tmpl ));
|
CodeBody impl_code_define = parse_global_body( token_fmt( "typename", name(CodeDefine), code_impl_tmpl ));
|
||||||
CodeBody impl_code_destruct = parse_global_body( token_fmt( "typename", StrC name(CodeDestructor), code_impl_tmpl ));
|
CodeBody impl_code_define_params = parse_global_body( token_fmt( "typename", name(CodeDefineParams), code_impl_tmpl ));
|
||||||
CodeBody impl_code_enum = parse_global_body( token_fmt( "typename", StrC name(CodeEnum), code_impl_tmpl ));
|
CodeBody impl_code_destruct = parse_global_body( token_fmt( "typename", name(CodeDestructor), code_impl_tmpl ));
|
||||||
CodeBody impl_code_exec = parse_global_body( token_fmt( "typename", StrC name(CodeExec), code_impl_tmpl ));
|
CodeBody impl_code_enum = parse_global_body( token_fmt( "typename", name(CodeEnum), code_impl_tmpl ));
|
||||||
CodeBody impl_code_extern = parse_global_body( token_fmt( "typename", StrC name(CodeExtern), code_impl_tmpl ));
|
CodeBody impl_code_exec = parse_global_body( token_fmt( "typename", name(CodeExec), code_impl_tmpl ));
|
||||||
CodeBody impl_code_include = parse_global_body( token_fmt( "typename", StrC name(CodeInclude), code_impl_tmpl ));
|
CodeBody impl_code_extern = parse_global_body( token_fmt( "typename", name(CodeExtern), code_impl_tmpl ));
|
||||||
CodeBody impl_code_friend = parse_global_body( token_fmt( "typename", StrC name(CodeFriend), code_impl_tmpl ));
|
CodeBody impl_code_include = parse_global_body( token_fmt( "typename", name(CodeInclude), code_impl_tmpl ));
|
||||||
CodeBody impl_code_fn = parse_global_body( token_fmt( "typename", StrC name(CodeFn), code_impl_tmpl ));
|
CodeBody impl_code_friend = parse_global_body( token_fmt( "typename", name(CodeFriend), code_impl_tmpl ));
|
||||||
CodeBody impl_code_module = parse_global_body( token_fmt( "typename", StrC name(CodeModule), code_impl_tmpl ));
|
CodeBody impl_code_fn = parse_global_body( token_fmt( "typename", name(CodeFn), code_impl_tmpl ));
|
||||||
CodeBody impl_code_ns = parse_global_body( token_fmt( "typename", StrC name(CodeNS), code_impl_tmpl ));
|
CodeBody impl_code_module = parse_global_body( token_fmt( "typename", name(CodeModule), code_impl_tmpl ));
|
||||||
CodeBody impl_code_op = parse_global_body( token_fmt( "typename", StrC name(CodeOperator), code_impl_tmpl ));
|
CodeBody impl_code_ns = parse_global_body( token_fmt( "typename", name(CodeNS), code_impl_tmpl ));
|
||||||
CodeBody impl_code_opcast = parse_global_body( token_fmt( "typename", StrC name(CodeOpCast), code_impl_tmpl ));
|
CodeBody impl_code_op = parse_global_body( token_fmt( "typename", name(CodeOperator), code_impl_tmpl ));
|
||||||
CodeBody impl_code_params = parse_global_body( token_fmt( "typename", StrC name(CodeParams), code_impl_tmpl ));
|
CodeBody impl_code_opcast = parse_global_body( token_fmt( "typename", name(CodeOpCast), code_impl_tmpl ));
|
||||||
CodeBody impl_code_pragma = parse_global_body( token_fmt( "typename", StrC name(CodePragma), code_impl_tmpl ));
|
CodeBody impl_code_params = parse_global_body( token_fmt( "typename", name(CodeParams), code_impl_tmpl ));
|
||||||
CodeBody impl_code_precond = parse_global_body( token_fmt( "typename", StrC name(CodePreprocessCond), code_impl_tmpl ));
|
CodeBody impl_code_pragma = parse_global_body( token_fmt( "typename", name(CodePragma), code_impl_tmpl ));
|
||||||
CodeBody impl_code_specs = parse_global_body( token_fmt( "typename", StrC name(CodeSpecifiers), code_impl_tmpl ));
|
CodeBody impl_code_precond = parse_global_body( token_fmt( "typename", name(CodePreprocessCond), code_impl_tmpl ));
|
||||||
CodeBody impl_code_struct = parse_global_body( token_fmt( "typename", StrC name(CodeStruct), code_impl_tmpl ));
|
CodeBody impl_code_specs = parse_global_body( token_fmt( "typename", name(CodeSpecifiers), code_impl_tmpl ));
|
||||||
CodeBody impl_code_tmpl = parse_global_body( token_fmt( "typename", StrC name(CodeTemplate), code_impl_tmpl ));
|
CodeBody impl_code_struct = parse_global_body( token_fmt( "typename", name(CodeStruct), code_impl_tmpl ));
|
||||||
CodeBody impl_code_type = parse_global_body( token_fmt( "typename", StrC name(CodeTypename), code_impl_tmpl ));
|
CodeBody impl_code_tmpl = parse_global_body( token_fmt( "typename", name(CodeTemplate), code_impl_tmpl ));
|
||||||
CodeBody impl_code_typedef = parse_global_body( token_fmt( "typename", StrC name(CodeTypedef), code_impl_tmpl ));
|
CodeBody impl_code_type = parse_global_body( token_fmt( "typename", name(CodeTypename), code_impl_tmpl ));
|
||||||
CodeBody impl_code_union = parse_global_body( token_fmt( "typename", StrC name(CodeUnion), code_impl_tmpl ));
|
CodeBody impl_code_typedef = parse_global_body( token_fmt( "typename", name(CodeTypedef), code_impl_tmpl ));
|
||||||
CodeBody impl_code_using = parse_global_body( token_fmt( "typename", StrC name(CodeUsing), code_impl_tmpl ));
|
CodeBody impl_code_union = parse_global_body( token_fmt( "typename", name(CodeUnion), code_impl_tmpl ));
|
||||||
CodeBody impl_code_var = parse_global_body( token_fmt( "typename", StrC name(CodeVar), 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", StrC name(Attributes), 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", StrC name(Comment), 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", StrC name(Constructor), 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", StrC name(Define), 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", StrC name(Destructor), 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", StrC name(Enum), 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", StrC name(Exec), 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", StrC name(Extern), 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", StrC name(Include), 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", StrC name(Friend), 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", StrC name(Fn), 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", StrC name(Module), 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", StrC name(NS), 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", StrC name(Operator), 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", StrC name(OpCast), 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", StrC name(Pragma), 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", StrC name(PreprocessCond), 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", StrC name(Template), 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", StrC name(Typename), 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", StrC name(Typedef), 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", StrC name(Union), 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", StrC name(Using), 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", StrC name(Var), codetype_impl_tmpl )));
|
body_append(impl_code_var, parse_global_body( token_fmt( "typename", name(Var), codetype_impl_tmpl )));
|
||||||
|
|
||||||
#pragma push_macro("forceinline")
|
#pragma push_macro("forceinline")
|
||||||
#undef forceinline
|
#undef forceinline
|
||||||
@ -582,34 +576,35 @@ CodeBody gen_ast_inlines()
|
|||||||
);
|
);
|
||||||
#pragma pop_macro("forceinline")
|
#pragma pop_macro("forceinline")
|
||||||
|
|
||||||
CodeBody impl_cast_body = parse_global_body( token_fmt( "typename", StrC name(Body), 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", StrC name(Attributes), 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", StrC name(Comment), 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", StrC name(Constructor), 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", StrC name(Class), 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", StrC name(Define), cast_tmpl ));
|
CodeBody impl_cast_define = parse_global_body( token_fmt( "typename", name(Define), cast_tmpl ));
|
||||||
CodeBody impl_cast_destruct = parse_global_body( token_fmt( "typename", StrC name(Destructor), cast_tmpl ));
|
CodeBody impl_cast_define_params = parse_global_body( token_fmt( "typename", name(DefineParams), cast_tmpl ));
|
||||||
CodeBody impl_cast_enum = parse_global_body( token_fmt( "typename", StrC name(Enum), cast_tmpl ));
|
CodeBody impl_cast_destruct = parse_global_body( token_fmt( "typename", name(Destructor), cast_tmpl ));
|
||||||
CodeBody impl_cast_exec = parse_global_body( token_fmt( "typename", StrC name(Exec), cast_tmpl ));
|
CodeBody impl_cast_enum = parse_global_body( token_fmt( "typename", name(Enum), cast_tmpl ));
|
||||||
CodeBody impl_cast_extern = parse_global_body( token_fmt( "typename", StrC name(Extern), cast_tmpl ));
|
CodeBody impl_cast_exec = parse_global_body( token_fmt( "typename", name(Exec), cast_tmpl ));
|
||||||
CodeBody impl_cast_friend = parse_global_body( token_fmt( "typename", StrC name(Friend), cast_tmpl ));
|
CodeBody impl_cast_extern = parse_global_body( token_fmt( "typename", name(Extern), cast_tmpl ));
|
||||||
CodeBody impl_cast_fn = parse_global_body( token_fmt( "typename", StrC name(Fn), cast_tmpl ));
|
CodeBody impl_cast_friend = parse_global_body( token_fmt( "typename", name(Friend), cast_tmpl ));
|
||||||
CodeBody impl_cast_include = parse_global_body( token_fmt( "typename", StrC name(Include), cast_tmpl ));
|
CodeBody impl_cast_fn = parse_global_body( token_fmt( "typename", name(Fn), cast_tmpl ));
|
||||||
CodeBody impl_cast_module = parse_global_body( token_fmt( "typename", StrC name(Module), cast_tmpl ));
|
CodeBody impl_cast_include = parse_global_body( token_fmt( "typename", name(Include), cast_tmpl ));
|
||||||
CodeBody impl_cast_ns = parse_global_body( token_fmt( "typename", StrC name(NS), cast_tmpl ));
|
CodeBody impl_cast_module = parse_global_body( token_fmt( "typename", name(Module), cast_tmpl ));
|
||||||
CodeBody impl_cast_op = parse_global_body( token_fmt( "typename", StrC name(Operator), cast_tmpl ));
|
CodeBody impl_cast_ns = parse_global_body( token_fmt( "typename", name(NS), cast_tmpl ));
|
||||||
CodeBody impl_cast_opcast = parse_global_body( token_fmt( "typename", StrC name(OpCast), cast_tmpl ));
|
CodeBody impl_cast_op = parse_global_body( token_fmt( "typename", name(Operator), cast_tmpl ));
|
||||||
CodeBody impl_cast_params = parse_global_body( token_fmt( "typename", StrC name(Params), cast_tmpl ));
|
CodeBody impl_cast_opcast = parse_global_body( token_fmt( "typename", name(OpCast), cast_tmpl ));
|
||||||
CodeBody impl_cast_pragma = parse_global_body( token_fmt( "typename", StrC name(Pragma), cast_tmpl ));
|
CodeBody impl_cast_params = parse_global_body( token_fmt( "typename", name(Params), cast_tmpl ));
|
||||||
CodeBody impl_cast_precond = parse_global_body( token_fmt( "typename", StrC name(PreprocessCond), cast_tmpl ));
|
CodeBody impl_cast_pragma = parse_global_body( token_fmt( "typename", name(Pragma), cast_tmpl ));
|
||||||
CodeBody impl_cast_specs = parse_global_body( token_fmt( "typename", StrC name(Specifiers), cast_tmpl ));
|
CodeBody impl_cast_precond = parse_global_body( token_fmt( "typename", name(PreprocessCond), cast_tmpl ));
|
||||||
CodeBody impl_cast_struct = parse_global_body( token_fmt( "typename", StrC name(Struct), cast_tmpl ));
|
CodeBody impl_cast_specs = parse_global_body( token_fmt( "typename", name(Specifiers), cast_tmpl ));
|
||||||
CodeBody impl_cast_tmpl = parse_global_body( token_fmt( "typename", StrC name(Template), cast_tmpl ));
|
CodeBody impl_cast_struct = parse_global_body( token_fmt( "typename", name(Struct), cast_tmpl ));
|
||||||
CodeBody impl_cast_type = parse_global_body( token_fmt( "typename", StrC name(Typename), cast_tmpl ));
|
CodeBody impl_cast_tmpl = parse_global_body( token_fmt( "typename", name(Template), cast_tmpl ));
|
||||||
CodeBody impl_cast_typedef = parse_global_body( token_fmt( "typename", StrC name(Typedef), cast_tmpl ));
|
CodeBody impl_cast_type = parse_global_body( token_fmt( "typename", name(Typename), cast_tmpl ));
|
||||||
CodeBody impl_cast_union = parse_global_body( token_fmt( "typename", StrC name(Union), cast_tmpl ));
|
CodeBody impl_cast_typedef = parse_global_body( token_fmt( "typename", name(Typedef), cast_tmpl ));
|
||||||
CodeBody impl_cast_using = parse_global_body( token_fmt( "typename", StrC name(Using), cast_tmpl ));
|
CodeBody impl_cast_union = parse_global_body( token_fmt( "typename", name(Union), cast_tmpl ));
|
||||||
CodeBody impl_cast_var = parse_global_body( token_fmt( "typename", StrC name(Var), 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(
|
CodeBody result = def_global_body( args(
|
||||||
def_pragma( txt("region generated code inline implementation")),
|
def_pragma( txt("region generated code inline implementation")),
|
||||||
@ -621,6 +616,7 @@ CodeBody gen_ast_inlines()
|
|||||||
impl_code_constr,
|
impl_code_constr,
|
||||||
impl_code_class,
|
impl_code_class,
|
||||||
impl_code_define,
|
impl_code_define,
|
||||||
|
impl_code_define_params,
|
||||||
impl_code_destruct,
|
impl_code_destruct,
|
||||||
impl_code_enum,
|
impl_code_enum,
|
||||||
impl_code_exec,
|
impl_code_exec,
|
||||||
@ -655,6 +651,7 @@ CodeBody gen_ast_inlines()
|
|||||||
impl_cast_constr,
|
impl_cast_constr,
|
||||||
impl_cast_class,
|
impl_cast_class,
|
||||||
impl_cast_define,
|
impl_cast_define,
|
||||||
|
impl_cast_define_params,
|
||||||
impl_cast_destruct,
|
impl_cast_destruct,
|
||||||
impl_cast_enum,
|
impl_cast_enum,
|
||||||
impl_cast_exec,
|
impl_cast_exec,
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
# define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||||
# define GEN_ENFORCE_STRONG_CODE_TYPES
|
# define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||||
# define GEN_EXPOSE_BACKEND
|
# define GEN_EXPOSE_BACKEND
|
||||||
# include "gen.hpp"
|
# include "gen.hpp"
|
||||||
# include "helpers/push_ignores.inline.hpp"
|
# include "helpers/push_ignores.inline.hpp"
|
||||||
# include "helpers/helper.hpp"
|
# include "helpers/helper.hpp"
|
||||||
# include "auxillary/builder.hpp"
|
# include "auxiliary/builder.hpp"
|
||||||
# include "auxillary/builder.cpp"
|
# include "auxiliary/builder.cpp"
|
||||||
# include "auxillary/scanner.hpp"
|
# include "auxiliary/scanner.hpp"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@ -21,22 +21,22 @@ using namespace gen;
|
|||||||
void clang_format_file( char const* path, char const* style_path )
|
void clang_format_file( char const* path, char const* style_path )
|
||||||
{
|
{
|
||||||
GEN_ASSERT_NOT_NULL(path);
|
GEN_ASSERT_NOT_NULL(path);
|
||||||
String resolved_path = string_make_strc(GlobalAllocator, to_strc_from_c_str(path));
|
StrBuilder resolved_path = strbuilder_make_str(_ctx->Allocator_Temp, to_str_from_c_str(path));
|
||||||
String style_arg;
|
StrBuilder style_arg;
|
||||||
if (style_path) {
|
if (style_path) {
|
||||||
style_arg = string_make_strc(GlobalAllocator, txt("-style=file:"));
|
style_arg = strbuilder_make_str(_ctx->Allocator_Temp, txt("-style=file:"));
|
||||||
string_append_fmt( & style_arg, "%s ", style_path );
|
strbuilder_append_fmt( & style_arg, "%s ", style_path );
|
||||||
}
|
}
|
||||||
|
|
||||||
StrC clang_format = txt("clang-format ");
|
Str clang_format = txt("clang-format ");
|
||||||
StrC cf_format_inplace = txt("-i ");
|
Str cf_format_inplace = txt("-i ");
|
||||||
StrC cf_verbose = txt("-verbose ");
|
Str cf_verbose = txt("-verbose ");
|
||||||
|
|
||||||
String command = string_make_strc( GlobalAllocator, clang_format );
|
StrBuilder command = strbuilder_make_str( _ctx->Allocator_Temp, clang_format );
|
||||||
string_append_strc( & command, cf_format_inplace );
|
strbuilder_append_str( & command, cf_format_inplace );
|
||||||
string_append_strc( & command, cf_verbose );
|
strbuilder_append_str( & command, cf_verbose );
|
||||||
string_append_string( & command, style_arg );
|
strbuilder_append_string( & command, style_arg );
|
||||||
string_append_string( & command, resolved_path );
|
strbuilder_append_string( & command, resolved_path );
|
||||||
system( command );
|
system( command );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,11 +48,11 @@ void refactor_file( char const* path, char const* refactor_script )
|
|||||||
GEN_ASSERT_NOT_NULL(path);
|
GEN_ASSERT_NOT_NULL(path);
|
||||||
GEN_ASSERT_NOT_NULL(refactor_script);
|
GEN_ASSERT_NOT_NULL(refactor_script);
|
||||||
|
|
||||||
String command = string_make_strc(GlobalAllocator, txt("refactor "));
|
StrBuilder command = strbuilder_make_str(_ctx->Allocator_Temp, txt("refactor "));
|
||||||
// string_append_strc( & command, txt("-debug ") );
|
// strbuilder_append_str( & command, txt("-debug ") );
|
||||||
string_append_strc( & command, txt("-num=1 ") );
|
strbuilder_append_str( & command, txt("-num=1 ") );
|
||||||
string_append_fmt( & command, "-src=%s ", path );
|
strbuilder_append_fmt( & command, "-src=%s ", path );
|
||||||
string_append_fmt( & command,"-spec=%s ", refactor_script );
|
strbuilder_append_fmt( & command,"-spec=%s ", refactor_script );
|
||||||
system(command);
|
system(command);
|
||||||
log_fmt("\n");
|
log_fmt("\n");
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
#undef local_persist
|
#undef local_persist
|
||||||
|
|
||||||
#undef bit
|
#undef bit
|
||||||
#undef bitfield_is_equal
|
#undef bitfield_is_set
|
||||||
|
|
||||||
#undef cast
|
#undef cast
|
||||||
|
|
||||||
@ -173,12 +173,12 @@
|
|||||||
|
|
||||||
#undef GEN_DEFINE_ATTRIBUTE_TOKENS
|
#undef GEN_DEFINE_ATTRIBUTE_TOKENS
|
||||||
|
|
||||||
#undef GEN_AST_BODY_CLASS_UNALLOWED_TYPES
|
#undef GEN_AST_BODY_CLASS_UNALLOWED_TYPES_CASES
|
||||||
#undef GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES
|
#undef GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES_CASES
|
||||||
#undef GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
|
#undef GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES_CASES
|
||||||
#undef GEN_AST_BODY_EXPORT_UNALLOWED_TYPES
|
#undef GEN_AST_BODY_EXPORT_UNALLOWED_TYPES_CASES
|
||||||
#undef GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES
|
#undef GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES_CASES
|
||||||
#undef GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES
|
#undef GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES_CASES
|
||||||
|
|
||||||
#undef GEN_GLOBAL_BUCKET_SIZE
|
#undef GEN_GLOBAL_BUCKET_SIZE
|
||||||
#undef GEN_CODEPOOL_NUM_BLOCKS
|
#undef GEN_CODEPOOL_NUM_BLOCKS
|
||||||
|
@ -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/)
|
When its the [C generated variant of the library](../gen_c_library/)
|
||||||
```c
|
```c
|
||||||
typedef AST* Code;
|
typedef AST* Code;
|
||||||
tyepdef AST_<name>* Code<name>;
|
typedef AST_<name>* Code<name>;
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ The full definitions of all asts are within:
|
|||||||
|
|
||||||
* [`ast.hpp`](../base/components/ast.hpp)
|
* [`ast.hpp`](../base/components/ast.hpp)
|
||||||
* [`ast_types.hpp`](../base/components/ast_types.hpp)
|
* [`ast_types.hpp`](../base/components/ast_types.hpp)
|
||||||
* [`code_types.hpp`](../base/components/ast_types.hpp)
|
* [`code_types.hpp`](../base/components/code_types.hpp)
|
||||||
|
|
||||||
The C/C++ interface procedures are located with `ast.hpp` (for the Code type), and `code_types.hpp` for all others.
|
The C/C++ interface procedures are located with `ast.hpp` (for the Code type), and `code_types.hpp` for all others.
|
||||||
|
|
||||||
@ -46,13 +46,14 @@ The C/C++ interface procedures are located with `ast.hpp` (for the Code type), a
|
|||||||
All code types can either serialize using a function of the pattern:
|
All code types can either serialize using a function of the pattern:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
String <prefix>_to_string(Code code);
|
StrBuilder <prefix>_to_strbuilder(Code code);
|
||||||
// or
|
// or
|
||||||
<prefix>_to_string(Code code, String& result);
|
<prefix>_to_strbuilder(Code code, StrBuilder& result);
|
||||||
```
|
```
|
||||||
|
|
||||||
Where the first generates strings allocated using Allocator_StringArena and the other appends an existing strings with their backed allocator.
|
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_string_ptr` & `code_to_string`.
|
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).
|
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.
|
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
|
# 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
|
## Body
|
||||||
|
|
||||||
@ -25,19 +25,19 @@ These are containers representing a scope body of a definition that can be of th
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Front;
|
Code Front;
|
||||||
Code Back;
|
Code Back;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
```
|
```
|
||||||
|
|
||||||
The `Front` member represents the start of the link list and `Back` the end.
|
The `Front` member represents the start of the link list and `Back` the end.
|
||||||
NumEntries is the number of entries in the body.
|
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:
|
Serialization:
|
||||||
|
|
||||||
@ -56,13 +56,13 @@ Represent standard or vendor specific C/C++ attributes.
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Content;
|
StrCached Content;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -80,13 +80,13 @@ Stores a comment.
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Content;
|
StrCached Content;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -95,7 +95,7 @@ Serialization:
|
|||||||
<Content>
|
<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.
|
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.
|
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;
|
CodeAttributes Attributes;
|
||||||
CodeType ParentType;
|
CodeType ParentType;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeType Prev;
|
CodeType Prev;
|
||||||
CodeType Next;
|
CodeType Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
AccessSpec ParentAccess;
|
AccessSpec ParentAccess;
|
||||||
```
|
```
|
||||||
@ -139,16 +139,16 @@ You'll notice that only one parent type is supported only with parent access. Th
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
CodeComment InlineCmt; // Only supported by forward declarations
|
CodeComment InlineCmt; // Only supported by forward declarations
|
||||||
Code InitializerList;
|
Code InitializerList;
|
||||||
CodeParams Params;
|
CodeParams Params;
|
||||||
Code Body;
|
Code Body;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -178,13 +178,14 @@ Represents a preprocessor define
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Content;
|
CodeDefineParams Params;
|
||||||
StringCached Name;
|
Code Body;
|
||||||
Code Prev;
|
StrCached Name;
|
||||||
Code Next;
|
Code Prev;
|
||||||
Token* Tok;
|
Code Next;
|
||||||
Code Parent;
|
Token* Tok;
|
||||||
CodeT Type;
|
Code Parent;
|
||||||
|
CodeType Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -193,6 +194,28 @@ Serialization:
|
|||||||
#define <Name> <Content>
|
#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
|
## Destructor
|
||||||
|
|
||||||
Fields:
|
Fields:
|
||||||
@ -201,12 +224,12 @@ Fields:
|
|||||||
CodeComment InlineCmt;
|
CodeComment InlineCmt;
|
||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
Code Body;
|
Code Body;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -242,13 +265,13 @@ Code Prev;
|
|||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
```
|
```
|
||||||
|
|
||||||
UnderlyingTypeMacro is a macro the library natively supports: `enum_underlying(type)` that is meant to behave as a wrapper for underlying type assignment.
|
UnderlyingTypeMacro is a macro the library natively supports: `enum_underlying(type)` that is meant to behave as a wrapper for underlying type assignment.
|
||||||
The `enum_underlying_sig` is a `StrC` global var that can be set which will be defined within `PreprocessorDefines` and used in `parser_parse_enum` to identify a valid macro.
|
The `enum_underlying_sig` is a `Str` global var that can be set which will be defined within `PreprocessorDefines` and used in `parser_parse_enum` to identify a valid macro.
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
|
|
||||||
@ -266,18 +289,18 @@ Serialization:
|
|||||||
## Execution
|
## Execution
|
||||||
|
|
||||||
Just represents an execution body. Equivalent to an untyped body.
|
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:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Content;
|
StrCached Content;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -286,18 +309,18 @@ Serialization:
|
|||||||
<Content>
|
<Content>
|
||||||
```
|
```
|
||||||
|
|
||||||
## External Linkage
|
## External Linkage (Extern)
|
||||||
|
|
||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -314,13 +337,13 @@ extern "<Name>"
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Content;
|
StrCached Content;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -336,14 +359,14 @@ This library (until its necessary become some third-party library to do otherwis
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
CodeComment InlineCmt;
|
CodeComment InlineCmt;
|
||||||
Code Declaration;
|
Code Declaration;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -363,12 +386,12 @@ CodeSpecifiers Specs;
|
|||||||
CodeType ReturnType;
|
CodeType ReturnType;
|
||||||
CodeParams Params;
|
CodeParams Params;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -390,13 +413,13 @@ Serialization:
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -410,14 +433,14 @@ Serialization:
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -440,12 +463,12 @@ CodeSpecifiers Specs;
|
|||||||
CodeType ReturnType;
|
CodeType ReturnType;
|
||||||
CodeParams Params;
|
CodeParams Params;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
OperatorT Op;
|
OperatorT Op;
|
||||||
```
|
```
|
||||||
@ -472,12 +495,12 @@ CodeComment InlineCmt;
|
|||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
CodeType ValueType;
|
CodeType ValueType;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -498,17 +521,17 @@ Serialization:
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
CodeType ValueType;
|
CodeType ValueType;
|
||||||
Code Macro;
|
Code Macro;
|
||||||
Code Value;
|
Code Value;
|
||||||
Code PostNameMacro;
|
Code PostNameMacro;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeParams Last;
|
CodeParams Last;
|
||||||
CodeParams Next;
|
CodeParams Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -524,13 +547,13 @@ Serialization:
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Content;
|
StrCached Content;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -544,13 +567,13 @@ Serialization:
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Content;
|
StrCached Content;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -566,12 +589,12 @@ Fields:
|
|||||||
```cpp
|
```cpp
|
||||||
SpecifierT ArrSpecs[ AST_ArrSpecs_Cap ];
|
SpecifierT ArrSpecs[ AST_ArrSpecs_Cap ];
|
||||||
CodeSpecifiers NextSpecs;
|
CodeSpecifiers NextSpecs;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -586,15 +609,15 @@ Serialization:
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
CodeParams Params;
|
CodeParams Params;
|
||||||
Code Declaration;
|
Code Declaration;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -621,8 +644,8 @@ Code Prev;
|
|||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
b32 IsParamPack;
|
b32 IsParamPack;
|
||||||
ETypenameTag TypeTag;
|
ETypenameTag TypeTag;
|
||||||
```
|
```
|
||||||
@ -637,7 +660,7 @@ Serialization:
|
|||||||
|
|
||||||
`<Name>` currently has the full serialization of anything with
|
`<Name>` currently has the full serialization of anything with
|
||||||
|
|
||||||
*Note: ArrExpr is not used in serialization by `typename_to_string_ref` its instead handled by a parent AST's serailization (variable, typedef, using).*
|
*Note: ArrExpr is not used in serialization by `typename_to_strbuilder_ref` its instead handled by a parent AST's serailization (variable, typedef, using).*
|
||||||
|
|
||||||
## Typedef
|
## Typedef
|
||||||
|
|
||||||
@ -647,16 +670,16 @@ Those (macros) don't use the underlying type field as everything was serialized
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
CodeComment InlineCmt;
|
CodeComment InlineCmt;
|
||||||
Code UnderlyingType;
|
Code UnderlyingType;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok
|
Token* Tok
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
b32 IsFunction;
|
b32 IsFunction;
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -682,12 +705,12 @@ Fields:
|
|||||||
```cpp
|
```cpp
|
||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -708,12 +731,12 @@ Fields:
|
|||||||
CodeComment InlineCmt;
|
CodeComment InlineCmt;
|
||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
CodeType UnderlyingType;
|
CodeType UnderlyingType;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -740,13 +763,13 @@ CodeSpecifiers Specs;
|
|||||||
CodeType ValueType;
|
CodeType ValueType;
|
||||||
Code BitfieldSize;
|
Code BitfieldSize;
|
||||||
Code Value;
|
Code Value;
|
||||||
StringCached Name;
|
StrCached Name;
|
||||||
CodeVar NextVar;
|
CodeVar NextVar;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeT Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
s32 VarParenthesizedInit;
|
s32 VarParenthesizedInit;
|
||||||
```
|
```
|
||||||
|
1183
docs/Parser_Algo.md
1183
docs/Parser_Algo.md
File diff suppressed because it is too large
Load Diff
131
docs/Parsing.md
131
docs/Parsing.md
@ -6,34 +6,35 @@
|
|||||||
|
|
||||||
# Parsing
|
# 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:
|
User exposed interface:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
CodeClass parse_class ( StrC class_def );
|
CodeClass parse_class ( Str class_def );
|
||||||
CodeConstructor parse_constructor ( StrC constructor_def );
|
CodeConstructor parse_constructor ( Str constructor_def );
|
||||||
CodeDestructor parse_destructor ( StrC destructor_def );
|
CodeDefine parse_define ( Str define_def );
|
||||||
CodeEnum parse_enum ( StrC enum_def );
|
CodeDestructor parse_destructor ( Str destructor_def );
|
||||||
CodeBody parse_export_body ( StrC export_def );
|
CodeEnum parse_enum ( Str enum_def );
|
||||||
CodeExtern parse_extern_link ( StrC exten_link_def );
|
CodeBody parse_export_body ( Str export_def );
|
||||||
CodeFriend parse_friend ( StrC friend_def );
|
CodeExtern parse_extern_link ( Str exten_link_def );
|
||||||
CodeFn parse_function ( StrC fn_def );
|
CodeFriend parse_friend ( Str friend_def );
|
||||||
CodeBody parse_global_body ( StrC body_def );
|
CodeFn parse_function ( Str fn_def );
|
||||||
CodeNS parse_namespace ( StrC namespace_def );
|
CodeBody parse_global_body ( Str body_def );
|
||||||
CodeOperator parse_operator ( StrC operator_def );
|
CodeNS parse_namespace ( Str namespace_def );
|
||||||
CodeOpCast parse_operator_cast( StrC operator_def );
|
CodeOperator parse_operator ( Str operator_def );
|
||||||
CodeStruct parse_struct ( StrC struct_def );
|
CodeOpCast parse_operator_cast( Str operator_def );
|
||||||
CodeTemplate parse_template ( StrC template_def );
|
CodeStruct parse_struct ( Str struct_def );
|
||||||
CodeType parse_type ( StrC type_def );
|
CodeTemplate parse_template ( Str template_def );
|
||||||
CodeTypedef parse_typedef ( StrC typedef_def );
|
CodeType parse_type ( Str type_def );
|
||||||
CodeUnion parse_union ( StrC union_def );
|
CodeTypedef parse_typedef ( Str typedef_def );
|
||||||
CodeUsing parse_using ( StrC using_def );
|
CodeUnion parse_union ( Str union_def );
|
||||||
CodeVar parse_variable ( StrC var_def );
|
CodeUsing parse_using ( Str using_def );
|
||||||
|
CodeVar parse_variable ( Str var_def );
|
||||||
```
|
```
|
||||||
|
|
||||||
To parse file buffers, use the `parse_global_body` function.
|
To parse file buffers, use the `parse_global_body` function.
|
||||||
@ -53,38 +54,98 @@ The keywords supported for the preprocessor are:
|
|||||||
* endif
|
* endif
|
||||||
* pragma
|
* 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.
|
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 )
|
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***
|
***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).
|
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:
|
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`
|
* Disable with: `#define GEN_PARSER_DISABLE_MACRO_FUNCTION_SIGNATURES`
|
||||||
* typedefs allow for a preprocessed macro: `typedef MACRO();`
|
* typedefs allow for a preprocessed macro: `typedef MACRO();`
|
||||||
* Disable with: `#define GEN_PARSER_DISABLE_MACRO_TYPEDEF`
|
* Disable with: `#define GEN_PARSER_DISABLE_MACRO_TYPEDEF`
|
||||||
* Macros can behave as typenames
|
* 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)*
|
*(Exceptions are added on an on-demand basis)*
|
||||||
*(See functions `parse_operator_function_or_variable` and `parse_typedef` )*
|
*(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.
|
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.
|
1. The register macro interface within [interface.hpp](../base/components/interface.hpp).
|
||||||
* 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.
|
2. Using `def_define` to create a CodeDefine and making sure to not set `opts.dont_register_to_preprocess_macros` to `true`.
|
||||||
* 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`.
|
|
||||||
|
|
||||||
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.
|
* 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)
|
* 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.*
|
* *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)
|
* 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.
|
* 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).**
|
||||||
|
126
docs/Readme.md
126
docs/Readme.md
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Contains:
|
Contains:
|
||||||
|
|
||||||
* [AST_Design](./AST_Design.md): Overvie of ASTs
|
* [AST_Design](./AST_Design.md): Overview of ASTs
|
||||||
* [AST Types](./AST_Types.md): Listing of all AST types along with their Code type interface.
|
* [AST Types](./AST_Types.md): Listing of all AST types along with their Code type interface.
|
||||||
* [Parsing](./Parsing.md): Overview of the parsing interface.
|
* [Parsing](./Parsing.md): Overview of the parsing interface.
|
||||||
* [Parser Algo](./Parser_Algo.md): In-depth breakdown of the parser's implementation.
|
* [Parser Algo](./Parser_Algo.md): In-depth breakdown of the parser's implementation.
|
||||||
@ -26,7 +26,7 @@ This means that the typename entry for the parameter AST would be either:
|
|||||||
***Concepts and Constraints are not supported***
|
***Concepts and Constraints are not supported***
|
||||||
Its a [todo](https://github.com/Ed94/gencpp/issues/21)
|
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.
|
* `GEN_DEFINE_ATTRIBUTE_TOKENS` : Allows user to define their own attribute macros for use in parsing.
|
||||||
* This can be generated using base.cpp.
|
* 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_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_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_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 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.
|
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.
|
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)
|
[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`*
|
*`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`*
|
*`OperatorT` is a typedef for `EOperator::Type` which has an underlying type of `u32`*
|
||||||
*`StringCahced` is a typedef for `String const`, to denote it is an interned string*
|
*`StrBuilder` is the dynamically allocating string builder type for the library*
|
||||||
*`String` is the dynamically allocated string 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:
|
The width dictates how much the static array can hold before it must give way to using an allocated array:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
@ -63,7 +94,7 @@ int AST_ArrSpecs_Cap =
|
|||||||
(
|
(
|
||||||
AST_POD_Size
|
AST_POD_Size
|
||||||
- sizeof(Code)
|
- sizeof(Code)
|
||||||
- sizeof(StringCached)
|
- sizeof(StrCached)
|
||||||
- sizeof(Code) * 2
|
- sizeof(Code) * 2
|
||||||
- sizeof(Token*)
|
- sizeof(Token*)
|
||||||
- sizeof(Code)
|
- sizeof(Code)
|
||||||
@ -73,41 +104,16 @@ int AST_ArrSpecs_Cap =
|
|||||||
)
|
)
|
||||||
/ sizeof(Specifier) - 1;
|
/ sizeof(Specifier) - 1;
|
||||||
```
|
```
|
||||||
|
|
||||||
*Ex: If the AST_POD_Size is 128 the capacity of the static array is 20.*
|
|
||||||
|
|
||||||
Data Notes:
|
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_string_allocator`, `get_cached_string`, `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.
|
* 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.
|
* Code types have member symbols but their data layout is enforced to be POD types.
|
||||||
* This library treats memory failures as fatal.
|
* 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.
|
* 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.
|
* Strings used for serialization and file buffers are not contained by those used for cached strings.
|
||||||
* They are currently using `GlobalAllocator`, which are tracked array of arenas that grows as needed (adds buckets when one runs out).
|
* `_ctx->Allocator_Temp` is used.
|
||||||
* 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.
|
|
||||||
* 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.
|
* 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):
|
* Any modifcations to an existing AST should be to just construct another with the modifications done on-demand while traversing the AST (non-destructive).
|
||||||
* `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`
|
|
||||||
|
|
||||||
The following CodeTypes are used which the user may optionally use strong typing with if they enable: `GEN_ENFORCE_STRONG_CODE_TYPES`
|
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
|
* CodeClass
|
||||||
* CodeConstructor
|
* CodeConstructor
|
||||||
* CodeDefine
|
* CodeDefine
|
||||||
|
* CodeDefineParams
|
||||||
* CodeDestructor
|
* CodeDestructor
|
||||||
* CodeEnum
|
* CodeEnum
|
||||||
* CodeExec
|
* CodeExec
|
||||||
@ -127,7 +134,7 @@ The following CodeTypes are used which the user may optionally use strong typing
|
|||||||
* CodeModule
|
* CodeModule
|
||||||
* CodeNS
|
* CodeNS
|
||||||
* CodeOperator
|
* CodeOperator
|
||||||
* CodeOpCast
|
* CodeOpCast : User defined member operator conversion
|
||||||
* CodeParams : Has support for `for : range` iterating across parameters.
|
* CodeParams : Has support for `for : range` iterating across parameters.
|
||||||
* CodePreprocessCond
|
* CodePreprocessCond
|
||||||
* CodePragma
|
* CodePragma
|
||||||
@ -140,11 +147,15 @@ The following CodeTypes are used which the user may optionally use strong typing
|
|||||||
* CodeUsing
|
* CodeUsing
|
||||||
* CodeVar
|
* 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.
|
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
|
* Upfront
|
||||||
* Parsing
|
* Parsing
|
||||||
@ -164,6 +175,7 @@ Interface :``
|
|||||||
* def_class
|
* def_class
|
||||||
* def_constructor
|
* def_constructor
|
||||||
* def_define
|
* def_define
|
||||||
|
* def_define_params
|
||||||
* def_destructor
|
* def_destructor
|
||||||
* def_enum
|
* def_enum
|
||||||
* def_execution
|
* 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:
|
When using the body functions, its recommended to use the args macro to auto determine the number of arguments for the varadic:
|
||||||
|
|
||||||
```cpp
|
```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 );
|
def_global_body( 3, ht_entry, array_ht_entry, hashtable );
|
||||||
```
|
```
|
||||||
|
|
||||||
If a more incremental approach is desired for the body ASTs, `Code def_body( CodeT type )` can be used to create an empty body.
|
If a more incremental approach is desired for the body ASTs, `Code def_body( CodeT type )` can be used to create an empty bodyss
|
||||||
When the members have been populated use: `AST::validate_body` to verify that the members are valid entires for that type.
|
When the members have been populated use: `code_validate_body` to verify that the members are valid entires for that type.
|
||||||
|
|
||||||
### Parse construction
|
### Parse construction
|
||||||
|
|
||||||
@ -238,12 +271,12 @@ Interface :
|
|||||||
|
|
||||||
* parse_class
|
* parse_class
|
||||||
* parse_constructor
|
* parse_constructor
|
||||||
|
* parse_define
|
||||||
* parse_destructor
|
* parse_destructor
|
||||||
* parse_enum
|
* parse_enum
|
||||||
* parse_export_body
|
* parse_export_body
|
||||||
* parse_extern_link
|
* parse_extern_link
|
||||||
* parse_friend
|
* parse_friend
|
||||||
* Purposefully are only support forward declares with this constructor.
|
|
||||||
* parse_function
|
* parse_function
|
||||||
* parse_global_body
|
* parse_global_body
|
||||||
* parse_namespace
|
* parse_namespace
|
||||||
@ -308,7 +341,7 @@ Code <name> = code_str( <some code without "" quotes > )
|
|||||||
Template metaprogramming in the traditional sense becomes possible with the use of `token_fmt` and parse constructors:
|
Template metaprogramming in the traditional sense becomes possible with the use of `token_fmt` and parse constructors:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StrC value = txt("Something");
|
Str value = txt("Something");
|
||||||
|
|
||||||
char const* template_str = txt(
|
char const* template_str = txt(
|
||||||
Code with <key> to replace with token_values
|
Code with <key> to replace with token_values
|
||||||
@ -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:
|
The following are provided predefined by the library as they are commonly used:
|
||||||
|
|
||||||
|
* `enum_underlying_macro`
|
||||||
* `access_public`
|
* `access_public`
|
||||||
* `access_protected`
|
* `access_protected`
|
||||||
* `access_private`
|
* `access_private`
|
||||||
@ -398,19 +432,19 @@ and have the desired specifiers assigned to them beforehand.
|
|||||||
|
|
||||||
## Code generation and modification
|
## Code generation and modification
|
||||||
|
|
||||||
There are two provided auxillary interfaces:
|
There are two provided auxiliary interfaces:
|
||||||
|
|
||||||
* Builder
|
* Builder
|
||||||
* Scanner
|
* Scanner
|
||||||
|
|
||||||
### Builder is a similar object to the jai language's string_builder
|
### Builder is a similar object to the jai language's strbuilder_builder
|
||||||
|
|
||||||
* The purpose of it is to generate a file.
|
* The purpose of it is to generate a file.
|
||||||
* A file is specified and opened for writing using the open( file_path) function.
|
* A file is specified and opened for writing using the open( file_path) function.
|
||||||
* The code is provided via print( code ) function will be serialized to its buffer.
|
* 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.
|
* 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
|
* The purpose is to scan or parse files
|
||||||
* Some with two basic functions to convert a fil to code: `scan_file` and `parse_file`
|
* 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
|
## Navigation
|
||||||
|
|
||||||
# base
|
|
||||||
|
|
||||||
[Top](../Readme.md)
|
[Top](../Readme.md)
|
||||||
|
|
||||||
* [docs](../docs/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:
|
If using the library's provided build scripts:
|
||||||
|
|
||||||
```ps1
|
```ps1
|
||||||
.\build.ps1 <compiler> <debug or omit> c_library
|
.\build.ps1 <compiler> <debug or omit> c_lib
|
||||||
```
|
```
|
||||||
|
|
||||||
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.
|
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.**
|
**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.
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,7 @@ word global, gen_global
|
|||||||
word internal, gen_internal
|
word internal, gen_internal
|
||||||
word local_persist, gen_local_persist
|
word local_persist, gen_local_persist
|
||||||
word bit, gen_bit
|
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 cast, gen_cast
|
||||||
word ccast, gen_ccast
|
word ccast, gen_ccast
|
||||||
word pcast, gen_pcast
|
word pcast, gen_pcast
|
||||||
@ -167,7 +167,7 @@ namespace pool_, gen_pool_
|
|||||||
|
|
||||||
// Printing
|
// Printing
|
||||||
|
|
||||||
namespace str_, gen_str_
|
namespace c_str_, gen_c_str_
|
||||||
|
|
||||||
word PrintF_Buffer, gen_PrintF_Buffer
|
word PrintF_Buffer, gen_PrintF_Buffer
|
||||||
word Msg_Invalid_Value, gen_Msg_Invalid_Value
|
word Msg_Invalid_Value, gen_Msg_Invalid_Value
|
||||||
@ -211,20 +211,20 @@ word crc64, gen_crc64
|
|||||||
|
|
||||||
// Strings
|
// Strings
|
||||||
|
|
||||||
word StrC, gen_StrC
|
word Str, gen_Str
|
||||||
|
|
||||||
word to_strc_from_c_str, gen_to_strc_from_c_str
|
word to_str_from_c_str, gen_to_str_from_c_str
|
||||||
|
|
||||||
namespace strc_, gen_strc_
|
namespace str_, gen_str_
|
||||||
|
|
||||||
word cast_to_strc, gen_cast_to_strc
|
word cast_to_str, gen_cast_to_str
|
||||||
|
|
||||||
word StringHeader, gen_StringHeader
|
word StrBuilderHeader, gen_StrBuilderHeader
|
||||||
word String, gen_String
|
word StrBuilder, gen_StrBuilder
|
||||||
|
|
||||||
namespace string_, gen_string_
|
namespace strbuilder_, gen_strbuilder_
|
||||||
|
|
||||||
word StringCached, gen_StringCached
|
word StrCached, gen_StrCached
|
||||||
|
|
||||||
word StringTable, gen_StringTable
|
word StringTable, gen_StringTable
|
||||||
|
|
||||||
@ -308,7 +308,15 @@ word operator_to_str, gen_operator_to_str
|
|||||||
word Specifier, gen_Specifier
|
word Specifier, gen_Specifier
|
||||||
word spec_to_str, gen_spec_to_str
|
word spec_to_str, gen_spec_to_str
|
||||||
word spec_is_trailing, gen_spec_is_trailing
|
word spec_is_trailing, gen_spec_is_trailing
|
||||||
// word strc_to_specifier, gen_strc_to_specifier
|
// 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
|
// AST
|
||||||
|
|
||||||
@ -325,6 +333,7 @@ word CodeComment, gen_CodeComment
|
|||||||
word CodeClass, gen_CodeClass
|
word CodeClass, gen_CodeClass
|
||||||
word CodeConstructor, gen_CodeConstructor
|
word CodeConstructor, gen_CodeConstructor
|
||||||
word CodeDefine, gen_CodeDefine
|
word CodeDefine, gen_CodeDefine
|
||||||
|
word CodeDefineParams, gen_CodeDefineParams
|
||||||
word CodeDestructor, gen_CodeDestructor
|
word CodeDestructor, gen_CodeDestructor
|
||||||
word CodeEnum, gen_CodeEnum
|
word CodeEnum, gen_CodeEnum
|
||||||
word CodeExec, gen_CodeExec
|
word CodeExec, gen_CodeExec
|
||||||
@ -340,6 +349,7 @@ word CodePragma, gen_CodePragma
|
|||||||
word CodeParams, gen_CodeParams
|
word CodeParams, gen_CodeParams
|
||||||
word CodePreprocessCond, gen_CodePreprocessCond
|
word CodePreprocessCond, gen_CodePreprocessCond
|
||||||
word CodeSpecifiers, gen_CodeSpecifiers
|
word CodeSpecifiers, gen_CodeSpecifiers
|
||||||
|
word CodeStruct, gen_CodeStruct
|
||||||
word CodeTemplate, gen_CodeTemplate
|
word CodeTemplate, gen_CodeTemplate
|
||||||
word CodeTypename, gen_CodeTypename
|
word CodeTypename, gen_CodeTypename
|
||||||
word CodeTypedef, gen_CodeTypedef
|
word CodeTypedef, gen_CodeTypedef
|
||||||
@ -349,6 +359,8 @@ word CodeVar, gen_CodeVar
|
|||||||
|
|
||||||
// Code Interface
|
// Code Interface
|
||||||
|
|
||||||
|
word Context, gen_Context
|
||||||
|
|
||||||
namespace code_, gen_code_
|
namespace code_, gen_code_
|
||||||
|
|
||||||
word Code_Global, gen_Code_Global
|
word Code_Global, gen_Code_Global
|
||||||
@ -396,16 +408,24 @@ namespace var_, gen_var_
|
|||||||
|
|
||||||
// Gen Interface
|
// Gen Interface
|
||||||
|
|
||||||
|
word _ctx, gen__ctx
|
||||||
|
|
||||||
word init, gen_init
|
word init, gen_init
|
||||||
word deinit, gen_deinit
|
word deinit, gen_deinit
|
||||||
word reset, gen_reset
|
word reset, gen_reset
|
||||||
|
|
||||||
word get_cached_string, gen_get_cached_string
|
word cache_str, gen_cache_str
|
||||||
|
|
||||||
word make_code, gen_make_code
|
word make_code, gen_make_code
|
||||||
|
|
||||||
namespace set_allocator_, gen_set_allocator_
|
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 def_, gen_def_
|
||||||
namespace parse_, gen_parse_
|
namespace parse_, gen_parse_
|
||||||
namespace token_, gen_token_
|
namespace token_, gen_token_
|
||||||
@ -413,20 +433,6 @@ namespace untyped_, gen_untyped_
|
|||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
|
|
||||||
word TokenMap_FixedArena, gen_TokenMap_FixedArena
|
|
||||||
word InitSize_DataArrays, gen_InitSize_DataArrays
|
|
||||||
|
|
||||||
word Global_BucketSize, gen_Global_BucketSize
|
|
||||||
word CodePool_NumBlocks, gen_CodePool_NumBlocks
|
|
||||||
word SizePer_StringArena, gen_SizePer_StringArena
|
|
||||||
|
|
||||||
word MaxCommentLineLength, gen_MaxCommentLineLength
|
|
||||||
word MaxNameLength, gen_MaxNameLength
|
|
||||||
word MaxUntypedStrLength, gen_MaxUntypedStrLength
|
|
||||||
|
|
||||||
word LexAllocator_Size, gen_LexAllocator_Size
|
|
||||||
word Builder_StrBufferReserve, gen_Builder_StrBufferReserve
|
|
||||||
|
|
||||||
word access_public, gen_access_public
|
word access_public, gen_access_public
|
||||||
word access_protected, gen_access_protected
|
word access_protected, gen_access_protected
|
||||||
word access_private, gen_access_private
|
word access_private, gen_access_private
|
||||||
@ -445,28 +451,20 @@ word preprocess_else, gen_preprocess_else
|
|||||||
namespace spec_, gen_spec_
|
namespace spec_, gen_spec_
|
||||||
namespace t_, gen_t_
|
namespace t_, gen_t_
|
||||||
|
|
||||||
word PreprocessorDefines, gen_PreprocessorDefines
|
|
||||||
|
|
||||||
// Backend
|
// Backend
|
||||||
|
|
||||||
word GlobalAllocator, gen_GlobalAllocator
|
|
||||||
word Global_AllocatorBuckets, gen_Global_AllocatorBuckets
|
|
||||||
word CodePools, gen_CodePools
|
|
||||||
word StringArenas, gen_StringArenas
|
|
||||||
word StringCache, gen_StringCache
|
|
||||||
word LexArena, gen_LexArena
|
|
||||||
word Allocator_DataArrays, gen_Allocator_DataArrays
|
|
||||||
word Allocator_CodePool, gen_Allocator_CodePool
|
|
||||||
word Allocator_Lexer, gen_Allocator_Lexer
|
|
||||||
word Allocator_StringArena, gen_Allocator_StringArena
|
|
||||||
word Allocator_StringTable, gen_Allocator_StringTable
|
|
||||||
word Allocator_TypeTable, gen_Allocator_TypeTable
|
|
||||||
|
|
||||||
// Builder
|
// Builder
|
||||||
|
|
||||||
word Builder, gen_Builder
|
word Builder, gen_Builder
|
||||||
namespace builder_, gen_builder_
|
namespace builder_, gen_builder_
|
||||||
|
|
||||||
|
// Scanner
|
||||||
|
|
||||||
|
word scan_file, gen_scan_file
|
||||||
|
|
||||||
|
word CSV_Column, gen_CSV_Column
|
||||||
|
word CSV_Columns2, gen_CSV_Columns2
|
||||||
|
|
||||||
// Implementation (prviate)
|
// Implementation (prviate)
|
||||||
|
|
||||||
word _format_info, gen__format_info
|
word _format_info, gen__format_info
|
||||||
@ -513,7 +511,7 @@ word _adt_get_field, gen__adt_get_field
|
|||||||
word _csv_write_record, gen__csv_write_record
|
word _csv_write_record, gen__csv_write_record
|
||||||
word _csv_write_header, gen__csv_write_header
|
word _csv_write_header, gen__csv_write_header
|
||||||
|
|
||||||
word Global_Allocator_Proc, gen_Global_Allocator_Proc
|
word fallback_allocator_proc, gen_Global_Allocator_Proc
|
||||||
word define_constants, gen_define_constants
|
word define_constants, gen_define_constants
|
||||||
word operator__validate, gen_operator__validate
|
word operator__validate, gen_operator__validate
|
||||||
|
|
||||||
@ -522,7 +520,6 @@ word parser_deinit, gen_parser_deinit
|
|||||||
|
|
||||||
word TokType, gen_TokType
|
word TokType, gen_TokType
|
||||||
word toktype_to_str, gen_toktype_to_str
|
word toktype_to_str, gen_toktype_to_str
|
||||||
// word strc_to_toktype, gen_strc_to_toktype
|
|
||||||
word NullToken, gen_NullToken
|
word NullToken, gen_NullToken
|
||||||
|
|
||||||
namespace tok_, gen_tok_
|
namespace tok_, gen_tok_
|
||||||
|
@ -22,9 +22,9 @@ CodeBody gen_array_base()
|
|||||||
Code get_header = untyped_str( txt( "#define array_get_header( self ) ( (ArrayHeader*)( self ) - 1)\n" ));
|
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 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_begin = def_define(txt("array_begin(array)"), MT_Expression, { {}, code( (array) ) } );
|
||||||
Code array_end = def_define(txt("array_end(array)"), code( (array + array_get_header(array)->Num ) ));
|
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)"), code( (entry + 1) ));
|
Code array_next = def_define(txt("array_next(array, entry)"), MT_Expression, { {}, code( (entry + 1) ) } );
|
||||||
|
|
||||||
return def_global_body( args(
|
return def_global_body( args(
|
||||||
fmt_newline,
|
fmt_newline,
|
||||||
@ -40,11 +40,11 @@ CodeBody gen_array_base()
|
|||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
CodeBody gen_array( StrC type, StrC array_name )
|
CodeBody gen_array( Str type, Str array_name )
|
||||||
{
|
{
|
||||||
String array_type = String::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr );
|
StrBuilder array_type = StrBuilder::fmt_buf( _ctx->Allocator_Temp, "%.*s", array_name.Len, array_name.Ptr );
|
||||||
String fn = String::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr );
|
StrBuilder fn = StrBuilder::fmt_buf( _ctx->Allocator_Temp, "%.*s", array_name.Len, array_name.Ptr );
|
||||||
// str_to_lower(fn.Data);
|
// c_str_to_lower(fn.Data);
|
||||||
|
|
||||||
#pragma push_macro( "GEN_ASSERT" )
|
#pragma push_macro( "GEN_ASSERT" )
|
||||||
#pragma push_macro( "rcast" )
|
#pragma push_macro( "rcast" )
|
||||||
@ -56,7 +56,7 @@ CodeBody gen_array( StrC type, StrC array_name )
|
|||||||
#undef cast
|
#undef cast
|
||||||
#undef typeof
|
#undef typeof
|
||||||
#undef forceinline
|
#undef forceinline
|
||||||
CodeBody result = parse_global_body( token_fmt( "array_type", (StrC)array_type, "fn", (StrC)fn, "type", (StrC)type
|
CodeBody result = parse_global_body( token_fmt( "array_type", (Str)array_type, "fn", (Str)fn, "type", (Str)type
|
||||||
, stringize(
|
, stringize(
|
||||||
typedef <type>* <array_type>;
|
typedef <type>* <array_type>;
|
||||||
|
|
||||||
@ -238,10 +238,10 @@ CodeBody gen_array( StrC type, StrC array_name )
|
|||||||
GEN_ASSERT(begin <= end);
|
GEN_ASSERT(begin <= end);
|
||||||
ArrayHeader* header = array_get_header( self );
|
ArrayHeader* header = array_get_header( self );
|
||||||
|
|
||||||
if ( begin < 0 || end >= header->Num )
|
if ( begin < 0 || end > header->Num )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for ( ssize idx = begin; idx < end; idx ++ )
|
for ( ssize idx = (ssize)begin; idx < (ssize)end; idx ++ )
|
||||||
self[ idx ] = value;
|
self[ idx ] = value;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -375,9 +375,9 @@ CodeBody gen_array( StrC type, StrC array_name )
|
|||||||
#pragma pop_macro( "forceinline" )
|
#pragma pop_macro( "forceinline" )
|
||||||
|
|
||||||
++ Array_DefinitionCounter;
|
++ Array_DefinitionCounter;
|
||||||
StrC slot_str = String::fmt_buf(GlobalAllocator, "%d", Array_DefinitionCounter).to_strc();
|
Str slot_str = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "%d", Array_DefinitionCounter).to_str();
|
||||||
|
|
||||||
Code generic_interface_slot = untyped_str(token_fmt( "type", type, "array_type", (StrC)array_type, "slot", (StrC)slot_str,
|
Code generic_interface_slot = untyped_str(token_fmt( "type", type, "array_type", (Str)array_type, "slot", (Str)slot_str,
|
||||||
R"(#define GENERIC_SLOT_<slot>__array_init <type>, <array_type>_init
|
R"(#define GENERIC_SLOT_<slot>__array_init <type>, <array_type>_init
|
||||||
#define GENERIC_SLOT_<slot>__array_init_reserve <type>, <array_type>_init_reserve
|
#define GENERIC_SLOT_<slot>__array_init_reserve <type>, <array_type>_init_reserve
|
||||||
#define GENERIC_SLOT_<slot>__array_append <array_type>, <array_type>_append
|
#define GENERIC_SLOT_<slot>__array_append <array_type>, <array_type>_append
|
||||||
@ -399,13 +399,13 @@ R"(#define GENERIC_SLOT_<slot>__array_init <type>, <array_type>_i
|
|||||||
));
|
));
|
||||||
|
|
||||||
return def_global_body( args(
|
return def_global_body( args(
|
||||||
def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "region %S", array_type ))),
|
def_pragma( strbuilder_to_str( strbuilder_fmt_buf( _ctx->Allocator_Temp, "region %SB", array_type ))),
|
||||||
fmt_newline,
|
fmt_newline,
|
||||||
generic_interface_slot,
|
generic_interface_slot,
|
||||||
fmt_newline,
|
fmt_newline,
|
||||||
result,
|
result,
|
||||||
fmt_newline,
|
fmt_newline,
|
||||||
def_pragma( string_to_strc(string_fmt_buf( GlobalAllocator, "endregion %S", array_type ))),
|
def_pragma( strbuilder_to_str(strbuilder_fmt_buf( _ctx->Allocator_Temp, "endregion %SB", array_type ))),
|
||||||
fmt_newline
|
fmt_newline
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,7 @@ CodeBody gen_hashtable_base()
|
|||||||
));
|
));
|
||||||
|
|
||||||
Code define_type = untyped_str(txt(
|
Code define_type = untyped_str(txt(
|
||||||
R"(#define HashTable(_type) struct _type
|
R"(#define HashTable(_type) struct gen_HashTable_##_type
|
||||||
)"
|
)"
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -27,24 +27,24 @@ R"(#define HashTable(_type) struct _type
|
|||||||
return def_global_body(args(struct_def, define_type, define_critical_load_scale));
|
return def_global_body(args(struct_def, define_type, define_critical_load_scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeBody gen_hashtable( StrC type, StrC hashtable_name )
|
CodeBody gen_hashtable( Str type, Str hashtable_name )
|
||||||
{
|
{
|
||||||
|
|
||||||
String tbl_type = {(char*) hashtable_name.duplicate(GlobalAllocator).Ptr};
|
StrBuilder tbl_type = {(char*) hashtable_name.duplicate(_ctx->Allocator_Temp).Ptr};
|
||||||
String fn = tbl_type.duplicate(GlobalAllocator);
|
StrBuilder fn = tbl_type.duplicate(_ctx->Allocator_Temp);
|
||||||
// str_to_lower(fn.Data);
|
// c_str_to_lower(fn.Data);
|
||||||
|
|
||||||
String name_lower = String::make( GlobalAllocator, hashtable_name );
|
StrBuilder name_lower = StrBuilder::make( _ctx->Allocator_Temp, hashtable_name );
|
||||||
// str_to_lower( name_lower.Data );
|
// c_str_to_lower( name_lower.Data );
|
||||||
|
|
||||||
String hashtable_entry = String::fmt_buf( GlobalAllocator, "HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr );
|
StrBuilder hashtable_entry = StrBuilder::fmt_buf( _ctx->Allocator_Temp, "HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr );
|
||||||
String entry_array_name = String::fmt_buf( GlobalAllocator, "Arr_HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr );
|
StrBuilder entry_array_name = StrBuilder::fmt_buf( _ctx->Allocator_Temp, "Arr_HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr );
|
||||||
String entry_array_fn_ns = String::fmt_buf( GlobalAllocator, "arr_hte_%.*s", name_lower.length(), name_lower.Data );
|
StrBuilder entry_array_fn_ns = StrBuilder::fmt_buf( _ctx->Allocator_Temp, "arr_hte_%.*s", name_lower.length(), name_lower.Data );
|
||||||
|
|
||||||
CodeBody hashtable_types = parse_global_body( token_fmt(
|
CodeBody hashtable_types = parse_global_body( token_fmt(
|
||||||
"type", (StrC) type,
|
"type", (Str) type,
|
||||||
"tbl_name", (StrC) hashtable_name,
|
"tbl_name", (Str) hashtable_name,
|
||||||
"tbl_type", (StrC) tbl_type,
|
"tbl_type", (Str) tbl_type,
|
||||||
stringize(
|
stringize(
|
||||||
typedef struct HashTable_<type> <tbl_type>;
|
typedef struct HashTable_<type> <tbl_type>;
|
||||||
typedef struct HTE_<tbl_name> HTE_<tbl_name>;
|
typedef struct HTE_<tbl_name> HTE_<tbl_name>;
|
||||||
@ -74,13 +74,13 @@ CodeBody gen_hashtable( StrC type, StrC hashtable_name )
|
|||||||
#undef typeof
|
#undef typeof
|
||||||
#undef forceinline
|
#undef forceinline
|
||||||
CodeBody hashtable_def = parse_global_body( token_fmt(
|
CodeBody hashtable_def = parse_global_body( token_fmt(
|
||||||
"type", (StrC) type,
|
"type", (Str) type,
|
||||||
"tbl_name", (StrC) hashtable_name,
|
"tbl_name", (Str) hashtable_name,
|
||||||
"tbl_type", (StrC) tbl_type,
|
"tbl_type", (Str) tbl_type,
|
||||||
"fn", (StrC) fn,
|
"fn", (Str) fn,
|
||||||
"entry_type", (StrC) hashtable_entry,
|
"entry_type", (Str) hashtable_entry,
|
||||||
"array_entry", (StrC) entry_array_name,
|
"array_entry", (Str) entry_array_name,
|
||||||
"fn_array", (StrC) entry_array_fn_ns,
|
"fn_array", (Str) entry_array_fn_ns,
|
||||||
stringize(
|
stringize(
|
||||||
struct HashTable_<type> {
|
struct HashTable_<type> {
|
||||||
Array_ssize Hashes;
|
Array_ssize Hashes;
|
||||||
@ -372,9 +372,9 @@ CodeBody gen_hashtable( StrC type, StrC hashtable_name )
|
|||||||
#pragma pop_macro( "forceinline" )
|
#pragma pop_macro( "forceinline" )
|
||||||
|
|
||||||
++ HashTable_DefinitionCounter;
|
++ HashTable_DefinitionCounter;
|
||||||
StrC slot_str = String::fmt_buf(GlobalAllocator, "%d", HashTable_DefinitionCounter).to_strc();
|
Str slot_str = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "%d", HashTable_DefinitionCounter).to_str();
|
||||||
|
|
||||||
Code generic_interface_slot = untyped_str(token_fmt( "type", type, "tbl_type", (StrC)tbl_type, "slot", (StrC)slot_str,
|
Code generic_interface_slot = untyped_str(token_fmt( "type", type, "tbl_type", (Str)tbl_type, "slot", (Str)slot_str,
|
||||||
R"(#define GENERIC_SLOT_<slot>__hashtable_init <type>, <tbl_type>_init
|
R"(#define GENERIC_SLOT_<slot>__hashtable_init <type>, <tbl_type>_init
|
||||||
#define GENERIC_SLOT_<slot>__hashtable_init_reserve <type>, <tbl_type>_init_reserve
|
#define GENERIC_SLOT_<slot>__hashtable_init_reserve <type>, <tbl_type>_init_reserve
|
||||||
#define GENERIC_SLOT_<slot>__hashtable_clear <tbl_type>, <tbl_type>_clear
|
#define GENERIC_SLOT_<slot>__hashtable_clear <tbl_type>, <tbl_type>_clear
|
||||||
@ -395,12 +395,12 @@ R"(#define GENERIC_SLOT_<slot>__hashtable_init <type>, <tbl_type>_
|
|||||||
)"
|
)"
|
||||||
));
|
));
|
||||||
|
|
||||||
char const* cmt_str = str_fmt_buf( "Name: %.*s Type: %.*s"
|
char const* cmt_str = c_str_fmt_buf( "Name: %.*s Type: %.*s"
|
||||||
, tbl_type.length(), tbl_type.Data
|
, tbl_type.length(), tbl_type.Data
|
||||||
, type.Len, type.Ptr );
|
, type.Len, type.Ptr );
|
||||||
|
|
||||||
return def_global_body(args(
|
return def_global_body(args(
|
||||||
def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "region %S", tbl_type ))),
|
def_pragma( strbuilder_to_str( strbuilder_fmt_buf( _ctx->Allocator_Temp, "region %SB", tbl_type ))),
|
||||||
fmt_newline,
|
fmt_newline,
|
||||||
generic_interface_slot,
|
generic_interface_slot,
|
||||||
fmt_newline,
|
fmt_newline,
|
||||||
@ -409,7 +409,7 @@ R"(#define GENERIC_SLOT_<slot>__hashtable_init <type>, <tbl_type>_
|
|||||||
entry_array,
|
entry_array,
|
||||||
hashtable_def,
|
hashtable_def,
|
||||||
fmt_newline,
|
fmt_newline,
|
||||||
def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "endregion %S", tbl_type ))),
|
def_pragma( strbuilder_to_str( strbuilder_fmt_buf( _ctx->Allocator_Temp, "endregion %SB", tbl_type ))),
|
||||||
fmt_newline
|
fmt_newline
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
// ____ _ ______ _ _ ____ _ __ _
|
// ____ _ ______ _ _ ____ _ __ _
|
||||||
// / ___} (_) | ____} | | (_) / __ \ | | | |(_)
|
// / ___} (_) | ____} | | (_) / __ \ | | | |(_)
|
||||||
// | | ___ ___ _ __ ___ _ __ _ ___ | |__ _ _ _ __ ___| |_ _ ___ _ __ | | | |_ _____ _ __ | | ___ __ _ __| | _ _ __ __ _
|
// | | ___ ___ _ __ ___ _ __ _ ___ | |__ _ _ _ __ ___| |_ _ ___ _ __ | | | |_ _____ _ __ | | ___ __ _ __| | _ _ __ __ _
|
||||||
// | |{__ |/ _ \ '_ \ / _ \ '__} |/ __| | __} | | | '_ \ / __} __} |/ _ \| '_ \ | | | \ \ / / _ \ '_ \| |/ _ \ / _` |/ _` || | '_ \ / _` |
|
// | |{__ |/ _ \ '_ \ / _ \ '__} |/ __| | __} | | | '_ \ / __} __} |/ _ \| '_ \ | | | \ \ / / _ \ '_ }| |/ _ \ / _` |/ _` || | '_ \ / _` |
|
||||||
// | |__j | __/ | | | __/ | | | (__ | | | |_| | | | | (__| l_| | (_) | | | | | l__| |\ V / __/ | | | | (_) | (_| | (_| || | | | | (_| |
|
// | |__j | __/ | | | __/ | | | (__ | | | |_| | | | | (__| l_| | (_) | | | | | l__| |\ V / __/ | | | (_) | (_| | (_| || | | | | (_| |
|
||||||
// \____/ \___}_l l_l\___}_l l_l\___| l_l \__,_l_l l_l\___}\__}_l\___/l_l l_l \____/ \_/ \___}_l l_l_l\___/ \__,_l\__,_l|_|_| |_|\__, |
|
// \____/ \___}_l l_l\___}_l l_l\___| l_l \__,_l_l l_l\___}\__}_l\___/l_l l_l \____/ \_/ \___}_l l_l\___/ \__,_l\__,_l|_|_| |_|\__, |
|
||||||
// This implemnents macros for utilizing "The Naive Extendible _Generic Macro" explained in: __| |
|
// This implemnents macros for utilizing "The Naive Extendible _Generic Macro" explained in: __| |
|
||||||
// https://github.com/JacksonAllan/CC/blob/main/articles/Better_C_Generics_Part_1_The_Extendible_Generic.md {___/
|
// https://github.com/JacksonAllan/CC/blob/main/articles/Better_C_Generics_Part_1_The_Extendible_Generic.md {___/
|
||||||
// Since gencpp is used to generate the c-library, it was choosen over the more novel implementations to keep the macros as easy to understand and unobfuscated as possible.
|
// Since gencpp is used to generate the c-library, it was choosen over the more novel implementations to keep the macros as easy to understand and unobfuscated as possible.
|
||||||
@ -30,7 +30,7 @@
|
|||||||
// Where GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER is specifically looking for that <comma> ,
|
// Where GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER is specifically looking for that <comma> ,
|
||||||
#define GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( slot_exp ) GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER( slot_exp, GEN_GENERIC_SEL_ENTRY_TYPE( slot_exp, ): GEN_GENERIC_SEL_ENTRY_FUNCTION( slot_exp, ) GEN_COMMA_OPERATOR, , )
|
#define GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( slot_exp ) GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER( slot_exp, GEN_GENERIC_SEL_ENTRY_TYPE( slot_exp, ): GEN_GENERIC_SEL_ENTRY_FUNCTION( slot_exp, ) GEN_COMMA_OPERATOR, , )
|
||||||
// ^ Selects the comma ^ is the type ^ is the function ^ Insert a comma
|
// ^ Selects the comma ^ is the type ^ is the function ^ Insert a comma
|
||||||
// The slot won't exist if that comma is not found. |
|
// The slot won't exist if that comma is not found.
|
||||||
|
|
||||||
// For the occastion where an expression didn't resolve to a selection option the "default: <value>" will be set to:
|
// For the occastion where an expression didn't resolve to a selection option the "default: <value>" will be set to:
|
||||||
typedef struct GENCPP_NO_RESOLVED_GENERIC_SELECTION GENCPP_NO_RESOLVED_GENERIC_SELECTION;
|
typedef struct GENCPP_NO_RESOLVED_GENERIC_SELECTION GENCPP_NO_RESOLVED_GENERIC_SELECTION;
|
||||||
@ -43,12 +43,12 @@ GENCPP_NO_RESOLVED_GENERIC_SELECTION const gen_generic_selection_fail = {0};
|
|||||||
|
|
||||||
// Below are generated on demand for an overlaod depdendent on a type:
|
// Below are generated on demand for an overlaod depdendent on a type:
|
||||||
// ----------------------------------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
||||||
#define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg ) _Generic( \
|
#define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg ) _Generic( \
|
||||||
(selector_arg), /* Select Via Expression*/ \
|
(selector_arg), /* Select Via Expression*/ \
|
||||||
/* Extendibility slots: */ \
|
/* Extendibility slots: */ \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1__function_sig ) \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_2__function_sig ) \
|
||||||
default: gen_generic_selection_fail \
|
default: gen_generic_selection_fail \
|
||||||
) GEN_RESOLVED_FUNCTION_CALL( selector_arg )
|
) GEN_RESOLVED_FUNCTION_CALL( selector_arg )
|
||||||
// ----------------------------------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -68,20 +68,21 @@ size_t gen_example_hash__P_long( long val ) { return val * 2654435761ull; }
|
|||||||
#define GENERIC_SLOT_2_gen_example_hash long long, gen_example_hash__P_long_long
|
#define GENERIC_SLOT_2_gen_example_hash long long, gen_example_hash__P_long_long
|
||||||
size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761ull; }
|
size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761ull; }
|
||||||
|
|
||||||
// If using an Editor with support for syntax hightlighting macros: HASH__ARGS_SIG_1 and HASH_ARGS_SIG_2 should show color highlighting indicating the slot is enabled,
|
// If using an Editor with support for syntax hightlighting macros:
|
||||||
|
// GENERIC_SLOT_1_gen_example_hash and GENERIC_SLOT_2_gen_example_hash should show color highlighting indicating the slot is enabled,
|
||||||
// or, "defined" for usage during the compilation pass that handles the _Generic instrinsic.
|
// or, "defined" for usage during the compilation pass that handles the _Generic instrinsic.
|
||||||
#define gen_hash_example( function_arguments ) _Generic( \
|
#define gen_hash_example( function_arguments ) _Generic( \
|
||||||
(function_arguments), /* Select Via Expression*/ \
|
(function_arguments), /* Select Via Expression*/ \
|
||||||
/* Extendibility slots: */ \
|
/* Extendibility slots: */ \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_1 ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1_gen_example_hash ) \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_2 ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_2_gen_example_hash ) \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_3 ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_3_gen_example_hash ) \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_4 ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_4_gen_example_hash ) \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_5 ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_5_gen_example_hash ) \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_6 ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_6_gen_example_hash ) \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_7 ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_7_gen_example_hash ) \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_8 ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_8_gen_example_hash ) \
|
||||||
default: gen_generic_selection_fail \
|
default: gen_generic_selection_fail \
|
||||||
) GEN_RESOLVED_FUNCTION_CALL( function_arguments )
|
) GEN_RESOLVED_FUNCTION_CALL( function_arguments )
|
||||||
|
|
||||||
// Additional Variations:
|
// Additional Variations:
|
||||||
@ -89,20 +90,20 @@ size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761u
|
|||||||
// If the function takes more than one argument the following is used:
|
// If the function takes more than one argument the following is used:
|
||||||
#define GEN_FUNCTION_GENERIC_EXAMPLE_VARADIC( selector_arg, ... ) _Generic( \
|
#define GEN_FUNCTION_GENERIC_EXAMPLE_VARADIC( selector_arg, ... ) _Generic( \
|
||||||
(selector_arg), \
|
(selector_arg), \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1__function_sig ) \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_2 ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_2__function_sig ) \
|
||||||
/* ... */ \
|
/* ... */ \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(FunctionID__ARGS_SIG_N ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(GENERIC_SLOT_N__function_sig ) \
|
||||||
default: gen_generic_selection_fail \
|
default: gen_generic_selection_fail \
|
||||||
) GEN_RESOLVED_FUNCTION_CALL( selector_arg, __VA_ARG__ )
|
) GEN_RESOLVED_FUNCTION_CALL( selector_arg, __VA_ARG__ )
|
||||||
|
|
||||||
// If the function does not take the arugment as a parameter:
|
// If the function does not take the arugment as a parameter:
|
||||||
#define GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( selector_arg ) _Generic( \
|
#define GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( selector_arg ) _Generic( \
|
||||||
( GEN_TYPE_TO_EXP(selector_arg) ), \
|
( GEN_TYPE_TO_EXP(selector_arg) ), \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1__function_sig ) \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_2 ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_2__function_sig ) \
|
||||||
/* ... */ \
|
/* ... */ \
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(FunctionID__ARGS_SIG_N ) \
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(GENERIC_SLOT_N__function_sig ) \
|
||||||
default: gen_generic_selection_fail \
|
default: gen_generic_selection_fail \
|
||||||
) GEN_RESOLVED_FUNCTION_CALL()
|
) GEN_RESOLVED_FUNCTION_CALL()
|
||||||
|
|
@ -13,7 +13,7 @@
|
|||||||
| \_____|\___}_l |_|\___} .__/| .__/ {_____/ \__\__/_l\__. |\___/\__,_l \____}{_____}{_____} |
|
| \_____|\___}_l |_|\___} .__/| .__/ {_____/ \__\__/_l\__. |\___/\__,_l \____}{_____}{_____} |
|
||||||
| | | | | __} | |
|
| | | | | __} | |
|
||||||
| l_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 |
|
! 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 |
|
! 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_2mb);
|
||||||
result.append(arena_interface_4mb);
|
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(def);
|
||||||
result.append(fmt_newline);
|
result.append(fmt_newline);
|
||||||
|
|
||||||
|
@ -7,30 +7,41 @@ void convert_cpp_enum_to_c( CodeEnum to_convert, CodeBody to_append )
|
|||||||
{
|
{
|
||||||
#pragma push_macro("enum_underlying")
|
#pragma push_macro("enum_underlying")
|
||||||
#undef 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)
|
if (to_convert->UnderlyingType)
|
||||||
{
|
{
|
||||||
to_convert->UnderlyingTypeMacro = untyped_str(token_fmt("type", to_convert->UnderlyingType->Name, stringize(enum_underlying(<type>))));
|
to_convert->UnderlyingTypeMacro = untyped_str(token_fmt("type", to_convert->UnderlyingType->Name, stringize(enum_underlying(<type>))));
|
||||||
to_convert->UnderlyingType = CodeTypename{nullptr};
|
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(to_convert);
|
||||||
to_append.append(tdef);
|
to_append.append(tdef);
|
||||||
#pragma pop_macro("enum_underlying")
|
#pragma pop_macro("enum_underlying")
|
||||||
}
|
}
|
||||||
|
|
||||||
b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& parsed_body, CodeBody& body )
|
b32 ignore_preprocess_cond_block( Str cond_sig, Code& entry_iter, CodeBody& parsed_body, CodeBody& body )
|
||||||
{
|
{
|
||||||
b32 found = false;
|
b32 found = false;
|
||||||
CodePreprocessCond cond = cast(CodePreprocessCond, entry_iter);
|
CodePreprocessCond cond = cast(CodePreprocessCond, entry_iter);
|
||||||
if ( cond->Content.is_equal(cond_sig) )
|
if ( cond->Content.is_equal(cond_sig) )
|
||||||
{
|
{
|
||||||
//log_fmt("Preprocess cond found: %SC\n", cond->Content);
|
//log_fmt("Preprocess cond found: %S\n", cond->Content);
|
||||||
found = true;
|
found = true;
|
||||||
|
|
||||||
s32 depth = 1;
|
s32 depth = 0;
|
||||||
++ entry_iter;
|
for(b32 continue_for = true; continue_for && entry_iter != parsed_body.end(); ) switch (entry_iter->Type)
|
||||||
for(b32 continue_for = true; continue_for && entry_iter != parsed_body.end(); ) switch
|
{
|
||||||
(entry_iter->Type) {
|
|
||||||
case CT_Preprocess_If:
|
case CT_Preprocess_If:
|
||||||
case CT_Preprocess_IfDef:
|
case CT_Preprocess_IfDef:
|
||||||
case CT_Preprocess_IfNotDef:
|
case CT_Preprocess_IfNotDef:
|
||||||
@ -40,20 +51,18 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& par
|
|||||||
|
|
||||||
case CT_Preprocess_Else:
|
case CT_Preprocess_Else:
|
||||||
++ entry_iter;
|
++ 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)
|
if ( entry_iter->Type == CT_Preprocess_EndIf)
|
||||||
{
|
|
||||||
continue_for = false;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
body.append(entry_iter);
|
body.append(entry_iter);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CT_Preprocess_EndIf:
|
case CT_Preprocess_EndIf:
|
||||||
{
|
{
|
||||||
depth --;
|
-- depth;
|
||||||
if (depth == 0) {
|
if (depth == 0) {
|
||||||
continue_for = false;
|
continue_for = false;
|
||||||
break;
|
break;
|
||||||
@ -72,7 +81,7 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& par
|
|||||||
|
|
||||||
constexpr bool GenericSel_One_Arg = true;
|
constexpr bool GenericSel_One_Arg = true;
|
||||||
enum GenericSelectionOpts : u32 { GenericSel_Default, GenericSel_By_Ref, GenericSel_Direct_Type };
|
enum GenericSelectionOpts : u32 { GenericSel_Default, GenericSel_By_Ref, GenericSel_Direct_Type };
|
||||||
Code gen_generic_selection_function_macro( s32 num_slots, StrC macro_name, GenericSelectionOpts opts = GenericSel_Default, bool one_arg = false )
|
Code gen_generic_selection_function_macro( s32 num_slots, Str macro_name, GenericSelectionOpts opts = GenericSel_Default, bool one_arg = false )
|
||||||
{
|
{
|
||||||
/* Implements:
|
/* Implements:
|
||||||
#define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg, ... ) _Generic( \
|
#define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg, ... ) _Generic( \
|
||||||
@ -84,18 +93,18 @@ Code gen_generic_selection_function_macro( s32 num_slots, StrC macro_name, Gener
|
|||||||
) GEN_RESOLVED_FUNCTION_CALL( selector_arg )
|
) GEN_RESOLVED_FUNCTION_CALL( selector_arg )
|
||||||
*/
|
*/
|
||||||
local_persist
|
local_persist
|
||||||
String define_builder = String::make_reserve(GlobalAllocator, kilobytes(64));
|
StrBuilder define_builder = StrBuilder::make_reserve(_ctx->Allocator_Temp, kilobytes(64));
|
||||||
define_builder.clear();
|
define_builder.clear();
|
||||||
|
|
||||||
StrC macro_begin;
|
Str macro_begin;
|
||||||
if (opts == GenericSel_Direct_Type) {
|
if (opts == GenericSel_Direct_Type) {
|
||||||
macro_begin = token_fmt( "macro_name", (StrC)macro_name,
|
macro_begin = token_fmt( "macro_name", (Str)macro_name,
|
||||||
R"(#define <macro_name>(selector_arg, ...) _Generic( (*(selector_arg*)NULL ), \
|
R"(#define <macro_name>(selector_arg, ...) _Generic( (*(selector_arg*)NULL ), \
|
||||||
)"
|
)"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
macro_begin = token_fmt( "macro_name", (StrC)macro_name,
|
macro_begin = token_fmt( "macro_name", (Str)macro_name,
|
||||||
R"(#define <macro_name>(selector_arg, ...) _Generic( (selector_arg), \
|
R"(#define <macro_name>(selector_arg, ...) _Generic( (selector_arg), \
|
||||||
)"
|
)"
|
||||||
);
|
);
|
||||||
@ -104,73 +113,56 @@ R"(#define <macro_name>(selector_arg, ...) _Generic( (selector_arg), \
|
|||||||
|
|
||||||
for ( s32 slot = 1; slot <= num_slots; ++ slot )
|
for ( s32 slot = 1; slot <= num_slots; ++ slot )
|
||||||
{
|
{
|
||||||
StrC slot_str = String::fmt_buf(GlobalAllocator, "%d", slot).to_strc();
|
Str slot_str = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "%d", slot).to_str();
|
||||||
if (slot == num_slots && false)
|
|
||||||
{
|
|
||||||
define_builder.append( token_fmt( "macro_name", macro_name, "slot", slot_str,
|
|
||||||
R"( GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT_LAST( GENERIC_SLOT_<slot>__<macro_name> ) \
|
|
||||||
)"
|
|
||||||
));
|
|
||||||
// if ( one_arg )
|
|
||||||
// define_builder.append(token_fmt( "macro_name", macro_name, stringize(
|
|
||||||
// default: static_assert(false, "<macro_name>: Failed to select correct function signature (Did you pass the type?)")
|
|
||||||
// )));
|
|
||||||
// else
|
|
||||||
// define_builder.append(token_fmt( "macro_name", macro_name, stringize(
|
|
||||||
// default: static_assert(false, "<macro_name>: Failed to select correct function signature")
|
|
||||||
// )));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
define_builder.append( token_fmt( "macro_name", macro_name, "slot", slot_str,
|
define_builder.append( token_fmt( "macro_name", macro_name, "slot", slot_str,
|
||||||
R"( GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_<slot>__<macro_name> ) \
|
R"(GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_<slot>__<macro_name> ) \
|
||||||
)"
|
)"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
define_builder.append( txt("default: gen_generic_selection_fail") );
|
define_builder.append( txt("default: gen_generic_selection_fail\\\n") );
|
||||||
|
|
||||||
if ( ! one_arg )
|
if ( ! one_arg )
|
||||||
{
|
{
|
||||||
if (opts == GenericSel_By_Ref)
|
if (opts == GenericSel_By_Ref)
|
||||||
define_builder.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( & selector_arg, __VA_ARGS__ )"));
|
define_builder.append(txt(")\\\nGEN_RESOLVED_FUNCTION_CALL( & selector_arg, __VA_ARGS__ )"));
|
||||||
else if (opts == GenericSel_Direct_Type)
|
else if (opts == GenericSel_Direct_Type)
|
||||||
define_builder.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( __VA_ARGS__ )"));
|
define_builder.append(txt(")\\\nGEN_RESOLVED_FUNCTION_CALL( __VA_ARGS__ )"));
|
||||||
else
|
else
|
||||||
define_builder.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( selector_arg, __VA_ARGS__ )"));
|
define_builder.append(txt(")\\\nGEN_RESOLVED_FUNCTION_CALL( selector_arg, __VA_ARGS__ )"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (opts == GenericSel_By_Ref)
|
if (opts == GenericSel_By_Ref)
|
||||||
define_builder.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( & selector_arg )"));
|
define_builder.append(txt(")\\\nGEN_RESOLVED_FUNCTION_CALL( & selector_arg )"));
|
||||||
else if (opts == GenericSel_Direct_Type)
|
else if (opts == GenericSel_Direct_Type)
|
||||||
define_builder.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL()"));
|
define_builder.append(txt(")\\\nGEN_RESOLVED_FUNCTION_CALL()"));
|
||||||
else
|
else
|
||||||
define_builder.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( selector_arg )"));
|
define_builder.append(txt(")\\\nGEN_RESOLVED_FUNCTION_CALL( selector_arg )"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add gap for next definition
|
// Add gap for next definition
|
||||||
define_builder.append(txt("\n\n"));
|
define_builder.append(txt("\n\n"));
|
||||||
|
|
||||||
Code macro = untyped_str(define_builder.to_strc());
|
Code macro = untyped_str(define_builder.to_str());
|
||||||
return macro;
|
return macro;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt(""))
|
CodeFn rename_function_to_unique_symbol(CodeFn fn, Str optional_prefix = txt(""))
|
||||||
{
|
{
|
||||||
// Get basic components for the name
|
// Get basic components for the name
|
||||||
StrC old_name = fn->Name;
|
Str old_name = fn->Name;
|
||||||
String new_name;
|
StrBuilder new_name;
|
||||||
|
|
||||||
// Add prefix if provided
|
// Add prefix if provided
|
||||||
if (optional_prefix.Len)
|
if (optional_prefix.Len)
|
||||||
new_name = string_fmt_buf(GlobalAllocator, "%SC_%SC_", optional_prefix, old_name);
|
new_name = strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S_%S_", optional_prefix, old_name);
|
||||||
else
|
else
|
||||||
new_name = string_fmt_buf(GlobalAllocator, "%SC_", old_name);
|
new_name = strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S_", old_name);
|
||||||
|
|
||||||
// Add return type to the signature
|
// Add return type to the signature
|
||||||
if (fn->ReturnType)
|
if (fn->ReturnType)
|
||||||
new_name.append_fmt("_%SC", fn->ReturnType->Name);
|
new_name.append_fmt("_%S", fn->ReturnType->Name);
|
||||||
|
|
||||||
// Add parameter types to create a unique signature
|
// Add parameter types to create a unique signature
|
||||||
bool first_param = true;
|
bool first_param = true;
|
||||||
@ -198,11 +190,11 @@ CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt(""
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_name.append_fmt("%SC_", spec_to_str(spec));
|
new_name.append_fmt("%S_", spec_to_str(spec));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new_name.append_fmt("%SC", param->ValueType->Name);
|
new_name.append_fmt("%S", param->ValueType->Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,7 +206,7 @@ CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt(""
|
|||||||
spec != end(fn->Specs);
|
spec != end(fn->Specs);
|
||||||
++spec)
|
++spec)
|
||||||
{
|
{
|
||||||
new_name.append_fmt("%SC_", spec_to_str(*spec));
|
new_name.append_fmt("%S_", spec_to_str(*spec));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,13 +215,13 @@ CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt(""
|
|||||||
}
|
}
|
||||||
|
|
||||||
using SwapContentProc = CodeBody(void);
|
using SwapContentProc = CodeBody(void);
|
||||||
bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body )
|
bool swap_pragma_region_implementation( Str region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body )
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
CodePragma possible_region = cast(CodePragma, entry_iter);
|
CodePragma possible_region = cast(CodePragma, entry_iter);
|
||||||
|
|
||||||
String region_sig = string_fmt_buf(GlobalAllocator, "region %s", region_name.Ptr);
|
StrBuilder region_sig = strbuilder_fmt_buf(_ctx->Allocator_Temp, "region %s", region_name.Ptr);
|
||||||
String endregion_sig = string_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr);
|
StrBuilder endregion_sig = strbuilder_fmt_buf(_ctx->Allocator_Temp, "endregion %s", region_name.Ptr);
|
||||||
if ( possible_region->Content.contains(region_sig))
|
if ( possible_region->Content.contains(region_sig))
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
#define GEN_IMPLEMENTATION
|
|
||||||
#include "gen/gen.c"
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
// init();
|
|
||||||
__debugbreak();
|
|
||||||
}
|
|
6
gen_c_library/gen_c_lib.c
Normal file
6
gen_c_library/gen_c_lib.c
Normal file
@ -0,0 +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)
|
* [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`.
|
The principal (user) files are `gen.hpp` and `gen.cpp`.
|
||||||
They contain includes for its various components: `components/<component_name>.<hpp/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.
|
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:
|
If using the library's provided build scripts:
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||||
#define GEN_EXPOSE_BACKEND
|
|
||||||
#define GEN_C_LIKE_CPP 1
|
#define GEN_C_LIKE_CPP 1
|
||||||
#include "gen.cpp"
|
#include "gen.cpp"
|
||||||
#include "helpers/push_ignores.inline.hpp"
|
#include "helpers/push_ignores.inline.hpp"
|
||||||
@ -32,7 +31,10 @@ Code format( Code code ) {
|
|||||||
|
|
||||||
int gen_main()
|
int gen_main()
|
||||||
{
|
{
|
||||||
gen::init();
|
Context ctx {
|
||||||
|
|
||||||
|
};
|
||||||
|
gen::init(& ctx);
|
||||||
|
|
||||||
Code push_ignores = scan_file( (path_base "helpers/push_ignores.inline.hpp") );
|
Code push_ignores = scan_file( (path_base "helpers/push_ignores.inline.hpp") );
|
||||||
Code pop_ignores = scan_file( (path_base "helpers/pop_ignores.inline.hpp") );
|
Code pop_ignores = scan_file( (path_base "helpers/pop_ignores.inline.hpp") );
|
||||||
@ -112,28 +114,30 @@ int gen_main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
CodeBody gen_component_header = def_global_body( args(
|
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,
|
pragma_once,
|
||||||
def_include(txt("components/types.hpp")),
|
def_include(txt("components/types.hpp")),
|
||||||
preprocess_endif,
|
preprocess_endif,
|
||||||
fmt_newline,
|
fmt_newline,
|
||||||
untyped_str( to_strc_from_c_str(generation_notice) )
|
untyped_str( to_str_from_c_str(generation_notice) )
|
||||||
));
|
));
|
||||||
|
|
||||||
// gen.hpp
|
// gen.hpp
|
||||||
{
|
{
|
||||||
Code header_start = scan_file( path_base "components/header_start.hpp" );
|
Code header_start = scan_file( path_base "components/header_start.hpp" );
|
||||||
Code types = scan_file( path_base "components/types.hpp" );
|
Code types = scan_file( path_base "components/types.hpp" );
|
||||||
|
Code parser_types = scan_file( path_base "components/parser_types.hpp" );
|
||||||
Code ast = scan_file( path_base "components/ast.hpp" );
|
Code ast = scan_file( path_base "components/ast.hpp" );
|
||||||
Code ast_types = scan_file( path_base "components/ast_types.hpp" );
|
Code ast_types = scan_file( path_base "components/ast_types.hpp" );
|
||||||
Code code_types = scan_file( path_base "components/code_types.hpp" );
|
Code code_types = scan_file( path_base "components/code_types.hpp" );
|
||||||
Code interface = scan_file( path_base "components/interface.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 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 ecode = gen_ecode ( path_base "enums/ECodeTypes.csv" );
|
||||||
CodeBody eoperator = gen_eoperator ( path_base "enums/EOperator.csv" );
|
CodeBody eoperator = gen_eoperator ( path_base "enums/EOperator.csv" );
|
||||||
CodeBody especifier = gen_especifier( path_base "enums/ESpecifier.csv" );
|
CodeBody especifier = gen_especifier( path_base "enums/ESpecifier.csv" );
|
||||||
|
CodeBody etoktype = gen_etoktype ( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv" );
|
||||||
CodeBody ast_inlines = gen_ast_inlines();
|
CodeBody ast_inlines = gen_ast_inlines();
|
||||||
|
|
||||||
Builder _header = builder_open( "gen/gen.hpp" );
|
Builder _header = builder_open( "gen/gen.hpp" );
|
||||||
@ -153,6 +157,8 @@ int gen_main()
|
|||||||
builder_print( header, fmt_newline);
|
builder_print( header, fmt_newline);
|
||||||
builder_print( header, format(especifier) );
|
builder_print( header, format(especifier) );
|
||||||
builder_print( header, fmt_newline);
|
builder_print( header, fmt_newline);
|
||||||
|
builder_print( header, format(etoktype));
|
||||||
|
builder_print( header, parser_types);
|
||||||
builder_print_fmt( header, "#pragma endregion Types\n\n" );
|
builder_print_fmt( header, "#pragma endregion Types\n\n" );
|
||||||
|
|
||||||
builder_print_fmt( header, "#pragma region AST\n" );
|
builder_print_fmt( header, "#pragma region AST\n" );
|
||||||
@ -162,6 +168,7 @@ int gen_main()
|
|||||||
builder_print_fmt( header, "\n#pragma endregion AST\n" );
|
builder_print_fmt( header, "\n#pragma endregion AST\n" );
|
||||||
|
|
||||||
builder_print( header, interface );
|
builder_print( header, interface );
|
||||||
|
builder_print( header, constants );
|
||||||
|
|
||||||
builder_print_fmt( header, "\n#pragma region Inlines\n" );
|
builder_print_fmt( header, "\n#pragma region Inlines\n" );
|
||||||
builder_print( header, inlines );
|
builder_print( header, inlines );
|
||||||
@ -170,8 +177,7 @@ int gen_main()
|
|||||||
builder_print( header, fmt_newline );
|
builder_print( header, fmt_newline );
|
||||||
builder_print_fmt( header, "#pragma endregion Inlines\n" );
|
builder_print_fmt( header, "#pragma endregion Inlines\n" );
|
||||||
|
|
||||||
builder_print( header, header_end );
|
builder_print_fmt( header, "\nGEN_NS_END\n\n" );
|
||||||
builder_print_fmt( header, "GEN_NS_END\n\n" );
|
|
||||||
builder_print( header, pop_ignores );
|
builder_print( header, pop_ignores );
|
||||||
builder_write(header);
|
builder_write(header);
|
||||||
}
|
}
|
||||||
@ -186,16 +192,11 @@ int gen_main()
|
|||||||
Code interface = scan_file( path_base "components/interface.cpp" );
|
Code interface = scan_file( path_base "components/interface.cpp" );
|
||||||
Code upfront = scan_file( path_base "components/interface.upfront.cpp" );
|
Code upfront = scan_file( path_base "components/interface.upfront.cpp" );
|
||||||
Code lexer = scan_file( path_base "components/lexer.cpp" );
|
Code lexer = scan_file( path_base "components/lexer.cpp" );
|
||||||
|
Code parser_case_macros = scan_file( path_base "components/parser_case_macros.cpp" );
|
||||||
Code parser = scan_file( path_base "components/parser.cpp" );
|
Code parser = scan_file( path_base "components/parser.cpp" );
|
||||||
Code parsing_interface = scan_file( path_base "components/interface.parsing.cpp" );
|
Code parsing_interface = scan_file( path_base "components/interface.parsing.cpp" );
|
||||||
Code untyped = scan_file( path_base "components/interface.untyped.cpp" );
|
Code untyped = scan_file( path_base "components/interface.untyped.cpp" );
|
||||||
|
|
||||||
CodeBody etoktype = gen_etoktype( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv" );
|
|
||||||
CodeBody nspaced_etoktype = def_global_body( args(
|
|
||||||
etoktype
|
|
||||||
));
|
|
||||||
Code formatted_toktype = format(nspaced_etoktype);
|
|
||||||
|
|
||||||
Builder _src = builder_open( "gen/gen.cpp" );
|
Builder _src = builder_open( "gen/gen.cpp" );
|
||||||
Builder* src = & _src;
|
Builder* src = & _src;
|
||||||
builder_print_fmt( src, generation_notice );
|
builder_print_fmt( src, generation_notice );
|
||||||
@ -215,8 +216,8 @@ int gen_main()
|
|||||||
builder_print( src, interface );
|
builder_print( src, interface );
|
||||||
builder_print( src, upfront );
|
builder_print( src, upfront );
|
||||||
builder_print_fmt( src, "\n#pragma region Parsing\n\n" );
|
builder_print_fmt( src, "\n#pragma region Parsing\n\n" );
|
||||||
builder_print( src, formatted_toktype );
|
|
||||||
builder_print( src, lexer );
|
builder_print( src, lexer );
|
||||||
|
builder_print( src, parser_case_macros );
|
||||||
builder_print( src, parser );
|
builder_print( src, parser );
|
||||||
builder_print( src, parsing_interface );
|
builder_print( src, parsing_interface );
|
||||||
builder_print_fmt( src, "\n#pragma endregion Parsing\n\n" );
|
builder_print_fmt( src, "\n#pragma endregion Parsing\n\n" );
|
||||||
@ -230,7 +231,7 @@ int gen_main()
|
|||||||
|
|
||||||
// gen_builder.hpp
|
// 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 header = builder_open( "gen/gen.builder.hpp" );
|
||||||
builder_print_fmt( & header, generation_notice );
|
builder_print_fmt( & header, generation_notice );
|
||||||
@ -238,13 +239,13 @@ int gen_main()
|
|||||||
builder_print( & header, def_include( txt("gen.hpp") ));
|
builder_print( & header, def_include( txt("gen.hpp") ));
|
||||||
builder_print_fmt( & header, "\nGEN_NS_BEGIN\n" );
|
builder_print_fmt( & header, "\nGEN_NS_BEGIN\n" );
|
||||||
builder_print( & header, builder );
|
builder_print( & header, builder );
|
||||||
builder_print_fmt( & header, "GEN_NS_END\n" );
|
builder_print_fmt( & header, "\nGEN_NS_END\n" );
|
||||||
builder_write( & header);
|
builder_write( & header);
|
||||||
}
|
}
|
||||||
|
|
||||||
// gen_builder.cpp
|
// 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 src = builder_open( "gen/gen.builder.cpp" );
|
||||||
builder_print_fmt( & src, generation_notice );
|
builder_print_fmt( & src, generation_notice );
|
||||||
@ -257,7 +258,7 @@ int gen_main()
|
|||||||
|
|
||||||
// gen_scanner.hpp
|
// 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 header = builder_open( "gen/gen.scanner.hpp" );
|
||||||
builder_print_fmt( & header, generation_notice );
|
builder_print_fmt( & header, generation_notice );
|
||||||
@ -271,17 +272,17 @@ int gen_main()
|
|||||||
|
|
||||||
// gen_scanner.cpp
|
// 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 src = builder_open( "gen/gen.scanner.cpp" );
|
||||||
builder_print_fmt( & src, generation_notice );
|
builder_print_fmt( & src, generation_notice );
|
||||||
builder_print( & src, def_include( txt("gen.scanner.hpp") ) );
|
builder_print( & src, def_include( txt("gen.scanner.hpp") ) );
|
||||||
builder_print_fmt( & src, "\nGEN_NS_BEGIN\n" );
|
builder_print_fmt( & src, "\nGEN_NS_BEGIN\n" );
|
||||||
builder_print( & src, scanner );
|
builder_print( & src, scanner );
|
||||||
builder_print_fmt( & src, "GEN_NS_END\n" );
|
builder_print_fmt( & src, "\nGEN_NS_END\n" );
|
||||||
builder_write( & src);
|
builder_write( & src);
|
||||||
}
|
}
|
||||||
|
|
||||||
gen::deinit();
|
gen::deinit( & ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
|
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
|
||||||
| Singleheader | | | | __} | |
|
| Singleheader | | | | __} | |
|
||||||
| l_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 |
|
! 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 |
|
! 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_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||||
#define GEN_EXPOSE_BACKEND
|
|
||||||
#include "gen.cpp"
|
#include "gen.cpp"
|
||||||
#include "helpers/push_ignores.inline.hpp"
|
#include "helpers/push_ignores.inline.hpp"
|
||||||
|
|
||||||
@ -17,24 +16,24 @@ constexpr char const* generation_notice =
|
|||||||
"// This file was generated automatially by gencpp's singleheader.cpp"
|
"// This file was generated automatially by gencpp's singleheader.cpp"
|
||||||
"(See: https://github.com/Ed94/gencpp)\n\n";
|
"(See: https://github.com/Ed94/gencpp)\n\n";
|
||||||
|
|
||||||
constexpr StrC implementation_guard_start = txt(R"(
|
constexpr Str implementation_guard_start = txt(R"(
|
||||||
#pragma region GENCPP IMPLEMENTATION GUARD
|
#pragma region GENCPP IMPLEMENTATION GUARD
|
||||||
#if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED)
|
#if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED)
|
||||||
# define GEN_IMPLEMENTED
|
# define GEN_IMPLEMENTED
|
||||||
)");
|
)");
|
||||||
|
|
||||||
constexpr StrC implementation_guard_end = txt(R"(
|
constexpr Str implementation_guard_end = txt(R"(
|
||||||
#endif
|
#endif
|
||||||
#pragma endregion GENCPP IMPLEMENTATION GUARD
|
#pragma endregion GENCPP IMPLEMENTATION GUARD
|
||||||
)");
|
)");
|
||||||
|
|
||||||
constexpr StrC roll_own_dependencies_guard_start = txt(R"(
|
constexpr Str roll_own_dependencies_guard_start = txt(R"(
|
||||||
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
|
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
|
||||||
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
|
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
|
||||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
||||||
)");
|
)");
|
||||||
|
|
||||||
constexpr StrC roll_own_dependencies_guard_end = txt(R"(
|
constexpr Str roll_own_dependencies_guard_end = txt(R"(
|
||||||
// GEN_ROLL_OWN_DEPENDENCIES
|
// GEN_ROLL_OWN_DEPENDENCIES
|
||||||
#endif
|
#endif
|
||||||
)");
|
)");
|
||||||
@ -54,7 +53,8 @@ Code format( Code code ) {
|
|||||||
|
|
||||||
int gen_main()
|
int gen_main()
|
||||||
{
|
{
|
||||||
gen::init();
|
Context ctx {};
|
||||||
|
gen::init( & ctx);
|
||||||
|
|
||||||
Code push_ignores = scan_file( path_base "helpers/push_ignores.inline.hpp" );
|
Code push_ignores = scan_file( path_base "helpers/push_ignores.inline.hpp" );
|
||||||
Code pop_ignores = scan_file( path_base "helpers/pop_ignores.inline.hpp" );
|
Code pop_ignores = scan_file( path_base "helpers/pop_ignores.inline.hpp" );
|
||||||
@ -77,7 +77,7 @@ int gen_main()
|
|||||||
Code basic_types = scan_file( path_base "dependencies/basic_types.hpp" );
|
Code basic_types = scan_file( path_base "dependencies/basic_types.hpp" );
|
||||||
Code debug = scan_file( path_base "dependencies/debug.hpp" );
|
Code debug = scan_file( path_base "dependencies/debug.hpp" );
|
||||||
Code memory = scan_file( path_base "dependencies/memory.hpp" );
|
Code memory = scan_file( path_base "dependencies/memory.hpp" );
|
||||||
Code string_ops = scan_file( path_base "dependencies/string_ops.hpp" );
|
Code stirng_ops = scan_file( path_base "dependencies/string_ops.hpp" );
|
||||||
Code printing = scan_file( path_base "dependencies/printing.hpp" );
|
Code printing = scan_file( path_base "dependencies/printing.hpp" );
|
||||||
Code containers = scan_file( path_base "dependencies/containers.hpp" );
|
Code containers = scan_file( path_base "dependencies/containers.hpp" );
|
||||||
Code hashing = scan_file( path_base "dependencies/hashing.hpp" );
|
Code hashing = scan_file( path_base "dependencies/hashing.hpp" );
|
||||||
@ -93,7 +93,7 @@ int gen_main()
|
|||||||
header.print( basic_types );
|
header.print( basic_types );
|
||||||
header.print( debug );
|
header.print( debug );
|
||||||
header.print( memory );
|
header.print( memory );
|
||||||
header.print( string_ops );
|
header.print( stirng_ops );
|
||||||
header.print( printing );
|
header.print( printing );
|
||||||
header.print( containers );
|
header.print( containers );
|
||||||
header.print( hashing );
|
header.print( hashing );
|
||||||
@ -105,22 +105,25 @@ int gen_main()
|
|||||||
header.print( scan_file( path_base "dependencies/parsing.hpp" ) );
|
header.print( scan_file( path_base "dependencies/parsing.hpp" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header.print(fmt_newline);
|
||||||
header.print_fmt( "GEN_NS_END\n" );
|
header.print_fmt( "GEN_NS_END\n" );
|
||||||
header.print_fmt( roll_own_dependencies_guard_end );
|
header.print_fmt( roll_own_dependencies_guard_end );
|
||||||
header.print( fmt_newline );
|
header.print( fmt_newline );
|
||||||
}
|
}
|
||||||
|
|
||||||
Code types = scan_file( path_base "components/types.hpp" );
|
Code types = scan_file( path_base "components/types.hpp" );
|
||||||
Code ast = scan_file( path_base "components/ast.hpp" );
|
Code parser_types = scan_file( path_base "components/parser_types.hpp");
|
||||||
Code ast_types = scan_file( path_base "components/ast_types.hpp" );
|
Code ast = scan_file( path_base "components/ast.hpp" );
|
||||||
Code code_types = scan_file( path_base "components/code_types.hpp" );
|
Code ast_types = scan_file( path_base "components/ast_types.hpp" );
|
||||||
Code interface = scan_file( path_base "components/interface.hpp" );
|
Code code_types = scan_file( path_base "components/code_types.hpp" );
|
||||||
Code inlines = scan_file( path_base "components/inlines.hpp" );
|
Code interface = scan_file( path_base "components/interface.hpp" );
|
||||||
Code header_end = scan_file( path_base "components/header_end.hpp" );
|
Code constants = scan_file( path_base "components/constants.hpp" );
|
||||||
|
Code inlines = scan_file( path_base "components/inlines.hpp" );
|
||||||
|
|
||||||
CodeBody ecode = gen_ecode ( path_base "enums/ECodeTypes.csv" );
|
CodeBody ecode = gen_ecode ( path_base "enums/ECodeTypes.csv" );
|
||||||
CodeBody eoperator = gen_eoperator ( path_base "enums/EOperator.csv" );
|
CodeBody eoperator = gen_eoperator ( path_base "enums/EOperator.csv" );
|
||||||
CodeBody especifier = gen_especifier( path_base "enums/ESpecifier.csv" );
|
CodeBody especifier = gen_especifier( path_base "enums/ESpecifier.csv" );
|
||||||
|
CodeBody etoktype = gen_etoktype ( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv" );
|
||||||
CodeBody ast_inlines = gen_ast_inlines();
|
CodeBody ast_inlines = gen_ast_inlines();
|
||||||
|
|
||||||
header.print_fmt( "GEN_NS_BEGIN\n\n" );
|
header.print_fmt( "GEN_NS_BEGIN\n\n" );
|
||||||
@ -134,6 +137,9 @@ int gen_main()
|
|||||||
header.print( fmt_newline );
|
header.print( fmt_newline );
|
||||||
header.print( format( especifier ));
|
header.print( format( especifier ));
|
||||||
header.print( fmt_newline );
|
header.print( fmt_newline );
|
||||||
|
header.print( format( etoktype ));
|
||||||
|
header.print( parser_types );
|
||||||
|
header.print( fmt_newline );
|
||||||
header.print_fmt("#pragma endregion Types\n\n");
|
header.print_fmt("#pragma endregion Types\n\n");
|
||||||
|
|
||||||
header.print_fmt("#pragma region AST\n");
|
header.print_fmt("#pragma region AST\n");
|
||||||
@ -143,6 +149,7 @@ int gen_main()
|
|||||||
header.print_fmt("\n#pragma endregion AST\n");
|
header.print_fmt("\n#pragma endregion AST\n");
|
||||||
|
|
||||||
header.print( interface );
|
header.print( interface );
|
||||||
|
header.print( constants );
|
||||||
|
|
||||||
header.print_fmt( "\n#pragma region Inlines\n" );
|
header.print_fmt( "\n#pragma region Inlines\n" );
|
||||||
header.print( inlines );
|
header.print( inlines );
|
||||||
@ -150,12 +157,14 @@ int gen_main()
|
|||||||
header.print( fmt_newline );
|
header.print( fmt_newline );
|
||||||
header.print_fmt( "#pragma endregion Inlines\n" );
|
header.print_fmt( "#pragma endregion Inlines\n" );
|
||||||
|
|
||||||
header.print( header_end );
|
|
||||||
|
|
||||||
if ( generate_builder ) {
|
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 "auxiliary/scanner.hpp" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header.print(fmt_newline);
|
||||||
header.print_fmt( "GEN_NS_END\n" );
|
header.print_fmt( "GEN_NS_END\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,9 +185,10 @@ int gen_main()
|
|||||||
Code timing = scan_file( path_base "dependencies/timing.cpp" );
|
Code timing = scan_file( path_base "dependencies/timing.cpp" );
|
||||||
|
|
||||||
header.print_fmt( roll_own_dependencies_guard_start );
|
header.print_fmt( roll_own_dependencies_guard_start );
|
||||||
header.print_fmt( "GEN_NS_BEGIN\n\n");
|
|
||||||
|
|
||||||
header.print( impl_start );
|
header.print( impl_start );
|
||||||
|
header.print( fmt_newline );
|
||||||
|
header.print_fmt( "GEN_NS_BEGIN\n");
|
||||||
|
|
||||||
header.print( debug );
|
header.print( debug );
|
||||||
header.print( string_ops );
|
header.print( string_ops );
|
||||||
header.print( printing );
|
header.print( printing );
|
||||||
@ -198,22 +208,21 @@ int gen_main()
|
|||||||
header.print_fmt( roll_own_dependencies_guard_end );
|
header.print_fmt( roll_own_dependencies_guard_end );
|
||||||
}
|
}
|
||||||
|
|
||||||
Code static_data = scan_file( path_base "components/static_data.cpp" );
|
Code static_data = scan_file( path_base "components/static_data.cpp" );
|
||||||
Code ast_case_macros = scan_file( path_base "components/ast_case_macros.cpp" );
|
Code ast_case_macros = scan_file( path_base "components/ast_case_macros.cpp" );
|
||||||
Code ast = scan_file( path_base "components/ast.cpp" );
|
Code ast = scan_file( path_base "components/ast.cpp" );
|
||||||
Code code = scan_file( path_base "components/code_serialization.cpp" );
|
Code code = scan_file( path_base "components/code_serialization.cpp" );
|
||||||
Code interface = scan_file( path_base "components/interface.cpp" );
|
Code interface = scan_file( path_base "components/interface.cpp" );
|
||||||
Code upfront = scan_file( path_base "components/interface.upfront.cpp" );
|
Code upfront = scan_file( path_base "components/interface.upfront.cpp" );
|
||||||
Code lexer = scan_file( path_base "components/lexer.cpp" );
|
Code lexer = scan_file( path_base "components/lexer.cpp" );
|
||||||
Code parser = scan_file( path_base "components/parser.cpp" );
|
Code parser_case_macros = scan_file( path_base "components/parser_case_macros.cpp" );
|
||||||
Code parsing_interface = scan_file( path_base "components/interface.parsing.cpp" );
|
Code parser = scan_file( path_base "components/parser.cpp" );
|
||||||
Code untyped = scan_file( path_base "components/interface.untyped.cpp" );
|
Code parsing_interface = scan_file( path_base "components/interface.parsing.cpp" );
|
||||||
|
Code untyped = scan_file( path_base "components/interface.untyped.cpp" );
|
||||||
CodeBody etoktype = gen_etoktype( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv" );
|
|
||||||
CodeNS parser_nspace = def_namespace( name(parser), def_namespace_body( args(etoktype)) );
|
|
||||||
|
|
||||||
header.print_fmt( "\nGEN_NS_BEGIN\n");
|
header.print_fmt( "\nGEN_NS_BEGIN\n");
|
||||||
header.print( static_data );
|
header.print( static_data );
|
||||||
|
header.print( fmt_newline);
|
||||||
|
|
||||||
header.print_fmt( "#pragma region AST\n\n" );
|
header.print_fmt( "#pragma region AST\n\n" );
|
||||||
header.print( ast_case_macros );
|
header.print( ast_case_macros );
|
||||||
@ -225,27 +234,25 @@ int gen_main()
|
|||||||
header.print( interface );
|
header.print( interface );
|
||||||
header.print( upfront );
|
header.print( upfront );
|
||||||
header.print_fmt( "\n#pragma region Parsing\n\n" );
|
header.print_fmt( "\n#pragma region Parsing\n\n" );
|
||||||
header.print( format(parser_nspace) );
|
|
||||||
header.print( lexer );
|
header.print( lexer );
|
||||||
|
header.print( parser_case_macros );
|
||||||
header.print( parser );
|
header.print( parser );
|
||||||
header.print( parsing_interface );
|
header.print( parsing_interface );
|
||||||
header.print_fmt( "\n#pragma endregion Parsing\n" );
|
header.print_fmt( "\n#pragma endregion Parsing\n" );
|
||||||
|
header.print_fmt("\n#pragma region Untyped\n");
|
||||||
header.print( untyped );
|
header.print( untyped );
|
||||||
header.print_fmt( "\n#pragma endregion Interface\n\n");
|
header.print_fmt("\n#pragma endregion Untyped\n");
|
||||||
|
header.print_fmt( "\n#pragma endregion Interface\n");
|
||||||
|
|
||||||
if ( generate_builder ) {
|
if ( generate_builder ) {
|
||||||
header.print( scan_file( path_base "auxillary/builder.cpp" ) );
|
header.print( scan_file( path_base "auxiliary/builder.cpp" ) );
|
||||||
}
|
|
||||||
|
|
||||||
// Scanner header depends on implementation
|
|
||||||
if ( generate_scanner ) {
|
|
||||||
header.print( scan_file( path_base "auxillary/scanner.hpp" ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( generate_scanner ) {
|
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);
|
||||||
header.print_fmt( "GEN_NS_END\n");
|
header.print_fmt( "GEN_NS_END\n");
|
||||||
|
|
||||||
header.print_fmt( "%s\n", (char const*) implementation_guard_end );
|
header.print_fmt( "%s\n", (char const*) implementation_guard_end );
|
||||||
@ -254,6 +261,6 @@ int gen_main()
|
|||||||
header.print( pop_ignores );
|
header.print( pop_ignores );
|
||||||
header.write();
|
header.write();
|
||||||
|
|
||||||
gen::deinit();
|
gen::deinit( & ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -15,3 +15,20 @@ If using the library's provided build scripts:
|
|||||||
```ps1
|
```ps1
|
||||||
.\build.ps1 <compiler> <debug or omit> unreal
|
.\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.
|
||||||
|
@ -7,12 +7,20 @@
|
|||||||
https://github.com/Ed94/gencpp
|
https://github.com/Ed94/gencpp
|
||||||
|
|
||||||
This is a variant intended for use with Unreal Engine 5
|
This is a variant intended for use with Unreal Engine 5
|
||||||
|
https://github.com/Ed94/gencpp --------------------------------------------------------------.
|
||||||
! ----------------------------------------------------------------------- VERSION: v0.20-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 !
|
| | |{_ |/ _ \ '_ \ / __} '_ l| '_ l `\___ \| __/ _` |/ _` |/ _ \/ _` | |
|
||||||
! ============================================================================================ !
|
| | l__j | ___/ | | | {__; |+l } |+l | ____) | l| (_| | {_| | ___/ (_| | |
|
||||||
|
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
|
||||||
|
| Unreal Engine | | | | __} | |
|
||||||
|
| l_l l_l {___/ |
|
||||||
|
! ----------------------------------------------------------------------- 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 |
|
||||||
|
! ============================================================================================ /
|
||||||
*/
|
*/
|
||||||
#if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME)
|
#if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME)
|
||||||
# error Gen.hpp : GEN_TIME not defined
|
# error Gen.hpp : GEN_TIME not defined
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user