mt-lang 0.3.17 → 0.3.22
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.
- checksums.yaml +4 -4
- data/lib/milk_tea/base.rb +1 -1
- data/lib/milk_tea/core/c_backend/expressions.rb +34 -23
- data/lib/milk_tea/core/c_backend/feature_detection.rb +25 -45
- data/lib/milk_tea/core/c_backend/type_collectors.rb +18 -30
- data/lib/milk_tea/core/c_backend/type_declaration.rb +0 -6
- data/lib/milk_tea/core/c_backend.rb +49 -39
- data/lib/milk_tea/core/compile_time.rb +98 -72
- data/lib/milk_tea/core/control_flow/builder.rb +2 -1
- data/lib/milk_tea/core/intrinsics.rb +7 -0
- data/lib/milk_tea/core/lexer.rb +46 -35
- data/lib/milk_tea/core/lowering/block.rb +9 -0
- data/lib/milk_tea/core/lowering/calls.rb +2 -0
- data/lib/milk_tea/core/lowering/declarations.rb +1 -1
- data/lib/milk_tea/core/lowering/functions.rb +11 -8
- data/lib/milk_tea/core/lowering/resolve.rb +11 -4
- data/lib/milk_tea/core/lowering/scans.rb +13 -18
- data/lib/milk_tea/core/module_binder.rb +19 -15
- data/lib/milk_tea/core/module_loader.rb +212 -59
- data/lib/milk_tea/core/module_path_resolver.rb +8 -7
- data/lib/milk_tea/core/parser/declarations.rb +43 -19
- data/lib/milk_tea/core/parser/expressions.rb +5 -8
- data/lib/milk_tea/core/parser/statements.rb +5 -5
- data/lib/milk_tea/core/parser.rb +26 -0
- data/lib/milk_tea/core/semantic_analyzer/calls.rb +24 -31
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +20 -23
- data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +146 -92
- data/lib/milk_tea/core/semantic_analyzer/statements.rb +19 -41
- data/lib/milk_tea/core/semantic_analyzer.rb +56 -37
- data/lib/milk_tea/core/types.rb +12 -17
- data/lib/milk_tea/lsp/diagnostics.rb +13 -0
- data/lib/milk_tea/lsp/server/semantic_tokens.rb +6 -0
- data/lib/milk_tea/tooling/cli/commands/bindgen.rb +11 -0
- data/lib/milk_tea/tooling/cli/commands/build.rb +37 -0
- data/lib/milk_tea/tooling/cli/commands/cache.rb +46 -0
- data/lib/milk_tea/tooling/cli/commands/check.rb +106 -0
- data/lib/milk_tea/tooling/cli/commands/command_base.rb +8 -0
- data/lib/milk_tea/tooling/cli/commands/completions.rb +48 -0
- data/lib/milk_tea/tooling/cli/commands/dap.rb +58 -0
- data/lib/milk_tea/tooling/cli/commands/debug.rb +77 -0
- data/lib/milk_tea/tooling/cli/commands/deps.rb +17 -0
- data/lib/milk_tea/tooling/cli/commands/docs.rb +58 -0
- data/lib/milk_tea/tooling/cli/commands/emit_c.rb +64 -0
- data/lib/milk_tea/tooling/cli/commands/format.rb +199 -0
- data/lib/milk_tea/tooling/cli/commands/lex.rb +46 -0
- data/lib/milk_tea/tooling/cli/commands/lint.rb +248 -0
- data/lib/milk_tea/tooling/cli/commands/lower.rb +50 -0
- data/lib/milk_tea/tooling/cli/commands/lsp.rb +43 -0
- data/lib/milk_tea/tooling/cli/commands/new.rb +26 -0
- data/lib/milk_tea/tooling/cli/commands/parse.rb +51 -0
- data/lib/milk_tea/tooling/cli/commands/run.rb +99 -0
- data/lib/milk_tea/tooling/cli/commands/snapshot.rb +117 -0
- data/lib/milk_tea/tooling/cli/commands/test.rb +557 -0
- data/lib/milk_tea/tooling/cli/commands/toolchain.rb +16 -0
- data/lib/milk_tea/tooling/cli.rb +101 -1893
- data/lib/milk_tea/tooling/sexpr_dumper.rb +7 -7
- metadata +24 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6dc76fcf0acde63fa4060157d6c6864dedcc32b0f5c2cd60422e9948d9861dab
|
|
4
|
+
data.tar.gz: 0b1bf5aee4d6be4d0f1968a7dacaf35e37557336a5911834a17324d23bd60ba3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1b34537660a1c2424b3f829ff6ef18d35de4366fe76d0a0938216261b1f9c7c56d8fce2c8a0ac1162f17ddc8c1a2c565f9e08f2f5f0056624f4959d35833cabf
|
|
7
|
+
data.tar.gz: 9b6b00b5b761ab3128c617acb8398c64b829df1e2d6984661bc6e8bfb2081b9fa408fd5e8774e1b540884a59caef4eef146c3a05f0d176cb62019471b4e28b88
|
data/lib/milk_tea/base.rb
CHANGED
|
@@ -331,11 +331,10 @@ module MilkTea
|
|
|
331
331
|
end
|
|
332
332
|
|
|
333
333
|
def emit_cast_operand(expression)
|
|
334
|
-
|
|
335
|
-
when IR::Name, IR::IntegerLiteral, IR::FloatLiteral, IR::StringLiteral, IR::BooleanLiteral, IR::NullLiteral, IR::ZeroInit, IR::Member, IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex, IR::Call, IR::AggregateLiteral, IR::ArrayLiteral, IR::ReinterpretExpr, IR::SizeofExpr, IR::AlignofExpr, IR::OffsetofExpr, IR::AddressOf, IR::Cast, IR::Unary
|
|
336
|
-
emit_expression(expression)
|
|
337
|
-
else
|
|
334
|
+
if expression.is_a?(IR::Binary) || expression.is_a?(IR::Conditional)
|
|
338
335
|
"(#{emit_expression(expression)})"
|
|
336
|
+
else
|
|
337
|
+
emit_expression(expression)
|
|
339
338
|
end
|
|
340
339
|
end
|
|
341
340
|
|
|
@@ -425,28 +424,16 @@ module MilkTea
|
|
|
425
424
|
|
|
426
425
|
def emit_variant_field_initializer(type, arm_name, field)
|
|
427
426
|
field_type = type.arm(arm_name).fetch(field.name)
|
|
427
|
+
outer_c = named_type_c_name(type)
|
|
428
|
+
|
|
428
429
|
if field_type.is_a?(Types::Nullable) && !field.value.type.is_a?(Types::Nullable) && !c_backend_pointer_like_type?(field_type.base)
|
|
429
430
|
emit_nullable_some_initializer(field_type, field.value)
|
|
430
431
|
elsif field.value.is_a?(IR::AddressOf) && !field_type.is_a?(Types::Nullable)
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
elsif aggregate_field_creates_cycle?(field_type,
|
|
435
|
-
|
|
436
|
-
elem_c_name = c_type(array_element_type(field_type))
|
|
437
|
-
elem_count = array_length(field_type)
|
|
438
|
-
elements = field.value.is_a?(IR::ArrayLiteral) ? field.value.elements.map { |e| emit_initializer(e) }.join(", ") : ""
|
|
439
|
-
"((#{elem_c_name}*)memcpy(malloc(#{elem_count} * sizeof(#{elem_c_name})), &(#{elem_c_name}[#{elem_count}]){ #{elements} }, #{elem_count} * sizeof(#{elem_c_name})))"
|
|
440
|
-
elsif aggregate_field_creates_cycle?(field_type, named_type_c_name(type)) &&
|
|
441
|
-
!field_type.is_a?(Types::GenericInstance)
|
|
442
|
-
field_c_name = named_type_c_name(field_type)
|
|
443
|
-
init = emit_initializer(field.value)
|
|
444
|
-
source_expr = if init.start_with?("{")
|
|
445
|
-
"&(#{c_type(field_type)})#{init}"
|
|
446
|
-
else
|
|
447
|
-
"&(#{init})"
|
|
448
|
-
end
|
|
449
|
-
"((#{field_c_name}*)memcpy(malloc(sizeof(#{field_c_name})), #{source_expr}, sizeof(#{field_c_name})))"
|
|
432
|
+
emit_addressof_field_initializer(field_type, field.value)
|
|
433
|
+
elsif aggregate_field_creates_cycle?(field_type, outer_c) && array_type?(field_type)
|
|
434
|
+
emit_cyclic_array_initializer(field_type, field.value)
|
|
435
|
+
elsif aggregate_field_creates_cycle?(field_type, outer_c) && !field_type.is_a?(Types::GenericInstance)
|
|
436
|
+
emit_cyclic_struct_initializer(field_type, field.value)
|
|
450
437
|
elsif void_storage_field?(field_type)
|
|
451
438
|
emit_void_field_initializer(field.value)
|
|
452
439
|
else
|
|
@@ -454,6 +441,30 @@ module MilkTea
|
|
|
454
441
|
end
|
|
455
442
|
end
|
|
456
443
|
|
|
444
|
+
def emit_addressof_field_initializer(field_type, value)
|
|
445
|
+
c_type_name = named_type_c_name(field_type)
|
|
446
|
+
inner = value.expression
|
|
447
|
+
"((#{c_type_name}*)memcpy(malloc(sizeof(#{c_type_name})), &(#{emit_expression(inner)}), sizeof(#{c_type_name})))"
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
def emit_cyclic_array_initializer(field_type, value)
|
|
451
|
+
elem_c_name = c_type(array_element_type(field_type))
|
|
452
|
+
elem_count = array_length(field_type)
|
|
453
|
+
elements = value.is_a?(IR::ArrayLiteral) ? value.elements.map { |e| emit_initializer(e) }.join(", ") : ""
|
|
454
|
+
"((#{elem_c_name}*)memcpy(malloc(#{elem_count} * sizeof(#{elem_c_name})), &(#{elem_c_name}[#{elem_count}]){ #{elements} }, #{elem_count} * sizeof(#{elem_c_name})))"
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
def emit_cyclic_struct_initializer(field_type, value)
|
|
458
|
+
field_c_name = named_type_c_name(field_type)
|
|
459
|
+
init = emit_initializer(value)
|
|
460
|
+
source_expr = if init.start_with?("{")
|
|
461
|
+
"&(#{c_type(field_type)})#{init}"
|
|
462
|
+
else
|
|
463
|
+
"&(#{init})"
|
|
464
|
+
end
|
|
465
|
+
"((#{field_c_name}*)memcpy(malloc(sizeof(#{field_c_name})), #{source_expr}, sizeof(#{field_c_name})))"
|
|
466
|
+
end
|
|
467
|
+
|
|
457
468
|
def emit_void_field_initializer(expression)
|
|
458
469
|
"(#{emit_expression(expression)}, 0)"
|
|
459
470
|
end
|
|
@@ -342,66 +342,46 @@ module MilkTea
|
|
|
342
342
|
function.body.any? { |statement| statement_uses_str_equality?(statement) }
|
|
343
343
|
end
|
|
344
344
|
|
|
345
|
-
def
|
|
345
|
+
def any_ir_statement?(statement, expression_pred:, **kwargs)
|
|
346
346
|
case statement
|
|
347
347
|
when IR::LocalDecl
|
|
348
|
-
|
|
348
|
+
statement.value && expression_pred.call(statement.value, **kwargs)
|
|
349
349
|
when IR::Assignment
|
|
350
|
-
|
|
350
|
+
expression_pred.call(statement.target, **kwargs) || expression_pred.call(statement.value, **kwargs)
|
|
351
351
|
when IR::BlockStmt
|
|
352
|
-
statement.body.any? { |inner|
|
|
352
|
+
statement.body.any? { |inner| any_ir_statement?(inner, expression_pred:, **kwargs) }
|
|
353
353
|
when IR::WhileStmt
|
|
354
|
-
|
|
354
|
+
expression_pred.call(statement.condition, **kwargs) ||
|
|
355
|
+
statement.body.any? { |inner| any_ir_statement?(inner, expression_pred:, **kwargs) }
|
|
355
356
|
when IR::ForStmt
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
statement.body.any? { |inner|
|
|
359
|
-
|
|
357
|
+
any_ir_statement?(statement.init, expression_pred:, **kwargs) ||
|
|
358
|
+
expression_pred.call(statement.condition, **kwargs) ||
|
|
359
|
+
statement.body.any? { |inner| any_ir_statement?(inner, expression_pred:, **kwargs) } ||
|
|
360
|
+
any_ir_statement?(statement.post, expression_pred:, **kwargs)
|
|
360
361
|
when IR::IfStmt
|
|
361
|
-
|
|
362
|
-
statement.then_body.any? { |inner|
|
|
363
|
-
(statement.else_body && statement.else_body.any? { |inner|
|
|
362
|
+
expression_pred.call(statement.condition, **kwargs) ||
|
|
363
|
+
statement.then_body.any? { |inner| any_ir_statement?(inner, expression_pred:, **kwargs) } ||
|
|
364
|
+
(statement.else_body && statement.else_body.any? { |inner| any_ir_statement?(inner, expression_pred:, **kwargs) })
|
|
364
365
|
when IR::SwitchStmt
|
|
365
|
-
|
|
366
|
+
expression_pred.call(statement.expression, **kwargs) ||
|
|
367
|
+
statement.cases.any? { |switch_case| switch_case.body.any? { |inner| any_ir_statement?(inner, expression_pred:, **kwargs) } }
|
|
366
368
|
when IR::StaticAssert
|
|
367
|
-
|
|
369
|
+
expression_pred.call(statement.condition, **kwargs) || expression_pred.call(statement.message, **kwargs)
|
|
368
370
|
when IR::ReturnStmt
|
|
369
|
-
statement.value &&
|
|
371
|
+
statement.value && expression_pred.call(statement.value, **kwargs)
|
|
370
372
|
when IR::ExpressionStmt
|
|
371
|
-
|
|
373
|
+
expression_pred.call(statement.expression, **kwargs)
|
|
374
|
+
else
|
|
375
|
+
false
|
|
372
376
|
end
|
|
373
377
|
end
|
|
374
378
|
|
|
379
|
+
def statement_uses_named_call?(statement, callees)
|
|
380
|
+
any_ir_statement?(statement, expression_pred: ->(e) { expression_uses_named_call?(e, callees) })
|
|
381
|
+
end
|
|
382
|
+
|
|
375
383
|
def statement_uses_str_equality?(statement)
|
|
376
|
-
|
|
377
|
-
when IR::LocalDecl
|
|
378
|
-
expression_uses_str_equality?(statement.value)
|
|
379
|
-
when IR::Assignment
|
|
380
|
-
expression_uses_str_equality?(statement.target) || expression_uses_str_equality?(statement.value)
|
|
381
|
-
when IR::BlockStmt
|
|
382
|
-
statement.body.any? { |inner| statement_uses_str_equality?(inner) }
|
|
383
|
-
when IR::WhileStmt
|
|
384
|
-
expression_uses_str_equality?(statement.condition) || statement.body.any? { |inner| statement_uses_str_equality?(inner) }
|
|
385
|
-
when IR::ForStmt
|
|
386
|
-
statement_uses_str_equality?(statement.init) ||
|
|
387
|
-
expression_uses_str_equality?(statement.condition) ||
|
|
388
|
-
statement.body.any? { |inner| statement_uses_str_equality?(inner) } ||
|
|
389
|
-
statement_uses_str_equality?(statement.post)
|
|
390
|
-
when IR::IfStmt
|
|
391
|
-
expression_uses_str_equality?(statement.condition) ||
|
|
392
|
-
statement.then_body.any? { |inner| statement_uses_str_equality?(inner) } ||
|
|
393
|
-
(statement.else_body && statement.else_body.any? { |inner| statement_uses_str_equality?(inner) })
|
|
394
|
-
when IR::SwitchStmt
|
|
395
|
-
expression_uses_str_equality?(statement.expression) || statement.cases.any? { |switch_case| switch_case.body.any? { |inner| statement_uses_str_equality?(inner) } }
|
|
396
|
-
when IR::StaticAssert
|
|
397
|
-
expression_uses_str_equality?(statement.condition) || expression_uses_str_equality?(statement.message)
|
|
398
|
-
when IR::ReturnStmt
|
|
399
|
-
statement.value && expression_uses_str_equality?(statement.value)
|
|
400
|
-
when IR::ExpressionStmt
|
|
401
|
-
expression_uses_str_equality?(statement.expression)
|
|
402
|
-
else
|
|
403
|
-
false
|
|
404
|
-
end
|
|
384
|
+
any_ir_statement?(statement, expression_pred: ->(e) { expression_uses_str_equality?(e) })
|
|
405
385
|
end
|
|
406
386
|
|
|
407
387
|
def expression_uses_named_call?(expression, callees)
|
|
@@ -241,21 +241,15 @@ module MilkTea
|
|
|
241
241
|
end
|
|
242
242
|
|
|
243
243
|
def collect_soa_from_statements(statements, soa_types, visited)
|
|
244
|
-
statements
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
when IR::WhileStmt
|
|
254
|
-
collect_soa_from_statements(stmt.body || [], soa_types, visited)
|
|
255
|
-
when IR::ForStmt
|
|
256
|
-
collect_soa_from_statements(stmt.body || [], soa_types, visited)
|
|
257
|
-
end
|
|
258
|
-
end
|
|
244
|
+
each_ir_statement_for_type_collection(statements,
|
|
245
|
+
type_collector_method: :collect_soa_type,
|
|
246
|
+
expression_walker_method: :collect_soa_type_in_expression,
|
|
247
|
+
accumulator: soa_types, visited:)
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def collect_soa_type_in_expression(expression, soa_types, visited)
|
|
251
|
+
return unless expression.respond_to?(:type)
|
|
252
|
+
collect_soa_type(expression.type, soa_types, visited)
|
|
259
253
|
end
|
|
260
254
|
|
|
261
255
|
def collect_soa_type(type, soa_types, visited)
|
|
@@ -290,21 +284,15 @@ module MilkTea
|
|
|
290
284
|
end
|
|
291
285
|
|
|
292
286
|
def collect_simd_from_statements(statements, simd_types, visited)
|
|
293
|
-
statements
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
when IR::WhileStmt
|
|
303
|
-
collect_simd_from_statements(stmt.body || [], simd_types, visited)
|
|
304
|
-
when IR::ForStmt
|
|
305
|
-
collect_simd_from_statements(stmt.body || [], simd_types, visited)
|
|
306
|
-
end
|
|
307
|
-
end
|
|
287
|
+
each_ir_statement_for_type_collection(statements,
|
|
288
|
+
type_collector_method: :collect_simd_type,
|
|
289
|
+
expression_walker_method: :collect_simd_type_in_expression,
|
|
290
|
+
accumulator: simd_types, visited:)
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
def collect_simd_type_in_expression(expression, simd_types, visited)
|
|
294
|
+
return unless expression.respond_to?(:type)
|
|
295
|
+
collect_simd_type(expression.type, simd_types, visited)
|
|
308
296
|
end
|
|
309
297
|
|
|
310
298
|
def collect_simd_type(type, simd_types, visited)
|
|
@@ -61,12 +61,6 @@ module MilkTea
|
|
|
61
61
|
lines
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
def variant_self_reference?(type, outer_c)
|
|
65
|
-
return false unless type.is_a?(Types::Variant) || type.is_a?(Types::VariantInstance)
|
|
66
|
-
|
|
67
|
-
named_type_c_name(type) == outer_c
|
|
68
|
-
end
|
|
69
|
-
|
|
70
64
|
def emit_variant(variant_decl)
|
|
71
65
|
lines = []
|
|
72
66
|
outer_c = variant_decl.linkage_name
|
|
@@ -75,11 +75,27 @@ module MilkTea
|
|
|
75
75
|
|
|
76
76
|
def emit
|
|
77
77
|
lines = []
|
|
78
|
+
@cyclic_aggregate_pairs = build_cyclic_aggregate_pairs(
|
|
79
|
+
emitted_aggregate_structs + collect_generic_struct_decls + collect_task_decls + collect_proc_decls + collect_dyn_decls + collect_str_buffer_decls + collect_nullable_opt_decls +
|
|
80
|
+
emitted_aggregate_unions +
|
|
81
|
+
emitted_aggregate_variants + collect_generic_variant_decls
|
|
82
|
+
)
|
|
83
|
+
|
|
78
84
|
constants = emitted_constants
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
|
|
86
|
+
emit_preamble(lines)
|
|
87
|
+
emit_conditional_helpers(lines)
|
|
88
|
+
emit_type_declarations(lines)
|
|
89
|
+
emit_function_forward_declarations(lines)
|
|
90
|
+
emit_globals_and_constants(lines, constants)
|
|
91
|
+
emit_per_type_helpers(lines)
|
|
92
|
+
emit_string_literal_constants_section(lines)
|
|
93
|
+
emit_function_definitions(lines)
|
|
94
|
+
|
|
95
|
+
lines.join("\n").rstrip + "\n"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def emit_preamble(lines)
|
|
83
99
|
headers = @program.includes.map(&:header)
|
|
84
100
|
if headers.include?("\"fs_support.h\"") || headers.include?("\"tls_support.h\"") || uses_parallel_for_helper? || uses_spawn_all_helper? || uses_detach_helper?
|
|
85
101
|
lines << "#ifndef _GNU_SOURCE"
|
|
@@ -103,70 +119,61 @@ module MilkTea
|
|
|
103
119
|
lines << "#include #{header}"
|
|
104
120
|
end
|
|
105
121
|
lines << ""
|
|
122
|
+
end
|
|
106
123
|
|
|
124
|
+
def emit_conditional_helpers(lines)
|
|
107
125
|
if uses_string_view?
|
|
108
126
|
lines.concat(emit_string_type)
|
|
109
127
|
lines << ""
|
|
110
128
|
end
|
|
111
|
-
|
|
112
129
|
if uses_vector_math_types?
|
|
113
130
|
lines.concat(emit_vector_math_types)
|
|
114
131
|
lines << ""
|
|
115
132
|
end
|
|
116
|
-
|
|
117
133
|
if uses_fatal_helper?
|
|
118
134
|
lines.concat(emit_fatal_helper)
|
|
119
135
|
lines << ""
|
|
120
136
|
end
|
|
121
|
-
|
|
122
137
|
if uses_format_helpers?
|
|
123
138
|
lines.concat(emit_format_helpers)
|
|
124
139
|
lines << ""
|
|
125
140
|
end
|
|
126
|
-
|
|
127
141
|
if uses_fmt_builder?
|
|
128
142
|
lines.concat(emit_fmt_builder_helpers)
|
|
129
143
|
lines << ""
|
|
130
144
|
end
|
|
131
|
-
|
|
132
145
|
if uses_str_equality_helper?
|
|
133
146
|
lines.concat(emit_str_equality_helper)
|
|
134
147
|
lines << ""
|
|
135
148
|
end
|
|
136
|
-
|
|
137
149
|
if uses_text_buffer_helpers?
|
|
138
150
|
lines.concat(emit_text_buffer_helpers)
|
|
139
151
|
lines << ""
|
|
140
152
|
end
|
|
141
|
-
|
|
142
153
|
if uses_async_memory_helpers?
|
|
143
154
|
lines.concat(emit_async_memory_helpers)
|
|
144
155
|
lines << ""
|
|
145
156
|
end
|
|
146
|
-
|
|
147
157
|
if uses_parallel_for_helper?
|
|
148
158
|
lines.concat(emit_parallel_for_helper)
|
|
149
159
|
lines << ""
|
|
150
160
|
end
|
|
151
|
-
|
|
152
161
|
if uses_spawn_all_helper?
|
|
153
162
|
lines.concat(emit_spawn_all_helper)
|
|
154
163
|
lines << ""
|
|
155
164
|
end
|
|
156
|
-
|
|
157
165
|
if uses_detach_helper?
|
|
158
166
|
lines.concat(emit_detach_helpers)
|
|
159
167
|
lines << ""
|
|
160
168
|
end
|
|
169
|
+
end
|
|
161
170
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
all_variant_decls,
|
|
167
|
-
)
|
|
171
|
+
def emit_type_declarations(lines)
|
|
172
|
+
all_struct_decls = emitted_aggregate_structs + collect_generic_struct_decls + collect_task_decls + collect_proc_decls + collect_dyn_decls + collect_str_buffer_decls + collect_nullable_opt_decls
|
|
173
|
+
all_variant_decls = emitted_aggregate_variants + collect_generic_variant_decls
|
|
174
|
+
aggregate_decls = sort_aggregate_decls(all_struct_decls, emitted_aggregate_unions, all_variant_decls)
|
|
168
175
|
|
|
169
|
-
forward_declarations = emit_forward_declarations(
|
|
176
|
+
forward_declarations = emit_forward_declarations(@program.opaques, aggregate_decls)
|
|
170
177
|
unless forward_declarations.empty?
|
|
171
178
|
lines.concat(forward_declarations)
|
|
172
179
|
lines << ""
|
|
@@ -236,13 +243,17 @@ module MilkTea
|
|
|
236
243
|
lines.concat(emit_variant_equality_helpers)
|
|
237
244
|
lines << ""
|
|
238
245
|
end
|
|
246
|
+
end
|
|
239
247
|
|
|
248
|
+
def emit_function_forward_declarations(lines)
|
|
240
249
|
function_declarations = emit_function_declarations(emitted_functions)
|
|
241
250
|
unless function_declarations.empty?
|
|
242
251
|
lines.concat(function_declarations)
|
|
243
252
|
lines << ""
|
|
244
253
|
end
|
|
254
|
+
end
|
|
245
255
|
|
|
256
|
+
def emit_globals_and_constants(lines, constants)
|
|
246
257
|
constants.each do |constant|
|
|
247
258
|
@current_line = constant.line if constant.line
|
|
248
259
|
@source_path ||= constant.path if constant.path
|
|
@@ -262,51 +273,50 @@ module MilkTea
|
|
|
262
273
|
lines << emit_static_assert(statement)
|
|
263
274
|
end
|
|
264
275
|
lines << "" unless @program.static_asserts.empty?
|
|
276
|
+
end
|
|
265
277
|
|
|
266
|
-
|
|
267
|
-
|
|
278
|
+
def emit_per_type_helpers(lines)
|
|
279
|
+
collect_reinterpret_helpers.each do |helper|
|
|
268
280
|
lines.concat(emit_reinterpret_helper(helper))
|
|
269
281
|
lines << ""
|
|
270
282
|
end
|
|
271
283
|
|
|
272
|
-
|
|
273
|
-
checked_array_index_types.each do |type|
|
|
284
|
+
collect_checked_array_index_types.each do |type|
|
|
274
285
|
lines.concat(emit_checked_array_index_helper(type))
|
|
275
286
|
lines << ""
|
|
276
287
|
end
|
|
277
288
|
|
|
278
|
-
|
|
279
|
-
checked_span_index_types.each do |type|
|
|
289
|
+
collect_checked_span_index_types.each do |type|
|
|
280
290
|
lines.concat(emit_checked_span_index_helper(type))
|
|
281
291
|
lines << ""
|
|
282
292
|
end
|
|
283
293
|
|
|
284
|
-
|
|
285
|
-
nullable_array_index_types.each do |type|
|
|
294
|
+
collect_checked_array_index_types(nullable_only: true).each do |type|
|
|
286
295
|
lines.concat(emit_nullable_array_index_helper(type))
|
|
287
296
|
lines << ""
|
|
288
297
|
end
|
|
289
298
|
|
|
290
|
-
|
|
291
|
-
nullable_span_index_types.each do |type|
|
|
299
|
+
collect_checked_span_index_types(nullable_only: true).each do |type|
|
|
292
300
|
lines.concat(emit_nullable_span_index_helper(type))
|
|
293
301
|
lines << ""
|
|
294
302
|
end
|
|
303
|
+
end
|
|
295
304
|
|
|
305
|
+
def emit_string_literal_constants_section(lines)
|
|
296
306
|
str_literals = collect_str_literals
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
307
|
+
return if str_literals.empty?
|
|
308
|
+
|
|
309
|
+
@str_literal_map = {}
|
|
310
|
+
str_literals.each_with_index { |value, i| @str_literal_map[value] = str_literal_name(i) }
|
|
311
|
+
lines.concat(emit_str_literal_constants(str_literals))
|
|
312
|
+
lines << ""
|
|
313
|
+
end
|
|
303
314
|
|
|
315
|
+
def emit_function_definitions(lines)
|
|
304
316
|
emitted_functions.each do |function|
|
|
305
317
|
lines.concat(emit_function(function))
|
|
306
318
|
lines << ""
|
|
307
319
|
end
|
|
308
|
-
|
|
309
|
-
lines.join("\n").rstrip + "\n"
|
|
310
320
|
end
|
|
311
321
|
end
|
|
312
322
|
end
|
|
@@ -252,75 +252,7 @@ module MilkTea
|
|
|
252
252
|
resolve_member_access: ->(ma_expr) {
|
|
253
253
|
@checker.evaluate_compile_time_const_value(ma_expr, scopes:)
|
|
254
254
|
},
|
|
255
|
-
resolve_call: ->(call_expr) {
|
|
256
|
-
if call_expr.callee.is_a?(AST::Identifier)
|
|
257
|
-
func = @checker.top_level_function(call_expr.callee.name)
|
|
258
|
-
if func&.ast&.respond_to?(:const) && func.ast.const
|
|
259
|
-
begin
|
|
260
|
-
initial_vars = {}
|
|
261
|
-
func.ast.params.each_with_index do |param, idx|
|
|
262
|
-
return nil if idx >= call_expr.arguments.length
|
|
263
|
-
|
|
264
|
-
arg_expr = call_expr.arguments[idx].value
|
|
265
|
-
arg_value = case arg_expr
|
|
266
|
-
when AST::Identifier
|
|
267
|
-
@variables[arg_expr.name] || @checker.evaluate_compile_time_const_value(arg_expr, scopes:)
|
|
268
|
-
else
|
|
269
|
-
CompileTime.evaluate(
|
|
270
|
-
arg_expr,
|
|
271
|
-
resolve_identifier: ->(id) { @variables[id.name] || @checker.evaluate_compile_time_const_value(id, scopes:) },
|
|
272
|
-
resolve_member_access: ->(ma) { @checker.evaluate_compile_time_const_value(ma, scopes:) },
|
|
273
|
-
resolve_type_ref: nil,
|
|
274
|
-
resolve_call: nil,
|
|
275
|
-
)
|
|
276
|
-
end
|
|
277
|
-
return nil unless arg_value
|
|
278
|
-
|
|
279
|
-
initial_vars[param.name] = arg_value
|
|
280
|
-
end
|
|
281
|
-
ctx = CompileTime::BlockContext.new(@checker, initial_variables: initial_vars)
|
|
282
|
-
next ctx.evaluate_block(func.ast.body, scopes:)
|
|
283
|
-
rescue CompileTime::ReturnValue => e
|
|
284
|
-
next e.value
|
|
285
|
-
end
|
|
286
|
-
end
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
types = if @checker.respond_to?(:types)
|
|
290
|
-
@checker.types
|
|
291
|
-
else
|
|
292
|
-
@checker.instance_variable_get(:@ctx).types
|
|
293
|
-
end
|
|
294
|
-
callee_name = if call_expr.callee.is_a?(AST::Specialization) && call_expr.callee.callee.respond_to?(:name)
|
|
295
|
-
call_expr.callee.callee.name
|
|
296
|
-
elsif call_expr.callee.respond_to?(:name)
|
|
297
|
-
call_expr.callee.name
|
|
298
|
-
end
|
|
299
|
-
if callee_name && (type = types[callee_name]) && type.is_a?(Types::Struct)
|
|
300
|
-
fields = {}
|
|
301
|
-
call_expr.arguments.each do |argument|
|
|
302
|
-
val = evaluate_expression(argument.value, scopes:)
|
|
303
|
-
return nil unless val
|
|
304
|
-
fields[argument.name] = val
|
|
305
|
-
end
|
|
306
|
-
next fields
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
if call_expr.callee.is_a?(AST::Specialization) && @checker.respond_to?(:resolve_type_expression)
|
|
310
|
-
resolved = @checker.resolve_type_expression(call_expr.callee)
|
|
311
|
-
if resolved && @checker.respond_to?(:array_type?) && @checker.array_type?(resolved)
|
|
312
|
-
values = []
|
|
313
|
-
call_expr.arguments.each do |argument|
|
|
314
|
-
val = evaluate_expression(argument.value, scopes:)
|
|
315
|
-
return nil unless val
|
|
316
|
-
values << val
|
|
317
|
-
end
|
|
318
|
-
next values
|
|
319
|
-
end
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
@checker.evaluate_compile_time_const_value(call_expr, scopes:)
|
|
323
|
-
},
|
|
255
|
+
resolve_call: ->(call_expr) { resolve_compile_time_call(call_expr, scopes:) },
|
|
324
256
|
)
|
|
325
257
|
end
|
|
326
258
|
end
|
|
@@ -435,13 +367,108 @@ module MilkTea
|
|
|
435
367
|
|
|
436
368
|
nil
|
|
437
369
|
end
|
|
370
|
+
|
|
371
|
+
def resolve_compile_time_call(call_expr, scopes:)
|
|
372
|
+
result = try_const_function_call(call_expr, scopes:)
|
|
373
|
+
return result if result
|
|
374
|
+
|
|
375
|
+
result = try_struct_constructor_call(call_expr, scopes:)
|
|
376
|
+
return result if result
|
|
377
|
+
|
|
378
|
+
result = try_array_constructor_call(call_expr, scopes:)
|
|
379
|
+
return result if result
|
|
380
|
+
|
|
381
|
+
@checker.evaluate_compile_time_const_value(call_expr, scopes:)
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def try_const_function_call(call_expr, scopes:)
|
|
385
|
+
return unless call_expr.callee.is_a?(AST::Identifier)
|
|
386
|
+
|
|
387
|
+
func = @checker.top_level_function(call_expr.callee.name)
|
|
388
|
+
return unless func&.ast&.respond_to?(:const) && func.ast.const
|
|
389
|
+
|
|
390
|
+
begin
|
|
391
|
+
initial_vars = {}
|
|
392
|
+
func.ast.params.each_with_index do |param, idx|
|
|
393
|
+
return nil if idx >= call_expr.arguments.length
|
|
394
|
+
|
|
395
|
+
arg_expr = call_expr.arguments[idx].value
|
|
396
|
+
arg_value = case arg_expr
|
|
397
|
+
when AST::Identifier
|
|
398
|
+
@variables[arg_expr.name] || @checker.evaluate_compile_time_const_value(arg_expr, scopes:)
|
|
399
|
+
else
|
|
400
|
+
CompileTime.evaluate(
|
|
401
|
+
arg_expr,
|
|
402
|
+
resolve_identifier: ->(id) { @variables[id.name] || @checker.evaluate_compile_time_const_value(id, scopes:) },
|
|
403
|
+
resolve_member_access: ->(ma) { @checker.evaluate_compile_time_const_value(ma, scopes:) },
|
|
404
|
+
resolve_type_ref: nil,
|
|
405
|
+
resolve_call: nil,
|
|
406
|
+
)
|
|
407
|
+
end
|
|
408
|
+
return nil unless arg_value
|
|
409
|
+
|
|
410
|
+
initial_vars[param.name] = arg_value
|
|
411
|
+
end
|
|
412
|
+
ctx = BlockContext.new(@checker, initial_variables: initial_vars)
|
|
413
|
+
ctx.evaluate_block(func.ast.body, scopes:)
|
|
414
|
+
rescue ReturnValue => e
|
|
415
|
+
e.value
|
|
416
|
+
end
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
def try_struct_constructor_call(call_expr, scopes:)
|
|
420
|
+
types = if @checker.respond_to?(:types)
|
|
421
|
+
@checker.types
|
|
422
|
+
else
|
|
423
|
+
@checker.instance_variable_get(:@ctx).types
|
|
424
|
+
end
|
|
425
|
+
callee_name = if call_expr.callee.is_a?(AST::Specialization) && call_expr.callee.callee.respond_to?(:name)
|
|
426
|
+
call_expr.callee.callee.name
|
|
427
|
+
elsif call_expr.callee.respond_to?(:name)
|
|
428
|
+
call_expr.callee.name
|
|
429
|
+
end
|
|
430
|
+
return unless callee_name
|
|
431
|
+
|
|
432
|
+
type = types[callee_name]
|
|
433
|
+
return unless type.is_a?(Types::Struct)
|
|
434
|
+
|
|
435
|
+
fields = {}
|
|
436
|
+
call_expr.arguments.each do |argument|
|
|
437
|
+
val = evaluate_expression(argument.value, scopes:)
|
|
438
|
+
return nil unless val
|
|
439
|
+
fields[argument.name] = val
|
|
440
|
+
end
|
|
441
|
+
fields
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
def try_array_constructor_call(call_expr, scopes:)
|
|
445
|
+
return unless call_expr.callee.is_a?(AST::Specialization)
|
|
446
|
+
return unless @checker.respond_to?(:resolve_type_expression)
|
|
447
|
+
|
|
448
|
+
resolved = @checker.resolve_type_expression(call_expr.callee)
|
|
449
|
+
return unless resolved && @checker.respond_to?(:array_type?) && @checker.array_type?(resolved)
|
|
450
|
+
|
|
451
|
+
values = []
|
|
452
|
+
call_expr.arguments.each do |argument|
|
|
453
|
+
val = evaluate_expression(argument.value, scopes:)
|
|
454
|
+
return nil unless val
|
|
455
|
+
values << val
|
|
456
|
+
end
|
|
457
|
+
values
|
|
458
|
+
end
|
|
438
459
|
end
|
|
439
460
|
|
|
440
461
|
class Evaluator < ConstEval::Evaluator
|
|
441
462
|
|
|
442
463
|
def resolve_layout_type(type_ref)
|
|
443
|
-
|
|
444
|
-
|
|
464
|
+
result = begin
|
|
465
|
+
super
|
|
466
|
+
rescue SemanticError
|
|
467
|
+
nil
|
|
468
|
+
end
|
|
469
|
+
return result if result
|
|
470
|
+
return result if result
|
|
471
|
+
|
|
445
472
|
return unless type_ref.respond_to?(:name) && type_ref.name.parts.length >= 1
|
|
446
473
|
|
|
447
474
|
expression = ::MilkTea::AST.build_chain_from_parts(type_ref.name.parts)
|
|
@@ -455,7 +482,6 @@ module MilkTea
|
|
|
455
482
|
nil
|
|
456
483
|
end
|
|
457
484
|
|
|
458
|
-
|
|
459
485
|
end
|
|
460
486
|
|
|
461
487
|
def self.evaluate(expression, resolve_identifier:, resolve_member_access:, resolve_type_ref: nil, resolve_call: nil)
|