work
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
use crate::{
|
||||
io::{CompilerMsg, Span},
|
||||
parser::{
|
||||
Id, Ident, Node, Nodes,
|
||||
cursor::{Cursor, Lit},
|
||||
},
|
||||
};
|
||||
|
||||
pub trait Parsable: Sized + Node {
|
||||
fn parse(ctx: &mut ParseCtx) -> Result<Self, CompilerMsg>;
|
||||
}
|
||||
|
||||
pub struct ParseCtx<'a> {
|
||||
start: usize,
|
||||
cursor: Cursor<'a>,
|
||||
nodes: Nodes,
|
||||
}
|
||||
|
||||
impl<'a> ParseCtx<'a> {
|
||||
pub fn new(cursor: Cursor<'a>) -> Self {
|
||||
Self {
|
||||
start: 0,
|
||||
nodes: Nodes::default(),
|
||||
cursor,
|
||||
}
|
||||
}
|
||||
pub fn parse<P: Parsable>(&mut self) -> Result<Id<P>, CompilerMsg> {
|
||||
let old_start = self.start;
|
||||
self.start = self.cursor.peek_start();
|
||||
let res = P::parse(self).map(|r| self.push(r));
|
||||
self.start = old_start;
|
||||
res
|
||||
}
|
||||
|
||||
pub fn ident(&mut self, s: String) -> Id<Ident> {
|
||||
let span = self.cursor.span;
|
||||
self.nodes.idents.add(Ident { inner: s }, span)
|
||||
}
|
||||
pub fn lit(&mut self, lit: Lit) -> Id<Lit> {
|
||||
let span = self.cursor.span;
|
||||
self.nodes.lits.add(lit, span)
|
||||
}
|
||||
pub fn push_adv<N: Node>(&mut self, node: N) -> Id<N> {
|
||||
let res = self.push(node);
|
||||
self.cursor.next();
|
||||
res
|
||||
}
|
||||
pub fn push<N: Node>(&mut self, node: N) -> Id<N> {
|
||||
let end = self.cursor.cur_end();
|
||||
N::vec_mut(&mut self.nodes).add(
|
||||
node,
|
||||
Span {
|
||||
file: self.cursor.file(),
|
||||
start: self.start,
|
||||
end,
|
||||
},
|
||||
)
|
||||
}
|
||||
pub fn finish(self) -> Nodes {
|
||||
self.nodes
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::ops::Deref for ParseCtx<'a> {
|
||||
type Target = Cursor<'a>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.cursor
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::ops::DerefMut for ParseCtx<'a> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.cursor
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user