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, pub re: Regex, } #[derive(Clone, Debug)] pub struct Chunk { pub constants: Vec, pub bytecode: Vec, pub keywords: Vec<&'static str>, pub string_patterns: Vec, pub env: HashMap<&'static str, Value>, pub msgs: Vec, } 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 { // self.kw_index_from(kw).map(Value::Keyword) // } // pub fn kw_index_from(&self, kw: &str) -> Option { // self.keywords.iter().position(|s| *s == kw) // } }