openscad-cpp-evaluator 0.40.0__tar.gz → 0.41.0__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.40.0 → openscad_cpp_evaluator-0.41.0}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +10 -2
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/ast/expression.cpp +4 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +4 -2
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +3 -1
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +13 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/evaluator.hpp +6 -1
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/value.hpp +1 -16
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/control.cpp +0 -2
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/function_builtins.cpp +1 -5
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/bytecode_compiler.cpp +1 -1
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/bytecode_vm.cpp +1 -5
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/expr_eval.cpp +22 -4
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/stmt_eval.cpp +0 -2
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/user_calls.cpp +1 -3
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/value.cpp +6 -18
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_control_flow.cpp +41 -16
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/README.md +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/dxf_dim.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/uv.lock +0 -0
|
@@ -80,14 +80,22 @@ public:
|
|
|
80
80
|
class RangeLiteral : public Primary {
|
|
81
81
|
public:
|
|
82
82
|
RangeLiteral(Position position, std::unique_ptr<Expression> start, std::unique_ptr<Expression> end,
|
|
83
|
-
std::unique_ptr<Expression> step)
|
|
83
|
+
std::unique_ptr<Expression> step, bool implicitStep = false)
|
|
84
84
|
: Primary(NodeKind::RangeLiteral, std::move(position)), start(std::move(start)), end(std::move(end)),
|
|
85
|
-
step(std::move(step)) {}
|
|
85
|
+
step(std::move(step)), implicitStep(implicitStep) {}
|
|
86
86
|
|
|
87
87
|
std::unique_ptr<Expression> start;
|
|
88
88
|
std::unique_ptr<Expression> end;
|
|
89
89
|
std::unique_ptr<Expression> step;
|
|
90
90
|
|
|
91
|
+
// True when the source wrote the two-argument form `[a:b]` and the step
|
|
92
|
+
// node below is the literal 1.0 this parser synthesized for it. Consumers
|
|
93
|
+
// that only need the value can ignore this and read `step` as always
|
|
94
|
+
// present; it exists because "the author did not choose a step" is not
|
|
95
|
+
// recoverable from the synthesized node, and the evaluator's backwards-range
|
|
96
|
+
// warning fires only for that case (an explicit step is taken as deliberate).
|
|
97
|
+
bool implicitStep = false;
|
|
98
|
+
|
|
91
99
|
std::string toString() const override;
|
|
92
100
|
void buildScope(Scope& parentScope) override;
|
|
93
101
|
};
|
|
@@ -22,6 +22,10 @@ std::string NumberLiteral::toString() const {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
std::string RangeLiteral::toString() const {
|
|
25
|
+
// Print back the form that was written. Emitting the synthesized step for
|
|
26
|
+
// a two-argument range would round-trip `[5:0]` into `[5 : 1 : 0]`, which
|
|
27
|
+
// reads identically but suppresses the evaluator's backwards-range warning.
|
|
28
|
+
if (implicitStep) return "[" + start->toString() + " : " + end->toString() + "]";
|
|
25
29
|
return "[" + start->toString() + " : " + step->toString() + " : " + end->toString() + "]";
|
|
26
30
|
}
|
|
27
31
|
|
|
@@ -46,11 +46,13 @@ NodePtr makeUndefinedLiteral(ParserDriver& driver, const OscadLocation& loc) {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
NodePtr makeRangeLiteral(ParserDriver& driver, const OscadLocation& loc, NodePtr start, NodePtr end, NodePtr step) {
|
|
49
|
-
|
|
49
|
+
const bool implicitStep = !step;
|
|
50
|
+
if (implicitStep) {
|
|
50
51
|
step = std::make_unique<NumberLiteral>(driver.toPosition(loc), 1.0);
|
|
51
52
|
}
|
|
52
53
|
return std::make_unique<RangeLiteral>(driver.toPosition(loc), nodeCast<Expression>(std::move(start)),
|
|
53
|
-
nodeCast<Expression>(std::move(end)), nodeCast<Expression>(std::move(step))
|
|
54
|
+
nodeCast<Expression>(std::move(end)), nodeCast<Expression>(std::move(step)),
|
|
55
|
+
implicitStep);
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
NodePtr makePositionalArgument(ParserDriver& driver, const OscadLocation& loc, NodePtr expr) {
|
|
@@ -112,6 +112,7 @@ json toJsonImpl(const ASTNode& node, bool includePos) {
|
|
|
112
112
|
j["start"] = valueToJson(n.start.get(), includePos);
|
|
113
113
|
j["end"] = valueToJson(n.end.get(), includePos);
|
|
114
114
|
j["step"] = valueToJson(n.step.get(), includePos);
|
|
115
|
+
if (n.implicitStep) j["implicitStep"] = true;
|
|
115
116
|
break;
|
|
116
117
|
}
|
|
117
118
|
case NodeKind::ParameterDeclaration: {
|
|
@@ -410,7 +411,8 @@ const std::unordered_map<std::string, Builder>& registry() {
|
|
|
410
411
|
{"RangeLiteral",
|
|
411
412
|
[](const json& j, Position pos) -> std::unique_ptr<ASTNode> {
|
|
412
413
|
return std::make_unique<RangeLiteral>(std::move(pos), childFromJson<Expression>(j, "start"),
|
|
413
|
-
childFromJson<Expression>(j, "end"), childFromJson<Expression>(j, "step")
|
|
414
|
+
childFromJson<Expression>(j, "end"), childFromJson<Expression>(j, "step"),
|
|
415
|
+
j.value("implicitStep", false));
|
|
414
416
|
}},
|
|
415
417
|
{"ParameterDeclaration",
|
|
416
418
|
[](const json& j, Position pos) -> std::unique_ptr<ASTNode> {
|
|
@@ -515,3 +515,16 @@ TEST(PrettyPrint, AssignmentRhsWithLeadingCommentAndTrailingLineComment) {
|
|
|
515
515
|
// no other translation unit -- including this test file -- can name them.
|
|
516
516
|
// Left as a known, permanent coverage ceiling rather than weakening the
|
|
517
517
|
// encapsulation just to reach 100%.
|
|
518
|
+
|
|
519
|
+
// The two-argument range keeps its shape through a print/reparse cycle.
|
|
520
|
+
// It would be easy to always print the synthesized step, and the result
|
|
521
|
+
// would still be a correct program -- but `[5:0]` and `[5:1:0]` mean
|
|
522
|
+
// different things to the evaluator's backwards-range warning, so
|
|
523
|
+
// reformatting a file must not quietly convert one into the other.
|
|
524
|
+
TEST(PrettyPrint, ImplicitRangeStepSurvivesRoundTrip) {
|
|
525
|
+
auto ast = parseAst("a = [5:0];\nb = [5:1:0];\n");
|
|
526
|
+
const std::string printed = toOpenscad(ast);
|
|
527
|
+
EXPECT_NE(printed.find("[5 : 0]"), std::string::npos) << printed;
|
|
528
|
+
EXPECT_NE(printed.find("[5 : 1 : 0]"), std::string::npos) << printed;
|
|
529
|
+
expectStablePrint("a = [5:0];\nb = [5:1:0];\n");
|
|
530
|
+
}
|
|
@@ -392,7 +392,12 @@ public:
|
|
|
392
392
|
Value applyUnaryOp(oscad::NodeKind kind, const Value& v, const oscad::Position& pos);
|
|
393
393
|
Value applyIndexAccess(const Value& obj, const Value& idx);
|
|
394
394
|
Value applyMemberAccess(const Value& obj, const std::string& member);
|
|
395
|
-
|
|
395
|
+
// `implicitStep` is the RangeLiteral's own flag: true when the source
|
|
396
|
+
// wrote `[a:b]` and the parser supplied the 1.0. It only affects whether
|
|
397
|
+
// the backwards-range warning fires; the resulting value is the same
|
|
398
|
+
// either way. `pos` locates that warning.
|
|
399
|
+
Value applyRange(const Value& startV, const Value& endV, const Value& stepV, bool implicitStep = false,
|
|
400
|
+
const oscad::Position* pos = nullptr);
|
|
396
401
|
|
|
397
402
|
// Entry point for a call site resolved INSIDE compiled bytecode (the
|
|
398
403
|
// CALL_FN opcode, bytecode_vm.cpp): `bound` is already fully evaluated
|
|
@@ -355,20 +355,6 @@ private:
|
|
|
355
355
|
// it, keeping expandIterable() itself free of any Evaluator/echo coupling.
|
|
356
356
|
using RangeTooManyFn = std::function<void(size_t count)>;
|
|
357
357
|
|
|
358
|
-
// Called when a range's step points AWAY from its end -- begin > end with a
|
|
359
|
-
// positive step, or begin < end with a negative step. Such a range is
|
|
360
|
-
// naturally empty, and the reference warns rather than iterating zero times
|
|
361
|
-
// in silence. `stepPositive` picks which of its two messages applies; use
|
|
362
|
-
// rangeDirectionWarning() to build the text.
|
|
363
|
-
//
|
|
364
|
-
// Separate from RangeTooManyFn for the same reason that one exists: it
|
|
365
|
-
// keeps expandIterable() free of any Evaluator/echo coupling.
|
|
366
|
-
using RangeDirectionFn = std::function<void(bool stepPositive)>;
|
|
367
|
-
|
|
368
|
-
// The reference's own wording, quoted verbatim, for a range whose step
|
|
369
|
-
// points away from its end. Shared so the five call sites cannot drift.
|
|
370
|
-
std::string rangeDirectionWarning(bool stepPositive);
|
|
371
|
-
|
|
372
358
|
// Converts a for()/intersection_for() loop assignment's evaluated RHS into
|
|
373
359
|
// the sequence of values to iterate: undef -> empty, range -> a LAZY
|
|
374
360
|
// sequence (matching OscRange's own start/step/end iteration, half-open
|
|
@@ -394,8 +380,7 @@ std::string rangeDirectionWarning(bool stepPositive);
|
|
|
394
380
|
// one with a live consumer (BelfrySCAD) that surfaced it. The count is
|
|
395
381
|
// computed in closed form (not IterableValues::size()'s O(n) walk) so a
|
|
396
382
|
// legitimate huge-but-under-the-limit range never pays an eager pass.
|
|
397
|
-
IterableValues expandIterable(const Value& v, const RangeTooManyFn& onTooMany = nullptr
|
|
398
|
-
const RangeDirectionFn& onWrongDirection = nullptr);
|
|
383
|
+
IterableValues expandIterable(const Value& v, const RangeTooManyFn& onTooMany = nullptr);
|
|
399
384
|
|
|
400
385
|
// `each <body>`'s own flatten-one-level rule, shared by the AST interpreter
|
|
401
386
|
// (evalListLiteral/evalListElement's ListCompEach handling, expr_eval.cpp)
|
|
@@ -128,8 +128,6 @@ CSGParams resolveIntersectionFor(Evaluator& ev, const oscad::ModularIntersection
|
|
|
128
128
|
const oscad::Position* pos = &assign->position();
|
|
129
129
|
IterableValues iter = expandIterable(values, [&](size_t count) {
|
|
130
130
|
ev.warn("Bad range parameter in for statement: too many elements (" + std::to_string(count) + ")", pos);
|
|
131
|
-
}, [&](bool stepPositive) {
|
|
132
|
-
ev.warn(rangeDirectionWarning(stepPositive), pos);
|
|
133
131
|
});
|
|
134
132
|
for (const Value& val : iter) {
|
|
135
133
|
EvalContext childCtx = parentCtx.childCtx(nullptr, std::nullopt, ctx.childrenNodes, ctx.childrenCallerCtx);
|
{openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/src/builtins/function_builtins.cpp
RENAMED
|
@@ -952,11 +952,7 @@ Value evalBuiltinFunction(Evaluator& ev, const std::string& name, const CallArgs
|
|
|
952
952
|
}
|
|
953
953
|
if (const OscRange* r = std::get_if<OscRange>(&c)) {
|
|
954
954
|
std::string out;
|
|
955
|
-
|
|
956
|
-
// as much a typo as for(i=[70:1:65]) would be.
|
|
957
|
-
const IterableValues seq = expandIterable(Value{*r}, nullptr, [&](bool stepPositive) {
|
|
958
|
-
ev.warn(rangeDirectionWarning(stepPositive), &node.position());
|
|
959
|
-
});
|
|
955
|
+
const IterableValues seq = expandIterable(Value{*r});
|
|
960
956
|
for (const Value& item : seq) out += encode(item);
|
|
961
957
|
return out;
|
|
962
958
|
}
|
|
@@ -466,7 +466,7 @@ public:
|
|
|
466
466
|
compileExpr(*n.start, out, scope);
|
|
467
467
|
compileExpr(*n.end, out, scope);
|
|
468
468
|
compileExpr(*n.step, out, scope);
|
|
469
|
-
out.push_back({Op::Range, 0, 0, &n.position()});
|
|
469
|
+
out.push_back({Op::Range, n.implicitStep ? 1 : 0, 0, &n.position()});
|
|
470
470
|
return;
|
|
471
471
|
}
|
|
472
472
|
case NodeKind::PrimaryIndex: {
|
|
@@ -634,7 +634,7 @@ Value driveVm(Evaluator& ev, size_t floor) {
|
|
|
634
634
|
f.stack.pop_back();
|
|
635
635
|
Value start = std::move(f.stack.back());
|
|
636
636
|
f.stack.pop_back();
|
|
637
|
-
f.stack.push_back(ev.applyRange(start, end, step));
|
|
637
|
+
f.stack.push_back(ev.applyRange(start, end, step, ins.a != 0, ins.pos));
|
|
638
638
|
++f.pc;
|
|
639
639
|
break;
|
|
640
640
|
}
|
|
@@ -740,8 +740,6 @@ Value driveVm(Evaluator& ev, size_t floor) {
|
|
|
740
740
|
il.values = expandIterable(v, [&](size_t count) {
|
|
741
741
|
ev.warn("Bad range parameter in for statement: too many elements (" + std::to_string(count) + ")",
|
|
742
742
|
ins.pos);
|
|
743
|
-
}, [&](bool stepPositive) {
|
|
744
|
-
ev.warn(rangeDirectionWarning(stepPositive), ins.pos);
|
|
745
743
|
});
|
|
746
744
|
il.index = 0;
|
|
747
745
|
il.total = il.values.size();
|
|
@@ -1466,8 +1464,6 @@ Value driveVm(Evaluator& ev, size_t floor) {
|
|
|
1466
1464
|
il.values = expandIterable(v, [&](size_t count) {
|
|
1467
1465
|
ev.warn("Bad range parameter in for statement: too many elements (" + std::to_string(count) + ")",
|
|
1468
1466
|
ins.pos);
|
|
1469
|
-
}, [&](bool stepPositive) {
|
|
1470
|
-
ev.warn(rangeDirectionWarning(stepPositive), ins.pos);
|
|
1471
1467
|
});
|
|
1472
1468
|
il.index = 0;
|
|
1473
1469
|
il.total = il.values.size();
|
|
@@ -177,8 +177,6 @@ void Evaluator::evalListElement(const oscad::ASTNode& elem, EvalContext& ctx, st
|
|
|
177
177
|
const oscad::Position* pos = &assign->position();
|
|
178
178
|
IterableValues iter = expandIterable(values, [&](size_t count) {
|
|
179
179
|
warn("Bad range parameter in for statement: too many elements (" + std::to_string(count) + ")", pos);
|
|
180
|
-
}, [&](bool stepPositive) {
|
|
181
|
-
warn(rangeDirectionWarning(stepPositive), pos);
|
|
182
180
|
});
|
|
183
181
|
for (const Value& val : iter) {
|
|
184
182
|
EvalContext childCtx = parentCtx.letChildCtx();
|
|
@@ -294,16 +292,36 @@ Value Evaluator::evalListLiteral(const oscad::ListComprehension& node, EvalConte
|
|
|
294
292
|
}
|
|
295
293
|
|
|
296
294
|
Value Evaluator::evalRangeLiteral(const oscad::RangeLiteral& node, EvalContext& ctx) {
|
|
297
|
-
return applyRange(evalExpr(*node.start, ctx), evalExpr(*node.end, ctx), evalExpr(*node.step, ctx)
|
|
295
|
+
return applyRange(evalExpr(*node.start, ctx), evalExpr(*node.end, ctx), evalExpr(*node.step, ctx),
|
|
296
|
+
node.implicitStep, &node.position());
|
|
298
297
|
}
|
|
299
298
|
|
|
300
299
|
// Shared with the bytecode VM's RANGE opcode -- see applyBinaryOp's own
|
|
301
300
|
// comment on why these are factored out as plain Value x Value x Value ->
|
|
302
301
|
// Value functions.
|
|
303
|
-
Value Evaluator::applyRange(const Value& startV, const Value& endV, const Value& stepV
|
|
302
|
+
Value Evaluator::applyRange(const Value& startV, const Value& endV, const Value& stepV, bool implicitStep,
|
|
303
|
+
const oscad::Position* pos) {
|
|
304
304
|
double start = std::holds_alternative<std::monostate>(startV) ? 0.0 : toDoubleLenient(startV);
|
|
305
305
|
double end = std::holds_alternative<std::monostate>(endV) ? 0.0 : toDoubleLenient(endV);
|
|
306
306
|
double step = std::holds_alternative<std::monostate>(stepV) ? 1.0 : toDoubleLenient(stepV);
|
|
307
|
+
// A range whose begin is already past its end iterates zero times, which
|
|
308
|
+
// is almost always a typo -- [5:0] where [5:-1:0] was meant. Reported
|
|
309
|
+
// here, at construction, because that is where the reference reports it:
|
|
310
|
+
// `r = [5:0];` warns even if nothing ever iterates r.
|
|
311
|
+
//
|
|
312
|
+
// Only an IMPLICIT step is checked. Writing the step out is taken as
|
|
313
|
+
// deliberate, so [5:1:0] and [0:-1:5] stay silent -- a deliberate
|
|
314
|
+
// divergence from the reference, which warns for those too. An implicit
|
|
315
|
+
// step is always exactly 1, so the reference's other wording ("begin is
|
|
316
|
+
// smaller than the end, but step is negative") cannot arise here and no
|
|
317
|
+
// longer exists in this port.
|
|
318
|
+
//
|
|
319
|
+
// The epsilon matches the one the iteration path used before this check
|
|
320
|
+
// moved here, so a range built from float arithmetic that lands a hair
|
|
321
|
+
// past its end is still treated as empty-but-fine rather than a typo.
|
|
322
|
+
if (implicitStep && (start - end) > 1e-10) {
|
|
323
|
+
warn("begin is greater than the end, but step is positive", pos);
|
|
324
|
+
}
|
|
307
325
|
return Value{OscRange{start, step, end}};
|
|
308
326
|
}
|
|
309
327
|
|
|
@@ -112,8 +112,6 @@ void Evaluator::evalFor(const oscad::ModularFor& node, EvalContext& ctx) {
|
|
|
112
112
|
const oscad::Position* pos = &assign->position();
|
|
113
113
|
IterableValues iter = expandIterable(values, [&](size_t count) {
|
|
114
114
|
warn("Bad range parameter in for statement: too many elements (" + std::to_string(count) + ")", pos);
|
|
115
|
-
}, [&](bool stepPositive) {
|
|
116
|
-
warn(rangeDirectionWarning(stepPositive), pos);
|
|
117
115
|
});
|
|
118
116
|
for (const Value& val : iter) {
|
|
119
117
|
EvalContext childCtx = parentCtx.childCtx(nullptr, std::nullopt, ctx.childrenNodes, ctx.childrenCallerCtx);
|
|
@@ -1006,9 +1006,7 @@ std::optional<Evaluator::ChildrenForward> Evaluator::prepareChildrenForward(cons
|
|
|
1006
1006
|
if (std::holds_alternative<double>(idxArg)) {
|
|
1007
1007
|
indexValues.push_back(idxArg);
|
|
1008
1008
|
} else if (std::holds_alternative<ListPtr>(idxArg) || std::holds_alternative<OscRange>(idxArg)) {
|
|
1009
|
-
const IterableValues iter = expandIterable(idxArg
|
|
1010
|
-
warn(rangeDirectionWarning(stepPositive), currentWarnEntry());
|
|
1011
|
-
});
|
|
1009
|
+
const IterableValues iter = expandIterable(idxArg);
|
|
1012
1010
|
for (const Value& v : iter) indexValues.push_back(v);
|
|
1013
1011
|
} else {
|
|
1014
1012
|
warn("Bad parameter type (" + fmtValue(idxArg) +
|
|
@@ -490,30 +490,18 @@ std::optional<size_t> rangeElementCount(const OscRange& r) {
|
|
|
490
490
|
return static_cast<size_t>(std::floor(n + 1e-10)) + 1;
|
|
491
491
|
}
|
|
492
492
|
|
|
493
|
-
|
|
494
|
-
return stepPositive ? "begin is greater than the end, but step is positive"
|
|
495
|
-
: "begin is smaller than the end, but step is negative";
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
IterableValues expandIterable(const Value& v, const RangeTooManyFn& onTooMany,
|
|
499
|
-
const RangeDirectionFn& onWrongDirection) {
|
|
493
|
+
IterableValues expandIterable(const Value& v, const RangeTooManyFn& onTooMany) {
|
|
500
494
|
if (std::holds_alternative<std::monostate>(v)) return IterableValues{};
|
|
501
495
|
if (const OscRange* r = std::get_if<OscRange>(&v)) {
|
|
502
496
|
if (const std::optional<size_t> count = rangeElementCount(*r); count && *count >= 1'000'000) {
|
|
503
497
|
if (onTooMany) onTooMany(*count);
|
|
504
498
|
return IterableValues{};
|
|
505
499
|
}
|
|
506
|
-
// A step pointing away from the end yields nothing
|
|
507
|
-
// always a typo --
|
|
508
|
-
//
|
|
509
|
-
//
|
|
510
|
-
//
|
|
511
|
-
// failure (the reference calls it "too many elements") and shares
|
|
512
|
-
// rangeElementCount's nullopt with this case only by coincidence.
|
|
513
|
-
if (onWrongDirection && r->step != 0.0) {
|
|
514
|
-
const double n = (r->end - r->start) / r->step;
|
|
515
|
-
if (n < -1e-10) onWrongDirection(r->step > 0.0);
|
|
516
|
-
}
|
|
500
|
+
// A step pointing away from the end yields nothing, and that is
|
|
501
|
+
// almost always a typo -- but the warning for it belongs to the
|
|
502
|
+
// range's CONSTRUCTION, not its iteration: only the range literal
|
|
503
|
+
// knows whether the author chose the step or the parser supplied
|
|
504
|
+
// it. See Evaluator::applyRange.
|
|
517
505
|
// Lazy -- IterableValues itself reproduces this exact
|
|
518
506
|
// termination condition (a zero step is naturally empty: neither
|
|
519
507
|
// `x <= end` nor `x >= end` branch ever fires for it) without
|
|
@@ -1355,18 +1355,34 @@ const char* kSmaller = "begin is smaller than the end, but step is negative";
|
|
|
1355
1355
|
|
|
1356
1356
|
} // namespace
|
|
1357
1357
|
|
|
1358
|
-
TEST(RangeDirection,
|
|
1359
|
-
EXPECT_TRUE(hasWarning(warningsFrom("for (i=[
|
|
1360
|
-
EXPECT_TRUE(hasWarning(warningsFrom("for (i=[1
|
|
1358
|
+
TEST(RangeDirection, ImplicitStepPastTheEndWarns) {
|
|
1359
|
+
EXPECT_TRUE(hasWarning(warningsFrom("for (i=[1:0]) echo(i);"), kGreater));
|
|
1360
|
+
EXPECT_TRUE(hasWarning(warningsFrom("for (i=[3:1]) echo(i);"), kGreater));
|
|
1361
1361
|
}
|
|
1362
1362
|
|
|
1363
|
-
TEST(RangeDirection,
|
|
1364
|
-
|
|
1363
|
+
TEST(RangeDirection, AnExplicitStepIsTakenAsDeliberate) {
|
|
1364
|
+
// Divergence from the reference, which warns for both of these. Writing
|
|
1365
|
+
// the step out is a statement of intent; the warning exists for the
|
|
1366
|
+
// author who wrote [3:1] meaning [3:-1:1] and got an empty loop.
|
|
1367
|
+
for (const char* src : {"for (i=[3:1:1]) echo(i);", "for (i=[0:-1:3]) echo(i);"}) {
|
|
1368
|
+
EXPECT_TRUE(warningsFrom(src).empty()) << src;
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
TEST(RangeDirection, TheNegativeStepWordingIsUnreachable) {
|
|
1373
|
+
// An implicit step is always exactly 1, so no input can produce the
|
|
1374
|
+
// reference's second message. If this ever fires, the gate has been
|
|
1375
|
+
// widened back to explicit steps and this port needs that wording back.
|
|
1376
|
+
for (const char* src : {"for (i=[0:-1:3]) echo(i);", "for (i=[3:1]) echo(i);",
|
|
1377
|
+
"x = [5:0];", "echo(chr([70:65]));"}) {
|
|
1378
|
+
EXPECT_FALSE(hasWarning(warningsFrom(src), kSmaller)) << src;
|
|
1379
|
+
}
|
|
1365
1380
|
}
|
|
1366
1381
|
|
|
1367
1382
|
TEST(RangeDirection, AWellFormedRangeIsSilent) {
|
|
1368
1383
|
for (const char* src : {"for (i=[1:1:3]) echo(i);", "for (i=[3:-1:1]) echo(i);",
|
|
1369
|
-
"for (i=[3:3]) echo(i);", "for (i=[0:0.5:2]) echo(i);"
|
|
1384
|
+
"for (i=[3:3]) echo(i);", "for (i=[0:0.5:2]) echo(i);",
|
|
1385
|
+
"for (i=[1:3]) echo(i);"}) {
|
|
1370
1386
|
EXPECT_TRUE(warningsFrom(src).empty()) << src;
|
|
1371
1387
|
}
|
|
1372
1388
|
}
|
|
@@ -1380,24 +1396,33 @@ TEST(RangeDirection, AZeroStepIsNotReportedAsADirectionProblem) {
|
|
|
1380
1396
|
EXPECT_FALSE(hasWarning(w, kSmaller));
|
|
1381
1397
|
}
|
|
1382
1398
|
|
|
1383
|
-
TEST(RangeDirection,
|
|
1384
|
-
// The
|
|
1399
|
+
TEST(RangeDirection, WarnsWhereTheRangeIsBuiltNotWhereItIsIterated) {
|
|
1400
|
+
// The reference reports this against the range literal, so a range that
|
|
1401
|
+
// is assigned and never iterated still warns -- matched here.
|
|
1402
|
+
EXPECT_TRUE(hasWarning(warningsFrom("r = [5:0];\ncube(1);"), kGreater));
|
|
1403
|
+
// And a range built once, iterated twice, warns once.
|
|
1404
|
+
const std::vector<std::string> w =
|
|
1405
|
+
warningsFrom("r = [5:0];\nfor (i=r) echo(i);\nfor (j=r) echo(j);");
|
|
1406
|
+
EXPECT_EQ(w.size(), 1u);
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
TEST(RangeDirection, EveryRangeBuildingConstructWarns) {
|
|
1410
|
+
// Construction is one shared site, but each of these reaches it by its
|
|
1411
|
+
// own route -- the interpreter's literal, the VM's Range op, and the
|
|
1412
|
+
// argument-evaluation path into a builtin.
|
|
1385
1413
|
{
|
|
1386
|
-
const std::vector<std::string> w = warningsFrom("x = [for (i=[3:1
|
|
1414
|
+
const std::vector<std::string> w = warningsFrom("x = [for (i=[3:1]) i];");
|
|
1387
1415
|
std::string got;
|
|
1388
1416
|
for (const std::string& m : w) got += "\n " + m;
|
|
1389
1417
|
EXPECT_TRUE(hasWarning(w, kGreater)) << "list comprehension, got:" << got;
|
|
1390
1418
|
}
|
|
1391
|
-
EXPECT_TRUE(hasWarning(warningsFrom("intersection_for (i=[3:1
|
|
1419
|
+
EXPECT_TRUE(hasWarning(warningsFrom("intersection_for (i=[3:1]) cube(1);"), kGreater))
|
|
1392
1420
|
<< "intersection_for";
|
|
1393
|
-
EXPECT_TRUE(hasWarning(warningsFrom("echo(chr([70:
|
|
1394
|
-
<< "chr";
|
|
1421
|
+
EXPECT_TRUE(hasWarning(warningsFrom("echo(chr([70:65]));"), kGreater)) << "chr";
|
|
1395
1422
|
EXPECT_TRUE(hasWarning(warningsFrom(
|
|
1396
1423
|
"module p() { children([1:0]); }\np() { cube(1); cube(2); }"), kGreater))
|
|
1397
1424
|
<< "children";
|
|
1425
|
+
EXPECT_TRUE(hasWarning(warningsFrom("function f() = [5:0];\nx = f();"), kGreater))
|
|
1426
|
+
<< "returned from a function";
|
|
1398
1427
|
}
|
|
1399
1428
|
|
|
1400
|
-
TEST(RangeDirection, WarnsOncePerEvaluationNotPerAbsentIteration) {
|
|
1401
|
-
const std::vector<std::string> w = warningsFrom("for (i=[3:1:1]) echo(i);");
|
|
1402
|
-
EXPECT_EQ(w.size(), 1u);
|
|
1403
|
-
}
|
|
File without changes
|
{openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/.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
|
{openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/examples/eval_perf_benchmark.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/examples/manifold_cache_reuse.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-0.40.0 → openscad_cpp_evaluator-0.41.0}/examples/minimal_debugger.cpp
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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
|