openscad-cpp-evaluator 0.9.2__tar.gz → 0.13.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.9.2 → openscad_cpp_evaluator-0.13.0}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/bytecode.hpp +296 -2
- openscad_cpp_evaluator-0.13.0/include/openscad_cpp_evaluator/bytecode_compiler.hpp +126 -0
- openscad_cpp_evaluator-0.13.0/include/openscad_cpp_evaluator/bytecode_vm.hpp +244 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/csg_node.hpp +13 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/eval_error.hpp +9 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/evaluator.hpp +523 -52
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/call_args.cpp +2 -2
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/bytecode_compiler.cpp +531 -23
- openscad_cpp_evaluator-0.13.0/src/bytecode_vm.cpp +1158 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/csg_resolve.cpp +85 -32
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/eval_error.cpp +32 -1
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/stmt_eval.cpp +31 -8
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/user_calls.cpp +224 -24
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_bytecode_compiler.cpp +476 -45
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_control_flow.cpp +32 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_csg_tree.cpp +89 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_debug_hooks.cpp +35 -1
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_tail_calls.cpp +102 -8
- openscad_cpp_evaluator-0.9.2/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -22
- openscad_cpp_evaluator-0.9.2/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -107
- openscad_cpp_evaluator-0.9.2/src/bytecode_vm.cpp +0 -805
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/.github/workflows/wheels.yml +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/README.md +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/bindings/module.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/stb_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/value.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/booleans.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/primitives_3d.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/text/stb_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/value.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_function_builtins.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_value.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tools/cli/main.cpp +0 -0
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
namespace oscad {
|
|
13
13
|
class FunctionDeclaration;
|
|
14
14
|
class FunctionLiteral;
|
|
15
|
+
class ModuleDeclaration;
|
|
16
|
+
class ModularCall;
|
|
17
|
+
class ModularAssert;
|
|
18
|
+
class Expression;
|
|
15
19
|
} // namespace oscad
|
|
16
20
|
|
|
17
21
|
namespace oscadeval {
|
|
@@ -37,7 +41,33 @@ enum class Op {
|
|
|
37
41
|
StoreLocal, // a = slot index (pops)
|
|
38
42
|
LoadDyn, // a = name pool index ($-prefixed)
|
|
39
43
|
StoreDyn, // a = name pool index (pops; also marks dynExplicit)
|
|
40
|
-
LoadFree, // a = name pool index -- Evaluator::evalIdentifier fallback
|
|
44
|
+
LoadFree, // a = name pool index -- Evaluator::evalIdentifier fallback (warnIfUndef=true)
|
|
45
|
+
// Same as LoadFree, but Evaluator::evalIdentifier's warnIfUndef=false --
|
|
46
|
+
// only ever emitted for a PrimaryCall's own callee probe (bytecode_
|
|
47
|
+
// compiler.cpp's PrimaryCall case), mirroring evalFunctionCall's own
|
|
48
|
+
// `evalIdentifier(leftId->name, ..., /*warnIfUndef=*/false)` fallback
|
|
49
|
+
// exactly: probing whether a bare identifier resolves to a callable
|
|
50
|
+
// Closure value shouldn't itself warn "unknown variable" when it
|
|
51
|
+
// doesn't -- Op::CallDynamic's own runtime handler already warns
|
|
52
|
+
// "unknown function" once the probe comes back non-Closure, so using
|
|
53
|
+
// plain LoadFree here doubled that up into two warnings for one
|
|
54
|
+
// genuinely-unknown callee.
|
|
55
|
+
LoadFreeNoWarn, // a = name pool index
|
|
56
|
+
// a = slot index, b = name pool index (pops). Only emitted for a
|
|
57
|
+
// compiled ASSIGNMENT BLOCK (Evaluator::tryCompileAssignmentBlock,
|
|
58
|
+
// user_calls.cpp -- a run of sibling `name = expr;` statements sharing
|
|
59
|
+
// one scope, exactly what Evaluator::evalChildren already isolates as
|
|
60
|
+
// its own `assignments` sub-list before any non-assignment statement
|
|
61
|
+
// runs). Stores into BOTH the slot (so a LATER sibling assignment in
|
|
62
|
+
// the SAME batch can read this one back via a fast LoadLocal, mirroring
|
|
63
|
+
// how LetOp's own bindings already work) AND ctx.let_ (so code OUTSIDE
|
|
64
|
+
// this compiled batch -- a later non-assignment statement, a nested
|
|
65
|
+
// block, a module call -- still sees it the ordinary way, since this
|
|
66
|
+
// batch's own slots are invisible once it returns). Plain StoreLocal
|
|
67
|
+
// alone would lose that outer visibility entirely; plain "store to
|
|
68
|
+
// let_ only" would lose the fast intra-batch slot reads a batch of
|
|
69
|
+
// assignments exists to buy back in the first place.
|
|
70
|
+
StoreLocalAndLet,
|
|
41
71
|
Range, // pops step, pops end, pops start (pushed in that order); pushes applyRange(start, end, step)
|
|
42
72
|
Index, // pops idx, pops obj, pushes applyIndexAccess(obj, idx)
|
|
43
73
|
Member, // a = name pool index (member name); pops obj, pushes applyMemberAccess(obj, name)
|
|
@@ -210,6 +240,206 @@ enum class Op {
|
|
|
210
240
|
// which recomputes this on every failing call). pos/node: same
|
|
211
241
|
// Evaluator::error() TRACE-walk need CheckIterLimit already has.
|
|
212
242
|
AssertFail,
|
|
243
|
+
|
|
244
|
+
// -- Module-body compilation (Stage 2) --------------------------------
|
|
245
|
+
// A call to a user module resolved to a specific ModuleDeclaration AT
|
|
246
|
+
// COMPILE TIME (see CompiledChunk::ModuleCallSite) -- the module-side
|
|
247
|
+
// analog of Op::CallFn. a = index into CompiledChunk::moduleCallSites.
|
|
248
|
+
// Arguments are NOT pre-pushed onto the operand stack the way CallFn's
|
|
249
|
+
// are (bindArgs runs directly against site.callNode->arguments at
|
|
250
|
+
// runtime instead) -- module-call argument evaluation was never the
|
|
251
|
+
// recursion-safety target here, so there's no need to teach the
|
|
252
|
+
// compiler a separate "push each arg" step just for this. Produces no
|
|
253
|
+
// stack Value at all: its effect is entirely the side effect of
|
|
254
|
+
// splicing (or wrapping into a synthetic "union") whatever CSGNodes
|
|
255
|
+
// the callee's body produces into the CURRENT treeStack_ frame -- see
|
|
256
|
+
// Evaluator::spliceModuleChildren's own doc comment (bytecode_vm.cpp)
|
|
257
|
+
// for why this is always the splice branch, never the "wrap as a
|
|
258
|
+
// builtin-tagged CSGNode" one evalModularCall's own general form also
|
|
259
|
+
// has (Op::CallModule only ever targets a resolved USER module, for
|
|
260
|
+
// which splice is unconditional).
|
|
261
|
+
CallModule,
|
|
262
|
+
|
|
263
|
+
// A single "native passthrough" statement -- a modifier wrapper,
|
|
264
|
+
// intersection_for, children(), a builtin module call, or a user-
|
|
265
|
+
// module call that didn't resolve at compile time (shadowed, forward-
|
|
266
|
+
// declared, or otherwise not statically known) -- anything
|
|
267
|
+
// compileStatementList doesn't give its own real bytecode. (Assignment/
|
|
268
|
+
// ModularEcho/ModularAssert/ModularLet used to fall here too; they now
|
|
269
|
+
// have their own real bytecode -- Op::StoreModuleVar/Op::Echo/
|
|
270
|
+
// Op::AssertStatement/Op::OpenLetScope+StoreLetVar -- purely a
|
|
271
|
+
// throughput change, since none of these were ever the recursion-depth
|
|
272
|
+
// risk this compiler targets.)
|
|
273
|
+
// a = index into CompiledChunk::nativeStatements. Runtime just does
|
|
274
|
+
// what Evaluator::evalChildren's own per-statement loop already does
|
|
275
|
+
// for one node: derive childCtx via ctx.withScope(...), checkDebug,
|
|
276
|
+
// evalStatement. These are "leaf-shaped" in the sense the Stage 2 plan
|
|
277
|
+
// means it: whatever native recursion they make (a builtin's own
|
|
278
|
+
// resolve function walking ITS children, etc.) is bounded by ordinary
|
|
279
|
+
// script structure, not by how deep a recursive module chain goes --
|
|
280
|
+
// that risk is fully covered by CallModule/ForIterNext/the Jump-based
|
|
281
|
+
// if/for control flow instead, regardless of how many of THESE sit
|
|
282
|
+
// alongside them in the same body.
|
|
283
|
+
NativeStatement,
|
|
284
|
+
|
|
285
|
+
// If/if-else's own condition, evaluated NATIVELY (Evaluator::
|
|
286
|
+
// evalExprMaybeCompiled -- gets the SAME expression-level compilation
|
|
287
|
+
// a bare statement-context expression already would, just not folded
|
|
288
|
+
// into THIS chunk's own instruction stream) rather than compiled
|
|
289
|
+
// inline -- module-body compilation's job is the STATEMENT-level
|
|
290
|
+
// control flow (so a recursive module call nested inside doesn't hide
|
|
291
|
+
// behind a native evalStatement call), not re-deriving expression
|
|
292
|
+
// compilation tryCompileStatementExpr already does. a = index into
|
|
293
|
+
// CompiledChunk::nativeExprs, b = jump target on false (mirrors
|
|
294
|
+
// JumpIfFalse's own semantics, just with a native condition source
|
|
295
|
+
// instead of a popped stack Value).
|
|
296
|
+
NativeCondJumpIfFalse,
|
|
297
|
+
|
|
298
|
+
// The "entering this branch/iteration" expr-level checkDebug marker
|
|
299
|
+
// ModularIf/ModularIfElse/ModularFor's own interpreted forms each fire
|
|
300
|
+
// once (see evalStatement's ModularIf/ModularIfElse cases and evalFor,
|
|
301
|
+
// stmt_eval.cpp) -- a = index into CompiledChunk::nativeStatements
|
|
302
|
+
// (reusing that same table; the entry here is whichever ASTNode the
|
|
303
|
+
// interpreter would have passed to checkDebug -- the branch/body's
|
|
304
|
+
// own first statement, or the ModularIf/For node itself when that
|
|
305
|
+
// branch/body is empty).
|
|
306
|
+
NativeCheckDebugExprLevel,
|
|
307
|
+
|
|
308
|
+
// One ModularFor assignment's own RHS range/list expression, evaluated
|
|
309
|
+
// NATIVELY (same reasoning as NativeCondJumpIfFalse) and materialized
|
|
310
|
+
// into an IterList exactly like the existing (list-comprehension)
|
|
311
|
+
// Op::IterMaterialize -- a = index into CompiledChunk::nativeExprs, b
|
|
312
|
+
// = iterList id.
|
|
313
|
+
NativeIterMaterialize,
|
|
314
|
+
|
|
315
|
+
// Statement-for's own per-iteration advance -- the module-body analog
|
|
316
|
+
// of Op::IterNext, but binding into ctx.let_ (a real, dynamically-
|
|
317
|
+
// discoverable statement-scope variable, exactly like the
|
|
318
|
+
// interpreter's own per-iteration childCtx.let_->set()) instead of a
|
|
319
|
+
// slot, and -- critically -- pushing a FRESH child EvalContext onto
|
|
320
|
+
// f.ctxChain for the upcoming iteration rather than mutating the
|
|
321
|
+
// current one in place: evalFor derives a brand-new childCtx per
|
|
322
|
+
// iteration (see stmt_eval.cpp), so an ordinary local assignment made
|
|
323
|
+
// inside the loop body doesn't trip evalAssignment's own "was
|
|
324
|
+
// assigned on line N but overwritten" warning on iteration 2 onward,
|
|
325
|
+
// and so a value bound in one iteration never leaks into the next.
|
|
326
|
+
// a = name-pool index (the loop variable's own name), b = iterList id,
|
|
327
|
+
// c = jump target on exhaustion (taken WITHOUT pushing a new ctx --
|
|
328
|
+
// mirrors the cartesian loop simply not entering the body once that
|
|
329
|
+
// dimension is exhausted). `node` = the Assignment AST node, for the
|
|
330
|
+
// matching per-iteration checkDebug call (mirrors evalFor's own
|
|
331
|
+
// `checkDebug(*node.assignments[depth], childCtx)`). Always paired
|
|
332
|
+
// with a matching Op::ForIterEnd at the bottom of the SAME dimension's
|
|
333
|
+
// loop body.
|
|
334
|
+
ForIterNext,
|
|
335
|
+
|
|
336
|
+
// Pops the ctx Op::ForIterNext just pushed for the iteration that's
|
|
337
|
+
// ending (f.ctxChain.pop_back()) and jumps back to that same
|
|
338
|
+
// ForIterNext instruction to attempt the next one. a = jump target
|
|
339
|
+
// (the matching ForIterNext's own pc).
|
|
340
|
+
ForIterEnd,
|
|
341
|
+
|
|
342
|
+
// -- Module-body leaf-statement compilation (throughput, not a --------
|
|
343
|
+
// -- recursion-safety concern -- see NativeStatement's own doc comment
|
|
344
|
+
// for why THAT stayed native for these same node kinds in Stage 2;
|
|
345
|
+
// this closes the "every sub-expression is a separate nested driveVm
|
|
346
|
+
// call via evalExprMaybeCompiled" gap instead by inlining them into
|
|
347
|
+
// the enclosing chunk's own instruction stream) --------------------
|
|
348
|
+
//
|
|
349
|
+
// A module-body statement's own top-level checkDebug -- the compiled
|
|
350
|
+
// analog of what evalChildren's native per-statement loop / Op::
|
|
351
|
+
// NativeStatement's own handler already does for the SAME node
|
|
352
|
+
// (`ev.checkDebug(*stmt, ctx)`, exprLevel=false, forced=false) -- kept
|
|
353
|
+
// as a real op (not simply omitted) so a compiled statement's debug
|
|
354
|
+
// behavior is identical to its native form, not just "usually doesn't
|
|
355
|
+
// matter because fast-continue only compiles breakpoint-free chunks."
|
|
356
|
+
// a = index into CompiledChunk::nativeStatements (reusing that table).
|
|
357
|
+
CheckDebugStatement,
|
|
358
|
+
|
|
359
|
+
// Assignment's own compiled form -- pops one Value (already evaluated
|
|
360
|
+
// via an ordinary inline compileExpr, NOT native evalExprMaybeCompiled)
|
|
361
|
+
// and replicates Evaluator::evalAssignment exactly: a `$`-prefixed name
|
|
362
|
+
// goes to ctx.dyn (+ dynExplicit), everything else checks
|
|
363
|
+
// ctx.dynPositions for the "assigned but overwritten" warning, then
|
|
364
|
+
// writes ctx.let_ and records this position. Never slot-addressed --
|
|
365
|
+
// module-level/top-level assignments are always ctx-visible, dynamic-
|
|
366
|
+
// scope writes, exactly like today. a = name pool index, pos = the
|
|
367
|
+
// Assignment node's own position (for both the overwritten warning and
|
|
368
|
+
// the position recorded into dynPositions).
|
|
369
|
+
StoreModuleVar,
|
|
370
|
+
|
|
371
|
+
// ModularEcho/ModularAssert's own statement form share Op::Echo/a
|
|
372
|
+
// dedicated AssertStatement op (below) for the "pop N already-compiled
|
|
373
|
+
// argument values" mechanics -- see those ops' own doc comments
|
|
374
|
+
// (Op::Echo, above; Op::AssertStatement, below) for why the
|
|
375
|
+
// EXPRESSION-form opcodes are directly reusable (statement-shaped
|
|
376
|
+
// already: no value pushed, straight fall-through) while assert's
|
|
377
|
+
// needs its own op (named-argument support + eager-not-lazy message
|
|
378
|
+
// evaluation, both genuinely different from AssertOp's own contract).
|
|
379
|
+
|
|
380
|
+
// Isolates ONE inline-compiled sub-expression's own `$`-writes from the
|
|
381
|
+
// rest of this chunk's shared, long-lived ctx -- pushes ctx.
|
|
382
|
+
// letChildCtx() (reads still see through to the parent level; only
|
|
383
|
+
// WRITES are isolated) onto f.ctxChain, mirroring exactly what
|
|
384
|
+
// runCompiledExprChunk's own wrapper already does for a native call
|
|
385
|
+
// into a compiled EXPRESSION chunk (evalExprMaybeCompiled). Needed
|
|
386
|
+
// because a module-body statement's own inline-compiled sub-
|
|
387
|
+
// expression (Assignment's RHS, one echo()/assert() argument) has NO
|
|
388
|
+
// such wrapper of its own the way a genuinely separate chunk call
|
|
389
|
+
// does -- without this, `v1 = let($fn=55) f(); v2 = f();` leaks $fn=55
|
|
390
|
+
// into v2 too (caught for real by UserFunction.
|
|
391
|
+
// DollarVarLetAsAssignmentRhsDoesNotLeak once Assignment got its own
|
|
392
|
+
// inline compiled form). Always emitted, unconditionally, around
|
|
393
|
+
// EVERY such sub-expression -- not just ones statically known to
|
|
394
|
+
// contain a `let($...)` -- for the same reason runCompiledExprChunk's
|
|
395
|
+
// own wrapper is unconditional: a nested call/closure could still
|
|
396
|
+
// reach one indirectly, and the cost when nothing $-scoped is present
|
|
397
|
+
// is just one cheap trail-level open, not a real expression re-walk.
|
|
398
|
+
OpenExprScope,
|
|
399
|
+
// Pops the ctx OpenExprScope just pushed (f.ctxChain.pop_back()) --
|
|
400
|
+
// always paired, immediately after the sub-expression's own compiled
|
|
401
|
+
// code finishes (its RESULT, if any, is already on f.stack by then;
|
|
402
|
+
// this only tears down the ctx, never touches the value stack). Also
|
|
403
|
+
// reused to close Op::OpenLetScope's own child ctx (below) -- both are
|
|
404
|
+
// just "pop the current ctx level", identical either way.
|
|
405
|
+
CloseExprScope,
|
|
406
|
+
|
|
407
|
+
// ModularLet's own (statement-form) child scope -- mirrors
|
|
408
|
+
// Evaluator::evalLetBlock's own `ctx.childCtx(nullptr, std::nullopt,
|
|
409
|
+
// ctx.childrenNodes, ctx.childrenCallerCtx)` call exactly, pushed onto
|
|
410
|
+
// f.ctxChain (Op::CloseExprScope, above, pops it back off once the
|
|
411
|
+
// let-block's own body finishes compiling/running). Every assignment's
|
|
412
|
+
// own RHS is compiled+evaluated BEFORE this runs (while the PARENT ctx
|
|
413
|
+
// is still current -- see ModularLet's own compileOneStatement case,
|
|
414
|
+
// bytecode_compiler.cpp, for why: the statement form's RHS must never
|
|
415
|
+
// see an EARLIER sibling's own write in the SAME let-block, unlike the
|
|
416
|
+
// let-EXPRESSION form's sequential visibility), each left on f.stack;
|
|
417
|
+
// only the WRITES (Op::StoreLetVar, below) happen after this runs.
|
|
418
|
+
OpenLetScope,
|
|
419
|
+
|
|
420
|
+
// Op::StoreLetVar -- pops one value and writes it into the CURRENT ctx
|
|
421
|
+
// (by then, the child Op::OpenLetScope just pushed) via the same
|
|
422
|
+
// `$`-prefix branch Op::StoreModuleVar uses, but WITHOUT its
|
|
423
|
+
// dynPositions "assigned but overwritten" bookkeeping -- evalLetBlock's
|
|
424
|
+
// own writes never do that check either (a let-block's own child scope
|
|
425
|
+
// is always fresh, so "reassigning the same name in the same scope"
|
|
426
|
+
// can never happen the way a module-body Assignment's own can). a =
|
|
427
|
+
// name pool index, pos = the Assignment node's own position (unused by
|
|
428
|
+
// the handler itself, kept for consistency/future debugging only).
|
|
429
|
+
StoreLetVar,
|
|
430
|
+
|
|
431
|
+
// a = index into CompiledChunk::assertSites. Pops site.argCount values
|
|
432
|
+
// (all of this statement's own arguments, already compiled+pushed in
|
|
433
|
+
// source order via compileExpr -- EVERY one, not just condition/
|
|
434
|
+
// message, mirrors evalAssertStatement's own eager resolveArgs() over
|
|
435
|
+
// AssertOp's lazy-message contract) and replicates
|
|
436
|
+
// Evaluator::evalAssertStatement exactly: named "condition"/"message"
|
|
437
|
+
// win over positional 0/1 (resolved at COMPILE time into
|
|
438
|
+
// AssertSite::conditionArgIndex/messageArgIndex -- the argument SHAPE
|
|
439
|
+
// is static, only values vary per call), throws via Evaluator::error()
|
|
440
|
+
// on failure, otherwise runs any chained node.children natively (rare;
|
|
441
|
+
// not worth its own compiled path -- see AssertSite's own doc comment).
|
|
442
|
+
AssertStatement,
|
|
213
443
|
};
|
|
214
444
|
|
|
215
445
|
struct Instruction {
|
|
@@ -241,7 +471,11 @@ struct Instruction {
|
|
|
241
471
|
struct CompiledChunk {
|
|
242
472
|
struct Param {
|
|
243
473
|
std::string name;
|
|
244
|
-
int slot = 0;
|
|
474
|
+
int slot = 0; // unused when isDyn is true -- $-params are never slot-addressed
|
|
475
|
+
// $-prefixed parameter: binds through ctx.dyn (dynamically scoped)
|
|
476
|
+
// instead of a slot -- see compileFunctionLike's own doc comment,
|
|
477
|
+
// bytecode_compiler.cpp, and bindCompiledArgs', bytecode_vm.cpp.
|
|
478
|
+
bool isDyn = false;
|
|
245
479
|
};
|
|
246
480
|
|
|
247
481
|
// A call site statically resolved at compile time (see
|
|
@@ -335,6 +569,59 @@ struct CompiledChunk {
|
|
|
335
569
|
std::vector<std::optional<std::string>> argNames;
|
|
336
570
|
};
|
|
337
571
|
|
|
572
|
+
// One Op::CallModule site -- a ModularCall statically resolved (at
|
|
573
|
+
// compile time, via the enclosing ModuleDeclaration's own static
|
|
574
|
+
// scope) to a specific user ModuleDeclaration. Unlike CallSite,
|
|
575
|
+
// there's no isBuiltin/isImport branch to represent: a callee that
|
|
576
|
+
// ISN'T a resolved user ModuleDeclaration (a builtin, children(), an
|
|
577
|
+
// unresolvable name) never gets one of these -- it's compiled as a
|
|
578
|
+
// NativeStatement instead (see Op::CallModule's own doc comment for
|
|
579
|
+
// why that's exactly right, not a missed optimization).
|
|
580
|
+
struct ModuleCallSite {
|
|
581
|
+
const oscad::ModuleDeclaration* decl = nullptr;
|
|
582
|
+
const oscad::ModularCall* callNode = nullptr;
|
|
583
|
+
std::string calleeName;
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
// One Op::AssertStatement site -- see that op's own doc comment for
|
|
587
|
+
// the full contract. `conditionArgIndex`/`messageArgIndex` are indices
|
|
588
|
+
// into the site's own argCount-sized popped-argument array (source
|
|
589
|
+
// order), resolved at COMPILE time via the same "named wins over
|
|
590
|
+
// positional 0/1" priority Evaluator::getArg applies at runtime --
|
|
591
|
+
// nullopt means "no argument supplies this logical parameter" (mirrors
|
|
592
|
+
// getArg's own defaultValue fallback: absent condition reads as
|
|
593
|
+
// `Value{true}`, absent message means no ": ..." suffix).
|
|
594
|
+
// `condTextConstIdx`: constants[] index of the condition argument's own
|
|
595
|
+
// source text (or "false" when no condition argument exists, matching
|
|
596
|
+
// evalAssertStatement's `node.arguments.empty() ? "false" : ...`),
|
|
597
|
+
// interned once at compile time. `node`: for both Evaluator::error()'s
|
|
598
|
+
// TRACE walk and the (rare) chained-children fallback below.
|
|
599
|
+
//
|
|
600
|
+
// ponytail: a script with TWO named args of the SAME name (e.g.
|
|
601
|
+
// `assert(condition=true, condition=false)`) would resolve to the
|
|
602
|
+
// LAST one here, not getArg's own first-match; not worth the extra
|
|
603
|
+
// bookkeeping to fix for input that's already nonsensical.
|
|
604
|
+
struct AssertSite {
|
|
605
|
+
int argCount = 0;
|
|
606
|
+
std::optional<int> conditionArgIndex;
|
|
607
|
+
std::optional<int> messageArgIndex;
|
|
608
|
+
int condTextConstIdx = -1;
|
|
609
|
+
const oscad::ModularAssert* node = nullptr;
|
|
610
|
+
};
|
|
611
|
+
|
|
612
|
+
// Every distinct chunk this SPECIFIC CompiledChunk owns is either a
|
|
613
|
+
// function body (bodyCode is one expression's own instruction stream)
|
|
614
|
+
// or a module body (bodyCode is a compiled STATEMENT list -- see
|
|
615
|
+
// tryCompileModuleBody, bytecode_compiler.cpp) -- never both. `params`/
|
|
616
|
+
// `defaultCode` mean the same thing either way (a ModuleDeclaration's
|
|
617
|
+
// parameters are shaped identically to a FunctionDeclaration's).
|
|
618
|
+
// Gates driveVm's own frame-completion branch (bytecode_vm.cpp):a
|
|
619
|
+
// function frame's completion produces a Value (popped off f.stack);
|
|
620
|
+
// a module frame's produces nothing on the stack at all -- its whole
|
|
621
|
+
// effect already landed in treeStack_ as a side effect of running its
|
|
622
|
+
// own body.
|
|
623
|
+
bool isModule = false;
|
|
624
|
+
|
|
338
625
|
// The FunctionDeclaration/FunctionLiteral this chunk's own body was
|
|
339
626
|
// compiled from (bytecode_compiler.cpp's compileFunctionLike sets this
|
|
340
627
|
// to its own `selfDecl` parameter) -- Op::MakeClosure's runtime handler
|
|
@@ -353,6 +640,13 @@ struct CompiledChunk {
|
|
|
353
640
|
std::vector<UpvalueRef> upvalues;
|
|
354
641
|
std::vector<ClosureSite> closureSites;
|
|
355
642
|
std::vector<EchoSite> echoSites;
|
|
643
|
+
// Module-body-only tables (see Op::CallModule/NativeStatement/
|
|
644
|
+
// NativeCondJumpIfFalse/NativeCheckDebugExprLevel/NativeIterMaterialize's
|
|
645
|
+
// own doc comments, above) -- always empty for a function chunk.
|
|
646
|
+
std::vector<ModuleCallSite> moduleCallSites;
|
|
647
|
+
std::vector<AssertSite> assertSites;
|
|
648
|
+
std::vector<const oscad::Expression*> nativeExprs;
|
|
649
|
+
std::vector<const oscad::ASTNode*> nativeStatements;
|
|
356
650
|
int numSlots = 0;
|
|
357
651
|
// Count of distinct ListCompFor-assignment iterLists allocated across
|
|
358
652
|
// this whole chunk (see IterMaterialize/IterReset/IterNext) -- runChunk
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "openscad_cpp_evaluator/bytecode.hpp"
|
|
4
|
+
|
|
5
|
+
#include <optional>
|
|
6
|
+
#include <vector>
|
|
7
|
+
|
|
8
|
+
namespace oscad {
|
|
9
|
+
class Assignment;
|
|
10
|
+
class FunctionDeclaration;
|
|
11
|
+
class ModuleDeclaration;
|
|
12
|
+
class Expression;
|
|
13
|
+
class Scope;
|
|
14
|
+
} // namespace oscad
|
|
15
|
+
|
|
16
|
+
namespace oscadeval {
|
|
17
|
+
|
|
18
|
+
// Attempts to compile `decl`'s parameter defaults + body to bytecode.
|
|
19
|
+
// Returns nullopt if `decl` uses a construct this compiler doesn't handle
|
|
20
|
+
// yet -- the caller falls back to the ordinary AST interpreter for that
|
|
21
|
+
// whole function, unconditionally correct since nothing about this
|
|
22
|
+
// function's behavior changes based on whether it happened to compile.
|
|
23
|
+
std::optional<CompiledChunk> tryCompileFunction(const oscad::FunctionDeclaration& decl);
|
|
24
|
+
|
|
25
|
+
// Compiles a bare STATEMENT-context expression -- an assignment's RHS, an
|
|
26
|
+
// if/for condition, a module-call or echo()/assert() argument -- rather
|
|
27
|
+
// than a whole function body. No parameters, no enclosing/upvalue chain, no
|
|
28
|
+
// self declaration: every name reference resolves through Op::LoadFree/
|
|
29
|
+
// Op::LoadDyn, the identical ctx.let_/ctx.dyn lookup evalExpr's own
|
|
30
|
+
// Identifier case already does for a statement-level local (a for-loop
|
|
31
|
+
// variable, an assignment-declared name) -- this buys back the AST
|
|
32
|
+
// dispatch overhead compileExpr already saves for functions, not faster
|
|
33
|
+
// variable access (statement-level locals were never slot-addressable to
|
|
34
|
+
// begin with; they're declared by scattered Assignment statements, not a
|
|
35
|
+
// fixed parameter list known in advance). A nested let() inside the
|
|
36
|
+
// expression still gets a real compile-time slot, exactly as it would
|
|
37
|
+
// inside a function body.
|
|
38
|
+
//
|
|
39
|
+
// Refuses to compile (returns nullopt) if the expression creates any
|
|
40
|
+
// closure that captures something (chunk.closureSites non-empty after
|
|
41
|
+
// compileFunctionLike returns) -- with no enclosing chain and no self
|
|
42
|
+
// declaration for this bare wrapper, such a closure's own upvalue
|
|
43
|
+
// resolution would target a CallStackFrame that will never exist (this
|
|
44
|
+
// path pushes none), which is silently WRONG (stale/undef) rather than a
|
|
45
|
+
// safe fallback. Not a hypothetical carve-out: it's the one shape this
|
|
46
|
+
// wrapper cannot support correctly, so it's excluded rather than risked.
|
|
47
|
+
// `scope` is the expression's own lexical scope (Expression::scope(),
|
|
48
|
+
// always set by buildScope() regardless of node kind) -- needed to resolve
|
|
49
|
+
// any callee inside it statically, the same way a function body's call
|
|
50
|
+
// sites are.
|
|
51
|
+
std::optional<CompiledChunk> tryCompileStatementExpr(const oscad::Expression& expr, const oscad::Scope* scope);
|
|
52
|
+
|
|
53
|
+
// Compiles a run of SIBLING assignment statements sharing one scope --
|
|
54
|
+
// exactly Evaluator::evalChildren's own `assignments` sub-list (stmt_eval.
|
|
55
|
+
// cpp), which OpenSCAD already runs as a self-contained group before any
|
|
56
|
+
// non-assignment statement in the same block. Unlike tryCompileStatementExpr
|
|
57
|
+
// (one independent chunk per leaf expression -- fine for a single
|
|
58
|
+
// assignment, but its own per-call overhead dominated a WHOLE block of
|
|
59
|
+
// them, see this feature's own commit message for the measured regression),
|
|
60
|
+
// this compiles the ENTIRE run as one chunk with one shared CompileScope:
|
|
61
|
+
// each assignment's own name gets a real slot (declared in source order,
|
|
62
|
+
// mirroring LetOp's own sequential-visibility rule -- `y = x + 1;` after
|
|
63
|
+
// `x = 1;` reads `x` via a fast LoadLocal, not a name lookup), and each
|
|
64
|
+
// value is written out via Op::StoreLocalAndLet so code OUTSIDE this batch
|
|
65
|
+
// still sees it the ordinary way (see runCompiledAssignmentBlock's own doc
|
|
66
|
+
// comment, bytecode_vm.hpp, for why `ctx` is used directly, not a scoped
|
|
67
|
+
// child).
|
|
68
|
+
//
|
|
69
|
+
// Refuses to compile (returns nullopt) for any of:
|
|
70
|
+
// - the same plain (non-$) name assigned more than once in this run --
|
|
71
|
+
// evalAssignment's own "was assigned on line N but overwritten" warning
|
|
72
|
+
// would otherwise silently stop firing for a reassignment inside a
|
|
73
|
+
// compiled batch; safer to fall back than to lose it silently.
|
|
74
|
+
// - any closure that captures something (same hazard, same reasoning, as
|
|
75
|
+
// tryCompileStatementExpr's own doc comment above).
|
|
76
|
+
// - a $-prefixed assignment nested inside a let()/list-comprehension-let
|
|
77
|
+
// clause ANYWHERE in this run (post-compile: any Op::StoreDyn in the
|
|
78
|
+
// resulting bodyCode) -- runCompiledAssignmentBlock runs directly against
|
|
79
|
+
// the caller's own `ctx`, not a scoped child the way a bare expression
|
|
80
|
+
// chunk gets (letChildCtx(), see runCompiledExprChunk's own doc comment)
|
|
81
|
+
// -- there is no scope here for that nested let()'s own dyn write to be
|
|
82
|
+
// contained by, so it would leak into the caller's ctx.dyn permanently
|
|
83
|
+
// instead of just for that one assignment's own RHS.
|
|
84
|
+
std::optional<CompiledChunk> tryCompileAssignmentBlock(const std::vector<const oscad::Assignment*>& assigns,
|
|
85
|
+
const oscad::Scope* scope);
|
|
86
|
+
|
|
87
|
+
// Attempts to compile `decl`'s parameter defaults + STATEMENT-list body
|
|
88
|
+
// (decl.children) to bytecode (Stage 2) -- the module-side analog of
|
|
89
|
+
// tryCompileFunction. Returns nullopt (falls back to the ordinary
|
|
90
|
+
// interpreter for this whole module) for a construct compileStatementList
|
|
91
|
+
// doesn't handle -- see its own doc comment (bytecode_compiler.cpp) for
|
|
92
|
+
// exactly which statement kinds get real bytecode (assignment/if/for/a
|
|
93
|
+
// resolved user-module call) versus a native passthrough (everything
|
|
94
|
+
// else: echo/assert/let-blocks/modifiers/intersection_for/builtin or
|
|
95
|
+
// unresolved module calls) -- the native passthrough shapes never bail
|
|
96
|
+
// compilation of the WHOLE body the way an unsupported EXPRESSION
|
|
97
|
+
// construct does for tryCompileFunction; only a genuinely unsupported
|
|
98
|
+
// EXPRESSION (inside an if-condition/for-range/argument) can still bail
|
|
99
|
+
// (via tryCompileStatementExpr's own NotCompilable, propagated up).
|
|
100
|
+
std::optional<CompiledChunk> tryCompileModuleBody(const oscad::ModuleDeclaration& decl);
|
|
101
|
+
|
|
102
|
+
// Same compilation (assignment/if/for/resolved-module-call get real
|
|
103
|
+
// bytecode, everything else a native passthrough), but for an ARBITRARY
|
|
104
|
+
// statement list, not just a ModuleDeclaration's own `children` -- the
|
|
105
|
+
// general form behind Evaluator::tryRunCompiledChildren, which every
|
|
106
|
+
// evalChildren() call now tries first (stmt_eval.cpp), including a
|
|
107
|
+
// builtin module's own children (translate()/union()/etc.'s internal
|
|
108
|
+
// evalChildren call, src/builtins/*.cpp) and a for-loop's/let-block's
|
|
109
|
+
// body. This is what actually reaches the "native passthrough wraps a
|
|
110
|
+
// recursive module call" case Op::NativeStatement alone can't -- see this
|
|
111
|
+
// project's own session notes on the Stage 2 "NativeStatement gap" for
|
|
112
|
+
// why a builtin call itself (translate, not just what's declared inside
|
|
113
|
+
// this project's own module bodies) still can't become a SINGLE flat
|
|
114
|
+
// instruction stream with its caller this way (its own resolve function,
|
|
115
|
+
// e.g. resolveTransform, computes params AND evaluates children as one
|
|
116
|
+
// opaque native call -- decoupling that is a separate, larger project),
|
|
117
|
+
// but this DOES mean the children of any wrapping builtin get their own,
|
|
118
|
+
// independent chance to compile, cutting the number of native stack
|
|
119
|
+
// frames needed per recursive "wrap-then-recurse" level rather than
|
|
120
|
+
// eliminating them entirely. `scope`: the list's own lexical scope for
|
|
121
|
+
// resolving a call site's callee -- callers pass `children.front()->
|
|
122
|
+
// scope()`, mirroring tryRunCompiledAssignmentBlock's own convention.
|
|
123
|
+
std::optional<CompiledChunk> tryCompileChildrenList(const std::vector<const oscad::ASTNode*>& children,
|
|
124
|
+
const oscad::Scope* scope);
|
|
125
|
+
|
|
126
|
+
} // namespace oscadeval
|