mindustry logic execution, map- and schematic- parsing and rendering
counter 😔
bendn 7 months ago
parent 8383d24 · commit fc908dd
-rw-r--r--lemu/src/executor/builder.rs5
-rw-r--r--lemu/src/executor/mod.rs30
-rw-r--r--lemu/src/instructions/mod.rs17
-rw-r--r--lemu/src/lexer.rs3
-rw-r--r--lemu/src/memory.rs7
-rw-r--r--lemu/src/parser/mod.rs18
6 files changed, 56 insertions, 24 deletions
diff --git a/lemu/src/executor/builder.rs b/lemu/src/executor/builder.rs
index 936a3b6..83bec1e 100644
--- a/lemu/src/executor/builder.rs
+++ b/lemu/src/executor/builder.rs
@@ -2,8 +2,8 @@ use fimg::Image;
use std::{collections::VecDeque, io::Write as Wr};
use super::{
- Display, DisplayState, Drawing, Executor, ExecutorContext, Instruction, Limit, Memory, PInstr,
- UPInstr, BANK_SIZE, CELL_SIZE,
+ BANK_SIZE, CELL_SIZE, Display, DisplayState, Drawing, Executor, ExecutorContext, Instruction,
+ Limit, Memory, PInstr, UPInstr,
};
use crate::{
code::Code,
@@ -144,7 +144,6 @@ impl<'s, W: Wr> ExecutorBuilderInternal<'s, W> {
cells: cst::<CELL_SIZE>(cells),
banks: cst::<BANK_SIZE>(banks),
memory: LRegistry(mem.into()),
- counter: 0,
iterations: 0,
display: Drawing {
displays,
diff --git a/lemu/src/executor/mod.rs b/lemu/src/executor/mod.rs
index acc8284..0989bc0 100644
--- a/lemu/src/executor/mod.rs
+++ b/lemu/src/executor/mod.rs
@@ -1,5 +1,5 @@
mod builder;
-
+const COUNTER: LAddress = unsafe { LAddress::addr(0) };
use crate::{
debug::{info::DebugInfo, printable::Printable},
instructions::draw::Drawn,
@@ -150,7 +150,6 @@ pub struct ExecutorContext<'strings, W: Write> {
// maximum of 127 elements, so can use ~500KB
pub banks: Box<[[f64; BANK_SIZE]]>,
pub memory: LRegistry<'strings>,
- pub counter: usize,
pub display: Drawing,
pub output: Option<W>,
/// Counter for the number of iterations we have run so far.
@@ -208,7 +207,17 @@ impl<'s, W: Write> ExecutorContext<'s, W> {
}
pub fn jump(&mut self, Instruction(n): Instruction) {
- self.counter = n;
+ *self.counter() = n as f64;
+ }
+
+ pub fn counter(&mut self) -> &mut f64 {
+ unsafe {
+ self.memory
+ .0
+ .get_unchecked_mut(0)
+ .num_mut()
+ .unwrap_unchecked()
+ }
}
pub fn get<'a>(&'a self, a: LAddress) -> &LVar<'s> {
@@ -248,7 +257,10 @@ impl<'s, W: Write> Executor<'s, W> {
/// `counter` *must* be in bounds.
unsafe fn run_current(&mut self) -> Flow {
// SAFETY: yee
- match unsafe { self.program.get_unchecked(self.inner.counter) } {
+ let c = self.inner.counter();
+ let i = unsafe { self.program.get_unchecked(*c as usize) };
+ *c += 1.0;
+ match i {
PInstr::Instr(i) => {
#[cfg(feature = "debug")]
{
@@ -258,7 +270,7 @@ impl<'s, W: Write> Executor<'s, W> {
self.inner.memory.print(&self.debug_info, &mut mem).unwrap();
comat::cprintln!(
"{black}{:0<2} | {green}{instr} {black}({mem}){reset}",
- self.inner.counter
+ self.inner.counter(),
);
}
@@ -272,7 +284,7 @@ impl<'s, W: Write> Executor<'s, W> {
self.inner.memory.print(&self.debug_info, &mut mem).unwrap();
comat::cprintln!(
"{black}{:0<2} | {magenta}{i} {black}({mem}){reset}",
- self.inner.counter
+ self.inner.counter()
);
}
self.inner.display.buffer(i)
@@ -298,9 +310,9 @@ impl<'s, W: Write> Executor<'s, W> {
}
};
self.instructions_ran += 1;
- self.inner.counter += 1;
- if self.inner.counter >= self.program.len() {
- self.inner.counter = 0;
+ let c = self.inner.counter();
+ if *c as usize >= self.program.len() {
+ *c = 0.0;
self.inner.iterations += 1;
}
}
diff --git a/lemu/src/instructions/mod.rs b/lemu/src/instructions/mod.rs
index b4fc0aa..6724ed1 100644
--- a/lemu/src/instructions/mod.rs
+++ b/lemu/src/instructions/mod.rs
@@ -107,6 +107,7 @@ pub enum Instr {
Stop(Stop),
PackColor(PackColor),
Select(Select),
+ Noop(Noop),
End(End),
}
@@ -127,6 +128,7 @@ impl Printable for Instr {
Self::End(i) => i.print(info, f),
Self::PackColor(i) => i.print(info, f),
Self::Select(i) => i.print(info, f),
+ Self::Noop(i) => i.print(info, f),
}
}
}
@@ -307,6 +309,21 @@ impl Printable for End {
}
#[derive(Debug, Copy, Clone)]
+pub struct Noop {}
+
+impl LInstruction for Noop {
+ fn run<W: Write>(&self, _: &mut ExecutorContext<'_, W>) -> Flow {
+ Flow::Continue
+ }
+}
+
+impl Printable for Noop {
+ fn print(&self, _: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result {
+ write!(f, "noop")
+ }
+}
+
+#[derive(Debug, Copy, Clone)]
pub struct AlwaysJump {
pub(crate) to: Instruction,
}
diff --git a/lemu/src/lexer.rs b/lemu/src/lexer.rs
index 3552101..e6b85c6 100644
--- a/lemu/src/lexer.rs
+++ b/lemu/src/lexer.rs
@@ -33,7 +33,7 @@ macro_rules! instrs {
#[regex(r#"@[^ "\n]*"#, |lex| Cow::from(lex.slice()))]
#[regex(r#""[^"]*""#, callback = |lex| Cow::from(lex.slice()[1..lex.slice().len()-1].replace(r"\n", "\n")), priority = 8)]
String(Cow<'strings, str>),
- #[regex("[^@%0-9- \t\n][^ \t\n]*", priority = 7)]
+ #[regex("[^%0-9- \t\n][^ \t\n]*", priority = 7)]
Ident(&'strings str),
$(#[token($z, priority = 8)] $v,)+
@@ -67,7 +67,6 @@ instrs! {
"print" => Print,
"jump" => Jump,
"stop" => Stop,
- "@counter" => Counter,
"equal" => Equal,
"notEqual" => NotEqual,
"lessThan" => LessThan,
diff --git a/lemu/src/memory.rs b/lemu/src/memory.rs
index ff99dc8..bd9ca52 100644
--- a/lemu/src/memory.rs
+++ b/lemu/src/memory.rs
@@ -35,6 +35,13 @@ impl LVar<'_> {
Self::String(_) => None,
}
}
+
+ pub const fn num_mut(&mut self) -> Option<&mut f64> {
+ match self {
+ LVar::Num(x) => Some(x),
+ LVar::String(_) => None,
+ }
+ }
}
#[derive(Clone, Copy)]
diff --git a/lemu/src/parser/mod.rs b/lemu/src/parser/mod.rs
index 6ef5253..0764189 100644
--- a/lemu/src/parser/mod.rs
+++ b/lemu/src/parser/mod.rs
@@ -44,7 +44,6 @@ macro_rules! tokstr {
Token::Print => Some("print"),
Token::Jump => Some("jump"),
Token::Stop => Some("stop"),
- Token::Counter => Some("@counter"),
Token::Equal => Some("equal"),
Token::NotEqual => Some("notEqual"),
Token::LessThan => Some("lessThan"),
@@ -139,6 +138,7 @@ pub fn parse<'source, W: Wr>(
unsafe { Ok(LAddress::addr(used - 1)) }
}};
}
+ push!("@counter")?;
macro_rules! addr {
($val:expr) => {{
let val = $val;
@@ -279,14 +279,9 @@ pub fn parse<'source, W: Wr>(
// set x 4
Token::Set => {
let from = tok!()?;
- if from == Token::Counter {
- let to = take_numvar!(tok!()?)?;
- executor.add(DynJump { to, proglen: 0 });
- } else {
- let from = addr!(take_ident!(from)?)?;
- let to = take_var!(tok!()?)?;
- executor.add(Set { from, to });
- }
+ let from = addr!(take_ident!(from)?)?;
+ let to = take_var!(tok!()?)?;
+ executor.add(Set { from, to });
}
// stop
Token::Stop => {
@@ -643,7 +638,10 @@ pub fn parse<'source, W: Wr>(
}};
}
match i {
- "noop" => {}
+ "noop" => {
+ // executor.program.push(UPInstr::Comment("a"));
+ executor.add(crate::instructions::Noop {});
+ }
"printflush" => instr! {
(1) => |b| {
let t = tok!()?;