rue_compiler/compile/item/
constant.rs1use log::debug;
2use rue_ast::{AstConstantItem, AstNode};
3use rue_diagnostic::DiagnosticKind;
4use rue_hir::{ConstantSymbol, Declaration, Symbol, SymbolId, Value};
5
6use crate::{Compiler, CompletionContext, SyntaxItem, SyntaxItemKind, compile_expr, compile_type};
7
8pub fn declare_constant(ctx: &mut Compiler, constant: &AstConstantItem) -> SymbolId {
9 ctx.syntax_map_mut().add_item(SyntaxItem::new(
10 SyntaxItemKind::CompletionContext(CompletionContext::Item),
11 constant.syntax().text_range(),
12 ));
13
14 let symbol = ctx.alloc_symbol(Symbol::Unresolved);
15
16 ctx.push_declaration(Declaration::Symbol(symbol));
17
18 let ty = if let Some(ty) = constant.ty() {
19 compile_type(ctx, &ty)
20 } else {
21 debug!("Unresolved constant type");
22 ctx.builtins().unresolved.ty
23 };
24
25 let value = ctx.builtins().unresolved.hir;
26
27 *ctx.symbol_mut(symbol) = Symbol::Constant(ConstantSymbol {
28 name: constant.name(),
29 value: Value::new(value, ty),
30 inline: constant.inline().is_some(),
31 });
32
33 if let Some(name) = constant.name() {
34 if ctx.last_scope().symbol(name.text()).is_some() {
35 ctx.diagnostic(
36 &name,
37 DiagnosticKind::DuplicateSymbol(name.text().to_string()),
38 );
39 } else {
40 ctx.last_scope_mut().insert_symbol(
41 name.text().to_string(),
42 symbol,
43 constant.export().is_some(),
44 );
45 }
46
47 ctx.declaration_span(Declaration::Symbol(symbol), name.text_range());
48 }
49
50 ctx.pop_declaration();
51
52 symbol
53}
54
55pub fn compile_constant(ctx: &mut Compiler, constant: &AstConstantItem, symbol: SymbolId) {
56 ctx.push_declaration(Declaration::Symbol(symbol));
57
58 let ty = if let Symbol::Constant(ConstantSymbol { value, .. }) = ctx.symbol(symbol) {
59 value.ty
60 } else {
61 unreachable!();
62 };
63
64 let resolved_value = if let Some(expr) = constant.value() {
65 let value = compile_expr(ctx, &expr, Some(ty));
66 ctx.assign_type(expr.syntax(), value.ty, ty);
67 value
68 } else {
69 debug!("Unresolved constant value");
70 ctx.builtins().unresolved.clone()
71 };
72
73 let Symbol::Constant(ConstantSymbol { value, .. }) = ctx.symbol_mut(symbol) else {
74 unreachable!();
75 };
76
77 *value = resolved_value.with_type(ty);
78
79 ctx.pop_declaration();
80}