mirror of
https://forge.katzen.cafe/katzen-cafe/iowo.git
synced 2024-11-21 21:24:41 +01:00
lang: implement vec, list and matrix
This commit is contained in:
parent
8a541546d9
commit
9af71ed3f4
|
@ -5,13 +5,12 @@ use crate::parser::{
|
||||||
CompletedMarker, Parser,
|
CompletedMarker, Parser,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::{attr_set::attr_set, matrix::matrix, vec::vec};
|
use self::{attr_set::attr_set, vec::vec_matrix_list};
|
||||||
|
|
||||||
mod attr_set;
|
mod attr_set;
|
||||||
mod matrix;
|
|
||||||
mod vec;
|
mod vec;
|
||||||
|
|
||||||
const COLLECTION_START: TokenSet = enum_set!(MAT_KW | L_BRACK | L_BRACE);
|
const COLLECTION_START: TokenSet = enum_set!(L_BRACK | L_BRACE);
|
||||||
|
|
||||||
pub fn collection(p: &mut Parser) -> Option<CompletedMarker> {
|
pub fn collection(p: &mut Parser) -> Option<CompletedMarker> {
|
||||||
if !COLLECTION_START.contains(p.current()) {
|
if !COLLECTION_START.contains(p.current()) {
|
||||||
|
@ -19,8 +18,7 @@ pub fn collection(p: &mut Parser) -> Option<CompletedMarker> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(match p.current() {
|
Some(match p.current() {
|
||||||
MAT_KW => matrix(p),
|
L_BRACK => vec_matrix_list(p),
|
||||||
L_BRACK => vec(p),
|
|
||||||
L_BRACE => attr_set(p),
|
L_BRACE => attr_set(p),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
use crate::parser::{
|
|
||||||
error::SyntaxError,
|
|
||||||
grammar::expression::{self, expression},
|
|
||||||
syntax_kind::SyntaxKind::*,
|
|
||||||
CompletedMarker, Marker, Parser,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn matrix(p: &mut Parser) -> CompletedMarker {
|
|
||||||
let matrix = p.start("matrix");
|
|
||||||
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) {
|
|
||||||
let mat_body = p.start("mat_body");
|
|
||||||
if !p.eat(L_BRACK) {
|
|
||||||
mat_body.complete_err(p, SyntaxError::Expected(vec![MAT_BODY]));
|
|
||||||
return ();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut going = true;
|
|
||||||
|
|
||||||
let mut mat_row = p.start("mat_row");
|
|
||||||
let mut row_items = 0;
|
|
||||||
while going {
|
|
||||||
let mat_item = p.start("mat_item");
|
|
||||||
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);
|
|
||||||
mat_row = p.start("mat_row");
|
|
||||||
p.do_bump();
|
|
||||||
row_items = 0;
|
|
||||||
}
|
|
||||||
R_BRACK => going = false,
|
|
||||||
_ => {
|
|
||||||
let err = p.start("err");
|
|
||||||
p.do_bump();
|
|
||||||
|
|
||||||
err.complete_err(p, SyntaxError::Expected(vec![COMMA, SEMICOLON, R_BRACK]));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else if p.at(R_BRACK) {
|
|
||||||
mat_item.abandon(p);
|
|
||||||
going = false;
|
|
||||||
} else {
|
|
||||||
mat_item.abandon(p);
|
|
||||||
let err = p.start("err");
|
|
||||||
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);
|
|
||||||
}
|
|
|
@ -1,5 +1,70 @@
|
||||||
use crate::parser::{CompletedMarker, Parser};
|
use crate::parser::{
|
||||||
|
error::SyntaxError, grammar::expression::atom, CompletedMarker, Marker, Parser, SyntaxKind::*,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn vec(p: &mut Parser) -> CompletedMarker {
|
pub fn vec_matrix_list(p: &mut Parser) -> CompletedMarker {
|
||||||
todo!()
|
let start = p.start("vec_matrix_list_start");
|
||||||
|
assert!(p.eat(L_BRACK));
|
||||||
|
let row_start = p.start("matrix_row_start");
|
||||||
|
if let Some(item) = atom(p) {
|
||||||
|
item.precede(p).complete(p, COLLECTION_ITEM);
|
||||||
|
|
||||||
|
if p.at(COMMA) {
|
||||||
|
row_start.abandon(p);
|
||||||
|
return finish_list(p, start);
|
||||||
|
}
|
||||||
|
|
||||||
|
finish_mat_or_vec(p, start, row_start)
|
||||||
|
} else if p.eat(R_BRACK) {
|
||||||
|
start.complete(p, LIST)
|
||||||
|
} else {
|
||||||
|
start.complete_err(p, SyntaxError::Expected(vec![EXPR, R_BRACK]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: handle semicolons, other wrong toks
|
||||||
|
fn finish_list(p: &mut Parser, list_start: Marker) -> CompletedMarker {
|
||||||
|
loop {
|
||||||
|
if p.eat(COMMA) {
|
||||||
|
if let Some(item) = atom(p) {
|
||||||
|
item.precede(p).complete(p, COLLECTION_ITEM);
|
||||||
|
} else if p.eat(R_BRACK) {
|
||||||
|
return list_start.complete(p, LIST);
|
||||||
|
}
|
||||||
|
} else if p.eat(R_BRACK) {
|
||||||
|
return list_start.complete(p, LIST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: handle commas, general other wrong toks
|
||||||
|
fn finish_mat_or_vec(p: &mut Parser, coll_start: Marker, mut row_start: Marker) -> CompletedMarker {
|
||||||
|
let mut is_matrix = false;
|
||||||
|
let mut row_item_count = 1;
|
||||||
|
loop {
|
||||||
|
if let Some(item) = atom(p) {
|
||||||
|
item.precede(p).complete(p, COLLECTION_ITEM);
|
||||||
|
row_item_count += 1;
|
||||||
|
} else if p.at(SEMICOLON) {
|
||||||
|
is_matrix = true;
|
||||||
|
row_start.complete(p, MAT_ROW);
|
||||||
|
p.eat(SEMICOLON);
|
||||||
|
row_start = p.start("matrix_row_start");
|
||||||
|
row_item_count = 0;
|
||||||
|
} else if p.at(R_BRACK) {
|
||||||
|
if is_matrix && row_item_count == 0 {
|
||||||
|
row_start.abandon(p);
|
||||||
|
p.eat(R_BRACK);
|
||||||
|
return coll_start.complete(p, MATRIX);
|
||||||
|
} else if is_matrix {
|
||||||
|
row_start.complete(p, MAT_ROW);
|
||||||
|
p.eat(R_BRACK);
|
||||||
|
return coll_start.complete(p, MATRIX);
|
||||||
|
} else {
|
||||||
|
row_start.abandon(p);
|
||||||
|
p.eat(R_BRACK);
|
||||||
|
return coll_start.complete(p, VEC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::parser::{syntax_kind::SyntaxKind::*, CompletedMarker, Parser};
|
use crate::parser::{syntax_kind::SyntaxKind::*, CompletedMarker, Parser};
|
||||||
|
|
||||||
use super::lit::literal;
|
use super::{atom, lit::literal};
|
||||||
|
|
||||||
pub fn instr(p: &mut Parser) -> Option<CompletedMarker> {
|
pub fn instr(p: &mut Parser) -> Option<CompletedMarker> {
|
||||||
if !p.at(IDENT) {
|
if !p.at(IDENT) {
|
||||||
|
@ -26,8 +26,8 @@ fn instr_name(p: &mut Parser) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn instr_params(p: &mut Parser) {
|
fn instr_params(p: &mut Parser) {
|
||||||
if let Some(start) = literal(p) {
|
if let Some(start) = atom(p) {
|
||||||
while literal(p).is_some() {}
|
while atom(p).is_some() {}
|
||||||
|
|
||||||
start.precede(p).complete(p, INSTR_PARAMS);
|
start.precede(p).complete(p, INSTR_PARAMS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,6 @@ pub enum SyntaxKind {
|
||||||
LET_KW,
|
LET_KW,
|
||||||
#[token("in")]
|
#[token("in")]
|
||||||
IN_KW,
|
IN_KW,
|
||||||
#[token("mat")]
|
|
||||||
MAT_KW,
|
|
||||||
#[regex("[\\d]+x[\\d]+")]
|
|
||||||
PAT_DIMENSIONS,
|
|
||||||
#[regex("[\\d]+")]
|
#[regex("[\\d]+")]
|
||||||
INT_NUM,
|
INT_NUM,
|
||||||
#[regex("[+-]?([\\d]+\\.[\\d]*|[\\d]*\\.[\\d]+)")]
|
#[regex("[+-]?([\\d]+\\.[\\d]*|[\\d]*\\.[\\d]+)")]
|
||||||
|
@ -34,11 +30,12 @@ pub enum SyntaxKind {
|
||||||
#[regex(r#""([^"\\]|\\["\\bnfrt]|u[a-fA-F0-9]{4})*""#)]
|
#[regex(r#""([^"\\]|\\["\\bnfrt]|u[a-fA-F0-9]{4})*""#)]
|
||||||
STRING,
|
STRING,
|
||||||
MATRIX,
|
MATRIX,
|
||||||
MAT_BODY,
|
|
||||||
MAT_ROW,
|
MAT_ROW,
|
||||||
MAT_ITEM,
|
VEC,
|
||||||
DECL,
|
|
||||||
LIST,
|
LIST,
|
||||||
|
// either of a vec, a matrix or a list
|
||||||
|
COLLECTION_ITEM,
|
||||||
|
DECL,
|
||||||
PARENTHESIZED_EXPR,
|
PARENTHESIZED_EXPR,
|
||||||
EXPR,
|
EXPR,
|
||||||
LITERAL,
|
LITERAL,
|
||||||
|
|
Loading…
Reference in a new issue