// Copyright 2019 Jeremy Wall // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. 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 { // Primitive Types Int(i64), Float(f64), Str(String), 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>, Vec), Tuple(Vec<(String, Rc)>, Vec<(Position, Position)>), } use Composite::{List, Tuple}; #[derive(Debug, PartialEq, Clone)] pub struct Func { ptr: OpPointer, bindings: Vec, snapshot: Stack, } #[derive(Debug, PartialEq, Clone)] pub struct Module { ptr: OpPointer, result_ptr: Option, flds: Vec<(String, Rc)>, flds_pos_list: Vec<(Position, Position)>, pkg_ptr: Option, } #[derive(Clone)] pub enum Value { // Binding names. S(String), // Primitive Types P(Primitive), // Composite Types. C(Composite), // Program Pointer T(usize), // Function F(Func), // Module 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 { // Stack and Name manipulation. Bind, // Bind a Val to a name in the heap BindOver, // Overwrite a value in the heap Pop, // Pop a Value off the value stack and discard it. NewScope(i32), // Math ops Add, Sub, Div, Mul, Mod, // Comparison Ops Equal, Gt, Lt, GtEq, LtEq, // Not, Not, // Primitive Types ops Val(Primitive), // Primitive casts Cast(CastType), // A bareword for use in bindings or lookups Sym(String), // Reference a binding on the heap DeRef(String), // Complex Type ops InitTuple, Field, InitList, Element, // Copy Operation Cp, // Control Flow Bang, Jump(i32), JumpIfTrue(i32), JumpIfFalse(i32), SelectJump(i32), And(i32), Or(i32), // Spacer operation, Does nothing. Index, // indexing operation SafeIndex, // Safe indexing operation. Does Null Coelescing Exist, Noop, // Pending Computation InitThunk(i32), // Basically just used for module return expressions Module(i32), Func(i32), Return, // Calls FCall, // TypeSystem Typ, // Runtime hooks Runtime(Hook), Render, // The self lookup for tuples. 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, } } }