mt-lang 0.3.17 → 0.3.22
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/c_backend/expressions.rb +34 -23
- data/lib/milk_tea/core/c_backend/feature_detection.rb +25 -45
- data/lib/milk_tea/core/c_backend/type_collectors.rb +18 -30
- data/lib/milk_tea/core/c_backend/type_declaration.rb +0 -6
- data/lib/milk_tea/core/c_backend.rb +49 -39
- data/lib/milk_tea/core/compile_time.rb +98 -72
- data/lib/milk_tea/core/control_flow/builder.rb +2 -1
- data/lib/milk_tea/core/intrinsics.rb +7 -0
- data/lib/milk_tea/core/lexer.rb +46 -35
- data/lib/milk_tea/core/lowering/block.rb +9 -0
- data/lib/milk_tea/core/lowering/calls.rb +2 -0
- data/lib/milk_tea/core/lowering/declarations.rb +1 -1
- data/lib/milk_tea/core/lowering/functions.rb +11 -8
- data/lib/milk_tea/core/lowering/resolve.rb +11 -4
- data/lib/milk_tea/core/lowering/scans.rb +13 -18
- data/lib/milk_tea/core/module_binder.rb +19 -15
- data/lib/milk_tea/core/module_loader.rb +212 -59
- data/lib/milk_tea/core/module_path_resolver.rb +8 -7
- data/lib/milk_tea/core/parser/declarations.rb +43 -19
- data/lib/milk_tea/core/parser/expressions.rb +5 -8
- data/lib/milk_tea/core/parser/statements.rb +5 -5
- data/lib/milk_tea/core/parser.rb +26 -0
- data/lib/milk_tea/core/semantic_analyzer/calls.rb +24 -31
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +20 -23
- data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +146 -92
- data/lib/milk_tea/core/semantic_analyzer/statements.rb +19 -41
- data/lib/milk_tea/core/semantic_analyzer.rb +56 -37
- data/lib/milk_tea/core/types.rb +12 -17
- data/lib/milk_tea/lsp/diagnostics.rb +13 -0
- data/lib/milk_tea/lsp/server/semantic_tokens.rb +6 -0
- data/lib/milk_tea/tooling/cli/commands/bindgen.rb +11 -0
- data/lib/milk_tea/tooling/cli/commands/build.rb +37 -0
- data/lib/milk_tea/tooling/cli/commands/cache.rb +46 -0
- data/lib/milk_tea/tooling/cli/commands/check.rb +106 -0
- data/lib/milk_tea/tooling/cli/commands/command_base.rb +8 -0
- data/lib/milk_tea/tooling/cli/commands/completions.rb +48 -0
- data/lib/milk_tea/tooling/cli/commands/dap.rb +58 -0
- data/lib/milk_tea/tooling/cli/commands/debug.rb +77 -0
- data/lib/milk_tea/tooling/cli/commands/deps.rb +17 -0
- data/lib/milk_tea/tooling/cli/commands/docs.rb +58 -0
- data/lib/milk_tea/tooling/cli/commands/emit_c.rb +64 -0
- data/lib/milk_tea/tooling/cli/commands/format.rb +199 -0
- data/lib/milk_tea/tooling/cli/commands/lex.rb +46 -0
- data/lib/milk_tea/tooling/cli/commands/lint.rb +248 -0
- data/lib/milk_tea/tooling/cli/commands/lower.rb +50 -0
- data/lib/milk_tea/tooling/cli/commands/lsp.rb +43 -0
- data/lib/milk_tea/tooling/cli/commands/new.rb +26 -0
- data/lib/milk_tea/tooling/cli/commands/parse.rb +51 -0
- data/lib/milk_tea/tooling/cli/commands/run.rb +99 -0
- data/lib/milk_tea/tooling/cli/commands/snapshot.rb +117 -0
- data/lib/milk_tea/tooling/cli/commands/test.rb +557 -0
- data/lib/milk_tea/tooling/cli/commands/toolchain.rb +16 -0
- data/lib/milk_tea/tooling/cli.rb +101 -1893
- data/lib/milk_tea/tooling/sexpr_dumper.rb +7 -7
- metadata +24 -2
|
@@ -413,7 +413,8 @@ module MilkTea
|
|
|
413
413
|
read_identifiers(expression.expression, names, reads_info)
|
|
414
414
|
expression.arms.each do |arm|
|
|
415
415
|
read_identifiers(arm.pattern, names, reads_info)
|
|
416
|
-
|
|
416
|
+
arm_value = arm.is_a?(AST::MatchExprArm) ? arm.value : arm.body
|
|
417
|
+
read_identifiers(arm_value, names, reads_info)
|
|
417
418
|
end
|
|
418
419
|
when AST::MatchStmt
|
|
419
420
|
read_identifiers(expression.expression, names, reads_info)
|
|
@@ -45,6 +45,13 @@ module MilkTea
|
|
|
45
45
|
"with" => :simd_lane_with,
|
|
46
46
|
}.freeze
|
|
47
47
|
|
|
48
|
+
SPECIALIZED_RECEIVERS = {
|
|
49
|
+
"str_buffer" => { predicate: :str_buffer_type?, kinds: STR_BUFFER_METHOD_KINDS },
|
|
50
|
+
"event" => { predicate: :event_type?, kinds: EVENT_METHOD_KINDS },
|
|
51
|
+
"atomic" => { predicate: :atomic_type?, kinds: ATOMIC_METHOD_KINDS },
|
|
52
|
+
"simd" => { predicate: :simd_type?, kinds: SIMD_METHOD_KINDS },
|
|
53
|
+
}.freeze
|
|
54
|
+
|
|
48
55
|
def type_ref_from_specialization(expression)
|
|
49
56
|
case expression.callee
|
|
50
57
|
when AST::Identifier
|
data/lib/milk_tea/core/lexer.rb
CHANGED
|
@@ -279,43 +279,17 @@ module MilkTea
|
|
|
279
279
|
break
|
|
280
280
|
end
|
|
281
281
|
|
|
282
|
-
if char == "c"
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
raise error
|
|
282
|
+
if (char == "c" || char == "f")
|
|
283
|
+
result = dispatch_cf_prefix(char, line, index, line_number, line_offset, lines:, line_index:)
|
|
284
|
+
if result
|
|
285
|
+
if result[0] == :return
|
|
286
|
+
return result[1]
|
|
287
|
+
else
|
|
288
|
+
index = result[1]
|
|
289
|
+
next
|
|
290
|
+
end
|
|
292
291
|
end
|
|
293
292
|
end
|
|
294
|
-
if char == "c" && line[index + 1] == '"'
|
|
295
|
-
result = lex_string(lines, line_index, line, index, line_number, line_offset:, cstring: true)
|
|
296
|
-
return result.consumed_lines if result.consumed_lines > 1
|
|
297
|
-
|
|
298
|
-
index = result.next_index
|
|
299
|
-
next
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
if char == "f" && heredoc_start?(line, index, format: true)
|
|
303
|
-
return lex_heredoc(lines, line_index, index, line_number, line_offset, cstring: false, format: true)
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
if char == "f" && line[index + 1] == "<" && line[index + 2] == "-" && identifier_start?(line[index + 3])
|
|
307
|
-
error = LexError.new("expected '<<-' for heredoc string; did you mean 'f<<-#{identifier_start_token(line, index + 3)}'?", line: line_number, column: index + 1, path: @path)
|
|
308
|
-
if @recovery_errors
|
|
309
|
-
@recovery_errors << error
|
|
310
|
-
else
|
|
311
|
-
raise error
|
|
312
|
-
end
|
|
313
|
-
end
|
|
314
|
-
|
|
315
|
-
if char == "f" && line[index + 1] == '"'
|
|
316
|
-
index = lex_format_string(line, index, line_number, line_offset:)
|
|
317
|
-
next
|
|
318
|
-
end
|
|
319
293
|
|
|
320
294
|
if char == "<" && heredoc_start?(line, index)
|
|
321
295
|
return lex_heredoc(lines, line_index, index, line_number, line_offset, cstring: false)
|
|
@@ -391,6 +365,43 @@ module MilkTea
|
|
|
391
365
|
end
|
|
392
366
|
end
|
|
393
367
|
|
|
368
|
+
def dispatch_cf_prefix(char, line, index, line_number, line_offset, lines:, line_index:)
|
|
369
|
+
return nil unless char == "c" || char == "f"
|
|
370
|
+
|
|
371
|
+
is_c = char == "c"
|
|
372
|
+
is_f = char == "f"
|
|
373
|
+
|
|
374
|
+
if heredoc_start?(line, index, cstring: is_c, format: is_f)
|
|
375
|
+
n = lex_heredoc(lines, line_index, index, line_number, line_offset, cstring: is_c, format: is_f)
|
|
376
|
+
return [:return, n]
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
if line[index + 1] == "<" && line[index + 2] == "-" && identifier_start?(line[index + 3])
|
|
380
|
+
error = LexError.new("expected '<<-' for heredoc string; did you mean '#{char}<<-#{identifier_start_token(line, index + 3)}'?", line: line_number, column: index + 1, path: @path)
|
|
381
|
+
if @recovery_errors
|
|
382
|
+
@recovery_errors << error
|
|
383
|
+
else
|
|
384
|
+
raise error
|
|
385
|
+
end
|
|
386
|
+
return nil
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
if line[index + 1] == '"'
|
|
390
|
+
if is_c
|
|
391
|
+
string_result = lex_string(lines, line_index, line, index, line_number, line_offset:, cstring: true)
|
|
392
|
+
if string_result.consumed_lines > 1
|
|
393
|
+
return [:return, string_result.consumed_lines]
|
|
394
|
+
end
|
|
395
|
+
return [:next, string_result.next_index]
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
new_index = lex_format_string(line, index, line_number, line_offset:)
|
|
399
|
+
return [:next, new_index]
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
nil
|
|
403
|
+
end
|
|
404
|
+
|
|
394
405
|
def token(type, lexeme, literal, line, column, start_offset:, end_offset:)
|
|
395
406
|
Token.new(
|
|
396
407
|
type:,
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "expressions"
|
|
4
|
+
require_relative "loops"
|
|
5
|
+
require_relative "proc"
|
|
6
|
+
require_relative "resolve"
|
|
7
|
+
require_relative "utils"
|
|
8
|
+
require_relative "foreign_cstr"
|
|
9
|
+
require_relative "declarations"
|
|
10
|
+
require_relative "calls"
|
|
11
|
+
|
|
3
12
|
module MilkTea
|
|
4
13
|
module LowererBlock
|
|
5
14
|
def lower_block(statements, env:, active_defers:, return_type:, loop_flow:, allow_return: true)
|
|
@@ -78,7 +78,7 @@ module MilkTea
|
|
|
78
78
|
end
|
|
79
79
|
IR::AggregateLiteral.new(type:, fields:)
|
|
80
80
|
else
|
|
81
|
-
|
|
81
|
+
raise LoweringError.new("unsupported const value type #{const_value.class}", line: 0, column: 0, path: @ctx.current_analysis_path)
|
|
82
82
|
end
|
|
83
83
|
end
|
|
84
84
|
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "resolve"
|
|
4
|
+
require_relative "utils"
|
|
5
|
+
require_relative "block"
|
|
6
|
+
require_relative "async/normalization"
|
|
7
|
+
require_relative "async/lowering"
|
|
8
|
+
|
|
3
9
|
module MilkTea
|
|
4
10
|
module LowererFunctions
|
|
5
11
|
def lower_functions
|
|
6
12
|
lowered = []
|
|
13
|
+
cursor = 0
|
|
14
|
+
declarations = @ctx.ast.declarations
|
|
7
15
|
|
|
8
|
-
|
|
9
|
-
while changed
|
|
10
|
-
changed = false
|
|
11
|
-
|
|
16
|
+
while cursor < declarations.length
|
|
12
17
|
expanded_declarations.each do |decl|
|
|
13
18
|
case decl
|
|
14
19
|
when AST::FunctionDef
|
|
@@ -21,7 +26,6 @@ module MilkTea
|
|
|
21
26
|
|
|
22
27
|
lowered << lower_function_decl(instance)
|
|
23
28
|
@artifacts.lowered_function_linkage_names[linkage_name] = true
|
|
24
|
-
changed = true
|
|
25
29
|
end
|
|
26
30
|
else
|
|
27
31
|
linkage_name = function_binding_c_name(binding, module_name: @ctx.module_name)
|
|
@@ -37,7 +41,6 @@ module MilkTea
|
|
|
37
41
|
@artifacts.lowered_function_linkage_names[entrypoint.linkage_name] = true
|
|
38
42
|
end
|
|
39
43
|
end
|
|
40
|
-
changed = true
|
|
41
44
|
end
|
|
42
45
|
when AST::ExtendingBlock
|
|
43
46
|
receiver_type = resolve_extending_receiver_type(@ctx.analysis, decl.type_name)
|
|
@@ -56,7 +59,6 @@ module MilkTea
|
|
|
56
59
|
|
|
57
60
|
lowered << lower_function_decl(instance, receiver_type:)
|
|
58
61
|
@artifacts.lowered_function_linkage_names[linkage_name] = true
|
|
59
|
-
changed = true
|
|
60
62
|
end
|
|
61
63
|
else
|
|
62
64
|
linkage_name = function_binding_c_name(binding, module_name: @ctx.module_name, receiver_type:)
|
|
@@ -64,11 +66,12 @@ module MilkTea
|
|
|
64
66
|
|
|
65
67
|
lowered << lower_function_decl(binding, receiver_type:)
|
|
66
68
|
@artifacts.lowered_function_linkage_names[linkage_name] = true
|
|
67
|
-
changed = true
|
|
68
69
|
end
|
|
69
70
|
end
|
|
70
71
|
end
|
|
71
72
|
end
|
|
73
|
+
|
|
74
|
+
cursor = declarations.length
|
|
72
75
|
end
|
|
73
76
|
|
|
74
77
|
lowered
|
|
@@ -1506,7 +1506,7 @@ module MilkTea
|
|
|
1506
1506
|
case argument
|
|
1507
1507
|
when AST::TypeRef
|
|
1508
1508
|
resolve_type_argument_ref(argument, type_params:)
|
|
1509
|
-
when AST::FunctionType, AST::ProcType
|
|
1509
|
+
when AST::FunctionType, AST::ProcType, AST::TupleType
|
|
1510
1510
|
resolve_type_ref(argument, type_params:)
|
|
1511
1511
|
when AST::IntegerLiteral, AST::FloatLiteral
|
|
1512
1512
|
Types::LiteralTypeArg.new(argument.value)
|
|
@@ -1518,12 +1518,19 @@ module MilkTea
|
|
|
1518
1518
|
def resolve_type_argument_ref(type_ref, type_params:)
|
|
1519
1519
|
return resolve_type_ref(type_ref, type_params:) unless literal_type_argument_name_candidate?(type_ref)
|
|
1520
1520
|
|
|
1521
|
-
|
|
1522
|
-
|
|
1521
|
+
result = try_resolve_type_ref(type_ref, type_params:)
|
|
1522
|
+
return result if result
|
|
1523
|
+
|
|
1523
1524
|
literal_type_argument = resolve_named_literal_type_argument(type_ref)
|
|
1524
1525
|
return literal_type_argument if literal_type_argument
|
|
1525
1526
|
|
|
1526
|
-
|
|
1527
|
+
resolve_type_ref(type_ref, type_params:)
|
|
1528
|
+
end
|
|
1529
|
+
|
|
1530
|
+
def try_resolve_type_ref(type_ref, type_params:)
|
|
1531
|
+
resolve_type_ref(type_ref, type_params:)
|
|
1532
|
+
rescue LoweringError
|
|
1533
|
+
nil
|
|
1527
1534
|
end
|
|
1528
1535
|
|
|
1529
1536
|
def literal_type_argument_name_candidate?(type_ref)
|
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "functions"
|
|
4
|
+
require_relative "resolve"
|
|
5
|
+
require_relative "utils"
|
|
6
|
+
|
|
3
7
|
module MilkTea
|
|
4
8
|
module LowererScans
|
|
5
9
|
def collect_structs
|
|
6
|
-
@ctx.ast.declarations.each
|
|
7
|
-
case decl
|
|
8
|
-
when AST::WhenStmt
|
|
9
|
-
body = lower_when_chosen_body(decl)
|
|
10
|
-
body&.each { |nested| collect_struct_from_decl(nested) }
|
|
11
|
-
when AST::OpaqueDecl
|
|
12
|
-
@ctx.opaque_types[decl.name] = @ctx.types.fetch(decl.name)
|
|
13
|
-
when AST::StructDecl
|
|
14
|
-
@ctx.struct_types[decl.name] = @ctx.types.fetch(decl.name)
|
|
15
|
-
collect_nested_structs(decl)
|
|
16
|
-
when AST::UnionDecl
|
|
17
|
-
@ctx.union_types[decl.name] = @ctx.types.fetch(decl.name)
|
|
18
|
-
end
|
|
19
|
-
end
|
|
10
|
+
@ctx.ast.declarations.each { |decl| collect_one_struct_decl(decl) }
|
|
20
11
|
end
|
|
21
12
|
|
|
22
|
-
def
|
|
13
|
+
def collect_one_struct_decl(decl)
|
|
23
14
|
case decl
|
|
15
|
+
when AST::WhenStmt
|
|
16
|
+
body = lower_when_chosen_body(decl)
|
|
17
|
+
body&.each { |nested| collect_one_struct_decl(nested) }
|
|
24
18
|
when AST::OpaqueDecl
|
|
25
19
|
@ctx.opaque_types[decl.name] = @ctx.types.fetch(decl.name)
|
|
26
20
|
when AST::StructDecl
|
|
@@ -28,12 +22,13 @@ module MilkTea
|
|
|
28
22
|
collect_nested_structs(decl)
|
|
29
23
|
when AST::UnionDecl
|
|
30
24
|
@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
25
|
end
|
|
35
26
|
end
|
|
36
27
|
|
|
28
|
+
def collect_struct_from_decl(decl)
|
|
29
|
+
collect_one_struct_decl(decl)
|
|
30
|
+
end
|
|
31
|
+
|
|
37
32
|
def lower_when_chosen_body(decl)
|
|
38
33
|
val = compile_time_const_value(decl.discriminant)
|
|
39
34
|
return nil if val.nil?
|
|
@@ -20,19 +20,24 @@ module MilkTea
|
|
|
20
20
|
when AST::StructDecl, AST::UnionDecl, AST::VariantDecl, AST::EnumDecl, AST::FlagsDecl, AST::OpaqueDecl, AST::TypeAliasDecl
|
|
21
21
|
type_declarations[declaration.name] = declaration
|
|
22
22
|
target = exported_declaration?(analysis, declaration) ? types : private_types
|
|
23
|
-
|
|
23
|
+
resolved_type = analysis.types[declaration.name]
|
|
24
|
+
target[declaration.name] = resolved_type if resolved_type
|
|
24
25
|
when AST::InterfaceDecl
|
|
25
26
|
target = exported_declaration?(analysis, declaration) ? interfaces : private_interfaces
|
|
26
|
-
|
|
27
|
+
resolved_iface = analysis.interfaces[declaration.name]
|
|
28
|
+
target[declaration.name] = resolved_iface if resolved_iface
|
|
27
29
|
when AST::AttributeDecl
|
|
28
30
|
target = exported_declaration?(analysis, declaration) ? attributes : private_attributes
|
|
29
|
-
|
|
31
|
+
resolved_attr = analysis.attributes[declaration.name]
|
|
32
|
+
target[declaration.name] = resolved_attr if resolved_attr
|
|
30
33
|
when AST::ConstDecl, AST::VarDecl, AST::EventDecl
|
|
31
34
|
target = exported_declaration?(analysis, declaration) ? values : private_values
|
|
32
|
-
|
|
35
|
+
resolved_val = analysis.values[declaration.name]
|
|
36
|
+
target[declaration.name] = resolved_val if resolved_val
|
|
33
37
|
when AST::FunctionDef, AST::ExternFunctionDecl, AST::ForeignFunctionDecl
|
|
34
38
|
target = exported_declaration?(analysis, declaration) ? functions : private_functions
|
|
35
|
-
|
|
39
|
+
resolved_func = analysis.functions[declaration.name]
|
|
40
|
+
target[declaration.name] = resolved_func if resolved_func
|
|
36
41
|
end
|
|
37
42
|
end
|
|
38
43
|
|
|
@@ -136,17 +141,16 @@ module MilkTea
|
|
|
136
141
|
imported_interface_binding?(interface, analysis.imports)
|
|
137
142
|
end
|
|
138
143
|
|
|
144
|
+
BUILTIN_EXPORTABLE_RECEIVER_TYPES = %w[
|
|
145
|
+
StringView Primitive Vector Matrix Quaternion SoA Simd Span Task Dyn
|
|
146
|
+
].map { |n| "Types::#{n}" }.freeze
|
|
147
|
+
|
|
148
|
+
def builtin_exportable_receiver?(receiver_type)
|
|
149
|
+
BUILTIN_EXPORTABLE_RECEIVER_TYPES.any? { |name| receiver_type.class.to_s.end_with?(name.split("::").last) }
|
|
150
|
+
end
|
|
151
|
+
|
|
139
152
|
def exported_method_receiver?(receiver_type, analysis, exported_types)
|
|
140
|
-
return true if
|
|
141
|
-
return true if receiver_type.is_a?(Types::Primitive)
|
|
142
|
-
return true if receiver_type.is_a?(Types::Vector)
|
|
143
|
-
return true if receiver_type.is_a?(Types::Matrix)
|
|
144
|
-
return true if receiver_type.is_a?(Types::Quaternion)
|
|
145
|
-
return true if receiver_type.is_a?(Types::SoA)
|
|
146
|
-
return true if receiver_type.is_a?(Types::Simd)
|
|
147
|
-
return true if receiver_type.is_a?(Types::Span)
|
|
148
|
-
return true if receiver_type.is_a?(Types::Task)
|
|
149
|
-
return true if receiver_type.is_a?(Types::Dyn)
|
|
153
|
+
return true if builtin_exportable_receiver?(receiver_type)
|
|
150
154
|
return true if exported_types.value?(receiver_type)
|
|
151
155
|
return true if imported_receiver_type?(receiver_type, analysis.imports)
|
|
152
156
|
return exported_method_receiver?(receiver_type.base, analysis, exported_types) if receiver_type.is_a?(Types::Nullable)
|