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
@@ -2,27 +2,12 @@
2
2
 
3
3
  module MilkTea
4
4
  module LowererScans
5
- private
6
-
7
- def collect_structs
8
- @ctx.ast.declarations.each do |decl|
9
- case decl
10
- when AST::WhenStmt
11
- body = lower_when_chosen_body(decl)
12
- body&.each { |nested| collect_struct_from_decl(nested) }
13
- when AST::OpaqueDecl
14
- @ctx.opaque_types[decl.name] = @ctx.types.fetch(decl.name)
15
- when AST::StructDecl
16
- @ctx.struct_types[decl.name] = @ctx.types.fetch(decl.name)
17
- collect_nested_structs(decl)
18
- when AST::UnionDecl
19
- @ctx.union_types[decl.name] = @ctx.types.fetch(decl.name)
20
- end
21
- end
22
- end
23
-
24
- def collect_struct_from_decl(decl)
5
+ def collect_structs
6
+ @ctx.ast.declarations.each do |decl|
25
7
  case decl
8
+ when AST::WhenStmt
9
+ body = lower_when_chosen_body(decl)
10
+ body&.each { |nested| collect_struct_from_decl(nested) }
26
11
  when AST::OpaqueDecl
27
12
  @ctx.opaque_types[decl.name] = @ctx.types.fetch(decl.name)
28
13
  when AST::StructDecl
@@ -30,191 +15,204 @@ module MilkTea
30
15
  collect_nested_structs(decl)
31
16
  when AST::UnionDecl
32
17
  @ctx.union_types[decl.name] = @ctx.types.fetch(decl.name)
33
- when AST::WhenStmt
34
- body = lower_when_chosen_body(decl)
35
- body&.each { |nested| collect_struct_from_decl(nested) }
36
- end
37
- end
38
-
39
- def lower_when_chosen_body(decl)
40
- val = compile_time_const_value(decl.discriminant)
41
- return nil if val.nil?
42
-
43
- chosen = decl.branches.find { |b| val == compile_time_const_value(b.pattern) }
44
- chosen&.body || decl.else_body
45
- end
46
-
47
- def collect_nested_structs(parent_decl, parent_name: parent_decl.name)
48
- parent_decl.nested_types.each do |nested|
49
- qualified_name = "#{parent_name}.#{nested.name}"
50
- @ctx.struct_types[qualified_name] = @ctx.types.fetch(qualified_name)
51
- collect_nested_structs(nested, parent_name: qualified_name)
52
- end
53
- end
54
-
55
- def collect_includes
56
- headers = ["<stdbool.h>", "<stdint.h>", "<string.h>"]
57
- headers << "<stddef.h>" if program_uses_offsetof?
58
- headers << "<stdio.h>" if program_uses_fatal?
59
-
60
- each_raw_module_analysis do |analysis|
61
- analysis.directives.grep(AST::IncludeDirective).each do |directive|
62
- headers << normalized_include_header(directive.value)
63
- end
64
18
  end
65
-
66
- headers.uniq.map { |header| IR::Include.new(header:) }
67
- end
68
-
69
- def normalized_include_header(header_name)
70
- return "<#{header_name}>" if standard_c_runtime_header?(header_name)
71
-
72
- %("#{header_name}")
73
- end
74
-
75
- def standard_c_runtime_header?(header_name)
76
- %w[stdbool.h stdint.h stdlib.h string.h stddef.h stdio.h time.h].include?(header_name)
77
19
  end
78
-
79
- def program_uses_fatal?
80
- each_non_raw_module_analysis.any? do |analysis|
81
- analysis_uses_fatal?(analysis)
20
+ end
21
+
22
+ def collect_struct_from_decl(decl)
23
+ case decl
24
+ when AST::OpaqueDecl
25
+ @ctx.opaque_types[decl.name] = @ctx.types.fetch(decl.name)
26
+ when AST::StructDecl
27
+ @ctx.struct_types[decl.name] = @ctx.types.fetch(decl.name)
28
+ collect_nested_structs(decl)
29
+ when AST::UnionDecl
30
+ @ctx.union_types[decl.name] = @ctx.types.fetch(decl.name)
31
+ when AST::WhenStmt
32
+ body = lower_when_chosen_body(decl)
33
+ body&.each { |nested| collect_struct_from_decl(nested) }
34
+ end
35
+ end
36
+
37
+ def lower_when_chosen_body(decl)
38
+ val = compile_time_const_value(decl.discriminant)
39
+ return nil if val.nil?
40
+
41
+ chosen = decl.branches.find { |b| val == compile_time_const_value(b.pattern) }
42
+ chosen&.body || decl.else_body
43
+ end
44
+
45
+ def collect_nested_structs(parent_decl, parent_name: parent_decl.name)
46
+ parent_decl.nested_types.each do |nested|
47
+ qualified_name = "#{parent_name}.#{nested.name}"
48
+ @ctx.struct_types[qualified_name] = @ctx.types.fetch(qualified_name)
49
+ collect_nested_structs(nested, parent_name: qualified_name)
50
+ end
51
+ end
52
+
53
+ def collect_includes
54
+ headers = ["<stdbool.h>", "<stdint.h>", "<string.h>"]
55
+ headers << "<stddef.h>" if program_uses_offsetof?
56
+ headers << "<stdio.h>" if program_uses_fatal?
57
+
58
+ each_raw_module_analysis do |analysis|
59
+ analysis.directives.grep(AST::IncludeDirective).each do |directive|
60
+ headers << normalized_include_header(directive.value)
82
61
  end
83
62
  end
84
63
 
85
- def program_uses_offsetof?
86
- each_non_raw_module_analysis.any? do |analysis|
87
- analysis_uses_offsetof?(analysis)
88
- end
89
- end
64
+ headers.uniq.map { |header| IR::Include.new(header:) }
65
+ end
90
66
 
91
- def analysis_uses_fatal?(analysis)
92
- analysis.ast.declarations.any? do |decl|
93
- case decl
94
- when AST::FunctionDef
95
- block_uses_fatal?(decl.body)
96
- when AST::ExtendingBlock
97
- decl.methods.any? { |method| block_uses_fatal?(method.body) }
98
- else
99
- false
100
- end
101
- end
102
- end
67
+ def normalized_include_header(header_name)
68
+ return "<#{header_name}>" if standard_c_runtime_header?(header_name)
103
69
 
104
- def analysis_uses_offsetof?(analysis)
105
- analysis.ast.declarations.any? do |decl|
106
- case decl
107
- when AST::FunctionDef
108
- block_uses_offsetof?(decl.body)
109
- when AST::ExtendingBlock
110
- decl.methods.any? { |method| block_uses_offsetof?(method.body) }
111
- else
112
- false
113
- end
114
- end
115
- end
70
+ %("#{header_name}")
71
+ end
116
72
 
117
- def block_uses_fatal?(statements)
118
- block_uses_expression_pattern?(statements) { |expression| fatal_expression?(expression) }
119
- end
73
+ def standard_c_runtime_header?(header_name)
74
+ %w[stdbool.h stdint.h stdlib.h string.h stddef.h stdio.h time.h].include?(header_name)
75
+ end
120
76
 
121
- def block_uses_offsetof?(statements)
122
- block_uses_expression_pattern?(statements) { |expression| offsetof_expression?(expression) }
77
+ def program_uses_fatal?
78
+ each_non_raw_module_analysis.any? do |analysis|
79
+ analysis_uses_fatal?(analysis)
123
80
  end
81
+ end
124
82
 
125
- def block_uses_expression_pattern?(statements, &predicate)
126
- statements.any? { |statement| statement_uses_expression_pattern?(statement, &predicate) }
83
+ def program_uses_offsetof?
84
+ each_non_raw_module_analysis.any? do |analysis|
85
+ analysis_uses_offsetof?(analysis)
127
86
  end
87
+ end
128
88
 
129
- def statement_uses_expression_pattern?(statement, &predicate)
130
- case statement
131
- when AST::LocalDecl
132
- expression_uses_pattern?(statement.value, &predicate)
133
- when AST::Assignment
134
- expression_uses_pattern?(statement.target, &predicate) || expression_uses_pattern?(statement.value, &predicate)
135
- when AST::IfStmt
136
- statement.branches.any? { |branch| expression_uses_pattern?(branch.condition, &predicate) || block_uses_expression_pattern?(branch.body, &predicate) } ||
137
- (statement.else_body && block_uses_expression_pattern?(statement.else_body, &predicate))
138
- when AST::MatchStmt
139
- expression_uses_pattern?(statement.expression, &predicate) || statement.arms.any? { |arm| expression_uses_pattern?(arm.pattern, &predicate) || block_uses_expression_pattern?(arm.body, &predicate) }
140
- when AST::StaticAssert
141
- expression_uses_pattern?(statement.condition, &predicate) || expression_uses_pattern?(statement.message, &predicate)
142
- when AST::ForStmt
143
- statement.iterables.any? { |iterable| expression_uses_pattern?(iterable, &predicate) } || block_uses_expression_pattern?(statement.body, &predicate)
144
- when AST::UnsafeStmt, AST::WhileStmt
145
- expression = statement.is_a?(AST::WhileStmt) ? statement.condition : nil
146
- (expression && expression_uses_pattern?(expression, &predicate)) || block_uses_expression_pattern?(statement.body, &predicate)
147
- when AST::ReturnStmt
148
- statement.value && expression_uses_pattern?(statement.value, &predicate)
149
- when AST::DeferStmt, AST::ExpressionStmt
150
- expression_uses_pattern?(statement.expression, &predicate)
89
+ def analysis_uses_fatal?(analysis)
90
+ analysis.ast.declarations.any? do |decl|
91
+ case decl
92
+ when AST::FunctionDef
93
+ block_uses_fatal?(decl.body)
94
+ when AST::ExtendingBlock
95
+ decl.methods.any? { |method| block_uses_fatal?(method.body) }
151
96
  else
152
97
  false
153
98
  end
154
99
  end
100
+ end
155
101
 
156
- def fatal_expression?(expression)
157
- expression.is_a?(AST::Call) && expression.callee.is_a?(AST::Identifier) && expression.callee.name == "fatal"
158
- end
159
-
160
- def offsetof_expression?(expression)
161
- expression.is_a?(AST::OffsetofExpr)
162
- end
163
-
164
- def expression_uses_pattern?(expression, &predicate)
165
- return false unless expression
166
- return true if predicate.call(expression)
167
-
168
- case expression
169
- when AST::AwaitExpr
170
- expression_uses_pattern?(expression.expression, &predicate)
171
- when AST::Call
172
- expression_uses_pattern?(expression.callee, &predicate) || expression.arguments.any? { |argument| expression_uses_pattern?(argument.value, &predicate) }
173
- when AST::BinaryOp
174
- expression_uses_pattern?(expression.left, &predicate) || expression_uses_pattern?(expression.right, &predicate)
175
- when AST::RangeExpr
176
- expression_uses_pattern?(expression.start_expr, &predicate) || expression_uses_pattern?(expression.end_expr, &predicate)
177
- when AST::IfExpr
178
- expression_uses_pattern?(expression.condition, &predicate) || expression_uses_pattern?(expression.then_expression, &predicate) || expression_uses_pattern?(expression.else_expression, &predicate)
179
- when AST::MatchExpr
180
- expression_uses_pattern?(expression.expression, &predicate) || expression.arms.any? { |arm| expression_uses_pattern?(arm.pattern, &predicate) || expression_uses_pattern?(arm.value, &predicate) }
181
- when AST::UnsafeExpr
182
- expression_uses_pattern?(expression.expression, &predicate)
183
- when AST::PrefixCast
184
- expression_uses_pattern?(expression.expression, &predicate)
185
- when AST::UnaryOp
186
- expression_uses_pattern?(expression.operand, &predicate)
187
- when AST::MemberAccess
188
- expression_uses_pattern?(expression.receiver, &predicate)
189
- when AST::IndexAccess
190
- expression_uses_pattern?(expression.receiver, &predicate) || expression_uses_pattern?(expression.index, &predicate)
191
- when AST::Specialization
192
- expression_uses_pattern?(expression.callee, &predicate) || expression.arguments.any? { |argument| expression_uses_pattern?(argument.value, &predicate) }
102
+ def analysis_uses_offsetof?(analysis)
103
+ analysis.ast.declarations.any? do |decl|
104
+ case decl
105
+ when AST::FunctionDef
106
+ block_uses_offsetof?(decl.body)
107
+ when AST::ExtendingBlock
108
+ decl.methods.any? { |method| block_uses_offsetof?(method.body) }
193
109
  else
194
110
  false
195
111
  end
196
112
  end
197
-
198
- def prepare_analysis(analysis, source_path: nil)
199
- @ctx.install(analysis)
200
- @ctx.current_analysis_path = source_path
201
- @ctx.module_prefix = module_c_prefix(@ctx.module_name)
202
- end
203
-
204
- private def sanitize_type_name_for_tuple(type)
205
- type.to_s.gsub(/[^a-zA-Z0-9]/, "_").gsub(/_+/, "_").gsub(/^_|_$/, "")
206
- end
207
-
208
- def build_method_definitions
209
- @program.analyses_by_path.values.each_with_object({}) do |analysis, definitions|
210
- analysis.ast.declarations.grep(AST::ExtendingBlock).each do |extending_block|
211
- receiver_type = resolve_extending_receiver_type(analysis, extending_block.type_name)
212
- extending_block.methods.each do |method|
213
- method_key = method.kind == :static ? "static:#{method.name}" : method.name
214
- definitions[[receiver_type, method_key]] = [analysis, method]
215
- end
113
+ end
114
+
115
+ def block_uses_fatal?(statements)
116
+ block_uses_expression_pattern?(statements) { |expression| fatal_expression?(expression) }
117
+ end
118
+
119
+ def block_uses_offsetof?(statements)
120
+ block_uses_expression_pattern?(statements) { |expression| offsetof_expression?(expression) }
121
+ end
122
+
123
+ def block_uses_expression_pattern?(statements, &predicate)
124
+ statements.any? { |statement| statement_uses_expression_pattern?(statement, &predicate) }
125
+ end
126
+
127
+ def statement_uses_expression_pattern?(statement, &predicate)
128
+ case statement
129
+ when AST::LocalDecl
130
+ expression_uses_pattern?(statement.value, &predicate)
131
+ when AST::Assignment
132
+ expression_uses_pattern?(statement.target, &predicate) || expression_uses_pattern?(statement.value, &predicate)
133
+ when AST::IfStmt
134
+ statement.branches.any? { |branch| expression_uses_pattern?(branch.condition, &predicate) || block_uses_expression_pattern?(branch.body, &predicate) } ||
135
+ (statement.else_body && block_uses_expression_pattern?(statement.else_body, &predicate))
136
+ when AST::MatchStmt
137
+ expression_uses_pattern?(statement.expression, &predicate) || statement.arms.any? { |arm| expression_uses_pattern?(arm.pattern, &predicate) || block_uses_expression_pattern?(arm.body, &predicate) }
138
+ when AST::StaticAssert
139
+ expression_uses_pattern?(statement.condition, &predicate) || expression_uses_pattern?(statement.message, &predicate)
140
+ when AST::ForStmt
141
+ statement.iterables.any? { |iterable| expression_uses_pattern?(iterable, &predicate) } || block_uses_expression_pattern?(statement.body, &predicate)
142
+ when AST::UnsafeStmt, AST::WhileStmt
143
+ expression = statement.is_a?(AST::WhileStmt) ? statement.condition : nil
144
+ (expression && expression_uses_pattern?(expression, &predicate)) || block_uses_expression_pattern?(statement.body, &predicate)
145
+ when AST::ReturnStmt
146
+ statement.value && expression_uses_pattern?(statement.value, &predicate)
147
+ when AST::DeferStmt, AST::ExpressionStmt
148
+ expression_uses_pattern?(statement.expression, &predicate)
149
+ else
150
+ false
151
+ end
152
+ end
153
+
154
+ def fatal_expression?(expression)
155
+ expression.is_a?(AST::Call) && expression.callee.is_a?(AST::Identifier) && expression.callee.name == "fatal"
156
+ end
157
+
158
+ def offsetof_expression?(expression)
159
+ expression.is_a?(AST::OffsetofExpr)
160
+ end
161
+
162
+ def expression_uses_pattern?(expression, &predicate)
163
+ return false unless expression
164
+ return true if predicate.call(expression)
165
+
166
+ case expression
167
+ when AST::AwaitExpr
168
+ expression_uses_pattern?(expression.expression, &predicate)
169
+ when AST::Call
170
+ expression_uses_pattern?(expression.callee, &predicate) || expression.arguments.any? { |argument| expression_uses_pattern?(argument.value, &predicate) }
171
+ when AST::BinaryOp
172
+ expression_uses_pattern?(expression.left, &predicate) || expression_uses_pattern?(expression.right, &predicate)
173
+ when AST::RangeExpr
174
+ expression_uses_pattern?(expression.start_expr, &predicate) || expression_uses_pattern?(expression.end_expr, &predicate)
175
+ when AST::IfExpr
176
+ expression_uses_pattern?(expression.condition, &predicate) || expression_uses_pattern?(expression.then_expression, &predicate) || expression_uses_pattern?(expression.else_expression, &predicate)
177
+ when AST::MatchExpr
178
+ expression_uses_pattern?(expression.expression, &predicate) || expression.arms.any? { |arm| expression_uses_pattern?(arm.pattern, &predicate) || expression_uses_pattern?(arm.value, &predicate) }
179
+ when AST::UnsafeExpr
180
+ expression_uses_pattern?(expression.expression, &predicate)
181
+ when AST::PrefixCast
182
+ expression_uses_pattern?(expression.expression, &predicate)
183
+ when AST::UnaryOp
184
+ expression_uses_pattern?(expression.operand, &predicate)
185
+ when AST::MemberAccess
186
+ expression_uses_pattern?(expression.receiver, &predicate)
187
+ when AST::IndexAccess
188
+ expression_uses_pattern?(expression.receiver, &predicate) || expression_uses_pattern?(expression.index, &predicate)
189
+ when AST::Specialization
190
+ expression_uses_pattern?(expression.callee, &predicate) || expression.arguments.any? { |argument| expression_uses_pattern?(argument.value, &predicate) }
191
+ else
192
+ false
193
+ end
194
+ end
195
+
196
+ def prepare_analysis(analysis, path: nil)
197
+ @ctx.install(analysis)
198
+ @ctx.current_analysis_path = path
199
+ @ctx.module_prefix = module_c_prefix(@ctx.module_name)
200
+ end
201
+
202
+ def sanitize_type_name_for_tuple(type)
203
+ type.to_s.gsub(/[^a-zA-Z0-9]/, "_").gsub(/_+/, "_").gsub(/^_|_$/, "")
204
+ end
205
+
206
+ def build_method_definitions
207
+ @program.analyses_by_path.values.each_with_object({}) do |analysis, definitions|
208
+ analysis.ast.declarations.grep(AST::ExtendingBlock).each do |extending_block|
209
+ receiver_type = resolve_extending_receiver_type(analysis, extending_block.type_name)
210
+ extending_block.methods.each do |method|
211
+ method_key = method.kind == :static ? "static:#{method.name}" : method.name
212
+ definitions[[receiver_type, method_key]] = [analysis, method]
216
213
  end
217
214
  end
218
215
  end
216
+ end
219
217
  end
220
218
  end
@@ -2,124 +2,121 @@
2
2
 
3
3
  module MilkTea
4
4
  module LowererStrBuffer
5
- private
5
+ def str_buffer_method_kind(receiver_type, name)
6
+ return unless str_buffer_type?(receiver_type)
6
7
 
7
-
8
- def str_buffer_method_kind(receiver_type, name)
9
- return unless str_buffer_type?(receiver_type)
10
-
11
- case name
12
- when "clear"
13
- :str_buffer_clear
14
- when "assign"
15
- :str_buffer_assign
16
- when "append"
17
- :str_buffer_append
18
- when "assign_format"
19
- :str_buffer_assign_format
20
- when "append_format"
21
- :str_buffer_append_format
22
- when "len"
23
- :str_buffer_len
24
- when "capacity"
25
- :str_buffer_capacity
26
- when "as_str"
27
- :str_buffer_as_str
28
- when "as_cstr"
29
- :str_buffer_as_cstr
30
- end
8
+ case name
9
+ when "clear"
10
+ :str_buffer_clear
11
+ when "assign"
12
+ :str_buffer_assign
13
+ when "append"
14
+ :str_buffer_append
15
+ when "assign_format"
16
+ :str_buffer_assign_format
17
+ when "append_format"
18
+ :str_buffer_append_format
19
+ when "len"
20
+ :str_buffer_len
21
+ when "capacity"
22
+ :str_buffer_capacity
23
+ when "as_str"
24
+ :str_buffer_as_str
25
+ when "as_cstr"
26
+ :str_buffer_as_cstr
31
27
  end
28
+ end
32
29
 
33
- def str_buffer_method_type(kind, receiver_type)
34
- return_type, params = case kind
35
- when :str_buffer_clear
36
- [@ctx.types.fetch("void"), []]
37
- when :str_buffer_assign, :str_buffer_append, :str_buffer_assign_format, :str_buffer_append_format
38
- [@ctx.types.fetch("void"), [Types::Registry.parameter("value", @ctx.types.fetch("str"))]]
39
- when :str_buffer_len, :str_buffer_capacity
40
- [@ctx.types.fetch("ptr_uint"), []]
41
- when :str_buffer_as_str
42
- [@ctx.types.fetch("str"), []]
43
- when :str_buffer_as_cstr
44
- [@ctx.types.fetch("cstr"), []]
45
- else
46
- raise LoweringError.new("unsupported str_buffer method #{kind}", line: 0, column: 0, path: @ctx.current_analysis_path)
47
- end
30
+ def str_buffer_method_type(kind, receiver_type)
31
+ return_type, params = case kind
32
+ when :str_buffer_clear
33
+ [@ctx.types.fetch("void"), []]
34
+ when :str_buffer_assign, :str_buffer_append, :str_buffer_assign_format, :str_buffer_append_format
35
+ [@ctx.types.fetch("void"), [Types::Registry.parameter("value", @ctx.types.fetch("str"))]]
36
+ when :str_buffer_len, :str_buffer_capacity
37
+ [@ctx.types.fetch("ptr_uint"), []]
38
+ when :str_buffer_as_str
39
+ [@ctx.types.fetch("str"), []]
40
+ when :str_buffer_as_cstr
41
+ [@ctx.types.fetch("cstr"), []]
42
+ else
43
+ raise LoweringError.new("unsupported str_buffer method #{kind}", line: 0, column: 0, path: @ctx.current_analysis_path)
44
+ end
48
45
 
49
- Types::Registry.function(
50
- kind.to_s,
51
- params:,
52
- return_type:,
53
- receiver_type:,
54
- receiver_editable: %i[str_buffer_clear str_buffer_assign str_buffer_append str_buffer_assign_format str_buffer_append_format].include?(kind),
55
- external: false,
56
- )
57
- end
46
+ Types::Registry.function(
47
+ kind.to_s,
48
+ params:,
49
+ return_type:,
50
+ receiver_type:,
51
+ receiver_editable: %i[str_buffer_clear str_buffer_assign str_buffer_append str_buffer_assign_format str_buffer_append_format].include?(kind),
52
+ external: false,
53
+ )
54
+ end
58
55
 
59
- def lower_char_array_data_pointer(expression, env:)
60
- lowered_receiver = lower_expression(expression, env:)
61
- IR::AddressOf.new(
62
- expression: IR::Index.new(
63
- receiver: lowered_receiver,
64
- index: IR::IntegerLiteral.new(value: 0, type: @ctx.types.fetch("ptr_uint")),
65
- type: @ctx.types.fetch("char"),
66
- ),
67
- type: pointer_to(@ctx.types.fetch("char")),
68
- )
69
- end
56
+ def lower_char_array_data_pointer(expression, env:)
57
+ lowered_receiver = lower_expression(expression, env:)
58
+ IR::AddressOf.new(
59
+ expression: IR::Index.new(
60
+ receiver: lowered_receiver,
61
+ index: IR::IntegerLiteral.new(value: 0, type: @ctx.types.fetch("ptr_uint")),
62
+ type: @ctx.types.fetch("char"),
63
+ ),
64
+ type: pointer_to(@ctx.types.fetch("char")),
65
+ )
66
+ end
70
67
 
71
- def lower_str_buffer_data_pointer(expression, env:)
72
- lower_str_buffer_data_pointer_from_lowered(lower_expression(expression, env:))
73
- end
68
+ def lower_str_buffer_data_pointer(expression, env:)
69
+ lower_str_buffer_data_pointer_from_lowered(lower_expression(expression, env:))
70
+ end
74
71
 
75
- def lower_str_buffer_data_pointer_from_lowered(lowered_receiver)
76
- IR::AddressOf.new(
77
- expression: IR::Index.new(
78
- receiver: IR::Member.new(
79
- receiver: lowered_receiver,
80
- member: "data",
81
- type: Types::Registry.generic_instance(
82
- "array",
83
- [@ctx.types.fetch("char"), Types::LiteralTypeArg.new(str_buffer_storage_capacity(lowered_receiver.type))],
84
- ),
72
+ def lower_str_buffer_data_pointer_from_lowered(lowered_receiver)
73
+ IR::AddressOf.new(
74
+ expression: IR::Index.new(
75
+ receiver: IR::Member.new(
76
+ receiver: lowered_receiver,
77
+ member: "data",
78
+ type: Types::Registry.generic_instance(
79
+ "array",
80
+ [@ctx.types.fetch("char"), Types::LiteralTypeArg.new(str_buffer_storage_capacity(lowered_receiver.type))],
85
81
  ),
86
- index: IR::IntegerLiteral.new(value: 0, type: @ctx.types.fetch("ptr_uint")),
87
- type: @ctx.types.fetch("char"),
88
82
  ),
89
- type: pointer_to(@ctx.types.fetch("char")),
90
- )
91
- end
83
+ index: IR::IntegerLiteral.new(value: 0, type: @ctx.types.fetch("ptr_uint")),
84
+ type: @ctx.types.fetch("char"),
85
+ ),
86
+ type: pointer_to(@ctx.types.fetch("char")),
87
+ )
88
+ end
92
89
 
93
- def lower_str_buffer_len_pointer(expression, env:)
94
- lower_str_buffer_len_pointer_from_lowered(lower_expression(expression, env:))
95
- end
90
+ def lower_str_buffer_len_pointer(expression, env:)
91
+ lower_str_buffer_len_pointer_from_lowered(lower_expression(expression, env:))
92
+ end
96
93
 
97
- def lower_str_buffer_len_pointer_from_lowered(lowered_receiver)
98
- IR::AddressOf.new(
99
- expression: IR::Member.new(receiver: lowered_receiver, member: "len", type: @ctx.types.fetch("ptr_uint")),
100
- type: pointer_to(@ctx.types.fetch("ptr_uint")),
101
- )
102
- end
94
+ def lower_str_buffer_len_pointer_from_lowered(lowered_receiver)
95
+ IR::AddressOf.new(
96
+ expression: IR::Member.new(receiver: lowered_receiver, member: "len", type: @ctx.types.fetch("ptr_uint")),
97
+ type: pointer_to(@ctx.types.fetch("ptr_uint")),
98
+ )
99
+ end
103
100
 
104
- def lower_str_buffer_dirty_pointer(expression, env:)
105
- lower_str_buffer_dirty_pointer_from_lowered(lower_expression(expression, env:))
106
- end
101
+ def lower_str_buffer_dirty_pointer(expression, env:)
102
+ lower_str_buffer_dirty_pointer_from_lowered(lower_expression(expression, env:))
103
+ end
107
104
 
108
- def lower_str_buffer_dirty_pointer_from_lowered(lowered_receiver)
109
- IR::AddressOf.new(
110
- expression: IR::Member.new(receiver: lowered_receiver, member: "dirty", type: @ctx.types.fetch("bool")),
111
- type: pointer_to(@ctx.types.fetch("bool")),
112
- )
113
- end
105
+ def lower_str_buffer_dirty_pointer_from_lowered(lowered_receiver)
106
+ IR::AddressOf.new(
107
+ expression: IR::Member.new(receiver: lowered_receiver, member: "dirty", type: @ctx.types.fetch("bool")),
108
+ type: pointer_to(@ctx.types.fetch("bool")),
109
+ )
110
+ end
114
111
 
115
- def str_buffer_args(receiver, env:)
116
- receiver_type = infer_expression_type(receiver, env:)
117
- [
118
- lower_str_buffer_data_pointer(receiver, env:),
119
- IR::IntegerLiteral.new(value: str_buffer_capacity(receiver_type), type: @ctx.types.fetch("ptr_uint")),
120
- lower_str_buffer_len_pointer(receiver, env:),
121
- lower_str_buffer_dirty_pointer(receiver, env:),
122
- ]
123
- end
112
+ def str_buffer_args(receiver, env:)
113
+ receiver_type = infer_expression_type(receiver, env:)
114
+ [
115
+ lower_str_buffer_data_pointer(receiver, env:),
116
+ IR::IntegerLiteral.new(value: str_buffer_capacity(receiver_type), type: @ctx.types.fetch("ptr_uint")),
117
+ lower_str_buffer_len_pointer(receiver, env:),
118
+ lower_str_buffer_dirty_pointer(receiver, env:),
119
+ ]
120
+ end
124
121
  end
125
122
  end