maybe properly compile functions? need to start work on fn calls to test
This commit is contained in:
parent
b6f9b35b4c
commit
de3d7e834c
|
@ -62,6 +62,7 @@ pub enum Op {
|
|||
Stringify,
|
||||
|
||||
Call,
|
||||
Return,
|
||||
|
||||
Eq,
|
||||
Add,
|
||||
|
@ -183,6 +184,7 @@ impl std::fmt::Display for Op {
|
|||
Not => "not",
|
||||
|
||||
Call => "call",
|
||||
Return => "return",
|
||||
};
|
||||
write!(f, "{rep}")
|
||||
}
|
||||
|
@ -204,31 +206,42 @@ pub struct Chunk {
|
|||
}
|
||||
|
||||
impl Chunk {
|
||||
pub fn dissasemble_instr(&self, i: usize) {
|
||||
let op = Op::from_u8(self.bytecode[i]).unwrap();
|
||||
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 | MatchWord | ResetMatch | GetKey | PanicNoWhen | PanicNoMatch
|
||||
| TypeOf | Duplicate | Decrement | Truncate | Noop | LoadTuple | LoadList | Eq
|
||||
| Add | Sub | Mult | Div | Unbox | BoxStore | Assert | Get | At | Not | Panic
|
||||
| EmptyString | ConcatStrings | Stringify | MatchType => {
|
||||
| EmptyString | ConcatStrings | Stringify | MatchType | Return => {
|
||||
println!("{i:04}: {op}")
|
||||
}
|
||||
Constant | MatchConstant => {
|
||||
let next = self.bytecode[i + 1];
|
||||
let next = self.bytecode[*i + 1];
|
||||
let value = &self.constants[next as usize].show(self);
|
||||
println!("{i:04}: {:16} {next:04}: {value}", op.to_string());
|
||||
*i += 1;
|
||||
}
|
||||
PushBinding | MatchTuple | MatchList | MatchDict | LoadDictValue | PushTuple
|
||||
| PushDict | PushList | PushBox | Jump | JumpIfFalse | JumpIfTrue | JumpIfNoMatch
|
||||
| JumpIfMatch | JumpBack | JumpIfZero | MatchDepth | PopN | StoreAt | Call => {
|
||||
let next = self.bytecode[i + 1];
|
||||
let next = self.bytecode[*i + 1];
|
||||
println!("{i:04}: {:16} {next:04}", op.to_string());
|
||||
*i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
@ -840,6 +853,7 @@ impl Compiler {
|
|||
}
|
||||
}
|
||||
self.emit_op(Op::Call);
|
||||
self.emit_byte(args.len());
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
|
@ -1015,17 +1029,10 @@ impl Compiler {
|
|||
compiler.pop();
|
||||
}
|
||||
compiler.stack_depth = 0;
|
||||
compiler.emit_op(Op::Jump);
|
||||
compiler.emit_byte(0xff);
|
||||
compiler.emit_op(Op::Return);
|
||||
compiler.chunk.bytecode[jnm_idx] = compiler.len() as u8 - jnm_idx as u8;
|
||||
compiler.scope_depth -= 1;
|
||||
}
|
||||
if crate::DEBUG_COMPILE {
|
||||
for (arity, compiler) in compilers.iter() {
|
||||
println!("==function clause: {name}/{arity}==");
|
||||
compiler.disassemble();
|
||||
}
|
||||
}
|
||||
|
||||
// let mut the_chunks = vec![];
|
||||
|
||||
|
@ -1046,8 +1053,14 @@ impl Compiler {
|
|||
//
|
||||
let mut the_chunks = vec![];
|
||||
|
||||
for (arity, compiler) in compilers.into_iter() {
|
||||
the_chunks.push((arity as u8, compiler.chunk));
|
||||
for (arity, mut compiler) in compilers.into_iter() {
|
||||
compiler.emit_op(Op::PanicNoMatch);
|
||||
let mut chunk = compiler.chunk;
|
||||
if crate::DEBUG_COMPILE {
|
||||
println!("=== function chuncktion: {name}/{arity} ===");
|
||||
chunk.dissasemble();
|
||||
}
|
||||
the_chunks.push((arity as u8, chunk));
|
||||
}
|
||||
|
||||
let lfn = crate::value::LFn {
|
||||
|
@ -1071,11 +1084,16 @@ impl Compiler {
|
|||
self.emit_constant(lfn);
|
||||
self.bind(name);
|
||||
}
|
||||
FnBody(clauses) => {
|
||||
self.emit_op(Op::ResetMatch);
|
||||
todo!();
|
||||
}
|
||||
FnBody(_) => unreachable!(),
|
||||
// TODO: add a check to make sure times >= 0
|
||||
// TODO: fix this so that the algorithm is actually correct
|
||||
// * truncate
|
||||
// * check that it's 0 or more, panic if not
|
||||
// * jump if 0 to end of loop
|
||||
// * body
|
||||
// * pop
|
||||
// * decrement counter (which is now at the top of the stack)
|
||||
// * jump back to jump if 0 instruction
|
||||
Repeat(times, body) => {
|
||||
self.visit(times);
|
||||
self.emit_op(Op::Truncate);
|
||||
|
@ -1241,32 +1259,6 @@ impl Compiler {
|
|||
|
||||
pub fn disassemble(&self) {
|
||||
println!("=== chunk: {} ===", self.name);
|
||||
println!("IDX | CODE | INFO");
|
||||
let mut codes = self.chunk.bytecode.iter().enumerate();
|
||||
while let Some((i, byte)) = codes.next() {
|
||||
let op = Op::from_u8(*byte).unwrap();
|
||||
use Op::*;
|
||||
match op {
|
||||
Noop | Pop | Store | Stash | Load | Nil | True | False | MatchNil | MatchTrue
|
||||
| MatchFalse | MatchWord | ResetMatch | PanicIfNoMatch | GetKey | PanicNoWhen
|
||||
| PanicNoMatch | TypeOf | Duplicate | Truncate | Decrement | LoadTuple
|
||||
| LoadList | Eq | Add | Sub | Mult | Div | Unbox | BoxStore | Assert | Get | At
|
||||
| Not | Panic | EmptyString | ConcatStrings | Stringify | MatchType => {
|
||||
println!("{i:04}: {op}")
|
||||
}
|
||||
Constant | MatchConstant => {
|
||||
let (_, next) = codes.next().unwrap();
|
||||
let value = &self.chunk.constants[*next as usize].show(&self.chunk);
|
||||
println!("{i:04}: {:16} {next:04}: {value}", op.to_string());
|
||||
}
|
||||
PushBinding | MatchTuple | MatchList | PushTuple | PushDict | PushList
|
||||
| MatchDict | LoadDictValue | PushBox | Jump | JumpIfFalse | JumpIfTrue
|
||||
| JumpIfNoMatch | JumpIfMatch | JumpBack | JumpIfZero | MatchDepth | PopN
|
||||
| StoreAt | Call => {
|
||||
let (_, next) = codes.next().unwrap();
|
||||
println!("{i:04}: {:16} {next:04}", op.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
self.chunk.dissasemble();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,8 @@ impl<'a> Vm<'a> {
|
|||
|
||||
fn print_debug(&self) {
|
||||
self.print_stack();
|
||||
self.chunk.dissasemble_instr(self.ip);
|
||||
let mut ip = self.ip;
|
||||
self.chunk.dissasemble_instr(&mut ip);
|
||||
}
|
||||
|
||||
pub fn run(&mut self) -> &Result<Value, Panic> {
|
||||
|
@ -611,6 +612,7 @@ impl<'a> Vm<'a> {
|
|||
self.ip += 1;
|
||||
}
|
||||
Call => todo!(),
|
||||
Return => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user