forked from AbleScript/ablescript
Reduced parser boilerplate
This commit is contained in:
parent
f6e6f8cea1
commit
ffcbdc258b
|
@ -49,6 +49,15 @@ impl<'source> Parser<'source> {
|
||||||
Ok(ast)
|
Ok(ast)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get next item
|
||||||
|
///
|
||||||
|
/// If EOF, return Error instead of None
|
||||||
|
fn checked_next(&mut self) -> Result<Token, Error> {
|
||||||
|
self.lexer
|
||||||
|
.next()
|
||||||
|
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse a token
|
/// Parse a token
|
||||||
///
|
///
|
||||||
/// This function will route to corresponding flow functions
|
/// This function will route to corresponding flow functions
|
||||||
|
@ -120,11 +129,7 @@ impl<'source> Parser<'source> {
|
||||||
|
|
||||||
/// Get an Identifier
|
/// Get an Identifier
|
||||||
fn get_iden(&mut self) -> Result<Iden, Error> {
|
fn get_iden(&mut self) -> Result<Iden, Error> {
|
||||||
match self
|
match self.checked_next()? {
|
||||||
.lexer
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
|
|
||||||
{
|
|
||||||
Token::Identifier(iden) => Ok(Iden {
|
Token::Identifier(iden) => Ok(Iden {
|
||||||
iden: if self.tdark {
|
iden: if self.tdark {
|
||||||
iden.replace("lang", "script")
|
iden.replace("lang", "script")
|
||||||
|
@ -203,10 +208,7 @@ impl<'source> Parser<'source> {
|
||||||
|
|
||||||
Token::Not => Ok(Expr::new(
|
Token::Not => Ok(Expr::new(
|
||||||
{
|
{
|
||||||
let next = self
|
let next = self.checked_next()?;
|
||||||
.lexer
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?;
|
|
||||||
ExprKind::Not(Box::new(self.parse_expr(next, buf)?))
|
ExprKind::Not(Box::new(self.parse_expr(next, buf)?))
|
||||||
},
|
},
|
||||||
start..self.lexer.span().end,
|
start..self.lexer.span().end,
|
||||||
|
@ -242,11 +244,7 @@ impl<'source> Parser<'source> {
|
||||||
fn expr_flow(&mut self, terminate: Token) -> Result<Expr, Error> {
|
fn expr_flow(&mut self, terminate: Token) -> Result<Expr, Error> {
|
||||||
let mut buf = None;
|
let mut buf = None;
|
||||||
Ok(loop {
|
Ok(loop {
|
||||||
match self
|
match self.checked_next()? {
|
||||||
.lexer
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
|
|
||||||
{
|
|
||||||
t if t == terminate => {
|
t if t == terminate => {
|
||||||
break buf.take().ok_or_else(|| {
|
break buf.take().ok_or_else(|| {
|
||||||
Error::new(ErrorKind::UnexpectedToken(t), self.lexer.span())
|
Error::new(ErrorKind::UnexpectedToken(t), self.lexer.span())
|
||||||
|
@ -263,11 +261,7 @@ impl<'source> Parser<'source> {
|
||||||
let mut block = vec![];
|
let mut block = vec![];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match self
|
match self.checked_next()? {
|
||||||
.lexer
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
|
|
||||||
{
|
|
||||||
Token::RightCurly => break,
|
Token::RightCurly => break,
|
||||||
t => block.push(self.parse(t)?),
|
t => block.push(self.parse(t)?),
|
||||||
}
|
}
|
||||||
|
@ -281,11 +275,7 @@ impl<'source> Parser<'source> {
|
||||||
fn value_flow(&mut self, init: Token) -> Result<StmtKind, Error> {
|
fn value_flow(&mut self, init: Token) -> Result<StmtKind, Error> {
|
||||||
let mut buf = Some(self.parse_expr(init, &mut None)?);
|
let mut buf = Some(self.parse_expr(init, &mut None)?);
|
||||||
let r = loop {
|
let r = loop {
|
||||||
match self
|
match self.checked_next()? {
|
||||||
.lexer
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
|
|
||||||
{
|
|
||||||
// Print to stdout
|
// Print to stdout
|
||||||
Token::Print => {
|
Token::Print => {
|
||||||
let stmt = StmtKind::Print(buf.take().ok_or_else(|| {
|
let stmt = StmtKind::Print(buf.take().ok_or_else(|| {
|
||||||
|
@ -360,21 +350,13 @@ impl<'source> Parser<'source> {
|
||||||
|
|
||||||
let mut params = vec![];
|
let mut params = vec![];
|
||||||
loop {
|
loop {
|
||||||
match self
|
match self.checked_next()? {
|
||||||
.lexer
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
|
|
||||||
{
|
|
||||||
Token::RightParen => break,
|
Token::RightParen => break,
|
||||||
Token::Identifier(i) => {
|
Token::Identifier(i) => {
|
||||||
params.push(Iden::new(i, self.lexer.span()));
|
params.push(Iden::new(i, self.lexer.span()));
|
||||||
|
|
||||||
// Require comma (next) or right paren (end) after identifier
|
// Require comma (next) or right paren (end) after identifier
|
||||||
match self
|
match self.checked_next()? {
|
||||||
.lexer
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
|
|
||||||
{
|
|
||||||
Token::Comma => continue,
|
Token::Comma => continue,
|
||||||
Token::RightParen => break,
|
Token::RightParen => break,
|
||||||
t => {
|
t => {
|
||||||
|
@ -400,11 +382,7 @@ impl<'source> Parser<'source> {
|
||||||
fn bff_flow(&mut self) -> Result<StmtKind, Error> {
|
fn bff_flow(&mut self) -> Result<StmtKind, Error> {
|
||||||
let iden = self.get_iden()?;
|
let iden = self.get_iden()?;
|
||||||
|
|
||||||
let tape_len = match self
|
let tape_len = match self.checked_next()? {
|
||||||
.lexer
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
|
|
||||||
{
|
|
||||||
Token::LeftParen => {
|
Token::LeftParen => {
|
||||||
let len = Some(self.expr_flow(Token::RightParen)?);
|
let len = Some(self.expr_flow(Token::RightParen)?);
|
||||||
self.require(Token::LeftCurly)?;
|
self.require(Token::LeftCurly)?;
|
||||||
|
@ -421,11 +399,7 @@ impl<'source> Parser<'source> {
|
||||||
|
|
||||||
let mut code: Vec<u8> = vec![];
|
let mut code: Vec<u8> = vec![];
|
||||||
loop {
|
loop {
|
||||||
match self
|
match self.checked_next()? {
|
||||||
.lexer
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
|
|
||||||
{
|
|
||||||
Token::Plus
|
Token::Plus
|
||||||
| Token::Minus
|
| Token::Minus
|
||||||
| Token::Dot
|
| Token::Dot
|
||||||
|
@ -451,11 +425,7 @@ impl<'source> Parser<'source> {
|
||||||
let mut args = vec![];
|
let mut args = vec![];
|
||||||
let mut buf = None;
|
let mut buf = None;
|
||||||
loop {
|
loop {
|
||||||
match self
|
match self.checked_next()? {
|
||||||
.lexer
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
|
|
||||||
{
|
|
||||||
// End of argument list
|
// End of argument list
|
||||||
Token::RightParen => {
|
Token::RightParen => {
|
||||||
if let Some(expr) = buf.take() {
|
if let Some(expr) = buf.take() {
|
||||||
|
@ -486,11 +456,7 @@ impl<'source> Parser<'source> {
|
||||||
/// Parse variable declaration
|
/// Parse variable declaration
|
||||||
fn var_flow(&mut self) -> Result<StmtKind, Error> {
|
fn var_flow(&mut self) -> Result<StmtKind, Error> {
|
||||||
let iden = self.get_iden()?;
|
let iden = self.get_iden()?;
|
||||||
let init = match self
|
let init = match self.checked_next()? {
|
||||||
.lexer
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
|
|
||||||
{
|
|
||||||
Token::Equal => Some(self.expr_flow(Token::Semicolon)?),
|
Token::Equal => Some(self.expr_flow(Token::Semicolon)?),
|
||||||
Token::Semicolon => None,
|
Token::Semicolon => None,
|
||||||
t => return Err(Error::new(ErrorKind::UnexpectedToken(t), self.lexer.span())),
|
t => return Err(Error::new(ErrorKind::UnexpectedToken(t), self.lexer.span())),
|
||||||
|
|
Loading…
Reference in a new issue