Compare commits

..

No commits in common. "9f5e27b28932e5ac813214560a18e9d312eb76f4" and "d38b30b755ed3be6888c38cc97679ec4d172a466" have entirely different histories.

5 changed files with 34 additions and 144 deletions

View File

@ -1,12 +0,0 @@
class Greeter(fld greeting: String) {
pub fn greet() {
println(greeting);
}
}
fn main() {
let greeter = Greeter('Hello, world!');
with greeter {
greet()
}
}

View File

@ -3,4 +3,4 @@ pub mod children;
pub mod node; pub mod node;
pub mod pretty_print; pub mod pretty_print;
pub mod unparse; pub mod unparse;
pub mod walk; mod walk;

View File

@ -250,9 +250,9 @@ fn gather_parameter(
match insert_result { match insert_result {
Ok(parameter_symbol) => { Ok(parameter_symbol) => {
let mut identifier = parameter.identifier_mut(); parameter
identifier.set_scope_id(symbol_table.current_scope_id()); .identifier_mut()
identifier.set_saved_symbol(Symbol::Parameter(parameter_symbol.clone())); .set_scope_id(symbol_table.current_scope_id());
gather_type_use( gather_type_use(
parameter.type_use_mut(), parameter.type_use_mut(),
@ -694,9 +694,9 @@ fn gather_function_definition(
match insert_result { match insert_result {
Ok(function_symbol) => { Ok(function_symbol) => {
let mut identifier = function.identifier_mut(); function
identifier.set_saved_symbol(Symbol::Function(function_symbol.clone())); .identifier_mut()
identifier.set_scope_id(symbol_table.current_scope_id()); .set_scope_id(symbol_table.current_scope_id());
symbol_table.push_scope(&format!("FunctionParameterScope({})", resolved_name)); symbol_table.push_scope(&format!("FunctionParameterScope({})", resolved_name));
@ -1043,22 +1043,21 @@ fn gather_variable_declaration(
Some(identifier), Some(identifier),
)); ));
match insert_result { if let Err(err) = insert_result {
Ok(variable_symbol) => { handle_insert_error(
let mut identifier = variable_declaration.identifier_mut();
identifier.set_saved_symbol(Symbol::Variable(variable_symbol));
identifier.set_scope_id(symbol_table.current_scope_id());
}
Err(err) => handle_insert_error(
err, err,
&variable_name, &variable_name,
identifier.file_id(), identifier.file_id(),
identifier.range(), identifier.range(),
"function/variable", "function/variable",
diagnostics, diagnostics,
), )
} }
variable_declaration
.identifier_mut()
.set_scope_id(symbol_table.current_scope_id());
if let Some(initializer) = variable_declaration.initializer_mut() { if let Some(initializer) = variable_declaration.initializer_mut() {
gather_expression(initializer, symbol_table, diagnostics); gather_expression(initializer, symbol_table, diagnostics);
} }

View File

@ -55,9 +55,6 @@ pub fn analyze_names(
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::ast::node::use_statement::UseStatementLast;
use crate::ast::walk::walk_depth_first;
use crate::parser::{DeimosParser, Rule}; use crate::parser::{DeimosParser, Rule};
use crate::std_core::add_std_core_symbols; use crate::std_core::add_std_core_symbols;
use codespan_reporting::files::SimpleFiles; use codespan_reporting::files::SimpleFiles;
@ -71,7 +68,7 @@ mod tests {
sources: HashMap<&str, &str>, sources: HashMap<&str, &str>,
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,
n_diagnostics: usize, n_diagnostics: usize,
) -> Vec<CompilationUnit> { ) {
let mut files = SimpleFiles::new(); let mut files = SimpleFiles::new();
let mut compilation_units = vec![]; let mut compilation_units = vec![];
@ -86,12 +83,12 @@ mod tests {
panic!("Parsing did not consume entire input."); panic!("Parsing did not consume entire input.");
} }
compilation_units.push(build_ast(file_name, file_id, pairs.next().unwrap())); compilation_units.push(build_ast(file_name, file_id, pairs.next().unwrap()))
} }
let diagnostics = analyze_names(&mut compilation_units, symbol_table); let diagnostics = analyze_names(&mut compilation_units, symbol_table);
if diagnostics.len() != n_diagnostics { if !diagnostics.is_empty() {
let writer = StandardStream::stderr(ColorChoice::Always); let writer = StandardStream::stderr(ColorChoice::Always);
let config = term::Config::default(); let config = term::Config::default();
@ -104,88 +101,13 @@ mod tests {
assert_eq!(n_diagnostics, diagnostics.len()); assert_eq!(n_diagnostics, diagnostics.len());
compilation_units for compilation_unit in &compilation_units {
dbg!(compilation_unit);
}
} }
fn assert_no_diagnostics( fn assert_no_diagnostics(sources: HashMap<&str, &str>, symbol_table: &mut SymbolTable) {
sources: HashMap<&str, &str>, assert_number_of_diagnostics(sources, symbol_table, 0);
symbol_table: &mut SymbolTable,
) -> Vec<CompilationUnit> {
assert_number_of_diagnostics(sources, symbol_table, 0)
}
fn assert_saved_symbols(compilation_unit: &CompilationUnit) {
walk_depth_first(compilation_unit, &mut |node_ref| match node_ref {
NodeRef::Identifier(identifier) => {
if identifier.saved_symbol().is_none() {
panic!("{:?} does not have a saved symbol.", identifier)
}
}
NodeRef::FullyQualifiedName(fqn) => {
if fqn.saved_symbol().is_none() {
panic!("{:?} does not have a saved symbol.", fqn)
}
}
NodeRef::UseStatement(use_statement) => match use_statement.last() {
UseStatementLast::Identifier(identifier) => {
if identifier.saved_symbol().is_none() {
panic!(
"UseStatement {:?} does not have a saved symbol.",
identifier
)
}
}
UseStatementLast::Identifiers(identifiers) => {
for identifier in identifiers {
if identifier.saved_symbol().is_none() {
panic!(
"UseStatement {:?} does not have a saved symbol.",
identifier
)
}
}
}
_ => todo!(),
},
_ => {}
})
}
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.last() {
UseStatementLast::Identifier(identifier) => {
let use_statement_symbol = identifier
.saved_symbol()
.unwrap()
.unwrap_use_statement_symbol();
let borrowed = use_statement_symbol.borrow();
if borrowed.referenced_symbol().is_none() {
panic!(
"{:?} does not have a referenced symbol.",
use_statement_symbol
)
}
}
UseStatementLast::Identifiers(identifiers) => {
for identifier in identifiers {
let use_statement_symbol = identifier
.saved_symbol()
.unwrap()
.unwrap_use_statement_symbol();
let borrowed = use_statement_symbol.borrow();
if borrowed.referenced_symbol().is_none() {
panic!(
"{:?} does not have a referenced symbol.",
use_statement_symbol
)
}
}
}
_ => todo!(),
},
_ => {}
})
} }
#[test] #[test]
@ -198,10 +120,7 @@ mod tests {
}"}, }"},
)]); )]);
let cus = assert_no_diagnostics(sources, &mut SymbolTable::new()); assert_no_diagnostics(sources, &mut SymbolTable::new());
for ref cu in cus {
assert_saved_symbols(cu);
}
} }
#[test] #[test]
@ -223,11 +142,7 @@ mod tests {
), ),
]); ]);
let cus = assert_no_diagnostics(sources, &mut SymbolTable::new()); assert_no_diagnostics(sources, &mut SymbolTable::new());
for ref cu in cus {
assert_saved_symbols(cu);
assert_resolved_symbols(cu);
}
} }
#[test] #[test]
@ -243,11 +158,7 @@ mod tests {
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 cus = assert_no_diagnostics(sources, &mut symbol_table); assert_no_diagnostics(sources, &mut symbol_table);
for ref cu in cus {
assert_saved_symbols(cu);
assert_resolved_symbols(cu);
}
} }
#[test] #[test]
@ -283,11 +194,7 @@ mod tests {
), ),
]); ]);
let mut symbol_table = SymbolTable::new(); let mut symbol_table = SymbolTable::new();
let cus = assert_no_diagnostics(sources, &mut symbol_table); assert_no_diagnostics(sources, &mut symbol_table);
for ref cu in cus {
assert_saved_symbols(cu);
assert_resolved_symbols(cu);
}
} }
#[test] #[test]

View File

@ -311,31 +311,27 @@ impl SymbolTable {
pub fn insert_variable_symbol( pub fn insert_variable_symbol(
&mut self, &mut self,
variable_symbol: VariableSymbol, variable_symbol: VariableSymbol,
) -> Result<Rc<VariableSymbol>, SymbolInsertError> { ) -> Result<(), SymbolInsertError> {
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap(); let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
if let Some(defined_symbol) = if let Some(defined_symbol) =
current_scope.get_value_symbol_by_declared_name(variable_symbol.declared_name()) current_scope.get_value_symbol_by_declared_name(variable_symbol.declared_name())
{ {
Err(SymbolAlreadyDefined(defined_symbol)) Err(SymbolAlreadyDefined(defined_symbol))
} else { } else {
let declared_name = variable_symbol.declared_name().to_string(); current_scope.variable_symbols.insert(
let to_insert = Rc::new(variable_symbol); variable_symbol.declared_name().to_string(),
let to_return = to_insert.clone(); Rc::new(variable_symbol),
current_scope );
.variable_symbols Ok(())
.insert(declared_name, to_insert);
Ok(to_return)
} }
} }
pub fn insert_class_member_symbol( pub fn insert_class_member_symbol(
&mut self, &mut self,
class_member_symbol: ClassMemberSymbol, class_member_symbol: ClassMemberSymbol,
) -> Result<(), SymbolInsertError> { ) -> Result<(), SymbolInsertError> {
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap(); let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
if let Some(defined_symbol) = if let Some(defined_symbol) = current_scope.get_expressible_by_declared_name(class_member_symbol.declared_name()) {
current_scope.get_expressible_by_declared_name(class_member_symbol.declared_name())
{
Err(SymbolAlreadyDefined(defined_symbol)) Err(SymbolAlreadyDefined(defined_symbol))
} else { } else {
current_scope.class_member_symbols.insert( current_scope.class_member_symbols.insert(