mt-lang 0.2.21 → 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 (49) 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/asset_pack.mt +13 -13
  44. data/std/binary.mt +1 -1
  45. data/std/hash.mt +11 -11
  46. data/std/net/session.mt +5 -5
  47. data/std/random.mt +23 -31
  48. data/std/raylib.mt +14 -14
  49. 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/asset_pack.mt CHANGED
@@ -50,18 +50,18 @@ public function open(path: str) -> Result[Reader, Error]:
50
50
  stdio.file_close(file)
51
51
  return Result[Reader, Error].failure(error= Error.invalid_magic)
52
52
 
53
- let version = decode_u16_le(unsafe: header_ptr + 4)
53
+ let version = decode_ushort_le(unsafe: header_ptr + 4)
54
54
  if version != VERSION:
55
55
  stdio.file_close(file)
56
56
  return Result[Reader, Error].failure(error= Error.unsupported_version)
57
57
 
58
- let header_bits = decode_u16_le(unsafe: header_ptr + 6)
58
+ let header_bits = decode_ushort_le(unsafe: header_ptr + 6)
59
59
  if header_bits != HEADER_FLAGS:
60
60
  stdio.file_close(file)
61
61
  return Result[Reader, Error].failure(error= Error.unsupported_flags)
62
62
 
63
- let entry_count = decode_u32_le(unsafe: header_ptr + 8)
64
- let index_size_result = decode_u64_le(unsafe: header_ptr + 12)
63
+ let entry_count = decode_uint_le(unsafe: header_ptr + 8)
64
+ let index_size_result = decode_ulong_le(unsafe: header_ptr + 12)
65
65
  var index_size: ptr_uint
66
66
  match index_size_result:
67
67
  Result.failure as payload:
@@ -70,7 +70,7 @@ public function open(path: str) -> Result[Reader, Error]:
70
70
  Result.success as index_payload:
71
71
  index_size = index_payload.value
72
72
 
73
- let data_offset_result = decode_u64_le(unsafe: header_ptr + 20)
73
+ let data_offset_result = decode_ulong_le(unsafe: header_ptr + 20)
74
74
  var data_offset: ptr_uint
75
75
  match data_offset_result:
76
76
  Result.failure as payload:
@@ -147,12 +147,12 @@ function read_entry_metadata(file: stdio.File?) -> Result[EntryMetadata, Error]:
147
147
  if not read_exact(file, prefix_ptr, ENTRY_PREFIX_SIZE_BYTES):
148
148
  return Result[EntryMetadata, Error].failure(error= Error.malformed_index)
149
149
 
150
- let path_length = ptr_uint<-decode_u32_le(prefix_ptr)
150
+ let path_length = ptr_uint<-decode_uint_le(prefix_ptr)
151
151
  if path_length == 0:
152
152
  return Result[EntryMetadata, Error].failure(error= Error.malformed_index)
153
153
 
154
- let entry_bits = decode_u32_le(unsafe: prefix_ptr + 4)
155
- let data_offset_result = decode_u64_le(unsafe: prefix_ptr + 8)
154
+ let entry_bits = decode_uint_le(unsafe: prefix_ptr + 4)
155
+ let data_offset_result = decode_ulong_le(unsafe: prefix_ptr + 8)
156
156
  var data_offset: ptr_uint
157
157
  match data_offset_result:
158
158
  Result.failure as payload:
@@ -160,7 +160,7 @@ function read_entry_metadata(file: stdio.File?) -> Result[EntryMetadata, Error]:
160
160
  Result.success as data_offset_payload:
161
161
  data_offset = data_offset_payload.value
162
162
 
163
- let stored_size_result = decode_u64_le(unsafe: prefix_ptr + 16)
163
+ let stored_size_result = decode_ulong_le(unsafe: prefix_ptr + 16)
164
164
  var stored_size: ptr_uint
165
165
  match stored_size_result:
166
166
  Result.failure as payload:
@@ -168,7 +168,7 @@ function read_entry_metadata(file: stdio.File?) -> Result[EntryMetadata, Error]:
168
168
  Result.success as stored_size_payload:
169
169
  stored_size = stored_size_payload.value
170
170
 
171
- let unpacked_size_result = decode_u64_le(unsafe: prefix_ptr + 24)
171
+ let unpacked_size_result = decode_ulong_le(unsafe: prefix_ptr + 24)
172
172
  var unpacked_size: ptr_uint
173
173
  match unpacked_size_result:
174
174
  Result.failure as payload:
@@ -228,12 +228,12 @@ function bytes_equal_str(left: ptr[ubyte], left_len: ptr_uint, right: str) -> bo
228
228
  return true
229
229
 
230
230
 
231
- function decode_u16_le(bytes: ptr[ubyte]) -> uint:
231
+ function decode_ushort_le(bytes: ptr[ubyte]) -> uint:
232
232
  unsafe:
233
233
  return uint<-read(bytes + 0) | (uint<-read(bytes + 1) << 8)
234
234
 
235
235
 
236
- function decode_u32_le(bytes: ptr[ubyte]) -> uint:
236
+ function decode_uint_le(bytes: ptr[ubyte]) -> uint:
237
237
  unsafe:
238
238
  return (
239
239
  uint<-read(bytes + 0) |
@@ -243,7 +243,7 @@ function decode_u32_le(bytes: ptr[ubyte]) -> uint:
243
243
  )
244
244
 
245
245
 
246
- function decode_u64_le(bytes: ptr[ubyte]) -> Result[ptr_uint, Error]:
246
+ function decode_ulong_le(bytes: ptr[ubyte]) -> Result[ptr_uint, Error]:
247
247
  if size_of(ptr[void]) < 8:
248
248
  var upper_index: ptr_uint = 4
249
249
  while upper_index < 8:
data/std/binary.mt CHANGED
@@ -114,7 +114,7 @@ extending Writer:
114
114
  public editable function write_uint_at(position: ptr_uint, value: uint) -> void:
115
115
  let buffer_span = this.buffer.as_span()
116
116
  if position + 4 > buffer_span.len:
117
- fatal(c"binary.write_u32_at position out of bounds")
117
+ fatal(c"binary.write_uint_at position out of bounds")
118
118
  unsafe:
119
119
  read(buffer_span.data + position) = ubyte<-(value & 0xFF)
120
120
  read(buffer_span.data + position + 1) = ubyte<-((value >> 8) & 0xFF)
data/std/hash.mt CHANGED
@@ -189,7 +189,7 @@ extending char:
189
189
  # hash mixes the value's bytes (FNV-1a); equal/order use native operators.
190
190
  # ---------------------------------------------------------------------------
191
191
 
192
- function hash_u32(value: uint) -> uint:
192
+ function hash_uint(value: uint) -> uint:
193
193
  let fnv: uint = 0x811C9DC5
194
194
  let prime: uint = 0x01000193
195
195
  var h = fnv
@@ -200,14 +200,14 @@ function hash_u32(value: uint) -> uint:
200
200
  return h
201
201
 
202
202
 
203
- function hash_u64(value: ulong) -> uint:
204
- return hash_u32(uint<-((value >> uint<-(32)) ^ value))
203
+ function hash_ulong(value: ulong) -> uint:
204
+ return hash_uint(uint<-((value >> uint<-(32)) ^ value))
205
205
 
206
206
 
207
207
  extending byte:
208
208
  public static function hash(value: const_ptr[byte]) -> uint:
209
209
  unsafe:
210
- return hash_u32(uint<-(int<-read(ptr[byte]<-value)))
210
+ return hash_uint(uint<-(int<-read(ptr[byte]<-value)))
211
211
 
212
212
 
213
213
  public static function equal(a: const_ptr[byte], b: const_ptr[byte]) -> bool:
@@ -229,7 +229,7 @@ extending byte:
229
229
  extending ubyte:
230
230
  public static function hash(value: const_ptr[ubyte]) -> uint:
231
231
  unsafe:
232
- return hash_u32(uint<-read(ptr[ubyte]<-value))
232
+ return hash_uint(uint<-read(ptr[ubyte]<-value))
233
233
 
234
234
 
235
235
  public static function equal(a: const_ptr[ubyte], b: const_ptr[ubyte]) -> bool:
@@ -251,7 +251,7 @@ extending ubyte:
251
251
  extending short:
252
252
  public static function hash(value: const_ptr[short]) -> uint:
253
253
  unsafe:
254
- return hash_u32(uint<-(int<-read(ptr[short]<-value)))
254
+ return hash_uint(uint<-(int<-read(ptr[short]<-value)))
255
255
 
256
256
 
257
257
  public static function equal(a: const_ptr[short], b: const_ptr[short]) -> bool:
@@ -273,7 +273,7 @@ extending short:
273
273
  extending ushort:
274
274
  public static function hash(value: const_ptr[ushort]) -> uint:
275
275
  unsafe:
276
- return hash_u32(uint<-read(ptr[ushort]<-value))
276
+ return hash_uint(uint<-read(ptr[ushort]<-value))
277
277
 
278
278
 
279
279
  public static function equal(a: const_ptr[ushort], b: const_ptr[ushort]) -> bool:
@@ -295,7 +295,7 @@ extending ushort:
295
295
  extending long:
296
296
  public static function hash(value: const_ptr[long]) -> uint:
297
297
  unsafe:
298
- return hash_u64(ulong<-read(ptr[long]<-value))
298
+ return hash_ulong(ulong<-read(ptr[long]<-value))
299
299
 
300
300
 
301
301
  public static function equal(a: const_ptr[long], b: const_ptr[long]) -> bool:
@@ -317,7 +317,7 @@ extending long:
317
317
  extending ulong:
318
318
  public static function hash(value: const_ptr[ulong]) -> uint:
319
319
  unsafe:
320
- return hash_u64(read(ptr[ulong]<-value))
320
+ return hash_ulong(read(ptr[ulong]<-value))
321
321
 
322
322
 
323
323
  public static function equal(a: const_ptr[ulong], b: const_ptr[ulong]) -> bool:
@@ -339,7 +339,7 @@ extending ulong:
339
339
  extending ptr_int:
340
340
  public static function hash(value: const_ptr[ptr_int]) -> uint:
341
341
  unsafe:
342
- return hash_u64(ulong<-read(ptr[ptr_int]<-value))
342
+ return hash_ulong(ulong<-read(ptr[ptr_int]<-value))
343
343
 
344
344
 
345
345
  public static function equal(a: const_ptr[ptr_int], b: const_ptr[ptr_int]) -> bool:
@@ -410,7 +410,7 @@ public function order_struct[T](a: const_ptr[T], b: const_ptr[T]) -> int:
410
410
  extending ptr_uint:
411
411
  public static function hash(value: const_ptr[ptr_uint]) -> uint:
412
412
  unsafe:
413
- return hash_u64(ulong<-read(ptr[ptr_uint]<-value))
413
+ return hash_ulong(ulong<-read(ptr[ptr_uint]<-value))
414
414
 
415
415
 
416
416
  public static function equal(a: const_ptr[ptr_uint], b: const_ptr[ptr_uint]) -> bool:
data/std/net/session.mt CHANGED
@@ -167,7 +167,7 @@ function generate_handshake_key() -> Result[ulong, net.Error]:
167
167
  return Result[ulong, net.Error].success(value = value)
168
168
 
169
169
 
170
- function decode_u32_at(data: span[ubyte], offset: ptr_uint) -> uint:
170
+ function decode_uint_at(data: span[ubyte], offset: ptr_uint) -> uint:
171
171
  unsafe:
172
172
  return uint<-read(data.data + offset) | (uint<-read(data.data + offset + 1) << 8) | (uint<-read(data.data + offset + 2) << 16) | (uint<-read(data.data + offset + 3) << 24)
173
173
 
@@ -536,7 +536,7 @@ function handle_incoming_conn(conn: ref[Connection], msg: ref[chan.Message]) ->
536
536
  conn.frame_since_last_recv = 0
537
537
  let hb_span = unsafe: span[ubyte](data = span.data + 1, len = span.len - 1)
538
538
  if hb_span.len >= 4:
539
- let echoed = decode_u32_at(hb_span, 0)
539
+ let echoed = decode_uint_at(hb_span, 0)
540
540
  var ack = build_heartbeat_ack(echoed)
541
541
  let peer_addr_result = conn.channel.peer_address()
542
542
  match peer_addr_result:
@@ -555,7 +555,7 @@ function handle_incoming_conn(conn: ref[Connection], msg: ref[chan.Message]) ->
555
555
  conn.frame_since_last_recv = 0
556
556
  let echo_span = unsafe: span[ubyte](data = span.data + 1, len = span.len - 1)
557
557
  if echo_span.len >= 4:
558
- let echoed = decode_u32_at(echo_span, 0)
558
+ let echoed = decode_uint_at(echo_span, 0)
559
559
  if conn.last_heartbeat_sent > echoed:
560
560
  conn.ping_rtt_frames = conn.last_heartbeat_sent - echoed
561
561
  msg.release()
@@ -920,7 +920,7 @@ function handle_incoming_session(session: ref[Session], msg: ref[chan.HostMessag
920
920
  update_peer_last_recv(session, peer_payload.value)
921
921
  let hb_span = unsafe: span[ubyte](data = span.data + 1, len = span.len - 1)
922
922
  if hb_span.len >= 4:
923
- let echoed = decode_u32_at(hb_span, 0)
923
+ let echoed = decode_uint_at(hb_span, 0)
924
924
  var ack = build_heartbeat_ack(echoed)
925
925
  let addr_result = msg.source.copy()
926
926
  match addr_result:
@@ -973,7 +973,7 @@ function handle_connect_request(session: ref[Session], msg: ref[chan.HostMessage
973
973
  msg.release()
974
974
  return
975
975
 
976
- let client_version = decode_u32_at(req_span, 0)
976
+ let client_version = decode_uint_at(req_span, 0)
977
977
  if client_version != session.config.protocol_version:
978
978
  var reject = build_connect_reject(reject_reason_version)
979
979
  let addr_result = msg.source.copy()