openscad-cpp-evaluator 1.49.2__tar.gz → 1.49.4__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-1.49.2 → openscad_cpp_evaluator-1.49.4}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/bytecode.hpp +4 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/evaluator.hpp +16 -0
- openscad_cpp_evaluator-1.49.4/include/openscad_cpp_evaluator/reassign.hpp +61 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/bytecode_compiler.cpp +5 -1
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/csg_resolve.cpp +1 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/eval_use.cpp +59 -3
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/stmt_eval.cpp +32 -1
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/user_calls.cpp +13 -2
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_scoping.cpp +32 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_use.cpp +31 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/uv.lock +1 -1
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/.gitignore +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/.gitmodules +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/LICENSE +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/README.md +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/cmake/patch_manifold.cmake +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/LICENSE +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/.DS_Store +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_concurrent_parse.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/resources/fonts/LiberationSans-Bold.ttf +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/resources/fonts/LiberationSans-Italic.ttf +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/dxf_dim.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/bytecode_vm.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/format_closure.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/import/scene_import.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/utf8.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/xkcd_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/xkcd_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_children_separate.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_discretizer.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_feature_detection.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_include_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_openscad_parity.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_profile_time.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_undef_args.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/tools/cli/main.cpp +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
3
|
#include "openscad_cpp_evaluator/function_builtins.hpp"
|
|
4
|
+
#include "openscad_cpp_evaluator/reassign.hpp"
|
|
4
5
|
#include "openscad_cpp_evaluator/value.hpp"
|
|
5
6
|
|
|
6
7
|
#include "openscad_cpp_parser/ast/ast_node.hpp"
|
|
@@ -756,6 +757,9 @@ struct CompiledChunk {
|
|
|
756
757
|
// with how many: the Evaluator warns for them once, when the chunk is
|
|
757
758
|
// compiled (it has the warning channel; the compiler does not).
|
|
758
759
|
std::vector<std::pair<const oscad::StringLiteral*, int>> undefinedEscapeLiterals;
|
|
760
|
+
// Reassignments merged in the statement lists compiled into this chunk
|
|
761
|
+
// (see mergeReassignments), warned about the same way.
|
|
762
|
+
std::vector<Reassignment> reassignments;
|
|
759
763
|
struct Param {
|
|
760
764
|
std::string name;
|
|
761
765
|
int slot = 0; // unused when isDyn is true -- $-params are never slot-addressed
|
|
@@ -592,8 +592,11 @@ public:
|
|
|
592
592
|
return false;
|
|
593
593
|
}
|
|
594
594
|
std::unordered_set<const oscad::StringLiteral*> undefinedEscapesWarned_;
|
|
595
|
+
// Warnings a chunk's compile found, given once it is built: undefined
|
|
596
|
+
// string escapes, and reassignments its statement lists merged.
|
|
595
597
|
void warnUndefinedEscapes(const CompiledChunk& chunk) {
|
|
596
598
|
for (const auto& [lit, n] : chunk.undefinedEscapeLiterals) warnUndefinedEscapes(*lit, n);
|
|
599
|
+
for (const Reassignment& r : chunk.reassignments) warnReassignment(r);
|
|
597
600
|
}
|
|
598
601
|
// Hands one already-formatted warning line to echoFn_, recording it in
|
|
599
602
|
// warnCapture first when one is active. Every warning path goes through
|
|
@@ -1393,6 +1396,19 @@ private:
|
|
|
1393
1396
|
};
|
|
1394
1397
|
std::unordered_map<std::pair<const oscad::ASTNode*, size_t>, std::optional<CompiledChunk>, ChildrenListKeyHash>
|
|
1395
1398
|
childrenListChunkCache_;
|
|
1399
|
+
// A statement list with its reassignments merged (see
|
|
1400
|
+
// mergedStatementList), or nullopt when it has none -- the common
|
|
1401
|
+
// case, which then costs one lookup. Same key, same clearing, same
|
|
1402
|
+
// dangling-pointer reasoning as childrenListChunkCache_ above.
|
|
1403
|
+
std::unordered_map<std::pair<const oscad::ASTNode*, size_t>, std::optional<std::vector<const oscad::ASTNode*>>,
|
|
1404
|
+
ChildrenListKeyHash>
|
|
1405
|
+
mergedListCache_;
|
|
1406
|
+
// "origin:line:name" of each reassignment already warned about, so a
|
|
1407
|
+
// cleared mergedListCache_ never warns twice. Strings, not node
|
|
1408
|
+
// pointers: these outlive the ASTs the cache is cleared for.
|
|
1409
|
+
std::unordered_set<std::string> warnedReassignments_;
|
|
1410
|
+
const std::vector<const oscad::ASTNode*>& mergedStatementList(const std::vector<const oscad::ASTNode*>& children);
|
|
1411
|
+
void warnReassignment(const Reassignment& r);
|
|
1396
1412
|
|
|
1397
1413
|
// See stmtExprChunkCache_'s own doc comment, immediately above, for why
|
|
1398
1414
|
// this exists. Not a reentrancy guard (resolveTreeImpl is never called
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "openscad_cpp_parser/ast/expression.hpp"
|
|
4
|
+
#include "openscad_cpp_parser/position.hpp"
|
|
5
|
+
|
|
6
|
+
#include <optional>
|
|
7
|
+
#include <string>
|
|
8
|
+
#include <unordered_map>
|
|
9
|
+
#include <utility>
|
|
10
|
+
#include <vector>
|
|
11
|
+
|
|
12
|
+
namespace oscadeval {
|
|
13
|
+
|
|
14
|
+
// One name assigned again in the same statement list.
|
|
15
|
+
struct Reassignment {
|
|
16
|
+
std::string name;
|
|
17
|
+
const oscad::Position* first; // where the variable is evaluated
|
|
18
|
+
const oscad::Position* here; // the assignment whose value it takes
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// OpenSCAD's handle_assignment (parser.y): a name assigned twice in one
|
|
22
|
+
// statement list is ONE assignment, made where it was FIRST assigned but
|
|
23
|
+
// with the LAST expression. `x = 1; y = x * 10; x = 2;` gives y = 20.
|
|
24
|
+
// Running them in order gave 10 -- and with include<> spliced into the top
|
|
25
|
+
// level, that broke the usual way of configuring a library (include it,
|
|
26
|
+
// then override its defaults) for every value the library derives from one
|
|
27
|
+
// (BelfrySCAD #809).
|
|
28
|
+
//
|
|
29
|
+
// Returns the merged list -- the last assignment's node in the first one's
|
|
30
|
+
// place, later slots dropped -- or nullopt when nothing repeats. ASTs are
|
|
31
|
+
// shared and never modified; only this list of pointers changes. Each merge
|
|
32
|
+
// is appended to `found` for the caller to warn about.
|
|
33
|
+
inline std::optional<std::vector<const oscad::ASTNode*>> mergeReassignments(
|
|
34
|
+
const std::vector<const oscad::ASTNode*>& stmts, std::vector<Reassignment>* found = nullptr) {
|
|
35
|
+
if (stmts.size() < 2) return std::nullopt;
|
|
36
|
+
std::vector<const oscad::ASTNode*> out;
|
|
37
|
+
out.reserve(stmts.size());
|
|
38
|
+
std::unordered_map<std::string, std::pair<size_t, const oscad::Position*>> seen;
|
|
39
|
+
bool merged = false;
|
|
40
|
+
for (const oscad::ASTNode* node : stmts) {
|
|
41
|
+
if (node->kind() != oscad::NodeKind::Assignment) {
|
|
42
|
+
out.push_back(node);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const auto& a = static_cast<const oscad::Assignment&>(*node);
|
|
46
|
+
const std::string& name = a.name->name;
|
|
47
|
+
auto it = seen.find(name);
|
|
48
|
+
if (it == seen.end()) {
|
|
49
|
+
seen.emplace(name, std::make_pair(out.size(), &a.position()));
|
|
50
|
+
out.push_back(node);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (found) found->push_back({name, it->second.second, &a.position()});
|
|
54
|
+
out[it->second.first] = node;
|
|
55
|
+
merged = true;
|
|
56
|
+
}
|
|
57
|
+
if (!merged) return std::nullopt;
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
} // namespace oscadeval
|
|
@@ -1283,7 +1283,11 @@ public:
|
|
|
1283
1283
|
// necessarily one this Compiler's own declaration owns) -- see
|
|
1284
1284
|
// tryCompileChildrenList's own doc comment, below, for the entry point
|
|
1285
1285
|
// that needs this shape directly.
|
|
1286
|
-
void compileStatementList(const std::vector<const oscad::ASTNode*>&
|
|
1286
|
+
void compileStatementList(const std::vector<const oscad::ASTNode*>& childrenIn, std::vector<Instruction>& out) {
|
|
1287
|
+
// Reassignments merged first, as Evaluator::evalChildren does for the
|
|
1288
|
+
// interpreted path: a list compiled inline here never reaches it.
|
|
1289
|
+
const auto merged = mergeReassignments(childrenIn, &chunk_.reassignments);
|
|
1290
|
+
const std::vector<const oscad::ASTNode*>& children = merged ? *merged : childrenIn;
|
|
1287
1291
|
std::vector<const oscad::ASTNode*> assignments;
|
|
1288
1292
|
std::vector<const oscad::ASTNode*> others;
|
|
1289
1293
|
for (const oscad::ASTNode* c : children) {
|
|
@@ -247,6 +247,7 @@ std::vector<std::unique_ptr<CSGNode>> Evaluator::resolveTreeImpl(const NodeList&
|
|
|
247
247
|
stmtExprChunkCache_.clear();
|
|
248
248
|
assignBlockChunkCache_.clear();
|
|
249
249
|
childrenListChunkCache_.clear();
|
|
250
|
+
mergedListCache_.clear();
|
|
250
251
|
ResolvePassGuard resolvePassGuard(inResolvePass_);
|
|
251
252
|
evalChildren(nodes, ctx);
|
|
252
253
|
std::vector<std::unique_ptr<CSGNode>> tree = std::move(treeStack_.back());
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
#include "openscad_cpp_evaluator/eval_use.hpp"
|
|
2
2
|
|
|
3
|
+
#include "openscad_cpp_evaluator/eval_error.hpp"
|
|
4
|
+
#include "openscad_cpp_evaluator/reassign.hpp"
|
|
3
5
|
#include "openscad_cpp_parser/ast/declarations.hpp"
|
|
6
|
+
#include "openscad_cpp_parser/ast/expression.hpp"
|
|
4
7
|
|
|
8
|
+
#include <filesystem>
|
|
9
|
+
#include <unordered_map>
|
|
5
10
|
#include <utility>
|
|
6
11
|
|
|
7
12
|
namespace oscadeval {
|
|
@@ -19,6 +24,55 @@ ResolvedUseScopes resolveUseScopes(const std::vector<std::unique_ptr<oscad::ASTN
|
|
|
19
24
|
|
|
20
25
|
namespace {
|
|
21
26
|
|
|
27
|
+
namespace fs = std::filesystem;
|
|
28
|
+
|
|
29
|
+
std::string normalPath(const std::string& p) {
|
|
30
|
+
std::error_code ec;
|
|
31
|
+
fs::path abs = fs::absolute(fs::path(p), ec);
|
|
32
|
+
return (ec ? fs::path(p) : abs).lexically_normal().generic_string();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Each file's top-level list, merged before any scope is built (see
|
|
36
|
+
// mergeReassignments, reassign.hpp), so the interpreter, the compiled VM
|
|
37
|
+
// and the scope tables all see one assignment per name. This is where an
|
|
38
|
+
// include<>'d library's defaults meet the main file's overrides.
|
|
39
|
+
//
|
|
40
|
+
// Warnings follow parser.y's rules exactly. The deliberate silence is the
|
|
41
|
+
// main file overriding an included file's variable: that is configuration,
|
|
42
|
+
// not a mistake. Two different included files overriding each other are
|
|
43
|
+
// silent too.
|
|
44
|
+
std::vector<const oscad::ASTNode*> mergeTopLevel(const std::vector<const oscad::ASTNode*>& nodes,
|
|
45
|
+
const std::string& mainFile,
|
|
46
|
+
const std::function<void(const std::string&)>& logFn) {
|
|
47
|
+
std::vector<Reassignment> found;
|
|
48
|
+
auto merged = mergeReassignments(nodes, &found);
|
|
49
|
+
if (!merged) return nodes;
|
|
50
|
+
const std::string main = normalPath(mainFile);
|
|
51
|
+
for (const Reassignment& r : found) {
|
|
52
|
+
const std::string prevFile = normalPath(r.first->origin);
|
|
53
|
+
const std::string currFile = normalPath(r.here->origin);
|
|
54
|
+
std::string where; // the file named in the message, if not the main one
|
|
55
|
+
bool warnIt = false;
|
|
56
|
+
if (prevFile == main && currFile == main) {
|
|
57
|
+
warnIt = true;
|
|
58
|
+
} else if (prevFile == currFile) {
|
|
59
|
+
warnIt = r.first->line != r.here->line; // equal: one file included twice
|
|
60
|
+
where = prevFile;
|
|
61
|
+
} else if (prevFile == main) {
|
|
62
|
+
warnIt = true; // the main file's value overwritten by an include
|
|
63
|
+
where = prevFile;
|
|
64
|
+
}
|
|
65
|
+
if (!warnIt || !logFn) continue;
|
|
66
|
+
std::string msg = r.name + " was assigned on line " + std::to_string(r.first->line);
|
|
67
|
+
if (!where.empty()) {
|
|
68
|
+
const fs::path rel = fs::path(where).lexically_relative(fs::path(main).parent_path());
|
|
69
|
+
msg += " of " + (rel.empty() ? where : rel.generic_string());
|
|
70
|
+
}
|
|
71
|
+
logFn(formatWarning(msg + " but was overwritten", r.here, {}));
|
|
72
|
+
}
|
|
73
|
+
return *merged;
|
|
74
|
+
}
|
|
75
|
+
|
|
22
76
|
// The recursion. `table` is threaded through every level rather than each
|
|
23
77
|
// level building its own: `use <file>` gives each used file its own root
|
|
24
78
|
// Scope, but one evaluation reads all of them back, so every node's scope
|
|
@@ -26,11 +80,13 @@ namespace {
|
|
|
26
80
|
// could not see anything a nested resolution recorded -- every node of a
|
|
27
81
|
// used file read back as having no scope, and `use` silently resolved to
|
|
28
82
|
// undef. BelfrySCAD's own suite caught that; this repo's did not.
|
|
29
|
-
ResolvedUseScopes resolveUseScopesInto(const std::vector<const oscad::ASTNode*>&
|
|
83
|
+
ResolvedUseScopes resolveUseScopesInto(const std::vector<const oscad::ASTNode*>& ownNodesIn,
|
|
30
84
|
const std::string& currentFile,
|
|
85
|
+
const std::string& mainFile,
|
|
31
86
|
const std::function<void(const std::string&)>& logFn,
|
|
32
87
|
oscad::ScopeTable& table) {
|
|
33
88
|
ResolvedUseScopes result;
|
|
89
|
+
const std::vector<const oscad::ASTNode*> ownNodes = mergeTopLevel(ownNodesIn, mainFile, logFn);
|
|
34
90
|
|
|
35
91
|
std::vector<const oscad::ASTNode*> injected;
|
|
36
92
|
// Declarations pulled in from one used file, paired with that file's
|
|
@@ -70,7 +126,7 @@ ResolvedUseScopes resolveUseScopesInto(const std::vector<const oscad::ASTNode*>&
|
|
|
70
126
|
std::vector<const oscad::ASTNode*> libBorrowed;
|
|
71
127
|
libBorrowed.reserve(libAst.size());
|
|
72
128
|
for (const auto& n : libAst) libBorrowed.push_back(n.get());
|
|
73
|
-
ResolvedUseScopes nested = resolveUseScopesInto(libBorrowed, lib.resolvedPath, logFn, table);
|
|
129
|
+
ResolvedUseScopes nested = resolveUseScopesInto(libBorrowed, lib.resolvedPath, mainFile, logFn, table);
|
|
74
130
|
|
|
75
131
|
std::vector<const oscad::ASTNode*> libInjected;
|
|
76
132
|
for (const oscad::ASTNode* n : nested.ownNodesFiltered) {
|
|
@@ -137,7 +193,7 @@ ResolvedUseScopes resolveUseScopes(const std::vector<const oscad::ASTNode*>& own
|
|
|
137
193
|
// One table for the whole resolution, handed to the root scope at the
|
|
138
194
|
// end so it lives exactly as long as the scopes it points into.
|
|
139
195
|
auto table = std::make_unique<oscad::ScopeTable>();
|
|
140
|
-
ResolvedUseScopes result = resolveUseScopesInto(ownNodes, currentFile, logFn, *table);
|
|
196
|
+
ResolvedUseScopes result = resolveUseScopesInto(ownNodes, currentFile, currentFile, logFn, *table);
|
|
141
197
|
if (result.rootScope) result.rootScope->adoptTable(std::move(table));
|
|
142
198
|
return result;
|
|
143
199
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#include "openscad_cpp_evaluator/evaluator.hpp"
|
|
2
2
|
#include "openscad_cpp_evaluator/format_closure.hpp"
|
|
3
|
+
#include "openscad_cpp_evaluator/reassign.hpp"
|
|
3
4
|
|
|
4
5
|
#include "openscad_cpp_evaluator/call_args.hpp"
|
|
5
6
|
|
|
@@ -325,7 +326,37 @@ void Evaluator::evalStatement(const oscad::ASTNode& node, EvalContext& ctx) {
|
|
|
325
326
|
}
|
|
326
327
|
}
|
|
327
328
|
|
|
328
|
-
|
|
329
|
+
// A statement list inside a module body or a block, with its reassignments
|
|
330
|
+
// merged (mergeReassignments, reassign.hpp). The top level of each file is
|
|
331
|
+
// merged once before scopes are built (eval_use.cpp); these lists live in
|
|
332
|
+
// shared, immutable ASTs, so they are merged here, as they are run, and
|
|
333
|
+
// cached. The compiler merges the lists it compiles inline itself
|
|
334
|
+
// (compileStatementList), so both paths agree.
|
|
335
|
+
const std::vector<const oscad::ASTNode*>& Evaluator::mergedStatementList(
|
|
336
|
+
const std::vector<const oscad::ASTNode*>& children) {
|
|
337
|
+
if (children.size() < 2) return children;
|
|
338
|
+
const auto key = std::make_pair(children.front(), children.size());
|
|
339
|
+
auto it = mergedListCache_.find(key);
|
|
340
|
+
if (it == mergedListCache_.end()) {
|
|
341
|
+
std::vector<Reassignment> found;
|
|
342
|
+
it = mergedListCache_.emplace(key, mergeReassignments(children, &found)).first;
|
|
343
|
+
for (const Reassignment& r : found) warnReassignment(r);
|
|
344
|
+
}
|
|
345
|
+
return it->second ? *it->second : children;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
void Evaluator::warnReassignment(const Reassignment& r) {
|
|
349
|
+
// A body is one file, so parser.y's rule reduces to: always warn (its
|
|
350
|
+
// same-line exemption is for one file included twice, which only the
|
|
351
|
+
// top level can see). Once per assignment however often its list is
|
|
352
|
+
// run or recompiled.
|
|
353
|
+
const std::string tag = r.here->origin + ":" + std::to_string(r.here->start_offset) + ":" + r.name;
|
|
354
|
+
if (!warnedReassignments_.insert(tag).second) return;
|
|
355
|
+
warn(r.name + " was assigned on line " + std::to_string(r.first->line) + " but was overwritten", r.here);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
void Evaluator::evalChildren(const std::vector<const oscad::ASTNode*>& childrenIn, EvalContext& ctx) {
|
|
359
|
+
const std::vector<const oscad::ASTNode*>& children = mergedStatementList(childrenIn);
|
|
329
360
|
// Whole-LIST compile first (see tryRunCompiledChildren's own doc
|
|
330
361
|
// comment, evaluator.hpp) -- tries the FULL `children` as one chunk
|
|
331
362
|
// before falling back to assignments-then-others below. This is what
|
|
@@ -1043,9 +1043,12 @@ std::optional<Evaluator::ChildrenForward> Evaluator::prepareChildrenForward(cons
|
|
|
1043
1043
|
// subsequent body-index lookup, so the Nth statement is evaluated
|
|
1044
1044
|
// directly instead.
|
|
1045
1045
|
std::vector<const oscad::ASTNode*> geoNodes;
|
|
1046
|
+
std::vector<const oscad::ASTNode*> assignments;
|
|
1046
1047
|
for (const oscad::ASTNode* c : *ctx.childrenNodes) {
|
|
1047
|
-
if (c->kind()
|
|
1048
|
-
c
|
|
1048
|
+
if (c->kind() == oscad::NodeKind::Assignment) {
|
|
1049
|
+
assignments.push_back(c);
|
|
1050
|
+
} else if (c->kind() != oscad::NodeKind::ModuleDeclaration &&
|
|
1051
|
+
c->kind() != oscad::NodeKind::FunctionDeclaration) {
|
|
1049
1052
|
geoNodes.push_back(c);
|
|
1050
1053
|
}
|
|
1051
1054
|
}
|
|
@@ -1112,6 +1115,14 @@ std::optional<Evaluator::ChildrenForward> Evaluator::prepareChildrenForward(cons
|
|
|
1112
1115
|
pickedIndices.push_back(static_cast<size_t>(idx));
|
|
1113
1116
|
}
|
|
1114
1117
|
if (picked.empty()) return std::nullopt;
|
|
1118
|
+
// The picked statement runs in its block's scope, so the block's
|
|
1119
|
+
// assignments must be in it: `m() { n = 2; for (i=[0:n]) ...; }` with
|
|
1120
|
+
// `children(0)` in m() read n as unknown (#815, BOSL2's attachable()).
|
|
1121
|
+
// evalChildren runs them into evalCtx's let_, which the picked
|
|
1122
|
+
// statements' scopes share (withScope).
|
|
1123
|
+
// ponytail: a children(i, separate=true) expansion prepares twice, so a
|
|
1124
|
+
// side effect in one of these assignments (echo, rands) runs twice there.
|
|
1125
|
+
if (!assignments.empty()) evalChildren(assignments, evalCtx);
|
|
1115
1126
|
return ChildrenForward{std::move(evalCtx), std::move(picked), separate, std::move(pickedIndices)};
|
|
1116
1127
|
}
|
|
1117
1128
|
|
|
@@ -195,3 +195,35 @@ TEST(SpecialVariables, PreviewIsAlwaysFalse) {
|
|
|
195
195
|
ASSERT_EQ(msgs.size(), 1u) << (msgs.empty() ? "" : msgs[0]);
|
|
196
196
|
EXPECT_EQ(msgs[0], "ECHO: false, true, \"r\"");
|
|
197
197
|
}
|
|
198
|
+
|
|
199
|
+
// OpenSCAD evaluates a reassigned variable once, at its FIRST assignment,
|
|
200
|
+
// with its LAST value (parser.y's handle_assignment) -- in a module body or
|
|
201
|
+
// a block as at the top level. Checked against OpenSCAD 2026.02.01.
|
|
202
|
+
TEST(Scoping, ReassignedVariableTakesItsLastValueAtItsFirstPosition) {
|
|
203
|
+
std::vector<std::string> out;
|
|
204
|
+
evaluateSrc("x = 1;\ny = x * 10;\nx = 2;\necho(y = y);\n"
|
|
205
|
+
"module m() {\n u = 1;\n v = u * 10;\n u = 2;\n echo(v = v);\n}\nm();\n"
|
|
206
|
+
"if (true) { a = 1; b = a + 1; a = 5; echo(b = b); }\n",
|
|
207
|
+
[&](const std::string& m) { out.push_back(m); });
|
|
208
|
+
EXPECT_TRUE(anyContains(out, "ECHO: y = 20"));
|
|
209
|
+
EXPECT_TRUE(anyContains(out, "ECHO: v = 20"));
|
|
210
|
+
EXPECT_TRUE(anyContains(out, "ECHO: b = 6"));
|
|
211
|
+
size_t warnings = 0;
|
|
212
|
+
for (const auto& m : out) warnings += m.find("but was overwritten") != std::string::npos;
|
|
213
|
+
EXPECT_EQ(warnings, 3u) << "one per reassignment, even though m() could run again";
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// #815: BOSL2's attachable() runs its children by index, and children(N)
|
|
217
|
+
// used to skip the child block's assignments, so `last` was unknown.
|
|
218
|
+
TEST(Scoping, IndexedChildrenSeeTheirBlocksAssignments) {
|
|
219
|
+
std::vector<std::string> out;
|
|
220
|
+
evaluateSrc("module one() children(0);\n"
|
|
221
|
+
"module both() { children(1); children([0:1]); }\n"
|
|
222
|
+
"one() { n = 2; for (i = [0:n]) echo(a = i); }\n"
|
|
223
|
+
"both() { k = 3; echo(b = k); echo(c = k + 1); }\n",
|
|
224
|
+
[&](const std::string& m) { out.push_back(m); });
|
|
225
|
+
EXPECT_TRUE(anyContains(out, "ECHO: a = 2"));
|
|
226
|
+
EXPECT_TRUE(anyContains(out, "ECHO: b = 3"));
|
|
227
|
+
EXPECT_TRUE(anyContains(out, "ECHO: c = 4"));
|
|
228
|
+
EXPECT_FALSE(anyContains(out, "unknown variable"));
|
|
229
|
+
}
|
|
@@ -173,3 +173,34 @@ TEST(UseStatement, MainFileGlobalReadFromFunctionIsStable) {
|
|
|
173
173
|
EXPECT_EQ(echoed[2], "ECHO: undef");
|
|
174
174
|
std::filesystem::remove(main);
|
|
175
175
|
}
|
|
176
|
+
|
|
177
|
+
// BelfrySCAD #809: OpenSCAD evaluates a reassigned variable at its FIRST
|
|
178
|
+
// assignment with its LAST value, so a main file overriding an included
|
|
179
|
+
// library's default changes everything the library derives from it -- the
|
|
180
|
+
// standard way to configure a library. And it says nothing: overriding an
|
|
181
|
+
// included file's variable is configuration, not a mistake. Expected values
|
|
182
|
+
// and warnings checked against OpenSCAD 2026.02.01.
|
|
183
|
+
TEST(IncludeReassignment, MainFileOverrideReachesValuesTheLibraryDerives) {
|
|
184
|
+
auto lib = writeFile("reassign_lib.scad", "x = 1;\ny = x * 10;\no = object(k = 5);\np = o.k;\n");
|
|
185
|
+
auto main = writeFile("reassign_main.scad", "include <" + lib.string() + ">\n"
|
|
186
|
+
"x = 2;\no = object(k = 7);\necho(y = y, p = p);\n");
|
|
187
|
+
std::vector<std::string> out;
|
|
188
|
+
evalFile(main, [&](const std::string& m) { out.push_back(m); });
|
|
189
|
+
ASSERT_EQ(out.size(), 1u) << "no warnings: overriding an include is configuration";
|
|
190
|
+
EXPECT_EQ(out[0], "ECHO: y = 20, p = 7");
|
|
191
|
+
std::filesystem::remove(lib);
|
|
192
|
+
std::filesystem::remove(main);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
TEST(IncludeReassignment, IncludeOverwritingTheMainFileWarnsNamingIt) {
|
|
196
|
+
auto lib = writeFile("reassign_lib2.scad", "a = 1;\n");
|
|
197
|
+
auto main = writeFile("reassign_main2.scad", "a = 2;\ninclude <" + lib.string() + ">\necho(a = a);\n");
|
|
198
|
+
std::vector<std::string> out;
|
|
199
|
+
evalFile(main, [&](const std::string& m) { out.push_back(m); });
|
|
200
|
+
ASSERT_EQ(out.size(), 2u);
|
|
201
|
+
EXPECT_EQ(out[0], "WARNING: a was assigned on line 1 of " + main.filename().string() +
|
|
202
|
+
" but was overwritten in file " + lib.string() + ", line 1");
|
|
203
|
+
EXPECT_EQ(out[1], "ECHO: a = 1");
|
|
204
|
+
std::filesystem::remove(lib);
|
|
205
|
+
std::filesystem::remove(main);
|
|
206
|
+
}
|
|
File without changes
|
{openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/.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
|
|
File without changes
|
|
File without changes
|
{openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/examples/eval_perf_benchmark.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/examples/manifold_cache_reuse.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/examples/minimal_debugger.cpp
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openscad_cpp_evaluator-1.49.2 → openscad_cpp_evaluator-1.49.4}/external/openscad_cpp_parser/LICENSE
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
|
|
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
|