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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +24 -1
  3. data/docs/index.html +2 -1
  4. data/docs/language-design.md +2 -0
  5. data/docs/language-manual.md +16 -1
  6. data/lib/milk_tea/base.rb +1 -1
  7. data/lib/milk_tea/core/ast.rb +2 -2
  8. data/lib/milk_tea/core/c_backend/expressions.rb +11 -0
  9. data/lib/milk_tea/core/c_backend/type_collectors.rb +49 -0
  10. data/lib/milk_tea/core/c_backend/type_declaration.rb +7 -0
  11. data/lib/milk_tea/core/c_backend/type_system.rb +12 -0
  12. data/lib/milk_tea/core/c_backend.rb +8 -0
  13. data/lib/milk_tea/core/compatibility_helpers.rb +4 -0
  14. data/lib/milk_tea/core/compile_time.rb +16 -0
  15. data/lib/milk_tea/core/ir.rb +1 -0
  16. data/lib/milk_tea/core/keywords.rb +1 -1
  17. data/lib/milk_tea/core/lowering/block.rb +48 -16
  18. data/lib/milk_tea/core/lowering/calls.rb +75 -1
  19. data/lib/milk_tea/core/lowering/declarations.rb +7 -0
  20. data/lib/milk_tea/core/lowering/expressions.rb +39 -8
  21. data/lib/milk_tea/core/lowering/functions.rb +1 -1
  22. data/lib/milk_tea/core/lowering/resolve.rb +70 -5
  23. data/lib/milk_tea/core/lowering/utils.rb +26 -0
  24. data/lib/milk_tea/core/module_binder.rb +4 -0
  25. data/lib/milk_tea/core/parser/expressions.rb +11 -3
  26. data/lib/milk_tea/core/parser/statements.rb +2 -2
  27. data/lib/milk_tea/core/parser/types.rb +8 -1
  28. data/lib/milk_tea/core/semantic_analyzer/calls.rb +97 -4
  29. data/lib/milk_tea/core/semantic_analyzer/expressions.rb +52 -2
  30. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +7 -0
  31. data/lib/milk_tea/core/semantic_analyzer/generics.rb +40 -0
  32. data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +11 -0
  33. data/lib/milk_tea/core/semantic_analyzer/statements.rb +21 -4
  34. data/lib/milk_tea/core/semantic_analyzer/top_level.rb +23 -0
  35. data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +37 -0
  36. data/lib/milk_tea/core/types/layout.rb +7 -0
  37. data/lib/milk_tea/core/types/predicates.rb +44 -3
  38. data/lib/milk_tea/core/types/registry.rb +4 -0
  39. data/lib/milk_tea/core/types/types.rb +42 -0
  40. data/lib/milk_tea/core/types/visitor.rb +2 -0
  41. data/lib/milk_tea/lsp/server/completion.rb +1 -1
  42. data/lib/milk_tea/lsp/server/hover.rb +8 -1
  43. data/std/raylib.mt +14 -14
  44. 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 |argument, index|
18
- argument.is_a?(Types::LiteralTypeArg) ? argument : Types::TypeVar.new("__receiver_arg#{index}")
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
@@ -15,7 +15,7 @@ module MilkTea
15
15
  ].freeze
16
16
 
17
17
  TYPE_CONSTRUCTOR_KEYWORDS = %w[
18
- ptr ref span array dyn Option Result Task SoA str_buffer const_ptr
18
+ ptr ref span array dyn Option Result Task SoA str_buffer const_ptr simd
19
19
  ].freeze
20
20
 
21
21
  private
@@ -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, v_1: Vector2, v_2: Vector2, v_3: Vector2, color: Color) -> void = c.ImageDrawTriangle
456
- public foreign function image_draw_triangle_ex(inout dst: Image, v_1: Vector2, v_2: Vector2, v_3: Vector2, c_1: Color, c_2: Color, c_3: Color) -> void = c.ImageDrawTriangleEx
457
- public foreign function image_draw_triangle_lines(inout dst: Image, v_1: Vector2, v_2: Vector2, v_3: Vector2, color: Color) -> void = c.ImageDrawTriangleLines
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(v_1: Vector2, v_2: Vector2, v_3: Vector2, color: Color) -> void:
930
- image_draw_triangle(this, v_1, v_2, v_3, color)
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
- v_1: Vector2,
935
- v_2: Vector2,
936
- v_3: Vector2,
937
- c_1: Color,
938
- c_2: Color,
939
- c_3: Color
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, v_1, v_2, v_3, c_1, c_2, c_3)
941
+ image_draw_triangle_ex(this, v1, v2, v3, c1, c2, c3)
942
942
 
943
943
 
944
- public editable function draw_triangle_lines(v_1: Vector2, v_2: Vector2, v_3: Vector2, color: Color) -> void:
945
- image_draw_triangle_lines(this, v_1, v_2, v_3, color)
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.2.22
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.2.22 installed!
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