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.
- checksums.yaml +4 -4
- data/lib/milk_tea/base.rb +1 -1
- data/lib/milk_tea/core/bindings/attribute_binding.rb +51 -49
- data/lib/milk_tea/core/bindings/function_binding.rb +3 -1
- data/lib/milk_tea/core/bindings/module_binding.rb +42 -40
- data/lib/milk_tea/core/bindings/value_binding.rb +16 -14
- data/lib/milk_tea/core/bindings.rb +4 -9
- data/lib/milk_tea/core/c_backend/control_flow_emission.rb +11 -11
- data/lib/milk_tea/core/c_backend/expressions.rb +11 -11
- data/lib/milk_tea/core/c_backend/feature_detection.rb +15 -19
- data/lib/milk_tea/core/c_backend/format_helpers.rb +1 -1
- data/lib/milk_tea/core/c_backend/reinterpret.rb +10 -10
- data/lib/milk_tea/core/c_backend/runtime_helpers.rb +1 -1
- data/lib/milk_tea/core/c_backend/statements.rb +20 -20
- data/lib/milk_tea/core/c_backend/type_declaration.rb +4 -4
- data/lib/milk_tea/core/c_backend/type_system.rb +1 -1
- data/lib/milk_tea/core/c_backend.rb +3 -3
- data/lib/milk_tea/core/compile_time.rb +41 -70
- data/lib/milk_tea/core/control_flow/builder.rb +3 -3
- data/lib/milk_tea/core/control_flow/constant_propagation.rb +1 -1
- data/lib/milk_tea/core/control_flow/graph.rb +1 -1
- data/lib/milk_tea/core/control_flow/termination.rb +1 -1
- data/lib/milk_tea/core/cst.rb +16 -0
- data/lib/milk_tea/core/flow_scope.rb +13 -0
- data/lib/milk_tea/core/lexer/character_classes.rb +2 -2
- data/lib/milk_tea/core/lexer/format_strings.rb +5 -5
- data/lib/milk_tea/core/lexer/heredocs.rb +6 -6
- data/lib/milk_tea/core/lexer/indentation.rb +4 -4
- data/lib/milk_tea/core/lexer/numbers.rb +1 -1
- data/lib/milk_tea/core/lexer/strings.rb +4 -4
- data/lib/milk_tea/core/lexer/symbols.rb +3 -3
- data/lib/milk_tea/core/lexer/trivia.rb +4 -4
- data/lib/milk_tea/core/lexer.rb +17 -17
- data/lib/milk_tea/core/lowering/async/analysis.rb +210 -208
- data/lib/milk_tea/core/lowering/async/async_lowering.rb +1406 -0
- data/lib/milk_tea/core/lowering/async/frame_builder.rb +615 -613
- data/lib/milk_tea/core/lowering/async/normalization.rb +410 -408
- data/lib/milk_tea/core/lowering/block.rb +982 -980
- data/lib/milk_tea/core/lowering/calls.rb +1360 -1358
- data/lib/milk_tea/core/lowering/declarations.rb +175 -173
- data/lib/milk_tea/core/lowering/dyn.rb +171 -169
- data/lib/milk_tea/core/lowering/events.rb +946 -944
- data/lib/milk_tea/core/lowering/expressions.rb +1514 -1512
- data/lib/milk_tea/core/lowering/foreign_cstr.rb +180 -178
- data/lib/milk_tea/core/lowering/functions.rb +186 -184
- data/lib/milk_tea/core/lowering/loops.rb +1004 -1002
- data/lib/milk_tea/core/lowering/lowering_context.rb +1 -1
- data/lib/milk_tea/core/lowering/proc.rb +355 -353
- data/lib/milk_tea/core/lowering/resolve.rb +2127 -2125
- data/lib/milk_tea/core/lowering/scans.rb +162 -168
- data/lib/milk_tea/core/lowering/str_buffer.rb +104 -102
- data/lib/milk_tea/core/lowering/utils.rb +964 -963
- data/lib/milk_tea/core/lowering.rb +22 -22
- data/lib/milk_tea/core/module_binder.rb +1 -1
- data/lib/milk_tea/core/module_loader.rb +2 -2
- data/lib/milk_tea/core/parser/attributes.rb +1 -1
- data/lib/milk_tea/core/parser/blocks.rb +2 -2
- data/lib/milk_tea/core/parser/declarations.rb +15 -15
- data/lib/milk_tea/core/parser/expressions.rb +20 -20
- data/lib/milk_tea/core/parser/recovery.rb +1 -1
- data/lib/milk_tea/core/parser/statements.rb +3 -3
- data/lib/milk_tea/core/parser/types.rb +4 -4
- data/lib/milk_tea/core/parser.rb +39 -21
- data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +6 -6
- data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +5 -5
- data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +2 -2
- data/lib/milk_tea/core/semantic_analyzer/calls.rb +1 -1
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +4 -4
- data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +37 -37
- data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +4 -4
- data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +4 -4
- data/lib/milk_tea/core/semantic_analyzer/generics.rb +4 -4
- data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +7 -7
- data/lib/milk_tea/core/semantic_analyzer/nullability.rb +59 -59
- data/lib/milk_tea/core/semantic_analyzer/statements.rb +3 -3
- data/lib/milk_tea/core/semantic_analyzer/top_level.rb +1 -1
- data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +12 -12
- data/lib/milk_tea/core/types/layout.rb +3 -1
- data/lib/milk_tea/core/types/visitor.rb +351 -349
- data/lib/milk_tea/core.rb +0 -2
- data/lib/milk_tea/tooling/cli/commands/bindgen.rb +1 -1
- data/lib/milk_tea/tooling/cli/commands/check.rb +5 -5
- data/lib/milk_tea/tooling/cli/commands/debug.rb +3 -3
- data/lib/milk_tea/tooling/cli/commands/deps.rb +1 -1
- data/lib/milk_tea/tooling/cli/commands/emit_c.rb +2 -2
- data/lib/milk_tea/tooling/cli/commands/format.rb +6 -6
- data/lib/milk_tea/tooling/cli/commands/lint.rb +3 -3
- data/lib/milk_tea/tooling/cli/commands/lower.rb +3 -3
- data/lib/milk_tea/tooling/cli/commands/parse.rb +3 -3
- data/lib/milk_tea/tooling/cli/commands/test.rb +3 -3
- data/lib/milk_tea/tooling/cli/commands/toolchain.rb +1 -1
- data/lib/milk_tea/tooling/cli.rb +22 -34
- data/lib/milk_tea/tooling/linter/flow_rules.rb +3 -3
- metadata +4 -5
- data/lib/milk_tea/core/cst_builder.rb +0 -19
- data/lib/milk_tea/core/lowering/async/lowering.rb +0 -1404
- data/lib/milk_tea/core/token_stream.rb +0 -30
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 95066d5ccb69388c431a7b4b963853211c3ef57d8e776de1f8468ecdc983899b
|
|
4
|
+
data.tar.gz: 83a55caa84c9d54eda5b104727ce0ee4615b4780270d14d0cea4d2001b2fe9fd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a6e8f3cf4ed18ec8cd2bdbfbb8ee458f7662546619f31c55bb00123d22bb9150888e405a692cbeea9c67b10bad2e3c82c621efae9992223e1d0c9bd51281f0a2
|
|
7
|
+
data.tar.gz: 7cb61c0021e8864897a5b23077dadf54586bf11b11a546ec9b19cbb59083dce4c60d7c8bd996c39380d1a80ea266a364008a1a3f2e3fba7f362ad57c2d97c1d0
|
data/lib/milk_tea/base.rb
CHANGED
|
@@ -1,56 +1,58 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module MilkTea
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
module Bindings
|
|
5
|
+
AttributeBinding = Data.define(:name, :targets, :params, :module_name, :builtin, :ast)
|
|
6
|
+
BUILTIN_ATTRIBUTE_NAMES = %w[packed align deprecated test expect_fatal].freeze
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
8
|
+
def self.builtin_attribute_binding(name, types)
|
|
9
|
+
case name
|
|
10
|
+
when "packed"
|
|
11
|
+
AttributeBinding.new(
|
|
12
|
+
name: "packed",
|
|
13
|
+
targets: [:struct].freeze,
|
|
14
|
+
params: [].freeze,
|
|
15
|
+
module_name: nil,
|
|
16
|
+
builtin: true,
|
|
17
|
+
ast: nil,
|
|
18
|
+
)
|
|
19
|
+
when "align"
|
|
20
|
+
AttributeBinding.new(
|
|
21
|
+
name: "align",
|
|
22
|
+
targets: [:struct].freeze,
|
|
23
|
+
params: [Types::Registry.parameter("bytes", types.fetch("ptr_uint"))].freeze,
|
|
24
|
+
module_name: nil,
|
|
25
|
+
builtin: true,
|
|
26
|
+
ast: nil,
|
|
27
|
+
)
|
|
28
|
+
when "deprecated"
|
|
29
|
+
AttributeBinding.new(
|
|
30
|
+
name: "deprecated",
|
|
31
|
+
targets: %i[callable struct const enum flags union variant event].freeze,
|
|
32
|
+
params: [Types::Registry.parameter("message", types.fetch("str"))].freeze,
|
|
33
|
+
module_name: nil,
|
|
34
|
+
builtin: true,
|
|
35
|
+
ast: nil,
|
|
36
|
+
)
|
|
37
|
+
when "test"
|
|
38
|
+
AttributeBinding.new(
|
|
39
|
+
name: "test",
|
|
40
|
+
targets: [:callable].freeze,
|
|
41
|
+
params: [].freeze,
|
|
42
|
+
module_name: nil,
|
|
43
|
+
builtin: true,
|
|
44
|
+
ast: nil,
|
|
45
|
+
)
|
|
46
|
+
when "expect_fatal"
|
|
47
|
+
AttributeBinding.new(
|
|
48
|
+
name: "expect_fatal",
|
|
49
|
+
targets: [:callable].freeze,
|
|
50
|
+
params: [].freeze,
|
|
51
|
+
module_name: nil,
|
|
52
|
+
builtin: true,
|
|
53
|
+
ast: nil,
|
|
54
|
+
)
|
|
55
|
+
end
|
|
54
56
|
end
|
|
55
57
|
end
|
|
56
58
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module MilkTea
|
|
4
|
-
|
|
4
|
+
module Bindings
|
|
5
|
+
FunctionBinding = Data.define(:name, :type, :body_params, :body_return_type, :ast, :external, :async, :type_params, :type_param_constraints, :instances, :type_arguments, :owner, :specialization_owner, :type_substitutions, :declared_receiver_type)
|
|
6
|
+
end
|
|
5
7
|
end
|
|
@@ -1,58 +1,60 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module MilkTea
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def private_interface?(name)
|
|
10
|
-
private_interfaces.key?(name)
|
|
11
|
-
end
|
|
4
|
+
module Bindings
|
|
5
|
+
ModuleBinding = Data.define(:name, :types, :type_declarations, :interfaces, :attributes, :attribute_applications, :values, :functions, :methods, :implemented_interfaces, :imports, :private_types, :private_interfaces, :private_attributes, :private_values, :private_functions, :private_methods, :private_implemented_interfaces) do
|
|
6
|
+
def private_type?(name)
|
|
7
|
+
private_types.key?(name)
|
|
8
|
+
end
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
def private_interface?(name)
|
|
11
|
+
private_interfaces.key?(name)
|
|
12
|
+
end
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
def private_attribute?(name)
|
|
15
|
+
private_attributes.key?(name)
|
|
16
|
+
end
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
def private_value?(name)
|
|
19
|
+
private_values.key?(name)
|
|
20
|
+
end
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if receiver_type.is_a?(Types::GenericInstance)
|
|
29
|
-
dispatch_receiver_type = Types::Registry.generic_instance(
|
|
30
|
-
receiver_type.name,
|
|
31
|
-
receiver_type.arguments.each_with_index.map do |argument, index|
|
|
32
|
-
argument.is_a?(Types::LiteralTypeArg) ? argument : Types::TypeVar.new("__receiver_arg#{index}")
|
|
33
|
-
end,
|
|
34
|
-
)
|
|
35
|
-
return true if dispatch_receiver_type != receiver_type && private_methods.fetch(dispatch_receiver_type, {}).key?(name)
|
|
22
|
+
def private_function?(name)
|
|
23
|
+
private_functions.key?(name)
|
|
36
24
|
end
|
|
37
25
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
dispatch_base_type.arguments.each_with_index.map do |argument, index|
|
|
26
|
+
def private_method?(receiver_type, name)
|
|
27
|
+
return true if private_methods.fetch(receiver_type, {}).key?(name)
|
|
28
|
+
|
|
29
|
+
if receiver_type.is_a?(Types::GenericInstance)
|
|
30
|
+
dispatch_receiver_type = Types::Registry.generic_instance(
|
|
31
|
+
receiver_type.name,
|
|
32
|
+
receiver_type.arguments.each_with_index.map do |argument, index|
|
|
46
33
|
argument.is_a?(Types::LiteralTypeArg) ? argument : Types::TypeVar.new("__receiver_arg#{index}")
|
|
47
34
|
end,
|
|
48
35
|
)
|
|
36
|
+
return true if dispatch_receiver_type != receiver_type && private_methods.fetch(dispatch_receiver_type, {}).key?(name)
|
|
49
37
|
end
|
|
50
38
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
if receiver_type.is_a?(Types::Nullable)
|
|
40
|
+
dispatch_base_type = receiver_type.base
|
|
41
|
+
if dispatch_base_type.is_a?(Types::StructInstance)
|
|
42
|
+
dispatch_base_type = dispatch_base_type.definition
|
|
43
|
+
elsif dispatch_base_type.is_a?(Types::GenericInstance)
|
|
44
|
+
dispatch_base_type = Types::Registry.generic_instance(
|
|
45
|
+
dispatch_base_type.name,
|
|
46
|
+
dispatch_base_type.arguments.each_with_index.map do |argument, index|
|
|
47
|
+
argument.is_a?(Types::LiteralTypeArg) ? argument : Types::TypeVar.new("__receiver_arg#{index}")
|
|
48
|
+
end,
|
|
49
|
+
)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
dispatch_receiver_type = Types::Registry.nullable(dispatch_base_type)
|
|
53
|
+
return true if dispatch_receiver_type != receiver_type && private_methods.fetch(dispatch_receiver_type, {}).key?(name)
|
|
54
|
+
end
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
receiver_type.is_a?(Types::StructInstance) && private_methods.fetch(receiver_type.definition, {}).key?(name)
|
|
57
|
+
end
|
|
56
58
|
end
|
|
57
59
|
end
|
|
58
60
|
end
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module MilkTea
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
module Bindings
|
|
5
|
+
ValueBinding = Data.define(:id, :name, :storage_type, :flow_type, :mutable, :kind, :const_value) do
|
|
6
|
+
def type
|
|
7
|
+
flow_type || storage_type
|
|
8
|
+
end
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
def with_flow_type(refined_type)
|
|
11
|
+
ValueBinding.new(
|
|
12
|
+
id:,
|
|
13
|
+
name:,
|
|
14
|
+
storage_type:,
|
|
15
|
+
flow_type: refined_type == storage_type ? nil : refined_type,
|
|
16
|
+
mutable:,
|
|
17
|
+
kind:,
|
|
18
|
+
const_value:,
|
|
19
|
+
)
|
|
20
|
+
end
|
|
19
21
|
end
|
|
20
22
|
end
|
|
21
23
|
end
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "flow_scope"
|
|
4
|
+
|
|
3
5
|
require_relative "bindings/value_binding"
|
|
4
6
|
require_relative "bindings/function_binding"
|
|
5
7
|
require_relative "bindings/module_binding"
|
|
6
8
|
require_relative "bindings/attribute_binding"
|
|
7
9
|
|
|
8
10
|
module MilkTea
|
|
9
|
-
|
|
10
|
-
def initialize = (@bindings = {})
|
|
11
|
-
def [](key) = @bindings[key]
|
|
12
|
-
def []=(key, val); @bindings[key] = val; end
|
|
13
|
-
def key?(key) = @bindings.key?(key)
|
|
14
|
-
def empty? = @bindings.empty?
|
|
15
|
-
def each(&block) = @bindings.each(&block)
|
|
16
|
-
def each_with_object(init, &block) = @bindings.each_with_object(init, &block)
|
|
11
|
+
module Bindings
|
|
17
12
|
end
|
|
18
|
-
end
|
|
13
|
+
end
|
|
@@ -52,26 +52,26 @@ module MilkTea
|
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
def
|
|
55
|
+
def block_requires_break_label?(statements, label_name, loop_break_label_active:)
|
|
56
56
|
statements.any? do |statement|
|
|
57
|
-
|
|
57
|
+
statement_requires_break_label?(statement, label_name, loop_break_label_active:)
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
def
|
|
61
|
+
def statement_requires_break_label?(statement, label_name, loop_break_label_active:)
|
|
62
62
|
case statement
|
|
63
63
|
when IR::BlockStmt, IR::IfStmt
|
|
64
64
|
then_body = statement.is_a?(IR::IfStmt) ? statement.then_body : statement.body
|
|
65
65
|
else_body = statement.is_a?(IR::IfStmt) ? statement.else_body : nil
|
|
66
|
-
|
|
67
|
-
(else_body &&
|
|
66
|
+
block_requires_break_label?(then_body, label_name, loop_break_label_active:) ||
|
|
67
|
+
(else_body && block_requires_break_label?(else_body, label_name, loop_break_label_active:))
|
|
68
68
|
when IR::WhileStmt, IR::ForStmt
|
|
69
|
-
|
|
69
|
+
block_requires_break_label?(statement.body, label_name, loop_break_label_active: false)
|
|
70
70
|
when IR::SwitchStmt
|
|
71
71
|
return false unless statement_references_label?(statement, label_name)
|
|
72
72
|
|
|
73
|
-
active = loop_break_label_active &&
|
|
74
|
-
|
|
73
|
+
active = loop_break_label_active && can_emit_switch_as_if?(statement, loop_break_label: label_name)
|
|
74
|
+
block_requires_break_label?(
|
|
75
75
|
statement.cases.flat_map(&:body),
|
|
76
76
|
label_name,
|
|
77
77
|
loop_break_label_active: active,
|
|
@@ -83,7 +83,7 @@ module MilkTea
|
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
-
def
|
|
86
|
+
def can_emit_switch_as_if?(statement, loop_break_label: nil)
|
|
87
87
|
return false unless loop_break_label
|
|
88
88
|
return false unless statement.exhaustive
|
|
89
89
|
return false unless statement.cases.length == 2
|
|
@@ -183,7 +183,7 @@ module MilkTea
|
|
|
183
183
|
lines = ["#{indent}if (#{emit_expression(statement.condition)}) {"]
|
|
184
184
|
lines.concat(emit_statement_sequence(statement.then_body, level + 1, function:, used_labels:, loop_continue_label:, loop_break_label:))
|
|
185
185
|
|
|
186
|
-
nested_else_if =
|
|
186
|
+
nested_else_if = extract_nested_else_if(statement.else_body)
|
|
187
187
|
if nested_else_if
|
|
188
188
|
nested_lines = emit_if_statement(nested_else_if, level, function:, used_labels:, loop_continue_label:, loop_break_label:)
|
|
189
189
|
lines << "#{indent}} else #{nested_lines.first.sub(/^#{Regexp.escape(indent)}/, "") }"
|
|
@@ -199,7 +199,7 @@ module MilkTea
|
|
|
199
199
|
lines
|
|
200
200
|
end
|
|
201
201
|
|
|
202
|
-
def
|
|
202
|
+
def extract_nested_else_if(else_body)
|
|
203
203
|
return unless else_body && else_body.length == 1
|
|
204
204
|
|
|
205
205
|
nested = else_body.first
|
|
@@ -45,7 +45,7 @@ module MilkTea
|
|
|
45
45
|
"#{expression.operator}#{wrap_expression(expression.operand)}"
|
|
46
46
|
end
|
|
47
47
|
when IR::Binary
|
|
48
|
-
return
|
|
48
|
+
return emit_string_equality_expression(expression) if string_equality_expression?(expression)
|
|
49
49
|
return emit_variant_equality_expression(expression) if variant_equality_expression?(expression)
|
|
50
50
|
return emit_nullable_null_comparison(expression) if nullable_null_comparison?(expression)
|
|
51
51
|
|
|
@@ -53,7 +53,7 @@ module MilkTea
|
|
|
53
53
|
when IR::Conditional
|
|
54
54
|
emit_conditional_expression(expression)
|
|
55
55
|
when IR::ReinterpretExpr
|
|
56
|
-
if
|
|
56
|
+
if identity_reinterpret?(expression.target_type, expression.source_type)
|
|
57
57
|
emit_expression(expression.expression)
|
|
58
58
|
else
|
|
59
59
|
"#{reinterpret_helper_name(expression.target_type, expression.source_type)}(#{emit_expression(expression.expression)})"
|
|
@@ -88,7 +88,7 @@ module MilkTea
|
|
|
88
88
|
emit_address_of_operand(expression.expression)
|
|
89
89
|
end
|
|
90
90
|
when IR::Cast
|
|
91
|
-
if
|
|
91
|
+
if identity_cast?(expression)
|
|
92
92
|
emit_expression(expression.expression)
|
|
93
93
|
else
|
|
94
94
|
"(#{c_type(expression.target_type)}) #{emit_cast_operand(expression.expression)}"
|
|
@@ -106,7 +106,7 @@ module MilkTea
|
|
|
106
106
|
end
|
|
107
107
|
end
|
|
108
108
|
|
|
109
|
-
def
|
|
109
|
+
def string_equality_expression?(expression)
|
|
110
110
|
EQUALITY_OPERATORS.include?(expression.operator) && expression.left.type.is_a?(Types::StringView) && expression.right.type.is_a?(Types::StringView)
|
|
111
111
|
end
|
|
112
112
|
|
|
@@ -164,7 +164,7 @@ module MilkTea
|
|
|
164
164
|
end
|
|
165
165
|
end
|
|
166
166
|
|
|
167
|
-
def
|
|
167
|
+
def emit_string_equality_expression(expression)
|
|
168
168
|
call = "mt_str_equal(#{emit_expression(expression.left)}, #{emit_expression(expression.right)})"
|
|
169
169
|
expression.operator == "!=" ? "!#{call}" : call
|
|
170
170
|
end
|
|
@@ -278,7 +278,7 @@ module MilkTea
|
|
|
278
278
|
return call unless omit_receiver && expression.arguments.any?
|
|
279
279
|
return call if side_effect_free_expression?(expression.arguments.first)
|
|
280
280
|
|
|
281
|
-
"(#{
|
|
281
|
+
"(#{emit_void_expression(expression.arguments.first)}, #{call})"
|
|
282
282
|
end
|
|
283
283
|
|
|
284
284
|
def emit_array_call_statement(expression, out_argument, indent)
|
|
@@ -300,7 +300,7 @@ module MilkTea
|
|
|
300
300
|
]
|
|
301
301
|
end
|
|
302
302
|
|
|
303
|
-
def
|
|
303
|
+
def call_emission_params(function)
|
|
304
304
|
omitted_method_receiver_function?(function) ? function.params.drop(1) : function.params
|
|
305
305
|
end
|
|
306
306
|
|
|
@@ -320,7 +320,7 @@ module MilkTea
|
|
|
320
320
|
name_reference_count_in_statements(function.body, function.params.first.linkage_name).zero?
|
|
321
321
|
end
|
|
322
322
|
|
|
323
|
-
def
|
|
323
|
+
def emit_void_expression(expression)
|
|
324
324
|
"(void)#{wrap_expression(expression)}"
|
|
325
325
|
end
|
|
326
326
|
|
|
@@ -411,7 +411,7 @@ module MilkTea
|
|
|
411
411
|
field_type = aggregate_field_type(type, field.name)
|
|
412
412
|
if field_type.is_a?(Types::Nullable) && !field.value.type.is_a?(Types::Nullable) && !c_backend_pointer_like_type?(field_type.base)
|
|
413
413
|
emit_nullable_some_initializer(field_type, field.value)
|
|
414
|
-
elsif
|
|
414
|
+
elsif void_typed_field?(field_type)
|
|
415
415
|
emit_void_field_initializer(field.value)
|
|
416
416
|
else
|
|
417
417
|
emit_initializer(field.value)
|
|
@@ -434,7 +434,7 @@ module MilkTea
|
|
|
434
434
|
emit_cyclic_array_initializer(field_type, field.value)
|
|
435
435
|
elsif aggregate_field_creates_cycle?(field_type, outer_c) && !field_type.is_a?(Types::GenericInstance)
|
|
436
436
|
emit_cyclic_struct_initializer(field_type, field.value)
|
|
437
|
-
elsif
|
|
437
|
+
elsif void_typed_field?(field_type)
|
|
438
438
|
emit_void_field_initializer(field.value)
|
|
439
439
|
else
|
|
440
440
|
emit_initializer(field.value)
|
|
@@ -469,7 +469,7 @@ module MilkTea
|
|
|
469
469
|
"(#{emit_expression(expression)}, 0)"
|
|
470
470
|
end
|
|
471
471
|
|
|
472
|
-
def
|
|
472
|
+
def void_typed_field?(type)
|
|
473
473
|
type.is_a?(Types::Primitive) && type.void?
|
|
474
474
|
end
|
|
475
475
|
|
|
@@ -152,10 +152,6 @@ module MilkTea
|
|
|
152
152
|
emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_entry_argv_to_span_str mt_free_entry_argv_strs]) }
|
|
153
153
|
end
|
|
154
154
|
|
|
155
|
-
def uses_text_buffer_helpers?
|
|
156
|
-
uses_str_buffer_helpers?
|
|
157
|
-
end
|
|
158
|
-
|
|
159
155
|
def uses_str_buffer_helpers?
|
|
160
156
|
emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_str_buffer_len mt_str_buffer_as_cstr mt_str_buffer_clear mt_str_buffer_assign mt_str_buffer_append mt_str_buffer_prepare_write]) }
|
|
161
157
|
end
|
|
@@ -229,8 +225,8 @@ module MilkTea
|
|
|
229
225
|
]
|
|
230
226
|
end
|
|
231
227
|
|
|
232
|
-
def
|
|
233
|
-
@
|
|
228
|
+
def required_format_helper_callees
|
|
229
|
+
@required_format_helper_callees ||= begin
|
|
234
230
|
helpers = {}
|
|
235
231
|
|
|
236
232
|
emitted_functions.each do |function|
|
|
@@ -286,7 +282,7 @@ module MilkTea
|
|
|
286
282
|
}.freeze
|
|
287
283
|
|
|
288
284
|
def uses_format_helpers?
|
|
289
|
-
!
|
|
285
|
+
!required_format_helper_callees.empty?
|
|
290
286
|
end
|
|
291
287
|
|
|
292
288
|
def uses_str_equality_helper?
|
|
@@ -342,29 +338,29 @@ module MilkTea
|
|
|
342
338
|
function.body.any? { |statement| statement_uses_str_equality?(statement) }
|
|
343
339
|
end
|
|
344
340
|
|
|
345
|
-
def
|
|
341
|
+
def statement_matches_expression_predicate?(statement, expression_pred:, **kwargs)
|
|
346
342
|
case statement
|
|
347
343
|
when IR::LocalDecl
|
|
348
344
|
statement.value && expression_pred.call(statement.value, **kwargs)
|
|
349
345
|
when IR::Assignment
|
|
350
346
|
expression_pred.call(statement.target, **kwargs) || expression_pred.call(statement.value, **kwargs)
|
|
351
347
|
when IR::BlockStmt
|
|
352
|
-
statement.body.any? { |inner|
|
|
348
|
+
statement.body.any? { |inner| statement_matches_expression_predicate?(inner, expression_pred:, **kwargs) }
|
|
353
349
|
when IR::WhileStmt
|
|
354
350
|
expression_pred.call(statement.condition, **kwargs) ||
|
|
355
|
-
statement.body.any? { |inner|
|
|
351
|
+
statement.body.any? { |inner| statement_matches_expression_predicate?(inner, expression_pred:, **kwargs) }
|
|
356
352
|
when IR::ForStmt
|
|
357
|
-
|
|
353
|
+
statement_matches_expression_predicate?(statement.init, expression_pred:, **kwargs) ||
|
|
358
354
|
expression_pred.call(statement.condition, **kwargs) ||
|
|
359
|
-
statement.body.any? { |inner|
|
|
360
|
-
|
|
355
|
+
statement.body.any? { |inner| statement_matches_expression_predicate?(inner, expression_pred:, **kwargs) } ||
|
|
356
|
+
statement_matches_expression_predicate?(statement.post, expression_pred:, **kwargs)
|
|
361
357
|
when IR::IfStmt
|
|
362
358
|
expression_pred.call(statement.condition, **kwargs) ||
|
|
363
|
-
statement.then_body.any? { |inner|
|
|
364
|
-
(statement.else_body && statement.else_body.any? { |inner|
|
|
359
|
+
statement.then_body.any? { |inner| statement_matches_expression_predicate?(inner, expression_pred:, **kwargs) } ||
|
|
360
|
+
(statement.else_body && statement.else_body.any? { |inner| statement_matches_expression_predicate?(inner, expression_pred:, **kwargs) })
|
|
365
361
|
when IR::SwitchStmt
|
|
366
362
|
expression_pred.call(statement.expression, **kwargs) ||
|
|
367
|
-
statement.cases.any? { |switch_case| switch_case.body.any? { |inner|
|
|
363
|
+
statement.cases.any? { |switch_case| switch_case.body.any? { |inner| statement_matches_expression_predicate?(inner, expression_pred:, **kwargs) } }
|
|
368
364
|
when IR::StaticAssert
|
|
369
365
|
expression_pred.call(statement.condition, **kwargs) || expression_pred.call(statement.message, **kwargs)
|
|
370
366
|
when IR::ReturnStmt
|
|
@@ -377,11 +373,11 @@ module MilkTea
|
|
|
377
373
|
end
|
|
378
374
|
|
|
379
375
|
def statement_uses_named_call?(statement, callees)
|
|
380
|
-
|
|
376
|
+
statement_matches_expression_predicate?(statement, expression_pred: ->(e) { expression_uses_named_call?(e, callees) })
|
|
381
377
|
end
|
|
382
378
|
|
|
383
379
|
def statement_uses_str_equality?(statement)
|
|
384
|
-
|
|
380
|
+
statement_matches_expression_predicate?(statement, expression_pred: ->(e) { expression_uses_str_equality?(e) })
|
|
385
381
|
end
|
|
386
382
|
|
|
387
383
|
def expression_uses_named_call?(expression, callees)
|
|
@@ -416,7 +412,7 @@ module MilkTea
|
|
|
416
412
|
def expression_uses_str_equality?(expression)
|
|
417
413
|
case expression
|
|
418
414
|
when IR::Binary
|
|
419
|
-
|
|
415
|
+
string_equality_expression?(expression) || expression_uses_str_equality?(expression.left) || expression_uses_str_equality?(expression.right)
|
|
420
416
|
when IR::Call
|
|
421
417
|
(!expression.callee.is_a?(String) && expression_uses_str_equality?(expression.callee)) || expression.arguments.any? { |argument| expression_uses_str_equality?(argument) }
|
|
422
418
|
when IR::Member
|
|
@@ -72,7 +72,7 @@ module MilkTea
|
|
|
72
72
|
collect_reinterpret_helpers_from_expression(expression.then_expression, helpers, seen)
|
|
73
73
|
collect_reinterpret_helpers_from_expression(expression.else_expression, helpers, seen)
|
|
74
74
|
when IR::ReinterpretExpr
|
|
75
|
-
return if
|
|
75
|
+
return if identity_reinterpret?(expression.target_type, expression.source_type)
|
|
76
76
|
|
|
77
77
|
key = [expression.target_type, expression.source_type]
|
|
78
78
|
unless seen[key]
|
|
@@ -112,7 +112,7 @@ module MilkTea
|
|
|
112
112
|
"mt_reinterpret_#{sanitize_identifier(target_type.to_s)}_from_#{sanitize_identifier(source_type.to_s)}"
|
|
113
113
|
end
|
|
114
114
|
|
|
115
|
-
def
|
|
115
|
+
def identity_cast?(expression)
|
|
116
116
|
return false if expression.expression.type.is_a?(Types::Null)
|
|
117
117
|
|
|
118
118
|
c_type(expression.target_type) == c_type(expression.expression.type)
|
|
@@ -120,37 +120,37 @@ module MilkTea
|
|
|
120
120
|
false
|
|
121
121
|
end
|
|
122
122
|
|
|
123
|
-
def
|
|
123
|
+
def identity_reinterpret?(target_type, source_type)
|
|
124
124
|
c_type(target_type) == c_type(source_type)
|
|
125
125
|
rescue StandardError
|
|
126
126
|
false
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
def checked_array_index_helper_name(type)
|
|
130
|
-
return "mt_checked_index_array_#{sanitize_identifier(c_declaration(array_element_type(type), 'value'))}_#{array_length(type)}" if array_type?(type) &&
|
|
130
|
+
return "mt_checked_index_array_#{sanitize_identifier(c_declaration(array_element_type(type), 'value'))}_#{array_length(type)}" if array_type?(type) && function_or_proc_element_type?(array_element_type(type))
|
|
131
131
|
|
|
132
132
|
"mt_checked_index_#{sanitize_identifier(type.to_s)}"
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
def checked_span_index_helper_name(type)
|
|
136
|
-
return "mt_checked_span_index_#{sanitize_identifier(c_declaration(type.element_type, 'value'))}" if
|
|
136
|
+
return "mt_checked_span_index_#{sanitize_identifier(c_declaration(type.element_type, 'value'))}" if function_or_proc_element_type?(type.element_type)
|
|
137
137
|
|
|
138
138
|
"mt_checked_span_index_#{sanitize_identifier(type.to_s)}"
|
|
139
139
|
end
|
|
140
140
|
|
|
141
141
|
def nullable_array_index_helper_name(type)
|
|
142
|
-
return "mt_nullable_index_array_#{sanitize_identifier(c_declaration(array_element_type(type), 'value'))}_#{array_length(type)}" if array_type?(type) &&
|
|
142
|
+
return "mt_nullable_index_array_#{sanitize_identifier(c_declaration(array_element_type(type), 'value'))}_#{array_length(type)}" if array_type?(type) && function_or_proc_element_type?(array_element_type(type))
|
|
143
143
|
|
|
144
144
|
"mt_nullable_index_#{sanitize_identifier(type.to_s)}"
|
|
145
145
|
end
|
|
146
146
|
|
|
147
147
|
def nullable_span_index_helper_name(type)
|
|
148
|
-
return "mt_nullable_span_index_#{sanitize_identifier(c_declaration(type.element_type, 'value'))}" if
|
|
148
|
+
return "mt_nullable_span_index_#{sanitize_identifier(c_declaration(type.element_type, 'value'))}" if function_or_proc_element_type?(type.element_type)
|
|
149
149
|
|
|
150
150
|
"mt_nullable_span_index_#{sanitize_identifier(type.to_s)}"
|
|
151
151
|
end
|
|
152
152
|
|
|
153
|
-
def
|
|
153
|
+
def function_or_proc_element_type?(type)
|
|
154
154
|
type.is_a?(Types::Function) || type.is_a?(Types::Proc)
|
|
155
155
|
end
|
|
156
156
|
|
|
@@ -184,7 +184,7 @@ module MilkTea
|
|
|
184
184
|
end
|
|
185
185
|
|
|
186
186
|
(expression.is_a?(IR::Name) && expression.pointer) ||
|
|
187
|
-
(expression.respond_to?(:type) && (raw_pointer_type?(expression.type) || ref_type?(expression.type) ||
|
|
187
|
+
(expression.respond_to?(:type) && (raw_pointer_type?(expression.type) || ref_type?(expression.type) || nullable_pointer_like_type?(expression.type)))
|
|
188
188
|
end
|
|
189
189
|
|
|
190
190
|
def variant_arm_payload_field_type(member_expr)
|
|
@@ -196,7 +196,7 @@ module MilkTea
|
|
|
196
196
|
variant_type.arm(arm_name)&.fetch(member_expr.member)
|
|
197
197
|
end
|
|
198
198
|
|
|
199
|
-
def
|
|
199
|
+
def nullable_pointer_like_type?(type)
|
|
200
200
|
return false unless type.is_a?(Types::Nullable)
|
|
201
201
|
|
|
202
202
|
c_backend_pointer_like_type?(type.base)
|