mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'lemu/src/instructions/mod.rs')
| -rw-r--r-- | lemu/src/instructions/mod.rs | 203 |
1 files changed, 80 insertions, 123 deletions
diff --git a/lemu/src/instructions/mod.rs b/lemu/src/instructions/mod.rs index 7bc2c57..39507a9 100644 --- a/lemu/src/instructions/mod.rs +++ b/lemu/src/instructions/mod.rs @@ -30,7 +30,6 @@ use std::{ use super::{ executor::{ExecutorContext, Instruction}, - lexer::Token, memory::{LAddress, LVar}, }; @@ -88,27 +87,27 @@ pub enum Flow { } #[enum_dispatch] -pub trait LInstruction<'v>: Display { - fn run<W: Write>(&self, exec: &mut ExecutorContext<'v, W>) -> Flow; +pub trait LInstruction: Display { + fn run<'v, W: Write>(&self, exec: &mut ExecutorContext<'v, W>) -> Flow; } -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] #[enum_dispatch(LInstruction)] -pub enum Instr<'v> { - Op2(Op2<'v>), - Jump(Jump<'v>), - AlwaysJump(AlwaysJump<'v>), - Set(Set<'v>), - Op1(Op1<'v>), - Read(io::Read<'v>), - Write(io::Write<'v>), +pub enum Instr { + Op2(Op2), + Jump(Jump), + AlwaysJump(AlwaysJump), + Set(Set), + Op1(Op1), + Read(io::Read), + Write(io::Write), DrawFlush(draw::Flush), - DynJump(DynJump<'v>), - Print(io::Print<'v>), + DynJump(DynJump), + Print(io::Print), Stop(Stop), End(End), } -impl Display for Instr<'_> { +impl Display for Instr { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Self::Op2(i) => write!(f, "{i}"), @@ -127,19 +126,19 @@ impl Display for Instr<'_> { } } -#[derive(Debug)] -pub struct Set<'v> { - pub(crate) from: LAddress<'v>, - pub(crate) to: LAddress<'v>, +#[derive(Debug, Copy, Clone)] +pub struct Set { + pub(crate) from: LAddress, + pub(crate) to: LAddress, } -impl<'v> LInstruction<'v> for Set<'v> { - fn run<W: Write>(&self, exec: &mut ExecutorContext<'v, W>) -> Flow { - exec.set(&self.from, self.to.clone()); +impl LInstruction for Set { + fn run<'v, W: Write>(&self, exec: &mut ExecutorContext<'v, W>) -> Flow { + exec.set(self.from, self.to.clone()); Flow::Continue } } -impl Display for Set<'_> { +impl Display for Set { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "set {} {}", self.from, self.to) } @@ -185,17 +184,15 @@ macro_rules! get_num { } use get_num; -#[derive(Debug)] -pub struct Op1<'v> { - op_id: MathOp1, - op: fn(&LVar<'v>) -> f64, - x: LAddress<'v>, - out: LAddress<'v>, +#[derive(Debug, Copy, Clone)] +pub struct Op1 { + op: for<'v> fn(&LVar<'v>) -> f64, + x: LAddress, + out: LAddress, } -impl<'v> Op1<'v> { - pub(crate) const fn new(op: MathOp1, x: LAddress<'v>, out: LAddress<'v>) -> Self { +impl<'v> Op1 { + pub(crate) const fn new(op: MathOp1, x: LAddress, out: LAddress) -> Self { Self { - op_id: op, op: op.get_fn(), x, out, @@ -203,40 +200,31 @@ impl<'v> Op1<'v> { } } -impl<'s> LInstruction<'s> for Op1<'s> { - fn run<W: Write>(&self, exec: &mut ExecutorContext<'s, W>) -> Flow { - let x = (self.op)(exec.get(&self.x)); - if let Some(y) = exec.get_mut(&self.out) { - *y = LVar::Num(x); - } +impl LInstruction for Op1 { + fn run<'s, W: Write>(&self, exec: &mut ExecutorContext<'s, W>) -> Flow { + let x = (self.op)(exec.get(self.x)); + *exec.get_mut(self.out) = LVar::Num(x); Flow::Continue } } -impl Display for Op1<'_> { +impl Display for Op1 { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let Self { op_id, x, out, .. } = self; - write!(f, "op {} {out} {x}", Token::from(*op_id)) + let Self { x, out, .. } = self; + write!(f, "op .. {out} {x}") } } -#[derive(Debug)] -pub struct Op2<'v> { - op_id: MathOp2, - op: fn(&LVar<'v>, &LVar<'v>) -> f64, - a: LAddress<'v>, - b: LAddress<'v>, - out: LAddress<'v>, +#[derive(Debug, Copy, Clone)] +pub struct Op2 { + op: for<'v> fn(&LVar<'v>, &LVar<'v>) -> f64, + a: LAddress, + b: LAddress, + out: LAddress, } -impl<'v> Op2<'v> { - pub(crate) const fn new( - op: MathOp2, - a: LAddress<'v>, - b: LAddress<'v>, - out: LAddress<'v>, - ) -> Self { +impl Op2 { + pub(crate) const fn new(op: MathOp2, a: LAddress, b: LAddress, out: LAddress) -> Self { Self { - op_id: op, op: op.get_fn(), a, b, @@ -245,31 +233,26 @@ impl<'v> Op2<'v> { } } -impl<'v> LInstruction<'v> for Op2<'v> { - fn run<W: Write>(&self, exec: &mut ExecutorContext<'v, W>) -> Flow { - let x = (self.op)(exec.get(&self.a), exec.get(&self.b)); - if let Some(y) = exec.get_mut(&self.out) { - *y = LVar::from(x); - } +impl LInstruction for Op2 { + fn run<'v, W: Write>(&self, exec: &mut ExecutorContext<'v, W>) -> Flow { + let x = (self.op)(exec.get(self.a), exec.get(self.b)); + exec.memory[self.out] = LVar::Num(x); Flow::Continue } } -impl Display for Op2<'_> { +impl Display for Op2 { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let Self { - op_id, a, b, out, .. - } = self; - write!(f, "op {} {out} {a} {b}", Token::from(*op_id)) + let Self { a, b, out, .. } = self; + write!(f, "op .. {out} {a} {b}") } } -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub struct End {} -impl LInstruction<'_> for End { +impl LInstruction for End { fn run<W: Write>(&self, exec: &mut ExecutorContext<'_, W>) -> Flow { - exec.memory.clear(); exec.iterations += 1; // SAFETY: if we exist, 0 exists. unsafe { exec.jump(Instruction::new(0)) }; @@ -283,48 +266,34 @@ impl Display for End { } } -#[derive(Debug)] -pub struct AlwaysJump<'s> { +#[derive(Debug, Copy, Clone)] +pub struct AlwaysJump { pub(crate) to: Instruction, - pub(crate) label: Option<&'s str>, } -impl LInstruction<'_> for AlwaysJump<'_> { +impl LInstruction for AlwaysJump { fn run<W: Write>(&self, exec: &mut ExecutorContext<'_, W>) -> Flow { exec.jump(self.to); Flow::Stay } } -impl Display for AlwaysJump<'_> { +impl Display for AlwaysJump { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self.label { - None => write!(f, "jump {} always", self.to.get()), - Some(l) => write!(f, "jump {l} always"), - } + write!(f, "jump {} always", self.to.get()) } } -#[derive(Debug)] -pub struct Jump<'v> { - label: Option<&'v str>, - op_id: ConditionOp, - op: fn(&LVar<'v>, &LVar<'v>) -> bool, +#[derive(Debug, Copy, Clone)] +pub struct Jump { + op: for<'v> fn(&LVar<'v>, &LVar<'v>) -> bool, pub(crate) to: Instruction, - a: LAddress<'v>, - b: LAddress<'v>, + a: LAddress, + b: LAddress, } -impl<'v> Jump<'v> { - pub fn new( - op: ConditionOp, - to: Instruction, - a: LAddress<'v>, - b: LAddress<'v>, - label: Option<&'v str>, - ) -> Self { +impl Jump { + pub fn new(op: ConditionOp, to: Instruction, a: LAddress, b: LAddress) -> Self { Self { - op_id: op, op: op.get_fn(), - label, to, a, b, @@ -332,9 +301,9 @@ impl<'v> Jump<'v> { } } -impl<'v> LInstruction<'v> for Jump<'v> { - fn run<W: Write>(&self, exec: &mut ExecutorContext<'v, W>) -> Flow { - if (self.op)(exec.get(&self.a), exec.get(&self.b)) { +impl LInstruction for Jump { + fn run<'v, W: Write>(&self, exec: &mut ExecutorContext<'v, W>) -> Flow { + if (self.op)(exec.get(self.a), exec.get(self.b)) { exec.jump(self.to); Flow::Stay } else { @@ -343,34 +312,22 @@ impl<'v> LInstruction<'v> for Jump<'v> { } } -impl Display for Jump<'_> { +impl Display for Jump { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let Self { - op_id, - label, - to, - a, - b, - .. - } = self; - write!(f, "jump ")?; - match label { - Some(v) => write!(f, "{v} "), - None => write!(f, "{} ", to.get()), - }?; - write!(f, "{} {a} {b}", Token::from(*op_id)) + let Self { to, a, b, .. } = self; + write!(f, "jump .. {} {a} {b}", to.get()) } } -#[derive(Debug)] -pub struct DynJump<'v> { - pub to: LAddress<'v>, +#[derive(Debug, Copy, Clone)] +pub struct DynJump { + pub to: LAddress, pub proglen: usize, } -impl<'v> LInstruction<'v> for DynJump<'v> { - fn run<W: Write>(&self, exec: &mut ExecutorContext<'v, W>) -> Flow { - if let &LVar::Num(n) = exec.get(&self.to) { +impl LInstruction for DynJump { + fn run<'v, W: Write>(&self, exec: &mut ExecutorContext<'v, W>) -> Flow { + if let &LVar::Num(n) = exec.get(self.to) { let i = n.round() as usize; if i < self.proglen { // SAFETY: just checked bounds @@ -382,15 +339,15 @@ impl<'v> LInstruction<'v> for DynJump<'v> { } } -impl Display for DynJump<'_> { +impl Display for DynJump { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "set @counter {}", self.to) } } -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub struct Stop {} -impl LInstruction<'_> for Stop { +impl LInstruction for Stop { fn run<W: Write>(&self, _: &mut ExecutorContext<'_, W>) -> Flow { Flow::Exit } |