use crate::js::*; use crate::op::Op; use crate::value::{Key, Value}; use chumsky::prelude::SimpleSpan; use imbl::HashMap; use num_traits::FromPrimitive; use regex::Regex; #[derive(Clone, Debug)] pub struct StrPattern { pub words: Vec<&'static str>, 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, pub msgs: Vec, pub spans: Vec, pub src: &'static str, pub input: &'static str, } impl std::fmt::Display for Chunk { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "Chunk.") } } 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 | ResetMatch | GetKey | PanicWhenFallthrough | PanicNoMatch | PanicNoFnMatch | PanicNoLetMatch | 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 | LoadMessage | NextMessage | MatchMessage | ClearMessage | SendMethod | LoadScrutinee | Spawn => { console_log!("{} | {i:04}: {op}", self.spans[*i]) } 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(); console_log!( "{} | {i:04}: {:16} {idx:05}: {value}", self.spans[*i], op.to_string() ); *i += 2; } Msg => { let msg_idx = self.bytecode[*i + 1]; let msg = &self.msgs[msg_idx as usize]; console_log!("{} | {i:04}: {msg}", self.spans[*i]); *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]; console_log!( "{} | {i:04}: {:16} {next:03}", self.spans[*i], 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; console_log!( "{} | {i:04}: {:16} {len:05}", self.spans[*i], op.to_string() ); *i += 2; } } } pub fn dissasemble(&self) { console_log!("IDX | CODE | INFO"); let mut i = 0; while i < self.bytecode.len() { self.dissasemble_instr(&mut i); i += 1; } } }