rudus/src/chunk.rs

87 lines
3.2 KiB
Rust

use crate::op::Op;
use crate::value::Value;
use imbl::HashMap;
use num_traits::FromPrimitive;
use regex::Regex;
#[derive(Clone, Debug)]
pub struct StrPattern {
pub words: Vec<String>,
pub re: Regex,
}
#[derive(Clone, Debug)]
pub struct Chunk {
pub constants: Vec<Value>,
pub bytecode: Vec<u8>,
pub keywords: Vec<&'static str>,
pub string_patterns: Vec<StrPattern>,
pub env: HashMap<&'static str, Value>,
pub msgs: Vec<String>,
}
impl Chunk {
pub fn dissasemble_instr(&self, i: &mut usize) {
let op = Op::from_u8(self.bytecode[*i]).unwrap();
use Op::*;
match op {
Pop | Store | Stash | Load | Nil | True | False | MatchNil | MatchTrue | MatchFalse
| PanicIfNoMatch | ResetMatch | GetKey | PanicNoWhen | PanicNoMatch | TypeOf
| Duplicate | Decrement | ToInt | Noop | LoadTuple | LoadList | Eq | Add | Sub
| Mult | Div | Unbox | BoxStore | Assert | Get | At | Not | Panic | EmptyString
| ConcatStrings | Stringify | MatchType | Return | UnconditionalMatch | Print
| AppendList | ConcatList | PushList | PushDict | AppendDict | ConcatDict | Nothing
| PushGlobal | SetUpvalue => {
println!("{i:04}: {op}")
}
Constant | MatchConstant => {
let high = self.bytecode[*i + 1];
let low = self.bytecode[*i + 2];
let idx = ((high as usize) << 8) + low as usize;
let value = &self.constants[idx].show();
println!("{i:04}: {:16} {idx:05}: {value}", op.to_string());
*i += 2;
}
Msg => {
let msg_idx = self.bytecode[*i + 1];
let msg = &self.msgs[msg_idx as usize];
println!("{i:04}: {msg}");
*i += 1;
}
PushBinding | MatchTuple | MatchSplattedTuple | LoadSplattedTuple | MatchList
| MatchSplattedList | LoadSplattedList | MatchDict | MatchSplattedDict
| DropDictEntry | LoadDictValue | PushTuple | PushBox | MatchDepth | PopN | StoreN
| Call | GetUpvalue | Partial | MatchString | PushStringMatches | TailCall | LoadN => {
let next = self.bytecode[*i + 1];
println!("{i:04}: {:16} {next:03}", op.to_string());
*i += 1;
}
Jump | JumpIfFalse | JumpIfTrue | JumpIfNoMatch | JumpIfMatch | JumpBack
| JumpIfZero => {
let high = self.bytecode[*i + 1];
let low = self.bytecode[*i + 2];
let len = ((high as u16) << 8) + low as u16;
println!("{i:04}: {:16} {len:05}", op.to_string());
*i += 2;
}
}
}
pub fn dissasemble(&self) {
println!("IDX | CODE | INFO");
let mut i = 0;
while i < self.bytecode.len() {
self.dissasemble_instr(&mut i);
i += 1;
}
}
// pub fn kw_from(&self, kw: &str) -> Option<Value> {
// self.kw_index_from(kw).map(Value::Keyword)
// }
// pub fn kw_index_from(&self, kw: &str) -> Option<usize> {
// self.keywords.iter().position(|s| *s == kw)
// }
}