mt-lang 0.3.24 → 0.3.26

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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/lib/milk_tea/base.rb +1 -1
  3. data/lib/milk_tea/core/bindings/attribute_binding.rb +51 -49
  4. data/lib/milk_tea/core/bindings/function_binding.rb +3 -1
  5. data/lib/milk_tea/core/bindings/module_binding.rb +42 -40
  6. data/lib/milk_tea/core/bindings/value_binding.rb +16 -14
  7. data/lib/milk_tea/core/bindings.rb +4 -9
  8. data/lib/milk_tea/core/c_backend/control_flow_emission.rb +11 -11
  9. data/lib/milk_tea/core/c_backend/expressions.rb +11 -11
  10. data/lib/milk_tea/core/c_backend/feature_detection.rb +15 -19
  11. data/lib/milk_tea/core/c_backend/format_helpers.rb +1 -1
  12. data/lib/milk_tea/core/c_backend/reinterpret.rb +10 -10
  13. data/lib/milk_tea/core/c_backend/runtime_helpers.rb +1 -1
  14. data/lib/milk_tea/core/c_backend/statements.rb +20 -20
  15. data/lib/milk_tea/core/c_backend/type_declaration.rb +4 -4
  16. data/lib/milk_tea/core/c_backend/type_system.rb +1 -1
  17. data/lib/milk_tea/core/c_backend.rb +3 -3
  18. data/lib/milk_tea/core/compile_time.rb +41 -70
  19. data/lib/milk_tea/core/control_flow/builder.rb +3 -3
  20. data/lib/milk_tea/core/control_flow/constant_propagation.rb +1 -1
  21. data/lib/milk_tea/core/control_flow/graph.rb +1 -1
  22. data/lib/milk_tea/core/control_flow/termination.rb +1 -1
  23. data/lib/milk_tea/core/cst.rb +16 -0
  24. data/lib/milk_tea/core/flow_scope.rb +13 -0
  25. data/lib/milk_tea/core/lexer/character_classes.rb +2 -2
  26. data/lib/milk_tea/core/lexer/format_strings.rb +5 -5
  27. data/lib/milk_tea/core/lexer/heredocs.rb +6 -6
  28. data/lib/milk_tea/core/lexer/indentation.rb +4 -4
  29. data/lib/milk_tea/core/lexer/numbers.rb +1 -1
  30. data/lib/milk_tea/core/lexer/strings.rb +4 -4
  31. data/lib/milk_tea/core/lexer/symbols.rb +3 -3
  32. data/lib/milk_tea/core/lexer/trivia.rb +4 -4
  33. data/lib/milk_tea/core/lexer.rb +17 -17
  34. data/lib/milk_tea/core/lowering/async/analysis.rb +210 -208
  35. data/lib/milk_tea/core/lowering/async/async_lowering.rb +1406 -0
  36. data/lib/milk_tea/core/lowering/async/frame_builder.rb +615 -613
  37. data/lib/milk_tea/core/lowering/async/normalization.rb +410 -408
  38. data/lib/milk_tea/core/lowering/block.rb +982 -980
  39. data/lib/milk_tea/core/lowering/calls.rb +1360 -1358
  40. data/lib/milk_tea/core/lowering/declarations.rb +175 -173
  41. data/lib/milk_tea/core/lowering/dyn.rb +171 -169
  42. data/lib/milk_tea/core/lowering/events.rb +946 -944
  43. data/lib/milk_tea/core/lowering/expressions.rb +1514 -1512
  44. data/lib/milk_tea/core/lowering/foreign_cstr.rb +180 -178
  45. data/lib/milk_tea/core/lowering/functions.rb +186 -184
  46. data/lib/milk_tea/core/lowering/loops.rb +1004 -1002
  47. data/lib/milk_tea/core/lowering/lowering_context.rb +1 -1
  48. data/lib/milk_tea/core/lowering/proc.rb +355 -353
  49. data/lib/milk_tea/core/lowering/resolve.rb +2127 -2125
  50. data/lib/milk_tea/core/lowering/scans.rb +162 -168
  51. data/lib/milk_tea/core/lowering/str_buffer.rb +104 -102
  52. data/lib/milk_tea/core/lowering/utils.rb +964 -963
  53. data/lib/milk_tea/core/lowering.rb +22 -22
  54. data/lib/milk_tea/core/module_binder.rb +1 -1
  55. data/lib/milk_tea/core/module_loader.rb +2 -2
  56. data/lib/milk_tea/core/parser/attributes.rb +1 -1
  57. data/lib/milk_tea/core/parser/blocks.rb +2 -2
  58. data/lib/milk_tea/core/parser/declarations.rb +15 -15
  59. data/lib/milk_tea/core/parser/expressions.rb +20 -20
  60. data/lib/milk_tea/core/parser/recovery.rb +1 -1
  61. data/lib/milk_tea/core/parser/statements.rb +3 -3
  62. data/lib/milk_tea/core/parser/types.rb +4 -4
  63. data/lib/milk_tea/core/parser.rb +39 -21
  64. data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +6 -6
  65. data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +5 -5
  66. data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +2 -2
  67. data/lib/milk_tea/core/semantic_analyzer/calls.rb +1 -1
  68. data/lib/milk_tea/core/semantic_analyzer/expressions.rb +4 -4
  69. data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +37 -37
  70. data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +4 -4
  71. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +4 -4
  72. data/lib/milk_tea/core/semantic_analyzer/generics.rb +4 -4
  73. data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +7 -7
  74. data/lib/milk_tea/core/semantic_analyzer/nullability.rb +59 -59
  75. data/lib/milk_tea/core/semantic_analyzer/statements.rb +3 -3
  76. data/lib/milk_tea/core/semantic_analyzer/top_level.rb +1 -1
  77. data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +12 -12
  78. data/lib/milk_tea/core/types/layout.rb +3 -1
  79. data/lib/milk_tea/core/types/visitor.rb +351 -349
  80. data/lib/milk_tea/core.rb +0 -2
  81. data/lib/milk_tea/tooling/cli/commands/bindgen.rb +1 -1
  82. data/lib/milk_tea/tooling/cli/commands/check.rb +5 -5
  83. data/lib/milk_tea/tooling/cli/commands/debug.rb +3 -3
  84. data/lib/milk_tea/tooling/cli/commands/deps.rb +1 -1
  85. data/lib/milk_tea/tooling/cli/commands/emit_c.rb +2 -2
  86. data/lib/milk_tea/tooling/cli/commands/format.rb +6 -6
  87. data/lib/milk_tea/tooling/cli/commands/lint.rb +3 -3
  88. data/lib/milk_tea/tooling/cli/commands/lower.rb +3 -3
  89. data/lib/milk_tea/tooling/cli/commands/parse.rb +3 -3
  90. data/lib/milk_tea/tooling/cli/commands/test.rb +3 -3
  91. data/lib/milk_tea/tooling/cli/commands/toolchain.rb +1 -1
  92. data/lib/milk_tea/tooling/cli.rb +22 -34
  93. data/lib/milk_tea/tooling/linter/flow_rules.rb +3 -3
  94. metadata +4 -5
  95. data/lib/milk_tea/core/cst_builder.rb +0 -19
  96. data/lib/milk_tea/core/lowering/async/lowering.rb +0 -1404
  97. data/lib/milk_tea/core/token_stream.rb +0 -30
@@ -10,11 +10,11 @@
10
10
  # .imports imported module bindings
11
11
  # .types Hash[name → Types::Base]
12
12
  # .interfaces Hash[name → InterfaceBinding|GenericInterfaceBinding]
13
- # .attributes Hash[name → AttributeBinding]
13
+ # .attributes Hash[name → Bindings::AttributeBinding]
14
14
  # .attribute_applications Hash[...]
15
- # .values Hash[name → ValueBinding]
16
- # .functions Hash[name → FunctionBinding]
17
- # .methods Hash[type → Hash[name → FunctionBinding]]
15
+ # .values Hash[name → Bindings::ValueBinding]
16
+ # .functions Hash[name → Bindings::FunctionBinding]
17
+ # .methods Hash[type → Hash[name → Bindings::FunctionBinding]]
18
18
  # .implemented_interfaces Hash[type → Set[InterfaceBinding]]
19
19
  # .resolved_expr_types Hash[expression.object_id → Types::Base]
20
20
  # .uses_parallel_for bool
@@ -30,7 +30,7 @@ require_relative "lowering/events"
30
30
  require_relative "lowering/functions"
31
31
  require_relative "lowering/async/analysis"
32
32
  require_relative "lowering/async/normalization"
33
- require_relative "lowering/async/lowering"
33
+ require_relative "lowering/async/async_lowering"
34
34
  require_relative "lowering/async/frame_builder"
35
35
  require_relative "lowering/block"
36
36
  require_relative "lowering/proc"
@@ -61,7 +61,7 @@ module MilkTea
61
61
  end
62
62
  end
63
63
 
64
- class Lowering
64
+ module Lowering
65
65
  def self.lower(program)
66
66
  lowerer = Lowerer.new(program)
67
67
  ir_program, _modules, _synths = lowerer.lower_and_assemble
@@ -90,25 +90,25 @@ module MilkTea
90
90
  attr_accessor :bypass_sema_type_cache
91
91
  attr_reader :recorded_expr_types
92
92
 
93
- include LowererScans
94
- include LowererDeclarations
95
- include LowererEvents
96
- include LowererFunctions
97
- include LowererAsync
98
- include LowererBlock
99
- include LowererProc
100
- include LowererLoops
101
- include LowererExpressions
102
- include LowererCalls
103
- include LowererForeignCstr
104
- include LowererStrBuffer
105
- include LowererResolve
106
- include LowererDyn
107
- include LowererUtils
93
+ include Lowering::Scans
94
+ include Lowering::Declarations
95
+ include Lowering::Events
96
+ include Lowering::Functions
97
+ include Lowering::Async
98
+ include Lowering::Block
99
+ include Lowering::Proc
100
+ include Lowering::Loops
101
+ include Lowering::Expressions
102
+ include Lowering::Calls
103
+ include Lowering::ForeignCstr
104
+ include Lowering::StrBuffer
105
+ include Lowering::Resolve
106
+ include Lowering::Dyn
107
+ include Lowering::Utils
108
108
 
109
109
  def initialize(program)
110
110
  @program = program
111
- @ctx = ModuleContext.new
111
+ @ctx = LoweringContext.new
112
112
  @artifacts = Artifacts.new
113
113
  @synthetic_proc_counter = 0
114
114
  @parallel_for_counter = 0
@@ -44,7 +44,7 @@ module MilkTea
44
44
  methods, private_methods = exported_methods(analysis, types)
45
45
  implemented_interfaces, private_implemented_interfaces = exported_interface_implementations(analysis, types, interfaces)
46
46
 
47
- ModuleBinding.new(
47
+ Bindings::ModuleBinding.new(
48
48
  name: analysis.module_name,
49
49
  types:,
50
50
  type_declarations:,
@@ -651,7 +651,7 @@ module MilkTea
651
651
  full_binding.types.reject { |name, _| fw_binding.types.key?(name) }
652
652
  )
653
653
 
654
- @forward_bindings[resolved_path] = ModuleBinding.new(
654
+ @forward_bindings[resolved_path] = Bindings::ModuleBinding.new(
655
655
  name: full_binding.name,
656
656
  types: merged_types,
657
657
  type_declarations: full_binding.type_declarations,
@@ -699,7 +699,7 @@ module MilkTea
699
699
  end
700
700
  end
701
701
 
702
- ModuleBinding.new(
702
+ Bindings::ModuleBinding.new(
703
703
  name: module_name, types:, type_declarations: {},
704
704
  interfaces: {}, attributes: {}, attribute_applications: {},
705
705
  values: {}, functions: {}, methods: {},
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MilkTea
4
- module Parse
4
+ class Parser
5
5
  module Attributes
6
6
  def parse_attribute_applications
7
7
  attributes = []
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MilkTea
4
- module Parse
4
+ class Parser
5
5
  module Blocks
6
6
  def parse_block
7
7
  consume(:colon, "expected ':' before block")
@@ -51,7 +51,7 @@ module MilkTea
51
51
  statements
52
52
  end
53
53
 
54
- def parse_named_block(&block)
54
+ def parse_recoverable_block(&block)
55
55
  consume(:colon, "expected ':' before block")
56
56
  consume(:newline, "expected newline before block")
57
57
  consume(:indent, "expected indented block")
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MilkTea
4
- module Parse
4
+ class Parser
5
5
  module Declarations
6
6
  def parse_import
7
7
  line = previous.line
@@ -375,9 +375,9 @@ module MilkTea
375
375
  name = name_token.lexeme
376
376
  lifetime_params, type_params = parse_struct_decl_params
377
377
  implements = parse_implements_clause
378
- c_name = parse_optional_explicit_c_name
378
+ c_name = parse_optional_c_name
379
379
  packed, alignment = parse_struct_layout_attributes(attributes) if attributes.any?
380
- members = parse_named_block do
380
+ members = parse_recoverable_block do
381
381
  parse_struct_member
382
382
  end
383
383
  fields = members.filter_map { |kind, member| member if kind == :field }
@@ -462,8 +462,8 @@ module MilkTea
462
462
  line = previous.line
463
463
  name_token = consume_name("expected union name")
464
464
  name = name_token.lexeme
465
- c_name = parse_optional_explicit_c_name
466
- fields = parse_named_block do
465
+ c_name = parse_optional_c_name
466
+ fields = parse_recoverable_block do
467
467
  field_name = consume_name_allowing_keywords("expected field name").lexeme
468
468
  consume(:colon, "expected ':' after field name")
469
469
  field_type = parse_type_ref
@@ -473,7 +473,7 @@ module MilkTea
473
473
  AST::UnionDecl.new(name:, c_name:, fields:, visibility:, attributes:, line:, column: name_token.column)
474
474
  end
475
475
 
476
- def parse_optional_explicit_c_name
476
+ def parse_optional_c_name
477
477
  return nil unless match(:equal)
478
478
 
479
479
  consume(:cstring, "expected C string literal after '='").literal
@@ -516,7 +516,7 @@ module MilkTea
516
516
  name_token = consume_name("expected variant name")
517
517
  name = name_token.lexeme
518
518
  type_params = parse_declaration_type_params
519
- arms = parse_named_block do
519
+ arms = parse_recoverable_block do
520
520
  arm_name = consume_name_allowing_keywords("expected variant arm name").lexeme
521
521
  fields = if match(:lparen)
522
522
  parsed = parse_comma_separated_until(:rparen) do
@@ -554,7 +554,7 @@ module MilkTea
554
554
  name_token = consume_name("expected interface name")
555
555
  name = name_token.lexeme
556
556
  type_params = parse_declaration_type_params
557
- methods = parse_named_block do
557
+ methods = parse_recoverable_block do
558
558
  method_attributes = parse_attribute_applications
559
559
  parse_interface_method_decl(attributes: method_attributes)
560
560
  end
@@ -566,7 +566,7 @@ module MilkTea
566
566
  type_name = parse_type_ref
567
567
  receiver_type_param_names = extending_target_type_param_names(type_name)
568
568
  methods = with_type_param_names(receiver_type_param_names) do
569
- parse_named_block do
569
+ parse_recoverable_block do
570
570
  method_attributes = parse_attribute_applications
571
571
  parse_method_def(attributes: method_attributes)
572
572
  end
@@ -588,7 +588,7 @@ module MilkTea
588
588
  end
589
589
  if value.name.parts.length == 1 && value.arguments.empty? && !value.nullable
590
590
  name = value.name.parts.first
591
- nested_names << name unless known_type_like_name?(name)
591
+ nested_names << name unless known_type_context_name?(name)
592
592
  end
593
593
  nested_names
594
594
  when AST::FunctionType, AST::ProcType
@@ -613,7 +613,7 @@ module MilkTea
613
613
  end
614
614
 
615
615
  def parse_method_def(attributes: [])
616
- visibility, _visibility_token, async, kind, line, name_token = parse_method_like_decl_head
616
+ visibility, _visibility_token, async, kind, line, name_token = parse_method_head
617
617
  name = name_token.lexeme
618
618
  type_params, params, return_type, body = parse_callable_signature
619
619
  AST::MethodDef.new(name:, type_params:, params:, return_type:, body:, kind:, visibility:, async:, attributes:, line:, column: name_token.column)
@@ -628,7 +628,7 @@ module MilkTea
628
628
  end
629
629
 
630
630
  def parse_interface_method_decl(attributes: [])
631
- visibility, visibility_token, async, kind, line, name_token = parse_method_like_decl_head
631
+ visibility, visibility_token, async, kind, line, name_token = parse_method_head
632
632
  raise error(visibility_token, "public is not allowed on interface methods") if visibility == :public
633
633
 
634
634
  name = name_token.lexeme
@@ -641,7 +641,7 @@ module MilkTea
641
641
  AST::InterfaceMethodDecl.new(name:, params:, return_type:, kind:, async:, attributes:, line:, column: name_token.column)
642
642
  end
643
643
 
644
- def parse_method_like_decl_head
644
+ def parse_method_head
645
645
  visibility, visibility_token = parse_visibility
646
646
  async = match(:async)
647
647
  kind = parse_method_kind
@@ -679,7 +679,7 @@ module MilkTea
679
679
  params = parse_params
680
680
  return_type = match(:arrow) ? parse_type_ref : nil
681
681
  if allow_body
682
- body = parse_block_body_safe
682
+ body = parse_block_body_with_recovery
683
683
  else
684
684
  consume_end_of_statement
685
685
  end
@@ -688,7 +688,7 @@ module MilkTea
688
688
  [type_params, params, return_type, body]
689
689
  end
690
690
 
691
- def parse_block_body_safe
691
+ def parse_block_body_with_recovery
692
692
  parse_block
693
693
  rescue ParseError => e
694
694
  raise unless @recovery_errors
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MilkTea
4
- module Parse
4
+ class Parser
5
5
  module Expressions
6
6
  def parse_expression
7
7
  return parse_if_expression if match(:if)
@@ -231,7 +231,7 @@ module MilkTea
231
231
 
232
232
  def try_parse_prefix_cast_expression
233
233
  saved_current = @current
234
- return nil unless check_name && known_type_like_name?(peek.lexeme)
234
+ return nil unless check_name && known_type_context_name?(peek.lexeme)
235
235
 
236
236
  start_token = peek
237
237
  expression = nil
@@ -253,7 +253,7 @@ module MilkTea
253
253
  expression = parse_unary
254
254
  AST::PrefixCast.new(target_type:, expression:, line: start_token.line, column: start_token.column)
255
255
  rescue ParseError => e
256
- raise e if parse_diagnostic_hint?(e)
256
+ raise e if diagnostic_hint_error?(e)
257
257
 
258
258
  nil
259
259
  ensure
@@ -324,7 +324,7 @@ module MilkTea
324
324
 
325
325
  AST::Specialization.new(callee: expression, arguments:)
326
326
  rescue ParseError => e
327
- raise e if parse_diagnostic_hint?(e)
327
+ raise e if diagnostic_hint_error?(e)
328
328
 
329
329
  @current = saved_current
330
330
  nil
@@ -344,7 +344,7 @@ module MilkTea
344
344
  end
345
345
 
346
346
  def parse_call_argument
347
- if (check_name || keyword_token?(peek)) && check_next(:equal)
347
+ if (check_name || keyword?(peek)) && check_next(:equal)
348
348
  name = advance.lexeme
349
349
  consume(:equal, "expected '=' after named argument name")
350
350
  AST::Argument.new(name:, value: parse_expression)
@@ -355,15 +355,15 @@ module MilkTea
355
355
 
356
356
  def parse_primary
357
357
  if match(:size_of)
358
- parse_sizeof_expr
358
+ parse_sizeof_expression
359
359
  elsif match(:align_of)
360
- parse_alignof_expr
360
+ parse_alignof_expression
361
361
  elsif match(:offset_of)
362
- parse_offsetof_expr
362
+ parse_offsetof_expression
363
363
  elsif match(:members_of) || match(:attributes_of) || match(:field_of) || match(:callable_of) || match(:attribute_of) || match(:has_attribute) || match(:attribute_arg) || match(:fields_of)
364
364
  AST::Identifier.new(name: previous.lexeme, line: previous.line, column: previous.column)
365
365
  elsif match(:proc)
366
- parse_proc_expr
366
+ parse_proc_expression
367
367
  elsif match_name
368
368
  AST::Identifier.new(name: previous.lexeme, line: previous.line, column: previous.column)
369
369
  elsif match(:integer)
@@ -394,7 +394,7 @@ module MilkTea
394
394
  elsif match(:lparen)
395
395
  line = previous.line
396
396
  column = previous.column
397
- first = if (check_name || keyword_token?(peek)) && check_next(:equal)
397
+ first = if (check_name || keyword?(peek)) && check_next(:equal)
398
398
  name_token = advance
399
399
  consume(:equal, "expected '=' after named tuple field")
400
400
  AST::Argument.new(name: name_token.lexeme, value: parse_expression)
@@ -404,7 +404,7 @@ module MilkTea
404
404
  if match(:comma)
405
405
  elements = [first]
406
406
  loop do
407
- if (check_name || keyword_token?(peek)) && check_next(:equal)
407
+ if (check_name || keyword?(peek)) && check_next(:equal)
408
408
  name_token = advance
409
409
  consume(:equal, "expected '=' after named tuple field")
410
410
  value = parse_expression
@@ -421,7 +421,7 @@ module MilkTea
421
421
  consume(:rparen, "expected ')' after expression")
422
422
  first
423
423
  end
424
- elsif keyword_token?(peek)
424
+ elsif keyword?(peek)
425
425
  advance
426
426
  AST::Identifier.new(name: previous.lexeme, line: previous.line, column: previous.column)
427
427
  else
@@ -444,9 +444,9 @@ module MilkTea
444
444
  AST::StringLiteral.new(lexeme:, value:, cstring: all_cstring)
445
445
  end
446
446
 
447
- def parse_proc_expr
447
+ def parse_proc_expression
448
448
  consume(:lparen, "expected '(' after proc")
449
- params = parse_comma_separated_until(:rparen) { parse_function_type_param }
449
+ params = parse_comma_separated_until(:rparen) { parse_callable_type_param }
450
450
 
451
451
  consume(:rparen, "expected ')' after proc parameters")
452
452
  consume(:arrow, "expected '->' after proc parameters")
@@ -463,21 +463,21 @@ module MilkTea
463
463
  AST::ProcExpr.new(params:, return_type:, body:)
464
464
  end
465
465
 
466
- def parse_sizeof_expr
466
+ def parse_sizeof_expression
467
467
  consume(:lparen, "expected '(' after size_of")
468
468
  type = parse_type_ref
469
469
  consume(:rparen, "expected ')' after size_of type")
470
470
  AST::SizeofExpr.new(type:)
471
471
  end
472
472
 
473
- def parse_alignof_expr
473
+ def parse_alignof_expression
474
474
  consume(:lparen, "expected '(' after align_of")
475
475
  type = parse_type_ref
476
476
  consume(:rparen, "expected ')' after align_of type")
477
477
  AST::AlignofExpr.new(type:)
478
478
  end
479
479
 
480
- def parse_offsetof_expr
480
+ def parse_offsetof_expression
481
481
  consume(:lparen, "expected '(' after offset_of")
482
482
  type = parse_type_ref
483
483
  consume(:comma, "expected ',' after offset_of type")
@@ -581,7 +581,7 @@ module MilkTea
581
581
  expression.is_a?(AST::Identifier) && %w[array reinterpret span zero ptr const_ptr own ref adapt equal hash order simd SoA].include?(expression.name)
582
582
  end
583
583
 
584
- def parse_diagnostic_hint?(error)
584
+ def diagnostic_hint_error?(error)
585
585
  error.message.include?("did you mean T<-expr?")
586
586
  end
587
587
 
@@ -598,7 +598,7 @@ module MilkTea
598
598
 
599
599
  def specialization_call_target?(expression, arguments, call_arguments)
600
600
  if expression.is_a?(AST::Identifier) && %w[default zero].include?(expression.name) &&
601
- !known_type_like_name?(expression.name) && !generic_callable_specialization_target?(expression)
601
+ !known_type_context_name?(expression.name) && !generic_callable_specialization_target?(expression)
602
602
  return false
603
603
  end
604
604
 
@@ -643,7 +643,7 @@ module MilkTea
643
643
  when AST::FunctionType, AST::TupleType
644
644
  true
645
645
  when AST::TypeRef
646
- known_type_like_name?(value.name.parts.first)
646
+ known_type_context_name?(value.name.parts.first)
647
647
  else
648
648
  false
649
649
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MilkTea
4
- module Parse
4
+ class Parser
5
5
  module Recovery
6
6
  TOP_LEVEL_RECOVERY_START_TYPES = %i[
7
7
  module import at public attribute const var type struct union enum flags variant interface
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MilkTea
4
- module Parse
4
+ class Parser
5
5
  module Statements
6
6
  def check_inline_stmt_start?
7
7
  return false unless check(:inline)
@@ -363,7 +363,7 @@ module MilkTea
363
363
  binding_token.lexeme
364
364
  end
365
365
 
366
- if match_arm_expr_form?
366
+ if match_arm_expression_form?
367
367
  consume(:colon, "expected ':' after match expression arm pattern")
368
368
  value = parse_expression
369
369
  finish_expression_statement(value)
@@ -410,7 +410,7 @@ module MilkTea
410
410
  raise
411
411
  end
412
412
 
413
- def match_arm_expr_form?
413
+ def match_arm_expression_form?
414
414
  check(:colon) && @current + 1 < @tokens.length && @tokens[@current + 1].type != :newline
415
415
  end
416
416
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MilkTea
4
- module Parse
4
+ class Parser
5
5
  module Types
6
6
  def parse_params(allow_variadic: false)
7
7
  parse_parameter_list(allow_variadic:) { parse_param }
@@ -63,7 +63,7 @@ module MilkTea
63
63
  end
64
64
 
65
65
  def parse_foreign_param
66
- mode = if foreign_param_qualifier_mode?
66
+ mode = if foreign_param_mode_start?
67
67
  advance.type
68
68
  else
69
69
  :plain
@@ -158,7 +158,7 @@ module MilkTea
158
158
 
159
159
  def parse_callable_type_ref(keyword:, param_context:)
160
160
  consume(:lparen, "expected '(' after #{keyword}")
161
- params = parse_comma_separated_until(:rparen) { parse_function_type_param }
161
+ params = parse_comma_separated_until(:rparen) { parse_callable_type_param }
162
162
 
163
163
  consume(:rparen, "expected ')' after #{param_context}")
164
164
  consume(:arrow, "expected '->' after #{param_context}")
@@ -166,7 +166,7 @@ module MilkTea
166
166
  yield params, return_type
167
167
  end
168
168
 
169
- def parse_function_type_param
169
+ def parse_callable_type_param
170
170
  name_token = consume_name_allowing_keywords("expected function type parameter name")
171
171
  name = name_token.lexeme
172
172
  consume(:colon, "expected ':' after function type parameter name")
@@ -33,6 +33,24 @@ module MilkTea
33
33
  end
34
34
  end
35
35
 
36
+ class SyntaxTokenStream
37
+ def initialize(tokens)
38
+ @tokens = tokens
39
+ end
40
+
41
+ def [](index)
42
+ @tokens[index]
43
+ end
44
+
45
+ def length
46
+ @tokens.length
47
+ end
48
+
49
+ def to_a
50
+ @tokens
51
+ end
52
+ end
53
+
36
54
  class Parser
37
55
  ParseRecoveryResult = Data.define(:ast, :errors) do
38
56
  def initialize(ast:, errors: []) = super
@@ -40,13 +58,13 @@ module MilkTea
40
58
 
41
59
  ParseContext = Data.define(:known_type_names, :known_import_aliases, :known_generic_callable_names, :current_type_param_names)
42
60
 
43
- include Parse::Blocks
44
- include Parse::Recovery
45
- include Parse::Types
46
- include Parse::Attributes
47
- include Parse::Expressions
48
- include Parse::Declarations
49
- include Parse::Statements
61
+ include Blocks
62
+ include Recovery
63
+ include Types
64
+ include Attributes
65
+ include Expressions
66
+ include Declarations
67
+ include Statements
50
68
 
51
69
  def self.parse(source = nil, path: nil, tokens: nil)
52
70
  token_stream = tokens || Lexer.lex(source, path: path)
@@ -106,7 +124,7 @@ module MilkTea
106
124
  directives = []
107
125
  declarations = []
108
126
 
109
- if external_file_header?
127
+ if at_external_file?
110
128
  advance
111
129
  module_line = previous.line
112
130
  module_kind = :raw_module
@@ -150,7 +168,7 @@ module MilkTea
150
168
  AST.assign_node_ids(AST::SourceFile.new(module_name:, module_kind:, imports:, directives:, declarations:, line: module_line))
151
169
  end
152
170
 
153
- def external_file_header?
171
+ def at_external_file?
154
172
  return false unless check(:external)
155
173
 
156
174
  next_token = @tokens[@current + 1]
@@ -188,7 +206,7 @@ module MilkTea
188
206
  end
189
207
 
190
208
  def consume_name(message)
191
- if keyword_token?(peek)
209
+ if keyword?(peek)
192
210
  name_role = message.sub(/\A(?:expected|required)\s+/, "")
193
211
  clearer_message = if name_role == message
194
212
  message
@@ -204,14 +222,14 @@ module MilkTea
204
222
  def consume_name_allowing_keywords(message)
205
223
  if check(:identifier)
206
224
  advance
207
- elsif keyword_token?(peek)
225
+ elsif keyword?(peek)
208
226
  advance
209
227
  else
210
228
  raise error(peek, message)
211
229
  end
212
230
  end
213
231
 
214
- def keyword_token?(token)
232
+ def keyword?(token)
215
233
  token && Token::KEYWORDS.key?(token.lexeme)
216
234
  end
217
235
 
@@ -288,7 +306,7 @@ module MilkTea
288
306
  items
289
307
  end
290
308
 
291
- def foreign_param_qualifier_mode?
309
+ def foreign_param_mode_start?
292
310
  return false unless %i[out in inout consuming].include?(peek.type)
293
311
 
294
312
  @tokens[@current + 1]&.type == :identifier
@@ -298,7 +316,7 @@ module MilkTea
298
316
  token&.type == :identifier && BUILTIN_ATTRIBUTE_NAME_LEXEMES.include?(token.lexeme)
299
317
  end
300
318
 
301
- def known_type_like_name?(name)
319
+ def known_type_context_name?(name)
302
320
  @known_type_names.key?(name) || @known_import_aliases.key?(name) || @current_type_param_names.include?(name)
303
321
  end
304
322
 
@@ -348,7 +366,7 @@ module MilkTea
348
366
  if depth.zero?
349
367
  name_token = @tokens[index + 1]
350
368
  type_param_token = @tokens[index + 2]
351
- if type_name_token?(name_token) && type_param_token&.type == :lbracket
369
+ if identifier_token?(name_token) && type_param_token&.type == :lbracket
352
370
  @known_generic_callable_names[name_token.lexeme] = true
353
371
  end
354
372
  end
@@ -356,7 +374,7 @@ module MilkTea
356
374
  if depth.zero? && @tokens[index + 1]&.type == :function
357
375
  name_token = @tokens[index + 2]
358
376
  type_param_token = @tokens[index + 3]
359
- if type_name_token?(name_token) && type_param_token&.type == :lbracket
377
+ if identifier_token?(name_token) && type_param_token&.type == :lbracket
360
378
  @known_generic_callable_names[name_token.lexeme] = true
361
379
  end
362
380
  end
@@ -364,14 +382,14 @@ module MilkTea
364
382
  if depth.zero? && @tokens[index + 1]&.type == :function
365
383
  name_token = @tokens[index + 2]
366
384
  type_param_token = @tokens[index + 3]
367
- if type_name_token?(name_token) && type_param_token&.type == :lbracket
385
+ if identifier_token?(name_token) && type_param_token&.type == :lbracket
368
386
  @known_generic_callable_names[name_token.lexeme] = true
369
387
  end
370
388
  end
371
389
  when :struct, :union, :enum, :flags, :opaque, :type, :variant
372
390
  if depth.zero?
373
391
  name_token = @tokens[index + 1]
374
- @known_type_names[name_token.lexeme] = true if type_name_token?(name_token)
392
+ @known_type_names[name_token.lexeme] = true if identifier_token?(name_token)
375
393
  end
376
394
  end
377
395
 
@@ -387,11 +405,11 @@ module MilkTea
387
405
  token = @tokens[cursor]
388
406
  if token.type == :as
389
407
  alias_token = @tokens[cursor + 1]
390
- @known_import_aliases[alias_token.lexeme] = true if type_name_token?(alias_token)
408
+ @known_import_aliases[alias_token.lexeme] = true if identifier_token?(alias_token)
391
409
  return cursor
392
410
  end
393
411
 
394
- last_part = token.lexeme if type_name_token?(token)
412
+ last_part = token.lexeme if identifier_token?(token)
395
413
  cursor += 1
396
414
  end
397
415
 
@@ -399,7 +417,7 @@ module MilkTea
399
417
  cursor
400
418
  end
401
419
 
402
- def type_name_token?(token)
420
+ def identifier_token?(token)
403
421
  token&.type == :identifier
404
422
  end
405
423