mindustry logic execution, map- and schematic- parsing and rendering
do escapes properly
bendn 2023-09-13
parent 5f6fa99 · commit ff22dfe
-rw-r--r--lemu/Cargo.toml3
-rw-r--r--lemu/src/executor/mod.rs6
-rw-r--r--lemu/src/instructions/cop.rs10
-rw-r--r--lemu/src/instructions/draw.rs18
-rw-r--r--lemu/src/instructions/io.rs6
-rw-r--r--lemu/src/instructions/mod.rs42
-rw-r--r--lemu/src/instructions/mop.rs17
-rw-r--r--lemu/src/instructions/mop2.rs18
-rw-r--r--lemu/src/lexer.rs19
-rw-r--r--lemu/src/memory.rs31
-rw-r--r--lemu/src/parser.rs10
11 files changed, 91 insertions, 89 deletions
diff --git a/lemu/Cargo.toml b/lemu/Cargo.toml
index 84f4a11..df6d6c5 100644
--- a/lemu/Cargo.toml
+++ b/lemu/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "lemu"
-version = "0.1.3"
+version = "0.1.4"
edition = "2021"
description = "M-LOG runner"
authors = ["bend-n <[email protected]>"]
@@ -16,6 +16,7 @@ fimg = { version = "0.4", default-features = false }
logos = "0.13.0"
yumy = { version = "0.2.1", optional = true }
rust-fuzzy-search = { version = "0.1.1", optional = true }
+beef = "0.5"
[features]
bin = ["fimg/save", "diagnose"]
diff --git a/lemu/src/executor/mod.rs b/lemu/src/executor/mod.rs
index c900045..7d5fc60 100644
--- a/lemu/src/executor/mod.rs
+++ b/lemu/src/executor/mod.rs
@@ -159,11 +159,11 @@ impl<'s, W: Write> ExecutorContext<'s, W> {
}
}
- pub fn set(&mut self, a: LAddress<'s>, b: LAddress<'s>) -> bool {
+ pub fn set(&mut self, a: &LAddress<'s>, b: LAddress<'s>) -> bool {
self.memory.set(a, b)
}
- pub fn get_mut(&mut self, a: LAddress<'s>) -> Option<&mut LVar<'s>> {
+ pub fn get_mut(&mut self, a: &LAddress<'s>) -> Option<&mut LVar<'s>> {
self.memory.get_mut(a)
}
@@ -172,7 +172,7 @@ impl<'s, W: Write> ExecutorContext<'s, W> {
self.counter = n;
}
- pub fn get(&self, a: LAddress<'s>) -> LVar<'s> {
+ pub fn get<'a>(&'a self, a: &'a LAddress<'s>) -> &LVar<'s> {
self.memory.get(a)
}
}
diff --git a/lemu/src/instructions/cop.rs b/lemu/src/instructions/cop.rs
index 9e32720..250a0f1 100644
--- a/lemu/src/instructions/cop.rs
+++ b/lemu/src/instructions/cop.rs
@@ -12,16 +12,16 @@ super::op_enum! { pub enum ConditionOp {
macro_rules! op {
($name: ident $op:tt ) => {
- fn $name<'v>(a: LVar<'v>, b: LVar<'v>) -> bool {
- if let LVar::Num(a) = a && let LVar::Num(b) = b { a $op b } else { false }
+ fn $name<'v>(a: &LVar<'v>, b: &LVar<'v>) -> bool {
+ if let &LVar::Num(a) = a && let &LVar::Num(b) = b { a $op b } else { false }
}
};
}
-fn eq<'v>(a: LVar<'v>, b: LVar<'v>) -> bool {
+fn eq<'v>(a: &LVar<'v>, b: &LVar<'v>) -> bool {
a == b
}
-fn ne<'v>(a: LVar<'v>, b: LVar<'v>) -> bool {
+fn ne<'v>(a: &LVar<'v>, b: &LVar<'v>) -> bool {
a != b
}
op!(lt <);
@@ -30,7 +30,7 @@ op!(le <=);
op!(ge >=);
impl ConditionOp {
- pub const fn get_fn(self) -> for<'f> fn(LVar<'f>, LVar<'f>) -> bool {
+ pub const fn get_fn(self) -> for<'f> fn(&LVar<'f>, &LVar<'f>) -> bool {
match self {
Self::Equal | Self::StrictEqual => eq,
Self::NotEqual => ne,
diff --git a/lemu/src/instructions/draw.rs b/lemu/src/instructions/draw.rs
index 701fc55..fcd7dc6 100644
--- a/lemu/src/instructions/draw.rs
+++ b/lemu/src/instructions/draw.rs
@@ -46,7 +46,7 @@ impl<'v> DrawInstruction<'v> for Clear<'v> {
fn draw(&self, mem: &mut LRegistry<'v>, image: &mut Image<&mut [u8], 4>, _: &mut DisplayState) {
macro_rules! u8 {
($v:ident) => {
- match mem.get(self.$v) {
+ match mem.get(&self.$v) {
LVar::Num(n) => n.round() as u8,
_ => return,
}
@@ -70,7 +70,7 @@ impl<'v> DrawInstruction<'v> for SetColorDyn<'v> {
fn draw(&self, mem: &mut LRegistry<'v>, _: &mut Image<&mut [u8], 4>, state: &mut DisplayState) {
macro_rules! u8 {
($v:ident) => {
- match mem.get(self.$v) {
+ match mem.get(&self.$v) {
LVar::Num(n) => n.round() as u8,
_ => return,
}
@@ -99,7 +99,7 @@ pub struct SetStroke<'v> {
}
impl<'v> DrawInstruction<'v> for SetStroke<'v> {
fn draw(&self, mem: &mut LRegistry<'v>, _: &mut Image<&mut [u8], 4>, state: &mut DisplayState) {
- if let LVar::Num(n) = mem.get(self.size) {
+ if let &LVar::Num(n) = mem.get(&self.size) {
state.stroke = n;
}
}
@@ -109,8 +109,8 @@ pub type Point<'v> = (LAddress<'v>, LAddress<'v>);
#[rustfmt::skip]
macro_rules! point {
($mem:ident@$point:expr) => {{
- let LVar::Num(a) = $mem.get($point.0) else { return; };
- let LVar::Num(b) = $mem.get($point.1) else { return; };
+ let &LVar::Num(a) = $mem.get(&$point.0) else { return; };
+ let &LVar::Num(b) = $mem.get(&$point.1) else { return; };
(a,b)
}}
}
@@ -161,8 +161,8 @@ impl<'v> DrawInstruction<'v> for RectFilled<'v> {
state: &mut DisplayState,
) {
let pos = map!(point!([email protected]), |n| n as u32);
- let width = get_num!(mem.get(self.width), or ret) as u32;
- let height = get_num!(mem.get(self.height), or ret) as u32;
+ let width = get_num!(mem.get(&self.width)) as u32;
+ let height = get_num!(mem.get(&self.height)) as u32;
if unbounded!(image @ pos.0 + width => pos.1 + height) {
return;
}
@@ -187,8 +187,8 @@ impl<'v> DrawInstruction<'v> for RectBordered<'v> {
) {
// happily ignoring that state specifies box stroke width
let pos = map!(point!([email protected]), |n| n as u32);
- let width = get_num!(mem.get(self.width), or ret) as u32;
- let height = get_num!(mem.get(self.height), or ret) as u32;
+ let width = get_num!(mem.get(&self.width)) as u32;
+ let height = get_num!(mem.get(&self.height)) as u32;
if unbounded!(image @ pos.0 + width => pos.1 + height) {
return;
}
diff --git a/lemu/src/instructions/io.rs b/lemu/src/instructions/io.rs
index b6564a8..75b9c0e 100644
--- a/lemu/src/instructions/io.rs
+++ b/lemu/src/instructions/io.rs
@@ -16,7 +16,7 @@ pub struct Read<'v> {
impl<'v> LInstruction<'v> for Read<'v> {
fn run<W: Wr>(&self, exec: &mut ExecutorContext<'v, W>) -> Flow {
let to = exec.mem(self.container)[self.index];
- let Some(out) = exec.get_mut(self.output) else {
+ let Some(out) = exec.get_mut(&self.output) else {
return Flow::Continue;
};
*out = LVar::from(to);
@@ -34,7 +34,7 @@ pub struct Write<'v> {
impl<'v> LInstruction<'v> for Write<'v> {
fn run<W: Wr>(&self, exec: &mut ExecutorContext<'v, W>) -> Flow {
- let LVar::Num(n) = exec.get(self.set) else {
+ let &LVar::Num(n) = exec.get(&self.set) else {
return Flow::Continue;
};
exec.mem(self.container)[self.index] = n;
@@ -48,7 +48,7 @@ pub struct Print<'v> {
}
impl LInstruction<'_> for Print<'_> {
fn run<W: Wr>(&self, exec: &mut ExecutorContext<'_, W>) -> Flow {
- let v = exec.get(self.val);
+ let v = exec.get(&self.val).clone();
if let Some(o) = &mut exec.output {
write!(o, "{v}").unwrap();
}
diff --git a/lemu/src/instructions/mod.rs b/lemu/src/instructions/mod.rs
index 514bc8e..8dbae7e 100644
--- a/lemu/src/instructions/mod.rs
+++ b/lemu/src/instructions/mod.rs
@@ -128,7 +128,7 @@ pub struct Set<'v> {
}
impl<'v> LInstruction<'v> for Set<'v> {
fn run<W: Write>(&self, exec: &mut ExecutorContext<'v, W>) -> Flow {
- exec.set(self.from, self.to);
+ exec.set(&self.from, self.to.clone());
Flow::Continue
}
}
@@ -142,12 +142,12 @@ macro_rules! op_enum {
$($variant),+
}
- impl TryFrom<Token<'_>> for $name {
- type Error = ();
- fn try_from(value: Token<'_>) -> Result<Self, Self::Error> {
+ impl<'a> TryFrom<Token<'a>> for $name {
+ type Error = Token<'a>;
+ fn try_from(value: Token<'a>) -> Result<Self, Self::Error> {
match value {
$(Token::$variant => Ok(Self::$variant),)+
- _ => Err(())
+ v => Err(v)
}
}
}
@@ -158,14 +158,8 @@ use op_enum;
macro_rules! get_num {
($x:expr) => {
match $x {
- LVar::Num(x) => x,
- _ => return LVar::null(),
- }
- };
- ($x:expr, or ret) => {
- match $x {
- LVar::Num(x) => x,
- _ => return,
+ LVar::Num(x) => *x,
+ _ => return Default::default(),
}
};
}
@@ -173,7 +167,7 @@ use get_num;
#[derive(Debug)]
pub struct Op1<'v> {
- pub(crate) op: fn(LVar<'v>) -> LVar<'v>,
+ pub(crate) op: fn(&LVar<'v>) -> f64,
pub(crate) x: LAddress<'v>,
pub(crate) out: LAddress<'v>,
}
@@ -189,9 +183,9 @@ 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 = x;
+ let x = (self.op)(exec.get(&self.x));
+ if let Some(y) = exec.get_mut(&self.out) {
+ *y = LVar::Num(x);
}
Flow::Continue
}
@@ -199,7 +193,7 @@ impl<'s> LInstruction<'s> for Op1<'s> {
#[derive(Debug)]
pub struct Op2<'v> {
- pub(crate) op: fn(LVar<'v>, LVar<'v>) -> LVar<'v>,
+ pub(crate) op: fn(&LVar<'v>, &LVar<'v>) -> f64,
pub(crate) a: LAddress<'v>,
pub(crate) b: LAddress<'v>,
pub(crate) out: LAddress<'v>,
@@ -222,9 +216,9 @@ 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 = x;
+ 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);
}
Flow::Continue
}
@@ -247,7 +241,7 @@ impl LInstruction<'_> for AlwaysJump {
#[derive(Debug)]
pub struct Jump<'v> {
- pub(crate) op: fn(LVar<'v>, LVar<'v>) -> bool,
+ pub(crate) op: fn(&LVar<'v>, &LVar<'v>) -> bool,
pub(crate) to: Instruction,
pub(crate) a: LAddress<'v>,
pub(crate) b: LAddress<'v>,
@@ -271,7 +265,7 @@ pub struct DynJump<'v> {
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) {
+ if let &LVar::Num(n) = exec.get(&self.to) {
let i = n.round() as usize;
if i < self.proglen {
exec.jump(Instruction(i));
@@ -285,7 +279,7 @@ impl<'v> LInstruction<'v> for DynJump<'v> {
impl<'v> LInstruction<'v> for Jump<'v> {
#[allow(unused_variables)]
fn run<W: Write>(&self, exec: &mut ExecutorContext<'v, W>) -> Flow {
- if (self.op)(exec.get(self.a), exec.get(self.b)) {
+ if (self.op)(exec.get(&self.a), exec.get(&self.b)) {
exec.jump(self.to);
Flow::Stay
} else {
diff --git a/lemu/src/instructions/mop.rs b/lemu/src/instructions/mop.rs
index 1710731..eb315eb 100644
--- a/lemu/src/instructions/mop.rs
+++ b/lemu/src/instructions/mop.rs
@@ -20,8 +20,8 @@ super::op_enum! { pub enum MathOp1 {
macro_rules! num {
($fn: ident $c:expr) => {
- fn $fn(x: LVar<'_>) -> LVar<'_> {
- LVar::from($c(get_num!(x)))
+ fn $fn(x: &LVar<'_>) -> f64 {
+ f64::from($c(get_num!(x)))
}
};
}
@@ -33,16 +33,13 @@ macro_rules! flbop {
}
num!(floor f64::floor);
-fn not(x: LVar<'_>) -> LVar<'_> {
- match x {
- LVar::Num(n) => LVar::Num(flbop!(n, |n: u64| !n)),
- LVar::String(_) => LVar::null(),
- }
+fn not(x: &LVar<'_>) -> f64 {
+ flbop!(get_num!(x), |n: u64| !n)
}
num!(log f64::ln);
num!(abs f64::abs);
-const fn rand(_: LVar<'_>) -> LVar<'_> {
- LVar::Num(4.0)
+const fn rand(_: &LVar<'_>) -> f64 {
+ 4.0
}
num!(ceil f64::ceil);
num!(sqrt f64::sqrt);
@@ -55,7 +52,7 @@ num!(atan f64::atan);
num!(log10 f64::log10);
impl MathOp1 {
- pub const fn get_fn(self) -> for<'f> fn(LVar<'f>) -> LVar<'f> {
+ pub const fn get_fn(self) -> for<'f> fn(&LVar<'f>) -> f64 {
match self {
Self::Floor => floor,
Self::Not => not,
diff --git a/lemu/src/instructions/mop2.rs b/lemu/src/instructions/mop2.rs
index 2eacd91..9fb208f 100644
--- a/lemu/src/instructions/mop2.rs
+++ b/lemu/src/instructions/mop2.rs
@@ -33,29 +33,29 @@ super::op_enum! { pub enum MathOp2 {
macro_rules! num {
($fn:ident $closure:expr) => {
- fn $fn<'v>(a: LVar<'v>, b: LVar<'v>) -> LVar<'v> {
- LVar::from($closure(get_num!(a), get_num!(b)))
+ fn $fn<'v>(a: &LVar<'v>, b: &LVar<'v>) -> f64 {
+ f64::from($closure(get_num!(a), get_num!(b)))
}
};
}
macro_rules! op {
($fn:ident $op:tt) => {
- fn $fn<'v>(a: LVar<'v>, b: LVar<'v>) -> LVar<'v> {
- LVar::from(get_num!(a) $op get_num!(b))
+ fn $fn<'v>(a: &LVar<'v>, b: &LVar<'v>) -> f64 {
+ f64::from(get_num!(a) $op get_num!(b))
}
}
}
macro_rules! bop {
($fn: ident $op: tt) => {
- fn $fn<'v>(a: LVar<'v>, b: LVar<'v>) -> LVar<'v> {
- LVar::from(((get_num!(a) as u64) $op (get_num!(b) as u64)) as f64)
+ fn $fn<'v>(a: &LVar<'v>, b:& LVar<'v>) -> f64 {
+ f64::from(((get_num!(a) as u64) $op (get_num!(b) as u64)) as f64)
}
};
}
macro_rules! nofun {
($fn:ident $closure:expr) => {
- fn $fn<'v>(a: LVar<'v>, b: LVar<'v>) -> LVar<'v> {
- LVar::from($closure(a, b))
+ fn $fn<'v>(a: &LVar<'v>, b: &LVar<'v>) -> f64 {
+ f64::from($closure(a, b))
}
};
}
@@ -100,7 +100,7 @@ num!(angle |a: f64, b: f64| {
});
impl MathOp2 {
- pub const fn get_fn(self) -> for<'f> fn(LVar<'f>, LVar<'f>) -> LVar<'f> {
+ pub const fn get_fn(self) -> for<'f> fn(&LVar<'f>, &LVar<'f>) -> f64 {
match self {
// we kind of interpret strings as numbers so yeah
Self::Equal | Self::StrictEqual => eq,
diff --git a/lemu/src/lexer.rs b/lemu/src/lexer.rs
index 1a5be66..4d85822 100644
--- a/lemu/src/lexer.rs
+++ b/lemu/src/lexer.rs
@@ -1,7 +1,8 @@
+use beef::lean::Cow;
use logos::{Lexer as RealLexer, Logos, Span};
macro_rules! instrs {
($($z:literal => $v:ident,)+) => {
- #[derive(Logos, Debug, PartialEq, Copy, Clone)]
+ #[derive(Logos, Debug, PartialEq, Clone)]
#[logos(skip r"[ \t]+")]
pub enum Token<'strings> {
#[token("\n")]
@@ -10,11 +11,12 @@ macro_rules! instrs {
Comment(&'strings str),
#[regex(r"[0-9]+(\.[0-9]+)?", |lex| lex.slice().parse().ok())]
#[regex(r"(true)|(false)", |lex| lex.slice().parse::<bool>().ok().map(f64::from))]
- #[regex(r#""[0-9]+(\.[0-9]+)?""#, |lex| lex.slice()[1..lex.slice().len()-1].parse().ok())]
+ #[regex(r#""[0-9]+(\.[0-9]+)?""#, callback = |lex| lex.slice()[1..lex.slice().len()-1].parse().ok(), priority = 6)]
Num(f64),
- #[regex(r#""[^"]*""#, |lex| &lex.slice()[1..lex.slice().len()-1])]
- #[regex(r#"@[^ "\n]*"#, |lex| &lex.slice()[1..])]
- String(&'strings str),
+ #[regex(r#""([^\\"\n])*""#, callback = |lex| Cow::from(&lex.slice()[1..lex.slice().len()-1]), priority = 5)]
+ #[regex(r#"@[^ "\n]*"#, |lex| Cow::from(&lex.slice()[1..]))]
+ #[regex(r#""[^"]*""#, |lex| Cow::from(lex.slice()[1..lex.slice().len()-1].replace(r"\n", "\n")))]
+ String(Cow<'strings, str>),
#[regex("[^0-9 \t\n]+")]
Ident(&'strings str),
@@ -25,7 +27,8 @@ macro_rules! instrs {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
$(Self::$v => write!(f, $z,),)+
- Self::String(s) | Self::Ident(s)| Self::Comment(s) => write!(f, "{s}"),
+ Self::Ident(s)| Self::Comment(s) => write!(f, "{s}"),
+ Self::String(s) => write!(f, "{s}"),
Self::Num(n) => write!(f, "{n}"),
Self::Newline => write!(f, "\n"),
}
@@ -134,7 +137,7 @@ fn lexer() {
set x "4""#);
macro_rules! test {
($($tok:ident$(($var:literal))?),+ $(,)?) => {{
- $(assert_eq!(lex.next(), Some(Token::$tok$(($var))?));)+
+ $(assert_eq!(lex.next(), Some(Token::$tok$(($var.into()))?));)+
assert_eq!(lex.next(), None);
}}
}
@@ -151,6 +154,6 @@ fn lexer() {
Newline,
Set,
Ident("x"),
- Num(4.0),
+ Num(4),
];
}
diff --git a/lemu/src/memory.rs b/lemu/src/memory.rs
index b350110..561569c 100644
--- a/lemu/src/memory.rs
+++ b/lemu/src/memory.rs
@@ -1,7 +1,8 @@
-#[derive(Copy, Clone, Debug)]
+use beef::lean::Cow;
+#[derive(Clone, Debug)]
pub enum LVar<'string> {
Num(f64),
- String(&'string str),
+ String(Cow<'string, str>),
}
impl PartialEq for LVar<'_> {
@@ -21,7 +22,7 @@ impl LVar<'_> {
}
}
-#[derive(Copy, Clone)]
+#[derive(Clone)]
pub enum LAddress<'str> {
Const(LVar<'str>),
Address(usize, Priv),
@@ -58,7 +59,7 @@ impl std::fmt::Display for LVar<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Num(n) => write!(f, "{n}"),
- Self::String(s) => write!(f, r#"{}"#, s.replace(r"\n", "\n")),
+ Self::String(s) => write!(f, r#"{s}"#),
}
}
}
@@ -77,6 +78,12 @@ impl From<bool> for LVar<'_> {
impl<'s> From<&'s str> for LVar<'s> {
fn from(value: &'s str) -> Self {
+ Self::String(value.into())
+ }
+}
+
+impl<'s> From<Cow<'s, str>> for LVar<'s> {
+ fn from(value: Cow<'s, str>) -> Self {
Self::String(value)
}
}
@@ -96,28 +103,28 @@ impl<'s> LRegistry<'s> {
}
}
- pub fn get(&self, a: LAddress<'s>) -> LVar<'s> {
+ pub fn get<'a>(&'a self, a: &'a LAddress<'s>) -> &LVar<'s> {
match a {
// SAFETY: addr constructor requires bounds
- LAddress::Address(n, ..) => unsafe { *self.0.get_unchecked(n) },
+ LAddress::Address(n, ..) => unsafe { self.0.get_unchecked(*n) },
LAddress::Const(n) => n,
}
}
- pub fn set(&mut self, a: LAddress<'s>, b: LAddress<'s>) -> bool {
+ pub fn set(&mut self, a: &LAddress<'s>, b: LAddress<'s>) -> bool {
match a {
LAddress::Const(_) => false,
LAddress::Address(v, ..) => {
match b {
LAddress::Const(n) => {
// SAFETY: v comes from Address, therefore safe
- *unsafe { self.0.get_unchecked_mut(v) } = n;
+ *unsafe { self.0.get_unchecked_mut(*v) } = n;
}
LAddress::Address(n, ..) => {
// SAFETY: n comes from Address, therefore safe
- let b = *unsafe { self.0.get_unchecked(n) };
+ let b = unsafe { self.0.get_unchecked(n).clone() };
// SAFETY: v comes from Addr, therefore safe
- *unsafe { self.0.get_unchecked_mut(v) } = b;
+ *unsafe { self.0.get_unchecked_mut(*v) } = b;
}
};
true
@@ -125,11 +132,11 @@ impl<'s> LRegistry<'s> {
}
}
- pub fn get_mut(&mut self, a: LAddress<'s>) -> Option<&mut LVar<'s>> {
+ pub fn get_mut(&mut self, a: &LAddress<'s>) -> Option<&mut LVar<'s>> {
match a {
LAddress::Const(_) => None,
// SAFETY: addr constructor requires bounds
- LAddress::Address(n, ..) => Some(unsafe { self.0.get_unchecked_mut(n) }),
+ LAddress::Address(n, ..) => Some(unsafe { self.0.get_unchecked_mut(*n) }),
}
}
}
diff --git a/lemu/src/parser.rs b/lemu/src/parser.rs
index f81c71b..04305ad 100644
--- a/lemu/src/parser.rs
+++ b/lemu/src/parser.rs
@@ -466,19 +466,19 @@ pub fn parse<'source, W: Wr>(
executor.jmp();
unfinished_jumps.push((UJump::Always, i, executor.last()));
} else {
- let op = op.try_into().map_err(|()| err!(ExpectedOp(op)))?;
+ let op = op.try_into().map_err(|op| err!(ExpectedOp(op)))?;
let a = take_var!(tok!()?)?;
let b = take_var!(tok!()?)?;
executor.jmp();
unfinished_jumps.push((UJump::Sometimes { a, b, op }, i, executor.last()));
}
- } else if let Ok(n) = take_int!(tok) {
+ } else if let Ok(n) = take_int!(tok.clone()) {
let to = Instruction(n);
let op = tok!()?;
if op == Token::Always {
executor.add(AlwaysJump { to });
} else {
- let op = op.try_into().map_err(|()| err!(ExpectedOp(op)))?;
+ let op = op.try_into().map_err(|op| err!(ExpectedOp(op)))?;
let a = take_var!(tok!()?)?;
let b = take_var!(tok!()?)?;
executor.add(Jump::new(op, to, a, b));
@@ -490,12 +490,12 @@ pub fn parse<'source, W: Wr>(
// op add c 1 2
Token::Op => {
let op = tok!()?;
- if let Ok(op) = MathOp1::try_from(op) {
+ if let Ok(op) = MathOp1::try_from(op.clone()) {
// assigning to a var is useless but legal
let out = take_numvar!(tok!()?)?;
let x = take_numvar!(tok!()?)?;
executor.add(Op1::new(op, x, out));
- } else if let Ok(op) = MathOp2::try_from(op) {
+ } else if let Ok(op) = MathOp2::try_from(op.clone()) {
let out = take_numvar!(tok!()?)?;
let a = take_numvar!(tok!()?)?;
let b = take_numvar!(tok!()?)?;