diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 0bd73f0..965a4cf 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -7,14 +7,7 @@ - - - - - - - - + - { + "keyToString": { + "Cargo.Run whython-8.executor": "Run", + "RunOnceActivity.OpenProjectViewOnStart": "true", + "RunOnceActivity.ShowReadmeOnStart": "true", + "RunOnceActivity.rust.reset.selective.auto.import": "true", + "git-widget-placeholder": "master", + "ignore.virus.scanning.warn.message": "true", + "node.js.detected.package.eslint": "true", + "node.js.detected.package.tslint": "true", + "node.js.selected.package.eslint": "(autodetect)", + "node.js.selected.package.tslint": "(autodetect)", + "nodejs_package_manager_path": "npm", + "org.rust.cargo.project.model.PROJECT_DISCOVERY": "true", + "org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "", + "org.rust.first.attach.projects": "true", + "settings.editor.selected.configurable": "reference.settingsdialog.IDE.editor.colors.Rust", + "vue.rearranger.settings.migration": "true" } -}]]> +} diff --git a/Cargo.lock b/Cargo.lock index 05c09ba..dcc7964 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,6 +151,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "derive-getters" version = "0.3.0" @@ -162,6 +168,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + [[package]] name = "either" version = "1.12.0" @@ -287,6 +306,15 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "rustversion" version = "1.0.17" @@ -302,6 +330,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + [[package]] name = "strsim" version = "0.11.1" @@ -428,6 +462,7 @@ dependencies = [ "clap", "color-print", "derive-getters", + "derive_more", "either", "itertools", "lazy_static", diff --git a/Cargo.toml b/Cargo.toml index 031d848..bee8ea2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ nom_locate = "4.2.0" nom-supreme = "0.8.0" substring = "1.4.5" derive-getters = "0.3.0" +derive_more = "0.99.17" [profile.release] opt-level = 3 diff --git a/src/root.rs b/src/root.rs index 99c0c85..53fa25a 100644 --- a/src/root.rs +++ b/src/root.rs @@ -9,6 +9,7 @@ use std::fs; use std::io::ErrorKind; use std::path::PathBuf; use crate::root::name_resolver::resolve::resolve; +use crate::root::shared::types::ByteSize; // #[cfg(target_os = "windows")] // use crate::root::runner::run; @@ -27,8 +28,9 @@ pub mod utils; pub mod name_resolver; pub mod builtin; pub mod shared; +pub mod compiler; -pub const POINTER_SIZE: usize = 8; +pub const POINTER_SIZE: ByteSize = ByteSize(8); /// Compiler for Whython files (.why) #[derive(Parser)] diff --git a/src/root/builtin/int.rs b/src/root/builtin/int.rs index 3933fe7..7503b2d 100644 --- a/src/root/builtin/int.rs +++ b/src/root/builtin/int.rs @@ -1,16 +1,16 @@ use unique_type_id::UniqueTypeId; -use crate::root::shared::types::Type; +use crate::root::shared::types::{ByteSize, Type, TypeID}; #[derive(UniqueTypeId)] #[UniqueTypeIdType = "u16"] pub struct IntType {} impl Type for IntType { - fn id(&self) -> isize { - -(IntType::unique_type_id().0 as isize) - 1 + fn id(&self) -> TypeID { + TypeID(-(IntType::unique_type_id().0 as isize) - 1) } - fn size(&self) -> usize { - 8 + fn size(&self) -> ByteSize { + ByteSize(8) } } \ No newline at end of file diff --git a/src/root/compiler/mod.rs b/src/root/compiler/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/root/name_resolver/name_resolvers.rs b/src/root/name_resolver/name_resolvers.rs index 98af483..90f66c7 100644 --- a/src/root/name_resolver/name_resolvers.rs +++ b/src/root/name_resolver/name_resolvers.rs @@ -2,22 +2,21 @@ use std::collections::HashMap; use std::path::PathBuf; use std::rc::Rc; use derive_getters::Getters; -use crate::root::name_resolver::resolve::{AddressedTypeRef, TypeRef}; use crate::root::name_resolver::resolve_function_signatures::FunctionSignature; -use crate::root::shared::types::Type; +use crate::root::shared::types::{AddressedTypeRef, FunctionID, Type, TypeID, TypeRef}; use crate::root::parser::parse_function::FunctionToken; -use crate::root::parser::parse_name::{NameConnectors, UnresolvedNameToken}; +use crate::root::parser::parse_name::UnresolvedNameToken; use crate::root::parser::parse_struct::StructToken; #[derive(Default)] pub struct ImplNode { - functions: HashMap + functions: HashMap } /// Contents of a `DefinitionTable` enum FileLevelTreeNode { - Function(isize), - Type(isize, ImplNode), + Function(FunctionID), + Type(TypeID, ImplNode), } /// Recursive tree containing all named objects/functions/types @@ -27,12 +26,12 @@ struct FileLevelTree { } impl FileLevelTree { - pub fn add_type(&mut self, name: String, id: isize) { + pub fn add_type(&mut self, name: String, id: TypeID) { // TODO: Handle collision self.table.insert(name, FileLevelTreeNode::Type(id, ImplNode::default())); } - pub fn add_function_impl(&mut self, name: String, id: isize, containing_class: isize) -> bool { + 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(_) => {} @@ -51,7 +50,7 @@ impl FileLevelTree { return false; } - pub fn add_function(&mut self, name: String, id: isize) { + pub fn add_function(&mut self, name: String, id: FunctionID) { self.table.insert(name, FileLevelTreeNode::Function(id)); } } @@ -95,7 +94,7 @@ impl LocalVariableTable { } } - pub fn get_ref_and_type<'a>(&self, name: &str, type_defs: &'a HashMap>) -> Option<(AddressedTypeRef, &'a dyn Type)> { + pub fn get_ref_and_type<'a>(&self, name: &str, type_defs: &'a HashMap>) -> Option<(AddressedTypeRef, &'a dyn Type)> { if let Some(r) = self.table.get(name) { if let Some(t) = type_defs.get(r.type_ref().type_id()) { return Some((r.clone(), t.as_ref())); @@ -111,11 +110,11 @@ impl LocalVariableTable { #[derive(Getters)] pub struct GlobalDefinitionTable { id_counter: isize, - type_definitions: HashMap>, - function_signatures: HashMap, + type_definitions: HashMap>, + function_signatures: HashMap, name_table: TopLevelNameTree, - builtin_type_name_table: HashMap, - builtin_function_name_table: HashMap + builtin_type_name_table: HashMap, + builtin_function_name_table: HashMap } @@ -127,7 +126,7 @@ pub enum NameResult<'a> { } pub enum NameResultId { - Function(isize), + Function(FunctionID), Type(TypeRef), NotFound } @@ -149,27 +148,27 @@ impl GlobalDefinitionTable { self.builtin_type_name_table.insert(name, (id, impl_node)); } - pub fn register_builtin_function(&mut self, name: String, t: FunctionSignature, id: isize) { + pub fn register_builtin_function(&mut self, name: String, t: FunctionSignature, id: FunctionID) { self.function_signatures.insert(id, t); self.builtin_function_name_table.insert(name, id); } - pub fn add_from_struct_token(&mut self, st: &StructToken) -> isize { + pub fn add_from_struct_token(&mut self, st: &StructToken) -> TypeID { let file_level_tree = self.name_table.get_path_tree(st.location().path()); self.id_counter += 1; - let id = self.id_counter - 1; + let id = TypeID(self.id_counter - 1); file_level_tree.add_type(st.name().clone(), id); id } - pub fn add_from_function_token(&mut self, ft: &FunctionToken, containing_class: Option) -> isize { + pub fn add_from_function_token(&mut self, ft: &FunctionToken, containing_class: Option) -> FunctionID { let id = if ft.name() == "main" { - 0 + FunctionID(0) } else { self.id_counter += 1; - self.id_counter - 1 + FunctionID(self.id_counter - 1) }; @@ -189,11 +188,11 @@ impl GlobalDefinitionTable { id } - pub fn add_function_signature(&mut self, given_id: isize, function_signature: FunctionSignature) { + pub fn add_function_signature(&mut self, given_id: FunctionID, function_signature: FunctionSignature) { self.function_signatures.insert(given_id, function_signature); } - pub fn add_type(&mut self, given_id: isize, definition: Box) { + pub fn add_type(&mut self, given_id: TypeID, definition: Box) { // TODO: handle collisions self.type_definitions.insert(given_id, definition); } @@ -237,7 +236,7 @@ impl GlobalDefinitionTable { match base { FileLevelTreeNode::Function(fid) => { - if name_iter.next().is_some() || *name.indirection() > 0 { + if name_iter.next().is_some() || name.indirection().has_indirection() { // TODO return Err(()); } @@ -320,7 +319,7 @@ impl GlobalDefinitionTable { if let Some(id) = self.builtin_function_name_table.get(name.base()) { // TODO - if !name.names().is_empty() || *name.indirection() != 0 { + if !name.names().is_empty() || name.indirection().has_indirection() { return Err(()); } diff --git a/src/root/name_resolver/resolve.rs b/src/root/name_resolver/resolve.rs index f84b7e9..0d6d2b3 100644 --- a/src/root/name_resolver/resolve.rs +++ b/src/root/name_resolver/resolve.rs @@ -1,40 +1,16 @@ -use derive_getters::Getters; use crate::root::builtin::register_builtin; use crate::root::name_resolver::name_resolvers::GlobalDefinitionTable; use crate::root::name_resolver::resolve_names::resolve_names; use crate::root::parser::parse_function::FunctionToken; use crate::root::parser::parse_toplevel::TopLevelTokens; +use crate::root::shared::types::FunctionID; -#[derive(Getters, Clone)] -pub struct TypeRef { - type_id: isize, - indirection: usize -} - -impl TypeRef { - pub fn new(type_id: isize, indirection: usize) -> TypeRef { - TypeRef { type_id, indirection } - } -} - -#[derive(Getters, Clone)] -pub struct AddressedTypeRef { - local_address: isize, - type_ref: TypeRef -} - -impl AddressedTypeRef { - pub fn new(local_address: isize, type_ref: TypeRef) -> AddressedTypeRef { - AddressedTypeRef { local_address, type_ref } - } -} - -pub fn resolve(ast: Vec) -> (GlobalDefinitionTable, Vec<(isize, FunctionToken)>) { +pub fn resolve(ast: Vec) -> (GlobalDefinitionTable, Vec<(FunctionID, FunctionToken)>) { let mut global_table = GlobalDefinitionTable::new(); register_builtin(&mut global_table); let unprocessed_functions = resolve_names(ast, &mut global_table); - if !global_table.function_signatures().contains_key(&0) { + if !global_table.function_signatures().contains_key(&FunctionID(0)) { // NO MAIN! todo!() } diff --git a/src/root/name_resolver/resolve_function_signatures.rs b/src/root/name_resolver/resolve_function_signatures.rs index 7994b0f..0696b38 100644 --- a/src/root/name_resolver/resolve_function_signatures.rs +++ b/src/root/name_resolver/resolve_function_signatures.rs @@ -1,6 +1,6 @@ use derive_getters::Getters; use crate::root::name_resolver::name_resolvers::{GlobalDefinitionTable, NameResult, NameResultId}; -use crate::root::name_resolver::resolve::TypeRef; +use crate::root::shared::types::TypeRef; use crate::root::parser::parse_function::FunctionToken; #[derive(Getters)] diff --git a/src/root/name_resolver/resolve_names.rs b/src/root/name_resolver/resolve_names.rs index f47a749..e0a1c41 100644 --- a/src/root/name_resolver/resolve_names.rs +++ b/src/root/name_resolver/resolve_names.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use derive_getters::Getters; use itertools::Itertools; use crate::root::name_resolver::name_resolvers::{GlobalDefinitionTable, NameResultId}; -use crate::root::name_resolver::resolve::TypeRef; +use crate::root::shared::types::{ByteSize, FunctionID, TypeID, TypeRef}; use crate::root::name_resolver::resolve_function_signatures::resolve_function_signature; use crate::root::name_resolver::resolve_type_sizes::{resolve_type_sizes, UnsizedUserType}; use crate::root::parser::parse::Location; @@ -53,30 +53,30 @@ use crate::root::shared::types::Type; /// A whython-code-defined type #[derive(Getters)] pub struct UserType { - id: isize, - size: usize, + id: TypeID, + size: ByteSize, attributes: Vec<(usize, String, TypeRef)>, location: Location } impl UserType { - pub fn new(id: isize, size: usize, attributes: Vec<(usize, String, TypeRef)>, location: Location) -> UserType { + pub fn new(id: TypeID, size: ByteSize, attributes: Vec<(usize, String, TypeRef)>, location: Location) -> UserType { UserType { id, size, attributes, location } } } impl Type for UserType { - fn id(&self) -> isize { + fn id(&self) -> TypeID { self.id } - fn size(&self) -> usize { + fn size(&self) -> ByteSize { self.size } } // ! Unoptimised -pub fn resolve_names(ast: Vec, global_table: &mut GlobalDefinitionTable) -> Vec<(isize, FunctionToken)> { +pub fn resolve_names(ast: Vec, global_table: &mut GlobalDefinitionTable) -> Vec<(FunctionID, FunctionToken)> { let mut ast = ast; // ? User types > 1; Builtin Types < -1 @@ -97,8 +97,8 @@ pub fn resolve_names(ast: Vec, global_table: &mut GlobalDefiniti }; } - let mut unsized_final_types: HashMap = HashMap::new(); - let mut unprocessed_functions: Vec<(isize, FunctionToken)> = Vec::new(); + let mut unsized_final_types: HashMap = HashMap::new(); + let mut unprocessed_functions: Vec<(FunctionID, FunctionToken)> = Vec::new(); for symbol in ast { match symbol { @@ -129,7 +129,7 @@ pub fn resolve_names(ast: Vec, global_table: &mut GlobalDefiniti }; // TODO - if *type_ref.indirection() != 0 { + if type_ref.indirection().has_indirection() { panic!() } @@ -147,7 +147,7 @@ pub fn resolve_names(ast: Vec, global_table: &mut GlobalDefiniti }; } - let mut final_types: HashMap = HashMap::new(); + let mut final_types: HashMap = HashMap::new(); while !unsized_final_types.is_empty() { let next_type_id = *unsized_final_types.keys().next().unwrap(); diff --git a/src/root/name_resolver/resolve_type_sizes.rs b/src/root/name_resolver/resolve_type_sizes.rs index 373a053..b7c7fa0 100644 --- a/src/root/name_resolver/resolve_type_sizes.rs +++ b/src/root/name_resolver/resolve_type_sizes.rs @@ -1,31 +1,31 @@ use std::collections::HashMap; use derive_getters::{Dissolve, Getters}; use crate::root::name_resolver::name_resolvers::GlobalDefinitionTable; -use crate::root::name_resolver::resolve::TypeRef; +use crate::root::shared::types::{ByteSize, TypeID, TypeRef}; use crate::root::name_resolver::resolve_names::UserType; use crate::root::parser::parse::Location; use crate::root::POINTER_SIZE; #[derive(Dissolve)] pub struct UnsizedUserType { - id: isize, + id: TypeID, attributes: Vec<(String, TypeRef)>, location: Location } impl UnsizedUserType { - pub fn new(id: isize, attributes: Vec<(String, TypeRef)>, location: Location) -> UnsizedUserType { + pub fn new(id: TypeID, attributes: Vec<(String, TypeRef)>, location: Location) -> UnsizedUserType { UnsizedUserType { id, attributes, location } } } pub fn resolve_type_sizes( unsized_type: UnsizedUserType, - final_types: &mut HashMap, - unsized_types: &mut HashMap, + final_types: &mut HashMap, + unsized_types: &mut HashMap, global_table: &GlobalDefinitionTable, - path: &mut Vec -) -> usize { + path: &mut Vec +) -> ByteSize { let (id, attributes, location) = unsized_type.dissolve(); if path.contains(&id) { @@ -34,17 +34,17 @@ pub fn resolve_type_sizes( } path.push(id); - let mut size: usize = 0; + let mut size: ByteSize = ByteSize(0); let mut processed_attributes: Vec<(usize, String, TypeRef)> = Vec::new(); for (attribute_name, attribute_type) in attributes { let offset = size; - if *attribute_type.indirection() != 0 { + if attribute_type.indirection().has_indirection() { size += POINTER_SIZE; } else if let Some(sized_type) = final_types.get(&attribute_type.type_id()) { - size += sized_type.size(); + size += *sized_type.size(); } else { if let Some(unsized_type) = unsized_types.remove(&attribute_type.type_id()) { @@ -60,7 +60,7 @@ pub fn resolve_type_sizes( } } - processed_attributes.push((offset, attribute_name, attribute_type)); + processed_attributes.push((offset.0, attribute_name, attribute_type)); } final_types.insert(id, UserType::new(id, size, processed_attributes, location)); diff --git a/src/root/parser/parse_name.rs b/src/root/parser/parse_name.rs index dacd235..662ada8 100644 --- a/src/root/parser/parse_name.rs +++ b/src/root/parser/parse_name.rs @@ -10,6 +10,7 @@ use nom_supreme::error::{BaseErrorKind, Expectation}; use crate::root::parser::parse_arguments::parse_arguments; use crate::root::parser::parse_blocks::{default_section, section}; use crate::root::parser::parse_util::discard_ignored; +use crate::root::shared::types::Indirection; #[derive(Debug)] pub enum NameConnectors { @@ -21,7 +22,7 @@ pub enum NameConnectors { pub struct UnresolvedNameToken { location: Location, containing_class: Option, - indirection: usize, + indirection: Indirection, base: String, names: Vec<(NameConnectors, String)>, function_call: Option>, @@ -37,7 +38,7 @@ impl UnresolvedNameToken { UnresolvedNameToken { location, containing_class, - indirection: 0, + indirection: Indirection(0), base: s.to_string(), names: Vec::new(), function_call: None @@ -51,7 +52,7 @@ impl UnresolvedNameToken { UnresolvedNameToken { location, containing_class: None, - indirection: 0, + indirection: Indirection(0), base: s, names: Vec::new(), function_call: None @@ -116,7 +117,7 @@ pub fn parse_full_name(s: Span, containing_class: Option) -> ParseResult UnresolvedNameToken { location, containing_class, - indirection: 0, // TODO + indirection: Indirection(0), // TODO base: base_name.to_string(), names, function_call, diff --git a/src/root/parser/parse_struct.rs b/src/root/parser/parse_struct.rs index ed78af9..8eb9454 100644 --- a/src/root/parser/parse_struct.rs +++ b/src/root/parser/parse_struct.rs @@ -12,17 +12,18 @@ use nom_supreme::tag::complete::tag; use substring::Substring; use crate::root::parser::parse_blocks::default_section; use crate::root::parser::parse_util::{discard_ignored, require_ignored}; +use crate::root::shared::types::TypeID; #[derive(Debug, Getters, Dissolve)] pub struct StructToken { location: Location, name: String, attributes: Parameters, - id: Option + id: Option } impl StructToken { - pub fn set_id(&mut self, id: isize) { + pub fn set_id(&mut self, id: TypeID) { self.id = Some(id); } } diff --git a/src/root/shared/types.rs b/src/root/shared/types.rs index 2139aa8..7d48674 100644 --- a/src/root/shared/types.rs +++ b/src/root/shared/types.rs @@ -1,7 +1,61 @@ -use crate::root::name_resolver::resolve_names::UserType; +use derive_getters::Getters; +use derive_more::{Add, AddAssign, Display, Div, Sub, SubAssign}; + +#[derive(Debug, PartialEq, Eq, Hash, Display, Copy, Clone)] +#[display(fmt = "TypeID: {}", .0)] +pub struct TypeID(pub isize); + +#[derive(Debug, PartialEq, Eq, Hash, Display, Copy, Clone)] +#[display(fmt = "FunctionID: {}", .0)] +pub struct FunctionID(pub isize); + +#[derive(Debug, PartialEq, Eq, Hash, Display, Copy, Clone)] +#[derive(Add, AddAssign, Sub, SubAssign)] +#[display(fmt = "Indirection: {}", .0)] +pub struct Indirection(pub usize); + +impl Indirection { + pub fn has_indirection(&self) -> bool { + self.0 != 0 + } +} + +#[derive(Debug, PartialEq, Eq, Hash, Display, Copy, Clone)] +#[derive(Add, AddAssign, Sub, SubAssign)] +#[display(fmt = "ByteSize: {}", .0)] +pub struct ByteSize(pub usize); + +#[derive(Debug, PartialEq, Eq, Hash, Display, Copy, Clone)] +#[derive(Add, AddAssign, Sub, SubAssign)] +#[display(fmt = "LocalAddress: {}", .0)] +pub struct LocalAddress(pub isize); pub trait Type { - fn id(&self) -> isize; + fn id(&self) -> TypeID; + + fn size(&self) -> ByteSize; +} + +#[derive(Getters, Clone)] +pub struct TypeRef { + type_id: TypeID, + indirection: Indirection +} + +impl TypeRef { + pub fn new(type_id: TypeID, indirection: Indirection) -> TypeRef { + TypeRef { type_id, indirection } + } +} + +#[derive(Getters, Clone)] +pub struct AddressedTypeRef { + local_address: LocalAddress, + type_ref: TypeRef +} - fn size(&self) -> usize; +impl AddressedTypeRef { + pub fn new(local_address: LocalAddress, type_ref: TypeRef) -> AddressedTypeRef { + AddressedTypeRef { local_address, type_ref } + } }