openscad-cpp-evaluator 1.6.0__tar.gz → 1.7.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-1.6.0 → openscad_cpp_evaluator-1.7.0}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/bytecode.hpp +35 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/function_builtins.hpp +27 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/scope_trail.hpp +104 -34
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/function_builtins.cpp +16 -12
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/bytecode_compiler.cpp +48 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/bytecode_vm.cpp +123 -22
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/eval_context.cpp +17 -3
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/mesh_check.cpp +92 -19
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_bytecode_compiler.cpp +65 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_mesh_check.cpp +13 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/README.md +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/dxf_dim.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/format_closure.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/utf8.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_children_separate.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_feature_detection.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_include_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/uv.lock +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
#include "openscad_cpp_evaluator/function_builtins.hpp"
|
|
3
4
|
#include "openscad_cpp_evaluator/value.hpp"
|
|
4
5
|
|
|
5
6
|
#include "openscad_cpp_parser/ast/ast_node.hpp"
|
|
@@ -787,6 +788,40 @@ struct CompiledChunk {
|
|
|
787
788
|
const oscad::FunctionDeclaration* decl = nullptr;
|
|
788
789
|
std::vector<std::optional<std::string>> argNames;
|
|
789
790
|
const oscad::ASTNode* callNode = nullptr;
|
|
791
|
+
// Everything below is `calleeName` already looked up, once, here at
|
|
792
|
+
// compile time. The VM used to redo all three on EVERY builtin call:
|
|
793
|
+
// two std::string hashes into static tables plus a string compare
|
|
794
|
+
// against "object", for answers that cannot change once this site is
|
|
795
|
+
// compiled. `declaredParams` points into a function-local static
|
|
796
|
+
// table with process lifetime, so holding the pointer is safe.
|
|
797
|
+
BuiltinFnId builtinId = BuiltinFnId::None;
|
|
798
|
+
const std::vector<std::string>* declaredParams = nullptr;
|
|
799
|
+
bool isObjectBuiltin = false;
|
|
800
|
+
|
|
801
|
+
// Where each argument of this call goes, worked out once at compile
|
|
802
|
+
// time against `decl`'s parameter list -- see ArgBind. Only filled in
|
|
803
|
+
// for a static user-function callee (`decl` set); a builtin, an
|
|
804
|
+
// import or a dynamic/closure callee has no compile-time parameter
|
|
805
|
+
// list to match against and keeps the name-matching path.
|
|
806
|
+
//
|
|
807
|
+
// The names on both sides of that matching are fixed the moment this
|
|
808
|
+
// site is compiled, but the VM was redoing it on every call, twice:
|
|
809
|
+
// buildBoundArgs linear-scanned a name-keyed BoundArgs (copying each
|
|
810
|
+
// name into it), then bindBoundArgsIntoFrame linear-scanned it again
|
|
811
|
+
// for every parameter, then a third nested loop compared every bound
|
|
812
|
+
// name against every parameter name. A two-argument call did roughly
|
|
813
|
+
// ten std::string comparisons and two string copies to reach an
|
|
814
|
+
// answer that was already known. Binding straight into the frame's
|
|
815
|
+
// slots also MOVES each argument instead of moving it into BoundArgs
|
|
816
|
+
// and copying it back out.
|
|
817
|
+
struct ArgBind {
|
|
818
|
+
int paramIndex = -1; // >=0: this argument binds that parameter
|
|
819
|
+
bool toDyn = false; // instead bind by name into ctx.dyn ($-named, undeclared)
|
|
820
|
+
bool warnUnexpectedNamed = false;
|
|
821
|
+
bool warnTooManyPositional = false;
|
|
822
|
+
};
|
|
823
|
+
std::vector<ArgBind> argBinds;
|
|
824
|
+
bool hasArgPlan = false; // argBinds is authoritative (it is empty for a zero-argument call too)
|
|
790
825
|
};
|
|
791
826
|
|
|
792
827
|
// An upvalue read (see Op::LoadUpvalue): `targetDecl` is the enclosing
|
|
@@ -26,8 +26,35 @@ bool isBuiltinFunctionName(const std::string& name);
|
|
|
26
26
|
// accept $-prefixed named-argument overrides). Mirrors the reference's
|
|
27
27
|
// _math_fns dispatch table plus the textmetrics()/fontmetrics() special
|
|
28
28
|
// cases (implemented on top of FontProvider, text_metrics.hpp).
|
|
29
|
+
// One id per name evalBuiltinFunction handles (NOT the same list as
|
|
30
|
+
// isBuiltinFunctionName -- "object" is deliberately absent, since it is
|
|
31
|
+
// special-cased to builtinObject() before this function is reached). Public
|
|
32
|
+
// so a CALL SITE can resolve its callee once, at compile time
|
|
33
|
+
// (CompiledChunk::CallSite::builtinId), instead of hashing the name string
|
|
34
|
+
// on every single call.
|
|
35
|
+
enum class BuiltinFnId {
|
|
36
|
+
None, // not a name evalBuiltinFunction handles
|
|
37
|
+
TextMetrics, FontMetrics, Abs, Sign, Ceil, Floor, Round, Sqrt, Ln, Log, Exp, Sin, Cos, Tan,
|
|
38
|
+
Asin, Acos, Atan, Atan2, Max, Min, Pow, Norm, Cross, Rands, Concat, Len, Str, Chr, Ord,
|
|
39
|
+
IsUndef, IsNum, IsBool, IsString, IsList, IsFunction, IsObject, Search, Lookup, HasKey,
|
|
40
|
+
Version, VersionNum, ParentModule, DxfDim, DxfCross, SupportedFeature, LinearSolve,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// `name` -> its id, or None. The one place that hashes the name; everything
|
|
44
|
+
// on a hot path should call this once at compile time and keep the answer.
|
|
45
|
+
BuiltinFnId builtinFnIdFor(const std::string& name);
|
|
46
|
+
|
|
29
47
|
Value evalBuiltinFunction(Evaluator& ev, const std::string& name, const CallArgs& args, const oscad::ASTNode& node);
|
|
30
48
|
|
|
49
|
+
// The same dispatch with both of its name lookups already done: `id` from
|
|
50
|
+
// builtinFnIdFor and `declaredParams` from builtinParamNames (dispatch.hpp),
|
|
51
|
+
// which for all but a couple of builtins is null. `name` survives only
|
|
52
|
+
// because diagnostics quote it. The string-taking overload above is just
|
|
53
|
+
// this one with the two lookups performed first, and remains the entry point
|
|
54
|
+
// for the AST interpreter, where there is no call site to cache them on.
|
|
55
|
+
Value evalBuiltinFunctionResolved(Evaluator& ev, BuiltinFnId id, const std::vector<std::string>* declaredParams,
|
|
56
|
+
const std::string& name, const CallArgs& args, const oscad::ASTNode& node);
|
|
57
|
+
|
|
31
58
|
// object(a=1, b=2, ...) -- an ordered string-keyed map merging positional
|
|
32
59
|
// (an existing object's entries, or a list of [key,value] pairs) and named
|
|
33
60
|
// arguments, later arguments winning over earlier ones for the same key --
|
|
@@ -12,37 +12,101 @@
|
|
|
12
12
|
|
|
13
13
|
namespace oscadeval {
|
|
14
14
|
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
// because this codebase has no escaping closures: a FunctionLiteral value
|
|
22
|
-
// is a bare AST pointer with no captured environment, and callCtxFor()
|
|
23
|
-
// re-derives every call's context from the LIVE call stack -- nothing ever
|
|
24
|
-
// reads a binding after the scope that pushed it has already exited.
|
|
15
|
+
// Recycles the blocks that TrailView/IndexedTrailView's own shared_ptrs are
|
|
16
|
+
// made of. Deriving one EvalContext opens three trail levels -- dyn, let_,
|
|
17
|
+
// dynPositions -- and each was a fresh make_shared: ~2M allocations in one
|
|
18
|
+
// Anklet.scad render, all of them the same size, almost all of them freed in
|
|
19
|
+
// reverse order a few microseconds later. This hands the same block straight
|
|
20
|
+
// back out.
|
|
25
21
|
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
22
|
+
// It changes WHERE the memory comes from and nothing else: no lifetime, no
|
|
23
|
+
// visibility, no popLevel timing. That is the whole point -- the trail's
|
|
24
|
+
// escaping-closure rules are the most delicate thing in this file, and an
|
|
25
|
+
// allocator cannot get them wrong.
|
|
26
|
+
//
|
|
27
|
+
// One size class, because there is exactly one: every block is the control
|
|
28
|
+
// block plus one view object. Anything else falls through to the global
|
|
29
|
+
// allocator rather than being kept.
|
|
30
|
+
//
|
|
31
|
+
// Worth ~1% of an Anklet.scad render, for 2M allocations removed -- a modest
|
|
32
|
+
// return, and deliberately recorded here as such: macOS's own small-object
|
|
33
|
+
// allocator is already a free list, so swapping it for another one only pays
|
|
34
|
+
// for the bookkeeping either side of it. Removing an allocation that also
|
|
35
|
+
// removed real work (a vector's worth of Value moves, say) has paid far
|
|
36
|
+
// better everywhere it has been tried in this codebase.
|
|
37
|
+
class ViewBlockPool {
|
|
38
|
+
public:
|
|
39
|
+
ViewBlockPool() { free_.reserve(kMaxKept); }
|
|
40
|
+
~ViewBlockPool() {
|
|
41
|
+
for (void* p : free_) ::operator delete(p);
|
|
42
|
+
}
|
|
43
|
+
ViewBlockPool(const ViewBlockPool&) = delete;
|
|
44
|
+
ViewBlockPool& operator=(const ViewBlockPool&) = delete;
|
|
45
|
+
|
|
46
|
+
void* take(std::size_t bytes) {
|
|
47
|
+
if (bytes == blockSize_ && !free_.empty()) {
|
|
48
|
+
void* p = free_.back();
|
|
49
|
+
free_.pop_back();
|
|
50
|
+
return p;
|
|
51
|
+
}
|
|
52
|
+
if (blockSize_ == 0) blockSize_ = bytes;
|
|
53
|
+
return ::operator new(bytes);
|
|
54
|
+
}
|
|
55
|
+
// noexcept is safe: free_ was reserved to kMaxKept up front and is never
|
|
56
|
+
// pushed past it, so this push_back cannot reallocate and cannot throw.
|
|
57
|
+
void give(void* p, std::size_t bytes) noexcept {
|
|
58
|
+
if (bytes != blockSize_ || free_.size() >= kMaxKept) {
|
|
59
|
+
::operator delete(p);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
free_.push_back(p);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private:
|
|
66
|
+
static constexpr std::size_t kMaxKept = 512;
|
|
67
|
+
std::size_t blockSize_ = 0;
|
|
68
|
+
std::vector<void*> free_;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// A STATELESS allocator over one pool per view type (each type has exactly
|
|
72
|
+
// one block size, so each gets its own single-size-class pool). Stateless
|
|
73
|
+
// matters twice over: std::allocate_shared stores a copy of the allocator
|
|
74
|
+
// inside the very block it allocated, so a stateful one both grows every
|
|
75
|
+
// block and -- if it held a shared_ptr to keep the pool alive past the last
|
|
76
|
+
// view, which a pool owned by the storage would need -- pays an atomic
|
|
77
|
+
// refcount pair per allocation. That version was measured, and it was SLOWER
|
|
78
|
+
// than not pooling at all.
|
|
79
|
+
//
|
|
80
|
+
// thread_local, so no locking and no cross-thread sharing, and it outlives
|
|
81
|
+
// every view on its thread, which is what makes "keep the pool alive for the
|
|
82
|
+
// final deallocate" a non-problem rather than a lifetime puzzle.
|
|
83
|
+
template <typename T>
|
|
84
|
+
class ViewBlockAllocator {
|
|
85
|
+
public:
|
|
86
|
+
using value_type = T;
|
|
87
|
+
ViewBlockAllocator() = default;
|
|
88
|
+
template <typename U>
|
|
89
|
+
ViewBlockAllocator(const ViewBlockAllocator<U>&) {}
|
|
90
|
+
|
|
91
|
+
T* allocate(std::size_t n) { return static_cast<T*>(pool().take(n * sizeof(T))); }
|
|
92
|
+
void deallocate(T* p, std::size_t n) noexcept { pool().give(p, n * sizeof(T)); }
|
|
93
|
+
|
|
94
|
+
template <typename U>
|
|
95
|
+
bool operator==(const ViewBlockAllocator<U>&) const noexcept {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
template <typename U>
|
|
99
|
+
bool operator!=(const ViewBlockAllocator<U>&) const noexcept {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private:
|
|
104
|
+
static ViewBlockPool& pool() {
|
|
105
|
+
static thread_local ViewBlockPool p;
|
|
106
|
+
return p;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
46
110
|
template <typename T>
|
|
47
111
|
class ScopeTrailStorage {
|
|
48
112
|
public:
|
|
@@ -207,6 +271,7 @@ private:
|
|
|
207
271
|
// depends on level numbers being globally monotonic.
|
|
208
272
|
std::vector<int> parent_{0};
|
|
209
273
|
int nextLevel_ = 0;
|
|
274
|
+
|
|
210
275
|
};
|
|
211
276
|
|
|
212
277
|
// Per-EvalContext handle onto a shared ScopeTrailStorage<T>: this view's
|
|
@@ -235,7 +300,8 @@ public:
|
|
|
235
300
|
static std::shared_ptr<TrailView<T>> makeRoot() {
|
|
236
301
|
auto storage = std::make_shared<ScopeTrailStorage<T>>();
|
|
237
302
|
int level = storage->openLevel(0);
|
|
238
|
-
return std::
|
|
303
|
+
return std::allocate_shared<TrailView<T>>(ViewBlockAllocator<TrailView<T>>(), storage,
|
|
304
|
+
level);
|
|
239
305
|
}
|
|
240
306
|
|
|
241
307
|
// Open a fresh level for writes. `isolate=true` terminates the new
|
|
@@ -272,7 +338,8 @@ public:
|
|
|
272
338
|
// changes what happens when something holds an EXTRA reference.
|
|
273
339
|
std::shared_ptr<TrailView<T>> openChild(bool isolate) const {
|
|
274
340
|
int level = storage_->openLevel(isolate ? 0 : level_);
|
|
275
|
-
auto child = std::
|
|
341
|
+
auto child = std::allocate_shared<TrailView<T>>(ViewBlockAllocator<TrailView<T>>(),
|
|
342
|
+
storage_, level);
|
|
276
343
|
if (!isolate) child->parentView_ = this->shared_from_this();
|
|
277
344
|
return child;
|
|
278
345
|
}
|
|
@@ -462,6 +529,7 @@ private:
|
|
|
462
529
|
std::unordered_map<int, std::vector<int>> dirty_;
|
|
463
530
|
std::vector<int> parent_{0}; // see ScopeTrailStorage::parent_
|
|
464
531
|
int nextLevel_ = 0;
|
|
532
|
+
|
|
465
533
|
};
|
|
466
534
|
|
|
467
535
|
// Per-EvalContext handle onto a shared IndexedScopeTrailStorage<T> -- the
|
|
@@ -474,12 +542,14 @@ public:
|
|
|
474
542
|
static std::shared_ptr<IndexedTrailView<T>> makeRoot(std::shared_ptr<DynNameIntern> intern) {
|
|
475
543
|
auto storage = std::make_shared<IndexedScopeTrailStorage<T>>(std::move(intern));
|
|
476
544
|
int level = storage->openLevel(0);
|
|
477
|
-
return std::
|
|
545
|
+
return std::allocate_shared<IndexedTrailView<T>>(
|
|
546
|
+
ViewBlockAllocator<IndexedTrailView<T>>(), storage, level);
|
|
478
547
|
}
|
|
479
548
|
|
|
480
549
|
std::shared_ptr<IndexedTrailView<T>> openChild(bool isolate) const {
|
|
481
550
|
int level = storage_->openLevel(isolate ? 0 : level_);
|
|
482
|
-
return std::
|
|
551
|
+
return std::allocate_shared<IndexedTrailView<T>>(
|
|
552
|
+
ViewBlockAllocator<IndexedTrailView<T>>(), storage_, level);
|
|
483
553
|
}
|
|
484
554
|
|
|
485
555
|
IndexedTrailView(std::shared_ptr<IndexedScopeTrailStorage<T>> storage, int level)
|
{openscad_cpp_evaluator-1.6.0 → openscad_cpp_evaluator-1.7.0}/src/builtins/function_builtins.cpp
RENAMED
|
@@ -1007,12 +1007,7 @@ namespace {
|
|
|
1007
1007
|
// `if (name == "...")` string-compare chain; the switch below then
|
|
1008
1008
|
// compiles to a jump table instead of sequential comparisons. No branch's
|
|
1009
1009
|
// logic changed, only how it's reached.
|
|
1010
|
-
|
|
1011
|
-
TextMetrics, FontMetrics, Abs, Sign, Ceil, Floor, Round, Sqrt, Ln, Log, Exp, Sin, Cos, Tan,
|
|
1012
|
-
Asin, Acos, Atan, Atan2, Max, Min, Pow, Norm, Cross, Rands, Concat, Len, Str, Chr, Ord,
|
|
1013
|
-
IsUndef, IsNum, IsBool, IsString, IsList, IsFunction, IsObject, Search, Lookup, HasKey,
|
|
1014
|
-
Version, VersionNum, ParentModule, DxfDim, DxfCross, SupportedFeature, LinearSolve,
|
|
1015
|
-
};
|
|
1010
|
+
// BuiltinFnId itself now lives in function_builtins.hpp -- see builtinFnIdFor.
|
|
1016
1011
|
|
|
1017
1012
|
// supported_feature("name") -> the level at which this build implements that
|
|
1018
1013
|
// feature, or 0 for one it does not implement (and for a name it has never
|
|
@@ -1242,18 +1237,26 @@ bool checkBuiltinArgs(Evaluator& ev, const std::string& name, BuiltinFnId id, co
|
|
|
1242
1237
|
|
|
1243
1238
|
} // namespace
|
|
1244
1239
|
|
|
1240
|
+
BuiltinFnId builtinFnIdFor(const std::string& name) {
|
|
1241
|
+
const auto& ids = builtinFnIds();
|
|
1242
|
+
const auto it = ids.find(name);
|
|
1243
|
+
return it == ids.end() ? BuiltinFnId::None : it->second;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1245
1246
|
Value evalBuiltinFunction(Evaluator& ev, const std::string& name, const CallArgs& args, const oscad::ASTNode& node) {
|
|
1247
|
+
return evalBuiltinFunctionResolved(ev, builtinFnIdFor(name), builtinParamNames(name), name, args, node);
|
|
1248
|
+
}
|
|
1246
1249
|
|
|
1247
|
-
|
|
1248
|
-
|
|
1250
|
+
Value evalBuiltinFunctionResolved(Evaluator& ev, BuiltinFnId id, const std::vector<std::string>* declaredParams,
|
|
1251
|
+
const std::string& name, const CallArgs& args, const oscad::ASTNode& node) {
|
|
1249
1252
|
// Not one of the names this function handles (e.g. "object", routed
|
|
1250
1253
|
// elsewhere before reaching here) -- mirrors the old chain's fallthrough.
|
|
1251
|
-
if (
|
|
1254
|
+
if (id == BuiltinFnId::None) return Value{};
|
|
1252
1255
|
|
|
1253
1256
|
// Only textmetrics/fontmetrics have an entry -- every other builtin
|
|
1254
1257
|
// function reads its arguments positionally upstream and warns about
|
|
1255
1258
|
// nothing. See builtinParamNames (registry.cpp).
|
|
1256
|
-
if (const std::vector<std::string>* declared =
|
|
1259
|
+
if (const std::vector<std::string>* declared = declaredParams) {
|
|
1257
1260
|
for (const auto& [argName, _] : args.named) {
|
|
1258
1261
|
if (!isConfigVariable(argName) &&
|
|
1259
1262
|
std::find(declared->begin(), declared->end(), argName) == declared->end()) {
|
|
@@ -1265,9 +1268,10 @@ Value evalBuiltinFunction(Evaluator& ev, const std::string& name, const CallArgs
|
|
|
1265
1268
|
// Arity and argument types, with the reference's own two diagnostics.
|
|
1266
1269
|
// This replaced a silent version of the same gate (scalarNumericArity /
|
|
1267
1270
|
// numericOnlyNames), which returned undef without ever saying why.
|
|
1268
|
-
if (!checkBuiltinArgs(ev, name,
|
|
1271
|
+
if (!checkBuiltinArgs(ev, name, id, args, &node.position())) return Value{};
|
|
1269
1272
|
|
|
1270
|
-
switch (
|
|
1273
|
+
switch (id) {
|
|
1274
|
+
case BuiltinFnId::None: return Value{}; // unreachable: handled above
|
|
1271
1275
|
case BuiltinFnId::TextMetrics: return builtinTextmetrics(ev, args);
|
|
1272
1276
|
case BuiltinFnId::FontMetrics: return builtinFontmetrics(ev, args);
|
|
1273
1277
|
case BuiltinFnId::Abs: return Value{std::fabs(toDoubleLenient(getArg(args, 0, "x", Value{})))};
|
|
@@ -20,6 +20,46 @@
|
|
|
20
20
|
namespace oscadeval {
|
|
21
21
|
|
|
22
22
|
namespace {
|
|
23
|
+
// Replays buildBoundArgs' own positional/named matching rule (bytecode_vm.cpp)
|
|
24
|
+
// against a parameter list known at compile time, recording the answer per
|
|
25
|
+
// argument instead of recomputing it per call. The rule, unchanged: a named
|
|
26
|
+
// argument binds the parameter of that name, warning when there is none and
|
|
27
|
+
// the name is not a $-config variable; a positional argument binds the
|
|
28
|
+
// parameter at its own positional index, warning once when it runs past the
|
|
29
|
+
// end; an undeclared $-name still reaches ctx.dyn; anything else is dropped.
|
|
30
|
+
// A later argument writing the same parameter still wins, because both bind
|
|
31
|
+
// the same slot in order.
|
|
32
|
+
void planCallSiteArgs(CompiledChunk::CallSite& site,
|
|
33
|
+
const std::vector<std::unique_ptr<oscad::ParameterDeclaration>>& params) {
|
|
34
|
+
const size_t nparams = params.size();
|
|
35
|
+
size_t positionalIdx = 0;
|
|
36
|
+
site.argBinds.resize(site.argNames.size());
|
|
37
|
+
for (size_t i = 0; i < site.argNames.size(); ++i) {
|
|
38
|
+
CompiledChunk::CallSite::ArgBind& b = site.argBinds[i];
|
|
39
|
+
if (site.argNames[i]) {
|
|
40
|
+
const std::string& name = *site.argNames[i];
|
|
41
|
+
int found = -1;
|
|
42
|
+
for (size_t p = 0; p < nparams; ++p) {
|
|
43
|
+
if (params[p]->name->name == name) {
|
|
44
|
+
found = static_cast<int>(p);
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
b.paramIndex = found;
|
|
49
|
+
b.warnUnexpectedNamed = (found < 0) && !isConfigVariable(name);
|
|
50
|
+
b.toDyn = (found < 0) && !name.empty() && name[0] == '$';
|
|
51
|
+
} else {
|
|
52
|
+
if (positionalIdx < nparams) {
|
|
53
|
+
b.paramIndex = static_cast<int>(positionalIdx);
|
|
54
|
+
} else if (positionalIdx == nparams) {
|
|
55
|
+
b.warnTooManyPositional = true;
|
|
56
|
+
}
|
|
57
|
+
++positionalIdx;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
site.hasArgPlan = true;
|
|
61
|
+
}
|
|
62
|
+
|
|
23
63
|
|
|
24
64
|
// Thrown by compileExpr wherever it hits a construct this phase doesn't
|
|
25
65
|
// compile yet -- tryCompileFunction catches it and returns nullopt (falls
|
|
@@ -601,6 +641,11 @@ public:
|
|
|
601
641
|
// call-site interleaved order, not resolveArgs'
|
|
602
642
|
// split positional/named CallArgs shape).
|
|
603
643
|
site.isBuiltin = true;
|
|
644
|
+
// Resolve the callee here rather than per call; see
|
|
645
|
+
// CallSite's own doc comment (bytecode.hpp).
|
|
646
|
+
site.builtinId = builtinFnIdFor(calleeName);
|
|
647
|
+
site.declaredParams = builtinParamNames(calleeName);
|
|
648
|
+
site.isObjectBuiltin = (calleeName == "object");
|
|
604
649
|
isStatic = true;
|
|
605
650
|
}
|
|
606
651
|
// Anything else stays dynamic: a function-literal value,
|
|
@@ -674,6 +719,9 @@ public:
|
|
|
674
719
|
}
|
|
675
720
|
}
|
|
676
721
|
}
|
|
722
|
+
// Resolve every argument to its parameter now; see
|
|
723
|
+
// CallSite::argBinds (bytecode.hpp) for why.
|
|
724
|
+
if (site.decl) planCallSiteArgs(site, site.decl->parameters);
|
|
677
725
|
int siteIdx = static_cast<int>(chunk_.callSites.size());
|
|
678
726
|
chunk_.callSites.push_back(std::move(site));
|
|
679
727
|
// Builtins and import() never trampoline (matching
|