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,
|
Stringify,
|
||||||
|
|
||||||
Call,
|
Call,
|
||||||
|
Return,
|
||||||
|
|
||||||
Eq,
|
Eq,
|
||||||
Add,
|
Add,
|
||||||
|
@ -183,6 +184,7 @@ impl std::fmt::Display for Op {
|
||||||
Not => "not",
|
Not => "not",
|
||||||
|
|
||||||
Call => "call",
|
Call => "call",
|
||||||
|
Return => "return",
|
||||||
};
|
};
|
||||||
write!(f, "{rep}")
|
write!(f, "{rep}")
|
||||||
}
|
}
|
||||||
|
@ -204,31 +206,42 @@ pub struct Chunk {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Chunk {
|
impl Chunk {
|
||||||
pub fn dissasemble_instr(&self, i: usize) {
|
pub fn dissasemble_instr(&self, i: &mut usize) {
|
||||||
let op = Op::from_u8(self.bytecode[i]).unwrap();
|
let op = Op::from_u8(self.bytecode[*i]).unwrap();
|
||||||
use Op::*;
|
use Op::*;
|
||||||
match op {
|
match op {
|
||||||
Pop | Store | Stash | Load | Nil | True | False | MatchNil | MatchTrue | MatchFalse
|
Pop | Store | Stash | Load | Nil | True | False | MatchNil | MatchTrue | MatchFalse
|
||||||
| PanicIfNoMatch | MatchWord | ResetMatch | GetKey | PanicNoWhen | PanicNoMatch
|
| PanicIfNoMatch | MatchWord | ResetMatch | GetKey | PanicNoWhen | PanicNoMatch
|
||||||
| TypeOf | Duplicate | Decrement | Truncate | Noop | LoadTuple | LoadList | Eq
|
| TypeOf | Duplicate | Decrement | Truncate | Noop | LoadTuple | LoadList | Eq
|
||||||
| Add | Sub | Mult | Div | Unbox | BoxStore | Assert | Get | At | Not | Panic
|
| Add | Sub | Mult | Div | Unbox | BoxStore | Assert | Get | At | Not | Panic
|
||||||
| EmptyString | ConcatStrings | Stringify | MatchType => {
|
| EmptyString | ConcatStrings | Stringify | MatchType | Return => {
|
||||||
println!("{i:04}: {op}")
|
println!("{i:04}: {op}")
|
||||||
}
|
}
|
||||||
Constant | MatchConstant => {
|
Constant | MatchConstant => {
|
||||||
let next = self.bytecode[i + 1];
|
let next = self.bytecode[*i + 1];
|
||||||
let value = &self.constants[next as usize].show(self);
|
let value = &self.constants[next as usize].show(self);
|
||||||
println!("{i:04}: {:16} {next:04}: {value}", op.to_string());
|
println!("{i:04}: {:16} {next:04}: {value}", op.to_string());
|
||||||
|
*i += 1;
|
||||||
}
|
}
|
||||||
PushBinding | MatchTuple | MatchList | MatchDict | LoadDictValue | PushTuple
|
PushBinding | MatchTuple | MatchList | MatchDict | LoadDictValue | PushTuple
|
||||||
| PushDict | PushList | PushBox | Jump | JumpIfFalse | JumpIfTrue | JumpIfNoMatch
|
| PushDict | PushList | PushBox | Jump | JumpIfFalse | JumpIfTrue | JumpIfNoMatch
|
||||||
| JumpIfMatch | JumpBack | JumpIfZero | MatchDepth | PopN | StoreAt | Call => {
|
| 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());
|
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> {
|
pub fn kw_from(&self, kw: &str) -> Option<Value> {
|
||||||
self.kw_index_from(kw).map(Value::Keyword)
|
self.kw_index_from(kw).map(Value::Keyword)
|
||||||
}
|
}
|
||||||
|
@ -840,6 +853,7 @@ impl Compiler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.emit_op(Op::Call);
|
self.emit_op(Op::Call);
|
||||||
|
self.emit_byte(args.len());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -1015,17 +1029,10 @@ impl Compiler {
|
||||||
compiler.pop();
|
compiler.pop();
|
||||||
}
|
}
|
||||||
compiler.stack_depth = 0;
|
compiler.stack_depth = 0;
|
||||||
compiler.emit_op(Op::Jump);
|
compiler.emit_op(Op::Return);
|
||||||
compiler.emit_byte(0xff);
|
|
||||||
compiler.chunk.bytecode[jnm_idx] = compiler.len() as u8 - jnm_idx as u8;
|
compiler.chunk.bytecode[jnm_idx] = compiler.len() as u8 - jnm_idx as u8;
|
||||||
compiler.scope_depth -= 1;
|
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![];
|
// let mut the_chunks = vec![];
|
||||||
|
|
||||||
|
@ -1046,8 +1053,14 @@ impl Compiler {
|
||||||
//
|
//
|
||||||
let mut the_chunks = vec![];
|
let mut the_chunks = vec![];
|
||||||
|
|
||||||
for (arity, compiler) in compilers.into_iter() {
|
for (arity, mut compiler) in compilers.into_iter() {
|
||||||
the_chunks.push((arity as u8, compiler.chunk));
|
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 {
|
let lfn = crate::value::LFn {
|
||||||
|
@ -1071,11 +1084,16 @@ impl Compiler {
|
||||||
self.emit_constant(lfn);
|
self.emit_constant(lfn);
|
||||||
self.bind(name);
|
self.bind(name);
|
||||||
}
|
}
|
||||||
FnBody(clauses) => {
|
FnBody(_) => unreachable!(),
|
||||||
self.emit_op(Op::ResetMatch);
|
|
||||||
todo!();
|
|
||||||
}
|
|
||||||
// TODO: add a check to make sure times >= 0
|
// 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) => {
|
Repeat(times, body) => {
|
||||||
self.visit(times);
|
self.visit(times);
|
||||||
self.emit_op(Op::Truncate);
|
self.emit_op(Op::Truncate);
|
||||||
|
@ -1241,32 +1259,6 @@ impl Compiler {
|
||||||
|
|
||||||
pub fn disassemble(&self) {
|
pub fn disassemble(&self) {
|
||||||
println!("=== chunk: {} ===", self.name);
|
println!("=== chunk: {} ===", self.name);
|
||||||
println!("IDX | CODE | INFO");
|
self.chunk.dissasemble();
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,8 @@ impl<'a> Vm<'a> {
|
||||||
|
|
||||||
fn print_debug(&self) {
|
fn print_debug(&self) {
|
||||||
self.print_stack();
|
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> {
|
pub fn run(&mut self) -> &Result<Value, Panic> {
|
||||||
|
@ -611,6 +612,7 @@ impl<'a> Vm<'a> {
|
||||||
self.ip += 1;
|
self.ip += 1;
|
||||||
}
|
}
|
||||||
Call => todo!(),
|
Call => todo!(),
|
||||||
|
Return => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user