From e85fb16707266e11ae202afc468a8fb1ed82bbe2 Mon Sep 17 00:00:00 2001 From: James Harton Date: Fri, 22 Feb 2019 22:08:48 +1300 Subject: [PATCH] Beginnings of a much simpler type system. --- huia-compiler/Cargo.toml | 2 + huia-compiler/src/bootstrap/any.rs | 9 -- huia-compiler/src/bootstrap/array.rs | 15 --- huia-compiler/src/bootstrap/mod.rs | 10 -- huia-compiler/src/class.rs | 140 +++++++++++++++++--- huia-compiler/src/constant.rs | 169 ------------------------ huia-compiler/src/context.rs | 131 +++++++----------- huia-compiler/src/identifier.rs | 42 ++++++ huia-compiler/src/lib.rs | 23 ++-- huia-compiler/src/method_table.rs | 67 ---------- huia-compiler/src/scope.rs | 23 ---- huia-compiler/src/trait.rs | 134 +++++++++++++++++++ huia-compiler/src/type.rs | 68 ++++++++++ huia-compiler/src/type_spec.rs | 36 +++++ huia-compiler/src/vtable/function.rs | 67 ---------- huia-compiler/src/vtable/method.rs | 91 ------------- huia-compiler/src/vtable/mod.rs | 38 ------ huia-compiler/src/vtable/requirement.rs | 23 ---- huia-compiler/src/vtable/tables.rs | 81 ------------ huia-compiler/src/vtable/trait.rs | 30 ----- 20 files changed, 465 insertions(+), 734 deletions(-) delete mode 100644 huia-compiler/src/bootstrap/any.rs delete mode 100644 huia-compiler/src/bootstrap/array.rs delete mode 100644 huia-compiler/src/bootstrap/mod.rs delete mode 100644 huia-compiler/src/constant.rs create mode 100644 huia-compiler/src/identifier.rs delete mode 100644 huia-compiler/src/method_table.rs delete mode 100644 huia-compiler/src/scope.rs create mode 100644 huia-compiler/src/trait.rs create mode 100644 huia-compiler/src/type.rs create mode 100644 huia-compiler/src/type_spec.rs delete mode 100644 huia-compiler/src/vtable/function.rs delete mode 100644 huia-compiler/src/vtable/method.rs delete mode 100644 huia-compiler/src/vtable/mod.rs delete mode 100644 huia-compiler/src/vtable/requirement.rs delete mode 100644 huia-compiler/src/vtable/tables.rs delete mode 100644 huia-compiler/src/vtable/trait.rs diff --git a/huia-compiler/Cargo.toml b/huia-compiler/Cargo.toml index 97a5236..7cd8fd2 100644 --- a/huia-compiler/Cargo.toml +++ b/huia-compiler/Cargo.toml @@ -6,3 +6,5 @@ edition = "2018" [dependencies] huia-parser = { path = "../huia-parser" } +wrc = "0.3.0" +string-interner = "0.7.0" diff --git a/huia-compiler/src/bootstrap/any.rs b/huia-compiler/src/bootstrap/any.rs deleted file mode 100644 index d11c0c7..0000000 --- a/huia-compiler/src/bootstrap/any.rs +++ /dev/null @@ -1,9 +0,0 @@ -use crate::constant::Constant; -use crate::context::Context; -use std::rc::Rc; - -pub fn bootstrap(context: &mut Context) { - let any_trait = Constant::new_trait("Any", Vec::new()); - - context.add_constant(Rc::new(any_trait)); -} diff --git a/huia-compiler/src/bootstrap/array.rs b/huia-compiler/src/bootstrap/array.rs deleted file mode 100644 index 0ee1495..0000000 --- a/huia-compiler/src/bootstrap/array.rs +++ /dev/null @@ -1,15 +0,0 @@ -use crate::constant::Constant; -use crate::context::Context; -use crate::method_table::{Method, MethodTable}; -use std::rc::Rc; - -pub fn bootstrap(context: &mut Context) { - let mut ary_type = Constant::native_array(); - - let method = Method::new("new", true); - - ary_type.insert_method(method); - ary_type.implement(context.get_constant("Any").unwrap(), MethodTable::new()); - - context.add_constant(Rc::new(ary_type)); -} diff --git a/huia-compiler/src/bootstrap/mod.rs b/huia-compiler/src/bootstrap/mod.rs deleted file mode 100644 index 1548ae8..0000000 --- a/huia-compiler/src/bootstrap/mod.rs +++ /dev/null @@ -1,10 +0,0 @@ -use crate::constant::Constant; -use crate::context::Context; - -mod any; -mod array; - -pub fn bootstrap(mut context: &mut Context) { - any::bootstrap(&mut context); - array::bootstrap(&mut context); -} diff --git a/huia-compiler/src/class.rs b/huia-compiler/src/class.rs index 586ab87..32683d1 100644 --- a/huia-compiler/src/class.rs +++ b/huia-compiler/src/class.rs @@ -1,32 +1,134 @@ -use crate::vtable::{Method, TraitData, VTable, VTableClassData, VTableImplData}; +use crate::identifier::Identifier; +use std::sync::RwLock; +use wrc::WRC; -#[derive(Debug, Clone)] -pub struct ClassData { - name: String, - vtable: VTableClassData, - impls: Vec<(TraitData, VTableImplData)>, +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct ClassId(usize); + +impl From for usize { + fn from(data: ClassId) -> usize { + data.0 + } } -impl ClassData { - pub fn new(name: &str) -> ClassData { - ClassData { - name: name.to_string(), - vtable: VTableClassData::new(), - impls: Vec::new(), +impl From for ClassId { + fn from(data: usize) -> ClassId { + ClassId(data) + } +} + +pub struct Classes(RwLock>); + +impl Classes { + pub fn new() -> Classes { + Classes(RwLock::new(Vec::new())) + } + + pub fn push(&mut self, class: Class) -> ClassId { + let mut elements = self.0.write().unwrap(); + let idx = elements.len(); + elements.push(class); + ClassId::from(idx) + } + + pub fn get(&self, idx: ClassId) -> Option { + let elements = self.0.read().unwrap(); + match elements.get(idx.0) { + Some(class) => Some(class.clone()), + None => None, } } - pub fn name(&self) -> &str { - &self.name + pub fn next_id(&self) -> ClassId { + let elements = self.0.read().unwrap(); + ClassId(elements.len()) + } + + pub fn is_empty(&self) -> bool { + let elements = self.0.read().unwrap(); + elements.is_empty() } } -impl VTable for ClassData { - fn insert_method(&mut self, method: Method) -> usize { - self.vtable.insert_method(method) +#[derive(Debug, Clone)] +pub struct Class(WRC>); + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct ClassInner { + id: ClassId, + name: Identifier, +} + +impl ClassInner { + fn id(&self) -> ClassId { + self.id } - fn get_method(&self, id: usize) -> Option<&Method> { - self.vtable.get_method(id) + fn name(&self) -> Identifier { + self.name + } + + fn set_name(&mut self, name: Identifier) { + self.name = name + } +} + +impl Class { + pub fn new(id: ClassId, name: Identifier) -> Class { + Class(WRC::new(RwLock::new(ClassInner { id, name }))) + } + + pub fn id(&self) -> ClassId { + let class = self.0.read().unwrap(); + class.id() + } + + pub fn name(&self) -> Identifier { + let class = self.0.read().unwrap(); + class.name() + } + + pub fn set_name(&self, name: Identifier) { + let mut class = self.0.write().unwrap(); + class.set_name(name); + } +} + +impl PartialEq for Class { + fn eq(&self, other: &Class) -> bool { + self.id() == other.id() + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::context::Context; + use crate::identifier::Identifiers; + + #[test] + fn classes() { + let mut identifiers = Identifiers::new(); + let mut classes = Classes::new(); + + let id = classes.next_id(); + let name = identifiers.get("Marty McFly"); + let class0 = Class::new(id, name); + + let idx = classes.push(class0); + assert_eq!(idx.0, 0); + + let class1 = classes.get(idx).unwrap(); + assert_eq!(class1.id(), id); + assert_eq!(class1.name(), identifiers.get("Marty McFly")); + } + + #[test] + fn set_name() { + let mut context = Context::new(); + let class = context.new_class("Marty McFly"); + assert_eq!(class.name(), context.get_identifier("Marty McFly")); + class.set_name(context.get_identifier("Doc Brown")); + assert_eq!(class.name(), context.get_identifier("Doc Brown")); } } diff --git a/huia-compiler/src/constant.rs b/huia-compiler/src/constant.rs deleted file mode 100644 index 141480b..0000000 --- a/huia-compiler/src/constant.rs +++ /dev/null @@ -1,169 +0,0 @@ -use crate::method_table::{Method, MethodTable}; -use std::collections::BTreeMap; -use std::rc::Rc; - -#[derive(Debug)] -pub struct Constant { - identifier: String, - inner: ConstantInner, - methods: MethodTable, - implements: Vec<(Rc, MethodTable)>, -} - -#[derive(Debug)] -pub enum ConstantInner { - NativeBoolean, - NativeFloat, - NativeInteger, - NativeArray, - NativeHashMap, - UserDefinedType { - property_types: BTreeMap>, - }, - Trait { - corequires: Vec>, - }, -} - -pub struct Instance { - type_ref: Rc, - inner: InstanceInner, -} - -pub enum InstanceInner { - NativeBoolean(bool), - NativeFloat(f64), - NativeInteger(i64), -} - -impl Constant { - pub fn native_array() -> Constant { - Constant { - identifier: "Huia.NativeArray".to_string(), - inner: ConstantInner::NativeArray, - methods: MethodTable::new(), - implements: Vec::new(), - } - } - - pub fn native_boolean() -> Constant { - Constant { - identifier: "Huia.NativeBoolean".to_string(), - inner: ConstantInner::NativeBoolean, - methods: MethodTable::new(), - implements: Vec::new(), - } - } - - pub fn native_float() -> Constant { - Constant { - identifier: "Huia.NativeFloat".to_string(), - inner: ConstantInner::NativeFloat, - methods: MethodTable::new(), - implements: Vec::new(), - } - } - - pub fn native_hash_map() -> Constant { - Constant { - identifier: "Huia.NativeHashMap".to_string(), - inner: ConstantInner::NativeHashMap, - methods: MethodTable::new(), - implements: Vec::new(), - } - } - - pub fn native_integer() -> Constant { - Constant { - identifier: "Huia.NativeInteger".to_string(), - inner: ConstantInner::NativeInteger, - methods: MethodTable::new(), - implements: Vec::new(), - } - } - - pub fn new_trait(name: &str, corequires: Vec>) -> Constant { - Constant { - identifier: name.to_string(), - inner: ConstantInner::Trait { corequires }, - methods: MethodTable::new(), - implements: Vec::new(), - } - } - - pub fn new_type(name: &str, property_types: BTreeMap>) -> Constant { - Constant { - identifier: name.to_string(), - inner: ConstantInner::UserDefinedType { property_types }, - methods: MethodTable::new(), - implements: Vec::new(), - } - } - - pub fn identifier(&self) -> &str { - &self.identifier - } - - pub fn is_native(&self) -> bool { - match self.inner { - ConstantInner::NativeArray => true, - ConstantInner::NativeBoolean => true, - ConstantInner::NativeFloat => true, - ConstantInner::NativeHashMap => true, - ConstantInner::NativeInteger => true, - _ => false, - } - } - - pub fn insert_method(&mut self, method: Method) { - self.methods.insert(method); - } - - pub fn get_method(&self, name: &str) -> Option> { - self.methods.get(name) - } - - pub fn implement(&mut self, r#trait: Rc, method_table: MethodTable) { - self.implements.push((r#trait, method_table)); - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn native_array() { - let con = Constant::native_array(); - assert_eq!(con.identifier(), "Huia.NativeArray"); - assert!(con.is_native()); - } - - #[test] - fn native_boolean() { - let con = Constant::native_boolean(); - assert_eq!(con.identifier(), "Huia.NativeBoolean"); - assert!(con.is_native()); - } - - #[test] - fn native_float() { - let con = Constant::native_float(); - assert_eq!(con.identifier(), "Huia.NativeFloat"); - assert!(con.is_native()); - } - - #[test] - fn native_hash_map() { - let con = Constant::native_hash_map(); - assert_eq!(con.identifier(), "Huia.NativeHashMap"); - assert!(con.is_native()); - } - - #[test] - fn native_integer() { - let con = Constant::native_integer(); - assert_eq!(con.identifier(), "Huia.NativeInteger"); - assert!(con.is_native()); - } -} diff --git a/huia-compiler/src/context.rs b/huia-compiler/src/context.rs index 3d8531f..de86ba9 100644 --- a/huia-compiler/src/context.rs +++ b/huia-compiler/src/context.rs @@ -1,105 +1,58 @@ -use crate::bootstrap::bootstrap; -use crate::constant::Constant; -use crate::scope::Scope; -use huia_parser::ast; -use huia_parser::ast::Value; -use std::collections::BTreeMap; -use std::rc::Rc; +use crate::class::{Class, ClassId, Classes}; +use crate::identifier::{Identifier, Identifiers}; +use crate::r#trait::{Trait, TraitId, Traits}; pub struct Context { - globals: Scope, + classes: Classes, + traits: Traits, + identifiers: Identifiers, } impl Context { pub fn new() -> Context { - let globals = Scope::new(); - let mut context = Context { globals }; - - bootstrap(&mut context); - - context - } - - pub fn consume(&mut self, terms: Vec) { - for term in terms { - match term.node_type() { - ast::NodeType::Array => {} - ast::NodeType::Atom => {} - ast::NodeType::Binary => {} - ast::NodeType::Boolean => {} - ast::NodeType::Call => {} - ast::NodeType::Constant => {} - ast::NodeType::Constructor => {} - ast::NodeType::Declaration => {} - ast::NodeType::Definition => { - // let (deftype, defname, args, body) = term.definition().unwrap(); - // match deftype.value_ref().as_ref() { - // "type" => self.define_type(defname, args, body), - // "def" => self.define_public_method(defname, args, body), - // "defp" => self.define_private_method(defname, args, body), - // "defs" => self.define_static_method(defname, args, body), - // _ => panic!("Unknown deftype {:?}", deftype), - // } - } - ast::NodeType::Float => {} - ast::NodeType::Integer => {} - ast::NodeType::Local => {} - ast::NodeType::Map => {} - ast::NodeType::MethodCall => {} - ast::NodeType::String => {} - ast::NodeType::Unary => {} - } + Context { + classes: Classes::new(), + traits: Traits::new(), + identifiers: Identifiers::new(), } } - fn define_type( - &mut self, - defname: &ast::Term, - args: &Vec<(ast::Identifier, ast::Term)>, - body: &Vec<(ast::Identifier, Vec)>, - ) { - // let name = defname.constant().unwrap().value_ref(); - // let mut property_types = BTreeMap::new(); - // for (ident, value) in args { - // property_types.insert(ident.value_ref().to_string(), value); - // } - - // let t = Constant::new_type(name, property_types); + pub fn new_class(&mut self, name: &str) -> Class { + let name = self.identifiers.get(name); + let id = self.classes.next_id(); + let class = Class::new(id, name); + self.classes.push(class); + self.classes.get(id).unwrap() } - fn define_public_method( - &mut self, - defname: &ast::Term, - args: &Vec<(ast::Identifier, ast::Term)>, - body: &Vec<(ast::Identifier, Vec)>, - ) { - + pub fn get_class(&self, id: ClassId) -> Option { + self.classes.get(id) } - fn define_private_method( - &mut self, - defname: &ast::Term, - args: &Vec<(ast::Identifier, ast::Term)>, - body: &Vec<(ast::Identifier, Vec)>, - ) { - + pub fn new_trait(&mut self, name: &str) -> Trait { + let name = self.identifiers.get(name); + let id = self.traits.next_id(); + let tr = Trait::new(id, name); + self.traits.push(tr); + self.traits.get(id).unwrap() } - fn define_static_method( - &mut self, - defname: &ast::Term, - args: &Vec<(ast::Identifier, ast::Term)>, - body: &Vec<(ast::Identifier, Vec)>, - ) { - + pub fn get_trait(&self, id: TraitId) -> Option { + self.traits.get(id) } - pub fn add_constant(&mut self, constant: Rc) { - self.globals.insert(constant); + pub fn get_identifier(&mut self, value: &str) -> Identifier { + self.identifiers.get(value) } - pub fn get_constant(&self, name: &str) -> Option> { - self.globals.get(name) + pub fn get_identifier_value(&self, identifier: Identifier) -> Option<&str> { + self.identifiers.resolve(identifier) + } + + pub fn is_empty(&self) -> bool { + // Traits and Classes must be empty if identifiers is empty because + // classes and traits must be initialised with identifier names. + self.identifiers.is_empty() } } @@ -109,6 +62,16 @@ mod test { #[test] fn new() { - let context = Context::new(); + let mut context = Context::new(); + let class0 = context.new_class("Marty McFly"); + let class1 = context.get_class(class0.id()).unwrap(); + assert_eq!(class0, class1); + + let tr0 = context.new_trait("Doc Brown"); + let tr1 = context.get_trait(tr0.id()).unwrap(); + assert_eq!(tr0, tr1); + + let id = context.get_identifier("Einstein Brown"); + assert_eq!(context.get_identifier_value(id).unwrap(), "Einstein Brown"); } } diff --git a/huia-compiler/src/identifier.rs b/huia-compiler/src/identifier.rs new file mode 100644 index 0000000..1dcf2d5 --- /dev/null +++ b/huia-compiler/src/identifier.rs @@ -0,0 +1,42 @@ +use string_interner::{StringInterner, Sym}; + +#[derive(Debug, Clone, Hash, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct Identifier(Sym); + +pub struct Identifiers(StringInterner); + +impl Identifiers { + pub fn new() -> Identifiers { + Identifiers(StringInterner::default()) + } + + pub fn get(&mut self, value: &str) -> Identifier { + let sym = self.0.get_or_intern(value); + Identifier(sym) + } + + pub fn resolve(&self, identifier: Identifier) -> Option<&str> { + self.0.resolve(identifier.0) + } + + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test() { + let mut identifiers = Identifiers::new(); + + assert!(identifiers.is_empty()); + let sym0 = identifiers.get("Marty McFly"); + let sym1 = identifiers.get("Marty McFly"); + assert!(!identifiers.is_empty()); + assert_eq!(sym0, sym1); + assert_eq!(identifiers.resolve(sym0).unwrap(), "Marty McFly"); + } +} diff --git a/huia-compiler/src/lib.rs b/huia-compiler/src/lib.rs index cfc30a3..c1978bb 100644 --- a/huia-compiler/src/lib.rs +++ b/huia-compiler/src/lib.rs @@ -1,10 +1,17 @@ extern crate huia_parser; -mod bootstrap; -mod class; -mod constant; -mod context; -mod method_table; -mod scope; -mod vtable; +extern crate string_interner; +extern crate wrc; -pub use class::ClassData; +mod class; +mod context; +mod identifier; +mod r#trait; +mod r#type; +mod type_spec; + +pub use class::{Class, ClassId}; +pub use context::Context; +pub use identifier::Identifier; +pub use r#trait::{Trait, TraitId}; +pub use r#type::Type; +pub use type_spec::TypeSpec; diff --git a/huia-compiler/src/method_table.rs b/huia-compiler/src/method_table.rs deleted file mode 100644 index 4a3ce22..0000000 --- a/huia-compiler/src/method_table.rs +++ /dev/null @@ -1,67 +0,0 @@ -use crate::constant::Constant; -use std::collections::BTreeMap; -use std::rc::Rc; - -#[derive(Debug)] -pub struct MethodTable(BTreeMap>); - -impl MethodTable { - pub fn new() -> MethodTable { - MethodTable(BTreeMap::new()) - } - - pub fn insert(&mut self, method: Method) { - let name = method.identifier(); - self.0.insert(name.to_string(), Rc::new(method)); - } - - pub fn get(&self, name: &str) -> Option> { - match self.0.get(name) { - Some(m) => Some(m.clone()), - None => None, - } - } -} - -#[derive(Debug)] -pub enum Visibility { - Public, - Private, -} - -#[derive(Debug)] -pub struct Method { - identifier: String, - visibility: Visibility, -} - -impl Method { - pub fn new(name: &str, public: bool) -> Method { - let visibility = match public { - true => Visibility::Public, - false => Visibility::Private, - }; - - Method { - identifier: name.to_string(), - visibility, - } - } - - pub fn identifier(&self) -> &str { - &self.identifier - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn method_table() { - let mut mt = MethodTable::new(); - let m = Method::new("marty", true); - - mt.insert(m); - } -} diff --git a/huia-compiler/src/scope.rs b/huia-compiler/src/scope.rs deleted file mode 100644 index 5f7c43e..0000000 --- a/huia-compiler/src/scope.rs +++ /dev/null @@ -1,23 +0,0 @@ -use crate::constant::Constant; -use std::collections::BTreeMap; -use std::rc::Rc; - -#[derive(Debug)] -pub struct Scope(BTreeMap>); - -impl Scope { - pub fn new() -> Scope { - Scope(BTreeMap::new()) - } - - pub fn insert(&mut self, constant: Rc) { - self.0.insert(constant.identifier().to_string(), constant); - } - - pub fn get(&self, name: &str) -> Option> { - match self.0.get(name) { - Some(c) => Some(c.clone()), - None => None, - } - } -} diff --git a/huia-compiler/src/trait.rs b/huia-compiler/src/trait.rs new file mode 100644 index 0000000..1ea375f --- /dev/null +++ b/huia-compiler/src/trait.rs @@ -0,0 +1,134 @@ +use crate::identifier::Identifier; +use std::sync::RwLock; +use wrc::WRC; + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct TraitId(usize); + +impl From for usize { + fn from(data: TraitId) -> usize { + data.0 + } +} + +impl From for TraitId { + fn from(data: usize) -> TraitId { + TraitId(data) + } +} + +pub struct Traits(RwLock>); + +impl Traits { + pub fn new() -> Traits { + Traits(RwLock::new(Vec::new())) + } + + pub fn push(&mut self, r#trait: Trait) -> TraitId { + let mut elements = self.0.write().unwrap(); + let idx = elements.len(); + elements.push(r#trait); + TraitId::from(idx) + } + + pub fn get(&self, idx: TraitId) -> Option { + let elements = self.0.read().unwrap(); + match elements.get(idx.0) { + Some(tr) => Some(tr.clone()), + None => None, + } + } + + pub fn next_id(&self) -> TraitId { + let elements = self.0.read().unwrap(); + TraitId(elements.len()) + } + + pub fn is_empty(&self) -> bool { + let elements = self.0.read().unwrap(); + elements.is_empty() + } +} + +#[derive(Debug, Clone)] +pub struct Trait(WRC>); + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct TraitInner { + id: TraitId, + name: Identifier, +} + +impl TraitInner { + fn id(&self) -> TraitId { + self.id + } + + fn name(&self) -> Identifier { + self.name + } + + fn set_name(&mut self, name: Identifier) { + self.name = name + } +} + +impl Trait { + pub fn new(id: TraitId, name: Identifier) -> Trait { + Trait(WRC::new(RwLock::new(TraitInner { id, name }))) + } + + pub fn id(&self) -> TraitId { + let tr = self.0.read().unwrap(); + tr.id() + } + + pub fn name(&self) -> Identifier { + let tr = self.0.read().unwrap(); + tr.name() + } + + pub fn set_name(&self, name: Identifier) { + let mut tr = self.0.write().unwrap(); + tr.set_name(name); + } +} + +impl PartialEq for Trait { + fn eq(&self, other: &Trait) -> bool { + self.id() == other.id() + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::context::Context; + use crate::identifier::Identifiers; + + #[test] + fn traits() { + let mut identifiers = Identifiers::new(); + let mut traits = Traits::new(); + + let id = traits.next_id(); + let name = identifiers.get("Marty McFly"); + let trait0 = Trait::new(id, name); + + let idx = traits.push(trait0); + assert_eq!(idx.0, 0); + + let trait1 = traits.get(idx).unwrap(); + assert_eq!(trait1.id(), id); + assert_eq!(trait1.name(), identifiers.get("Marty McFly")); + } + + #[test] + fn set_name() { + let mut context = Context::new(); + let tr = context.new_trait("Marty McFly"); + assert_eq!(tr.name(), context.get_identifier("Marty McFly")); + tr.set_name(context.get_identifier("Doc Brown")); + assert_eq!(tr.name(), context.get_identifier("Doc Brown")); + } +} diff --git a/huia-compiler/src/type.rs b/huia-compiler/src/type.rs new file mode 100644 index 0000000..34e1fe4 --- /dev/null +++ b/huia-compiler/src/type.rs @@ -0,0 +1,68 @@ +use crate::class::ClassId; +use crate::r#trait::TraitId; + +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] +pub enum Type { + Class(ClassId), + Trait(TraitId), +} + +impl Type { + pub fn is_class(&self) -> bool { + match self { + Type::Class(_) => true, + _ => false, + } + } + + pub fn is_trait(&self) -> bool { + match self { + Type::Trait(_) => true, + _ => false, + } + } + + pub fn class_id(&self) -> Option { + match self { + Type::Class(id) => Some(id.clone()), + _ => None, + } + } + + pub fn trait_id(&self) -> Option { + match self { + Type::Trait(id) => Some(id.clone()), + _ => None, + } + } +} + +impl From for Type { + fn from(id: ClassId) -> Type { + Type::Class(id) + } +} + +impl From for Type { + fn from(id: TraitId) -> Type { + Type::Trait(id) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test() { + let ty0 = Type::from(ClassId::from(0)); + let ty1 = Type::from(TraitId::from(0)); + + assert_ne!(ty0, ty1); + assert!(ty0.is_class()); + assert!(ty1.is_trait()); + + assert_eq!(ty0.class_id().unwrap(), ClassId::from(0)); + assert_eq!(ty1.trait_id().unwrap(), TraitId::from(0)); + } +} diff --git a/huia-compiler/src/type_spec.rs b/huia-compiler/src/type_spec.rs new file mode 100644 index 0000000..b65820b --- /dev/null +++ b/huia-compiler/src/type_spec.rs @@ -0,0 +1,36 @@ +use crate::r#type::Type; + +#[derive(Debug)] +pub struct TypeSpec(Vec); + +impl TypeSpec { + pub fn new() -> TypeSpec { + TypeSpec(Vec::new()) + } + + pub fn push(&mut self, ty: Type) { + self.0.push(ty) + } + + pub fn matches(&self, ty: Type) -> bool { + self.0.iter().any(|i| i == &ty) + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::class::ClassId; + use crate::r#trait::TraitId; + + #[test] + fn test() { + let mut type_spec = TypeSpec::new(); + let ty0 = Type::from(ClassId::from(0)); + let ty1 = Type::from(TraitId::from(0)); + assert!(ty0.is_class()); + assert!(ty1.is_trait()); + type_spec.push(ty0); + type_spec.push(ty1); + } +} diff --git a/huia-compiler/src/vtable/function.rs b/huia-compiler/src/vtable/function.rs deleted file mode 100644 index e685797..0000000 --- a/huia-compiler/src/vtable/function.rs +++ /dev/null @@ -1,67 +0,0 @@ -use crate::vtable::{Instance, Requirement}; -use std::fmt; - -#[derive(Debug, Clone)] -pub struct Function { - return_requirements: Requirement, - heads: Vec, -} - -impl Function { - pub fn new() -> Function { - Function { - return_requirements: Requirement::new(), - heads: Vec::new(), - } - } -} - -#[derive(Debug, Clone)] -pub struct FunctionClause { - argument_names: Vec, - argument_requirements: Vec, - function_body: FunctionBody, -} - -impl FunctionClause { - pub fn new() -> FunctionClause { - FunctionClause { - argument_names: Vec::new(), - argument_requirements: Vec::new(), - function_body: FunctionBody::Empty, - } - } - - pub fn add_argument(&mut self, argument_name: &str, argument_type: Requirement) { - self.argument_names.push(argument_name.to_string()); - self.argument_requirements.push(argument_type); - } -} - -#[derive(Clone)] -pub enum FunctionBody { - Empty, - NativeFunction(fn(Instance, Vec<&str>, Vec) -> Instance), - UserFunction(), -} - -impl fmt::Debug for FunctionBody { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - FunctionBody::Empty => write!(f, "Empty"), - FunctionBody::NativeFunction(_) => write!(f, "NativeFunction"), - FunctionBody::UserFunction() => write!(f, "UserFunction"), - } - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test() { - let mut f = Function::new(); - let mut fhead = FunctionClause::new(); - } -} diff --git a/huia-compiler/src/vtable/method.rs b/huia-compiler/src/vtable/method.rs deleted file mode 100644 index d97fb44..0000000 --- a/huia-compiler/src/vtable/method.rs +++ /dev/null @@ -1,91 +0,0 @@ -use crate::vtable::Function; - -#[derive(Debug, Clone)] -pub struct Method { - name: String, - flag: MethodFlag, - fun: Function, -} - -impl Method { - pub fn new(name: &str, flag: MethodFlag, fun: Function) -> Method { - let name = name.to_string(); - - Method { name, flag, fun } - } - - pub fn is_public(&self) -> bool { - match self.flag { - MethodFlag::Public => true, - _ => false, - } - } - - pub fn is_private(&self) -> bool { - match self.flag { - MethodFlag::Private => true, - _ => false, - } - } - - pub fn is_static(&self) -> bool { - match self.flag { - MethodFlag::Static => true, - _ => false, - } - } - - pub fn flag(&self) -> MethodFlag { - self.flag.clone() - } - - pub fn set_flag(&mut self, flag: MethodFlag) { - self.flag = flag; - } - - pub fn fun(&self) -> &Function { - &self.fun - } - - pub fn set_fun(&mut self, fun: Function) { - self.fun = fun; - } -} - -#[derive(Debug, Clone)] -pub enum MethodFlag { - Public, - Private, - Static, -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test() { - let f = Function::new(); - - let m = Method::new("marty", MethodFlag::Public, f.clone()); - assert!(m.is_public()); - assert!(!m.is_private()); - assert!(!m.is_static()); - - let m = Method::new("marty", MethodFlag::Private, f.clone()); - assert!(!m.is_public()); - assert!(m.is_private()); - assert!(!m.is_static()); - - let m = Method::new("marty", MethodFlag::Static, f.clone()); - assert!(!m.is_public()); - assert!(!m.is_private()); - assert!(m.is_static()); - - let mut m = Method::new("marty", MethodFlag::Static, f.clone()); - m.set_flag(MethodFlag::Public); - assert!(m.is_public()); - assert!(!m.is_private()); - assert!(!m.is_static()); - } -} diff --git a/huia-compiler/src/vtable/mod.rs b/huia-compiler/src/vtable/mod.rs deleted file mode 100644 index fb620e6..0000000 --- a/huia-compiler/src/vtable/mod.rs +++ /dev/null @@ -1,38 +0,0 @@ -mod function; -mod method; -mod requirement; -mod tables; -mod r#trait; -pub use function::{Function, FunctionBody, FunctionClause}; -pub use method::{Method, MethodFlag}; -pub use r#trait::TraitData; -pub use requirement::Requirement; -use std::rc::Rc; -pub use tables::{VTableClassData, VTableDefaultImplData, VTableImplData, VTableTraitData}; - -use crate::ClassData; - -#[derive(Debug, Clone)] -pub enum Type { - Class(ClassData), - Trait(TraitData), -} - -#[derive(Debug, Clone)] -pub struct Instance { - class: Rc, -} - -pub trait VTable { - fn insert_method(&mut self, method: Method) -> usize; - - fn get_method(&self, id: usize) -> Option<&Method>; -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test() {} -} diff --git a/huia-compiler/src/vtable/requirement.rs b/huia-compiler/src/vtable/requirement.rs deleted file mode 100644 index dd9c025..0000000 --- a/huia-compiler/src/vtable/requirement.rs +++ /dev/null @@ -1,23 +0,0 @@ -use crate::vtable::Type; -use std::rc::Rc; - -#[derive(Debug, Clone)] -pub struct Requirement(Vec>); - -impl Requirement { - pub fn new() -> Requirement { - Requirement(Vec::new()) - } - - pub fn push(&mut self, r#type: Rc) { - self.0.push(r#type); - } - - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - pub fn len(&self) -> usize { - self.0.len() - } -} diff --git a/huia-compiler/src/vtable/tables.rs b/huia-compiler/src/vtable/tables.rs deleted file mode 100644 index 98a035c..0000000 --- a/huia-compiler/src/vtable/tables.rs +++ /dev/null @@ -1,81 +0,0 @@ -use crate::vtable::{Method, VTable}; - -#[derive(Debug, Clone)] -pub struct VTableImplData(Vec); - -impl VTableImplData { - pub fn new() -> VTableImplData { - VTableImplData(Vec::new()) - } -} - -#[derive(Debug, Clone)] -pub struct VTableDefaultImplData(Vec); - -impl VTableDefaultImplData { - pub fn new() -> VTableDefaultImplData { - VTableDefaultImplData(Vec::new()) - } -} - -#[derive(Debug, Clone)] -pub struct VTableClassData(Vec); - -impl VTableClassData { - pub fn new() -> VTableClassData { - VTableClassData(Vec::new()) - } -} - -#[derive(Debug, Clone)] -pub struct VTableTraitData(Vec); - -impl VTableTraitData { - pub fn new() -> VTableTraitData { - VTableTraitData(Vec::new()) - } -} - -impl VTable for VTableImplData { - fn insert_method(&mut self, method: Method) -> usize { - self.0.push(method); - self.0.len() - } - - fn get_method(&self, id: usize) -> Option<&Method> { - self.0.get(id) - } -} - -impl VTable for VTableDefaultImplData { - fn insert_method(&mut self, method: Method) -> usize { - self.0.push(method); - self.0.len() - } - - fn get_method(&self, id: usize) -> Option<&Method> { - self.0.get(id) - } -} - -impl VTable for VTableClassData { - fn insert_method(&mut self, method: Method) -> usize { - self.0.push(method); - self.0.len() - } - - fn get_method(&self, id: usize) -> Option<&Method> { - self.0.get(id) - } -} - -impl VTable for VTableTraitData { - fn insert_method(&mut self, method: Method) -> usize { - self.0.push(method); - self.0.len() - } - - fn get_method(&self, id: usize) -> Option<&Method> { - self.0.get(id) - } -} diff --git a/huia-compiler/src/vtable/trait.rs b/huia-compiler/src/vtable/trait.rs deleted file mode 100644 index 7195306..0000000 --- a/huia-compiler/src/vtable/trait.rs +++ /dev/null @@ -1,30 +0,0 @@ -use crate::vtable::{Method, VTable, VTableTraitData}; - -#[derive(Debug, Clone)] -pub struct TraitData { - name: String, - vtable: VTableTraitData, -} - -impl TraitData { - pub fn new(name: &str) -> TraitData { - TraitData { - name: name.to_string(), - vtable: VTableTraitData::new(), - } - } - - pub fn name(&self) -> &str { - &self.name - } -} - -impl VTable for TraitData { - fn insert_method(&mut self, method: Method) -> usize { - self.vtable.insert_method(method) - } - - fn get_method(&self, id: usize) -> Option<&Method> { - self.vtable.get_method(id) - } -}