Add functions/clauses/arguments.
This commit is contained in:
parent
4aa61a7a21
commit
2b2d40bb55
12 changed files with 320 additions and 5 deletions
|
@ -7,7 +7,7 @@ use wrc::WRC;
|
||||||
pub struct Class(WRC<RwLock<ClassInner>>);
|
pub struct Class(WRC<RwLock<ClassInner>>);
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
pub struct ClassInner {
|
struct ClassInner {
|
||||||
id: ClassId,
|
id: ClassId,
|
||||||
name: Identifier,
|
name: Identifier,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::class::{Class, Classes};
|
use crate::class::{Class, Classes};
|
||||||
use crate::constant::Constants;
|
use crate::constant::Constants;
|
||||||
|
use crate::function::Functions;
|
||||||
use crate::identifier::Identifiers;
|
use crate::identifier::Identifiers;
|
||||||
use crate::r#trait::{Trait, Traits};
|
use crate::r#trait::{Trait, Traits};
|
||||||
|
|
||||||
|
@ -9,6 +10,7 @@ pub struct Context {
|
||||||
traits: Traits,
|
traits: Traits,
|
||||||
identifiers: Identifiers,
|
identifiers: Identifiers,
|
||||||
constants: Constants,
|
constants: Constants,
|
||||||
|
functions: Functions,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
|
@ -18,6 +20,7 @@ impl Context {
|
||||||
traits: Traits::new(),
|
traits: Traits::new(),
|
||||||
identifiers: Identifiers::new(),
|
identifiers: Identifiers::new(),
|
||||||
constants: Constants::new(),
|
constants: Constants::new(),
|
||||||
|
functions: Functions::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +61,10 @@ impl Context {
|
||||||
pub fn traits(&self) -> &Traits {
|
pub fn traits(&self) -> &Traits {
|
||||||
&self.traits
|
&self.traits
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn functions(&self) -> &Functions {
|
||||||
|
&self.functions
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
76
huia-compiler/src/function/actual.rs
Normal file
76
huia-compiler/src/function/actual.rs
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
29
huia-compiler/src/function/argument.rs
Normal file
29
huia-compiler/src/function/argument.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
41
huia-compiler/src/function/clause.rs
Normal file
41
huia-compiler/src/function/clause.rs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
15
huia-compiler/src/function/clause_id.rs
Normal file
15
huia-compiler/src/function/clause_id.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
14
huia-compiler/src/function/function_id.rs
Normal file
14
huia-compiler/src/function/function_id.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
69
huia-compiler/src/function/functions.rs
Normal file
69
huia-compiler/src/function/functions.rs
Normal 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"));
|
||||||
|
}
|
||||||
|
}
|
13
huia-compiler/src/function/mod.rs
Normal file
13
huia-compiler/src/function/mod.rs
Normal 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;
|
|
@ -1,12 +1,10 @@
|
||||||
extern crate huia_parser;
|
|
||||||
extern crate string_interner;
|
|
||||||
extern crate wrc;
|
|
||||||
|
|
||||||
mod class;
|
mod class;
|
||||||
mod constant;
|
mod constant;
|
||||||
mod context;
|
mod context;
|
||||||
|
mod function;
|
||||||
mod identifier;
|
mod identifier;
|
||||||
mod instructions;
|
mod instructions;
|
||||||
|
mod property_type_map;
|
||||||
mod r#trait;
|
mod r#trait;
|
||||||
mod r#type;
|
mod r#type;
|
||||||
mod type_spec;
|
mod type_spec;
|
||||||
|
|
44
huia-compiler/src/property_type_map.rs
Normal file
44
huia-compiler/src/property_type_map.rs
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
Reference in a new issue