1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#![no_std]
use hash32::{Hasher, Murmur3Hasher};
use heapless::{self, consts, LinearMap, Vec};

mod compiler;
pub mod spool;
mod vm;

pub use compiler::*;
pub use vm::*;

pub type Prog = Vec<Word, consts::U512>;
pub type Stack = Vec<Value, consts::U32>;
pub type ScopeStack = Vec<Scope, consts::U16>;
pub type VTable = LinearMap<u32, (usize, usize), consts::U16>;
pub type Vars = LinearMap<u32, Value, consts::U16>;
pub type SpoolData = LinearMap<u32, String, consts::U32>;
pub type String = heapless::String<consts::U12>;

#[derive(Debug, PartialEq)]
pub enum VMError {
    CompileError(CompileError),
    InvalidArguments(Word),
    ProgramHalted,
    DivisionByZero,
    StackOverflow,
    StackUnderflow,
    UnknownVar,
    InvalidScope,
    InvalidPtr,
    TooManyVars,
}

#[derive(Debug, PartialEq, Clone)]
pub enum Value {
    Num(i32),
    Str(u32),
    Var(u32),
    Net(u32),
    Port(u32),
}

#[derive(Debug, PartialEq)]
pub enum VMRequest {
    Idle,
    CallProc(u32),
    IO(IO),
}

#[derive(Debug, PartialEq, Clone)]
pub enum IO {
    Clear,
    PrintChar,
    PrintStack,
    PrintTop,
    PrintVar,
    ReadChar,
    ReadVal,
    Space,
    Spaces,
    Cr,
    Nl,
}

#[derive(Debug, PartialEq, Clone)]
pub enum Word {
    NumImm(i32),
    StrImm(u32),
    VarImm(u32),
    NetImm(u32),
    PortImm(u32),
    Proc(u32),
    Call(u32),
    IO(IO),
    Ret,
    Drop,
    Dup,
    Swap,
    Over,
    Nip,
    Tuck,
    Rot,
    RRot,
    Inc,
    Dec,
    Plus,
    Minus,
    Mul,
    Div,
    Mod,
    And,
    Or,
    Xor,
    Invert,
    Lt,
    Gt,
    Lte,
    Gte,
    Eq,
    NotEq,
    EqZero,
    NotEqZero,
    LtZero,
    GtZero,
    SetVar,
    GetVar,
    If,
    Then,
    Else,
    Begin,
    Until,
    Do,
    I,
    Loop,
}

pub fn hash_str(string: &str) -> u32 {
    let mut hasher = Murmur3Hasher::default();
    hasher.write(&string.as_bytes());
    hasher.finish()
}

pub fn bool_enc(val: bool) -> i32 {
    if val {
        -1
    } else {
        0
    }
}