diff --git a/data/err.lang b/data/err.lang index aec9269..426e136 100644 --- a/data/err.lang +++ b/data/err.lang @@ -27,5 +27,5 @@ fn test() { } fn test2() { - + let a anerit; } diff --git a/src/ir/mod.rs b/src/ir/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/main.rs b/src/main.rs index b553643..17da4cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,10 @@ mod util; mod compiler; +mod ir; mod parser; fn main() { - compiler::main(); + parser::main(); + // compiler::main(); } diff --git a/src/parser/v1/body.rs b/src/parser/v1/body.rs index 80f4ce2..a7ad8a4 100644 --- a/src/parser/v1/body.rs +++ b/src/parser/v1/body.rs @@ -1,37 +1,16 @@ use std::fmt::{Debug, Write}; use super::{ - token::{Keyword, Symbol, Token}, - Node, Parsable, ParserErrors, + token::Symbol, MaybeResolved, Node, NodeParsable, Parsable, ParserError, ParserErrors, + Resolvable, Resolved, Statement, TokenCursor, Unresolved, }; use crate::util::Padder; -use super::{Expr, ParserError, TokenCursor}; - -#[derive(Clone)] -pub struct Body { - statements: Vec>, +pub struct Body { + statements: Vec, R>>, } -#[derive(Clone)] -pub enum Statement { - Let(String, Node), - Return(Node), - Expr(Node), -} - -impl Statement { - pub fn ended_with_error(&self) -> bool { - let expr = match self { - Statement::Let(_, e) => e, - Statement::Return(e) => e, - Statement::Expr(e) => e, - }; - expr.is_err() || expr.as_ref().is_ok_and(|e| e.ended_with_error()) - } -} - -impl Parsable for Body { +impl Parsable for Body { fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Result { let mut statements = Vec::new(); let statement_end = &[Symbol::Semicolon, Symbol::CloseCurly]; @@ -57,7 +36,7 @@ impl Parsable for Body { spans: vec![cursor.next_pos().char_span()], }); } - let statement: Node = Node::parse(cursor, errors); + let statement = Statement::parse_node(cursor, errors); expect_semi = true; if statement.is_err() || statement.as_ref().is_ok_and(|s| s.ended_with_error()) { let res = cursor @@ -69,51 +48,19 @@ impl Parsable for Body { } } -impl Parsable for Statement { - fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Result { - let next = cursor.expect_peek()?; - Ok(match next.token { - Token::Keyword(Keyword::Let) => { - cursor.next(); - let name = cursor.expect_ident()?; - cursor.expect_sym(Symbol::Equals)?; - let expr = Node::parse(cursor, errors); - Self::Let(name, expr) - } - Token::Keyword(Keyword::Return) => { - cursor.next(); - Self::Return(Node::parse(cursor, errors)) - } - _ => Self::Expr(Node::parse(cursor, errors)), +impl Resolvable> for Body { + fn resolve(self) -> Result, ()> { + Ok(Body { + statements: self + .statements + .into_iter() + .map(|s| s.resolve()) + .collect::>()?, }) } } -impl Debug for Statement { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Statement::Let(n, e) => { - f.write_str("let ")?; - f.write_str(n)?; - f.write_str(" = ")?; - e.fmt(f)?; - f.write_char(';')?; - } - Statement::Return(e) => { - f.write_str("return ")?; - e.fmt(f)?; - f.write_char(';')?; - } - Statement::Expr(e) => { - e.fmt(f)?; - f.write_char(';')?; - } - } - Ok(()) - } -} - -impl Debug for Body { +impl Debug for Body { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if self.statements.first().is_some() { f.write_str("{\n ")?; diff --git a/src/parser/v1/expr.rs b/src/parser/v1/expr.rs index 87361d1..3efa1c7 100644 --- a/src/parser/v1/expr.rs +++ b/src/parser/v1/expr.rs @@ -1,33 +1,23 @@ use std::fmt::{Debug, Write}; use super::token::{Symbol, Token}; -use super::{Body, Node, Parsable, ParserError, ParserErrors, TokenCursor, Literal}; +use super::{ + Body, Literal, MaybeResolved, Node, Operator, Parsable, ParserError, ParserErrors, Resolvable, + Resolved, TokenCursor, Unresolved, +}; -pub type ExprNode = Node>; +type BoxNode = Node>, R>; -#[derive(Clone)] -pub enum Expr { - Lit(Node), +pub enum Expr { + Lit(Node), Ident(String), - BinaryOp(Operator, ExprNode, ExprNode), - Block(Node), - Call(ExprNode, Vec>), - Group(ExprNode), + BinaryOp(Operator, BoxNode, BoxNode), + Block(Node, R>), + Call(BoxNode, Vec, R>>), + Group(BoxNode), } -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum Operator { - Add, - Sub, - Mul, - Div, - LessThan, - GreaterThan, - Access, - Assign, -} - -impl Expr { +impl Expr { pub fn ended_with_error(&self) -> bool { match self { Expr::Lit(_) => false, @@ -40,7 +30,7 @@ impl Expr { } } -impl Parsable for Expr { +impl Parsable for Expr { fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Result { let start = cursor.next_pos(); let next = cursor.expect_peek()?; @@ -48,7 +38,7 @@ impl Parsable for Expr { cursor.next(); if cursor.expect_peek()?.is_symbol(Symbol::CloseParen) { cursor.next(); - return Ok(Expr::Lit(Node::new( + return Ok(Expr::Lit(Node::new_unres( Literal::Unit, cursor.next_pos().char_span(), ))); @@ -84,7 +74,7 @@ impl Parsable for Expr { let inner = Node::parse(cursor, errors); cursor.expect_sym(Symbol::CloseParen)?; let end = cursor.prev_end(); - e1 = Self::Call(Node::new(Box::new(e1), start.to(end)), vec![inner]); + e1 = Self::Call(Node::new_unres(Box::new(e1), start.to(end)), vec![inner]); let Some(next2) = cursor.peek() else { return Ok(e1); }; @@ -93,16 +83,17 @@ impl Parsable for Expr { let end = cursor.prev_end(); Ok(if let Some(mut op) = Operator::from_token(&next.token) { cursor.next(); - let mut n1 = Node::new(Box::new(e1), start.to(end)); + let mut n1 = Node::new_unres(e1, start.to(end)).bx(); let mut n2 = Node::parse(cursor, errors).bx(); - if let Ok(box Self::BinaryOp(op2, n21, n22)) = n2.as_ref() { + if let Ok(box Self::BinaryOp(op2, _, _)) = n2.as_ref() { if op.presedence() > op2.presedence() { - n1 = Node::new( - Box::new(Self::BinaryOp(op, n1, n21.clone())), - start.to(n21.span.end), - ); - op = *op2; - n2 = n22.clone(); + let Ok(box Self::BinaryOp(op2, n21, n22)) = n2.inner else { + unreachable!(); + }; + let end = n21.span.end; + n1 = Node::new_unres(Self::BinaryOp(op, n1, n21), start.to(end)).bx(); + op = op2; + n2 = n22; } } Self::BinaryOp(op, n1, n2) @@ -112,64 +103,25 @@ impl Parsable for Expr { } } -impl Operator { - pub fn presedence(&self) -> u32 { - match self { - Operator::Assign => 0, - Operator::LessThan => 1, - Operator::GreaterThan => 1, - Operator::Add => 2, - Operator::Sub => 3, - Operator::Mul => 4, - Operator::Div => 5, - Operator::Access => 6, - } - } - pub fn str(&self) -> &str { - match self { - Self::Add => "+", - Self::Sub => "-", - Self::Mul => "*", - Self::Div => "/", - Self::LessThan => "<", - Self::GreaterThan => ">", - Self::Access => ".", - Self::Assign => "=", - } - } - pub fn from_token(token: &Token) -> Option { - let Token::Symbol(symbol) = token else { - return None; - }; - Some(match symbol { - Symbol::OpenAngle => Operator::LessThan, - Symbol::CloseAngle => Operator::GreaterThan, - Symbol::Plus => Operator::Add, - Symbol::Minus => Operator::Sub, - Symbol::Asterisk => Operator::Mul, - Symbol::Slash => Operator::Div, - Symbol::Dot => Operator::Access, - Symbol::Equals => Operator::Assign, - _ => { - return None; - } +impl Resolvable> for Expr { + fn resolve(self) -> Result, ()> { + Ok(match self { + Expr::Lit(l) => Expr::Lit(l.resolve()?), + Expr::Ident(n) => Expr::Ident(n), + Expr::BinaryOp(o, e1, e2) => Expr::BinaryOp(o, e1.resolve()?, e2.resolve()?), + Expr::Block(b) => Expr::Block(b.resolve()?), + Expr::Call(f, args) => Expr::Call( + f.resolve()?, + args.into_iter() + .map(|arg| arg.resolve()) + .collect::>()?, + ), + Expr::Group(e) => Expr::Group(e.resolve()?), }) } - pub fn pad(&self) -> bool { - match self { - Self::Add => true, - Self::Sub => true, - Self::Mul => true, - Self::Div => true, - Self::LessThan => true, - Self::GreaterThan => true, - Self::Access => false, - Self::Assign => true, - } - } } -impl Debug for Expr { +impl Debug for Expr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Expr::Lit(c) => c.fmt(f)?, diff --git a/src/parser/v1/func.rs b/src/parser/v1/func.rs new file mode 100644 index 0000000..c2ff857 --- /dev/null +++ b/src/parser/v1/func.rs @@ -0,0 +1,39 @@ +use super::{ + Body, Keyword, MaybeResolved, Node, Parsable, ParserError, ParserErrors, Resolvable, Resolved, Symbol, TokenCursor, Unresolved +}; +use std::fmt::Debug; + +pub struct Function { + pub name: String, + pub body: Node, R>, +} + +impl Parsable for Function { + fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Result { + cursor.expect_kw(Keyword::Fn)?; + let name = cursor.expect_ident()?; + cursor.expect_sym(Symbol::OpenParen)?; + cursor.expect_sym(Symbol::CloseParen)?; + let body = Node::parse(cursor, errors); + Ok(Self { name, body }) + } +} + +impl Debug for Function { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("fn ")?; + f.write_str(&self.name)?; + f.write_str("() ")?; + self.body.fmt(f)?; + Ok(()) + } +} + +impl Resolvable> for Function { + fn resolve(self) -> Result, ()> { + Ok(Function { + name: self.name, + body: self.body.resolve()? + }) + } +} diff --git a/src/parser/v1/mod.rs b/src/parser/v1/mod.rs index 2a52ce8..b3d9ca7 100644 --- a/src/parser/v1/mod.rs +++ b/src/parser/v1/mod.rs @@ -6,8 +6,11 @@ mod error; mod expr; mod module; mod node; +mod op; mod token; mod val; +mod statement; +mod func; pub use body::*; pub use cursor::*; @@ -15,15 +18,17 @@ pub use error::*; pub use expr::*; pub use module::*; pub use node::*; -pub use val::*; +pub use op::*; use token::*; +pub use val::*; +pub use statement::*; pub fn parse_file(file: &str) { let mut errors = ParserErrors::new(); - let node = Node::::parse(&mut TokenCursor::from(file), &mut errors); - if let Ok(module) = node.as_ref() { - println!("{module:#?}"); - }; + let node = Module::parse_node(&mut TokenCursor::from(file), &mut errors); + if errors.errs.is_empty() { + let module = node.resolve().expect("what"); + } let out = &mut stdout(); for err in errors.errs { err.write_for(out, file).unwrap(); @@ -35,7 +40,7 @@ pub fn run_stdin() { let mut errors = ParserErrors::new(); let str = &line.expect("failed to read line"); let mut cursor = TokenCursor::from(&str[..]); - if let Ok(expr) = Node::::parse(&mut cursor, &mut errors).as_ref() { + if let Ok(expr) = Statement::parse_node(&mut cursor, &mut errors).as_ref() { println!("{:?}", expr); } let out = &mut stdout(); diff --git a/src/parser/v1/module.rs b/src/parser/v1/module.rs index 857d880..3c48968 100644 --- a/src/parser/v1/module.rs +++ b/src/parser/v1/module.rs @@ -1,19 +1,14 @@ +use super::{ + func::Function, Keyword, MaybeResolved, Node, Parsable, ParserError, ParserErrors, Resolvable, + Resolved, TokenCursor, Unresolved, +}; use std::fmt::Debug; -use super::{token::*, Body, Node, Parsable, ParserError, ParserErrors, TokenCursor}; - -#[derive(Debug)] -pub struct Module { - functions: Vec>, +pub struct Module { + pub functions: Vec, R>>, } -#[derive(Clone)] -pub struct Function { - pub name: String, - pub body: Node, -} - -impl Parsable for Module { +impl Parsable for Module { fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Result { let mut functions = Vec::new(); loop { @@ -23,30 +18,27 @@ impl Parsable for Module { if next.is_keyword(Keyword::Fn) { functions.push(Node::parse(cursor, errors)); } else { - return Err(ParserError::unexpected_token(next, "fn")); + errors.add(ParserError::unexpected_token(next, "fn")); + cursor.next(); } } } } -impl Parsable for Function { - fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Result { - cursor.expect_kw(Keyword::Fn)?; - let name = cursor.expect_ident()?; - cursor.expect_sym(Symbol::OpenParen)?; - cursor.expect_sym(Symbol::CloseParen)?; - let body = Node::parse(cursor, errors); - Ok(Self { name, body }) - } -} - -impl Debug for Function { +impl Debug for Module { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str("fn ")?; - f.write_str(&self.name)?; - f.write_str("() ")?; - self.body.fmt(f)?; - Ok(()) + self.functions.fmt(f) } } +impl Resolvable> for Module { + fn resolve(self) -> Result, ()> { + Ok(Module { + functions: self + .functions + .into_iter() + .map(|f| f.resolve()) + .collect::>()?, + }) + } +} diff --git a/src/parser/v1/node.rs b/src/parser/v1/node.rs index 1746a26..316fa05 100644 --- a/src/parser/v1/node.rs +++ b/src/parser/v1/node.rs @@ -5,9 +5,22 @@ use std::{ use super::{FileSpan, ParserError, ParserErrors, TokenCursor}; -#[derive(Clone)] -pub struct Node { - pub inner: Result, +pub trait MaybeResolved { + type Inner; +} + +pub struct Resolved; +impl MaybeResolved for Resolved { + type Inner = T; +} + +pub struct Unresolved; +impl MaybeResolved for Unresolved { + type Inner = Result; +} + +pub struct Node { + pub inner: ::Inner, pub span: FileSpan, } @@ -22,7 +35,7 @@ pub trait MaybeParsable: Sized { ) -> Result, ParserError>; } -impl Node { +impl Node { pub fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Self { let start = cursor.next_pos(); let inner = T::parse(cursor, errors).map_err(|e| errors.add(e)); @@ -34,7 +47,7 @@ impl Node { } } -impl Node { +impl Node { pub fn maybe_parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Option { let start = cursor.next_pos(); let inner = match T::maybe_parse(cursor, errors) { @@ -52,14 +65,28 @@ impl Node { } } -impl Node { - pub fn new(inner: T, span: FileSpan) -> Self { +pub trait NodeParsable { + fn parse_node(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Node + where + Self: Sized; +} +impl NodeParsable for T { + fn parse_node(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Node + where + Self: Sized, + { + Node::::parse(cursor, errors) + } +} + +impl Node { + pub fn new_unres(inner: T, span: FileSpan) -> Self { Self { inner: Ok(inner), span, } } - pub fn bx(self) -> Node> { + pub fn bx(self) -> Node, Unresolved> { Node { inner: self.inner.map(|v| Box::new(v)), span: self.span, @@ -67,28 +94,20 @@ impl Node { } } -impl Node> { - pub fn unbx(self) -> Node { - Node { - inner: self.inner.map(|v| *v), - span: self.span, - } - } -} -impl Deref for Node { - type Target = Result; +impl Deref for Node { + type Target = ::Inner; fn deref(&self) -> &Self::Target { &self.inner } } -impl DerefMut for Node { +impl DerefMut for Node { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner } } -impl Debug for Node { +impl Debug for Node { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match &self.inner { Ok(v) => v.fmt(f), @@ -96,3 +115,31 @@ impl Debug for Node { } } } + +impl Debug for Node { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.inner.fmt(f) + } +} + +pub trait Resolvable { + fn resolve(self) -> Result; +} + +impl, Res> Resolvable> for Node { + fn resolve(self) -> Result, ()> { + if let Ok(inner) = self.inner { + return Ok(Node { + inner: inner.resolve()?, + span: self.span, + }); + } + Err(()) + } +} + +impl, Res> Resolvable> for Box { + fn resolve(self) -> Result, ()> { + Ok(Box::new((*self).resolve()?)) + } +} diff --git a/src/parser/v1/op.rs b/src/parser/v1/op.rs new file mode 100644 index 0000000..5dada7e --- /dev/null +++ b/src/parser/v1/op.rs @@ -0,0 +1,71 @@ +use super::{Symbol, Token}; + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum Operator { + Add, + Sub, + Mul, + Div, + LessThan, + GreaterThan, + Access, + Assign, +} + +impl Operator { + pub fn presedence(&self) -> u32 { + match self { + Operator::Assign => 0, + Operator::LessThan => 1, + Operator::GreaterThan => 1, + Operator::Add => 2, + Operator::Sub => 3, + Operator::Mul => 4, + Operator::Div => 5, + Operator::Access => 6, + } + } + pub fn str(&self) -> &str { + match self { + Self::Add => "+", + Self::Sub => "-", + Self::Mul => "*", + Self::Div => "/", + Self::LessThan => "<", + Self::GreaterThan => ">", + Self::Access => ".", + Self::Assign => "=", + } + } + pub fn from_token(token: &Token) -> Option { + let Token::Symbol(symbol) = token else { + return None; + }; + Some(match symbol { + Symbol::OpenAngle => Operator::LessThan, + Symbol::CloseAngle => Operator::GreaterThan, + Symbol::Plus => Operator::Add, + Symbol::Minus => Operator::Sub, + Symbol::Asterisk => Operator::Mul, + Symbol::Slash => Operator::Div, + Symbol::Dot => Operator::Access, + Symbol::Equals => Operator::Assign, + _ => { + return None; + } + }) + } + pub fn pad(&self) -> bool { + match self { + Self::Add => true, + Self::Sub => true, + Self::Mul => true, + Self::Div => true, + Self::LessThan => true, + Self::GreaterThan => true, + Self::Access => false, + Self::Assign => true, + } + } +} + diff --git a/src/parser/v1/statement.rs b/src/parser/v1/statement.rs new file mode 100644 index 0000000..0b1fa83 --- /dev/null +++ b/src/parser/v1/statement.rs @@ -0,0 +1,76 @@ +use std::fmt::{Debug, Write}; +use super::{ + Expr, Keyword, MaybeResolved, Node, Parsable, ParserError, ParserErrors, Resolvable, Resolved, + Symbol, Token, TokenCursor, Unresolved, +}; + +pub enum Statement { + Let(String, Node, R>), + Return(Node, R>), + Expr(Node, R>), +} + +impl Statement { + pub fn ended_with_error(&self) -> bool { + let expr = match self { + Statement::Let(_, e) => e, + Statement::Return(e) => e, + Statement::Expr(e) => e, + }; + expr.is_err() || expr.as_ref().is_ok_and(|e| e.ended_with_error()) + } +} + +impl Parsable for Statement { + fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Result { + let next = cursor.expect_peek()?; + Ok(match next.token { + Token::Keyword(Keyword::Let) => { + cursor.next(); + let name = cursor.expect_ident()?; + cursor.expect_sym(Symbol::Equals)?; + let expr = Node::parse(cursor, errors); + Self::Let(name, expr) + } + Token::Keyword(Keyword::Return) => { + cursor.next(); + Self::Return(Node::parse(cursor, errors)) + } + _ => Self::Expr(Node::parse(cursor, errors)), + }) + } +} + +impl Resolvable> for Statement { + fn resolve(self) -> Result, ()> { + Ok(match self { + Self::Let(i, e) => Statement::Let(i, e.resolve()?), + Self::Return(e) => Statement::Return(e.resolve()?), + Self::Expr(e) => Statement::Expr(e.resolve()?), + }) + } +} + +impl Debug for Statement { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Statement::Let(n, e) => { + f.write_str("let ")?; + f.write_str(n)?; + f.write_str(" = ")?; + e.fmt(f)?; + f.write_char(';')?; + } + Statement::Return(e) => { + f.write_str("return ")?; + e.fmt(f)?; + f.write_char(';')?; + } + Statement::Expr(e) => { + e.fmt(f)?; + f.write_char(';')?; + } + } + Ok(()) + } +} diff --git a/src/parser/v1/val.rs b/src/parser/v1/val.rs index 2683ed3..8f235db 100644 --- a/src/parser/v1/val.rs +++ b/src/parser/v1/val.rs @@ -1,4 +1,4 @@ -use super::{CharCursor, MaybeParsable, ParserError, ParserErrors, Symbol, Token, TokenCursor}; +use super::{CharCursor, MaybeParsable, ParserError, ParserErrors, Resolvable, Symbol, Token, TokenCursor}; use std::fmt::Debug; #[derive(Clone, PartialEq, Eq)] @@ -85,6 +85,12 @@ pub fn string_from(cursor: &mut CharCursor) -> Result { } } +impl Resolvable for Literal { + fn resolve(self) -> Result { + Ok(self) + } +} + impl Debug for Literal { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self {