mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'lemu/src/parser.rs')
| -rw-r--r-- | lemu/src/parser.rs | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/lemu/src/parser.rs b/lemu/src/parser.rs index 9fd08e1..b524bce 100644 --- a/lemu/src/parser.rs +++ b/lemu/src/parser.rs @@ -13,7 +13,7 @@ use super::{ AlwaysJump, ConditionOp, DynJump, End, Instr, Jump, MathOp1, MathOp2, Op1, Op2, Set, Stop, }, lexer::{Lexer, Token}, - memory::LAddress, + memory::{LAddress, LVar}, }; /// Errors returned when parsing fails. @@ -49,14 +49,17 @@ pub enum Error<'s> { /// jump label always /// ``` /// (typo: lable not label) - #[error("unable to find label {0:?}")] + #[error("unable to find label {0}")] LabelNotFound(&'s str, Span), /// Occurs from eg `jump 4910294029 always` #[error("unable to jump to instruction {0:?}")] InvalidJump(Instruction, Span), /// Occurs from eg `read bank9223372036854775807 5` (only `126` banks can exist) - #[error("cannot get cell>{0:?}")] + #[error("cannot get cell>{0}")] MemoryTooFar(usize, Span), + /// Occurs from eg `read bank1 512` + #[error("index {0} out of bounds ({1} max)")] + IndexOutOfBounds(usize, usize, Span), /// Occurs from `read register1` #[error("unknown memory type {0:?}, expected (cell)|(bank)")] InvalidMemoryType(&'s str, Span), @@ -217,11 +220,11 @@ impl Error<'_> { )); } Self::ExpectedVar(_, s) => { - msg!("{error}: expected a variable") + msg!("{error}: expected variable") .label(err!(s, "this was supposed to be a variable")); } Self::ExpectedIdent(_, s) => { - msg!("{error}: expected a identifier") + msg!("{error}: expected identifier") .label(err!(s, "this was supposed to be a identifier")); } Self::ExpectedJump(t, s) => { @@ -298,6 +301,10 @@ impl Error<'_> { Self::NoDisplay(disp, s) => { msg!("{error}: no display allocated").label(err!(s, "display#{disp} has not been created")).note(format!("{note}: it is impossible for me to dynamically allocate displays, as 'display1' could be large or small")); } + Self::IndexOutOfBounds(index, size, s) => { + msg!("{error}: index {index} out of bounds") + .label(err!(s, "memory has only {size} elements")); + } }; e } @@ -327,12 +334,12 @@ pub fn parse<'source, W: Wr>( }; } macro_rules! err { - ($e:ident($($stuff:expr)+)) => { + ($e:ident($($stuff:expr),+)) => { Error::$e($($stuff,)+ tokens.span()) } } macro_rules! yeet { - ($e:ident($($stuff:expr)+)) => { + ($e:ident($($stuff:expr),+)) => { return Err(Error::$e($($stuff,)+ tokens.span())) }; } @@ -499,7 +506,15 @@ pub fn parse<'source, W: Wr>( Token::Write => { let set = take_numvar!(tok!()?)?; let container = take_memory!(); - let index = container.limit(take_int!(tok!()?)?); + let index = take_numvar!(tok!()?)?; + match index { + LAddress::Const(LVar::Num(v)) => { + if !container.fits(v.round() as usize) { + yeet!(IndexOutOfBounds(v.round() as usize, container.size())); + } + } + _ => {} + } executor.add(Write { index, @@ -511,7 +526,15 @@ pub fn parse<'source, W: Wr>( Token::Read => { let output = take_var!(tok!()?)?; let container = take_memory!(); - let index = container.limit(take_int!(tok!()?)?); + let index = take_numvar!(tok!()?)?; + match index { + LAddress::Const(LVar::Num(v)) => { + if !container.fits(v.round() as usize) { + yeet!(IndexOutOfBounds(v.round() as usize, container.size())); + } + } + _ => {} + } executor.add(Read { index, output, |