mt-lang 0.3.8 → 0.3.10

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 (200) hide show
  1. checksums.yaml +4 -4
  2. data/lib/milk_tea/base.rb +1 -2
  3. data/lib/milk_tea/bindings/bindgen/ast_parser.rb +0 -2
  4. data/lib/milk_tea/bindings/bindgen/declaration.rb +0 -2
  5. data/lib/milk_tea/bindings/bindgen/emitter.rb +0 -2
  6. data/lib/milk_tea/bindings/bindgen/overrides.rb +0 -2
  7. data/lib/milk_tea/bindings/bindgen/type_mapper.rb +51 -53
  8. data/lib/milk_tea/bindings/imported_bindings/generator.rb +7 -9
  9. data/lib/milk_tea/bindings/imported_bindings/method_source.rb +0 -2
  10. data/lib/milk_tea/bindings/imported_bindings/naming.rb +6 -8
  11. data/lib/milk_tea/bindings/imported_bindings.rb +0 -2
  12. data/lib/milk_tea/bindings/opengl_registry.rb +3 -7
  13. data/lib/milk_tea/bindings/steamworks.rb +12 -16
  14. data/lib/milk_tea/bindings/upstream_sources.rb +10 -14
  15. data/lib/milk_tea/bindings/vendored_box2d.rb +10 -12
  16. data/lib/milk_tea/bindings/vendored_cjson.rb +6 -8
  17. data/lib/milk_tea/bindings/vendored_flecs.rb +10 -12
  18. data/lib/milk_tea/bindings/vendored_glfw.rb +11 -13
  19. data/lib/milk_tea/bindings/vendored_libuv.rb +11 -13
  20. data/lib/milk_tea/bindings/vendored_pcre2.rb +11 -13
  21. data/lib/milk_tea/bindings/vendored_raylib.rb +6 -10
  22. data/lib/milk_tea/bindings/vendored_sdl3.rb +11 -13
  23. data/lib/milk_tea/bindings/vendored_steamworks.rb +1 -5
  24. data/lib/milk_tea/core/ast.rb +103 -45
  25. data/lib/milk_tea/core/async_runtime_installer.rb +0 -2
  26. data/lib/milk_tea/core/bindings/attribute_binding.rb +1 -3
  27. data/lib/milk_tea/core/c_backend/aggregate_utils.rb +147 -84
  28. data/lib/milk_tea/core/c_backend/control_flow_emission.rb +394 -396
  29. data/lib/milk_tea/core/c_backend/expressions.rb +489 -476
  30. data/lib/milk_tea/core/c_backend/feature_detection.rb +446 -437
  31. data/lib/milk_tea/core/c_backend/format_helpers.rb +0 -2
  32. data/lib/milk_tea/core/c_backend/reachability.rb +339 -341
  33. data/lib/milk_tea/core/c_backend/reinterpret.rb +231 -217
  34. data/lib/milk_tea/core/c_backend/runtime_helpers.rb +531 -526
  35. data/lib/milk_tea/core/c_backend/statements.rb +528 -530
  36. data/lib/milk_tea/core/c_backend/type_collectors.rb +1344 -1346
  37. data/lib/milk_tea/core/c_backend/type_declaration.rb +215 -213
  38. data/lib/milk_tea/core/c_backend/type_system.rb +347 -349
  39. data/lib/milk_tea/core/c_backend.rb +17 -9
  40. data/lib/milk_tea/core/compatibility_helpers.rb +0 -2
  41. data/lib/milk_tea/core/compile_time/const_eval.rb +7 -12
  42. data/lib/milk_tea/core/compile_time.rb +32 -38
  43. data/lib/milk_tea/core/control_flow/builder.rb +3 -5
  44. data/lib/milk_tea/core/control_flow/constant_propagation.rb +14 -17
  45. data/lib/milk_tea/core/control_flow/definite_assignment.rb +0 -1
  46. data/lib/milk_tea/core/ir.rb +10 -10
  47. data/lib/milk_tea/core/lexer/character_classes.rb +5 -7
  48. data/lib/milk_tea/core/lexer/format_strings.rb +7 -9
  49. data/lib/milk_tea/core/lexer/heredocs.rb +22 -22
  50. data/lib/milk_tea/core/lexer/indentation.rb +0 -2
  51. data/lib/milk_tea/core/lexer/numbers.rb +0 -2
  52. data/lib/milk_tea/core/lexer/recovery.rb +0 -2
  53. data/lib/milk_tea/core/lexer/strings.rb +0 -2
  54. data/lib/milk_tea/core/lexer/symbols.rb +0 -2
  55. data/lib/milk_tea/core/lexer/trivia.rb +0 -2
  56. data/lib/milk_tea/core/lexer.rb +0 -2
  57. data/lib/milk_tea/core/lowering/async/analysis.rb +0 -2
  58. data/lib/milk_tea/core/lowering/async/lowering.rb +1264 -1265
  59. data/lib/milk_tea/core/lowering/async/normalization.rb +0 -2
  60. data/lib/milk_tea/core/lowering/async.rb +627 -630
  61. data/lib/milk_tea/core/lowering/block.rb +413 -416
  62. data/lib/milk_tea/core/lowering/calls.rb +1381 -1384
  63. data/lib/milk_tea/core/lowering/declarations.rb +180 -183
  64. data/lib/milk_tea/core/lowering/dyn.rb +48 -50
  65. data/lib/milk_tea/core/lowering/events.rb +983 -985
  66. data/lib/milk_tea/core/lowering/expressions.rb +1513 -1518
  67. data/lib/milk_tea/core/lowering/foreign_cstr.rb +181 -184
  68. data/lib/milk_tea/core/lowering/functions.rb +185 -188
  69. data/lib/milk_tea/core/lowering/loops.rb +1028 -1031
  70. data/lib/milk_tea/core/lowering/proc.rb +363 -366
  71. data/lib/milk_tea/core/lowering/resolve.rb +2133 -2135
  72. data/lib/milk_tea/core/lowering/scans.rb +179 -181
  73. data/lib/milk_tea/core/lowering/str_buffer.rb +102 -105
  74. data/lib/milk_tea/core/lowering/utils.rb +1040 -1044
  75. data/lib/milk_tea/core/lowering.rb +5 -7
  76. data/lib/milk_tea/core/module_binder.rb +0 -2
  77. data/lib/milk_tea/core/module_loader/errors.rb +4 -2
  78. data/lib/milk_tea/core/module_loader.rb +113 -20
  79. data/lib/milk_tea/core/module_path_resolver.rb +0 -2
  80. data/lib/milk_tea/core/module_roots.rb +6 -8
  81. data/lib/milk_tea/core/parser/attributes.rb +0 -2
  82. data/lib/milk_tea/core/parser/blocks.rb +0 -2
  83. data/lib/milk_tea/core/parser/declarations.rb +0 -2
  84. data/lib/milk_tea/core/parser/expressions.rb +31 -14
  85. data/lib/milk_tea/core/parser/recovery.rb +0 -2
  86. data/lib/milk_tea/core/parser/statements.rb +0 -2
  87. data/lib/milk_tea/core/parser/types.rb +8 -10
  88. data/lib/milk_tea/core/parser.rb +1 -3
  89. data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +31 -33
  90. data/lib/milk_tea/core/pretty_printer/base_formatter.rb +0 -2
  91. data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +0 -2
  92. data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +0 -2
  93. data/lib/milk_tea/core/semantic_analyzer/attributes.rb +14 -16
  94. data/lib/milk_tea/core/semantic_analyzer/calls.rb +0 -2
  95. data/lib/milk_tea/core/semantic_analyzer/expressions.rb +1 -14
  96. data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +18 -21
  97. data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +0 -3
  98. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +12 -15
  99. data/lib/milk_tea/core/semantic_analyzer/generics.rb +57 -59
  100. data/lib/milk_tea/core/semantic_analyzer/interface_conformance.rb +0 -2
  101. data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +5 -9
  102. data/lib/milk_tea/core/semantic_analyzer/nullability.rb +0 -3
  103. data/lib/milk_tea/core/semantic_analyzer/statements.rb +35 -40
  104. data/lib/milk_tea/core/semantic_analyzer/top_level.rb +10 -12
  105. data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +0 -6
  106. data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +102 -105
  107. data/lib/milk_tea/core/semantic_analyzer.rb +17 -8
  108. data/lib/milk_tea/core/types/layout.rb +21 -22
  109. data/lib/milk_tea/core/types/predicates.rb +0 -2
  110. data/lib/milk_tea/core/types/registry.rb +16 -18
  111. data/lib/milk_tea/core/types/visitor.rb +0 -4
  112. data/lib/milk_tea/dap/backends/lldb_dap.rb +0 -2
  113. data/lib/milk_tea/dap/protocol.rb +1 -1
  114. data/lib/milk_tea/dap/server/breakpoints.rb +0 -2
  115. data/lib/milk_tea/dap/server/debug_map.rb +0 -2
  116. data/lib/milk_tea/dap/server/handlers.rb +0 -2
  117. data/lib/milk_tea/dap/server/launch.rb +0 -2
  118. data/lib/milk_tea/dap/server/lldb_backend.rb +8 -10
  119. data/lib/milk_tea/dap/server/pause_diagnostics.rb +14 -16
  120. data/lib/milk_tea/dap/server/utilities.rb +0 -2
  121. data/lib/milk_tea/dap/server/wire.rb +0 -2
  122. data/lib/milk_tea/dap/server.rb +0 -2
  123. data/lib/milk_tea/lsp/diagnostics.rb +16 -16
  124. data/lib/milk_tea/lsp/server/call_hierarchy.rb +11 -12
  125. data/lib/milk_tea/lsp/server/code_actions.rb +355 -357
  126. data/lib/milk_tea/lsp/server/code_lens.rb +23 -25
  127. data/lib/milk_tea/lsp/server/completion.rb +873 -875
  128. data/lib/milk_tea/lsp/server/configuration.rb +129 -131
  129. data/lib/milk_tea/lsp/server/debug_info.rb +0 -2
  130. data/lib/milk_tea/lsp/server/definition.rb +564 -565
  131. data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +191 -193
  132. data/lib/milk_tea/lsp/server/execute_command.rb +0 -2
  133. data/lib/milk_tea/lsp/server/folding_range.rb +0 -4
  134. data/lib/milk_tea/lsp/server/formatting.rb +478 -480
  135. data/lib/milk_tea/lsp/server/hover.rb +1282 -1284
  136. data/lib/milk_tea/lsp/server/inlay_hints.rb +179 -181
  137. data/lib/milk_tea/lsp/server/lifecycle.rb +192 -194
  138. data/lib/milk_tea/lsp/server/linked_editing_range.rb +0 -2
  139. data/lib/milk_tea/lsp/server/on_type_formatting.rb +0 -2
  140. data/lib/milk_tea/lsp/server/progress.rb +0 -2
  141. data/lib/milk_tea/lsp/server/references.rb +316 -318
  142. data/lib/milk_tea/lsp/server/rename.rb +445 -447
  143. data/lib/milk_tea/lsp/server/selection_range.rb +0 -4
  144. data/lib/milk_tea/lsp/server/semantic_tokens.rb +1318 -1320
  145. data/lib/milk_tea/lsp/server/signature_help.rb +146 -148
  146. data/lib/milk_tea/lsp/server/text_documents.rb +99 -101
  147. data/lib/milk_tea/lsp/server/type_hierarchy.rb +2 -4
  148. data/lib/milk_tea/lsp/server/utilities.rb +397 -399
  149. data/lib/milk_tea/lsp/server.rb +0 -3
  150. data/lib/milk_tea/lsp/workspace/analysis.rb +40 -42
  151. data/lib/milk_tea/lsp/workspace/dependency_graph.rb +4 -10
  152. data/lib/milk_tea/lsp/workspace/utilities.rb +19 -19
  153. data/lib/milk_tea/packages/atomic_write.rb +4 -5
  154. data/lib/milk_tea/packages/dependency_solver.rb +15 -15
  155. data/lib/milk_tea/packages/lock.rb +4 -4
  156. data/lib/milk_tea/packages/manager_cli.rb +1 -1
  157. data/lib/milk_tea/packages/manifest.rb +3 -3
  158. data/lib/milk_tea/packages/registry_store.rb +4 -6
  159. data/lib/milk_tea/packages/services.rb +16 -16
  160. data/lib/milk_tea/packages/source_cache.rb +4 -6
  161. data/lib/milk_tea/packages/source_resolver.rb +44 -44
  162. data/lib/milk_tea/packages/version.rb +8 -8
  163. data/lib/milk_tea/tooling/build.rb +3 -7
  164. data/lib/milk_tea/tooling/build_cache.rb +0 -2
  165. data/lib/milk_tea/tooling/debug_info_formatter.rb +31 -33
  166. data/lib/milk_tea/tooling/debug_map.rb +8 -10
  167. data/lib/milk_tea/tooling/docs_app.rb +0 -2
  168. data/lib/milk_tea/tooling/linter/doc_tags.rb +25 -27
  169. data/lib/milk_tea/tooling/linter/fix_engine.rb +87 -24
  170. data/lib/milk_tea/tooling/linter/flow_rules.rb +44 -46
  171. data/lib/milk_tea/tooling/linter/imports_platform.rb +14 -16
  172. data/lib/milk_tea/tooling/linter/release_rules.rb +3 -5
  173. data/lib/milk_tea/tooling/linter/reserved_names.rb +23 -25
  174. data/lib/milk_tea/tooling/linter/rules.rb +87 -89
  175. data/lib/milk_tea/tooling/linter/source_helpers.rb +40 -42
  176. data/lib/milk_tea/tooling/linter/trailing_comma.rb +17 -19
  177. data/lib/milk_tea/tooling/linter/visitors.rb +162 -50
  178. data/lib/milk_tea/tooling/linter.rb +0 -2
  179. data/lib/milk_tea/tooling/project_scaffold.rb +0 -2
  180. data/lib/milk_tea/tooling/run.rb +0 -2
  181. data/lib/milk_tea/tooling/toolchain_cli.rb +0 -2
  182. data/std/cli.mt +13 -32
  183. data/std/color.mt +28 -28
  184. data/std/encoding.mt +4 -4
  185. data/std/graph.mt +1 -2
  186. data/std/hash.mt +14 -14
  187. data/std/http/server.mt +3 -3
  188. data/std/input.mt +1 -1
  189. data/std/json.mt +1 -1
  190. data/std/linear_algebra.mt +6 -6
  191. data/std/net/mux.mt +1 -1
  192. data/std/noise.mt +23 -23
  193. data/std/parse.mt +2 -2
  194. data/std/process.mt +3 -4
  195. data/std/sparse_set.mt +1 -1
  196. data/std/steering.mt +5 -5
  197. data/std/str.mt +1 -1
  198. data/std/tween.mt +4 -4
  199. data/std/utility.mt +3 -3
  200. metadata +2 -2
@@ -3,228 +3,230 @@
3
3
  module MilkTea
4
4
  class CBackend
5
5
  module TypeDeclaration
6
- private
7
-
8
- C_KEYWORDS = %w[
9
- auto break case char const continue default do double
10
- else enum extern float for goto if inline int long
11
- register restrict return short signed sizeof static
12
- struct switch typedef union unsigned void volatile while
13
- _Bool _Complex _Imaginary alignas alignof bool complex
14
- imaginary noreturn static_assert thread_local
15
- ].to_set.freeze
16
-
17
- def sanitize_c_identifier(name)
18
- C_KEYWORDS.include?(name) ? "#{name}_" : name
19
- end
20
-
21
- def emit_forward_declarations(opaque_decls, aggregate_decls)
22
- lines = []
23
- opaque_decls.uniq { |opaque_decl| opaque_decl.linkage_name }.each do |opaque_decl|
24
- next unless opaque_decl.forward_declarable
25
- next unless opaque_decl.linkage_name.match?(/\A[A-Za-z_][A-Za-z0-9_]*\z/)
26
-
27
- lines << "typedef struct #{opaque_decl.linkage_name} #{opaque_decl.linkage_name};"
6
+ C_KEYWORDS = %w[
7
+ auto break case char const continue default do double
8
+ else enum extern float for goto if inline int long
9
+ register restrict return short signed sizeof static
10
+ struct switch typedef union unsigned void volatile while
11
+ _Bool _Complex _Imaginary alignas alignof bool complex
12
+ imaginary noreturn static_assert thread_local
13
+ ].to_set.freeze
14
+
15
+ def sanitize_c_identifier(name)
16
+ C_KEYWORDS.include?(name) ? "#{name}_" : name
17
+ end
18
+
19
+ def emit_forward_declarations(opaque_decls, aggregate_decls)
20
+ lines = []
21
+ opaque_decls.uniq { |opaque_decl| opaque_decl.linkage_name }.each do |opaque_decl|
22
+ next unless opaque_decl.forward_declarable
23
+ next unless opaque_decl.linkage_name.match?(/\A[A-Za-z_][A-Za-z0-9_]*\z/)
24
+
25
+ lines << "typedef struct #{opaque_decl.linkage_name} #{opaque_decl.linkage_name};"
26
+ end
27
+ aggregate_decls.uniq { |aggregate_decl| [aggregate_decl.class.name, aggregate_decl.linkage_name] }.each do |aggregate_decl|
28
+ case aggregate_decl
29
+ when IR::StructDecl
30
+ lines << "typedef struct #{aggregate_decl.linkage_name} #{aggregate_decl.linkage_name};"
31
+ when IR::UnionDecl
32
+ lines << "typedef union #{aggregate_decl.linkage_name} #{aggregate_decl.linkage_name};"
33
+ when IR::VariantDecl
34
+ lines << "typedef struct #{aggregate_decl.linkage_name} #{aggregate_decl.linkage_name};"
35
+ aggregate_decl.arms.each do |arm|
36
+ next if arm.fields.empty?
37
+ lines << "typedef struct #{arm.linkage_name} #{arm.linkage_name};"
28
38
  end
29
- aggregate_decls.uniq { |aggregate_decl| [aggregate_decl.class.name, aggregate_decl.linkage_name] }.each do |aggregate_decl|
30
- case aggregate_decl
31
- when IR::StructDecl
32
- lines << "typedef struct #{aggregate_decl.linkage_name} #{aggregate_decl.linkage_name};"
33
- when IR::UnionDecl
34
- lines << "typedef union #{aggregate_decl.linkage_name} #{aggregate_decl.linkage_name};"
35
- when IR::VariantDecl
36
- lines << "typedef struct #{aggregate_decl.linkage_name} #{aggregate_decl.linkage_name};"
37
- aggregate_decl.arms.each do |arm|
38
- next if arm.fields.empty?
39
- lines << "typedef struct #{arm.linkage_name} #{arm.linkage_name};"
40
- end
41
- end
42
- end
43
- lines
44
- end
45
-
46
- def emit_struct(struct_decl)
47
- lines = []
48
- lines << "struct #{struct_decl.linkage_name} {"
49
- struct_decl.fields.each do |field|
50
- lines << "#{INDENT}#{c_field_declaration(field.type, sanitize_c_identifier(field.name))};"
51
- end
52
- lines << "}#{struct_layout_attributes(struct_decl)};"
53
- lines
54
- end
55
-
56
- def emit_union(union_decl)
57
- lines = []
58
- lines << "union #{union_decl.linkage_name} {"
59
- union_decl.fields.each do |field|
60
- lines << "#{INDENT}#{c_field_declaration(field.type, sanitize_c_identifier(field.name))};"
61
- end
62
- lines << "};"
63
- lines
64
39
  end
65
-
66
- def variant_self_reference?(type, outer_c)
67
- return false unless type.is_a?(Types::Variant) || type.is_a?(Types::VariantInstance)
68
-
69
- named_type_c_name(type) == outer_c
70
- end
71
-
72
- def emit_variant(variant_decl)
73
- lines = []
74
- outer_c = variant_decl.linkage_name
75
- payload_arms = variant_decl.arms.select { |a| a.fields.any? }
76
-
77
- # Per-arm payload structs
78
- payload_arms.each do |arm|
79
- lines << "struct #{arm.linkage_name} {"
80
- arm.fields.each do |field|
81
- if variant_self_reference?(field.type, outer_c)
82
- lines << "#{INDENT}#{c_declaration(field.type, "*#{sanitize_c_identifier(field.name)}")};"
83
- else
84
- lines << "#{INDENT}#{c_field_declaration(field.type, sanitize_c_identifier(field.name))};"
85
- end
40
+ end
41
+ lines
42
+ end
43
+
44
+ def emit_struct(struct_decl)
45
+ lines = []
46
+ lines << "struct #{struct_decl.linkage_name} {"
47
+ struct_decl.fields.each do |field|
48
+ lines << "#{INDENT}#{c_field_declaration(field.type, sanitize_c_identifier(field.name))};"
49
+ end
50
+ lines << "}#{struct_layout_attributes(struct_decl)};"
51
+ lines
52
+ end
53
+
54
+ def emit_union(union_decl)
55
+ lines = []
56
+ lines << "union #{union_decl.linkage_name} {"
57
+ union_decl.fields.each do |field|
58
+ lines << "#{INDENT}#{c_field_declaration(field.type, sanitize_c_identifier(field.name))};"
59
+ end
60
+ lines << "};"
61
+ lines
62
+ end
63
+
64
+ def variant_self_reference?(type, outer_c)
65
+ return false unless type.is_a?(Types::Variant) || type.is_a?(Types::VariantInstance)
66
+
67
+ named_type_c_name(type) == outer_c
68
+ end
69
+
70
+ def emit_variant(variant_decl)
71
+ lines = []
72
+ outer_c = variant_decl.linkage_name
73
+ payload_arms = variant_decl.arms.select { |a| a.fields.any? }
74
+
75
+ # Per-arm payload structs
76
+ payload_arms.each do |arm|
77
+ lines << "struct #{arm.linkage_name} {"
78
+ arm.fields.each do |field|
79
+ if aggregate_field_creates_cycle?(field.type, outer_c)
80
+ if array_type?(field.type)
81
+ lines << "#{INDENT}#{c_declaration(array_element_type(field.type), "*#{sanitize_c_identifier(field.name)}")};"
82
+ else
83
+ lines << "#{INDENT}#{c_declaration(field.type, "*#{sanitize_c_identifier(field.name)}")};"
86
84
  end
87
- lines << "};"
88
- end
89
-
90
-
91
- # Kind enum
92
- lines << "typedef int32_t #{outer_c}_kind;"
93
- unless variant_decl.arms.empty?
94
- lines << "enum {"
95
- variant_decl.arms.each_with_index do |arm, index|
96
- suffix = index == variant_decl.arms.length - 1 ? "" : ","
97
- lines << "#{INDENT}#{outer_c}_kind_#{arm.name} = #{index}#{suffix}"
85
+ else
86
+ lines << "#{INDENT}#{c_field_declaration(field.type, sanitize_c_identifier(field.name))};"
98
87
  end
99
- lines << "};"
100
88
  end
101
-
102
- # Data union (only if at least one arm has payload)
103
- if payload_arms.any?
104
- lines << "union #{outer_c}_data {"
105
- payload_arms.each do |arm|
106
- lines << "#{INDENT}struct #{arm.linkage_name} #{sanitize_c_identifier(arm.name)};"
107
- end
108
- lines << "};"
109
- end
110
-
111
- # Outer struct
112
- lines << "struct #{outer_c} {"
113
- lines << "#{INDENT}#{outer_c}_kind kind;"
114
- lines << "#{INDENT}union #{outer_c}_data data;" if payload_arms.any?
115
89
  lines << "};"
116
- lines
117
90
  end
118
91
 
119
- def emit_enum(enum_decl)
120
- lines = ["typedef #{c_type(enum_decl.backing_type)} #{enum_decl.linkage_name};"]
121
- return lines if enum_decl.members.empty?
122
92
 
123
- lines << "enum {"
124
- enum_decl.members.each_with_index do |member, index|
125
- suffix = index == enum_decl.members.length - 1 ? "" : ","
126
- lines << "#{INDENT}#{member.linkage_name} = #{emit_expression(member.value)}#{suffix}"
127
- end
128
- lines << "};"
129
- lines
130
- end
131
-
132
- def emit_function_declarations(functions)
133
- functions.map { |function| "#{function_signature(function)};" }
134
- end
135
-
136
- def function_signature(function)
137
- prefix = function.entry_point ? "" : "static "
138
- "#{prefix}#{c_function_declaration(function.return_type, function.linkage_name, function_params(function))}"
139
- end
140
-
141
- def function_params(function)
142
- params = []
143
- params << array_out_param_declaration(function.return_type, ARRAY_OUT_PARAM_NAME) if array_type?(function.return_type)
144
- params.concat(emitted_function_params(function).map { |param| c_declaration(param.pointer ? pointer_to(param.type) : param.type, param.linkage_name) })
145
-
146
- if params.empty?
147
- "void"
148
- else
149
- params.join(", ")
150
- end
151
- end
152
-
153
- def emit_function(function)
154
- @checked_index_alias_stack.clear
155
- @checked_index_alias_id = 0
156
- @suppressed_labels = []
157
- body = compact_generated_statement_sequence(function.body)
158
- lines = ["#{function_signature(function)} {"]
159
- used_labels = collect_used_labels(body)
160
- if body.empty?
161
- lines << "}"
162
- else
163
- lines.concat(emit_statement_sequence(body, 1, function:, used_labels:))
164
- lines << "}"
165
- end
166
- lines
167
- end
168
-
169
- def emit_string_type
170
- [
171
- "typedef struct mt_str {",
172
- "#{INDENT}char* data;",
173
- "#{INDENT}uintptr_t len;",
174
- "} mt_str;",
175
- ]
176
- end
177
-
178
- def emit_span_type(type)
179
- span_type = span_type_name(type)
180
- [
181
- "typedef struct #{span_type} {",
182
- "#{INDENT}#{c_declaration(pointer_to(type.element_type), 'data')};",
183
- "#{INDENT}#{c_declaration(Types::Registry.primitive('ptr_uint'), 'len')};",
184
- "} #{span_type};",
185
- ]
186
- end
187
-
188
- def emit_soa_type(type)
189
- name = soa_type_name(type)
190
- lines = ["typedef struct #{name} {"]
191
- type.fields.each do |field_name, field_type|
192
- lines << "#{INDENT}#{c_field_declaration(field_type, sanitize_c_identifier(field_name))};"
193
- end
194
- lines << "} #{name};"
195
- lines
196
- end
197
-
198
- def emit_simd_type(type)
199
- name = simd_type_name(type)
200
- elem_c = primitive_c_type(type.element_type.name)
201
- width = type.lane_count * Layout.primitive_layout(type.element_type).first
202
- ["typedef #{elem_c} #{name} __attribute__((__vector_size__(#{width})));"]
203
- end
204
-
205
- def struct_layout_attributes(struct_decl)
206
- attributes = []
207
- attributes << "packed" if struct_decl.packed
208
- attributes << "aligned(#{struct_decl.alignment})" if struct_decl.alignment
209
- return "" if attributes.empty?
210
-
211
- " __attribute__((#{attributes.join(', ')}))"
212
- end
213
-
214
- def emit_vector_math_types
215
- lines = []
216
- lines << "typedef struct mt_vec2 { float x; float y; } mt_vec2;"
217
- lines << "typedef struct mt_vec3 { float x; float y; float z; } mt_vec3;"
218
- lines << "typedef struct mt_vec4 { float x; float y; float z; float w; } mt_vec4;"
219
- lines << "typedef struct mt_ivec2 { int32_t x; int32_t y; } mt_ivec2;"
220
- lines << "typedef struct mt_ivec3 { int32_t x; int32_t y; int32_t z; } mt_ivec3;"
221
- lines << "typedef struct mt_ivec4 { int32_t x; int32_t y; int32_t z; int32_t w; } mt_ivec4;"
222
- lines << ""
223
- lines << "typedef struct mt_mat3 { mt_vec3 col0; mt_vec3 col1; mt_vec3 col2; } mt_mat3;"
224
- lines << "typedef struct mt_mat4 { mt_vec4 col0; mt_vec4 col1; mt_vec4 col2; mt_vec4 col3; } mt_mat4;"
225
- lines << "typedef struct mt_quat { float x; float y; float z; float w; } mt_quat;"
226
- lines
227
- end
93
+ # Kind enum
94
+ lines << "typedef int32_t #{outer_c}_kind;"
95
+ unless variant_decl.arms.empty?
96
+ lines << "enum {"
97
+ variant_decl.arms.each_with_index do |arm, index|
98
+ suffix = index == variant_decl.arms.length - 1 ? "" : ","
99
+ lines << "#{INDENT}#{outer_c}_kind_#{arm.name} = #{index}#{suffix}"
100
+ end
101
+ lines << "};"
102
+ end
103
+
104
+ # Data union (only if at least one arm has payload)
105
+ if payload_arms.any?
106
+ lines << "union #{outer_c}_data {"
107
+ payload_arms.each do |arm|
108
+ lines << "#{INDENT}struct #{arm.linkage_name} #{sanitize_c_identifier(arm.name)};"
109
+ end
110
+ lines << "};"
111
+ end
112
+
113
+ # Outer struct
114
+ lines << "struct #{outer_c} {"
115
+ lines << "#{INDENT}#{outer_c}_kind kind;"
116
+ lines << "#{INDENT}union #{outer_c}_data data;" if payload_arms.any?
117
+ lines << "};"
118
+ lines
119
+ end
120
+
121
+ def emit_enum(enum_decl)
122
+ lines = ["typedef #{c_type(enum_decl.backing_type)} #{enum_decl.linkage_name};"]
123
+ return lines if enum_decl.members.empty?
124
+
125
+ lines << "enum {"
126
+ enum_decl.members.each_with_index do |member, index|
127
+ suffix = index == enum_decl.members.length - 1 ? "" : ","
128
+ lines << "#{INDENT}#{member.linkage_name} = #{emit_expression(member.value)}#{suffix}"
129
+ end
130
+ lines << "};"
131
+ lines
132
+ end
133
+
134
+ def emit_function_declarations(functions)
135
+ functions.map { |function| "#{function_signature(function)};" }
136
+ end
137
+
138
+ def function_signature(function)
139
+ prefix = function.entry_point ? "" : "static "
140
+ "#{prefix}#{c_function_declaration(function.return_type, function.linkage_name, function_params(function))}"
141
+ end
142
+
143
+ def function_params(function)
144
+ params = []
145
+ params << array_out_param_declaration(function.return_type, ARRAY_OUT_PARAM_NAME) if array_type?(function.return_type)
146
+ params.concat(emitted_function_params(function).map { |param| c_declaration(param.pointer ? pointer_to(param.type) : param.type, param.linkage_name) })
147
+
148
+ if params.empty?
149
+ "void"
150
+ else
151
+ params.join(", ")
152
+ end
153
+ end
154
+
155
+ def emit_function(function)
156
+ @checked_index_alias_stack.clear
157
+ @checked_index_alias_id = 0
158
+ @suppressed_labels = []
159
+ body = compact_generated_statement_sequence(function.body)
160
+ lines = ["#{function_signature(function)} {"]
161
+ used_labels = collect_used_labels(body)
162
+ if body.empty?
163
+ lines << "}"
164
+ else
165
+ lines.concat(emit_statement_sequence(body, 1, function:, used_labels:))
166
+ lines << "}"
167
+ end
168
+ lines
169
+ end
170
+
171
+ def emit_string_type
172
+ [
173
+ "typedef struct mt_str {",
174
+ "#{INDENT}char* data;",
175
+ "#{INDENT}uintptr_t len;",
176
+ "} mt_str;",
177
+ ]
178
+ end
179
+
180
+ def emit_span_type(type)
181
+ span_type = span_type_name(type)
182
+ [
183
+ "typedef struct #{span_type} {",
184
+ "#{INDENT}#{c_declaration(pointer_to(type.element_type), 'data')};",
185
+ "#{INDENT}#{c_declaration(Types::Registry.primitive('ptr_uint'), 'len')};",
186
+ "} #{span_type};",
187
+ ]
188
+ end
189
+
190
+ def emit_soa_type(type)
191
+ name = soa_type_name(type)
192
+ lines = ["typedef struct #{name} {"]
193
+ type.fields.each do |field_name, field_type|
194
+ lines << "#{INDENT}#{c_field_declaration(field_type, sanitize_c_identifier(field_name))};"
195
+ end
196
+ lines << "} #{name};"
197
+ lines
198
+ end
199
+
200
+ def emit_simd_type(type)
201
+ name = simd_type_name(type)
202
+ elem_c = primitive_c_type(type.element_type.name)
203
+ width = type.lane_count * Layout.primitive_layout(type.element_type).first
204
+ ["typedef #{elem_c} #{name} __attribute__((__vector_size__(#{width})));"]
205
+ end
206
+
207
+ def struct_layout_attributes(struct_decl)
208
+ attributes = []
209
+ attributes << "packed" if struct_decl.packed
210
+ attributes << "aligned(#{struct_decl.alignment})" if struct_decl.alignment
211
+ return "" if attributes.empty?
212
+
213
+ " __attribute__((#{attributes.join(', ')}))"
214
+ end
215
+
216
+ def emit_vector_math_types
217
+ lines = []
218
+ lines << "typedef struct mt_vec2 { float x; float y; } mt_vec2;"
219
+ lines << "typedef struct mt_vec3 { float x; float y; float z; } mt_vec3;"
220
+ lines << "typedef struct mt_vec4 { float x; float y; float z; float w; } mt_vec4;"
221
+ lines << "typedef struct mt_ivec2 { int32_t x; int32_t y; } mt_ivec2;"
222
+ lines << "typedef struct mt_ivec3 { int32_t x; int32_t y; int32_t z; } mt_ivec3;"
223
+ lines << "typedef struct mt_ivec4 { int32_t x; int32_t y; int32_t z; int32_t w; } mt_ivec4;"
224
+ lines << ""
225
+ lines << "typedef struct mt_mat3 { mt_vec3 col0; mt_vec3 col1; mt_vec3 col2; } mt_mat3;"
226
+ lines << "typedef struct mt_mat4 { mt_vec4 col0; mt_vec4 col1; mt_vec4 col2; mt_vec4 col3; } mt_mat4;"
227
+ lines << "typedef struct mt_quat { float x; float y; float z; float w; } mt_quat;"
228
+ lines
229
+ end
228
230
  end
229
231
  end
230
232
  end