Extract types into separate files.
This commit is contained in:
parent
80b549b586
commit
4aa61a7a21
13 changed files with 362 additions and 290 deletions
|
@ -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"));
|
|
||||||
}
|
|
||||||
}
|
|
68
huia-compiler/src/class/actual.rs
Normal file
68
huia-compiler/src/class/actual.rs
Normal 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"));
|
||||||
|
}
|
||||||
|
}
|
14
huia-compiler/src/class/class_id.rs
Normal file
14
huia-compiler/src/class/class_id.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
69
huia-compiler/src/class/classes.rs
Normal file
69
huia-compiler/src/class/classes.rs
Normal 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"));
|
||||||
|
}
|
||||||
|
}
|
6
huia-compiler/src/class/mod.rs
Normal file
6
huia-compiler/src/class/mod.rs
Normal 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;
|
1
huia-compiler/src/instructions/mod.rs
Normal file
1
huia-compiler/src/instructions/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"));
|
|
||||||
}
|
|
||||||
}
|
|
99
huia-compiler/src/trait/actual.rs
Normal file
99
huia-compiler/src/trait/actual.rs
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
6
huia-compiler/src/trait/mod.rs
Normal file
6
huia-compiler/src/trait/mod.rs
Normal 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;
|
14
huia-compiler/src/trait/trait_id.rs
Normal file
14
huia-compiler/src/trait/trait_id.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
70
huia-compiler/src/trait/traits.rs
Normal file
70
huia-compiler/src/trait/traits.rs
Normal 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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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::*;
|
||||||
|
|
Reference in a new issue