Minor refactor.

This commit is contained in:
Stephen Chung 2020-03-03 23:31:29 +08:00
parent 3af421ae5f
commit b421c8ac50

View File

@ -5,6 +5,9 @@ use std::fmt;
use std::iter::Peekable; use std::iter::Peekable;
use std::str::Chars; use std::str::Chars;
const MAX_LINES: u16 = 65535;
const MAX_POS: u16 = 65535;
#[derive(Debug, Eq, PartialEq, Hash, Clone)] #[derive(Debug, Eq, PartialEq, Hash, Clone)]
pub enum LexError { pub enum LexError {
UnexpectedChar(char), UnexpectedChar(char),
@ -47,7 +50,7 @@ impl fmt::Display for LexError {
pub enum ParseErrorType { pub enum ParseErrorType {
BadInput(String), BadInput(String),
InputPastEndOfFile, InputPastEndOfFile,
UnknownOperator, UnknownOperator(String),
MissingRightParen, MissingRightParen,
MissingLeftBrace, MissingLeftBrace,
MissingRightBrace, MissingRightBrace,
@ -57,14 +60,11 @@ pub enum ParseErrorType {
VarExpectsIdentifier, VarExpectsIdentifier,
WrongFnDefinition, WrongFnDefinition,
FnMissingName, FnMissingName,
FnMissingParams, FnMissingParams(String),
} }
type PERR = ParseErrorType; type PERR = ParseErrorType;
const MAX_LINES: u16 = 65535;
const MAX_POS: u16 = 65535;
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)]
pub struct Position { pub struct Position {
line: u16, line: u16,
@ -171,7 +171,7 @@ impl Error for ParseError {
match self.0 { match self.0 {
PERR::BadInput(ref p) => p, PERR::BadInput(ref p) => p,
PERR::InputPastEndOfFile => "Script is incomplete", PERR::InputPastEndOfFile => "Script is incomplete",
PERR::UnknownOperator => "Unknown operator", PERR::UnknownOperator(_) => "Unknown operator",
PERR::MissingRightParen => "Expecting ')'", PERR::MissingRightParen => "Expecting ')'",
PERR::MissingLeftBrace => "Expecting '{'", PERR::MissingLeftBrace => "Expecting '{'",
PERR::MissingRightBrace => "Expecting '}'", PERR::MissingRightBrace => "Expecting '}'",
@ -180,7 +180,7 @@ impl Error for ParseError {
PERR::MalformedIndexExpr => "Invalid index in indexing expression", PERR::MalformedIndexExpr => "Invalid index in indexing expression",
PERR::VarExpectsIdentifier => "Expecting name of a variable", PERR::VarExpectsIdentifier => "Expecting name of a variable",
PERR::FnMissingName => "Expecting name in function declaration", PERR::FnMissingName => "Expecting name in function declaration",
PERR::FnMissingParams => "Expecting parameters in function declaration", PERR::FnMissingParams(_) => "Expecting parameters in function declaration",
PERR::WrongFnDefinition => "Function definitions must be at top level and cannot be inside a block or another function", PERR::WrongFnDefinition => "Function definitions must be at top level and cannot be inside a block or another function",
} }
} }
@ -194,6 +194,8 @@ impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 { match self.0 {
PERR::BadInput(ref s) => write!(f, "{}", s)?, PERR::BadInput(ref s) => write!(f, "{}", s)?,
PERR::UnknownOperator(ref s) => write!(f, "{}: '{}'", self.description(), s)?,
PERR::FnMissingParams(ref s) => write!(f, "Missing parameters for function '{}'", s)?,
_ => write!(f, "{}", self.description())?, _ => write!(f, "{}", self.description())?,
} }
@ -1648,7 +1650,12 @@ fn parse_binary_op<'a>(
)), )),
) )
} }
_ => return Err(ParseError(PERR::UnknownOperator, pos)), token => {
return Err(ParseError(
PERR::UnknownOperator(token.syntax().to_string()),
pos,
))
}
}; };
} }
} }
@ -1844,22 +1851,17 @@ fn parse_fn<'a>(input: &mut Peekable<TokenIterator<'a>>) -> Result<FnDef, ParseE
Some(&(Token::LeftParen, _)) => { Some(&(Token::LeftParen, _)) => {
input.next(); input.next();
} }
Some(&(_, pos)) => return Err(ParseError(PERR::FnMissingParams, pos)), Some(&(_, pos)) => return Err(ParseError(PERR::FnMissingParams(name), pos)),
None => return Err(ParseError(PERR::FnMissingParams, Position::eof())), None => return Err(ParseError(PERR::FnMissingParams(name), Position::eof())),
} }
let mut params = Vec::new(); let mut params = Vec::new();
let skip_params = match input.peek() { match input.peek() {
Some(&(Token::RightParen, _)) => { Some(&(Token::RightParen, _)) => {
input.next(); input.next();
true
} }
_ => false, _ => loop {
};
if !skip_params {
loop {
match input.next() { match input.next() {
Some((Token::RightParen, _)) => break, Some((Token::RightParen, _)) => break,
Some((Token::Comma, _)) => (), Some((Token::Comma, _)) => (),
@ -1869,7 +1871,7 @@ fn parse_fn<'a>(input: &mut Peekable<TokenIterator<'a>>) -> Result<FnDef, ParseE
Some((_, pos)) => return Err(ParseError(PERR::MalformedCallExpr, pos)), Some((_, pos)) => return Err(ParseError(PERR::MalformedCallExpr, pos)),
None => return Err(ParseError(PERR::MalformedCallExpr, Position::eof())), None => return Err(ParseError(PERR::MalformedCallExpr, Position::eof())),
} }
} },
} }
let body = parse_block(input)?; let body = parse_block(input)?;