This commit is contained in:
minish 2025-12-04 20:55:58 -05:00
parent 4fa6cd9ae0
commit bfafb46f38
Signed by: min
SSH Key Fingerprint: SHA256:mf+pUTmK92Y57BuCjlkBdd82LqztTfDCQIUp0fCKABc
3 changed files with 806 additions and 804 deletions

File diff suppressed because it is too large Load Diff

View File

@ -9,21 +9,25 @@ mod parser;
mod vm; mod vm;
fn main() { fn main() {
// lexer (iterator)
let script = std::fs::read_to_string("./start.lf").unwrap(); let script = std::fs::read_to_string("./start.lf").unwrap();
let lexer = Lexer::new(script.chars()); let lexer = Lexer::new(script.chars());
let mut parser = Parser::new(lexer.map(Result::unwrap)); let mut parser = Parser::new(lexer.map(Result::unwrap));
// parser
let start = Instant::now(); let start = Instant::now();
let block = parser.parse().unwrap(); let block = parser.parse().unwrap();
println!("Parse took {:?}", start.elapsed()); println!("Parse took {:?}", start.elapsed());
let mut e = parser::Expr::Block(block); let mut e = parser::Expr::Block(block);
parser::util::display(&e); parser::util::display(&e);
// compiler - analysis
let start = Instant::now(); let start = Instant::now();
compiler::analysis_demo(&mut e); compiler::analysis_demo(&mut e);
println!("Analysis took {:?}", start.elapsed()); println!("Analysis took {:?}", start.elapsed());
parser::util::display(&e); parser::util::display(&e);
// compiler - translation
let start = Instant::now(); let start = Instant::now();
let insts = compiler::translation_demo(e); let insts = compiler::translation_demo(e);
println!("Translation took {:?}", start.elapsed()); println!("Translation took {:?}", start.elapsed());
@ -31,6 +35,7 @@ fn main() {
println!("=> {i:?}"); println!("=> {i:?}");
} }
// vm
println!("Starting VM!!!!!!!!!!!!!!!!"); println!("Starting VM!!!!!!!!!!!!!!!!");
let start = Instant::now(); let start = Instant::now();
let out = vm::run(&insts); let out = vm::run(&insts);

308
src/vm.rs
View File

@ -1,155 +1,153 @@
use std::cell::RefCell; use std::cell::RefCell;
use crate::compiler::{Inst, Stkval, Val}; use crate::compiler::{Inst, Stkval, Val};
#[derive(Default)] #[derive(Default)]
struct FuncVm<'a> { struct FuncVm<'a> {
depth: usize, depth: usize,
parent_vm: Option<&'a FuncVm<'a>>, parent_vm: Option<&'a FuncVm<'a>>,
shared: RefCell<Vec<Val>>, shared: RefCell<Vec<Val>>,
locals: Vec<Val>, locals: Vec<Val>,
} }
impl<'a> FuncVm<'a> { impl<'a> FuncVm<'a> {
fn with(parent_vm: &'a FuncVm<'a>, locals: Vec<Val>) -> Self { fn with(parent_vm: &'a FuncVm<'a>, locals: Vec<Val>) -> Self {
Self { Self {
parent_vm: Some(parent_vm), parent_vm: Some(parent_vm),
depth: parent_vm.depth + 1, depth: parent_vm.depth + 1,
shared: RefCell::default(), shared: RefCell::default(),
locals, locals,
} }
} }
fn get(&mut self, v: &Val) -> Val { fn get(&mut self, v: &Val) -> Val {
use {Stkval::*, Val::*}; use {Stkval::*, Val::*};
match v { match v {
Stack(Local(o), true) => self.locals.remove(*o as usize), Stack(Local(o), true) => self.locals.remove(*o as usize),
Stack(Local(o), false) => self.locals[*o as usize].clone(), Stack(Local(o), false) => self.locals[*o as usize].clone(),
Stack(Shared(l, o), false) => { Stack(Shared(l, o), false) => {
let mut vm = &*self; let mut vm = &*self;
for _ in 0..*l { for _ in 0..*l {
vm = vm.parent_vm.as_ref().unwrap(); vm = vm.parent_vm.as_ref().unwrap();
} }
vm.shared.borrow_mut()[*o as usize].clone() vm.shared.borrow_mut()[*o as usize].clone()
} }
Stack(Shared(_, _), true) => panic!("not allowed"), Stack(Shared(_, _), true) => panic!("not allowed"),
v => v.clone(), v => v.clone(),
} }
} }
fn eval_all(&mut self, insts: &[Inst]) -> Val { fn eval_all(&mut self, insts: &[Inst]) -> Val {
use {Inst::*, Val::*}; use {Inst::*, Val::*};
let mut pc = 0; let mut pc = 0;
while pc < insts.len() { while pc < insts.len() {
let inst = &insts[pc]; let inst = &insts[pc];
// println!("{}> {:?} {inst:?}", "=".repeat(self.depth), self.locals); match inst {
/* rhs */
match inst { Not(a) | Return(a) => {
/* rhs */ let r = match (inst, self.get(a)) {
Not(a) | Return(a) => { (Not(_), Bool(a)) => Bool(!a),
let r = match (inst, self.get(a)) { (Return(_), Func(true, _, _)) => panic!("func is unreturnable"),
(Not(_), Bool(a)) => Bool(!a), (Return(_), a) => return a,
(Return(_), Func(true, _, _)) => panic!("func is unreturnable"), _ => unimplemented!(),
(Return(_), a) => return a, };
_ => unimplemented!(), self.locals.push(r);
}; }
self.locals.push(r); /* s rhs */
} Copy(s, a) => {
/* s rhs */ let a = self.get(a);
Copy(s, a) => { if !*s {
let a = self.get(a); self.locals.push(a);
if !*s { } else {
self.locals.push(a); self.shared.borrow_mut().push(a);
} else { }
self.shared.borrow_mut().push(a); }
} /* k rhs */
} Call(k, n, a) => {
/* k rhs */ // check validity
Call(k, n, a) => { let a = self.get(a);
// check validity let Func(_, arity, insts) = a else {
let a = self.get(a); panic!("called non-function {a:?}")
let Func(_, arity, insts) = a else { };
panic!("called non-function {a:?}")
}; // collect args from stack :)
let args_start = self.locals.len() - *n as usize;
// collect args from stack :) let args = self.locals.split_off(args_start);
let args_start = self.locals.len() - *n as usize;
let args = self.locals.split_off(args_start); // make sure its the right amount
if *n != arity {
// make sure its the right amount panic!("wrong # args")
if *n != arity { }
panic!("wrong # args")
} // exec
let mut vm = FuncVm::with(self, args);
// exec let r = vm.eval_all(&insts);
let mut vm = FuncVm::with(self, args); // push value if were supposed to
let r = vm.eval_all(&insts); if *k {
// push value if were supposed to self.locals.push(r);
if *k { }
self.locals.push(r); }
}
} /* sv rhs */
Move(sv, a) => {
/* sv rhs */ let a = self.get(a);
Move(sv, a) => { match sv {
let a = self.get(a); Stkval::Local(o) => {
match sv { self.locals[*o as usize] = a;
Stkval::Local(o) => { }
self.locals[*o as usize] = a; Stkval::Shared(l, o) => {
} let mut vm = &*self;
Stkval::Shared(l, o) => { for _ in 0..*l {
let mut vm = &*self; vm = vm.parent_vm.unwrap();
for _ in 0..*l { }
vm = vm.parent_vm.unwrap(); vm.shared.borrow_mut()[*o as usize] = a;
} }
vm.shared.borrow_mut()[*o as usize] = a; }
} }
}
} /* lhs rhs */
Eq(a, b)
/* lhs rhs */ | Gt(a, b)
Eq(a, b) | GtEq(a, b)
| Gt(a, b) | Add(a, b)
| GtEq(a, b) | Mul(a, b)
| Add(a, b) | Div(a, b)
| Mul(a, b) | Mod(a, b)
| Div(a, b) | Pow(a, b)
| Mod(a, b) | And(a, b)
| Pow(a, b) | Or(a, b) => {
| And(a, b) let r = match (inst, self.get(a), self.get(b)) {
| Or(a, b) => { (Add(_, _), Int64(a), Int64(b)) => Int64(a + b),
let r = match (inst, self.get(a), self.get(b)) { (Mul(_, _), Int64(a), Int64(b)) => Int64(a * b),
(Add(_, _), Int64(a), Int64(b)) => Int64(a + b), (Div(_, _), Int64(a), Int64(b)) => Int64(a / b),
(Mul(_, _), Int64(a), Int64(b)) => Int64(a * b), (Mod(_, _), Int64(a), Int64(b)) => Int64(a % b),
(Div(_, _), Int64(a), Int64(b)) => Int64(a / b), (Pow(_, _), Int64(a), Int64(b)) => Int64(a.pow(b.try_into().unwrap())),
(Mod(_, _), Int64(a), Int64(b)) => Int64(a % b), (And(_, _), Bool(a), Bool(b)) => Bool(a && b),
(Pow(_, _), Int64(a), Int64(b)) => Int64(a.pow(b.try_into().unwrap())), (Or(_, _), Bool(a), Bool(b)) => Bool(a || b),
(And(_, _), Bool(a), Bool(b)) => Bool(a && b), (Eq(_, _), a, b) => Bool(a == b),
(Or(_, _), Bool(a), Bool(b)) => Bool(a || b), (Gt(_, _), Int64(a), Int64(b)) => Bool(a > b),
(Eq(_, _), a, b) => Bool(a == b), (GtEq(_, _), Int64(a), Int64(b)) => Bool(a >= b),
(Gt(_, _), Int64(a), Int64(b)) => Bool(a > b),
(GtEq(_, _), Int64(a), Int64(b)) => Bool(a >= b), x => unimplemented!("{x:?}"),
};
x => unimplemented!("{x:?}"), self.locals.push(r);
}; }
self.locals.push(r);
} _ => unimplemented!(),
}
_ => unimplemented!(),
} pc += 1;
}
pc += 1;
} Nil
}
Nil }
}
} pub fn run(insts: &[Inst]) -> Val {
let mut vm = FuncVm::default();
pub fn run(insts: &[Inst]) -> Val { vm.eval_all(insts)
let mut vm = FuncVm::default(); }
vm.eval_all(insts)
}