forked from katzen-cafe/iowo
Compare commits
No commits in common. "2bea3994c29c9802eef50b166963f4aad15a46a0" and "06c9094227d477ea18556074ef37e6339e4c51c6" have entirely different histories.
2bea3994c2
...
06c9094227
7 changed files with 18 additions and 144 deletions
|
@ -94,7 +94,6 @@ impl Marker {
|
||||||
bomb: DropBomb::new("Marker must be completed or abandoned"),
|
bomb: DropBomb::new("Marker must be completed or abandoned"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn complete(mut self, p: &mut Parser<'_, '_>, kind: SyntaxKind) -> CompletedMarker {
|
pub(crate) fn complete(mut self, p: &mut Parser<'_, '_>, kind: SyntaxKind) -> CompletedMarker {
|
||||||
self.bomb.defuse();
|
self.bomb.defuse();
|
||||||
match &mut p.events[self.pos] {
|
match &mut p.events[self.pos] {
|
||||||
|
@ -109,11 +108,6 @@ impl Marker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn complete_err(mut self, p: &mut Parser, kind: SyntaxError) -> CompletedMarker {
|
|
||||||
p.errors.push(kind);
|
|
||||||
self.complete(p, SyntaxKind::PARSE_ERR)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn abandon(mut self, p: &mut Parser<'_, '_>) {
|
pub(crate) fn abandon(mut self, p: &mut Parser<'_, '_>) {
|
||||||
self.bomb.defuse();
|
self.bomb.defuse();
|
||||||
if self.pos == p.events.len() - 1 {
|
if self.pos == p.events.len() - 1 {
|
||||||
|
|
|
@ -1,62 +1,14 @@
|
||||||
use crate::parser::{syntax_kind::SyntaxKind::*, CompletedMarker, Parser};
|
use crate::parser::{syntax_kind::SyntaxKind::*, Parser};
|
||||||
|
|
||||||
use self::{collection::collection, instruction::instr, lit::literal};
|
use self::{instruction::instr, lit::literal};
|
||||||
|
|
||||||
mod instruction;
|
mod instruction;
|
||||||
mod lit;
|
mod lit;
|
||||||
mod collection {
|
|
||||||
use enumset::enum_set;
|
|
||||||
|
|
||||||
use crate::parser::{
|
pub fn expression(p: &mut Parser) {
|
||||||
syntax_kind::{SyntaxKind::*, TokenSet},
|
|
||||||
CompletedMarker, Parser,
|
|
||||||
};
|
|
||||||
|
|
||||||
use self::{attr_set::attr_set, matrix::matrix, vec::vec};
|
|
||||||
|
|
||||||
const COLLECTION_START: TokenSet = enum_set!(MAT_KW | L_BRACK | L_BRACE);
|
|
||||||
|
|
||||||
pub fn collection(p: &mut Parser) -> Option<CompletedMarker> {
|
|
||||||
if !COLLECTION_START.contains(p.current()) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(match p.current() {
|
|
||||||
MAT_KW => matrix(p),
|
|
||||||
L_BRACK => vec(p),
|
|
||||||
L_BRACE => attr_set(p),
|
|
||||||
_ => unreachable!(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
mod matrix;
|
|
||||||
mod vec {
|
|
||||||
use crate::parser::{CompletedMarker, Parser};
|
|
||||||
|
|
||||||
pub fn vec(p: &mut Parser) -> CompletedMarker {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mod attr_set {
|
|
||||||
use crate::parser::{CompletedMarker, Parser};
|
|
||||||
|
|
||||||
pub fn attr_set(p: &mut Parser) -> CompletedMarker {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn expression(p: &mut Parser) -> Option<CompletedMarker> {
|
|
||||||
let expr = p.start();
|
let expr = p.start();
|
||||||
|
|
||||||
if atom(p).or_else(|| instr(p)).is_none() {
|
instr(p);
|
||||||
expr.abandon(p);
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(expr.complete(p, EXPR))
|
expr.complete(p, EXPR);
|
||||||
}
|
|
||||||
|
|
||||||
pub fn atom(p: &mut Parser) -> Option<CompletedMarker> {
|
|
||||||
literal(p).or_else(|| collection(p))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,69 +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();
|
|
||||||
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();
|
|
||||||
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();
|
|
||||||
let mut row_items = 0;
|
|
||||||
while going {
|
|
||||||
let mat_item = p.start();
|
|
||||||
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();
|
|
||||||
p.do_bump();
|
|
||||||
row_items = 0;
|
|
||||||
}
|
|
||||||
R_BRACK => going = false,
|
|
||||||
_ => {
|
|
||||||
let err = p.start();
|
|
||||||
p.do_bump();
|
|
||||||
|
|
||||||
err.complete_err(p, SyntaxError::Expected(vec![COMMA, SEMICOLON, R_BRACK]));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else if p.at(R_BRACK) {
|
|
||||||
going = false;
|
|
||||||
} else {
|
|
||||||
let err = p.start();
|
|
||||||
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,18 +1,14 @@
|
||||||
use crate::parser::{syntax_kind::SyntaxKind::*, CompletedMarker, Parser};
|
use crate::parser::{syntax_kind::SyntaxKind::*, Parser};
|
||||||
|
|
||||||
use super::lit::literal;
|
use super::lit::literal;
|
||||||
|
|
||||||
pub fn instr(p: &mut Parser) -> Option<CompletedMarker> {
|
pub fn instr(p: &mut Parser) {
|
||||||
if !p.at(IDENT) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let instr = p.start();
|
let instr = p.start();
|
||||||
|
|
||||||
instr_name(p);
|
instr_name(p);
|
||||||
instr_params(p);
|
instr_params(p);
|
||||||
|
|
||||||
Some(instr.complete(p, INSTR))
|
instr.complete(p, INSTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn instr_name(p: &mut Parser) {
|
fn instr_name(p: &mut Parser) {
|
||||||
|
|
6
crates/lang/src/parser/parser.rs
Normal file
6
crates/lang/src/parser/parser.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
//! The parser architecture is *heavily* inspired (and partially copied and adapted) from the amazing rust-analyzer
|
||||||
|
use drop_bomb::DropBomb;
|
||||||
|
|
||||||
|
use self::{error::SyntaxError, events::Event, input::Input};
|
||||||
|
|
||||||
|
use super::syntax_kind::SyntaxKind;
|
|
@ -34,11 +34,9 @@ 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_ITEM,
|
|
||||||
DECL,
|
DECL,
|
||||||
LIST,
|
LIST,
|
||||||
|
MAT_BODY,
|
||||||
PARENTHESIZED_EXPR,
|
PARENTHESIZED_EXPR,
|
||||||
EXPR,
|
EXPR,
|
||||||
LITERAL,
|
LITERAL,
|
||||||
|
@ -47,9 +45,9 @@ pub enum SyntaxKind {
|
||||||
#[token(")")]
|
#[token(")")]
|
||||||
R_PAREN,
|
R_PAREN,
|
||||||
#[token("{")]
|
#[token("{")]
|
||||||
L_BRACE,
|
L_CURLY,
|
||||||
#[token("}")]
|
#[token("}")]
|
||||||
R_BRACE,
|
R_CURLY,
|
||||||
#[token("[")]
|
#[token("[")]
|
||||||
L_BRACK,
|
L_BRACK,
|
||||||
#[token("]")]
|
#[token("]")]
|
||||||
|
|
|
@ -1,4 +1 @@
|
||||||
mat 2x2 [
|
hello world test 1.5 42 69 "gay"
|
||||||
1, 2;
|
|
||||||
3, 4
|
|
||||||
]
|
|
||||||
|
|
Loading…
Reference in a new issue