iowo/crates/lang/src/parser/grammar/expression/collection/matrix.rs

70 lines
1.9 KiB
Rust
Raw Normal View History

2024-04-24 19:37:52 +02:00
use crate::parser::{
error::SyntaxError,
grammar::expression::{self, expression},
syntax_kind::SyntaxKind::*,
CompletedMarker, Marker, Parser,
};
pub fn matrix(p: &mut Parser) -> CompletedMarker {
2024-04-24 19:55:16 +02:00
let matrix = p.start("matrix");
2024-04-24 19:37:52 +02:00
p.eat(MAT_KW);
if !p.eat(PAT_DIMENSIONS) {
eprintln!("TODO (as eprintln so i dont forget): improve recovery algorithms");
return matrix.complete_err(p, SyntaxError::Expected(vec![PAT_DIMENSIONS]));
}
matrix_body(p);
matrix.complete(p, MATRIX)
}
fn matrix_body(p: &mut Parser) {
2024-04-24 19:55:16 +02:00
let mat_body = p.start("mat_body");
2024-04-24 19:37:52 +02:00
if !p.eat(L_BRACK) {
mat_body.complete_err(p, SyntaxError::Expected(vec![MAT_BODY]));
return ();
}
let mut going = true;
2024-04-24 19:55:16 +02:00
let mut mat_row = p.start("mat_row");
2024-04-24 19:37:52 +02:00
let mut row_items = 0;
while going {
2024-04-24 19:55:16 +02:00
let mat_item = p.start("mat_item");
2024-04-24 19:37:52 +02:00
if expression(p).is_some() {
mat_item.complete(p, MAT_ITEM);
row_items += 1;
match p.current() {
COMMA => p.do_bump(),
SEMICOLON => {
mat_row.complete(p, MAT_ROW);
2024-04-24 19:55:16 +02:00
mat_row = p.start("mat_row");
2024-04-24 19:37:52 +02:00
p.do_bump();
row_items = 0;
}
R_BRACK => going = false,
_ => {
2024-04-24 19:55:16 +02:00
let err = p.start("err");
2024-04-24 19:37:52 +02:00
p.do_bump();
err.complete_err(p, SyntaxError::Expected(vec![COMMA, SEMICOLON, R_BRACK]));
}
};
} else if p.at(R_BRACK) {
going = false;
} else {
2024-04-24 19:55:16 +02:00
let err = p.start("err");
2024-04-24 19:37:52 +02:00
p.do_bump();
err.complete_err(p, SyntaxError::Expected(vec![EXPR, R_BRACK]));
}
}
if row_items != 0 {
mat_row.complete(p, MAT_ROW);
} else {
mat_row.abandon(p);
}
p.eat(R_BRACK);
mat_body.complete(p, MAT_BODY);
}