Skip to content

Commit

Permalink
parse: rand, rand(
Browse files Browse the repository at this point in the history
  • Loading branch information
rpitasky committed Dec 1, 2024
1 parent a24b84d commit 1fcd9f4
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 12 deletions.
31 changes: 19 additions & 12 deletions ti-basic-optimizer/src/parse/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub use crate::parse::components::{
matrix_name::MatrixName,
numeric_var_name::NumericVarName,
pic_image_name::{ImageName, PicName},
rand::Rand,
store_target::StoreTarget,
string::TIString,
string_name::StringName,
Expand All @@ -32,6 +33,7 @@ mod matrix_name;
mod numeric_literal;
mod numeric_var_name;
mod pic_image_name;
mod rand;
mod store_target;
mod string;
mod string_name;
Expand Down Expand Up @@ -80,6 +82,7 @@ pub enum Operand {
EquationAccess(EquationIndex),
Ans,
I,
Rand(Rand),
GetKey,
GetDate,
StartTmr,
Expand All @@ -101,22 +104,26 @@ impl Parse for Operand {
Token::OneByte(0x41..=0x5B) | Token::TwoByte(0x62, 0x21) => {
Ok(NumericVarName::parse(token, more)?.map(Self::NumericVarName))
}
Token::OneByte(0x72) => Ok(Some(Self::Ans)),
Token::OneByte(0x72) => {
if more.peek() == Some(Token::OneByte(0x10)) { // (
if more.peek() == Some(Token::OneByte(0x10)) {
// (
more.next();
// conservatively guess that this is a list or matrix access- we can maybe demote it to a muliplication later
let index = expect_some!(Expression::parse(next_or_err!(more)?, more)?, more, "an expression")?;
let index = expect_some!(
Expression::parse(next_or_err!(more)?, more)?,
more,
"an expression"
)?;

match more.peek() {
Some(Token ::OneByte(0x2B)) => {
Some(Token::OneByte(0x2B)) => {
// , -> matrix access
todo!()
},
}
Some(Token::OneByte(0x11)) => {
// )
more.next();
},
}

_ => {}
};
Expand All @@ -128,14 +135,15 @@ impl Parse for Operand {
} else {
Ok(Some(Self::Ans))
}
},
}
Token::OneByte(0x2C) => Ok(Some(Self::I)),
Token::OneByte(0xAB) => Ok(Rand::parse(token, more)?.map(Self::Rand)),
Token::OneByte(0xAD) => Ok(Some(Self::GetKey)),
Token::TwoByte(0xEF, 0x09) => Ok(Some(Self::GetDate)),
Token::TwoByte(0xEF, 0x0B) => Ok(Some(Self::StartTmr)),
Token::OneByte(0x2A) => Ok(TIString::parse(token, more)?.map(Self::StringLiteral)),
Token::OneByte(0x08) => Ok(TIList::parse(token, more)?.map(Self::ListLiteral)),

Token::OneByte(0x06) => Ok(TIMatrix::parse(token, more)?.map(Self::MatrixLiteral)),
Token::TwoByte(0xAA, _) => Ok(StringName::parse(token, more)?.map(Self::StringName)),
Token::TwoByte(0x5C, _) => {
if let Some(name) = MatrixName::parse(token, more)? {
Expand Down Expand Up @@ -164,10 +172,8 @@ impl Parse for Operand {
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),
)
Ok(EquationIndex::parse(name, more.next().unwrap(), more)?
.map(Self::EquationAccess))
} else {
Ok(Some(Self::EquationName(name)))
}
Expand Down Expand Up @@ -197,6 +203,7 @@ impl Reconstruct for Operand {
Operand::EquationAccess(x) => x.reconstruct(config),
Operand::Ans => vec![Token::OneByte(0x72)],
Operand::I => vec![Token::OneByte(0x2C)],
Operand::Rand(x) => x.reconstruct(config),
Operand::GetKey => vec![Token::OneByte(0xAD)],
Operand::GetDate => vec![Token::TwoByte(0xEF, 0x09)],
Operand::StartTmr => vec![Token::TwoByte(0xEF, 0x0B)],
Expand Down
69 changes: 69 additions & 0 deletions ti-basic-optimizer/src/parse/components/rand.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::iter;

use titokens::{Token, Tokens};

use crate::{
error_reporting::TokenReport,
parse::{
expression::Expression,
Parse,
},
};

use super::{expect_some, next_or_err, Reconstruct};

#[derive(Clone, Debug)]
pub struct Rand {
pub count: Option<Box<Expression>>,
}

impl Rand {
pub fn is_list(&self) -> bool {
self.count.is_some()
}
}

impl Parse for Rand {
fn parse(token: Token, more: &mut Tokens) -> Result<Option<Self>, TokenReport> {
if token != Token::OneByte(0xAB) {
return Ok(None);
}

if more.peek() == Some(Token::OneByte(0x10)){
more.next();
let result = expect_some!(
Expression::parse(
next_or_err!(more, "Unexpected end of input: expected an expression.")?,
more
)?,
more,
"an expression"
)
.map(|x| {
Some(Rand {
count: Some(Box::new(x)),
})
});

if more.peek() == Some(Token::OneByte(0x11)) {
more.next();
}

result
} else {
Ok(Some(Rand { count: None }))
}
}
}

impl Reconstruct for Rand {
fn reconstruct(&self, config: &crate::Config) -> Vec<Token> {
if let Some(count) = &self.count {
let inner = count.reconstruct(config);

vec![Token::OneByte(0xAB), Token::OneByte(0x10)].into_iter().chain(inner).chain(iter::once(Token::OneByte(0x11))).collect::<Vec<_>>()
} else {
vec![Token::OneByte(0xAB)]
}
}
}

0 comments on commit 1fcd9f4

Please sign in to comment.