openscad-cpp-evaluator 1.43.0__tar.gz → 1.45.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 (235) hide show
  1. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/CLAUDE.md +21 -5
  2. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/PKG-INFO +1 -1
  3. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/bytecode.hpp +36 -34
  4. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -9
  5. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/evaluator.hpp +14 -7
  6. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/format_closure.hpp +4 -0
  7. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/pyproject.toml +1 -1
  8. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/builtins.hpp +5 -11
  9. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/extrude.cpp +1 -3
  10. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/function_builtins.cpp +5 -3
  11. openscad_cpp_evaluator-1.45.0/src/builtins/roof.cpp +1162 -0
  12. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/text.cpp +7 -1
  13. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/bytecode_compiler.cpp +40 -20
  14. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/bytecode_vm.cpp +19 -27
  15. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/export.cpp +9 -1
  16. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/expr_eval.cpp +4 -6
  17. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/format_closure.cpp +2 -0
  18. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/stmt_eval.cpp +60 -21
  19. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/user_calls.cpp +8 -4
  20. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/value.cpp +48 -13
  21. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_bytecode_compiler.cpp +100 -26
  22. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_control_flow.cpp +3 -3
  23. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_csg_tree.cpp +2 -2
  24. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_expr_eval.cpp +2 -2
  25. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_extrude_roof.cpp +151 -8
  26. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_openscad_parity.cpp +36 -3
  27. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_python_bindings.py +14 -0
  28. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_use.cpp +1 -1
  29. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_value.cpp +28 -7
  30. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/uv.lock +1 -1
  31. openscad_cpp_evaluator-1.43.0/src/builtins/roof.cpp +0 -485
  32. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/.github/workflows/ci.yml +0 -0
  33. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/.github/workflows/wheels.yml +0 -0
  34. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/.gitignore +0 -0
  35. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/.gitmodules +0 -0
  36. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/CMakeLists.txt +0 -0
  37. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/LICENSE +0 -0
  38. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/README.md +0 -0
  39. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/bindings/CMakeLists.txt +0 -0
  40. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/bindings/ast_to_py.cpp +0 -0
  41. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/bindings/module.cpp +0 -0
  42. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/cmake/embed_font.cmake +0 -0
  43. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/cmake/patch_manifold.cmake +0 -0
  44. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/examples/CMakeLists.txt +0 -0
  45. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/examples/eval_perf_benchmark.cpp +0 -0
  46. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/examples/manifold_cache_reuse.cpp +0 -0
  47. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/examples/minimal_debugger.cpp +0 -0
  48. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
  49. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/.gitignore +0 -0
  50. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
  51. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
  52. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/LICENSE +0 -0
  53. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/README.md +0 -0
  54. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
  55. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
  56. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
  57. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
  58. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
  59. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
  60. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
  61. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
  62. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
  63. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
  64. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
  65. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
  66. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
  67. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
  68. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
  69. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
  70. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/.DS_Store +0 -0
  71. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
  72. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
  73. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
  74. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
  75. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
  76. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
  77. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
  78. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
  79. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
  80. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
  81. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
  82. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
  83. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
  84. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
  85. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
  86. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
  87. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
  88. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
  89. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
  90. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
  91. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
  92. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
  93. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
  94. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
  95. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
  96. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
  97. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
  98. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
  99. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_concurrent_parse.cpp +0 -0
  100. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
  101. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
  102. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
  103. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
  104. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
  105. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
  106. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
  107. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
  108. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
  109. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
  110. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_profile_time.cpp +0 -0
  111. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
  112. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
  113. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
  114. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
  115. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
  116. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
  117. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
  118. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
  119. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
  120. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
  121. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
  122. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
  123. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
  124. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
  125. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
  126. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
  127. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
  128. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
  129. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
  130. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
  131. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
  132. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
  133. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
  134. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
  135. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/export.hpp +0 -0
  136. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
  137. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
  138. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
  139. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
  140. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
  141. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
  142. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
  143. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
  144. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
  145. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
  146. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
  147. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
  148. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
  149. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
  150. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
  151. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/value.hpp +0 -0
  152. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
  153. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/python/openscad_cpp_evaluator/__init__.py +0 -0
  154. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/resources/fonts/LICENSE +0 -0
  155. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/resources/fonts/LiberationSans-Bold.ttf +0 -0
  156. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
  157. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/resources/fonts/LiberationSans-Italic.ttf +0 -0
  158. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
  159. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/CMakeLists.txt +0 -0
  160. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/booleans.cpp +0 -0
  161. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/call_args.cpp +0 -0
  162. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/color.cpp +0 -0
  163. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/control.cpp +0 -0
  164. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/dxf_dim.cpp +0 -0
  165. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/import.cpp +0 -0
  166. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/modifiers.cpp +0 -0
  167. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/primitives_2d.cpp +0 -0
  168. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/primitives_3d.cpp +0 -0
  169. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/profile_time.cpp +0 -0
  170. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/registry.cpp +0 -0
  171. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/segments.cpp +0 -0
  172. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/surface.cpp +0 -0
  173. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/topology.cpp +0 -0
  174. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/builtins/transforms.cpp +0 -0
  175. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/colored_body.cpp +0 -0
  176. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/coverage.cpp +0 -0
  177. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/csg_generate.cpp +0 -0
  178. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/csg_resolve.cpp +0 -0
  179. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/css_colors.cpp +0 -0
  180. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/debug/debug_repl.cpp +0 -0
  181. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/debug_profile.cpp +0 -0
  182. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/eval_context.cpp +0 -0
  183. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/eval_error.cpp +0 -0
  184. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/eval_use.cpp +0 -0
  185. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/import/dxf_import.cpp +0 -0
  186. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/import/mesh_import.cpp +0 -0
  187. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/import/scene_import.cpp +0 -0
  188. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/import/surface_load.cpp +0 -0
  189. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/import/svg_import.cpp +0 -0
  190. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/manifold_cache.cpp +0 -0
  191. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/measure_geometry.cpp +0 -0
  192. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/mesh_check.cpp +0 -0
  193. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/text/font_match.cpp +0 -0
  194. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/text/freetype_font_provider.cpp +0 -0
  195. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/text/text_metrics.cpp +0 -0
  196. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/utf8.cpp +0 -0
  197. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/xkcd_colors.cpp +0 -0
  198. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/xkcd_colors.hpp +0 -0
  199. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/src/zip_stored.cpp +0 -0
  200. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/CMakeLists.txt +0 -0
  201. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_booleans.cpp +0 -0
  202. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_children_separate.cpp +0 -0
  203. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_cli.cpp +0 -0
  204. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_coverage.cpp +0 -0
  205. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_debug_hooks.cpp +0 -0
  206. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_discretizer.cpp +0 -0
  207. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_dxf_svg_import.cpp +0 -0
  208. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_eval_context.cpp +0 -0
  209. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_export.cpp +0 -0
  210. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_feature_detection.cpp +0 -0
  211. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_function_builtins.cpp +0 -0
  212. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_helpers.hpp +0 -0
  213. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_import_export.cpp +0 -0
  214. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_include_cache.cpp +0 -0
  215. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_manifold_cache.cpp +0 -0
  216. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_mesh_check.cpp +0 -0
  217. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_multi_color_merge.cpp +0 -0
  218. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_primitives.cpp +0 -0
  219. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_profile_time.cpp +0 -0
  220. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_profiling.cpp +0 -0
  221. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_render_expr.cpp +0 -0
  222. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_scope_trail.cpp +0 -0
  223. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_scoping.cpp +0 -0
  224. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_surface.cpp +0 -0
  225. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_tail_calls.cpp +0 -0
  226. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_text.cpp +0 -0
  227. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_transforms.cpp +0 -0
  228. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_undef_args.cpp +0 -0
  229. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_unexpected_args.cpp +0 -0
  230. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_viewport_params.cpp +0 -0
  231. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tests/test_zip_stored.cpp +0 -0
  232. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tools/cli/CMakeLists.txt +0 -0
  233. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tools/cli/cli_lib.cpp +0 -0
  234. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tools/cli/cli_lib.hpp +0 -0
  235. {openscad_cpp_evaluator-1.43.0 → openscad_cpp_evaluator-1.45.0}/tools/cli/main.cpp +0 -0
@@ -211,8 +211,23 @@ Challenges and Experiences"), `roof.cpp` was rewritten from scratch as a close p
211
211
  `roof_vd.cc`'s `voronoi_diagram_roof`/`vd_inner_faces`/`discretize_arc` (CGAL/Eigen/Clipper2Lib
212
212
  swapped for `manifold::vec2` arithmetic and `manifold::Triangulate`), on top of Boost.Polygon's
213
213
  Voronoi builder (fetched as just `boostorg/polygon` + `boostorg/config`, confirmed to need nothing
214
- else from Boost). Both `method` values dispatch to this same construction (no CGAL-based `"straight"`
215
- path exists in this port). **Verified independently**, not just "it compiles": a brute-force
214
+ else from Boost). **`method="straight"` is its own construction** (`StraightSkeletonRoof` in
215
+ `roof.cpp`), a true straight-skeleton roof written from the literature (Aichholzer et al. 1995;
216
+ Felkel & Obdržálek 1998's event-driven wavefront) and the reference binary's black-box output --
217
+ no CGAL, and no OpenSCAD roof source read. It simulates the shrinking wavefront event by event
218
+ (edge, split and vertex events; a vertex event reconnects every wavefront edge at the meeting point
219
+ by angle), O(n^2 log n): 5000 vertices in ~0.5 s. Its input is welded first (`weldContours`: corners
220
+ within 2^-19 of the extent snapped together or onto edges, then a Clipper2 union), because a 2D
221
+ union often hands back pieces sharing an edge as separate outlines a hairline apart, and spikes
222
+ are cut away (`dropSpikes`). It matches OpenSCAD 2026.02.01 (`--enable=roof`) in volume, height and
223
+ vertex set on every shape compared that the reference does not crash on -- the reference segfaults
224
+ on many unions of rectangles/triangles that touch along edges, so those were checked only for being
225
+ valid 45-degree roofs (roof area = floor area x sqrt 2). Until this landed both methods built the
226
+ Voronoi roof, wrong for any concave outline. **Warnings**: `$fs`/`$fa` clamping (via the shared
227
+ `Discretizer::fromCtx`) and `Unknown roof method '...'` (a non-string shown as str() shows it) are
228
+ printed BEFORE the children run, as the reference does -- `computeRoofParams` therefore runs at
229
+ `Op::PushBuiltinWrap` time like every other wrap kind (it used to be deferred to Pop on the belief
230
+ that the warning followed the children). **Verified independently**, not just "it compiles": a brute-force
216
231
  distance-transform grid search over a square-frame-with-a-hole test case found the same ridge height
217
232
  (≈1.756) this implementation produces — the Python reference's own SDF fallback gets this case
218
233
  measurably wrong (≈1.5, ~15% low) since it was never more than a documented approximation for
@@ -1115,9 +1130,10 @@ grep for `ponytail:`.
1115
1130
  `toCrossSection`; no children/generate-time-bounds dependency, so its resolve/generate split is
1116
1131
  the simple kind (segment count for `r=` IS resolvable early here, unlike `rotate_extrude`'s,
1117
1132
  since `offset`'s own radius argument is already known at resolve time).
1118
- - `src/builtins/roof.cpp` — `roof()`, built on Boost.Polygon's segment Voronoi diagram (see the
1119
- `roof()` note above for the full story of why this replaced an earlier straight-skeleton
1120
- approximation mid-Phase-6). `voronoiRoof` scales the merged cross-section's polygons into signed
1133
+ - `src/builtins/roof.cpp` — `roof()`: the default `method="voronoi"` built on Boost.Polygon's
1134
+ segment Voronoi diagram (see the `roof()` note above for the full story of why this replaced an
1135
+ earlier straight-skeleton approximation mid-Phase-6), and `method="straight"`'s straight-skeleton
1136
+ wavefront simulation (`StraightSkeletonRoof`, same note). `voronoiRoof` scales the merged cross-section's polygons into signed
1121
1137
  32-bit integer coordinates (`chooseScale`, headroom below 2^31 for Boost.Polygon's own internal
1122
1138
  robustness margin), constructs the Voronoi diagram over the resulting segments, walks it
1123
1139
  (`vdInnerFaces`, discretizing parabolic point-vs-segment bisector edges via `discretizeArc`) to get
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscad_cpp_evaluator
3
- Version: 1.43.0
3
+ Version: 1.45.0
4
4
  Summary: C++ OpenSCAD evaluator with Python bindings
5
5
  Author: NeuSCAD Contributors
6
6
  License-Expression: MIT AND OFL-1.1
@@ -287,14 +287,13 @@ enum class Op {
287
287
  // this AFTER would silently drop uncacheable/ManifoldCache taint
288
288
  // tracking for a rands() call embedded in the wrapper's own
289
289
  // arguments), computes this site's own params for every kind except
290
- // Modifier (empty, no ctx push) and Roof (deferred to Pop -- see
291
- // BuiltinWrapSite's own doc comment) via that kind's own native
290
+ // Modifier (empty, no ctx push) via that kind's own native
292
291
  // compute function (computeTransformParams/computeColorParams/etc.,
293
292
  // builtins.hpp) -- always a possibly-$-scoped child EvalContext,
294
293
  // pushed onto f.ctxChain unconditionally for every non-Modifier kind
295
- // (Roof pushes it too, params or not) -- pushes a fresh ev.treeStack_
296
- // frame, and stashes {params, randsBefore, siteIdx, (Roof only)
297
- // deferredArgs} onto VmFrame::builtinWrapStack (a real per-frame LIFO
294
+ // -- pushes a fresh ev.treeStack_
295
+ // frame, and stashes {params, randsBefore, siteIdx} onto
296
+ // VmFrame::builtinWrapStack (a real per-frame LIFO
298
297
  // stack, not a single slot: Push/PopBuiltinWrap pairs can nest or
299
298
  // sequence within one frame's own instruction stream, e.g.
300
299
  // `translate(a) translate(b) recur();`). The compiler always emits a
@@ -311,12 +310,7 @@ enum class Op {
311
310
  // VmFrame::builtinWrapStack's own top entry FIRST (before anything
312
311
  // that can itself throw, e.g. Evaluator::setTreeDepthOrThrow below --
313
312
  // so the exception-teardown path's own pending count is already
314
- // correct if THIS throws); for Roof only, computes `pending.params`
315
- // HERE via computeRoofParams(ev, pending.deferredArgs, ctx) -- the one
316
- // kind whose params computation has an observable side effect
317
- // (ev.warn()) that must stay ordered AFTER children, unlike every
318
- // other kind's params (computed at Push, before children, since
319
- // nothing else in this group has an order-sensitive side effect); pops
313
+ // correct if THIS throws); pops
320
314
  // the ctx Push made (every kind except Modifier); pops ev.treeStack_
321
315
  // to retrieve the children this bracket's own body produced, and
322
316
  // builds the tagged CSGNode exactly like Evaluator::buildTreeNode's
@@ -511,7 +505,7 @@ enum class Op {
511
505
  // anything compileStatementList doesn't give its own real bytecode.
512
506
  // (Assignment/ModularEcho/ModularAssert/ModularLet used to fall here
513
507
  // too; they now have their own real bytecode -- Op::StoreModuleVar/
514
- // Op::Echo/Op::AssertStatement/Op::OpenLetScope+StoreLetVar -- purely
508
+ // Op::Echo/Op::AssertPass+AssertFail/Op::OpenLetScope+StoreLetVar -- purely
515
509
  // a throughput change, since none of these were ever the recursion-
516
510
  // depth risk this compiler targets. `#`/`%`/`!` modifiers and
517
511
  // translate/rotate/scale/mirror/multmatrix/resize/color used to fall
@@ -640,14 +634,9 @@ enum class Op {
640
634
  // the position recorded into dynPositions).
641
635
  StoreModuleVar,
642
636
 
643
- // ModularEcho/ModularAssert's own statement form share Op::Echo/a
644
- // dedicated AssertStatement op (below) for the "pop N already-compiled
645
- // argument values" mechanics -- see those ops' own doc comments
646
- // (Op::Echo, above; Op::AssertStatement, below) for why the
647
- // EXPRESSION-form opcodes are directly reusable (statement-shaped
648
- // already: no value pushed, straight fall-through) while assert's
649
- // needs its own op (named-argument support + eager-not-lazy message
650
- // evaluation, both genuinely different from AssertOp's own contract).
637
+ // ModularEcho/ModularAssert's own statement form share Op::Echo and
638
+ // Op::AssertPass/AssertFail (below) with the expression forms: both are
639
+ // statement-shaped already (no value pushed, straight fall-through).
651
640
 
652
641
  // Isolates ONE inline-compiled sub-expression's own `$`-writes from the
653
642
  // rest of this chunk's shared, long-lived ctx -- pushes ctx.
@@ -703,12 +692,15 @@ enum class Op {
703
692
  // the handler itself, kept for consistency/future debugging only).
704
693
  StoreLetVar,
705
694
 
706
- // a = index into CompiledChunk::assertSites. Pops site.argCount values
707
- // (every argument of an assert() statement or expression, pushed in
708
- // source order) and hands them to Evaluator::checkAssert; a statement
709
- // then runs any chained children natively (rare; not worth its own
710
- // compiled path).
711
- AssertStatement,
695
+ // assert(): the condition is compiled first, then JumpIfFalse to the
696
+ // failure path; the passing path never evaluates any other argument
697
+ // (see Evaluator::evalAssert). a = index into CompiledChunk::assertSites.
698
+ // AssertPass prints the site's unexpected-argument warnings and runs a
699
+ // statement's chained children; it is emitted only when the site has
700
+ // either. AssertFail pops every non-condition argument (source order)
701
+ // and throws via Evaluator::failAssert.
702
+ AssertPass,
703
+ AssertFail,
712
704
  // a = nativeStatements index of the AST node whose arm this is. Emitted
713
705
  // only when the Evaluator was built with coverage on (compile-time
714
706
  // flag, and chunks are per-Evaluator): Evaluator::coverHit(node), nothing
@@ -717,6 +709,17 @@ enum class Op {
717
709
  Cover,
718
710
  };
719
711
 
712
+ // Which of an assert() call's arguments are its condition and message, and
713
+ // whether the call has any unexpected argument to warn about -- all fixed by
714
+ // the call's shape, so worked out once per call site (assertLayout,
715
+ // stmt_eval.cpp). -1 = not given.
716
+ struct AssertLayout {
717
+ int cond = -1;
718
+ int msg = -1;
719
+ bool warns = false;
720
+ };
721
+ AssertLayout assertLayout(const std::vector<std::unique_ptr<oscad::Argument>>& arguments);
722
+
720
723
  struct Instruction {
721
724
  Op op;
722
725
  int a = 0;
@@ -956,10 +959,9 @@ struct CompiledChunk {
956
959
  // rotate_extrude()/projection()/offset()/roof()) share Transform/
957
960
  // Color's exact push-time-computed-params shape, just via a different
958
961
  // native compute function each (Op::PushBuiltinWrap's own runtime
959
- // handler switches on `kind` to pick it) -- see that op's own doc
960
- // comment for the one exception (Roof, whose params computation has
961
- // to run at POP time instead, after children, to preserve an
962
- // observable warn() ordering).
962
+ // handler switches on `kind` to pick it). Roof's warnings ($fs/$fa
963
+ // clamping, unknown method) therefore come before its children's
964
+ // output, as in OpenSCAD 2026.02.01.
963
965
  struct BuiltinWrapSite {
964
966
  enum class Kind {
965
967
  Transform,
@@ -977,7 +979,7 @@ struct CompiledChunk {
977
979
  RotateExtrude,
978
980
  Projection,
979
981
  Offset,
980
- Roof, // computed at POP time, not PUSH -- see this struct's own doc comment
982
+ Roof,
981
983
  };
982
984
  Kind kind;
983
985
  std::string tagName; // "translate"/"rotate"/.../"color"/"highlight"/"background"/"show_only"/"hull"/...
@@ -1021,10 +1023,10 @@ struct CompiledChunk {
1021
1023
  const oscad::ASTNode* node = nullptr;
1022
1024
  };
1023
1025
 
1024
- // One Op::AssertStatement site. `statement` is null for the expression
1025
- // form, which has no children.
1026
+ // One Op::AssertPass/AssertFail site. `statement` is null for the
1027
+ // expression form, which has no children.
1026
1028
  struct AssertSite {
1027
- int argCount = 0;
1029
+ AssertLayout layout;
1028
1030
  const std::vector<std::unique_ptr<oscad::Argument>>* arguments = nullptr;
1029
1031
  const oscad::ASTNode* node = nullptr;
1030
1032
  const oscad::ModularAssert* statement = nullptr;
@@ -30,15 +30,6 @@ struct PendingBuiltinWrap {
30
30
  CSGParams params;
31
31
  std::uint64_t randsBefore = 0;
32
32
  int siteIdx = -1;
33
- // Only populated for BuiltinWrapSite::Kind::Roof -- the already-
34
- // resolved call arguments, retained across the whole bracket so
35
- // Op::PopBuiltinWrap's handler can compute roof()'s own params AFTER
36
- // children finish (computeRoofParams needs them; re-running
37
- // resolveCallArgs at Pop time instead would re-evaluate every argument
38
- // expression a second time -- double rands()/side effects). Every
39
- // other kind computes its params at Push time and leaves this default-
40
- // empty.
41
- CallArgs deferredArgs;
42
33
 
43
34
  // ev.measuring_ as it stood immediately BEFORE this bracket opened.
44
35
  // Recorded for EVERY kind, not just Measure, so the exception teardown
@@ -565,13 +565,20 @@ public:
565
565
  void warnUndefinedEscapes(const oscad::StringLiteral& lit, int count);
566
566
  // let() keeps the FIRST binding of a repeated name: OpenSCAD evaluates
567
567
  // the later right-hand side, warns with its value, and discards it.
568
- // OpenSCAD's Assert::performAssert, given every argument's value in
569
- // source order -- it evaluates them all, pass or fail, so a passing
570
- // `assert(true, nosuch)` still warns. Warns about unexpected arguments;
571
- // throws via error() when the condition is false or missing (`assert()`
572
- // fails). The message prints as echo() would print it.
573
- void checkAssert(const std::vector<std::unique_ptr<oscad::Argument>>& arguments, const std::vector<Value>& values,
574
- const oscad::ASTNode& node);
568
+ // assert(), interpreted: the condition first, and only on failure the
569
+ // message and any other argument -- see the definition (stmt_eval.cpp)
570
+ // for why this deliberately diverges from OpenSCAD. `maybeCompiled`
571
+ // picks evalExprMaybeCompiled (statement form) over evalExpr.
572
+ void evalAssert(const std::vector<std::unique_ptr<oscad::Argument>>& arguments, const oscad::ASTNode& node,
573
+ EvalContext& ctx, bool maybeCompiled);
574
+ // The unexpected-argument warnings, which a passing assert still prints.
575
+ void warnAssertArgs(const std::vector<std::unique_ptr<oscad::Argument>>& arguments, const AssertLayout& layout);
576
+ // A failed (or condition-less) assert, once every non-condition argument
577
+ // has been evaluated: warns about unexpected arguments, then throws via
578
+ // error(). `message` is null when none was given; it prints as echo()
579
+ // would print it.
580
+ [[noreturn]] void failAssert(const std::vector<std::unique_ptr<oscad::Argument>>& arguments,
581
+ const AssertLayout& layout, const Value* message, const oscad::ASTNode& node);
575
582
  void warnDuplicateLet(const std::string& name, const Value& v, const oscad::Position* position);
576
583
  template <typename Assignments>
577
584
  static bool repeatsEarlierLetName(const Assignments& assignments, size_t i) {
@@ -3,6 +3,7 @@
3
3
  #include <string>
4
4
 
5
5
  namespace oscad {
6
+ class ASTNode;
6
7
  class FunctionLiteral;
7
8
  }
8
9
 
@@ -16,5 +17,8 @@ namespace oscadeval {
16
17
  // precedence-minimal and which 94 places inside the parser depend on. See
17
18
  // format_closure.cpp for where each rule came from.
18
19
  std::string formatFunctionLiteral(const oscad::FunctionLiteral& fn);
20
+ // Any expression, spelled the same way: what assert() quotes as its
21
+ // condition ("Assertion '(a > 1)' failed").
22
+ std::string formatExpression(const oscad::ASTNode& expr);
19
23
 
20
24
  } // namespace oscadeval
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "openscad_cpp_evaluator"
7
- version = "1.43.0"
7
+ version = "1.45.0"
8
8
  description = "C++ OpenSCAD evaluator with Python bindings"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -246,17 +246,11 @@ CSGParams resolveOffset(Evaluator& ev, const oscad::ModularCall& node, EvalConte
246
246
  std::vector<ColoredBody> generateOffset(Evaluator& ev, const CSGParams& params,
247
247
  const std::vector<std::unique_ptr<CSGNode>>& children, const oscad::ASTNode& node);
248
248
 
249
- // roof() -- roof.cpp. Tier 1 (exact straight skeleton, stable single-
250
- // contour polygons) + Tier 3 (SDF/level-set fallback) only, per the plan --
251
- // Tier 2 (general multi-contour/hole straight skeleton) is a named,
252
- // documented follow-up, not silently dropped (see CLAUDE.md).
253
- // computeRoofParams: UNLIKE computeLinearExtrudeParams and friends above,
254
- // this is the params-computation half taken from AFTER evalChildren (it
255
- // calls ev.warn(), an observable side effect that must stay ordered after
256
- // any child's own echo/warn output) -- takes already-resolved CallArgs,
257
- // not a raw node+ctx, since Op::PushBuiltinWrap's own runtime handler
258
- // calls this at POP time. See its own doc comment (roof.cpp).
259
- CSGParams computeRoofParams(Evaluator& ev, const CallArgs& args, EvalContext& effCtx);
249
+ // roof() -- roof.cpp. method="voronoi" (the default) is the Voronoi-diagram
250
+ // roof, method="straight" the straight-skeleton one.
251
+ // computeRoofParams: the params half, from already-resolved arguments;
252
+ // it warns ($fs/$fa clamping, unknown method), before the children run.
253
+ CSGParams computeRoofParams(Evaluator& ev, const CallArgs& args, EvalContext& effCtx, const oscad::Position* where);
260
254
  CSGParams resolveRoof(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx);
261
255
  std::vector<ColoredBody> generateRoof(Evaluator& ev, const CSGParams& params,
262
256
  const std::vector<std::unique_ptr<CSGNode>>& children, const oscad::ASTNode& node);
@@ -27,9 +27,7 @@ namespace oscadeval {
27
27
  // side effect of its own (no warn()/echo()/rands() call), so moving it
28
28
  // before evalChildren (unlike this function's own former single-body
29
29
  // shape, which computed params AFTER children like every other builtin
30
- // still not covered by PushBuiltinWrap) is behaviorally unobservable --
31
- // see computeRoofParams's own doc comment (roof.cpp) for the one builtin
32
- // in this group where that ISN'T true and a different split was needed.
30
+ // still not covered by PushBuiltinWrap) is behaviorally unobservable.
33
31
  namespace {
34
32
 
35
33
  // Picks the diagonal that splits one side quad: true for A0-B1, false for
@@ -1242,9 +1242,12 @@ Value evalBuiltinFunctionResolved(Evaluator& ev, BuiltinFnId id, const std::vect
1242
1242
  // was 0, concat(a=[1], b=[2]) was [], rands(seed_value=) went unseeded.
1243
1243
  // (textmetrics/fontmetrics -- with declaredParams -- and dxf_dim/
1244
1244
  // dxf_cross bind by name in OpenSCAD too.)
1245
+ // The common all-positional call goes straight through, with no
1246
+ // reordered copy built (or destroyed) on its way.
1245
1247
  const bool byName = declaredParams || id == BuiltinFnId::DxfDim || id == BuiltinFnId::DxfCross;
1248
+ if (byName || args.named.empty()) return evalBuiltinFunctionInOrder(ev, id, name, args, node);
1246
1249
  CallArgs ordered;
1247
- if (!byName && node.kind() == oscad::NodeKind::PrimaryCall && !args.named.empty()) {
1250
+ if (node.kind() == oscad::NodeKind::PrimaryCall) {
1248
1251
  int k = 0, out = 0;
1249
1252
  for (const auto& a : static_cast<const oscad::PrimaryCall&>(node).arguments) {
1250
1253
  const Value* v = nullptr;
@@ -1258,8 +1261,7 @@ Value evalBuiltinFunctionResolved(Evaluator& ev, BuiltinFnId id, const std::vect
1258
1261
  ordered.setPositional(out++, v ? *v : Value{});
1259
1262
  }
1260
1263
  }
1261
- const CallArgs& argsInOrder = (!byName && !args.named.empty()) ? ordered : args;
1262
- return evalBuiltinFunctionInOrder(ev, id, name, argsInOrder, node);
1264
+ return evalBuiltinFunctionInOrder(ev, id, name, ordered, node);
1263
1265
  }
1264
1266
 
1265
1267
  Value evalBuiltinFunctionInOrder(Evaluator& ev, BuiltinFnId id, const std::string& name, const CallArgs& args,