openscad-cpp-evaluator 0.13.4__tar.gz → 0.13.5__tar.gz
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.
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/bytecode.hpp +125 -12
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/bytecode_vm.hpp +27 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/bytecode_compiler.cpp +46 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/bytecode_vm.cpp +69 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_bytecode_compiler.cpp +106 -11
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/.gitignore +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/.gitmodules +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/LICENSE +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/README.md +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/stb_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/text/stb_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tools/cli/main.cpp +0 -0
|
@@ -325,6 +325,101 @@ enum class Op {
|
|
|
325
325
|
// same seam, now a counter).
|
|
326
326
|
PopBuiltinWrap,
|
|
327
327
|
|
|
328
|
+
// -- CSG-wrap compilation (closes the LAST native-reentry source in ----
|
|
329
|
+
// -- the original NativeStatement gap: union()/difference()/ -
|
|
330
|
+
// -- intersection()) ----------------------------------------------------
|
|
331
|
+
// union()/difference()/intersection() weren't covered by the original
|
|
332
|
+
// Op::PushBuiltinWrap (see that op's own doc comment) because they need
|
|
333
|
+
// bespoke bookkeeping PushBuiltinWrap's single all-children bracket
|
|
334
|
+
// doesn't do: Evaluator's own resolveCsg (booleans.cpp) evaluates each
|
|
335
|
+
// TOP-LEVEL child statement of the block SEPARATELY and records how
|
|
336
|
+
// many CSGNodes it individually contributed ("group_sizes") -- e.g.
|
|
337
|
+
// `difference(){ A; B; C; }` = A - (B u C), preserving A's own group
|
|
338
|
+
// even when A itself expands to more than one body (an attachable()-
|
|
339
|
+
// style call returning parent+children as one operand). A flat
|
|
340
|
+
// all-children bracket the way Transform/Color/Modifier use would lose
|
|
341
|
+
// that grouping entirely. This op pair (PushCsgWrap/PopCsgWrap) plus
|
|
342
|
+
// Op::CsgGroupStart/CsgGroupEnd (below) replicate resolveCsg's exact
|
|
343
|
+
// two-pass shape (all assignments first, THEN one evalChildren-per-
|
|
344
|
+
// geometry-statement) as inline compiled bytecode instead, exactly as
|
|
345
|
+
// PushBuiltinWrap already did for translate/rotate/scale/mirror/
|
|
346
|
+
// multmatrix/resize/color/#/%/! -- same rationale (a recursive
|
|
347
|
+
// union()/difference()/intersection()-wrapped module chain was still a
|
|
348
|
+
// real Windows native-reentry depth risk, just never independently
|
|
349
|
+
// fixed when PushBuiltinWrap's own set was).
|
|
350
|
+
//
|
|
351
|
+
// a = index into CompiledChunk::csgWrapSites. Runtime handler: captures
|
|
352
|
+
// ev.randsCallCount() BEFORE argument resolution (same rands-in-args
|
|
353
|
+
// taint reasoning as PushBuiltinWrap), resolves the (rare, $-only)
|
|
354
|
+
// arguments via resolveCallArgs exactly like resolveCsg itself does
|
|
355
|
+
// (discarding the positional/named result -- union/difference/
|
|
356
|
+
// intersection take no real parameters -- keeping only the possibly-
|
|
357
|
+
// $-scoped child ctx), pushes that ctx onto f.ctxChain unconditionally
|
|
358
|
+
// (mirrors Transform/Color's own unconditional push -- a bare
|
|
359
|
+
// `union() {...}` with no `$fn=...` override still pushes a ctx that's
|
|
360
|
+
// merely a copy, cheap and uniform rather than a special-cased branch),
|
|
361
|
+
// pushes a fresh ev.treeStack_ frame (every child statement's own
|
|
362
|
+
// CSGNode(s), across every group, land flat in this ONE frame --
|
|
363
|
+
// mirrors Evaluator::buildTreeNode/evalModularCall's own single
|
|
364
|
+
// treeStack_.emplace_back() around the whole call, not one per group),
|
|
365
|
+
// and stashes {op, randsBefore, siteIdx, empty groupSizes} onto
|
|
366
|
+
// VmFrame::csgWrapStack (a real per-frame LIFO, same reasoning as
|
|
367
|
+
// builtinWrapStack: nested/sequenced CSG wraps within one frame's own
|
|
368
|
+
// instruction stream, e.g. `union() { difference() {...} }`). The
|
|
369
|
+
// compiler always emits a plain Op::CheckDebugStatement immediately
|
|
370
|
+
// before this (see emitCsgWrap, bytecode_compiler.cpp), mirroring
|
|
371
|
+
// emitBuiltinWrap's own pattern -- this is a genuine statement doing
|
|
372
|
+
// real work here, not a call transferring control to a declaration.
|
|
373
|
+
PushCsgWrap,
|
|
374
|
+
|
|
375
|
+
// Opens one "group" within an already-open Op::PushCsgWrap bracket --
|
|
376
|
+
// emitted immediately before each top-level GEOMETRY child statement's
|
|
377
|
+
// own inline-compiled bytecode (compileStatementList of exactly that
|
|
378
|
+
// one statement). Records ev.treeStack_.back().size() into
|
|
379
|
+
// csgWrapStack.back().groupStartSize -- always operates on the
|
|
380
|
+
// TOPMOST (innermost still-open) csgWrapStack entry, matching
|
|
381
|
+
// PopBuiltinWrap's own back()-is-always-mine LIFO discipline, so no
|
|
382
|
+
// operand is needed. Assignments among the block's children are
|
|
383
|
+
// compiled separately, BEFORE any CsgGroupStart/End pair at all (see
|
|
384
|
+
// emitCsgWrap) -- mirrors resolveCsg's own two-pass split exactly
|
|
385
|
+
// (Evaluator::evalChildren(assignNodes, effCtx) always runs to
|
|
386
|
+
// completion before the per-geoNode loop starts).
|
|
387
|
+
CsgGroupStart,
|
|
388
|
+
|
|
389
|
+
// Closes the matching Op::CsgGroupStart: computes
|
|
390
|
+
// ev.treeStack_.back().size() - csgWrapStack.back().groupStartSize
|
|
391
|
+
// (how many CSGNodes THIS one top-level statement just contributed,
|
|
392
|
+
// however many that turned out to be -- 0 for a statement whose own
|
|
393
|
+
// evaluation spliced nothing, e.g. a no-op unknown-module warning; >1
|
|
394
|
+
// for an attachable()-style multi-body operand) and appends it, as a
|
|
395
|
+
// Value, onto csgWrapStack.back().groupSizes -- exactly one entry per
|
|
396
|
+
// top-level geometry statement, in source order, mirroring resolveCsg's
|
|
397
|
+
// own `groupSizes.push_back(Value{...})` loop.
|
|
398
|
+
CsgGroupEnd,
|
|
399
|
+
|
|
400
|
+
// Closes the matching Op::PushCsgWrap bracket: pops
|
|
401
|
+
// VmFrame::csgWrapStack's own top entry FIRST (before anything that can
|
|
402
|
+
// itself throw, e.g. setTreeDepthOrThrow below -- same "exception-
|
|
403
|
+
// teardown's own pending count must already be right" reasoning as
|
|
404
|
+
// PopBuiltinWrap), pops the ctx PushCsgWrap unconditionally pushed,
|
|
405
|
+
// pops ev.treeStack_ to retrieve every group's own CSGNode(s) (flat,
|
|
406
|
+
// exactly like resolveCsg's own `children` result -- group boundaries
|
|
407
|
+
// live only in group_sizes, never in the CSGNode list's own shape), and
|
|
408
|
+
// builds the tagged CSGNode exactly like Evaluator::buildTreeNode's own
|
|
409
|
+
// post-resolveBody() half does, with params = {"op": site.op,
|
|
410
|
+
// "group_sizes": ValueList(pending.groupSizes)} -- byte-for-byte what
|
|
411
|
+
// native resolveCsg returns -- pushing the result onto the new top of
|
|
412
|
+
// treeStack_. a = index into CompiledChunk::csgWrapSites (same site
|
|
413
|
+
// Push used).
|
|
414
|
+
//
|
|
415
|
+
// teardownVmCallStackDownTo's own exception path (bytecode_vm.cpp) pops
|
|
416
|
+
// frame->csgWrapStack.size() additional treeStack_ entries per
|
|
417
|
+
// torn-down frame, alongside its existing builtinWrapStack/
|
|
418
|
+
// ownsModuleSplice accounting -- same reasoning as PopBuiltinWrap's own
|
|
419
|
+
// doc comment: an exception can leave N of these brackets open in one
|
|
420
|
+
// frame.
|
|
421
|
+
PopCsgWrap,
|
|
422
|
+
|
|
328
423
|
// A `children()` / `children(N)` statement -- the runtime-varying
|
|
329
424
|
// sibling of Op::CallModule/Op::PushBuiltinWrap, closing the LAST
|
|
330
425
|
// dominant native-reentry source (BOSL2's attachable() calls
|
|
@@ -367,10 +462,11 @@ enum class Op {
|
|
|
367
462
|
// no separate site table needed).
|
|
368
463
|
CallChildren,
|
|
369
464
|
|
|
370
|
-
// A single "native passthrough" statement -- intersection_for,
|
|
371
|
-
//
|
|
372
|
-
//
|
|
373
|
-
//
|
|
465
|
+
// A single "native passthrough" statement -- intersection_for, every
|
|
466
|
+
// OTHER builtin module call not covered by Op::PushBuiltinWrap/
|
|
467
|
+
// Op::PushCsgWrap (see those ops' own doc comments for exactly which
|
|
468
|
+
// builtins ARE covered -- cube/sphere/hull/linear_extrude/etc., the
|
|
469
|
+
// ones that never wrap a recursive call in idiomatic OpenSCAD), the `*`
|
|
374
470
|
// modifier's own no-op case, or a user-module call that didn't
|
|
375
471
|
// resolve at compile time (shadowed, forward-declared, or otherwise
|
|
376
472
|
// not statically known) -- anything compileStatementList doesn't give
|
|
@@ -387,18 +483,21 @@ enum class Op {
|
|
|
387
483
|
// crash risk in practice, not just a missed optimization. See
|
|
388
484
|
// Op::PushBuiltinWrap's own doc comment for the real story and the
|
|
389
485
|
// fix. children() fell here too, and was the LAST and largest such
|
|
390
|
-
// reentry source once PushBuiltinWrap's own set was covered -- it
|
|
391
|
-
//
|
|
486
|
+
// reentry source once PushBuiltinWrap's own set was covered -- it now
|
|
487
|
+
// has Op::CallChildren, above. union()/difference()/intersection()
|
|
488
|
+
// fell here too, and were the last remaining REAL native-reentry risk
|
|
489
|
+
// (bespoke group_sizes bookkeeping meant they couldn't just reuse
|
|
490
|
+
// PushBuiltinWrap's own bracket) -- they now have Op::PushCsgWrap,
|
|
491
|
+
// above.)
|
|
392
492
|
// a = index into CompiledChunk::nativeStatements. Runtime just does
|
|
393
493
|
// what Evaluator::evalChildren's own per-statement loop already does
|
|
394
494
|
// for one node: derive childCtx via ctx.withScope(...), checkDebug,
|
|
395
495
|
// evalStatement. These are still "leaf-shaped" for what's left here
|
|
396
|
-
//
|
|
397
|
-
// recursion safety for a recursive module
|
|
398
|
-
// CallModule/PushBuiltinWrap/
|
|
399
|
-
// flow, not by how many of
|
|
400
|
-
//
|
|
401
|
-
// (translate()-wrapped recursion) has its own real bytecode instead.
|
|
496
|
+
// now that Op::PushBuiltinWrap/Op::PushCsgWrap have peeled off every
|
|
497
|
+
// proven-risky construct: real recursion safety for a recursive module
|
|
498
|
+
// chain is covered by CallModule/PushBuiltinWrap/PushCsgWrap/
|
|
499
|
+
// ForIterNext/the Jump-based if/for control flow, not by how many of
|
|
500
|
+
// THESE sit alongside them in the same body.
|
|
402
501
|
NativeStatement,
|
|
403
502
|
|
|
404
503
|
// If/if-else's own condition, evaluated NATIVELY (Evaluator::
|
|
@@ -734,6 +833,19 @@ struct CompiledChunk {
|
|
|
734
833
|
const oscad::ASTNode* node = nullptr;
|
|
735
834
|
};
|
|
736
835
|
|
|
836
|
+
// One Op::PushCsgWrap/PopCsgWrap site pair -- see those ops' own doc
|
|
837
|
+
// comments for the full "why union/difference/intersection need
|
|
838
|
+
// bespoke group_sizes bookkeeping instead of just reusing
|
|
839
|
+
// BuiltinWrapSite" rationale. `op` is always "union"/"difference"/
|
|
840
|
+
// "intersection" (the only 3 names resolveDispatch() maps to
|
|
841
|
+
// resolveCsg) -- always a genuine ModularCall (unlike BuiltinWrapSite's
|
|
842
|
+
// Modifier kind, this construct has no non-ModularCall variant), so
|
|
843
|
+
// `node` is typed precisely rather than a generic ASTNode*.
|
|
844
|
+
struct CsgWrapSite {
|
|
845
|
+
std::string op;
|
|
846
|
+
const oscad::ModularCall* node = nullptr;
|
|
847
|
+
};
|
|
848
|
+
|
|
737
849
|
// One Op::AssertStatement site -- see that op's own doc comment for
|
|
738
850
|
// the full contract. `conditionArgIndex`/`messageArgIndex` are indices
|
|
739
851
|
// into the site's own argCount-sized popped-argument array (source
|
|
@@ -796,6 +908,7 @@ struct CompiledChunk {
|
|
|
796
908
|
// own doc comments, above) -- always empty for a function chunk.
|
|
797
909
|
std::vector<ModuleCallSite> moduleCallSites;
|
|
798
910
|
std::vector<BuiltinWrapSite> builtinWrapSites;
|
|
911
|
+
std::vector<CsgWrapSite> csgWrapSites;
|
|
799
912
|
std::vector<AssertSite> assertSites;
|
|
800
913
|
std::vector<const oscad::Expression*> nativeExprs;
|
|
801
914
|
std::vector<const oscad::ASTNode*> nativeStatements;
|
|
@@ -30,6 +30,24 @@ struct PendingBuiltinWrap {
|
|
|
30
30
|
int siteIdx = -1;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
+
// One still-open Op::PushCsgWrap bracket's own state -- see that op's own
|
|
34
|
+
// doc comment (bytecode.hpp) for the full contract. `groupSizes` is built
|
|
35
|
+
// up incrementally, one entry per Op::CsgGroupStart/CsgGroupEnd pair (one
|
|
36
|
+
// per top-level GEOMETRY child statement); `groupStartSize` is scratch
|
|
37
|
+
// space for the CURRENTLY OPEN group only (set by CsgGroupStart, consumed
|
|
38
|
+
// by the matching CsgGroupEnd) -- safe as a single scalar, not a stack of
|
|
39
|
+
// its own, because groups within one CSG wrap are siblings in sequence,
|
|
40
|
+
// never nested (unlike PushCsgWrap brackets themselves, which CAN nest,
|
|
41
|
+
// e.g. `union() { difference() {...} }` -- that's what makes
|
|
42
|
+
// VmFrame::csgWrapStack itself a real LIFO, below).
|
|
43
|
+
struct PendingCsgWrap {
|
|
44
|
+
std::string op;
|
|
45
|
+
std::uint64_t randsBefore = 0;
|
|
46
|
+
int siteIdx = -1;
|
|
47
|
+
std::vector<Value> groupSizes;
|
|
48
|
+
size_t groupStartSize = 0;
|
|
49
|
+
};
|
|
50
|
+
|
|
33
51
|
// One ListCompFor/statement-for assignment's own materialized iteration
|
|
34
52
|
// state -- see Op::IterMaterialize/IterReset/IterNext's own doc comments
|
|
35
53
|
// (bytecode.hpp). Lives in the header (not bytecode_vm.cpp's own anonymous
|
|
@@ -127,6 +145,15 @@ struct VmFrame {
|
|
|
127
145
|
// existing invariant ("whoever pops this frame drains its own open
|
|
128
146
|
// brackets first") already covers it.
|
|
129
147
|
std::vector<PendingBuiltinWrap> builtinWrapStack;
|
|
148
|
+
// Op::PushCsgWrap's own per-frame LIFO -- same role/lifetime/teardown
|
|
149
|
+
// discipline as builtinWrapStack, just for union()/difference()/
|
|
150
|
+
// intersection() (see PendingCsgWrap's own doc comment, above, and
|
|
151
|
+
// Op::PushCsgWrap's, bytecode.hpp). Not explicitly cleared in
|
|
152
|
+
// releaseVmFrame, same as builtinWrapStack/accumStack/ctxChain -- the
|
|
153
|
+
// existing invariant ("whoever pops this frame drains its own open
|
|
154
|
+
// brackets first", normally via matched Push/Pop, or via
|
|
155
|
+
// teardownVmCallStackDownTo on the exception path) already covers it.
|
|
156
|
+
std::vector<PendingCsgWrap> csgWrapStack;
|
|
130
157
|
// The ORIGINAL callee name at push time, used by
|
|
131
158
|
// Evaluator::exitUserCallSuccess's own returnHook call when this frame
|
|
132
159
|
// carries a bracket -- deliberately NOT updated by a later tail hop
|
|
@@ -1202,6 +1202,45 @@ public:
|
|
|
1202
1202
|
out.push_back({Op::PopBuiltinWrap, idx, 0, &wrapperNode.position()});
|
|
1203
1203
|
}
|
|
1204
1204
|
|
|
1205
|
+
// union()/difference()/intersection() -- see Op::PushCsgWrap's own doc
|
|
1206
|
+
// comment (bytecode.hpp) for why these can't just reuse emitBuiltinWrap:
|
|
1207
|
+
// resolveCsg (booleans.cpp) needs per-top-level-child-statement
|
|
1208
|
+
// "group_sizes" bookkeeping, replicated here as one Op::CsgGroupStart/
|
|
1209
|
+
// CsgGroupEnd pair per GEOMETRY child, with every ASSIGNMENT child
|
|
1210
|
+
// compiled first, unconditionally, regardless of interleaving in
|
|
1211
|
+
// source -- mirrors resolveCsg's own two-pass split (`assignNodes`
|
|
1212
|
+
// fully evaluated, THEN one evalChildren call per `geoNodes` entry)
|
|
1213
|
+
// exactly, including its ModuleDeclaration/FunctionDeclaration
|
|
1214
|
+
// exclusion (a nested declaration inside a CSG block contributes to
|
|
1215
|
+
// neither pass -- already hoisted into scope, nothing to run here).
|
|
1216
|
+
void emitCsgWrap(const oscad::ModularCall& call, std::vector<Instruction>& out) {
|
|
1217
|
+
out.push_back({Op::CheckDebugStatement, internNativeStatement(&call), 0, nullptr});
|
|
1218
|
+
CompiledChunk::CsgWrapSite site;
|
|
1219
|
+
site.op = call.name->name;
|
|
1220
|
+
site.node = &call;
|
|
1221
|
+
chunk_.csgWrapSites.push_back(std::move(site));
|
|
1222
|
+
const int idx = static_cast<int>(chunk_.csgWrapSites.size()) - 1;
|
|
1223
|
+
out.push_back({Op::PushCsgWrap, idx, 0, &call.position()});
|
|
1224
|
+
|
|
1225
|
+
std::vector<const oscad::ASTNode*> assignNodes;
|
|
1226
|
+
std::vector<const oscad::ASTNode*> geoNodes;
|
|
1227
|
+
for (const auto& c : call.children) {
|
|
1228
|
+
if (c->kind() == oscad::NodeKind::Assignment) {
|
|
1229
|
+
assignNodes.push_back(c.get());
|
|
1230
|
+
} else if (c->kind() != oscad::NodeKind::ModuleDeclaration &&
|
|
1231
|
+
c->kind() != oscad::NodeKind::FunctionDeclaration) {
|
|
1232
|
+
geoNodes.push_back(c.get());
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
compileStatementList(assignNodes, out);
|
|
1236
|
+
for (const oscad::ASTNode* geoNode : geoNodes) {
|
|
1237
|
+
out.push_back({Op::CsgGroupStart, 0, 0, nullptr});
|
|
1238
|
+
compileStatementList(std::vector<const oscad::ASTNode*>{geoNode}, out);
|
|
1239
|
+
out.push_back({Op::CsgGroupEnd, 0, 0, nullptr});
|
|
1240
|
+
}
|
|
1241
|
+
out.push_back({Op::PopCsgWrap, idx, 0, &call.position()});
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1205
1244
|
void compileOneStatement(const oscad::ASTNode& stmt, std::vector<Instruction>& out) {
|
|
1206
1245
|
using oscad::NodeKind;
|
|
1207
1246
|
trackSpan(stmt);
|
|
@@ -1434,6 +1473,13 @@ public:
|
|
|
1434
1473
|
out.push_back({Op::CallChildren, internNativeStatement(&stmt), 0, &stmt.position()});
|
|
1435
1474
|
return;
|
|
1436
1475
|
}
|
|
1476
|
+
// union()/difference()/intersection() -- see emitCsgWrap's
|
|
1477
|
+
// own doc comment for why these need their own bespoke
|
|
1478
|
+
// bracket rather than emitBuiltinWrap's.
|
|
1479
|
+
if (dispatchIt != dispatch.end() && dispatchIt->second == &resolveCsg) {
|
|
1480
|
+
emitCsgWrap(call, out);
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1437
1483
|
// Every other builtin, or a name that didn't resolve to a
|
|
1438
1484
|
// user module statically -- native passthrough, exactly
|
|
1439
1485
|
// like echo/assert/etc. below. Never the recursion-depth
|
|
@@ -401,6 +401,11 @@ void teardownVmCallStackDownTo(Evaluator& ev, size_t floor) {
|
|
|
401
401
|
// at once; at most one module-call splice ever can).
|
|
402
402
|
for (size_t i = 0; i < frame->builtinWrapStack.size(); ++i) ev.treeStack_.pop_back();
|
|
403
403
|
frame->builtinWrapStack.clear();
|
|
404
|
+
// Same reasoning, same LIFO-order requirement, for any still-open
|
|
405
|
+
// Op::PushCsgWrap bracket(s) -- see PendingCsgWrap's/Op::PushCsgWrap's
|
|
406
|
+
// own doc comments.
|
|
407
|
+
for (size_t i = 0; i < frame->csgWrapStack.size(); ++i) ev.treeStack_.pop_back();
|
|
408
|
+
frame->csgWrapStack.clear();
|
|
404
409
|
// A module frame's own CALLER (Op::CallModule, mirroring
|
|
405
410
|
// evalModularCall/buildTreeNode) always pushes a treeStack_
|
|
406
411
|
// accumulator for it before pushing this frame -- normally popped
|
|
@@ -1108,6 +1113,70 @@ Value driveVm(Evaluator& ev, size_t floor) {
|
|
|
1108
1113
|
++f.pc;
|
|
1109
1114
|
break;
|
|
1110
1115
|
}
|
|
1116
|
+
case Op::PushCsgWrap: {
|
|
1117
|
+
const CompiledChunk::CsgWrapSite& site = f.chunk->csgWrapSites[static_cast<size_t>(ins.a)];
|
|
1118
|
+
// Captured BEFORE argument resolution -- same
|
|
1119
|
+
// rands-in-args taint reasoning as Op::PushBuiltinWrap.
|
|
1120
|
+
const std::uint64_t randsBefore = ev.randsCallCount();
|
|
1121
|
+
// union/difference/intersection take no positional
|
|
1122
|
+
// arguments in real OpenSCAD -- `args` is discarded,
|
|
1123
|
+
// exactly mirroring resolveCsg's own `(void)args;`
|
|
1124
|
+
// (booleans.cpp). Only `effCtx` (a possibly-$-scoped
|
|
1125
|
+
// child ctx, e.g. `difference($fn=8) {...}`) matters.
|
|
1126
|
+
auto [args, effCtx] = resolveCallArgs(ev, site.node->arguments, ctx);
|
|
1127
|
+
(void)args;
|
|
1128
|
+
f.ctxChain.push_back(std::move(effCtx));
|
|
1129
|
+
ev.treeStack_.emplace_back();
|
|
1130
|
+
f.csgWrapStack.push_back({site.op, randsBefore, ins.a, {}, 0});
|
|
1131
|
+
++f.pc;
|
|
1132
|
+
break;
|
|
1133
|
+
}
|
|
1134
|
+
case Op::CsgGroupStart: {
|
|
1135
|
+
f.csgWrapStack.back().groupStartSize = ev.treeStack_.back().size();
|
|
1136
|
+
++f.pc;
|
|
1137
|
+
break;
|
|
1138
|
+
}
|
|
1139
|
+
case Op::CsgGroupEnd: {
|
|
1140
|
+
PendingCsgWrap& pending = f.csgWrapStack.back();
|
|
1141
|
+
const size_t after = ev.treeStack_.back().size();
|
|
1142
|
+
pending.groupSizes.push_back(Value{static_cast<double>(after - pending.groupStartSize)});
|
|
1143
|
+
++f.pc;
|
|
1144
|
+
break;
|
|
1145
|
+
}
|
|
1146
|
+
case Op::PopCsgWrap: {
|
|
1147
|
+
// Pop this bracket's own bookkeeping FIRST -- before
|
|
1148
|
+
// anything below that can itself throw
|
|
1149
|
+
// (setTreeDepthOrThrow) -- same ordering reasoning as
|
|
1150
|
+
// Op::PopBuiltinWrap's own doc comment.
|
|
1151
|
+
PendingCsgWrap pending = std::move(f.csgWrapStack.back());
|
|
1152
|
+
f.csgWrapStack.pop_back();
|
|
1153
|
+
const CompiledChunk::CsgWrapSite& site =
|
|
1154
|
+
f.chunk->csgWrapSites[static_cast<size_t>(pending.siteIdx)];
|
|
1155
|
+
f.ctxChain.pop_back();
|
|
1156
|
+
std::vector<std::unique_ptr<CSGNode>> children = std::move(ev.treeStack_.back());
|
|
1157
|
+
ev.treeStack_.pop_back();
|
|
1158
|
+
// Mirrors resolveCsg's own params exactly (booleans.cpp).
|
|
1159
|
+
CSGParams params;
|
|
1160
|
+
params["op"] = Value{pending.op};
|
|
1161
|
+
params["group_sizes"] =
|
|
1162
|
+
Value{std::make_shared<const ValueList>(ValueList{std::move(pending.groupSizes)})};
|
|
1163
|
+
// Mirrors Evaluator::buildTreeNode's own post-
|
|
1164
|
+
// resolveBody() half exactly (csg_resolve.cpp).
|
|
1165
|
+
const bool uncacheable =
|
|
1166
|
+
(ev.randsCallCount() != pending.randsBefore) ||
|
|
1167
|
+
std::any_of(children.begin(), children.end(), [](const auto& c) { return c->uncacheable; });
|
|
1168
|
+
auto treeNode = std::make_unique<CSGNode>();
|
|
1169
|
+
treeNode->kind = site.op;
|
|
1170
|
+
treeNode->node = site.node;
|
|
1171
|
+
treeNode->isBuiltin = true;
|
|
1172
|
+
treeNode->children = std::move(children);
|
|
1173
|
+
treeNode->params = std::move(params);
|
|
1174
|
+
treeNode->uncacheable = uncacheable;
|
|
1175
|
+
ev.setTreeDepthOrThrow(*treeNode, *site.node);
|
|
1176
|
+
ev.treeStack_.back().push_back(std::move(treeNode));
|
|
1177
|
+
++f.pc;
|
|
1178
|
+
break;
|
|
1179
|
+
}
|
|
1111
1180
|
case Op::NativeStatement: {
|
|
1112
1181
|
const oscad::ASTNode* stmt = f.chunk->nativeStatements[static_cast<size_t>(ins.a)];
|
|
1113
1182
|
EvalContext childCtx = ctx.withScope(stmt->scope() ? stmt->scope() : ctx.scope);
|
{openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/tests/test_bytecode_compiler.cpp
RENAMED
|
@@ -1397,16 +1397,35 @@ TEST(ModuleBodyCompiles, RecursiveModifierWrappedCallSucceedsWellPastTheOldNativ
|
|
|
1397
1397
|
ASSERT_EQ(e.bodies.size(), 1u);
|
|
1398
1398
|
}
|
|
1399
1399
|
|
|
1400
|
-
// union()/difference()/intersection()
|
|
1401
|
-
// Op::
|
|
1402
|
-
//
|
|
1403
|
-
//
|
|
1404
|
-
//
|
|
1405
|
-
//
|
|
1406
|
-
//
|
|
1407
|
-
//
|
|
1408
|
-
//
|
|
1409
|
-
|
|
1400
|
+
// union()/difference()/intersection() now have their own real bytecode
|
|
1401
|
+
// (Op::PushCsgWrap/CsgGroupStart/CsgGroupEnd/PopCsgWrap) instead of falling
|
|
1402
|
+
// to Op::NativeStatement -- see that op's own doc comment (bytecode.hpp)
|
|
1403
|
+
// for why they needed a bespoke bracket rather than just reusing
|
|
1404
|
+
// Op::PushBuiltinWrap's. A union()/difference()/intersection()-wrapped
|
|
1405
|
+
// recursive call no longer costs any native reentry at all: `recur2(n);`
|
|
1406
|
+
// (a resolved user-module call) compiles inline to Op::CallModule, a pure
|
|
1407
|
+
// in-VM push, so the whole chain never touches driveVmNativeDepth_.
|
|
1408
|
+
// Depth 1500 (same figure the PushBuiltinWrap/CallChildren tests above use)
|
|
1409
|
+
// comfortably clears the old 40-level Windows-unsafe native-reentry ceiling
|
|
1410
|
+
// while staying under kMaxCsgTreeDepth=2000 -- each `recur` level's own
|
|
1411
|
+
// union() still contributes one real CSGNode to the tree (this fix
|
|
1412
|
+
// eliminates native-stack cost, not CSG-tree depth, which is an orthogonal,
|
|
1413
|
+
// unrelated cap on the RESULT shape, not the call chain).
|
|
1414
|
+
TEST(ModuleBodyCompiles, UnionWrappedRecursionSucceedsWellPastTheOldNativeReentryLimit) {
|
|
1415
|
+
ScopedVm vm(true);
|
|
1416
|
+
Evaluated e = evalSrc("module recur(n) { union() { recur2(n); } }\n"
|
|
1417
|
+
"module recur2(n) { if (n > 0) { recur(n - 1); } else { cube(1); } }\n"
|
|
1418
|
+
"recur(1500);");
|
|
1419
|
+
ASSERT_EQ(e.bodies.size(), 1u);
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
// The SAME chain pushed deep enough (3000 levels, one union() CSGNode per
|
|
1423
|
+
// `recur` level) now hits the orthogonal, pre-existing CSG-TREE-depth guard
|
|
1424
|
+
// (kMaxCsgTreeDepth=2000, csg_resolve.cpp) instead of a native-reentry
|
|
1425
|
+
// guard -- proves the native-reentry elimination didn't silently trade one
|
|
1426
|
+
// crash risk for an unguarded one; something still stops an unreasonably
|
|
1427
|
+
// deep result, just a different (and correctly-named) error now.
|
|
1428
|
+
TEST(ModuleBodyCompiles, UnionWrappedRecursionPastCsgTreeDepthLimitStillErrorsCleanly) {
|
|
1410
1429
|
ScopedVm vm(true);
|
|
1411
1430
|
try {
|
|
1412
1431
|
evalSrc("module recur(n) { union() { recur2(n); } }\n"
|
|
@@ -1415,10 +1434,86 @@ TEST(ModuleBodyCompiles, UnionWrappedRecursionStillHitsTheNativeReentryGuardCont
|
|
|
1415
1434
|
FAIL() << "expected EvalError";
|
|
1416
1435
|
} catch (const EvalError& e) {
|
|
1417
1436
|
const std::string what = e.what();
|
|
1418
|
-
EXPECT_NE(what.find("Recursion too deep"), std::string::npos) << what;
|
|
1437
|
+
EXPECT_NE(what.find("Recursion too deep while building geometry"), std::string::npos) << what;
|
|
1419
1438
|
}
|
|
1420
1439
|
}
|
|
1421
1440
|
|
|
1441
|
+
// difference()/intersection() get the same treatment -- one representative
|
|
1442
|
+
// test each rather than the full union() coverage above, since all three
|
|
1443
|
+
// share emitCsgWrap/Op::PushCsgWrap verbatim (only the runtime `op` string
|
|
1444
|
+
// differs, consumed solely by generateCsg at generate time, never by the
|
|
1445
|
+
// compiled path itself).
|
|
1446
|
+
TEST(ModuleBodyCompiles, DifferenceWrappedRecursionSucceedsWellPastTheOldNativeReentryLimit) {
|
|
1447
|
+
ScopedVm vm(true);
|
|
1448
|
+
Evaluated e = evalSrc("module recur(n) { difference() { recur2(n); } }\n"
|
|
1449
|
+
"module recur2(n) { if (n > 0) { recur(n - 1); } else { cube(1); } }\n"
|
|
1450
|
+
"recur(1500);");
|
|
1451
|
+
ASSERT_EQ(e.bodies.size(), 1u);
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
TEST(ModuleBodyCompiles, IntersectionWrappedRecursionSucceedsWellPastTheOldNativeReentryLimit) {
|
|
1455
|
+
ScopedVm vm(true);
|
|
1456
|
+
Evaluated e = evalSrc("module recur(n) { intersection() { recur2(n); } }\n"
|
|
1457
|
+
"module recur2(n) { if (n > 0) { recur(n - 1); } else { cube(1); } }\n"
|
|
1458
|
+
"recur(1500);");
|
|
1459
|
+
ASSERT_EQ(e.bodies.size(), 1u);
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
// group_sizes/multi-body-operand grouping correctness under the COMPILED
|
|
1463
|
+
// path (test_booleans.cpp's own Difference.MultipleBodiesInFirstStatement
|
|
1464
|
+
// FormOnePositiveOperand/Union.MultipleBodiesInFirstStatementAllSurvive
|
|
1465
|
+
// already cover this for the default ambient VM state; this pins it
|
|
1466
|
+
// explicitly under ScopedVm(true) plus a MODULE body, not just a top-level
|
|
1467
|
+
// script, since that's the shape emitCsgWrap actually compiles).
|
|
1468
|
+
TEST(ModuleBodyCompiles, CsgWrapGroupingSurvivesInsideACompiledModuleBody) {
|
|
1469
|
+
ScopedVm vm(true);
|
|
1470
|
+
// First statement's own union() contributes TWO disjoint bodies (one
|
|
1471
|
+
// group, size 2); the second statement subtracts a cube overlapping
|
|
1472
|
+
// only the first of those two by 1. A flat (non-grouped) evaluation
|
|
1473
|
+
// would instead treat the second cube as its own separate operand.
|
|
1474
|
+
Evaluated e = evalSrc("module m() {"
|
|
1475
|
+
" difference() {"
|
|
1476
|
+
" union() { cube(2); translate([10,0,0]) cube(2); }"
|
|
1477
|
+
" translate([1,0,0]) cube(2);"
|
|
1478
|
+
" }"
|
|
1479
|
+
"}"
|
|
1480
|
+
"m();");
|
|
1481
|
+
ASSERT_EQ(e.bodies.size(), 1u);
|
|
1482
|
+
// 16 - overlap(1*2*2=4) = 12, same expected volume as the top-level test.
|
|
1483
|
+
EXPECT_NEAR(e.bodies[0].body->Volume(), 12.0, 1e-6);
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
// $-named-argument propagation into a compiled CSG wrap's children --
|
|
1487
|
+
// union/difference/intersection take no positional args in real OpenSCAD,
|
|
1488
|
+
// but `difference($fn=8) {...}` is legal and must still reach its children,
|
|
1489
|
+
// exactly like resolveCsg's own resolveCallArgs call preserves natively
|
|
1490
|
+
// (booleans.cpp). Verifies Op::PushCsgWrap's ctx push (unconditional,
|
|
1491
|
+
// unlike PushBuiltinWrap's Transform/Color-only push) actually carries it.
|
|
1492
|
+
TEST(ModuleBodyCompiles, DollarArgPropagatesIntoCompiledCsgWrapChildren) {
|
|
1493
|
+
ScopedVm vm(true);
|
|
1494
|
+
EXPECT_EQ(runCapturingEcho("module m() { union($fn = 9) { echo($fn); cube(1); } }\n"
|
|
1495
|
+
"m();"),
|
|
1496
|
+
"ECHO: 9");
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
// Assignment-before-geometry ordering: resolveCsg evaluates EVERY
|
|
1500
|
+
// assignment child first, regardless of source interleaving with geometry
|
|
1501
|
+
// statements, THEN each geometry statement in its own group -- emitCsgWrap
|
|
1502
|
+
// mirrors this with a separate compile pass, not source order. A geometry
|
|
1503
|
+
// statement referencing a LATER-in-source assignment must still see it.
|
|
1504
|
+
TEST(ModuleBodyCompiles, CompiledCsgWrapEvaluatesAllAssignmentsBeforeAnyGeometryStatement) {
|
|
1505
|
+
ScopedVm vm(true);
|
|
1506
|
+
Evaluated e = evalSrc("module m() {"
|
|
1507
|
+
" union() {"
|
|
1508
|
+
" translate([sz, 0, 0]) cube(1);" // geometry statement first in SOURCE order
|
|
1509
|
+
" sz = 5;" // assignment second in source order
|
|
1510
|
+
" }"
|
|
1511
|
+
"}"
|
|
1512
|
+
"m();");
|
|
1513
|
+
ASSERT_EQ(e.bodies.size(), 1u);
|
|
1514
|
+
EXPECT_NEAR(e.bodies[0].body->Volume(), 1.0, 1e-6);
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1422
1517
|
// The BOSL2 attachable() shape this whole effort targets: a wrapper module
|
|
1423
1518
|
// whose body is just `children();`, applied at every level of a recursive
|
|
1424
1519
|
// chain. children() used to fall to Op::NativeStatement -- one genuine
|
|
File without changes
|
{openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/.github/workflows/wheels.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/examples/eval_perf_benchmark.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/examples/manifold_cache_reuse.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-0.13.4 → openscad_cpp_evaluator-0.13.5}/examples/minimal_debugger.cpp
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|