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,618 @@
|
|
|
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 "stack.h"
|
|
8
|
+
#include "string_table.h"
|
|
9
|
+
|
|
10
|
+
namespace ink::runtime::internal
|
|
11
|
+
{
|
|
12
|
+
basic_stack::basic_stack(entry* data, size_t size)
|
|
13
|
+
: base(data, size)
|
|
14
|
+
{
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
void basic_stack::set(hash_t name, const value& val)
|
|
18
|
+
{
|
|
19
|
+
// If we have a save point, always add no matter what
|
|
20
|
+
if (base::is_saved())
|
|
21
|
+
{
|
|
22
|
+
add(name, val);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Either set an existing variable or add it to the stack
|
|
27
|
+
value* existing = const_cast<value*>(get(name));
|
|
28
|
+
if (existing == nullptr)
|
|
29
|
+
add(name, val);
|
|
30
|
+
else
|
|
31
|
+
*existing = val;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
bool reverse_find_predicat(hash_t name, thread_t& skip, uint32_t& jumping, entry& e) {
|
|
35
|
+
// Jumping
|
|
36
|
+
if (jumping > 0) {
|
|
37
|
+
jumping--;
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// If this is an end thread marker, skip over it
|
|
42
|
+
if (skip == ~0 && e.data.type() == value_type::thread_end) {
|
|
43
|
+
skip = e.data.get<value_type::thread_end>();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// If we're skipping
|
|
47
|
+
if (skip != ~0) {
|
|
48
|
+
// Stop if we get to the start of the thread block
|
|
49
|
+
if (e.data.type() == value_type::thread_start && skip == e.data.get<value_type::thread_start>().jump) {
|
|
50
|
+
skip = ~0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Don't return anything in the hidden thread block
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Is it a thread start or a jump marker
|
|
58
|
+
if (e.name == InvalidHash && (e.data.type() == value_type::thread_start || e.data.type() == value_type::jump_marker))
|
|
59
|
+
{
|
|
60
|
+
// If this thread start has a jump value
|
|
61
|
+
uint32_t jump = e.data.get<value_type::jump_marker>().thread_id;
|
|
62
|
+
|
|
63
|
+
// Then we need to do some jumping. Skip
|
|
64
|
+
if (jump > 0) {
|
|
65
|
+
jumping = jump;
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return e.name == name || e.name == InvalidHash;
|
|
71
|
+
}
|
|
72
|
+
class reverse_find_predicat_operator {
|
|
73
|
+
public:
|
|
74
|
+
explicit reverse_find_predicat_operator(hash_t name) : _name{name} {}
|
|
75
|
+
bool operator()(entry& e) {
|
|
76
|
+
return reverse_find_predicat(_name, _skip, _jumping, e);
|
|
77
|
+
}
|
|
78
|
+
private:
|
|
79
|
+
hash_t _name;
|
|
80
|
+
thread_t _skip = ~0;
|
|
81
|
+
uint32_t _jumping = 0;
|
|
82
|
+
};
|
|
83
|
+
class reverse_find_from_frame_predicat_operator {
|
|
84
|
+
public:
|
|
85
|
+
reverse_find_from_frame_predicat_operator(int ci, hash_t name) : _ci{ci}, _name{name} {
|
|
86
|
+
inkAssert(ci == -1 || ci == 0, "only support ci == -1, for now!");
|
|
87
|
+
}
|
|
88
|
+
bool operator()(entry& e) {
|
|
89
|
+
if(reverse_find_predicat(_name, _skip, _jumping, e)) {
|
|
90
|
+
if(_ci == _current_frame) { return true; }
|
|
91
|
+
_current_frame -= 1;
|
|
92
|
+
}
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
private:
|
|
96
|
+
int _ci;
|
|
97
|
+
int _current_frame = 0;
|
|
98
|
+
hash_t _name;
|
|
99
|
+
thread_t _skip = ~0;
|
|
100
|
+
uint32_t _jumping = 0;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const value* basic_stack::get(hash_t name) const {
|
|
104
|
+
// Find whatever comes first: a matching entry or a stack frame entry
|
|
105
|
+
const entry* found = base::reverse_find(reverse_find_predicat_operator(name));
|
|
106
|
+
|
|
107
|
+
// If nothing found, no value
|
|
108
|
+
if (found == nullptr)
|
|
109
|
+
return nullptr;
|
|
110
|
+
|
|
111
|
+
// If we found something of that name, return the value
|
|
112
|
+
if (found->name == name)
|
|
113
|
+
return &found->data;
|
|
114
|
+
|
|
115
|
+
// Otherwise, nothing in this stack frame
|
|
116
|
+
return nullptr;
|
|
117
|
+
}
|
|
118
|
+
value* basic_stack::get(hash_t name) {
|
|
119
|
+
// Find whatever comes first: a matching entry or a stack frame entry
|
|
120
|
+
entry* found = base::reverse_find(reverse_find_predicat_operator(name));
|
|
121
|
+
|
|
122
|
+
// If nothing found, no value
|
|
123
|
+
if (found == nullptr)
|
|
124
|
+
return nullptr;
|
|
125
|
+
|
|
126
|
+
// If we found something of that name, return the value
|
|
127
|
+
if (found->name == name)
|
|
128
|
+
return &found->data;
|
|
129
|
+
|
|
130
|
+
// Otherwise, nothing in this stack frame
|
|
131
|
+
return nullptr;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
value* basic_stack::get_from_frame(int ci, hash_t name) {
|
|
135
|
+
entry* found = base::reverse_find(reverse_find_from_frame_predicat_operator(ci, name));
|
|
136
|
+
if(found == nullptr && ci == -1) {
|
|
137
|
+
found = base::reverse_find(reverse_find_from_frame_predicat_operator(0, name));
|
|
138
|
+
}
|
|
139
|
+
if(found == nullptr) { return nullptr; }
|
|
140
|
+
if(found->name == name) { return &found->data; }
|
|
141
|
+
return nullptr;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
template<>
|
|
145
|
+
void basic_stack::push_frame<frame_type::function>(offset_t return_to, bool eval)
|
|
146
|
+
{
|
|
147
|
+
add(InvalidHash, value{}.set<value_type::function_frame>(return_to, eval));
|
|
148
|
+
}
|
|
149
|
+
template<>
|
|
150
|
+
void basic_stack::push_frame<frame_type::tunnel>(offset_t return_to, bool eval)
|
|
151
|
+
{
|
|
152
|
+
add(InvalidHash, value{}.set<value_type::tunnel_frame>(return_to, eval));
|
|
153
|
+
}
|
|
154
|
+
template<>
|
|
155
|
+
void basic_stack::push_frame<frame_type::thread>(offset_t return_to, bool eval)
|
|
156
|
+
{
|
|
157
|
+
add(InvalidHash, value{}.set<value_type::thread_frame>(return_to, eval));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const entry* basic_stack::pop()
|
|
161
|
+
{
|
|
162
|
+
return &base::pop([](const entry& elem) { return elem.name == ~0; });
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
entry* basic_stack::do_thread_jump_pop(const basic_stack::iterator& jumpStart)
|
|
166
|
+
{
|
|
167
|
+
// Start an iterator right after the jumping marker (might be a thread_start or a jump_marker)
|
|
168
|
+
iterator threadIter = jumpStart;
|
|
169
|
+
|
|
170
|
+
// Get a reference to its jump count
|
|
171
|
+
value& start = threadIter.get()->data;
|
|
172
|
+
value_type vt = start.type();
|
|
173
|
+
auto jump = start.get<value_type::jump_marker>();
|
|
174
|
+
|
|
175
|
+
// Move over it
|
|
176
|
+
threadIter.next();
|
|
177
|
+
|
|
178
|
+
// Move back over the current jump value
|
|
179
|
+
for (uint32_t i = 0; i < jump.thread_id; i++)
|
|
180
|
+
threadIter.next();
|
|
181
|
+
|
|
182
|
+
// Now keep iterating back until we get to a frame marker
|
|
183
|
+
// FIXME: meta types or subtypes?
|
|
184
|
+
while (!threadIter.done() && (threadIter.get()->name != InvalidHash
|
|
185
|
+
|| threadIter.get()->data.type() == value_type::thread_start
|
|
186
|
+
|| threadIter.get()->data.type() == value_type::thread_end))
|
|
187
|
+
{
|
|
188
|
+
// If we've hit an end of thread marker
|
|
189
|
+
auto e = threadIter.get();
|
|
190
|
+
if (e->data.type() == value_type::thread_end)
|
|
191
|
+
{
|
|
192
|
+
// We basically want to skip until we get to the start of this thread (leave the block alone)
|
|
193
|
+
thread_t tid = e->data.get<value_type::thread_end>();
|
|
194
|
+
while (threadIter.get()->data.type() != value_type::thread_start
|
|
195
|
+
|| threadIter.get()->data.get<value_type::thread_start>().jump != tid)
|
|
196
|
+
{
|
|
197
|
+
jump.thread_id++;
|
|
198
|
+
threadIter.next();
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Now let us skip over the thread start
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
threadIter.next();
|
|
205
|
+
jump.thread_id++;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Move us over the frame marker
|
|
209
|
+
jump.thread_id++;
|
|
210
|
+
|
|
211
|
+
// Now that thread marker is set to the correct jump value.
|
|
212
|
+
if (vt == value_type::jump_marker) {
|
|
213
|
+
start.set<value_type::jump_marker>(jump);
|
|
214
|
+
} else if (vt == value_type::thread_start) {
|
|
215
|
+
start.set<value_type::thread_start>(jump);
|
|
216
|
+
} else {
|
|
217
|
+
inkFail("unknown jump type");
|
|
218
|
+
}
|
|
219
|
+
return threadIter.get();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
frame_type get_frame_type(value_type type)
|
|
223
|
+
{
|
|
224
|
+
switch (type)
|
|
225
|
+
{
|
|
226
|
+
case value_type::tunnel_frame:
|
|
227
|
+
return frame_type::tunnel;
|
|
228
|
+
case value_type::function_frame:
|
|
229
|
+
return frame_type::function;
|
|
230
|
+
case value_type::thread_frame:
|
|
231
|
+
return frame_type::thread;
|
|
232
|
+
default:
|
|
233
|
+
inkAssert(false, "Unknown frame type detected");
|
|
234
|
+
return (frame_type)-1;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
offset_t basic_stack::pop_frame(frame_type* type, bool& eval)
|
|
239
|
+
{
|
|
240
|
+
inkAssert(!base::is_empty(), "Can not pop frame from empty callstack.");
|
|
241
|
+
|
|
242
|
+
const entry* returnedFrame = nullptr;
|
|
243
|
+
auto isNull = [](const entry& e) { return e.name == ~0; };
|
|
244
|
+
|
|
245
|
+
// Start iterating backwards
|
|
246
|
+
iterator iter = base::begin();
|
|
247
|
+
if(isNull(*iter.get())) { iter.next(isNull); }
|
|
248
|
+
while (!iter.done())
|
|
249
|
+
{
|
|
250
|
+
// Keep popping if it's not a frame marker or thread marker of some kind
|
|
251
|
+
entry* frame = iter.get();
|
|
252
|
+
if (frame->name != InvalidHash)
|
|
253
|
+
{
|
|
254
|
+
pop();
|
|
255
|
+
iter = base::begin();
|
|
256
|
+
if(isNull(*iter.get())) { iter.next(isNull); }
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// We now have a frame marker. Check if it's a thread
|
|
261
|
+
// Thread handling
|
|
262
|
+
if (
|
|
263
|
+
// FIXME: is_tghead_marker, is_jump_marker
|
|
264
|
+
frame->data.type() == value_type::thread_start
|
|
265
|
+
|| frame->data.type() == value_type::thread_end
|
|
266
|
+
|| frame->data.type() == value_type::jump_marker
|
|
267
|
+
)
|
|
268
|
+
{
|
|
269
|
+
// End of thread marker, we need to create a jump marker
|
|
270
|
+
if (frame->data.type() == value_type::thread_end)
|
|
271
|
+
{
|
|
272
|
+
// Push a new jump marker after the thread end
|
|
273
|
+
entry& jump = push({ InvalidHash, value{}.set<value_type::jump_marker>(0u,0u) });
|
|
274
|
+
|
|
275
|
+
// Do a pop back
|
|
276
|
+
returnedFrame = do_thread_jump_pop(base::begin());
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// If this is a jump marker, we actually want to extend it to the next frame
|
|
281
|
+
if (frame->data.type() == value_type::jump_marker)
|
|
282
|
+
{
|
|
283
|
+
// Use the thread jump pop method using this jump marker
|
|
284
|
+
returnedFrame = do_thread_jump_pop(iter);
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Popping past thread start
|
|
289
|
+
if (frame->data.type() == value_type::thread_start)
|
|
290
|
+
{
|
|
291
|
+
returnedFrame = do_thread_jump_pop(iter);
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Otherwise, pop the frame marker off and return it
|
|
297
|
+
returnedFrame = pop();
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// If we didn't find a frame entry, we never had a frame to return from
|
|
302
|
+
inkAssert(returnedFrame, "Attempting to pop_frame when no frames exist! Stack reset.");
|
|
303
|
+
|
|
304
|
+
// Make sure we're not somehow trying to "return" from a thread
|
|
305
|
+
inkAssert(returnedFrame->data.type() != value_type::thread_start
|
|
306
|
+
&& returnedFrame->data.type() != value_type::thread_end,
|
|
307
|
+
"Can not return from a thread! How did this happen?");
|
|
308
|
+
|
|
309
|
+
// Store frame type
|
|
310
|
+
if (type != nullptr)
|
|
311
|
+
{
|
|
312
|
+
*type = get_frame_type(returnedFrame->data.type());
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Return the offset stored in the frame record
|
|
316
|
+
// FIXME: correct type?
|
|
317
|
+
const auto& frame = returnedFrame->data.get<value_type::function_frame>();
|
|
318
|
+
eval = frame.eval;
|
|
319
|
+
return frame.addr;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
bool basic_stack::has_frame(frame_type* returnType) const
|
|
323
|
+
{
|
|
324
|
+
// Empty case
|
|
325
|
+
if (base::is_empty())
|
|
326
|
+
return false;
|
|
327
|
+
|
|
328
|
+
uint32_t jumping = 0;
|
|
329
|
+
uint32_t thread = ~0;
|
|
330
|
+
// Search in reverse for a stack frame
|
|
331
|
+
const entry* frame = base::reverse_find([&jumping, &thread](const entry& elem) {
|
|
332
|
+
// If we're jumping over data, just keep returning false until we're done
|
|
333
|
+
if (jumping > 0) {
|
|
334
|
+
jumping--;
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// We only care about elements with InvalidHash
|
|
339
|
+
if (elem.name != InvalidHash)
|
|
340
|
+
return false;
|
|
341
|
+
|
|
342
|
+
// If we're skipping over a thread, wait until we hit its start before checking
|
|
343
|
+
if (thread != ~0) {
|
|
344
|
+
if (elem.data.type() == value_type::thread_start && elem.data.get<value_type::thread_start>().jump == thread)
|
|
345
|
+
thread = ~0;
|
|
346
|
+
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// If it's a jump marker or a thread start
|
|
351
|
+
if (elem.data.type() == value_type::jump_marker || elem.data.type() == value_type::thread_start) {
|
|
352
|
+
jumping = elem.data.get<value_type::jump_marker>().thread_id;
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// If it's a thread end, we need to skip to the matching thread start
|
|
357
|
+
if (elem.data.type() == value_type::thread_end) {
|
|
358
|
+
thread = elem.data.get<value_type::thread_end>();
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return elem.name == InvalidHash;
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
if (frame != nullptr && returnType != nullptr)
|
|
366
|
+
*returnType = get_frame_type(frame->data.type());
|
|
367
|
+
|
|
368
|
+
// Return true if a frame was found
|
|
369
|
+
return frame != nullptr;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
void basic_stack::clear()
|
|
373
|
+
{
|
|
374
|
+
base::clear();
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
void basic_stack::mark_used(string_table& strings, list_table& lists) const
|
|
378
|
+
{
|
|
379
|
+
// Mark all strings
|
|
380
|
+
base::for_each_all(
|
|
381
|
+
[&strings, &lists](const entry& elem) {
|
|
382
|
+
if (elem.data.type() == value_type::string) {
|
|
383
|
+
strings.mark_used(elem.data.get<value_type::string>());
|
|
384
|
+
} else if (elem.data.type() == value_type::list) {
|
|
385
|
+
lists.mark_used(elem.data.get<value_type::list>());
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
thread_t basic_stack::fork_thread()
|
|
391
|
+
{
|
|
392
|
+
// TODO create unique thread ID
|
|
393
|
+
thread_t new_thread = _next_thread++;
|
|
394
|
+
|
|
395
|
+
// Push a thread start marker here
|
|
396
|
+
entry& thread_entry = add(InvalidHash, value{}.set<value_type::thread_start>(new_thread, 0u));
|
|
397
|
+
|
|
398
|
+
// Set stack jump counter for thread to 0. This number is used if the thread ever
|
|
399
|
+
// tries to pop past its origin. It keeps track of how much of the preceeding stack it's popped back
|
|
400
|
+
|
|
401
|
+
return new_thread;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
void basic_stack::complete_thread(thread_t thread)
|
|
405
|
+
{
|
|
406
|
+
// Add a thread complete marker
|
|
407
|
+
add(InvalidHash, value{}.set<value_type::thread_end>(thread));
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
void basic_stack::collapse_to_thread(thread_t thread)
|
|
411
|
+
{
|
|
412
|
+
// Reset thread counter
|
|
413
|
+
_next_thread = 0;
|
|
414
|
+
|
|
415
|
+
// If we're restoring a specific thread (and not the main thread)
|
|
416
|
+
if (thread != ~0)
|
|
417
|
+
{
|
|
418
|
+
// Keep popping until we find the requested thread's end marker
|
|
419
|
+
const entry* top = pop();
|
|
420
|
+
while (!(
|
|
421
|
+
top->data.type() == value_type::thread_end &&
|
|
422
|
+
top->data.get<value_type::thread_end>() == thread))
|
|
423
|
+
{
|
|
424
|
+
inkAssert(!is_empty(), "Ran out of stack while searching for end of thread marker. Did you call complete_thread?");
|
|
425
|
+
top = pop();
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// Now, start iterating backwards
|
|
430
|
+
thread_t nulling = ~0;
|
|
431
|
+
uint32_t jumping = 0;
|
|
432
|
+
base::reverse_for_each([&nulling, &jumping](entry& elem) {
|
|
433
|
+
if (jumping > 0) {
|
|
434
|
+
// delete data
|
|
435
|
+
elem.name = NulledHashId;
|
|
436
|
+
|
|
437
|
+
// Move on
|
|
438
|
+
jumping--;
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// Thread end. We just need to delete this whole block
|
|
443
|
+
if (nulling == ~0 && elem.data.type() == value_type::thread_end && elem.name == InvalidHash) {
|
|
444
|
+
nulling = elem.data.get<value_type::thread_end>();
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// If we're deleting a useless thread block
|
|
448
|
+
if (nulling != ~0) {
|
|
449
|
+
// If this is the start of the block, stop deleting
|
|
450
|
+
if (elem.name == InvalidHash && elem.data.type() == value_type::thread_start && elem.data.get<value_type::thread_start>().jump == nulling) {
|
|
451
|
+
nulling = ~0;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// delete data
|
|
455
|
+
elem.name = NulledHashId;
|
|
456
|
+
}
|
|
457
|
+
else
|
|
458
|
+
{
|
|
459
|
+
// Clear thread start markers. We don't need or want them anymore
|
|
460
|
+
if (elem.name == InvalidHash &&
|
|
461
|
+
(elem.data.type() == value_type::thread_start || elem.data.type() == value_type::jump_marker)) {
|
|
462
|
+
// Clear it out
|
|
463
|
+
elem.name = NulledHashId;
|
|
464
|
+
|
|
465
|
+
// Check if this is a jump, if so we need to ignore even more data
|
|
466
|
+
jumping = elem.data.get<value_type::jump_marker>().thread_id;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// Clear thread frame markers. We can't use them anymore
|
|
470
|
+
if (elem.name == InvalidHash && elem.data.type() == value_type::thread_frame) {
|
|
471
|
+
elem.name = NulledHashId;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
}, [](entry& elem) { return elem.name == NulledHashId; });
|
|
476
|
+
|
|
477
|
+
// No more threads. Clear next thread counter
|
|
478
|
+
_next_thread = 0;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
void basic_stack::save()
|
|
482
|
+
{
|
|
483
|
+
base::save();
|
|
484
|
+
|
|
485
|
+
// Save thread counter
|
|
486
|
+
_backup_next_thread = _next_thread;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
void basic_stack::restore()
|
|
490
|
+
{
|
|
491
|
+
base::restore();
|
|
492
|
+
|
|
493
|
+
// Restore thread counter
|
|
494
|
+
_next_thread = _backup_next_thread;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
void basic_stack::forget()
|
|
498
|
+
{
|
|
499
|
+
base::forget([](entry& elem) { elem.name = ~0; });
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
entry& basic_stack::add(hash_t name, const value& val)
|
|
503
|
+
{
|
|
504
|
+
return base::push({ name, val });
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
basic_eval_stack::basic_eval_stack(value* data, size_t size)
|
|
508
|
+
: base(data, size)
|
|
509
|
+
{
|
|
510
|
+
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
void basic_eval_stack::push(const value& val)
|
|
514
|
+
{
|
|
515
|
+
base::push(val);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
value basic_eval_stack::pop()
|
|
519
|
+
{
|
|
520
|
+
return base::pop([](const value& v) { return v.type() == value_type::none; });
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
const value& basic_eval_stack::top() const
|
|
524
|
+
{
|
|
525
|
+
return base::top([](const value& v){ return false; });
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
const value& basic_eval_stack::top_value() const
|
|
529
|
+
{
|
|
530
|
+
return base::top([](const value& v){ return v.type() == value_type::none; });
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
bool basic_eval_stack::is_empty() const
|
|
534
|
+
{
|
|
535
|
+
return base::is_empty();
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
void basic_eval_stack::clear()
|
|
539
|
+
{
|
|
540
|
+
base::clear();
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
void basic_eval_stack::mark_used(string_table& strings, list_table& lists) const
|
|
544
|
+
{
|
|
545
|
+
// Iterate everything (including what we have saved) and mark strings
|
|
546
|
+
base::for_each_all([&strings,&lists](const value& elem) {
|
|
547
|
+
if (elem.type() == value_type::string) {
|
|
548
|
+
string_type str = elem.get<value_type::string>();
|
|
549
|
+
if (str.allocated) {
|
|
550
|
+
strings.mark_used(str.str);
|
|
551
|
+
}
|
|
552
|
+
} else if (elem.type() == value_type::list) {
|
|
553
|
+
lists.mark_used(elem.get<value_type::list>());
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
void basic_eval_stack::save()
|
|
559
|
+
{
|
|
560
|
+
base::save();
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
void basic_eval_stack::restore()
|
|
564
|
+
{
|
|
565
|
+
base::restore();
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
void basic_eval_stack::forget()
|
|
569
|
+
{
|
|
570
|
+
// Clear out
|
|
571
|
+
value x; x.set<value_type::none>();
|
|
572
|
+
value none = value(x);
|
|
573
|
+
base::forget([&none](value& elem) { elem = none; });
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
void basic_stack::fetch_values(basic_stack& stack) {
|
|
577
|
+
auto itr = base::begin();
|
|
578
|
+
auto predicat = [](entry& e)
|
|
579
|
+
{ return !(e.name == InvalidHash || e.data.type() == value_type::value_pointer); };
|
|
580
|
+
|
|
581
|
+
if(!itr.done() && predicat(*itr.get())) { itr.next(predicat); }
|
|
582
|
+
for(; !itr.done() && itr.get()->name != InvalidHash; itr.next(predicat)) {
|
|
583
|
+
auto [name, ci] = itr.get()->data.get<value_type::value_pointer>();
|
|
584
|
+
inkAssert(ci != 0, "Global refs should not exists on ref stack!");
|
|
585
|
+
inkAssert(ci == -1, "only support ci = -1 for now!");
|
|
586
|
+
if(ci == -1) {
|
|
587
|
+
set(name, *stack.get(itr.get()->name));
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
void basic_stack::push_values(basic_stack& stack) {
|
|
593
|
+
for(auto itr = base::begin();
|
|
594
|
+
itr.get()->name != InvalidHash && itr.get()->data.type() != value_type::value_pointer;
|
|
595
|
+
itr.next())
|
|
596
|
+
{
|
|
597
|
+
stack.set(itr.get()->name, itr.get()->data);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
size_t basic_stack::snap(unsigned char* data, const snapper& snapper) const
|
|
602
|
+
{
|
|
603
|
+
unsigned char* ptr = data;
|
|
604
|
+
bool should_write = data != nullptr;
|
|
605
|
+
ptr = snap_write(ptr, _next_thread, should_write );
|
|
606
|
+
ptr = snap_write(ptr, _backup_next_thread, should_write );
|
|
607
|
+
ptr += base::snap(data ? ptr : nullptr, snapper);
|
|
608
|
+
return ptr - data;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
const unsigned char* basic_stack::snap_load(const unsigned char* ptr, const loader& loader)
|
|
612
|
+
{
|
|
613
|
+
ptr = snap_read(ptr, _next_thread);
|
|
614
|
+
ptr = snap_read(ptr, _backup_next_thread);
|
|
615
|
+
ptr = base::snap_load(ptr, loader);
|
|
616
|
+
return ptr;
|
|
617
|
+
}
|
|
618
|
+
}
|