deimos-lang/dmc-lib/src/ast/parameter.rs

94 lines
2.9 KiB
Rust

use crate::ast::type_use::TypeUse;
use crate::diagnostic::Diagnostic;
use crate::source_range::SourceRange;
use crate::symbol::class_symbol::ClassSymbol;
use crate::symbol::parameter_symbol::ParameterSymbol;
use crate::symbol_table::{SymbolInsertError, SymbolTable};
use std::cell::RefCell;
use std::rc::Rc;
pub struct Parameter {
declared_name: Rc<str>,
declared_name_source_range: SourceRange,
type_use: TypeUse,
parameter_symbol: Option<Rc<RefCell<ParameterSymbol>>>,
}
impl Parameter {
pub fn new(
declared_name: &str,
declared_name_source_range: SourceRange,
type_use: TypeUse,
) -> Self {
Self {
declared_name: declared_name.into(),
declared_name_source_range,
type_use,
parameter_symbol: None,
}
}
pub fn gather_declared_names(
&mut self,
symbol_table: &mut SymbolTable,
) -> Result<Rc<RefCell<ParameterSymbol>>, Vec<Diagnostic>> {
// insert parameter symbol
let insert_result = symbol_table.insert_parameter_symbol(ParameterSymbol::new(
&self.declared_name,
self.declared_name_source_range.clone(),
));
match insert_result {
Ok(parameter_symbol) => {
self.parameter_symbol = Some(parameter_symbol.clone());
}
Err(symbol_insert_error) => {
return match symbol_insert_error {
SymbolInsertError::AlreadyDeclared(already_declared) => {
Err(vec![Diagnostic::new(
&format!(
"Parameter {} already declared.",
already_declared.symbol().borrow().declared_name()
),
self.declared_name_source_range.start(),
self.declared_name_source_range.end(),
)])
}
};
}
}
// type use
self.type_use.gather_declared_names(symbol_table)?;
Ok(self.parameter_symbol.clone().unwrap())
}
pub fn check_name_usages(
&mut self,
symbol_table: &SymbolTable,
class_context: Option<&Rc<RefCell<ClassSymbol>>>,
) -> Result<(), Vec<Diagnostic>> {
// check the type use
self.type_use
.check_name_usages(symbol_table, class_context)?;
// set type on parameter symbol
self.parameter_symbol
.as_mut()
.unwrap()
.borrow_mut()
.set_type_info(self.type_use.type_info().clone());
Ok(())
}
pub fn type_check(&mut self, _symbol_table: &SymbolTable) -> Result<(), Vec<Diagnostic>> {
Ok(()) // no-op for now
}
pub fn parameter_symbol(&self) -> &Rc<RefCell<ParameterSymbol>> {
self.parameter_symbol
.as_ref()
.expect("parameter symbol not initialized")
}
}