openscad-cpp-evaluator 0.41.0__tar.gz → 0.42.1__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.41.0 → openscad_cpp_evaluator-0.42.1}/CLAUDE.md +7 -1
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/bytecode_vm.hpp +4 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/csg_node.hpp +18 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/evaluator.hpp +35 -1
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/booleans.cpp +7 -3
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/control.cpp +1 -2
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/registry.cpp +1 -1
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/bytecode_vm.cpp +21 -6
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/csg_resolve.cpp +21 -4
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/expr_eval.cpp +8 -6
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/user_calls.cpp +10 -2
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/CMakeLists.txt +1 -0
- openscad_cpp_evaluator-0.42.1/tests/test_children_separate.cpp +296 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/.gitignore +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/.gitmodules +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/LICENSE +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/README.md +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/dxf_dim.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-0.41.0 → openscad_cpp_evaluator-0.42.1}/uv.lock +0 -0
|
@@ -481,7 +481,13 @@ grep for `ponytail:`.
|
|
|
481
481
|
lexically nested inside an already-active call," picking `childCtx()` vs `callCtx()`
|
|
482
482
|
accordingly; read its doc comment before touching it, it's the second-trickiest mechanism in this
|
|
483
483
|
codebase after the CSG tree stack), `evalUserModule`/`evalUserFunction`/`evalFunctionLiteral`,
|
|
484
|
-
and `builtinChildren` (children()/children(N), deferred evaluation
|
|
484
|
+
and `builtinChildren` (children()/children(N), deferred evaluation; `children(separate=true)`
|
|
485
|
+
additionally marks each forwarded node `separateOperand` so the enclosing
|
|
486
|
+
union/difference/intersection treats them as separate operands rather than one grouped one --
|
|
487
|
+
a BelfrySCAD extension, see `Evaluator::appendGroupSizes`. The marks stop at a user-module
|
|
488
|
+
boundary: only the children() call's own splice honours them
|
|
489
|
+
(`spliceModuleChildren`'s `honorSeparateMarks`), so a module wrapping such a call wraps its
|
|
490
|
+
children as usual and its own caller sees one operand). `evalFunctionCall`'s
|
|
485
491
|
precedence order (checked in this exact sequence): `import` (special-cased, its own
|
|
486
492
|
module/expression-context split) → `isBuiltinFunctionName` (function_builtins.hpp — always wins
|
|
487
493
|
if true) → user function lookup → function-literal *value* probe → "unknown function" warning.
|
|
@@ -219,6 +219,10 @@ struct VmFrame {
|
|
|
219
219
|
// mirrors evalModularCall's own `&node` (csg_resolve.cpp). Only
|
|
220
220
|
// meaningful when ownsModuleSplice is true.
|
|
221
221
|
const oscad::ASTNode* moduleSpliceCallNode = nullptr;
|
|
222
|
+
// children(separate=true) on the call this frame is forwarding for.
|
|
223
|
+
// Only meaningful while ownsModuleSplice is true, same as the two
|
|
224
|
+
// fields above; reset in releaseVmFrame for the same pooling reason.
|
|
225
|
+
bool separateChildren = false;
|
|
222
226
|
|
|
223
227
|
// Whether callStack_.back() (at push time) genuinely IS this frame's
|
|
224
228
|
// own logical call, and therefore safe for a tail hop inside this
|
|
@@ -34,6 +34,16 @@ struct CSGNode {
|
|
|
34
34
|
CSGParams params; // resolve step's plain-data output
|
|
35
35
|
bool uncacheable = false; // set by a later phase (ManifoldCache, Phase 8)
|
|
36
36
|
|
|
37
|
+
// Set only by children(separate=true): this node begins its OWN operand
|
|
38
|
+
// group in an enclosing union/difference/intersection/intersection_for,
|
|
39
|
+
// instead of merging into the single group its enclosing statement
|
|
40
|
+
// would otherwise form. See Evaluator::appendGroupSizes.
|
|
41
|
+
//
|
|
42
|
+
// Deliberately absent from cacheKey()'s allowlist (manifold_cache.cpp):
|
|
43
|
+
// it changes the PARENT's hashed "group_sizes" param, never this node's
|
|
44
|
+
// own geometry, so the parent already re-keys and this node must not.
|
|
45
|
+
bool separateOperand = false;
|
|
46
|
+
|
|
37
47
|
// The call site that entered this node's call chain from the top
|
|
38
48
|
// level, captured at RESOLVE time -- non-owning, AST-lifetime-bound
|
|
39
49
|
// like `node`. nullptr for a node resolved at top level.
|
|
@@ -73,4 +83,12 @@ struct CSGNode {
|
|
|
73
83
|
std::optional<std::string> cachedKey;
|
|
74
84
|
};
|
|
75
85
|
|
|
86
|
+
// Marks every node from `from` onward as starting its own operand group --
|
|
87
|
+
// what children(separate=true) does to the geometry it just forwarded.
|
|
88
|
+
// A free function, not a member, so all three splice sites (user_calls.cpp
|
|
89
|
+
// and bytecode_vm.cpp's two) can reach it from this header alone.
|
|
90
|
+
inline void markSeparateOperands(std::vector<std::unique_ptr<CSGNode>>& nodes, size_t from) {
|
|
91
|
+
for (size_t i = from; i < nodes.size(); ++i) nodes[i]->separateOperand = true;
|
|
92
|
+
}
|
|
93
|
+
|
|
76
94
|
} // namespace oscadeval
|
|
@@ -190,6 +190,30 @@ public:
|
|
|
190
190
|
// statement.
|
|
191
191
|
size_t currentTreeFrameSize() const { return treeStack_.back().size(); }
|
|
192
192
|
|
|
193
|
+
// Records the group(s) one child statement contributed, given the frame
|
|
194
|
+
// size captured before it ran. Normally that is exactly one group, of
|
|
195
|
+
// however many nodes the statement pushed -- including a group of size
|
|
196
|
+
// ZERO for a statement that produced no geometry (a disabled `*cube()`),
|
|
197
|
+
// which generateCsg relies on to reset intersection() and to bail
|
|
198
|
+
// difference(). Only children(separate=true) produces more than one:
|
|
199
|
+
// each node it marked starts a fresh group, so its forwarded children
|
|
200
|
+
// reach the enclosing operator as separate operands.
|
|
201
|
+
//
|
|
202
|
+
// Shared by all four group builders -- resolveCsg, resolveIntersectionFor
|
|
203
|
+
// and the VM's Op::CsgGroupEnd (which serves both) -- because
|
|
204
|
+
// "group_sizes" is otherwise built twice, once per engine, and would
|
|
205
|
+
// drift.
|
|
206
|
+
void appendGroupSizes(std::vector<Value>& groupSizes, size_t before) const {
|
|
207
|
+
const std::vector<std::unique_ptr<CSGNode>>& frame = treeStack_.back();
|
|
208
|
+
size_t start = before;
|
|
209
|
+
for (size_t i = before + 1; i < frame.size(); ++i) {
|
|
210
|
+
if (!frame[i]->separateOperand) continue;
|
|
211
|
+
groupSizes.push_back(Value{static_cast<double>(i - start)});
|
|
212
|
+
start = i;
|
|
213
|
+
}
|
|
214
|
+
groupSizes.push_back(Value{static_cast<double>(frame.size() - start)});
|
|
215
|
+
}
|
|
216
|
+
|
|
193
217
|
// Generate pass: walks `tree` bottom-up (children before their own
|
|
194
218
|
// node), calling each node's registered GenerateFn (falling back to
|
|
195
219
|
// concatenating children's bodies for a kind with none registered).
|
|
@@ -342,6 +366,11 @@ public:
|
|
|
342
366
|
struct ChildrenForward {
|
|
343
367
|
EvalContext evalCtx;
|
|
344
368
|
std::vector<const oscad::ASTNode*> nodes;
|
|
369
|
+
// children(separate=true): hand these to the enclosing union/
|
|
370
|
+
// difference/intersection as SEPARATE operands rather than as one
|
|
371
|
+
// grouped operand. Acted on after the nodes are evaluated, by
|
|
372
|
+
// marking the CSGNodes they produced -- see markSeparateOperands.
|
|
373
|
+
bool separate = false;
|
|
345
374
|
};
|
|
346
375
|
std::optional<ChildrenForward> prepareChildrenForward(const CallArgs& args, EvalContext& ctx);
|
|
347
376
|
|
|
@@ -970,8 +999,13 @@ public:
|
|
|
970
999
|
// (evalModularCall's OWN "is this splice or wrap-as-a-tagged-node"
|
|
971
1000
|
// branch already decided `splice` before ever reaching a user module,
|
|
972
1001
|
// so this helper never needs that decision itself).
|
|
1002
|
+
// `honorSeparateMarks` is true only for a children() call's OWN splice.
|
|
1003
|
+
// A user module's splice passes false, so it wraps its marked children
|
|
1004
|
+
// as usual and the marks stop there -- children(separate=true) applies
|
|
1005
|
+
// to the operator enclosing that call, not to whatever encloses the
|
|
1006
|
+
// module the call happens to sit in.
|
|
973
1007
|
void spliceModuleChildren(std::vector<std::unique_ptr<CSGNode>> children, std::uint64_t randsBefore,
|
|
974
|
-
const oscad::ASTNode& callNode);
|
|
1008
|
+
const oscad::ASTNode& callNode, bool honorSeparateMarks = false);
|
|
975
1009
|
private:
|
|
976
1010
|
Value evalUserFunction(const std::string& name, const oscad::FunctionDeclaration& decl,
|
|
977
1011
|
const std::vector<std::unique_ptr<oscad::Argument>>& arguments, EvalContext& ctx,
|
|
@@ -68,7 +68,12 @@ std::optional<manifold::CrossSection> toCrossSection(const std::vector<ColoredBo
|
|
|
68
68
|
// operand (unioned together), and each subsequent statement's bodies are
|
|
69
69
|
// unioned then subtracted -- a flat evaluation would lose this grouping and
|
|
70
70
|
// misbehave when e.g. BOSL2's attachable() returns multiple bodies (parent
|
|
71
|
-
// + attached children) as one operand.
|
|
71
|
+
// + attached children) as one operand.
|
|
72
|
+
//
|
|
73
|
+
// One statement can contribute MORE than one group: children(separate=true)
|
|
74
|
+
// marks the nodes it forwards so each starts its own operand group, which is
|
|
75
|
+
// how `difference() children(separate=true)` subtracts children 1..n from
|
|
76
|
+
// child 0. See Evaluator::appendGroupSizes, which both engines share. Mirrors _resolve_csg/_generate_csg,
|
|
72
77
|
// minus _attach_tri_colors' multi-color-merge provenance (ponytail: a
|
|
73
78
|
// merged body always takes its first contributing child's color, matching
|
|
74
79
|
// this evaluator's own pre-tri_colors baseline behavior -- revisit
|
|
@@ -101,8 +106,7 @@ CSGParams resolveCsg(Evaluator& ev, const oscad::ModularCall& node, EvalContext&
|
|
|
101
106
|
for (const oscad::ASTNode* geoNode : geoNodes) {
|
|
102
107
|
const size_t before = ev.currentTreeFrameSize();
|
|
103
108
|
ev.evalChildren(std::vector<const oscad::ASTNode*>{geoNode}, effCtx);
|
|
104
|
-
|
|
105
|
-
groupSizes.push_back(Value{static_cast<double>(after - before)});
|
|
109
|
+
ev.appendGroupSizes(groupSizes, before);
|
|
106
110
|
}
|
|
107
111
|
|
|
108
112
|
CSGParams params;
|
|
@@ -119,8 +119,7 @@ CSGParams resolveIntersectionFor(Evaluator& ev, const oscad::ModularIntersection
|
|
|
119
119
|
if (!bodyNodes.empty()) ev.checkDebug(*bodyNodes.front(), parentCtx, /*forced=*/false, /*exprLevel=*/true);
|
|
120
120
|
const size_t before = ev.currentTreeFrameSize();
|
|
121
121
|
ev.evalChildren(bodyNodes, parentCtx);
|
|
122
|
-
|
|
123
|
-
groupSizes.push_back(Value{static_cast<double>(after - before)});
|
|
122
|
+
ev.appendGroupSizes(groupSizes, before);
|
|
124
123
|
return;
|
|
125
124
|
}
|
|
126
125
|
const auto& assign = node.assignments[depth];
|
|
@@ -112,7 +112,7 @@ const std::vector<std::string>* builtinParamNames(const std::string& name) {
|
|
|
112
112
|
{"intersection", {}},
|
|
113
113
|
{"hull", {}},
|
|
114
114
|
{"minkowski", {"convexity"}},
|
|
115
|
-
{"children", {"index"}},
|
|
115
|
+
{"children", {"index", "separate"}},
|
|
116
116
|
{"render", {"convexity"}},
|
|
117
117
|
// "repair" is this port's own addition, not an upstream parameter.
|
|
118
118
|
{"import",
|
|
@@ -360,7 +360,7 @@ void pushBracketedModuleFrame(Evaluator& ev, const CompiledChunk& chunk, const o
|
|
|
360
360
|
// because module chunks never contain tail-call opcodes); don't inherit
|
|
361
361
|
// a pooled function frame's stale true here either.
|
|
362
362
|
void pushChildrenForwardFrame(Evaluator& ev, const CompiledChunk& chunk, EvalContext evalCtx,
|
|
363
|
-
std::uint64_t randsBefore, const oscad::ASTNode& callNode) {
|
|
363
|
+
std::uint64_t randsBefore, const oscad::ASTNode& callNode, bool separate) {
|
|
364
364
|
if (ev.vmCallStack_.size() >= Evaluator::kMaxVmCallStackDepth) {
|
|
365
365
|
ev.error("Recursion too deep while forwarding children()", callNode);
|
|
366
366
|
}
|
|
@@ -381,6 +381,7 @@ void pushChildrenForwardFrame(Evaluator& ev, const CompiledChunk& chunk, EvalCon
|
|
|
381
381
|
frame->ownsModuleSplice = true;
|
|
382
382
|
frame->moduleRandsBefore = randsBefore;
|
|
383
383
|
frame->moduleSpliceCallNode = &callNode;
|
|
384
|
+
frame->separateChildren = separate;
|
|
384
385
|
ev.vmCallStack_.push_back(std::move(frame));
|
|
385
386
|
ev.vmCallBrackets_.emplace_back(std::nullopt);
|
|
386
387
|
}
|
|
@@ -505,6 +506,7 @@ Value driveVm(Evaluator& ev, size_t floor) {
|
|
|
505
506
|
const bool ownsModuleSplice = finished->ownsModuleSplice;
|
|
506
507
|
const std::uint64_t moduleRandsBefore = finished->moduleRandsBefore;
|
|
507
508
|
const oscad::ASTNode* moduleSpliceCallNode = finished->moduleSpliceCallNode;
|
|
509
|
+
const bool separateChildren = finished->separateChildren;
|
|
508
510
|
while (!finished->ctxChain.empty()) finished->ctxChain.pop_back();
|
|
509
511
|
// Module frames never fire returnHook (native evalUserModule
|
|
510
512
|
// never did either -- a module call has no "return value"
|
|
@@ -514,7 +516,12 @@ Value driveVm(Evaluator& ev, size_t floor) {
|
|
|
514
516
|
if (isModule && ownsModuleSplice) {
|
|
515
517
|
std::vector<std::unique_ptr<CSGNode>> children = std::move(ev.treeStack_.back());
|
|
516
518
|
ev.treeStack_.pop_back();
|
|
517
|
-
|
|
519
|
+
// separateChildren is set only by pushChildrenForwardFrame,
|
|
520
|
+
// so it also answers "is this a children() splice?" -- a
|
|
521
|
+
// user module's frame always passes false and wraps.
|
|
522
|
+
if (separateChildren) markSeparateOperands(children, 0);
|
|
523
|
+
ev.spliceModuleChildren(std::move(children), moduleRandsBefore, *moduleSpliceCallNode,
|
|
524
|
+
/*honorSeparateMarks=*/separateChildren);
|
|
518
525
|
}
|
|
519
526
|
if (isFloorFrame) {
|
|
520
527
|
finalResult = std::move(result); // unused by a module caller (runCompiledModuleBody ignores it)
|
|
@@ -1023,6 +1030,11 @@ Value driveVm(Evaluator& ev, size_t floor) {
|
|
|
1023
1030
|
static_cast<const oscad::ModularCall*>(f.chunk->nativeStatements[static_cast<size_t>(ins.a)]);
|
|
1024
1031
|
EvalContext scopedCtx = ctx.withScope(callNode->scope() ? callNode->scope() : ctx.scope);
|
|
1025
1032
|
ev.checkDebug(*callNode, scopedCtx);
|
|
1033
|
+
// Same order as evalModularCall's own (csg_resolve.cpp):
|
|
1034
|
+
// warn, then resolve. Without this a children() typo
|
|
1035
|
+
// warns only under the interpreter, so no test for that
|
|
1036
|
+
// warning could run under both engines.
|
|
1037
|
+
warnUnexpectedBuiltinArgs(ev, *callNode);
|
|
1026
1038
|
const std::uint64_t randsBefore = ev.randsCallCount();
|
|
1027
1039
|
auto [args, effCtx] = resolveCallArgs(ev, callNode->arguments, scopedCtx);
|
|
1028
1040
|
std::optional<Evaluator::ChildrenForward> fwd = ev.prepareChildrenForward(args, effCtx);
|
|
@@ -1039,9 +1051,11 @@ Value driveVm(Evaluator& ev, size_t floor) {
|
|
|
1039
1051
|
const CompiledChunk* chunk = (ev.useBytecodeVm() && ev.inResolvePass())
|
|
1040
1052
|
? ev.lookupOrCompileChildrenListChunk(fwd->nodes)
|
|
1041
1053
|
: nullptr;
|
|
1054
|
+
// Read before fwd->evalCtx is moved from.
|
|
1055
|
+
const bool separate = fwd->separate;
|
|
1042
1056
|
if (chunk) {
|
|
1043
1057
|
ev.treeStack_.emplace_back();
|
|
1044
|
-
pushChildrenForwardFrame(ev, *chunk, std::move(fwd->evalCtx), randsBefore, *callNode);
|
|
1058
|
+
pushChildrenForwardFrame(ev, *chunk, std::move(fwd->evalCtx), randsBefore, *callNode, separate);
|
|
1045
1059
|
// f.pc deliberately NOT advanced -- resumes when
|
|
1046
1060
|
// the pushed frame completes; driveVm's completion
|
|
1047
1061
|
// branch runs the splice (isModule &&
|
|
@@ -1065,7 +1079,9 @@ Value driveVm(Evaluator& ev, size_t floor) {
|
|
|
1065
1079
|
}
|
|
1066
1080
|
std::vector<std::unique_ptr<CSGNode>> children = std::move(ev.treeStack_.back());
|
|
1067
1081
|
ev.treeStack_.pop_back();
|
|
1068
|
-
|
|
1082
|
+
if (separate) markSeparateOperands(children, 0);
|
|
1083
|
+
ev.spliceModuleChildren(std::move(children), randsBefore, *callNode,
|
|
1084
|
+
/*honorSeparateMarks=*/true);
|
|
1069
1085
|
++f.pc;
|
|
1070
1086
|
}
|
|
1071
1087
|
break;
|
|
@@ -1304,8 +1320,7 @@ Value driveVm(Evaluator& ev, size_t floor) {
|
|
|
1304
1320
|
}
|
|
1305
1321
|
case Op::CsgGroupEnd: {
|
|
1306
1322
|
PendingCsgWrap& pending = f.csgWrapStack.back();
|
|
1307
|
-
|
|
1308
|
-
pending.groupSizes.push_back(Value{static_cast<double>(after - pending.groupStartSize)});
|
|
1323
|
+
ev.appendGroupSizes(pending.groupSizes, pending.groupStartSize);
|
|
1309
1324
|
++f.pc;
|
|
1310
1325
|
break;
|
|
1311
1326
|
}
|
|
@@ -126,9 +126,10 @@ void Evaluator::evalModularCall(const oscad::ModularCall& node, EvalContext& ctx
|
|
|
126
126
|
// under a synthetic (display-only, is_builtin=false) "union" node so
|
|
127
127
|
// the tree still reads as one shape at this call site. Mirrors
|
|
128
128
|
// _eval_statement's splice branch exactly.
|
|
129
|
-
const bool
|
|
129
|
+
const bool isChildrenCall = (name == "children" && isBuiltin);
|
|
130
|
+
const bool splice = isChildrenCall || !isBuiltin;
|
|
130
131
|
if (splice) {
|
|
131
|
-
spliceModuleChildren(std::move(children), randsBefore, node);
|
|
132
|
+
spliceModuleChildren(std::move(children), randsBefore, node, isChildrenCall);
|
|
132
133
|
return;
|
|
133
134
|
}
|
|
134
135
|
|
|
@@ -147,7 +148,7 @@ void Evaluator::evalModularCall(const oscad::ModularCall& node, EvalContext& ctx
|
|
|
147
148
|
}
|
|
148
149
|
|
|
149
150
|
void Evaluator::spliceModuleChildren(std::vector<std::unique_ptr<CSGNode>> children, std::uint64_t randsBefore,
|
|
150
|
-
const oscad::ASTNode& callNode) {
|
|
151
|
+
const oscad::ASTNode& callNode, bool honorSeparateMarks) {
|
|
151
152
|
if (randsCallCount_ != randsBefore) {
|
|
152
153
|
// rands() fired directly during *this* call's own resolve (e.g. an
|
|
153
154
|
// assignment before any geometry statement in a user module's
|
|
@@ -158,7 +159,23 @@ void Evaluator::spliceModuleChildren(std::vector<std::unique_ptr<CSGNode>> child
|
|
|
158
159
|
// landed on.
|
|
159
160
|
for (auto& c : children) c->uncacheable = true;
|
|
160
161
|
}
|
|
161
|
-
|
|
162
|
+
// children(separate=true) marked these to start their own operand
|
|
163
|
+
// groups, and the group walk only inspects the enclosing frame's top
|
|
164
|
+
// level -- so the wrapper would hide the marks. Splice instead.
|
|
165
|
+
//
|
|
166
|
+
// Only for the children() call's own splice. A USER MODULE wrapping
|
|
167
|
+
// such a call wraps as usual, which hides the marks and is exactly what
|
|
168
|
+
// makes separateness stop at the module boundary:
|
|
169
|
+
//
|
|
170
|
+
// module pass() { children(separate=true); }
|
|
171
|
+
// difference() pass() { a; b; } // a | b, not a - b
|
|
172
|
+
//
|
|
173
|
+
// pass() is its own shape; that it happens to forward its children
|
|
174
|
+
// separately is its business, not its caller's.
|
|
175
|
+
const bool anySeparate =
|
|
176
|
+
honorSeparateMarks &&
|
|
177
|
+
std::any_of(children.begin(), children.end(), [](const auto& c) { return c->separateOperand; });
|
|
178
|
+
if (children.size() > 1 && !anySeparate) {
|
|
162
179
|
auto unionNode = std::make_unique<CSGNode>();
|
|
163
180
|
unionNode->kind = "union";
|
|
164
181
|
unionNode->node = &callNode;
|
|
@@ -309,12 +309,14 @@ Value Evaluator::applyRange(const Value& startV, const Value& endV, const Value&
|
|
|
309
309
|
// here, at construction, because that is where the reference reports it:
|
|
310
310
|
// `r = [5:0];` warns even if nothing ever iterates r.
|
|
311
311
|
//
|
|
312
|
-
//
|
|
313
|
-
//
|
|
314
|
-
//
|
|
315
|
-
//
|
|
316
|
-
//
|
|
317
|
-
//
|
|
312
|
+
// ponytail: only an IMPLICIT step is checked -- a deliberate divergence
|
|
313
|
+
// from the reference, which warns for [5:1:0] and [0:-1:5] as well.
|
|
314
|
+
// Writing the step out is taken as a statement of intent; the warning is
|
|
315
|
+
// for the author who wrote [5:0] meaning [5:-1:0] and got a silent empty
|
|
316
|
+
// loop. An implicit step is always exactly 1, so the reference's other
|
|
317
|
+
// wording ("begin is smaller than the end, but step is negative") cannot
|
|
318
|
+
// arise here and no longer exists in this port -- if it is ever needed
|
|
319
|
+
// again, this gate has been widened back to explicit steps.
|
|
318
320
|
//
|
|
319
321
|
// The epsilon matches the one the iteration path used before this check
|
|
320
322
|
// moved here, so a range built from float arithmetic that lands a hair
|
|
@@ -179,6 +179,7 @@ void Evaluator::releaseVmFrame(std::unique_ptr<VmFrame> frame) {
|
|
|
179
179
|
frame->ownsModuleSplice = false;
|
|
180
180
|
frame->moduleRandsBefore = 0;
|
|
181
181
|
frame->moduleSpliceCallNode = nullptr;
|
|
182
|
+
frame->separateChildren = false;
|
|
182
183
|
vmFramePool_.push_back(std::move(frame));
|
|
183
184
|
}
|
|
184
185
|
|
|
@@ -932,6 +933,11 @@ Value Evaluator::parentModuleName(int idx) const {
|
|
|
932
933
|
|
|
933
934
|
std::optional<Evaluator::ChildrenForward> Evaluator::prepareChildrenForward(const CallArgs& args, EvalContext& ctx) {
|
|
934
935
|
Value idxArg = getArg(args, 0, "index", Value{});
|
|
936
|
+
// Positional slot 1 is accepted as well as the name: adding "separate"
|
|
937
|
+
// to the builtin's parameter list already suppresses the "Too many
|
|
938
|
+
// unnamed arguments" warning for children(0, true), so reading it
|
|
939
|
+
// named-only would silently ignore an argument the author wrote.
|
|
940
|
+
const bool separate = truthy(getArg(args, 1, "separate", Value{false}));
|
|
935
941
|
if (!ctx.childrenNodes || ctx.childrenNodes->empty()) return std::nullopt;
|
|
936
942
|
const EvalContext* callerCtx = ctx.childrenCallerCtx;
|
|
937
943
|
if (!callerCtx) return std::nullopt;
|
|
@@ -977,7 +983,7 @@ std::optional<Evaluator::ChildrenForward> Evaluator::prepareChildrenForward(cons
|
|
|
977
983
|
}
|
|
978
984
|
|
|
979
985
|
if (std::holds_alternative<std::monostate>(idxArg)) {
|
|
980
|
-
return ChildrenForward{std::move(evalCtx), *ctx.childrenNodes};
|
|
986
|
+
return ChildrenForward{std::move(evalCtx), *ctx.childrenNodes, separate};
|
|
981
987
|
}
|
|
982
988
|
|
|
983
989
|
// children(N) indexes child *statements*, not output bodies -- a
|
|
@@ -1041,13 +1047,15 @@ std::optional<Evaluator::ChildrenForward> Evaluator::prepareChildrenForward(cons
|
|
|
1041
1047
|
picked.push_back(geoNodes[static_cast<size_t>(idx)]);
|
|
1042
1048
|
}
|
|
1043
1049
|
if (picked.empty()) return std::nullopt;
|
|
1044
|
-
return ChildrenForward{std::move(evalCtx), std::move(picked)};
|
|
1050
|
+
return ChildrenForward{std::move(evalCtx), std::move(picked), separate};
|
|
1045
1051
|
}
|
|
1046
1052
|
|
|
1047
1053
|
void Evaluator::builtinChildren(const CallArgs& args, EvalContext& ctx) {
|
|
1048
1054
|
std::optional<ChildrenForward> fwd = prepareChildrenForward(args, ctx);
|
|
1049
1055
|
if (!fwd) return;
|
|
1056
|
+
const size_t before = currentTreeFrameSize();
|
|
1050
1057
|
evalChildren(fwd->nodes, fwd->evalCtx);
|
|
1058
|
+
if (fwd->separate) markSeparateOperands(treeStack_.back(), before);
|
|
1051
1059
|
}
|
|
1052
1060
|
|
|
1053
1061
|
} // namespace oscadeval
|