Statement parsing

This commit is contained in:
bad 2022-04-23 16:27:11 +02:00
parent 91f2a945c5
commit 3a5d81c8fb
13 changed files with 122 additions and 47 deletions

View file

View file

@ -1,2 +1,3 @@
pub mod expression; pub mod expression;
pub mod statement;
pub mod parser; pub mod parser;

View file

@ -1,4 +1,5 @@
use super::expression::expression_node; use super::expression::expression_node;
use super::statement::statement_node;
use crate::error::ErrorLocationWrapper; use crate::error::ErrorLocationWrapper;
use crate::lexer::{token, token::TokenType}; use crate::lexer::{token, token::TokenType};
@ -28,32 +29,30 @@ pub struct Parser<'a, T: Iterator<Item = token::Token<'a>>> {
pub(super) token_iter: iter::Peekable<T>, pub(super) token_iter: iter::Peekable<T>,
} }
pub type ParseAllResult = StdResult<Vec<statement_node::Statement>, Vec<ASTParsingError>>;
impl<'a, T: Iterator<Item = token::Token<'a>>> Parser<'a, T> { impl<'a, T: Iterator<Item = token::Token<'a>>> Parser<'a, T> {
pub fn new(iter: T) -> Parser<'a, T> { pub fn new(iter: T) -> Parser<'a, T> {
Parser { Parser {
token_iter: iter.peekable(), token_iter: iter.peekable(),
} }
} }
pub fn parse_all( pub fn parse_all(&mut self) -> ParseAllResult {
&mut self, let mut res = Ok(Vec::new());
) -> StdResult<Vec<expression_node::ExpressionNode>, Vec<ASTParsingError>> {
let mut tokens = Vec::new();
let mut errors = Vec::new();
while self.token_iter.peek().is_some() { while !matches!(self.token_iter.peek().unwrap().token_type, token::TokenType::Eof) {
match self.expression() { match self.statement() {
Ok(token) => { Ok(s) => {
if errors.is_empty() { if let Ok(ref mut v) = res {
tokens.push(token) v.push(s)
} }
} }
Err(e) => errors.push(e), Err(e) => match res {
Ok(_) => res = Err(vec![e]),
Err(ref mut v) => v.push(e),
},
} }
} }
if errors.is_empty() { res
Ok(tokens)
} else {
Err(errors)
}
} }
} }

2
src/ast/statement/mod.rs Normal file
View file

@ -0,0 +1,2 @@
pub mod statement_node;
mod statement_parser;

View file

@ -0,0 +1,24 @@
use crate::ast::expression::expression_node::ExpressionNode;
use from_variants::FromVariants;
#[derive(FromVariants, Debug)]
pub enum Statement {
Expression(ExpressionStatement),
Print(PrintStatement),
}
#[derive(Debug)]
pub struct ExpressionStatement(ExpressionNode);
impl ExpressionStatement {
pub fn new(expr: ExpressionNode) -> Self {
Self(expr)
}
}
#[derive(Debug)]
pub struct PrintStatement(ExpressionNode);
impl PrintStatement {
pub fn new(expr: ExpressionNode) -> Self {
Self(expr)
}
}

View file

@ -0,0 +1,37 @@
use super::statement_node::{ExpressionStatement, Statement, PrintStatement};
use crate::{
ast::parser::{ASTParsingError, Parser, Result},
lexer::token,
};
impl<'a, T: Iterator<Item = token::Token<'a>>> Parser<'a, T> {
pub fn statement(&mut self) -> Result<Statement> {
if let Some(_) = self
.token_iter
.next_if(|t| matches!(t.token_type, token::TokenType::Print))
{
self.print_statement()
} else {
self.expression_statement()
}
}
fn print_statement(&mut self) -> Result<Statement> {
let expr = self.expression()?;
if let token::TokenType::Semicolon = self.token_iter.peek().unwrap().token_type {
self.token_iter.next();
Ok(PrintStatement::new(expr).into())
} else {
panic!();
}
}
fn expression_statement(&mut self) -> Result<Statement> {
let expr = self.expression()?;
if let token::TokenType::Semicolon = self.token_iter.peek().unwrap().token_type {
self.token_iter.next();
Ok(ExpressionStatement::new(expr).into())
} else {
panic!();
}
}
}

View file

@ -1,21 +1,8 @@
use std::fmt::Display; use super::{RuntimeError, types::Value};
use super::Interpret;
use super::types::Value;
use crate::ast::expression::expression_node; use crate::ast::expression::expression_node;
#[derive(Debug)]
pub struct RuntimeError;
impl Display for RuntimeError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "A runtime error occured")
}
}
impl std::error::Error for RuntimeError {}
pub trait Interpret {
fn interpret(&self) -> Result<Value, RuntimeError>;
}
impl Interpret for expression_node::ExpressionNode { impl Interpret for expression_node::ExpressionNode {
fn interpret(&self) -> Result<Value, RuntimeError> { fn interpret(&self) -> Result<Value, RuntimeError> {

View file

@ -0,0 +1,7 @@
mod expression_interpreter;
pub use super::{error::RuntimeError, types};
use super::types::Value;
pub trait Interpret {
fn interpret(&self) -> Result<Value, RuntimeError>;
}

11
src/interpreter/error.rs Normal file
View file

@ -0,0 +1,11 @@
use std::fmt::Display;
#[derive(Debug)]
pub struct RuntimeError;
impl Display for RuntimeError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "A runtime error occured")
}
}
impl std::error::Error for RuntimeError {}

View file

@ -1,2 +1,3 @@
pub mod ast_walker; pub mod ast_walker;
pub mod types; pub mod types;
pub mod error;

View file

@ -25,26 +25,26 @@ impl<'a, 'b> Lexer<'a, 'b> {
} }
pub fn scan_tokens(&mut self) -> Result<Vec<token::Token<'b>>, Vec<LexingError>> { pub fn scan_tokens(&mut self) -> Result<Vec<token::Token<'b>>, Vec<LexingError>> {
let mut tokens = Vec::new(); let mut res = Ok(Vec::new());
let mut errors = Vec::new();
while self.source_iter.peek().is_some() { while self.source_iter.peek().is_some() {
match self.scan_token() { match self.scan_token() {
Ok(Some(token)) => { Ok(Some(token)) => if let Ok(ref mut v) = res {
if errors.is_empty() { v.push(token)
tokens.push(token)
}
} }
Ok(None) => (), Ok(None) => (),
Err(e) => errors.push(e), Err(e) => match res {
Ok(_) => res = Err(vec![e]),
Err(ref mut v) => v.push(e)
}
} }
} }
if errors.is_empty() { if let Ok(ref mut v) = res {
Ok(tokens) v.push(self.get_token(token::TokenType::Eof));
} else {
Err(errors)
} }
res
} }
fn get_token(&self, token_type: token::TokenType) -> token::Token<'b> { fn get_token(&self, token_type: token::TokenType) -> token::Token<'b> {

View file

@ -47,4 +47,5 @@ pub enum TokenType {
True, True,
Let, Let,
While, While,
Eof,
} }

View file

@ -3,8 +3,8 @@ pub mod error;
pub mod interpreter; pub mod interpreter;
pub mod lexer; pub mod lexer;
use ast::expression::expression_node::ExpressionNode; use ast::parser::ParseAllResult;
use ast::parser::ASTParsingError; use ast::statement::statement_node::Statement;
use interpreter::ast_walker::{Interpret, RuntimeError}; use interpreter::ast_walker::{Interpret, RuntimeError};
use interpreter::types::Value; use interpreter::types::Value;
use lexer::{token::Token, Lexer, LexingError}; use lexer::{token::Token, Lexer, LexingError};
@ -17,13 +17,18 @@ pub fn lex<'a, 'b>(
lexer.scan_tokens() lexer.scan_tokens()
} }
pub fn parse(tokens: Vec<Token>) -> Result<Vec<ExpressionNode>, Vec<ASTParsingError>> { pub fn parse(tokens: Vec<Token>) -> ParseAllResult {
let mut parser = crate::ast::parser::Parser::new(tokens.into_iter()); let mut parser = crate::ast::parser::Parser::new(tokens.into_iter());
parser.parse_all() parser.parse_all()
} }
pub fn exec(nodes: Vec<ExpressionNode>) -> Result<Value, RuntimeError> { pub fn exec(nodes: Vec<Statement>) -> Result<Value, RuntimeError> {
nodes[0].interpret() todo!();
/*
for statement in nodes {
//statement.interpret()?;
}
*/
} }
pub fn run(code: &str) -> Result<Value, run::Error> { pub fn run(code: &str) -> Result<Value, run::Error> {