Begin name-analysis testing.
This commit is contained in:
parent
4224055860
commit
dda86f75e7
@ -1,6 +1,6 @@
|
|||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
use crate::name_analysis::symbol::Symbol;
|
|
||||||
|
|
||||||
pub mod build;
|
pub mod build;
|
||||||
pub mod named;
|
pub mod named;
|
||||||
@ -241,8 +241,8 @@ impl Default for Parameters {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Parameter {
|
pub struct Parameter {
|
||||||
identifier: Identifier,
|
pub identifier: Identifier,
|
||||||
type_use: TypeUse,
|
pub type_use: TypeUse,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return Type */
|
/* Return Type */
|
||||||
|
@ -50,11 +50,50 @@ fn gather_function_definition(
|
|||||||
.set_scope_id(symbol_table.current_scope_id());
|
.set_scope_id(symbol_table.current_scope_id());
|
||||||
|
|
||||||
symbol_table.push_scope(&format!("FunctionScope({})", resolved_name));
|
symbol_table.push_scope(&format!("FunctionScope({})", resolved_name));
|
||||||
// TODO: params
|
gather_parameters(
|
||||||
|
&mut function.parameters,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
gather_function_body(&mut function.body, symbol_table, fqn_context, diagnostics);
|
gather_function_body(&mut function.body, symbol_table, fqn_context, diagnostics);
|
||||||
symbol_table.pop_scope();
|
symbol_table.pop_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gather_parameters(
|
||||||
|
parameters: &mut Parameters,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut DiagnosticsContainer,
|
||||||
|
) {
|
||||||
|
for parameter in &mut parameters.0 {
|
||||||
|
gather_parameter(parameter, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gather_parameter(
|
||||||
|
parameter: &mut Parameter,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut DiagnosticsContainer,
|
||||||
|
) {
|
||||||
|
let parameter_name = parameter.identifier.name();
|
||||||
|
|
||||||
|
let insert_result = symbol_table.insert(
|
||||||
|
parameter_name.to_string(),
|
||||||
|
Symbol::Variable(VariableSymbol {
|
||||||
|
name: parameter_name.to_string(),
|
||||||
|
is_mutable: false,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Err(msg) = insert_result {
|
||||||
|
diagnostics.add_error_at_identifier(&msg, ¶meter.identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter.identifier.set_scope_id(symbol_table.current_scope_id());
|
||||||
|
}
|
||||||
|
|
||||||
fn gather_function_body(
|
fn gather_function_body(
|
||||||
function_body: &mut FunctionBody,
|
function_body: &mut FunctionBody,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -63,7 +102,7 @@ fn gather_function_body(
|
|||||||
) {
|
) {
|
||||||
use crate::ast::FunctionBody::*;
|
use crate::ast::FunctionBody::*;
|
||||||
match function_body {
|
match function_body {
|
||||||
Block(block) => gather_block_statement(block, symbol_table, fqn_context, diagnostics),
|
Block(block) => gather_block_statement_inner(block, symbol_table, fqn_context, diagnostics),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,10 +114,22 @@ fn gather_block_statement(
|
|||||||
diagnostics: &mut DiagnosticsContainer,
|
diagnostics: &mut DiagnosticsContainer,
|
||||||
) {
|
) {
|
||||||
symbol_table.push_scope("BlockStatementScope");
|
symbol_table.push_scope("BlockStatementScope");
|
||||||
|
gather_block_statement(block, symbol_table, fqn_context, diagnostics);
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gather_block_statement_inner(
|
||||||
|
block: &mut BlockStatement,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut DiagnosticsContainer,
|
||||||
|
) {
|
||||||
for statement in &mut block.statements {
|
for statement in &mut block.statements {
|
||||||
gather_statement(statement, symbol_table, fqn_context, diagnostics);
|
gather_statement(statement, symbol_table, fqn_context, diagnostics);
|
||||||
}
|
}
|
||||||
symbol_table.pop_scope();
|
if let Some(expression) = &mut block.expression {
|
||||||
|
gather_expression(expression, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_statement(
|
fn gather_statement(
|
||||||
@ -124,6 +175,10 @@ fn gather_variable_declaration(
|
|||||||
variable_declaration
|
variable_declaration
|
||||||
.identifier
|
.identifier
|
||||||
.set_scope_id(symbol_table.current_scope_id());
|
.set_scope_id(symbol_table.current_scope_id());
|
||||||
|
|
||||||
|
if let Some(initializer) = &mut variable_declaration.initializer {
|
||||||
|
gather_expression(initializer, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_assign_statement(
|
fn gather_assign_statement(
|
||||||
@ -132,11 +187,15 @@ fn gather_assign_statement(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut DiagnosticsContainer,
|
diagnostics: &mut DiagnosticsContainer,
|
||||||
) {
|
) {
|
||||||
gather_expression(&mut assign_statement.lhs, symbol_table);
|
gather_expression(&mut assign_statement.lhs, symbol_table, diagnostics);
|
||||||
gather_expression(&mut assign_statement.rhs, symbol_table);
|
gather_expression(&mut assign_statement.rhs, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_expression(expression: &mut Expression, symbol_table: &mut SymbolTable) {
|
fn gather_expression(
|
||||||
|
expression: &mut Expression,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut DiagnosticsContainer,
|
||||||
|
) {
|
||||||
use crate::ast::Expression::*;
|
use crate::ast::Expression::*;
|
||||||
match expression {
|
match expression {
|
||||||
FullyQualifiedName(fully_qualified_name) => {
|
FullyQualifiedName(fully_qualified_name) => {
|
||||||
|
@ -74,3 +74,53 @@ pub fn analyze_names(
|
|||||||
|
|
||||||
diagnostics.into()
|
diagnostics.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::ast::build::build_ast;
|
||||||
|
use crate::parser::{DeimosParser, Rule};
|
||||||
|
use codespan_reporting::files::SimpleFiles;
|
||||||
|
use codespan_reporting::term;
|
||||||
|
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
||||||
|
use pest::Parser;
|
||||||
|
|
||||||
|
fn assert_no_diagnostics(src: &str) {
|
||||||
|
let parse_result = DeimosParser::parse(Rule::CompilationUnit, src);
|
||||||
|
if let Err(err) = &parse_result {
|
||||||
|
panic!("{:?}", err);
|
||||||
|
}
|
||||||
|
let compilation_unit_pair = parse_result.unwrap().next().unwrap();
|
||||||
|
let mut ast = build_ast(compilation_unit_pair);
|
||||||
|
|
||||||
|
let mut files = SimpleFiles::new();
|
||||||
|
let test_file_id = files.add("test.dm", src);
|
||||||
|
|
||||||
|
let mut symbol_table = SymbolTable::new();
|
||||||
|
|
||||||
|
let diagnostics = analyze_names(test_file_id, &mut ast, &mut symbol_table);
|
||||||
|
|
||||||
|
if !diagnostics.is_empty() {
|
||||||
|
let writer = StandardStream::stderr(ColorChoice::Always);
|
||||||
|
let config = term::Config::default();
|
||||||
|
|
||||||
|
for diagnostic in &diagnostics {
|
||||||
|
term::emit(&mut writer.lock(), &config, &files, &diagnostic).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
eprintln!("{}", symbol_table);
|
||||||
|
panic!("Diagnostics was not empty!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn params_seen() {
|
||||||
|
assert_no_diagnostics(
|
||||||
|
r#"
|
||||||
|
fn main(args: Array<String>) {
|
||||||
|
let x = args;
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user