glowdust 0.0.1

A DBMS with a data model based on functions and pattern matching
Documentation
use crate::runtime::bytecode::OpCode::*;
use std::fmt;
use std::fmt::Display;

#[derive(Debug)]
#[rustfmt::skip]
pub enum OpCode {
    OpNone,         // This is a trap op, should never appear in compiled scripts. It also captures 0
    OpPop,
    OpConst,        // + 1 byte, the index in the current constants array
    OpTrue,
    OpFalse,
    OpMktuple,      // + 1 byte, the tuple size
    OpAdd,
    OpSubtract,
    OpMultiply,
    OpDivide,
    OpNegate,
    OpAnd,
    OpOr,
    OpNot,
    OpEquals,
    OpGt,
    OpLt,
    OpReturn,
    OpSetGlobal,    // + 1 byte, global variable's name index in the constants table
    OpGetGlobal,    // + 1 byte, global variable's name index in the constants table
    OpSetLocal,     // + 1 byte, the index of the local in this stack's variables vector
    OpGetLocal,     // + 1 byte, the index of the local in this stack's variables vector
    OpSetFunt,      // + 1 byte, the index of the function's name in the constants array
    OpCall,         // + 1 byte, the argument count
    OpJump,         // +1 byte, the forward offset
    OpJumpIfFalse,  // +1 byte, the forward offset
    OpLoop,         // +1 byte, the backward offset
    OpPull,         // +1 byte, the cursor to pull from
    OpProduce,      // +1 byte, the number of values to generate
    OpOpenCursor,   // +1 byte, the cursor id to use
    OpCloseCursor,  // +1 byte, the cursor id to close
    OpTupleGet,     // +1 byte, the number of elements to get

    OpNewInstance,  // +1 byte, the index of the constant that holds the type name
    OpSetField,     // +1 byte, the index of the constant that holds the field name
    OpGetField,     // +1 byte, the index of the constant that holds the field name
}

impl From<u8> for OpCode {
    fn from(value: u8) -> OpCode {
        OpCode::from_byte(value)
    }
}

impl From<OpCode> for u8 {
    fn from(value: OpCode) -> Self {
        value as u8
    }
}

impl OpCode {
    pub fn from_byte(value: u8) -> OpCode {
        match value {
            x if x == OpNone as u8 => OpNone,
            x if x == OpPop as u8 => OpPop,
            x if x == OpConst as u8 => OpConst,
            x if x == OpTrue as u8 => OpTrue,
            x if x == OpFalse as u8 => OpFalse,
            x if x == OpMktuple as u8 => OpMktuple,
            x if x == OpAdd as u8 => OpAdd,
            x if x == OpSubtract as u8 => OpSubtract,
            x if x == OpMultiply as u8 => OpMultiply,
            x if x == OpDivide as u8 => OpDivide,
            x if x == OpNegate as u8 => OpNegate,
            x if x == OpAnd as u8 => OpAnd,
            x if x == OpOr as u8 => OpOr,
            x if x == OpNot as u8 => OpNot,
            x if x == OpEquals as u8 => OpEquals,
            x if x == OpGt as u8 => OpGt,
            x if x == OpLt as u8 => OpLt,
            x if x == OpReturn as u8 => OpReturn,
            x if x == OpSetGlobal as u8 => OpSetGlobal,
            x if x == OpGetGlobal as u8 => OpGetGlobal,
            x if x == OpSetLocal as u8 => OpSetLocal,
            x if x == OpGetLocal as u8 => OpGetLocal,
            x if x == OpSetFunt as u8 => OpSetFunt,
            x if x == OpCall as u8 => OpCall,
            x if x == OpJump as u8 => OpJump,
            x if x == OpJumpIfFalse as u8 => OpJumpIfFalse,
            x if x == OpLoop as u8 => OpLoop,
            x if x == OpPull as u8 => OpPull,
            x if x == OpProduce as u8 => OpProduce,
            x if x == OpOpenCursor as u8 => OpOpenCursor,
            x if x == OpCloseCursor as u8 => OpCloseCursor,
            x if x == OpTupleGet as u8 => OpTupleGet,

            x if x == OpNewInstance as u8 => OpNewInstance,
            x if x == OpSetField as u8 => OpSetField,
            x if x == OpGetField as u8 => OpGetField,

            _ => {
                panic!("value {} does not correspond to an opcode", value)
            }
        }
    }
}

pub(crate) fn instruction_length(instruction: OpCode) -> usize {
    match instruction {
        OpNone => 1,

        OpPop => 1,
        OpConst => 2,
        OpTrue => 1,
        OpFalse => 1,
        OpMktuple => 2,
        OpAdd => 1,
        OpSubtract => 1,
        OpMultiply => 1,
        OpDivide => 1,
        OpNegate => 1,
        OpAnd => 1,
        OpOr => 1,
        OpNot => 1,
        OpEquals => 1,
        OpGt => 1,
        OpLt => 1,
        OpReturn => 1,
        OpSetGlobal => 2,
        OpGetGlobal => 2,
        OpSetLocal => 2,
        OpGetLocal => 2,
        OpSetFunt => 2,
        OpCall => 2,
        OpJump => 2,
        OpJumpIfFalse => 2,
        OpLoop => 2,
        OpPull => 2,
        OpProduce => 2,
        OpOpenCursor => 2,
        OpCloseCursor => 2,
        OpTupleGet => 2,

        OpNewInstance => 2,
        OpSetField => 2,
        OpGetField => 2,
    }
}

impl Display for OpCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}