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