mt-lang 0.3.8 → 0.3.10
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 -2
- data/lib/milk_tea/bindings/bindgen/ast_parser.rb +0 -2
- data/lib/milk_tea/bindings/bindgen/declaration.rb +0 -2
- data/lib/milk_tea/bindings/bindgen/emitter.rb +0 -2
- data/lib/milk_tea/bindings/bindgen/overrides.rb +0 -2
- data/lib/milk_tea/bindings/bindgen/type_mapper.rb +51 -53
- data/lib/milk_tea/bindings/imported_bindings/generator.rb +7 -9
- data/lib/milk_tea/bindings/imported_bindings/method_source.rb +0 -2
- data/lib/milk_tea/bindings/imported_bindings/naming.rb +6 -8
- data/lib/milk_tea/bindings/imported_bindings.rb +0 -2
- data/lib/milk_tea/bindings/opengl_registry.rb +3 -7
- data/lib/milk_tea/bindings/steamworks.rb +12 -16
- data/lib/milk_tea/bindings/upstream_sources.rb +10 -14
- data/lib/milk_tea/bindings/vendored_box2d.rb +10 -12
- data/lib/milk_tea/bindings/vendored_cjson.rb +6 -8
- data/lib/milk_tea/bindings/vendored_flecs.rb +10 -12
- data/lib/milk_tea/bindings/vendored_glfw.rb +11 -13
- data/lib/milk_tea/bindings/vendored_libuv.rb +11 -13
- data/lib/milk_tea/bindings/vendored_pcre2.rb +11 -13
- data/lib/milk_tea/bindings/vendored_raylib.rb +6 -10
- data/lib/milk_tea/bindings/vendored_sdl3.rb +11 -13
- data/lib/milk_tea/bindings/vendored_steamworks.rb +1 -5
- data/lib/milk_tea/core/ast.rb +103 -45
- data/lib/milk_tea/core/async_runtime_installer.rb +0 -2
- data/lib/milk_tea/core/bindings/attribute_binding.rb +1 -3
- data/lib/milk_tea/core/c_backend/aggregate_utils.rb +147 -84
- data/lib/milk_tea/core/c_backend/control_flow_emission.rb +394 -396
- data/lib/milk_tea/core/c_backend/expressions.rb +489 -476
- data/lib/milk_tea/core/c_backend/feature_detection.rb +446 -437
- data/lib/milk_tea/core/c_backend/format_helpers.rb +0 -2
- data/lib/milk_tea/core/c_backend/reachability.rb +339 -341
- data/lib/milk_tea/core/c_backend/reinterpret.rb +231 -217
- data/lib/milk_tea/core/c_backend/runtime_helpers.rb +531 -526
- data/lib/milk_tea/core/c_backend/statements.rb +528 -530
- data/lib/milk_tea/core/c_backend/type_collectors.rb +1344 -1346
- data/lib/milk_tea/core/c_backend/type_declaration.rb +215 -213
- data/lib/milk_tea/core/c_backend/type_system.rb +347 -349
- data/lib/milk_tea/core/c_backend.rb +17 -9
- data/lib/milk_tea/core/compatibility_helpers.rb +0 -2
- data/lib/milk_tea/core/compile_time/const_eval.rb +7 -12
- data/lib/milk_tea/core/compile_time.rb +32 -38
- data/lib/milk_tea/core/control_flow/builder.rb +3 -5
- data/lib/milk_tea/core/control_flow/constant_propagation.rb +14 -17
- data/lib/milk_tea/core/control_flow/definite_assignment.rb +0 -1
- data/lib/milk_tea/core/ir.rb +10 -10
- data/lib/milk_tea/core/lexer/character_classes.rb +5 -7
- data/lib/milk_tea/core/lexer/format_strings.rb +7 -9
- data/lib/milk_tea/core/lexer/heredocs.rb +22 -22
- data/lib/milk_tea/core/lexer/indentation.rb +0 -2
- data/lib/milk_tea/core/lexer/numbers.rb +0 -2
- data/lib/milk_tea/core/lexer/recovery.rb +0 -2
- data/lib/milk_tea/core/lexer/strings.rb +0 -2
- data/lib/milk_tea/core/lexer/symbols.rb +0 -2
- data/lib/milk_tea/core/lexer/trivia.rb +0 -2
- data/lib/milk_tea/core/lexer.rb +0 -2
- data/lib/milk_tea/core/lowering/async/analysis.rb +0 -2
- data/lib/milk_tea/core/lowering/async/lowering.rb +1264 -1265
- data/lib/milk_tea/core/lowering/async/normalization.rb +0 -2
- data/lib/milk_tea/core/lowering/async.rb +627 -630
- data/lib/milk_tea/core/lowering/block.rb +413 -416
- data/lib/milk_tea/core/lowering/calls.rb +1381 -1384
- data/lib/milk_tea/core/lowering/declarations.rb +180 -183
- data/lib/milk_tea/core/lowering/dyn.rb +48 -50
- data/lib/milk_tea/core/lowering/events.rb +983 -985
- data/lib/milk_tea/core/lowering/expressions.rb +1513 -1518
- data/lib/milk_tea/core/lowering/foreign_cstr.rb +181 -184
- data/lib/milk_tea/core/lowering/functions.rb +185 -188
- data/lib/milk_tea/core/lowering/loops.rb +1028 -1031
- data/lib/milk_tea/core/lowering/proc.rb +363 -366
- data/lib/milk_tea/core/lowering/resolve.rb +2133 -2135
- data/lib/milk_tea/core/lowering/scans.rb +179 -181
- data/lib/milk_tea/core/lowering/str_buffer.rb +102 -105
- data/lib/milk_tea/core/lowering/utils.rb +1040 -1044
- data/lib/milk_tea/core/lowering.rb +5 -7
- data/lib/milk_tea/core/module_binder.rb +0 -2
- data/lib/milk_tea/core/module_loader/errors.rb +4 -2
- data/lib/milk_tea/core/module_loader.rb +113 -20
- data/lib/milk_tea/core/module_path_resolver.rb +0 -2
- data/lib/milk_tea/core/module_roots.rb +6 -8
- data/lib/milk_tea/core/parser/attributes.rb +0 -2
- data/lib/milk_tea/core/parser/blocks.rb +0 -2
- data/lib/milk_tea/core/parser/declarations.rb +0 -2
- data/lib/milk_tea/core/parser/expressions.rb +31 -14
- data/lib/milk_tea/core/parser/recovery.rb +0 -2
- data/lib/milk_tea/core/parser/statements.rb +0 -2
- data/lib/milk_tea/core/parser/types.rb +8 -10
- data/lib/milk_tea/core/parser.rb +1 -3
- data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +31 -33
- data/lib/milk_tea/core/pretty_printer/base_formatter.rb +0 -2
- data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +0 -2
- data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +0 -2
- data/lib/milk_tea/core/semantic_analyzer/attributes.rb +14 -16
- data/lib/milk_tea/core/semantic_analyzer/calls.rb +0 -2
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +1 -14
- data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +18 -21
- data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +0 -3
- data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +12 -15
- data/lib/milk_tea/core/semantic_analyzer/generics.rb +57 -59
- data/lib/milk_tea/core/semantic_analyzer/interface_conformance.rb +0 -2
- data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +5 -9
- data/lib/milk_tea/core/semantic_analyzer/nullability.rb +0 -3
- data/lib/milk_tea/core/semantic_analyzer/statements.rb +35 -40
- data/lib/milk_tea/core/semantic_analyzer/top_level.rb +10 -12
- data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +0 -6
- data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +102 -105
- data/lib/milk_tea/core/semantic_analyzer.rb +17 -8
- data/lib/milk_tea/core/types/layout.rb +21 -22
- data/lib/milk_tea/core/types/predicates.rb +0 -2
- data/lib/milk_tea/core/types/registry.rb +16 -18
- data/lib/milk_tea/core/types/visitor.rb +0 -4
- data/lib/milk_tea/dap/backends/lldb_dap.rb +0 -2
- data/lib/milk_tea/dap/protocol.rb +1 -1
- data/lib/milk_tea/dap/server/breakpoints.rb +0 -2
- data/lib/milk_tea/dap/server/debug_map.rb +0 -2
- data/lib/milk_tea/dap/server/handlers.rb +0 -2
- data/lib/milk_tea/dap/server/launch.rb +0 -2
- data/lib/milk_tea/dap/server/lldb_backend.rb +8 -10
- data/lib/milk_tea/dap/server/pause_diagnostics.rb +14 -16
- data/lib/milk_tea/dap/server/utilities.rb +0 -2
- data/lib/milk_tea/dap/server/wire.rb +0 -2
- data/lib/milk_tea/dap/server.rb +0 -2
- data/lib/milk_tea/lsp/diagnostics.rb +16 -16
- data/lib/milk_tea/lsp/server/call_hierarchy.rb +11 -12
- data/lib/milk_tea/lsp/server/code_actions.rb +355 -357
- data/lib/milk_tea/lsp/server/code_lens.rb +23 -25
- data/lib/milk_tea/lsp/server/completion.rb +873 -875
- data/lib/milk_tea/lsp/server/configuration.rb +129 -131
- data/lib/milk_tea/lsp/server/debug_info.rb +0 -2
- data/lib/milk_tea/lsp/server/definition.rb +564 -565
- data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +191 -193
- data/lib/milk_tea/lsp/server/execute_command.rb +0 -2
- data/lib/milk_tea/lsp/server/folding_range.rb +0 -4
- data/lib/milk_tea/lsp/server/formatting.rb +478 -480
- data/lib/milk_tea/lsp/server/hover.rb +1282 -1284
- data/lib/milk_tea/lsp/server/inlay_hints.rb +179 -181
- data/lib/milk_tea/lsp/server/lifecycle.rb +192 -194
- data/lib/milk_tea/lsp/server/linked_editing_range.rb +0 -2
- data/lib/milk_tea/lsp/server/on_type_formatting.rb +0 -2
- data/lib/milk_tea/lsp/server/progress.rb +0 -2
- data/lib/milk_tea/lsp/server/references.rb +316 -318
- data/lib/milk_tea/lsp/server/rename.rb +445 -447
- data/lib/milk_tea/lsp/server/selection_range.rb +0 -4
- data/lib/milk_tea/lsp/server/semantic_tokens.rb +1318 -1320
- data/lib/milk_tea/lsp/server/signature_help.rb +146 -148
- data/lib/milk_tea/lsp/server/text_documents.rb +99 -101
- data/lib/milk_tea/lsp/server/type_hierarchy.rb +2 -4
- data/lib/milk_tea/lsp/server/utilities.rb +397 -399
- data/lib/milk_tea/lsp/server.rb +0 -3
- data/lib/milk_tea/lsp/workspace/analysis.rb +40 -42
- data/lib/milk_tea/lsp/workspace/dependency_graph.rb +4 -10
- data/lib/milk_tea/lsp/workspace/utilities.rb +19 -19
- data/lib/milk_tea/packages/atomic_write.rb +4 -5
- data/lib/milk_tea/packages/dependency_solver.rb +15 -15
- data/lib/milk_tea/packages/lock.rb +4 -4
- data/lib/milk_tea/packages/manager_cli.rb +1 -1
- data/lib/milk_tea/packages/manifest.rb +3 -3
- data/lib/milk_tea/packages/registry_store.rb +4 -6
- data/lib/milk_tea/packages/services.rb +16 -16
- data/lib/milk_tea/packages/source_cache.rb +4 -6
- data/lib/milk_tea/packages/source_resolver.rb +44 -44
- data/lib/milk_tea/packages/version.rb +8 -8
- data/lib/milk_tea/tooling/build.rb +3 -7
- data/lib/milk_tea/tooling/build_cache.rb +0 -2
- data/lib/milk_tea/tooling/debug_info_formatter.rb +31 -33
- data/lib/milk_tea/tooling/debug_map.rb +8 -10
- data/lib/milk_tea/tooling/docs_app.rb +0 -2
- data/lib/milk_tea/tooling/linter/doc_tags.rb +25 -27
- data/lib/milk_tea/tooling/linter/fix_engine.rb +87 -24
- data/lib/milk_tea/tooling/linter/flow_rules.rb +44 -46
- data/lib/milk_tea/tooling/linter/imports_platform.rb +14 -16
- data/lib/milk_tea/tooling/linter/release_rules.rb +3 -5
- data/lib/milk_tea/tooling/linter/reserved_names.rb +23 -25
- data/lib/milk_tea/tooling/linter/rules.rb +87 -89
- data/lib/milk_tea/tooling/linter/source_helpers.rb +40 -42
- data/lib/milk_tea/tooling/linter/trailing_comma.rb +17 -19
- data/lib/milk_tea/tooling/linter/visitors.rb +162 -50
- data/lib/milk_tea/tooling/linter.rb +0 -2
- data/lib/milk_tea/tooling/project_scaffold.rb +0 -2
- data/lib/milk_tea/tooling/run.rb +0 -2
- data/lib/milk_tea/tooling/toolchain_cli.rb +0 -2
- data/std/cli.mt +13 -32
- data/std/color.mt +28 -28
- data/std/encoding.mt +4 -4
- data/std/graph.mt +1 -2
- data/std/hash.mt +14 -14
- data/std/http/server.mt +3 -3
- data/std/input.mt +1 -1
- data/std/json.mt +1 -1
- data/std/linear_algebra.mt +6 -6
- data/std/net/mux.mt +1 -1
- data/std/noise.mt +23 -23
- data/std/parse.mt +2 -2
- data/std/process.mt +3 -4
- data/std/sparse_set.mt +1 -1
- data/std/steering.mt +5 -5
- data/std/str.mt +1 -1
- data/std/tween.mt +4 -4
- data/std/utility.mt +3 -3
- metadata +2 -2
|
@@ -55,13 +55,17 @@ module MilkTea
|
|
|
55
55
|
@checked_index_alias_id = 0
|
|
56
56
|
@loop_guard_id = 0
|
|
57
57
|
@emitted_span_type_names = Set.new
|
|
58
|
-
@source_path = program.
|
|
58
|
+
@source_path = program.path
|
|
59
59
|
@current_line = nil
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
def emit
|
|
63
63
|
lines = []
|
|
64
64
|
constants = emitted_constants
|
|
65
|
+
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
|
|
66
|
+
all_variant_decls = emitted_aggregate_variants + collect_generic_variant_decls
|
|
67
|
+
all_decls_for_cycle = all_struct_decls + emitted_aggregate_unions + all_variant_decls
|
|
68
|
+
@cyclic_aggregate_pairs = build_cyclic_aggregate_pairs(all_decls_for_cycle)
|
|
65
69
|
headers = @program.includes.map(&:header)
|
|
66
70
|
if headers.include?("\"fs_support.h\"") || headers.include?("\"tls_support.h\"") || uses_parallel_for_helper? || uses_spawn_all_helper? || uses_detach_helper?
|
|
67
71
|
lines << "#ifndef _GNU_SOURCE"
|
|
@@ -75,7 +79,7 @@ module MilkTea
|
|
|
75
79
|
if uses_fatal_helper? || uses_format_helpers?
|
|
76
80
|
headers << "<stdio.h>"
|
|
77
81
|
end
|
|
78
|
-
if uses_fatal_helper? || uses_format_helpers? || uses_async_memory_helpers? || uses_foreign_temp_cstr_helpers? || uses_detach_helper?
|
|
82
|
+
if uses_fatal_helper? || uses_format_helpers? || uses_async_memory_helpers? || uses_foreign_temp_cstr_helpers? || uses_detach_helper? || uses_cyclic_variant_heap_copy?
|
|
79
83
|
headers << "<stdlib.h>"
|
|
80
84
|
end
|
|
81
85
|
if uses_parallel_for_helper? || uses_spawn_all_helper? || uses_detach_helper?
|
|
@@ -143,9 +147,9 @@ module MilkTea
|
|
|
143
147
|
|
|
144
148
|
opaque_decls = @program.opaques
|
|
145
149
|
aggregate_decls = sort_aggregate_decls(
|
|
146
|
-
|
|
150
|
+
all_struct_decls,
|
|
147
151
|
emitted_aggregate_unions,
|
|
148
|
-
|
|
152
|
+
all_variant_decls,
|
|
149
153
|
)
|
|
150
154
|
|
|
151
155
|
forward_declarations = emit_forward_declarations(opaque_decls, aggregate_decls)
|
|
@@ -208,7 +212,13 @@ module MilkTea
|
|
|
208
212
|
end
|
|
209
213
|
|
|
210
214
|
if uses_variant_equality_helper?
|
|
211
|
-
|
|
215
|
+
unless uses_str_equality_helper?
|
|
216
|
+
variant_needs_str_eq = emitted_aggregate_variants.any? { |v| v.arms.any? { |a| a.fields.any? { |f| f.type.is_a?(Types::StringView) } } }
|
|
217
|
+
if variant_needs_str_eq
|
|
218
|
+
lines.concat(emit_string_type) unless uses_string_view?
|
|
219
|
+
lines.concat(emit_str_equality_helper)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
212
222
|
lines.concat(emit_variant_equality_helpers)
|
|
213
223
|
lines << ""
|
|
214
224
|
end
|
|
@@ -221,14 +231,14 @@ module MilkTea
|
|
|
221
231
|
|
|
222
232
|
constants.each do |constant|
|
|
223
233
|
@current_line = constant.line if constant.line
|
|
224
|
-
@source_path ||= constant.
|
|
234
|
+
@source_path ||= constant.path if constant.path
|
|
225
235
|
lines << "#{constant_storage(constant.type)} #{c_declaration(constant.type, constant.linkage_name)} = #{emit_initializer(constant.value)};"
|
|
226
236
|
end
|
|
227
237
|
@program.globals.each do |global|
|
|
228
238
|
next unless emitted_globals.include?(global)
|
|
229
239
|
if global.respond_to?(:line) && global.line
|
|
230
240
|
@current_line = global.line
|
|
231
|
-
@source_path ||= global.
|
|
241
|
+
@source_path ||= global.path if global.respond_to?(:path) && global.path
|
|
232
242
|
end
|
|
233
243
|
lines << "#{global_storage(global.type)} #{c_declaration(global.type, global.linkage_name)} = #{emit_initializer(global.value)};"
|
|
234
244
|
end
|
|
@@ -285,8 +295,6 @@ module MilkTea
|
|
|
285
295
|
lines.join("\n").rstrip + "\n"
|
|
286
296
|
end
|
|
287
297
|
|
|
288
|
-
private
|
|
289
|
-
|
|
290
298
|
EQUALITY_OPERATORS = ["==", "!="].freeze
|
|
291
299
|
|
|
292
300
|
include AggregateUtils
|
|
@@ -4,9 +4,8 @@ require_relative "../types/layout"
|
|
|
4
4
|
|
|
5
5
|
module MilkTea
|
|
6
6
|
module ConstEval
|
|
7
|
-
module_function
|
|
8
7
|
|
|
9
|
-
def evaluate(expression, resolve_identifier:, resolve_member_access:, resolve_type_ref: nil, resolve_call: nil)
|
|
8
|
+
def self.evaluate(expression, resolve_identifier:, resolve_member_access:, resolve_type_ref: nil, resolve_call: nil)
|
|
10
9
|
Evaluator.new(
|
|
11
10
|
resolve_identifier:,
|
|
12
11
|
resolve_member_access:,
|
|
@@ -15,7 +14,7 @@ module MilkTea
|
|
|
15
14
|
).evaluate(expression)
|
|
16
15
|
end
|
|
17
16
|
|
|
18
|
-
def equality_result(left, right)
|
|
17
|
+
def self.equality_result(left, right)
|
|
19
18
|
return left == right if left.is_a?(Numeric) && right.is_a?(Numeric)
|
|
20
19
|
return left == right if left.is_a?(String) && right.is_a?(String)
|
|
21
20
|
return left == right if boolean_value?(left) && boolean_value?(right)
|
|
@@ -24,13 +23,11 @@ module MilkTea
|
|
|
24
23
|
nil
|
|
25
24
|
end
|
|
26
25
|
|
|
27
|
-
def boolean_value?(value)
|
|
26
|
+
def self.boolean_value?(value)
|
|
28
27
|
value == true || value == false
|
|
29
28
|
end
|
|
30
29
|
|
|
31
30
|
class Evaluator
|
|
32
|
-
include Layout
|
|
33
|
-
|
|
34
31
|
def initialize(resolve_identifier:, resolve_member_access:, resolve_type_ref: nil, resolve_call: nil)
|
|
35
32
|
@resolve_identifier = resolve_identifier
|
|
36
33
|
@resolve_member_access = resolve_member_access
|
|
@@ -58,20 +55,20 @@ module MilkTea
|
|
|
58
55
|
@resolve_call&.call(expression)
|
|
59
56
|
when AST::SizeofExpr
|
|
60
57
|
type = resolve_layout_type(expression.type)
|
|
61
|
-
type && size_of(type)
|
|
58
|
+
type && Layout.size_of(type)
|
|
62
59
|
when AST::AlignofExpr
|
|
63
60
|
type = resolve_layout_type(expression.type)
|
|
64
|
-
type && alignment_of(type)
|
|
61
|
+
type && Layout.alignment_of(type)
|
|
65
62
|
when AST::OffsetofExpr
|
|
66
63
|
type = resolve_layout_type(expression.type)
|
|
67
64
|
if type
|
|
68
|
-
result = offset_of(type, expression.field)
|
|
65
|
+
result = Layout.offset_of(type, expression.field)
|
|
69
66
|
return result if result
|
|
70
67
|
|
|
71
68
|
id_expr = AST::Identifier.new(name: expression.field)
|
|
72
69
|
value = @resolve_identifier&.call(id_expr)
|
|
73
70
|
if value.is_a?(Types::FieldHandle)
|
|
74
|
-
return offset_of(type, value.field_name)
|
|
71
|
+
return Layout.offset_of(type, value.field_name)
|
|
75
72
|
end
|
|
76
73
|
end
|
|
77
74
|
nil
|
|
@@ -89,8 +86,6 @@ module MilkTea
|
|
|
89
86
|
end
|
|
90
87
|
end
|
|
91
88
|
|
|
92
|
-
private
|
|
93
|
-
|
|
94
89
|
def resolve_layout_type(type_ref)
|
|
95
90
|
return unless @resolve_type_ref
|
|
96
91
|
|
|
@@ -58,26 +58,24 @@ module MilkTea
|
|
|
58
58
|
result
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
private
|
|
62
|
-
|
|
63
61
|
def evaluate_expression(expression, scopes:)
|
|
64
62
|
case expression
|
|
65
63
|
when AST::Identifier
|
|
66
64
|
return @variables[expression.name] if @variables.key?(expression.name)
|
|
67
|
-
@checker.
|
|
65
|
+
@checker.evaluate_compile_time_const_value(expression, scopes:)
|
|
68
66
|
else
|
|
69
67
|
CompileTime.evaluate(
|
|
70
68
|
expression,
|
|
71
69
|
resolve_identifier: ->(id_expr) {
|
|
72
70
|
return @variables[id_expr.name] if @variables.key?(id_expr.name)
|
|
73
|
-
@checker.
|
|
71
|
+
@checker.evaluate_compile_time_const_value(id_expr, scopes:)
|
|
74
72
|
},
|
|
75
73
|
resolve_member_access: ->(ma_expr) {
|
|
76
|
-
@checker.
|
|
74
|
+
@checker.evaluate_compile_time_const_value(ma_expr, scopes:)
|
|
77
75
|
},
|
|
78
76
|
resolve_call: ->(call_expr) {
|
|
79
77
|
if call_expr.callee.is_a?(AST::Identifier)
|
|
80
|
-
func = @checker.
|
|
78
|
+
func = @checker.top_level_function(call_expr.callee.name)
|
|
81
79
|
if func&.ast&.respond_to?(:const) && func.ast.const
|
|
82
80
|
begin
|
|
83
81
|
initial_vars = {}
|
|
@@ -86,17 +84,17 @@ module MilkTea
|
|
|
86
84
|
|
|
87
85
|
arg_expr = call_expr.arguments[idx].value
|
|
88
86
|
arg_value = case arg_expr
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
87
|
+
when AST::Identifier
|
|
88
|
+
@variables[arg_expr.name] || @checker.evaluate_compile_time_const_value(arg_expr, scopes:)
|
|
89
|
+
else
|
|
90
|
+
CompileTime.evaluate(
|
|
91
|
+
arg_expr,
|
|
92
|
+
resolve_identifier: ->(id) { @variables[id.name] || @checker.evaluate_compile_time_const_value(id, scopes:) },
|
|
93
|
+
resolve_member_access: ->(ma) { @checker.evaluate_compile_time_const_value(ma, scopes:) },
|
|
94
|
+
resolve_type_ref: nil,
|
|
95
|
+
resolve_call: nil,
|
|
96
|
+
)
|
|
97
|
+
end
|
|
100
98
|
return nil unless arg_value
|
|
101
99
|
|
|
102
100
|
initial_vars[param.name] = arg_value
|
|
@@ -108,17 +106,17 @@ module MilkTea
|
|
|
108
106
|
end
|
|
109
107
|
end
|
|
110
108
|
end
|
|
111
|
-
|
|
109
|
+
|
|
112
110
|
types = if @checker.respond_to?(:types)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
@checker.types
|
|
112
|
+
else
|
|
113
|
+
@checker.instance_variable_get(:@ctx).types
|
|
114
|
+
end
|
|
117
115
|
callee_name = if call_expr.callee.is_a?(AST::Specialization) && call_expr.callee.callee.respond_to?(:name)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
116
|
+
call_expr.callee.callee.name
|
|
117
|
+
elsif call_expr.callee.respond_to?(:name)
|
|
118
|
+
call_expr.callee.name
|
|
119
|
+
end
|
|
122
120
|
if callee_name && (type = types[callee_name]) && type.is_a?(Types::Struct)
|
|
123
121
|
fields = {}
|
|
124
122
|
call_expr.arguments.each do |argument|
|
|
@@ -130,8 +128,8 @@ module MilkTea
|
|
|
130
128
|
end
|
|
131
129
|
|
|
132
130
|
if call_expr.callee.is_a?(AST::Specialization) && @checker.respond_to?(:resolve_type_expression)
|
|
133
|
-
resolved = @checker.
|
|
134
|
-
if resolved && @checker.respond_to?(:array_type?) && @checker.
|
|
131
|
+
resolved = @checker.resolve_type_expression(call_expr.callee)
|
|
132
|
+
if resolved && @checker.respond_to?(:array_type?) && @checker.array_type?(resolved)
|
|
135
133
|
values = []
|
|
136
134
|
call_expr.arguments.each do |argument|
|
|
137
135
|
val = evaluate_expression(argument.value, scopes:)
|
|
@@ -141,8 +139,8 @@ module MilkTea
|
|
|
141
139
|
next values
|
|
142
140
|
end
|
|
143
141
|
end
|
|
144
|
-
|
|
145
|
-
@checker.
|
|
142
|
+
|
|
143
|
+
@checker.evaluate_compile_time_const_value(call_expr, scopes:)
|
|
146
144
|
},
|
|
147
145
|
)
|
|
148
146
|
end
|
|
@@ -261,7 +259,6 @@ module MilkTea
|
|
|
261
259
|
end
|
|
262
260
|
|
|
263
261
|
class Evaluator < ConstEval::Evaluator
|
|
264
|
-
private
|
|
265
262
|
|
|
266
263
|
def resolve_layout_type(type_ref)
|
|
267
264
|
super
|
|
@@ -273,8 +270,8 @@ module MilkTea
|
|
|
273
270
|
|
|
274
271
|
value = evaluate(expression)
|
|
275
272
|
return value if value.is_a?(Types::Struct) || value.is_a?(Types::Primitive) ||
|
|
276
|
-
|
|
277
|
-
|
|
273
|
+
value.is_a?(Types::Union) || value.is_a?(Types::Nullable) ||
|
|
274
|
+
value.is_a?(Types::StructInstance)
|
|
278
275
|
|
|
279
276
|
nil
|
|
280
277
|
end
|
|
@@ -282,9 +279,7 @@ module MilkTea
|
|
|
282
279
|
|
|
283
280
|
end
|
|
284
281
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
def evaluate(expression, resolve_identifier:, resolve_member_access:, resolve_type_ref: nil, resolve_call: nil)
|
|
282
|
+
def self.evaluate(expression, resolve_identifier:, resolve_member_access:, resolve_type_ref: nil, resolve_call: nil)
|
|
288
283
|
Evaluator.new(
|
|
289
284
|
resolve_identifier:,
|
|
290
285
|
resolve_member_access:,
|
|
@@ -293,7 +288,7 @@ module MilkTea
|
|
|
293
288
|
).evaluate(expression)
|
|
294
289
|
end
|
|
295
290
|
|
|
296
|
-
def boolean_value?(value)
|
|
291
|
+
def self.boolean_value?(value)
|
|
297
292
|
ConstEval.boolean_value?(value)
|
|
298
293
|
end
|
|
299
294
|
|
|
@@ -357,7 +352,6 @@ module MilkTea
|
|
|
357
352
|
Types::BUILTIN_TYPE_META_TYPE
|
|
358
353
|
end
|
|
359
354
|
end
|
|
360
|
-
|
|
361
355
|
end
|
|
362
356
|
end
|
|
363
357
|
end
|
|
@@ -45,8 +45,6 @@ module MilkTea
|
|
|
45
45
|
@graph = nil
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
private
|
|
49
|
-
|
|
50
48
|
def build_block(stmts, next_id, break_target:, continue_target:)
|
|
51
49
|
current_next = next_id
|
|
52
50
|
stmts.reverse_each do |stmt|
|
|
@@ -114,7 +112,7 @@ module MilkTea
|
|
|
114
112
|
cond_id = @graph.add_node(
|
|
115
113
|
kind: :if_condition,
|
|
116
114
|
statement: branch,
|
|
117
|
-
line: branch.
|
|
115
|
+
line: branch.line || stmt.line,
|
|
118
116
|
reads: branch_reads,
|
|
119
117
|
reads_info: branch_reads_info,
|
|
120
118
|
)
|
|
@@ -140,7 +138,7 @@ module MilkTea
|
|
|
140
138
|
arm_body = if arm.respond_to?(:body)
|
|
141
139
|
arm.body
|
|
142
140
|
else
|
|
143
|
-
[MilkTea::AST::ExpressionStmt.new(expression: arm.value, line: arm.value.
|
|
141
|
+
[MilkTea::AST::ExpressionStmt.new(expression: arm.value, line: arm.value.line)]
|
|
144
142
|
end
|
|
145
143
|
arm_entry = build_block(arm_body, next_id, break_target:, continue_target:)
|
|
146
144
|
if arm.binding_name
|
|
@@ -267,7 +265,7 @@ module MilkTea
|
|
|
267
265
|
end
|
|
268
266
|
|
|
269
267
|
def add_linear_node(kind, stmt, next_id, reads: Set.new, reads_info: [], writes: Set.new, writes_info: [])
|
|
270
|
-
node_id = @graph.add_node(kind:, statement: stmt, line: stmt.
|
|
268
|
+
node_id = @graph.add_node(kind:, statement: stmt, line: stmt.line, reads:, reads_info:, writes:, writes_info:)
|
|
271
269
|
@graph.add_edge(node_id, next_id)
|
|
272
270
|
node_id
|
|
273
271
|
end
|
|
@@ -59,7 +59,6 @@ module MilkTea
|
|
|
59
59
|
|
|
60
60
|
a == b ? a : NAC
|
|
61
61
|
end
|
|
62
|
-
private_class_method :join_lattice
|
|
63
62
|
|
|
64
63
|
def self.eval_const(statement, _write, in_state, binding_resolution:, strict_binding_ids:)
|
|
65
64
|
case statement
|
|
@@ -71,7 +70,6 @@ module MilkTea
|
|
|
71
70
|
NAC
|
|
72
71
|
end
|
|
73
72
|
end
|
|
74
|
-
private_class_method :eval_const
|
|
75
73
|
|
|
76
74
|
def self.eval_assignment_const(statement, in_state, binding_resolution:, strict_binding_ids:)
|
|
77
75
|
return NAC unless statement.target.is_a?(AST::Identifier)
|
|
@@ -86,24 +84,23 @@ module MilkTea
|
|
|
86
84
|
|
|
87
85
|
begin
|
|
88
86
|
v = case statement.operator
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
87
|
+
when "+=" then lhs.value + rhs.value
|
|
88
|
+
when "-=" then lhs.value - rhs.value
|
|
89
|
+
when "*=" then lhs.value * rhs.value
|
|
90
|
+
when "/=" then rhs.value.zero? ? (return NAC) : lhs.value / rhs.value
|
|
91
|
+
when "%=" then rhs.value.zero? ? (return NAC) : lhs.value % rhs.value
|
|
92
|
+
when "&=" then lhs.value & rhs.value
|
|
93
|
+
when "|=" then lhs.value | rhs.value
|
|
94
|
+
when "^=" then lhs.value ^ rhs.value
|
|
95
|
+
when "<<=" then lhs.value << rhs.value
|
|
96
|
+
when ">>=" then lhs.value >> rhs.value
|
|
97
|
+
else return NAC
|
|
98
|
+
end
|
|
101
99
|
ConstVal.new(v)
|
|
102
100
|
rescue ZeroDivisionError, RangeError
|
|
103
101
|
NAC
|
|
104
102
|
end
|
|
105
103
|
end
|
|
106
|
-
private_class_method :eval_assignment_const
|
|
107
104
|
|
|
108
105
|
def self.eval_expr_const(expr, state, binding_resolution:, strict_binding_ids:)
|
|
109
106
|
return NAC if expr.nil?
|
|
@@ -120,8 +117,9 @@ module MilkTea
|
|
|
120
117
|
resolve_member_access: nil,
|
|
121
118
|
)
|
|
122
119
|
value.nil? ? NAC : ConstVal.new(value)
|
|
120
|
+
rescue CompileTime::Error
|
|
121
|
+
NAC
|
|
123
122
|
end
|
|
124
|
-
private_class_method :eval_expr_const
|
|
125
123
|
|
|
126
124
|
def self.constant_value_of(expr, in_state, binding_resolution: nil, strict_binding_ids: false)
|
|
127
125
|
result = send(:eval_expr_const, expr, in_state, binding_resolution:, strict_binding_ids:)
|
|
@@ -137,7 +135,6 @@ module MilkTea
|
|
|
137
135
|
|
|
138
136
|
identifier_expression.name
|
|
139
137
|
end
|
|
140
|
-
private_class_method :identifier_key
|
|
141
138
|
end
|
|
142
139
|
end
|
|
143
140
|
end
|
data/lib/milk_tea/core/ir.rb
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module MilkTea
|
|
4
4
|
module IR
|
|
5
|
-
Program = Data.define(:module_name, :includes, :constants, :globals, :opaques, :structs, :unions, :enums, :variants, :static_asserts, :functions, :
|
|
6
|
-
def initialize(module_name:, includes:, constants:, globals:, opaques:, structs:, unions:, enums:, variants:, static_asserts:, functions:,
|
|
5
|
+
Program = Data.define(:module_name, :includes, :constants, :globals, :opaques, :structs, :unions, :enums, :variants, :static_asserts, :functions, :path) do
|
|
6
|
+
def initialize(module_name:, includes:, constants:, globals:, opaques:, structs:, unions:, enums:, variants:, static_asserts:, functions:, path: nil) = super
|
|
7
7
|
end
|
|
8
8
|
Include = Data.define(:header)
|
|
9
|
-
Constant = Data.define(:name, :linkage_name, :type, :value, :line, :
|
|
10
|
-
def initialize(name:, linkage_name:, type:, value:, line: nil,
|
|
9
|
+
Constant = Data.define(:name, :linkage_name, :type, :value, :line, :path) do
|
|
10
|
+
def initialize(name:, linkage_name:, type:, value:, line: nil, path: nil) = super
|
|
11
11
|
end
|
|
12
12
|
Global = Data.define(:name, :linkage_name, :type, :value)
|
|
13
13
|
OpaqueDecl = Data.define(:name, :linkage_name, :forward_declarable, :source_module) do
|
|
@@ -27,8 +27,8 @@ module MilkTea
|
|
|
27
27
|
end
|
|
28
28
|
Param = Data.define(:name, :linkage_name, :type, :pointer)
|
|
29
29
|
|
|
30
|
-
LocalDecl = Data.define(:name, :linkage_name, :type, :value, :line, :
|
|
31
|
-
def initialize(name:, linkage_name:, type:, value:, line: nil,
|
|
30
|
+
LocalDecl = Data.define(:name, :linkage_name, :type, :value, :line, :path) do
|
|
31
|
+
def initialize(name:, linkage_name:, type:, value:, line: nil, path: nil) = super
|
|
32
32
|
end
|
|
33
33
|
Assignment = Data.define(:target, :operator, :value)
|
|
34
34
|
BlockStmt = Data.define(:body)
|
|
@@ -45,11 +45,11 @@ module MilkTea
|
|
|
45
45
|
GotoStmt = Data.define(:label)
|
|
46
46
|
LabelStmt = Data.define(:name)
|
|
47
47
|
StaticAssert = Data.define(:condition, :message)
|
|
48
|
-
ReturnStmt = Data.define(:value, :line, :
|
|
49
|
-
def initialize(value:, line: nil,
|
|
48
|
+
ReturnStmt = Data.define(:value, :line, :path) do
|
|
49
|
+
def initialize(value:, line: nil, path: nil) = super
|
|
50
50
|
end
|
|
51
|
-
ExpressionStmt = Data.define(:expression, :line, :
|
|
52
|
-
def initialize(expression:, line: nil,
|
|
51
|
+
ExpressionStmt = Data.define(:expression, :line, :path) do
|
|
52
|
+
def initialize(expression:, line: nil, path: nil) = super
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
Name = Data.define(:name, :type, :pointer)
|
|
@@ -4,8 +4,6 @@ module MilkTea
|
|
|
4
4
|
class Lexer
|
|
5
5
|
# Identifier lexing plus the raw-byte character-classification helpers.
|
|
6
6
|
module CharacterClasses
|
|
7
|
-
private
|
|
8
|
-
|
|
9
7
|
def lex_identifier(line, index, line_number, line_offset:)
|
|
10
8
|
start = index
|
|
11
9
|
length = line.length
|
|
@@ -17,11 +15,11 @@ module MilkTea
|
|
|
17
15
|
lexeme = line[start...index]
|
|
18
16
|
type = Token::KEYWORDS.fetch(lexeme, :identifier)
|
|
19
17
|
literal = case type
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
when :true then true
|
|
19
|
+
when :false then false
|
|
20
|
+
when :null then nil
|
|
21
|
+
else nil
|
|
22
|
+
end
|
|
25
23
|
|
|
26
24
|
@tokens << token(type, lexeme, literal, line_number, start + 1, start_offset: line_offset + start, end_offset: line_offset + index)
|
|
27
25
|
index
|
|
@@ -5,8 +5,6 @@ module MilkTea
|
|
|
5
5
|
# Format string lexing (`f"...#{expr}..."`) and the interpolation
|
|
6
6
|
# scanning / format-spec splitting shared with format heredocs.
|
|
7
7
|
module FormatStrings
|
|
8
|
-
private
|
|
9
|
-
|
|
10
8
|
def parse_format_heredoc_parts(content, start_line:, start_column:)
|
|
11
9
|
parts = []
|
|
12
10
|
text = +""
|
|
@@ -182,13 +180,13 @@ module MilkTea
|
|
|
182
180
|
end
|
|
183
181
|
|
|
184
182
|
case char
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
183
|
+
when "(", "[", "{"
|
|
184
|
+
depth += 1
|
|
185
|
+
when ")", "]", "}"
|
|
186
|
+
depth -= 1 if depth.positive?
|
|
187
|
+
when ":"
|
|
188
|
+
suffix = source[(index + 1)..]
|
|
189
|
+
format_spec_index = index if depth.zero? && format_spec_suffix?(suffix)
|
|
192
190
|
end
|
|
193
191
|
|
|
194
192
|
index += 1
|
|
@@ -5,8 +5,6 @@ module MilkTea
|
|
|
5
5
|
# Heredoc lexing (`<<-TAG`, `c<<-TAG`, `f<<-TAG`) including content
|
|
6
6
|
# dedenting, terminator detection, and recovery.
|
|
7
7
|
module Heredocs
|
|
8
|
-
private
|
|
9
|
-
|
|
10
8
|
def lex_heredoc(lines, line_index, index, line_number, line_offset, cstring:, format: false)
|
|
11
9
|
line = lines.fetch(line_index).delete_suffix("\n").b
|
|
12
10
|
prefix_length = heredoc_prefix(cstring:, format:).length
|
|
@@ -91,17 +89,18 @@ module MilkTea
|
|
|
91
89
|
content_margin = heredoc_content_margin(content_lines)
|
|
92
90
|
|
|
93
91
|
literal = if format
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
parse_format_heredoc_parts(value, start_line: line_number + 1, start_column: content_margin + 1)
|
|
93
|
+
else
|
|
94
|
+
value
|
|
95
|
+
end
|
|
96
|
+
|
|
98
97
|
token_type = if format
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
98
|
+
:fstring
|
|
99
|
+
elsif cstring
|
|
100
|
+
:cstring
|
|
101
|
+
else
|
|
102
|
+
:string
|
|
103
|
+
end
|
|
105
104
|
|
|
106
105
|
@tokens << token(token_type, lexeme, literal, line_number, index + 1, start_offset:, end_offset:)
|
|
107
106
|
emit_line_newline(last_line, last_line_number, last_line_offset, last_line_has_newline)
|
|
@@ -118,17 +117,18 @@ module MilkTea
|
|
|
118
117
|
content_margin = heredoc_content_margin(content_lines)
|
|
119
118
|
|
|
120
119
|
literal = if format
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
120
|
+
parse_format_heredoc_parts(value, start_line: line_number + 1, start_column: content_margin + 1)
|
|
121
|
+
else
|
|
122
|
+
value
|
|
123
|
+
end
|
|
124
|
+
|
|
125
125
|
token_type = if format
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
:fstring
|
|
127
|
+
elsif cstring
|
|
128
|
+
:cstring
|
|
129
|
+
else
|
|
130
|
+
:string
|
|
131
|
+
end
|
|
132
132
|
|
|
133
133
|
@tokens << token(token_type, lexeme, literal, line_number, index + 1, start_offset:, end_offset:)
|
|
134
134
|
emit_line_newline(terminator_line, terminator_line_number, terminator_line_offset, terminator_has_newline)
|
|
@@ -4,8 +4,6 @@ module MilkTea
|
|
|
4
4
|
class Lexer
|
|
5
5
|
# Indentation-to-INDENT/DEDENT token conversion and error recovery.
|
|
6
6
|
module Indentation
|
|
7
|
-
private
|
|
8
|
-
|
|
9
7
|
def emit_indentation(indent, line_number, line_offset)
|
|
10
8
|
if (indent % 4) != 0
|
|
11
9
|
raise LexError.new("indentation must use multiples of 4 spaces", line: line_number, column: indent + 1, path: @path)
|
|
@@ -5,8 +5,6 @@ module MilkTea
|
|
|
5
5
|
# Error-recovery heuristics: detecting a top-level declaration line to
|
|
6
6
|
# resynchronize on after an unterminated grouping or heredoc.
|
|
7
7
|
module Recovery
|
|
8
|
-
private
|
|
9
|
-
|
|
10
8
|
def top_level_resync_line?(line)
|
|
11
9
|
return false if line.strip.empty?
|
|
12
10
|
return false if leading_space_count(line).positive?
|
|
@@ -5,8 +5,6 @@ module MilkTea
|
|
|
5
5
|
# String literal lexing (including adjacent-literal continuation),
|
|
6
6
|
# character literal lexing, and escape-sequence decoding.
|
|
7
7
|
module Strings
|
|
8
|
-
private
|
|
9
|
-
|
|
10
8
|
def lex_string(lines, line_index, line, index, line_number, line_offset:, cstring: false)
|
|
11
9
|
segment = scan_string_segment(line, index, line_number, cstring:, recover: @recovery_errors)
|
|
12
10
|
consumed_lines = 1
|