> #81 Compiling brush doesn't seem to finish correctly sometimes, which causes loss of data > Sometimes it seems like the client state can get desynced (server render thread dies due to a panic?) and then the server starts dropping all requests for drawing the brush. > These panics should never happen of course, but we need better logging first to determine the exact cause.
133 lines
2.9 KiB
Rust
133 lines
2.9 KiB
Rust
use core::{error::Error, fmt::Display};
|
|
|
|
use alloc::vec::Vec;
|
|
|
|
use crate::source::Span;
|
|
|
|
pub mod dump;
|
|
pub mod walk;
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
pub struct NodeId(u32);
|
|
|
|
impl NodeId {
|
|
pub const NIL: NodeId = NodeId(0);
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum NodeKind {
|
|
Nil,
|
|
|
|
Token,
|
|
|
|
Ident,
|
|
Tag,
|
|
Number,
|
|
Color,
|
|
List,
|
|
|
|
Op,
|
|
Unary,
|
|
Binary,
|
|
Call,
|
|
ParenEmpty,
|
|
Paren,
|
|
Lambda,
|
|
Params,
|
|
Param,
|
|
If,
|
|
Let,
|
|
|
|
Toplevel,
|
|
|
|
Error,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub struct Node {
|
|
pub span: Span,
|
|
pub kind: NodeKind,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Ast {
|
|
kinds: Vec<NodeKind>,
|
|
spans: Vec<Span>,
|
|
children_spans: Vec<(u32, u32)>,
|
|
children: Vec<NodeId>,
|
|
}
|
|
|
|
impl Ast {
|
|
pub fn new(capacity: usize) -> Self {
|
|
assert!(capacity >= 1, "there must be space for at least a nil node");
|
|
assert!(capacity <= u32::MAX as usize);
|
|
|
|
let mut ast = Self {
|
|
kinds: Vec::with_capacity(capacity),
|
|
spans: Vec::with_capacity(capacity),
|
|
children_spans: Vec::with_capacity(capacity),
|
|
children: Vec::new(),
|
|
};
|
|
|
|
ast.alloc(NodeKind::Nil, Span::new(0, 0)).unwrap();
|
|
|
|
ast
|
|
}
|
|
|
|
pub fn len(&self) -> usize {
|
|
self.kinds.len()
|
|
}
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
self.len() == 0
|
|
}
|
|
|
|
pub fn alloc(&mut self, kind: NodeKind, span: Span) -> Result<NodeId, NodeAllocError> {
|
|
if self.kinds.len() >= self.kinds.capacity() {
|
|
return Err(NodeAllocError);
|
|
}
|
|
|
|
let index = self.kinds.len() as u32;
|
|
self.kinds.push(kind);
|
|
self.spans.push(span);
|
|
self.children_spans.push((0, 0));
|
|
Ok(NodeId(index))
|
|
}
|
|
|
|
// NOTE: This never produces a NodeAllocError, because there can more or less only ever be as many children for
|
|
// nodes as there are nodes.
|
|
pub fn alloc_children(&mut self, for_node: NodeId, children: &[NodeId]) {
|
|
let start = self.children.len();
|
|
self.children.extend_from_slice(children);
|
|
let end = self.children.len();
|
|
self.children_spans[for_node.0 as usize] = (start as u32, end as u32);
|
|
}
|
|
|
|
pub fn extend_span(&mut self, in_node: NodeId, end: u32) {
|
|
self.spans[in_node.0 as usize].end = end;
|
|
}
|
|
|
|
pub fn kind(&self, id: NodeId) -> NodeKind {
|
|
self.kinds[id.0 as usize]
|
|
}
|
|
|
|
pub fn span(&self, id: NodeId) -> Span {
|
|
self.spans[id.0 as usize]
|
|
}
|
|
|
|
pub fn children(&self, id: NodeId) -> &[NodeId] {
|
|
let (start, end) = self.children_spans[id.0 as usize];
|
|
&self.children[start as usize..end as usize]
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
pub struct NodeAllocError;
|
|
|
|
impl Display for NodeAllocError {
|
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
f.write_str("too many nodes")
|
|
}
|
|
}
|
|
|
|
impl Error for NodeAllocError {}
|