Add Bool builtin type, branches, and some more stuff

* obj::Bool builtin type is used for truthiness and decision-making
* Branches are compiled and seem to be working for basic integer
  comparison
* Updated version of Shredder to what is current as of writing
* CheckTruth VM instruction that will explicitly set the condition flag
* Probably some other stuff

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-11-06 16:57:25 -08:00
parent 692bb521ec
commit be9a659159
17 changed files with 435 additions and 78 deletions

View File

@@ -7,9 +7,6 @@ pub struct ConstPool {
pool: Vec<ObjRef>,
}
// Constant pools are constant, and live for the lifetime of the entire program.
impl shredder::EmptyScan for ConstPool {}
impl ConstPool {
pub fn new() -> Self {
Default::default()

View File

@@ -1,5 +1,4 @@
use crate::{obj::prelude::*, vm::consts::*};
use shredder::EmptyScan;
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum Inst {
@@ -36,6 +35,9 @@ pub enum Inst {
///
SetAttr(Sym),
/// Pops the top value off of the stack and checks if it is a `Bool` of a true value.
CheckTruth,
/// Jump to a given address in the current function unconditionally.
Jump(usize),
@@ -131,6 +133,7 @@ impl Inst {
Inst::PopGlobal(_) => "POP_GLOBAL",
Inst::GetAttr(_) => "GET_ATTR",
Inst::SetAttr(_) => "SET_ATTR",
Inst::CheckTruth => "CHECK_TRUTH",
Inst::Jump(_) => "JUMP",
Inst::JumpTrue(_) => "JUMP_TRUE",
Inst::Call(_) => "CALL",
@@ -154,4 +157,4 @@ impl Inst {
}
}
impl EmptyScan for Inst {}
unsafe impl shredder::marker::GcDrop for Inst {}

View File

@@ -254,6 +254,15 @@ impl<'c> Vm<'c> {
todo!("TODO: throw an error for attributes that can't be set");
}
}
Inst::CheckTruth => {
let source = self.pop().expect("no source available for CheckTruth");
read_obj_downcast!(let obj: Option<&Bool> = &source);
if let Some(obj) = obj {
self.condition = obj.value();
} else {
unreachable!("Expected a boolean for CheckTruth but got {:?} instead", source);
}
}
Inst::Jump(addr) => {
next_pc = addr;
}
@@ -272,12 +281,12 @@ impl<'c> Vm<'c> {
.expect("TODO: throw an error for missing __call__ attr");
signal = Some(Signal::Call(callee, args));
}
Inst::Index => todo!(),
Inst::Index => todo!("Inst::Index"),
Inst::Return => {
signal = Some(Signal::Return);
}
Inst::UnNeg => todo!(),
Inst::UnPos => todo!(),
Inst::UnNeg => todo!("Inst::UnNeg"),
Inst::UnPos => todo!("Inst::UnPos"),
Inst::BinPlus => {
let rhs = self.pop().unwrap();
let lhs = self.pop().unwrap();