work
This commit is contained in:
+15
-107
@@ -1,31 +1,23 @@
|
||||
use crate::{
|
||||
io::{CompilerMsg, CompilerOutput, Span},
|
||||
parser::cursor::{Cursor, Lit},
|
||||
io::{CompilerOutput, Span},
|
||||
parser::{Cursor, Lit, nodes::*},
|
||||
};
|
||||
use std::{marker::PhantomData, ops::Index};
|
||||
|
||||
mod expr;
|
||||
pub use expr::*;
|
||||
mod id;
|
||||
mod parse;
|
||||
pub use id::*;
|
||||
pub use parse::*;
|
||||
|
||||
pub trait Parsable: Sized + Node {
|
||||
fn parse(ctx: &mut ParseCtx) -> Result<Self, CompilerMsg>;
|
||||
}
|
||||
|
||||
pub struct ParseCtx<'a> {
|
||||
start: usize,
|
||||
cursor: Cursor<'a>,
|
||||
nodes: Nodes,
|
||||
}
|
||||
|
||||
def_nodes!(
|
||||
def_nodes! {
|
||||
exprs: Expr,
|
||||
idents: Ident,
|
||||
statements: Statement,
|
||||
blocks: Block,
|
||||
lits: Lit,
|
||||
);
|
||||
}
|
||||
|
||||
impl Nodes {
|
||||
pub fn parse_root(path: &str, output: &mut CompilerOutput) -> Option<(Self, Id<Expr>)> {
|
||||
pub fn parse_root(path: &str, output: &mut CompilerOutput) -> Option<(Self, Id<Block>)> {
|
||||
let root_code = match std::fs::read_to_string(path) {
|
||||
Ok(code) => code,
|
||||
Err(err) => {
|
||||
@@ -34,44 +26,15 @@ impl Nodes {
|
||||
}
|
||||
};
|
||||
output.files.push(path.to_string());
|
||||
let nodes = Self::default();
|
||||
let mut ctx = ParseCtx {
|
||||
start: 0,
|
||||
nodes,
|
||||
cursor: Cursor::new(&root_code, 0),
|
||||
};
|
||||
let root = match ctx.parse::<Expr>() {
|
||||
let mut ctx = ParseCtx::new(Cursor::new(&root_code, 0));
|
||||
let root = match ctx.parse() {
|
||||
Ok(expr) => expr,
|
||||
Err(msg) => {
|
||||
output.error(msg);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
Some((ctx.nodes, root))
|
||||
}
|
||||
|
||||
pub fn format<N: FmtNode>(
|
||||
&self,
|
||||
w: &mut impl std::io::Write,
|
||||
id: Id<N>,
|
||||
) -> std::io::Result<()> {
|
||||
self[id].format(w, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Node> Index<Id<N>> for Nodes {
|
||||
type Output = N;
|
||||
|
||||
fn index(&self, index: Id<N>) -> &Self::Output {
|
||||
&N::vec(self).vec[index.id]
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Node> Index<&Id<N>> for Nodes {
|
||||
type Output = N;
|
||||
|
||||
fn index(&self, index: &Id<N>) -> &Self::Output {
|
||||
&N::vec(self).vec[index.id]
|
||||
Some((ctx.finish(), root))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,10 +49,7 @@ impl<N> NodeVec<N> {
|
||||
let id = self.vec.len();
|
||||
self.vec.push(v);
|
||||
self.spans.push(span);
|
||||
Id {
|
||||
id,
|
||||
_pd: PhantomData,
|
||||
}
|
||||
Id::new(id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,61 +62,13 @@ impl<N> Default for NodeVec<N> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Id<T> {
|
||||
id: usize,
|
||||
_pd: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> Clone for Id<T> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Copy for Id<T> {}
|
||||
|
||||
pub trait Node: Sized {
|
||||
fn vec(nodes: &Nodes) -> &NodeVec<Self>;
|
||||
fn vec_mut(nodes: &mut Nodes) -> &mut NodeVec<Self>;
|
||||
}
|
||||
|
||||
impl ParseCtx<'_> {
|
||||
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,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! def_nodes {
|
||||
($($field:ident: $ty:ident,)*) => {
|
||||
{$($field:ident: $ty:ident,)*} => {
|
||||
#[derive(Default)]
|
||||
pub struct Nodes {
|
||||
$($field: NodeVec<$ty>,)*
|
||||
@@ -173,7 +85,3 @@ macro_rules! def_nodes {
|
||||
};
|
||||
}
|
||||
use def_nodes;
|
||||
|
||||
pub trait FmtNode: Node {
|
||||
fn format(&self, w: &mut impl std::io::Write, nodes: &Nodes) -> std::io::Result<()>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user