use std::collections;
use std::fmt;
use specs;
use specs::Component;
use specs::VecStorage;
#[derive(Component, Debug, VisitEntities, VisitEntitiesMut)]
#[storage(VecStorage)]
pub enum Element {
Number(Number),
String(String),
Symbol(Symbol),
Tuple(Tuple),
Record(Record),
UnOp(UnOp),
BiOp(BiOp),
Variable(Variable),
Select(Select),
Apply(Apply),
Parameter(Parameter),
Capture(Capture),
Closure(Closure),
Module(Module),
}
#[derive(Clone, Copy, Debug, VisitEntities, VisitEntitiesMut)]
pub enum Number {
U8(u8),
U16(u16),
U32(u32),
U64(u64),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
F32(f32),
F64(f64),
}
#[derive(Debug, VisitEntities, VisitEntitiesMut)]
pub struct Symbol {
pub label: String,
}
#[derive(Debug, VisitEntities, VisitEntitiesMut)]
pub struct Tuple {
pub fields: Vec<specs::Entity>,
}
#[derive(Debug, VisitEntities, VisitEntitiesMut)]
pub struct Record {
pub fields: collections::HashMap<String, specs::Entity>,
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, VisitEntities, VisitEntitiesMut)]
pub enum UnOperator {
Not,
BNot,
Cl0,
Cl1,
Cls,
Ct0,
Ct1,
C0,
C1,
Sqrt,
}
#[derive(Clone, Copy, Debug, PartialEq, VisitEntities, VisitEntitiesMut)]
pub struct UnOp {
pub operator: UnOperator,
pub operand: specs::Entity,
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, VisitEntities, VisitEntitiesMut)]
pub enum BiOperator {
Eq,
Ne,
Lt,
Ge,
Gt,
Le,
Cmp,
Add,
Sub,
Mul,
Div,
Rem,
And,
BAnd,
Or,
BOr,
Xor,
BXor,
AndNot,
BAndNot,
OrNot,
BOrNot,
XorNot,
BXorNot,
RotL,
RotR,
ShL,
ShR,
}
#[derive(Clone, Copy, Debug, PartialEq, VisitEntities, VisitEntitiesMut)]
pub struct BiOp {
pub lhs: specs::Entity,
pub operator: BiOperator,
pub rhs: specs::Entity,
}
#[derive(Debug, VisitEntities, VisitEntitiesMut)]
pub struct Variable {
pub name: String,
pub initializer: specs::Entity,
}
#[derive(Debug, VisitEntities, VisitEntitiesMut)]
pub struct Select {
pub record: specs::Entity,
pub field: String,
}
#[derive(Debug, VisitEntities, VisitEntitiesMut)]
pub struct Apply {
pub function: specs::Entity,
pub parameters: Vec<specs::Entity>,
}
#[derive(Debug, VisitEntities, VisitEntitiesMut)]
pub struct Parameter {
pub name: String,
pub signature: Option<specs::Entity>,
}
#[derive(Debug, VisitEntities, VisitEntitiesMut)]
pub struct Capture {
pub name: String,
pub captured: specs::Entity,
}
#[derive(Debug, VisitEntities, VisitEntitiesMut)]
pub struct Closure {
pub captures: Vec<specs::Entity>,
pub parameters: Vec<specs::Entity>,
pub statements: Vec<specs::Entity>,
pub signature: Option<specs::Entity>,
pub result: specs::Entity,
}
#[derive(Debug, VisitEntities, VisitEntitiesMut)]
pub struct Module {
pub variables: collections::HashMap<String, specs::Entity>,
}
impl fmt::Display for UnOperator {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match *self {
UnOperator::Not => "!",
UnOperator::BNot => "~!",
UnOperator::Cl0 => "#^0",
UnOperator::Cl1 => "#^1",
UnOperator::Cls => "#^-",
UnOperator::Ct0 => "#$0",
UnOperator::Ct1 => "#$1",
UnOperator::C0 => "#0",
UnOperator::C1 => "#1",
UnOperator::Sqrt => "^/",
})
}
}
impl fmt::Display for BiOperator {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match *self {
BiOperator::Eq => "==",
BiOperator::Ne => "!=",
BiOperator::Lt => "<",
BiOperator::Ge => ">=",
BiOperator::Gt => ">",
BiOperator::Le => "<=",
BiOperator::Cmp => "<=>",
BiOperator::Add => "+",
BiOperator::Sub => "-",
BiOperator::Mul => "*",
BiOperator::Div => "/",
BiOperator::Rem => "%",
BiOperator::And => "&",
BiOperator::BAnd => "~&",
BiOperator::Or => "|",
BiOperator::BOr => "~|",
BiOperator::Xor => "^",
BiOperator::BXor => "~^",
BiOperator::AndNot => "&!",
BiOperator::BAndNot => "~&!",
BiOperator::OrNot => "|!",
BiOperator::BOrNot => "~|!",
BiOperator::XorNot => "^!",
BiOperator::BXorNot => "~^!",
BiOperator::RotL => "<-<",
BiOperator::RotR => ">->",
BiOperator::ShL => "<<",
BiOperator::ShR => ">>",
})
}
}