use std::rc::Rc;
mod cache;
mod debug;
mod display;
pub mod environment;
#[macro_use]
pub mod error;
mod convert;
pub mod pointer;
mod runtime;
pub mod scope;
pub mod translate;
mod vm;
pub use environment::Environment;
pub use error::Error;
pub use vm::VM;
use crate::ast::{CastType, Position};
use pointer::OpPointer;
use scope::Stack;
#[derive(Debug, PartialEq, Clone)]
pub enum Primitive {
Int(i64),
Float(f64),
Str(Rc<str>),
Bool(bool),
Empty,
}
use Primitive::{Bool, Empty, Float, Int, Str};
impl Value {
fn type_name(&self) -> &'static str {
match self {
P(Int(_)) => "Int",
P(Float(_)) => "Float",
P(Str(_)) => "String",
P(Bool(_)) => "Bool",
P(Empty) => "NULL",
C(List(_, _)) => "List",
C(Tuple(_, _)) => "Tuple",
F(_) => "Func",
M(_) => "Func",
T(_) => "Expression",
S(_) => "Symbol",
}
}
}
#[derive(Debug, PartialEq, Clone)]
pub enum Composite {
List(Vec<Rc<Value>>, Vec<Position>),
Tuple(Vec<(Rc<str>, Rc<Value>)>, Vec<(Position, Position)>),
}
use Composite::{List, Tuple};
#[derive(Debug, PartialEq, Clone)]
pub struct Func {
ptr: OpPointer,
bindings: Vec<Rc<str>>,
snapshot: Stack,
}
#[derive(Debug, PartialEq, Clone)]
pub struct Module {
ptr: OpPointer,
result_ptr: Option<usize>,
flds: Vec<(Rc<str>, Rc<Value>)>,
flds_pos_list: Vec<(Position, Position)>,
pkg_ptr: Option<OpPointer>,
}
#[derive(Clone)]
pub enum Value {
S(Rc<str>),
P(Primitive),
C(Composite),
T(usize),
F(Func),
M(Module),
}
use Value::{C, F, M, P, S, T};
#[derive(Debug, PartialEq, Clone)]
pub enum Hook {
Map,
Include,
Filter,
Reduce,
Import,
Out,
Assert,
Convert,
Regex,
Range,
Trace(Position),
}
#[derive(Debug, PartialEq, Clone)]
pub enum Op {
Bind, BindOver, Pop, NewScope(i32),
Add,
Sub,
Div,
Mul,
Mod,
Equal,
Gt,
Lt,
GtEq,
LtEq,
Not,
Val(Primitive),
Cast(CastType),
Sym(Rc<str>),
DeRef(Rc<str>),
InitTuple,
Field,
InitList,
Element,
Cp,
Bang,
Jump(i32),
JumpIfTrue(i32),
JumpIfFalse(i32),
SelectJump(i32),
And(i32),
Or(i32),
Index, SafeIndex, Exist,
Noop,
InitThunk(i32), Module(i32),
Func(i32),
Return,
FCall,
Typ,
Runtime(Hook),
Render,
PushSelf,
PopSelf,
}
use super::ir::Val;
impl PartialEq for Value {
fn eq(&self, other: &Value) -> bool {
match (self, other) {
(P(left), P(right)) => left == right,
(C(List(left, _)), C(List(right, _))) => left == right,
(C(Tuple(left, _)), C(Tuple(right, _))) => {
if left.len() != right.len() {
return false;
}
for (ref lk, ref lv) in left.iter() {
let mut found = false;
for (ref rk, ref rv) in right.iter() {
if lk == rk {
found = true;
if lv != rv {
return false;
}
}
}
if !found {
return false;
}
}
true
}
(F(left), F(right)) => left == right,
(M(left), M(right)) => left == right,
(T(_), T(_)) | (S(_), S(_)) => false,
(_, _) => false,
}
}
}