mt-lang 0.3.31 → 0.3.33
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/bindings/bindgen/emitter.rb +1 -8
- data/lib/milk_tea/core/compile_time.rb +1 -1
- data/lib/milk_tea/core/control_flow/builder.rb +15 -80
- data/lib/milk_tea/core/lexer.rb +5 -1
- data/lib/milk_tea/core/lowering/declarations.rb +36 -2
- data/lib/milk_tea/core/lowering/expressions.rb +18 -5
- data/lib/milk_tea/core/lowering/functions.rb +11 -0
- data/lib/milk_tea/core/lowering/lowering_context.rb +2 -0
- data/lib/milk_tea/core/lowering/resolve.rb +23 -1
- data/lib/milk_tea/core/parser/declarations.rb +9 -4
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +5 -0
- data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +15 -0
- data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +12 -8
- data/lib/milk_tea/core/semantic_analyzer/top_level.rb +70 -5
- data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +4 -0
- data/lib/milk_tea/core/semantic_analyzer.rb +11 -4
- data/std/c/box2d.mt +1 -1
- data/std/c/cgltf.mt +8 -8
- data/std/c/cjson.mt +1 -1
- data/std/c/curl.mt +5 -5
- data/std/c/enet.mt +3 -3
- data/std/c/flecs.mt +31 -31
- data/std/c/libuv.mt +50 -50
- data/std/c/miniaudio.mt +20 -20
- data/std/c/raygui.mt +1 -1
- data/std/c/raylib.mt +1 -1
- data/std/c/rpng.mt +1 -1
- data/std/c/rres.mt +2 -2
- data/std/c/sdl3.mt +56 -56
- data/std/c/sqlite3.mt +1 -1
- data/std/c/stb_truetype.mt +1 -1
- data/std/sdl3/runtime.mt +11 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d03b5daec92d1aeea437f63bd934696f684e524e76985470d416f0bea8d61002
|
|
4
|
+
data.tar.gz: f83f7c79a70a575e0827819865c75955be0c4c03bb6761570afc4bb0df1a75ff
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7f30fbf67b0723afe3b16c14706b817c7b8adea64a0064cb2b7ecb0ff7935efab149a60eb84ced949bc7e6c5da922338d884ee20f1023a2f86ee78b47d2ee8c9
|
|
7
|
+
data.tar.gz: 4d879d9b77dce83a2900f04669c1d858f91c84d6cf101adedfce327b4a18be886f68425429e9dd630c00286d6f1ef53a2e97834ddcbaa30a79726cbe2c66193a
|
data/lib/milk_tea/base.rb
CHANGED
|
@@ -76,19 +76,12 @@ module MilkTea
|
|
|
76
76
|
fields = Array(node["inner"]).select { |child| child["kind"] == "FieldDecl" }
|
|
77
77
|
fields.each do |field|
|
|
78
78
|
field_type = aggregate_field_type(field, owner_name: name, aggregate_node: node)
|
|
79
|
-
mt_name
|
|
79
|
+
mt_name = emitted_name(aggregate_field_name(field, aggregate_node: node))
|
|
80
80
|
lines << " #{mt_name}: #{field_type}"
|
|
81
81
|
end
|
|
82
82
|
lines
|
|
83
83
|
end
|
|
84
84
|
|
|
85
|
-
def bindgen_field_name(name)
|
|
86
|
-
name = emitted_name(name)
|
|
87
|
-
return [name, nil] unless Token::KEYWORDS.key?(name)
|
|
88
|
-
|
|
89
|
-
["#{name}_", nil]
|
|
90
|
-
end
|
|
91
|
-
|
|
92
85
|
def bindgen_param_name(name)
|
|
93
86
|
name = emitted_name(name)
|
|
94
87
|
return [name, nil] unless generated_binding_name_conflict?(name)
|
|
@@ -437,7 +437,7 @@ module MilkTea
|
|
|
437
437
|
resolve_identifier: ->(id) { @variables[id.name] || @checker.evaluate_compile_time_const_value(id, scopes:) },
|
|
438
438
|
resolve_member_access: ->(ma) { @checker.evaluate_compile_time_const_value(ma, scopes:) },
|
|
439
439
|
resolve_type_ref: nil,
|
|
440
|
-
resolve_call:
|
|
440
|
+
resolve_call: ->(call_expr) { resolve_compile_time_call(call_expr, scopes:) },
|
|
441
441
|
)
|
|
442
442
|
end
|
|
443
443
|
return nil unless arg_value
|
|
@@ -56,16 +56,10 @@ module MilkTea
|
|
|
56
56
|
def build_statement(stmt, next_id, break_target:, continue_target:)
|
|
57
57
|
case stmt
|
|
58
58
|
when AST::LocalDecl
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
writes = Set.new
|
|
62
|
-
writes_info = []
|
|
63
|
-
declaration_key = declaration_binding_key(stmt, stmt.name)
|
|
64
|
-
if declaration_key && (stmt.value || @local_decl_without_initializer_writes)
|
|
65
|
-
writes << declaration_key
|
|
66
|
-
writes_info << { name: stmt.name, binding_key: declaration_key, line: stmt.line, column: stmt.column, origin: :declaration }
|
|
67
|
-
end
|
|
59
|
+
reads, reads_info = read_identifiers_with_sites(stmt.value)
|
|
60
|
+
writes, writes_info = local_decl_write_targets(stmt, stmt.name)
|
|
68
61
|
|
|
62
|
+
if stmt.else_body
|
|
69
63
|
success_id = add_linear_node(:local_decl, stmt, next_id, writes:, writes_info:)
|
|
70
64
|
null_entry = build_block(stmt.else_body, next_id, break_target:, continue_target:)
|
|
71
65
|
condition_id = @graph.add_node(
|
|
@@ -80,14 +74,6 @@ module MilkTea
|
|
|
80
74
|
return condition_id
|
|
81
75
|
end
|
|
82
76
|
|
|
83
|
-
reads, reads_info = read_identifiers_with_sites(stmt.value)
|
|
84
|
-
writes = Set.new
|
|
85
|
-
writes_info = []
|
|
86
|
-
declaration_key = declaration_binding_key(stmt, stmt.name)
|
|
87
|
-
if declaration_key && (stmt.value || @local_decl_without_initializer_writes)
|
|
88
|
-
writes << declaration_key
|
|
89
|
-
writes_info << { name: stmt.name, binding_key: declaration_key, line: stmt.line, column: stmt.column, origin: :declaration }
|
|
90
|
-
end
|
|
91
77
|
add_linear_node(:local_decl, stmt, next_id, reads:, reads_info:, writes:, writes_info:)
|
|
92
78
|
when AST::Assignment
|
|
93
79
|
reads, reads_info = read_identifiers_with_sites(stmt.value)
|
|
@@ -213,13 +199,10 @@ module MilkTea
|
|
|
213
199
|
build_block(stmt.body, next_id, break_target:, continue_target:)
|
|
214
200
|
when AST::DeferStmt
|
|
215
201
|
body_entry = build_block(stmt.body, next_id, break_target:, continue_target:)
|
|
216
|
-
expression_reads, expression_reads_info = statement_list_reads_with_sites(stmt.body)
|
|
217
202
|
defer_id = @graph.add_node(
|
|
218
203
|
kind: :defer,
|
|
219
204
|
statement: stmt,
|
|
220
205
|
line: stmt.line,
|
|
221
|
-
reads: expression_reads,
|
|
222
|
-
reads_info: expression_reads_info,
|
|
223
206
|
)
|
|
224
207
|
@graph.add_edge(defer_id, body_entry)
|
|
225
208
|
defer_id
|
|
@@ -315,66 +298,6 @@ module MilkTea
|
|
|
315
298
|
[reads, reads_info]
|
|
316
299
|
end
|
|
317
300
|
|
|
318
|
-
def statement_list_reads_with_sites(statements)
|
|
319
|
-
reads = Set.new
|
|
320
|
-
reads_info = []
|
|
321
|
-
statement_list_read_identifiers(statements, reads, reads_info)
|
|
322
|
-
[reads, reads_info]
|
|
323
|
-
end
|
|
324
|
-
|
|
325
|
-
def statement_list_read_identifiers(statements, reads, reads_info)
|
|
326
|
-
Array(statements).each do |statement|
|
|
327
|
-
statement_read_identifiers(statement, reads, reads_info)
|
|
328
|
-
end
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
def statement_read_identifiers(statement, reads, reads_info)
|
|
332
|
-
case statement
|
|
333
|
-
when AST::ExpressionStmt
|
|
334
|
-
read_identifiers(statement.expression, reads, reads_info)
|
|
335
|
-
when AST::DeferStmt
|
|
336
|
-
statement_list_read_identifiers(statement.body, reads, reads_info)
|
|
337
|
-
when AST::LocalDecl
|
|
338
|
-
read_identifiers(statement.value, reads, reads_info)
|
|
339
|
-
statement_list_read_identifiers(statement.else_body, reads, reads_info)
|
|
340
|
-
when AST::Assignment
|
|
341
|
-
read_identifiers(statement.target, reads, reads_info)
|
|
342
|
-
read_identifiers(statement.value, reads, reads_info)
|
|
343
|
-
when AST::ReturnStmt
|
|
344
|
-
read_identifiers(statement.value, reads, reads_info)
|
|
345
|
-
when AST::IfStmt
|
|
346
|
-
statement.branches.each do |branch|
|
|
347
|
-
read_identifiers(branch.condition, reads, reads_info)
|
|
348
|
-
statement_list_read_identifiers(branch.body, reads, reads_info)
|
|
349
|
-
end
|
|
350
|
-
statement_list_read_identifiers(statement.else_body, reads, reads_info)
|
|
351
|
-
when AST::WhileStmt
|
|
352
|
-
read_identifiers(statement.condition, reads, reads_info)
|
|
353
|
-
statement_list_read_identifiers(statement.body, reads, reads_info)
|
|
354
|
-
when AST::ForStmt
|
|
355
|
-
statement.iterables.each { |iterable| read_identifiers(iterable, reads, reads_info) }
|
|
356
|
-
statement_list_read_identifiers(statement.body, reads, reads_info)
|
|
357
|
-
when AST::UnsafeStmt
|
|
358
|
-
statement_list_read_identifiers(statement.body, reads, reads_info)
|
|
359
|
-
when AST::MatchStmt
|
|
360
|
-
read_identifiers(statement.expression, reads, reads_info)
|
|
361
|
-
statement.arms.each do |arm|
|
|
362
|
-
read_identifiers(arm.pattern, reads, reads_info)
|
|
363
|
-
statement_list_read_identifiers(arm.body, reads, reads_info)
|
|
364
|
-
end
|
|
365
|
-
when AST::StaticAssert
|
|
366
|
-
read_identifiers(statement.condition, reads, reads_info)
|
|
367
|
-
read_identifiers(statement.message, reads, reads_info)
|
|
368
|
-
when AST::WhenStmt
|
|
369
|
-
read_identifiers(statement.discriminant, reads, reads_info)
|
|
370
|
-
statement.branches.each do |branch|
|
|
371
|
-
read_identifiers(branch.pattern, reads, reads_info)
|
|
372
|
-
statement_list_read_identifiers(branch.body, reads, reads_info)
|
|
373
|
-
end
|
|
374
|
-
statement_list_read_identifiers(statement.else_body, reads, reads_info)
|
|
375
|
-
end
|
|
376
|
-
end
|
|
377
|
-
|
|
378
301
|
def read_identifiers(expression, names = Set.new, reads_info = [])
|
|
379
302
|
case expression
|
|
380
303
|
when nil
|
|
@@ -582,6 +505,18 @@ module MilkTea
|
|
|
582
505
|
name
|
|
583
506
|
end
|
|
584
507
|
|
|
508
|
+
def local_decl_write_targets(stmt, name)
|
|
509
|
+
writes = Set.new
|
|
510
|
+
writes_info = []
|
|
511
|
+
declaration_key = declaration_binding_key(stmt, name)
|
|
512
|
+
if declaration_key && (stmt.value || @local_decl_without_initializer_writes)
|
|
513
|
+
writes << declaration_key
|
|
514
|
+
writes_info << { name:, binding_key: declaration_key, line: stmt.line, column: stmt.column, origin: :declaration }
|
|
515
|
+
end
|
|
516
|
+
write_targets_from_expression(stmt.value, line: stmt.line, writes:, writes_info:)
|
|
517
|
+
[writes, writes_info]
|
|
518
|
+
end
|
|
519
|
+
|
|
585
520
|
def add_null_test_refinements(cond_id, true_succ, false_succ, condition)
|
|
586
521
|
pairs = null_check_pairs(condition, positive: true)
|
|
587
522
|
return if pairs.empty?
|
data/lib/milk_tea/core/lexer.rb
CHANGED
|
@@ -324,7 +324,7 @@ module MilkTea
|
|
|
324
324
|
newline_start = line_offset + line.length
|
|
325
325
|
newline_end = has_newline ? (newline_start + 1) : newline_start
|
|
326
326
|
if @grouping_depth.zero?
|
|
327
|
-
if Token::LINE_CONTINUATION_OPERATORS.include?(@tokens.last&.type)
|
|
327
|
+
if Token::LINE_CONTINUATION_OPERATORS.include?(@tokens.last&.type) && !trailing_is_member_access?
|
|
328
328
|
@continuation_pending = true
|
|
329
329
|
else
|
|
330
330
|
@tokens << build_token(:newline, "\n", nil, line_number, line.length + 1, start_offset: newline_start, end_offset: newline_end)
|
|
@@ -345,6 +345,10 @@ module MilkTea
|
|
|
345
345
|
1
|
|
346
346
|
end
|
|
347
347
|
|
|
348
|
+
def trailing_is_member_access?
|
|
349
|
+
@tokens.last&.type == :is && @tokens[-2]&.type == :dot
|
|
350
|
+
end
|
|
351
|
+
|
|
348
352
|
def emit_newline(line, line_number, line_offset, has_newline)
|
|
349
353
|
newline_start = line_offset + line.bytesize
|
|
350
354
|
newline_end = has_newline ? (newline_start + 1) : newline_start
|
|
@@ -26,9 +26,9 @@ module MilkTea
|
|
|
26
26
|
|
|
27
27
|
next if type == Types::BUILTIN_TYPE_META_TYPE
|
|
28
28
|
|
|
29
|
-
if const_value && (decl.value.is_a?(AST::Call) || decl.value.is_a?(AST::Specialization))
|
|
29
|
+
if !const_value.nil? && (decl.value.is_a?(AST::Call) || decl.value.is_a?(AST::Specialization))
|
|
30
30
|
value = lower_const_value_literal(type, const_value)
|
|
31
|
-
elsif const_value && (decl.block_body || decl.value.is_a?(AST::ExpressionList))
|
|
31
|
+
elsif !const_value.nil? && (decl.block_body || decl.value.is_a?(AST::ExpressionList))
|
|
32
32
|
if const_value.is_a?(Array) && const_value.empty? && decl.value.is_a?(AST::ExpressionList) && !decl.value.elements.empty?
|
|
33
33
|
value = lower_static_storage_initializer(decl.value, env: empty_env, expected_type: type)
|
|
34
34
|
else
|
|
@@ -38,12 +38,46 @@ module MilkTea
|
|
|
38
38
|
raise LoweringError.new("constant #{decl.name} has no compile-time value", line: decl.line, column: decl.column)
|
|
39
39
|
else
|
|
40
40
|
value = lower_static_storage_initializer(decl.value, env: empty_env, expected_type: type)
|
|
41
|
+
if (decl.value.is_a?(AST::Call) || decl.value.is_a?(AST::Specialization)) && static_initializer_ir_has_call?(value)
|
|
42
|
+
raise LoweringError.new("constant #{decl.name} initializer is not a compile-time value", line: decl.line, column: decl.column, path: @ctx.current_analysis_path)
|
|
43
|
+
end
|
|
41
44
|
end
|
|
42
45
|
|
|
43
46
|
IR::Constant.new(name: decl.name, linkage_name: value_c_name(decl.name), type:, value:, line: decl.line, path: @ctx.current_analysis_path)
|
|
44
47
|
end
|
|
45
48
|
end
|
|
46
49
|
|
|
50
|
+
def static_initializer_ir_has_call?(node)
|
|
51
|
+
case node
|
|
52
|
+
when IR::Call
|
|
53
|
+
true
|
|
54
|
+
when IR::AggregateLiteral
|
|
55
|
+
node.fields.any? { |field| static_initializer_ir_has_call?(field.value) }
|
|
56
|
+
when IR::ArrayLiteral
|
|
57
|
+
node.elements.any? { |element| static_initializer_ir_has_call?(element) }
|
|
58
|
+
when IR::VariantLiteral
|
|
59
|
+
node.fields.any? { |field| static_initializer_ir_has_call?(field.value) }
|
|
60
|
+
when IR::Binary
|
|
61
|
+
static_initializer_ir_has_call?(node.left) || static_initializer_ir_has_call?(node.right)
|
|
62
|
+
when IR::Unary
|
|
63
|
+
static_initializer_ir_has_call?(node.operand)
|
|
64
|
+
when IR::Conditional
|
|
65
|
+
static_initializer_ir_has_call?(node.condition) || static_initializer_ir_has_call?(node.then_expression) || static_initializer_ir_has_call?(node.else_expression)
|
|
66
|
+
when IR::Cast
|
|
67
|
+
static_initializer_ir_has_call?(node.expression)
|
|
68
|
+
when IR::AddressOf
|
|
69
|
+
static_initializer_ir_has_call?(node.expression)
|
|
70
|
+
when IR::Member
|
|
71
|
+
static_initializer_ir_has_call?(node.receiver)
|
|
72
|
+
when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
|
|
73
|
+
static_initializer_ir_has_call?(node.receiver) || static_initializer_ir_has_call?(node.index)
|
|
74
|
+
when IR::ReinterpretExpr
|
|
75
|
+
static_initializer_ir_has_call?(node.expression)
|
|
76
|
+
else
|
|
77
|
+
false
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
47
81
|
def lower_const_value_literal(type, const_value)
|
|
48
82
|
case const_value
|
|
49
83
|
when Integer
|
|
@@ -1323,10 +1323,10 @@ module MilkTea
|
|
|
1323
1323
|
IR::FloatLiteral.new(value: expression.value, type:)
|
|
1324
1324
|
when AST::SizeofExpr
|
|
1325
1325
|
target_type = resolve_type_ref_with_fallback(expression.type, env:)
|
|
1326
|
-
target_type ? IR::SizeofExpr.new(target_type:, type:) : raise(LoweringError
|
|
1326
|
+
target_type ? IR::SizeofExpr.new(target_type:, type:) : raise(LoweringError.new("size_of argument is not a concrete type", line: expression.line, column: expression.column, path: @ctx.current_analysis_path))
|
|
1327
1327
|
when AST::AlignofExpr
|
|
1328
1328
|
target_type = resolve_type_ref_with_fallback(expression.type, env:)
|
|
1329
|
-
target_type ? IR::AlignofExpr.new(target_type:, type:) : raise(LoweringError
|
|
1329
|
+
target_type ? IR::AlignofExpr.new(target_type:, type:) : raise(LoweringError.new("align_of argument is not a concrete type", line: expression.line, column: expression.column, path: @ctx.current_analysis_path))
|
|
1330
1330
|
when AST::OffsetofExpr
|
|
1331
1331
|
target_type = resolve_type_ref(expression.type)
|
|
1332
1332
|
if !@bypass_sema_type_cache && (precomputed = @ctx.const_values[@ctx.ast.node_ids[expression.object_id]])
|
|
@@ -1348,6 +1348,8 @@ module MilkTea
|
|
|
1348
1348
|
binding = lookup_value(expression.name, env)
|
|
1349
1349
|
if binding
|
|
1350
1350
|
lower_bound_identifier(binding, expected_type:)
|
|
1351
|
+
elsif (value_param = value_param_literal(expression.name, type))
|
|
1352
|
+
value_param
|
|
1351
1353
|
elsif @ctx.functions.key?(expression.name)
|
|
1352
1354
|
function_binding = @ctx.functions.fetch(expression.name)
|
|
1353
1355
|
raise LoweringError.new("generic function #{expression.name} cannot be used as a value", line: 0, column: 0, path: @ctx.current_analysis_path) if function_binding.type_params.any?
|
|
@@ -1699,13 +1701,24 @@ module MilkTea
|
|
|
1699
1701
|
return unless expression
|
|
1700
1702
|
|
|
1701
1703
|
ct_value = compile_time_const_value(expression, env:)
|
|
1702
|
-
if
|
|
1703
|
-
ct_value.is_a?(Types::Union) || ct_value.is_a?(Types::Nullable) ||
|
|
1704
|
-
ct_value.is_a?(Types::StructInstance)
|
|
1704
|
+
if sized_layout_ct_value?(ct_value)
|
|
1705
1705
|
ct_value
|
|
1706
1706
|
end
|
|
1707
1707
|
end
|
|
1708
1708
|
|
|
1709
|
+
def sized_layout_ct_value?(type)
|
|
1710
|
+
case type
|
|
1711
|
+
when Types::Primitive, Types::Struct, Types::StructInstance, Types::Union, Types::Enum, Types::Flags, Types::Variant, Types::Span, Types::StringView, Types::Task, Types::Event, Types::Subscription
|
|
1712
|
+
true
|
|
1713
|
+
when Types::Nullable
|
|
1714
|
+
true
|
|
1715
|
+
when Types::GenericInstance
|
|
1716
|
+
pointer_type?(type) || array_type?(type) || str_buffer_type?(type)
|
|
1717
|
+
else
|
|
1718
|
+
false
|
|
1719
|
+
end
|
|
1720
|
+
end
|
|
1721
|
+
|
|
1709
1722
|
def build_expression_from_qualified_name(qualified_name)
|
|
1710
1723
|
parts = qualified_name.parts
|
|
1711
1724
|
return unless parts.length >= 1
|
|
@@ -117,7 +117,9 @@ module MilkTea
|
|
|
117
117
|
env = empty_env
|
|
118
118
|
parameter_setup = []
|
|
119
119
|
previous_type_substitutions = @ctx.current_type_substitutions
|
|
120
|
+
previous_value_type_params = @ctx.current_value_type_params
|
|
120
121
|
@ctx.current_type_substitutions = binding.type_substitutions
|
|
122
|
+
@ctx.current_value_type_params = resolve_value_type_params(decl.type_params)
|
|
121
123
|
|
|
122
124
|
return lower_async_function_decl(binding, receiver_type:) if binding.async
|
|
123
125
|
|
|
@@ -176,6 +178,15 @@ module MilkTea
|
|
|
176
178
|
)
|
|
177
179
|
ensure
|
|
178
180
|
@ctx.current_type_substitutions = previous_type_substitutions
|
|
181
|
+
@ctx.current_value_type_params = previous_value_type_params
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def resolve_value_type_params(type_params)
|
|
185
|
+
type_params.each_with_object({}) do |type_param, map|
|
|
186
|
+
next unless type_param.is_a?(AST::ValueTypeParam)
|
|
187
|
+
|
|
188
|
+
map[type_param.name] = resolve_type_ref(type_param.type, type_params: current_type_params)
|
|
189
|
+
end
|
|
179
190
|
end
|
|
180
191
|
|
|
181
192
|
def lower_async_function_decl(binding, receiver_type: nil)
|
|
@@ -9,6 +9,7 @@ module MilkTea
|
|
|
9
9
|
attr_accessor :methods, :attributes, :attribute_applications, :implemented_interfaces
|
|
10
10
|
attr_accessor :struct_types, :union_types, :opaque_types
|
|
11
11
|
attr_accessor :current_type_substitutions
|
|
12
|
+
attr_accessor :current_value_type_params
|
|
12
13
|
attr_accessor :resolved_expr_types
|
|
13
14
|
attr_accessor :resolved_call_kinds
|
|
14
15
|
attr_accessor :const_values
|
|
@@ -27,6 +28,7 @@ module MilkTea
|
|
|
27
28
|
@attribute_applications = {}
|
|
28
29
|
@implemented_interfaces = {}
|
|
29
30
|
@current_type_substitutions = nil
|
|
31
|
+
@current_value_type_params = nil
|
|
30
32
|
@resolved_expr_types = {}
|
|
31
33
|
@resolved_call_kinds = {}
|
|
32
34
|
@const_values = {}
|
|
@@ -699,7 +699,7 @@ module MilkTea
|
|
|
699
699
|
end
|
|
700
700
|
|
|
701
701
|
def infer_expression_type(expression, env:, expected_type: nil)
|
|
702
|
-
if !@bypass_sema_type_cache && expected_type.nil? && (id = @ctx.ast.node_ids[expression.object_id]) && (resolved = @ctx.resolved_expr_types[id])
|
|
702
|
+
if !@bypass_sema_type_cache && expected_type.nil? && !expression.is_a?(AST::Identifier) && (id = @ctx.ast.node_ids[expression.object_id]) && (resolved = @ctx.resolved_expr_types[id])
|
|
703
703
|
return resolved
|
|
704
704
|
end
|
|
705
705
|
|
|
@@ -740,6 +740,9 @@ module MilkTea
|
|
|
740
740
|
when AST::Identifier
|
|
741
741
|
binding = lookup_value(expression.name, env)
|
|
742
742
|
return binding[:type] if binding
|
|
743
|
+
if (value_param_type = value_param_declared_type(expression.name))
|
|
744
|
+
return value_param_type
|
|
745
|
+
end
|
|
743
746
|
return function_type_for_name(expression.name) if @ctx.functions.key?(expression.name)
|
|
744
747
|
|
|
745
748
|
raise LoweringError.new("unknown identifier #{expression.name}", line: expression.line, column: expression.column)
|
|
@@ -2437,6 +2440,25 @@ module MilkTea
|
|
|
2437
2440
|
@ctx.current_type_substitutions || {}
|
|
2438
2441
|
end
|
|
2439
2442
|
|
|
2443
|
+
def value_param_substitution(name)
|
|
2444
|
+
substitution = current_type_params[name]
|
|
2445
|
+
substitution.is_a?(Types::LiteralTypeArg) ? substitution : nil
|
|
2446
|
+
end
|
|
2447
|
+
|
|
2448
|
+
def value_param_declared_type(name)
|
|
2449
|
+
return nil unless value_param_substitution(name)
|
|
2450
|
+
|
|
2451
|
+
@ctx.current_value_type_params&.[](name)
|
|
2452
|
+
end
|
|
2453
|
+
|
|
2454
|
+
def value_param_literal(name, expected_type = nil)
|
|
2455
|
+
substitution = value_param_substitution(name)
|
|
2456
|
+
return nil unless substitution && substitution.value.is_a?(Integer)
|
|
2457
|
+
|
|
2458
|
+
type = @ctx.current_value_type_params&.[](name) || expected_type || @ctx.types.fetch("int")
|
|
2459
|
+
IR::IntegerLiteral.new(value: substitution.value, type:)
|
|
2460
|
+
end
|
|
2461
|
+
|
|
2440
2462
|
def resolve_type_ref(type_ref, type_params: current_type_params)
|
|
2441
2463
|
if type_ref.is_a?(AST::FunctionType)
|
|
2442
2464
|
params = type_ref.params.map do |param|
|
|
@@ -454,7 +454,7 @@ module MilkTea
|
|
|
454
454
|
match(:async)
|
|
455
455
|
match(:editable) if check(:editable)
|
|
456
456
|
match(:static) if check(:static)
|
|
457
|
-
result = check(:function)
|
|
457
|
+
result = check(:function) && !check_next(:colon)
|
|
458
458
|
@current = saved
|
|
459
459
|
result
|
|
460
460
|
end
|
|
@@ -468,11 +468,13 @@ module MilkTea
|
|
|
468
468
|
|
|
469
469
|
visibility, visibility_token = parse_visibility
|
|
470
470
|
|
|
471
|
-
if
|
|
471
|
+
if check(:event) && !check_next(:colon)
|
|
472
|
+
advance
|
|
472
473
|
return [:event, parse_event_decl(visibility:, attributes: field_attributes)]
|
|
473
474
|
end
|
|
474
475
|
|
|
475
|
-
if
|
|
476
|
+
if check(:struct) && !check_next(:colon)
|
|
477
|
+
advance
|
|
476
478
|
return [:nested_type, parse_struct_decl(visibility:, attributes: field_attributes, inline_methods: false)]
|
|
477
479
|
end
|
|
478
480
|
|
|
@@ -741,7 +743,10 @@ module MilkTea
|
|
|
741
743
|
end
|
|
742
744
|
|
|
743
745
|
def parse_visibility
|
|
744
|
-
|
|
746
|
+
if check(:public) && !check_next(:colon)
|
|
747
|
+
advance
|
|
748
|
+
return [:public, previous]
|
|
749
|
+
end
|
|
745
750
|
|
|
746
751
|
[:private, nil]
|
|
747
752
|
end
|
|
@@ -31,6 +31,7 @@ module MilkTea
|
|
|
31
31
|
receiver_type = infer_lvalue_receiver(
|
|
32
32
|
expression.receiver,
|
|
33
33
|
scopes:,
|
|
34
|
+
allow_ref_identifier: true,
|
|
34
35
|
allow_pointer_identifier: true,
|
|
35
36
|
require_mutable_pointer: true,
|
|
36
37
|
allow_span_param_identifier: true,
|
|
@@ -333,6 +334,10 @@ module MilkTea
|
|
|
333
334
|
return binding.type
|
|
334
335
|
end
|
|
335
336
|
|
|
337
|
+
if (value_param_type = current_value_type_params[expression.name])
|
|
338
|
+
return value_param_type
|
|
339
|
+
end
|
|
340
|
+
|
|
336
341
|
if @ctx.top_level_functions.key?(expression.name)
|
|
337
342
|
raise_sema_error("generic function #{expression.name} must be called") if @ctx.top_level_functions.fetch(expression.name).type_params.any?
|
|
338
343
|
|
|
@@ -615,6 +615,7 @@ module MilkTea
|
|
|
615
615
|
|
|
616
616
|
previous_type_substitutions = @current_type_substitutions
|
|
617
617
|
previous_specialization_owner = @current_specialization_owner
|
|
618
|
+
previous_value_type_params = @current_value_type_params
|
|
618
619
|
started_check = false
|
|
619
620
|
return if binding.external
|
|
620
621
|
return if @checked_function_bindings[binding.object_id]
|
|
@@ -624,6 +625,7 @@ module MilkTea
|
|
|
624
625
|
started_check = true
|
|
625
626
|
@current_type_substitutions = binding.type_substitutions
|
|
626
627
|
@current_specialization_owner = binding.specialization_owner
|
|
628
|
+
@current_value_type_params = resolve_value_type_params(binding.ast.type_params)
|
|
627
629
|
with_error_node(binding.ast) do
|
|
628
630
|
with_scope(binding.body_params) do |scopes|
|
|
629
631
|
start_local_completion_frame(binding, scopes)
|
|
@@ -678,8 +680,21 @@ module MilkTea
|
|
|
678
680
|
@nullability_flow_result = nil
|
|
679
681
|
@current_type_substitutions = previous_type_substitutions
|
|
680
682
|
@current_specialization_owner = previous_specialization_owner
|
|
683
|
+
@current_value_type_params = previous_value_type_params
|
|
681
684
|
@checking_function_bindings.delete(binding.object_id)
|
|
682
685
|
end
|
|
686
|
+
|
|
687
|
+
def resolve_value_type_params(type_params)
|
|
688
|
+
type_params.each_with_object({}) do |type_param, map|
|
|
689
|
+
next unless type_param.is_a?(AST::ValueTypeParam)
|
|
690
|
+
|
|
691
|
+
map[type_param.name] = resolve_type_ref(
|
|
692
|
+
type_param.type,
|
|
693
|
+
type_params: current_type_params,
|
|
694
|
+
type_param_constraints: current_type_param_constraints,
|
|
695
|
+
)
|
|
696
|
+
end
|
|
697
|
+
end
|
|
683
698
|
end
|
|
684
699
|
end
|
|
685
700
|
end
|
|
@@ -7,6 +7,10 @@ module MilkTea
|
|
|
7
7
|
@current_type_substitutions || {}
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
def current_value_type_params
|
|
11
|
+
@current_value_type_params || {}
|
|
12
|
+
end
|
|
13
|
+
|
|
10
14
|
def current_type_param_constraints
|
|
11
15
|
@current_type_param_constraints || {}
|
|
12
16
|
end
|
|
@@ -463,9 +467,13 @@ module MilkTea
|
|
|
463
467
|
resolve_imported_module_const_value(type_ref.name.parts.first, type_ref.name.parts.last)
|
|
464
468
|
end
|
|
465
469
|
|
|
466
|
-
return
|
|
470
|
+
return if value.nil?
|
|
471
|
+
return Types::LiteralTypeArg.new(value) if value.is_a?(Integer) || value.is_a?(Float)
|
|
472
|
+
return value if value.is_a?(Types::Base)
|
|
467
473
|
|
|
468
|
-
|
|
474
|
+
nil
|
|
475
|
+
rescue SemanticError
|
|
476
|
+
nil
|
|
469
477
|
end
|
|
470
478
|
|
|
471
479
|
def resolve_current_module_const_value(name)
|
|
@@ -657,12 +665,8 @@ module MilkTea
|
|
|
657
665
|
return false unless expression
|
|
658
666
|
|
|
659
667
|
ct_value = evaluate_compile_time_const_value(expression, scopes:)
|
|
660
|
-
if
|
|
661
|
-
|
|
662
|
-
ct_value.is_a?(Types::StructInstance)
|
|
663
|
-
if sized_layout_type?(ct_value)
|
|
664
|
-
return true
|
|
665
|
-
end
|
|
668
|
+
if sized_layout_type?(ct_value)
|
|
669
|
+
return true
|
|
666
670
|
end
|
|
667
671
|
|
|
668
672
|
false
|