From 93f4b9ce5179db17b847ca3a0be2dbbc0948fa6c Mon Sep 17 00:00:00 2001 From: itamar Date: Fri, 20 Mar 2026 18:39:03 +0000 Subject: [PATCH] push --- file.rs | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 file.rs diff --git a/file.rs b/file.rs new file mode 100644 index 0000000..acc5eea --- /dev/null +++ b/file.rs @@ -0,0 +1,127 @@ +#[derive(Clone, Copy, Debug)] +enum Instruction { + LoadInt { dst: u8, value: i16 }, + Copy { dst: u8, src: u8 }, + Add { dst: u8, src1: u8, src2: u8 }, + Sub { dst: u8, src1: u8, src2: u8 }, + Call { func: u8, arg: u8, dst: u8 }, + Return { src: u8 }, + JumpNotLess { target: u8, src1: u8, src2: u8 }, +} + +struct Function { + code: Vec, + num_registers: usize, +} + +struct Vm { + functions: Vec, + stack: Vec, +} + +impl Vm { + pub fn new() -> Vm { + Vm { + functions: vec![], + stack: vec![], + } + } + + pub fn call(&mut self, func: u8, arg: i64) -> i64 { + let func = func as usize; + + let base_pointer = self.stack.len(); + { + let function = &self.functions[func]; + let stack_top = base_pointer + function.num_registers; + self.stack.resize(stack_top, 0); + self.stack[base_pointer] = arg; + } + + let bp = base_pointer; + let mut program_counter = 0; + + loop { + let func = &self.functions[func]; + let instr = func.code[program_counter]; + program_counter += 1; + + match instr { + Instruction::LoadInt { dst, value } => { + *self.reg(bp, dst) = value as i64; + } + + Instruction::Copy { dst, src } => { + *self.reg(bp, dst) = *self.reg(bp, src); + } + + Instruction::Add { dst, src1, src2 } => { + *self.reg(bp, dst) = *self.reg(bp, src1) + *self.reg(bp, src2); + } + + Instruction::Sub { dst, src1, src2 } => { + *self.reg(bp, dst) = *self.reg(bp, src1) - *self.reg(bp, src2); + } + + Instruction::Call { func, arg, dst } => { + let arg = *self.reg(bp, arg); + let result = self.call(func, arg); + *self.reg(bp, dst) = result; + } + + Instruction::Return { src } => { + let result = *self.reg(bp, src); + self.stack.truncate(base_pointer); + return result; + } + + Instruction::JumpNotLess { target, src1, src2 } => { + let src1 = *self.reg(bp, src1); + let src2 = *self.reg(bp, src2); + if !(src1 < src2) { + program_counter = target as usize; + } + } + } + } + } + + fn reg(&mut self, base_pointer: usize, index: u8) -> &mut i64 { + &mut self.stack[base_pointer + index as usize] + } +} + +fn main() { + let mut vm = Vm::new(); + + let fib = 0; + vm.functions.push(Function { + code: { + let n = 0; + let two = 1; + let one = 2; + let temp = 3; + let recursive_1 = 4; + let recursive_2 = 5; + let result = 6; + + vec![ + Instruction::LoadInt { dst: two, value: 2 }, + Instruction::JumpNotLess { target: 3, src1: n, src2: two }, + Instruction::Return { src: n }, + Instruction::Sub { dst: temp, src1: n, src2: two }, + Instruction::Call { func: fib, arg: temp, dst: recursive_1 }, + Instruction::LoadInt { dst: one, value: 1 }, + Instruction::Sub { dst: temp, src1: n, src2: one }, + Instruction::Call { func: fib, arg: temp, dst: recursive_2 }, + Instruction::Add { dst: result, src1: recursive_1, src2: recursive_2 }, + Instruction::Return { src: result }, + ] + }, + num_registers: 7, + }); + + for i in 0..10 { + println!("fib({}) = {}", i, vm.call(fib, i)); + } +}