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, Value,
}; };
use super::{AbstractTree, Block, Type}; use super::{AbstractTree, Statement, Type};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct Loop<'src> { 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> { impl<'src> AbstractTree for Loop<'src> {

View File

@ -123,6 +123,7 @@ pub fn lexer<'src>() -> impl Parser<
just("map").padded(), just("map").padded(),
just("range").padded(), just("range").padded(),
just("str").padded(), just("str").padded(),
just("loop").padded(),
)) ))
.map(Token::Keyword); .map(Token::Keyword);

View File

@ -7,6 +7,15 @@ use crate::{abstract_tree::*, error::Error, lexer::Token};
type ParserInput<'tokens, 'src> = type ParserInput<'tokens, 'src> =
SpannedInput<Token<'src>, SimpleSpan, &'tokens [(Token<'src>, SimpleSpan)]>; 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< fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
'tokens, 'tokens,
ParserInput<'tokens, 'src>, ParserInput<'tokens, 'src>,
@ -158,7 +167,18 @@ fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
.map(|statements| Statement::Block(Block::new(statements))) .map(|statements| Statement::Block(Block::new(statements)))
.boxed(); .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 statement
@ -167,21 +187,20 @@ fn parser<'tokens, 'src: 'tokens>() -> impl Parser<
.collect() .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)] #[cfg(test)]
mod tests { mod tests {
use crate::{abstract_tree::Logic, lexer::lex}; use crate::{abstract_tree::Logic, lexer::lex};
use super::*; use super::*;
#[test]
fn r#loop() {
assert_eq!(
parse(&lex("loop {}").unwrap()).unwrap()[0].0,
Statement::Loop(Loop::new(vec![]))
);
}
#[test] #[test]
fn block() { fn block() {
assert_eq!( assert_eq!(