Compare commits
5 Commits
5721bd1e83
...
13330300c1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13330300c1 | ||
|
|
12a3a61156 | ||
|
|
9b83a531ca | ||
|
|
e5c5be6d95 | ||
|
|
d653d26e14 |
@ -116,8 +116,7 @@ fn generate_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
|
|||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use crate::name_analysis::symbol::type_symbol::*;
|
use crate::name_analysis::symbol::*;
|
||||||
use crate::name_analysis::symbol::use_symbol::*;
|
|
||||||
|
|
||||||
#(#types)*
|
#(#types)*
|
||||||
};
|
};
|
||||||
|
|||||||
@ -79,9 +79,9 @@ pub mod build {
|
|||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/src/ast/build.rs"));
|
include!(concat!(env!("OUT_DIR"), "/src/ast/build.rs"));
|
||||||
|
|
||||||
pub fn build_ast(file_id: usize, parsed_pairs: &mut Pairs<Rule>) -> Box<CompilationUnit> {
|
pub fn build_ast(file_id: usize, parsed_pairs: &mut Pairs<Rule>) -> CompilationUnit {
|
||||||
let compilation_unit_pair = parsed_pairs.next().unwrap();
|
let compilation_unit_pair = parsed_pairs.next().unwrap();
|
||||||
Box::new(build_compilation_unit(file_id, compilation_unit_pair))
|
build_compilation_unit(file_id, compilation_unit_pair)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -174,22 +174,6 @@ pub mod pretty_print {
|
|||||||
|
|
||||||
pub mod ast_node {
|
pub mod ast_node {
|
||||||
include!(concat!(env!("OUT_DIR"), "/src/ast/ast_node.rs"));
|
include!(concat!(env!("OUT_DIR"), "/src/ast/ast_node.rs"));
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::ast::ast_node::AstNode;
|
|
||||||
use crate::ast::node::CompilationUnit;
|
|
||||||
|
|
||||||
fn get_cu() -> CompilationUnit {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn simple() {
|
|
||||||
let cu = get_cu();
|
|
||||||
for child in cu.children() {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod walk {
|
pub mod walk {
|
||||||
|
|||||||
@ -3,40 +3,69 @@ use codespan_reporting::term;
|
|||||||
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
||||||
use deimos::ast::build::build_ast;
|
use deimos::ast::build::build_ast;
|
||||||
use deimos::name_analysis::analyze_names;
|
use deimos::name_analysis::analyze_names;
|
||||||
use deimos::name_analysis::symbol_table::symbol_tree::SymbolTree;
|
|
||||||
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 deimos::std_core::add_std_core_symbols;
|
||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Error>> {
|
struct ParseErrors {
|
||||||
let mut compilation_units = vec![];
|
errors: Vec<pest::error::Error<Rule>>,
|
||||||
let mut files: SimpleFiles<String, String> = SimpleFiles::new();
|
}
|
||||||
|
|
||||||
|
impl Debug for ParseErrors {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
Display::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for ParseErrors {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
writeln!(f, "There were errors during parsing.")?;
|
||||||
|
for parse_error in &self.errors {
|
||||||
|
writeln!(f, "{}", parse_error)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for ParseErrors {}
|
||||||
|
|
||||||
|
pub fn name_analysis(paths: &[PathBuf]) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut paths_and_sources: HashMap<String, String> = HashMap::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);
|
paths_and_sources.insert(path.display().to_string(), src);
|
||||||
let file_id = files.add(path.display().to_string(), src.clone()); // I don't love this clone
|
}
|
||||||
|
|
||||||
|
let mut compilation_units = vec![];
|
||||||
|
let mut files: SimpleFiles<&str, &str> = SimpleFiles::new();
|
||||||
|
let mut parse_errors = vec![];
|
||||||
|
|
||||||
|
for (path, source) in &paths_and_sources {
|
||||||
|
let parse_result = DeimosParser::parse(Rule::CompilationUnit, source);
|
||||||
match parse_result {
|
match parse_result {
|
||||||
Ok(mut pairs) => {
|
Ok(mut pairs) => {
|
||||||
|
let file_id = files.add(path, source);
|
||||||
let compilation_unit = build_ast(file_id, &mut pairs);
|
let compilation_unit = build_ast(file_id, &mut pairs);
|
||||||
compilation_units.push(compilation_unit);
|
compilation_units.push(compilation_unit);
|
||||||
Ok::<(), Box<dyn std::error::Error>>(())
|
|
||||||
}
|
}
|
||||||
Err(e) => Err(e.into()),
|
Err(error) => {
|
||||||
}?;
|
parse_errors.push(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !parse_errors.is_empty() {
|
||||||
|
return Err(Box::new(ParseErrors { errors: parse_errors }));
|
||||||
}
|
}
|
||||||
|
|
||||||
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(&mut compilation_units, &files, &mut symbol_table);
|
||||||
&mut compilation_units,
|
|
||||||
&files,
|
|
||||||
&mut symbol_table,
|
|
||||||
);
|
|
||||||
if diagnostics.is_empty() {
|
if diagnostics.is_empty() {
|
||||||
println!("Name analysis complete.");
|
println!("Name analysis complete.");
|
||||||
println!("{}", symbol_table);
|
println!("{}", symbol_table);
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
use crate::ast::node::{
|
use crate::ast::node::{
|
||||||
CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody,
|
CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody,
|
||||||
GenericParameters, Identifier, IdentifierOrFqn, Module, ModuleLevelDeclaration, Parameters,
|
GenericParameters, Identifier, IdentifierOrFqn, Module, ModuleLevelDeclaration, Parameter,
|
||||||
PrimitiveType, ReturnType, TypeUse, TypedArray, UseStatement, UseStatementIdentifier,
|
Parameters, PrimitiveType, ReturnType, StarUseStatement, TypeUse, TypedArray, UseStatement,
|
||||||
UseStatementPrefix,
|
UseStatementIdentifier, UseStatementPrefix,
|
||||||
};
|
};
|
||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
@ -13,10 +13,13 @@ use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
|||||||
use crate::name_analysis::symbol::primitive_type_symbol::PrimitiveTypeSymbol;
|
use crate::name_analysis::symbol::primitive_type_symbol::PrimitiveTypeSymbol;
|
||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
||||||
use crate::name_analysis::symbol::use_symbol::ConcreteUseSymbol;
|
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
||||||
use crate::name_analysis::symbol_table::SymbolTable;
|
use crate::name_analysis::symbol_table::SymbolTable;
|
||||||
use crate::name_analysis::util::{format_fqn, handle_insert_error, handle_lookup_error};
|
use crate::name_analysis::util::{
|
||||||
|
format_fqn, handle_insert_error, handle_lookup_error, join_fqn_parts,
|
||||||
|
};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::fmt::format;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub fn na_p1_compilation_unit(
|
pub fn na_p1_compilation_unit(
|
||||||
@ -60,7 +63,7 @@ fn na_p1_use_statement(
|
|||||||
na_p1_concrete_use_statement(concrete_use_statement, symbol_table, diagnostics);
|
na_p1_concrete_use_statement(concrete_use_statement, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
UseStatement::StarUseStatement(star_use_statement) => {
|
UseStatement::StarUseStatement(star_use_statement) => {
|
||||||
todo!()
|
na_p1_star_use_statement(star_use_statement, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,7 +103,7 @@ fn na_p1_concrete_use_statement(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_concrete_use_statement_identifier(
|
fn handle_concrete_use_statement_identifier(
|
||||||
prefixes: &Vec<Rc<str>>,
|
prefixes: &[Rc<str>],
|
||||||
use_statement_identifier: &mut UseStatementIdentifier,
|
use_statement_identifier: &mut UseStatementIdentifier,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
@ -134,6 +137,40 @@ fn handle_concrete_use_statement_identifier(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn na_p1_star_use_statement(
|
||||||
|
star_use_statement: &mut StarUseStatement,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let fqn_parts = star_use_statement
|
||||||
|
.prefixes()
|
||||||
|
.map(UseStatementPrefix::identifier)
|
||||||
|
.map(Identifier::name)
|
||||||
|
.map(|name| Rc::from(name))
|
||||||
|
.collect::<Vec<Rc<str>>>();
|
||||||
|
|
||||||
|
let to_insert = StarUseSymbol::new(
|
||||||
|
&fqn_parts,
|
||||||
|
Some(SourceDefinition::from_star_use_statement(
|
||||||
|
star_use_statement,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
match symbol_table.insert_star_use_symbol(to_insert) {
|
||||||
|
Ok(star_use_symbol) => {
|
||||||
|
star_use_statement.set_symbol(star_use_symbol);
|
||||||
|
}
|
||||||
|
Err(symbol_insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
symbol_insert_error,
|
||||||
|
&join_fqn_parts(&fqn_parts),
|
||||||
|
star_use_statement.file_id(),
|
||||||
|
star_use_statement.range(),
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn na_p1_module_level_declaration(
|
fn na_p1_module_level_declaration(
|
||||||
module_level_declaration: &mut ModuleLevelDeclaration,
|
module_level_declaration: &mut ModuleLevelDeclaration,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -207,8 +244,6 @@ fn na_p1_function(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) -> Option<Rc<RefCell<FunctionSymbol>>> {
|
) -> Option<Rc<RefCell<FunctionSymbol>>> {
|
||||||
symbol_table.push_scope(&format!("FunctionScope {}", function.identifier().name()));
|
|
||||||
|
|
||||||
let to_insert = FunctionSymbol::new(
|
let to_insert = FunctionSymbol::new(
|
||||||
&symbol_table.resolve_fqn(Rc::from(function.identifier().name())),
|
&symbol_table.resolve_fqn(Rc::from(function.identifier().name())),
|
||||||
function.is_public(),
|
function.is_public(),
|
||||||
@ -216,28 +251,7 @@ fn na_p1_function(
|
|||||||
Some(SourceDefinition::from_identifier(function.identifier())),
|
Some(SourceDefinition::from_identifier(function.identifier())),
|
||||||
);
|
);
|
||||||
let function_symbol = match symbol_table.insert_function_symbol(to_insert) {
|
let function_symbol = match symbol_table.insert_function_symbol(to_insert) {
|
||||||
Ok(function_symbol) => {
|
Ok(function_symbol) => Some(function_symbol),
|
||||||
{
|
|
||||||
let mut as_ref_mut = function_symbol.borrow_mut();
|
|
||||||
// generics
|
|
||||||
na_p1_generic_parameters(function.generics_mut(), symbol_table, diagnostics);
|
|
||||||
|
|
||||||
// parameters
|
|
||||||
as_ref_mut.set_parameter_symbols(na_p1_parameters(
|
|
||||||
function.parameters_mut(),
|
|
||||||
symbol_table,
|
|
||||||
diagnostics,
|
|
||||||
));
|
|
||||||
|
|
||||||
// return type
|
|
||||||
let return_type =
|
|
||||||
na_p1_return_type(function.return_type_mut(), symbol_table, diagnostics);
|
|
||||||
if let Some(type_symbol) = return_type {
|
|
||||||
as_ref_mut.set_return_type(type_symbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(function_symbol)
|
|
||||||
}
|
|
||||||
Err(symbol_insert_error) => {
|
Err(symbol_insert_error) => {
|
||||||
handle_insert_error(
|
handle_insert_error(
|
||||||
symbol_insert_error,
|
symbol_insert_error,
|
||||||
@ -250,7 +264,42 @@ fn na_p1_function(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
symbol_table.pop_scope();
|
if function_symbol.is_some() {
|
||||||
|
let mut as_ref_mut = function_symbol.as_ref().unwrap().borrow_mut();
|
||||||
|
|
||||||
|
// push a scope for this function
|
||||||
|
symbol_table.push_scope(&format!("FunctionScope {}", function.identifier().name()));
|
||||||
|
|
||||||
|
// generics
|
||||||
|
na_p1_generic_parameters(function.generics_mut(), symbol_table, diagnostics);
|
||||||
|
|
||||||
|
// parameters
|
||||||
|
as_ref_mut.set_parameter_symbols(na_p1_parameters(
|
||||||
|
function.parameters_mut(),
|
||||||
|
symbol_table,
|
||||||
|
diagnostics,
|
||||||
|
));
|
||||||
|
|
||||||
|
// return type
|
||||||
|
let return_type = na_p1_return_type(function.return_type_mut(), symbol_table, diagnostics);
|
||||||
|
if let Some(type_symbol) = return_type {
|
||||||
|
as_ref_mut.set_return_type(type_symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_table.push_scope(&format!(
|
||||||
|
"FunctionBodyScope {}",
|
||||||
|
function.identifier().name()
|
||||||
|
));
|
||||||
|
|
||||||
|
na_p1_function_body(
|
||||||
|
function.function_body_mut(),
|
||||||
|
symbol_table,
|
||||||
|
diagnostics
|
||||||
|
);
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
}
|
||||||
|
|
||||||
function_symbol
|
function_symbol
|
||||||
}
|
}
|
||||||
@ -260,7 +309,38 @@ fn na_p1_parameters(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) -> Vec<Rc<RefCell<ParameterSymbol>>> {
|
) -> Vec<Rc<RefCell<ParameterSymbol>>> {
|
||||||
todo!()
|
parameters
|
||||||
|
.parameters_mut()
|
||||||
|
.map(|parameter| na_p1_parameter(parameter, symbol_table, diagnostics))
|
||||||
|
.filter(Option::is_some)
|
||||||
|
.map(Option::unwrap)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p1_parameter(
|
||||||
|
parameter: &mut Parameter,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) -> Option<Rc<RefCell<ParameterSymbol>>> {
|
||||||
|
let parameter_type_symbol = na_p1_type_use(parameter.type_use_mut(), symbol_table, diagnostics);
|
||||||
|
let to_insert = ParameterSymbol::new(
|
||||||
|
parameter.identifier().name(),
|
||||||
|
Some(SourceDefinition::from_identifier(parameter.identifier())),
|
||||||
|
parameter_type_symbol,
|
||||||
|
);
|
||||||
|
match symbol_table.insert_parameter_symbol(to_insert) {
|
||||||
|
Ok(parameter_symbol) => Some(parameter_symbol),
|
||||||
|
Err(symbol_insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
symbol_insert_error,
|
||||||
|
parameter.identifier().name(),
|
||||||
|
parameter.identifier().file_id(),
|
||||||
|
parameter.identifier().range(),
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn na_p1_return_type(
|
fn na_p1_return_type(
|
||||||
@ -394,5 +474,22 @@ fn na_p1_function_body(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
match function_body {
|
||||||
|
FunctionBody::FunctionAliasBody(alias_body) => {
|
||||||
|
// set scope id for pass 2; see below
|
||||||
|
alias_body.set_scope_id(symbol_table.current_scope_id());
|
||||||
|
}
|
||||||
|
FunctionBody::FunctionEqualsBody(equals_body) => {
|
||||||
|
// see below
|
||||||
|
equals_body.set_scope_id(symbol_table.current_scope_id());
|
||||||
|
}
|
||||||
|
FunctionBody::FunctionBlockBody(block_body) => {
|
||||||
|
// we need to do all insertion/resolution in pass 2, because we
|
||||||
|
// might call functions/use classes/etc from the same compilation
|
||||||
|
// unit which haven't been defined yet. So the strategy is to set
|
||||||
|
// the scope id for the body and then in pass 2, set the symbol
|
||||||
|
// table's current scope to that id.
|
||||||
|
block_body.set_scope_id(symbol_table.current_scope_id());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,8 +36,11 @@ pub mod symbol;
|
|||||||
pub mod symbol_table;
|
pub mod symbol_table;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>(
|
pub fn analyze_names<
|
||||||
compilation_units: &mut Vec<Box<CompilationUnit>>,
|
'a,
|
||||||
|
F: Files<'a, FileId = usize, Name = &'a str, Source = &'a str> + ?Sized,
|
||||||
|
>(
|
||||||
|
compilation_units: &mut Vec<CompilationUnit>,
|
||||||
files: &'a F,
|
files: &'a F,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
) -> Vec<DmDiagnostic> {
|
) -> Vec<DmDiagnostic> {
|
||||||
@ -46,7 +49,11 @@ pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>(
|
|||||||
// 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();
|
let file_name = files.name(compilation_unit.file_id()).unwrap();
|
||||||
na_p1_compilation_unit(&file_name, compilation_unit, symbol_table, &mut diagnostics);
|
na_p1_compilation_unit(file_name, compilation_unit, symbol_table, &mut diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !diagnostics.is_empty() {
|
||||||
|
return diagnostics;
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve symbols
|
// resolve symbols
|
||||||
@ -54,221 +61,160 @@ pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>(
|
|||||||
na_p2_compilation_unit(compilation_unit, symbol_table, &mut diagnostics);
|
na_p2_compilation_unit(compilation_unit, symbol_table, &mut diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
diagnostics.into()
|
diagnostics
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[cfg(test)]
|
#[cfg(test)]
|
||||||
// mod tests {
|
mod tests {
|
||||||
// use super::*;
|
use super::*;
|
||||||
// use crate::ast::build::build_ast;
|
use crate::ast::build::build_ast;
|
||||||
// use crate::ast::children::NodeRef;
|
use crate::parser::{DeimosParser, Rule};
|
||||||
// use crate::ast::walk::walk_depth_first;
|
use crate::std_core::add_std_core_symbols;
|
||||||
// use crate::parser::{DeimosParser, Rule};
|
use codespan_reporting::files::SimpleFiles;
|
||||||
// use crate::std_core::add_std_core_symbols;
|
use codespan_reporting::term;
|
||||||
// use codespan_reporting::files::SimpleFiles;
|
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
||||||
// use codespan_reporting::term;
|
use pest::Parser;
|
||||||
// use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
use std::collections::HashMap;
|
||||||
// use indoc::indoc;
|
use std::rc::Rc;
|
||||||
// use pest::Parser;
|
use crate::name_analysis::symbol::use_symbol::StarUseSymbol;
|
||||||
// use std::collections::HashMap;
|
|
||||||
//
|
fn parse_compilation_units<'a>(
|
||||||
// fn assert_number_of_diagnostics(
|
files: &mut SimpleFiles<&'a str, &'a str>,
|
||||||
// sources: HashMap<&str, &str>,
|
sources: HashMap<&'a str, &'a str>,
|
||||||
// symbol_table: &mut SymbolTable,
|
) -> Vec<CompilationUnit> {
|
||||||
// n_diagnostics: usize,
|
let mut compilation_units: Vec<CompilationUnit> = vec![];
|
||||||
// ) -> Vec<CompilationUnit> {
|
|
||||||
// let mut files = SimpleFiles::new();
|
for (file_name, source) in sources {
|
||||||
// let mut compilation_units = vec![];
|
let parse_result = DeimosParser::parse(Rule::CompilationUnit, source);
|
||||||
//
|
if let Err(err) = &parse_result {
|
||||||
// for (file_name, source) in sources {
|
panic!("{}", err);
|
||||||
// let file_id = files.add(file_name, source);
|
}
|
||||||
// let parse_result = DeimosParser::parse(Rule::CompilationUnit, source);
|
let mut pairs = parse_result.unwrap();
|
||||||
// if let Err(err) = &parse_result {
|
if pairs.as_str().trim() != source.trim() {
|
||||||
// panic!("{}", err);
|
panic!("Parsing did not consume entire input.");
|
||||||
// }
|
}
|
||||||
// let mut pairs = parse_result.unwrap();
|
let file_id = files.add(file_name, source);
|
||||||
// if pairs.as_str().trim() != source.trim() {
|
compilation_units.push(build_ast(file_id, &mut pairs));
|
||||||
// panic!("Parsing did not consume entire input.");
|
}
|
||||||
// }
|
|
||||||
//
|
compilation_units
|
||||||
// compilation_units.push(build_ast(file_name, file_id, pairs.next().unwrap()));
|
}
|
||||||
// }
|
|
||||||
//
|
fn assert_number_of_diagnostics<'a>(
|
||||||
// let diagnostics = analyze_names(&mut compilation_units, symbol_table);
|
sources: HashMap<&'a str, &'a str>,
|
||||||
//
|
symbol_table: &mut SymbolTable,
|
||||||
// if diagnostics.len() != n_diagnostics {
|
number_of_diagnostics: usize,
|
||||||
// let writer = StandardStream::stderr(ColorChoice::Always);
|
) -> Vec<CompilationUnit> {
|
||||||
// let config = term::Config::default();
|
let mut files = SimpleFiles::<&'a str, &'a str>::new();
|
||||||
//
|
let mut compilation_units = parse_compilation_units(&mut files, sources);
|
||||||
// for diagnostic in &diagnostics {
|
|
||||||
// term::emit(&mut writer.lock(), &config, &files, &diagnostic).unwrap();
|
let diagnostics = analyze_names(&mut compilation_units, &files, symbol_table);
|
||||||
// }
|
|
||||||
//
|
if diagnostics.len() != number_of_diagnostics {
|
||||||
// eprintln!("{}", symbol_table);
|
let writer = StandardStream::stderr(ColorChoice::Always);
|
||||||
// }
|
let config = term::Config::default();
|
||||||
//
|
|
||||||
// assert_eq!(n_diagnostics, diagnostics.len());
|
for diagnostic in &diagnostics {
|
||||||
//
|
term::emit(&mut writer.lock(), &config, &files, &diagnostic).unwrap();
|
||||||
// compilation_units
|
}
|
||||||
// }
|
|
||||||
//
|
eprintln!("{}", symbol_table);
|
||||||
// fn assert_no_diagnostics(
|
}
|
||||||
// sources: HashMap<&str, &str>,
|
|
||||||
// symbol_table: &mut SymbolTable,
|
assert_eq!(number_of_diagnostics, diagnostics.len());
|
||||||
// ) -> Vec<CompilationUnit> {
|
|
||||||
// assert_number_of_diagnostics(sources, symbol_table, 0)
|
compilation_units
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// fn assert_saved_symbols(compilation_unit: &CompilationUnit) {
|
fn assert_no_diagnostics(
|
||||||
// walk_depth_first(compilation_unit, &mut |node_ref| match node_ref {
|
sources: HashMap<&str, &str>,
|
||||||
// NodeRef::Identifier(identifier) => {
|
symbol_table: &mut SymbolTable,
|
||||||
// if identifier.saved_symbol().is_none() {
|
) -> Vec<CompilationUnit> {
|
||||||
// panic!("{:?} does not have a saved symbol.", identifier)
|
assert_number_of_diagnostics(sources, symbol_table, 0)
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
// NodeRef::FullyQualifiedName(fqn) => {
|
#[test]
|
||||||
// if fqn.saved_symbol().is_none() {
|
fn params_seen() {
|
||||||
// panic!("{:?} does not have a saved symbol.", fqn)
|
let sources = HashMap::from([(
|
||||||
// }
|
"main.dm",
|
||||||
// }
|
"
|
||||||
// NodeRef::UseStatement(use_statement) => match use_statement {
|
fn main(args: Array<String>)
|
||||||
// _ => todo!(),
|
let x = args
|
||||||
// },
|
end
|
||||||
// _ => {}
|
",
|
||||||
// })
|
)]);
|
||||||
// }
|
|
||||||
//
|
assert_no_diagnostics(sources, &mut SymbolTable::new());
|
||||||
// fn assert_resolved_symbols(compilation_unit: &CompilationUnit) {
|
}
|
||||||
// walk_depth_first(compilation_unit, &mut |node_ref| match node_ref {
|
|
||||||
// NodeRef::UseStatement(use_statement) => match use_statement {
|
#[test]
|
||||||
// _ => todo!(),
|
fn two_files() {
|
||||||
// },
|
let sources = HashMap::from([
|
||||||
// _ => {}
|
(
|
||||||
// })
|
"main.dm",
|
||||||
// }
|
"
|
||||||
//
|
use test::Greeter
|
||||||
// #[test]
|
",
|
||||||
// fn params_seen() {
|
),
|
||||||
// let sources: HashMap<&str, &str> = HashMap::from([(
|
(
|
||||||
// "main.dm",
|
"deps.dm",
|
||||||
// indoc! {"
|
"
|
||||||
// fn main(args: Array<String>) {
|
ns test
|
||||||
// let x = args;
|
|
||||||
// }"},
|
pub class Greeter end
|
||||||
// )]);
|
",
|
||||||
//
|
),
|
||||||
// let cus = assert_no_diagnostics(sources, &mut SymbolTable::new());
|
]);
|
||||||
// for ref cu in cus {
|
assert_no_diagnostics(sources, &mut SymbolTable::new());
|
||||||
// assert_saved_symbols(cu);
|
}
|
||||||
// }
|
|
||||||
// }
|
#[test]
|
||||||
//
|
fn sees_std_core_println() {
|
||||||
// #[test]
|
let sources: HashMap<&str, &str> = HashMap::from([(
|
||||||
// fn two_files() {
|
"main.dm",
|
||||||
// let sources: HashMap<&str, &str> = HashMap::from([
|
"
|
||||||
// (
|
fn main(args: Array<String>)
|
||||||
// "main.dm",
|
std::core::println args
|
||||||
// indoc! {"
|
end
|
||||||
// use test::Greeter;
|
",
|
||||||
// "},
|
)]);
|
||||||
// ),
|
|
||||||
// (
|
let mut symbol_table = SymbolTable::new();
|
||||||
// "deps.dm",
|
add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols.");
|
||||||
// indoc! {"
|
assert_no_diagnostics(sources, &mut symbol_table);
|
||||||
// ns test;
|
}
|
||||||
//
|
|
||||||
// pub class Greeter {}
|
#[test]
|
||||||
// "},
|
fn sees_duplicate_fn() {
|
||||||
// ),
|
let sources: HashMap<&str, &str> = HashMap::from([(
|
||||||
// ]);
|
"main.dm",
|
||||||
//
|
"
|
||||||
// let cus = assert_no_diagnostics(sources, &mut SymbolTable::new());
|
fn main(args: Array<String>) end
|
||||||
// for ref cu in cus {
|
fn main(args: Array<String>) end
|
||||||
// assert_saved_symbols(cu);
|
",
|
||||||
// assert_resolved_symbols(cu);
|
)]);
|
||||||
// }
|
assert_number_of_diagnostics(sources, &mut SymbolTable::new(), 1);
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// #[test]
|
#[test]
|
||||||
// fn sees_std_core_println() {
|
fn sees_println() {
|
||||||
// let sources: HashMap<&str, &str> = HashMap::from([(
|
let sources = HashMap::from([(
|
||||||
// "main.dm",
|
"main.dm",
|
||||||
// indoc! {"
|
"
|
||||||
// fn main(args: Array<String>) {
|
fn main(args: Array<String>)
|
||||||
// println(args)
|
println args
|
||||||
// }
|
end
|
||||||
// "},
|
"
|
||||||
// )]);
|
)]);
|
||||||
//
|
let mut symbol_table = SymbolTable::new();
|
||||||
// let mut symbol_table = SymbolTable::new();
|
let global_std_core_use = StarUseSymbol::new(
|
||||||
// add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols.");
|
&[Rc::from("std"), Rc::from("core")],
|
||||||
// let cus = assert_no_diagnostics(sources, &mut symbol_table);
|
None
|
||||||
// for ref cu in cus {
|
);
|
||||||
// assert_saved_symbols(cu);
|
symbol_table.insert_star_use_symbol(global_std_core_use)
|
||||||
// assert_resolved_symbols(cu);
|
.expect("Failed to insert star use symbol.");
|
||||||
// }
|
|
||||||
// }
|
add_std_core_symbols(&mut symbol_table).expect("Failed to add std/core symbols.");
|
||||||
//
|
assert_no_diagnostics(sources, &mut symbol_table);
|
||||||
// #[test]
|
}
|
||||||
// fn sees_duplicate_fn() {
|
}
|
||||||
// let sources: HashMap<&str, &str> = HashMap::from([(
|
|
||||||
// "main.dm",
|
|
||||||
// indoc! {"
|
|
||||||
// fn main(args: Array<String>) {}
|
|
||||||
// fn main(args: Array<String>) {}
|
|
||||||
// "},
|
|
||||||
// )]);
|
|
||||||
// assert_number_of_diagnostics(sources, &mut SymbolTable::new(), 1);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// #[test]
|
|
||||||
// fn use_class_from_other_file() {
|
|
||||||
// let sources: HashMap<&str, &str> = HashMap::from([
|
|
||||||
// (
|
|
||||||
// "main.dm",
|
|
||||||
// indoc! {"
|
|
||||||
// use greeter::Greeter;
|
|
||||||
//
|
|
||||||
// fn test(greeter: Greeter) {}
|
|
||||||
// "},
|
|
||||||
// ),
|
|
||||||
// (
|
|
||||||
// "greeter.dm",
|
|
||||||
// indoc! {"
|
|
||||||
// ns greeter;
|
|
||||||
//
|
|
||||||
// class Greeter {}
|
|
||||||
// "},
|
|
||||||
// ),
|
|
||||||
// ]);
|
|
||||||
// let mut symbol_table = SymbolTable::new();
|
|
||||||
// let cus = assert_no_diagnostics(sources, &mut symbol_table);
|
|
||||||
// for ref cu in cus {
|
|
||||||
// assert_saved_symbols(cu);
|
|
||||||
// assert_resolved_symbols(cu);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// #[test]
|
|
||||||
// fn shadow_import() {
|
|
||||||
// let sources: HashMap<&str, &str> = HashMap::from([
|
|
||||||
// (
|
|
||||||
// "main.dm",
|
|
||||||
// indoc! {"
|
|
||||||
// use greeter::Greeter;
|
|
||||||
//
|
|
||||||
// class Greeter {}
|
|
||||||
// "},
|
|
||||||
// ),
|
|
||||||
// (
|
|
||||||
// "greeter.dm",
|
|
||||||
// indoc! {"
|
|
||||||
// ns greeter;
|
|
||||||
//
|
|
||||||
// class Greeter {}
|
|
||||||
// "},
|
|
||||||
// ),
|
|
||||||
// ]);
|
|
||||||
// assert_number_of_diagnostics(sources, &mut SymbolTable::new(), 1);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|||||||
@ -1,27 +1,27 @@
|
|||||||
use crate::ast::node::{
|
use crate::ast::node::{AssignmentStatement, CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Expression, ExpressionStatement, Function, FunctionAliasBody, FunctionBlockBody, FunctionBody, Identifier, LValue, ModuleLevelDeclaration, StarUseStatement, Statement, TypeUse, UseStatement, UseStatementIdentifier, UseStatementPrefix, VariableDeclaration, VariableUse};
|
||||||
CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Identifier, UseStatement,
|
|
||||||
UseStatementIdentifier, UseStatementPrefix,
|
|
||||||
};
|
|
||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::symbol::variable_symbol::VariableSymbol;
|
||||||
use crate::name_analysis::symbol_table::{SymbolLookupError, SymbolTable};
|
use crate::name_analysis::symbol_table::{SymbolLookupError, SymbolTable};
|
||||||
use crate::name_analysis::util::handle_lookup_error;
|
use crate::name_analysis::util::{handle_insert_error, handle_lookup_error, join_fqn_parts};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub fn na_p2_compilation_unit(
|
pub fn na_p2_compilation_unit(
|
||||||
compilation_unit: &mut CompilationUnit,
|
compilation_unit: &mut CompilationUnit,
|
||||||
symbol_table: &SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
// TODO: check namespace for proper file name
|
|
||||||
for use_statement in compilation_unit.use_statements_mut() {
|
for use_statement in compilation_unit.use_statements_mut() {
|
||||||
na_p2_use_statement(use_statement, symbol_table, diagnostics);
|
na_p2_use_statement(use_statement, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
|
for declaration in compilation_unit.module_level_declarations_mut() {
|
||||||
// TODO: declarations
|
na_p2_module_level_declaration(declaration, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn na_p2_use_statement(
|
fn na_p2_use_statement(
|
||||||
use_statement: &mut UseStatement,
|
use_statement: &mut UseStatement,
|
||||||
symbol_table: &SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
match use_statement {
|
match use_statement {
|
||||||
@ -29,22 +29,22 @@ fn na_p2_use_statement(
|
|||||||
na_p2_concrete_use_statement(concrete_use_statement, symbol_table, diagnostics);
|
na_p2_concrete_use_statement(concrete_use_statement, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
UseStatement::StarUseStatement(star_use_statement) => {
|
UseStatement::StarUseStatement(star_use_statement) => {
|
||||||
todo!()
|
na_p2_star_use_statement(star_use_statement, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn na_p2_concrete_use_statement(
|
fn na_p2_concrete_use_statement(
|
||||||
concrete_use_statement: &mut ConcreteUseStatement,
|
concrete_use_statement: &mut ConcreteUseStatement,
|
||||||
symbol_table: &SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
let base_fqn_parts: Vec<String> = concrete_use_statement
|
let base_fqn_parts = concrete_use_statement
|
||||||
.prefixes()
|
.prefixes()
|
||||||
.map(UseStatementPrefix::identifier)
|
.map(UseStatementPrefix::identifier)
|
||||||
.map(Identifier::name)
|
.map(Identifier::name)
|
||||||
.map(ToString::to_string)
|
.map(Rc::from)
|
||||||
.collect();
|
.collect::<Vec<Rc<str>>>();
|
||||||
|
|
||||||
match concrete_use_statement.suffix_mut() {
|
match concrete_use_statement.suffix_mut() {
|
||||||
ConcreteUseStatementSuffix::UseStatementIdentifier(use_statement_identifier) => {
|
ConcreteUseStatementSuffix::UseStatementIdentifier(use_statement_identifier) => {
|
||||||
@ -69,17 +69,14 @@ fn na_p2_concrete_use_statement(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_concrete_use_statement_identifier(
|
fn handle_concrete_use_statement_identifier(
|
||||||
base_fqn_parts: &[String],
|
base_fqn_parts: &[Rc<str>],
|
||||||
use_statement_identifier: &mut UseStatementIdentifier,
|
use_statement_identifier: &mut UseStatementIdentifier,
|
||||||
symbol_table: &SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
let fqn_parts = {
|
let fqn_parts = {
|
||||||
let mut all_parts: Vec<&str> = vec![];
|
let mut all_parts = base_fqn_parts.to_vec();
|
||||||
for part in base_fqn_parts {
|
all_parts.push(Rc::from(use_statement_identifier.identifier().name()));
|
||||||
all_parts.push(part);
|
|
||||||
}
|
|
||||||
all_parts.push(use_statement_identifier.identifier().name());
|
|
||||||
all_parts
|
all_parts
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,10 +90,305 @@ fn handle_concrete_use_statement_identifier(
|
|||||||
} else {
|
} else {
|
||||||
handle_lookup_error(
|
handle_lookup_error(
|
||||||
SymbolLookupError::NoDefinition,
|
SymbolLookupError::NoDefinition,
|
||||||
&fqn_parts.join("::"),
|
&join_fqn_parts(&fqn_parts),
|
||||||
use_statement_identifier.identifier().file_id(),
|
use_statement_identifier.identifier().file_id(),
|
||||||
use_statement_identifier.identifier().range(),
|
use_statement_identifier.identifier().range(),
|
||||||
diagnostics,
|
diagnostics,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn na_p2_star_use_statement(
|
||||||
|
star_use_statement: &mut StarUseStatement,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let mut symbol_ref_mut = star_use_statement.symbol().unwrap().borrow_mut();
|
||||||
|
match symbol_table.find_usable_symbols_by_base_fqn(symbol_ref_mut.fqn_parts()) {
|
||||||
|
Ok(usable_symbols) => {
|
||||||
|
symbol_ref_mut.set_resolved_symbols(usable_symbols);
|
||||||
|
}
|
||||||
|
Err(symbol_lookup_error) => {
|
||||||
|
handle_lookup_error(
|
||||||
|
symbol_lookup_error,
|
||||||
|
&join_fqn_parts(symbol_ref_mut.fqn_parts()),
|
||||||
|
star_use_statement.file_id(),
|
||||||
|
star_use_statement.range(),
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_module_level_declaration(
|
||||||
|
module_level_declaration: &mut ModuleLevelDeclaration,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
match module_level_declaration {
|
||||||
|
ModuleLevelDeclaration::Module(module_declaration) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
ModuleLevelDeclaration::Interface(interface) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
ModuleLevelDeclaration::Class(class) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
ModuleLevelDeclaration::Function(function) => {
|
||||||
|
na_p2_function(function, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
ModuleLevelDeclaration::PlatformFunction(platform_function) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_function(
|
||||||
|
function: &mut Function,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
na_p2_function_body(function.function_body_mut(), symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_function_body(
|
||||||
|
function_body: &mut FunctionBody,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
match function_body {
|
||||||
|
FunctionBody::FunctionAliasBody(alias_body) => {
|
||||||
|
na_p2_function_alias_body(alias_body, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
FunctionBody::FunctionEqualsBody(equals_body) => {}
|
||||||
|
FunctionBody::FunctionBlockBody(block_body) => {
|
||||||
|
na_p2_function_block_body(block_body, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_function_alias_body(
|
||||||
|
function_alias_body: &mut FunctionAliasBody,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let maybe_function_symbol = symbol_table.lookup_function_symbol(
|
||||||
|
function_alias_body.identifier().name(),
|
||||||
|
*function_alias_body.scope_id().unwrap(),
|
||||||
|
);
|
||||||
|
match maybe_function_symbol {
|
||||||
|
Ok(function_symbol) => {
|
||||||
|
function_alias_body.set_resolved_function_symbol(function_symbol);
|
||||||
|
}
|
||||||
|
Err(symbol_lookup_error) => {
|
||||||
|
handle_lookup_error(
|
||||||
|
symbol_lookup_error,
|
||||||
|
function_alias_body.identifier().name(),
|
||||||
|
function_alias_body.identifier().file_id(),
|
||||||
|
function_alias_body.identifier().range(),
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_function_block_body(
|
||||||
|
function_block_body: &mut FunctionBlockBody,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
symbol_table.set_current_scope(*function_block_body.scope_id().unwrap());
|
||||||
|
for statement in function_block_body.statements_mut() {
|
||||||
|
na_p2_statement(statement, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_statement(
|
||||||
|
statement: &mut Statement,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
match statement {
|
||||||
|
Statement::VariableDeclaration(variable_declaration) => {
|
||||||
|
na_p2_variable_declaration(variable_declaration, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
Statement::AssignmentStatement(assignment_statement) => {
|
||||||
|
na_p2_assignment_statement(assignment_statement, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
Statement::ExpressionStatement(expression_statement) => {
|
||||||
|
na_p2_expression_statement(expression_statement, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
Statement::UseStatement(use_statement) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Statement::IfStatement(if_statement) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Statement::WhileStatement(while_statement) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Statement::ForStatement(for_statement) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_variable_declaration(
|
||||||
|
variable_declaration: &mut VariableDeclaration,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
// handle variable itself
|
||||||
|
let to_insert = VariableSymbol::new(
|
||||||
|
variable_declaration.identifier().name(),
|
||||||
|
variable_declaration.is_mut(),
|
||||||
|
Some(SourceDefinition::from_identifier(
|
||||||
|
variable_declaration.identifier(),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
match symbol_table.insert_variable_symbol(to_insert) {
|
||||||
|
Ok(variable_symbol) => {
|
||||||
|
variable_declaration.set_variable_symbol(variable_symbol);
|
||||||
|
}
|
||||||
|
Err(symbol_insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
symbol_insert_error,
|
||||||
|
variable_declaration.identifier().name(),
|
||||||
|
variable_declaration.identifier().file_id(),
|
||||||
|
variable_declaration.identifier().range(),
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// type-use
|
||||||
|
if let Some(type_use) = variable_declaration.type_use_mut() {
|
||||||
|
na_p2_type_use(type_use, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
// initializer
|
||||||
|
if let Some(expression) = variable_declaration.expression_mut() {
|
||||||
|
na_p2_expression(expression, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_assignment_statement(
|
||||||
|
assignment_statement: &mut AssignmentStatement,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
na_p2_l_value(assignment_statement.l_value_mut(), symbol_table, diagnostics);
|
||||||
|
na_p2_expression(assignment_statement.expression_mut(), symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_l_value(
|
||||||
|
l_value: &mut LValue,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
na_p2_variable_use(l_value.variable_use_mut(), symbol_table, diagnostics);
|
||||||
|
// TODO: suffixes
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_expression_statement(
|
||||||
|
expression_statement: &mut ExpressionStatement,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
na_p2_expression(expression_statement.expression_mut(), symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_variable_use(
|
||||||
|
variable_use: &mut VariableUse,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
match symbol_table.lookup_lv_symbol(variable_use.identifier().name()) {
|
||||||
|
Ok(lv_symbol) => {
|
||||||
|
variable_use.set_lv_symbol(lv_symbol);
|
||||||
|
}
|
||||||
|
Err(symbol_lookup_error) => {
|
||||||
|
handle_lookup_error(
|
||||||
|
symbol_lookup_error,
|
||||||
|
variable_use.identifier().name(),
|
||||||
|
variable_use.identifier().file_id(),
|
||||||
|
variable_use.identifier().range(),
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_expression(
|
||||||
|
expression: &mut Expression,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
match expression {
|
||||||
|
Expression::Ternary(ternary) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Expression::Or(or) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Expression::And(and) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Expression::Comparison(comparison) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Expression::Shift(shift) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Expression::Additive(additive) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Expression::Multiplicative(multiplicative) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Expression::Prefix(prefix) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Expression::Suffix(suffix) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Expression::Literal(literal) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Expression::VariableUse(variable_use) => {
|
||||||
|
na_p2_variable_use(variable_use, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
Expression::Fqn(fqn) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Expression::Closure(closure) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Expression::List(list) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p2_type_use(
|
||||||
|
type_use: &mut TypeUse,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
match type_use {
|
||||||
|
TypeUse::PrimitiveType(primitive_type_use) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
TypeUse::InterfaceOrClassTypeUse(interface_or_class_type_use) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
TypeUse::TupleTypeUse(tuple_type_use) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
TypeUse::FunctionTypeUse(function_type_use) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -23,11 +24,11 @@ impl ClassMemberSymbol {
|
|||||||
source_definition,
|
source_definition,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_public(&self) -> bool {
|
pub fn is_public(&self) -> bool {
|
||||||
self.is_public
|
self.is_public
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_mut(&self) -> bool {
|
pub fn is_mut(&self) -> bool {
|
||||||
self.is_mut
|
self.is_mut
|
||||||
}
|
}
|
||||||
@ -35,8 +36,10 @@ impl ClassMemberSymbol {
|
|||||||
pub fn declared_name(&self) -> &str {
|
pub fn declared_name(&self) -> &str {
|
||||||
&self.declared_name
|
&self.declared_name
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
impl Symbol for ClassMemberSymbol {
|
||||||
|
fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
self.source_definition.as_ref()
|
self.source_definition.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
src/name_analysis/symbol/lv_symbol.rs
Normal file
28
src/name_analysis/symbol/lv_symbol.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol;
|
||||||
|
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
|
use crate::name_analysis::symbol::variable_symbol::VariableSymbol;
|
||||||
|
|
||||||
|
pub enum LVSymbol {
|
||||||
|
ClassMember(Rc<RefCell<ClassMemberSymbol>>),
|
||||||
|
Parameter(Rc<RefCell<ParameterSymbol>>),
|
||||||
|
Variable(Rc<RefCell<VariableSymbol>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LVSymbol {
|
||||||
|
pub fn to_symbol(self) -> Rc<RefCell<dyn Symbol>> {
|
||||||
|
match self {
|
||||||
|
LVSymbol::ClassMember(class_member_symbol) => {
|
||||||
|
class_member_symbol as Rc<RefCell<dyn Symbol>>
|
||||||
|
}
|
||||||
|
LVSymbol::Parameter(parameter_symbol) => {
|
||||||
|
parameter_symbol as Rc<RefCell<dyn Symbol>>
|
||||||
|
}
|
||||||
|
LVSymbol::Variable(variable_symbol) => {
|
||||||
|
variable_symbol as Rc<RefCell<dyn Symbol>>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ pub mod class_symbol;
|
|||||||
pub mod function_symbol;
|
pub mod function_symbol;
|
||||||
pub mod generic_type_symbol;
|
pub mod generic_type_symbol;
|
||||||
pub mod interface_symbol;
|
pub mod interface_symbol;
|
||||||
|
pub mod lv_symbol;
|
||||||
pub mod module_level_symbol;
|
pub mod module_level_symbol;
|
||||||
pub mod module_symbol;
|
pub mod module_symbol;
|
||||||
pub mod parameter_symbol;
|
pub mod parameter_symbol;
|
||||||
@ -16,6 +17,13 @@ pub mod variable_symbol;
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
pub use self::{
|
||||||
|
class_member_symbol::*, class_symbol::*, function_symbol::*, function_symbol::*,
|
||||||
|
generic_type_symbol::*, interface_symbol::*, lv_symbol::*, module_level_symbol::*,
|
||||||
|
module_symbol::*, parameter_symbol::*, primitive_type_symbol::*, type_symbol::*,
|
||||||
|
usable_symbol::*, use_symbol::*, variable_symbol::*,
|
||||||
|
};
|
||||||
|
|
||||||
pub trait Symbol: Debug {
|
pub trait Symbol: Debug {
|
||||||
fn source_definition(&self) -> Option<&SourceDefinition>;
|
fn source_definition(&self) -> Option<&SourceDefinition>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct ParameterSymbol {
|
pub struct ParameterSymbol {
|
||||||
declared_name: String,
|
declared_name: Rc<str>,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
type_symbol: Option<TypeSymbol>,
|
type_symbol: Option<TypeSymbol>,
|
||||||
}
|
}
|
||||||
@ -14,8 +16,8 @@ impl ParameterSymbol {
|
|||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
type_symbol: Option<TypeSymbol>,
|
type_symbol: Option<TypeSymbol>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
ParameterSymbol {
|
Self {
|
||||||
declared_name: declared_name.to_string(),
|
declared_name: Rc::from(declared_name),
|
||||||
source_definition,
|
source_definition,
|
||||||
type_symbol,
|
type_symbol,
|
||||||
}
|
}
|
||||||
@ -25,7 +27,13 @@ impl ParameterSymbol {
|
|||||||
&self.declared_name
|
&self.declared_name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||||
|
self.declared_name.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Symbol for ParameterSymbol {
|
||||||
|
fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
self.source_definition.as_ref()
|
self.source_definition.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use crate::ast::node::{Identifier, Operator};
|
use crate::ast::node::{Identifier, Operator, StarUseStatement};
|
||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -14,7 +14,7 @@ impl SourceDefinition {
|
|||||||
range: identifier.range(),
|
range: identifier.range(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_operator(operator: &Operator) -> Self {
|
pub fn from_operator(operator: &Operator) -> Self {
|
||||||
Self {
|
Self {
|
||||||
file_id: operator.file_id(),
|
file_id: operator.file_id(),
|
||||||
@ -22,6 +22,13 @@ impl SourceDefinition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_star_use_statement(star_use_statement: &StarUseStatement) -> Self {
|
||||||
|
Self {
|
||||||
|
file_id: star_use_statement.file_id(),
|
||||||
|
range: star_use_statement.range(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn file_id(&self) -> usize {
|
pub fn file_id(&self) -> usize {
|
||||||
self.file_id
|
self.file_id
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use crate::name_analysis::symbol::Symbol;
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum UsableSymbol {
|
pub enum UsableSymbol {
|
||||||
Interface(Rc<RefCell<InterfaceSymbol>>),
|
Interface(Rc<RefCell<InterfaceSymbol>>),
|
||||||
Class(Rc<RefCell<ClassSymbol>>),
|
Class(Rc<RefCell<ClassSymbol>>),
|
||||||
|
|||||||
@ -76,6 +76,7 @@ impl Debug for ConcreteUseSymbol {
|
|||||||
pub struct StarUseSymbol {
|
pub struct StarUseSymbol {
|
||||||
fqn_parts: Vec<Rc<str>>,
|
fqn_parts: Vec<Rc<str>>,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
|
resolved_symbols: Vec<UsableSymbol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StarUseSymbol {
|
impl StarUseSymbol {
|
||||||
@ -83,12 +84,21 @@ impl StarUseSymbol {
|
|||||||
Self {
|
Self {
|
||||||
fqn_parts: fqn_parts.to_vec(),
|
fqn_parts: fqn_parts.to_vec(),
|
||||||
source_definition,
|
source_definition,
|
||||||
|
resolved_symbols: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fqn_parts(&self) -> &[Rc<str>] {
|
pub fn fqn_parts(&self) -> &[Rc<str>] {
|
||||||
&self.fqn_parts
|
&self.fqn_parts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resolved_symbols(&self) -> &[UsableSymbol] {
|
||||||
|
&self.resolved_symbols
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_resolved_symbols(&mut self, symbols: Vec<UsableSymbol>) {
|
||||||
|
self.resolved_symbols = symbols;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Symbol for StarUseSymbol {
|
impl Symbol for StarUseSymbol {
|
||||||
|
|||||||
@ -1,17 +1,23 @@
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct VariableSymbol {
|
pub struct VariableSymbol {
|
||||||
declared_name: String,
|
declared_name: Rc<str>,
|
||||||
is_mutable: bool,
|
is_mutable: bool,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VariableSymbol {
|
impl VariableSymbol {
|
||||||
pub fn new(declared_name: &str, is_mutable: bool, source_definition: Option<SourceDefinition>) -> Self {
|
pub fn new(
|
||||||
|
declared_name: &str,
|
||||||
|
is_mutable: bool,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
) -> Self {
|
||||||
VariableSymbol {
|
VariableSymbol {
|
||||||
declared_name: declared_name.to_string(),
|
declared_name: Rc::from(declared_name),
|
||||||
is_mutable,
|
is_mutable,
|
||||||
source_definition,
|
source_definition,
|
||||||
}
|
}
|
||||||
@ -21,11 +27,17 @@ impl VariableSymbol {
|
|||||||
&self.declared_name
|
&self.declared_name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||||
|
self.declared_name.clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_mutable(&self) -> bool {
|
pub fn is_mutable(&self) -> bool {
|
||||||
self.is_mutable
|
self.is_mutable
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
|
||||||
|
impl Symbol for VariableSymbol {
|
||||||
|
fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
self.source_definition.as_ref()
|
self.source_definition.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
|
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
|
||||||
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
||||||
|
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
||||||
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
||||||
use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
|
use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
|
||||||
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
||||||
use crate::name_analysis::symbol::Symbol;
|
use crate::name_analysis::symbol::{LVSymbol, Symbol};
|
||||||
use crate::name_analysis::symbol_table::fqn_context::FqnContext;
|
use crate::name_analysis::symbol_table::fqn_context::FqnContext;
|
||||||
use crate::name_analysis::symbol_table::symbol_tree::SymbolTree;
|
use crate::name_analysis::symbol_table::symbol_tree::SymbolTree;
|
||||||
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
|
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
|
||||||
@ -12,7 +14,7 @@ use std::cell::RefCell;
|
|||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
|
use crate::name_analysis::symbol::variable_symbol::VariableSymbol;
|
||||||
|
|
||||||
pub(self) mod fqn_context;
|
pub(self) mod fqn_context;
|
||||||
mod scope;
|
mod scope;
|
||||||
@ -25,6 +27,7 @@ pub enum SymbolInsertError {
|
|||||||
|
|
||||||
pub enum SymbolLookupError {
|
pub enum SymbolLookupError {
|
||||||
NoDefinition,
|
NoDefinition,
|
||||||
|
NoSuchNamespace,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -65,6 +68,10 @@ impl SymbolTable {
|
|||||||
self.current_scope_id = parent_id;
|
self.current_scope_id = parent_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_current_scope(&mut self, id: usize) {
|
||||||
|
self.current_scope_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_current_fqn(&mut self, names: &[&str]) {
|
pub fn set_current_fqn(&mut self, names: &[&str]) {
|
||||||
self.fqn_context = Box::new(FqnContext::new());
|
self.fqn_context = Box::new(FqnContext::new());
|
||||||
@ -95,7 +102,7 @@ impl SymbolTable {
|
|||||||
parts
|
parts
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_usable_symbol(&self, fqn_parts: &[&str]) -> Option<UsableSymbol> {
|
pub fn find_usable_symbol(&self, fqn_parts: &[Rc<str>]) -> Option<UsableSymbol> {
|
||||||
self.symbol_tree
|
self.symbol_tree
|
||||||
.find_interface(fqn_parts)
|
.find_interface(fqn_parts)
|
||||||
.map(|interface_symbol| UsableSymbol::Interface(interface_symbol))
|
.map(|interface_symbol| UsableSymbol::Interface(interface_symbol))
|
||||||
@ -111,6 +118,17 @@ impl SymbolTable {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn register_module(&mut self, fqn_parts: &[&str]) {
|
||||||
|
self.symbol_tree.register_module_by_fqn_parts(fqn_parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_usable_symbols_by_base_fqn(
|
||||||
|
&self,
|
||||||
|
fqn_parts: &[Rc<str>],
|
||||||
|
) -> Result<Vec<UsableSymbol>, SymbolLookupError> {
|
||||||
|
self.symbol_tree.find_all_by_base_fqn(fqn_parts)
|
||||||
|
}
|
||||||
|
|
||||||
fn current_scope(&self) -> &Scope {
|
fn current_scope(&self) -> &Scope {
|
||||||
&self.scopes[self.current_scope_id]
|
&self.scopes[self.current_scope_id]
|
||||||
}
|
}
|
||||||
@ -179,15 +197,54 @@ impl SymbolTable {
|
|||||||
Ok(inserted)
|
Ok(inserted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_generic_type_symbol(
|
pub fn insert_generic_type_symbol(
|
||||||
&mut self,
|
&mut self,
|
||||||
generic_type_symbol: GenericTypeSymbol,
|
generic_type_symbol: GenericTypeSymbol,
|
||||||
) -> Result<Rc<RefCell<GenericTypeSymbol>>, SymbolInsertError> {
|
) -> Result<Rc<RefCell<GenericTypeSymbol>>, SymbolInsertError> {
|
||||||
if let Some(defined_symbol) = self.current_scope().find_type_symbol(generic_type_symbol.declared_name()) {
|
if let Some(defined_symbol) = self
|
||||||
|
.current_scope()
|
||||||
|
.find_type_symbol(generic_type_symbol.declared_name())
|
||||||
|
{
|
||||||
Err(SymbolAlreadyDefined(defined_symbol.to_symbol()))
|
Err(SymbolAlreadyDefined(defined_symbol.to_symbol()))
|
||||||
} else {
|
} else {
|
||||||
let inserted = self.current_scope_mut().insert_generic_type_symbol(generic_type_symbol);
|
let inserted = self
|
||||||
|
.current_scope_mut()
|
||||||
|
.insert_generic_type_symbol(generic_type_symbol);
|
||||||
|
Ok(inserted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_parameter_symbol(
|
||||||
|
&mut self,
|
||||||
|
parameter_symbol: ParameterSymbol,
|
||||||
|
) -> Result<Rc<RefCell<ParameterSymbol>>, SymbolInsertError> {
|
||||||
|
if let Some(defined_symbol) = self
|
||||||
|
.current_scope()
|
||||||
|
.find_lv_symbol(parameter_symbol.declared_name())
|
||||||
|
{
|
||||||
|
Err(SymbolAlreadyDefined(defined_symbol.to_symbol()))
|
||||||
|
} else {
|
||||||
|
let inserted = self
|
||||||
|
.current_scope_mut()
|
||||||
|
.insert_parameter_symbol(parameter_symbol);
|
||||||
|
Ok(inserted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_variable_symbol(
|
||||||
|
&mut self,
|
||||||
|
variable_symbol: VariableSymbol,
|
||||||
|
) -> Result<Rc<RefCell<VariableSymbol>>, SymbolInsertError> {
|
||||||
|
if let Some(defined_symbol) = self
|
||||||
|
.current_scope()
|
||||||
|
.find_lv_symbol(variable_symbol.declared_name())
|
||||||
|
{
|
||||||
|
Err(SymbolAlreadyDefined(defined_symbol.to_symbol()))
|
||||||
|
} else {
|
||||||
|
let inserted = self
|
||||||
|
.current_scope_mut()
|
||||||
|
.insert_variable_symbol(variable_symbol);
|
||||||
Ok(inserted)
|
Ok(inserted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -205,10 +262,38 @@ impl SymbolTable {
|
|||||||
}
|
}
|
||||||
Err(SymbolLookupError::NoDefinition)
|
Err(SymbolLookupError::NoDefinition)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lookup_type_by_fqn(&self, fqn_parts: &[&str]) -> Result<TypeSymbol, SymbolLookupError> {
|
pub fn lookup_type_by_fqn(&self, fqn_parts: &[&str]) -> Result<TypeSymbol, SymbolLookupError> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lookup_function_symbol(&self, declared_name: &str, scope_id: usize) -> Result<Rc<RefCell<FunctionSymbol>>, SymbolLookupError> {
|
||||||
|
let mut current_scope: Option<&Scope> = self.scopes.get(scope_id);
|
||||||
|
while let Some(scope) = current_scope.take() {
|
||||||
|
if let Some(function_symbol) = scope.find_function_symbol(declared_name) {
|
||||||
|
return Ok(function_symbol.clone());
|
||||||
|
} else {
|
||||||
|
current_scope = scope
|
||||||
|
.parent()
|
||||||
|
.and_then(|parent_id| self.scopes.get(parent_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(SymbolLookupError::NoDefinition)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lookup_lv_symbol(&self, declared_name: &str) -> Result<LVSymbol, SymbolLookupError> {
|
||||||
|
let mut current_scope: Option<&Scope> = Some(self.current_scope());
|
||||||
|
while let Some(scope) = current_scope.take() {
|
||||||
|
if let Some(lv_symbol) = scope.find_lv_symbol(declared_name) {
|
||||||
|
return Ok(lv_symbol)
|
||||||
|
} else {
|
||||||
|
current_scope = scope
|
||||||
|
.parent()
|
||||||
|
.and_then(|parent_id| self.scopes.get(parent_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(SymbolLookupError::NoDefinition)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for SymbolTable {
|
impl Display for SymbolTable {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use crate::name_analysis::symbol::class_symbol::ClassSymbol;
|
|||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
|
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
|
||||||
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
||||||
|
use crate::name_analysis::symbol::lv_symbol::LVSymbol;
|
||||||
use crate::name_analysis::symbol::module_level_symbol::ModuleLevelSymbol;
|
use crate::name_analysis::symbol::module_level_symbol::ModuleLevelSymbol;
|
||||||
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
||||||
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
||||||
@ -26,9 +27,9 @@ pub struct Scope {
|
|||||||
class_symbols: HashMap<Rc<str>, Rc<RefCell<ClassSymbol>>>,
|
class_symbols: HashMap<Rc<str>, Rc<RefCell<ClassSymbol>>>,
|
||||||
generic_symbols: HashMap<Rc<str>, Rc<RefCell<GenericTypeSymbol>>>,
|
generic_symbols: HashMap<Rc<str>, Rc<RefCell<GenericTypeSymbol>>>,
|
||||||
function_symbols: HashMap<Rc<str>, Rc<RefCell<FunctionSymbol>>>,
|
function_symbols: HashMap<Rc<str>, Rc<RefCell<FunctionSymbol>>>,
|
||||||
parameter_symbols: HashMap<Rc<str>, ParameterSymbol>,
|
parameter_symbols: HashMap<Rc<str>, Rc<RefCell<ParameterSymbol>>>,
|
||||||
variable_symbols: HashMap<Rc<str>, VariableSymbol>,
|
variable_symbols: HashMap<Rc<str>, Rc<RefCell<VariableSymbol>>>,
|
||||||
class_member_symbols: HashMap<Rc<str>, ClassMemberSymbol>,
|
class_member_symbols: HashMap<Rc<str>, Rc<RefCell<ClassMemberSymbol>>>,
|
||||||
debug_name: String,
|
debug_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,12 +126,31 @@ impl Scope {
|
|||||||
pub fn get_class_symbol(&self, declared_name: &str) -> Option<&Rc<RefCell<ClassSymbol>>> {
|
pub fn get_class_symbol(&self, declared_name: &str) -> Option<&Rc<RefCell<ClassSymbol>>> {
|
||||||
self.class_symbols.get(declared_name)
|
self.class_symbols.get(declared_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_generic_type_symbol(&mut self, symbol: GenericTypeSymbol) -> Rc<RefCell<GenericTypeSymbol>> {
|
pub fn insert_generic_type_symbol(
|
||||||
|
&mut self,
|
||||||
|
symbol: GenericTypeSymbol,
|
||||||
|
) -> Rc<RefCell<GenericTypeSymbol>> {
|
||||||
let key = symbol.declared_name_owned();
|
let key = symbol.declared_name_owned();
|
||||||
insert_symbol!(self.generic_symbols, symbol, key)
|
insert_symbol!(self.generic_symbols, symbol, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn insert_parameter_symbol(
|
||||||
|
&mut self,
|
||||||
|
symbol: ParameterSymbol,
|
||||||
|
) -> Rc<RefCell<ParameterSymbol>> {
|
||||||
|
let key = symbol.declared_name_owned();
|
||||||
|
insert_symbol!(self.parameter_symbols, symbol, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_variable_symbol(
|
||||||
|
&mut self,
|
||||||
|
symbol: VariableSymbol,
|
||||||
|
) -> Rc<RefCell<VariableSymbol>> {
|
||||||
|
let key = symbol.declared_name_owned();
|
||||||
|
insert_symbol!(self.variable_symbols, symbol, key)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn find_module_level_symbol(&self, declared_name: &str) -> Option<ModuleLevelSymbol> {
|
pub fn find_module_level_symbol(&self, declared_name: &str) -> Option<ModuleLevelSymbol> {
|
||||||
self.module_symbols
|
self.module_symbols
|
||||||
.get(declared_name)
|
.get(declared_name)
|
||||||
@ -168,6 +188,26 @@ impl Scope {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_lv_symbol(&self, declared_name: &str) -> Option<LVSymbol> {
|
||||||
|
self.class_member_symbols
|
||||||
|
.get(declared_name)
|
||||||
|
.map(|class_member_symbol| LVSymbol::ClassMember(class_member_symbol.clone()))
|
||||||
|
.or_else(|| {
|
||||||
|
self.parameter_symbols
|
||||||
|
.get(declared_name)
|
||||||
|
.map(|parameter_symbol| LVSymbol::Parameter(parameter_symbol.clone()))
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
self.variable_symbols
|
||||||
|
.get(declared_name)
|
||||||
|
.map(|variable_symbol| LVSymbol::Variable(variable_symbol.clone()))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_function_symbol(&self, declared_name: &str) -> Option<&Rc<RefCell<FunctionSymbol>>> {
|
||||||
|
self.function_symbols.get(declared_name)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn debug_name(&self) -> &str {
|
pub fn debug_name(&self) -> &str {
|
||||||
&self.debug_name
|
&self.debug_name
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,8 @@ use crate::name_analysis::symbol::class_symbol::ClassSymbol;
|
|||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
||||||
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
||||||
|
use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
|
||||||
|
use crate::name_analysis::symbol_table::SymbolLookupError;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -24,35 +26,35 @@ impl SymbolTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_class(&self, fqn_parts: &[&str]) -> Option<Rc<RefCell<ClassSymbol>>> {
|
pub fn find_class(&self, fqn_parts: &[Rc<str>]) -> Option<Rc<RefCell<ClassSymbol>>> {
|
||||||
match fqn_parts.len() {
|
match fqn_parts.len() {
|
||||||
0 => None,
|
0 => None,
|
||||||
1 => self.classes.get(fqn_parts[0]).cloned(),
|
1 => self.classes.get(&fqn_parts[0]).cloned(),
|
||||||
_ => self
|
_ => self
|
||||||
.children
|
.children
|
||||||
.get(fqn_parts[0])
|
.get(&fqn_parts[0])
|
||||||
.and_then(|child_tree| child_tree.find_class(&fqn_parts[1..])),
|
.and_then(|child_tree| child_tree.find_class(&fqn_parts[1..])),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_interface(&self, fqn_parts: &[&str]) -> Option<Rc<RefCell<InterfaceSymbol>>> {
|
pub fn find_interface(&self, fqn_parts: &[Rc<str>]) -> Option<Rc<RefCell<InterfaceSymbol>>> {
|
||||||
match fqn_parts.len() {
|
match fqn_parts.len() {
|
||||||
0 => None,
|
0 => None,
|
||||||
1 => self.interfaces.get(fqn_parts[0]).cloned(),
|
1 => self.interfaces.get(&fqn_parts[0]).cloned(),
|
||||||
_ => self
|
_ => self
|
||||||
.children
|
.children
|
||||||
.get(fqn_parts[0])
|
.get(&fqn_parts[0])
|
||||||
.and_then(|child_tree| child_tree.find_interface(&fqn_parts[1..])),
|
.and_then(|child_tree| child_tree.find_interface(&fqn_parts[1..])),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_function(&self, fqn_parts: &[&str]) -> Option<Rc<RefCell<FunctionSymbol>>> {
|
pub fn find_function(&self, fqn_parts: &[Rc<str>]) -> Option<Rc<RefCell<FunctionSymbol>>> {
|
||||||
match fqn_parts.len() {
|
match fqn_parts.len() {
|
||||||
0 => None,
|
0 => None,
|
||||||
1 => self.functions.get(fqn_parts[0]).cloned(),
|
1 => self.functions.get(&fqn_parts[0]).cloned(),
|
||||||
_ => self
|
_ => self
|
||||||
.children
|
.children
|
||||||
.get(fqn_parts[0])
|
.get(&fqn_parts[0])
|
||||||
.and_then(|child_tree| child_tree.find_function(&fqn_parts[1..])),
|
.and_then(|child_tree| child_tree.find_function(&fqn_parts[1..])),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,6 +63,15 @@ impl SymbolTree {
|
|||||||
self.recurse_register_module(&module_symbol.borrow().fqn_parts());
|
self.recurse_register_module(&module_symbol.borrow().fqn_parts());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn register_module_by_fqn_parts(&mut self, fqn_parts: &[&str]) {
|
||||||
|
self.recurse_register_module(
|
||||||
|
&fqn_parts
|
||||||
|
.iter()
|
||||||
|
.map(|part| Rc::from(*part))
|
||||||
|
.collect::<Vec<Rc<str>>>(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn recurse_register_module(&mut self, fqn_parts: &[Rc<str>]) {
|
fn recurse_register_module(&mut self, fqn_parts: &[Rc<str>]) {
|
||||||
if fqn_parts.len() == 0 {
|
if fqn_parts.len() == 0 {
|
||||||
panic!("Unable to register module fqn with no parts.")
|
panic!("Unable to register module fqn with no parts.")
|
||||||
@ -79,15 +90,19 @@ impl SymbolTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_function(&mut self, function_symbol: Rc<RefCell<FunctionSymbol>>) {
|
pub fn register_function(&mut self, function_symbol: Rc<RefCell<FunctionSymbol>>) {
|
||||||
let fqn_parts = function_symbol.borrow().fqn_parts_owned();
|
let fqn_parts = function_symbol.borrow().fqn_parts_owned();
|
||||||
self.recurse_register_function(function_symbol, &fqn_parts);
|
self.recurse_register_function(function_symbol, &fqn_parts);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recurse_register_function(&mut self, function_symbol: Rc<RefCell<FunctionSymbol>>, fqn_parts: &[Rc<str>]) {
|
fn recurse_register_function(
|
||||||
|
&mut self,
|
||||||
|
function_symbol: Rc<RefCell<FunctionSymbol>>,
|
||||||
|
fqn_parts: &[Rc<str>],
|
||||||
|
) {
|
||||||
if fqn_parts.len() == 0 {
|
if fqn_parts.len() == 0 {
|
||||||
panic!("Unable to register function fqn with no parts.")
|
panic!("Unable to register function fqn with no parts.");
|
||||||
}
|
}
|
||||||
if fqn_parts.len() == 1 {
|
if fqn_parts.len() == 1 {
|
||||||
self.functions.insert(fqn_parts[0].clone(), function_symbol);
|
self.functions.insert(fqn_parts[0].clone(), function_symbol);
|
||||||
@ -100,5 +115,33 @@ impl SymbolTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_all_by_base_fqn(
|
||||||
|
&self,
|
||||||
|
fqn_parts: &[Rc<str>],
|
||||||
|
) -> Result<Vec<UsableSymbol>, SymbolLookupError> {
|
||||||
|
match fqn_parts.len() {
|
||||||
|
0 => {
|
||||||
|
let mut all_symbols: Vec<UsableSymbol> = vec![];
|
||||||
|
for interface_symbol in self.interfaces.values() {
|
||||||
|
all_symbols.push(UsableSymbol::Interface(interface_symbol.clone()));
|
||||||
|
}
|
||||||
|
for class_symbol in self.classes.values() {
|
||||||
|
all_symbols.push(UsableSymbol::Class(class_symbol.clone()));
|
||||||
|
}
|
||||||
|
for function_symbol in self.functions.values() {
|
||||||
|
all_symbols.push(UsableSymbol::Function(function_symbol.clone()));
|
||||||
|
}
|
||||||
|
Ok(all_symbols)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if self.children.contains_key(fqn_parts[0].as_ref()) {
|
||||||
|
let child = self.children.get(fqn_parts[0].as_ref()).unwrap();
|
||||||
|
child.find_all_by_base_fqn(fqn_parts)
|
||||||
|
} else {
|
||||||
|
Err(SymbolLookupError::NoSuchNamespace)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,11 +45,19 @@ pub fn handle_lookup_error(
|
|||||||
match err {
|
match err {
|
||||||
SymbolLookupError::NoDefinition => {
|
SymbolLookupError::NoDefinition => {
|
||||||
let diagnostic = Diagnostic::error()
|
let diagnostic = Diagnostic::error()
|
||||||
.with_message(format!("No such symbol '{}' in scope.", error_symbol_name,))
|
.with_message(format!("No such symbol '{}' in scope.", error_symbol_name))
|
||||||
.with_label(
|
.with_label(
|
||||||
Label::primary(error_file_id, error_range).with_message("Symbol used here."),
|
Label::primary(error_file_id, error_range).with_message("Symbol used here."),
|
||||||
);
|
);
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
|
},
|
||||||
|
SymbolLookupError::NoSuchNamespace => {
|
||||||
|
let diagnostic = Diagnostic::error()
|
||||||
|
.with_message(format!("No such namespace '{}' found", error_symbol_name))
|
||||||
|
.with_label(
|
||||||
|
Label::primary(error_file_id, error_range).with_message("Namespace used here.")
|
||||||
|
);
|
||||||
|
diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,17 +60,17 @@ FullyQualifiedName:
|
|||||||
vec:
|
vec:
|
||||||
rule: Identifier
|
rule: Identifier
|
||||||
- file_id:
|
- file_id:
|
||||||
special:
|
special:
|
||||||
kind: file_id
|
kind: file_id
|
||||||
- range:
|
- range:
|
||||||
special:
|
special:
|
||||||
kind: range
|
kind: range
|
||||||
derive:
|
derive:
|
||||||
- PartialEq
|
- PartialEq
|
||||||
- Eq
|
- Eq
|
||||||
- Hash
|
- Hash
|
||||||
IdentifierOrFqn:
|
IdentifierOrFqn:
|
||||||
tree_enum:
|
tree_enum:
|
||||||
rules:
|
rules:
|
||||||
- Identifier
|
- Identifier
|
||||||
- FullyQualifiedName
|
- FullyQualifiedName
|
||||||
@ -281,6 +281,10 @@ StarUseStatement:
|
|||||||
- range:
|
- range:
|
||||||
special:
|
special:
|
||||||
kind: range
|
kind: range
|
||||||
|
fields:
|
||||||
|
- symbol:
|
||||||
|
kind: StarUseSymbol
|
||||||
|
wrap: rc_ref_cell
|
||||||
UseStatementPrefix:
|
UseStatementPrefix:
|
||||||
struct:
|
struct:
|
||||||
children:
|
children:
|
||||||
@ -605,6 +609,9 @@ FunctionEqualsBody:
|
|||||||
struct:
|
struct:
|
||||||
children:
|
children:
|
||||||
- expression
|
- expression
|
||||||
|
fields:
|
||||||
|
- scope_id:
|
||||||
|
kind: usize
|
||||||
FunctionAliasBody:
|
FunctionAliasBody:
|
||||||
struct:
|
struct:
|
||||||
children:
|
children:
|
||||||
@ -612,6 +619,12 @@ FunctionAliasBody:
|
|||||||
skip:
|
skip:
|
||||||
rule: Alias
|
rule: Alias
|
||||||
- identifier
|
- identifier
|
||||||
|
fields:
|
||||||
|
- scope_id:
|
||||||
|
kind: usize
|
||||||
|
- resolved_function_symbol:
|
||||||
|
kind: FunctionSymbol
|
||||||
|
wrap: rc_ref_cell
|
||||||
FunctionBlockBody:
|
FunctionBlockBody:
|
||||||
struct:
|
struct:
|
||||||
children:
|
children:
|
||||||
@ -621,6 +634,9 @@ FunctionBlockBody:
|
|||||||
- end_kw:
|
- end_kw:
|
||||||
skip:
|
skip:
|
||||||
rule: End
|
rule: End
|
||||||
|
fields:
|
||||||
|
- scope_id:
|
||||||
|
kind: usize
|
||||||
|
|
||||||
# Class constructs
|
# Class constructs
|
||||||
ClassConstructor:
|
ClassConstructor:
|
||||||
@ -677,6 +693,10 @@ VariableDeclaration:
|
|||||||
- expression:
|
- expression:
|
||||||
member:
|
member:
|
||||||
optional: true
|
optional: true
|
||||||
|
fields:
|
||||||
|
- variable_symbol:
|
||||||
|
kind: VariableSymbol
|
||||||
|
wrap: rc_ref_cell
|
||||||
AssignmentStatement:
|
AssignmentStatement:
|
||||||
struct:
|
struct:
|
||||||
children:
|
children:
|
||||||
@ -782,10 +802,9 @@ VariableUse:
|
|||||||
struct:
|
struct:
|
||||||
children:
|
children:
|
||||||
- identifier
|
- identifier
|
||||||
derive:
|
fields:
|
||||||
- PartialEq
|
- lv_symbol:
|
||||||
- Eq
|
kind: LVSymbol
|
||||||
- Hash
|
|
||||||
|
|
||||||
# Expressions
|
# Expressions
|
||||||
Expression:
|
Expression:
|
||||||
|
|||||||
@ -7,11 +7,16 @@ use std::cell::RefCell;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> {
|
pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> {
|
||||||
|
symbol_table.register_module(&["std"]);
|
||||||
|
symbol_table.register_module(&["std", "core"]);
|
||||||
|
|
||||||
symbol_table.set_current_fqn(&vec!["std", "core"]);
|
symbol_table.set_current_fqn(&vec!["std", "core"]);
|
||||||
|
|
||||||
let println_msg_symbol = ParameterSymbol::new("msg", None, Some(
|
let println_msg_symbol = ParameterSymbol::new(
|
||||||
TypeSymbol::Primitive(PrimitiveTypeSymbol::Any)
|
"msg",
|
||||||
));
|
None,
|
||||||
|
Some(TypeSymbol::Primitive(PrimitiveTypeSymbol::Any)),
|
||||||
|
);
|
||||||
|
|
||||||
let println_symbol = FunctionSymbol::with_parameters_and_return_type(
|
let println_symbol = FunctionSymbol::with_parameters_and_return_type(
|
||||||
&symbol_table.resolve_fqn(Rc::from("println")),
|
&symbol_table.resolve_fqn(Rc::from("println")),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user