From 4aa61a7a21e6e493583de14b96208c6f233d2e9e Mon Sep 17 00:00:00 2001 From: James Harton Date: Sat, 23 Feb 2019 10:14:46 +1300 Subject: [PATCH] Extract types into separate files. --- huia-compiler/src/class.rs | 144 -------------------------- huia-compiler/src/class/actual.rs | 68 ++++++++++++ huia-compiler/src/class/class_id.rs | 14 +++ huia-compiler/src/class/classes.rs | 69 ++++++++++++ huia-compiler/src/class/mod.rs | 6 ++ huia-compiler/src/instructions/mod.rs | 1 + huia-compiler/src/lib.rs | 1 + huia-compiler/src/trait.rs | 144 -------------------------- huia-compiler/src/trait/actual.rs | 99 ++++++++++++++++++ huia-compiler/src/trait/mod.rs | 6 ++ huia-compiler/src/trait/trait_id.rs | 14 +++ huia-compiler/src/trait/traits.rs | 70 +++++++++++++ huia-compiler/src/type.rs | 16 ++- 13 files changed, 362 insertions(+), 290 deletions(-) delete mode 100644 huia-compiler/src/class.rs create mode 100644 huia-compiler/src/class/actual.rs create mode 100644 huia-compiler/src/class/class_id.rs create mode 100644 huia-compiler/src/class/classes.rs create mode 100644 huia-compiler/src/class/mod.rs create mode 100644 huia-compiler/src/instructions/mod.rs delete mode 100644 huia-compiler/src/trait.rs create mode 100644 huia-compiler/src/trait/actual.rs create mode 100644 huia-compiler/src/trait/mod.rs create mode 100644 huia-compiler/src/trait/trait_id.rs create mode 100644 huia-compiler/src/trait/traits.rs diff --git a/huia-compiler/src/class.rs b/huia-compiler/src/class.rs deleted file mode 100644 index 1902e74..0000000 --- a/huia-compiler/src/class.rs +++ /dev/null @@ -1,144 +0,0 @@ -use crate::identifier::Identifier; -use std::sync::RwLock; -use wrc::WRC; - -#[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 From for ClassId { - fn from(data: usize) -> ClassId { - ClassId(data) - } -} - -#[derive(Default, Debug)] -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 next_id(&self) -> ClassId { - let elements = self.0.read().unwrap(); - ClassId(elements.len()) - } - - pub fn find(&self, name: Identifier) -> Option { - let elements = self.0.read().unwrap(); - let class = elements.iter().find(|class| class.name() == name); - match class { - Some(class) => Some(class.id()), - None => None, - } - } - - pub fn is_empty(&self) -> bool { - let elements = self.0.read().unwrap(); - elements.is_empty() - } -} - -#[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 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 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.identifiers().get("Marty McFly")); - class.set_name(context.identifiers().get("Doc Brown")); - assert_eq!(class.name(), context.identifiers().get("Doc Brown")); - } -} diff --git a/huia-compiler/src/class/actual.rs b/huia-compiler/src/class/actual.rs new file mode 100644 index 0000000..c69482e --- /dev/null +++ b/huia-compiler/src/class/actual.rs @@ -0,0 +1,68 @@ +use crate::class::ClassId; +use crate::identifier::Identifier; +use std::sync::RwLock; +use wrc::WRC; + +#[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 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 crate::context::Context; + + #[test] + fn set_name() { + let mut context = Context::new(); + let class = context.new_class("Marty McFly"); + assert_eq!(class.name(), context.identifiers().get("Marty McFly")); + class.set_name(context.identifiers().get("Doc Brown")); + assert_eq!(class.name(), context.identifiers().get("Doc Brown")); + } +} diff --git a/huia-compiler/src/class/class_id.rs b/huia-compiler/src/class/class_id.rs new file mode 100644 index 0000000..366e8a8 --- /dev/null +++ b/huia-compiler/src/class/class_id.rs @@ -0,0 +1,14 @@ +#[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 From for ClassId { + fn from(data: usize) -> ClassId { + ClassId(data) + } +} diff --git a/huia-compiler/src/class/classes.rs b/huia-compiler/src/class/classes.rs new file mode 100644 index 0000000..0438eb7 --- /dev/null +++ b/huia-compiler/src/class/classes.rs @@ -0,0 +1,69 @@ +use crate::class::{Class, ClassId}; +use crate::identifier::Identifier; +use std::sync::RwLock; + +#[derive(Default, Debug)] +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(usize::from(idx)) { + Some(class) => Some(class.clone()), + None => None, + } + } + + pub fn next_id(&self) -> ClassId { + let elements = self.0.read().unwrap(); + ClassId::from(elements.len()) + } + + pub fn find(&self, name: Identifier) -> Option { + let elements = self.0.read().unwrap(); + let class = elements.iter().find(|class| class.name() == name); + match class { + Some(class) => Some(class.id()), + None => None, + } + } + + pub fn is_empty(&self) -> bool { + let elements = self.0.read().unwrap(); + elements.is_empty() + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::identifier::Identifiers; + + #[test] + fn test() { + let 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!(usize::from(idx), 0); + + let class1 = classes.get(idx).unwrap(); + assert_eq!(class1.id(), id); + assert_eq!(class1.name(), identifiers.get("Marty McFly")); + } +} diff --git a/huia-compiler/src/class/mod.rs b/huia-compiler/src/class/mod.rs new file mode 100644 index 0000000..3908365 --- /dev/null +++ b/huia-compiler/src/class/mod.rs @@ -0,0 +1,6 @@ +mod actual; +mod class_id; +mod classes; +pub use actual::Class; +pub use class_id::ClassId; +pub use classes::Classes; diff --git a/huia-compiler/src/instructions/mod.rs b/huia-compiler/src/instructions/mod.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/huia-compiler/src/instructions/mod.rs @@ -0,0 +1 @@ + diff --git a/huia-compiler/src/lib.rs b/huia-compiler/src/lib.rs index 80ef8d0..db51a90 100644 --- a/huia-compiler/src/lib.rs +++ b/huia-compiler/src/lib.rs @@ -6,6 +6,7 @@ mod class; mod constant; mod context; mod identifier; +mod instructions; mod r#trait; mod r#type; mod type_spec; diff --git a/huia-compiler/src/trait.rs b/huia-compiler/src/trait.rs deleted file mode 100644 index e6c81dd..0000000 --- a/huia-compiler/src/trait.rs +++ /dev/null @@ -1,144 +0,0 @@ -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) - } -} - -#[derive(Default, Debug)] -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 find(&self, name: Identifier) -> Option { - let elements = self.0.read().unwrap(); - let tr = elements.iter().find(|tr| tr.name() == name); - match tr { - Some(tr) => Some(tr.id()), - None => None, - } - } - - 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 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.identifiers().get("Marty McFly")); - tr.set_name(context.identifiers().get("Doc Brown")); - assert_eq!(tr.name(), context.identifiers().get("Doc Brown")); - } -} diff --git a/huia-compiler/src/trait/actual.rs b/huia-compiler/src/trait/actual.rs new file mode 100644 index 0000000..fdaead8 --- /dev/null +++ b/huia-compiler/src/trait/actual.rs @@ -0,0 +1,99 @@ +use crate::identifier::Identifier; +use crate::r#trait::TraitId; +use crate::r#type::Type; +use crate::type_spec::TypeSpec; +use std::sync::RwLock; +use wrc::WRC; + +#[derive(Debug, Clone)] +pub struct Trait(WRC>); + +#[derive(Debug)] +pub struct TraitInner { + id: TraitId, + name: Identifier, + requires: TypeSpec, +} + +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 { + let requires = TypeSpec::new(); + Trait(WRC::new(RwLock::new(TraitInner { id, name, requires }))) + } + + 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); + } + + pub fn require>(&self, r#type: T) { + let ty: Type = r#type.into(); + let mut tr = self.0.write().unwrap(); + tr.requires.push(ty); + } + + pub fn requires>(&self, r#type: T) -> bool { + let ty: Type = r#type.into(); + let tr = self.0.read().unwrap(); + tr.requires.matches(ty) + } +} + +impl PartialEq for Trait { + fn eq(&self, other: &Trait) -> bool { + self.id() == other.id() + } +} + +#[cfg(test)] +mod test { + use crate::context::Context; + + #[test] + fn set_name() { + let mut context = Context::new(); + let tr = context.new_trait("Marty McFly"); + assert_eq!(tr.name(), context.identifiers().get("Marty McFly")); + tr.set_name(context.identifiers().get("Doc Brown")); + assert_eq!(tr.name(), context.identifiers().get("Doc Brown")); + } + + #[test] + fn requires() { + let mut context = Context::new(); + let tr0 = context.new_trait("Marty McFly"); + + let tr1 = context.new_trait("Doc Brown"); + let cl0 = context.new_class("Einstein Brown"); + + tr0.require(tr1.id()); + tr0.require(cl0.id()); + + assert!(tr0.requires(tr1)); + assert!(tr0.requires(cl0)); + } +} diff --git a/huia-compiler/src/trait/mod.rs b/huia-compiler/src/trait/mod.rs new file mode 100644 index 0000000..3f26abf --- /dev/null +++ b/huia-compiler/src/trait/mod.rs @@ -0,0 +1,6 @@ +mod actual; +mod trait_id; +mod traits; +pub use actual::Trait; +pub use trait_id::TraitId; +pub use traits::Traits; diff --git a/huia-compiler/src/trait/trait_id.rs b/huia-compiler/src/trait/trait_id.rs new file mode 100644 index 0000000..d9fc83c --- /dev/null +++ b/huia-compiler/src/trait/trait_id.rs @@ -0,0 +1,14 @@ +#[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) + } +} diff --git a/huia-compiler/src/trait/traits.rs b/huia-compiler/src/trait/traits.rs new file mode 100644 index 0000000..19caf71 --- /dev/null +++ b/huia-compiler/src/trait/traits.rs @@ -0,0 +1,70 @@ +use crate::identifier::Identifier; +use crate::r#trait::{Trait, TraitId}; +use std::sync::RwLock; + +#[derive(Default, Debug)] +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(usize::from(idx)) { + Some(tr) => Some(tr.clone()), + None => None, + } + } + + pub fn next_id(&self) -> TraitId { + let elements = self.0.read().unwrap(); + TraitId::from(elements.len()) + } + + pub fn find(&self, name: Identifier) -> Option { + let elements = self.0.read().unwrap(); + let tr = elements.iter().find(|tr| tr.name() == name); + match tr { + Some(tr) => Some(tr.id()), + None => None, + } + } + + pub fn is_empty(&self) -> bool { + let elements = self.0.read().unwrap(); + elements.is_empty() + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::identifier::Identifiers; + + #[test] + fn test() { + let 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!(usize::from(idx), 0); + + let trait1 = traits.get(idx).unwrap(); + assert_eq!(trait1.id(), id); + assert_eq!(trait1.name(), identifiers.get("Marty McFly")); + } + +} diff --git a/huia-compiler/src/type.rs b/huia-compiler/src/type.rs index 853c92c..57a95c6 100644 --- a/huia-compiler/src/type.rs +++ b/huia-compiler/src/type.rs @@ -1,5 +1,5 @@ -use crate::class::ClassId; -use crate::r#trait::TraitId; +use crate::class::{Class, ClassId}; +use crate::r#trait::{Trait, TraitId}; #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] pub enum Type { @@ -49,6 +49,18 @@ impl From for Type { } } +impl From for Type { + fn from(class: Class) -> Type { + Type::Class(class.id()) + } +} + +impl From for Type { + fn from(tr: Trait) -> Type { + Type::Trait(tr.id()) + } +} + #[cfg(test)] mod test { use super::*;