From 1fbc353ebf2cb0a873d66b91f93e1c11f8d406ae Mon Sep 17 00:00:00 2001 From: Araozu Date: Thu, 21 Sep 2023 20:52:55 -0500 Subject: [PATCH] Extract params list parsing --- src/syntax/ast.rs | 4 ++ src/syntax/block.rs | 32 ++++++----- src/syntax/function_declaration.rs | 87 +++++++++++------------------- src/syntax/mod.rs | 3 +- src/syntax/params_list.rs | 47 ++++++++++++++++ src/syntax/utils.rs | 44 --------------- 6 files changed, 102 insertions(+), 115 deletions(-) create mode 100644 src/syntax/params_list.rs diff --git a/src/syntax/ast.rs b/src/syntax/ast.rs index 2ea3db8..e262536 100644 --- a/src/syntax/ast.rs +++ b/src/syntax/ast.rs @@ -11,11 +11,15 @@ pub enum TopLevelDeclaration { #[derive(Debug)] pub struct FunctionDeclaration { pub identifier: Box, + pub params_list: Box, } #[derive(Debug)] pub struct Block {} +#[derive(Debug)] +pub struct ParamsList {} + #[derive(Debug)] pub enum Binding { Val(ValBinding), diff --git a/src/syntax/block.rs b/src/syntax/block.rs index 65c2909..37fd142 100644 --- a/src/syntax/block.rs +++ b/src/syntax/block.rs @@ -1,6 +1,6 @@ use crate::{ + error_handling::SyntaxError, lexic::token::{Token, TokenType}, - syntax::{utils::expect_token_w, SyntaxResult}, }; use super::{ast::Block, utils::parse_token_type, ParseResult}; @@ -19,17 +19,25 @@ pub fn parse_block<'a>(tokens: &'a Vec, pos: usize) -> ParseResult t, - Err(Some(SyntaxResult::Err(err))) => return ParseResult::Err(err), - _ => panic!("parse_block: invalid state"), - }; + let (_closing_brace, next_pos) = + match parse_token_type(tokens, current_pos, TokenType::RightBrace) { + ParseResult::Ok(t, next) => (t, next), + ParseResult::Err(err) => return ParseResult::Err(err), + ParseResult::Mismatch(t) => { + return ParseResult::Err(SyntaxError { + reason: String::from("Expected a closing brace after the block body."), + error_start: t.position, + error_end: t.get_end_position(), + }); + } + ParseResult::Unmatched => { + return ParseResult::Err(SyntaxError { + reason: String::from("Expected a closing brace after the block body."), + error_start: opening_brace.position, + error_end: opening_brace.get_end_position(), + }); + } + }; current_pos = next_pos; ParseResult::Ok(Block {}, current_pos) diff --git a/src/syntax/function_declaration.rs b/src/syntax/function_declaration.rs index 07944e1..989c2ce 100644 --- a/src/syntax/function_declaration.rs +++ b/src/syntax/function_declaration.rs @@ -1,5 +1,3 @@ -use std::thread::current; - use crate::{ error_handling::SyntaxError, lexic::token::{Token, TokenType}, @@ -7,10 +5,11 @@ use crate::{ }; use super::{ - ast::{FunctionDeclaration, TopLevelDeclaration}, + ast::{FunctionDeclaration, ParamsList}, block::parse_block, - utils::{expect_token_w, parse_token_type, try_token_type}, - ParseResult, SyntaxResult, + params_list::parse_params_list, + utils::{parse_token_type, try_token_type}, + ParseResult, }; pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult { @@ -45,51 +44,24 @@ pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult (id, next), - ParseResult::Err(err) => return ParseResult::Err(err), - ParseResult::Mismatch(wrong_token) => { - return ParseResult::Err(SyntaxError { - reason: String::from( - "Expected an opening paren afted the function identifier.", - ), - error_start: wrong_token.position, - error_end: wrong_token.get_end_position(), - }); - } - ParseResult::Unmatched => { - return ParseResult::Err(SyntaxError { - reason: String::from( - "Expected an opening paren afted the function identifier.", - ), - error_start: identifier.position, - error_end: identifier.get_end_position(), - }); - } - }; - current_pos = next_pos; - - let (closing_paren, next_pos) = - match parse_token_type(tokens, current_pos, TokenType::RightParen) { - ParseResult::Ok(id, next) => (id, next), - ParseResult::Err(err) => return ParseResult::Err(err), - ParseResult::Mismatch(wrong_token) => { - return ParseResult::Err(SyntaxError { - reason: String::from("Expected a closing paren afted the function identifier."), - error_start: wrong_token.position, - error_end: wrong_token.get_end_position(), - }); - } - ParseResult::Unmatched => { - return ParseResult::Err(SyntaxError { - reason: String::from("Expected a closing paren afted the function identifier."), - error_start: opening_paren.position, - error_end: opening_paren.get_end_position(), - }); - } - }; + let (params_list, next_pos) = match parse_params_list(tokens, current_pos) { + ParseResult::Ok(params, next_pos) => (params, next_pos), + ParseResult::Err(err) => return ParseResult::Err(err), + ParseResult::Mismatch(wrong_token) => { + return ParseResult::Err(SyntaxError { + reason: String::from("Expected an opening paren afted the function identifier."), + error_start: wrong_token.position, + error_end: wrong_token.get_end_position(), + }); + } + ParseResult::Unmatched => { + return ParseResult::Err(SyntaxError { + reason: String::from("Expected an opening paren afted the function identifier."), + error_start: identifier.position, + error_end: identifier.get_end_position(), + }); + } + }; current_pos = next_pos; let (_block, next_pos) = match parse_block(tokens, current_pos) { @@ -107,8 +79,8 @@ pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult { return ParseResult::Err(SyntaxError { reason: String::from("Expected a block after the function declaration."), - error_start: closing_paren.position, - error_end: closing_paren.get_end_position(), + error_start: identifier.position, + error_end: identifier.get_end_position(), }); } }; @@ -118,8 +90,9 @@ pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult { assert_eq!( err.reason, - "Expected a closing paren afted the function identifier." + "Expected a closing paren after the function identifier." ); assert_eq!(err.error_start, 7); assert_eq!(err.error_end, 8); @@ -226,7 +199,7 @@ mod tests { ParseResult::Err(err) => { assert_eq!( err.reason, - "Expected a closing paren afted the function identifier." + "Expected a closing paren after the function identifier." ); assert_eq!(err.error_start, 6); assert_eq!(err.error_end, 7); @@ -294,8 +267,8 @@ mod tests { err.reason, "Expected a block after the function declaration." ); - assert_eq!(err.error_start, 7); - assert_eq!(err.error_end, 8); + assert_eq!(err.error_start, 4); + assert_eq!(err.error_end, 6); } _ => panic!("Expected an error: {:?}", fun_decl), } diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 1e00871..47759c6 100755 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -1,11 +1,10 @@ -use std::f32::consts::E; - use crate::error_handling::{MistiError, SyntaxError}; mod binding; mod block; mod expression; mod function_declaration; +mod params_list; mod utils; pub mod ast; diff --git a/src/syntax/params_list.rs b/src/syntax/params_list.rs new file mode 100644 index 0000000..ca57547 --- /dev/null +++ b/src/syntax/params_list.rs @@ -0,0 +1,47 @@ +use crate::{ + error_handling::SyntaxError, + lexic::token::{Token, TokenType}, + syntax::utils::parse_token_type, +}; + +use super::{ast::ParamsList, ParseResult}; + +pub fn parse_params_list<'a>( + tokens: &'a Vec, + pos: usize, +) -> ParseResult { + let mut current_pos = pos; + + let (opening_paren, next_pos) = + match parse_token_type(tokens, current_pos, TokenType::LeftParen) { + ParseResult::Ok(t, next) => (t, next), + ParseResult::Err(err) => return ParseResult::Err(err), + ParseResult::Mismatch(t) => return ParseResult::Mismatch(t), + ParseResult::Unmatched => return ParseResult::Unmatched, + }; + current_pos = next_pos; + + // Parse closing paren + let (_closing_paren, next_pos) = + match parse_token_type(tokens, current_pos, TokenType::RightParen) { + ParseResult::Ok(t, next) => (t, next), + ParseResult::Err(err) => return ParseResult::Err(err), + ParseResult::Mismatch(t) => { + return ParseResult::Err(SyntaxError { + reason: String::from("Expected a closing paren after the function identifier."), + error_start: t.position, + error_end: t.get_end_position(), + }); + } + ParseResult::Unmatched => { + return ParseResult::Err(SyntaxError { + reason: String::from("Expected a closing paren after the function identifier."), + error_start: opening_paren.position, + error_end: opening_paren.get_end_position(), + }); + } + }; + current_pos = next_pos; + + ParseResult::Ok(ParamsList {}, current_pos) +} diff --git a/src/syntax/utils.rs b/src/syntax/utils.rs index 21e5f4f..6309bfb 100644 --- a/src/syntax/utils.rs +++ b/src/syntax/utils.rs @@ -103,47 +103,3 @@ pub fn _try_operator_w<'a>( }))), } } - -/// Ignores all whitespace and newlines -pub fn expect_token_w<'a>( - tokens: &'a Vec, - pos: usize, - token_type: TokenType, - error_message: String, - prev_token: &Token, -) -> Result<(&'a Token, usize), Option> { - let mut current_pos = pos; - - // Ignore all whitespace and newlines - while let Some(t) = tokens.get(current_pos) { - if t.token_type == TokenType::INDENT - || t.token_type == TokenType::DEDENT - || t.token_type == TokenType::NewLine - { - current_pos += 1; - } else { - break; - } - } - - match tokens.get(current_pos) { - Some(t) if t.token_type == token_type => Ok((t, current_pos + 1)), - Some(t) if t.token_type == TokenType::EOF || t.token_type == TokenType::NewLine => { - Err(Some(SyntaxResult::Err(SyntaxError { - reason: error_message, - error_start: prev_token.position, - error_end: prev_token.get_end_position(), - }))) - } - Some(t) => Err(Some(SyntaxResult::Err(SyntaxError { - reason: error_message, - error_start: t.position, - error_end: t.get_end_position(), - }))), - None => Err(Some(SyntaxResult::Err(SyntaxError { - reason: error_message, - error_start: prev_token.position, - error_end: prev_token.get_end_position(), - }))), - } -}