mt-lang 0.2.0

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 (258) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-version +1 -0
  3. data/AUTHORS +3 -0
  4. data/Gemfile +19 -0
  5. data/Gemfile.lock +82 -0
  6. data/LICENSE +21 -0
  7. data/README.md +1208 -0
  8. data/Rakefile +332 -0
  9. data/bin/mtc +8 -0
  10. data/bin/profile-mtc-checks +133 -0
  11. data/bin/tracy-profiler +0 -0
  12. data/docs/build-guide.md +536 -0
  13. data/docs/index.html +2778 -0
  14. data/docs/language-design.md +1519 -0
  15. data/docs/language-manual.md +1534 -0
  16. data/lib/milk_tea/base.rb +49 -0
  17. data/lib/milk_tea/bindings/bindgen/ast_parser.rb +398 -0
  18. data/lib/milk_tea/bindings/bindgen/declaration.rb +319 -0
  19. data/lib/milk_tea/bindings/bindgen/emitter.rb +387 -0
  20. data/lib/milk_tea/bindings/bindgen/overrides.rb +134 -0
  21. data/lib/milk_tea/bindings/bindgen/type_mapper.rb +622 -0
  22. data/lib/milk_tea/bindings/bindgen.rb +207 -0
  23. data/lib/milk_tea/bindings/cli.rb +121 -0
  24. data/lib/milk_tea/bindings/imported_bindings/defaults.rb +210 -0
  25. data/lib/milk_tea/bindings/imported_bindings/generator.rb +1114 -0
  26. data/lib/milk_tea/bindings/imported_bindings/method_source.rb +190 -0
  27. data/lib/milk_tea/bindings/imported_bindings/naming.rb +286 -0
  28. data/lib/milk_tea/bindings/imported_bindings.rb +215 -0
  29. data/lib/milk_tea/bindings/opengl_registry.rb +547 -0
  30. data/lib/milk_tea/bindings/raw_bindings/defaults.rb +1338 -0
  31. data/lib/milk_tea/bindings/raw_bindings.rb +269 -0
  32. data/lib/milk_tea/bindings/steamworks.rb +629 -0
  33. data/lib/milk_tea/bindings/upstream_sources.rb +352 -0
  34. data/lib/milk_tea/bindings/vendored_box2d.rb +79 -0
  35. data/lib/milk_tea/bindings/vendored_c_library.rb +322 -0
  36. data/lib/milk_tea/bindings/vendored_cjson.rb +52 -0
  37. data/lib/milk_tea/bindings/vendored_flecs.rb +78 -0
  38. data/lib/milk_tea/bindings/vendored_glfw.rb +77 -0
  39. data/lib/milk_tea/bindings/vendored_libuv.rb +75 -0
  40. data/lib/milk_tea/bindings/vendored_pcre2.rb +84 -0
  41. data/lib/milk_tea/bindings/vendored_raylib.rb +131 -0
  42. data/lib/milk_tea/bindings/vendored_sdl3.rb +78 -0
  43. data/lib/milk_tea/bindings/vendored_steamworks.rb +71 -0
  44. data/lib/milk_tea/bindings/vendored_tool.rb +71 -0
  45. data/lib/milk_tea/bindings/vendored_tools.rb +23 -0
  46. data/lib/milk_tea/bindings/vendored_tracy.rb +37 -0
  47. data/lib/milk_tea/bindings.rb +23 -0
  48. data/lib/milk_tea/core/ast.rb +311 -0
  49. data/lib/milk_tea/core/async_runtime_installer.rb +28 -0
  50. data/lib/milk_tea/core/binding_types.rb +18 -0
  51. data/lib/milk_tea/core/bindings/attribute_binding.rb +58 -0
  52. data/lib/milk_tea/core/bindings/function_binding.rb +5 -0
  53. data/lib/milk_tea/core/bindings/module_binding.rb +58 -0
  54. data/lib/milk_tea/core/bindings/value_binding.rb +21 -0
  55. data/lib/milk_tea/core/c_backend/aggregate_utils.rb +103 -0
  56. data/lib/milk_tea/core/c_backend/control_flow_emission.rb +412 -0
  57. data/lib/milk_tea/core/c_backend/expressions.rb +468 -0
  58. data/lib/milk_tea/core/c_backend/feature_detection.rb +483 -0
  59. data/lib/milk_tea/core/c_backend/reachability.rb +398 -0
  60. data/lib/milk_tea/core/c_backend/reinterpret.rb +226 -0
  61. data/lib/milk_tea/core/c_backend/runtime_helpers.rb +1080 -0
  62. data/lib/milk_tea/core/c_backend/statements.rb +563 -0
  63. data/lib/milk_tea/core/c_backend/type_collectors.rb +1545 -0
  64. data/lib/milk_tea/core/c_backend/type_declaration.rb +223 -0
  65. data/lib/milk_tea/core/c_backend/type_system.rb +345 -0
  66. data/lib/milk_tea/core/c_backend.rb +287 -0
  67. data/lib/milk_tea/core/compatibility_helpers.rb +79 -0
  68. data/lib/milk_tea/core/compile_time/const_eval.rb +187 -0
  69. data/lib/milk_tea/core/compile_time.rb +329 -0
  70. data/lib/milk_tea/core/control_flow/builder.rb +582 -0
  71. data/lib/milk_tea/core/control_flow/constant_propagation.rb +143 -0
  72. data/lib/milk_tea/core/control_flow/dataflow.rb +74 -0
  73. data/lib/milk_tea/core/control_flow/definite_assignment.rb +79 -0
  74. data/lib/milk_tea/core/control_flow/graph.rb +90 -0
  75. data/lib/milk_tea/core/control_flow/liveness.rb +24 -0
  76. data/lib/milk_tea/core/control_flow/nullability_flow.rb +43 -0
  77. data/lib/milk_tea/core/control_flow/reachability.rb +22 -0
  78. data/lib/milk_tea/core/control_flow/termination.rb +31 -0
  79. data/lib/milk_tea/core/control_flow.rb +34 -0
  80. data/lib/milk_tea/core/cst.rb +48 -0
  81. data/lib/milk_tea/core/cst_builder.rb +19 -0
  82. data/lib/milk_tea/core/ir.rb +85 -0
  83. data/lib/milk_tea/core/keywords.rb +97 -0
  84. data/lib/milk_tea/core/lexer/character_classes.rb +60 -0
  85. data/lib/milk_tea/core/lexer/format_strings.rb +225 -0
  86. data/lib/milk_tea/core/lexer/heredocs.rb +199 -0
  87. data/lib/milk_tea/core/lexer/indentation.rb +62 -0
  88. data/lib/milk_tea/core/lexer/numbers.rb +96 -0
  89. data/lib/milk_tea/core/lexer/recovery.rb +32 -0
  90. data/lib/milk_tea/core/lexer/strings.rb +167 -0
  91. data/lib/milk_tea/core/lexer/symbols.rb +71 -0
  92. data/lib/milk_tea/core/lexer/trivia.rb +53 -0
  93. data/lib/milk_tea/core/lexer.rb +430 -0
  94. data/lib/milk_tea/core/lowering/artifacts.rb +26 -0
  95. data/lib/milk_tea/core/lowering/async/analysis.rb +245 -0
  96. data/lib/milk_tea/core/lowering/async/lowering.rb +1399 -0
  97. data/lib/milk_tea/core/lowering/async/normalization.rb +459 -0
  98. data/lib/milk_tea/core/lowering/async.rb +714 -0
  99. data/lib/milk_tea/core/lowering/block.rb +1052 -0
  100. data/lib/milk_tea/core/lowering/calls.rb +1565 -0
  101. data/lib/milk_tea/core/lowering/declarations.rb +214 -0
  102. data/lib/milk_tea/core/lowering/dyn.rb +206 -0
  103. data/lib/milk_tea/core/lowering/events.rb +1054 -0
  104. data/lib/milk_tea/core/lowering/expressions.rb +1645 -0
  105. data/lib/milk_tea/core/lowering/foreign_cstr.rb +206 -0
  106. data/lib/milk_tea/core/lowering/functions.rb +242 -0
  107. data/lib/milk_tea/core/lowering/loops.rb +1087 -0
  108. data/lib/milk_tea/core/lowering/lowering_context.rb +80 -0
  109. data/lib/milk_tea/core/lowering/proc.rb +419 -0
  110. data/lib/milk_tea/core/lowering/resolve.rb +2516 -0
  111. data/lib/milk_tea/core/lowering/scans.rb +220 -0
  112. data/lib/milk_tea/core/lowering/str_buffer.rb +125 -0
  113. data/lib/milk_tea/core/lowering/utils.rb +1453 -0
  114. data/lib/milk_tea/core/lowering.rb +378 -0
  115. data/lib/milk_tea/core/module_binder.rb +181 -0
  116. data/lib/milk_tea/core/module_loader/errors.rb +21 -0
  117. data/lib/milk_tea/core/module_loader.rb +479 -0
  118. data/lib/milk_tea/core/module_path_resolver.rb +153 -0
  119. data/lib/milk_tea/core/module_roots.rb +88 -0
  120. data/lib/milk_tea/core/parser/attributes.rb +71 -0
  121. data/lib/milk_tea/core/parser/blocks.rb +119 -0
  122. data/lib/milk_tea/core/parser/declarations.rb +749 -0
  123. data/lib/milk_tea/core/parser/expressions.rb +624 -0
  124. data/lib/milk_tea/core/parser/recovery.rb +131 -0
  125. data/lib/milk_tea/core/parser/statements.rb +756 -0
  126. data/lib/milk_tea/core/parser/types.rb +271 -0
  127. data/lib/milk_tea/core/parser.rb +400 -0
  128. data/lib/milk_tea/core/prelude_installer.rb +29 -0
  129. data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +917 -0
  130. data/lib/milk_tea/core/pretty_printer/base_formatter.rb +87 -0
  131. data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +300 -0
  132. data/lib/milk_tea/core/pretty_printer.rb +17 -0
  133. data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +314 -0
  134. data/lib/milk_tea/core/semantic_analyzer/attributes.rb +184 -0
  135. data/lib/milk_tea/core/semantic_analyzer/calls.rb +992 -0
  136. data/lib/milk_tea/core/semantic_analyzer/expressions.rb +1735 -0
  137. data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +355 -0
  138. data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +155 -0
  139. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +354 -0
  140. data/lib/milk_tea/core/semantic_analyzer/generics.rb +383 -0
  141. data/lib/milk_tea/core/semantic_analyzer/interface_conformance.rb +78 -0
  142. data/lib/milk_tea/core/semantic_analyzer/module_context.rb +35 -0
  143. data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +1438 -0
  144. data/lib/milk_tea/core/semantic_analyzer/nullability.rb +421 -0
  145. data/lib/milk_tea/core/semantic_analyzer/statements.rb +1308 -0
  146. data/lib/milk_tea/core/semantic_analyzer/top_level.rb +588 -0
  147. data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +307 -0
  148. data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +851 -0
  149. data/lib/milk_tea/core/semantic_analyzer.rb +327 -0
  150. data/lib/milk_tea/core/token.rb +26 -0
  151. data/lib/milk_tea/core/token_stream.rb +30 -0
  152. data/lib/milk_tea/core/types/layout.rb +243 -0
  153. data/lib/milk_tea/core/types/predicates.rb +609 -0
  154. data/lib/milk_tea/core/types/registry.rb +83 -0
  155. data/lib/milk_tea/core/types/types.rb +1696 -0
  156. data/lib/milk_tea/core/types/visitor.rb +442 -0
  157. data/lib/milk_tea/core.rb +25 -0
  158. data/lib/milk_tea/dap/backends/lldb_dap.rb +158 -0
  159. data/lib/milk_tea/dap/protocol.rb +58 -0
  160. data/lib/milk_tea/dap/server/breakpoints.rb +66 -0
  161. data/lib/milk_tea/dap/server/debug_map.rb +291 -0
  162. data/lib/milk_tea/dap/server/handlers.rb +374 -0
  163. data/lib/milk_tea/dap/server/launch.rb +261 -0
  164. data/lib/milk_tea/dap/server/lldb_backend.rb +380 -0
  165. data/lib/milk_tea/dap/server/pause_diagnostics.rb +109 -0
  166. data/lib/milk_tea/dap/server/utilities.rb +160 -0
  167. data/lib/milk_tea/dap/server/wire.rb +55 -0
  168. data/lib/milk_tea/dap/server.rb +131 -0
  169. data/lib/milk_tea/dap/session.rb +152 -0
  170. data/lib/milk_tea/dap.rb +6 -0
  171. data/lib/milk_tea/lsp/dependency_resolution.rb +52 -0
  172. data/lib/milk_tea/lsp/diagnostics.rb +611 -0
  173. data/lib/milk_tea/lsp/protocol.rb +104 -0
  174. data/lib/milk_tea/lsp/server/call_hierarchy.rb +274 -0
  175. data/lib/milk_tea/lsp/server/code_actions.rb +446 -0
  176. data/lib/milk_tea/lsp/server/code_lens.rb +97 -0
  177. data/lib/milk_tea/lsp/server/completion.rb +1099 -0
  178. data/lib/milk_tea/lsp/server/configuration.rb +167 -0
  179. data/lib/milk_tea/lsp/server/debug_info.rb +45 -0
  180. data/lib/milk_tea/lsp/server/definition.rb +779 -0
  181. data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +239 -0
  182. data/lib/milk_tea/lsp/server/execute_command.rb +25 -0
  183. data/lib/milk_tea/lsp/server/folding_range.rb +153 -0
  184. data/lib/milk_tea/lsp/server/formatting.rb +575 -0
  185. data/lib/milk_tea/lsp/server/hover.rb +1465 -0
  186. data/lib/milk_tea/lsp/server/inlay_hints.rb +204 -0
  187. data/lib/milk_tea/lsp/server/lifecycle.rb +234 -0
  188. data/lib/milk_tea/lsp/server/linked_editing_range.rb +43 -0
  189. data/lib/milk_tea/lsp/server/on_type_formatting.rb +73 -0
  190. data/lib/milk_tea/lsp/server/progress.rb +47 -0
  191. data/lib/milk_tea/lsp/server/references.rb +433 -0
  192. data/lib/milk_tea/lsp/server/rename.rb +598 -0
  193. data/lib/milk_tea/lsp/server/selection_range.rb +130 -0
  194. data/lib/milk_tea/lsp/server/semantic_tokens.rb +1745 -0
  195. data/lib/milk_tea/lsp/server/signature_help.rb +200 -0
  196. data/lib/milk_tea/lsp/server/text_documents.rb +125 -0
  197. data/lib/milk_tea/lsp/server/type_hierarchy.rb +167 -0
  198. data/lib/milk_tea/lsp/server/utilities.rb +520 -0
  199. data/lib/milk_tea/lsp/server.rb +415 -0
  200. data/lib/milk_tea/lsp/workspace/analysis.rb +209 -0
  201. data/lib/milk_tea/lsp/workspace/caches.rb +260 -0
  202. data/lib/milk_tea/lsp/workspace/collection.rb +98 -0
  203. data/lib/milk_tea/lsp/workspace/definition_index.rb +184 -0
  204. data/lib/milk_tea/lsp/workspace/dependency_graph.rb +282 -0
  205. data/lib/milk_tea/lsp/workspace/store.rb +154 -0
  206. data/lib/milk_tea/lsp/workspace/utilities.rb +490 -0
  207. data/lib/milk_tea/lsp/workspace.rb +127 -0
  208. data/lib/milk_tea/lsp.rb +13 -0
  209. data/lib/milk_tea/packages/atomic_write.rb +63 -0
  210. data/lib/milk_tea/packages/dependency_solver.rb +194 -0
  211. data/lib/milk_tea/packages/graph.rb +139 -0
  212. data/lib/milk_tea/packages/lock.rb +421 -0
  213. data/lib/milk_tea/packages/manager_cli.rb +485 -0
  214. data/lib/milk_tea/packages/manifest.rb +356 -0
  215. data/lib/milk_tea/packages/manifest_editor.rb +134 -0
  216. data/lib/milk_tea/packages/registry_metadata_provider.rb +34 -0
  217. data/lib/milk_tea/packages/registry_store.rb +420 -0
  218. data/lib/milk_tea/packages/services.rb +41 -0
  219. data/lib/milk_tea/packages/source_cache.rb +71 -0
  220. data/lib/milk_tea/packages/source_fetcher.rb +124 -0
  221. data/lib/milk_tea/packages/source_resolver.rb +389 -0
  222. data/lib/milk_tea/packages/version.rb +164 -0
  223. data/lib/milk_tea/packages.rb +16 -0
  224. data/lib/milk_tea/tooling/asset_pack.rb +141 -0
  225. data/lib/milk_tea/tooling/build.rb +1124 -0
  226. data/lib/milk_tea/tooling/build_cache.rb +240 -0
  227. data/lib/milk_tea/tooling/cli.rb +2688 -0
  228. data/lib/milk_tea/tooling/cst_formatter.rb +13 -0
  229. data/lib/milk_tea/tooling/debug_info_formatter.rb +456 -0
  230. data/lib/milk_tea/tooling/debug_map.rb +248 -0
  231. data/lib/milk_tea/tooling/docs_app.rb +369 -0
  232. data/lib/milk_tea/tooling/error_formatter.rb +86 -0
  233. data/lib/milk_tea/tooling/formatter.rb +787 -0
  234. data/lib/milk_tea/tooling/linter/doc_tags.rb +212 -0
  235. data/lib/milk_tea/tooling/linter/fix_engine.rb +237 -0
  236. data/lib/milk_tea/tooling/linter/flow_rules.rb +380 -0
  237. data/lib/milk_tea/tooling/linter/imports_platform.rb +841 -0
  238. data/lib/milk_tea/tooling/linter/release_rules.rb +744 -0
  239. data/lib/milk_tea/tooling/linter/reserved_names.rb +199 -0
  240. data/lib/milk_tea/tooling/linter/rules.rb +593 -0
  241. data/lib/milk_tea/tooling/linter/source_helpers.rb +407 -0
  242. data/lib/milk_tea/tooling/linter/trailing_comma.rb +139 -0
  243. data/lib/milk_tea/tooling/linter/visitors.rb +1286 -0
  244. data/lib/milk_tea/tooling/linter.rb +798 -0
  245. data/lib/milk_tea/tooling/project_scaffold.rb +82 -0
  246. data/lib/milk_tea/tooling/public/css/docs.css +166 -0
  247. data/lib/milk_tea/tooling/public/js/docs.js +94 -0
  248. data/lib/milk_tea/tooling/run.rb +408 -0
  249. data/lib/milk_tea/tooling/templates/wasm_shell.html +48 -0
  250. data/lib/milk_tea/tooling/toolchain_cli.rb +157 -0
  251. data/lib/milk_tea/tooling/views/404.erb +7 -0
  252. data/lib/milk_tea/tooling/views/index.erb +87 -0
  253. data/lib/milk_tea/tooling/views/layout.erb +69 -0
  254. data/lib/milk_tea/tooling/views/module.erb +97 -0
  255. data/lib/milk_tea/tooling/views/stdlib.erb +21 -0
  256. data/lib/milk_tea/tooling.rb +20 -0
  257. data/lib/milk_tea.rb +8 -0
  258. metadata +426 -0
@@ -0,0 +1,307 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MilkTea
4
+ class SemanticAnalyzer
5
+ class Checker
6
+ private
7
+
8
+ def call_argument_compatible?(actual_type, expected_type, scopes:, external:, expression: nil)
9
+ return true if array_to_span_call_argument_compatible?(actual_type, expected_type, expression:, scopes:)
10
+ return true if argument_types_compatible?(actual_type, expected_type, external:, expression:, scopes:, contextual_int_to_float: !external)
11
+ return true if implicit_ref_argument_compatible?(actual_type, expected_type, expression, scopes)
12
+ return true if direct_task_to_proc_argument_compatible?(actual_type, expected_type)
13
+ return true if direct_function_to_proc_argument_compatible?(actual_type, expected_type, expression, scopes)
14
+
15
+ false
16
+ end
17
+
18
+ def implicit_ref_argument_compatible?(actual_type, expected_type, expression, scopes)
19
+ return false unless expression && scopes
20
+ return false unless ref_type?(expected_type)
21
+ return false unless actual_type == referenced_type(expected_type)
22
+ return false unless safe_reference_source_expression?(expression, scopes:)
23
+
24
+ infer_lvalue(expression, scopes:)
25
+ true
26
+ rescue SemanticError
27
+ false
28
+ end
29
+
30
+ def types_compatible?(actual_type, expected_type, expression: nil, scopes: nil, external_numeric: false, external_pointer_null: false, contextual_int_to_float: false)
31
+ return true if error_type?(actual_type) || error_type?(expected_type)
32
+ return true if actual_type == expected_type
33
+ return true if ref_types_compatible?(actual_type, expected_type)
34
+ return true if null_assignable_to?(actual_type, expected_type)
35
+ return true if external_pointer_null && external_typed_null_pointer_compatibility?(actual_type, expected_type)
36
+ return true if expected_type.is_a?(Types::Nullable) && actual_type == expected_type.base
37
+ return true if mutable_to_const_pointer_compatibility?(actual_type, expected_type)
38
+ return true if own_to_raw_pointer_compatibility?(actual_type, expected_type)
39
+ return true if string_literal_cstr_compatibility?(expression, expected_type)
40
+ return true if exact_compile_time_numeric_compatibility?(actual_type, expression, expected_type, scopes:)
41
+ return true if integer_to_char_compatibility?(actual_type, expected_type) &&
42
+ (!expression || !scopes || integer_constant_fits_in_char?(expression, scopes))
43
+ return true if lossless_integer_compatibility?(actual_type, expected_type)
44
+ return true if external_numeric && external_numeric_compatibility?(actual_type, expected_type)
45
+ return true if contextual_int_to_float && contextual_int_to_float_compatibility?(actual_type, expected_type) &&
46
+ (!expression || !scopes || contextual_int_to_float_fits?(expression, expected_type, scopes))
47
+ return true if same_external_opaque_handle_pointer_compatibility?(actual_type, expected_type)
48
+ return true if actual_type.is_a?(Types::Function) && expected_type.is_a?(Types::Function) &&
49
+ !actual_type.receiver_type && !actual_type.variadic &&
50
+ function_type_matches_proc_type?(actual_type, expected_type)
51
+ return true if quat_vec4_compatible?(actual_type, expected_type)
52
+
53
+ false
54
+ end
55
+
56
+ def ref_types_compatible?(actual_type, expected_type)
57
+ return false unless ref_type?(actual_type) && ref_type?(expected_type)
58
+
59
+ referenced_type(actual_type) == referenced_type(expected_type)
60
+ end
61
+
62
+ def quat_vec4_compatible?(a, b)
63
+ (a.is_a?(Types::Quaternion) && b.is_a?(Types::Vector) && b.width == 4 && b.element_type.name == "float") ||
64
+ (b.is_a?(Types::Quaternion) && a.is_a?(Types::Vector) && a.width == 4 && a.element_type.name == "float")
65
+ end
66
+
67
+ def argument_types_compatible?(actual_type, expected_type, external:, expression: nil, scopes: nil, contextual_int_to_float: false)
68
+ return true if types_compatible?(actual_type, expected_type, expression:, scopes:, external_numeric: external, contextual_int_to_float:)
69
+ return true if external && external_void_pointer_argument_compatibility?(actual_type, expected_type)
70
+ return true if external && extern_enum_integer_argument_compatibility?(actual_type, expected_type)
71
+ if external && foreign_mapping_context? && foreign_identity_projection_compatible?(actual_type, expected_type)
72
+ return false if actual_type == @ctx.types.fetch("cstr") && char_pointer_type?(expected_type)
73
+
74
+ return true
75
+ end
76
+
77
+ false
78
+ end
79
+
80
+ def direct_function_to_proc_argument_compatible?(actual_type, expected_type, expression, scopes)
81
+ return false unless expression
82
+ return false unless actual_type.is_a?(Types::Function) && proc_type?(expected_type)
83
+ return false unless direct_function_identity_expression?(expression, scopes)
84
+
85
+ function_type_matches_proc_type?(actual_type, expected_type)
86
+ end
87
+
88
+ def direct_task_to_proc_argument_compatible?(actual_type, expected_type)
89
+ return false unless actual_type.is_a?(Types::Task)
90
+ return false unless task_root_proc_type?(expected_type)
91
+
92
+ actual_type == expected_type.return_type
93
+ end
94
+
95
+ def direct_function_identity_expression?(expression, scopes)
96
+ case expression
97
+ when AST::Identifier
98
+ return false if lookup_value(expression.name, scopes)
99
+ return false unless @ctx.top_level_functions.key?(expression.name)
100
+
101
+ binding = @ctx.top_level_functions.fetch(expression.name)
102
+ !binding.type_params.any? && !foreign_function_binding?(binding)
103
+ when AST::MemberAccess
104
+ return false unless expression.receiver.is_a?(AST::Identifier) && @ctx.imports.key?(expression.receiver.name)
105
+
106
+ imported_module = @ctx.imports.fetch(expression.receiver.name)
107
+ return false unless imported_module.functions.key?(expression.member)
108
+
109
+ binding = imported_module.functions.fetch(expression.member)
110
+ !binding.type_params.any? && !foreign_function_binding?(binding)
111
+ when AST::Specialization
112
+ binding = resolve_specialized_function_binding(expression)
113
+ binding && !foreign_function_binding?(binding)
114
+ else
115
+ false
116
+ end
117
+ end
118
+
119
+ def external_void_pointer_argument_compatibility?(actual_type, expected_type)
120
+ if actual_type.is_a?(Types::Nullable) && expected_type.is_a?(Types::Nullable)
121
+ return external_void_pointer_argument_compatibility?(actual_type.base, expected_type.base)
122
+ end
123
+
124
+ return external_void_pointer_argument_compatibility?(actual_type, expected_type.base) if expected_type.is_a?(Types::Nullable)
125
+ return false if actual_type.is_a?(Types::Nullable)
126
+ return false unless pointer_type?(actual_type) && pointer_type?(expected_type)
127
+ return false if const_pointer_type?(actual_type) && mutable_pointer_type?(expected_type)
128
+
129
+ actual_pointee = pointee_type(actual_type)
130
+ expected_pointee = pointee_type(expected_type)
131
+
132
+ actual_pointee == @ctx.types.fetch("void") || expected_pointee == @ctx.types.fetch("void")
133
+ end
134
+
135
+ def exact_compile_time_numeric_compatibility?(actual_type, expression, expected_type, scopes: nil)
136
+ return false unless expected_type.is_a?(Types::Primitive) && expected_type.numeric?
137
+ return false if actual_type.is_a?(Types::EnumBase)
138
+
139
+ value = evaluate_compile_time_const_value(expression, scopes:)
140
+ return false unless value.is_a?(Numeric)
141
+
142
+ numeric_constant_fits_type?(value, expected_type)
143
+ end
144
+
145
+ def integer_constant_fits_in_char?(expression, scopes)
146
+ value = evaluate_compile_time_const_value(expression, scopes:)
147
+ return true unless value.is_a?(Integer)
148
+
149
+ value >= 0 && value <= 255
150
+ end
151
+
152
+ def contextual_int_to_float_fits?(expression, expected_type, scopes)
153
+ value = evaluate_compile_time_const_value(expression, scopes:)
154
+ return true unless value.is_a?(Numeric)
155
+
156
+ float_constant_fits_type?(value, expected_type)
157
+ end
158
+
159
+ def extern_enum_integer_argument_compatibility?(actual_type, expected_type)
160
+ return unless actual_type.is_a?(Types::EnumBase)
161
+ return unless expected_type.is_a?(Types::Primitive) && expected_type.integer? && expected_type.fixed_width_integer?
162
+
163
+ backing_type = actual_type.backing_type
164
+ return unless backing_type.is_a?(Types::Primitive) && backing_type.integer? && backing_type.fixed_width_integer?
165
+
166
+ backing_type.integer_width == expected_type.integer_width
167
+ end
168
+
169
+ def common_numeric_type(left_type, right_type)
170
+ left_type = left_type.backing_type if left_type.is_a?(Types::EnumBase)
171
+ right_type = right_type.backing_type if right_type.is_a?(Types::EnumBase)
172
+ return unless left_type.is_a?(Types::Primitive) && right_type.is_a?(Types::Primitive)
173
+ return unless left_type.numeric? && right_type.numeric?
174
+ return left_type if left_type == right_type
175
+
176
+ return common_integer_type(left_type, right_type) if left_type.integer? && right_type.integer?
177
+ return wider_float_type(left_type, right_type) if left_type.float? && right_type.float?
178
+
179
+ float_type, integer_type = left_type.float? ? [left_type, right_type] : [right_type, left_type]
180
+ return unless integer_type.integer? && integer_type.fixed_width_integer?
181
+
182
+ float_type
183
+ end
184
+
185
+ def common_integer_type(left_type, right_type)
186
+ left_type = left_type.backing_type if left_type.is_a?(Types::EnumBase)
187
+ right_type = right_type.backing_type if right_type.is_a?(Types::EnumBase)
188
+ return unless left_type.is_a?(Types::Primitive) && right_type.is_a?(Types::Primitive)
189
+ return unless left_type.integer? && right_type.integer?
190
+ return left_type if left_type == right_type
191
+ return unless left_type.fixed_width_integer? && right_type.fixed_width_integer?
192
+ return unless left_type.signed_integer? == right_type.signed_integer?
193
+
194
+ left_type.integer_width >= right_type.integer_width ? left_type : right_type
195
+ end
196
+
197
+ def wider_float_type(left_type, right_type)
198
+ left_type.float_width >= right_type.float_width ? left_type : right_type
199
+ end
200
+
201
+ def pointer_arithmetic_result(operator, left_type, right_type)
202
+ if pointer_type?(left_type) && integer_type?(right_type)
203
+ require_unsafe!("pointer arithmetic requires unsafe") unless own_type?(left_type)
204
+
205
+ return left_type if operator == "+" || operator == "-"
206
+ end
207
+
208
+ if operator == "+" && integer_type?(left_type) && pointer_type?(right_type)
209
+ require_unsafe!("pointer arithmetic requires unsafe") unless own_type?(right_type)
210
+
211
+ return right_type
212
+ end
213
+
214
+ nil
215
+ end
216
+
217
+ def vector_arithmetic_result(operator, left_type, right_type)
218
+ return vector_op_result(operator, left_type, right_type) if vector_type?(left_type) || vector_type?(right_type)
219
+ return matrix_op_result(operator, left_type, right_type) if matrix_type?(left_type) || matrix_type?(right_type)
220
+ return quaternion_op_result(operator, left_type, right_type) if quaternion_type?(left_type) || quaternion_type?(right_type)
221
+
222
+ nil
223
+ end
224
+
225
+ private
226
+
227
+ def vector_op_result(operator, left_type, right_type)
228
+ if vector_type?(left_type) && vector_type?(right_type) && left_type.element_type == right_type.element_type
229
+ return left_type if operator == "+" || operator == "-"
230
+ return left_type if operator == "*"
231
+ end
232
+
233
+ if vector_type?(left_type) && right_type.numeric?
234
+ return left_type if operator == "*" || operator == "/"
235
+ end
236
+
237
+ if left_type.numeric? && vector_type?(right_type) && operator == "*"
238
+ return right_type
239
+ end
240
+
241
+ nil
242
+ end
243
+
244
+ def matrix_op_result(operator, left_type, right_type)
245
+ if matrix_type?(left_type) && matrix_type?(right_type) && left_type.dim == right_type.dim
246
+ return left_type if operator == "+" || operator == "-"
247
+ return left_type if operator == "*"
248
+ end
249
+
250
+ if matrix_type?(left_type) && vector_type?(right_type) && left_type.dim == right_type.width && right_type.element_type == Types::BUILTIN_VECTOR_ELEMENT
251
+ return Types::Vector.new(right_type.name, element_type: right_type.element_type, width: right_type.width) if operator == "*"
252
+ end
253
+
254
+ if matrix_type?(left_type) && right_type.numeric?
255
+ return left_type if operator == "*" || operator == "/"
256
+ end
257
+
258
+ nil
259
+ end
260
+
261
+ def quaternion_op_result(operator, left_type, right_type)
262
+ if quaternion_type?(left_type) && quaternion_type?(right_type)
263
+ return left_type if operator == "+" || operator == "-"
264
+ return left_type if operator == "*"
265
+ end
266
+
267
+ if quaternion_type?(left_type) && vector_type?(right_type) && right_type.width == 3 && right_type.element_type == Types::BUILTIN_VECTOR_ELEMENT
268
+ return right_type if operator == "*"
269
+ end
270
+
271
+ nil
272
+ end
273
+
274
+ def pointer_cast?(source_type, target_type)
275
+ pointer_cast_type?(source_type) && pointer_cast_type?(target_type)
276
+ end
277
+
278
+ def ref_to_pointer_cast?(source_type, target_type)
279
+ ref_type?(source_type) && pointer_cast_type?(target_type)
280
+ end
281
+
282
+ def pointer_cast_type?(type)
283
+ return typed_null_target_type?(type.target_type) if type.is_a?(Types::Null)
284
+ return true if type == @ctx.types.fetch("cstr")
285
+ if type.is_a?(Types::Nullable)
286
+ return true if function_pointer_type?(type.base)
287
+
288
+ return pointer_type?(type.base)
289
+ end
290
+
291
+ return true if function_pointer_type?(type)
292
+
293
+ pointer_type?(type)
294
+ end
295
+
296
+ def typed_null_target_type?(type)
297
+ type == @ctx.types.fetch("cstr") || pointer_type?(type) || function_pointer_type?(type)
298
+ end
299
+
300
+ def function_pointer_type?(type)
301
+ type.is_a?(Types::Function)
302
+ end
303
+
304
+
305
+ end
306
+ end
307
+ end