mt-lang 0.3.4 → 0.3.5

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.
@@ -4,6 +4,19 @@ module MilkTea
4
4
  module LowererResolve
5
5
  private
6
6
 
7
+ PASS_THROUGH_BUILTINS = {
8
+ "fatal" => :fatal,
9
+ "ref_of" => :ref_of,
10
+ "const_ptr_of" => :const_ptr_of,
11
+ "read" => :read,
12
+ "ptr_of" => :ptr_of,
13
+ "get" => :get,
14
+ }.freeze
15
+
16
+ COMPILE_TIME_BUILTINS = %w[
17
+ field_of callable_of has_attribute attribute_of
18
+ ].freeze
19
+
7
20
 
8
21
  def direct_function_to_proc_contextual_compatibility?(expression, actual_type, env:, expected_type:)
9
22
  return false unless actual_type.is_a?(Types::Function) && proc_type?(expected_type)
@@ -397,256 +410,248 @@ module MilkTea
397
410
  def resolve_callee(callee, env, arguments: nil)
398
411
  case callee
399
412
  when AST::Identifier
400
- if (binding = lookup_value(callee.name, env))
401
- return [:callable_value, nil, nil, binding[:type], nil] if callable_type?(binding[:type])
413
+ resolve_identifier_callee(callee, env, arguments)
414
+ when AST::MemberAccess
415
+ resolve_member_access_callee(callee, env, arguments)
416
+ when AST::Specialization
417
+ resolve_specialization_callee(callee, env)
418
+ else
419
+ resolve_expression_callee(callee, env)
420
+ end
421
+ end
402
422
 
403
- raise LoweringError, "#{callee.name} is not callable"
404
- end
423
+ def resolve_identifier_callee(callee, env, arguments)
424
+ if (binding = lookup_value(callee.name, env))
425
+ return [:callable_value, nil, nil, binding[:type], nil] if callable_type?(binding[:type])
405
426
 
406
- if @ctx.functions.key?(callee.name)
407
- binding = specialize_function_binding(@ctx.functions.fetch(callee.name), arguments, env)
408
- callee_name = if binding.external
409
- external_function_c_name(binding)
410
- else
411
- function_binding_c_name(binding, module_name: @ctx.module_name)
412
- end
413
- [ :function, callee_name, nil, binding.type, binding ]
414
- elsif callee.name == "fatal"
415
- [:fatal, nil, nil, nil]
416
- elsif callee.name == "ref_of"
417
- [:ref_of, nil, nil, nil]
418
- elsif callee.name == "const_ptr_of"
419
- [:const_ptr_of, nil, nil, nil]
420
- elsif callee.name == "read"
421
- [:read, nil, nil, nil]
422
- elsif callee.name == "ptr_of"
423
- [:ptr_of, nil, nil, nil]
424
- elsif callee.name == "field_of"
425
- [:compile_time_builtin, "field_of", nil, compile_time_builtin_function_type("field_of", arguments, env)]
426
- elsif callee.name == "callable_of"
427
- [:compile_time_builtin, "callable_of", nil, compile_time_builtin_function_type("callable_of", arguments, env)]
428
- elsif callee.name == "has_attribute"
429
- [:compile_time_builtin, "has_attribute", nil, compile_time_builtin_function_type("has_attribute", arguments, env)]
430
- elsif callee.name == "attribute_of"
431
- [:compile_time_builtin, "attribute_of", nil, compile_time_builtin_function_type("attribute_of", arguments, env)]
432
- elsif callee.name == "get"
433
- [:get, nil, nil, nil]
434
- elsif (type = @ctx.types[callee.name]).is_a?(Types::Struct) || type.is_a?(Types::StringView) || task_type?(type) || type.is_a?(Types::Vector) || type.is_a?(Types::Matrix) || type.is_a?(Types::Quaternion)
435
- [ :struct_literal, nil, nil, type ]
436
- elsif (type = @ctx.types[callee.name]).is_a?(Types::GenericStructDefinition) || type.is_a?(Types::GenericVariantDefinition)
437
- raise LoweringError, "generic type #{callee.name} requires type arguments"
438
- else
439
- emit_fn = @artifacts.emitted_declarations.find { |d| d.is_a?(IR::Function) && d.name == callee.name }
440
- if emit_fn
441
- return [:function, emit_fn.linkage_name, nil, emit_fn.return_type, nil]
442
- end
427
+ raise LoweringError, "#{callee.name} is not callable"
428
+ end
443
429
 
444
- raise LoweringError, "unknown callee #{callee.name}"
445
- end
446
- when AST::MemberAccess
447
- if callee.receiver.is_a?(AST::Identifier) && @ctx.imports.key?(callee.receiver.name)
448
- imported_module = @ctx.imports.fetch(callee.receiver.name)
430
+ if @ctx.functions.key?(callee.name)
431
+ binding = specialize_function_binding(@ctx.functions.fetch(callee.name), arguments, env)
432
+ callee_name = if binding.external
433
+ external_function_c_name(binding)
434
+ else
435
+ function_binding_c_name(binding, module_name: @ctx.module_name)
436
+ end
437
+ return [:function, callee_name, nil, binding.type, binding]
438
+ end
449
439
 
450
- if imported_module.functions.key?(callee.member)
451
- binding = specialize_function_binding(imported_module.functions.fetch(callee.member), arguments, env)
452
- unless binding.owner
453
- binding = binding.with(owner: imported_module.respond_to?(:analysis) ? imported_module.analysis : imported_module)
454
- end
455
- return [:function, function_binding_c_name(binding, module_name: imported_module.name), nil, binding.type, binding] unless binding.external
440
+ if (kind = PASS_THROUGH_BUILTINS[callee.name])
441
+ return [kind, nil, nil, nil]
442
+ end
456
443
 
457
- return [:function, external_function_c_name(binding), nil, binding.type, binding]
458
- end
459
- imported_type = imported_module.types[callee.member]
460
- if imported_type.is_a?(Types::GenericStructDefinition) || imported_type.is_a?(Types::GenericVariantDefinition)
461
- raise LoweringError, "generic type #{callee.receiver.name}.#{callee.member} requires type arguments"
462
- end
444
+ if COMPILE_TIME_BUILTINS.include?(callee.name)
445
+ return [:compile_time_builtin, callee.name, nil, compile_time_builtin_function_type(callee.name, arguments, env)]
446
+ end
463
447
 
464
- if imported_type.is_a?(Types::Struct) || imported_type.is_a?(Types::StringView) || task_type?(imported_type) || imported_type.is_a?(Types::Vector) || imported_type.is_a?(Types::Matrix) || imported_type.is_a?(Types::Quaternion)
465
- return [:struct_literal, nil, nil, imported_module.types.fetch(callee.member)]
466
- end
448
+ type = @ctx.types[callee.name]
449
+ if type.is_a?(Types::Struct) || type.is_a?(Types::StringView) || task_type?(type) || type.is_a?(Types::Vector) || type.is_a?(Types::Matrix) || type.is_a?(Types::Quaternion)
450
+ return [:struct_literal, nil, nil, type]
451
+ end
467
452
 
468
- if imported_type.is_a?(Types::Variant) && imported_type.arm_names.include?(callee.member)
469
- arm_name = callee.member
470
- return [:variant_arm_ctor, nil, nil, imported_type, [imported_type, arm_name]]
471
- end
472
- end
453
+ if type.is_a?(Types::GenericStructDefinition) || type.is_a?(Types::GenericVariantDefinition)
454
+ raise LoweringError, "generic type #{callee.name} requires type arguments"
455
+ end
473
456
 
474
- if (type_expr = resolve_type_expression(callee.receiver))
475
- if type_expr.is_a?(Types::Variant) && type_expr.arm_names.include?(callee.member)
476
- arm_name = callee.member
477
- return [:variant_arm_ctor, nil, nil, type_expr, [type_expr, arm_name]]
478
- end
457
+ emit_fn = @artifacts.emitted_declarations.find { |d| d.is_a?(IR::Function) && d.name == callee.name }
458
+ if emit_fn
459
+ return [:function, emit_fn.linkage_name, nil, emit_fn.return_type, nil]
460
+ end
479
461
 
480
- if type_expr.respond_to?(:nested_types) && type_expr.nested_types.key?(callee.member)
481
- return [:struct_literal, nil, nil, type_expr.nested_types[callee.member]]
482
- end
462
+ raise LoweringError, "unknown callee #{callee.name}"
463
+ end
483
464
 
484
- dispatch_receiver_type = method_dispatch_receiver_type(type_expr)
485
- method_entry_receiver_type = type_expr
486
- method_entry = @method_definitions[[type_expr, callee.member]]
487
- method_entry ||= @method_definitions[[type_expr, "static:#{callee.member}"]]
488
- unless method_entry || dispatch_receiver_type == type_expr
489
- method_entry_receiver_type = dispatch_receiver_type
490
- method_entry = @method_definitions[[dispatch_receiver_type, callee.member]]
491
- method_entry ||= @method_definitions[[dispatch_receiver_type, "static:#{callee.member}"]]
492
- end
493
- if method_entry
494
- method_analysis, method_ast = method_entry
495
- method_binding = method_analysis.methods.fetch(method_entry_receiver_type).fetch(method_analysis_key(method_ast))
496
- if method_binding.type.receiver_type.nil?
497
- method_binding = specialize_function_binding(method_binding, arguments, env, receiver_type: type_expr) if method_binding.type_params.any?
498
- return [:associated_method, function_binding_c_name(method_binding, module_name: method_analysis.module_name, receiver_type: method_entry_receiver_type), nil, method_binding.type, method_binding]
499
- end
465
+ def resolve_member_access_callee(callee, env, arguments)
466
+ if callee.receiver.is_a?(AST::Identifier) && @ctx.imports.key?(callee.receiver.name)
467
+ imported_module = @ctx.imports.fetch(callee.receiver.name)
468
+
469
+ if imported_module.functions.key?(callee.member)
470
+ binding = specialize_function_binding(imported_module.functions.fetch(callee.member), arguments, env)
471
+ unless binding.owner
472
+ binding = binding.with(owner: imported_module.respond_to?(:analysis) ? imported_module.analysis : imported_module)
500
473
  end
474
+ return [:function, function_binding_c_name(binding, module_name: imported_module.name), nil, binding.type, binding] unless binding.external
475
+
476
+ return [:function, external_function_c_name(binding), nil, binding.type, binding]
477
+ end
478
+ imported_type = imported_module.types[callee.member]
479
+ if imported_type.is_a?(Types::GenericStructDefinition) || imported_type.is_a?(Types::GenericVariantDefinition)
480
+ raise LoweringError, "generic type #{callee.receiver.name}.#{callee.member} requires type arguments"
481
+ end
501
482
 
502
- raise LoweringError, "unknown associated function #{type_expr}.#{callee.member}"
483
+ if imported_type.is_a?(Types::Struct) || imported_type.is_a?(Types::StringView) || task_type?(imported_type) || imported_type.is_a?(Types::Vector) || imported_type.is_a?(Types::Matrix) || imported_type.is_a?(Types::Quaternion)
484
+ return [:struct_literal, nil, nil, imported_module.types.fetch(callee.member)]
503
485
  end
504
486
 
505
- resolved_receiver_type = infer_method_receiver_type(callee.receiver, env:, member_name: callee.member)
487
+ if imported_type.is_a?(Types::Variant) && imported_type.arm_names.include?(callee.member)
488
+ arm_name = callee.member
489
+ return [:variant_arm_ctor, nil, nil, imported_type, [imported_type, arm_name]]
490
+ end
491
+ end
506
492
 
507
- if dyn_type?(resolved_receiver_type)
508
- interface = resolved_receiver_type.interface_binding
509
- method_binding = interface.methods[callee.member]
510
- raise LoweringError, "no method '#{callee.member}' on interface #{interface.name}" unless method_binding
511
- return [:dyn_method, nil, callee.receiver, method_binding, nil]
493
+ if (type_expr = resolve_type_expression(callee.receiver))
494
+ if type_expr.is_a?(Types::Variant) && type_expr.arm_names.include?(callee.member)
495
+ arm_name = callee.member
496
+ return [:variant_arm_ctor, nil, nil, type_expr, [type_expr, arm_name]]
512
497
  end
513
498
 
514
- dispatch_receiver_type = method_dispatch_receiver_type(resolved_receiver_type)
515
- method_entry_receiver_type = resolved_receiver_type
516
- method_entry = @method_definitions[[resolved_receiver_type, callee.member]]
517
- unless method_entry || dispatch_receiver_type == resolved_receiver_type
499
+ if type_expr.respond_to?(:nested_types) && type_expr.nested_types.key?(callee.member)
500
+ return [:struct_literal, nil, nil, type_expr.nested_types[callee.member]]
501
+ end
502
+
503
+ dispatch_receiver_type = method_dispatch_receiver_type(type_expr)
504
+ method_entry_receiver_type = type_expr
505
+ method_entry = @method_definitions[[type_expr, callee.member]]
506
+ method_entry ||= @method_definitions[[type_expr, "static:#{callee.member}"]]
507
+ unless method_entry || dispatch_receiver_type == type_expr
518
508
  method_entry_receiver_type = dispatch_receiver_type
519
509
  method_entry = @method_definitions[[dispatch_receiver_type, callee.member]]
510
+ method_entry ||= @method_definitions[[dispatch_receiver_type, "static:#{callee.member}"]]
520
511
  end
521
512
  if method_entry
522
- method_analysis, method_ast = method_entry
523
- method_analysis_key = method_ast.kind == :static ? "static:#{method_ast.name}" : method_ast.name
524
- method_binding = method_analysis.methods.fetch(method_entry_receiver_type).fetch(method_analysis_key)
525
- method_binding = specialize_function_binding(method_binding, arguments, env, receiver_type: resolved_receiver_type)
526
- return [
527
- :method,
528
- function_binding_c_name(method_binding, module_name: method_analysis.module_name, receiver_type: method_entry_receiver_type),
529
- callee.receiver,
530
- method_binding.type,
531
- method_binding,
532
- ]
533
- end
534
-
535
- if callee.member == "with" && struct_with_target_type?(resolved_receiver_type)
536
- return [:struct_with, nil, callee.receiver, resolved_receiver_type]
537
- end
538
-
539
- if (precomputed = @ctx.resolved_call_kinds[@ctx.ast.node_ids[callee.object_id]])
540
- case precomputed
541
- when :str_buffer_clear, :str_buffer_assign, :str_buffer_append, :str_buffer_assign_format, :str_buffer_append_format,
542
- :str_buffer_len, :str_buffer_capacity, :str_buffer_as_str, :str_buffer_as_cstr
543
- return [precomputed, nil, callee.receiver, str_buffer_method_type(precomputed, resolved_receiver_type)]
544
- when :event_subscribe, :event_subscribe_once, :event_unsubscribe, :event_emit, :event_wait
545
- event_type = infer_expression_type(callee.receiver, env:)
546
- return [precomputed, nil, callee.receiver, event_method_type(precomputed, event_type)]
547
- when :atomic_load, :atomic_store, :atomic_add, :atomic_sub, :atomic_exchange, :atomic_compare_exchange
548
- elem = atomic_element_type(resolved_receiver_type)
549
- ret = case precomputed
550
- when :atomic_load, :atomic_add, :atomic_sub, :atomic_exchange then elem
551
- when :atomic_store then @ctx.types.fetch("void")
552
- when :atomic_compare_exchange then @ctx.types.fetch("bool")
553
- end
554
- return [precomputed, nil, callee.receiver, Types::Registry.function(nil, params: [], return_type: ret)]
555
- when :simd_lane_with
556
- return [precomputed, nil, callee.receiver, Types::Registry.function(nil, params: [], return_type: resolved_receiver_type)]
513
+ method_analysis, method_ast = method_entry
514
+ method_binding = method_analysis.methods.fetch(method_entry_receiver_type).fetch(method_analysis_key(method_ast))
515
+ if method_binding.type.receiver_type.nil?
516
+ method_binding = specialize_function_binding(method_binding, arguments, env, receiver_type: type_expr) if method_binding.type_params.any?
517
+ return [:associated_method, function_binding_c_name(method_binding, module_name: method_analysis.module_name, receiver_type: method_entry_receiver_type), nil, method_binding.type, method_binding]
557
518
  end
558
519
  end
559
520
 
560
- if (str_buffer_method = str_buffer_method_kind(resolved_receiver_type, callee.member))
561
- return [str_buffer_method, nil, callee.receiver, str_buffer_method_type(str_buffer_method, resolved_receiver_type)]
562
- end
521
+ raise LoweringError, "unknown associated function #{type_expr}.#{callee.member}"
522
+ end
563
523
 
564
- if (event_method = event_method_kind(resolved_receiver_type, callee.member))
565
- event_type = infer_expression_type(callee.receiver, env:)
566
- return [event_method, nil, callee.receiver, event_method_type(event_method, event_type)]
567
- end
524
+ resolved_receiver_type = infer_method_receiver_type(callee.receiver, env:, member_name: callee.member)
568
525
 
569
- if (atomic_method = atomic_method_kind(resolved_receiver_type, callee.member))
526
+ if dyn_type?(resolved_receiver_type)
527
+ interface = resolved_receiver_type.interface_binding
528
+ method_binding = interface.methods[callee.member]
529
+ raise LoweringError, "no method '#{callee.member}' on interface #{interface.name}" unless method_binding
530
+ return [:dyn_method, nil, callee.receiver, method_binding, nil]
531
+ end
532
+
533
+ dispatch_receiver_type = method_dispatch_receiver_type(resolved_receiver_type)
534
+ method_entry_receiver_type = resolved_receiver_type
535
+ method_entry = @method_definitions[[resolved_receiver_type, callee.member]]
536
+ unless method_entry || dispatch_receiver_type == resolved_receiver_type
537
+ method_entry_receiver_type = dispatch_receiver_type
538
+ method_entry = @method_definitions[[dispatch_receiver_type, callee.member]]
539
+ end
540
+ if method_entry
541
+ method_analysis, method_ast = method_entry
542
+ method_analysis_key = method_ast.kind == :static ? "static:#{method_ast.name}" : method_ast.name
543
+ method_binding = method_analysis.methods.fetch(method_entry_receiver_type).fetch(method_analysis_key)
544
+ method_binding = specialize_function_binding(method_binding, arguments, env, receiver_type: resolved_receiver_type)
545
+ return [
546
+ :method,
547
+ function_binding_c_name(method_binding, module_name: method_analysis.module_name, receiver_type: method_entry_receiver_type),
548
+ callee.receiver,
549
+ method_binding.type,
550
+ method_binding,
551
+ ]
552
+ end
553
+
554
+ if callee.member == "with" && struct_with_target_type?(resolved_receiver_type)
555
+ return [:struct_with, nil, callee.receiver, resolved_receiver_type]
556
+ end
557
+
558
+ if (precomputed = @ctx.resolved_call_kinds[@ctx.ast.node_ids[callee.object_id]])
559
+ case precomputed
560
+ when :str_buffer_clear, :str_buffer_assign, :str_buffer_append, :str_buffer_assign_format, :str_buffer_append_format,
561
+ :str_buffer_len, :str_buffer_capacity, :str_buffer_as_str, :str_buffer_as_cstr
562
+ return [precomputed, nil, callee.receiver, str_buffer_method_type(precomputed, resolved_receiver_type)]
563
+ when :event_subscribe, :event_subscribe_once, :event_unsubscribe, :event_emit, :event_wait
564
+ event_type = infer_expression_type(callee.receiver, env:)
565
+ return [precomputed, nil, callee.receiver, event_method_type(precomputed, event_type)]
566
+ when :atomic_load, :atomic_store, :atomic_add, :atomic_sub, :atomic_exchange, :atomic_compare_exchange
570
567
  elem = atomic_element_type(resolved_receiver_type)
571
- ret = case atomic_method
568
+ ret = case precomputed
572
569
  when :atomic_load, :atomic_add, :atomic_sub, :atomic_exchange then elem
573
570
  when :atomic_store then @ctx.types.fetch("void")
574
571
  when :atomic_compare_exchange then @ctx.types.fetch("bool")
575
572
  end
576
- return [atomic_method, nil, callee.receiver, Types::Registry.function(nil, params: [], return_type: ret)]
573
+ return [precomputed, nil, callee.receiver, Types::Registry.function(nil, params: [], return_type: ret)]
574
+ when :simd_lane_with
575
+ return [precomputed, nil, callee.receiver, Types::Registry.function(nil, params: [], return_type: resolved_receiver_type)]
577
576
  end
577
+ end
578
578
 
579
- if (simd_method = simd_method_kind(resolved_receiver_type, callee.member))
580
- ret = case simd_method
581
- when :simd_lane_with then resolved_receiver_type
582
- end
583
- return [simd_method, nil, callee.receiver, Types::Registry.function(nil, params: [], return_type: ret)]
584
- end
579
+ if (str_buffer_method = str_buffer_method_kind(resolved_receiver_type, callee.member))
580
+ return [str_buffer_method, nil, callee.receiver, str_buffer_method_type(str_buffer_method, resolved_receiver_type)]
581
+ end
585
582
 
586
- field_receiver_type = infer_field_receiver_type(callee.receiver, env:)
587
- if array_type?(field_receiver_type) && callee.member == "as_span"
588
- return [:array_as_span, nil, callee.receiver, Types::Registry.span(array_element_type(field_receiver_type))]
589
- end
583
+ if (event_method = event_method_kind(resolved_receiver_type, callee.member))
584
+ event_type = infer_expression_type(callee.receiver, env:)
585
+ return [event_method, nil, callee.receiver, event_method_type(event_method, event_type)]
586
+ end
587
+
588
+ if (atomic_method = atomic_method_kind(resolved_receiver_type, callee.member))
589
+ elem = atomic_element_type(resolved_receiver_type)
590
+ ret = case atomic_method
591
+ when :atomic_load, :atomic_add, :atomic_sub, :atomic_exchange then elem
592
+ when :atomic_store then @ctx.types.fetch("void")
593
+ when :atomic_compare_exchange then @ctx.types.fetch("bool")
594
+ end
595
+ return [atomic_method, nil, callee.receiver, Types::Registry.function(nil, params: [], return_type: ret)]
596
+ end
590
597
 
591
- member_type = field_receiver_type.respond_to?(:field) ? field_receiver_type.field(callee.member) : nil
592
- member_type = field_receiver_type.respond_to?(:field) ? field_receiver_type.field(callee.member) : nil
593
- return [:callable_value, nil, nil, member_type, nil] if callable_type?(member_type)
598
+ if (simd_method = simd_method_kind(resolved_receiver_type, callee.member))
599
+ ret = case simd_method
600
+ when :simd_lane_with then resolved_receiver_type
601
+ end
602
+ return [simd_method, nil, callee.receiver, Types::Registry.function(nil, params: [], return_type: ret)]
603
+ end
594
604
 
595
- raise LoweringError, "unknown callee #{callee.receiver}.#{callee.member}"
596
- when AST::Specialization
597
- if callee.callee.is_a?(AST::Identifier) && callee.callee.name == "reinterpret"
605
+ field_receiver_type = infer_field_receiver_type(callee.receiver, env:)
606
+ if array_type?(field_receiver_type) && callee.member == "as_span"
607
+ return [:array_as_span, nil, callee.receiver, Types::Registry.span(array_element_type(field_receiver_type))]
608
+ end
609
+
610
+ member_type = field_receiver_type.respond_to?(:field) ? field_receiver_type.field(callee.member) : nil
611
+ member_type = field_receiver_type.respond_to?(:field) ? field_receiver_type.field(callee.member) : nil
612
+ return [:callable_value, nil, nil, member_type, nil] if callable_type?(member_type)
613
+
614
+ raise LoweringError, "unknown callee #{callee.receiver}.#{callee.member}"
615
+ end
616
+
617
+ def resolve_specialization_callee(callee, env)
618
+ if callee.callee.is_a?(AST::Identifier)
619
+ case callee.callee.name
620
+ when "reinterpret"
598
621
  target_type = resolve_type_ref(callee.arguments.fetch(0).value)
599
622
  return [:reinterpret, nil, nil, Types::Registry.function("reinterpret", params: [Types::Registry.parameter("value", target_type)], return_type: target_type)]
600
- end
601
-
602
- if callee.callee.is_a?(AST::Identifier) && callee.callee.name == "array"
623
+ when "array"
603
624
  array_type = resolve_type_ref(AST::TypeRef.new(name: AST::QualifiedName.new(parts: ["array"]), arguments: callee.arguments, nullable: false))
604
625
  return [:array, nil, nil, array_type]
605
- end
606
-
607
- if callee.callee.is_a?(AST::Identifier) && callee.callee.name == "simd"
626
+ when "simd"
608
627
  simd_type = resolve_type_ref(AST::TypeRef.new(name: AST::QualifiedName.new(parts: ["simd"]), arguments: callee.arguments, nullable: false))
609
628
  return [:simd, nil, nil, simd_type]
610
- end
611
-
612
- if callee.callee.is_a?(AST::Identifier) && callee.callee.name == "span"
629
+ when "span"
613
630
  span_type = resolve_type_ref(AST::TypeRef.new(name: AST::QualifiedName.new(parts: ["span"]), arguments: callee.arguments, nullable: false))
614
631
  return [:struct_literal, nil, nil, span_type]
615
- end
616
-
617
- if callee.callee.is_a?(AST::Identifier) && callee.callee.name == "zero"
632
+ when "zero"
618
633
  target_type = resolve_type_ref(callee.arguments.fetch(0).value)
619
634
  return [:zero, nil, nil, Types::Registry.function("zero", params: [], return_type: target_type)]
620
- end
621
-
622
- if callee.callee.is_a?(AST::Identifier) && callee.callee.name == "hash"
635
+ when "hash"
623
636
  resolution = resolve_hash_specialization(callee, env:)
624
637
  return [:hash, resolution.callee_name, nil, Types::Registry.function("hash", params: [Types::Registry.parameter("value", resolution.target_type)], return_type: @ctx.types.fetch("uint")), resolution.binding]
625
- end
626
-
627
- if callee.callee.is_a?(AST::Identifier) && callee.callee.name == "equal"
638
+ when "equal"
628
639
  resolution = resolve_equal_specialization(callee, env:)
629
640
  params = [
630
641
  Types::Registry.parameter("left", resolution.target_type),
631
642
  Types::Registry.parameter("right", resolution.target_type),
632
643
  ]
633
644
  return [:equal, resolution.callee_name, nil, Types::Registry.function("equal", params:, return_type: @ctx.types.fetch("bool")), resolution.binding]
634
- end
635
-
636
- if callee.callee.is_a?(AST::Identifier) && callee.callee.name == "order"
645
+ when "order"
637
646
  resolution = resolve_order_specialization(callee, env:)
638
647
  params = [
639
648
  Types::Registry.parameter("left", resolution.target_type),
640
649
  Types::Registry.parameter("right", resolution.target_type),
641
650
  ]
642
651
  return [:order, resolution.callee_name, nil, Types::Registry.function("order", params:, return_type: @ctx.types.fetch("int")), resolution.binding]
643
- end
644
-
645
- if callee.callee.is_a?(AST::Identifier) && callee.callee.name == "attribute_arg"
652
+ when "attribute_arg"
646
653
  return [:compile_time_builtin, "attribute_arg", nil, compile_time_builtin_specialization_function_type(callee)]
647
- end
648
-
649
- if callee.callee.is_a?(AST::Identifier) && callee.callee.name == "adapt"
654
+ when "adapt"
650
655
  raise LoweringError, "adapt requires exactly one type argument" unless callee.arguments.length == 1
651
656
 
652
657
  type_arg = callee.arguments.first.value
@@ -658,38 +663,40 @@ module MilkTea
658
663
  dyn_type = Types::Dyn.new(interface, interface.respond_to?(:type_arguments) ? (interface.type_arguments || []) : [])
659
664
  return [:adapt, nil, nil, dyn_type, interface]
660
665
  end
666
+ end
661
667
 
662
- if (callable_resolution = resolve_specialized_callable_binding(callee, env:))
663
- callable_kind, function_binding, receiver = callable_resolution
664
- if callable_kind == :method
665
- return [
666
- :method,
667
- function_binding_c_name(function_binding, module_name: function_binding.owner.module_name, receiver_type: function_binding.type.receiver_type),
668
- receiver,
669
- function_binding.type,
670
- function_binding,
671
- ]
672
- end
673
-
674
- if function_binding.external
675
- return [:function, external_function_c_name(function_binding), nil, function_binding.type, function_binding]
676
- end
677
-
678
- return [:function, function_binding_c_name(function_binding, module_name: function_binding.owner.module_name), nil, function_binding.type, function_binding]
668
+ if (callable_resolution = resolve_specialized_callable_binding(callee, env:))
669
+ callable_kind, function_binding, receiver = callable_resolution
670
+ if callable_kind == :method
671
+ return [
672
+ :method,
673
+ function_binding_c_name(function_binding, module_name: function_binding.owner.module_name, receiver_type: function_binding.type.receiver_type),
674
+ receiver,
675
+ function_binding.type,
676
+ function_binding,
677
+ ]
679
678
  end
680
679
 
681
- if (type_ref = type_ref_from_specialization(callee))
682
- specialized_type = resolve_type_ref(type_ref)
683
- return [:struct_literal, nil, nil, specialized_type] if specialized_type.is_a?(Types::Struct) || task_type?(specialized_type) || specialized_type.is_a?(Types::Vector) || specialized_type.is_a?(Types::Matrix) || specialized_type.is_a?(Types::Quaternion) || specialized_type.is_a?(Types::Simd)
680
+ if function_binding.external
681
+ return [:function, external_function_c_name(function_binding), nil, function_binding.type, function_binding]
684
682
  end
685
683
 
686
- raise LoweringError, "unsupported specialization callee"
687
- else
688
- callee_type = infer_expression_type(callee, env:)
689
- return [:callable_value, nil, nil, callee_type, nil] if callable_type?(callee_type)
684
+ return [:function, function_binding_c_name(function_binding, module_name: function_binding.owner.module_name), nil, function_binding.type, function_binding]
685
+ end
690
686
 
691
- raise LoweringError, "unsupported callee #{callee.class.name}"
687
+ if (type_ref = type_ref_from_specialization(callee))
688
+ specialized_type = resolve_type_ref(type_ref)
689
+ return [:struct_literal, nil, nil, specialized_type] if specialized_type.is_a?(Types::Struct) || task_type?(specialized_type) || specialized_type.is_a?(Types::Vector) || specialized_type.is_a?(Types::Matrix) || specialized_type.is_a?(Types::Quaternion) || specialized_type.is_a?(Types::Simd)
692
690
  end
691
+
692
+ raise LoweringError, "unsupported specialization callee"
693
+ end
694
+
695
+ def resolve_expression_callee(callee, env)
696
+ callee_type = infer_expression_type(callee, env:)
697
+ return [:callable_value, nil, nil, callee_type, nil] if callable_type?(callee_type)
698
+
699
+ raise LoweringError, "unsupported callee #{callee.class.name}"
693
700
  end
694
701
 
695
702
  def infer_expression_type(expression, env:, expected_type: nil)