Skip to content

Commit

Permalink
parse: Equation invocations
Browse files Browse the repository at this point in the history
These are things like `Y1(1`
  • Loading branch information
rpitasky committed Nov 28, 2024
1 parent 9193176 commit af174cc
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 8 deletions.
Binary file added test-files/programs/basic_note/BNOTECE.8xp
Binary file not shown.
Binary file added test-files/programs/basic_note/BNOTECE2.8xp
Binary file not shown.
47 changes: 47 additions & 0 deletions ti-basic-optimizer/src/parse/components/data_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -179,3 +181,48 @@ impl Reconstruct for ListIndex {
data
}
}

#[derive(Clone, Debug)]
pub struct EquationIndex {
pub subject: EquationName,
pub index: Box<Expression>,
}

impl EquationIndex {
pub fn parse(
subject: EquationName,
token: Token,
more: &mut Tokens,
) -> Result<Option<Self>, 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<Token> {
let mut data = self.subject.reconstruct(config);
data.push(Token::OneByte(0x10));
data.extend(self.index.reconstruct(config));
data.push(Token::OneByte(0x11));

data
}
}
24 changes: 21 additions & 3 deletions ti-basic-optimizer/src/parse/components/mod.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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))
Expand All @@ -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)],
Expand Down
11 changes: 6 additions & 5 deletions ti-basic-optimizer/src/parse/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
))?
}
}

Expand Down

0 comments on commit af174cc

Please sign in to comment.