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.
Files changed (197) hide show
  1. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/PKG-INFO +1 -1
  2. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/bytecode.hpp +296 -2
  3. openscad_cpp_evaluator-0.13.0/include/openscad_cpp_evaluator/bytecode_compiler.hpp +126 -0
  4. openscad_cpp_evaluator-0.13.0/include/openscad_cpp_evaluator/bytecode_vm.hpp +244 -0
  5. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/csg_node.hpp +13 -0
  6. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/eval_error.hpp +9 -0
  7. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/evaluator.hpp +523 -52
  8. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/pyproject.toml +1 -1
  9. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/call_args.cpp +2 -2
  10. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/bytecode_compiler.cpp +531 -23
  11. openscad_cpp_evaluator-0.13.0/src/bytecode_vm.cpp +1158 -0
  12. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/csg_resolve.cpp +85 -32
  13. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/eval_error.cpp +32 -1
  14. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/stmt_eval.cpp +31 -8
  15. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/user_calls.cpp +224 -24
  16. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_bytecode_compiler.cpp +476 -45
  17. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_control_flow.cpp +32 -0
  18. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_csg_tree.cpp +89 -0
  19. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_debug_hooks.cpp +35 -1
  20. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_tail_calls.cpp +102 -8
  21. openscad_cpp_evaluator-0.9.2/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -22
  22. openscad_cpp_evaluator-0.9.2/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -107
  23. openscad_cpp_evaluator-0.9.2/src/bytecode_vm.cpp +0 -805
  24. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/.github/workflows/ci.yml +0 -0
  25. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/.github/workflows/wheels.yml +0 -0
  26. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/.gitignore +0 -0
  27. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/.gitmodules +0 -0
  28. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/CLAUDE.md +0 -0
  29. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/CMakeLists.txt +0 -0
  30. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/LICENSE +0 -0
  31. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/README.md +0 -0
  32. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/bindings/CMakeLists.txt +0 -0
  33. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/bindings/module.cpp +0 -0
  34. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/cmake/embed_font.cmake +0 -0
  35. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/examples/CMakeLists.txt +0 -0
  36. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/examples/eval_perf_benchmark.cpp +0 -0
  37. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/examples/manifold_cache_reuse.cpp +0 -0
  38. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/examples/minimal_debugger.cpp +0 -0
  39. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
  40. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/.gitignore +0 -0
  41. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
  42. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
  43. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/README.md +0 -0
  44. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
  45. {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
  46. {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
  47. {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
  48. {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
  49. {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
  50. {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
  51. {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
  52. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
  53. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
  54. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
  55. {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
  56. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
  57. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
  58. {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
  59. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
  60. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
  61. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
  62. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
  63. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
  64. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
  65. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
  66. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
  67. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
  68. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
  69. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
  70. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
  71. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
  72. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
  73. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
  74. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
  75. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
  76. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
  77. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
  78. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
  79. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
  80. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
  81. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
  82. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
  83. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
  84. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
  85. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
  86. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
  87. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
  88. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
  89. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
  90. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
  91. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
  92. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
  93. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
  94. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
  95. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
  96. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
  97. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
  98. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
  99. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
  100. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
  101. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
  102. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
  103. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
  104. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
  105. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
  106. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
  107. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
  108. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
  109. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
  110. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
  111. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
  112. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
  113. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
  114. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
  115. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/export.hpp +0 -0
  116. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
  117. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
  118. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
  119. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
  120. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
  121. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
  122. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
  123. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
  124. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
  125. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/stb_font_provider.hpp +0 -0
  126. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
  127. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
  128. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/value.hpp +0 -0
  129. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
  130. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/python/openscad_cpp_evaluator/__init__.py +0 -0
  131. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/resources/fonts/LICENSE +0 -0
  132. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
  133. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/CMakeLists.txt +0 -0
  134. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/booleans.cpp +0 -0
  135. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/builtins.hpp +0 -0
  136. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/color.cpp +0 -0
  137. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/control.cpp +0 -0
  138. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/extrude.cpp +0 -0
  139. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/function_builtins.cpp +0 -0
  140. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/import.cpp +0 -0
  141. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/modifiers.cpp +0 -0
  142. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/primitives_2d.cpp +0 -0
  143. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/primitives_3d.cpp +0 -0
  144. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/registry.cpp +0 -0
  145. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/roof.cpp +0 -0
  146. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/segments.cpp +0 -0
  147. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/surface.cpp +0 -0
  148. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/text.cpp +0 -0
  149. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/topology.cpp +0 -0
  150. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/builtins/transforms.cpp +0 -0
  151. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/colored_body.cpp +0 -0
  152. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/csg_generate.cpp +0 -0
  153. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/css_colors.cpp +0 -0
  154. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/debug/debug_repl.cpp +0 -0
  155. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/debug_profile.cpp +0 -0
  156. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/eval_context.cpp +0 -0
  157. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/eval_use.cpp +0 -0
  158. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/export.cpp +0 -0
  159. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/expr_eval.cpp +0 -0
  160. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/import/dxf_import.cpp +0 -0
  161. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/import/mesh_import.cpp +0 -0
  162. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/import/surface_load.cpp +0 -0
  163. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/import/svg_import.cpp +0 -0
  164. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/manifold_cache.cpp +0 -0
  165. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/text/stb_font_provider.cpp +0 -0
  166. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/text/text_metrics.cpp +0 -0
  167. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/value.cpp +0 -0
  168. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/src/zip_stored.cpp +0 -0
  169. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/CMakeLists.txt +0 -0
  170. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_booleans.cpp +0 -0
  171. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_cli.cpp +0 -0
  172. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_dxf_svg_import.cpp +0 -0
  173. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_eval_context.cpp +0 -0
  174. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_export.cpp +0 -0
  175. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_expr_eval.cpp +0 -0
  176. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_extrude_roof.cpp +0 -0
  177. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_function_builtins.cpp +0 -0
  178. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_helpers.hpp +0 -0
  179. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_import_export.cpp +0 -0
  180. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_manifold_cache.cpp +0 -0
  181. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_multi_color_merge.cpp +0 -0
  182. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_primitives.cpp +0 -0
  183. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_profiling.cpp +0 -0
  184. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_python_bindings.py +0 -0
  185. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_scope_trail.cpp +0 -0
  186. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_scoping.cpp +0 -0
  187. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_surface.cpp +0 -0
  188. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_text.cpp +0 -0
  189. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_transforms.cpp +0 -0
  190. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_use.cpp +0 -0
  191. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_value.cpp +0 -0
  192. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_viewport_params.cpp +0 -0
  193. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tests/test_zip_stored.cpp +0 -0
  194. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tools/cli/CMakeLists.txt +0 -0
  195. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tools/cli/cli_lib.cpp +0 -0
  196. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tools/cli/cli_lib.hpp +0 -0
  197. {openscad_cpp_evaluator-0.9.2 → openscad_cpp_evaluator-0.13.0}/tools/cli/main.cpp +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscad_cpp_evaluator
3
- Version: 0.9.2
3
+ Version: 0.13.0
4
4
  Summary: C++ OpenSCAD evaluator with Python bindings
5
5
  Author: NeuSCAD Contributors
6
6
  License-Expression: MIT
@@ -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