use hashbrown::HashMap; use ecow::EcoString; use crate::ty::internal::{Const, Param}; type Slice = Box<[T]>; pub type OpCodes = Slice; #[derive(Debug, Clone, Copy)] pub enum OpCode { /// load a constant onto stack Const { idx: usize }, /// load a dynamic var onto stack LookUp { sym: usize }, /// load a thunk lazily onto stack LoadThunk { idx: usize }, /// let TOS capture current environment CaptureEnv, /// force TOS to value ForceValue, /// [ .. func args @ .. ] consume (`arity` + 1) elements, call `func` with args` of length `arity` /// Example: __add 1 2 => [ LookUp("__add") Const(1) Const(2) Call(2) ] Call { arity: usize }, /// make a function Func { idx: usize }, /// consume 1 element, assert TOS is true Assert, /// jump forward Jmp { step: usize }, /// [ .. cond ] consume 1 element, if `cond`` is true, then jump forward JmpIfTrue { step: usize }, /// [ .. cond ] consume 1 element, if `cond` is false, then jump forward JmpIfFalse { step: usize }, /// push an empty attribute set onto stack AttrSet, /// finalize the recursive attribute set at TOS FinalizeRec, /// [ .. set value ] consume 1 element, push a static kv pair (`name`, `value`) into `set` PushStaticAttr { name: usize }, /// [ .. set name value ] consume 2 elements, push a dynamic kv pair (`name`, `value`) in to `set` PushDynamicAttr, /// push an empty list onto stack List, /// [ .. list elem ] consume 1 element, push `elem` into `list` PushElem, /// convert the string as TOS to a path Path, /// [ .. a b ] consume 2 elements, perform a string concatenation `a` + `b` ConcatString, /// [ .. a b ] consume 2 elements, perform a binary operation `a` `op` `b` BinOp { op: BinOp }, /// [ .. a ] consume 1 element, perform a unary operation `op` `a` UnOp { op: UnOp }, /// set TOS to the bool value of whether TOS contains `sym` HasAttr { sym: usize }, /// [ .. set sym ] consume 2 elements, set TOS to the bool value of whether `set` contains `sym` HasDynamicAttr, /// [ .. set ] select `sym` from `set` Select { sym: usize }, /// [ .. set default ] select `sym` from `set` or `default` SelectOrDefault { sym: usize }, /// [ .. set sym ] select `sym` from `set` SelectDynamic, /// [ .. set sym default ] select `sym` from `set` or `default` SelectDynamicOrDefault, /// enter the environment of the attribute set at TOS EnterEnv, /// exit current envrironment LeaveEnv, /// illegal operation, used as termporary placeholder Illegal, } #[derive(Debug, Clone, Copy)] pub enum BinOp { Add, Sub, Mul, Div, And, Or, Eq, Lt, Con, Upd, } #[derive(Debug, Clone, Copy)] pub enum UnOp { Neg, Not, } #[derive(Debug)] pub struct Func { pub param: Param, pub opcodes: OpCodes, } #[derive(Debug)] pub struct Program { pub top_level: OpCodes, pub thunks: Slice, pub funcs: Slice, pub symbols: Vec, pub symmap: HashMap, pub consts: Box<[Const]>, }