summaryrefslogtreecommitdiff
path: root/matrix-lang/src/parse.rs
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-02-29 17:04:28 -0500
committerFreya Murphy <freya@freyacat.org>2024-02-29 17:04:28 -0500
commit5d2747e26f51cc2344a6bd95f93457248fdfebd8 (patch)
tree8755b4068166c3854d26817683ce438a771ab319 /matrix-lang/src/parse.rs
parentmore mat, sys, and os stdlib functions, better matrix printing, other fixes (diff)
downloadmatrix-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())