mt-lang 0.2.0
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 +7 -0
- data/.ruby-version +1 -0
- data/AUTHORS +3 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +82 -0
- data/LICENSE +21 -0
- data/README.md +1208 -0
- data/Rakefile +332 -0
- data/bin/mtc +8 -0
- data/bin/profile-mtc-checks +133 -0
- data/bin/tracy-profiler +0 -0
- data/docs/build-guide.md +536 -0
- data/docs/index.html +2778 -0
- data/docs/language-design.md +1519 -0
- data/docs/language-manual.md +1534 -0
- data/lib/milk_tea/base.rb +49 -0
- data/lib/milk_tea/bindings/bindgen/ast_parser.rb +398 -0
- data/lib/milk_tea/bindings/bindgen/declaration.rb +319 -0
- data/lib/milk_tea/bindings/bindgen/emitter.rb +387 -0
- data/lib/milk_tea/bindings/bindgen/overrides.rb +134 -0
- data/lib/milk_tea/bindings/bindgen/type_mapper.rb +622 -0
- data/lib/milk_tea/bindings/bindgen.rb +207 -0
- data/lib/milk_tea/bindings/cli.rb +121 -0
- data/lib/milk_tea/bindings/imported_bindings/defaults.rb +210 -0
- data/lib/milk_tea/bindings/imported_bindings/generator.rb +1114 -0
- data/lib/milk_tea/bindings/imported_bindings/method_source.rb +190 -0
- data/lib/milk_tea/bindings/imported_bindings/naming.rb +286 -0
- data/lib/milk_tea/bindings/imported_bindings.rb +215 -0
- data/lib/milk_tea/bindings/opengl_registry.rb +547 -0
- data/lib/milk_tea/bindings/raw_bindings/defaults.rb +1338 -0
- data/lib/milk_tea/bindings/raw_bindings.rb +269 -0
- data/lib/milk_tea/bindings/steamworks.rb +629 -0
- data/lib/milk_tea/bindings/upstream_sources.rb +352 -0
- data/lib/milk_tea/bindings/vendored_box2d.rb +79 -0
- data/lib/milk_tea/bindings/vendored_c_library.rb +322 -0
- data/lib/milk_tea/bindings/vendored_cjson.rb +52 -0
- data/lib/milk_tea/bindings/vendored_flecs.rb +78 -0
- data/lib/milk_tea/bindings/vendored_glfw.rb +77 -0
- data/lib/milk_tea/bindings/vendored_libuv.rb +75 -0
- data/lib/milk_tea/bindings/vendored_pcre2.rb +84 -0
- data/lib/milk_tea/bindings/vendored_raylib.rb +131 -0
- data/lib/milk_tea/bindings/vendored_sdl3.rb +78 -0
- data/lib/milk_tea/bindings/vendored_steamworks.rb +71 -0
- data/lib/milk_tea/bindings/vendored_tool.rb +71 -0
- data/lib/milk_tea/bindings/vendored_tools.rb +23 -0
- data/lib/milk_tea/bindings/vendored_tracy.rb +37 -0
- data/lib/milk_tea/bindings.rb +23 -0
- data/lib/milk_tea/core/ast.rb +311 -0
- data/lib/milk_tea/core/async_runtime_installer.rb +28 -0
- data/lib/milk_tea/core/binding_types.rb +18 -0
- data/lib/milk_tea/core/bindings/attribute_binding.rb +58 -0
- data/lib/milk_tea/core/bindings/function_binding.rb +5 -0
- data/lib/milk_tea/core/bindings/module_binding.rb +58 -0
- data/lib/milk_tea/core/bindings/value_binding.rb +21 -0
- data/lib/milk_tea/core/c_backend/aggregate_utils.rb +103 -0
- data/lib/milk_tea/core/c_backend/control_flow_emission.rb +412 -0
- data/lib/milk_tea/core/c_backend/expressions.rb +468 -0
- data/lib/milk_tea/core/c_backend/feature_detection.rb +483 -0
- data/lib/milk_tea/core/c_backend/reachability.rb +398 -0
- data/lib/milk_tea/core/c_backend/reinterpret.rb +226 -0
- data/lib/milk_tea/core/c_backend/runtime_helpers.rb +1080 -0
- data/lib/milk_tea/core/c_backend/statements.rb +563 -0
- data/lib/milk_tea/core/c_backend/type_collectors.rb +1545 -0
- data/lib/milk_tea/core/c_backend/type_declaration.rb +223 -0
- data/lib/milk_tea/core/c_backend/type_system.rb +345 -0
- data/lib/milk_tea/core/c_backend.rb +287 -0
- data/lib/milk_tea/core/compatibility_helpers.rb +79 -0
- data/lib/milk_tea/core/compile_time/const_eval.rb +187 -0
- data/lib/milk_tea/core/compile_time.rb +329 -0
- data/lib/milk_tea/core/control_flow/builder.rb +582 -0
- data/lib/milk_tea/core/control_flow/constant_propagation.rb +143 -0
- data/lib/milk_tea/core/control_flow/dataflow.rb +74 -0
- data/lib/milk_tea/core/control_flow/definite_assignment.rb +79 -0
- data/lib/milk_tea/core/control_flow/graph.rb +90 -0
- data/lib/milk_tea/core/control_flow/liveness.rb +24 -0
- data/lib/milk_tea/core/control_flow/nullability_flow.rb +43 -0
- data/lib/milk_tea/core/control_flow/reachability.rb +22 -0
- data/lib/milk_tea/core/control_flow/termination.rb +31 -0
- data/lib/milk_tea/core/control_flow.rb +34 -0
- data/lib/milk_tea/core/cst.rb +48 -0
- data/lib/milk_tea/core/cst_builder.rb +19 -0
- data/lib/milk_tea/core/ir.rb +85 -0
- data/lib/milk_tea/core/keywords.rb +97 -0
- data/lib/milk_tea/core/lexer/character_classes.rb +60 -0
- data/lib/milk_tea/core/lexer/format_strings.rb +225 -0
- data/lib/milk_tea/core/lexer/heredocs.rb +199 -0
- data/lib/milk_tea/core/lexer/indentation.rb +62 -0
- data/lib/milk_tea/core/lexer/numbers.rb +96 -0
- data/lib/milk_tea/core/lexer/recovery.rb +32 -0
- data/lib/milk_tea/core/lexer/strings.rb +167 -0
- data/lib/milk_tea/core/lexer/symbols.rb +71 -0
- data/lib/milk_tea/core/lexer/trivia.rb +53 -0
- data/lib/milk_tea/core/lexer.rb +430 -0
- data/lib/milk_tea/core/lowering/artifacts.rb +26 -0
- data/lib/milk_tea/core/lowering/async/analysis.rb +245 -0
- data/lib/milk_tea/core/lowering/async/lowering.rb +1399 -0
- data/lib/milk_tea/core/lowering/async/normalization.rb +459 -0
- data/lib/milk_tea/core/lowering/async.rb +714 -0
- data/lib/milk_tea/core/lowering/block.rb +1052 -0
- data/lib/milk_tea/core/lowering/calls.rb +1565 -0
- data/lib/milk_tea/core/lowering/declarations.rb +214 -0
- data/lib/milk_tea/core/lowering/dyn.rb +206 -0
- data/lib/milk_tea/core/lowering/events.rb +1054 -0
- data/lib/milk_tea/core/lowering/expressions.rb +1645 -0
- data/lib/milk_tea/core/lowering/foreign_cstr.rb +206 -0
- data/lib/milk_tea/core/lowering/functions.rb +242 -0
- data/lib/milk_tea/core/lowering/loops.rb +1087 -0
- data/lib/milk_tea/core/lowering/lowering_context.rb +80 -0
- data/lib/milk_tea/core/lowering/proc.rb +419 -0
- data/lib/milk_tea/core/lowering/resolve.rb +2516 -0
- data/lib/milk_tea/core/lowering/scans.rb +220 -0
- data/lib/milk_tea/core/lowering/str_buffer.rb +125 -0
- data/lib/milk_tea/core/lowering/utils.rb +1453 -0
- data/lib/milk_tea/core/lowering.rb +378 -0
- data/lib/milk_tea/core/module_binder.rb +181 -0
- data/lib/milk_tea/core/module_loader/errors.rb +21 -0
- data/lib/milk_tea/core/module_loader.rb +479 -0
- data/lib/milk_tea/core/module_path_resolver.rb +153 -0
- data/lib/milk_tea/core/module_roots.rb +88 -0
- data/lib/milk_tea/core/parser/attributes.rb +71 -0
- data/lib/milk_tea/core/parser/blocks.rb +119 -0
- data/lib/milk_tea/core/parser/declarations.rb +749 -0
- data/lib/milk_tea/core/parser/expressions.rb +624 -0
- data/lib/milk_tea/core/parser/recovery.rb +131 -0
- data/lib/milk_tea/core/parser/statements.rb +756 -0
- data/lib/milk_tea/core/parser/types.rb +271 -0
- data/lib/milk_tea/core/parser.rb +400 -0
- data/lib/milk_tea/core/prelude_installer.rb +29 -0
- data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +917 -0
- data/lib/milk_tea/core/pretty_printer/base_formatter.rb +87 -0
- data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +300 -0
- data/lib/milk_tea/core/pretty_printer.rb +17 -0
- data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +314 -0
- data/lib/milk_tea/core/semantic_analyzer/attributes.rb +184 -0
- data/lib/milk_tea/core/semantic_analyzer/calls.rb +992 -0
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +1735 -0
- data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +355 -0
- data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +155 -0
- data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +354 -0
- data/lib/milk_tea/core/semantic_analyzer/generics.rb +383 -0
- data/lib/milk_tea/core/semantic_analyzer/interface_conformance.rb +78 -0
- data/lib/milk_tea/core/semantic_analyzer/module_context.rb +35 -0
- data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +1438 -0
- data/lib/milk_tea/core/semantic_analyzer/nullability.rb +421 -0
- data/lib/milk_tea/core/semantic_analyzer/statements.rb +1308 -0
- data/lib/milk_tea/core/semantic_analyzer/top_level.rb +588 -0
- data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +307 -0
- data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +851 -0
- data/lib/milk_tea/core/semantic_analyzer.rb +327 -0
- data/lib/milk_tea/core/token.rb +26 -0
- data/lib/milk_tea/core/token_stream.rb +30 -0
- data/lib/milk_tea/core/types/layout.rb +243 -0
- data/lib/milk_tea/core/types/predicates.rb +609 -0
- data/lib/milk_tea/core/types/registry.rb +83 -0
- data/lib/milk_tea/core/types/types.rb +1696 -0
- data/lib/milk_tea/core/types/visitor.rb +442 -0
- data/lib/milk_tea/core.rb +25 -0
- data/lib/milk_tea/dap/backends/lldb_dap.rb +158 -0
- data/lib/milk_tea/dap/protocol.rb +58 -0
- data/lib/milk_tea/dap/server/breakpoints.rb +66 -0
- data/lib/milk_tea/dap/server/debug_map.rb +291 -0
- data/lib/milk_tea/dap/server/handlers.rb +374 -0
- data/lib/milk_tea/dap/server/launch.rb +261 -0
- data/lib/milk_tea/dap/server/lldb_backend.rb +380 -0
- data/lib/milk_tea/dap/server/pause_diagnostics.rb +109 -0
- data/lib/milk_tea/dap/server/utilities.rb +160 -0
- data/lib/milk_tea/dap/server/wire.rb +55 -0
- data/lib/milk_tea/dap/server.rb +131 -0
- data/lib/milk_tea/dap/session.rb +152 -0
- data/lib/milk_tea/dap.rb +6 -0
- data/lib/milk_tea/lsp/dependency_resolution.rb +52 -0
- data/lib/milk_tea/lsp/diagnostics.rb +611 -0
- data/lib/milk_tea/lsp/protocol.rb +104 -0
- data/lib/milk_tea/lsp/server/call_hierarchy.rb +274 -0
- data/lib/milk_tea/lsp/server/code_actions.rb +446 -0
- data/lib/milk_tea/lsp/server/code_lens.rb +97 -0
- data/lib/milk_tea/lsp/server/completion.rb +1099 -0
- data/lib/milk_tea/lsp/server/configuration.rb +167 -0
- data/lib/milk_tea/lsp/server/debug_info.rb +45 -0
- data/lib/milk_tea/lsp/server/definition.rb +779 -0
- data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +239 -0
- data/lib/milk_tea/lsp/server/execute_command.rb +25 -0
- data/lib/milk_tea/lsp/server/folding_range.rb +153 -0
- data/lib/milk_tea/lsp/server/formatting.rb +575 -0
- data/lib/milk_tea/lsp/server/hover.rb +1465 -0
- data/lib/milk_tea/lsp/server/inlay_hints.rb +204 -0
- data/lib/milk_tea/lsp/server/lifecycle.rb +234 -0
- data/lib/milk_tea/lsp/server/linked_editing_range.rb +43 -0
- data/lib/milk_tea/lsp/server/on_type_formatting.rb +73 -0
- data/lib/milk_tea/lsp/server/progress.rb +47 -0
- data/lib/milk_tea/lsp/server/references.rb +433 -0
- data/lib/milk_tea/lsp/server/rename.rb +598 -0
- data/lib/milk_tea/lsp/server/selection_range.rb +130 -0
- data/lib/milk_tea/lsp/server/semantic_tokens.rb +1745 -0
- data/lib/milk_tea/lsp/server/signature_help.rb +200 -0
- data/lib/milk_tea/lsp/server/text_documents.rb +125 -0
- data/lib/milk_tea/lsp/server/type_hierarchy.rb +167 -0
- data/lib/milk_tea/lsp/server/utilities.rb +520 -0
- data/lib/milk_tea/lsp/server.rb +415 -0
- data/lib/milk_tea/lsp/workspace/analysis.rb +209 -0
- data/lib/milk_tea/lsp/workspace/caches.rb +260 -0
- data/lib/milk_tea/lsp/workspace/collection.rb +98 -0
- data/lib/milk_tea/lsp/workspace/definition_index.rb +184 -0
- data/lib/milk_tea/lsp/workspace/dependency_graph.rb +282 -0
- data/lib/milk_tea/lsp/workspace/store.rb +154 -0
- data/lib/milk_tea/lsp/workspace/utilities.rb +490 -0
- data/lib/milk_tea/lsp/workspace.rb +127 -0
- data/lib/milk_tea/lsp.rb +13 -0
- data/lib/milk_tea/packages/atomic_write.rb +63 -0
- data/lib/milk_tea/packages/dependency_solver.rb +194 -0
- data/lib/milk_tea/packages/graph.rb +139 -0
- data/lib/milk_tea/packages/lock.rb +421 -0
- data/lib/milk_tea/packages/manager_cli.rb +485 -0
- data/lib/milk_tea/packages/manifest.rb +356 -0
- data/lib/milk_tea/packages/manifest_editor.rb +134 -0
- data/lib/milk_tea/packages/registry_metadata_provider.rb +34 -0
- data/lib/milk_tea/packages/registry_store.rb +420 -0
- data/lib/milk_tea/packages/services.rb +41 -0
- data/lib/milk_tea/packages/source_cache.rb +71 -0
- data/lib/milk_tea/packages/source_fetcher.rb +124 -0
- data/lib/milk_tea/packages/source_resolver.rb +389 -0
- data/lib/milk_tea/packages/version.rb +164 -0
- data/lib/milk_tea/packages.rb +16 -0
- data/lib/milk_tea/tooling/asset_pack.rb +141 -0
- data/lib/milk_tea/tooling/build.rb +1124 -0
- data/lib/milk_tea/tooling/build_cache.rb +240 -0
- data/lib/milk_tea/tooling/cli.rb +2688 -0
- data/lib/milk_tea/tooling/cst_formatter.rb +13 -0
- data/lib/milk_tea/tooling/debug_info_formatter.rb +456 -0
- data/lib/milk_tea/tooling/debug_map.rb +248 -0
- data/lib/milk_tea/tooling/docs_app.rb +369 -0
- data/lib/milk_tea/tooling/error_formatter.rb +86 -0
- data/lib/milk_tea/tooling/formatter.rb +787 -0
- data/lib/milk_tea/tooling/linter/doc_tags.rb +212 -0
- data/lib/milk_tea/tooling/linter/fix_engine.rb +237 -0
- data/lib/milk_tea/tooling/linter/flow_rules.rb +380 -0
- data/lib/milk_tea/tooling/linter/imports_platform.rb +841 -0
- data/lib/milk_tea/tooling/linter/release_rules.rb +744 -0
- data/lib/milk_tea/tooling/linter/reserved_names.rb +199 -0
- data/lib/milk_tea/tooling/linter/rules.rb +593 -0
- data/lib/milk_tea/tooling/linter/source_helpers.rb +407 -0
- data/lib/milk_tea/tooling/linter/trailing_comma.rb +139 -0
- data/lib/milk_tea/tooling/linter/visitors.rb +1286 -0
- data/lib/milk_tea/tooling/linter.rb +798 -0
- data/lib/milk_tea/tooling/project_scaffold.rb +82 -0
- data/lib/milk_tea/tooling/public/css/docs.css +166 -0
- data/lib/milk_tea/tooling/public/js/docs.js +94 -0
- data/lib/milk_tea/tooling/run.rb +408 -0
- data/lib/milk_tea/tooling/templates/wasm_shell.html +48 -0
- data/lib/milk_tea/tooling/toolchain_cli.rb +157 -0
- data/lib/milk_tea/tooling/views/404.erb +7 -0
- data/lib/milk_tea/tooling/views/index.erb +87 -0
- data/lib/milk_tea/tooling/views/layout.erb +69 -0
- data/lib/milk_tea/tooling/views/module.erb +97 -0
- data/lib/milk_tea/tooling/views/stdlib.erb +21 -0
- data/lib/milk_tea/tooling.rb +20 -0
- data/lib/milk_tea.rb +8 -0
- metadata +426 -0
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MilkTea
|
|
4
|
+
class SemanticAnalyzer
|
|
5
|
+
class Checker
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def check_top_level_values
|
|
9
|
+
expanded_declarations.each do |decl|
|
|
10
|
+
with_error_node(decl) do
|
|
11
|
+
case decl
|
|
12
|
+
when AST::ConstDecl
|
|
13
|
+
begin
|
|
14
|
+
if decl.block_body
|
|
15
|
+
check_block_body_const(decl)
|
|
16
|
+
else
|
|
17
|
+
check_expr_const(decl)
|
|
18
|
+
end
|
|
19
|
+
rescue SemanticError => e
|
|
20
|
+
collect_structural_error(e)
|
|
21
|
+
end
|
|
22
|
+
when AST::VarDecl
|
|
23
|
+
binding = @ctx.top_level_values.fetch(decl.name)
|
|
24
|
+
if decl.value
|
|
25
|
+
validate_consuming_foreign_expression!(decl.value, scopes: [], root_allowed: false)
|
|
26
|
+
validate_hoistable_foreign_expression!(decl.value, scopes: [], root_hoistable: false)
|
|
27
|
+
actual_type = infer_expression(decl.value, scopes: [], expected_type: binding.type)
|
|
28
|
+
ensure_assignable!(
|
|
29
|
+
actual_type,
|
|
30
|
+
binding.type,
|
|
31
|
+
"cannot assign #{actual_type} to module variable #{decl.name}: expected #{binding.type}",
|
|
32
|
+
expression: decl.value,
|
|
33
|
+
)
|
|
34
|
+
validate_static_storage_initializer!(decl.value, scopes: [])
|
|
35
|
+
else
|
|
36
|
+
zero_initializable_type?(binding.type)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def check_expr_const(decl)
|
|
44
|
+
binding = @ctx.top_level_values.fetch(decl.name)
|
|
45
|
+
validate_consuming_foreign_expression!(decl.value, scopes: [], root_allowed: false)
|
|
46
|
+
validate_hoistable_foreign_expression!(decl.value, scopes: [], root_hoistable: false)
|
|
47
|
+
|
|
48
|
+
if binding.type == builtin_type_meta_type
|
|
49
|
+
evaluate_compile_time_const_value(decl.value)
|
|
50
|
+
return
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
actual_type = infer_expression(decl.value, scopes: [], expected_type: binding.type)
|
|
54
|
+
ensure_assignable!(
|
|
55
|
+
actual_type,
|
|
56
|
+
binding.type,
|
|
57
|
+
"cannot assign #{actual_type} to constant #{decl.name}: expected #{binding.type}",
|
|
58
|
+
expression: decl.value,
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def check_block_body_const(decl)
|
|
63
|
+
return unless decl.block_body
|
|
64
|
+
|
|
65
|
+
last_stmt = decl.block_body.last
|
|
66
|
+
unless last_stmt.is_a?(AST::ReturnStmt) && last_stmt.value
|
|
67
|
+
raise_sema_error("block-bodied const must end with a return statement")
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def validate_static_storage_initializer!(expression, scopes:)
|
|
72
|
+
case expression
|
|
73
|
+
when AST::ErrorExpr
|
|
74
|
+
return
|
|
75
|
+
when AST::IntegerLiteral, AST::FloatLiteral, AST::StringLiteral, AST::BooleanLiteral, AST::NullLiteral,
|
|
76
|
+
AST::SizeofExpr, AST::AlignofExpr, AST::OffsetofExpr
|
|
77
|
+
return
|
|
78
|
+
when AST::Identifier
|
|
79
|
+
if (binding = lookup_value(expression.name, scopes))
|
|
80
|
+
return if binding.kind == :const
|
|
81
|
+
|
|
82
|
+
raise_sema_error("module variable initializer cannot reference mutable value #{expression.name}")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
function = @ctx.top_level_functions[expression.name]
|
|
86
|
+
return if function && static_storage_function_value?(function)
|
|
87
|
+
|
|
88
|
+
raise_sema_error("module variable initializer must be static-storage-safe")
|
|
89
|
+
when AST::MemberAccess
|
|
90
|
+
return if static_storage_member_initializer?(expression, scopes:)
|
|
91
|
+
|
|
92
|
+
raise_sema_error("module variable initializer must be static-storage-safe")
|
|
93
|
+
when AST::UnaryOp
|
|
94
|
+
validate_static_storage_initializer!(expression.operand, scopes:)
|
|
95
|
+
when AST::BinaryOp
|
|
96
|
+
validate_static_storage_initializer!(expression.left, scopes:)
|
|
97
|
+
validate_static_storage_initializer!(expression.right, scopes:)
|
|
98
|
+
when AST::IfExpr
|
|
99
|
+
validate_static_storage_initializer!(expression.condition, scopes:)
|
|
100
|
+
validate_static_storage_initializer!(expression.then_expression, scopes:)
|
|
101
|
+
validate_static_storage_initializer!(expression.else_expression, scopes:)
|
|
102
|
+
when AST::UnsafeExpr
|
|
103
|
+
validate_static_storage_initializer!(expression.expression, scopes:)
|
|
104
|
+
when AST::ExpressionList
|
|
105
|
+
expression.elements.each { |element| validate_static_storage_initializer!(element, scopes:) }
|
|
106
|
+
when AST::Specialization
|
|
107
|
+
if expression.callee.is_a?(AST::Identifier)
|
|
108
|
+
return if expression.callee.name == "zero"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
raise_sema_error("module variable initializer must be static-storage-safe")
|
|
112
|
+
when AST::Call
|
|
113
|
+
validate_static_storage_call_initializer!(expression, scopes:)
|
|
114
|
+
when AST::ProcExpr
|
|
115
|
+
# Proc expressions are static-storage-safe when their body only
|
|
116
|
+
# references module-level constants, functions, types, and imports.
|
|
117
|
+
# The lowering handles capture detection; if a proc truly captures
|
|
118
|
+
# a local from an enclosing scope (impossible at module level),
|
|
119
|
+
# the sema validation above already rejects it via the
|
|
120
|
+
# "cannot reference mutable value" check on the proc body.
|
|
121
|
+
return
|
|
122
|
+
else
|
|
123
|
+
raise_sema_error("module variable initializer must be static-storage-safe")
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def static_storage_member_initializer?(expression, scopes:)
|
|
128
|
+
if (type_expr = resolve_type_expression(expression.receiver))
|
|
129
|
+
return true if resolve_type_member(type_expr, expression.member)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
return false unless expression.receiver.is_a?(AST::Identifier)
|
|
133
|
+
return false unless @ctx.imports.key?(expression.receiver.name)
|
|
134
|
+
|
|
135
|
+
imported_module = @ctx.imports.fetch(expression.receiver.name)
|
|
136
|
+
if imported_module.private_value?(expression.member) || imported_module.private_function?(expression.member) || imported_module.private_type?(expression.member)
|
|
137
|
+
raise_sema_error("#{expression.receiver.name}.#{expression.member} is private to module #{imported_module.name}")
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
if (binding = imported_module.values[expression.member])
|
|
141
|
+
return true if binding.kind == :const
|
|
142
|
+
|
|
143
|
+
raise_sema_error("module variable initializer cannot reference mutable value #{expression.receiver.name}.#{expression.member}")
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
function = imported_module.functions[expression.member]
|
|
147
|
+
function && static_storage_function_value?(function)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def validate_static_storage_call_initializer!(expression, scopes:)
|
|
151
|
+
expression.arguments.each do |argument|
|
|
152
|
+
validate_static_storage_initializer!(argument.value, scopes:)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
callee = expression.callee
|
|
156
|
+
if callee.is_a?(AST::Identifier)
|
|
157
|
+
if (type_expr = resolve_type_expression(callee))
|
|
158
|
+
return if type_expr.is_a?(Types::Struct) || type_expr.is_a?(Types::StringView)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
if callee.is_a?(AST::MemberAccess)
|
|
163
|
+
if (type_expr = resolve_type_expression(callee))
|
|
164
|
+
return if type_expr.is_a?(Types::Struct) || type_expr.is_a?(Types::StringView)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
if callee.is_a?(AST::Specialization)
|
|
169
|
+
if callee.callee.is_a?(AST::Identifier)
|
|
170
|
+
case callee.callee.name
|
|
171
|
+
when "array", "span", "zero", "reinterpret"
|
|
172
|
+
return
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
if (type_ref = type_ref_from_specialization(callee))
|
|
177
|
+
specialized_type = resolve_type_ref(type_ref)
|
|
178
|
+
return if specialized_type.is_a?(Types::Struct) || result_type?(specialized_type)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
raise_sema_error("module variable initializer must be static-storage-safe")
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def static_storage_function_value?(binding)
|
|
186
|
+
!binding.external && binding.type_params.empty?
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def finalize_top_level_const_values
|
|
190
|
+
@ctx.const_declarations.each_key { |name| evaluate_top_level_const_value(name) }
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def evaluate_top_level_const_value(name)
|
|
194
|
+
return @ctx.top_level_values.fetch(name).const_value if @evaluated_const_values.key?(name)
|
|
195
|
+
|
|
196
|
+
raise_sema_error("cyclic constant value dependency involving #{name}") if @evaluating_const_values.include?(name)
|
|
197
|
+
|
|
198
|
+
decl = @ctx.const_declarations.fetch(name)
|
|
199
|
+
if decl.block_body
|
|
200
|
+
return evaluate_block_body_const(decl, name)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
if decl.value.is_a?(AST::ErrorExpr)
|
|
204
|
+
@evaluated_const_values[name] = true
|
|
205
|
+
return nil
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
@evaluating_const_values << name
|
|
209
|
+
value = evaluate_compile_time_const_value(decl.value)
|
|
210
|
+
@evaluating_const_values.pop
|
|
211
|
+
|
|
212
|
+
if value.is_a?(Integer)
|
|
213
|
+
binding_ = @ctx.top_level_values.fetch(name)
|
|
214
|
+
check_type = binding_.type
|
|
215
|
+
check_type = check_type.backing_type if check_type.respond_to?(:backing_type)
|
|
216
|
+
|
|
217
|
+
if check_type.is_a?(Types::Primitive) && check_type.integer? && (width = check_type.integer_width)
|
|
218
|
+
max_value = if check_type.signed_integer?
|
|
219
|
+
(1 << (width - 1)) - 1
|
|
220
|
+
else
|
|
221
|
+
(1 << width) - 1
|
|
222
|
+
end
|
|
223
|
+
if value > max_value
|
|
224
|
+
raise_sema_error("constant #{name} value #{value} does not fit in type #{binding_.type}")
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
set_const_value(name, value)
|
|
230
|
+
value
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def evaluate_block_body_const(decl, name)
|
|
234
|
+
@evaluating_const_values << name
|
|
235
|
+
value = evaluate_compile_time_block(decl.block_body)
|
|
236
|
+
@evaluating_const_values.pop
|
|
237
|
+
set_const_value(name, value)
|
|
238
|
+
value
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def set_const_value(name, value)
|
|
242
|
+
binding = @ctx.top_level_values.fetch(name)
|
|
243
|
+
@ctx.top_level_values[name] = ValueBinding.new(
|
|
244
|
+
id: binding.id,
|
|
245
|
+
name: binding.name,
|
|
246
|
+
storage_type: binding.storage_type,
|
|
247
|
+
flow_type: binding.flow_type,
|
|
248
|
+
mutable: binding.mutable,
|
|
249
|
+
kind: binding.kind,
|
|
250
|
+
const_value: value,
|
|
251
|
+
)
|
|
252
|
+
@evaluated_const_values[name] = true
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def evaluate_compile_time_block(statements, scopes: nil)
|
|
256
|
+
ctx = CompileTime::BlockContext.new(self)
|
|
257
|
+
result = ctx.evaluate_block(statements, scopes:)
|
|
258
|
+
result
|
|
259
|
+
rescue CompileTime::ReturnValue => e
|
|
260
|
+
e.value
|
|
261
|
+
rescue CompileTime::Error => e
|
|
262
|
+
raise_sema_error(e.message)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def evaluate_compile_time_const_value(expression, scopes: nil)
|
|
266
|
+
CompileTime.evaluate(
|
|
267
|
+
expression,
|
|
268
|
+
resolve_identifier: lambda do |identifier_expression|
|
|
269
|
+
if scopes
|
|
270
|
+
binding = lookup_value(identifier_expression.name, scopes)
|
|
271
|
+
return binding.const_value unless binding&.const_value.nil?
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
value = resolve_current_module_const_value(identifier_expression.name)
|
|
275
|
+
return value if value
|
|
276
|
+
|
|
277
|
+
# Resolve a bare type-parameter name (e.g. `T`) to its substituted
|
|
278
|
+
# concrete type so `inline if T == int` can fold at compile time.
|
|
279
|
+
current_type_params[identifier_expression.name] || @ctx.types[identifier_expression.name]
|
|
280
|
+
end,
|
|
281
|
+
resolve_member_access: lambda do |member_access_expression|
|
|
282
|
+
if member_access_expression.receiver.is_a?(AST::Identifier) && scopes
|
|
283
|
+
binding = lookup_value(member_access_expression.receiver.name, scopes)
|
|
284
|
+
if binding && binding.const_value
|
|
285
|
+
receiver_value = binding.const_value
|
|
286
|
+
case receiver_value
|
|
287
|
+
when Types::FieldHandle
|
|
288
|
+
case member_access_expression.member
|
|
289
|
+
when "name" then next receiver_value.field_name
|
|
290
|
+
when "type" then next receiver_value.struct_handle.struct_type.field(receiver_value.field_name)
|
|
291
|
+
end
|
|
292
|
+
when Types::MemberHandle
|
|
293
|
+
case member_access_expression.member
|
|
294
|
+
when "name" then next receiver_value.name
|
|
295
|
+
when "value" then next receiver_value.value
|
|
296
|
+
end
|
|
297
|
+
when Types::AttributeHandle
|
|
298
|
+
case member_access_expression.member
|
|
299
|
+
when "name" then next receiver_value.name
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
if (receiver_type = resolve_type_expression(member_access_expression.receiver))
|
|
306
|
+
next resolve_enum_member_const_value(receiver_type, member_access_expression.member)
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
next unless member_access_expression.receiver.is_a?(AST::Identifier)
|
|
310
|
+
|
|
311
|
+
resolve_imported_module_const_value(member_access_expression.receiver.name, member_access_expression.member)
|
|
312
|
+
end,
|
|
313
|
+
resolve_type_ref: lambda do |type_ref|
|
|
314
|
+
resolve_type_ref(type_ref)
|
|
315
|
+
end,
|
|
316
|
+
resolve_call: lambda do |call_expression|
|
|
317
|
+
evaluate_compile_time_call(call_expression, scopes:)
|
|
318
|
+
end,
|
|
319
|
+
)
|
|
320
|
+
rescue CompileTime::Error => e
|
|
321
|
+
raise_sema_error(e.message)
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def evaluate_compile_time_call(expression, scopes: nil)
|
|
325
|
+
case expression.callee
|
|
326
|
+
when AST::Identifier
|
|
327
|
+
case expression.callee.name
|
|
328
|
+
when "field_of"
|
|
329
|
+
evaluate_field_of_call(expression.arguments, scopes: scopes || [])
|
|
330
|
+
when "fields_of"
|
|
331
|
+
evaluate_fields_of_call(expression.arguments)
|
|
332
|
+
when "callable_of"
|
|
333
|
+
evaluate_callable_of_call(expression.arguments, scopes: scopes || [])
|
|
334
|
+
when "has_attribute"
|
|
335
|
+
evaluate_has_attribute_call(expression.arguments, scopes: scopes || [])
|
|
336
|
+
when "attribute_of"
|
|
337
|
+
evaluate_attribute_of_call(expression.arguments, scopes: scopes || [])
|
|
338
|
+
when "members_of"
|
|
339
|
+
evaluate_members_of_call(expression.arguments)
|
|
340
|
+
when "attributes_of"
|
|
341
|
+
evaluate_attributes_of_call(expression.arguments, scopes: scopes || [])
|
|
342
|
+
else
|
|
343
|
+
func = @ctx.top_level_functions[expression.callee.name]
|
|
344
|
+
if func&.ast&.respond_to?(:const) && func.ast.const
|
|
345
|
+
evaluate_const_function_body(func, expression.arguments, scopes:)
|
|
346
|
+
else
|
|
347
|
+
evaluate_type_returning_call(expression, scopes:)
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
when AST::Specialization
|
|
351
|
+
if expression.callee.callee.is_a?(AST::Identifier) && expression.callee.callee.name == "attribute_arg"
|
|
352
|
+
evaluate_attribute_arg_call(expression.arguments, scopes: scopes || [])
|
|
353
|
+
else
|
|
354
|
+
callee_name = expression.callee.callee.is_a?(AST::Identifier) ? expression.callee.callee.name : nil
|
|
355
|
+
if callee_name
|
|
356
|
+
func = @ctx.top_level_functions[callee_name]
|
|
357
|
+
if func&.ast&.respond_to?(:const) && func.ast.const
|
|
358
|
+
evaluate_const_function_body(func, expression.arguments, scopes:)
|
|
359
|
+
else
|
|
360
|
+
evaluate_type_returning_call(expression, scopes:)
|
|
361
|
+
end
|
|
362
|
+
else
|
|
363
|
+
evaluate_type_returning_call(expression, scopes:)
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
else
|
|
367
|
+
nil
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def evaluate_type_returning_call(expression, scopes:)
|
|
372
|
+
callee_name, type_args = extract_type_callee_info(expression)
|
|
373
|
+
return nil unless callee_name
|
|
374
|
+
|
|
375
|
+
CompileTime::Reflection.core_evaluate_type_returning(
|
|
376
|
+
callee_name, type_args,
|
|
377
|
+
evaluate_value: ->(v) { evaluate_compile_time_const_value(v, scopes:) },
|
|
378
|
+
resolve_type_ref: ->(tr) { resolve_type_ref(tr) },
|
|
379
|
+
pointer_to: ->(t) { pointer_to(t) },
|
|
380
|
+
const_pointer_to: ->(t) { const_pointer_to(t) },
|
|
381
|
+
top_level_functions: ->(name) { @ctx.top_level_functions[name] },
|
|
382
|
+
evaluate_type_returning_function_body: ->(func, targs) { evaluate_type_returning_function_body(func, targs) },
|
|
383
|
+
)
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
def extract_type_callee_info(expression)
|
|
387
|
+
if expression.is_a?(AST::Call) && expression.callee.is_a?(AST::Identifier)
|
|
388
|
+
[expression.callee.name, nil]
|
|
389
|
+
elsif expression.is_a?(AST::Specialization)
|
|
390
|
+
if expression.callee.is_a?(AST::Identifier)
|
|
391
|
+
[expression.callee.name, expression.arguments]
|
|
392
|
+
elsif expression.callee.is_a?(AST::Specialization) && expression.callee.callee.is_a?(AST::Identifier)
|
|
393
|
+
[expression.callee.callee.name, expression.callee.arguments]
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
def evaluate_type_returning_function_body(func, type_args)
|
|
399
|
+
value_params = func.ast.type_params.select { |p| p.is_a?(AST::ValueTypeParam) }
|
|
400
|
+
return nil if value_params.empty?
|
|
401
|
+
|
|
402
|
+
initial_vars = {}
|
|
403
|
+
value_params.zip(type_args).each do |param, arg|
|
|
404
|
+
arg_value = arg.value
|
|
405
|
+
case arg_value
|
|
406
|
+
when AST::IntegerLiteral
|
|
407
|
+
initial_vars[param.name] = arg_value.value
|
|
408
|
+
when AST::TypeRef
|
|
409
|
+
initial_vars[param.name] = resolve_type_ref(arg_value)
|
|
410
|
+
else
|
|
411
|
+
return nil
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
ctx = CompileTime::BlockContext.new(self, initial_variables: initial_vars)
|
|
416
|
+
ctx.evaluate_block(func.ast.body, scopes: nil)
|
|
417
|
+
rescue CompileTime::ReturnValue => e
|
|
418
|
+
e.value
|
|
419
|
+
rescue CompileTime::Error => e
|
|
420
|
+
raise_sema_error(e.message)
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
def evaluate_const_function_body(func, arguments, scopes:)
|
|
424
|
+
return nil unless func.ast.params.length == arguments.length
|
|
425
|
+
|
|
426
|
+
initial_vars = {}
|
|
427
|
+
func.ast.params.each_with_index do |param, idx|
|
|
428
|
+
arg_expr = arguments[idx].value
|
|
429
|
+
arg_value = if scopes
|
|
430
|
+
evaluate_compile_time_const_value(arg_expr, scopes:)
|
|
431
|
+
else
|
|
432
|
+
CompileTime.evaluate(
|
|
433
|
+
arg_expr,
|
|
434
|
+
resolve_identifier: lambda { |id| resolve_current_module_const_value(id.name) },
|
|
435
|
+
resolve_member_access: nil,
|
|
436
|
+
resolve_type_ref: lambda { |tr| resolve_type_ref(tr) },
|
|
437
|
+
resolve_call: nil,
|
|
438
|
+
)
|
|
439
|
+
end
|
|
440
|
+
return nil unless arg_value
|
|
441
|
+
|
|
442
|
+
initial_vars[param.name] = arg_value
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
ctx = CompileTime::BlockContext.new(self, initial_variables: initial_vars)
|
|
446
|
+
ctx.evaluate_block(func.ast.body, scopes: nil)
|
|
447
|
+
rescue CompileTime::ReturnValue => e
|
|
448
|
+
e.value
|
|
449
|
+
rescue CompileTime::Error => e
|
|
450
|
+
raise_sema_error(e.message)
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
def evaluate_has_attribute_call(arguments, scopes:)
|
|
454
|
+
target = evaluate_reflection_target_argument(arguments.first.value, scopes:)
|
|
455
|
+
binding = resolve_attribute_name_argument(arguments[1].value)
|
|
456
|
+
validate_attribute_target_compatibility!(target, binding)
|
|
457
|
+
!find_attribute_application(target, binding).nil?
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
def evaluate_attribute_of_call(arguments, scopes:)
|
|
461
|
+
target = evaluate_reflection_target_argument(arguments.first.value, scopes:)
|
|
462
|
+
binding = resolve_attribute_name_argument(arguments[1].value)
|
|
463
|
+
validate_attribute_target_compatibility!(target, binding)
|
|
464
|
+
|
|
465
|
+
application = find_attribute_application(target, binding)
|
|
466
|
+
return nil unless application
|
|
467
|
+
|
|
468
|
+
Types::AttributeHandle.new(
|
|
469
|
+
binding.name,
|
|
470
|
+
binding.module_name,
|
|
471
|
+
target,
|
|
472
|
+
binding.params,
|
|
473
|
+
application.argument_values,
|
|
474
|
+
)
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
def evaluate_attribute_arg_call(arguments, scopes:)
|
|
478
|
+
attribute_handle = evaluate_compile_time_const_value(arguments.first.value, scopes:)
|
|
479
|
+
return nil unless attribute_handle.is_a?(Types::AttributeHandle)
|
|
480
|
+
|
|
481
|
+
param_name = reflection_identifier_name(arguments[1].value, context: "attribute_arg")
|
|
482
|
+
return nil unless attribute_handle.argument_values
|
|
483
|
+
|
|
484
|
+
attribute_handle.argument_values[param_name]
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
def evaluate_reflection_target_argument(expression, scopes:)
|
|
488
|
+
if (type_expr = resolve_type_expression(expression))
|
|
489
|
+
handle = struct_handle_for_type(type_expr)
|
|
490
|
+
return handle if handle
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
value = evaluate_compile_time_const_value(expression, scopes:)
|
|
494
|
+
return value if value.is_a?(Types::FieldHandle) || value.is_a?(Types::CallableHandle)
|
|
495
|
+
|
|
496
|
+
nil
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
def evaluate_fields_of_call(arguments)
|
|
500
|
+
raise_sema_error("fields_of expects 1 argument") unless arguments.length == 1
|
|
501
|
+
|
|
502
|
+
type = resolve_type_expression(arguments.first.value)
|
|
503
|
+
raise_sema_error("fields_of requires a type argument") unless type
|
|
504
|
+
|
|
505
|
+
handle = struct_handle_for_type(type)
|
|
506
|
+
raise_sema_error("fields_of requires a struct type, got #{type}") unless handle
|
|
507
|
+
|
|
508
|
+
CompileTime::Reflection.core_field_handles(handle)
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
def evaluate_members_of_call(arguments)
|
|
512
|
+
raise_sema_error("members_of expects 1 argument") unless arguments.length == 1
|
|
513
|
+
|
|
514
|
+
type = resolve_type_expression(arguments.first.value)
|
|
515
|
+
raise_sema_error("members_of requires a type argument") unless type
|
|
516
|
+
|
|
517
|
+
unless type.is_a?(Types::Enum) || type.is_a?(Types::Flags)
|
|
518
|
+
raise_sema_error("members_of requires an enum or flags type, got #{type}")
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
CompileTime::Reflection.core_member_handles(type)
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
def evaluate_attributes_of_call(arguments, scopes:)
|
|
525
|
+
raise_sema_error("attributes_of expects 1 or 2 arguments") unless (1..2).include?(arguments.length)
|
|
526
|
+
|
|
527
|
+
target = evaluate_reflection_target_argument(arguments.first.value, scopes:)
|
|
528
|
+
|
|
529
|
+
if arguments.length == 2
|
|
530
|
+
attribute_binding = resolve_attribute_name_argument(arguments[1].value)
|
|
531
|
+
application = find_attribute_application(target, attribute_binding)
|
|
532
|
+
return [] unless application
|
|
533
|
+
|
|
534
|
+
[Types::AttributeHandle.new(
|
|
535
|
+
attribute_binding.name,
|
|
536
|
+
attribute_binding.module_name,
|
|
537
|
+
target,
|
|
538
|
+
attribute_binding.params,
|
|
539
|
+
application.argument_values,
|
|
540
|
+
)]
|
|
541
|
+
else
|
|
542
|
+
resolved_attribute_applications_for_target(target).map do |application|
|
|
543
|
+
Types::AttributeHandle.new(
|
|
544
|
+
application.binding.name,
|
|
545
|
+
application.binding.module_name,
|
|
546
|
+
target,
|
|
547
|
+
application.binding.params,
|
|
548
|
+
application.argument_values,
|
|
549
|
+
)
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
def evaluate_enum_member_const_value(expression, enum_type:, member_values:)
|
|
555
|
+
CompileTime.evaluate(
|
|
556
|
+
expression,
|
|
557
|
+
resolve_identifier: lambda do |identifier_expression|
|
|
558
|
+
resolve_current_module_const_value(identifier_expression.name)
|
|
559
|
+
end,
|
|
560
|
+
resolve_member_access: lambda do |member_access_expression|
|
|
561
|
+
if (receiver_type = resolve_type_expression(member_access_expression.receiver))
|
|
562
|
+
next resolve_enum_member_const_value(
|
|
563
|
+
receiver_type,
|
|
564
|
+
member_access_expression.member,
|
|
565
|
+
local_enum_type: enum_type,
|
|
566
|
+
local_member_values: member_values,
|
|
567
|
+
)
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
next unless member_access_expression.receiver.is_a?(AST::Identifier)
|
|
571
|
+
|
|
572
|
+
resolve_imported_module_const_value(member_access_expression.receiver.name, member_access_expression.member)
|
|
573
|
+
end,
|
|
574
|
+
resolve_type_ref: lambda do |type_ref|
|
|
575
|
+
resolve_type_ref(type_ref)
|
|
576
|
+
end,
|
|
577
|
+
)
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
def check_top_level_static_asserts
|
|
581
|
+
expanded_declarations.grep(AST::StaticAssert).each do |statement|
|
|
582
|
+
check_static_assert(statement, scopes: [])
|
|
583
|
+
end
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
end
|
|
587
|
+
end
|
|
588
|
+
end
|