mt-lang 0.3.42 → 0.4.0
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/README.md +5 -2
- data/docs/index.html +20 -4
- data/docs/language-design.md +5 -2
- data/docs/language-manual.md +28 -5
- data/lib/milk_tea/base.rb +1 -1
- data/lib/milk_tea/core/ast.rb +2 -2
- data/lib/milk_tea/core/c_backend/feature_detection.rb +6 -1
- data/lib/milk_tea/core/c_backend/runtime_helpers.rb +30 -0
- data/lib/milk_tea/core/c_backend/type_collectors.rb +74 -0
- data/lib/milk_tea/core/c_backend.rb +9 -0
- data/lib/milk_tea/core/compile_time/method_folding.rb +157 -0
- data/lib/milk_tea/core/compile_time.rb +303 -26
- data/lib/milk_tea/core/lowering/async/normalization.rb +2 -0
- data/lib/milk_tea/core/lowering/expressions.rb +31 -6
- data/lib/milk_tea/core/lowering/proc.rb +3 -0
- data/lib/milk_tea/core/lowering/resolve.rb +79 -2
- data/lib/milk_tea/core/lowering/utils.rb +26 -0
- data/lib/milk_tea/core/parser/declarations.rb +10 -5
- data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +10 -8
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +13 -0
- data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +46 -0
- data/lib/milk_tea/core/semantic_analyzer/statements.rb +1 -0
- data/lib/milk_tea/core/semantic_analyzer/top_level.rb +70 -1
- data/lib/milk_tea/core/semantic_analyzer.rb +9 -2
- data/lib/milk_tea/core/types/registry.rb +39 -16
- data/lib/milk_tea/lsp/server/hover.rb +0 -1
- data/lib/milk_tea/lsp/server/text_documents.rb +1 -1
- metadata +3 -2
|
@@ -213,6 +213,10 @@ module MilkTea
|
|
|
213
213
|
|
|
214
214
|
receiver_type = referenced_type(receiver_type) if ref_type?(receiver_type)
|
|
215
215
|
|
|
216
|
+
if receiver_type.is_a?(Types::StringView)
|
|
217
|
+
return @ctx.types.fetch("ubyte")
|
|
218
|
+
end
|
|
219
|
+
|
|
216
220
|
if array_type?(receiver_type)
|
|
217
221
|
return array_element_type(receiver_type)
|
|
218
222
|
end
|
|
@@ -236,6 +240,28 @@ module MilkTea
|
|
|
236
240
|
raise LoweringError.new("cannot index #{receiver_type}", line: 0, column: 0, path: @ctx.current_analysis_path)
|
|
237
241
|
end
|
|
238
242
|
|
|
243
|
+
def range_index_result_type(receiver_type)
|
|
244
|
+
receiver_type = referenced_type(receiver_type) if ref_type?(receiver_type)
|
|
245
|
+
|
|
246
|
+
if receiver_type.is_a?(Types::StringView)
|
|
247
|
+
return @ctx.types.fetch("str")
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
if array_type?(receiver_type)
|
|
251
|
+
return Types::Span.new(array_element_type(receiver_type))
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
if receiver_type.is_a?(Types::Span)
|
|
255
|
+
return receiver_type
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
raise LoweringError.new("cannot range-index #{receiver_type}; expected str, array[T, N], or span[T]", line: 0, column: 0, path: @ctx.current_analysis_path)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def span_slice_callee(span_type)
|
|
262
|
+
"mt_span_slice_#{sanitize_identifier(span_type.element_type.to_s)}"
|
|
263
|
+
end
|
|
264
|
+
|
|
239
265
|
def stored_ref_supported_type?(type, visited = {})
|
|
240
266
|
return true unless type
|
|
241
267
|
|
|
@@ -459,6 +459,7 @@ module MilkTea
|
|
|
459
459
|
match(:async)
|
|
460
460
|
match(:editable) if check(:editable)
|
|
461
461
|
match(:static) if check(:static)
|
|
462
|
+
match(:const) if check(:const)
|
|
462
463
|
result = check(:function) && !check_next(:colon)
|
|
463
464
|
@current = saved
|
|
464
465
|
result
|
|
@@ -657,10 +658,10 @@ module MilkTea
|
|
|
657
658
|
end
|
|
658
659
|
|
|
659
660
|
def parse_method_def(attributes: [])
|
|
660
|
-
visibility, _visibility_token, async, kind, line, name_token = parse_method_head
|
|
661
|
+
visibility, _visibility_token, async, kind, const, line, name_token = parse_method_head
|
|
661
662
|
name = name_token.lexeme
|
|
662
663
|
type_params, params, return_type, body = parse_callable_signature
|
|
663
|
-
AST::MethodDef.new(name:, type_params:, params:, return_type:, body:, kind:, visibility:, async:, attributes:, line:, column: name_token.column)
|
|
664
|
+
AST::MethodDef.new(name:, type_params:, params:, return_type:, body:, kind:, visibility:, async:, const:, attributes:, line:, column: name_token.column)
|
|
664
665
|
rescue ParseError => e
|
|
665
666
|
raise unless @recovery_errors
|
|
666
667
|
|
|
@@ -668,11 +669,12 @@ module MilkTea
|
|
|
668
669
|
name = name_token&.lexeme || "unknown"
|
|
669
670
|
col = name_token&.column || 1
|
|
670
671
|
advance until eof? || check(:function) || check(:dedent)
|
|
671
|
-
AST::MethodDef.new(name:, type_params: [], params: [], return_type: nil, body: nil, kind: kind || :plain, visibility: visibility || :private, async: async || false, attributes:, line:, column: col)
|
|
672
|
+
AST::MethodDef.new(name:, type_params: [], params: [], return_type: nil, body: nil, kind: kind || :plain, visibility: visibility || :private, async: async || false, const: const || false, attributes:, line:, column: col)
|
|
672
673
|
end
|
|
673
674
|
|
|
674
675
|
def parse_interface_method_decl(attributes: [])
|
|
675
|
-
visibility, visibility_token, async, kind, line, name_token = parse_method_head
|
|
676
|
+
visibility, visibility_token, async, kind, const, line, name_token = parse_method_head
|
|
677
|
+
raise error(name_token, "const is not allowed on interface methods") if const
|
|
676
678
|
raise error(visibility_token, "public is not allowed on interface methods") if visibility == :public
|
|
677
679
|
|
|
678
680
|
name = name_token.lexeme
|
|
@@ -689,6 +691,9 @@ module MilkTea
|
|
|
689
691
|
visibility, visibility_token = parse_visibility
|
|
690
692
|
async = match(:async)
|
|
691
693
|
kind = parse_method_kind
|
|
694
|
+
const = match(:const)
|
|
695
|
+
raise error(previous, "editable methods cannot be const") if kind == :editable && const
|
|
696
|
+
raise error(previous, "async methods cannot be const") if async && const
|
|
692
697
|
if check(:function)
|
|
693
698
|
consume(:function, "expected function declaration")
|
|
694
699
|
elsif check(:identifier)
|
|
@@ -699,7 +704,7 @@ module MilkTea
|
|
|
699
704
|
end
|
|
700
705
|
line = previous.line
|
|
701
706
|
name_token = consume_name("expected function name")
|
|
702
|
-
[visibility, visibility_token, async, kind, line, name_token]
|
|
707
|
+
[visibility, visibility_token, async, kind, const, line, name_token]
|
|
703
708
|
end
|
|
704
709
|
|
|
705
710
|
def parse_method_kind
|
|
@@ -298,14 +298,16 @@ module MilkTea
|
|
|
298
298
|
|
|
299
299
|
def render_function_signature(function, prefix: "")
|
|
300
300
|
signature_prefix = if function.is_a?(AST::MethodDef)
|
|
301
|
-
case function.kind
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
301
|
+
kind_prefix = case function.kind
|
|
302
|
+
when :editable
|
|
303
|
+
"editable "
|
|
304
|
+
when :static
|
|
305
|
+
"static "
|
|
306
|
+
else
|
|
307
|
+
""
|
|
308
|
+
end
|
|
309
|
+
const_prefix = function.respond_to?(:const) && function.const ? "const " : ""
|
|
310
|
+
"#{kind_prefix}#{const_prefix}function "
|
|
309
311
|
elsif function.is_a?(AST::ForeignFunctionDecl)
|
|
310
312
|
"foreign function "
|
|
311
313
|
else
|
|
@@ -37,6 +37,8 @@ module MilkTea
|
|
|
37
37
|
allow_span_param_identifier: true,
|
|
38
38
|
)
|
|
39
39
|
|
|
40
|
+
raise_sema_error("cannot assign through str index; str is an immutable borrowed view") if receiver_type.is_a?(Types::StringView)
|
|
41
|
+
|
|
40
42
|
index_type = infer_expression(expression.index, scopes:)
|
|
41
43
|
infer_index_result_type(receiver_type, index_type)
|
|
42
44
|
when AST::Call
|
|
@@ -101,6 +103,8 @@ module MilkTea
|
|
|
101
103
|
require_mutable_pointer:,
|
|
102
104
|
allow_span_param_identifier:,
|
|
103
105
|
)
|
|
106
|
+
raise_sema_error("cannot index through str as an assignment receiver; str is an immutable borrowed view") if receiver_type.is_a?(Types::StringView)
|
|
107
|
+
|
|
104
108
|
index_type = infer_expression(expression.index, scopes:)
|
|
105
109
|
infer_index_result_type(receiver_type, index_type)
|
|
106
110
|
when AST::Call
|
|
@@ -470,8 +474,17 @@ module MilkTea
|
|
|
470
474
|
|
|
471
475
|
def infer_index_access(expression, scopes:)
|
|
472
476
|
receiver_type = infer_expression(expression.receiver, scopes:)
|
|
477
|
+
|
|
478
|
+
if expression.index.is_a?(AST::RangeExpr)
|
|
479
|
+
return infer_range_index_access(expression, receiver_type, scopes:)
|
|
480
|
+
end
|
|
481
|
+
|
|
473
482
|
index_type = infer_expression(expression.index, scopes:)
|
|
474
483
|
|
|
484
|
+
if receiver_type.is_a?(Types::StringView) && (literal = integer_literal_bound_value(expression.index)) && literal < 0
|
|
485
|
+
raise_sema_error("str index #{literal} is negative; str indices must be non-negative", expression)
|
|
486
|
+
end
|
|
487
|
+
|
|
475
488
|
if soa_type?(receiver_type)
|
|
476
489
|
return receiver_type.element_type
|
|
477
490
|
end
|
|
@@ -1022,6 +1022,10 @@ module MilkTea
|
|
|
1022
1022
|
def infer_index_result_type(receiver_type, index_type)
|
|
1023
1023
|
raise_sema_error("index must be an integer type, got #{index_type}") unless integer_type?(index_type)
|
|
1024
1024
|
|
|
1025
|
+
if receiver_type.is_a?(Types::StringView)
|
|
1026
|
+
return @ctx.types.fetch("ubyte")
|
|
1027
|
+
end
|
|
1028
|
+
|
|
1025
1029
|
if array_type?(receiver_type)
|
|
1026
1030
|
return array_element_type(receiver_type)
|
|
1027
1031
|
end
|
|
@@ -1047,6 +1051,48 @@ module MilkTea
|
|
|
1047
1051
|
raise_sema_error("cannot index #{receiver_type}")
|
|
1048
1052
|
end
|
|
1049
1053
|
|
|
1054
|
+
def infer_range_index_access(expression, receiver_type, scopes:)
|
|
1055
|
+
start_type = infer_expression(expression.index.start_expr, scopes:)
|
|
1056
|
+
stop_type = infer_expression(expression.index.end_expr, scopes:)
|
|
1057
|
+
raise_sema_error("range index bounds must be integer types, got #{start_type} and #{stop_type}") unless start_type.integer? && stop_type.integer?
|
|
1058
|
+
|
|
1059
|
+
if array_type?(receiver_type) && !addressable_storage_expression?(expression.receiver, scopes:)
|
|
1060
|
+
raise_sema_error("array range slice requires an addressable array value; bind it to a local first", expression)
|
|
1061
|
+
end
|
|
1062
|
+
|
|
1063
|
+
if array_type?(receiver_type) && (start_val = integer_literal_bound_value(expression.index.start_expr)) && (stop_val = integer_literal_bound_value(expression.index.end_expr))
|
|
1064
|
+
length = array_length(receiver_type)
|
|
1065
|
+
unless start_val >= 0 && start_val <= stop_val && stop_val <= length
|
|
1066
|
+
raise_sema_error("range index [#{start_val}..#{stop_val}] is out of bounds for array[T, #{length}]", expression)
|
|
1067
|
+
end
|
|
1068
|
+
end
|
|
1069
|
+
|
|
1070
|
+
range_index_result_type(receiver_type)
|
|
1071
|
+
end
|
|
1072
|
+
|
|
1073
|
+
def range_index_result_type(receiver_type)
|
|
1074
|
+
if receiver_type.is_a?(Types::StringView)
|
|
1075
|
+
return @ctx.types.fetch("str")
|
|
1076
|
+
end
|
|
1077
|
+
|
|
1078
|
+
if array_type?(receiver_type)
|
|
1079
|
+
return Types::Span.new(array_element_type(receiver_type))
|
|
1080
|
+
end
|
|
1081
|
+
|
|
1082
|
+
if span_type?(receiver_type)
|
|
1083
|
+
return receiver_type
|
|
1084
|
+
end
|
|
1085
|
+
|
|
1086
|
+
raise_sema_error("cannot range-index #{receiver_type}; expected str, array[T, N], or span[T]")
|
|
1087
|
+
end
|
|
1088
|
+
|
|
1089
|
+
def integer_literal_bound_value(expression)
|
|
1090
|
+
return expression.value if expression.is_a?(AST::IntegerLiteral)
|
|
1091
|
+
return -expression.operand.value if expression.is_a?(AST::UnaryOp) && expression.operator == "-" && expression.operand.is_a?(AST::IntegerLiteral)
|
|
1092
|
+
|
|
1093
|
+
nil
|
|
1094
|
+
end
|
|
1095
|
+
|
|
1050
1096
|
def addressable_storage_expression?(expression, scopes:)
|
|
1051
1097
|
case expression
|
|
1052
1098
|
when AST::Identifier
|
|
@@ -538,6 +538,7 @@ module MilkTea
|
|
|
538
538
|
require_mutable_pointer: true,
|
|
539
539
|
allow_span_param_identifier: true,
|
|
540
540
|
)
|
|
541
|
+
raise_sema_error("cannot assign through str index; str is an immutable borrowed view") if receiver_type.is_a?(Types::StringView)
|
|
541
542
|
element_type = infer_index_result_type(receiver_type, @ctx.types.fetch("ptr_uint"))
|
|
542
543
|
|
|
543
544
|
statement.value.elements.each_with_index do |elem, i|
|
|
@@ -298,6 +298,33 @@ module MilkTea
|
|
|
298
298
|
current_type_params[identifier_expression.name] || @ctx.types[identifier_expression.name]
|
|
299
299
|
end,
|
|
300
300
|
resolve_member_access: lambda do |member_access_expression|
|
|
301
|
+
if (receiver_value = CompileTime.evaluate(
|
|
302
|
+
member_access_expression.receiver,
|
|
303
|
+
resolve_identifier: lambda do |identifier_expression|
|
|
304
|
+
if scopes
|
|
305
|
+
binding = lookup_value(identifier_expression.name, scopes)
|
|
306
|
+
return binding.const_value unless binding&.const_value.nil?
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
resolve_current_module_const_value(identifier_expression.name)
|
|
310
|
+
end,
|
|
311
|
+
resolve_member_access: lambda { |ma| evaluate_compile_time_const_value(ma, scopes:) },
|
|
312
|
+
resolve_type_ref: lambda { |tr| resolve_type_ref(tr) },
|
|
313
|
+
resolve_call: lambda { |ce| evaluate_compile_time_call(ce, scopes:) },
|
|
314
|
+
))
|
|
315
|
+
case receiver_value
|
|
316
|
+
when Hash
|
|
317
|
+
next receiver_value[member_access_expression.member] if receiver_value.key?(member_access_expression.member)
|
|
318
|
+
when Array
|
|
319
|
+
if member_access_expression.member =~ /\A_(\d+)\z/
|
|
320
|
+
next receiver_value[Regexp.last_match(1).to_i]
|
|
321
|
+
end
|
|
322
|
+
next receiver_value.length if member_access_expression.member == "len"
|
|
323
|
+
when String
|
|
324
|
+
next receiver_value.length if member_access_expression.member == "len"
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
|
|
301
328
|
if member_access_expression.receiver.is_a?(AST::Identifier) && scopes
|
|
302
329
|
binding = lookup_value(member_access_expression.receiver.name, scopes)
|
|
303
330
|
if binding && binding.const_value
|
|
@@ -392,6 +419,11 @@ module MilkTea
|
|
|
392
419
|
end
|
|
393
420
|
return CompileTime::VariantValue.new(arm: arm_name, fields: fields)
|
|
394
421
|
end
|
|
422
|
+
|
|
423
|
+
if (method_binding = comptime_method_binding(expression.callee, scopes))
|
|
424
|
+
receiver_value = comptime_member_receiver_value(expression.callee.receiver, scopes)
|
|
425
|
+
return comptime_const_method_body(method_binding, expression.arguments, scopes:, receiver_value:)
|
|
426
|
+
end
|
|
395
427
|
when AST::Identifier
|
|
396
428
|
if (struct_type = @ctx.types[expression.callee.name]) && struct_type.is_a?(Types::Struct)
|
|
397
429
|
fields = {}
|
|
@@ -587,7 +619,10 @@ module MilkTea
|
|
|
587
619
|
initial_vars[param.name] = arg_value
|
|
588
620
|
end
|
|
589
621
|
|
|
590
|
-
|
|
622
|
+
variable_types = func.body_params.each_with_object({}) do |param, acc|
|
|
623
|
+
acc[param.name] = param.type
|
|
624
|
+
end
|
|
625
|
+
ctx = CompileTime::BlockContext.new(self, initial_variables: initial_vars, variable_types: variable_types)
|
|
591
626
|
result = ctx.evaluate_block(func.ast.body, scopes: nil)
|
|
592
627
|
result.is_a?(CompileTime::ReturnOutcome) ? result.value : result
|
|
593
628
|
rescue CompileTime::Error => e
|
|
@@ -613,6 +648,40 @@ module MilkTea
|
|
|
613
648
|
end
|
|
614
649
|
end
|
|
615
650
|
|
|
651
|
+
def comptime_methods_map
|
|
652
|
+
@ctx.methods
|
|
653
|
+
end
|
|
654
|
+
|
|
655
|
+
def comptime_methods_map_by_to_s(_type)
|
|
656
|
+
nil
|
|
657
|
+
end
|
|
658
|
+
|
|
659
|
+
def comptime_scoped_value_type(name, ctx)
|
|
660
|
+
return nil unless ctx
|
|
661
|
+
|
|
662
|
+
lookup_value(name, ctx)&.type
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
def comptime_value_type(name)
|
|
666
|
+
@ctx.top_level_values[name]&.type
|
|
667
|
+
end
|
|
668
|
+
|
|
669
|
+
def comptime_const_function(name)
|
|
670
|
+
@ctx.top_level_functions[name]
|
|
671
|
+
end
|
|
672
|
+
|
|
673
|
+
def comptime_eval(expression, scopes)
|
|
674
|
+
evaluate_compile_time_const_value(expression, scopes: scopes)
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
def comptime_block_context(initial_vars, variable_types)
|
|
678
|
+
::MilkTea::CompileTime::BlockContext.new(self, initial_variables: initial_vars, variable_types: variable_types)
|
|
679
|
+
end
|
|
680
|
+
|
|
681
|
+
def comptime_raise_error(error)
|
|
682
|
+
raise_sema_error(error.message)
|
|
683
|
+
end
|
|
684
|
+
|
|
616
685
|
def evaluate_has_attribute_call(arguments, scopes:)
|
|
617
686
|
target = evaluate_reflection_target_argument(arguments.first.value, scopes:)
|
|
618
687
|
binding = resolve_attribute_name_argument(arguments[1].value)
|
|
@@ -131,6 +131,7 @@ module MilkTea
|
|
|
131
131
|
|
|
132
132
|
class Checker
|
|
133
133
|
include Intrinsics
|
|
134
|
+
include CompileTime::MethodFolding
|
|
134
135
|
|
|
135
136
|
attr_reader :ctx
|
|
136
137
|
|
|
@@ -222,8 +223,14 @@ module MilkTea
|
|
|
222
223
|
when AST::WhenStmt
|
|
223
224
|
body = when_chosen_body(decl)
|
|
224
225
|
collect_emit_from_declarations(body) if body
|
|
225
|
-
when AST::StructDecl
|
|
226
|
-
# no emit in structs
|
|
226
|
+
when AST::StructDecl
|
|
227
|
+
# no emit in structs
|
|
228
|
+
when AST::ExtendingBlock
|
|
229
|
+
decl.methods.each do |method|
|
|
230
|
+
next unless method.respond_to?(:const) && method.const && method.body
|
|
231
|
+
|
|
232
|
+
collect_emit_from_statements(method.body)
|
|
233
|
+
end
|
|
227
234
|
end
|
|
228
235
|
end
|
|
229
236
|
end
|
|
@@ -21,40 +21,63 @@ module MilkTea
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def self.nullable(base)
|
|
24
|
-
_intern([:nullable, base]) { Nullable.new(base) }
|
|
24
|
+
_intern([:nullable, type_signature(base)]) { Nullable.new(base) }
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def self.generic_instance(name, arguments)
|
|
28
28
|
args = arguments.freeze
|
|
29
|
-
_intern([:generic, name, args]) { GenericInstance.new(name, args) }
|
|
29
|
+
_intern([:generic, name, args.map { |a| type_signature(a) }.freeze]) { GenericInstance.new(name, args) }
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def self.span(element_type)
|
|
33
|
-
_intern([:span, element_type]) { Span.new(element_type) }
|
|
33
|
+
_intern([:span, type_signature(element_type)]) { Span.new(element_type) }
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def self.task(result_type)
|
|
37
|
-
_intern([:task, result_type]) { Task.new(result_type) }
|
|
37
|
+
_intern([:task, type_signature(result_type)]) { Task.new(result_type) }
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def self.string_view
|
|
41
41
|
_intern([:string_view]) { StringView.new }
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
#
|
|
45
|
-
# (assignability must not depend on parameter names), so
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
# never resets the registry between checks)
|
|
44
|
+
# Name-sensitive signature for intern keys. Parameter#eql? is
|
|
45
|
+
# name-insensitive (assignability must not depend on parameter names), so
|
|
46
|
+
# Function/Proc objects (and any wrapper containing them) that differ only
|
|
47
|
+
# in parameter names collide under Hash/==. Pool keys that embed such
|
|
48
|
+
# types raw therefore conflate fn(value: int) with fn(arg0: int) in a
|
|
49
|
+
# long-lived pool (the LSP never resets the registry between checks),
|
|
50
|
+
# leaking one program's parameter names into another's generated C.
|
|
51
|
+
# Embedding names here keeps distinct signatures distinct.
|
|
52
|
+
def self.type_signature(type)
|
|
53
|
+
case type
|
|
54
|
+
when Function
|
|
55
|
+
[:function, type.name, param_signature(type.params), type_signature(type.return_type), type_signature(type.receiver_type), type.receiver_editable, type.variadic, type.external]
|
|
56
|
+
when Proc
|
|
57
|
+
[:proc, param_signature(type.params), type_signature(type.return_type)]
|
|
58
|
+
when Nullable
|
|
59
|
+
[:nullable, type_signature(type.base)]
|
|
60
|
+
when GenericInstance
|
|
61
|
+
[:generic, type.name, type.arguments.map { |a| type_signature(a) }]
|
|
62
|
+
when Tuple
|
|
63
|
+
[:tuple, type.element_types.map { |t| type_signature(t) }, type.field_names]
|
|
64
|
+
when Span
|
|
65
|
+
[:span, type_signature(type.element_type)]
|
|
66
|
+
when Task
|
|
67
|
+
[:task, type_signature(type.result_type)]
|
|
68
|
+
else
|
|
69
|
+
type
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
50
73
|
def self.param_signature(params)
|
|
51
|
-
params.map { |p| [p.name, p.type, p.mutable, p.passing_mode, p.boundary_type] }
|
|
74
|
+
params.map { |p| [p.name, type_signature(p.type), p.mutable, p.passing_mode, p.boundary_type] }
|
|
52
75
|
end
|
|
53
76
|
|
|
54
77
|
def self.function(name, params:, return_type:, receiver_type: nil, receiver_editable: false, variadic: false, external: false)
|
|
55
78
|
params_frozen = params.freeze
|
|
56
79
|
param_key = param_signature(params_frozen)
|
|
57
|
-
_intern([:function, name, param_key, return_type, receiver_type, receiver_editable, variadic, external]) {
|
|
80
|
+
_intern([:function, name, param_key, type_signature(return_type), type_signature(receiver_type), receiver_editable, variadic, external]) {
|
|
58
81
|
Function.new(name, params: params_frozen, return_type: return_type, receiver_type: receiver_type, receiver_editable: receiver_editable, variadic: variadic, external: external)
|
|
59
82
|
}
|
|
60
83
|
end
|
|
@@ -62,7 +85,7 @@ module MilkTea
|
|
|
62
85
|
def self.proc(params:, return_type:)
|
|
63
86
|
params_frozen = params.freeze
|
|
64
87
|
param_key = param_signature(params_frozen)
|
|
65
|
-
_intern([:proc, param_key, return_type]) { Proc.new(params: params_frozen, return_type: return_type) }
|
|
88
|
+
_intern([:proc, param_key, type_signature(return_type)]) { Proc.new(params: params_frozen, return_type: return_type) }
|
|
66
89
|
end
|
|
67
90
|
|
|
68
91
|
def self.parameter(name, type, mutable: false, passing_mode: :plain, boundary_type: nil)
|
|
@@ -74,15 +97,15 @@ module MilkTea
|
|
|
74
97
|
def self.tuple(element_types, field_names: nil)
|
|
75
98
|
et_frozen = element_types.freeze
|
|
76
99
|
fn_frozen = field_names&.freeze
|
|
77
|
-
_intern([:tuple, et_frozen, fn_frozen]) { Tuple.new(et_frozen, field_names: fn_frozen) }
|
|
100
|
+
_intern([:tuple, et_frozen.map { |t| type_signature(t) }.freeze, fn_frozen]) { Tuple.new(et_frozen, field_names: fn_frozen) }
|
|
78
101
|
end
|
|
79
102
|
|
|
80
103
|
def self.soa(element_type, count:)
|
|
81
|
-
_intern([:soa, element_type, count]) { SoA.new(element_type, count: count) }
|
|
104
|
+
_intern([:soa, type_signature(element_type), count]) { SoA.new(element_type, count: count) }
|
|
82
105
|
end
|
|
83
106
|
|
|
84
107
|
def self.simd(element_type, lane_count:)
|
|
85
|
-
_intern([:simd, element_type, lane_count]) { Simd.new(element_type, lane_count: lane_count) }
|
|
108
|
+
_intern([:simd, type_signature(element_type), lane_count]) { Simd.new(element_type, lane_count: lane_count) }
|
|
86
109
|
end
|
|
87
110
|
|
|
88
111
|
def self.lifetime_ref(name)
|
|
@@ -86,7 +86,7 @@ module MilkTea
|
|
|
86
86
|
rescue StandardError
|
|
87
87
|
nil
|
|
88
88
|
end
|
|
89
|
-
clear_shared_module_cache if previous_content != disk_content
|
|
89
|
+
@workspace.clear_shared_module_cache if previous_content != disk_content
|
|
90
90
|
unless defined?(@pull_diagnostics_active) && @pull_diagnostics_active
|
|
91
91
|
@protocol.write_notification('textDocument/publishDiagnostics', {
|
|
92
92
|
uri: uri,
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mt-lang
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Long (Teefan) Tran
|
|
@@ -205,6 +205,7 @@ files:
|
|
|
205
205
|
- lib/milk_tea/core/c_backend/type_declaration.rb
|
|
206
206
|
- lib/milk_tea/core/c_backend/type_system.rb
|
|
207
207
|
- lib/milk_tea/core/compile_time.rb
|
|
208
|
+
- lib/milk_tea/core/compile_time/method_folding.rb
|
|
208
209
|
- lib/milk_tea/core/control_flow.rb
|
|
209
210
|
- lib/milk_tea/core/control_flow/builder.rb
|
|
210
211
|
- lib/milk_tea/core/control_flow/constant_propagation.rb
|
|
@@ -628,7 +629,7 @@ metadata:
|
|
|
628
629
|
homepage_uri: https://teefan.github.io/mt-lang/
|
|
629
630
|
source_code_uri: https://github.com/teefan/mt-lang
|
|
630
631
|
post_install_message: |
|
|
631
|
-
Milk Tea 0.
|
|
632
|
+
Milk Tea 0.4.0 installed!
|
|
632
633
|
|
|
633
634
|
System requirements:
|
|
634
635
|
- A C compiler (gcc or clang) must be available on PATH
|