mt-lang 0.3.14 → 0.3.17

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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/docs/index.html +8 -8
  4. data/docs/language-design.md +7 -12
  5. data/docs/language-manual.md +20 -8
  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/{binding_types.rb → bindings.rb} +1 -1
  9. data/lib/milk_tea/core/c_backend.rb +14 -15
  10. data/lib/milk_tea/core/compile_time.rb +181 -2
  11. data/lib/milk_tea/core/control_flow/builder.rb +62 -2
  12. data/lib/milk_tea/core/control_flow/constant_propagation.rb +1 -1
  13. data/lib/milk_tea/core/{compatibility_helpers.rb → intrinsics.rb} +2 -2
  14. data/lib/milk_tea/core/lexer.rb +10 -14
  15. data/lib/milk_tea/core/lowering/async/analysis.rb +3 -9
  16. data/lib/milk_tea/core/lowering/async/lowering.rb +2 -10
  17. data/lib/milk_tea/core/lowering/async/normalization.rb +2 -7
  18. data/lib/milk_tea/core/lowering/block.rb +1 -5
  19. data/lib/milk_tea/core/lowering/proc.rb +1 -5
  20. data/lib/milk_tea/core/lowering/scans.rb +3 -1
  21. data/lib/milk_tea/core/lowering/utils.rb +1 -27
  22. data/lib/milk_tea/core/lowering.rb +18 -18
  23. data/lib/milk_tea/core/module_loader.rb +26 -15
  24. data/lib/milk_tea/core/parser/statements.rb +18 -12
  25. data/lib/milk_tea/core/parser.rb +17 -17
  26. data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +3 -11
  27. data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +2 -3
  28. data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +1 -1
  29. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +1 -2
  30. data/lib/milk_tea/core/semantic_analyzer/nullability.rb +2 -4
  31. data/lib/milk_tea/core/semantic_analyzer/statements.rb +2 -8
  32. data/lib/milk_tea/core/semantic_analyzer.rb +1 -1
  33. data/lib/milk_tea/core.rb +6 -2
  34. data/lib/milk_tea/dap/lldb_dap_backend.rb +153 -0
  35. data/lib/milk_tea/dap/server/lldb_backend.rb +1 -1
  36. data/lib/milk_tea/dap.rb +1 -1
  37. data/lib/milk_tea/lsp.rb +1 -7
  38. data/lib/milk_tea/{bindings/cli.rb → tooling/bindgen_cli.rb} +1 -1
  39. data/lib/milk_tea/tooling/linter/imports_platform.rb +2 -4
  40. data/lib/milk_tea/tooling/linter/release_rules.rb +1 -6
  41. data/lib/milk_tea/tooling/linter/source_helpers.rb +0 -6
  42. data/lib/milk_tea/tooling/linter/visitors.rb +4 -8
  43. data/lib/milk_tea/tooling/sexpr_dumper.rb +2 -0
  44. data/lib/milk_tea/tooling.rb +1 -1
  45. data/std/asset_pack.mt +1 -1
  46. data/std/async/libuv_runtime.mt +6 -6
  47. data/std/async/mailbox.mt +4 -4
  48. data/std/cookie.mt +2 -2
  49. data/std/crypto.mt +1 -1
  50. data/std/curl/runtime.mt +10 -10
  51. data/std/fs.linux.mt +26 -26
  52. data/std/fs.windows.mt +22 -22
  53. data/std/goap.mt +2 -2
  54. data/std/http/server.mt +21 -21
  55. data/std/http.mt +14 -14
  56. data/std/jobs.mt +4 -4
  57. data/std/json.mt +5 -5
  58. data/std/log.mt +1 -1
  59. data/std/mem/tracking.mt +1 -1
  60. data/std/net/channel.mt +4 -4
  61. data/std/net/clock.mt +6 -6
  62. data/std/net/discovery.mt +7 -7
  63. data/std/net/lobby.mt +10 -10
  64. data/std/net/manager.mt +1 -1
  65. data/std/net/mux.mt +4 -4
  66. data/std/net/nat.mt +4 -4
  67. data/std/net/packet.mt +3 -3
  68. data/std/net/punch.mt +3 -3
  69. data/std/net/rpc.mt +3 -3
  70. data/std/net/session.mt +15 -15
  71. data/std/net/stun.mt +4 -4
  72. data/std/net/turn.mt +4 -4
  73. data/std/oauth2.mt +12 -12
  74. data/std/path.mt +8 -8
  75. data/std/process.mt +4 -4
  76. data/std/raylib/packed_assets.mt +5 -5
  77. data/std/serialize.mt +1 -1
  78. data/std/tar.mt +10 -10
  79. data/std/terminal.mt +18 -18
  80. data/std/tls.mt +8 -8
  81. data/std/uri.mt +1 -1
  82. data/std/utility.mt +1 -1
  83. metadata +7 -9
  84. data/lib/milk_tea/core/compile_time/const_eval.rb +0 -182
  85. data/lib/milk_tea/core/module_loader/errors.rb +0 -23
  86. data/lib/milk_tea/dap/backends/lldb_dap.rb +0 -156
  87. /data/lib/milk_tea/core/lowering/{async.rb → async/frame_builder.rb} +0 -0
@@ -145,15 +145,9 @@ module MilkTea
145
145
  when AST::UnsafeStmt
146
146
  await_counter = analyze_async_statements!(statement.body, await_counter, env, param_fields, local_fields, await_fields)
147
147
  when AST::DeferStmt
148
- if statement.body
149
- cleanup_env = duplicate_env(env)
150
- cleanup_env[:return_context] = cleanup_env[:return_context]&.merge(allow_return: false)
151
- await_counter = analyze_async_statements!(statement.body, await_counter, cleanup_env, param_fields, local_fields, await_fields)
152
- end
153
- if statement.expression.is_a?(AST::AwaitExpr)
154
- await_fields[statement.expression.object_id] = build_async_await_field_info(statement.expression, await_counter, env:, param_fields:, local_fields:)
155
- await_counter += 1
156
- end
148
+ cleanup_env = duplicate_env(env)
149
+ cleanup_env[:return_context] = cleanup_env[:return_context]&.merge(allow_return: false)
150
+ await_counter = analyze_async_statements!(statement.body, await_counter, cleanup_env, param_fields, local_fields, await_fields)
157
151
  else
158
152
  nil
159
153
  end
@@ -194,7 +194,7 @@ module MilkTea
194
194
  when AST::UnsafeStmt
195
195
  statements_contain_await?(s.body, async_info)
196
196
  when AST::DeferStmt
197
- (s.body && statements_contain_await?(s.body, async_info)) || (s.expression && async_expression_contains_await?(s.expression))
197
+ statements_contain_await?(s.body, async_info)
198
198
  else
199
199
  false
200
200
  end
@@ -1237,15 +1237,7 @@ module MilkTea
1237
1237
  end
1238
1238
 
1239
1239
  def lower_async_defer_cleanup(statement, env:, async_info:)
1240
- body = if statement.body
1241
- statement.body
1242
- elsif statement.expression
1243
- [AST::ExpressionStmt.new(expression: statement.expression, line: statement.line)]
1244
- else
1245
- []
1246
- end
1247
-
1248
- { body:, env: snapshot_env(env) }
1240
+ { body: statement.body, env: snapshot_env(env) }
1249
1241
  end
1250
1242
 
1251
1243
  def lower_async_cleanup_entries(local_defers, outer_defers, frame_expr:, raw_frame_expr:, async_info:)
@@ -154,13 +154,8 @@ module MilkTea
154
154
  when AST::DeferStmt
155
155
  cleanup_env = duplicate_env(env)
156
156
  cleanup_env[:return_context] = cleanup_env[:return_context]&.merge(allow_return: false)
157
- cleanup_body = if statement.body
158
- normalize_async_statements(statement.body, counter, cleanup_env, return_type:)
159
- else
160
- expression_setup, expression = normalize_async_expression(statement.expression, counter, env: cleanup_env)
161
- expression_setup + [AST::ExpressionStmt.new(expression:, line: statement.line)]
162
- end
163
- [AST::DeferStmt.new(expression: nil, body: cleanup_body, line: statement.line, column: statement.column, length: statement.length)]
157
+ cleanup_body = normalize_async_statements(statement.body, counter, cleanup_env, return_type:)
158
+ [AST::DeferStmt.new(body: cleanup_body, line: statement.line, column: statement.column, length: statement.length)]
164
159
  when AST::BreakStmt, AST::ContinueStmt, AST::StaticAssert, AST::PassStmt
165
160
  [statement]
166
161
  else
@@ -16,11 +16,7 @@ module MilkTea
16
16
  statements.each do |statement|
17
17
  case statement
18
18
  when AST::DeferStmt
19
- local_defers << if statement.body
20
- lower_defer_cleanup_body(statement.body, env: local_env, return_type:)
21
- else
22
- lower_defer_cleanup_expression(statement.expression, env: local_env)
23
- end
19
+ local_defers << lower_defer_cleanup_body(statement.body, env: local_env, return_type:)
24
20
  when AST::UnsafeStmt
25
21
  lower_block_unsafe_stmt(statement, lowered:, local_defers:, local_env:, active_defers:, return_type:, loop_flow:, allow_return:)
26
22
  when AST::LocalDecl
@@ -180,11 +180,7 @@ module MilkTea
180
180
  when AST::ReturnStmt
181
181
  collect_proc_captures_from_expression(statement.value, env, local_scopes, captures) if statement.value
182
182
  when AST::DeferStmt
183
- if statement.body
184
- collect_proc_captures_from_statements(statement.body, env, local_scopes + [{}], captures)
185
- else
186
- collect_proc_captures_from_expression(statement.expression, env, local_scopes, captures)
187
- end
183
+ collect_proc_captures_from_statements(statement.body, env, local_scopes + [{}], captures)
188
184
  when AST::ExpressionStmt
189
185
  collect_proc_captures_from_expression(statement.expression, env, local_scopes, captures)
190
186
  when AST::BreakStmt, AST::ContinueStmt, AST::PassStmt
@@ -144,8 +144,10 @@ module MilkTea
144
144
  (expression && expression_uses_pattern?(expression, &predicate)) || block_uses_expression_pattern?(statement.body, &predicate)
145
145
  when AST::ReturnStmt
146
146
  statement.value && expression_uses_pattern?(statement.value, &predicate)
147
- when AST::DeferStmt, AST::ExpressionStmt
147
+ when AST::ExpressionStmt
148
148
  expression_uses_pattern?(statement.expression, &predicate)
149
+ when AST::DeferStmt
150
+ block_uses_expression_pattern?(statement.body, &predicate)
149
151
  else
150
152
  false
151
153
  end
@@ -760,32 +760,6 @@ module MilkTea
760
760
  end
761
761
  end
762
762
 
763
- def lower_defer_cleanup_expression(expression, env:)
764
- prepared_setup, prepared_expression, prepared_cleanups = prepare_expression_with_cleanups(
765
- expression,
766
- env:,
767
- expected_type: infer_expression_type(expression, env:),
768
- allow_root_statement_foreign: true,
769
- )
770
-
771
- lowered = []
772
- lowered.concat(prepared_setup)
773
- if (foreign_call = foreign_call_info(prepared_expression, env))
774
- setup, = lower_foreign_call_statement(
775
- foreign_call,
776
- env:,
777
- expected_type: foreign_call[:binding].type.return_type,
778
- statement_position: true,
779
- discard_result: true,
780
- )
781
- lowered.concat(setup)
782
- else
783
- lowered << IR::ExpressionStmt.new(expression: lower_expression(prepared_expression, env:))
784
- end
785
- lowered.concat(prepared_cleanups.flat_map(&:itself))
786
- lowered
787
- end
788
-
789
763
  def lower_defer_cleanup_body(statements, env:, return_type:)
790
764
  lower_block(statements, env:, active_defers: [], return_type:, loop_flow: nil, allow_return: false)
791
765
  end
@@ -1161,7 +1135,7 @@ module MilkTea
1161
1135
  cached = cache[text]
1162
1136
  return cached if cached
1163
1137
 
1164
- identifier = text.gsub(/[^A-Za-z0-9_]+/, "_").gsub(/_+/, "_").sub(/_+$/, "").sub(/^_{2,}/, "_")
1138
+ identifier = text.gsub(/[^A-Za-z0-9_]+/, "_").gsub(/_+/, "_").sub(/_+$/, "").sub(/^_+/, "")
1165
1139
  cache[text] = identifier.empty? ? "value" : identifier
1166
1140
  end
1167
1141
 
@@ -31,7 +31,7 @@ require_relative "lowering/functions"
31
31
  require_relative "lowering/async/analysis"
32
32
  require_relative "lowering/async/normalization"
33
33
  require_relative "lowering/async/lowering"
34
- require_relative "lowering/async"
34
+ require_relative "lowering/async/frame_builder"
35
35
  require_relative "lowering/block"
36
36
  require_relative "lowering/proc"
37
37
  require_relative "lowering/loops"
@@ -85,11 +85,27 @@ module MilkTea
85
85
  OrderResolution = Data.define(:target_type, :binding, :callee_name)
86
86
 
87
87
  class Lowerer
88
- include CompatibilityHelpers
88
+ include Intrinsics
89
89
 
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
108
+
93
109
  def initialize(program)
94
110
  @program = program
95
111
  @ctx = ModuleContext.new
@@ -358,21 +374,5 @@ module MilkTea
358
374
  ordered.concat(modules.values - ordered)
359
375
  ordered
360
376
  end
361
-
362
- include LowererScans
363
- include LowererDeclarations
364
- include LowererEvents
365
- include LowererFunctions
366
- include LowererAsync
367
- include LowererBlock
368
- include LowererProc
369
- include LowererLoops
370
- include LowererExpressions
371
- include LowererCalls
372
- include LowererForeignCstr
373
- include LowererStrBuffer
374
- include LowererResolve
375
- include LowererDyn
376
- include LowererUtils
377
377
  end
378
378
  end
@@ -1,13 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "module_loader/errors"
4
- require_relative "module_path_resolver"
5
- require_relative "module_binder"
6
- require_relative "async_runtime_installer"
7
- require_relative "prelude_installer"
8
-
9
3
  module MilkTea
4
+ class ModuleLoadError < StandardError
5
+ attr_reader :path, :line, :column
6
+
7
+ def initialize(message, path:, line: nil, column: nil)
8
+ @path = path
9
+ @line = line
10
+ @column = column
11
+ super("#{message}: #{path}")
12
+ end
13
+
14
+ def code
15
+ "module/error"
16
+ end
17
+ end
18
+
10
19
  class ModuleLoader
20
+ ImportResolution = Data.define(:modules, :errors)
21
+ ImportResolutionError = Data.define(:import, :error)
11
22
  Program = Data.define(:root_path, :root_analysis, :analyses_by_path, :analyses_by_module_name)
12
23
  PLATFORM_SUFFIXES = {
13
24
  "linux" => :linux,
@@ -90,6 +101,15 @@ module MilkTea
90
101
  MilkTea.host_platform
91
102
  end
92
103
 
104
+ def self.raise_platform_conflict!(path, pinned_platform, active_platform, error_class: nil)
105
+ if error_class == ModuleLoadError
106
+ raise ModuleLoadError.new("source file targets platform #{pinned_platform}; active platform is #{active_platform}", path:)
107
+ end
108
+
109
+ message = "source file #{path} targets platform #{pinned_platform}; active platform is #{active_platform}"
110
+ raise(error_class || ArgumentError, message)
111
+ end
112
+
93
113
  def initialize(module_roots: [MilkTea.root], package_graph: nil, shared_cache: nil, source_overrides: nil, platform: nil)
94
114
  @module_roots = module_roots.map { |root| File.expand_path(root.to_s) }
95
115
  @ast_cache = {}
@@ -380,15 +400,6 @@ module MilkTea
380
400
  @collecting_path_errors
381
401
  end
382
402
 
383
- def self.raise_platform_conflict!(path, pinned_platform, active_platform, error_class: nil)
384
- if error_class == ModuleLoadError
385
- raise ModuleLoadError.new("source file targets platform #{pinned_platform}; active platform is #{active_platform}", path:)
386
- end
387
-
388
- message = "source file #{path} targets platform #{pinned_platform}; active platform is #{active_platform}"
389
- raise(error_class || ArgumentError, message)
390
- end
391
-
392
403
  def check_path(path)
393
404
  resolved_path, ast, cached = check_module_cache(path)
394
405
  return cached if cached
@@ -279,6 +279,18 @@ module MilkTea
279
279
  check(:colon) && @current + 1 < @tokens.length && @tokens[@current + 1].type != :newline
280
280
  end
281
281
 
282
+ def parse_inline_or_block_body(message)
283
+ if inline_block_body?
284
+ consume(:colon, "expected ':' #{message}")
285
+ @in_inline_block_body = true
286
+ result = [parse_statement]
287
+ @in_inline_block_body = false
288
+ result
289
+ else
290
+ parse_block
291
+ end
292
+ end
293
+
282
294
  def parse_match_stmt
283
295
  token = previous
284
296
  line = token.line
@@ -456,7 +468,7 @@ module MilkTea
456
468
  consume(:in, "expected 'in' in for loop")
457
469
  iterables = [parse_expression]
458
470
  iterables << parse_expression while match(:comma)
459
- body = parse_block
471
+ body = parse_inline_or_block_body("after 'in' iterables")
460
472
  AST::ForStmt.new(bindings:, iterables:, body:, line:, column: bindings.first.column)
461
473
  rescue ParseError => e
462
474
  raise unless @recovery_errors
@@ -530,7 +542,7 @@ module MilkTea
530
542
  token = previous
531
543
  line = token.line
532
544
  condition = parse_expression
533
- body = parse_block
545
+ body = parse_inline_or_block_body("after while condition")
534
546
  AST::WhileStmt.new(condition:, body:, line:, column: token.column, length: token.lexeme.length)
535
547
  rescue ParseError => e
536
548
  raise unless @recovery_errors
@@ -580,14 +592,8 @@ module MilkTea
580
592
  def parse_defer_stmt
581
593
  token = previous
582
594
  line = token.line
583
- if check(:colon)
584
- body = parse_block
585
- AST::DeferStmt.new(expression: nil, body:, line:, column: token.column, length: token.lexeme.length)
586
- else
587
- expression = parse_expression
588
- consume_end_of_statement unless block_expression?(expression)
589
- AST::DeferStmt.new(expression:, body: nil, line:, column: token.column, length: token.lexeme.length)
590
- end
595
+ body = parse_inline_or_block_body("after defer")
596
+ AST::DeferStmt.new(body:, line:, column: token.column, length: token.lexeme.length)
591
597
  end
592
598
 
593
599
  def parse_when_decl
@@ -690,7 +696,7 @@ module MilkTea
690
696
  consume(:in, "expected 'in' in for loop")
691
697
  iterables = [parse_expression]
692
698
  iterables << parse_expression while match(:comma)
693
- body = parse_block
699
+ body = parse_inline_or_block_body("after 'in' iterables")
694
700
  AST::ForStmt.new(bindings:, iterables:, body:, inline: true, line:, column: bindings.first.column)
695
701
  rescue ParseError => e
696
702
  raise unless @recovery_errors
@@ -705,7 +711,7 @@ module MilkTea
705
711
  def parse_inline_while_stmt(inline_token)
706
712
  line = inline_token.line
707
713
  condition = parse_expression
708
- body = parse_block
714
+ body = parse_inline_or_block_body("after inline while condition")
709
715
  AST::WhileStmt.new(condition:, body:, inline: true, line:, column: inline_token.column, length: inline_token.lexeme.length)
710
716
  rescue ParseError => e
711
717
  raise unless @recovery_errors
@@ -155,6 +155,23 @@ module MilkTea
155
155
  next_token.nil? || %i[newline eof].include?(next_token.type)
156
156
  end
157
157
 
158
+ def advance
159
+ @current += 1 unless eof?
160
+ previous
161
+ end
162
+
163
+ def eof?
164
+ peek.type == :eof
165
+ end
166
+
167
+ def peek
168
+ @tokens[@current]
169
+ end
170
+
171
+ def previous
172
+ @tokens[@current - 1]
173
+ end
174
+
158
175
  def match(*types)
159
176
  return false unless types.any? { |type| check(type) }
160
177
 
@@ -219,23 +236,6 @@ module MilkTea
219
236
  true
220
237
  end
221
238
 
222
- def advance
223
- @current += 1 unless eof?
224
- previous
225
- end
226
-
227
- def eof?
228
- peek.type == :eof
229
- end
230
-
231
- def peek
232
- @tokens[@current]
233
- end
234
-
235
- def previous
236
- @tokens[@current - 1]
237
- end
238
-
239
239
  def error(token, message)
240
240
  ParseError.new(message, token:, path: @path)
241
241
  end
@@ -521,13 +521,9 @@ module MilkTea
521
521
  when AST::ReturnStmt
522
522
  line(statement.value ? "return #{render_expression(statement.value)}" : "return")
523
523
  when AST::DeferStmt
524
- if statement.body
525
- line("defer:")
526
- with_indent do
527
- statement.body.each { |nested| emit_statement(nested) }
528
- end
529
- else
530
- line("defer #{render_expression(statement.expression)}")
524
+ line("defer:")
525
+ with_indent do
526
+ statement.body.each { |nested| emit_statement(nested) }
531
527
  end
532
528
  when AST::ExpressionStmt
533
529
  line(render_expression(statement.expression))
@@ -649,10 +645,6 @@ module MilkTea
649
645
  "continue"
650
646
  when AST::ReturnStmt
651
647
  statement.value ? "return #{render_expression(statement.value)}" : "return"
652
- when AST::DeferStmt
653
- return nil if statement.body
654
-
655
- "defer #{render_expression(statement.expression)}"
656
648
  when AST::ExpressionStmt
657
649
  render_expression(statement.expression)
658
650
  else
@@ -180,8 +180,7 @@ module MilkTea
180
180
  when AST::UnsafeStmt
181
181
  statement.body.each { |s| validate_async_statement!(s) }
182
182
  when AST::DeferStmt
183
- validate_async_expression_support!(statement.expression, context: "defer cleanup") if statement.expression
184
- statement.body&.each { |s| validate_async_statement!(s) }
183
+ statement.body.each { |s| validate_async_statement!(s) }
185
184
  when AST::WhenStmt
186
185
  statement.branches.each { |branch| branch.body.each { |s| validate_async_statement!(s) } }
187
186
  statement.else_body&.each { |s| validate_async_statement!(s) }
@@ -230,7 +229,7 @@ module MilkTea
230
229
  when AST::ReturnStmt
231
230
  statement.value && expression_contains_await?(statement.value)
232
231
  when AST::DeferStmt
233
- (statement.expression && expression_contains_await?(statement.expression)) || (statement.body && statements_contain_await?(statement.body))
232
+ statements_contain_await?(statement.body)
234
233
  when AST::ExpressionStmt
235
234
  expression_contains_await?(statement.expression)
236
235
  else
@@ -209,7 +209,7 @@ module MilkTea
209
209
  end
210
210
  end
211
211
  when AST::DeferStmt
212
- lines.concat(statement_list_lines(statement.body)) if statement.body
212
+ lines.concat(statement_list_lines(statement.body))
213
213
  when AST::Assignment
214
214
  lines << expression_end_line(statement.value)
215
215
  when AST::ReturnStmt
@@ -375,9 +375,8 @@ module MilkTea
375
375
  body_names = names.dup
376
376
  stmt.body&.each { |s| check_stmt_names(s, scopes, binding, body_names) }
377
377
  when AST::DeferStmt
378
- check_expr_names(stmt.expression, scopes, binding, names) if stmt.expression
379
378
  body_names = names.dup
380
- stmt.body&.each { |s| check_stmt_names(s, scopes, binding, body_names) }
379
+ stmt.body.each { |s| check_stmt_names(s, scopes, binding, body_names) }
381
380
  when AST::WhenStmt
382
381
  check_expr_names(stmt.discriminant, scopes, binding, names)
383
382
  stmt.branches.each do |b|
@@ -154,8 +154,7 @@ module MilkTea
154
154
  statement.iterables.each { |iterable| preassign_local_binding_ids_in_expression(iterable) }
155
155
  preassign_local_binding_ids_in_statements(statement.body || [])
156
156
  when AST::DeferStmt
157
- preassign_local_binding_ids_in_expression(statement.expression) if statement.expression
158
- preassign_local_binding_ids_in_statements(statement.body || []) if statement.body
157
+ preassign_local_binding_ids_in_statements(statement.body)
159
158
  when AST::ReturnStmt
160
159
  preassign_local_binding_ids_in_expression(statement.value) if statement.value
161
160
  when AST::StaticAssert
@@ -319,8 +318,7 @@ module MilkTea
319
318
  end
320
319
  walk_statements_for_precheck_resolution(statement.body || [], for_scopes, declaration_ids, identifier_ids)
321
320
  when AST::DeferStmt
322
- walk_expression_for_precheck_resolution(statement.expression, block_scopes, identifier_ids, declaration_ids) if statement.expression
323
- walk_statements_for_precheck_resolution(statement.body || [], block_scopes, declaration_ids, identifier_ids) if statement.body
321
+ walk_statements_for_precheck_resolution(statement.body, block_scopes, declaration_ids, identifier_ids)
324
322
  when AST::ExpressionStmt
325
323
  walk_expression_for_precheck_resolution(statement.expression, block_scopes, identifier_ids, declaration_ids)
326
324
  when AST::ReturnStmt
@@ -193,14 +193,8 @@ module MilkTea
193
193
  line: statement.line,
194
194
  )
195
195
  when AST::DeferStmt
196
- if statement.body
197
- with_loop_barrier do
198
- check_block(statement.body, scopes:, return_type:, allow_return: false)
199
- end
200
- else
201
- validate_consuming_foreign_expression!(statement.expression, scopes:, root_allowed: true)
202
- validate_hoistable_foreign_expression!(statement.expression, scopes:, root_hoistable: false)
203
- infer_expression(statement.expression, scopes:)
196
+ with_loop_barrier do
197
+ check_block(statement.body, scopes:, return_type:, allow_return: false)
204
198
  end
205
199
  when AST::ExpressionStmt
206
200
  validate_consuming_foreign_expression!(statement.expression, scopes:, root_allowed: true)
@@ -129,7 +129,7 @@ module MilkTea
129
129
  end
130
130
 
131
131
  class Checker
132
- include CompatibilityHelpers
132
+ include Intrinsics
133
133
 
134
134
  attr_reader :ctx
135
135
 
data/lib/milk_tea/core.rb CHANGED
@@ -10,11 +10,15 @@ require_relative "core/cst"
10
10
  require_relative "core/cst_builder"
11
11
  require_relative "core/ast"
12
12
  require_relative "core/types"
13
- require_relative "core/binding_types"
13
+ require_relative "core/bindings"
14
14
  require_relative "core/compile_time"
15
- require_relative "core/compatibility_helpers"
15
+ require_relative "core/intrinsics"
16
16
  require_relative "core/parser"
17
17
  require_relative "core/module_roots"
18
+ require_relative "core/module_path_resolver"
19
+ require_relative "core/module_binder"
20
+ require_relative "core/async_runtime_installer"
21
+ require_relative "core/prelude_installer"
18
22
  require_relative "core/module_loader"
19
23
  require_relative "core/semantic_analyzer"
20
24
  require_relative "core/ir"