Parse loops
This commit is contained in:
parent
5cb86b80df
commit
76be50eab3
@ -4,11 +4,17 @@ use crate::{
|
||||
Value,
|
||||
};
|
||||
|
||||
use super::{AbstractTree, Block, Type};
|
||||
use super::{AbstractTree, Statement, Type};
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||
pub struct Loop<'src> {
|
||||
block: Block<'src>,
|
||||
statements: Vec<Statement<'src>>,
|
||||
}
|
||||
|
||||
impl<'src> Loop<'src> {
|
||||
pub fn new(statements: Vec<Statement<'src>>) -> Self {
|
||||
Self { statements }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src> AbstractTree for Loop<'src> {
|
||||
|
@ -123,6 +123,7 @@ pub fn lexer<'src>() -> impl Parser<
|
||||
just("map").padded(),
|
||||
just("range").padded(),
|
||||
just("str").padded(),
|
||||
just("loop").padded(),
|
||||
))
|
||||
.map(Token::Keyword);
|
||||
|
||||
|
@ -7,6 +7,15 @@ use crate::{abstract_tree::*, error::Error, lexer::Token};
|
||||
type ParserInput<'tokens, 'src> =
|
||||
SpannedInput<Token<'src>, SimpleSpan, &'tokens [(Token<'src>, SimpleSpan)]>;
|
||||
|
||||
pub fn parse<'tokens, 'src: 'tokens>(
|
||||
tokens: &'tokens [(Token<'src>, SimpleSpan)],
|
||||
) -> Result<Vec<(Statement<'src>, SimpleSpan)>, Error<'tokens>> {
|
||||
parser()
|
||||
.parse(tokens.spanned((0..0).into()))
|
||||
.into_result()
|
||||
.map_err(|error| Error::Parse(error))
|
||||
}
|
||||
|
||||
fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
|
||||
'tokens,
|
||||
ParserInput<'tokens, 'src>,
|
||||
@ -158,7 +167,18 @@ fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
|
||||
.map(|statements| Statement::Block(Block::new(statements)))
|
||||
.boxed();
|
||||
|
||||
choice((assignment, expression_statement, block))
|
||||
let r#loop = statement
|
||||
.clone()
|
||||
.separated_by(just(Token::Control(";")).or_not())
|
||||
.collect()
|
||||
.delimited_by(
|
||||
just(Token::Keyword("loop")).then(just(Token::Control("{"))),
|
||||
just(Token::Control("}")),
|
||||
)
|
||||
.map(|statements| Statement::Loop(Loop::new(statements)))
|
||||
.boxed();
|
||||
|
||||
choice((assignment, expression_statement, block, r#loop))
|
||||
});
|
||||
|
||||
statement
|
||||
@ -167,21 +187,20 @@ fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn parse<'tokens, 'src: 'tokens>(
|
||||
tokens: &'tokens [(Token<'src>, SimpleSpan)],
|
||||
) -> Result<Vec<(Statement<'src>, SimpleSpan)>, Error<'tokens>> {
|
||||
parser()
|
||||
.parse(tokens.spanned((0..0).into()))
|
||||
.into_result()
|
||||
.map_err(|error| Error::Parse(error))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{abstract_tree::Logic, lexer::lex};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn r#loop() {
|
||||
assert_eq!(
|
||||
parse(&lex("loop {}").unwrap()).unwrap()[0].0,
|
||||
Statement::Loop(Loop::new(vec![]))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block() {
|
||||
assert_eq!(
|
||||
|
Loading…
Reference in New Issue
Block a user