feat: refactor
This commit is contained in:
169
src/bytecode.rs
169
src/bytecode.rs
@@ -1,11 +1,10 @@
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::hash::Hash;
|
||||
|
||||
use ecow::EcoString;
|
||||
use anyhow::Error;
|
||||
use derive_more::{IsVariant, Unwrap};
|
||||
|
||||
use crate::slice::Slice;
|
||||
use crate::value::Func;
|
||||
use crate::value::Const;
|
||||
|
||||
type Slice<T> = Box<[T]>;
|
||||
|
||||
pub type ThunkIdx = usize;
|
||||
pub type ConstIdx = usize;
|
||||
@@ -23,122 +22,6 @@ pub struct Thunk {
|
||||
#[derive(Debug, Clone, Hash)]
|
||||
pub enum Arg {}
|
||||
|
||||
#[derive(Debug, Clone, IsVariant, Unwrap)]
|
||||
pub enum Const {
|
||||
Bool(bool),
|
||||
Int(i64),
|
||||
Float(f64),
|
||||
String(EcoString),
|
||||
Func(Func),
|
||||
}
|
||||
|
||||
impl From<bool> for Const {
|
||||
fn from(value: bool) -> Self {
|
||||
Const::Bool(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i64> for Const {
|
||||
fn from(value: i64) -> Self {
|
||||
Const::Int(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f64> for Const {
|
||||
fn from(value: f64) -> Self {
|
||||
Const::Float(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<EcoString> for Const {
|
||||
fn from(value: EcoString) -> Self {
|
||||
Const::String(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Const {
|
||||
fn from(value: String) -> Self {
|
||||
Const::String(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Const {
|
||||
fn from(value: &str) -> Self {
|
||||
Const::String(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<&'a Const> for &'a bool {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: &'a Const) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
Const::Bool(b) => Ok(b),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'a> TryFrom<&'a Const> for &'a i64 {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: &'a Const) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
Const::Int(int) => Ok(int),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<&'a Const> for &'a f64 {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: &'a Const) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
Const::Float(float) => Ok(float),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<&'a Const> for &'a str {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: &'a Const) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
Const::String(string) => Ok(string),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Const {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
use Const::*;
|
||||
match (self, other) {
|
||||
(Bool(a), Bool(b)) => a == b,
|
||||
(Int(a), Int(b)) => a == b,
|
||||
(Float(a), Float(b)) => a == b,
|
||||
(String(a), String(b)) => a == b,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Const {}
|
||||
|
||||
impl Hash for Const {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
use Const::*;
|
||||
match self {
|
||||
Bool(b) => b.hash(state),
|
||||
Int(int) => int.hash(state),
|
||||
Float(float) => float.to_bits().hash(state),
|
||||
String(string) => string.hash(state),
|
||||
Func(func) => func.hash(state),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Hash)]
|
||||
pub enum OpCode {
|
||||
/// load a constant onto stack
|
||||
@@ -151,60 +34,58 @@ pub enum OpCode {
|
||||
LoadValue { idx: ThunkIdx },
|
||||
/// force TOS to value
|
||||
ForceValue,
|
||||
/// [ ... func, args @ .. ] call func with `arity` numbers of arg
|
||||
/// [ .. func args @ .. ] consume (`arity` + 2) elements, call `func` with args` of length `arity`
|
||||
/// Example: __add 1 2 => [ LookUp("__add") Const(1) Const(2) Call(2) ]
|
||||
Call { arity: usize },
|
||||
/// assert TOS is true then consume it
|
||||
/// consume 1 element, assert TOS is true
|
||||
Assert,
|
||||
/// jump forward
|
||||
Jmp { step: usize },
|
||||
/// [ ... cond ] if (cond) is true, then jump forward
|
||||
/// [ .. cond ] consume 1 element, if `cond`` is true, then jump forward
|
||||
JmpIfTrue { step: usize },
|
||||
/// [ ... cond ] if (cond) is false, then jump forward
|
||||
/// [ .. cond ] consume 1 element, if `cond` is false, then jump forward
|
||||
JmpIfFalse { step: usize },
|
||||
/// push an empty attribute set onto stack
|
||||
AttrSet,
|
||||
/// push an empty recursive attribute set onto stack
|
||||
RecAttrSet,
|
||||
/// [ ... set, value ] push the static kv pair (name, (value)) into (set)
|
||||
/// [ .. set value ] consume 1 element, push a static kv pair (`name`, `value`) into `set`
|
||||
PushStaticAttr { name: EcoString },
|
||||
/// [ ... set, name, value ] push the dynamic kv pair ((name), (value)) in to (set)
|
||||
/// [ .. 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 ] push (elem) into (list)
|
||||
/// [ .. list elem ] consume 1 element, push `elem` into `list`
|
||||
PushElem,
|
||||
/// [ ... a, b ] perform a binary operation ((a) `op` (b))
|
||||
BinOp { op: BinOp },
|
||||
/// [ ... a ] perform a unary operation (`op` (a))
|
||||
UnOp { op: UnOp },
|
||||
/// TODO:
|
||||
/// [ .. a b ] consume 2 elements, perform a string concatenation `a` + `b`
|
||||
ConcatString,
|
||||
/// TODO:
|
||||
/// [ .. 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: EcoString },
|
||||
/// TODO:
|
||||
/// [ .. set sym ] consume 2 elements, set TOS to the bool value of whether `set` contains `sym`
|
||||
HasDynamicAttr,
|
||||
// HasAttr { arity: usize },
|
||||
/// TODO:
|
||||
/// [ .. set ] select `sym` from `set`
|
||||
Select { sym: EcoString },
|
||||
// Select { arity: usize },
|
||||
/// TODO:
|
||||
SelectDynamic,
|
||||
// SelectDynamic { arity: usize },
|
||||
SelectWithDefault { sym: EcoString },
|
||||
/// TODO:
|
||||
SelectOrEmpty { sym: EcoString },
|
||||
/// TODO:
|
||||
SelectDynamicOrEmpty,
|
||||
SelectDynamic,
|
||||
/// TODO:
|
||||
SelectWithDefault { sym: EcoString },
|
||||
SelectDynamicOrEmpty,
|
||||
/// TODO:
|
||||
SelectDynamicWithDefault,
|
||||
/// enter the environment of the attribute set at TOS
|
||||
EnterEnv,
|
||||
/// exit the envrironment
|
||||
/// exit current envrironment
|
||||
LeaveEnv,
|
||||
/// return a value
|
||||
Ret,
|
||||
/// no-op
|
||||
/// no operation
|
||||
NoOp,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user