diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 5908c69..0a71e90 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -8,27 +8,13 @@
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -161,7 +147,7 @@
-
+
@@ -251,7 +237,15 @@
1717570846946
-
+
+
+ 1717572031837
+
+
+
+ 1717572031837
+
+
diff --git a/main.why b/main.why
index 3102473..761d81c 100644
--- a/main.why
+++ b/main.why
@@ -3,6 +3,6 @@ struct A {
b: int
}
-fn main() !-> int {
+fn main() -> int {
return 12;
}
diff --git a/src/root/builtin/int.rs b/src/root/builtin/int.rs
index 2960116..39f2894 100644
--- a/src/root/builtin/int.rs
+++ b/src/root/builtin/int.rs
@@ -1,7 +1,7 @@
use unique_type_id::UniqueTypeId;
use crate::root::compiler::assembly::utils::get_qword_stack_pointer;
use crate::root::parser::parse_function::parse_literal::{LiteralToken, LiteralTokens};
-use crate::root::shared::common::{AddressedTypeRef, ByteSize, LocalAddress, TypeID};
+use crate::root::shared::common::{AddressedTypeRef, ByteSize, FunctionID, LocalAddress, TypeID};
use crate::root::shared::types::Type;
#[derive(UniqueTypeId)]
diff --git a/src/root/builtin/mod.rs b/src/root/builtin/mod.rs
index c988f12..c88c275 100644
--- a/src/root/builtin/mod.rs
+++ b/src/root/builtin/mod.rs
@@ -1,15 +1,15 @@
pub mod int;
use crate::root::builtin::int::IntType;
-use crate::root::name_resolver::name_resolvers::{GlobalDefinitionTable, ImplNode};
+use crate::root::name_resolver::name_resolvers::{GlobalDefinitionTable};
use crate::root::shared::types::Type;
pub fn register_builtin(global_table: &mut GlobalDefinitionTable) {
- let types: [(String, Box, ImplNode); 1] = [
- ("int".to_string(), Box::new(IntType{}), ImplNode::default())
+ let types: [(String, Box); 1] = [
+ ("int".to_string(), Box::new(IntType{}))
];
- for (n, t, i) in types {
- global_table.register_builtin_type(n, t, i);
+ for (n, t) in types {
+ global_table.register_builtin_type(n, t);
}
}
diff --git a/src/root/compiler/compile.rs b/src/root/compiler/compile.rs
index 33dc182..d4cdf67 100644
--- a/src/root/compiler/compile.rs
+++ b/src/root/compiler/compile.rs
@@ -5,7 +5,7 @@ use crate::root::name_resolver::name_resolvers::GlobalDefinitionTable;
use crate::root::parser::parse_function::FunctionToken;
use crate::root::shared::common::FunctionID;
-pub fn compile(global_table: GlobalDefinitionTable, unprocessed_functions: HashMap) -> Result {
+pub fn compile(mut global_table: GlobalDefinitionTable, unprocessed_functions: HashMap) -> Result {
let mut unprocessed_functions = unprocessed_functions;
let mut compiled_functions = HashMap::new();
let mut compiled_len = 0usize;
@@ -18,7 +18,7 @@ pub fn compile(global_table: GlobalDefinitionTable, unprocessed_functions: HashM
let current_function_token = unprocessed_functions.remove(¤t_function).unwrap();
- let (compiled, called_functions) = compile_function(current_function, current_function_token, &global_table)?;
+ let (compiled, called_functions) = compile_function(current_function, current_function_token, &mut global_table)?;
compiled_len += compiled.len() + 10;
compiled_functions.insert(current_function, compiled);
diff --git a/src/root/compiler/compile_evaluable.rs b/src/root/compiler/compile_evaluable.rs
index 7ac9623..e8da345 100644
--- a/src/root/compiler/compile_evaluable.rs
+++ b/src/root/compiler/compile_evaluable.rs
@@ -9,7 +9,7 @@ pub fn compile_evaluable(fid: FunctionID, et: &EvaluableToken, target: Option todo!(),
+ EvaluableTokens::Name(_, _) => todo!(),
EvaluableTokens::Literal(literal) => {
let (address, t, tid) = if let Some(target) = target {
let (address, tid) = target.dissolve();
@@ -32,6 +32,9 @@ pub fn compile_evaluable(fid: FunctionID, et: &EvaluableToken, target: Option todo!(),
- EvaluableTokens::PrefixOperator(_, _) => todo!()
+ EvaluableTokens::PrefixOperator(_, _) => todo!(),
+ EvaluableTokens::DynamicAccess(_, _) => todo!(),
+ EvaluableTokens::StaticAccess(_, _) => todo!(),
+ EvaluableTokens::FunctionCall(_, _, _) => todo!()
}
}
\ No newline at end of file
diff --git a/src/root/compiler/compile_function.rs b/src/root/compiler/compile_function.rs
index 25afda4..58cd5fd 100644
--- a/src/root/compiler/compile_function.rs
+++ b/src/root/compiler/compile_function.rs
@@ -9,24 +9,15 @@ use crate::root::parser::parse_function::parse_line::LineTokens;
use crate::root::shared::common::{FunctionID, LocalAddress};
use crate::root::shared::common::AddressedTypeRef;
-pub fn compile_function(fid: FunctionID, function: FunctionToken, global_table: &GlobalDefinitionTable) -> Result<(String, HashSet), WError> {
+pub fn compile_function(fid: FunctionID, function: FunctionToken, global_table: &mut GlobalDefinitionTable) -> Result<(String, HashSet), WError> {
let mut local_variables = Box::new(LocalVariableTable::default());
let (_location, _name, return_type, parameters, lines) = function.dissolve();
let return_type = if fid.is_main() { None } else { return_type };
- let return_type = if let Some((t, loc)) = return_type {
- Some(match global_table.resolve_global_name_to_id(&t, &loc)? {
- NameResultId::Function(_) => todo!(),
- NameResultId::Type(type_ref) => {
- if type_ref.indirection().has_indirection() {
- todo!()
- }
- type_ref
- }
- NameResultId::NotFound => todo!()
- })
+ let return_type = if let Some(t) = return_type {
+ Some(global_table.resolve_to_type_ref(&t)?)
}
else {
None
@@ -34,20 +25,11 @@ pub fn compile_function(fid: FunctionID, function: FunctionToken, global_table:
let mut param_address = LocalAddress(8);
- for ((param_name, param_name_loc), (param_type, param_type_loc)) in parameters {
- let type_ref = match global_table.resolve_global_name_to_id(¶m_type, ¶m_type_loc)? {
- NameResultId::Function(_) => todo!(),
- NameResultId::Type(type_ref) => {
- if type_ref.indirection().has_indirection() {
- todo!()
- }
- type_ref
- }
- NameResultId::NotFound => todo!()
- };
+ for (param_name, param_type) in parameters {
+ let type_ref = global_table.resolve_to_type_ref(¶m_type)?;
let size = global_table.type_definitions().get(type_ref.type_id()).unwrap().size();
- local_variables.add_existing(param_name, AddressedTypeRef::new(param_address, type_ref));
+ local_variables.add_existing(param_name.name().clone(), AddressedTypeRef::new(param_address, type_ref));
param_address += LocalAddress(size.0 as isize);
}
diff --git a/src/root/errors/name_resolver_errors.rs b/src/root/errors/name_resolver_errors.rs
index 4bb543e..0de7b10 100644
--- a/src/root/errors/name_resolver_errors.rs
+++ b/src/root/errors/name_resolver_errors.rs
@@ -15,5 +15,11 @@ pub enum NRErrors {
#[error("Function reference cannot have indirection here")]
FunctionIndirectionError,
#[error("Identifier ({0}) not found")]
- IdentifierNotFound(String)
+ IdentifierNotFound(String),
+ #[error("Expected type ({0}), found function of same name")]
+ FoundFunctionNotType(String),
+ #[error("Type ({0}) not found")]
+ TypeNotFound(String),
+ #[error("Expected type, not method or attribute")]
+ ExpectedTypeNotMethodOrAttribute
}
diff --git a/src/root/name_resolver/name_resolvers.rs b/src/root/name_resolver/name_resolvers.rs
index 6e80623..f99466f 100644
--- a/src/root/name_resolver/name_resolvers.rs
+++ b/src/root/name_resolver/name_resolvers.rs
@@ -1,7 +1,9 @@
+use std::collections::hash_map::{Iter, IterMut};
use std::collections::HashMap;
use std::path::PathBuf;
use std::rc::Rc;
use derive_getters::Getters;
+use either::{Either, Left, Right};
use crate::root::compiler::local_variable_table::LocalVariableTable;
use crate::root::errors::name_resolver_errors::NRErrors;
use crate::root::errors::name_resolver_errors::NRErrors::IdentifierNotFound;
@@ -10,75 +12,45 @@ use crate::root::name_resolver::resolve_function_signatures::FunctionSignature;
use crate::root::parser::parse::Location;
use crate::root::shared::types::Type;
use crate::root::parser::parse_function::FunctionToken;
-use crate::root::parser::parse_function::parse_evaluable::FullNameWithIndirectionToken;
+use crate::root::parser::parse_function::parse_evaluable::{FullNameToken, FullNameTokens, FullNameWithIndirectionToken};
+use crate::root::parser::parse_name::SimpleNameToken;
use crate::root::parser::parse_struct::StructToken;
use crate::root::shared::common::{AddressedTypeRef, FunctionID, TypeID, TypeRef};
-#[derive(Default)]
-pub struct ImplNode {
- functions: HashMap
+#[derive(Debug)]
+enum NameTreeEntry {
+ Type(TypeID),
+ Function(FunctionID)
}
-/// Contents of a `DefinitionTable`
-enum FileLevelTreeNode {
- Function(FunctionID),
- Type(TypeID, ImplNode),
+#[derive(Default, Debug)]
+struct NameTree {
+ table: HashMap
}
-/// Recursive tree containing all named objects/functions/types
-#[derive(Default)]
-struct FileLevelTree {
- table: HashMap
-}
-
-impl FileLevelTree {
- pub fn add_type(&mut self, name: String, id: TypeID) {
- // TODO: Handle collision
- self.table.insert(name, FileLevelTreeNode::Type(id, ImplNode::default()));
+impl NameTree {
+ pub fn add_entry(&mut self, name: String, entry: NameTreeEntry) {
+ self.table.insert(name, entry);
}
- pub fn add_function_impl(&mut self, name: String, id: FunctionID, containing_class: TypeID) -> bool {
- for (_, n) in &mut self.table {
- match n {
- FileLevelTreeNode::Function(_) => {}
- FileLevelTreeNode::Type(type_id, i) => {
- if containing_class != *type_id {
- continue;
- }
-
- i.functions.insert(name, id);
-
- return true;
- }
- }
- }
-
- return false;
- }
-
- pub fn add_function(&mut self, name: String, id: FunctionID) {
- self.table.insert(name, FileLevelTreeNode::Function(id));
+ pub fn get_entry(&self, name: &str) -> Option<&NameTreeEntry> {
+ self.table.get(name)
}
}
/// Top level of recursive tree containing all named objects/functions/types
#[derive(Default)]
struct TopLevelNameTree {
- table: HashMap, Box>
+ table: HashMap, NameTree>
}
impl TopLevelNameTree {
- pub fn get_path_tree(&mut self, path: &Rc) -> &mut Box {
- // ! Inefficient, done to make borrow checker happy
- if !self.table.contains_key(path) {
- self.table.insert(path.clone(), Box::new(FileLevelTree::default()));
+ pub fn get_tree_mut(&mut self, path: Rc) -> &mut NameTree {
+ if !self.table.contains_key(&path) {
+ self.table.insert(path.clone(), Default::default());
}
- self.table.get_mut(path).unwrap()
- }
-
- pub fn get_path_tree_fallible(&self, path: &Rc) -> Option<&Box> {
- self.table.get(path)
+ self.table.get_mut(&path).unwrap()
}
}
@@ -86,9 +58,10 @@ impl TopLevelNameTree {
pub struct GlobalDefinitionTable {
id_counter: isize,
type_definitions: HashMap>,
+ impl_definitions: HashMap>,
function_signatures: HashMap,
name_table: TopLevelNameTree,
- builtin_type_name_table: HashMap,
+ builtin_type_name_table: HashMap,
builtin_function_name_table: HashMap
}
@@ -105,16 +78,17 @@ impl GlobalDefinitionTable {
GlobalDefinitionTable {
id_counter: 1,
type_definitions: Default::default(),
+ impl_definitions: Default::default(),
function_signatures: Default::default(),
name_table: Default::default(),
builtin_type_name_table: Default::default(),
builtin_function_name_table: Default::default(),
}
}
- pub fn register_builtin_type(&mut self, name: String, t: Box, impl_node: ImplNode) {
+ pub fn register_builtin_type(&mut self, name: String, t: Box) {
let id = t.id();
self.type_definitions.insert(id, t);
- self.builtin_type_name_table.insert(name, (id, impl_node));
+ self.builtin_type_name_table.insert(name, id);
}
pub fn register_builtin_function(&mut self, name: String, t: FunctionSignature, id: FunctionID) {
@@ -123,17 +97,17 @@ impl GlobalDefinitionTable {
}
pub fn add_from_struct_token(&mut self, st: &StructToken) -> TypeID {
- let file_level_tree = self.name_table.get_path_tree(st.location().path());
+ let file_level_tree = self.name_table.get_tree_mut(st.location().path().clone());
self.id_counter += 1;
let id = TypeID(self.id_counter - 1);
- file_level_tree.add_type(st.name().clone(), id);
+ file_level_tree.add_entry(st.name().name().clone(), NameTreeEntry::Type(id));
id
}
pub fn add_from_function_token(&mut self, ft: &FunctionToken, containing_class: Option) -> FunctionID {
- let id = if ft.name() == "main" {
+ let id = if ft.name().name() == "main" {
FunctionID(0)
} else {
self.id_counter += 1;
@@ -142,16 +116,15 @@ impl GlobalDefinitionTable {
if let Some(containing_class) = containing_class {
- for (_, file_level_tree) in &mut self.name_table.table {
- if file_level_tree.add_function_impl(ft.name().clone(), id, containing_class) {
- return id;
- }
+ if !self.impl_definitions.contains_key(&containing_class) {
+ self.impl_definitions.insert(containing_class, Default::default());
}
- panic!("Class for impl not found");
+
+ self.impl_definitions.get_mut(&containing_class).unwrap().insert(ft.name().name().clone(), id);
}
else {
- let file_level_tree = self.name_table.get_path_tree(ft.location().path());
- file_level_tree.add_function(ft.name().clone(), id);
+ let file_level_tree = self.name_table.get_tree_mut(ft.location().path().clone());
+ file_level_tree.add_entry(ft.name().name().clone(), NameTreeEntry::Function(id));
}
id
@@ -165,111 +138,56 @@ impl GlobalDefinitionTable {
self.type_definitions.insert(given_id, definition);
}
- pub fn resolve_name(&self, name: &UnresolvedNameToken, local_variable_table: &LocalVariableTable) -> NameResult {
- todo!()
- }
-
- pub fn resolve_global_name(&self, name: &UnresolvedNameToken) -> NameResult {
- todo!()
- }
- pub fn resolve_global_name_to_id(&self, name: &FullNameWithIndirectionToken) -> Result {
+ pub fn resolve_to_type_ref(&mut self, name: &FullNameWithIndirectionToken) -> Result {
let (indirection, full_name) = (name.indirection(), name.inner());
- let path = name.location().path();
-
- fn search_file_level_tree(tree: &Box, name: &UnresolvedNameToken, location: &Location) -> Result