jugando
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
#![feature(box_patterns)]
|
||||
|
||||
mod util;
|
||||
mod v1;
|
||||
mod v2;
|
||||
|
||||
@@ -2,38 +2,30 @@ use std::io::{stdout, BufRead, BufReader};
|
||||
|
||||
mod parser;
|
||||
|
||||
use parser::{Module, Node, NodeContainer, Statement, TokenCursor};
|
||||
use parser::{Module, Node, ParserErrors, Statement, TokenCursor};
|
||||
|
||||
pub fn parse_file(file: &str) {
|
||||
let node = Node::<Module>::parse(&mut TokenCursor::from(file));
|
||||
match node.inner {
|
||||
Err(err) => err.write_for(&mut stdout(), file).unwrap(),
|
||||
Ok(module) => {
|
||||
println!("{module:#?}");
|
||||
print_errors(module.children(), file)
|
||||
},
|
||||
let mut errors = ParserErrors::new();
|
||||
let node = Node::<Module>::parse(&mut TokenCursor::from(file), &mut errors);
|
||||
if let Ok(module) = node.as_ref() {
|
||||
println!("{module:#?}");
|
||||
};
|
||||
}
|
||||
|
||||
pub fn print_errors(nodes: Vec<Node<Box<dyn NodeContainer>>>, file: &str) {
|
||||
for node in &nodes {
|
||||
if let Err(err) = &node.inner {
|
||||
err.write_for(&mut stdout(), file).unwrap();
|
||||
}
|
||||
}
|
||||
for node in nodes {
|
||||
print_errors(node.children(), file)
|
||||
for err in errors.errs {
|
||||
err.write_for(&mut stdout(), file).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_stdin() {
|
||||
for line in BufReader::new(std::io::stdin()).lines() {
|
||||
let mut errors = ParserErrors::new();
|
||||
let str = &line.expect("failed to read line");
|
||||
let mut cursor = TokenCursor::from(&str[..]);
|
||||
let out = &mut stdout();
|
||||
match Node::<Statement>::parse(&mut cursor).inner {
|
||||
Ok(expr) => println!("{:?}", expr),
|
||||
Err(err) => err.write_for(out, str).unwrap(),
|
||||
if let Ok(expr) = Node::<Statement>::parse(&mut cursor, &mut errors).as_ref() {
|
||||
println!("{:?}", expr);
|
||||
}
|
||||
for err in errors.errs {
|
||||
err.write_for(&mut stdout(), str).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use std::fmt::{Debug, Write};
|
||||
|
||||
use super::{
|
||||
token::{Keyword, Symbol, Token}, Node, NodeContainer, Parsable
|
||||
token::{Keyword, Symbol, Token},
|
||||
Node, Parsable, ParserErrors,
|
||||
};
|
||||
use crate::util::Padder;
|
||||
|
||||
@@ -19,8 +20,19 @@ pub enum Statement {
|
||||
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) -> Result<Self, ParserError> {
|
||||
fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Result<Self, ParserError> {
|
||||
let mut statements = Vec::new();
|
||||
let statement_end = &[Symbol::Semicolon, Symbol::CloseCurly];
|
||||
cursor.expect_sym(Symbol::OpenCurly)?;
|
||||
@@ -28,54 +40,51 @@ impl Parsable for Body {
|
||||
cursor.next();
|
||||
return Ok(Self { statements });
|
||||
}
|
||||
let mut expect_semi = false;
|
||||
loop {
|
||||
let next = cursor.expect_peek()?;
|
||||
if next.is_symbol(Symbol::CloseCurly) {
|
||||
cursor.next();
|
||||
return Ok(Self { statements });
|
||||
}
|
||||
statements.push(Node::parse(cursor));
|
||||
let next = cursor.expect_next()?;
|
||||
match next.token {
|
||||
Token::Symbol(Symbol::Semicolon) => continue,
|
||||
Token::Symbol(Symbol::CloseCurly) => return Ok(Self { statements }),
|
||||
_ => {
|
||||
let start = next.span.start;
|
||||
cursor
|
||||
.seek(|t| t.is_symbol_and(|s| statement_end.contains(&s)))
|
||||
.ok_or(ParserError::unexpected_end())?;
|
||||
let end = cursor.prev_end();
|
||||
let next = cursor.expect_next()?;
|
||||
let span = start.to(end);
|
||||
statements.push(Node::err(ParserError {
|
||||
msg: "Unexpected tokens".to_string(),
|
||||
spans: vec![span],
|
||||
}, span));
|
||||
if next.is_symbol(Symbol::CloseCurly) {
|
||||
return Ok(Self { statements });
|
||||
}
|
||||
}
|
||||
if next.is_symbol(Symbol::Semicolon) {
|
||||
cursor.next();
|
||||
expect_semi = false;
|
||||
continue;
|
||||
} else if expect_semi {
|
||||
errors.add(ParserError {
|
||||
msg: "expected ';'".to_string(),
|
||||
spans: vec![cursor.next_pos().char_span()],
|
||||
});
|
||||
}
|
||||
let statement: Node<Statement> = Node::parse(cursor, errors);
|
||||
expect_semi = true;
|
||||
if statement.is_err() || statement.as_ref().is_ok_and(|s| s.ended_with_error()) {
|
||||
let res = cursor
|
||||
.seek(|t| t.is_symbol_and(|s| statement_end.contains(&s)))
|
||||
.ok_or(ParserError::unexpected_end())?;
|
||||
}
|
||||
statements.push(statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parsable for Statement {
|
||||
fn parse(cursor: &mut TokenCursor) -> Result<Self, ParserError> {
|
||||
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);
|
||||
let expr = Node::parse(cursor, errors);
|
||||
Self::Let(name, expr)
|
||||
}
|
||||
Token::Keyword(Keyword::Return) => {
|
||||
cursor.next();
|
||||
Self::Return(Node::parse(cursor))
|
||||
Self::Return(Node::parse(cursor, errors))
|
||||
}
|
||||
_ => Self::Expr(Node::parse(cursor)),
|
||||
_ => Self::Expr(Node::parse(cursor, errors)),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -120,19 +129,3 @@ impl Debug for Body {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeContainer for Body {
|
||||
fn children(&self) -> Vec<Node<Box<dyn NodeContainer>>> {
|
||||
self.statements.iter().map(|f| f.containerr()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeContainer for Statement {
|
||||
fn children(&self) -> Vec<Node<Box<dyn NodeContainer>>> {
|
||||
match self {
|
||||
Statement::Let(_, e) => vec![e.containerr()],
|
||||
Statement::Return(e) => vec![e.containerr()],
|
||||
Statement::Expr(e) => vec![e.containerr()],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ impl ParserError {
|
||||
let t = &inst.token;
|
||||
ParserError::from_instances(
|
||||
&[inst],
|
||||
format!("Unexpected token {t:?}; expected {expected}"),
|
||||
format!("unexpected token {t:?}; expected {expected}"),
|
||||
)
|
||||
}
|
||||
pub fn write_for(&self, writer: &mut impl std::io::Write, file: &str) -> std::io::Result<()> {
|
||||
@@ -53,6 +53,9 @@ impl ParserError {
|
||||
}
|
||||
|
||||
impl ParserErrors {
|
||||
pub fn new() -> Self {
|
||||
Self { errs: Vec::new() }
|
||||
}
|
||||
pub fn add(&mut self, err: ParserError) {
|
||||
self.errs.push(err);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
use std::fmt::{Debug, Write};
|
||||
|
||||
use super::token::{Symbol, Token};
|
||||
use super::{Body, Node, NodeContainer, Parsable, ParserError, TokenCursor, Val};
|
||||
use super::{Body, Node, Parsable, ParserError, ParserErrors, TokenCursor, Val};
|
||||
|
||||
pub type ExprNode = Node<Box<Expr>>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Expr {
|
||||
Val(Node<Val>),
|
||||
Ident(String),
|
||||
BinaryOp(Operator, Node<Box<Expr>>, Node<Box<Expr>>),
|
||||
BinaryOp(Operator, ExprNode, ExprNode),
|
||||
Block(Node<Body>),
|
||||
Call(Node<Box<Expr>>, Vec<Node<Expr>>),
|
||||
Call(ExprNode, Vec<Node<Expr>>),
|
||||
Group(ExprNode),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
@@ -21,29 +24,44 @@ pub enum Operator {
|
||||
LessThan,
|
||||
GreaterThan,
|
||||
Access,
|
||||
Assign,
|
||||
}
|
||||
|
||||
impl Expr {
|
||||
pub fn ended_with_error(&self) -> bool {
|
||||
match self {
|
||||
Expr::Val(_) => false,
|
||||
Expr::Ident(_) => false,
|
||||
Expr::BinaryOp(_, _, e) => e.is_err() || e.as_ref().is_ok_and(|e| e.ended_with_error()),
|
||||
Expr::Block(b) => b.is_err(),
|
||||
Expr::Call(_, _) => false,
|
||||
Expr::Group(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parsable for Expr {
|
||||
fn parse(cursor: &mut TokenCursor) -> Result<Self, ParserError> {
|
||||
fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Result<Self, ParserError> {
|
||||
let start = cursor.next_pos();
|
||||
let Some(next) = cursor.peek() else {
|
||||
return Ok(Expr::Val(Node::new(
|
||||
Val::Unit,
|
||||
cursor.next_pos().char_span(),
|
||||
)));
|
||||
};
|
||||
let next = cursor.expect_peek()?;
|
||||
let mut e1 = if next.is_symbol(Symbol::OpenParen) {
|
||||
cursor.next();
|
||||
let expr = Node::parse(cursor);
|
||||
if expr.is_ok() {
|
||||
cursor.expect_sym(Symbol::CloseParen)?;
|
||||
} else {
|
||||
if cursor.expect_peek()?.is_symbol(Symbol::CloseParen) {
|
||||
cursor.next();
|
||||
return Ok(Expr::Val(Node::new(
|
||||
Val::Unit,
|
||||
cursor.next_pos().char_span(),
|
||||
)));
|
||||
}
|
||||
let expr = Node::parse(cursor, errors).bx();
|
||||
if expr.is_err() {
|
||||
cursor.seek_sym(Symbol::CloseParen);
|
||||
}
|
||||
expr.take()?
|
||||
cursor.expect_sym(Symbol::CloseParen)?;
|
||||
Self::Group(expr)
|
||||
} else if next.is_symbol(Symbol::OpenCurly) {
|
||||
Self::Block(Node::parse(cursor))
|
||||
} else if let Some(val) = Node::maybe_parse(cursor) {
|
||||
Self::Block(Node::parse(cursor, errors))
|
||||
} else if let Some(val) = Node::maybe_parse(cursor, errors) {
|
||||
Self::Val(val)
|
||||
} else {
|
||||
let next = cursor.peek().unwrap();
|
||||
@@ -54,10 +72,7 @@ impl Parsable for Expr {
|
||||
Self::Ident(name)
|
||||
}
|
||||
_ => {
|
||||
return Ok(Expr::Val(Node::new(
|
||||
Val::Unit,
|
||||
cursor.next_pos().char_span(),
|
||||
)))
|
||||
return Err(ParserError::unexpected_token(next, "an expression"));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -66,7 +81,7 @@ impl Parsable for Expr {
|
||||
};
|
||||
while next.is_symbol(Symbol::OpenParen) {
|
||||
cursor.next();
|
||||
let inner = Node::parse(cursor);
|
||||
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]);
|
||||
@@ -79,18 +94,18 @@ impl Parsable for Expr {
|
||||
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 n2 = Node::<Self>::parse(cursor);
|
||||
if let Ok(Self::BinaryOp(op2, n21, n22)) = &*n2 {
|
||||
let mut n2 = Node::parse(cursor, errors).bx();
|
||||
if let Ok(box Self::BinaryOp(op2, n21, n22)) = 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().unbx();
|
||||
n2 = n22.clone();
|
||||
}
|
||||
}
|
||||
Self::BinaryOp(op, n1, n2.bx())
|
||||
Self::BinaryOp(op, n1, n2)
|
||||
} else {
|
||||
e1
|
||||
})
|
||||
@@ -100,13 +115,14 @@ impl Parsable for Expr {
|
||||
impl Operator {
|
||||
pub fn presedence(&self) -> u32 {
|
||||
match self {
|
||||
Operator::LessThan => 0,
|
||||
Operator::GreaterThan => 0,
|
||||
Operator::Add => 1,
|
||||
Operator::Sub => 2,
|
||||
Operator::Mul => 3,
|
||||
Operator::Div => 4,
|
||||
Operator::Access => 5,
|
||||
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 {
|
||||
@@ -118,6 +134,7 @@ impl Operator {
|
||||
Self::LessThan => "<",
|
||||
Self::GreaterThan => ">",
|
||||
Self::Access => ".",
|
||||
Self::Assign => "=",
|
||||
}
|
||||
}
|
||||
pub fn from_token(token: &Token) -> Option<Self> {
|
||||
@@ -132,6 +149,7 @@ impl Operator {
|
||||
Symbol::Asterisk => Operator::Mul,
|
||||
Symbol::Slash => Operator::Div,
|
||||
Symbol::Dot => Operator::Access,
|
||||
Symbol::Equals => Operator::Assign,
|
||||
_ => {
|
||||
return None;
|
||||
}
|
||||
@@ -139,13 +157,14 @@ impl Operator {
|
||||
}
|
||||
pub fn pad(&self) -> bool {
|
||||
match self {
|
||||
Operator::Add => true,
|
||||
Operator::Sub => true,
|
||||
Operator::Mul => true,
|
||||
Operator::Div => true,
|
||||
Operator::LessThan => true,
|
||||
Operator::GreaterThan => true,
|
||||
Operator::Access => false,
|
||||
Self::Add => true,
|
||||
Self::Sub => true,
|
||||
Self::Mul => true,
|
||||
Self::Div => true,
|
||||
Self::LessThan => true,
|
||||
Self::GreaterThan => true,
|
||||
Self::Access => false,
|
||||
Self::Assign => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,22 +196,8 @@ impl Debug for Expr {
|
||||
}
|
||||
f.write_char(')')?;
|
||||
}
|
||||
Expr::Group(inner) => inner.fmt(f)?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeContainer for Expr {
|
||||
fn children(&self) -> Vec<Node<Box<dyn NodeContainer>>> {
|
||||
match self {
|
||||
Expr::Val(_) => Vec::new(),
|
||||
Expr::Ident(_) => Vec::new(),
|
||||
Expr::BinaryOp(_, e1, e2) => vec![e1.container(), e2.container()],
|
||||
Expr::Block(b) => vec![b.containerr()],
|
||||
Expr::Call(e1, rest) => [e1.container()]
|
||||
.into_iter()
|
||||
.chain(rest.iter().map(|e| e.containerr()))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,14 +29,14 @@ pub struct Function {
|
||||
}
|
||||
|
||||
impl Parsable for Module {
|
||||
fn parse(cursor: &mut TokenCursor) -> Result<Self, ParserError> {
|
||||
fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Result<Self, ParserError> {
|
||||
let mut functions = Vec::new();
|
||||
loop {
|
||||
let Some(next) = cursor.peek() else {
|
||||
return Ok(Self { functions });
|
||||
};
|
||||
if next.is_keyword(Keyword::Fn) {
|
||||
functions.push(Node::parse(cursor));
|
||||
functions.push(Node::parse(cursor, errors));
|
||||
} else {
|
||||
return Err(ParserError::unexpected_token(next, "fn"));
|
||||
}
|
||||
@@ -45,12 +45,12 @@ impl Parsable for Module {
|
||||
}
|
||||
|
||||
impl Parsable for Function {
|
||||
fn parse(cursor: &mut TokenCursor) -> Result<Self, ParserError> {
|
||||
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);
|
||||
let body = Node::parse(cursor, errors);
|
||||
Ok(Self { name, body })
|
||||
}
|
||||
}
|
||||
@@ -65,14 +65,3 @@ impl Debug for Function {
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeContainer for Module {
|
||||
fn children(&self) -> Vec<Node<Box<dyn NodeContainer>>> {
|
||||
self.functions.iter().map(|f| f.containerr()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeContainer for Function {
|
||||
fn children(&self) -> Vec<Node<Box<dyn NodeContainer>>> {
|
||||
vec![self.body.containerr()]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,39 +3,29 @@ use std::{
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
|
||||
use super::{FileSpan, ParserError, TokenCursor};
|
||||
use super::{FileSpan, ParserError, ParserErrors, TokenCursor};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Node<T> {
|
||||
pub inner: Result<T, ParserError>,
|
||||
pub inner: Result<T, ()>,
|
||||
pub span: FileSpan,
|
||||
}
|
||||
|
||||
pub trait Parsable: Sized {
|
||||
fn parse(cursor: &mut TokenCursor) -> Result<Self, ParserError>;
|
||||
fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Result<Self, ParserError>;
|
||||
}
|
||||
|
||||
pub trait MaybeParsable: Sized {
|
||||
fn maybe_parse(cursor: &mut TokenCursor) -> Result<Option<Self>, ParserError>;
|
||||
}
|
||||
|
||||
pub trait NodeContainer {
|
||||
fn children(&self) -> Vec<Node<Box<dyn NodeContainer>>>;
|
||||
}
|
||||
|
||||
impl<T: NodeContainer + ?Sized> NodeContainer for Node<Box<T>> {
|
||||
fn children(&self) -> Vec<Node<Box<dyn NodeContainer>>> {
|
||||
match &self.inner {
|
||||
Ok(v) => v.children(),
|
||||
Err(_) => Vec::new(),
|
||||
}
|
||||
}
|
||||
fn maybe_parse(
|
||||
cursor: &mut TokenCursor,
|
||||
errors: &mut ParserErrors,
|
||||
) -> Result<Option<Self>, ParserError>;
|
||||
}
|
||||
|
||||
impl<T: Parsable> Node<T> {
|
||||
pub fn parse(cursor: &mut TokenCursor) -> Self {
|
||||
pub fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Self {
|
||||
let start = cursor.next_pos();
|
||||
let inner = T::parse(cursor);
|
||||
let inner = T::parse(cursor, errors).map_err(|e| errors.add(e));
|
||||
let end = cursor.prev_end();
|
||||
Self {
|
||||
inner,
|
||||
@@ -45,11 +35,14 @@ impl<T: Parsable> Node<T> {
|
||||
}
|
||||
|
||||
impl<T: MaybeParsable> Node<T> {
|
||||
pub fn maybe_parse(cursor: &mut TokenCursor) -> Option<Self> {
|
||||
pub fn maybe_parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Option<Self> {
|
||||
let start = cursor.next_pos();
|
||||
let inner = match T::maybe_parse(cursor) {
|
||||
let inner = match T::maybe_parse(cursor, errors) {
|
||||
Ok(v) => Ok(v?),
|
||||
Err(e) => Err(e),
|
||||
Err(e) => {
|
||||
errors.add(e);
|
||||
Err(())
|
||||
}
|
||||
};
|
||||
let end = cursor.prev_end();
|
||||
Some(Self {
|
||||
@@ -66,15 +59,6 @@ impl<T> Node<T> {
|
||||
span,
|
||||
}
|
||||
}
|
||||
pub fn err(inner: ParserError, span: FileSpan) -> Self {
|
||||
Self {
|
||||
inner: Err(inner),
|
||||
span,
|
||||
}
|
||||
}
|
||||
pub fn take(self) -> Result<T, ParserError> {
|
||||
self.inner
|
||||
}
|
||||
pub fn bx(self) -> Node<Box<T>> {
|
||||
Node {
|
||||
inner: self.inner.map(|v| Box::new(v)),
|
||||
@@ -83,15 +67,6 @@ impl<T> Node<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: NodeContainer + Clone + 'static> Node<T> {
|
||||
pub fn containerr(&self) -> Node<Box<dyn NodeContainer>> {
|
||||
Node {
|
||||
inner: self.clone().inner.map(|v| Box::new(v) as Box<dyn NodeContainer>),
|
||||
span: self.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Node<Box<T>> {
|
||||
pub fn unbx(self) -> Node<T> {
|
||||
Node {
|
||||
@@ -100,17 +75,8 @@ impl<T> Node<Box<T>> {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T: NodeContainer + Clone + 'static> Node<Box<T>> {
|
||||
pub fn container(&self) -> Node<Box<dyn NodeContainer>> {
|
||||
Node {
|
||||
inner: self.clone().inner.map(|v| v as Box<dyn NodeContainer>),
|
||||
span: self.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for Node<T> {
|
||||
type Target = Result<T, ParserError>;
|
||||
type Target = Result<T, ()>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ impl FilePos {
|
||||
}
|
||||
|
||||
const BEFORE: usize = 1;
|
||||
const AFTER: usize = 1;
|
||||
const AFTER: usize = 0;
|
||||
|
||||
impl FileSpan {
|
||||
pub fn at(pos: FilePos) -> Self {
|
||||
@@ -70,11 +70,11 @@ impl FileSpan {
|
||||
"^".repeat(self.end.col + 1)
|
||||
)?;
|
||||
}
|
||||
for i in 0..AFTER {
|
||||
if let Some(next) = lines.next() {
|
||||
writeln!(writer, "{:>width$} | {}", self.end.line + i + 1, next)?;
|
||||
}
|
||||
}
|
||||
// for i in 0..AFTER {
|
||||
// if let Some(next) = lines.next() {
|
||||
// writeln!(writer, "{:>width$} | {}", self.end.line + i + 1, next)?;
|
||||
// }
|
||||
// }
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ pub enum Token {
|
||||
Keyword(Keyword),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TokenInstance {
|
||||
pub token: Token,
|
||||
pub span: FileSpan,
|
||||
|
||||
@@ -27,6 +27,7 @@ pub enum Symbol {
|
||||
CloseAngle,
|
||||
SingleQuote,
|
||||
DoubleQuote,
|
||||
Bang,
|
||||
}
|
||||
|
||||
impl Symbol {
|
||||
@@ -57,6 +58,7 @@ impl Symbol {
|
||||
'.' => Self::Dot,
|
||||
'\'' => Self::SingleQuote,
|
||||
'"' => Self::DoubleQuote,
|
||||
'!' => Self::Bang,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@@ -88,30 +90,30 @@ impl Symbol {
|
||||
}
|
||||
pub fn str(&self) -> &str {
|
||||
match self {
|
||||
Symbol::Semicolon => ";",
|
||||
Symbol::Colon => ":",
|
||||
Symbol::DoubleColon => "::",
|
||||
Symbol::Equals => "=",
|
||||
Symbol::DoubleEquals => "==",
|
||||
Symbol::Arrow => "->",
|
||||
Symbol::DoubleArrow => "=>",
|
||||
Symbol::Plus => "+",
|
||||
Symbol::Minus => "-",
|
||||
Symbol::Asterisk => "*",
|
||||
Symbol::Slash => "/",
|
||||
Symbol::DoubleSlash => "//",
|
||||
Symbol::Dot => ".",
|
||||
Symbol::OpenParen => "(",
|
||||
Symbol::CloseParen => ")",
|
||||
Symbol::OpenCurly => "{",
|
||||
Symbol::CloseCurly => "}",
|
||||
Symbol::OpenSquare => "[",
|
||||
Symbol::CloseSquare => "]",
|
||||
Symbol::OpenAngle => "<",
|
||||
Symbol::CloseAngle => ">",
|
||||
Symbol::SingleQuote => "'",
|
||||
Symbol::DoubleQuote => "\"",
|
||||
|
||||
Self::Semicolon => ";",
|
||||
Self::Colon => ":",
|
||||
Self::DoubleColon => "::",
|
||||
Self::Equals => "=",
|
||||
Self::DoubleEquals => "==",
|
||||
Self::Arrow => "->",
|
||||
Self::DoubleArrow => "=>",
|
||||
Self::Plus => "+",
|
||||
Self::Minus => "-",
|
||||
Self::Asterisk => "*",
|
||||
Self::Slash => "/",
|
||||
Self::DoubleSlash => "//",
|
||||
Self::Dot => ".",
|
||||
Self::OpenParen => "(",
|
||||
Self::CloseParen => ")",
|
||||
Self::OpenCurly => "{",
|
||||
Self::CloseCurly => "}",
|
||||
Self::OpenSquare => "[",
|
||||
Self::CloseSquare => "]",
|
||||
Self::OpenAngle => "<",
|
||||
Self::CloseAngle => ">",
|
||||
Self::SingleQuote => "'",
|
||||
Self::DoubleQuote => "\"",
|
||||
Self::Bang => "!",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::{CharCursor, MaybeParsable, NodeContainer, ParserError, Symbol, Token, TokenCursor};
|
||||
use super::{CharCursor, MaybeParsable, ParserError, ParserErrors, Symbol, Token, TokenCursor};
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
@@ -17,7 +17,7 @@ pub struct Number {
|
||||
}
|
||||
|
||||
impl MaybeParsable for Val {
|
||||
fn maybe_parse(cursor: &mut TokenCursor) -> Result<Option<Self>, ParserError> {
|
||||
fn maybe_parse(cursor: &mut TokenCursor, _: &mut ParserErrors) -> Result<Option<Self>, ParserError> {
|
||||
let inst = cursor.expect_peek()?;
|
||||
let mut res = match &inst.token {
|
||||
Token::Symbol(Symbol::SingleQuote) => {
|
||||
|
||||
Reference in New Issue
Block a user