diff --git a/test-files/programs/basic_note/BNOTECE.8xp b/test-files/programs/basic_note/BNOTECE.8xp new file mode 100644 index 0000000..11fbaf2 Binary files /dev/null and b/test-files/programs/basic_note/BNOTECE.8xp differ diff --git a/test-files/programs/basic_note/BNOTECE2.8xp b/test-files/programs/basic_note/BNOTECE2.8xp new file mode 100644 index 0000000..84fd065 Binary files /dev/null and b/test-files/programs/basic_note/BNOTECE2.8xp differ diff --git a/ti-basic-optimizer/src/parse/components/data_access.rs b/ti-basic-optimizer/src/parse/components/data_access.rs index 179e640..d60f030 100644 --- a/ti-basic-optimizer/src/parse/components/data_access.rs +++ b/ti-basic-optimizer/src/parse/components/data_access.rs @@ -7,6 +7,8 @@ use crate::parse::{ use crate::Config; use titokens::{Token, Tokens}; +use super::EquationName; + #[derive(Debug, Clone)] pub enum ListIndexable { List(ListName), @@ -179,3 +181,48 @@ impl Reconstruct for ListIndex { data } } + +#[derive(Clone, Debug)] +pub struct EquationIndex { + pub subject: EquationName, + pub index: Box, +} + +impl EquationIndex { + pub fn parse( + subject: EquationName, + token: Token, + more: &mut Tokens, + ) -> Result, TokenReport> { + if token != Token::OneByte(0x10) { + return Ok(None); + } + + let index = expect_some!( + Expression::parse(next_or_err!(more)?, more)?, + more, + "an expression", + "This is a equation invocation and equation invocations require an index." + )?; + + if more.peek() == Some(Token::OneByte(0x11)) { + more.next(); + } + + Ok(Some(EquationIndex { + subject, + index: Box::new(index), + })) + } +} + +impl Reconstruct for EquationIndex { + fn reconstruct(&self, config: &Config) -> Vec { + let mut data = self.subject.reconstruct(config); + data.push(Token::OneByte(0x10)); + data.extend(self.index.reconstruct(config)); + data.push(Token::OneByte(0x11)); + + data + } +} diff --git a/ti-basic-optimizer/src/parse/components/mod.rs b/ti-basic-optimizer/src/parse/components/mod.rs index 18d4f6f..2715cad 100644 --- a/ti-basic-optimizer/src/parse/components/mod.rs +++ b/ti-basic-optimizer/src/parse/components/mod.rs @@ -1,7 +1,7 @@ use crate::error_reporting::TokenReport; pub use crate::parse::components::{ binary_operator::BinOp, - data_access::{ListIndex, ListIndexable, MatrixIndex, MatrixIndexable}, + data_access::{EquationIndex, ListIndex, ListIndexable, MatrixIndex, MatrixIndexable}, delvar_target::DelVarTarget, equation_name::EquationName, function_call::FunctionCall, @@ -73,9 +73,11 @@ pub enum Operand { NumericVarName(NumericVarName), ListName(ListName), MatrixName(MatrixName), + StringName(StringName), + EquationName(EquationName), ListAccess(ListIndex), MatrixAccess(MatrixIndex), - StringName(StringName), + EquationAccess(EquationIndex), Ans, I, GetKey, @@ -132,6 +134,20 @@ impl Parse for Operand { Ok(None) } } + Token::TwoByte(0x5E, 0x10..=0x2B | 0x40..=0x45 | 0x80..=0x82) => { + if let Some(name) = EquationName::parse(token, more)? { + if more.peek() == Some(Token::OneByte(0x10)) { + Ok( + EquationIndex::parse(name, more.next().unwrap(), more)? + .map(Self::EquationAccess), + ) + } else { + Ok(Some(Self::EquationName(name))) + } + } else { + Ok(None) + } + } Token::TwoByte(0x63, 0x2A) => Ok(Some(Self::TblInput)), // todo: TblIndex(n) list access Token::TwoByte(0x63, 0x00..=0x2A | 0x32..=0x38) => { Ok(WindowVarName::parse(token, more)?.map(Self::WindowVarName)) @@ -147,9 +163,11 @@ impl Reconstruct for Operand { Operand::NumericVarName(x) => x.reconstruct(config), Operand::ListName(x) => x.reconstruct(config), Operand::MatrixName(x) => x.reconstruct(config), + Operand::StringName(x) => x.reconstruct(config), + Operand::EquationName(x) => x.reconstruct(config), Operand::ListAccess(x) => x.reconstruct(config), Operand::MatrixAccess(x) => x.reconstruct(config), - Operand::StringName(x) => x.reconstruct(config), + Operand::EquationAccess(x) => x.reconstruct(config), Operand::Ans => vec![Token::OneByte(0x72)], Operand::I => vec![Token::OneByte(0x2C)], Operand::GetKey => vec![Token::OneByte(0xAD)], diff --git a/ti-basic-optimizer/src/parse/expression.rs b/ti-basic-optimizer/src/parse/expression.rs index 8768a7c..6878e1b 100644 --- a/ti-basic-optimizer/src/parse/expression.rs +++ b/ti-basic-optimizer/src/parse/expression.rs @@ -120,11 +120,12 @@ impl<'a> Builder<'a> { if let Some(Token::OneByte(0x10)) = self.tokens.peek() { // ( - match &operand { - Operand::Ans => { - unimplemented!() - } - _ => {} + if let Operand::Ans = &operand { + Err(TokenReport::new( + self.tokens.current_position(), + "Unsupported Ans( operation", + None, + ))? } }