mt-lang 0.3.24 → 0.3.26

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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/lib/milk_tea/base.rb +1 -1
  3. data/lib/milk_tea/core/bindings/attribute_binding.rb +51 -49
  4. data/lib/milk_tea/core/bindings/function_binding.rb +3 -1
  5. data/lib/milk_tea/core/bindings/module_binding.rb +42 -40
  6. data/lib/milk_tea/core/bindings/value_binding.rb +16 -14
  7. data/lib/milk_tea/core/bindings.rb +4 -9
  8. data/lib/milk_tea/core/c_backend/control_flow_emission.rb +11 -11
  9. data/lib/milk_tea/core/c_backend/expressions.rb +11 -11
  10. data/lib/milk_tea/core/c_backend/feature_detection.rb +15 -19
  11. data/lib/milk_tea/core/c_backend/format_helpers.rb +1 -1
  12. data/lib/milk_tea/core/c_backend/reinterpret.rb +10 -10
  13. data/lib/milk_tea/core/c_backend/runtime_helpers.rb +1 -1
  14. data/lib/milk_tea/core/c_backend/statements.rb +20 -20
  15. data/lib/milk_tea/core/c_backend/type_declaration.rb +4 -4
  16. data/lib/milk_tea/core/c_backend/type_system.rb +1 -1
  17. data/lib/milk_tea/core/c_backend.rb +3 -3
  18. data/lib/milk_tea/core/compile_time.rb +41 -70
  19. data/lib/milk_tea/core/control_flow/builder.rb +3 -3
  20. data/lib/milk_tea/core/control_flow/constant_propagation.rb +1 -1
  21. data/lib/milk_tea/core/control_flow/graph.rb +1 -1
  22. data/lib/milk_tea/core/control_flow/termination.rb +1 -1
  23. data/lib/milk_tea/core/cst.rb +16 -0
  24. data/lib/milk_tea/core/flow_scope.rb +13 -0
  25. data/lib/milk_tea/core/lexer/character_classes.rb +2 -2
  26. data/lib/milk_tea/core/lexer/format_strings.rb +5 -5
  27. data/lib/milk_tea/core/lexer/heredocs.rb +6 -6
  28. data/lib/milk_tea/core/lexer/indentation.rb +4 -4
  29. data/lib/milk_tea/core/lexer/numbers.rb +1 -1
  30. data/lib/milk_tea/core/lexer/strings.rb +4 -4
  31. data/lib/milk_tea/core/lexer/symbols.rb +3 -3
  32. data/lib/milk_tea/core/lexer/trivia.rb +4 -4
  33. data/lib/milk_tea/core/lexer.rb +17 -17
  34. data/lib/milk_tea/core/lowering/async/analysis.rb +210 -208
  35. data/lib/milk_tea/core/lowering/async/async_lowering.rb +1406 -0
  36. data/lib/milk_tea/core/lowering/async/frame_builder.rb +615 -613
  37. data/lib/milk_tea/core/lowering/async/normalization.rb +410 -408
  38. data/lib/milk_tea/core/lowering/block.rb +982 -980
  39. data/lib/milk_tea/core/lowering/calls.rb +1360 -1358
  40. data/lib/milk_tea/core/lowering/declarations.rb +175 -173
  41. data/lib/milk_tea/core/lowering/dyn.rb +171 -169
  42. data/lib/milk_tea/core/lowering/events.rb +946 -944
  43. data/lib/milk_tea/core/lowering/expressions.rb +1514 -1512
  44. data/lib/milk_tea/core/lowering/foreign_cstr.rb +180 -178
  45. data/lib/milk_tea/core/lowering/functions.rb +186 -184
  46. data/lib/milk_tea/core/lowering/loops.rb +1004 -1002
  47. data/lib/milk_tea/core/lowering/lowering_context.rb +1 -1
  48. data/lib/milk_tea/core/lowering/proc.rb +355 -353
  49. data/lib/milk_tea/core/lowering/resolve.rb +2127 -2125
  50. data/lib/milk_tea/core/lowering/scans.rb +162 -168
  51. data/lib/milk_tea/core/lowering/str_buffer.rb +104 -102
  52. data/lib/milk_tea/core/lowering/utils.rb +964 -963
  53. data/lib/milk_tea/core/lowering.rb +22 -22
  54. data/lib/milk_tea/core/module_binder.rb +1 -1
  55. data/lib/milk_tea/core/module_loader.rb +2 -2
  56. data/lib/milk_tea/core/parser/attributes.rb +1 -1
  57. data/lib/milk_tea/core/parser/blocks.rb +2 -2
  58. data/lib/milk_tea/core/parser/declarations.rb +15 -15
  59. data/lib/milk_tea/core/parser/expressions.rb +20 -20
  60. data/lib/milk_tea/core/parser/recovery.rb +1 -1
  61. data/lib/milk_tea/core/parser/statements.rb +3 -3
  62. data/lib/milk_tea/core/parser/types.rb +4 -4
  63. data/lib/milk_tea/core/parser.rb +39 -21
  64. data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +6 -6
  65. data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +5 -5
  66. data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +2 -2
  67. data/lib/milk_tea/core/semantic_analyzer/calls.rb +1 -1
  68. data/lib/milk_tea/core/semantic_analyzer/expressions.rb +4 -4
  69. data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +37 -37
  70. data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +4 -4
  71. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +4 -4
  72. data/lib/milk_tea/core/semantic_analyzer/generics.rb +4 -4
  73. data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +7 -7
  74. data/lib/milk_tea/core/semantic_analyzer/nullability.rb +59 -59
  75. data/lib/milk_tea/core/semantic_analyzer/statements.rb +3 -3
  76. data/lib/milk_tea/core/semantic_analyzer/top_level.rb +1 -1
  77. data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +12 -12
  78. data/lib/milk_tea/core/types/layout.rb +3 -1
  79. data/lib/milk_tea/core/types/visitor.rb +351 -349
  80. data/lib/milk_tea/core.rb +0 -2
  81. data/lib/milk_tea/tooling/cli/commands/bindgen.rb +1 -1
  82. data/lib/milk_tea/tooling/cli/commands/check.rb +5 -5
  83. data/lib/milk_tea/tooling/cli/commands/debug.rb +3 -3
  84. data/lib/milk_tea/tooling/cli/commands/deps.rb +1 -1
  85. data/lib/milk_tea/tooling/cli/commands/emit_c.rb +2 -2
  86. data/lib/milk_tea/tooling/cli/commands/format.rb +6 -6
  87. data/lib/milk_tea/tooling/cli/commands/lint.rb +3 -3
  88. data/lib/milk_tea/tooling/cli/commands/lower.rb +3 -3
  89. data/lib/milk_tea/tooling/cli/commands/parse.rb +3 -3
  90. data/lib/milk_tea/tooling/cli/commands/test.rb +3 -3
  91. data/lib/milk_tea/tooling/cli/commands/toolchain.rb +1 -1
  92. data/lib/milk_tea/tooling/cli.rb +22 -34
  93. data/lib/milk_tea/tooling/linter/flow_rules.rb +3 -3
  94. metadata +4 -5
  95. data/lib/milk_tea/core/cst_builder.rb +0 -19
  96. data/lib/milk_tea/core/lowering/async/lowering.rb +0 -1404
  97. data/lib/milk_tea/core/token_stream.rb +0 -30
@@ -5,208 +5,202 @@ require_relative "resolve"
5
5
  require_relative "utils"
6
6
 
7
7
  module MilkTea
8
- module LowererScans
9
- def collect_structs
10
- @ctx.ast.declarations.each { |decl| collect_one_struct_decl(decl) }
11
- end
12
-
13
- def collect_one_struct_decl(decl)
14
- case decl
15
- when AST::WhenStmt
16
- body = lower_when_chosen_body(decl)
17
- body&.each { |nested| collect_one_struct_decl(nested) }
18
- when AST::OpaqueDecl
19
- @ctx.opaque_types[decl.name] = @ctx.types.fetch(decl.name)
20
- when AST::StructDecl
21
- @ctx.struct_types[decl.name] = @ctx.types.fetch(decl.name)
22
- collect_nested_structs(decl)
23
- when AST::UnionDecl
24
- @ctx.union_types[decl.name] = @ctx.types.fetch(decl.name)
8
+ module Lowering
9
+ module Scans
10
+ def collect_structs
11
+ @ctx.ast.declarations.each { |decl| collect_one_struct_decl(decl) }
25
12
  end
26
- end
27
13
 
28
- def collect_struct_from_decl(decl)
29
- collect_one_struct_decl(decl)
30
- end
31
-
32
- def lower_when_chosen_body(decl)
33
- val = compile_time_const_value(decl.discriminant)
34
- return nil if val.nil?
14
+ def collect_one_struct_decl(decl)
15
+ case decl
16
+ when AST::WhenStmt
17
+ body = lower_when_chosen_body(decl)
18
+ body&.each { |nested| collect_one_struct_decl(nested) }
19
+ when AST::OpaqueDecl
20
+ @ctx.opaque_types[decl.name] = @ctx.types.fetch(decl.name)
21
+ when AST::StructDecl
22
+ @ctx.struct_types[decl.name] = @ctx.types.fetch(decl.name)
23
+ collect_nested_structs(decl)
24
+ when AST::UnionDecl
25
+ @ctx.union_types[decl.name] = @ctx.types.fetch(decl.name)
26
+ end
27
+ end
35
28
 
36
- chosen = decl.branches.find { |b| val == compile_time_const_value(b.pattern) }
37
- chosen&.body || decl.else_body
38
- end
29
+ def lower_when_chosen_body(decl)
30
+ val = compile_time_const_value(decl.discriminant)
31
+ return nil if val.nil?
39
32
 
40
- def collect_nested_structs(parent_decl, parent_name: parent_decl.name)
41
- parent_decl.nested_types.each do |nested|
42
- qualified_name = "#{parent_name}.#{nested.name}"
43
- @ctx.struct_types[qualified_name] = @ctx.types.fetch(qualified_name)
44
- collect_nested_structs(nested, parent_name: qualified_name)
33
+ chosen = decl.branches.find { |b| val == compile_time_const_value(b.pattern) }
34
+ chosen&.body || decl.else_body
45
35
  end
46
- end
47
-
48
- def collect_includes
49
- headers = ["<stdbool.h>", "<stdint.h>", "<string.h>"]
50
- headers << "<stddef.h>" if program_uses_offsetof?
51
- headers << "<stdio.h>" if program_uses_fatal?
52
36
 
53
- each_raw_module_analysis do |analysis|
54
- analysis.directives.grep(AST::IncludeDirective).each do |directive|
55
- headers << normalized_include_header(directive.value)
37
+ def collect_nested_structs(parent_decl, parent_name: parent_decl.name)
38
+ parent_decl.nested_types.each do |nested|
39
+ qualified_name = "#{parent_name}.#{nested.name}"
40
+ @ctx.struct_types[qualified_name] = @ctx.types.fetch(qualified_name)
41
+ collect_nested_structs(nested, parent_name: qualified_name)
56
42
  end
57
43
  end
58
44
 
59
- headers.uniq.map { |header| IR::Include.new(header:) }
60
- end
45
+ def collect_includes
46
+ headers = ["<stdbool.h>", "<stdint.h>", "<string.h>"]
47
+ headers << "<stddef.h>" if program_uses_offsetof?
48
+ headers << "<stdio.h>" if program_uses_fatal?
61
49
 
62
- def normalized_include_header(header_name)
63
- return "<#{header_name}>" if standard_c_runtime_header?(header_name)
50
+ each_raw_module_analysis do |analysis|
51
+ analysis.directives.grep(AST::IncludeDirective).each do |directive|
52
+ headers << normalized_include_header(directive.value)
53
+ end
54
+ end
64
55
 
65
- %("#{header_name}")
66
- end
56
+ headers.uniq.map { |header| IR::Include.new(header:) }
57
+ end
67
58
 
68
- def standard_c_runtime_header?(header_name)
69
- %w[stdbool.h stdint.h stdlib.h string.h stddef.h stdio.h time.h].include?(header_name)
70
- end
59
+ def normalized_include_header(header_name)
60
+ return "<#{header_name}>" if standard_c_runtime_header?(header_name)
71
61
 
72
- def program_uses_fatal?
73
- each_non_raw_module_analysis.any? do |analysis|
74
- analysis_uses_fatal?(analysis)
62
+ %("#{header_name}")
75
63
  end
76
- end
77
64
 
78
- def program_uses_offsetof?
79
- each_non_raw_module_analysis.any? do |analysis|
80
- analysis_uses_offsetof?(analysis)
65
+ def standard_c_runtime_header?(header_name)
66
+ %w[stdbool.h stdint.h stdlib.h string.h stddef.h stdio.h time.h].include?(header_name)
81
67
  end
82
- end
83
68
 
84
- def analysis_uses_fatal?(analysis)
85
- analysis.ast.declarations.any? do |decl|
86
- case decl
87
- when AST::FunctionDef
88
- block_uses_fatal?(decl.body)
89
- when AST::ExtendingBlock
90
- decl.methods.any? { |method| block_uses_fatal?(method.body) }
91
- else
92
- false
69
+ def program_uses_fatal?
70
+ each_non_raw_module_analysis.any? do |analysis|
71
+ analysis_uses_fatal?(analysis)
93
72
  end
94
73
  end
95
- end
96
74
 
97
- def analysis_uses_offsetof?(analysis)
98
- analysis.ast.declarations.any? do |decl|
99
- case decl
100
- when AST::FunctionDef
101
- block_uses_offsetof?(decl.body)
102
- when AST::ExtendingBlock
103
- decl.methods.any? { |method| block_uses_offsetof?(method.body) }
104
- else
105
- false
75
+ def program_uses_offsetof?
76
+ each_non_raw_module_analysis.any? do |analysis|
77
+ analysis_uses_offsetof?(analysis)
106
78
  end
107
79
  end
108
- end
109
80
 
110
- def block_uses_fatal?(statements)
111
- block_uses_expression_pattern?(statements) { |expression| fatal_expression?(expression) }
112
- end
81
+ def analysis_uses_fatal?(analysis)
82
+ analysis.ast.declarations.any? do |decl|
83
+ case decl
84
+ when AST::FunctionDef
85
+ block_uses_fatal?(decl.body)
86
+ when AST::ExtendingBlock
87
+ decl.methods.any? { |method| block_uses_fatal?(method.body) }
88
+ else
89
+ false
90
+ end
91
+ end
92
+ end
113
93
 
114
- def block_uses_offsetof?(statements)
115
- block_uses_expression_pattern?(statements) { |expression| offsetof_expression?(expression) }
116
- end
94
+ def analysis_uses_offsetof?(analysis)
95
+ analysis.ast.declarations.any? do |decl|
96
+ case decl
97
+ when AST::FunctionDef
98
+ block_uses_offsetof?(decl.body)
99
+ when AST::ExtendingBlock
100
+ decl.methods.any? { |method| block_uses_offsetof?(method.body) }
101
+ else
102
+ false
103
+ end
104
+ end
105
+ end
117
106
 
118
- def block_uses_expression_pattern?(statements, &predicate)
119
- statements.any? { |statement| statement_uses_expression_pattern?(statement, &predicate) }
120
- end
107
+ def block_uses_fatal?(statements)
108
+ block_uses_expression_pattern?(statements) { |expression| fatal_expression?(expression) }
109
+ end
121
110
 
122
- def statement_uses_expression_pattern?(statement, &predicate)
123
- case statement
124
- when AST::LocalDecl
125
- expression_uses_pattern?(statement.value, &predicate)
126
- when AST::Assignment
127
- expression_uses_pattern?(statement.target, &predicate) || expression_uses_pattern?(statement.value, &predicate)
128
- when AST::IfStmt
129
- statement.branches.any? { |branch| expression_uses_pattern?(branch.condition, &predicate) || block_uses_expression_pattern?(branch.body, &predicate) } ||
130
- (statement.else_body && block_uses_expression_pattern?(statement.else_body, &predicate))
131
- when AST::MatchStmt
132
- expression_uses_pattern?(statement.expression, &predicate) || statement.arms.any? { |arm| expression_uses_pattern?(arm.pattern, &predicate) || block_uses_expression_pattern?(arm.body, &predicate) }
133
- when AST::StaticAssert
134
- expression_uses_pattern?(statement.condition, &predicate) || expression_uses_pattern?(statement.message, &predicate)
135
- when AST::ForStmt
136
- statement.iterables.any? { |iterable| expression_uses_pattern?(iterable, &predicate) } || block_uses_expression_pattern?(statement.body, &predicate)
137
- when AST::UnsafeStmt, AST::WhileStmt
138
- expression = statement.is_a?(AST::WhileStmt) ? statement.condition : nil
139
- (expression && expression_uses_pattern?(expression, &predicate)) || block_uses_expression_pattern?(statement.body, &predicate)
140
- when AST::ReturnStmt
141
- statement.value && expression_uses_pattern?(statement.value, &predicate)
142
- when AST::ExpressionStmt
143
- expression_uses_pattern?(statement.expression, &predicate)
144
- when AST::DeferStmt
145
- block_uses_expression_pattern?(statement.body, &predicate)
146
- else
147
- false
111
+ def block_uses_offsetof?(statements)
112
+ block_uses_expression_pattern?(statements) { |expression| offsetof_expression?(expression) }
148
113
  end
149
- end
150
114
 
151
- def fatal_expression?(expression)
152
- expression.is_a?(AST::Call) && expression.callee.is_a?(AST::Identifier) && expression.callee.name == "fatal"
153
- end
115
+ def block_uses_expression_pattern?(statements, &predicate)
116
+ statements.any? { |statement| statement_uses_expression_pattern?(statement, &predicate) }
117
+ end
154
118
 
155
- def offsetof_expression?(expression)
156
- expression.is_a?(AST::OffsetofExpr)
157
- end
119
+ def statement_uses_expression_pattern?(statement, &predicate)
120
+ case statement
121
+ when AST::LocalDecl
122
+ expression_uses_pattern?(statement.value, &predicate)
123
+ when AST::Assignment
124
+ expression_uses_pattern?(statement.target, &predicate) || expression_uses_pattern?(statement.value, &predicate)
125
+ when AST::IfStmt
126
+ statement.branches.any? { |branch| expression_uses_pattern?(branch.condition, &predicate) || block_uses_expression_pattern?(branch.body, &predicate) } ||
127
+ (statement.else_body && block_uses_expression_pattern?(statement.else_body, &predicate))
128
+ when AST::MatchStmt
129
+ expression_uses_pattern?(statement.expression, &predicate) || statement.arms.any? { |arm| expression_uses_pattern?(arm.pattern, &predicate) || block_uses_expression_pattern?(arm.body, &predicate) }
130
+ when AST::StaticAssert
131
+ expression_uses_pattern?(statement.condition, &predicate) || expression_uses_pattern?(statement.message, &predicate)
132
+ when AST::ForStmt
133
+ statement.iterables.any? { |iterable| expression_uses_pattern?(iterable, &predicate) } || block_uses_expression_pattern?(statement.body, &predicate)
134
+ when AST::UnsafeStmt, AST::WhileStmt
135
+ expression = statement.is_a?(AST::WhileStmt) ? statement.condition : nil
136
+ (expression && expression_uses_pattern?(expression, &predicate)) || block_uses_expression_pattern?(statement.body, &predicate)
137
+ when AST::ReturnStmt
138
+ statement.value && expression_uses_pattern?(statement.value, &predicate)
139
+ when AST::ExpressionStmt
140
+ expression_uses_pattern?(statement.expression, &predicate)
141
+ when AST::DeferStmt
142
+ block_uses_expression_pattern?(statement.body, &predicate)
143
+ else
144
+ false
145
+ end
146
+ end
158
147
 
159
- def expression_uses_pattern?(expression, &predicate)
160
- return false unless expression
161
- return true if predicate.call(expression)
162
-
163
- case expression
164
- when AST::AwaitExpr
165
- expression_uses_pattern?(expression.expression, &predicate)
166
- when AST::Call
167
- expression_uses_pattern?(expression.callee, &predicate) || expression.arguments.any? { |argument| expression_uses_pattern?(argument.value, &predicate) }
168
- when AST::BinaryOp
169
- expression_uses_pattern?(expression.left, &predicate) || expression_uses_pattern?(expression.right, &predicate)
170
- when AST::RangeExpr
171
- expression_uses_pattern?(expression.start_expr, &predicate) || expression_uses_pattern?(expression.end_expr, &predicate)
172
- when AST::IfExpr
173
- expression_uses_pattern?(expression.condition, &predicate) || expression_uses_pattern?(expression.then_expression, &predicate) || expression_uses_pattern?(expression.else_expression, &predicate)
174
- when AST::MatchExpr
175
- expression_uses_pattern?(expression.expression, &predicate) || expression.arms.any? { |arm| expression_uses_pattern?(arm.pattern, &predicate) || expression_uses_pattern?(arm.value, &predicate) }
176
- when AST::UnsafeExpr
177
- expression_uses_pattern?(expression.expression, &predicate)
178
- when AST::PrefixCast
179
- expression_uses_pattern?(expression.expression, &predicate)
180
- when AST::UnaryOp
181
- expression_uses_pattern?(expression.operand, &predicate)
182
- when AST::MemberAccess
183
- expression_uses_pattern?(expression.receiver, &predicate)
184
- when AST::IndexAccess
185
- expression_uses_pattern?(expression.receiver, &predicate) || expression_uses_pattern?(expression.index, &predicate)
186
- when AST::Specialization
187
- expression_uses_pattern?(expression.callee, &predicate) || expression.arguments.any? { |argument| expression_uses_pattern?(argument.value, &predicate) }
188
- else
189
- false
148
+ def fatal_expression?(expression)
149
+ expression.is_a?(AST::Call) && expression.callee.is_a?(AST::Identifier) && expression.callee.name == "fatal"
190
150
  end
191
- end
192
151
 
193
- def prepare_analysis(analysis, path: nil)
194
- @ctx.install(analysis)
195
- @ctx.current_analysis_path = path
196
- @ctx.module_prefix = module_c_prefix(@ctx.module_name)
197
- end
152
+ def offsetof_expression?(expression)
153
+ expression.is_a?(AST::OffsetofExpr)
154
+ end
198
155
 
199
- def sanitize_type_name_for_tuple(type)
200
- type.to_s.gsub(/[^a-zA-Z0-9]/, "_").gsub(/_+/, "_").gsub(/^_|_$/, "")
201
- end
156
+ def expression_uses_pattern?(expression, &predicate)
157
+ return false unless expression
158
+ return true if predicate.call(expression)
159
+
160
+ case expression
161
+ when AST::AwaitExpr
162
+ expression_uses_pattern?(expression.expression, &predicate)
163
+ when AST::Call
164
+ expression_uses_pattern?(expression.callee, &predicate) || expression.arguments.any? { |argument| expression_uses_pattern?(argument.value, &predicate) }
165
+ when AST::BinaryOp
166
+ expression_uses_pattern?(expression.left, &predicate) || expression_uses_pattern?(expression.right, &predicate)
167
+ when AST::RangeExpr
168
+ expression_uses_pattern?(expression.start_expr, &predicate) || expression_uses_pattern?(expression.end_expr, &predicate)
169
+ when AST::IfExpr
170
+ expression_uses_pattern?(expression.condition, &predicate) || expression_uses_pattern?(expression.then_expression, &predicate) || expression_uses_pattern?(expression.else_expression, &predicate)
171
+ when AST::MatchExpr
172
+ expression_uses_pattern?(expression.expression, &predicate) || expression.arms.any? { |arm| expression_uses_pattern?(arm.pattern, &predicate) || expression_uses_pattern?(arm.value, &predicate) }
173
+ when AST::UnsafeExpr
174
+ expression_uses_pattern?(expression.expression, &predicate)
175
+ when AST::PrefixCast
176
+ expression_uses_pattern?(expression.expression, &predicate)
177
+ when AST::UnaryOp
178
+ expression_uses_pattern?(expression.operand, &predicate)
179
+ when AST::MemberAccess
180
+ expression_uses_pattern?(expression.receiver, &predicate)
181
+ when AST::IndexAccess
182
+ expression_uses_pattern?(expression.receiver, &predicate) || expression_uses_pattern?(expression.index, &predicate)
183
+ when AST::Specialization
184
+ expression_uses_pattern?(expression.callee, &predicate) || expression.arguments.any? { |argument| expression_uses_pattern?(argument.value, &predicate) }
185
+ else
186
+ false
187
+ end
188
+ end
189
+
190
+ def prepare_analysis(analysis, path: nil)
191
+ @ctx.install(analysis)
192
+ @ctx.current_analysis_path = path
193
+ @ctx.module_prefix = module_c_prefix(@ctx.module_name)
194
+ end
202
195
 
203
- def build_method_definitions
204
- @program.analyses_by_path.values.each_with_object({}) do |analysis, definitions|
205
- analysis.ast.declarations.grep(AST::ExtendingBlock).each do |extending_block|
206
- receiver_type = resolve_extending_receiver_type(analysis, extending_block.type_name)
207
- extending_block.methods.each do |method|
208
- method_key = method.kind == :static ? "static:#{method.name}" : method.name
209
- definitions[[receiver_type, method_key]] = [analysis, method]
196
+ def build_method_definitions
197
+ @program.analyses_by_path.values.each_with_object({}) do |analysis, definitions|
198
+ analysis.ast.declarations.grep(AST::ExtendingBlock).each do |extending_block|
199
+ receiver_type = resolve_extending_receiver_type(analysis, extending_block.type_name)
200
+ extending_block.methods.each do |method|
201
+ method_key = method.kind == :static ? "static:#{method.name}" : method.name
202
+ definitions[[receiver_type, method_key]] = [analysis, method]
203
+ end
210
204
  end
211
205
  end
212
206
  end
@@ -1,122 +1,124 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MilkTea
4
- module LowererStrBuffer
5
- def str_buffer_method_kind(receiver_type, name)
6
- return unless str_buffer_type?(receiver_type)
4
+ module Lowering
5
+ module StrBuffer
6
+ def str_buffer_method_kind(receiver_type, name)
7
+ return unless str_buffer_type?(receiver_type)
7
8
 
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
9
+ case name
10
+ when "clear"
11
+ :str_buffer_clear
12
+ when "assign"
13
+ :str_buffer_assign
14
+ when "append"
15
+ :str_buffer_append
16
+ when "assign_format"
17
+ :str_buffer_assign_format
18
+ when "append_format"
19
+ :str_buffer_append_format
20
+ when "len"
21
+ :str_buffer_len
22
+ when "capacity"
23
+ :str_buffer_capacity
24
+ when "as_str"
25
+ :str_buffer_as_str
26
+ when "as_cstr"
27
+ :str_buffer_as_cstr
28
+ end
27
29
  end
28
- end
29
30
 
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
31
+ def str_buffer_method_type(kind, receiver_type)
32
+ return_type, params = case kind
33
+ when :str_buffer_clear
34
+ [@ctx.types.fetch("void"), []]
35
+ when :str_buffer_assign, :str_buffer_append, :str_buffer_assign_format, :str_buffer_append_format
36
+ [@ctx.types.fetch("void"), [Types::Registry.parameter("value", @ctx.types.fetch("str"))]]
37
+ when :str_buffer_len, :str_buffer_capacity
38
+ [@ctx.types.fetch("ptr_uint"), []]
39
+ when :str_buffer_as_str
40
+ [@ctx.types.fetch("str"), []]
41
+ when :str_buffer_as_cstr
42
+ [@ctx.types.fetch("cstr"), []]
43
+ else
44
+ raise LoweringError.new("unsupported str_buffer method #{kind}", line: 0, column: 0, path: @ctx.current_analysis_path)
45
+ end
45
46
 
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
47
+ Types::Registry.function(
48
+ kind.to_s,
49
+ params:,
50
+ return_type:,
51
+ receiver_type:,
52
+ receiver_editable: %i[str_buffer_clear str_buffer_assign str_buffer_append str_buffer_assign_format str_buffer_append_format].include?(kind),
53
+ external: false,
54
+ )
55
+ end
55
56
 
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
57
+ def lower_char_array_data_pointer(expression, env:)
58
+ lowered_receiver = lower_expression(expression, env:)
59
+ IR::AddressOf.new(
60
+ expression: IR::Index.new(
61
+ receiver: lowered_receiver,
62
+ index: IR::IntegerLiteral.new(value: 0, type: @ctx.types.fetch("ptr_uint")),
63
+ type: @ctx.types.fetch("char"),
64
+ ),
65
+ type: pointer_to(@ctx.types.fetch("char")),
66
+ )
67
+ end
67
68
 
68
- def lower_str_buffer_data_pointer(expression, env:)
69
- lower_str_buffer_data_pointer_from_lowered(lower_expression(expression, env:))
70
- end
69
+ def lower_str_buffer_data_pointer(expression, env:)
70
+ lower_str_buffer_data_pointer_from_lowered(lower_expression(expression, env:))
71
+ end
71
72
 
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))],
73
+ def lower_str_buffer_data_pointer_from_lowered(lowered_receiver)
74
+ IR::AddressOf.new(
75
+ expression: IR::Index.new(
76
+ receiver: IR::Member.new(
77
+ receiver: lowered_receiver,
78
+ member: "data",
79
+ type: Types::Registry.generic_instance(
80
+ "array",
81
+ [@ctx.types.fetch("char"), Types::LiteralTypeArg.new(str_buffer_storage_capacity(lowered_receiver.type))],
82
+ ),
81
83
  ),
84
+ index: IR::IntegerLiteral.new(value: 0, type: @ctx.types.fetch("ptr_uint")),
85
+ type: @ctx.types.fetch("char"),
82
86
  ),
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
87
+ type: pointer_to(@ctx.types.fetch("char")),
88
+ )
89
+ end
89
90
 
90
- def lower_str_buffer_len_pointer(expression, env:)
91
- lower_str_buffer_len_pointer_from_lowered(lower_expression(expression, env:))
92
- end
91
+ def lower_str_buffer_len_pointer(expression, env:)
92
+ lower_str_buffer_len_pointer_from_lowered(lower_expression(expression, env:))
93
+ end
93
94
 
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
95
+ def lower_str_buffer_len_pointer_from_lowered(lowered_receiver)
96
+ IR::AddressOf.new(
97
+ expression: IR::Member.new(receiver: lowered_receiver, member: "len", type: @ctx.types.fetch("ptr_uint")),
98
+ type: pointer_to(@ctx.types.fetch("ptr_uint")),
99
+ )
100
+ end
100
101
 
101
- def lower_str_buffer_dirty_pointer(expression, env:)
102
- lower_str_buffer_dirty_pointer_from_lowered(lower_expression(expression, env:))
103
- end
102
+ def lower_str_buffer_dirty_pointer(expression, env:)
103
+ lower_str_buffer_dirty_pointer_from_lowered(lower_expression(expression, env:))
104
+ end
104
105
 
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
106
+ def lower_str_buffer_dirty_pointer_from_lowered(lowered_receiver)
107
+ IR::AddressOf.new(
108
+ expression: IR::Member.new(receiver: lowered_receiver, member: "dirty", type: @ctx.types.fetch("bool")),
109
+ type: pointer_to(@ctx.types.fetch("bool")),
110
+ )
111
+ end
111
112
 
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
- ]
113
+ def str_buffer_args(receiver, env:)
114
+ receiver_type = infer_expression_type(receiver, env:)
115
+ [
116
+ lower_str_buffer_data_pointer(receiver, env:),
117
+ IR::IntegerLiteral.new(value: str_buffer_capacity(receiver_type), type: @ctx.types.fetch("ptr_uint")),
118
+ lower_str_buffer_len_pointer(receiver, env:),
119
+ lower_str_buffer_dirty_pointer(receiver, env:),
120
+ ]
121
+ end
120
122
  end
121
123
  end
122
124
  end