Extract params list parsing
This commit is contained in:
parent
fec196d5aa
commit
1fbc353ebf
@ -11,11 +11,15 @@ pub enum TopLevelDeclaration {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FunctionDeclaration {
|
pub struct FunctionDeclaration {
|
||||||
pub identifier: Box<String>,
|
pub identifier: Box<String>,
|
||||||
|
pub params_list: Box<ParamsList>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Block {}
|
pub struct Block {}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ParamsList {}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Binding {
|
pub enum Binding {
|
||||||
Val(ValBinding),
|
Val(ValBinding),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
error_handling::SyntaxError,
|
||||||
lexic::token::{Token, TokenType},
|
lexic::token::{Token, TokenType},
|
||||||
syntax::{utils::expect_token_w, SyntaxResult},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{ast::Block, utils::parse_token_type, ParseResult};
|
use super::{ast::Block, utils::parse_token_type, ParseResult};
|
||||||
@ -19,17 +19,25 @@ pub fn parse_block<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Block,
|
|||||||
current_pos = next_pos;
|
current_pos = next_pos;
|
||||||
|
|
||||||
// Parse closing brace
|
// Parse closing brace
|
||||||
let (_closing_brace, next_pos) = match expect_token_w(
|
let (_closing_brace, next_pos) =
|
||||||
tokens,
|
match parse_token_type(tokens, current_pos, TokenType::RightBrace) {
|
||||||
current_pos,
|
ParseResult::Ok(t, next) => (t, next),
|
||||||
TokenType::RightBrace,
|
ParseResult::Err(err) => return ParseResult::Err(err),
|
||||||
"Expected a closing brace after the block body.".into(),
|
ParseResult::Mismatch(t) => {
|
||||||
opening_brace,
|
return ParseResult::Err(SyntaxError {
|
||||||
) {
|
reason: String::from("Expected a closing brace after the block body."),
|
||||||
Ok(t) => t,
|
error_start: t.position,
|
||||||
Err(Some(SyntaxResult::Err(err))) => return ParseResult::Err(err),
|
error_end: t.get_end_position(),
|
||||||
_ => panic!("parse_block: invalid state"),
|
});
|
||||||
};
|
}
|
||||||
|
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;
|
current_pos = next_pos;
|
||||||
|
|
||||||
ParseResult::Ok(Block {}, current_pos)
|
ParseResult::Ok(Block {}, current_pos)
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use std::thread::current;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error_handling::SyntaxError,
|
error_handling::SyntaxError,
|
||||||
lexic::token::{Token, TokenType},
|
lexic::token::{Token, TokenType},
|
||||||
@ -7,10 +5,11 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
ast::{FunctionDeclaration, TopLevelDeclaration},
|
ast::{FunctionDeclaration, ParamsList},
|
||||||
block::parse_block,
|
block::parse_block,
|
||||||
utils::{expect_token_w, parse_token_type, try_token_type},
|
params_list::parse_params_list,
|
||||||
ParseResult, SyntaxResult,
|
utils::{parse_token_type, try_token_type},
|
||||||
|
ParseResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<FunctionDeclaration, ()> {
|
pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<FunctionDeclaration, ()> {
|
||||||
@ -45,51 +44,24 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Function
|
|||||||
};
|
};
|
||||||
current_pos = next_pos;
|
current_pos = next_pos;
|
||||||
|
|
||||||
// TODO: Call function that parses a parameter list
|
let (params_list, next_pos) = match parse_params_list(tokens, current_pos) {
|
||||||
let (opening_paren, next_pos) =
|
ParseResult::Ok(params, next_pos) => (params, next_pos),
|
||||||
match parse_token_type(tokens, current_pos, TokenType::LeftParen) {
|
ParseResult::Err(err) => return ParseResult::Err(err),
|
||||||
ParseResult::Ok(id, next) => (id, next),
|
ParseResult::Mismatch(wrong_token) => {
|
||||||
ParseResult::Err(err) => return ParseResult::Err(err),
|
return ParseResult::Err(SyntaxError {
|
||||||
ParseResult::Mismatch(wrong_token) => {
|
reason: String::from("Expected an opening paren afted the function identifier."),
|
||||||
return ParseResult::Err(SyntaxError {
|
error_start: wrong_token.position,
|
||||||
reason: String::from(
|
error_end: wrong_token.get_end_position(),
|
||||||
"Expected an opening paren afted the function identifier.",
|
});
|
||||||
),
|
}
|
||||||
error_start: wrong_token.position,
|
ParseResult::Unmatched => {
|
||||||
error_end: wrong_token.get_end_position(),
|
return ParseResult::Err(SyntaxError {
|
||||||
});
|
reason: String::from("Expected an opening paren afted the function identifier."),
|
||||||
}
|
error_start: identifier.position,
|
||||||
ParseResult::Unmatched => {
|
error_end: identifier.get_end_position(),
|
||||||
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(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
current_pos = next_pos;
|
current_pos = next_pos;
|
||||||
|
|
||||||
let (_block, next_pos) = match parse_block(tokens, current_pos) {
|
let (_block, next_pos) = match parse_block(tokens, current_pos) {
|
||||||
@ -107,8 +79,8 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Function
|
|||||||
ParseResult::Unmatched => {
|
ParseResult::Unmatched => {
|
||||||
return ParseResult::Err(SyntaxError {
|
return ParseResult::Err(SyntaxError {
|
||||||
reason: String::from("Expected a block after the function declaration."),
|
reason: String::from("Expected a block after the function declaration."),
|
||||||
error_start: closing_paren.position,
|
error_start: identifier.position,
|
||||||
error_end: closing_paren.get_end_position(),
|
error_end: identifier.get_end_position(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -118,8 +90,9 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Function
|
|||||||
ParseResult::Ok(
|
ParseResult::Ok(
|
||||||
FunctionDeclaration {
|
FunctionDeclaration {
|
||||||
identifier: Box::new(identifier.value.clone()),
|
identifier: Box::new(identifier.value.clone()),
|
||||||
|
params_list: Box::new(params_list),
|
||||||
},
|
},
|
||||||
next_pos,
|
current_pos,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +185,7 @@ mod tests {
|
|||||||
ParseResult::Err(err) => {
|
ParseResult::Err(err) => {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
err.reason,
|
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_start, 7);
|
||||||
assert_eq!(err.error_end, 8);
|
assert_eq!(err.error_end, 8);
|
||||||
@ -226,7 +199,7 @@ mod tests {
|
|||||||
ParseResult::Err(err) => {
|
ParseResult::Err(err) => {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
err.reason,
|
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_start, 6);
|
||||||
assert_eq!(err.error_end, 7);
|
assert_eq!(err.error_end, 7);
|
||||||
@ -294,8 +267,8 @@ mod tests {
|
|||||||
err.reason,
|
err.reason,
|
||||||
"Expected a block after the function declaration."
|
"Expected a block after the function declaration."
|
||||||
);
|
);
|
||||||
assert_eq!(err.error_start, 7);
|
assert_eq!(err.error_start, 4);
|
||||||
assert_eq!(err.error_end, 8);
|
assert_eq!(err.error_end, 6);
|
||||||
}
|
}
|
||||||
_ => panic!("Expected an error: {:?}", fun_decl),
|
_ => panic!("Expected an error: {:?}", fun_decl),
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
use std::f32::consts::E;
|
|
||||||
|
|
||||||
use crate::error_handling::{MistiError, SyntaxError};
|
use crate::error_handling::{MistiError, SyntaxError};
|
||||||
|
|
||||||
mod binding;
|
mod binding;
|
||||||
mod block;
|
mod block;
|
||||||
mod expression;
|
mod expression;
|
||||||
mod function_declaration;
|
mod function_declaration;
|
||||||
|
mod params_list;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
pub mod ast;
|
pub mod ast;
|
||||||
|
47
src/syntax/params_list.rs
Normal file
47
src/syntax/params_list.rs
Normal file
@ -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<Token>,
|
||||||
|
pos: usize,
|
||||||
|
) -> ParseResult<ParamsList, &Token> {
|
||||||
|
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)
|
||||||
|
}
|
@ -103,47 +103,3 @@ pub fn _try_operator_w<'a>(
|
|||||||
}))),
|
}))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ignores all whitespace and newlines
|
|
||||||
pub fn expect_token_w<'a>(
|
|
||||||
tokens: &'a Vec<Token>,
|
|
||||||
pos: usize,
|
|
||||||
token_type: TokenType,
|
|
||||||
error_message: String,
|
|
||||||
prev_token: &Token,
|
|
||||||
) -> Result<(&'a Token, usize), Option<SyntaxResult>> {
|
|
||||||
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(),
|
|
||||||
}))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user