From 2f91e454ddfc9626b6256039f850afba95f5cc18 Mon Sep 17 00:00:00 2001 From: shadow cat Date: Fri, 17 Apr 2026 01:49:43 -0400 Subject: [PATCH] stuff --- src/main.rs | 8 +- src/parser/cursor/lit.rs | 8 -- src/parser/node/{parse.rs => ctx.rs} | 51 +++------ src/parser/node/dsp.rs | 59 ++++++++++ src/parser/node/id.rs | 116 ------------------- src/parser/node/mod.rs | 111 +++++++++--------- src/parser/nodes/body.rs | 19 +--- src/parser/nodes/expr.rs | 162 ++++++++++++++------------- src/parser/nodes/func.rs | 26 ++--- src/parser/nodes/ident.rs | 18 ++- src/parser/nodes/item.rs | 27 ++--- src/parser/nodes/mod.rs | 34 +----- src/parser/nodes/param.rs | 10 +- src/parser/nodes/struct_.rs | 8 +- src/parser/nodes/ty.rs | 6 +- test/main.lang | 6 +- 16 files changed, 268 insertions(+), 401 deletions(-) rename src/parser/node/{parse.rs => ctx.rs} (59%) create mode 100644 src/parser/node/dsp.rs delete mode 100644 src/parser/node/id.rs diff --git a/src/main.rs b/src/main.rs index 0f6d2ff..b35acf3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use crate::{io::CompilerOutput, parser::Nodes}; +use crate::{io::CompilerOutput, parser::parse_root}; mod io; mod parser; @@ -10,9 +10,9 @@ fn main() { return; }; let mut output = CompilerOutput::new(); - let nodes = Nodes::parse_root(&path, &mut output); - if let Some((nodes, root)) = nodes { - print!("{}", root.dsp(&nodes)); + let nodes = parse_root(&path, &mut output); + if let Some(root) = nodes { + print!("{root}"); } output.write(&mut std::io::stdout()); } diff --git a/src/parser/cursor/lit.rs b/src/parser/cursor/lit.rs index 19997f5..ae16f79 100644 --- a/src/parser/cursor/lit.rs +++ b/src/parser/cursor/lit.rs @@ -1,5 +1,3 @@ -use crate::parser::{DisplayCtx, FmtNode}; - use super::Token; #[derive(PartialEq)] @@ -26,9 +24,3 @@ impl std::fmt::Display for Lit { } } } - -impl FmtNode for Lit { - fn fmt(&self, f: &mut std::fmt::Formatter, _: DisplayCtx) -> std::fmt::Result { - write!(f, "{self}") - } -} diff --git a/src/parser/node/parse.rs b/src/parser/node/ctx.rs similarity index 59% rename from src/parser/node/parse.rs rename to src/parser/node/ctx.rs index 4d6e552..e1654fc 100644 --- a/src/parser/node/parse.rs +++ b/src/parser/node/ctx.rs @@ -1,40 +1,33 @@ -use std::ops::Index; - use crate::{ io::{CompilerMsg, Span}, parser::{ - Id, Ident, Node, Nodes, + Ident, Node, Parsed, cursor::{Cursor, Lit, Token}, }, }; -pub trait Parsable: Sized + Node { - fn parse(ctx: &mut ParseCtx) -> Result; -} - pub struct ParseCtx<'a> { start: usize, cursor: Cursor<'a>, - pub nodes: Nodes, } impl<'a> ParseCtx<'a> { pub fn new(cursor: Cursor<'a>) -> Self { - Self { - start: 0, - nodes: Nodes::default(), - cursor, - } + Self { start: 0, cursor } } - pub fn parse(&mut self) -> Result, CompilerMsg> { + pub fn parse_box(&mut self) -> Result>, CompilerMsg> { + self.parse_with(N::parse).map(Parsed::boxed) + } + + pub fn parse(&mut self) -> Result, CompilerMsg> { self.parse_with(N::parse) } pub fn parse_with( &mut self, f: impl FnOnce(&mut Self) -> Result, - ) -> Result, CompilerMsg> { + ) -> Result, CompilerMsg> { let old_start = self.start; self.start = self.cursor.peek_start(); let res = f(self).map(|r| self.push(r)); @@ -42,25 +35,25 @@ impl<'a> ParseCtx<'a> { res } - pub fn ident(&mut self, s: String) -> Id { + pub fn ident(&mut self, s: String) -> Parsed { let span = self.cursor.span; - self.nodes.idents.add(Ident { inner: s }, span) + Parsed::new(Ident(s), span) } - pub fn lit(&mut self, lit: Lit) -> Id { + pub fn lit(&mut self, lit: Lit) -> Parsed { let span = self.cursor.span; - self.nodes.lits.add(lit, span) + Parsed::new(lit, span) } - pub fn push_adv(&mut self, node: N) -> Id { + pub fn push_adv(&mut self, node: N) -> Parsed { let res = self.push(node); self.cursor.next(); res } - pub fn push(&mut self, node: N) -> Id { + pub fn push(&mut self, node: N) -> Parsed { let end = self.cursor.cur_end(); - N::vec_mut(&mut self.nodes).add( + Parsed::new( node, Span { file: self.cursor.file(), @@ -70,7 +63,7 @@ impl<'a> ParseCtx<'a> { ) } - pub fn list(&mut self, sep: Token, end: Token) -> Result>, CompilerMsg> { + pub fn list(&mut self, sep: Token, end: Token) -> Result>, CompilerMsg> { let mut list = Vec::new(); if self.next_if(&end) { return Ok(list); @@ -82,10 +75,6 @@ impl<'a> ParseCtx<'a> { self.expect(end)?; Ok(list) } - - pub fn finish(self) -> Nodes { - self.nodes - } } impl<'a> std::ops::Deref for ParseCtx<'a> { @@ -101,11 +90,3 @@ impl<'a> std::ops::DerefMut for ParseCtx<'a> { &mut self.cursor } } - -impl Index> for ParseCtx<'_> { - type Output = N; - - fn index(&self, index: Id) -> &Self::Output { - &self.nodes[index] - } -} diff --git a/src/parser/node/dsp.rs b/src/parser/node/dsp.rs new file mode 100644 index 0000000..4648954 --- /dev/null +++ b/src/parser/node/dsp.rs @@ -0,0 +1,59 @@ +use crate::parser::{Node, Parsed}; + +#[derive(Clone, Copy)] +pub struct DisplayCtx { + pub indent: usize, +} + +pub struct NodeDsp<'a, N: Node> { + pub node: &'a N, + pub ctx: DisplayCtx, +} + +impl std::fmt::Display for NodeDsp<'_, N> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.node.fmt(f, self.ctx) + } +} + +pub struct VecDsp<'a, N> { + list: &'a Vec>, + ctx: DisplayCtx, +} + +impl std::fmt::Display for VecDsp<'_, N> { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + if let Some((last, rest)) = self.list.split_last() { + for arg in rest { + write!(f, "{}, ", arg.dsp(self.ctx))?; + } + write!(f, "{}", last.dsp(self.ctx))?; + } + Ok(()) + } +} + +impl Parsed { + pub fn dsp(&self, ctx: DisplayCtx) -> NodeDsp<'_, N> + where + N: Node, + { + NodeDsp { node: self, ctx } + } +} + +pub trait VecDspT { + fn dsp<'a, 'b>(&'a self, ctx: impl Into) -> VecDsp<'b, N> + where + 'a: 'b; +} + +impl VecDspT for Vec> { + fn dsp<'a, 'b>(&'a self, ctx: impl Into) -> VecDsp<'b, N> + where + 'a: 'b, + { + let ctx = ctx.into(); + VecDsp { list: self, ctx } + } +} diff --git a/src/parser/node/id.rs b/src/parser/node/id.rs deleted file mode 100644 index 560df4f..0000000 --- a/src/parser/node/id.rs +++ /dev/null @@ -1,116 +0,0 @@ -use crate::parser::{Node, Nodes}; -use std::marker::PhantomData; - -pub struct Id { - id: usize, - _pd: PhantomData, -} - -impl Clone for Id { - fn clone(&self) -> Self { - *self - } -} - -impl Copy for Id {} - -impl std::ops::Index> for Nodes { - type Output = N; - - fn index(&self, index: Id) -> &Self::Output { - &N::vec(self).vec[index.id] - } -} - -impl std::ops::Index<&Id> for Nodes { - type Output = N; - - fn index(&self, index: &Id) -> &Self::Output { - &N::vec(self).vec[index.id] - } -} - -#[derive(Clone, Copy)] -pub struct DisplayCtx<'a> { - pub nodes: &'a Nodes, - pub indent: usize, -} - -pub struct IdDisplay<'a, N> { - id: Id, - ctx: DisplayCtx<'a>, -} - -pub trait FmtNode: Node { - fn fmt(&self, f: &mut std::fmt::Formatter, ctx: DisplayCtx) -> std::fmt::Result; -} - -impl std::fmt::Display for IdDisplay<'_, N> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.ctx.nodes[self.id].fmt(f, self.ctx) - } -} - -impl Id { - pub(super) fn new(id: usize) -> Self { - Self { - id, - _pd: PhantomData, - } - } -} - -impl Id { - pub fn fmt(&self, f: &mut std::fmt::Formatter, ctx: DisplayCtx) -> std::fmt::Result { - ctx.nodes[*self].fmt(f, ctx) - } - pub fn dsp<'a, 'b>(&self, ctx: impl Into>) -> IdDisplay<'b, N> - where - 'a: 'b, - { - let ctx = ctx.into(); - IdDisplay { id: *self, ctx } - } -} - -impl<'a> From<&'a Nodes> for DisplayCtx<'a> { - fn from(node: &'a Nodes) -> Self { - Self { - nodes: node, - indent: 0, - } - } -} - -pub struct VecDsp<'a, N> { - list: &'a Vec>, - ctx: DisplayCtx<'a>, -} - -impl std::fmt::Display for VecDsp<'_, N> { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - if let Some((last, rest)) = self.list.split_last() { - for arg in rest { - write!(f, "{}, ", arg.dsp(self.ctx))?; - } - write!(f, "{}", last.dsp(self.ctx))?; - } - Ok(()) - } -} - -pub trait VecDspT { - fn dsp<'a, 'b>(&'a self, ctx: impl Into>) -> VecDsp<'b, N> - where - 'a: 'b; -} - -impl VecDspT for Vec> { - fn dsp<'a, 'b>(&'a self, ctx: impl Into>) -> VecDsp<'b, N> - where - 'a: 'b, - { - let ctx = ctx.into(); - VecDsp { list: self, ctx } - } -} diff --git a/src/parser/node/mod.rs b/src/parser/node/mod.rs index 78430cb..edbfce2 100644 --- a/src/parser/node/mod.rs +++ b/src/parser/node/mod.rs @@ -1,60 +1,69 @@ use crate::{ - io::{CompilerOutput, Span}, + io::{CompilerMsg, CompilerOutput, Span}, parser::{Cursor, nodes::*}, }; -mod id; -mod parse; -pub use id::*; -pub use parse::*; +mod ctx; +mod dsp; +pub use ctx::*; +pub use dsp::*; -impl Nodes { - pub fn parse_root(path: &str, output: &mut CompilerOutput) -> Option<(Self, Id)> { - let root_code = match std::fs::read_to_string(path) { - Ok(code) => code, - Err(err) => { - output.error(format!("Failed to read input file: {err}")); - return None; - } - }; - output.files.push(path.to_string()); - 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.finish(), root)) - } -} - -#[derive(Debug)] -pub struct NodeVec { - vec: Vec, - spans: Vec, -} - -impl NodeVec { - pub fn add(&mut self, v: N, span: Span) -> Id { - let id = self.vec.len(); - self.vec.push(v); - self.spans.push(span); - Id::new(id) - } -} - -impl Default for NodeVec { - fn default() -> Self { - Self { - vec: Default::default(), - spans: Default::default(), - } - } +pub struct Parsed { + pub node: N, + pub span: Span, } pub trait Node: Sized { - fn vec(nodes: &Nodes) -> &NodeVec; - fn vec_mut(nodes: &mut Nodes) -> &mut NodeVec; + fn parse(ctx: &mut ParseCtx) -> Result; + fn fmt(&self, f: &mut std::fmt::Formatter, ctx: DisplayCtx) -> std::fmt::Result; +} + +pub fn parse_root(path: &str, output: &mut CompilerOutput) -> Option> { + let root_code = match std::fs::read_to_string(path) { + Ok(code) => code, + Err(err) => { + output.error(format!("Failed to read input file: {err}")); + return None; + } + }; + output.files.push(path.to_string()); + let mut ctx = ParseCtx::new(Cursor::new(&root_code, 0)); + let root = match ctx.parse() { + Ok(v) => v, + Err(msg) => { + output.error(msg); + return None; + } + }; + Some(root) +} + +impl Parsed { + pub fn new(node: N, span: Span) -> Self { + Self { node, span } + } + + pub fn boxed(self) -> Box { + Box::new(self) + } +} + +impl std::ops::Deref for Parsed { + type Target = N; + + fn deref(&self) -> &Self::Target { + &self.node + } +} + +impl std::ops::DerefMut for Parsed { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.node + } +} + +impl std::fmt::Display for Parsed { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.node.fmt(f, DisplayCtx { indent: 0 }) + } } diff --git a/src/parser/nodes/body.rs b/src/parser/nodes/body.rs index e4d1c4d..c395199 100644 --- a/src/parser/nodes/body.rs +++ b/src/parser/nodes/body.rs @@ -1,11 +1,11 @@ use super::*; pub struct Body { - pub items: Vec>, + pub items: Vec>, pub final_semicolon: bool, } -impl Parsable for Body { +impl Node for Body { fn parse(ctx: &mut ParseCtx) -> Result { let mut items = Vec::new(); fn at_end(ctx: &mut ParseCtx) -> bool { @@ -15,8 +15,8 @@ impl Parsable for Body { if at_end(ctx) { break true; } - let item: Id = ctx.parse()?; - let needs_semicolon = item.needs_semicolon(&ctx.nodes); + let item: Parsed = ctx.parse()?; + let needs_semicolon = item.needs_semicolon(); items.push(item); if at_end(ctx) { break false; @@ -31,23 +31,16 @@ impl Parsable for Body { final_semicolon, }) } -} -impl FmtNode for Body { fn fmt(&self, f: &mut std::fmt::Formatter, ctx: DisplayCtx) -> std::fmt::Result { - // surely there's a better way to do this if let Some((last, rest)) = self.items.split_last() { - for &i in rest { + for i in rest { writeln!( f, "{}{}{}", " ".repeat(ctx.indent), i.dsp(ctx), - if i.needs_semicolon(ctx.nodes) { - ";" - } else { - "" - } + if i.needs_semicolon() { ";" } else { "" } )?; } writeln!( diff --git a/src/parser/nodes/expr.rs b/src/parser/nodes/expr.rs index 0fed282..3d0d23f 100644 --- a/src/parser/nodes/expr.rs +++ b/src/parser/nodes/expr.rs @@ -2,46 +2,48 @@ use crate::parser::VecDspT; pub use super::*; +pub type BoxExpr = Box>; + pub enum Expr { - Block(Id), - Group(Id), - Ident(Id), - Lit(Id), - Negate(Id), + Block(Parsed), + Group(BoxExpr), + Ident(Ident), + Lit(Lit), + Negate(BoxExpr), Call { - target: Id, - args: Vec>, + target: BoxExpr, + args: Vec>, }, Assign { - target: Id, - val: Id, + target: BoxExpr, + val: BoxExpr, }, If { - cond: Id, - body: Id, + cond: BoxExpr, + body: BoxExpr, }, Loop { - body: Id, + body: BoxExpr, }, While { - cond: Id, - body: Id, + cond: BoxExpr, + body: BoxExpr, }, - Fn(Id), + Fn(Box>), } -impl Parsable for Expr { +impl Node for Expr { fn parse(ctx: &mut ParseCtx) -> Result { let mut res = Self::unit(ctx)?; while let Some(next) = ctx.peek() { res = match next { Token::Equal => { - let target = ctx.push_adv(res); - let val = ctx.parse_with(Self::unit)?; + let target = ctx.push_adv(res).boxed(); + let val = ctx.parse_with(Self::unit)?.boxed(); Expr::Assign { target, val } } Token::OpenParen => { - let target = ctx.push_adv(res); + let target = ctx.push_adv(res).boxed(); let args = ctx.list(Token::Comma, Token::CloseParen)?; Expr::Call { target, args } } @@ -50,34 +52,71 @@ impl Parsable for Expr { } Ok(res) } + + fn fmt(&self, f: &mut std::fmt::Formatter, mut ctx: DisplayCtx) -> std::fmt::Result { + match self { + Self::Ident(ident) => ident.fmt(f, ctx), + Self::Group(expr) => write!(f, "({})", expr.dsp(ctx)), + Self::Fn(func) => func.fmt(f, ctx), + Self::Lit(lit) => write!(f, "{}", lit), + Self::Negate(expr) => { + write!(f, "-{}", expr.dsp(ctx)) + } + Self::Call { target, args } => { + write!(f, "{}({})", target.dsp(ctx), args.dsp(ctx)) + } + Self::Assign { target, val } => { + write!(f, "{} = {}", target.dsp(ctx), val.dsp(ctx)) + } + Self::If { cond, body } => { + write!(f, "if {} {}", cond.dsp(ctx), body.dsp(ctx)) + } + Self::While { cond, body } => { + write!(f, "while {} {}", cond.dsp(ctx), body.dsp(ctx)) + } + Self::Loop { body } => { + write!(f, "loop {}", body.dsp(ctx)) + } + Self::Block(body) => { + write!(f, "{{")?; + if !body.items.is_empty() { + writeln!(f)?; + ctx.indent += 3; + body.fmt(f, ctx)?; + } + write!(f, "}}")?; + Ok(()) + } + } + } } impl Expr { fn unit(ctx: &mut ParseCtx) -> Result { Ok(match ctx.expect_next()? { - Token::Dash => Self::Negate(ctx.parse()?), - Token::Ident(s) => Self::Ident(ctx.ident(s)), - Token::Lit(l) => Self::Lit(ctx.lit(l)), - Token::Fn => Self::Fn(ctx.parse()?), + Token::Dash => Self::Negate(ctx.parse_box()?), + Token::Ident(s) => Self::Ident(Ident(s)), + Token::Lit(l) => Self::Lit(l), + Token::Fn => Self::Fn(ctx.parse_box()?), Token::If => { - let cond = ctx.parse()?; - let body = cond_body(ctx)?; + let cond = ctx.parse_box()?; + let body = Self::body(ctx)?.boxed(); Self::If { cond, body } } Token::While => { - let cond = ctx.parse()?; - let body = cond_body(ctx)?; + let cond = ctx.parse_box()?; + let body = Self::body(ctx)?.boxed(); Self::While { cond, body } } Token::Loop => { - let body = ctx.parse()?; + let body = ctx.parse_box()?; Self::Loop { body } } Token::OpenParen => { if ctx.next_if(Token::CloseParen) { - Self::Lit(ctx.push(Lit::Unit)) + Self::Lit(Lit::Unit) } else { - let inner = ctx.parse()?; + let inner = ctx.parse_box()?; ctx.expect(Token::CloseParen)?; Self::Group(inner) } @@ -105,67 +144,34 @@ impl Expr { ctx.expect(Token::CloseCurly)?; Ok(Expr::Block(id)) } -} -fn cond_body(ctx: &mut ParseCtx) -> Result, CompilerMsg> { - if ctx.next_if(Token::Do) { - ctx.parse() - } else { - ctx.parse_with(Expr::block) + pub fn body(ctx: &mut ParseCtx) -> Result, CompilerMsg> { + if ctx.next_if(Token::DoubleArrow) { + ctx.parse() + } else { + ctx.parse_with(Expr::block) + } } -} -impl Id { - pub fn ends_with_block(&self, nodes: &Nodes) -> bool { - match nodes[self] { + pub fn ends_with_block(&self) -> bool { + match self { Expr::Block(..) => true, Expr::Loop { body } | Expr::While { body, .. } | Expr::If { body, .. } | Expr::Negate(body) - | Expr::Assign { val: body, .. } => body.ends_with_block(nodes), - Expr::Fn(f) => f.ends_with_block(nodes), + | Expr::Assign { val: body, .. } => body.ends_with_block(), + Expr::Fn(f) => f.ends_with_block(), _ => false, } } } -impl FmtNode for Expr { - fn fmt(&self, f: &mut std::fmt::Formatter, mut ctx: DisplayCtx) -> std::fmt::Result { - let do_ = |id: Id| if ctx.nodes[id].is_block() { "" } else { "do " }; - match *self { - Self::Ident(id) => id.fmt(f, ctx), - Self::Group(id) => write!(f, "({})", id.dsp(ctx)), - Self::Fn(id) => id.fmt(f, ctx), - Self::Lit(id) => id.fmt(f, ctx), - Self::Negate(id) => { - write!(f, "-{}", id.dsp(ctx)) - } - Self::Call { target, ref args } => { - write!(f, "{}({})", target.dsp(ctx), args.dsp(ctx)) - } - Self::Assign { target, val } => { - write!(f, "{} = {}", target.dsp(ctx), val.dsp(ctx)) - } - Self::If { cond, body } => { - write!(f, "if {} {}{}", cond.dsp(ctx), do_(body), body.dsp(ctx)) - } - Self::While { cond, body } => { - write!(f, "while {} {}{}", cond.dsp(ctx), do_(body), body.dsp(ctx)) - } - Self::Loop { body } => { - write!(f, "loop {}", body.dsp(ctx)) - } - Self::Block(body) => { - write!(f, "{{")?; - if !ctx.nodes[body].items.is_empty() { - writeln!(f)?; - ctx.indent += 3; - body.fmt(f, ctx)?; - } - write!(f, "}}")?; - Ok(()) - } +impl Parsed { + pub fn fmt_body(&self, f: &mut std::fmt::Formatter, ctx: DisplayCtx) -> std::fmt::Result { + match &self.node { + Expr::Block(_) => self.node.fmt(f, ctx), + _ => write!(f, "=> {}", self.dsp(ctx)), } } } diff --git a/src/parser/nodes/func.rs b/src/parser/nodes/func.rs index 8d76eb4..41b79ec 100644 --- a/src/parser/nodes/func.rs +++ b/src/parser/nodes/func.rs @@ -1,12 +1,12 @@ use super::*; pub struct Func { - args: Vec>, - ret: Option>, - body: Id, + args: Vec>, + ret: Option>, + body: Parsed, } -impl Parsable for Func { +impl Node for Func { fn parse(ctx: &mut ParseCtx) -> Result { ctx.expect(Token::OpenParen)?; let args = ctx.list(Token::Comma, Token::CloseParen)?; @@ -14,16 +14,10 @@ impl Parsable for Func { if ctx.next_if(Token::Arrow) { ret = Some(ctx.parse()?); } - let body = if ret.is_some() { - ctx.parse_with(Expr::block) - } else { - ctx.parse() - }?; + let body = Expr::body(ctx)?; Ok(Self { args, ret, body }) } -} -impl FmtNode for Func { fn fmt(&self, f: &mut std::fmt::Formatter, ctx: DisplayCtx) -> std::fmt::Result { write!(f, "fn(")?; if let Some((last, rest)) = self.args.split_last() { @@ -33,16 +27,16 @@ impl FmtNode for Func { write!(f, "{}", last.dsp(ctx))?; } write!(f, ") ")?; - if let Some(ret) = self.ret { + if let Some(ret) = &self.ret { write!(f, "-> {} ", ret.dsp(ctx))?; } - self.body.fmt(f, ctx)?; + self.body.fmt_body(f, ctx)?; Ok(()) } } -impl Id { - pub fn ends_with_block(&self, nodes: &Nodes) -> bool { - nodes[self].body.ends_with_block(nodes) +impl Func { + pub fn ends_with_block(&self) -> bool { + self.body.ends_with_block() } } diff --git a/src/parser/nodes/ident.rs b/src/parser/nodes/ident.rs index 8c48674..78ece85 100644 --- a/src/parser/nodes/ident.rs +++ b/src/parser/nodes/ident.rs @@ -1,20 +1,16 @@ use super::*; -pub struct Ident { - pub inner: String, -} +pub struct Ident(pub String); -impl FmtNode for Ident { - fn fmt(&self, f: &mut std::fmt::Formatter, _: DisplayCtx) -> std::fmt::Result { - write!(f, "{}", self.inner) - } -} - -impl Parsable for Ident { +impl Node for Ident { fn parse(ctx: &mut super::ParseCtx) -> Result { match ctx.expect_next()? { - Token::Ident(ident) => Ok(Self { inner: ident }), + Token::Ident(ident) => Ok(Self(ident)), t => ctx.unexpected(&t, "an identifier"), } } + + fn fmt(&self, f: &mut std::fmt::Formatter, _: DisplayCtx) -> std::fmt::Result { + write!(f, "{}", self.0) + } } diff --git a/src/parser/nodes/item.rs b/src/parser/nodes/item.rs index 3c850d0..1fd2d0b 100644 --- a/src/parser/nodes/item.rs +++ b/src/parser/nodes/item.rs @@ -2,15 +2,14 @@ use super::*; pub enum Item { Let { - name: Id, - ty: Option>, - val: Id, + name: Parsed, + ty: Option>, + val: Parsed, }, - Struct(Id), - Expr(Id), + Expr(Parsed), } -impl Parsable for Item { +impl Node for Item { fn parse(ctx: &mut ParseCtx) -> Result { Ok(match ctx.expect_peek()? { Token::Let => { @@ -27,9 +26,7 @@ impl Parsable for Item { _ => Self::Expr(ctx.parse()?), }) } -} -impl FmtNode for Item { fn fmt(&self, f: &mut std::fmt::Formatter, ctx: DisplayCtx) -> std::fmt::Result { match self { Item::Let { name, ty, val } => { @@ -45,14 +42,14 @@ impl FmtNode for Item { } } -impl Id { - pub fn ends_with_block(&self, nodes: &Nodes) -> bool { - match nodes[self] { - Item::Let { name, ty, val } => val.ends_with_block(nodes), - Item::Expr(id) => id.ends_with_block(nodes), +impl Item { + pub fn ends_with_block(&self) -> bool { + match self { + Item::Let { val, .. } => val.ends_with_block(), + Item::Expr(id) => id.ends_with_block(), } } - pub fn needs_semicolon(&self, nodes: &Nodes) -> bool { - !self.ends_with_block(nodes) + pub fn needs_semicolon(&self) -> bool { + !self.ends_with_block() } } diff --git a/src/parser/nodes/mod.rs b/src/parser/nodes/mod.rs index b181d92..278d942 100644 --- a/src/parser/nodes/mod.rs +++ b/src/parser/nodes/mod.rs @@ -12,39 +12,7 @@ pub use func::*; pub use ident::*; pub use item::*; pub use param::*; -pub use struct_::*; pub use ty::*; -use super::{DisplayCtx, FmtNode, Id, Lit, Node, NodeVec, Parsable, ParseCtx, Token}; +use super::{DisplayCtx, Lit, Node, ParseCtx, Parsed, Token}; use crate::io::CompilerMsg; - -def_nodes! { - exprs: Expr, - idents: Ident, - blocks: Body, - lits: Lit, - types: Type, - funcs: Func, - params: Param, - items: Item, - structs: Struct, -} - -macro_rules! def_nodes { - {$($field:ident: $ty:ident,)*} => { - #[derive(Default)] - pub struct Nodes { - $(pub $field: NodeVec<$ty>,)* - } - - $(impl Node for $ty { - fn vec(nodes: &Nodes) -> &NodeVec { - &nodes.$field - } - fn vec_mut(nodes: &mut Nodes) -> &mut NodeVec { - &mut nodes.$field - } - })* - }; -} -use def_nodes; diff --git a/src/parser/nodes/param.rs b/src/parser/nodes/param.rs index 9d0de41..615cfc4 100644 --- a/src/parser/nodes/param.rs +++ b/src/parser/nodes/param.rs @@ -1,11 +1,11 @@ use super::*; pub struct Param { - name: Id, - ty: Option>, + name: Parsed, + ty: Option>, } -impl Parsable for Param { +impl Node for Param { fn parse(ctx: &mut ParseCtx) -> Result { let name = ctx.parse()?; let mut ty = None; @@ -14,12 +14,10 @@ impl Parsable for Param { } Ok(Self { name, ty }) } -} -impl FmtNode for Param { fn fmt(&self, f: &mut std::fmt::Formatter, ctx: DisplayCtx) -> std::fmt::Result { self.name.fmt(f, ctx)?; - if let Some(ty) = self.ty { + if let Some(ty) = &self.ty { write!(f, ": {}", ty.dsp(ctx))?; } Ok(()) diff --git a/src/parser/nodes/struct_.rs b/src/parser/nodes/struct_.rs index eaccd5b..7ab1c6f 100644 --- a/src/parser/nodes/struct_.rs +++ b/src/parser/nodes/struct_.rs @@ -5,10 +5,4 @@ pub struct Struct { fields: Vec, } -impl Parsable for Struct { - fn parse(ctx: &mut ParseCtx) -> Result { - } -} - -pub struct Field { -} +pub struct Field {} diff --git a/src/parser/nodes/ty.rs b/src/parser/nodes/ty.rs index f6c8c08..7517669 100644 --- a/src/parser/nodes/ty.rs +++ b/src/parser/nodes/ty.rs @@ -1,19 +1,17 @@ use super::*; pub enum Type { - Ident(Id), + Ident(Parsed), } -impl Parsable for Type { +impl Node for Type { fn parse(ctx: &mut ParseCtx) -> Result { Ok(match ctx.expect_next()? { Token::Ident(s) => Self::Ident(ctx.ident(s)), t => ctx.unexpected(&t, "a type")?, }) } -} -impl FmtNode for Type { fn fmt(&self, f: &mut std::fmt::Formatter, ctx: DisplayCtx) -> std::fmt::Result { match self { Type::Ident(id) => id.fmt(f, ctx), diff --git a/test/main.lang b/test/main.lang index 47ca136..5ea17e7 100644 --- a/test/main.lang +++ b/test/main.lang @@ -4,8 +4,6 @@ while true { print(x); }; -if x { - print("hello"); -} +let y = true; -let y = fn(x: i32) -> i32 {x}; +if y => print("hello");