87 lines
3.2 KiB
Rust
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)
|
|
// }
|
|
}
|