inkcpp_rb 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +1 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +84 -0
- data/LICENSE +7 -0
- data/README.md +3 -0
- data/Rakefile +16 -0
- data/bin/console +15 -0
- data/bin/setup +10 -0
- data/bin/tapioca +29 -0
- data/ext/inkcpp_rb/extconf.rb +19 -0
- data/ext/inkcpp_rb/inkcpp/.clang-format +99 -0
- data/ext/inkcpp_rb/inkcpp/.github/FUNDING.yml +1 -0
- data/ext/inkcpp_rb/inkcpp/.github/workflows/build.yml +344 -0
- data/ext/inkcpp_rb/inkcpp/.github/workflows/release.yml +49 -0
- data/ext/inkcpp_rb/inkcpp/.gitignore +25 -0
- data/ext/inkcpp_rb/inkcpp/.gitmodules +9 -0
- data/ext/inkcpp_rb/inkcpp/CMakeLists.txt +170 -0
- data/ext/inkcpp_rb/inkcpp/CODE_OF_CONDUCT.md +76 -0
- data/ext/inkcpp_rb/inkcpp/CONTRIBUTING.md +55 -0
- data/ext/inkcpp_rb/inkcpp/Config.cmake.in +2 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/CMakeLists.txt +13 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/main.c +38 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/main.cpp +40 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/test.ink +8 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example/test.ink.json +1 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/cmake_example.zip +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/InkCPP_DEMO.zip +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/CreateThread.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/HandleChoice.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/ListElementOf.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/MinimalRuntime.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/MinimalThread.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/ObseverChange.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/TagListGetValue.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Documentation/unreal/imgs/YieldResume.png +0 -0
- data/ext/inkcpp_rb/inkcpp/Doxyfile +2825 -0
- data/ext/inkcpp_rb/inkcpp/LICENSE.txt +22 -0
- data/ext/inkcpp_rb/inkcpp/Minimal.runsettings +8 -0
- data/ext/inkcpp_rb/inkcpp/README.md +192 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/CMakeLists.txt +67 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/array.h +481 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/avl_array.h +833 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/casting.h +93 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/choice.cpp +54 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/collections/restorable.cpp +124 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/collections/restorable.h +406 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/container_operations.cpp +52 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/container_operations.h +34 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/executioner.h +179 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/functional.cpp +86 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/functions.cpp +54 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/functions.h +40 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/globals_impl.cpp +289 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/globals_impl.h +149 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/header.cpp +44 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/choice.h +106 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/functional.h +327 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/globals.h +196 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/list.h +187 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/runner.h +291 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/snapshot.h +61 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/story.h +219 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/story_ptr.h +233 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/traits.h +270 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/include/types.h +169 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/list_impl.cpp +79 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/list_impl.h +39 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/list_operations.cpp +276 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/list_operations.h +356 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/list_table.cpp +841 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/list_table.h +450 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/numeric_operations.cpp +40 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/numeric_operations.h +529 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/operation_bases.h +164 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/operations.h +100 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/output.cpp +528 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/output.h +153 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/platform.h +22 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/random.h +38 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/runner_impl.cpp +1396 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/runner_impl.h +336 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/simple_restorable_stack.h +335 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/snapshot_impl.cpp +182 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/snapshot_impl.h +91 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/snapshot_interface.h +57 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/stack.cpp +618 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/stack.h +243 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/story_impl.cpp +361 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/story_impl.h +92 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/story_ptr.cpp +75 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/string_operations.cpp +125 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/string_operations.h +67 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/string_table.cpp +149 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/string_table.h +47 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/string_utils.h +207 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/system.cpp +39 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/tuple.hpp +151 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/value.cpp +279 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp/value.h +666 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/CMakeLists.txt +62 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/include/inkcpp.h +393 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/inkcpp.cpp +344 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/inkcpp_c.pc.in +10 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/ExternalFunction.c +56 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Globals.c +98 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Lists.c +73 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Observer.c +36 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_c/tests/Snapshot.c +65 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_cl/CMakeLists.txt +49 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_cl/inkcpp_cl.cpp +215 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_cl/test.cpp +209 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_cl/test.h +8 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/CMakeLists.txt +37 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_emitter.cpp +446 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_emitter.h +70 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_stream.cpp +166 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/binary_stream.h +79 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/command.cpp +107 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/compiler.cpp +96 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/emitter.cpp +62 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/emitter.h +104 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/include/compilation_results.h +22 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/include/compiler.h +44 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/json.hpp +24596 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/json_compiler.cpp +411 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/json_compiler.h +62 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/list_data.cpp +47 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/list_data.h +70 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/reporter.cpp +107 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_compiler/reporter.h +55 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/CMakeLists.txt +19 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/example.py +78 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/src/module.cpp +317 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/conftest.py +53 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_ExternalFunctions.py +35 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Globals.py +40 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Lists.py +43 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Observer.py +27 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/tests/test_Snapshot.py +57 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_py/unreal_example.ink +71 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Array.cpp +115 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/CMakeLists.txt +117 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Callstack.cpp +392 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/EmptyStringForDivert.cpp +36 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ExternalFunctionsExecuteProperly.cpp +34 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/FallbackFunction.cpp +77 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Globals.cpp +73 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/InkyJson.cpp +34 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/LabelCondition.cpp +60 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Lists.cpp +144 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/LookaheadSafe.cpp +46 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Main.cpp +7 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/MoveTo.cpp +95 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/NewLines.cpp +76 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/NoEarlyTags.cpp +33 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Observer.cpp +245 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Pointer.cpp +191 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Restorable.cpp +294 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/SpaceAfterBracketChoice.cpp +45 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Stack.cpp +224 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Tags.cpp +131 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ThirdTierChoiceAfterBrackets.cpp +38 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/UTF8.cpp +56 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/Value.cpp +210 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/catch.hpp +17970 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/AHF.ink +7 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ChoiceBracketStory.ink +7 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/EmptyStringForDivert.ink +13 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ExternalFunctionsExecuteProperly.ink +11 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/FallBack.ink +15 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/GlobalStory.ink +9 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/LabelConditionStory.ink +5 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/LinesStory.ink +42 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ListLogicStory.ink +40 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ListStory.ink +8 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/LookaheadSafe.ink +14 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/MoveTo.ink +36 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/NoEarlyTags.ink +19 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ObserverStory.ink +8 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/SimpleStoryFlow.ink +65 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/TagsStory.ink +22 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/TheIntercept.ink +1686 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/ThirdTierChoiceAfterBracketsStory.ink +13 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/UTF-8-demo.txt +212 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/UTF8Story.ink +218 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/simple-1.1.1-inklecate.json +154 -0
- data/ext/inkcpp_rb/inkcpp/inkcpp_test/ink/simple-1.1.1-inky.json +160 -0
- data/ext/inkcpp_rb/inkcpp/notes/ArchitectureNotes.md +54 -0
- data/ext/inkcpp_rb/inkcpp/notes/ListNotes.md +69 -0
- data/ext/inkcpp_rb/inkcpp/notes/OperationNotes.md +35 -0
- data/ext/inkcpp_rb/inkcpp/notes/TagsNotes.md +24 -0
- data/ext/inkcpp_rb/inkcpp/notes/WhitespaceNotes.md +28 -0
- data/ext/inkcpp_rb/inkcpp/proofing/README.md +3 -0
- data/ext/inkcpp_rb/inkcpp/proofing/inkcpp_runtime_driver +12 -0
- data/ext/inkcpp_rb/inkcpp/pyproject.toml +63 -0
- data/ext/inkcpp_rb/inkcpp/setup.py +166 -0
- data/ext/inkcpp_rb/inkcpp/shared/CMakeLists.txt +14 -0
- data/ext/inkcpp_rb/inkcpp/shared/private/command.h +172 -0
- data/ext/inkcpp_rb/inkcpp/shared/private/header.h +46 -0
- data/ext/inkcpp_rb/inkcpp/shared/public/config.h +53 -0
- data/ext/inkcpp_rb/inkcpp/shared/public/system.h +307 -0
- data/ext/inkcpp_rb/inkcpp/shared/public/version.h +14 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestAllSequenceTypes.ink +59 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestArithmetic.ink +17 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestBasicStringLiterals.ink +8 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestBasicTunnel.ink +10 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestBlanksInInlineSequences.ink +51 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestCallStackEvaluation.ink +15 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestChoiceCount.ink +15 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestChoiceDivertsToDone.ink +6 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestChoiceWithBracketsOnly.ink +9 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestCompareDivertTargets.ink +26 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestComplexTunnels.ink +22 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestConditionalChoiceInWeave.ink +19 -0
- data/ext/inkcpp_rb/inkcpp/tests/TestTunnelOnwardsAfterTunnel.ink +17 -0
- data/ext/inkcpp_rb/inkcpp/unreal/CMakeLists.txt +51 -0
- data/ext/inkcpp_rb/inkcpp/unreal/UE_example.ink +92 -0
- data/ext/inkcpp_rb/inkcpp/unreal/blueprint_filter.js +377 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Resources/Icon128.png +0 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkAsset.cpp +47 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkChoice.cpp +40 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkList.cpp +86 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkRuntime.cpp +265 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkThread.cpp +239 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/InkVar.cpp +143 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/TagList.cpp +95 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Private/inkcpp.cpp +13 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkAsset.h +50 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkChoice.h +58 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkDelegates.h +139 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkList.h +102 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkRuntime.h +177 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkSnapshot.h +30 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkThread.h +215 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/InkVar.h +245 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/TagList.h +77 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/Public/inkcpp.h +217 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp/inkcpp.Build.cs +62 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/InkAssetFactory.cpp +237 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/InkAssetFactory.h +43 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/inkcpp_editor.cpp +13 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Private/inklecate_cmd.cpp.in +24 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/Public/inkcpp_editor.h +9 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/Source/inkcpp_editor/inkcpp_editor.Build.cs +61 -0
- data/ext/inkcpp_rb/inkcpp/unreal/inkcpp/inkcpp.uplugin +44 -0
- data/ext/inkcpp_rb/inkcpp/unreal/render.css +1 -0
- data/ext/inkcpp_rb/inkcpp_rb.cpp +321 -0
- data/inkcpp_rb.gemspec +54 -0
- data/rbi/inkcpp_rb.rbi +211 -0
- data/sorbet/config +4 -0
- data/sorbet/rbi/annotations/.gitattributes +1 -0
- data/sorbet/rbi/annotations/minitest.rbi +119 -0
- data/sorbet/rbi/gems/.gitattributes +1 -0
- data/sorbet/rbi/gems/benchmark@0.4.0.rbi +618 -0
- data/sorbet/rbi/gems/erubi@1.13.1.rbi +155 -0
- data/sorbet/rbi/gems/minitest@5.25.4.rbi +1547 -0
- data/sorbet/rbi/gems/netrc@0.11.0.rbi +159 -0
- data/sorbet/rbi/gems/parallel@1.26.3.rbi +291 -0
- data/sorbet/rbi/gems/prism@1.3.0.rbi +40040 -0
- data/sorbet/rbi/gems/rake-compiler@1.2.8.rbi +9 -0
- data/sorbet/rbi/gems/rake@13.2.1.rbi +3033 -0
- data/sorbet/rbi/gems/rbi@0.2.2.rbi +4527 -0
- data/sorbet/rbi/gems/rice@4.3.3.rbi +44 -0
- data/sorbet/rbi/gems/spoom@1.5.0.rbi +4932 -0
- data/sorbet/rbi/gems/tapioca@0.16.7.rbi +3611 -0
- data/sorbet/rbi/gems/thor@1.3.2.rbi +4378 -0
- data/sorbet/rbi/gems/yard-sorbet@0.9.0.rbi +435 -0
- data/sorbet/rbi/gems/yard@0.9.37.rbi +18379 -0
- data/sorbet/tapioca/config.yml +13 -0
- data/sorbet/tapioca/require.rb +4 -0
- metadata +400 -0
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
/* Copyright (c) 2024 Julian Benda
|
|
2
|
+
*
|
|
3
|
+
* This file is part of inkCPP which is released under MIT license.
|
|
4
|
+
* See file LICENSE.txt or go to
|
|
5
|
+
* https://github.com/JBenda/inkcpp for full license details.
|
|
6
|
+
*/
|
|
7
|
+
#include "binary_emitter.h"
|
|
8
|
+
|
|
9
|
+
#include "header.h"
|
|
10
|
+
#include "version.h"
|
|
11
|
+
#include "list_data.h"
|
|
12
|
+
|
|
13
|
+
#include <vector>
|
|
14
|
+
#include <map>
|
|
15
|
+
#include <fstream>
|
|
16
|
+
|
|
17
|
+
#ifndef WIN32
|
|
18
|
+
# include <cstring>
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
namespace ink::compiler::internal
|
|
22
|
+
{
|
|
23
|
+
using std::vector;
|
|
24
|
+
using std::map;
|
|
25
|
+
using std::string;
|
|
26
|
+
|
|
27
|
+
char* strtok_s(char* s, const char* sep, char** context)
|
|
28
|
+
{
|
|
29
|
+
#if defined(_WIN32) || defined(_WIN64)
|
|
30
|
+
return ::strtok_s(s, sep, context);
|
|
31
|
+
#else
|
|
32
|
+
if (context == nullptr || sep == nullptr || (s == nullptr && *context == nullptr)) {
|
|
33
|
+
errno = EINVAL;
|
|
34
|
+
return nullptr;
|
|
35
|
+
}
|
|
36
|
+
return ::strtok_r(s, sep, context);
|
|
37
|
+
#endif
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// holds information about a container
|
|
41
|
+
struct container_data {
|
|
42
|
+
// child containers
|
|
43
|
+
vector<container_data*> children;
|
|
44
|
+
|
|
45
|
+
// children names (not all containers have names)
|
|
46
|
+
map<string, container_data*> named_children;
|
|
47
|
+
|
|
48
|
+
// Indexes of child containers (index is child index of parent)
|
|
49
|
+
map<int, container_data*> indexed_children;
|
|
50
|
+
|
|
51
|
+
// Offsets of noop operations
|
|
52
|
+
map<int, uint32_t> noop_offsets;
|
|
53
|
+
|
|
54
|
+
// parent pointer
|
|
55
|
+
container_data* parent = nullptr;
|
|
56
|
+
|
|
57
|
+
// Offset in the binary stream
|
|
58
|
+
uint32_t offset = 0;
|
|
59
|
+
uint32_t end_offset = 0;
|
|
60
|
+
|
|
61
|
+
// Index used in CNT? operations
|
|
62
|
+
container_t counter_index = ~0;
|
|
63
|
+
|
|
64
|
+
~container_data()
|
|
65
|
+
{
|
|
66
|
+
// Destroy children
|
|
67
|
+
for (auto child : children)
|
|
68
|
+
delete child;
|
|
69
|
+
|
|
70
|
+
// Clear lists
|
|
71
|
+
children.clear();
|
|
72
|
+
// named_children.clear();
|
|
73
|
+
// indexed_children.clear();
|
|
74
|
+
// noop_offsets.clear();
|
|
75
|
+
parent = nullptr;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
binary_emitter::binary_emitter()
|
|
80
|
+
: _root(nullptr)
|
|
81
|
+
{
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
binary_emitter::~binary_emitter()
|
|
85
|
+
{
|
|
86
|
+
if (_root != nullptr)
|
|
87
|
+
delete _root;
|
|
88
|
+
_root = nullptr;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
uint32_t binary_emitter::start_container(int index_in_parent, const std::string& name)
|
|
92
|
+
{
|
|
93
|
+
// Create new container metadata
|
|
94
|
+
auto container = new container_data();
|
|
95
|
+
|
|
96
|
+
// Store root
|
|
97
|
+
if (_root == nullptr)
|
|
98
|
+
_root = container;
|
|
99
|
+
|
|
100
|
+
// Parent it to the current container
|
|
101
|
+
container->parent = _current;
|
|
102
|
+
|
|
103
|
+
// Set offset to the current position
|
|
104
|
+
container->offset = _containers.pos();
|
|
105
|
+
|
|
106
|
+
// Add to parents lists
|
|
107
|
+
if (_current != nullptr) {
|
|
108
|
+
_current->children.push_back(container);
|
|
109
|
+
_current->indexed_children.insert({index_in_parent, container});
|
|
110
|
+
|
|
111
|
+
if (! name.empty()) {
|
|
112
|
+
_current->named_children.insert({name, container});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Set this as the current pointer
|
|
117
|
+
_current = container;
|
|
118
|
+
|
|
119
|
+
// Return current position
|
|
120
|
+
return _containers.pos();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
uint32_t binary_emitter::end_container()
|
|
124
|
+
{
|
|
125
|
+
// Move up the chain
|
|
126
|
+
_current->end_offset = _containers.pos();
|
|
127
|
+
_current = _current->parent;
|
|
128
|
+
|
|
129
|
+
// Return offset
|
|
130
|
+
return _containers.pos();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
int binary_emitter::function_container_arguments(const std::string& name)
|
|
134
|
+
{
|
|
135
|
+
if (_root == nullptr) {
|
|
136
|
+
return -1;
|
|
137
|
+
}
|
|
138
|
+
auto fn = _root->named_children.find(name);
|
|
139
|
+
if (fn == _root->named_children.end()) {
|
|
140
|
+
return -1;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
size_t offset = fn->second->offset;
|
|
144
|
+
byte_t cmd = _containers.get(offset);
|
|
145
|
+
int arity = 0;
|
|
146
|
+
while (static_cast<Command>(cmd) == Command::DEFINE_TEMP) {
|
|
147
|
+
offset += 6; // command(1) + flag(1) + variable_name_hash(4)
|
|
148
|
+
cmd = _containers.get(offset);
|
|
149
|
+
++arity;
|
|
150
|
+
}
|
|
151
|
+
return arity;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
void binary_emitter::write_raw(
|
|
155
|
+
Command command, CommandFlag flag, const char* payload, ink::size_t payload_size
|
|
156
|
+
)
|
|
157
|
+
{
|
|
158
|
+
_containers.write(command);
|
|
159
|
+
_containers.write(flag);
|
|
160
|
+
if (payload_size > 0)
|
|
161
|
+
_containers.write(( const byte_t* ) payload, payload_size);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
void binary_emitter::write_path(
|
|
165
|
+
Command command, CommandFlag flag, const std::string& path, bool useCountIndex
|
|
166
|
+
)
|
|
167
|
+
{
|
|
168
|
+
// Write blank command with 0 payload
|
|
169
|
+
write(command, ( uint32_t ) 0, flag);
|
|
170
|
+
|
|
171
|
+
// Note the position of this later so we can resolve the paths at the end
|
|
172
|
+
size_t param_position = _containers.pos() - sizeof(uint32_t);
|
|
173
|
+
bool op = flag & CommandFlag::FALLBACK_FUNCTION;
|
|
174
|
+
_paths.push_back(std::make_tuple(param_position, path, op, _current, useCountIndex));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
void binary_emitter::write_variable(Command command, CommandFlag flag, const std::string& name)
|
|
178
|
+
{
|
|
179
|
+
// Use hash as identifier
|
|
180
|
+
uint32_t hash = hash_string(name.c_str());
|
|
181
|
+
|
|
182
|
+
// Write it out
|
|
183
|
+
write(command, hash, flag);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
void binary_emitter::write_string(Command command, CommandFlag flag, const std::string& string)
|
|
187
|
+
{
|
|
188
|
+
// Save current position in table
|
|
189
|
+
uint32_t pos = _strings.pos();
|
|
190
|
+
|
|
191
|
+
// Write string to table (omit ^ if it begins with one)
|
|
192
|
+
if (string.length() > 0 && string[0] == '^')
|
|
193
|
+
_strings.write(string.substr(1));
|
|
194
|
+
else
|
|
195
|
+
_strings.write(string);
|
|
196
|
+
|
|
197
|
+
// Written position is what we write out in our command
|
|
198
|
+
write(command, pos, flag);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
void binary_emitter::write_list(
|
|
202
|
+
Command command, CommandFlag flag, const std::vector<list_flag>& entries
|
|
203
|
+
)
|
|
204
|
+
{
|
|
205
|
+
uint32_t id = _list_count++;
|
|
206
|
+
for (const list_flag& entry : entries) {
|
|
207
|
+
_lists.write(entry);
|
|
208
|
+
}
|
|
209
|
+
_lists.write(null_flag);
|
|
210
|
+
write(command, id, flag);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
void binary_emitter::handle_nop(int index_in_parent)
|
|
214
|
+
{
|
|
215
|
+
_current->noop_offsets.insert({index_in_parent, _containers.pos()});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
void binary_emitter::output(std::ostream& out)
|
|
219
|
+
{
|
|
220
|
+
// Write the ink version
|
|
221
|
+
// TODO: define this order in header?
|
|
222
|
+
using header = ink::internal::header;
|
|
223
|
+
header::endian_types same = header::endian_types::same;
|
|
224
|
+
out.write(( const char* ) &same, sizeof(decltype(same)));
|
|
225
|
+
out.write(( const char* ) &_ink_version, sizeof(decltype(_ink_version)));
|
|
226
|
+
out.write(( const char* ) &ink::InkBinVersion, sizeof(decltype(ink::InkBinVersion)));
|
|
227
|
+
|
|
228
|
+
// Write the string table
|
|
229
|
+
_strings.write_to(out);
|
|
230
|
+
|
|
231
|
+
// Write a separator
|
|
232
|
+
out << ( char ) 0;
|
|
233
|
+
|
|
234
|
+
// Write lists meta data and defined lists
|
|
235
|
+
_lists.write_to(out);
|
|
236
|
+
// Write a seperator
|
|
237
|
+
out.write(reinterpret_cast<const char*>(&null_flag), sizeof(null_flag));
|
|
238
|
+
|
|
239
|
+
// Write out container map
|
|
240
|
+
write_container_map(out, _container_map, _max_container_index);
|
|
241
|
+
|
|
242
|
+
// Write a separator
|
|
243
|
+
uint32_t END_MARKER = ~0;
|
|
244
|
+
out.write(( const char* ) &END_MARKER, sizeof(uint32_t));
|
|
245
|
+
|
|
246
|
+
// Write container hash list
|
|
247
|
+
write_container_hash_map(out);
|
|
248
|
+
out.write(( const char* ) &END_MARKER, sizeof(uint32_t));
|
|
249
|
+
|
|
250
|
+
// Write the container data
|
|
251
|
+
_containers.write_to(out);
|
|
252
|
+
|
|
253
|
+
// Flush the file
|
|
254
|
+
out.flush();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
void binary_emitter::initialize()
|
|
258
|
+
{
|
|
259
|
+
// Reset binary data stores
|
|
260
|
+
_strings.reset();
|
|
261
|
+
_list_count = 0;
|
|
262
|
+
_lists.reset();
|
|
263
|
+
_containers.reset();
|
|
264
|
+
|
|
265
|
+
// clear other data
|
|
266
|
+
_paths.clear();
|
|
267
|
+
|
|
268
|
+
if (_root != nullptr)
|
|
269
|
+
delete _root;
|
|
270
|
+
|
|
271
|
+
_current = nullptr;
|
|
272
|
+
_root = nullptr;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
void binary_emitter::finalize()
|
|
276
|
+
{
|
|
277
|
+
// post process path commands
|
|
278
|
+
process_paths();
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
void binary_emitter::setContainerIndex(container_t index) { _current->counter_index = index; }
|
|
282
|
+
|
|
283
|
+
uint32_t binary_emitter::fallthrough_divert()
|
|
284
|
+
{
|
|
285
|
+
// write a fallthrough divert ???
|
|
286
|
+
write<uint32_t>(Command::DIVERT, ( uint32_t ) 0, CommandFlag::DIVERT_IS_FALLTHROUGH);
|
|
287
|
+
|
|
288
|
+
// Return the location of the divert offset
|
|
289
|
+
return _containers.pos() - sizeof(uint32_t);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
void binary_emitter::patch_fallthroughs(uint32_t position)
|
|
293
|
+
{
|
|
294
|
+
// Patch
|
|
295
|
+
_containers.set(position, _containers.pos());
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
void binary_emitter::process_paths()
|
|
299
|
+
{
|
|
300
|
+
for (auto pair : _paths) {
|
|
301
|
+
// We need to replace the uint32_t at this location with the byte position of the requested
|
|
302
|
+
// container
|
|
303
|
+
using std::get;
|
|
304
|
+
size_t position = get<0>(pair);
|
|
305
|
+
const std::string& path = get<1>(pair);
|
|
306
|
+
bool optional = get<2>(pair);
|
|
307
|
+
container_data* context = get<3>(pair);
|
|
308
|
+
bool useCountIndex = get<4>(pair);
|
|
309
|
+
|
|
310
|
+
// Start at the root
|
|
311
|
+
container_data* container = _root;
|
|
312
|
+
|
|
313
|
+
// Unless it's a relative path
|
|
314
|
+
const char* path_cstr = path.c_str();
|
|
315
|
+
if (path_cstr[0] == '.') {
|
|
316
|
+
container = context;
|
|
317
|
+
path_cstr += 1;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
bool firstParent = true;
|
|
321
|
+
|
|
322
|
+
// We need to parse the path
|
|
323
|
+
offset_t noop_offset = ~0;
|
|
324
|
+
char* _context = nullptr;
|
|
325
|
+
const char* token
|
|
326
|
+
= ink::compiler::internal::strtok_s(const_cast<char*>(path_cstr), ".", &_context);
|
|
327
|
+
while (token != nullptr) {
|
|
328
|
+
// Number
|
|
329
|
+
// variable names can start with a number
|
|
330
|
+
bool isNumber = true;
|
|
331
|
+
for (const char* i = token; *i; ++i) {
|
|
332
|
+
if (! isdigit(*i)) {
|
|
333
|
+
isNumber = false;
|
|
334
|
+
break;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (isNumber) {
|
|
338
|
+
// Check if we have a nop registered at that index
|
|
339
|
+
int index = atoi(token);
|
|
340
|
+
auto nop_iter = container->noop_offsets.find(index);
|
|
341
|
+
if (nop_iter != container->noop_offsets.end()) {
|
|
342
|
+
noop_offset = nop_iter->second;
|
|
343
|
+
break;
|
|
344
|
+
} else
|
|
345
|
+
container = container->indexed_children[index];
|
|
346
|
+
}
|
|
347
|
+
// Parent
|
|
348
|
+
else if (token[0] == '^') {
|
|
349
|
+
if (! firstParent)
|
|
350
|
+
container = container->parent;
|
|
351
|
+
}
|
|
352
|
+
// Named child
|
|
353
|
+
else {
|
|
354
|
+
auto itr = container->named_children.find(token);
|
|
355
|
+
container = itr == container->named_children.end() ? nullptr : itr->second;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
firstParent = false;
|
|
359
|
+
|
|
360
|
+
// Get the next token
|
|
361
|
+
token = ink::compiler::internal::strtok_s(nullptr, ".", &_context);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
if (noop_offset != ~0) {
|
|
365
|
+
inkAssert(! useCountIndex, "Can't count visits to a noop!");
|
|
366
|
+
_containers.set(position, noop_offset);
|
|
367
|
+
} else {
|
|
368
|
+
// If we want the count index, write that out
|
|
369
|
+
if (useCountIndex) {
|
|
370
|
+
inkAssert(container->counter_index != ~0, "No count index available for this container!");
|
|
371
|
+
_containers.set(position, container->counter_index);
|
|
372
|
+
} else {
|
|
373
|
+
// Otherwise, write container address
|
|
374
|
+
if (container == nullptr) {
|
|
375
|
+
_containers.set(position, 0);
|
|
376
|
+
inkAssert(optional, "Was not able to resolve a not optional path! '%hs'", path.c_str());
|
|
377
|
+
} else {
|
|
378
|
+
_containers.set(position, container->offset);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
void binary_emitter::write_container_map(
|
|
386
|
+
std::ostream& out, const container_map& map, container_t num
|
|
387
|
+
)
|
|
388
|
+
{
|
|
389
|
+
// Write out container count
|
|
390
|
+
out.write(reinterpret_cast<const char*>(&num), sizeof(container_t));
|
|
391
|
+
|
|
392
|
+
// Write out entries
|
|
393
|
+
for (const auto& pair : map) {
|
|
394
|
+
out.write(( const char* ) &pair.first, sizeof(uint32_t));
|
|
395
|
+
out.write(( const char* ) &pair.second, sizeof(uint32_t));
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
void binary_emitter::write_container_hash_map(std::ostream& out)
|
|
400
|
+
{
|
|
401
|
+
write_container_hash_map(out, "", _root);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
void binary_emitter::write_container_hash_map(
|
|
405
|
+
std::ostream& out, const std::string& name, const container_data* context
|
|
406
|
+
)
|
|
407
|
+
{
|
|
408
|
+
for (auto child : context->named_children) {
|
|
409
|
+
// Get the child's name in the hierarchy
|
|
410
|
+
std::string child_name = name.empty() ? child.first : (name + "." + child.first);
|
|
411
|
+
hash_t name_hash = hash_string(child_name.c_str());
|
|
412
|
+
// Write out name hash and offset
|
|
413
|
+
out.write(( const char* ) &name_hash, sizeof(hash_t));
|
|
414
|
+
out.write(( const char* ) &child.second->offset, sizeof(uint32_t));
|
|
415
|
+
|
|
416
|
+
// Recurse
|
|
417
|
+
write_container_hash_map(out, child_name, child.second);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
for (auto child : context->indexed_children) {
|
|
421
|
+
write_container_hash_map(out, name, child.second);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
void binary_emitter::set_list_meta(const list_data& list_defs)
|
|
426
|
+
{
|
|
427
|
+
if (list_defs.empty()) {
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
auto flags = list_defs.get_flags();
|
|
432
|
+
auto list_names = list_defs.get_list_names().begin();
|
|
433
|
+
int list_id = -1;
|
|
434
|
+
for (const auto& flag : flags) {
|
|
435
|
+
_lists.write(flag.flag);
|
|
436
|
+
if (flag.flag.list_id != list_id) {
|
|
437
|
+
list_id = flag.flag.list_id;
|
|
438
|
+
_lists.write(reinterpret_cast<const byte_t*>(list_names->data()), list_names->size());
|
|
439
|
+
++list_names;
|
|
440
|
+
_lists.write('\0');
|
|
441
|
+
}
|
|
442
|
+
_lists.write(reinterpret_cast<const byte_t*>(flag.name->c_str()), flag.name->size() + 1);
|
|
443
|
+
}
|
|
444
|
+
_lists.write(null_flag);
|
|
445
|
+
}
|
|
446
|
+
} // namespace ink::compiler::internal
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/* Copyright (c) 2024 Julian Benda
|
|
2
|
+
*
|
|
3
|
+
* This file is part of inkCPP which is released under MIT license.
|
|
4
|
+
* See file LICENSE.txt or go to
|
|
5
|
+
* https://github.com/JBenda/inkcpp for full license details.
|
|
6
|
+
*/
|
|
7
|
+
#pragma once
|
|
8
|
+
|
|
9
|
+
#include "emitter.h"
|
|
10
|
+
#include "binary_stream.h"
|
|
11
|
+
|
|
12
|
+
namespace ink::compiler::internal
|
|
13
|
+
{
|
|
14
|
+
struct container_data;
|
|
15
|
+
class list_data;
|
|
16
|
+
|
|
17
|
+
// binary emitter
|
|
18
|
+
class binary_emitter : public emitter
|
|
19
|
+
{
|
|
20
|
+
public:
|
|
21
|
+
binary_emitter();
|
|
22
|
+
virtual ~binary_emitter();
|
|
23
|
+
|
|
24
|
+
// Begin emitter
|
|
25
|
+
virtual uint32_t start_container(int index_in_parent, const std::string& name) override;
|
|
26
|
+
virtual uint32_t end_container() override;
|
|
27
|
+
virtual int function_container_arguments(const std::string& name) override;
|
|
28
|
+
virtual void write_raw(Command command, CommandFlag flag = CommandFlag::NO_FLAGS, const char* payload = nullptr, ink::size_t payload_size = 0) override;
|
|
29
|
+
virtual void write_path(Command command, CommandFlag flag, const std::string& path, bool useCountIndex = false) override;
|
|
30
|
+
virtual void write_variable(Command command, CommandFlag flag, const std::string& name) override;
|
|
31
|
+
virtual void write_string(Command command, CommandFlag flag, const std::string& string) override;
|
|
32
|
+
virtual void handle_nop(int index_in_parent) override;
|
|
33
|
+
virtual uint32_t fallthrough_divert() override;
|
|
34
|
+
virtual void patch_fallthroughs(uint32_t position) override;
|
|
35
|
+
virtual void set_list_meta(const list_data& list_defs) override;
|
|
36
|
+
virtual void write_list(Command command, CommandFlag flag, const std::vector<list_flag>& entries) override;
|
|
37
|
+
// End emitter
|
|
38
|
+
|
|
39
|
+
// write out the emitters data
|
|
40
|
+
virtual void output(std::ostream&);
|
|
41
|
+
|
|
42
|
+
protected:
|
|
43
|
+
virtual void initialize() override;
|
|
44
|
+
virtual void finalize() override;
|
|
45
|
+
virtual void setContainerIndex(container_t index) override;
|
|
46
|
+
|
|
47
|
+
private:
|
|
48
|
+
void process_paths();
|
|
49
|
+
void write_container_map(std::ostream&, const container_map&, container_t);
|
|
50
|
+
void write_container_hash_map(std::ostream&);
|
|
51
|
+
void write_container_hash_map(std::ostream&, const std::string&, const container_data*);
|
|
52
|
+
|
|
53
|
+
private:
|
|
54
|
+
container_data* _root;
|
|
55
|
+
container_data* _current;
|
|
56
|
+
compilation_results* _results;
|
|
57
|
+
|
|
58
|
+
binary_stream _strings;
|
|
59
|
+
uint32_t _list_count = 0;
|
|
60
|
+
binary_stream _lists;
|
|
61
|
+
binary_stream _containers;
|
|
62
|
+
|
|
63
|
+
// positon to write address
|
|
64
|
+
// path as string
|
|
65
|
+
// if path may not exists (used for function fallbackes)
|
|
66
|
+
// container data
|
|
67
|
+
// use count index?
|
|
68
|
+
std::vector<std::tuple<size_t, std::string, bool, container_data*, bool>> _paths;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/* Copyright (c) 2024 Julian Benda
|
|
2
|
+
*
|
|
3
|
+
* This file is part of inkCPP which is released under MIT license.
|
|
4
|
+
* See file LICENSE.txt or go to
|
|
5
|
+
* https://github.com/JBenda/inkcpp for full license details.
|
|
6
|
+
*/
|
|
7
|
+
#include "binary_stream.h"
|
|
8
|
+
|
|
9
|
+
#include <cstring>
|
|
10
|
+
|
|
11
|
+
namespace ink
|
|
12
|
+
{
|
|
13
|
+
namespace compiler
|
|
14
|
+
{
|
|
15
|
+
namespace internal
|
|
16
|
+
{
|
|
17
|
+
template<>
|
|
18
|
+
size_t binary_stream::write(const std::string& value)
|
|
19
|
+
{
|
|
20
|
+
constexpr byte_t ZERO = 0;
|
|
21
|
+
size_t len;
|
|
22
|
+
if(value.length()) {
|
|
23
|
+
len = write((const byte_t*)value.c_str(), value.length());
|
|
24
|
+
} else {
|
|
25
|
+
len = write(' ');
|
|
26
|
+
}
|
|
27
|
+
len += write(ZERO);
|
|
28
|
+
return len;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
binary_stream::binary_stream()
|
|
32
|
+
: _currentSlab(nullptr)
|
|
33
|
+
, _ptr(nullptr)
|
|
34
|
+
{ }
|
|
35
|
+
|
|
36
|
+
binary_stream::~binary_stream()
|
|
37
|
+
{
|
|
38
|
+
reset();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
size_t binary_stream::write(const byte_t* data, size_t len)
|
|
42
|
+
{
|
|
43
|
+
// Create first slab if none exist
|
|
44
|
+
if (_currentSlab == nullptr)
|
|
45
|
+
{
|
|
46
|
+
_currentSlab = new byte_t[DATA_SIZE];
|
|
47
|
+
_ptr = _currentSlab;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Check how much space we have left
|
|
51
|
+
size_t slab_remaining = _currentSlab + DATA_SIZE - _ptr;
|
|
52
|
+
|
|
53
|
+
// If we're out of space...
|
|
54
|
+
if (slab_remaining < len)
|
|
55
|
+
{
|
|
56
|
+
// Write what we can into the slab
|
|
57
|
+
memcpy(_ptr, data, slab_remaining);
|
|
58
|
+
|
|
59
|
+
// Create a new slab
|
|
60
|
+
_slabs.push_back(_currentSlab);
|
|
61
|
+
_currentSlab = new byte_t[DATA_SIZE];
|
|
62
|
+
_ptr = _currentSlab;
|
|
63
|
+
|
|
64
|
+
// Recurse
|
|
65
|
+
return slab_remaining + write(data + slab_remaining, len - slab_remaining);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// We have the space
|
|
69
|
+
memcpy(_ptr, data, len);
|
|
70
|
+
_ptr += len;
|
|
71
|
+
return len;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
void binary_stream::write_to(std::ostream& out) const
|
|
75
|
+
{
|
|
76
|
+
// Write previous slabs
|
|
77
|
+
for (byte_t* slab : _slabs)
|
|
78
|
+
{
|
|
79
|
+
out.write(reinterpret_cast<const char*>(slab), DATA_SIZE);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Write current slab (if it exists)
|
|
83
|
+
if (_currentSlab != nullptr && _ptr != _currentSlab)
|
|
84
|
+
{
|
|
85
|
+
out.write(reinterpret_cast<const char*>(_currentSlab), _ptr - _currentSlab);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
size_t binary_stream::pos() const
|
|
90
|
+
{
|
|
91
|
+
// If we have no data, we're at position 0
|
|
92
|
+
if (_currentSlab == nullptr)
|
|
93
|
+
return 0;
|
|
94
|
+
|
|
95
|
+
// Each slabs is size DATA_SIZE then add the position in the current slab
|
|
96
|
+
return _slabs.size() * DATA_SIZE + (_ptr - _currentSlab);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
void binary_stream::set(size_t offset, const byte_t* data, size_t len)
|
|
100
|
+
{
|
|
101
|
+
// Find slab for offset
|
|
102
|
+
unsigned int slab_index = offset / DATA_SIZE;
|
|
103
|
+
size_t pos = offset % DATA_SIZE;
|
|
104
|
+
|
|
105
|
+
// Get slab and ptr
|
|
106
|
+
byte_t* slab = nullptr;
|
|
107
|
+
if (slab_index < _slabs.size())
|
|
108
|
+
slab = _slabs[slab_index];
|
|
109
|
+
else if (slab_index == _slabs.size())
|
|
110
|
+
slab = _currentSlab;
|
|
111
|
+
|
|
112
|
+
if (slab == nullptr)
|
|
113
|
+
return; // TODO: Error?
|
|
114
|
+
|
|
115
|
+
byte_t* ptr = slab + pos;
|
|
116
|
+
|
|
117
|
+
// Check if data will fit into slab
|
|
118
|
+
if (pos + len > DATA_SIZE)
|
|
119
|
+
{
|
|
120
|
+
// Write only what we can fit
|
|
121
|
+
size_t new_length = DATA_SIZE - pos;
|
|
122
|
+
memcpy(ptr, data, new_length);
|
|
123
|
+
|
|
124
|
+
// Recurse
|
|
125
|
+
set(offset + new_length, data + new_length, len - new_length);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Otherwise write the whole data
|
|
130
|
+
memcpy(ptr, data, len);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
byte_t binary_stream::get(size_t offset) const
|
|
134
|
+
{
|
|
135
|
+
// Find slab for offset
|
|
136
|
+
unsigned int slab_index = offset / DATA_SIZE;
|
|
137
|
+
size_t pos = offset % DATA_SIZE;
|
|
138
|
+
|
|
139
|
+
// Get slab and ptr
|
|
140
|
+
byte_t* slab = nullptr;
|
|
141
|
+
if (slab_index < _slabs.size())
|
|
142
|
+
slab = _slabs[slab_index];
|
|
143
|
+
else if (slab_index == _slabs.size())
|
|
144
|
+
slab = _currentSlab;
|
|
145
|
+
|
|
146
|
+
inkAssert(slab != nullptr, "try to access invalid slab in binary stream");
|
|
147
|
+
return slab[pos];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
void binary_stream::reset()
|
|
151
|
+
{
|
|
152
|
+
// Delete all slabs
|
|
153
|
+
for (byte_t* slab : _slabs)
|
|
154
|
+
{
|
|
155
|
+
delete[] slab;
|
|
156
|
+
}
|
|
157
|
+
_slabs.clear();
|
|
158
|
+
|
|
159
|
+
// Delete active slab (if it exists)
|
|
160
|
+
if (_currentSlab != nullptr)
|
|
161
|
+
delete[] _currentSlab;
|
|
162
|
+
_currentSlab = _ptr = nullptr;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|