Adding more name analysis gather.

This commit is contained in:
Jesse Brault 2025-10-03 10:43:20 -05:00
parent e879ad2d90
commit 8969186467
4 changed files with 131 additions and 18 deletions

View File

@ -5,14 +5,14 @@ use deimos::ast::build::build_ast;
use deimos::name_analysis::analyze_names; use deimos::name_analysis::analyze_names;
use deimos::name_analysis::symbol_table::SymbolTable; use deimos::name_analysis::symbol_table::SymbolTable;
use deimos::parser::{DeimosParser, Rule}; use deimos::parser::{DeimosParser, Rule};
use deimos::std_core::add_std_core_symbols;
use pest::Parser; use pest::Parser;
use std::path::PathBuf; use std::path::PathBuf;
use deimos::std_core::add_std_core_symbols;
pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Error>> { pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Error>> {
let mut compilation_units = vec![]; let mut compilation_units = vec![];
let mut files = SimpleFiles::new(); let mut files: SimpleFiles<String, String> = SimpleFiles::new();
for path in paths { for path in paths {
let src = std::fs::read_to_string(path).unwrap(); let src = std::fs::read_to_string(path).unwrap();
let parse_result = DeimosParser::parse(Rule::CompilationUnit, &src); let parse_result = DeimosParser::parse(Rule::CompilationUnit, &src);
@ -30,14 +30,11 @@ pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Err
let mut symbol_table = SymbolTable::new(); let mut symbol_table = SymbolTable::new();
add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols."); add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols.");
let diagnostics = analyze_names( let diagnostics = analyze_names(compilation_units.as_mut_slice(), &files, &mut symbol_table);
compilation_units.as_mut_slice(),
&mut symbol_table
);
if diagnostics.is_empty() { if diagnostics.is_empty() {
println!("Name analysis complete."); println!("Name analysis complete.");
println!("Symbol table\n-------\n{}", symbol_table); println!("{}", symbol_table);
} else { } else {
let writer = StandardStream::stderr(ColorChoice::Always); let writer = StandardStream::stderr(ColorChoice::Always);
let config = term::Config::default(); let config = term::Config::default();
@ -45,6 +42,6 @@ pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Err
term::emit(&mut writer.lock(), &config, &files, &diagnostic)?; term::emit(&mut writer.lock(), &config, &files, &diagnostic)?;
} }
} }
Ok(()) Ok(())
} }

View File

@ -1,8 +1,13 @@
use crate::ast::ast_node::{AstNode, AstNodeRef}; use crate::ast::ast_node::{AstNode, AstNodeRef};
use crate::ast::node::{CompilationUnit, Identifier, UseStatement, UseStatementSuffix}; use crate::ast::node::{
CompilationUnit, Function, FunctionBlockBody, FunctionBody, Identifier, Statement,
UseStatement, UseStatementSuffix, VariableDeclaration,
};
use crate::diagnostic::DmDiagnostic; use crate::diagnostic::DmDiagnostic;
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
use crate::name_analysis::symbol::source_definition::SourceDefinition; use crate::name_analysis::symbol::source_definition::SourceDefinition;
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol}; use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
use crate::name_analysis::symbol::variable_symbol::VariableSymbol;
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable}; use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
use codespan_reporting::diagnostic::{Diagnostic, Label}; use codespan_reporting::diagnostic::{Diagnostic, Label};
use std::collections::HashMap; use std::collections::HashMap;
@ -48,7 +53,12 @@ fn gather_identifier(
identifier_scope_ids.insert(identifier.clone(), symbol_table.current_scope_id()); identifier_scope_ids.insert(identifier.clone(), symbol_table.current_scope_id());
} }
fn gather_concrete_use_symbol(base_fqn: &str, identifier: &Identifier, symbol_table: &mut SymbolTable, diagnostics: &mut Vec<DmDiagnostic>) { fn gather_concrete_use_symbol(
base_fqn: &str,
identifier: &Identifier,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let symbol = ConcreteUseSymbol::new( let symbol = ConcreteUseSymbol::new(
base_fqn, base_fqn,
identifier.name(), identifier.name(),
@ -106,6 +116,76 @@ fn gather_use_statement(
} }
} }
fn gather_function(
function: &Function,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let function_symbol = FunctionSymbol::without_parameters_or_return_type(
"",
function.identifier().name(),
function.is_public(),
false,
Some(SourceDefinition::from_identifier(function.identifier())),
);
if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) {
handle_insert_error(
insert_error,
function.identifier().name(),
function.identifier().file_id(),
function.identifier().range(),
"Function",
diagnostics,
);
}
gather_node(
AstNodeRef::FunctionBody(function.function_body()),
symbol_table,
diagnostics,
);
}
fn gather_function_block_body(
function_block_body: &FunctionBlockBody,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
symbol_table.push_scope("FunctionBlockBody");
gather_node_children(function_block_body, symbol_table, diagnostics);
symbol_table.pop_scope();
}
fn gather_variable_declaration(
variable_declaration: &VariableDeclaration,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let variable_symbol = VariableSymbol::new(
variable_declaration.identifier().name(),
variable_declaration.is_mut(),
Some(SourceDefinition::from_identifier(
variable_declaration.identifier(),
)),
);
if let Err(insert_error) = symbol_table.insert_variable_symbol(variable_symbol) {
handle_insert_error(
insert_error,
variable_declaration.identifier().name(),
variable_declaration.identifier().file_id(),
variable_declaration.identifier().range(),
"Variable",
diagnostics,
);
}
if let Some(expression) = variable_declaration.expression() {
gather_node(
AstNodeRef::Expression(expression),
symbol_table,
diagnostics,
);
}
}
fn gather_node_children( fn gather_node_children(
node: &impl AstNode, node: &impl AstNode,
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
@ -151,27 +231,53 @@ fn gather_node(
AstNodeRef::UseStatementPrefix(_) => {} AstNodeRef::UseStatementPrefix(_) => {}
AstNodeRef::UseStatementSuffix(_) => {} AstNodeRef::UseStatementSuffix(_) => {}
AstNodeRef::UseList(_) => {} AstNodeRef::UseList(_) => {}
AstNodeRef::ModuleLevelDeclaration(_) => {} AstNodeRef::ModuleLevelDeclaration(module_level_declaration) => {
gather_node_children(module_level_declaration, symbol_table, diagnostics);
}
AstNodeRef::InterfaceLevelDeclaration(_) => {} AstNodeRef::InterfaceLevelDeclaration(_) => {}
AstNodeRef::ClassLevelDeclaration(_) => {} AstNodeRef::ClassLevelDeclaration(_) => {}
AstNodeRef::Module(_) => {} AstNodeRef::Module(_) => {}
AstNodeRef::CompanionModule(_) => {} AstNodeRef::CompanionModule(_) => {}
AstNodeRef::Interface(_) => {} AstNodeRef::Interface(_) => {}
AstNodeRef::Class(_) => {} AstNodeRef::Class(_) => {}
AstNodeRef::Function(_) => {} AstNodeRef::Function(function) => {
gather_function(function, symbol_table, diagnostics);
}
AstNodeRef::OperatorFunction(_) => {} AstNodeRef::OperatorFunction(_) => {}
AstNodeRef::PlatformFunction(_) => {} AstNodeRef::PlatformFunction(_) => {}
AstNodeRef::InterfaceFunction(_) => {} AstNodeRef::InterfaceFunction(_) => {}
AstNodeRef::InterfaceDefaultFunction(_) => {} AstNodeRef::InterfaceDefaultFunction(_) => {}
AstNodeRef::InterfaceOperatorFunction(_) => {} AstNodeRef::InterfaceOperatorFunction(_) => {}
AstNodeRef::InterfaceDefaultOperatorFunction(_) => {} AstNodeRef::InterfaceDefaultOperatorFunction(_) => {}
AstNodeRef::FunctionBody(_) => {} AstNodeRef::FunctionBody(function_body) => match function_body {
FunctionBody::FunctionAliasBody(alias_body) => {
gather_node(alias_body.as_node_ref(), symbol_table, diagnostics);
}
FunctionBody::FunctionEqualsBody(equals_body) => {
gather_node(equals_body.as_node_ref(), symbol_table, diagnostics);
}
FunctionBody::FunctionBlockBody(block_body) => {
gather_node(block_body.as_node_ref(), symbol_table, diagnostics);
}
},
AstNodeRef::FunctionEqualsBody(_) => {} AstNodeRef::FunctionEqualsBody(_) => {}
AstNodeRef::FunctionAliasBody(_) => {} AstNodeRef::FunctionAliasBody(_) => {}
AstNodeRef::FunctionBlockBody(_) => {} AstNodeRef::FunctionBlockBody(block_body) => {
gather_function_block_body(block_body, symbol_table, diagnostics);
}
AstNodeRef::ClassConstructor(_) => {} AstNodeRef::ClassConstructor(_) => {}
AstNodeRef::Member(_) => {} AstNodeRef::Member(_) => {}
AstNodeRef::Statement(_) => {} AstNodeRef::Statement(statement) => match statement {
Statement::VariableDeclaration(variable_declaration) => {
gather_variable_declaration(variable_declaration, symbol_table, diagnostics);
}
Statement::AssignmentStatement(_) => {}
Statement::ExpressionStatement(_) => {}
Statement::UseStatement(_) => {}
Statement::IfStatement(_) => {}
Statement::WhileStatement(_) => {}
Statement::ForStatement(_) => {}
},
AstNodeRef::VariableDeclaration(_) => {} AstNodeRef::VariableDeclaration(_) => {}
AstNodeRef::AssignmentStatement(_) => {} AstNodeRef::AssignmentStatement(_) => {}
AstNodeRef::ExpressionStatement(_) => {} AstNodeRef::ExpressionStatement(_) => {}
@ -224,9 +330,12 @@ fn gather_node(
pub fn gather_compilation_unit( pub fn gather_compilation_unit(
compilation_unit: &mut CompilationUnit, compilation_unit: &mut CompilationUnit,
file_name: &str,
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
identifier_scope_ids: &mut HashMap<Identifier, usize>, identifier_scope_ids: &mut HashMap<Identifier, usize>,
diagnostics: &mut Vec<DmDiagnostic>, diagnostics: &mut Vec<DmDiagnostic>,
) { ) {
symbol_table.push_scope(&format!("FileScope {}", file_name));
gather_node(compilation_unit.as_node_ref(), symbol_table, diagnostics); gather_node(compilation_unit.as_node_ref(), symbol_table, diagnostics);
symbol_table.pop_scope();
} }

View File

@ -24,6 +24,7 @@ use crate::diagnostic::DmDiagnostic;
use crate::name_analysis::gather::gather_compilation_unit; use crate::name_analysis::gather::gather_compilation_unit;
// use crate::name_analysis::resolve::resolve_compilation_unit; // use crate::name_analysis::resolve::resolve_compilation_unit;
use crate::name_analysis::symbol_table::SymbolTable; use crate::name_analysis::symbol_table::SymbolTable;
use codespan_reporting::files::Files;
use std::collections::HashMap; use std::collections::HashMap;
mod fqn_context; mod fqn_context;
@ -32,8 +33,9 @@ mod gather;
pub mod symbol; pub mod symbol;
pub mod symbol_table; pub mod symbol_table;
pub fn analyze_names( pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>(
compilation_units: &mut [Box<CompilationUnit>], compilation_units: &mut [Box<CompilationUnit>],
files: &'a F,
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
) -> Vec<DmDiagnostic> { ) -> Vec<DmDiagnostic> {
let mut diagnostics = vec![]; let mut diagnostics = vec![];
@ -41,8 +43,10 @@ pub fn analyze_names(
// gather symbols // gather symbols
for compilation_unit in compilation_units.iter_mut() { for compilation_unit in compilation_units.iter_mut() {
let file_name = files.name(compilation_unit.file_id()).unwrap();
gather_compilation_unit( gather_compilation_unit(
compilation_unit, compilation_unit,
&file_name,
symbol_table, symbol_table,
&mut identifier_scope_ids, &mut identifier_scope_ids,
&mut diagnostics, &mut diagnostics,

View File

@ -193,6 +193,9 @@ CompilationUnit:
- eoi: - eoi:
skip: skip:
rule: EOI rule: EOI
- file_id:
special:
kind: file_id
ParentMod: ParentMod:
struct: struct:
children: children: