Add functions/clauses/arguments.

This commit is contained in:
James Harton 2019-02-23 15:15:14 +13:00
parent 4aa61a7a21
commit 2b2d40bb55
12 changed files with 320 additions and 5 deletions

View file

@ -7,7 +7,7 @@ use wrc::WRC;
pub struct Class(WRC<RwLock<ClassInner>>);
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct ClassInner {
struct ClassInner {
id: ClassId,
name: Identifier,
}

View file

@ -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)]

View file

@ -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<RwLock<FunctionInner>>);
#[derive(Debug)]
struct FunctionInner {
id: FunctionId,
name: Identifier,
clauses: Vec<Clause>,
}
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()
}
}

View file

@ -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
}
}

View file

@ -0,0 +1,41 @@
use crate::function::{Argument, ClauseId};
use std::sync::RwLock;
use wrc::WRC;
#[derive(Debug)]
pub struct Clause(WRC<RwLock<ClauseInner>>);
#[derive(Debug)]
struct ClauseInner {
id: ClauseId,
args: Vec<Argument>,
}
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);
}
}

View file

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

View file

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

View file

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

View file

@ -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;

View file

@ -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;

View file

@ -0,0 +1,44 @@
use crate::identifier::Identifier;
use crate::type_spec::TypeSpec;
use std::collections::BTreeMap;
#[derive(Debug, Default)]
pub struct PropertyTypeMap(BTreeMap<Identifier, TypeSpec>);
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));
}
}

View file

@ -17,6 +17,15 @@ impl TypeSpec {
}
}
impl<T: Into<Type>> From<T> 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::*;