Compare commits
1 Commits
preview
...
non-enum-b
| Author | SHA1 | Date | |
|---|---|---|---|
| 6096bb431a |
150
src/bytecode.rs
150
src/bytecode.rs
@@ -2,40 +2,50 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use crate::ast::{Ast, Expr, Stmt, BinOpType};
|
use crate::ast::{Ast, Expr, Stmt, BinOpType};
|
||||||
|
|
||||||
pub mod op {
|
type OpcodeSize = u32;
|
||||||
type OpSize = u32;
|
|
||||||
|
|
||||||
pub const PUSH: OpSize = 0;
|
#[repr(u32)]
|
||||||
pub const POP: OpSize = 1;
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub const LOAD: OpSize = 2;
|
pub enum OP {
|
||||||
pub const STORE: OpSize = 3;
|
Push,
|
||||||
pub const ADD: OpSize = 4;
|
Pop,
|
||||||
pub const SUB: OpSize = 5;
|
Load,
|
||||||
pub const MUL: OpSize = 6;
|
Store,
|
||||||
pub const DIV: OpSize = 7;
|
|
||||||
pub const MOD: OpSize = 8;
|
Add,
|
||||||
pub const BOR: OpSize = 9;
|
Subtract,
|
||||||
pub const BAND: OpSize = 10;
|
Multiply,
|
||||||
pub const BXOR: OpSize = 11;
|
Divide,
|
||||||
pub const SHL: OpSize = 12;
|
Modulo,
|
||||||
pub const SHR: OpSize = 13;
|
BOr,
|
||||||
pub const EQ: OpSize = 14;
|
BAnd,
|
||||||
pub const NEQ: OpSize = 15;
|
BXor,
|
||||||
pub const GT: OpSize = 16;
|
Shl,
|
||||||
pub const GE: OpSize = 17;
|
Shr,
|
||||||
pub const LT: OpSize = 18;
|
|
||||||
pub const LE: OpSize = 19;
|
Eq,
|
||||||
pub const JUMP: OpSize = 20;
|
Neq,
|
||||||
pub const JUMP_TRUE: OpSize = 21;
|
|
||||||
pub const JUMP_FALSE: OpSize = 22;
|
Gt,
|
||||||
pub const PRINT: OpSize = 23;
|
Ge,
|
||||||
pub const DBG_PRINT: OpSize = 24;
|
Lt,
|
||||||
|
Le,
|
||||||
|
|
||||||
|
Jump,
|
||||||
|
|
||||||
|
JumpTrue,
|
||||||
|
|
||||||
|
JumpFalse,
|
||||||
|
|
||||||
|
Print,
|
||||||
|
|
||||||
|
DbgPrint,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Compiler {
|
pub struct Compiler {
|
||||||
ops: Vec<u32>,
|
ops: Vec<u32>,
|
||||||
global_vars: HashMap<String, u16>,
|
global_vars: HashMap<String, u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Compiler {
|
impl Compiler {
|
||||||
@@ -48,30 +58,26 @@ impl Compiler {
|
|||||||
match stmt {
|
match stmt {
|
||||||
Stmt::Expr(expr) => {
|
Stmt::Expr(expr) => {
|
||||||
self.compile_expr(expr);
|
self.compile_expr(expr);
|
||||||
self.ops.push(op::POP);
|
self.ops.push(OP::Pop as OpcodeSize);
|
||||||
}
|
}
|
||||||
Stmt::Let(name, rhs) => {
|
Stmt::Let(name, rhs) => {
|
||||||
let id = self.global_vars.len() as u16;
|
let id = self.global_vars.len() as u64;
|
||||||
self.global_vars.insert(name.clone(), id);
|
self.global_vars.insert(name.clone(), id);
|
||||||
|
|
||||||
self.compile_expr(rhs);
|
self.compile_expr(rhs);
|
||||||
self.gen_store(id);
|
self.gen_store(id);
|
||||||
}
|
}
|
||||||
Stmt::While(cond, body) => {
|
Stmt::While(cond, body) => {
|
||||||
|
let idx_start = self.ops.len();
|
||||||
self.compile_expr(cond);
|
self.compile_expr(cond);
|
||||||
|
|
||||||
self.ops.push(op::JUMP_FALSE);
|
self.ops.push(OP::JumpFalse as OpcodeSize);
|
||||||
let idx_jmp = self.ops.len();
|
let idx_jmp = self.ops.len();
|
||||||
self.gen_i64(0);
|
self.gen_i64(0);
|
||||||
|
|
||||||
let idx_start = self.ops.len();
|
|
||||||
|
|
||||||
self.compile(body);
|
self.compile(body);
|
||||||
|
|
||||||
// check condition before loop jump
|
self.ops.push(OP::Jump as OpcodeSize);
|
||||||
self.compile_expr(cond);
|
|
||||||
|
|
||||||
self.ops.push(op::JUMP_TRUE);
|
|
||||||
self.gen_i64(idx_start as i64);
|
self.gen_i64(idx_start as i64);
|
||||||
|
|
||||||
self.overwrite_i64(idx_jmp, self.ops.len() as i64);
|
self.overwrite_i64(idx_jmp, self.ops.len() as i64);
|
||||||
@@ -80,13 +86,13 @@ impl Compiler {
|
|||||||
Stmt::If(cond, if_block, else_block) => {
|
Stmt::If(cond, if_block, else_block) => {
|
||||||
self.compile_expr(cond);
|
self.compile_expr(cond);
|
||||||
|
|
||||||
self.ops.push(op::JUMP_FALSE);
|
self.ops.push(OP::JumpFalse as OpcodeSize);
|
||||||
let idx_if = self.ops.len();
|
let idx_if = self.ops.len();
|
||||||
self.gen_i64(0);
|
self.gen_i64(0);
|
||||||
|
|
||||||
self.compile(if_block);
|
self.compile(if_block);
|
||||||
|
|
||||||
self.ops.push(op::JUMP);
|
self.ops.push(OP::Jump as OpcodeSize);
|
||||||
let idx_else = self.ops.len();
|
let idx_else = self.ops.len();
|
||||||
self.gen_i64(0);
|
self.gen_i64(0);
|
||||||
|
|
||||||
@@ -99,11 +105,11 @@ impl Compiler {
|
|||||||
},
|
},
|
||||||
Stmt::DbgPrint(expr) => {
|
Stmt::DbgPrint(expr) => {
|
||||||
self.compile_expr(expr);
|
self.compile_expr(expr);
|
||||||
self.ops.push(op::DBG_PRINT);
|
self.ops.push(OP::DbgPrint as OpcodeSize);
|
||||||
}
|
}
|
||||||
Stmt::Print(expr) => {
|
Stmt::Print(expr) => {
|
||||||
self.compile_expr(expr);
|
self.compile_expr(expr);
|
||||||
self.ops.push(op::PRINT);
|
self.ops.push(OP::Print as OpcodeSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,7 +122,7 @@ impl Compiler {
|
|||||||
pub fn compile_expr(&mut self, expr: &Expr) {
|
pub fn compile_expr(&mut self, expr: &Expr) {
|
||||||
match expr {
|
match expr {
|
||||||
Expr::I64(val) => {
|
Expr::I64(val) => {
|
||||||
self.ops.push(op::PUSH);
|
self.ops.push(OP::Push as OpcodeSize);
|
||||||
self.gen_i64(*val)
|
self.gen_i64(*val)
|
||||||
}
|
}
|
||||||
Expr::Ident(name) => {
|
Expr::Ident(name) => {
|
||||||
@@ -149,44 +155,52 @@ impl Compiler {
|
|||||||
self.compile_expr(rhs);
|
self.compile_expr(rhs);
|
||||||
|
|
||||||
match bo {
|
match bo {
|
||||||
BinOpType::Add => self.ops.push(op::ADD),
|
BinOpType::Add => self.ops.push(OP::Add as OpcodeSize),
|
||||||
BinOpType::Sub => self.ops.push(op::SUB),
|
BinOpType::Sub => self.ops.push(OP::Subtract as OpcodeSize),
|
||||||
BinOpType::Mul => self.ops.push(op::MUL),
|
BinOpType::Mul => self.ops.push(OP::Multiply as OpcodeSize),
|
||||||
BinOpType::Div => self.ops.push(op::DIV),
|
BinOpType::Div => self.ops.push(OP::Divide as OpcodeSize),
|
||||||
BinOpType::Mod => self.ops.push(op::MOD),
|
BinOpType::Mod => self.ops.push(OP::Modulo as OpcodeSize),
|
||||||
BinOpType::BOr => self.ops.push(op::BOR),
|
BinOpType::BOr => self.ops.push(OP::BOr as OpcodeSize),
|
||||||
BinOpType::BAnd => self.ops.push(op::BAND),
|
BinOpType::BAnd => self.ops.push(OP::BAnd as OpcodeSize),
|
||||||
BinOpType::BXor => self.ops.push(op::BXOR),
|
BinOpType::BXor => self.ops.push(OP::BXor as OpcodeSize),
|
||||||
BinOpType::Shl => self.ops.push(op::SHL),
|
BinOpType::Shl => self.ops.push(OP::Shl as OpcodeSize),
|
||||||
BinOpType::Shr => self.ops.push(op::SHR),
|
BinOpType::Shr => self.ops.push(OP::Shr as OpcodeSize),
|
||||||
BinOpType::Equ => self.ops.push(op::EQ),
|
BinOpType::Equ => self.ops.push(OP::Eq as OpcodeSize),
|
||||||
BinOpType::Neq => self.ops.push(op::NEQ),
|
BinOpType::Neq => self.ops.push(OP::Neq as OpcodeSize),
|
||||||
BinOpType::Gt => self.ops.push(op::GT),
|
BinOpType::Gt => self.ops.push(OP::Gt as OpcodeSize),
|
||||||
BinOpType::Ge => self.ops.push(op::GE),
|
BinOpType::Ge => self.ops.push(OP::Ge as OpcodeSize),
|
||||||
BinOpType::Lt => self.ops.push(op::LT),
|
BinOpType::Lt => self.ops.push(OP::Lt as OpcodeSize),
|
||||||
BinOpType::Le => self.ops.push(op::LE),
|
BinOpType::Le => self.ops.push(OP::Le as OpcodeSize),
|
||||||
BinOpType::Assign => unreachable!(),
|
BinOpType::Assign => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_i64(&mut self, val: i64) {
|
fn gen_i64(&mut self, val: i64) {
|
||||||
self.ops.push((val & u32::MAX as i64) as u32);
|
// for i in 0 .. 8 {
|
||||||
self.ops.push((val >> 32) as u32);
|
// self.ops.push(((val >> i*8) & 0xff) as OpcodeSize);
|
||||||
|
// }
|
||||||
|
for i in 0 .. 2 {
|
||||||
|
self.ops.push(((val >> i*32) & 0xffffffff) as OpcodeSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn overwrite_i64(&mut self, idx: usize, val: i64) {
|
fn overwrite_i64(&mut self, idx: usize, val: i64) {
|
||||||
self.ops[idx] = (val & u32::MAX as i64) as u32;
|
// for i in 0 .. 8 {
|
||||||
self.ops[idx+1] = (val >> 32) as u32;
|
// self.ops[idx+i] = ((val >> i*8) & 0xff) as OpcodeSize;
|
||||||
|
// }
|
||||||
|
for i in 0 .. 2 {
|
||||||
|
self.ops[idx+i] = ((val >> i*32) & 0xffffffff) as OpcodeSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_load(&mut self, addr: u16) {
|
fn gen_load(&mut self, addr: u64) {
|
||||||
self.ops.push(op::LOAD | (addr << 8) as u32);
|
self.ops.push(OP::Load as OpcodeSize);
|
||||||
// self.gen_i64(addr as i64)
|
self.gen_i64(addr as i64)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_store(&mut self, addr: u16) {
|
fn gen_store(&mut self, addr: u64) {
|
||||||
self.ops.push(op::STORE | (addr << 8) as u32);
|
self.ops.push(OP::Store as OpcodeSize);
|
||||||
// self.gen_i64(addr as i64)
|
self.gen_i64(addr as i64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
127
src/vm.rs
127
src/vm.rs
@@ -1,4 +1,4 @@
|
|||||||
use crate::{bytecode::op::*, interpreter::Value};
|
use crate::{bytecode::OP, interpreter::Value};
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Vm {
|
pub struct Vm {
|
||||||
@@ -10,19 +10,6 @@ pub struct Vm {
|
|||||||
heap: Vec<Value>,
|
heap: Vec<Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! binop_stack {
|
|
||||||
($self:ident, $op:tt) => {
|
|
||||||
{
|
|
||||||
let rhs = $self.stack.pop().unwrap();
|
|
||||||
let lhs = $self.stack.last_mut().unwrap();
|
|
||||||
match (lhs, rhs) {
|
|
||||||
(Value::I64(lhs), Value::I64(rhs)) => *lhs = *lhs $op rhs,
|
|
||||||
_ => panic!("Invalid data for add"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Vm {
|
impl Vm {
|
||||||
pub fn new(prog: Vec<u32>) -> Self {
|
pub fn new(prog: Vec<u32>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -32,20 +19,19 @@ impl Vm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
pub fn run(&mut self) {
|
||||||
while let Some(op) = self.prog.get(self.ip).copied() {
|
while let Some(op) = self.prog.get(self.ip).copied().map(|op| unsafe { std::mem::transmute::<u32, OP>(op) }) {
|
||||||
self.ip += 1;
|
self.ip += 1;
|
||||||
|
|
||||||
match op & 0xff {
|
match op {
|
||||||
PUSH => {
|
OP::Push => {
|
||||||
let val = self.read_i64();
|
let val = self.read_i64();
|
||||||
self.stack.push(Value::I64(val));
|
self.stack.push(Value::I64(val));
|
||||||
}
|
}
|
||||||
POP => {
|
OP::Pop => {
|
||||||
self.stack.pop();
|
self.stack.pop();
|
||||||
}
|
}
|
||||||
LOAD => {
|
OP::Load => {
|
||||||
// let addr = self.read_i64() as usize;
|
let addr = self.read_i64() as usize;
|
||||||
let addr = (op >> 8) as usize;
|
|
||||||
|
|
||||||
if let Some(val) = self.heap.get(addr) {
|
if let Some(val) = self.heap.get(addr) {
|
||||||
self.stack.push(val.clone());
|
self.stack.push(val.clone());
|
||||||
@@ -53,28 +39,26 @@ impl Vm {
|
|||||||
panic!("Trying to load from uninitialized heap");
|
panic!("Trying to load from uninitialized heap");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
STORE => {
|
OP::Store => {
|
||||||
let val = self
|
let val = self
|
||||||
.stack
|
.stack
|
||||||
.pop()
|
.pop()
|
||||||
.expect("Trying to pop value from stack for storing");
|
.expect("Trying to pop value from stack for storing");
|
||||||
// let addr = self.read_i64() as usize;
|
let addr = self.read_i64() as usize;
|
||||||
let addr = (op >> 8) as usize;
|
|
||||||
|
|
||||||
if self.heap.len() == addr {
|
if self.heap.len() == addr {
|
||||||
self.heap.push(val);
|
self.heap.push(val);
|
||||||
} else {
|
} else {
|
||||||
self.heap[addr] = val;
|
self.heap[addr] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PRINT => {
|
OP::Print => {
|
||||||
let val = self
|
let val = self
|
||||||
.stack
|
.stack
|
||||||
.pop()
|
.pop()
|
||||||
.expect("Trying to pop value from stack for printing");
|
.expect("Trying to pop value from stack for printing");
|
||||||
print!("{}", val);
|
print!("{}", val);
|
||||||
}
|
}
|
||||||
DBG_PRINT => {
|
OP::DbgPrint => {
|
||||||
let val = self
|
let val = self
|
||||||
.stack
|
.stack
|
||||||
.pop()
|
.pop()
|
||||||
@@ -82,96 +66,91 @@ impl Vm {
|
|||||||
print!("{:?}", val);
|
print!("{:?}", val);
|
||||||
}
|
}
|
||||||
|
|
||||||
ADD => {
|
OP::Add => {
|
||||||
binop_stack!(self, +);
|
let vals = self.pop2_i64();
|
||||||
// self.stack.push(Value::I64(vals.0 + vals.1))
|
self.stack.push(Value::I64(vals.0 + vals.1))
|
||||||
}
|
}
|
||||||
SUB => {
|
OP::Subtract => {
|
||||||
binop_stack!(self, -);
|
let vals = self.pop2_i64();
|
||||||
// let vals = self.pop2_i64();
|
self.stack.push(Value::I64(vals.0 - vals.1))
|
||||||
// self.stack.push(Value::I64(vals.0 - vals.1))
|
|
||||||
}
|
}
|
||||||
MUL => {
|
OP::Multiply => {
|
||||||
binop_stack!(self, *);
|
let vals = self.pop2_i64();
|
||||||
// let vals = self.pop2_i64();
|
self.stack.push(Value::I64(vals.0 * vals.1))
|
||||||
// self.stack.push(Value::I64(vals.0 * vals.1))
|
|
||||||
}
|
}
|
||||||
DIV => {
|
OP::Divide => {
|
||||||
binop_stack!(self, /);
|
let vals = self.pop2_i64();
|
||||||
// let vals = self.pop2_i64();
|
self.stack.push(Value::I64(vals.0 / vals.1))
|
||||||
// self.stack.push(Value::I64(vals.0 / vals.1))
|
|
||||||
}
|
}
|
||||||
MOD => {
|
OP::Modulo => {
|
||||||
binop_stack!(self, %);
|
let vals = self.pop2_i64();
|
||||||
// let vals = self.pop2_i64();
|
self.stack.push(Value::I64(vals.0 % vals.1))
|
||||||
// self.stack.push(Value::I64(vals.0 % vals.1))
|
|
||||||
}
|
}
|
||||||
EQ => {
|
OP::Eq => {
|
||||||
let vals = self.pop2_i64();
|
let vals = self.pop2_i64();
|
||||||
self.stack
|
self.stack
|
||||||
.push(Value::I64(if vals.0 == vals.1 { 1 } else { 0 }))
|
.push(Value::I64(if vals.0 == vals.1 { 1 } else { 0 }))
|
||||||
}
|
}
|
||||||
NEQ => {
|
OP::Neq => {
|
||||||
let vals = self.pop2_i64();
|
let vals = self.pop2_i64();
|
||||||
self.stack
|
self.stack
|
||||||
.push(Value::I64(if vals.0 != vals.1 { 1 } else { 0 }))
|
.push(Value::I64(if vals.0 != vals.1 { 1 } else { 0 }))
|
||||||
}
|
}
|
||||||
GT => {
|
OP::Gt => {
|
||||||
let vals = self.pop2_i64();
|
let vals = self.pop2_i64();
|
||||||
self.stack
|
self.stack
|
||||||
.push(Value::I64(if vals.0 > vals.1 { 1 } else { 0 }))
|
.push(Value::I64(if vals.0 > vals.1 { 1 } else { 0 }))
|
||||||
}
|
}
|
||||||
GE => {
|
OP::Ge => {
|
||||||
let vals = self.pop2_i64();
|
let vals = self.pop2_i64();
|
||||||
self.stack
|
self.stack
|
||||||
.push(Value::I64(if vals.0 >= vals.1 { 1 } else { 0 }))
|
.push(Value::I64(if vals.0 >= vals.1 { 1 } else { 0 }))
|
||||||
}
|
}
|
||||||
LT => {
|
OP::Lt => {
|
||||||
let vals = self.pop2_i64();
|
let vals = self.pop2_i64();
|
||||||
self.stack
|
self.stack
|
||||||
.push(Value::I64(if vals.0 < vals.1 { 1 } else { 0 }))
|
.push(Value::I64(if vals.0 < vals.1 { 1 } else { 0 }))
|
||||||
}
|
}
|
||||||
LE => {
|
OP::Le => {
|
||||||
let vals = self.pop2_i64();
|
let vals = self.pop2_i64();
|
||||||
self.stack
|
self.stack
|
||||||
.push(Value::I64(if vals.0 <= vals.1 { 1 } else { 0 }))
|
.push(Value::I64(if vals.0 <= vals.1 { 1 } else { 0 }))
|
||||||
}
|
}
|
||||||
BOR => {
|
OP::BOr => {
|
||||||
let vals = self.pop2_i64();
|
let vals = self.pop2_i64();
|
||||||
self.stack.push(Value::I64(vals.0 | vals.1))
|
self.stack.push(Value::I64(vals.0 | vals.1))
|
||||||
}
|
}
|
||||||
BAND => {
|
OP::BAnd => {
|
||||||
let vals = self.pop2_i64();
|
let vals = self.pop2_i64();
|
||||||
self.stack.push(Value::I64(vals.0 & vals.1))
|
self.stack.push(Value::I64(vals.0 & vals.1))
|
||||||
}
|
}
|
||||||
BXOR => {
|
OP::BXor => {
|
||||||
let vals = self.pop2_i64();
|
let vals = self.pop2_i64();
|
||||||
self.stack.push(Value::I64(vals.0 ^ vals.1))
|
self.stack.push(Value::I64(vals.0 ^ vals.1))
|
||||||
}
|
}
|
||||||
SHL => {
|
OP::Shl => {
|
||||||
let vals = self.pop2_i64();
|
let vals = self.pop2_i64();
|
||||||
self.stack.push(Value::I64(vals.0 << vals.1))
|
self.stack.push(Value::I64(vals.0 << vals.1))
|
||||||
}
|
}
|
||||||
SHR => {
|
OP::Shr => {
|
||||||
let vals = self.pop2_i64();
|
let vals = self.pop2_i64();
|
||||||
self.stack.push(Value::I64(vals.0 >> vals.1))
|
self.stack.push(Value::I64(vals.0 >> vals.1))
|
||||||
}
|
}
|
||||||
JUMP => {
|
OP::Jump => {
|
||||||
self.ip = self.read_i64() as usize;
|
self.ip = self.read_i64() as usize;
|
||||||
}
|
}
|
||||||
JUMP_TRUE => {
|
OP::JumpTrue => {
|
||||||
let jmp_target = self.read_i64() as usize;
|
let jmp_target = self.read_i64() as usize;
|
||||||
if !matches!(self.stack.pop(), Some(Value::I64(0))) {
|
if !matches!(self.stack.pop(), Some(Value::I64(0))) {
|
||||||
self.ip = jmp_target;
|
self.ip = jmp_target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
JUMP_FALSE => {
|
OP::JumpFalse => {
|
||||||
let jmp_target = self.read_i64() as usize;
|
let jmp_target = self.read_i64() as usize;
|
||||||
if matches!(self.stack.pop(), Some(Value::I64(0))) {
|
if matches!(self.stack.pop(), Some(Value::I64(0))) {
|
||||||
self.ip = jmp_target;
|
self.ip = jmp_target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => panic!("Invalid opcode")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,22 +165,22 @@ impl Vm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn read_i64(&mut self) -> i64 {
|
fn read_i64(&mut self) -> i64 {
|
||||||
let mut val = if let Some(val) = self.prog.get(self.ip).copied() {
|
let mut val = *self.prog.get(self.ip).unwrap() as i64;
|
||||||
val
|
val |= (*self.prog.get(self.ip + 1).unwrap() as i64) << 32;
|
||||||
} else {
|
|
||||||
panic!("Expected Value as next OP")
|
|
||||||
} as i64;
|
|
||||||
|
|
||||||
self.ip += 1;
|
// let mut bytes = [0; 8];
|
||||||
|
// bytes.copy_from_slice(&self.prog[self.ip..self.ip+8]);
|
||||||
|
// val = i64::from_le_bytes(bytes);
|
||||||
|
|
||||||
val |= (if let Some(val) = self.prog.get(self.ip).copied() {
|
// for i in 0 .. 8 {
|
||||||
val
|
// if let Some(tmp) = self.prog.get(self.ip + i).copied() {
|
||||||
} else {
|
// val |= ((tmp as i64) << i*8) as i64;
|
||||||
panic!("Expected Value as next OP")
|
// } else {
|
||||||
} as i64)
|
// panic!("Expected Value as next OP")
|
||||||
<< 32;
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
self.ip += 1;
|
self.ip += 2;
|
||||||
|
|
||||||
val
|
val
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user