mt-lang 0.2.22 → 0.3.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 +24 -1
- data/docs/index.html +2 -1
- data/docs/language-design.md +2 -0
- data/docs/language-manual.md +16 -1
- data/lib/milk_tea/base.rb +1 -1
- data/lib/milk_tea/core/ast.rb +2 -2
- data/lib/milk_tea/core/c_backend/expressions.rb +11 -0
- data/lib/milk_tea/core/c_backend/type_collectors.rb +49 -0
- data/lib/milk_tea/core/c_backend/type_declaration.rb +7 -0
- data/lib/milk_tea/core/c_backend/type_system.rb +12 -0
- data/lib/milk_tea/core/c_backend.rb +8 -0
- data/lib/milk_tea/core/compatibility_helpers.rb +4 -0
- data/lib/milk_tea/core/compile_time.rb +16 -0
- data/lib/milk_tea/core/ir.rb +1 -0
- data/lib/milk_tea/core/keywords.rb +1 -1
- data/lib/milk_tea/core/lowering/block.rb +48 -16
- data/lib/milk_tea/core/lowering/calls.rb +75 -1
- data/lib/milk_tea/core/lowering/declarations.rb +7 -0
- data/lib/milk_tea/core/lowering/expressions.rb +39 -8
- data/lib/milk_tea/core/lowering/functions.rb +1 -1
- data/lib/milk_tea/core/lowering/resolve.rb +70 -5
- data/lib/milk_tea/core/lowering/utils.rb +26 -0
- data/lib/milk_tea/core/module_binder.rb +4 -0
- data/lib/milk_tea/core/parser/expressions.rb +11 -3
- data/lib/milk_tea/core/parser/statements.rb +2 -2
- data/lib/milk_tea/core/parser/types.rb +8 -1
- data/lib/milk_tea/core/semantic_analyzer/calls.rb +97 -4
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +52 -2
- data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +7 -0
- data/lib/milk_tea/core/semantic_analyzer/generics.rb +40 -0
- data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +11 -0
- data/lib/milk_tea/core/semantic_analyzer/statements.rb +21 -4
- data/lib/milk_tea/core/semantic_analyzer/top_level.rb +23 -0
- data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +37 -0
- data/lib/milk_tea/core/types/layout.rb +7 -0
- data/lib/milk_tea/core/types/predicates.rb +44 -3
- data/lib/milk_tea/core/types/registry.rb +4 -0
- data/lib/milk_tea/core/types/types.rb +42 -0
- data/lib/milk_tea/core/types/visitor.rb +2 -0
- data/lib/milk_tea/lsp/server/completion.rb +1 -1
- data/lib/milk_tea/lsp/server/hover.rb +8 -1
- data/std/raylib.mt +14 -14
- metadata +2 -2
|
@@ -291,6 +291,8 @@ module MilkTea
|
|
|
291
291
|
|
|
292
292
|
return Types::Registry.soa(arguments[0], count: arguments[1].value) if name == "SoA"
|
|
293
293
|
|
|
294
|
+
return Types::Registry.simd(arguments[0], lane_count: arguments[1].value) if name == "simd"
|
|
295
|
+
|
|
294
296
|
arguments = [type_ref.lifetime] + arguments if name == "ref" && type_ref.lifetime
|
|
295
297
|
return Types::Registry.generic_instance(name, arguments)
|
|
296
298
|
end
|
|
@@ -684,6 +686,7 @@ module MilkTea
|
|
|
684
686
|
return true if matrix_type?(type)
|
|
685
687
|
return true if quaternion_type?(type)
|
|
686
688
|
return true if soa_type?(type)
|
|
689
|
+
return true if simd_type?(type)
|
|
687
690
|
return true if atomic_type?(type)
|
|
688
691
|
|
|
689
692
|
raise_sema_error("#{operation} does not support type #{type}")
|
|
@@ -717,6 +720,10 @@ module MilkTea
|
|
|
717
720
|
type.is_a?(Types::SoA)
|
|
718
721
|
end
|
|
719
722
|
|
|
723
|
+
def simd_type?(type)
|
|
724
|
+
type.is_a?(Types::Simd)
|
|
725
|
+
end
|
|
726
|
+
|
|
720
727
|
def array_type?(type)
|
|
721
728
|
type.is_a?(Types::GenericInstance) && type.name == "array" && type.arguments.length == 2 &&
|
|
722
729
|
!type.arguments.first.is_a?(Types::LiteralTypeArg) && type.arguments[1].is_a?(Types::LiteralTypeArg)
|
|
@@ -929,6 +936,10 @@ module MilkTea
|
|
|
929
936
|
return receiver_type.element_type
|
|
930
937
|
end
|
|
931
938
|
|
|
939
|
+
if simd_type?(receiver_type)
|
|
940
|
+
return receiver_type.element_type
|
|
941
|
+
end
|
|
942
|
+
|
|
932
943
|
if pointer_type?(receiver_type)
|
|
933
944
|
require_unsafe!("pointer indexing requires unsafe") unless own_type?(receiver_type)
|
|
934
945
|
|
|
@@ -511,15 +511,15 @@ module MilkTea
|
|
|
511
511
|
)
|
|
512
512
|
end
|
|
513
513
|
when "%="
|
|
514
|
-
unless common_integer_type(target_type, value_type) == target_type
|
|
514
|
+
unless common_integer_type(target_type, value_type) == target_type || simd_mod_result(target_type, value_type)
|
|
515
515
|
raise_sema_error("operator #{statement.operator} requires compatible integer types, got #{target_type} and #{value_type}")
|
|
516
516
|
end
|
|
517
517
|
when "&=", "|=", "^="
|
|
518
|
-
unless target_type == value_type && bitwise_type?(target_type)
|
|
518
|
+
unless (target_type == value_type && bitwise_type?(target_type)) || (simd_type?(target_type) && simd_type?(value_type) && target_type == value_type)
|
|
519
519
|
raise_sema_error("operator #{statement.operator} requires matching integer or flags types, got #{target_type} and #{value_type}")
|
|
520
520
|
end
|
|
521
521
|
when "<<=", ">>="
|
|
522
|
-
unless target_type.is_a?(Types::Primitive) && target_type.integer? && value_type.is_a?(Types::Primitive) && value_type.integer?
|
|
522
|
+
unless (target_type.is_a?(Types::Primitive) && target_type.integer? && value_type.is_a?(Types::Primitive) && value_type.integer?) || simd_shift_result(target_type, value_type)
|
|
523
523
|
raise_sema_error("operator #{statement.operator} requires integer operands, got #{target_type} and #{value_type}")
|
|
524
524
|
end
|
|
525
525
|
else
|
|
@@ -645,8 +645,25 @@ module MilkTea
|
|
|
645
645
|
check_block(arm.body, scopes:, return_type:, allow_return:)
|
|
646
646
|
next
|
|
647
647
|
end
|
|
648
|
+
if arm.pattern.is_a?(AST::RangeExpr)
|
|
649
|
+
start_val = arm.pattern.start_expr
|
|
650
|
+
end_val = arm.pattern.end_expr
|
|
651
|
+
unless (start_val.is_a?(AST::IntegerLiteral) || start_val.is_a?(AST::CharLiteral)) &&
|
|
652
|
+
(end_val.is_a?(AST::IntegerLiteral) || end_val.is_a?(AST::CharLiteral))
|
|
653
|
+
raise_sema_error("range match arm bounds must be integer or char literals, got #{start_val.class.name}..#{end_val.class.name}")
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
raise_sema_error("range match arm start #{start_val.value} must be <= end #{end_val.value}") if start_val.value > end_val.value
|
|
657
|
+
|
|
658
|
+
range_key = [start_val.value, end_val.value]
|
|
659
|
+
raise_sema_error("duplicate match arm range #{range_key[0]}..#{range_key[1]}") if covered_values.key?(range_key)
|
|
660
|
+
|
|
661
|
+
covered_values[range_key] = true
|
|
662
|
+
check_block(arm.body, scopes:, return_type:, allow_return:)
|
|
663
|
+
next
|
|
664
|
+
end
|
|
648
665
|
unless arm.pattern.is_a?(AST::IntegerLiteral) || arm.pattern.is_a?(AST::CharLiteral)
|
|
649
|
-
raise_sema_error("match arm for integer scrutinee must be an integer literal, char literal, or _, got #{arm.pattern.class.name}")
|
|
666
|
+
raise_sema_error("match arm for integer scrutinee must be an integer literal, char literal, range, or _, got #{arm.pattern.class.name}")
|
|
650
667
|
end
|
|
651
668
|
value = arm.pattern.value
|
|
652
669
|
raise_sema_error("duplicate match arm value #{value}") if covered_values.key?(value)
|
|
@@ -324,6 +324,29 @@ module MilkTea
|
|
|
324
324
|
def evaluate_compile_time_call(expression, scopes: nil)
|
|
325
325
|
case expression.callee
|
|
326
326
|
when AST::Identifier
|
|
327
|
+
if (struct_type = @ctx.types[expression.callee.name]) && struct_type.is_a?(Types::Struct)
|
|
328
|
+
fields = {}
|
|
329
|
+
expression.arguments.each do |argument|
|
|
330
|
+
val = CompileTime.evaluate(argument.value, resolve_identifier: lambda { |id|
|
|
331
|
+
if scopes
|
|
332
|
+
binding = lookup_value(id.name, scopes)
|
|
333
|
+
return binding.const_value unless binding&.const_value.nil?
|
|
334
|
+
end
|
|
335
|
+
resolve_current_module_const_value(id.name)
|
|
336
|
+
}, resolve_member_access: lambda { |ma|
|
|
337
|
+
if (receiver_type = resolve_type_expression(ma.receiver))
|
|
338
|
+
next resolve_enum_member_const_value(receiver_type, ma.member)
|
|
339
|
+
end
|
|
340
|
+
nil
|
|
341
|
+
}, resolve_call: lambda { |inner_call|
|
|
342
|
+
evaluate_compile_time_call(inner_call, scopes:)
|
|
343
|
+
})
|
|
344
|
+
return nil unless val
|
|
345
|
+
fields[argument.name] = val
|
|
346
|
+
end
|
|
347
|
+
return fields
|
|
348
|
+
end
|
|
349
|
+
|
|
327
350
|
case expression.callee.name
|
|
328
351
|
when "field_of"
|
|
329
352
|
evaluate_field_of_call(expression.arguments, scopes: scopes || [])
|
|
@@ -218,12 +218,49 @@ module MilkTea
|
|
|
218
218
|
return vector_op_result(operator, left_type, right_type) if vector_type?(left_type) || vector_type?(right_type)
|
|
219
219
|
return matrix_op_result(operator, left_type, right_type) if matrix_type?(left_type) || matrix_type?(right_type)
|
|
220
220
|
return quaternion_op_result(operator, left_type, right_type) if quaternion_type?(left_type) || quaternion_type?(right_type)
|
|
221
|
+
return simd_op_result(operator, left_type, right_type) if simd_type?(left_type) || simd_type?(right_type)
|
|
221
222
|
|
|
222
223
|
nil
|
|
223
224
|
end
|
|
224
225
|
|
|
225
226
|
private
|
|
226
227
|
|
|
228
|
+
def simd_op_result(operator, left_type, right_type)
|
|
229
|
+
if simd_type?(left_type) && simd_type?(right_type) && left_type.element_type == right_type.element_type && left_type.lane_count == right_type.lane_count
|
|
230
|
+
return left_type if operator == "+" || operator == "-" || operator == "*" || operator == "/"
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
if simd_type?(left_type) && right_type.numeric? && right_type == left_type.element_type
|
|
234
|
+
return left_type if operator == "*" || operator == "/"
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
if left_type.numeric? && simd_type?(right_type) && left_type == right_type.element_type
|
|
238
|
+
return right_type if operator == "*"
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
nil
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def simd_bitwise_result(left_type, right_type)
|
|
245
|
+
return nil unless simd_type?(left_type) && simd_type?(right_type) && left_type == right_type
|
|
246
|
+
|
|
247
|
+
left_type
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def simd_mod_result(left_type, right_type)
|
|
251
|
+
return nil unless simd_type?(left_type) && left_type.element_type.integer?
|
|
252
|
+
return nil unless right_type == left_type.element_type || (simd_type?(right_type) && right_type == left_type)
|
|
253
|
+
|
|
254
|
+
left_type
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def simd_shift_result(left_type, right_type)
|
|
258
|
+
return nil unless simd_type?(left_type) && left_type.element_type.integer?
|
|
259
|
+
return nil unless right_type.is_a?(Types::Primitive) && right_type.integer?
|
|
260
|
+
|
|
261
|
+
left_type
|
|
262
|
+
end
|
|
263
|
+
|
|
227
264
|
def vector_op_result(operator, left_type, right_type)
|
|
228
265
|
if vector_type?(left_type) && vector_type?(right_type) && left_type.element_type == right_type.element_type
|
|
229
266
|
return left_type if operator == "+" || operator == "-"
|
|
@@ -70,6 +70,13 @@ module MilkTea
|
|
|
70
70
|
end
|
|
71
71
|
when Types::GenericInstance
|
|
72
72
|
generic_layout(type, stack)
|
|
73
|
+
when Types::Simd
|
|
74
|
+
element_layout = size_and_alignment(type.element_type, stack)
|
|
75
|
+
return unless element_layout
|
|
76
|
+
|
|
77
|
+
total = element_layout.first * type.lane_count
|
|
78
|
+
alignment = total > 16 ? 32 : 16
|
|
79
|
+
[total, alignment]
|
|
73
80
|
else
|
|
74
81
|
nil
|
|
75
82
|
end
|
|
@@ -4,18 +4,38 @@ module MilkTea
|
|
|
4
4
|
module TypePredicates
|
|
5
5
|
def method_dispatch_receiver_type(receiver_type)
|
|
6
6
|
return receiver_type.definition if receiver_type.is_a?(Types::StructInstance) || receiver_type.is_a?(Types::VariantInstance)
|
|
7
|
+
|
|
7
8
|
if receiver_type.is_a?(Types::Nullable)
|
|
8
9
|
dispatch_base_type = method_dispatch_receiver_type(receiver_type.base)
|
|
9
10
|
return receiver_type if dispatch_base_type == receiver_type.base
|
|
10
11
|
|
|
11
12
|
return Types::Registry.nullable(dispatch_base_type)
|
|
12
13
|
end
|
|
14
|
+
|
|
15
|
+
case receiver_type
|
|
16
|
+
when Types::Span
|
|
17
|
+
normalized = Types::Registry.span(Types::TypeVar.new("__receiver_arg0"))
|
|
18
|
+
return normalized == receiver_type ? receiver_type : normalized
|
|
19
|
+
when Types::SoA
|
|
20
|
+
normalized = Types::Registry.soa(Types::TypeVar.new("__receiver_arg0"), count: 0)
|
|
21
|
+
return normalized == receiver_type ? receiver_type : normalized
|
|
22
|
+
when Types::Simd
|
|
23
|
+
normalized = Types::Registry.simd(Types::TypeVar.new("__receiver_arg0"), lane_count: 0)
|
|
24
|
+
return normalized == receiver_type ? receiver_type : normalized
|
|
25
|
+
when Types::Task
|
|
26
|
+
normalized = Types::Registry.task(Types::TypeVar.new("__receiver_arg0"))
|
|
27
|
+
return normalized == receiver_type ? receiver_type : normalized
|
|
28
|
+
when Types::Dyn
|
|
29
|
+
normalized = Types::Registry.dyn(Types::TypeVar.new("__receiver_arg0"))
|
|
30
|
+
return normalized == receiver_type ? receiver_type : normalized
|
|
31
|
+
end
|
|
32
|
+
|
|
13
33
|
return receiver_type unless receiver_type.is_a?(Types::GenericInstance)
|
|
14
34
|
|
|
15
35
|
dispatch_receiver_type = Types::Registry.generic_instance(
|
|
16
36
|
receiver_type.name,
|
|
17
|
-
receiver_type.arguments.each_with_index.map do |
|
|
18
|
-
|
|
37
|
+
receiver_type.arguments.each_with_index.map do |_argument, index|
|
|
38
|
+
Types::TypeVar.new("__receiver_arg#{index}")
|
|
19
39
|
end,
|
|
20
40
|
)
|
|
21
41
|
dispatch_receiver_type == receiver_type ? receiver_type : dispatch_receiver_type
|
|
@@ -458,9 +478,11 @@ module MilkTea
|
|
|
458
478
|
actual_count == function_type.params.length
|
|
459
479
|
end
|
|
460
480
|
|
|
461
|
-
def arity_error_message(function_type, name, actual_count)
|
|
481
|
+
def arity_error_message(function_type, name, actual_count, required_count: nil)
|
|
462
482
|
if function_type.is_a?(Types::Function) && function_type.variadic
|
|
463
483
|
"function #{name} expects at least #{function_type.params.length} arguments, got #{actual_count}"
|
|
484
|
+
elsif required_count && required_count < function_type.params.length
|
|
485
|
+
"function #{name} expects #{required_count}..#{function_type.params.length} arguments, got #{actual_count}"
|
|
464
486
|
else
|
|
465
487
|
"function #{name} expects #{function_type.params.length} arguments, got #{actual_count}"
|
|
466
488
|
end
|
|
@@ -564,6 +586,17 @@ module MilkTea
|
|
|
564
586
|
error.call("SoA element type must be a struct with fields") unless arguments.first.respond_to?(:fields) && arguments.first.fields.any?
|
|
565
587
|
error.call("SoA length must be an integer literal, named const, or type parameter") unless generic_integer_type_argument?(arguments[1])
|
|
566
588
|
error.call("SoA length must be positive") if integer_type_argument?(arguments[1]) && !arguments[1].value.positive?
|
|
589
|
+
when "simd"
|
|
590
|
+
error.call("simd requires exactly two type arguments") unless arguments.length == 2
|
|
591
|
+
error.call("simd element type must be a type") if arguments.first.is_a?(Types::LiteralTypeArg)
|
|
592
|
+
error.call("simd element type must be a numeric primitive") unless arguments.first.is_a?(Types::Primitive) && arguments.first.numeric?
|
|
593
|
+
error.call("simd lane count must be an integer literal, named const, or type parameter") unless generic_integer_type_argument?(arguments[1])
|
|
594
|
+
error.call("simd lane count must be positive") if integer_type_argument?(arguments[1]) && !arguments[1].value.positive?
|
|
595
|
+
if integer_type_argument?(arguments[1])
|
|
596
|
+
width_bytes = arguments.first.name == "double" || arguments.first.name == "long" || arguments.first.name == "ulong" ? arguments[1].value * 8 : arguments.first.name == "int" || arguments.first.name == "uint" || arguments.first.name == "float" ? arguments[1].value * 4 : arguments.first.name == "short" || arguments.first.name == "ushort" ? arguments[1].value * 2 : arguments[1].value
|
|
597
|
+
valid = [16, 32].include?(width_bytes)
|
|
598
|
+
error.call("simd width must be 128 or 256 bits, got #{width_bytes * 8}") unless valid
|
|
599
|
+
end
|
|
567
600
|
when "str_buffer"
|
|
568
601
|
error.call("str_buffer requires exactly one type argument") unless arguments.length == 1
|
|
569
602
|
error.call("str_buffer capacity must be an integer literal, named const, or type parameter") unless generic_integer_type_argument?(arguments.first)
|
|
@@ -598,6 +631,14 @@ module MilkTea
|
|
|
598
631
|
type.arguments.length == 2 && type.arguments[1].is_a?(Types::LiteralTypeArg) && type.arguments[1].value.is_a?(Integer)
|
|
599
632
|
end
|
|
600
633
|
|
|
634
|
+
def soa_type?(type)
|
|
635
|
+
type.is_a?(Types::SoA)
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
def simd_type?(type)
|
|
639
|
+
type.is_a?(Types::Simd)
|
|
640
|
+
end
|
|
641
|
+
|
|
601
642
|
def array_length(type)
|
|
602
643
|
type.arguments[1].value
|
|
603
644
|
end
|
|
@@ -71,6 +71,10 @@ module MilkTea
|
|
|
71
71
|
_intern([:soa, element_type, count]) { SoA.new(element_type, count: count) }
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
+
def simd(element_type, lane_count:)
|
|
75
|
+
_intern([:simd, element_type, lane_count]) { Simd.new(element_type, lane_count: lane_count) }
|
|
76
|
+
end
|
|
77
|
+
|
|
74
78
|
def lifetime_ref(name)
|
|
75
79
|
LifetimeRef.new(name)
|
|
76
80
|
end
|
|
@@ -1560,6 +1560,48 @@ module MilkTea
|
|
|
1560
1560
|
end
|
|
1561
1561
|
end
|
|
1562
1562
|
|
|
1563
|
+
class Simd < Base
|
|
1564
|
+
attr_reader :name, :element_type, :lane_count, :module_name
|
|
1565
|
+
|
|
1566
|
+
def initialize(element_type, lane_count:)
|
|
1567
|
+
@element_type = element_type
|
|
1568
|
+
@lane_count = lane_count
|
|
1569
|
+
@name = "simd[#{element_type}, #{lane_count}]"
|
|
1570
|
+
@module_name = nil
|
|
1571
|
+
@fields = {}.freeze
|
|
1572
|
+
@hash = [self.class, element_type, lane_count].hash
|
|
1573
|
+
freeze
|
|
1574
|
+
end
|
|
1575
|
+
|
|
1576
|
+
def eql?(other)
|
|
1577
|
+
other.is_a?(Simd) && other.element_type == element_type && other.lane_count == lane_count
|
|
1578
|
+
end
|
|
1579
|
+
|
|
1580
|
+
alias == eql?
|
|
1581
|
+
|
|
1582
|
+
attr_reader :hash
|
|
1583
|
+
|
|
1584
|
+
def fields
|
|
1585
|
+
@fields
|
|
1586
|
+
end
|
|
1587
|
+
|
|
1588
|
+
def field(name)
|
|
1589
|
+
@fields[name]
|
|
1590
|
+
end
|
|
1591
|
+
|
|
1592
|
+
def numeric?
|
|
1593
|
+
true
|
|
1594
|
+
end
|
|
1595
|
+
|
|
1596
|
+
def to_s
|
|
1597
|
+
@name
|
|
1598
|
+
end
|
|
1599
|
+
|
|
1600
|
+
def children
|
|
1601
|
+
[element_type]
|
|
1602
|
+
end
|
|
1603
|
+
end
|
|
1604
|
+
|
|
1563
1605
|
class Tuple < Base
|
|
1564
1606
|
attr_reader :element_types, :field_names
|
|
1565
1607
|
|
|
@@ -38,6 +38,7 @@ module MilkTea
|
|
|
38
38
|
when Types::Tuple then visit_tuple(type)
|
|
39
39
|
when Types::Dyn then visit_dyn(type)
|
|
40
40
|
when Types::SoA then visit_soa(type)
|
|
41
|
+
when Types::Simd then visit_simd(type)
|
|
41
42
|
when Types::Event then visit_event(type)
|
|
42
43
|
when Types::LifetimeRef then visit_lifetime_ref(type)
|
|
43
44
|
else visit_default(type)
|
|
@@ -66,6 +67,7 @@ module MilkTea
|
|
|
66
67
|
def visit_tuple(type); visit_children(type); end
|
|
67
68
|
def visit_dyn(type); visit_children(type); end
|
|
68
69
|
def visit_soa(type); visit_children(type); end
|
|
70
|
+
def visit_simd(type); visit_children(type); end
|
|
69
71
|
def visit_event(type); visit_children(type); end
|
|
70
72
|
|
|
71
73
|
def visit_type_var(type); end
|
|
@@ -263,6 +263,7 @@ module MilkTea
|
|
|
263
263
|
'Option' => 'Built-in optional type: `Option[T]`. Arms: `some(value: T)` and `none`. Use `let ... else:` or `?` for safe unwrapping.',
|
|
264
264
|
'Result' => 'Built-in result type: `Result[T, E]`. Arms: `success(value: T)` and `failure(error: E)`. Use `let ... else:` or `?` for error propagation.',
|
|
265
265
|
'SoA' => 'Struct-of-Arrays: `SoA[T, N]`. Each struct field becomes a separate array of length `N`. Access `soa[i].field` reads from column `field` at row `i`.',
|
|
266
|
+
'simd' => 'SIMD vector type: `simd[T, N]`. Fixed-width vector of `N` lanes of numeric primitive type `T`. Supports component-wise arithmetic, lane access via `[i]`, and explicit aligned/unaligned load/store. Lowers to GCC/Clang vector extensions for portable, readable C output.',
|
|
266
267
|
'struct_handle' => 'Compile-time handle for a struct type. Obtained via reflection builtins like `fields_of`.',
|
|
267
268
|
'field_handle' => 'Compile-time handle for a struct field. Exposes `.name` and `.type`. Obtained via `field_of` and `fields_of`.',
|
|
268
269
|
'callable_handle' => 'Compile-time handle for a callable declaration. Obtained via `callable_of`. Used with `has_attribute`, `attribute_of`.',
|
|
@@ -1561,7 +1562,7 @@ module MilkTea
|
|
|
1561
1562
|
end
|
|
1562
1563
|
|
|
1563
1564
|
def builtin_type_constructor_hover_info(name, tokens, token_index)
|
|
1564
|
-
return nil unless %w[array span Option Result SoA str_buffer ref ptr const_ptr own Task atomic].include?(name)
|
|
1565
|
+
return nil unless %w[array span Option Result SoA str_buffer ref ptr const_ptr own Task atomic simd].include?(name)
|
|
1565
1566
|
|
|
1566
1567
|
lbracket_index = next_non_trivia_token_index(tokens, token_index + 1)
|
|
1567
1568
|
return nil unless lbracket_index && tokens[lbracket_index].type == :lbracket
|
|
@@ -1580,6 +1581,8 @@ module MilkTea
|
|
|
1580
1581
|
'`span[T](data = ..., len = ...)` constructs a span view over contiguous `T` storage.'
|
|
1581
1582
|
when 'SoA'
|
|
1582
1583
|
'`SoA[T, N](...)` constructs a Struct-of-Arrays value with `N` elements of type `T`. Fields are stored in separate contiguous arrays.'
|
|
1584
|
+
when 'simd'
|
|
1585
|
+
'`simd[T, N](...)` constructs a SIMD vector value with `N` lanes of type `T`. Lanes are stored in a single vector register.'
|
|
1583
1586
|
when 'Option'
|
|
1584
1587
|
'`Option[T]` is a built-in optional type with arms `some(value: T)` and `none`.'
|
|
1585
1588
|
when 'Result'
|
|
@@ -1594,6 +1597,8 @@ module MilkTea
|
|
|
1594
1597
|
"builtin #{specialization}(data = ..., len = ...) -> #{specialization}"
|
|
1595
1598
|
when 'SoA'
|
|
1596
1599
|
"builtin #{specialization}(...) -> #{specialization}"
|
|
1600
|
+
when 'simd'
|
|
1601
|
+
"builtin #{specialization}(...) -> #{specialization}"
|
|
1597
1602
|
when 'Option'
|
|
1598
1603
|
"builtin #{specialization}(some: value = ...) / #{specialization}(none:)"
|
|
1599
1604
|
when 'Result'
|
|
@@ -1610,6 +1615,8 @@ module MilkTea
|
|
|
1610
1615
|
'`span[T]` is the built-in non-owning contiguous view type.'
|
|
1611
1616
|
when 'SoA'
|
|
1612
1617
|
'`SoA[T, N]` is the built-in Struct-of-Arrays type. Each struct field is stored in a separate contiguous array of `N` elements, improving SIMD/cache behavior for parallel field access.'
|
|
1618
|
+
when 'simd'
|
|
1619
|
+
'`simd[T, N]` is the built-in SIMD vector type. Fixed-width vector of `N` numeric lanes. Supports component-wise arithmetic, lane access via `[i]`, and explicit aligned/unaligned load/store.'
|
|
1613
1620
|
when 'Option'
|
|
1614
1621
|
'`Option[T]` is the built-in optional value type with `some(value = ...)` and `none` arms.'
|
|
1615
1622
|
when 'Result'
|
data/std/raylib.mt
CHANGED
|
@@ -452,9 +452,9 @@ public foreign function image_draw_rectangle(inout dst: Image, pos_x: int, pos_y
|
|
|
452
452
|
public foreign function image_draw_rectangle_v(inout dst: Image, position: Vector2, size: Vector2, color: Color) -> void = c.ImageDrawRectangleV
|
|
453
453
|
public foreign function image_draw_rectangle_rec(inout dst: Image, rec: Rectangle, color: Color) -> void = c.ImageDrawRectangleRec
|
|
454
454
|
public foreign function image_draw_rectangle_lines(inout dst: Image, rec: Rectangle, thick: int, color: Color) -> void = c.ImageDrawRectangleLines
|
|
455
|
-
public foreign function image_draw_triangle(inout dst: Image,
|
|
456
|
-
public foreign function image_draw_triangle_ex(inout dst: Image,
|
|
457
|
-
public foreign function image_draw_triangle_lines(inout dst: Image,
|
|
455
|
+
public foreign function image_draw_triangle(inout dst: Image, v1: Vector2, v2: Vector2, v3: Vector2, color: Color) -> void = c.ImageDrawTriangle
|
|
456
|
+
public foreign function image_draw_triangle_ex(inout dst: Image, v1: Vector2, v2: Vector2, v3: Vector2, c1: Color, c2: Color, c3: Color) -> void = c.ImageDrawTriangleEx
|
|
457
|
+
public foreign function image_draw_triangle_lines(inout dst: Image, v1: Vector2, v2: Vector2, v3: Vector2, color: Color) -> void = c.ImageDrawTriangleLines
|
|
458
458
|
public foreign function image_draw_triangle_fan(inout dst: Image, points: const_ptr[Vector2], point_count: int, color: Color) -> void = c.ImageDrawTriangleFan
|
|
459
459
|
public foreign function image_draw_triangle_strip(inout dst: Image, points: const_ptr[Vector2], point_count: int, color: Color) -> void = c.ImageDrawTriangleStrip
|
|
460
460
|
public foreign function image_draw(inout dst: Image, src: Image, src_rec: Rectangle, dst_rec: Rectangle, tint: Color) -> void = c.ImageDraw
|
|
@@ -926,23 +926,23 @@ extending Image:
|
|
|
926
926
|
image_draw_rectangle_lines(this, rec, thick, color)
|
|
927
927
|
|
|
928
928
|
|
|
929
|
-
public editable function draw_triangle(
|
|
930
|
-
image_draw_triangle(this,
|
|
929
|
+
public editable function draw_triangle(v1: Vector2, v2: Vector2, v3: Vector2, color: Color) -> void:
|
|
930
|
+
image_draw_triangle(this, v1, v2, v3, color)
|
|
931
931
|
|
|
932
932
|
|
|
933
933
|
public editable function draw_triangle_ex(
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
934
|
+
v1: Vector2,
|
|
935
|
+
v2: Vector2,
|
|
936
|
+
v3: Vector2,
|
|
937
|
+
c1: Color,
|
|
938
|
+
c2: Color,
|
|
939
|
+
c3: Color
|
|
940
940
|
) -> void:
|
|
941
|
-
image_draw_triangle_ex(this,
|
|
941
|
+
image_draw_triangle_ex(this, v1, v2, v3, c1, c2, c3)
|
|
942
942
|
|
|
943
943
|
|
|
944
|
-
public editable function draw_triangle_lines(
|
|
945
|
-
image_draw_triangle_lines(this,
|
|
944
|
+
public editable function draw_triangle_lines(v1: Vector2, v2: Vector2, v3: Vector2, color: Color) -> void:
|
|
945
|
+
image_draw_triangle_lines(this, v1, v2, v3, color)
|
|
946
946
|
|
|
947
947
|
|
|
948
948
|
public editable function draw_triangle_fan(points: const_ptr[Vector2], point_count: int, color: Color) -> void:
|
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.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Long (Teefan) Tran
|
|
@@ -586,7 +586,7 @@ metadata:
|
|
|
586
586
|
homepage_uri: https://teefan.github.io/mt-lang/
|
|
587
587
|
source_code_uri: https://github.com/teefan/mt-lang
|
|
588
588
|
post_install_message: |
|
|
589
|
-
Milk Tea 0.
|
|
589
|
+
Milk Tea 0.3.0 installed!
|
|
590
590
|
|
|
591
591
|
System requirements:
|
|
592
592
|
- A C compiler (gcc or clang) must be available on PATH
|