Changes in api and upwards

- Removed out-of-stack error reporting
- Revised module system to match previous Orchid system
- Errors are now in a Vec everywhere
- Implemented atoms and lexer
- Started implementation of line parser
- Tree is now ephemeral to avoid copying Atoms held inside
- Moved numbers into std and the shared parser into base
- Started implementation of Commands
This commit is contained in:
2024-07-28 23:59:55 +02:00
parent cc3699bbe7
commit 9d35ba8040
46 changed files with 1236 additions and 642 deletions

View File

@@ -1,32 +1,46 @@
use std::ops::{Range, RangeInclusive};
use orchid_api::error::ReportError;
use orchid_api::parser::{LexId, SubLex};
use orchid_api::parser::{ParsId, SubLex};
use orchid_api::proto::ExtMsgSet;
use orchid_api::system::SysId;
use orchid_base::interner::Tok;
use orchid_base::location::Pos;
use orchid_base::reqnot::{ReqNot, Requester};
use crate::error::{
err_from_api_or_ref, err_or_ref_to_api, pack_err, unpack_err, ProjectErrorObj, ProjectResult,
ProjectError, ProjectResult
};
use crate::tree::{OwnedTok, OwnedTokTree};
use crate::tree::{GenTok, GenTokTree};
pub struct CascadingError;
impl ProjectError for CascadingError {
const DESCRIPTION: &'static str = "An error cascading from a recursive sublexer";
fn message(&self) -> String {
"This error should not surface. If you are seeing it, something is wrong".to_string()
}
fn one_position(&self) -> Pos { Pos::None }
}
pub struct NotApplicableLexerError;
impl ProjectError for NotApplicableLexerError {
const DESCRIPTION: &'static str = "Pseudo-error to communicate that the lexer doesn't apply";
fn message(&self) -> String { CascadingError.message() }
fn one_position(&self) -> Pos { Pos::None }
}
pub struct LexContext<'a> {
pub text: &'a Tok<String>,
pub sys: SysId,
pub id: LexId,
pub id: ParsId,
pub pos: u32,
pub reqnot: ReqNot<ExtMsgSet>,
}
impl<'a> LexContext<'a> {
pub fn recurse(&self, tail: &'a str) -> ProjectResult<(&'a str, OwnedTokTree)> {
pub fn recurse(&self, tail: &'a str) -> ProjectResult<(&'a str, GenTokTree)> {
let start = self.pos(tail);
self
.reqnot
.request(SubLex { pos: start, id: self.id })
.map_err(|e| pack_err(e.iter().map(|e| err_from_api_or_ref(e, self.reqnot.clone()))))
.map(|lx| (&self.text[lx.pos as usize..], OwnedTok::Slot(lx.ticket).at(start..lx.pos)))
let lx = (self.reqnot.request(SubLex { pos: start, id: self.id }))
.ok_or_else(|| CascadingError.pack())?;
Ok((&self.text[lx.pos as usize..], GenTok::Slot(lx.ticket).at(start..lx.pos)))
}
pub fn pos(&self, tail: &'a str) -> u32 { (self.text.len() - tail.len()) as u32 }
@@ -34,12 +48,6 @@ impl<'a> LexContext<'a> {
pub fn tok_ran(&self, len: u32, tail: &'a str) -> Range<u32> {
self.pos(tail) - len..self.pos(tail)
}
pub fn report(&self, e: ProjectErrorObj) {
for e in unpack_err(e) {
self.reqnot.notify(ReportError(self.sys, err_or_ref_to_api(e)))
}
}
}
pub trait Lexer: Send + Sync + Sized + Default + 'static {
@@ -47,7 +55,7 @@ pub trait Lexer: Send + Sync + Sized + Default + 'static {
fn lex<'a>(
tail: &'a str,
ctx: &'a LexContext<'a>,
) -> Option<ProjectResult<(&'a str, OwnedTokTree)>>;
) -> ProjectResult<(&'a str, GenTokTree)>;
}
pub trait DynLexer: Send + Sync + 'static {
@@ -56,7 +64,7 @@ pub trait DynLexer: Send + Sync + 'static {
&self,
tail: &'a str,
ctx: &'a LexContext<'a>,
) -> Option<ProjectResult<(&'a str, OwnedTokTree)>>;
) -> ProjectResult<(&'a str, GenTokTree)>;
}
impl<T: Lexer> DynLexer for T {
@@ -65,7 +73,7 @@ impl<T: Lexer> DynLexer for T {
&self,
tail: &'a str,
ctx: &'a LexContext<'a>,
) -> Option<ProjectResult<(&'a str, OwnedTokTree)>> {
) -> ProjectResult<(&'a str, GenTokTree)> {
T::lex(tail, ctx)
}
}