ucglib/build/opcode/
mod.rs

1// Copyright 2019 Jeremy Wall
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14use std::rc::Rc;
15
16mod cache;
17mod debug;
18mod display;
19pub mod environment;
20#[macro_use]
21pub mod error;
22mod convert;
23pub mod pointer;
24mod runtime;
25pub mod scope;
26pub mod translate;
27mod vm;
28
29pub use environment::Environment;
30pub use error::Error;
31pub use vm::VM;
32
33use crate::ast::{CastType, Position};
34use pointer::OpPointer;
35use scope::Stack;
36
37#[derive(Debug, PartialEq, Clone)]
38pub enum Primitive {
39    // Primitive Types
40    Int(i64),
41    Float(f64),
42    Str(String),
43    Bool(bool),
44    Empty,
45}
46
47use Primitive::{Bool, Empty, Float, Int, Str};
48
49impl Value {
50    fn type_name(&self) -> &'static str {
51        match self {
52            P(Int(_)) => "Int",
53            P(Float(_)) => "Float",
54            P(Str(_)) => "String",
55            P(Bool(_)) => "Bool",
56            P(Empty) => "NULL",
57            C(List(_, _)) => "List",
58            C(Tuple(_, _)) => "Tuple",
59            F(_) => "Func",
60            M(_) => "Func",
61            T(_) => "Expression",
62            S(_) => "Symbol",
63        }
64    }
65}
66
67#[derive(Debug, PartialEq, Clone)]
68pub enum Composite {
69    List(Vec<Rc<Value>>, Vec<Position>),
70    Tuple(Vec<(String, Rc<Value>)>, Vec<(Position, Position)>),
71}
72
73use Composite::{List, Tuple};
74
75#[derive(Debug, PartialEq, Clone)]
76pub struct Func {
77    ptr: OpPointer,
78    bindings: Vec<String>,
79    snapshot: Stack,
80}
81
82#[derive(Debug, PartialEq, Clone)]
83pub struct Module {
84    ptr: OpPointer,
85    result_ptr: Option<usize>,
86    flds: Vec<(String, Rc<Value>)>,
87    flds_pos_list: Vec<(Position, Position)>,
88    pkg_ptr: Option<OpPointer>,
89}
90
91#[derive(Clone)]
92pub enum Value {
93    // Binding names.
94    S(String),
95    // Primitive Types
96    P(Primitive),
97    // Composite Types.
98    C(Composite),
99    // Program Pointer
100    T(usize),
101    // Function
102    F(Func),
103    // Module
104    M(Module),
105}
106
107use Value::{C, F, M, P, S, T};
108
109#[derive(Debug, PartialEq, Clone)]
110pub enum Hook {
111    Map,
112    Include,
113    Filter,
114    Reduce,
115    Import,
116    Out,
117    Assert,
118    Convert,
119    Regex,
120    Range,
121    Trace(Position),
122}
123
124#[derive(Debug, PartialEq, Clone)]
125pub enum Op {
126    // Stack and Name manipulation.
127    Bind,     // Bind a Val to a name in the heap
128    BindOver, // Overwrite a value in the heap
129    Pop,      // Pop a Value off the value stack and discard it.
130    NewScope(i32),
131    // Math ops
132    Add,
133    Sub,
134    Div,
135    Mul,
136    Mod,
137    // Comparison Ops
138    Equal,
139    Gt,
140    Lt,
141    GtEq,
142    LtEq,
143    // Not,
144    Not,
145    // Primitive Types ops
146    Val(Primitive),
147    // Primitive casts
148    Cast(CastType),
149    // A bareword for use in bindings or lookups
150    Sym(String),
151    // Reference a binding on the heap
152    DeRef(String),
153    // Complex Type ops
154    InitTuple,
155    Field,
156    InitList,
157    Element,
158    // Copy Operation
159    Cp,
160    // Control Flow
161    Bang,
162    Jump(i32),
163    JumpIfTrue(i32),
164    JumpIfFalse(i32),
165    SelectJump(i32),
166    And(i32),
167    Or(i32),
168    // Spacer operation, Does nothing.
169    Index,     // indexing operation
170    SafeIndex, // Safe indexing operation. Does Null Coelescing
171    Exist,
172    Noop,
173    // Pending Computation
174    InitThunk(i32), // Basically just used for module return expressions
175    Module(i32),
176    Func(i32),
177    Return,
178    // Calls
179    FCall,
180    // TypeSystem
181    Typ,
182    // Runtime hooks
183    Runtime(Hook),
184    Render,
185    // The self lookup for tuples.
186    PushSelf,
187    PopSelf,
188}
189
190use super::ir::Val;
191
192impl PartialEq for Value {
193    fn eq(&self, other: &Value) -> bool {
194        match (self, other) {
195            (P(left), P(right)) => left == right,
196            (C(List(left, _)), C(List(right, _))) => left == right,
197            (C(Tuple(left, _)), C(Tuple(right, _))) => {
198                if left.len() != right.len() {
199                    return false;
200                }
201                for (ref lk, ref lv) in left.iter() {
202                    let mut found = false;
203                    for (ref rk, ref rv) in right.iter() {
204                        if lk == rk {
205                            found = true;
206                            if lv != rv {
207                                return false;
208                            }
209                        }
210                    }
211                    if !found {
212                        return false;
213                    }
214                }
215                true
216            }
217            (F(left), F(right)) => left == right,
218            (M(left), M(right)) => left == right,
219            (T(_), T(_)) | (S(_), S(_)) => false,
220            (_, _) => false,
221        }
222    }
223}