diff options
author | Freya Murphy <freya@freyacat.org> | 2024-02-29 17:04:28 -0500 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-02-29 17:04:28 -0500 |
commit | 5d2747e26f51cc2344a6bd95f93457248fdfebd8 (patch) | |
tree | 8755b4068166c3854d26817683ce438a771ab319 /matrix-lang/src/parse.rs | |
parent | more mat, sys, and os stdlib functions, better matrix printing, other fixes (diff) | |
download | matrix-5d2747e26f51cc2344a6bd95f93457248fdfebd8.tar.gz matrix-5d2747e26f51cc2344a6bd95f93457248fdfebd8.tar.bz2 matrix-5d2747e26f51cc2344a6bd95f93457248fdfebd8.zip |
fin prob
Diffstat (limited to '')
-rw-r--r-- | matrix-lang/src/parse.rs (renamed from matrix/src/parse.rs) | 94 |
1 files changed, 38 insertions, 56 deletions
diff --git a/matrix/src/parse.rs b/matrix-lang/src/parse.rs index d967130..3a4c5f2 100644 --- a/matrix/src/parse.rs +++ b/matrix-lang/src/parse.rs @@ -1,6 +1,4 @@ -use std::{fmt::Display, rc::Rc}; -use num_complex::Complex64; -use crate::{lex::{Lexer, self, Token, TokenData, Position}, ast::{Expr, BinaryOp, UnaryOp, optimize, ExprData, AstName}, value::{Value, self}, Result}; +use crate::prelude::*; use Value as V; use ExprData as E; @@ -33,38 +31,6 @@ pub struct Parser { optimize: bool } -#[derive(Debug)] -pub enum Error { - LexerError(crate::lex::Error), - UnexpectedToken(Token), - ExpectedToken(TokenData, Position), - MatrixInvDomain(usize, usize, usize), - NotAssignable(Expr), - ValueError(value::Error), -} - -impl Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use Error::*; - match self { - LexerError(err) => write!(f, "{err}"), - UnexpectedToken(tok) => write!(f, "Unexpected token: '{:?}' at {}:{}", tok.data, tok.pos.row, tok.pos.col), - ExpectedToken(tok, pos) => write!(f, "Expected token: '{tok:?}' at {}:{}", pos.row, pos.col), - MatrixInvDomain(row, should, was) => write!(f, "In row {row} of matrix, domain was expected to be {should} but was given {was}"), - NotAssignable(expr) => write!(f, "{expr:?} is not assignable"), - ValueError(err) => write!(f, "{err}"), - } - } -} - -impl From<lex::Error> for Error { - fn from(value: lex::Error) -> Self { - Self::LexerError(value) - } -} - -impl std::error::Error for Error {} - macro_rules! expr_parser { ($parser:ident, $pattern:pat, $fn:ident) => {{ let mut expr = $parser.$fn()?; @@ -99,12 +65,18 @@ macro_rules! expr_parser_reverse { }}; } +macro_rules! error { + ($($arg:tt)*) => { + exception!(PARSE_EXCEPTION, $($arg)*) + }; +} + impl Parser { fn force_token(&mut self, tok: TokenData) -> Result<TokenData> { let next = self.lexer.next_token()?; if next.data != tok { - Err(Error::ExpectedToken(tok, next.pos).into()) + Err(error!("expected token '{tok}'").pos(next.pos)) } else { Ok(tok) } @@ -113,7 +85,7 @@ impl Parser { fn force_token_nl(&mut self, tok: TokenData) -> Result<TokenData> { let next = self.lexer.next_token_nl()?; if next.data != tok { - Err(Error::ExpectedToken(tok, next.pos).into()) + Err(error!("expected token '{tok}'").pos(next.pos)) } else { Ok(tok) } @@ -135,7 +107,7 @@ impl Parser { match next.data { T::Comma => continue, T::RightParen => break, - _ => return Err(Error::UnexpectedToken(next).into()) + _ => return Err(error!("unexpected token '{next}'").pos(next.pos)) }; } Ok(params) @@ -157,7 +129,7 @@ impl Parser { match next.data { T::SemiColon => continue, T::RightBrack => break, - _ => return Err(Error::UnexpectedToken(next).into()) + _ => return Err(error!("unexpected token '{next}'").pos(next.pos)) }; } Ok(indicies) @@ -193,7 +165,7 @@ impl Parser { match next.data { T::SemiColon => continue, T::RightBrack => break, - _ => return Err(Error::UnexpectedToken(next).into()), + _ => return Err(error!("unexpected token '{next}'").pos(next.pos)) }; } if parts.len() == 1 { @@ -201,9 +173,9 @@ impl Parser { } else { let codomain = parts.len(); let domain = parts[0].len(); - for (i, part) in parts.iter().enumerate() { + for part in parts.iter() { if part.len() != domain { - return Err(Error::MatrixInvDomain(i, domain, part.len()).into()) + return Err(error!("matrix row domains do not match: {} != {}", domain, part.len()).pos(pos)) } } let mut data = Vec::new(); @@ -225,7 +197,7 @@ impl Parser { }, T::Ident(ident) => (E::Literal(V::String(ident.to_string().into())), tok.pos).into(), T::String(string) => (E::Literal(V::String(string.to_string().into())), tok.pos).into(), - _ => return Err(Error::UnexpectedToken(tok).into()) + t => return Err(error!("unexpected token '{t}'").pos(tok.pos)) }) } @@ -247,7 +219,7 @@ impl Parser { match next.data { T::Comma => continue, T::RightBrace => break, - _ => return Err(Error::UnexpectedToken(next).into()) + _ => return Err(error!("unexpected token '{next}'").pos(next.pos)) } } Ok((E::Table(table), pos).into()) @@ -273,7 +245,7 @@ impl Parser { } } T::LeftParen => (), - _ => return Err(Error::UnexpectedToken(tok).into()), + t => return Err(error!("unexpected token '{t}'").pos(tok.pos)) } let mut params = Vec::new(); @@ -295,7 +267,7 @@ impl Parser { } T::Comma => continue, T::RightParen => break, - _ => return Err(Error::UnexpectedToken(next).into()), + _ => return Err(error!("unexpected token '{next}'").pos(next.pos)) } } @@ -307,7 +279,7 @@ impl Parser { if let T::Ident(ident) = next.data { Ok((ident, next.pos)) } else { - Err(Error::UnexpectedToken(next).into()) + Err(error!("unexpected token '{next}'").pos(next.pos)) } } @@ -327,7 +299,7 @@ impl Parser { if let T::Ident(ident) = next.data { Ok((ident, next.pos)) } else { - Err(Error::UnexpectedToken(next).into()) + Err(error!("unexpected token '{next}'").pos(next.pos)) } } @@ -419,6 +391,15 @@ impl Parser { } } + fn parse_const(&mut self) -> Result<Expr> { + let pos = self.lexer.peek_token()?.pos; + self.force_token(T::Const)?; + let ident = self.parse_ident_nl()?; + self.force_token(T::Assign)?; + let expr = self.parse_expr()?; + Ok((E::Const(ident, Box::new(expr)), pos).into()) + } + fn parse_return(&mut self) -> Result<Expr> { let pos = self.lexer.peek_token()?.pos; self.force_token(T::Return)?; @@ -431,7 +412,10 @@ impl Parser { self.force_token(T::LeftBrace)?; loop { let expr = match self.lexer.peek_token()?.data { - T::RightBrace => break, + T::RightBrace => { + self.lexer.next_token()?; + break + }, T::SemiColon => { self.lexer.next_token()?; continue; @@ -443,12 +427,9 @@ impl Parser { match next.data { T::SemiColon => continue, T::RightBrace => break, - _ => return Err(Error::ExpectedToken(T::SemiColon, next.pos).into()) + _ => return Err(error!("expected a semicolon").pos(next.pos)) } } - if self.lexer.peek_token()?.data == T::RightBrace { - self.lexer.next_token()?; - } Ok((E::Block(block), pos).into()) } @@ -474,7 +455,7 @@ impl Parser { T::True => E::Literal(V::Bool(true)), T::False => E::Literal(V::Bool(false)), T::Ident(ident) => E::Ident(ident), - _ => return Err(Error::UnexpectedToken(tok).into()), + t => return Err(error!("unexpected token '{t}'").pos(tok.pos)) }; Ok((data, tok.pos).into()) } @@ -488,6 +469,7 @@ impl Parser { While => self.parse_while(), For => self.parse_for(), Let => self.parse_let(), + Const => self.parse_const(), LeftBrace => self.parse_block(), Return => self.parse_return(), If => self.parse_if(), @@ -752,11 +734,11 @@ impl Parser { }; let expr = self.parse_expr()?; block.push(expr); - let next = self.lexer.next_token()?; + let next = self.lexer.next_token_nl()?; match next.data { T::Eof => break, T::SemiColon => continue, - _ => return Err(Error::ExpectedToken(T::SemiColon, next.pos).into()) + _ => return Err(error!("expected a semicolon").pos(next.pos)) }; } Ok((E::Block(block), Position::default()).into()) |