openscad-cpp-evaluator 1.35.0__tar.gz → 1.37.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 (229) hide show
  1. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/CLAUDE.md +16 -2
  2. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/CMakeLists.txt +3 -0
  3. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/PKG-INFO +1 -1
  4. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/bindings/module.cpp +1 -1
  5. openscad_cpp_evaluator-1.37.0/cmake/patch_manifold.cmake +31 -0
  6. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +1 -1
  7. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/call_args.hpp +12 -0
  8. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/value.hpp +41 -15
  9. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/pyproject.toml +1 -1
  10. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/booleans.cpp +2 -2
  11. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/call_args.cpp +21 -4
  12. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/control.cpp +1 -1
  13. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/dxf_dim.cpp +1 -1
  14. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/extrude.cpp +4 -2
  15. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/function_builtins.cpp +1 -1
  16. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/import.cpp +11 -12
  17. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/primitives_2d.cpp +4 -4
  18. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/primitives_3d.cpp +7 -7
  19. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/registry.cpp +2 -2
  20. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/surface.cpp +2 -2
  21. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/text.cpp +2 -3
  22. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/bytecode_vm.cpp +9 -10
  23. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/colored_body.cpp +1 -1
  24. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/eval_context.cpp +2 -2
  25. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/expr_eval.cpp +15 -4
  26. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/measure_geometry.cpp +1 -1
  27. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/value.cpp +62 -21
  28. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/CMakeLists.txt +1 -0
  29. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_control_flow.cpp +91 -24
  30. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_expr_eval.cpp +26 -13
  31. openscad_cpp_evaluator-1.37.0/tests/test_undef_args.cpp +100 -0
  32. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_value.cpp +34 -19
  33. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_viewport_params.cpp +2 -2
  34. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/uv.lock +1 -1
  35. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/.github/workflows/ci.yml +0 -0
  36. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/.github/workflows/wheels.yml +0 -0
  37. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/.gitignore +0 -0
  38. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/.gitmodules +0 -0
  39. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/LICENSE +0 -0
  40. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/README.md +0 -0
  41. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/bindings/CMakeLists.txt +0 -0
  42. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/bindings/ast_to_py.cpp +0 -0
  43. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/cmake/embed_font.cmake +0 -0
  44. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/examples/CMakeLists.txt +0 -0
  45. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/examples/eval_perf_benchmark.cpp +0 -0
  46. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/examples/manifold_cache_reuse.cpp +0 -0
  47. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/examples/minimal_debugger.cpp +0 -0
  48. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
  49. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/.gitignore +0 -0
  50. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
  51. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
  52. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/README.md +0 -0
  53. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
  54. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
  55. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
  56. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
  57. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
  58. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
  59. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
  60. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
  61. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
  62. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
  63. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
  64. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
  65. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
  66. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
  67. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
  68. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
  69. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/.DS_Store +0 -0
  70. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
  71. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
  72. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
  73. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
  74. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
  75. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
  76. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
  77. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
  78. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
  79. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
  80. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
  81. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
  82. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
  83. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
  84. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
  85. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
  86. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
  87. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
  88. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
  89. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
  90. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
  91. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
  92. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
  93. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
  94. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
  95. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
  96. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
  97. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
  98. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_concurrent_parse.cpp +0 -0
  99. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
  100. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
  101. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
  102. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
  103. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
  104. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
  105. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
  106. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
  107. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
  108. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
  109. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
  110. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
  111. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
  112. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
  113. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
  114. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
  115. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
  116. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
  117. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
  118. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
  119. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
  120. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
  121. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
  122. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
  123. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
  124. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
  125. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
  126. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
  127. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
  128. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
  129. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
  130. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
  131. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
  132. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
  133. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
  134. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/export.hpp +0 -0
  135. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
  136. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
  137. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
  138. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
  139. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
  140. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
  141. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
  142. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
  143. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
  144. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
  145. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
  146. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
  147. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
  148. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
  149. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
  150. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
  151. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
  152. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/python/openscad_cpp_evaluator/__init__.py +0 -0
  153. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/resources/fonts/LICENSE +0 -0
  154. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/resources/fonts/LiberationSans-Bold.ttf +0 -0
  155. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
  156. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/resources/fonts/LiberationSans-Italic.ttf +0 -0
  157. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
  158. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/CMakeLists.txt +0 -0
  159. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/builtins.hpp +0 -0
  160. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/color.cpp +0 -0
  161. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/modifiers.cpp +0 -0
  162. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/roof.cpp +0 -0
  163. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/segments.cpp +0 -0
  164. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/topology.cpp +0 -0
  165. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/builtins/transforms.cpp +0 -0
  166. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/bytecode_compiler.cpp +0 -0
  167. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/coverage.cpp +0 -0
  168. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/csg_generate.cpp +0 -0
  169. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/csg_resolve.cpp +0 -0
  170. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/css_colors.cpp +0 -0
  171. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/debug/debug_repl.cpp +0 -0
  172. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/debug_profile.cpp +0 -0
  173. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/eval_error.cpp +0 -0
  174. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/eval_use.cpp +0 -0
  175. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/export.cpp +0 -0
  176. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/format_closure.cpp +0 -0
  177. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/import/dxf_import.cpp +0 -0
  178. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/import/mesh_import.cpp +0 -0
  179. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/import/scene_import.cpp +0 -0
  180. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/import/surface_load.cpp +0 -0
  181. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/import/svg_import.cpp +0 -0
  182. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/manifold_cache.cpp +0 -0
  183. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/mesh_check.cpp +0 -0
  184. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/stmt_eval.cpp +0 -0
  185. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/text/font_match.cpp +0 -0
  186. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/text/freetype_font_provider.cpp +0 -0
  187. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/text/text_metrics.cpp +0 -0
  188. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/user_calls.cpp +0 -0
  189. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/utf8.cpp +0 -0
  190. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/xkcd_colors.cpp +0 -0
  191. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/xkcd_colors.hpp +0 -0
  192. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/src/zip_stored.cpp +0 -0
  193. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_booleans.cpp +0 -0
  194. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_bytecode_compiler.cpp +0 -0
  195. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_children_separate.cpp +0 -0
  196. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_cli.cpp +0 -0
  197. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_coverage.cpp +0 -0
  198. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_csg_tree.cpp +0 -0
  199. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_debug_hooks.cpp +0 -0
  200. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_discretizer.cpp +0 -0
  201. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_dxf_svg_import.cpp +0 -0
  202. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_eval_context.cpp +0 -0
  203. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_export.cpp +0 -0
  204. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_extrude_roof.cpp +0 -0
  205. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_feature_detection.cpp +0 -0
  206. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_function_builtins.cpp +0 -0
  207. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_helpers.hpp +0 -0
  208. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_import_export.cpp +0 -0
  209. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_include_cache.cpp +0 -0
  210. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_manifold_cache.cpp +0 -0
  211. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_mesh_check.cpp +0 -0
  212. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_multi_color_merge.cpp +0 -0
  213. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_primitives.cpp +0 -0
  214. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_profiling.cpp +0 -0
  215. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_python_bindings.py +0 -0
  216. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_render_expr.cpp +0 -0
  217. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_scope_trail.cpp +0 -0
  218. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_scoping.cpp +0 -0
  219. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_surface.cpp +0 -0
  220. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_tail_calls.cpp +0 -0
  221. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_text.cpp +0 -0
  222. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_transforms.cpp +0 -0
  223. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_unexpected_args.cpp +0 -0
  224. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_use.cpp +0 -0
  225. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tests/test_zip_stored.cpp +0 -0
  226. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tools/cli/CMakeLists.txt +0 -0
  227. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tools/cli/cli_lib.cpp +0 -0
  228. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tools/cli/cli_lib.hpp +0 -0
  229. {openscad_cpp_evaluator-1.35.0 → openscad_cpp_evaluator-1.37.0}/tools/cli/main.cpp +0 -0
@@ -9,7 +9,14 @@ OpenSCAD AST and produces Manifold CSG geometry. This port builds on two depende
9
9
 
10
10
  - `openscad_cpp_parser` (git submodule, `external/openscad_cpp_parser`) for lexing/parsing/AST/scope
11
11
  - Manifold (https://github.com/elalish/manifold) v3.5.2, pulled in via CMake `FetchContent` (pinned
12
- tag, not vendored) — wired in as of Phase 2
12
+ tag, not vendored) — wired in as of Phase 2. **Patched at fetch time** by
13
+ `cmake/patch_manifold.cmake`: it deletes the `combined.RemoveDegenerates()` call in
14
+ `CsgLeafNode::Compose`, which on some inputs leaves the face data inconsistent so the sort after
15
+ it reads past an array (heap-buffer-overflow under ASan, reached by
16
+ `MinkowskiDifference.ShrinksANonConvexBodyOnEverySide`). Bisected with a Manifold-only repro to
17
+ upstream #1789 (969b1417), which fixes it by deleting the same call; unreleased as of 3.5.4.
18
+ The script fails the configure if the source around the call has changed, so **drop the patch
19
+ when bumping past #1789** rather than letting it rot
13
20
  - Boost.Polygon (`boostorg/polygon` + `boostorg/config`, fetched individually — not the full Boost
14
21
  superproject) for `roof()`'s Voronoi-diagram construction — wired in as of Phase 6, see below
15
22
  - `nothings/stb` (`stb_image.h`; header-only, no build step) for `surface()`'s PNG loader — wired
@@ -723,7 +730,14 @@ grep for `ponytail:`.
723
730
  parameter names live in `builtinParamNames` (`registry.cpp`): each list is the union of real
724
731
  OpenSCAD's own `Parameters::parse` declaration and any extra name this port reads via `getArg`,
725
732
  so the port never warns about an argument it goes on to honour — **add to it whenever a builtin
726
- gains a parameter**, or that parameter starts warning. Builtin *functions* deliberately have no
733
+ gains a parameter**, or that parameter starts warning. **An argument given as `undef` is not given**: `getArg`
734
+ returns the default for it, as every upstream builtin does (`if (v.isDefined())`). Wrappers
735
+ forward their own optional parameters as undef -- BOSL2's `rotate_extrude` override passes
736
+ `angle=angle`, and reading that as 0 degrees flattened every plain `rotate_extrude()` (#680).
737
+ Checked argument by argument against OpenSCAD 2026.02 (47 cases, `tests/test_undef_args.cpp`).
738
+ Aliases (`linear_extrude`'s `h`, `rotate_extrude`'s `a`) go through `getArgOrAlias`, which
739
+ warns `Specified both "height" and "h"` as upstream and lets the primary name win.
740
+ `linear_extrude`'s default height is 100, upstream's (it was 1). Builtin *functions* deliberately have no
727
741
  entries beyond `textmetrics`/`fontmetrics`: upstream reads their arguments positionally without
728
742
  `Parameters::parse`, so `sin(bogus=30)` warns about nothing there (verified against 2022.08.22)
729
743
  and warning here would be a divergence. Not ported: the reference's `argument X supplied more
@@ -137,6 +137,9 @@ FetchContent_Declare(
137
137
  GIT_REPOSITORY https://github.com/elalish/manifold.git
138
138
  GIT_TAG v3.5.2
139
139
  GIT_SHALLOW TRUE
140
+ # Backports the one line of upstream #1789 that fixes a heap overflow in
141
+ # CsgLeafNode::Compose -- see cmake/patch_manifold.cmake.
142
+ PATCH_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/patch_manifold.cmake
140
143
  )
141
144
  FetchContent_MakeAvailable(manifold)
142
145
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openscad_cpp_evaluator
3
- Version: 1.35.0
3
+ Version: 1.37.0
4
4
  Summary: C++ OpenSCAD evaluator with Python bindings
5
5
  Author: NeuSCAD Contributors
6
6
  License-Expression: MIT
@@ -76,7 +76,7 @@ oscadeval::Value pyToValue(nb::handle v) {
76
76
  std::vector<oscadeval::Value> items;
77
77
  for (nb::handle item : nb::borrow<nb::sequence>(v)) items.push_back(pyToValue(item));
78
78
  return oscadeval::Value{oscadeval::ListPtr(
79
- std::make_shared<const oscadeval::ValueList>(oscadeval::ValueList{std::move(items)}))};
79
+ oscadeval::makeList(std::move(items)))};
80
80
  }
81
81
  return oscadeval::Value{}; // monostate = undef
82
82
  }
@@ -0,0 +1,31 @@
1
+ # Patches the fetched Manifold v3.5.2 source; run as its FetchContent
2
+ # PATCH_COMMAND, in the source directory.
3
+ #
4
+ # CsgLeafNode::Compose calls RemoveDegenerates() on the combined mesh and
5
+ # then sorts it, and on some inputs the cleanup leaves the face data
6
+ # inconsistent: SortGeometry -> GatherFaces then reads past the end of an
7
+ # array (a heap-buffer-overflow under AddressSanitizer). Our
8
+ # MinkowskiDifference.ShrinksANonConvexBodyOnEverySide test reaches it;
9
+ # reproduced with Manifold alone, and bisected upstream to elalish/manifold
10
+ # #1789 ("Improved decimation", 969b1417), which fixes it by deleting this
11
+ # same call -- the only part of that commit the fix needs. Not in any
12
+ # release yet; drop this patch when Manifold is bumped past it.
13
+ #
14
+ # Idempotent: a re-run on already-patched source changes nothing. Anything
15
+ # else -- the call or its surroundings changed -- is an error, so a version
16
+ # bump can never silently skip the patch.
17
+ set(file src/csg_tree.cpp)
18
+ file(READ ${file} src)
19
+ set(call " // required to remove parts that are smaller than the tolerance\n combined.RemoveDegenerates();\n")
20
+ string(FIND "${src}" "${call}" at)
21
+ if(at EQUAL -1)
22
+ string(FIND "${src}" "combined.RemoveDegenerates();" any)
23
+ if(NOT any EQUAL -1)
24
+ message(FATAL_ERROR "patch_manifold.cmake: ${file} changed around RemoveDegenerates(); update the patch")
25
+ endif()
26
+ message(STATUS "patch_manifold.cmake: already applied")
27
+ return()
28
+ endif()
29
+ string(REPLACE "${call}" "" src "${src}")
30
+ file(WRITE ${file} "${src}")
31
+ message(STATUS "patch_manifold.cmake: removed RemoveDegenerates() from CsgLeafNode::Compose")
@@ -170,7 +170,7 @@ struct VmFrame {
170
170
  std::vector<Value> slots;
171
171
  std::vector<Value> stack;
172
172
  std::vector<bool> bound;
173
- std::vector<std::vector<Value>> accumStack;
173
+ std::vector<ListBuilder> accumStack;
174
174
  std::vector<IterList> iterLists;
175
175
  // std::deque, NOT vector: Evaluator::enterUserCall stores
176
176
  // CallStackFrame::bodyCtx as a pointer to ctxChain.back() (see
@@ -69,8 +69,20 @@ ResolvedCallArgs resolveCallArgs(Evaluator& ev, const std::vector<std::unique_pt
69
69
  // wins). `pos = std::nullopt` for an argument with no positional slot at
70
70
  // all (e.g. sphere's `d`, only ever named -- a later phase's need, plumbed
71
71
  // through now since the signature shape matters more than early callers).
72
+ //
73
+ // An argument given as undef counts as not given, as in every upstream
74
+ // builtin (`if (v.isDefined()) ...`): rotate_extrude(angle=undef) is 360
75
+ // degrees, not 0. It matters for wrappers that forward their own optional
76
+ // parameters -- BOSL2's rotate_extrude override passes `angle=angle`, which
77
+ // flattened every plain rotate_extrude() into its profile (#680).
72
78
  Value getArg(const CallArgs& args, std::optional<int> pos, const std::string& name, Value defaultValue = Value{});
73
79
 
80
+ // getArg for a parameter with an alternative name (linear_extrude's
81
+ // height/h, rotate_extrude's angle/a): `name` wins when both are given,
82
+ // with upstream's warning.
83
+ Value getArgOrAlias(Evaluator& ev, const oscad::Position* where, const CallArgs& args, std::optional<int> pos,
84
+ const std::string& name, const std::string& alias, Value defaultValue);
85
+
74
86
  // Encodes a CallArgs as a single Value (positional -> a list indexed 0..N,
75
87
  // named -> an object) so a resolve function can carry a call's raw
76
88
  // arguments across into CSGParams (which only holds Value) for a generate
@@ -3,6 +3,7 @@
3
3
  #include "openscad_cpp_evaluator/osc_range.hpp"
4
4
 
5
5
  #include <atomic>
6
+ #include <cstdint>
6
7
  #include <functional>
7
8
  #include <initializer_list>
8
9
  #include <memory>
@@ -114,41 +115,46 @@ inline std::shared_ptr<TrailView<Value>> capturedLetTrail(const Closure& c) {
114
115
  // with one compare-and-swap, so two lists sharing a prefix can never write
115
116
  // the same slot (the loser copies).
116
117
  struct ListBuffer {
117
- std::vector<Value> v;
118
- std::atomic<size_t> used;
118
+ std::vector<Value> v; // never reallocated once a list views it
119
+ std::atomic<uint32_t> used{0}; // with fromAppend, packs into one word
119
120
  // Set when this buffer came from appending: a list that was appended
120
121
  // to once is likely to be again, so ITS copies grow geometrically,
121
122
  // while a one-off concat's result is allocated at exactly its size.
122
123
  bool fromAppend = false;
123
- explicit ListBuffer(std::vector<Value>&& items) : v(std::move(items)), used(v.size()) {}
124
124
  };
125
125
 
126
+ // A list's elements: the first `size()` of a buffer. A list made by
127
+ // makeList keeps its buffer in its own allocation (keep_ empty); one made by
128
+ // appending in place views the buffer of the list it extends, and keep_
129
+ // holds that list's allocation alive. The element pointer is cached, so a
130
+ // read is one hop, as with a plain vector. Neither copyable nor movable:
131
+ // an own-buffer view must never outlive the allocation it sits in.
126
132
  class ListItems {
127
133
  public:
128
134
  ListItems() = default;
129
- ListItems(std::vector<Value>&& items) // NOLINT: implicit, as the old vector was
130
- : buf_(std::make_shared<ListBuffer>(std::move(items))), n_(buf_->v.size()) {}
131
- ListItems(const std::vector<Value>& items) : ListItems(std::vector<Value>(items)) {} // NOLINT
132
- ListItems(std::initializer_list<Value> items) : ListItems(std::vector<Value>(items)) {}
135
+ ListItems(const ListItems&) = delete;
136
+ ListItems& operator=(const ListItems&) = delete;
133
137
 
134
138
  size_t size() const { return n_; }
135
139
  bool empty() const { return n_ == 0; }
136
- const Value* data() const { return buf_ ? buf_->v.data() : nullptr; }
137
- const Value* begin() const { return data(); }
138
- const Value* end() const { return data() + n_; }
139
- const Value& operator[](size_t i) const { return data()[i]; }
140
+ const Value* data() const { return data_; }
141
+ const Value* begin() const { return data_; }
142
+ const Value* end() const { return data_ + n_; }
143
+ const Value& operator[](size_t i) const { return data_[i]; }
140
144
  const Value& at(size_t i) const;
141
- const Value& front() const { return data()[0]; }
142
- const Value& back() const { return data()[n_ - 1]; }
145
+ const Value& front() const { return data_[0]; }
146
+ const Value& back() const { return data_[n_ - 1]; }
143
147
  // A copy as a plain vector, for the few callers that build on one.
144
148
  // Explicit, so a copy is never made by accident binding a reference.
145
149
  explicit operator std::vector<Value>() const { return std::vector<Value>(begin(), end()); }
146
150
  std::vector<Value> toVector() const { return std::vector<Value>(begin(), end()); }
147
151
 
148
152
  private:
149
- ListItems(std::shared_ptr<ListBuffer> buf, size_t n) : buf_(std::move(buf)), n_(n) {}
150
- std::shared_ptr<ListBuffer> buf_;
153
+ std::shared_ptr<const void> keep_;
154
+ ListBuffer* buf_ = nullptr;
155
+ const Value* data_ = nullptr;
151
156
  size_t n_ = 0;
157
+ friend ListPtr makeList(std::vector<Value> items);
152
158
  friend ListPtr listAppend(const ListPtr& base, std::vector<Value>&& extra);
153
159
  };
154
160
 
@@ -156,6 +162,13 @@ struct ValueList {
156
162
  ListItems items;
157
163
  };
158
164
 
165
+ // A new list holding `items` (adopted, not copied): one allocation for the
166
+ // list and its buffer together, plus the elements' own -- as many as a list
167
+ // that was a plain vector cost.
168
+ ListPtr makeList(std::vector<Value> items);
169
+ inline ListPtr makeList() { return makeList(std::vector<Value>{}); }
170
+
171
+
159
172
  // `base` followed by `extra`, sharing base's buffer whenever base is the
160
173
  // longest list using it and the buffer has room: amortized O(|extra|)
161
174
  // rather than O(|base| + |extra|), which is what turns the idiomatic
@@ -164,6 +177,19 @@ struct ValueList {
164
177
  // its own elements.
165
178
  ListPtr listAppend(const ListPtr& base, std::vector<Value>&& extra);
166
179
 
180
+ // Builds a list literal or comprehension result from its contributions. When
181
+ // the first contribution is `each <a list>`, the result starts AS that list
182
+ // and everything after it is appended with listAppend -- so the other
183
+ // accumulator idiom, f(i, [each acc, x]), extends acc in place just as
184
+ // concat(acc, [x]) does, instead of copying it.
185
+ struct ListBuilder {
186
+ ListPtr seed; // the list an `each` started from, if any
187
+ std::vector<Value> rest; // everything contributed after it
188
+ void push(Value v) { rest.push_back(std::move(v)); }
189
+ void appendEach(const Value& v); // as appendEachInto
190
+ ListPtr finish();
191
+ };
192
+
167
193
  // Insertion-ordered key/value pairs, not a map: object()'s iteration order
168
194
  // and `==` are order-sensitive (doc: openscad_evaluator/docs/evaluator.md,
169
195
  // the object() entry).
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "openscad_cpp_evaluator"
7
- version = "1.35.0"
7
+ version = "1.37.0"
8
8
  description = "C++ OpenSCAD evaluator with Python bindings"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -143,9 +143,9 @@ CSGParams resolveCsg(Evaluator& ev, const oscad::ModularCall& node, EvalContext&
143
143
 
144
144
  CSGParams params;
145
145
  params["op"] = Value{op};
146
- params["group_sizes"] = Value{std::make_shared<const ValueList>(ValueList{std::move(groupSizes)})};
146
+ params["group_sizes"] = Value{makeList(std::move(groupSizes))};
147
147
  params["empty_is_a_group"] =
148
- Value{std::make_shared<const ValueList>(ValueList{std::move(emptyIsAGroup)})};
148
+ Value{makeList(std::move(emptyIsAGroup))};
149
149
  return params;
150
150
  }
151
151
 
@@ -56,14 +56,31 @@ CallArgs resolveArgs(Evaluator& ev, const std::vector<std::unique_ptr<oscad::Arg
56
56
  return result;
57
57
  }
58
58
 
59
+ namespace {
60
+ bool isUndef(const Value& v) { return std::holds_alternative<std::monostate>(v); }
61
+ } // namespace
62
+
59
63
  Value getArg(const CallArgs& args, std::optional<int> pos, const std::string& name, Value defaultValue) {
60
- if (const Value* named = args.findNamed(name)) return *named;
64
+ if (const Value* named = args.findNamed(name); named && !isUndef(*named)) return *named;
61
65
  if (pos.has_value()) {
62
- if (const Value* positional = args.findPositional(*pos)) return *positional;
66
+ if (const Value* positional = args.findPositional(*pos); positional && !isUndef(*positional))
67
+ return *positional;
63
68
  }
64
69
  return defaultValue;
65
70
  }
66
71
 
72
+ Value getArgOrAlias(Evaluator& ev, const oscad::Position* where, const CallArgs& args, std::optional<int> pos,
73
+ const std::string& name, const std::string& alias, Value defaultValue) {
74
+ const Value primary = getArg(args, pos, name, Value{});
75
+ const Value other = getArg(args, std::nullopt, alias, Value{});
76
+ if (!isUndef(primary)) {
77
+ if (!isUndef(other))
78
+ ev.warn("Specified both \"" + name + "\" and \"" + alias + "\"", where);
79
+ return primary;
80
+ }
81
+ return isUndef(other) ? defaultValue : other;
82
+ }
83
+
67
84
  ResolvedCallArgs resolveCallArgs(Evaluator& ev, const std::vector<std::unique_ptr<oscad::Argument>>& arguments,
68
85
  EvalContext& ctx) {
69
86
  CallArgs args = resolveArgs(ev, arguments, ctx);
@@ -93,10 +110,10 @@ Value callArgsToValue(const CallArgs& args) {
93
110
  std::vector<std::pair<std::string, Value>> namedVec(args.named.begin(), args.named.end());
94
111
 
95
112
  std::vector<Value> outer = {
96
- Value{std::make_shared<const ValueList>(ValueList{std::move(posVec)})},
113
+ Value{makeList(std::move(posVec))},
97
114
  Value{std::make_shared<const ValueObject>(ValueObject{std::move(namedVec)})},
98
115
  };
99
- return Value{std::make_shared<const ValueList>(ValueList{std::move(outer)})};
116
+ return Value{makeList(std::move(outer))};
100
117
  }
101
118
 
102
119
  const oscad::Expression* argExpr(const oscad::Argument& arg) {
@@ -141,7 +141,7 @@ CSGParams resolveIntersectionFor(Evaluator& ev, const oscad::ModularIntersection
141
141
  recurse(0, ctx);
142
142
 
143
143
  CSGParams params;
144
- params["group_sizes"] = Value{std::make_shared<const ValueList>(ValueList{std::move(groupSizes)})};
144
+ params["group_sizes"] = Value{makeList(std::move(groupSizes))};
145
145
  return params;
146
146
  }
147
147
 
@@ -234,7 +234,7 @@ Value builtinDxfCross(Evaluator& ev, const CallArgs& args, const oscad::ASTNode&
234
234
  if (dem == 0.0) break; // parallel: no cross, same as the reference
235
235
  const double ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / dem;
236
236
  std::vector<Value> xy{Value{x1 + ua * (x2 - x1)}, Value{y1 + ua * (y2 - y1)}};
237
- return Value{std::make_shared<const ValueList>(ValueList{std::move(xy)})};
237
+ return Value{makeList(std::move(xy))};
238
238
  }
239
239
  }
240
240
  ev.warn("Can't find cross in '" + c.rawFile + "', layer '" + c.layer + "'!", &node.position());
@@ -118,7 +118,9 @@ manifold::Manifold extrudeTwisted(const manifold::Polygons& polys, double height
118
118
  BuiltinWrapParams computeLinearExtrudeParams(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx) {
119
119
  auto [args, effCtx] = resolveCallArgs(ev, node.arguments, ctx);
120
120
 
121
- const double height = toDoubleLenient(getArg(args, 0, "height", Value{1.0}));
121
+ // 100 when not given, as upstream (the old 1 was a guess), and `h` as
122
+ // upstream's alias -- BOSL2's linear_extrude override forwards it.
123
+ const double height = toDoubleLenient(getArgOrAlias(ev, &node.position(), args, 0, "height", "h", Value{100.0}));
122
124
  const bool center = truthy(getArg(args, std::nullopt, "center", Value{false}));
123
125
  const double twist = toDoubleLenient(getArg(args, std::nullopt, "twist", Value{0.0}));
124
126
  // Upstream's validate_integral: any finite number counts as given, and is
@@ -239,7 +241,7 @@ std::vector<ColoredBody> generateLinearExtrude(Evaluator& ev, const CSGParams& p
239
241
  BuiltinWrapParams computeRotateExtrudeParams(Evaluator& ev, const oscad::ModularCall& node, EvalContext& ctx) {
240
242
  auto [args, effCtx] = resolveCallArgs(ev, node.arguments, ctx);
241
243
 
242
- const double angle = toDoubleLenient(getArg(args, 0, "angle", Value{360.0}));
244
+ const double angle = toDoubleLenient(getArgOrAlias(ev, &node.position(), args, 0, "angle", "a", Value{360.0}));
243
245
 
244
246
  CSGParams params;
245
247
  params["angle"] = Value{angle};
@@ -48,7 +48,7 @@ std::optional<std::vector<double>> allNumericList(const Value& v) {
48
48
  return out;
49
49
  }
50
50
 
51
- Value listOf(std::vector<Value> items) { return Value{std::make_shared<const ValueList>(ValueList{std::move(items)})}; }
51
+ Value listOf(std::vector<Value> items) { return Value{makeList(std::move(items))}; }
52
52
  Value numList(const std::vector<double>& xs) {
53
53
  std::vector<Value> items;
54
54
  items.reserve(xs.size());
@@ -66,7 +66,7 @@ Value jsonToValue(const nlohmann::ordered_json& j) {
66
66
  std::vector<Value> items;
67
67
  items.reserve(j.size());
68
68
  for (const auto& el : j) items.push_back(jsonToValue(el));
69
- return Value{std::make_shared<const ValueList>(ValueList{std::move(items)})};
69
+ return Value{makeList(std::move(items))};
70
70
  }
71
71
  if (j.is_object()) {
72
72
  std::vector<std::pair<std::string, Value>> items;
@@ -102,20 +102,19 @@ Value meshToVnf(const LoadedMesh& mesh) {
102
102
  if (it == vertMap.end()) {
103
103
  idx = static_cast<int>(vertsOut.size());
104
104
  vertMap.emplace(v, idx);
105
- vertsOut.push_back(Value{std::make_shared<const ValueList>(
106
- ValueList{{Value{v[0]}, Value{v[1]}, Value{v[2]}}})});
105
+ vertsOut.push_back(Value{makeList({Value{v[0]}, Value{v[1]}, Value{v[2]}})});
107
106
  } else {
108
107
  idx = it->second;
109
108
  }
110
109
  face.push_back(Value{static_cast<double>(idx)});
111
110
  }
112
- facesOut.push_back(Value{std::make_shared<const ValueList>(ValueList{std::move(face)})});
111
+ facesOut.push_back(Value{makeList(std::move(face))});
113
112
  }
114
113
  std::vector<Value> outer = {
115
- Value{std::make_shared<const ValueList>(ValueList{std::move(vertsOut)})},
116
- Value{std::make_shared<const ValueList>(ValueList{std::move(facesOut)})},
114
+ Value{makeList(std::move(vertsOut))},
115
+ Value{makeList(std::move(facesOut))},
117
116
  };
118
- return Value{std::make_shared<const ValueList>(ValueList{std::move(outer)})};
117
+ return Value{makeList(std::move(outer))};
119
118
  }
120
119
 
121
120
  } // namespace
@@ -152,10 +151,10 @@ Value contoursToValue(const std::vector<Contour2d>& contours) {
152
151
  for (const auto& c : contours) {
153
152
  std::vector<Value> pts;
154
153
  pts.reserve(c.size());
155
- for (const auto& p : c) pts.push_back(Value{std::make_shared<const ValueList>(ValueList{{Value{p[0]}, Value{p[1]}}})});
156
- outer.push_back(Value{std::make_shared<const ValueList>(ValueList{std::move(pts)})});
154
+ for (const auto& p : c) pts.push_back(Value{makeList({Value{p[0]}, Value{p[1]}})});
155
+ outer.push_back(Value{makeList(std::move(pts))});
157
156
  }
158
- return Value{std::make_shared<const ValueList>(ValueList{std::move(outer)})};
157
+ return Value{makeList(std::move(outer))};
159
158
  }
160
159
 
161
160
  std::vector<Contour2d> valueToContours(const Value& v) {
@@ -284,8 +283,8 @@ CSGParams resolveImport(Evaluator& ev, const oscad::ModularCall& node, EvalConte
284
283
  params["kind"] = Value{std::string("mesh")};
285
284
  params["repair"] = Value{repair};
286
285
  params["tolerance"] = toleranceArg;
287
- params["verts"] = Value{std::make_shared<const ValueList>(ValueList{std::move(vertsFlat)})};
288
- params["tris"] = Value{std::make_shared<const ValueList>(ValueList{std::move(trisFlat)})};
286
+ params["verts"] = Value{makeList(std::move(vertsFlat))};
287
+ params["tris"] = Value{makeList(std::move(trisFlat))};
289
288
  return params;
290
289
  }
291
290
  if (ext == ".json") {
@@ -79,9 +79,9 @@ CSGParams resolve2d(Evaluator& ev, const oscad::ModularCall& node, EvalContext&
79
79
  const double x = (pl && *pl && !(*pl)->items.empty()) ? toDoubleLenient((*pl)->items[0]) : 0.0;
80
80
  const double y = (pl && *pl && (*pl)->items.size() > 1) ? toDoubleLenient((*pl)->items[1]) : 0.0;
81
81
  std::vector<Value> xy = {Value{x}, Value{y}};
82
- pts.push_back(Value{std::make_shared<const ValueList>(ValueList{std::move(xy)})});
82
+ pts.push_back(Value{makeList(std::move(xy))});
83
83
  }
84
- params["pts"] = Value{std::make_shared<const ValueList>(ValueList{std::move(pts)})};
84
+ params["pts"] = Value{makeList(std::move(pts))};
85
85
 
86
86
  if (const ListPtr* pathsList = std::get_if<ListPtr>(&pathsArg); pathsList && *pathsList) {
87
87
  std::vector<Value> paths;
@@ -91,9 +91,9 @@ CSGParams resolve2d(Evaluator& ev, const oscad::ModularCall& node, EvalContext&
91
91
  if (pathIdxList && *pathIdxList) {
92
92
  for (const Value& idx : (*pathIdxList)->items) idxVals.push_back(Value{toDoubleLenient(idx)});
93
93
  }
94
- paths.push_back(Value{std::make_shared<const ValueList>(ValueList{std::move(idxVals)})});
94
+ paths.push_back(Value{makeList(std::move(idxVals))});
95
95
  }
96
- params["paths"] = Value{std::make_shared<const ValueList>(ValueList{std::move(paths)})};
96
+ params["paths"] = Value{makeList(std::move(paths))};
97
97
  } else {
98
98
  params["paths"] = Value{}; // undef == "no paths given" -- pts is one single contour
99
99
  }
@@ -141,7 +141,7 @@ CSGParams resolveCube(Evaluator& ev, const oscad::ModularCall& node, EvalContext
141
141
  }
142
142
 
143
143
  CSGParams params;
144
- params["size"] = Value{std::make_shared<const ValueList>(ValueList{std::move(sizeVec)})};
144
+ params["size"] = Value{makeList(std::move(sizeVec))};
145
145
  params["center"] = Value{center};
146
146
  params["color"] = colorToValue(effCtx.color);
147
147
  return params;
@@ -402,8 +402,8 @@ CSGParams resolveSphere(Evaluator& ev, const oscad::ModularCall& node, EvalConte
402
402
  // Manifold::Sphere IS a subdivided octahedron (Shape::Octahedron,
403
403
  // then Subdivide), so this needs no mesh of our own -- generate
404
404
  // calls it directly.
405
- params["verts"] = Value{std::make_shared<const ValueList>(ValueList{})};
406
- params["tris"] = Value{std::make_shared<const ValueList>(ValueList{})};
405
+ params["verts"] = Value{makeList()};
406
+ params["tris"] = Value{makeList()};
407
407
  return params;
408
408
  }
409
409
 
@@ -418,8 +418,8 @@ CSGParams resolveSphere(Evaluator& ev, const oscad::ModularCall& node, EvalConte
418
418
  std::vector<Value> trisValues;
419
419
  trisValues.reserve(m.tris.size());
420
420
  for (int t : m.tris) trisValues.push_back(Value{static_cast<double>(t)});
421
- params["verts"] = Value{std::make_shared<const ValueList>(ValueList{std::move(vertsValues)})};
422
- params["tris"] = Value{std::make_shared<const ValueList>(ValueList{std::move(trisValues)})};
421
+ params["verts"] = Value{makeList(std::move(vertsValues))};
422
+ params["tris"] = Value{makeList(std::move(trisValues))};
423
423
  return params;
424
424
  }
425
425
 
@@ -832,8 +832,8 @@ CSGParams resolvePolyhedron(Evaluator& ev, const oscad::ModularCall& node, EvalC
832
832
  for (uint32_t t : tris) trisValues.push_back(Value{static_cast<double>(t)});
833
833
 
834
834
  CSGParams params;
835
- params["verts"] = Value{std::make_shared<const ValueList>(ValueList{std::move(vertsValues)})};
836
- params["tris"] = Value{std::make_shared<const ValueList>(ValueList{std::move(trisValues)})};
835
+ params["verts"] = Value{makeList(std::move(vertsValues))};
836
+ params["tris"] = Value{makeList(std::move(trisValues))};
837
837
  params["color"] = colorToValue(effCtx.color);
838
838
  return params;
839
839
  }
@@ -125,8 +125,8 @@ const std::vector<std::string>* builtinParamNames(const std::string& name) {
125
125
  {"import",
126
126
  {"file", "layer", "convexity", "origin", "scale", "width", "height", "filename", "layername", "center", "dpi",
127
127
  "id", "class", "repair", "tolerance"}},
128
- {"linear_extrude", {"height", "v", "scale", "center", "twist", "slices", "segments", "convexity"}},
129
- {"rotate_extrude", {"angle", "start", "convexity"}},
128
+ {"linear_extrude", {"height", "h", "v", "scale", "center", "twist", "slices", "segments", "convexity"}},
129
+ {"rotate_extrude", {"angle", "a", "start", "convexity"}},
130
130
  {"projection", {"cut", "convexity"}},
131
131
  {"roof", {"method", "convexity"}},
132
132
  {"fill", {}},
@@ -44,9 +44,9 @@ CSGParams resolveSurface(Evaluator& ev, const oscad::ModularCall& node, EvalCont
44
44
  std::vector<Value> rowVals;
45
45
  rowVals.reserve(row.size());
46
46
  for (double v : row) rowVals.push_back(Value{v});
47
- rows.push_back(Value{std::make_shared<const ValueList>(ValueList{std::move(rowVals)})});
47
+ rows.push_back(Value{makeList(std::move(rowVals))});
48
48
  }
49
- params["heights"] = Value{std::make_shared<const ValueList>(ValueList{std::move(rows)})};
49
+ params["heights"] = Value{makeList(std::move(rows))};
50
50
  return params;
51
51
  }
52
52
 
@@ -69,8 +69,7 @@ CSGParams resolveText(Evaluator& ev, const oscad::ModularCall& node, EvalContext
69
69
  std::vector<Value> glyphs;
70
70
  glyphs.reserve(m.glyphs.size());
71
71
  for (const TextMeasurement::Placed& g : m.glyphs) {
72
- glyphs.push_back(Value{std::make_shared<const ValueList>(
73
- ValueList{{Value{static_cast<double>(g.glyph)}, Value{g.x}, Value{g.y}}})});
72
+ glyphs.push_back(Value{makeList({Value{static_cast<double>(g.glyph)}, Value{g.x}, Value{g.y}})});
74
73
  }
75
74
 
76
75
  CSGParams params;
@@ -89,7 +88,7 @@ CSGParams resolveText(Evaluator& ev, const oscad::ModularCall& node, EvalContext
89
88
  params["segs"] = Value{static_cast<double>(segs)};
90
89
  params["offset_x"] = Value{offsetX};
91
90
  params["offset_y"] = Value{offsetY};
92
- params["glyphs"] = Value{std::make_shared<const ValueList>(ValueList{std::move(glyphs)})};
91
+ params["glyphs"] = Value{makeList(std::move(glyphs))};
93
92
  params["color"] = colorToValue(effCtx.color);
94
93
  return params;
95
94
  }
@@ -792,7 +792,7 @@ Value driveVm(Evaluator& ev, size_t floor) {
792
792
  items[count - 1 - i] = std::move(f.stack.back());
793
793
  f.stack.pop_back();
794
794
  }
795
- f.stack.push_back(Value{std::make_shared<const ValueList>(ValueList{std::move(items)})});
795
+ f.stack.push_back(Value{makeList(std::move(items))});
796
796
  ++f.pc;
797
797
  break;
798
798
  }
@@ -803,28 +803,28 @@ Value driveVm(Evaluator& ev, size_t floor) {
803
803
  case Op::AccumAppendOne: {
804
804
  Value v = std::move(f.stack.back());
805
805
  f.stack.pop_back();
806
- f.accumStack.back().push_back(std::move(v));
806
+ f.accumStack.back().push(std::move(v));
807
807
  ++f.pc;
808
808
  break;
809
809
  }
810
810
  case Op::AccumAppendEach: {
811
811
  Value v = std::move(f.stack.back());
812
812
  f.stack.pop_back();
813
- appendEachInto(f.accumStack.back(), v);
813
+ f.accumStack.back().appendEach(v);
814
814
  ++f.pc;
815
815
  break;
816
816
  }
817
817
  case Op::AccumClose: {
818
- std::vector<Value> items = std::move(f.accumStack.back());
818
+ ListPtr list = f.accumStack.back().finish();
819
819
  f.accumStack.pop_back();
820
- f.stack.push_back(Value{std::make_shared<const ValueList>(ValueList{std::move(items)})});
820
+ f.stack.push_back(Value{std::move(list)});
821
821
  ++f.pc;
822
822
  break;
823
823
  }
824
824
  case Op::AccumMergeEach: {
825
- std::vector<Value> inner = std::move(f.accumStack.back());
825
+ const ListPtr inner = f.accumStack.back().finish();
826
826
  f.accumStack.pop_back();
827
- for (const Value& item : inner) appendEachInto(f.accumStack.back(), item);
827
+ for (const Value& item : inner->items) f.accumStack.back().appendEach(item);
828
828
  ++f.pc;
829
829
  break;
830
830
  }
@@ -1492,9 +1492,8 @@ Value driveVm(Evaluator& ev, size_t floor) {
1492
1492
  CSGParams params;
1493
1493
  if (site.includeOpParam) params["op"] = Value{pending.op};
1494
1494
  params["group_sizes"] =
1495
- Value{std::make_shared<const ValueList>(ValueList{std::move(pending.groupSizes)})};
1496
- params["empty_is_a_group"] = Value{std::make_shared<const ValueList>(
1497
- ValueList{std::move(pending.emptyIsAGroup)})};
1495
+ Value{makeList(std::move(pending.groupSizes))};
1496
+ params["empty_is_a_group"] = Value{makeList(std::move(pending.emptyIsAGroup))};
1498
1497
  // Mirrors Evaluator::buildTreeNode's own post-
1499
1498
  // resolveBody() half exactly (csg_resolve.cpp).
1500
1499
  const bool uncacheable =
@@ -5,7 +5,7 @@ namespace oscadeval {
5
5
  Value colorToValue(const std::optional<std::array<double, 4>>& color) {
6
6
  if (!color) return Value{};
7
7
  std::vector<Value> items = {Value{(*color)[0]}, Value{(*color)[1]}, Value{(*color)[2]}, Value{(*color)[3]}};
8
- return Value{std::make_shared<const ValueList>(ValueList{std::move(items)})};
8
+ return Value{makeList(std::move(items))};
9
9
  }
10
10
 
11
11
  std::optional<std::array<float, 4>> valueToColor(const Value& v) {
@@ -63,9 +63,9 @@ EvalContext EvalContext::makeRoot(const oscad::Scope* rootScope, const oscad::Sc
63
63
  // same script starts working there with no edit.
64
64
  ctx.dyn->set("$_SUPPORTED_FEATURE", Value{true});
65
65
  ctx.dyn->set("$_BELFRYSCAD",
66
- Value{std::make_shared<const ValueList>(ValueList{{Value{double{OSCAD_EVAL_VERSION_MAJOR}},
66
+ Value{makeList({Value{double{OSCAD_EVAL_VERSION_MAJOR}},
67
67
  Value{double{OSCAD_EVAL_VERSION_MINOR}},
68
- Value{double{OSCAD_EVAL_VERSION_PATCH}}}})});
68
+ Value{double{OSCAD_EVAL_VERSION_PATCH}}})});
69
69
  ctx.let_ = TrailView<Value>::makeRoot();
70
70
  ctx.dynPositions = TrailView<const oscad::Position*>::makeRoot();
71
71
  ctx.childrenNodes = emptyChildrenNodes();