WIP.
This commit is contained in:
parent
4dd3140538
commit
0b270c186b
@ -159,17 +159,26 @@ impl CompilationUnit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Associate each declared symbol with a TypeInfo.
|
/// Associate each declared symbol with a TypeInfo.
|
||||||
pub fn declared_types(&self, names_table: &NodesToSymbols) -> (SymbolsToTypes, Diagnostics) {
|
pub fn declared_types(
|
||||||
|
&self,
|
||||||
|
nodes_to_symbols: &NodesToSymbols,
|
||||||
|
) -> (SymbolsToTypes, Diagnostics) {
|
||||||
let mut diagnostics = Diagnostics::new();
|
let mut diagnostics = Diagnostics::new();
|
||||||
let mut declared_types = SymbolsToTypes::new();
|
let mut symbols_to_types = SymbolsToTypes::new();
|
||||||
|
|
||||||
for function in &self.functions {
|
for function in &self.functions {
|
||||||
let (dts, mut ds) = function.declared_types(names_table);
|
let (sts, mut ds) = function.declared_types(nodes_to_symbols);
|
||||||
insert_declared_types_into(dts, &mut declared_types);
|
insert_declared_types_into(sts, &mut symbols_to_types);
|
||||||
diagnostics.append(&mut ds);
|
diagnostics.append(&mut ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
(declared_types, diagnostics)
|
for extern_function in &self.extern_functions {
|
||||||
|
let (sts, mut ds) = extern_function.declared_types(nodes_to_symbols);
|
||||||
|
insert_declared_types_into(sts, &mut symbols_to_types);
|
||||||
|
diagnostics.append(&mut ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
(symbols_to_types, diagnostics)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve types of all nodes that have an implicit (perhaps not declared) type, checking that
|
/// Resolve types of all nodes that have an implicit (perhaps not declared) type, checking that
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use crate::ast::helpers::{
|
|||||||
};
|
};
|
||||||
use crate::ast::parameter::Parameter;
|
use crate::ast::parameter::Parameter;
|
||||||
use crate::ast::type_use::TypeUse;
|
use crate::ast::type_use::TypeUse;
|
||||||
use crate::ast::{NodeId, NodesToSymbols};
|
use crate::ast::{NodeId, NodesToSymbols, SymbolsToTypes};
|
||||||
use crate::diagnostic::{Diagnostic, Diagnostics};
|
use crate::diagnostic::{Diagnostic, Diagnostics};
|
||||||
use crate::source_range::SourceRange;
|
use crate::source_range::SourceRange;
|
||||||
use crate::symbol::Symbol;
|
use crate::symbol::Symbol;
|
||||||
@ -105,6 +105,23 @@ impl ExternFunction {
|
|||||||
(names_table, diagnostics)
|
(names_table, diagnostics)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn declared_types(
|
||||||
|
&self,
|
||||||
|
nodes_to_symbols: &NodesToSymbols,
|
||||||
|
) -> (SymbolsToTypes, Diagnostics) {
|
||||||
|
let mut diagnostics = Diagnostics::new();
|
||||||
|
let mut symbols_to_types = SymbolsToTypes::new();
|
||||||
|
|
||||||
|
for parameter in &self.parameters {
|
||||||
|
let (type_info, mut ds) = parameter.declared_type(nodes_to_symbols);
|
||||||
|
let parameter_symbol = nodes_to_symbols.get(¶meter.node_id()).unwrap();
|
||||||
|
symbols_to_types.insert(parameter_symbol.clone(), type_info);
|
||||||
|
diagnostics.append(&mut ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
(symbols_to_types, diagnostics)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn check_names(&self, symbol_table: &SymbolTable) -> Vec<Diagnostic> {
|
pub fn check_names(&self, symbol_table: &SymbolTable) -> Vec<Diagnostic> {
|
||||||
let mut diagnostics: Vec<Diagnostic> = Vec::new();
|
let mut diagnostics: Vec<Diagnostic> = Vec::new();
|
||||||
for parameter in &self.parameters {
|
for parameter in &self.parameters {
|
||||||
|
|||||||
@ -150,6 +150,12 @@ impl Function {
|
|||||||
diagnostics.append(&mut ds);
|
diagnostics.append(&mut ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// insert self function symbol with this node
|
||||||
|
let function_symbol = symbol_table
|
||||||
|
.get_function_symbol_owned(self.container_scope_id.unwrap(), &self.declared_name)
|
||||||
|
.unwrap();
|
||||||
|
nodes_to_symbols.insert(self.node_id, Symbol::Function(function_symbol));
|
||||||
|
|
||||||
(nodes_to_symbols, diagnostics)
|
(nodes_to_symbols, diagnostics)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -512,11 +512,11 @@ impl Identifier {
|
|||||||
|
|
||||||
pub fn resolve_type(
|
pub fn resolve_type(
|
||||||
&self,
|
&self,
|
||||||
resolved_symbols: &NodesToSymbols,
|
nodes_to_symbols: &NodesToSymbols,
|
||||||
resolved_symbol_type_infos: &SymbolsToTypes,
|
symbols_to_types: &SymbolsToTypes,
|
||||||
) -> (NodesToTypes, Diagnostics) {
|
) -> (NodesToTypes, Diagnostics) {
|
||||||
let self_symbol = resolved_symbols.get(&self.node_id).unwrap();
|
let self_symbol = nodes_to_symbols.get(&self.node_id).unwrap();
|
||||||
let type_info = resolved_symbol_type_infos.get(self_symbol).unwrap();
|
let type_info = symbols_to_types.get(self_symbol).unwrap();
|
||||||
|
|
||||||
let mut resolved_types = NodesToTypes::new();
|
let mut resolved_types = NodesToTypes::new();
|
||||||
resolved_types.insert(self.node_id, type_info.clone());
|
resolved_types.insert(self.node_id, type_info.clone());
|
||||||
|
|||||||
@ -30,14 +30,13 @@ fn parse_compilation_units(
|
|||||||
|
|
||||||
pub fn compile_compilation_units(
|
pub fn compile_compilation_units(
|
||||||
inputs: &HashMap<FileId, &str>,
|
inputs: &HashMap<FileId, &str>,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
) -> Result<(Vec<IrClass>, Vec<IrFunction>), Diagnostics> {
|
) -> Result<(Vec<IrClass>, Vec<IrFunction>), Diagnostics> {
|
||||||
let mut compilation_units = parse_compilation_units(inputs)?;
|
let mut compilation_units = parse_compilation_units(inputs)?;
|
||||||
|
|
||||||
let mut symbol_table = SymbolTable::new();
|
|
||||||
|
|
||||||
// init scopes
|
// init scopes
|
||||||
for compilation_unit in compilation_units.values_mut() {
|
for compilation_unit in compilation_units.values_mut() {
|
||||||
compilation_unit.init_scopes(&mut symbol_table);
|
compilation_unit.init_scopes(symbol_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
// gather unordered symbols
|
// gather unordered symbols
|
||||||
@ -45,14 +44,14 @@ pub fn compile_compilation_units(
|
|||||||
.values()
|
.values()
|
||||||
.flat_map(|compilation_unit| compilation_unit.declared_symbols())
|
.flat_map(|compilation_unit| compilation_unit.declared_symbols())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
try_insert_symbols_into(all_symbols, &mut symbol_table)?;
|
try_insert_symbols_into(all_symbols, symbol_table)?;
|
||||||
|
|
||||||
// now we can just finish each compilation unit, since we have the symbols
|
// now we can just finish each compilation unit, since we have the symbols
|
||||||
let mut ir_classes = Vec::new();
|
let mut ir_classes = Vec::new();
|
||||||
let mut ir_functions = Vec::new();
|
let mut ir_functions = Vec::new();
|
||||||
let mut diagnostics = Vec::new();
|
let mut diagnostics = Vec::new();
|
||||||
for compilation_unit in compilation_units.values() {
|
for compilation_unit in compilation_units.values() {
|
||||||
let (nodes_to_symbols, mut ds) = compilation_unit.resolve_names(&mut symbol_table);
|
let (nodes_to_symbols, mut ds) = compilation_unit.resolve_names(symbol_table);
|
||||||
|
|
||||||
// in the future, we'll ideally be able to *actually* continue with the following steps
|
// in the future, we'll ideally be able to *actually* continue with the following steps
|
||||||
// instead of aborting here, but this needs to be tested :)
|
// instead of aborting here, but this needs to be tested :)
|
||||||
@ -85,5 +84,63 @@ pub fn compile_compilation_units(
|
|||||||
ir_functions.append(&mut functions);
|
ir_functions.append(&mut functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((ir_classes, ir_functions))
|
if diagnostics.is_empty() {
|
||||||
|
Ok((ir_classes, ir_functions))
|
||||||
|
} else {
|
||||||
|
Err(diagnostics)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::symbol::class_symbol::ClassSymbol;
|
||||||
|
|
||||||
|
fn prepare_symbol_table(symbol_table: &mut SymbolTable) {
|
||||||
|
let global_scope = symbol_table.push_module_scope("global scope");
|
||||||
|
let any_symbol = ClassSymbol::new(
|
||||||
|
&"Any".into(),
|
||||||
|
None,
|
||||||
|
vec!["Any".into()],
|
||||||
|
false,
|
||||||
|
global_scope,
|
||||||
|
Vec::new(),
|
||||||
|
None,
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
);
|
||||||
|
symbol_table.insert_class_symbol(Rc::new(any_symbol));
|
||||||
|
|
||||||
|
let void_symbol = ClassSymbol::new(
|
||||||
|
&"Void".into(),
|
||||||
|
None,
|
||||||
|
vec!["Void".into()],
|
||||||
|
false,
|
||||||
|
global_scope,
|
||||||
|
Vec::new(),
|
||||||
|
None,
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
);
|
||||||
|
symbol_table.insert_class_symbol(Rc::new(void_symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hello_world() -> Result<(), Diagnostics> {
|
||||||
|
let input = "
|
||||||
|
extern fn println(msg: Any) -> Void
|
||||||
|
|
||||||
|
fn main()
|
||||||
|
println(\"Hello, World!\")
|
||||||
|
end
|
||||||
|
";
|
||||||
|
let mut inputs = HashMap::new();
|
||||||
|
inputs.insert(0, input);
|
||||||
|
let mut symbol_table = SymbolTable::new();
|
||||||
|
prepare_symbol_table(&mut symbol_table);
|
||||||
|
let (ir_classes, ir_functions) = compile_compilation_units(&inputs, &mut symbol_table)?;
|
||||||
|
assert_eq!(ir_classes.len(), 0);
|
||||||
|
assert_eq!(ir_functions.len(), 1);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user