From 2b2d40bb55faa4e07966495f57b7aeba1652c5e6 Mon Sep 17 00:00:00 2001 From: James Harton Date: Sat, 23 Feb 2019 15:15:14 +1300 Subject: [PATCH] Add functions/clauses/arguments. --- huia-compiler/src/class/actual.rs | 2 +- huia-compiler/src/context.rs | 7 +++ huia-compiler/src/function/actual.rs | 76 +++++++++++++++++++++++ huia-compiler/src/function/argument.rs | 29 +++++++++ huia-compiler/src/function/clause.rs | 41 ++++++++++++ huia-compiler/src/function/clause_id.rs | 15 +++++ huia-compiler/src/function/function_id.rs | 14 +++++ huia-compiler/src/function/functions.rs | 69 ++++++++++++++++++++ huia-compiler/src/function/mod.rs | 13 ++++ huia-compiler/src/lib.rs | 6 +- huia-compiler/src/property_type_map.rs | 44 +++++++++++++ huia-compiler/src/type_spec.rs | 9 +++ 12 files changed, 320 insertions(+), 5 deletions(-) create mode 100644 huia-compiler/src/function/actual.rs create mode 100644 huia-compiler/src/function/argument.rs create mode 100644 huia-compiler/src/function/clause.rs create mode 100644 huia-compiler/src/function/clause_id.rs create mode 100644 huia-compiler/src/function/function_id.rs create mode 100644 huia-compiler/src/function/functions.rs create mode 100644 huia-compiler/src/function/mod.rs create mode 100644 huia-compiler/src/property_type_map.rs diff --git a/huia-compiler/src/class/actual.rs b/huia-compiler/src/class/actual.rs index c69482e..a752cbb 100644 --- a/huia-compiler/src/class/actual.rs +++ b/huia-compiler/src/class/actual.rs @@ -7,7 +7,7 @@ use wrc::WRC; pub struct Class(WRC>); #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct ClassInner { +struct ClassInner { id: ClassId, name: Identifier, } diff --git a/huia-compiler/src/context.rs b/huia-compiler/src/context.rs index cb76dcb..84990e4 100644 --- a/huia-compiler/src/context.rs +++ b/huia-compiler/src/context.rs @@ -1,5 +1,6 @@ use crate::class::{Class, Classes}; use crate::constant::Constants; +use crate::function::Functions; use crate::identifier::Identifiers; use crate::r#trait::{Trait, Traits}; @@ -9,6 +10,7 @@ pub struct Context { traits: Traits, identifiers: Identifiers, constants: Constants, + functions: Functions, } impl Context { @@ -18,6 +20,7 @@ impl Context { traits: Traits::new(), identifiers: Identifiers::new(), constants: Constants::new(), + functions: Functions::new(), } } @@ -58,6 +61,10 @@ impl Context { pub fn traits(&self) -> &Traits { &self.traits } + + pub fn functions(&self) -> &Functions { + &self.functions + } } #[cfg(test)] diff --git a/huia-compiler/src/function/actual.rs b/huia-compiler/src/function/actual.rs new file mode 100644 index 0000000..7f4c630 --- /dev/null +++ b/huia-compiler/src/function/actual.rs @@ -0,0 +1,76 @@ +use crate::function::{Clause, ClauseId, FunctionId}; +use crate::identifier::Identifier; +use std::sync::RwLock; +use wrc::WRC; + +#[derive(Debug, Clone)] +pub struct Function(WRC>); + +#[derive(Debug)] +struct FunctionInner { + id: FunctionId, + name: Identifier, + clauses: Vec, +} + +impl FunctionInner { + fn id(&self) -> FunctionId { + self.id + } + + fn name(&self) -> Identifier { + self.name + } + + fn set_name(&mut self, name: Identifier) { + self.name = name + } + + fn add_clause(&mut self, clause: Clause) -> ClauseId { + let idx = self.clauses.len(); + self.clauses.push(clause); + ClauseId::from(idx) + } + + fn next_id(&self) -> ClauseId { + ClauseId::from(self.clauses.len()) + } +} + +impl Function { + pub fn new(id: FunctionId, name: Identifier) -> Function { + let clauses = Vec::new(); + Function(WRC::new(RwLock::new(FunctionInner { id, name, clauses }))) + } + + pub fn id(&self) -> FunctionId { + let fun = self.0.read().unwrap(); + fun.id() + } + + pub fn name(&self) -> Identifier { + let fun = self.0.read().unwrap(); + fun.name() + } + + pub fn set_name(&self, name: Identifier) { + let mut fun = self.0.write().unwrap(); + fun.set_name(name); + } + + pub fn add_clause(&self, clause: Clause) -> ClauseId { + let mut fun = self.0.write().unwrap(); + fun.add_clause(clause) + } + + pub fn next_id(&self) -> ClauseId { + let fun = self.0.read().unwrap(); + fun.next_id() + } +} + +impl PartialEq for Function { + fn eq(&self, other: &Function) -> bool { + self.id() == other.id() + } +} diff --git a/huia-compiler/src/function/argument.rs b/huia-compiler/src/function/argument.rs new file mode 100644 index 0000000..2757f48 --- /dev/null +++ b/huia-compiler/src/function/argument.rs @@ -0,0 +1,29 @@ +use crate::identifier::Identifier; +use crate::type_spec::TypeSpec; + +#[derive(Debug)] +pub struct Argument { + name: Identifier, + type_spec: TypeSpec, +} + +impl Argument { + pub fn new(name: Identifier) -> Argument { + Argument { + name, + type_spec: TypeSpec::new(), + } + } + + pub fn name(&self) -> Identifier { + self.name + } + + pub fn set_name(&mut self, name: Identifier) { + self.name = name; + } + + pub fn type_spec(&self) -> &TypeSpec { + &self.type_spec + } +} diff --git a/huia-compiler/src/function/clause.rs b/huia-compiler/src/function/clause.rs new file mode 100644 index 0000000..0eceff8 --- /dev/null +++ b/huia-compiler/src/function/clause.rs @@ -0,0 +1,41 @@ +use crate::function::{Argument, ClauseId}; +use std::sync::RwLock; +use wrc::WRC; + +#[derive(Debug)] +pub struct Clause(WRC>); + +#[derive(Debug)] +struct ClauseInner { + id: ClauseId, + args: Vec, +} + +impl ClauseInner { + fn id(&self) -> ClauseId { + self.id + } + + fn push_arg(&mut self, arg: Argument) { + self.args.push(arg); + } +} + +impl Clause { + pub fn new(id: ClauseId) -> Clause { + Clause(WRC::new(RwLock::new(ClauseInner { + id, + args: Vec::new(), + }))) + } + + pub fn id(&self) -> ClauseId { + let clause = self.0.read().unwrap(); + clause.id() + } + + pub fn push_arg(&self, arg: Argument) { + let mut clause = self.0.write().unwrap(); + clause.push_arg(arg); + } +} diff --git a/huia-compiler/src/function/clause_id.rs b/huia-compiler/src/function/clause_id.rs new file mode 100644 index 0000000..a227463 --- /dev/null +++ b/huia-compiler/src/function/clause_id.rs @@ -0,0 +1,15 @@ + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct ClauseId(usize); + +impl From for usize { + fn from(data: ClauseId) -> usize { + data.0 + } +} + +impl From for ClauseId { + fn from(data: usize) -> ClauseId { + ClauseId(data) + } +} diff --git a/huia-compiler/src/function/function_id.rs b/huia-compiler/src/function/function_id.rs new file mode 100644 index 0000000..95d932f --- /dev/null +++ b/huia-compiler/src/function/function_id.rs @@ -0,0 +1,14 @@ +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct FunctionId(usize); + +impl From for usize { + fn from(data: FunctionId) -> usize { + data.0 + } +} + +impl From for FunctionId { + fn from(data: usize) -> FunctionId { + FunctionId(data) + } +} diff --git a/huia-compiler/src/function/functions.rs b/huia-compiler/src/function/functions.rs new file mode 100644 index 0000000..544d1a4 --- /dev/null +++ b/huia-compiler/src/function/functions.rs @@ -0,0 +1,69 @@ +use crate::function::{Function, FunctionId}; +use crate::identifier::Identifier; +use std::sync::RwLock; + +#[derive(Default, Debug)] +pub struct Functions(RwLock>); + +impl Functions { + pub fn new() -> Functions { + Functions(RwLock::new(Vec::new())) + } + + pub fn push(&mut self, function: Function) -> FunctionId { + let mut elements = self.0.write().unwrap(); + let idx = elements.len(); + elements.push(function); + FunctionId::from(idx) + } + + pub fn get(&self, idx: FunctionId) -> Option { + let elements = self.0.read().unwrap(); + match elements.get(usize::from(idx)) { + Some(function) => Some(function.clone()), + None => None, + } + } + + pub fn next_id(&self) -> FunctionId { + let elements = self.0.read().unwrap(); + FunctionId::from(elements.len()) + } + + pub fn find(&self, name: Identifier) -> Option { + let elements = self.0.read().unwrap(); + let function = elements.iter().find(|function| function.name() == name); + match function { + Some(function) => Some(function.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 functions = Functions::new(); + + let id = functions.next_id(); + let name = identifiers.get("Marty McFly"); + let function0 = Function::new(id, name); + + let idx = functions.push(function0); + assert_eq!(usize::from(idx), 0); + + let function1 = functions.get(idx).unwrap(); + assert_eq!(function1.id(), id); + assert_eq!(function1.name(), identifiers.get("Marty McFly")); + } +} diff --git a/huia-compiler/src/function/mod.rs b/huia-compiler/src/function/mod.rs new file mode 100644 index 0000000..ff52f99 --- /dev/null +++ b/huia-compiler/src/function/mod.rs @@ -0,0 +1,13 @@ +mod actual; +mod clause; +mod clause_id; +mod function_id; +mod functions; +mod argument; + +pub use actual::Function; +pub use clause::Clause; +pub use clause_id::ClauseId; +pub use function_id::FunctionId; +pub use functions::Functions; +pub use argument::Argument; diff --git a/huia-compiler/src/lib.rs b/huia-compiler/src/lib.rs index db51a90..593dab6 100644 --- a/huia-compiler/src/lib.rs +++ b/huia-compiler/src/lib.rs @@ -1,12 +1,10 @@ -extern crate huia_parser; -extern crate string_interner; -extern crate wrc; - mod class; mod constant; mod context; +mod function; mod identifier; mod instructions; +mod property_type_map; mod r#trait; mod r#type; mod type_spec; diff --git a/huia-compiler/src/property_type_map.rs b/huia-compiler/src/property_type_map.rs new file mode 100644 index 0000000..1d1c3b3 --- /dev/null +++ b/huia-compiler/src/property_type_map.rs @@ -0,0 +1,44 @@ +use crate::identifier::Identifier; +use crate::type_spec::TypeSpec; +use std::collections::BTreeMap; + +#[derive(Debug, Default)] +pub struct PropertyTypeMap(BTreeMap); + +impl PropertyTypeMap { + pub fn new() -> PropertyTypeMap { + PropertyTypeMap(BTreeMap::new()) + } + + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + pub fn insert(&mut self, name: Identifier, ts: TypeSpec) { + self.0.insert(name, ts); + } + + pub fn has_property(&self, name: Identifier) -> bool { + self.0.contains_key(&name) + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::context::Context; + + #[test] + fn test() { + let mut context = Context::new(); + + let mut ptm = PropertyTypeMap::new(); + assert!(ptm.is_empty()); + + let pname = context.identifiers().get("character"); + let ptype = TypeSpec::from(context.new_trait("Character")); + ptm.insert(pname, ptype); + + assert!(ptm.has_property(pname)); + } +} diff --git a/huia-compiler/src/type_spec.rs b/huia-compiler/src/type_spec.rs index 3ec78ac..9a63347 100644 --- a/huia-compiler/src/type_spec.rs +++ b/huia-compiler/src/type_spec.rs @@ -17,6 +17,15 @@ impl TypeSpec { } } +impl> From for TypeSpec { + fn from(ty: T) -> TypeSpec { + let ty: Type = ty.into(); + let mut ts = TypeSpec::new(); + ts.push(ty); + ts + } +} + #[cfg(test)] mod test { use super::*;