Extract types into separate files.

This commit is contained in:
James Harton 2019-02-23 10:14:46 +13:00
parent 80b549b586
commit 4aa61a7a21
13 changed files with 362 additions and 290 deletions

View file

@ -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<ClassId> for usize {
fn from(data: ClassId) -> usize {
data.0
}
}
impl From<usize> for ClassId {
fn from(data: usize) -> ClassId {
ClassId(data)
}
}
#[derive(Default, Debug)]
pub struct Classes(RwLock<Vec<Class>>);
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<Class> {
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<ClassId> {
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<RwLock<ClassInner>>);
#[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"));
}
}

View file

@ -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<RwLock<ClassInner>>);
#[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"));
}
}

View file

@ -0,0 +1,14 @@
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct ClassId(usize);
impl From<ClassId> for usize {
fn from(data: ClassId) -> usize {
data.0
}
}
impl From<usize> for ClassId {
fn from(data: usize) -> ClassId {
ClassId(data)
}
}

View file

@ -0,0 +1,69 @@
use crate::class::{Class, ClassId};
use crate::identifier::Identifier;
use std::sync::RwLock;
#[derive(Default, Debug)]
pub struct Classes(RwLock<Vec<Class>>);
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<Class> {
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<ClassId> {
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"));
}
}

View file

@ -0,0 +1,6 @@
mod actual;
mod class_id;
mod classes;
pub use actual::Class;
pub use class_id::ClassId;
pub use classes::Classes;

View file

@ -0,0 +1 @@

View file

@ -6,6 +6,7 @@ mod class;
mod constant; mod constant;
mod context; mod context;
mod identifier; mod identifier;
mod instructions;
mod r#trait; mod r#trait;
mod r#type; mod r#type;
mod type_spec; mod type_spec;

View file

@ -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<TraitId> for usize {
fn from(data: TraitId) -> usize {
data.0
}
}
impl From<usize> for TraitId {
fn from(data: usize) -> TraitId {
TraitId(data)
}
}
#[derive(Default, Debug)]
pub struct Traits(RwLock<Vec<Trait>>);
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<Trait> {
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<TraitId> {
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<RwLock<TraitInner>>);
#[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"));
}
}

View file

@ -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<RwLock<TraitInner>>);
#[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<T: Into<Type>>(&self, r#type: T) {
let ty: Type = r#type.into();
let mut tr = self.0.write().unwrap();
tr.requires.push(ty);
}
pub fn requires<T: Into<Type>>(&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));
}
}

View file

@ -0,0 +1,6 @@
mod actual;
mod trait_id;
mod traits;
pub use actual::Trait;
pub use trait_id::TraitId;
pub use traits::Traits;

View file

@ -0,0 +1,14 @@
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct TraitId(usize);
impl From<TraitId> for usize {
fn from(data: TraitId) -> usize {
data.0
}
}
impl From<usize> for TraitId {
fn from(data: usize) -> TraitId {
TraitId(data)
}
}

View file

@ -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<Vec<Trait>>);
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<Trait> {
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<TraitId> {
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"));
}
}

View file

@ -1,5 +1,5 @@
use crate::class::ClassId; use crate::class::{Class, ClassId};
use crate::r#trait::TraitId; use crate::r#trait::{Trait, TraitId};
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub enum Type { pub enum Type {
@ -49,6 +49,18 @@ impl From<TraitId> for Type {
} }
} }
impl From<Class> for Type {
fn from(class: Class) -> Type {
Type::Class(class.id())
}
}
impl From<Trait> for Type {
fn from(tr: Trait) -> Type {
Type::Trait(tr.id())
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;