Parse loops

This commit is contained in:
Jeff 2024-03-01 20:17:55 -05:00
parent 5cb86b80df
commit 76be50eab3
3 changed files with 38 additions and 12 deletions

View File

@ -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> {

View File

@ -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);

View File

@ -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!(