Remove compiler. Again.
This commit is contained in:
parent
33e364bf38
commit
b7d15a2c3c
29 changed files with 0 additions and 1238 deletions
|
@ -1,29 +0,0 @@
|
|||
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, ts: TypeSpec) -> Argument {
|
||||
Argument {
|
||||
name,
|
||||
type_spec: ts,
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
use crate::context::Context;
|
||||
|
||||
pub fn bootstrap(context: &mut Context) {
|
||||
context.ensure_class(context.ident("Huia.Native.Array"));
|
||||
context.ensure_class(context.ident("Huia.Native.Atom"));
|
||||
context.ensure_class(context.ident("Huia.Native.Boolean"));
|
||||
context.ensure_class(context.ident("Huia.Native.Float"));
|
||||
context.ensure_class(context.ident("Huia.Native.Integer"));
|
||||
context.ensure_class(context.ident("Huia.Native.Map"));
|
||||
context.ensure_class(context.ident("Huia.Native.String"));
|
||||
}
|
|
@ -1,137 +0,0 @@
|
|||
use crate::argument::Argument;
|
||||
use crate::identifier::Identifier;
|
||||
use crate::method::{Method, MethodId};
|
||||
use crate::types::TypeId;
|
||||
use crate::vtable::VTable;
|
||||
use std::sync::RwLock;
|
||||
use wrc::WRC;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Class(WRC<RwLock<ClassInner>>);
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ClassInner {
|
||||
id: TypeId,
|
||||
name: Identifier,
|
||||
properties: Vec<Argument>,
|
||||
vtable: VTable,
|
||||
impls: Vec<(TypeId, VTable)>,
|
||||
}
|
||||
|
||||
impl ClassInner {
|
||||
fn id(&self) -> TypeId {
|
||||
self.id
|
||||
}
|
||||
|
||||
fn name(&self) -> Identifier {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn set_name(&mut self, name: Identifier) {
|
||||
self.name = name
|
||||
}
|
||||
|
||||
fn add_method(&mut self, method: Method) -> MethodId {
|
||||
self.vtable.add_method(method)
|
||||
}
|
||||
|
||||
fn next_id(&self) -> MethodId {
|
||||
self.vtable.next_id()
|
||||
}
|
||||
|
||||
fn add_property(&mut self, property: Argument) {
|
||||
self.properties.push(property);
|
||||
}
|
||||
|
||||
fn has_property(&self, name: Identifier) -> bool {
|
||||
self.properties.iter().any(|p| p.name() == name)
|
||||
}
|
||||
|
||||
fn implement(&mut self, tr: TypeId, vtable: VTable) {
|
||||
self.impls.push((tr, vtable));
|
||||
}
|
||||
|
||||
fn implements(&self, tr: TypeId) -> bool {
|
||||
self.impls.iter().any(|(tr0, _)| tr0 == &tr)
|
||||
}
|
||||
}
|
||||
|
||||
impl Class {
|
||||
pub fn new(id: TypeId, name: Identifier) -> Class {
|
||||
let vtable = VTable::new();
|
||||
let impls = Vec::new();
|
||||
let properties = Vec::new();
|
||||
Class(WRC::new(RwLock::new(ClassInner {
|
||||
id,
|
||||
name,
|
||||
vtable,
|
||||
properties,
|
||||
impls,
|
||||
})))
|
||||
}
|
||||
|
||||
pub fn id(&self) -> TypeId {
|
||||
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);
|
||||
}
|
||||
|
||||
pub fn add_method(&self, method: Method) -> MethodId {
|
||||
let mut class = self.0.write().unwrap();
|
||||
class.add_method(method)
|
||||
}
|
||||
|
||||
pub fn next_id(&self) -> MethodId {
|
||||
let class = self.0.read().unwrap();
|
||||
class.next_id()
|
||||
}
|
||||
|
||||
pub fn add_property(&self, property: Argument) {
|
||||
let mut class = self.0.write().unwrap();
|
||||
class.add_property(property);
|
||||
}
|
||||
|
||||
pub fn has_property(&self, name: Identifier) -> bool {
|
||||
let class = self.0.read().unwrap();
|
||||
class.has_property(name)
|
||||
}
|
||||
|
||||
pub fn implement(&self, tr: TypeId, vtable: VTable) {
|
||||
let mut class = self.0.write().unwrap();
|
||||
class.implement(tr, vtable);
|
||||
}
|
||||
|
||||
pub fn implements(&self, tr: TypeId) -> bool {
|
||||
let class = self.0.read().unwrap();
|
||||
class.implements(tr)
|
||||
}
|
||||
}
|
||||
|
||||
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.ensure_class(context.ident("Marty McFly"));
|
||||
assert_eq!(class.name(), context.ident("Marty McFly"));
|
||||
class.set_name(context.ident("Doc Brown"));
|
||||
assert_eq!(class.name(), context.ident("Doc Brown"));
|
||||
}
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
mod actual;
|
||||
pub use actual::Class;
|
|
@ -1,117 +0,0 @@
|
|||
use crate::classes::Class;
|
||||
use crate::function::Functions;
|
||||
use crate::identifier::{Identifier, Identifiers};
|
||||
use crate::scope::Scope;
|
||||
use crate::traits::Trait;
|
||||
use crate::types::{Type, TypeId, TypeTable};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Context {
|
||||
types: TypeTable,
|
||||
identifiers: Identifiers,
|
||||
functions: Functions,
|
||||
globals: Scope,
|
||||
}
|
||||
|
||||
impl Default for Context {
|
||||
fn default() -> Context {
|
||||
Context::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn new() -> Context {
|
||||
Context {
|
||||
types: TypeTable::new(),
|
||||
identifiers: Identifiers::new(),
|
||||
functions: Functions::new(),
|
||||
globals: Scope::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ensure_class(&self, name: Identifier) -> Class {
|
||||
match self.get_type_by_name(name) {
|
||||
Some(ty) => match ty.as_class() {
|
||||
Some(ty) => ty,
|
||||
None => self.create_class(name),
|
||||
},
|
||||
None => self.create_class(name),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ensure_trait(&self, name: Identifier) -> Trait {
|
||||
match self.get_type_by_name(name) {
|
||||
Some(ty) => match ty.as_trait() {
|
||||
Some(ty) => ty,
|
||||
None => self.create_trait(name),
|
||||
},
|
||||
None => self.create_trait(name),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_class(&self, name: Identifier) -> Class {
|
||||
let id = self.types.next_id();
|
||||
let class = Class::new(id, name);
|
||||
self.types.push(class.clone());
|
||||
class
|
||||
}
|
||||
|
||||
fn create_trait(&self, name: Identifier) -> Trait {
|
||||
let id = self.types.next_id();
|
||||
let tr = Trait::new(id, name);
|
||||
self.types.push(tr.clone());
|
||||
tr
|
||||
}
|
||||
|
||||
pub fn get_type(&self, id: TypeId) -> Option<Type> {
|
||||
self.types.get(id)
|
||||
}
|
||||
|
||||
pub fn get_type_by_name(&self, name: Identifier) -> Option<Type> {
|
||||
self.types.find(name)
|
||||
}
|
||||
|
||||
pub fn ident(&self, name: &str) -> Identifier {
|
||||
self.identifiers().get(name)
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.identifiers.is_empty() && self.types.is_empty()
|
||||
}
|
||||
|
||||
pub fn identifiers(&self) -> &Identifiers {
|
||||
&self.identifiers
|
||||
}
|
||||
|
||||
pub fn types(&self) -> &TypeTable {
|
||||
&self.types
|
||||
}
|
||||
|
||||
pub fn functions(&self) -> &Functions {
|
||||
&self.functions
|
||||
}
|
||||
|
||||
pub fn globals(&self) -> &Scope {
|
||||
&self.globals
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn new() {
|
||||
let context = Context::new();
|
||||
let class0 = context.ensure_class(context.ident("Marty McFly"));
|
||||
let class1 = context.types().get(class0.id()).unwrap();
|
||||
assert_eq!(class0, class1);
|
||||
|
||||
let tr0 = context.ensure_trait(context.ident("Doc Brown"));
|
||||
let tr1 = context.types().get(tr0.id()).unwrap();
|
||||
assert_eq!(tr0, tr1);
|
||||
|
||||
let id = context.ident("Einstein Brown");
|
||||
assert_eq!(context.identifiers().resolve(id).unwrap(), "Einstein Brown");
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
use crate::function::{Clause, ClauseId, FunctionId};
|
||||
use std::sync::RwLock;
|
||||
use wrc::WRC;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Function(WRC<RwLock<FunctionInner>>);
|
||||
|
||||
#[derive(Debug)]
|
||||
struct FunctionInner {
|
||||
id: FunctionId,
|
||||
clauses: Vec<Clause>,
|
||||
}
|
||||
|
||||
impl FunctionInner {
|
||||
fn id(&self) -> FunctionId {
|
||||
self.id
|
||||
}
|
||||
|
||||
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) -> Function {
|
||||
let clauses = Vec::new();
|
||||
Function(WRC::new(RwLock::new(FunctionInner { id, clauses })))
|
||||
}
|
||||
|
||||
pub fn id(&self) -> FunctionId {
|
||||
let fun = self.0.read().unwrap();
|
||||
fun.id()
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
use crate::argument::Argument;
|
||||
use crate::function::ClauseId;
|
||||
use std::sync::RwLock;
|
||||
use wrc::WRC;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
#[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)
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#[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)
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
use crate::function::{Function, FunctionId};
|
||||
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 is_empty(&self) -> bool {
|
||||
let elements = self.0.read().unwrap();
|
||||
elements.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let mut functions = Functions::new();
|
||||
|
||||
let id = functions.next_id();
|
||||
let function0 = Function::new(id);
|
||||
|
||||
let idx = functions.push(function0);
|
||||
assert_eq!(usize::from(idx), 0);
|
||||
|
||||
let function1 = functions.get(idx).unwrap();
|
||||
assert_eq!(function1.id(), id);
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
mod actual;
|
||||
mod clause;
|
||||
mod clause_id;
|
||||
mod function_id;
|
||||
mod functions;
|
||||
|
||||
pub use actual::Function;
|
||||
pub use clause::Clause;
|
||||
pub use clause_id::ClauseId;
|
||||
pub use function_id::FunctionId;
|
||||
pub use functions::Functions;
|
|
@ -1,49 +0,0 @@
|
|||
use std::sync::RwLock;
|
||||
use string_interner::{StringInterner, Sym};
|
||||
|
||||
#[derive(Debug, Clone, Hash, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Identifier(Sym);
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Identifiers(RwLock<StringInterner<Sym>>);
|
||||
|
||||
impl Identifiers {
|
||||
pub fn new() -> Identifiers {
|
||||
Identifiers(RwLock::new(StringInterner::default()))
|
||||
}
|
||||
|
||||
pub fn get(&self, value: &str) -> Identifier {
|
||||
let mut identifiers = self.0.write().unwrap();
|
||||
let sym = identifiers.get_or_intern(value);
|
||||
Identifier(sym)
|
||||
}
|
||||
|
||||
pub fn resolve(&self, identifier: Identifier) -> Option<String> {
|
||||
let identifiers = self.0.read().unwrap();
|
||||
match identifiers.resolve(identifier.0) {
|
||||
Some(s) => Some(s.to_string()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.read().unwrap().is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let identifiers = Identifiers::new();
|
||||
|
||||
assert!(identifiers.is_empty());
|
||||
let sym0 = identifiers.get("Marty McFly");
|
||||
let sym1 = identifiers.get("Marty McFly");
|
||||
assert!(!identifiers.is_empty());
|
||||
assert_eq!(sym0, sym1);
|
||||
assert_eq!(identifiers.resolve(sym0).unwrap(), "Marty McFly");
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
mod argument;
|
||||
mod bootstrap;
|
||||
mod classes;
|
||||
mod context;
|
||||
mod function;
|
||||
mod identifier;
|
||||
mod method;
|
||||
mod object;
|
||||
mod parse_consumer;
|
||||
mod scope;
|
||||
mod stack;
|
||||
mod traits;
|
||||
mod type_spec;
|
||||
mod types;
|
||||
mod vtable;
|
||||
|
||||
pub use argument::Argument;
|
||||
pub use classes::Class;
|
||||
pub use context::Context;
|
||||
pub use identifier::Identifier;
|
||||
pub use object::Object;
|
||||
pub use traits::Trait;
|
||||
pub use type_spec::TypeSpec;
|
||||
pub use types::TypeId;
|
|
@ -1,50 +0,0 @@
|
|||
use crate::function::FunctionId;
|
||||
use crate::identifier::Identifier;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Method {
|
||||
name: Identifier,
|
||||
function: FunctionId,
|
||||
flag: Flag,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Flag {
|
||||
Public,
|
||||
Private,
|
||||
Static,
|
||||
}
|
||||
|
||||
impl Method {
|
||||
pub fn new(name: Identifier, function: FunctionId, flag: Flag) -> Method {
|
||||
Method {
|
||||
name,
|
||||
function,
|
||||
flag,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> Identifier {
|
||||
self.name
|
||||
}
|
||||
|
||||
pub fn set_name(&mut self, name: Identifier) {
|
||||
self.name = name;
|
||||
}
|
||||
|
||||
pub fn function(&self) -> FunctionId {
|
||||
self.function
|
||||
}
|
||||
|
||||
pub fn set_function(&mut self, function: FunctionId) {
|
||||
self.function = function
|
||||
}
|
||||
|
||||
pub fn flag(&self) -> Flag {
|
||||
self.flag
|
||||
}
|
||||
|
||||
pub fn set_flag(&mut self, flag: Flag) {
|
||||
self.flag = flag;
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct MethodId(usize);
|
||||
|
||||
impl From<MethodId> for usize {
|
||||
fn from(data: MethodId) -> usize {
|
||||
data.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for MethodId {
|
||||
fn from(data: usize) -> MethodId {
|
||||
MethodId(data)
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
mod actual;
|
||||
mod method_id;
|
||||
|
||||
pub use actual::{Flag, Method};
|
||||
pub use method_id::MethodId;
|
|
@ -1,94 +0,0 @@
|
|||
use crate::classes::Class;
|
||||
use crate::types::TypeId;
|
||||
use std::hash;
|
||||
use string_interner::Sym;
|
||||
use wrc::WRC;
|
||||
|
||||
#[derive(Debug, PartialOrd, Clone)]
|
||||
pub struct Object(WRC<ObjectInner>);
|
||||
|
||||
#[derive(Debug, PartialEq, PartialOrd)]
|
||||
struct ObjectInner {
|
||||
type_id: TypeId,
|
||||
value: ObjectValue,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, PartialOrd)]
|
||||
pub enum ObjectValue {
|
||||
Array(Vec<Object>),
|
||||
Atom(Sym),
|
||||
False,
|
||||
Float(f64),
|
||||
Integer(i64),
|
||||
String(Sym),
|
||||
True,
|
||||
}
|
||||
|
||||
impl From<Vec<Object>> for ObjectValue {
|
||||
fn from(data: Vec<Object>) -> ObjectValue {
|
||||
ObjectValue::Array(data)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bool> for ObjectValue {
|
||||
fn from(data: bool) -> ObjectValue {
|
||||
if data {
|
||||
ObjectValue::True
|
||||
} else {
|
||||
ObjectValue::False
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f64> for ObjectValue {
|
||||
fn from(data: f64) -> ObjectValue {
|
||||
ObjectValue::Float(data)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i64> for ObjectValue {
|
||||
fn from(data: i64) -> ObjectValue {
|
||||
ObjectValue::Integer(data)
|
||||
}
|
||||
}
|
||||
|
||||
impl Object {
|
||||
pub fn alloc(class: Class, data: ObjectValue) -> Object {
|
||||
Object(WRC::new(ObjectInner {
|
||||
type_id: class.id(),
|
||||
value: data,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn type_id(&self) -> TypeId {
|
||||
self.0.type_id
|
||||
}
|
||||
}
|
||||
|
||||
impl hash::Hash for Object {
|
||||
fn hash<H: hash::Hasher>(&self, mut h: &mut H) {
|
||||
self.0.type_id.hash(&mut h);
|
||||
match &self.0.value {
|
||||
ObjectValue::Array(objs) => {
|
||||
for o in objs {
|
||||
o.hash(&mut h)
|
||||
}
|
||||
}
|
||||
ObjectValue::Atom(s) => s.hash(&mut h),
|
||||
ObjectValue::False => false.hash(&mut h),
|
||||
ObjectValue::Float(f) => {
|
||||
let bitpattern = unsafe { std::mem::transmute::<f64, u64>(*f) };
|
||||
bitpattern.hash(&mut h);
|
||||
}
|
||||
ObjectValue::Integer(i) => i.hash(&mut h),
|
||||
ObjectValue::String(s) => s.hash(&mut h),
|
||||
ObjectValue::True => true.hash(&mut h),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Object {
|
||||
fn eq(&self, other: &Object) -> bool {
|
||||
self.0.type_id == other.0.type_id && self.0.value == other.0.value
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
use crate::context::Context;
|
||||
use huia_parser::ast::{NodeType, Term, Value};
|
||||
|
||||
pub fn consume(mut context: &mut Context, term: &Term) {
|
||||
match term.node_type() {
|
||||
NodeType::Definition => {
|
||||
let (deftype, defname, args, body, reqs) = term.definition().unwrap();
|
||||
println!("deftype = {:?}", deftype);
|
||||
println!("defname = {:?}", defname);
|
||||
println!("args = {:?}", args);
|
||||
println!("body = {:?}", body);
|
||||
println!("reqs = {:?}", reqs);
|
||||
|
||||
match deftype.value_ref().as_str() {
|
||||
"type" => {
|
||||
let class = context
|
||||
.ensure_class(context.ident(defname.typename().unwrap().value_ref()));
|
||||
}
|
||||
"trait" => {
|
||||
let tr = context
|
||||
.ensure_trait(context.ident(defname.typename().unwrap().value_ref()));
|
||||
}
|
||||
"def" => {}
|
||||
"defp" => {}
|
||||
"defs" => {}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
_ => panic!("Unexpected term {:?}", term),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_definition() {
|
||||
let mut context = Context::new();
|
||||
let terms = Term::input("type Delorean(speed: Integer + Add)").unwrap();
|
||||
for term in terms {
|
||||
consume(&mut context, &term)
|
||||
}
|
||||
assert!(false);
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
use crate::identifier::Identifier;
|
||||
use crate::object::Object;
|
||||
use std::sync::RwLock;
|
||||
|
||||
// Uses a vec of ident-object pairs to ensure that assignments are in SSA form.
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Scope(RwLock<Vec<(Identifier, Object)>>);
|
||||
|
||||
impl Scope {
|
||||
pub fn new() -> Scope {
|
||||
Scope(RwLock::new(Vec::new()))
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
let scope = self.0.read().unwrap();
|
||||
scope.is_empty()
|
||||
}
|
||||
|
||||
pub fn set(&self, name: Identifier, value: Object) {
|
||||
let mut scope = self.0.write().unwrap();
|
||||
scope.push((name, value))
|
||||
}
|
||||
|
||||
pub fn get(&self, name: Identifier) -> Option<Object> {
|
||||
let scope = self.0.write().unwrap();
|
||||
match scope.iter().rev().find(|(n, _)| n == &name) {
|
||||
Some((_, o)) => Some(o.clone()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
use std::fmt::Debug;
|
||||
use std::sync::RwLock;
|
||||
use wrc::WRC;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Stack<T: Debug>(RwLock<StackInner<T>>);
|
||||
|
||||
impl<T: Debug> Stack<T> {
|
||||
pub fn new() -> Stack<T> {
|
||||
Stack(RwLock::new(StackInner::new()))
|
||||
}
|
||||
|
||||
pub fn push(&self, entry: T) {
|
||||
let mut entries = self.0.write().unwrap();
|
||||
entries.push(entry)
|
||||
}
|
||||
|
||||
pub fn pop(&self) -> Option<WRC<T>> {
|
||||
let mut entries = self.0.write().unwrap();
|
||||
entries.pop()
|
||||
}
|
||||
|
||||
pub fn peek(&self) -> WRC<T> {
|
||||
let entries = self.0.read().unwrap();
|
||||
entries.peek()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct StackInner<T: Debug>(Vec<WRC<T>>);
|
||||
|
||||
impl<T: Debug> StackInner<T> {
|
||||
fn new() -> StackInner<T> {
|
||||
StackInner(Vec::new())
|
||||
}
|
||||
|
||||
fn push(&mut self, entry: T) {
|
||||
self.0.push(WRC::new(entry))
|
||||
}
|
||||
|
||||
fn pop(&mut self) -> Option<WRC<T>> {
|
||||
self.0.pop().clone()
|
||||
}
|
||||
|
||||
fn peek(&self) -> WRC<T> {
|
||||
let idx = self.0.len() - 1;
|
||||
self.0[idx].clone()
|
||||
}
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
use crate::identifier::Identifier;
|
||||
use crate::method::{Method, MethodId};
|
||||
use crate::type_spec::TypeSpec;
|
||||
use crate::types::TypeId;
|
||||
use crate::types::TypeRef;
|
||||
use crate::vtable::VTable;
|
||||
use std::sync::RwLock;
|
||||
use wrc::WRC;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Trait(WRC<RwLock<TraitInner>>);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TraitInner {
|
||||
id: TypeId,
|
||||
name: Identifier,
|
||||
requires: TypeSpec,
|
||||
vtable: VTable,
|
||||
}
|
||||
|
||||
impl TraitInner {
|
||||
fn id(&self) -> TypeId {
|
||||
self.id
|
||||
}
|
||||
|
||||
fn name(&self) -> Identifier {
|
||||
self.name
|
||||
}
|
||||
|
||||
fn set_name(&mut self, name: Identifier) {
|
||||
self.name = name
|
||||
}
|
||||
|
||||
fn add_method(&mut self, method: Method) -> MethodId {
|
||||
self.vtable.add_method(method)
|
||||
}
|
||||
|
||||
fn next_id(&self) -> MethodId {
|
||||
self.vtable.next_id()
|
||||
}
|
||||
}
|
||||
|
||||
impl Trait {
|
||||
pub fn new(id: TypeId, name: Identifier) -> Trait {
|
||||
let requires = TypeSpec::new();
|
||||
let vtable = VTable::new();
|
||||
Trait(WRC::new(RwLock::new(TraitInner {
|
||||
id,
|
||||
name,
|
||||
requires,
|
||||
vtable,
|
||||
})))
|
||||
}
|
||||
|
||||
pub fn id(&self) -> TypeId {
|
||||
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(&self, t: TypeRef) {
|
||||
let mut tr = self.0.write().unwrap();
|
||||
tr.requires.push(t);
|
||||
}
|
||||
|
||||
pub fn requires(&self, t: TypeRef) -> bool {
|
||||
let tr = self.0.read().unwrap();
|
||||
tr.requires.matches(t)
|
||||
}
|
||||
|
||||
pub fn add_method(&self, method: Method) -> MethodId {
|
||||
let mut tr = self.0.write().unwrap();
|
||||
tr.add_method(method)
|
||||
}
|
||||
|
||||
pub fn next_id(&self) -> MethodId {
|
||||
let tr = self.0.read().unwrap();
|
||||
tr.next_id()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Trait {
|
||||
fn eq(&self, other: &Trait) -> bool {
|
||||
self.id() == other.id()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::context::Context;
|
||||
|
||||
#[test]
|
||||
fn set_name() {
|
||||
let mut context = Context::new();
|
||||
let tr = context.ensure_trait(context.ident("Marty McFly"));
|
||||
assert_eq!(tr.name(), context.ident("Marty McFly"));
|
||||
tr.set_name(context.ident("Doc Brown"));
|
||||
assert_eq!(tr.name(), context.ident("Doc Brown"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn requires() {
|
||||
let mut context = Context::new();
|
||||
let tr0 = context.ensure_trait(context.ident("Marty McFly"));
|
||||
|
||||
let tr1 = TypeRef::from(context.ident("Doc Brown"));
|
||||
let tr2 = TypeRef::from(context.ident("Einstein Brown"));
|
||||
|
||||
tr0.require(tr1);
|
||||
tr0.require(tr2);
|
||||
|
||||
assert!(tr0.requires(tr1));
|
||||
assert!(tr0.requires(tr2));
|
||||
}
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
mod actual;
|
||||
pub use actual::Trait;
|
|
@ -1,18 +0,0 @@
|
|||
use crate::types::TypeRef;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct TypeSpec(Vec<TypeRef>);
|
||||
|
||||
impl TypeSpec {
|
||||
pub fn new() -> TypeSpec {
|
||||
TypeSpec(Vec::new())
|
||||
}
|
||||
|
||||
pub fn push(&mut self, tr: TypeRef) {
|
||||
self.0.push(tr)
|
||||
}
|
||||
|
||||
pub fn matches(&self, tr: TypeRef) -> bool {
|
||||
self.0.iter().any(|i| i == &tr)
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
use crate::classes::Class;
|
||||
use crate::identifier::Identifier;
|
||||
use crate::traits::Trait;
|
||||
use crate::types::TypeId;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Type {
|
||||
Class(Class),
|
||||
Trait(Trait),
|
||||
}
|
||||
|
||||
impl Type {
|
||||
pub fn new<T: Into<Type>>(inner: T) -> Type {
|
||||
inner.into()
|
||||
}
|
||||
|
||||
pub fn id(&self) -> TypeId {
|
||||
match self {
|
||||
Type::Class(t) => t.id(),
|
||||
Type::Trait(t) => t.id(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> Identifier {
|
||||
match self {
|
||||
Type::Class(t) => t.name(),
|
||||
Type::Trait(t) => t.name(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_class(&self) -> Option<Class> {
|
||||
match self {
|
||||
Type::Class(t) => Some(t.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_trait(&self) -> Option<Trait> {
|
||||
match self {
|
||||
Type::Trait(t) => Some(t.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_class(&self) -> bool {
|
||||
match self {
|
||||
Type::Class(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_trait(&self) -> bool {
|
||||
match self {
|
||||
Type::Trait(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Class> for Type {
|
||||
fn from(class: Class) -> Type {
|
||||
Type::Class(class)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Trait> for Type {
|
||||
fn from(tr: Trait) -> Type {
|
||||
Type::Trait(tr)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Type {
|
||||
fn eq(&self, other: &Type) -> bool {
|
||||
self.id() == other.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Class> for Type {
|
||||
fn eq(&self, other: &Class) -> bool {
|
||||
match self {
|
||||
Type::Class(c) => c.id() == other.id(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Trait> for Type {
|
||||
fn eq(&self, other: &Trait) -> bool {
|
||||
match self {
|
||||
Type::Trait(c) => c.id() == other.id(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Type> for Trait {
|
||||
fn eq(&self, other: &Type) -> bool {
|
||||
match other {
|
||||
Type::Trait(c) => c.id() == self.id(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Type> for Class {
|
||||
fn eq(&self, other: &Type) -> bool {
|
||||
match other {
|
||||
Type::Class(c) => c.id() == self.id(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
mod actual;
|
||||
mod table;
|
||||
mod type_id;
|
||||
mod type_ref;
|
||||
pub use actual::Type;
|
||||
pub use table::TypeTable;
|
||||
pub use type_id::TypeId;
|
||||
pub use type_ref::TypeRef;
|
|
@ -1,45 +0,0 @@
|
|||
use crate::identifier::Identifier;
|
||||
use crate::types::{Type, TypeId};
|
||||
use std::sync::RwLock;
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct TypeTable(RwLock<Vec<Type>>);
|
||||
|
||||
impl TypeTable {
|
||||
pub fn new() -> TypeTable {
|
||||
TypeTable(RwLock::new(Vec::new()))
|
||||
}
|
||||
|
||||
pub fn push<T: Into<Type>>(&self, ty: T) -> TypeId {
|
||||
let mut elements = self.0.write().unwrap();
|
||||
let ty: Type = ty.into();
|
||||
elements.push(ty.clone());
|
||||
ty.id()
|
||||
}
|
||||
|
||||
pub fn get(&self, idx: TypeId) -> Option<Type> {
|
||||
let elements = self.0.read().unwrap();
|
||||
match elements.get(usize::from(idx)) {
|
||||
Some(ty) => Some(ty.clone()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next_id(&self) -> TypeId {
|
||||
let elements = self.0.read().unwrap();
|
||||
TypeId::from(elements.len())
|
||||
}
|
||||
|
||||
pub fn find(&self, name: Identifier) -> Option<Type> {
|
||||
let elements = self.0.read().unwrap();
|
||||
match elements.iter().find(|ty| ty.name() == name) {
|
||||
Some(ty) => Some(ty.clone()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
let elements = self.0.read().unwrap();
|
||||
elements.is_empty()
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
use crate::classes::Class;
|
||||
use crate::traits::Trait;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct TypeId(usize);
|
||||
|
||||
impl From<Class> for TypeId {
|
||||
fn from(cl: Class) -> TypeId {
|
||||
cl.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Trait> for TypeId {
|
||||
fn from(tr: Trait) -> TypeId {
|
||||
tr.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TypeId> for usize {
|
||||
fn from(id: TypeId) -> usize {
|
||||
id.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for TypeId {
|
||||
fn from(id: usize) -> TypeId {
|
||||
TypeId(id)
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
use crate::identifier::Identifier;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct TypeRef(Identifier);
|
||||
|
||||
impl From<Identifier> for TypeRef {
|
||||
fn from(i: Identifier) -> TypeRef {
|
||||
TypeRef(i)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TypeRef> for Identifier {
|
||||
fn from(tr: TypeRef) -> Identifier {
|
||||
tr.0
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
use crate::method::{Method, MethodId};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct VTable(Vec<Method>);
|
||||
|
||||
impl VTable {
|
||||
pub fn new() -> VTable {
|
||||
VTable(Vec::new())
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn add_method(&mut self, method: Method) -> MethodId {
|
||||
let idx = self.0.len();
|
||||
self.0.push(method);
|
||||
MethodId::from(idx)
|
||||
}
|
||||
|
||||
pub fn get(&self, idx: MethodId) -> Option<Method> {
|
||||
match self.0.get(usize::from(idx)) {
|
||||
Some(method) => Some(method.clone()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next_id(&self) -> MethodId {
|
||||
MethodId::from(self.0.len())
|
||||
}
|
||||
}
|
Reference in a new issue