diff options
| author | Mel <einebeere@gmail.com> | 2021-11-14 19:31:48 +0100 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2021-11-14 19:31:48 +0100 |
| commit | 98ac2e8f26ff4d90c37bb9c9536e9eb14e31efb4 (patch) | |
| tree | f7e4b47cd4d8a370597267f8f1819e874c5aacce /src/parse/parser.rs | |
| parent | 514ceb979c4ce79bfee2234cf981292ded714f66 (diff) | |
| download | rabbithole-98ac2e8f26ff4d90c37bb9c9536e9eb14e31efb4.tar.zst rabbithole-98ac2e8f26ff4d90c37bb9c9536e9eb14e31efb4.zip | |
Parse and walk str embeds.
Diffstat (limited to 'src/parse/parser.rs')
| -rw-r--r-- | src/parse/parser.rs | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 6b0a785..5a09a8f 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -1,11 +1,12 @@ use super::ast::expression::Expression; -use super::ast::nodes::{ArrayNode, LoopNode, UnaryOperator}; +use super::ast::nodes::{ArrayNode, LoopNode, StrNode, UnaryOperator}; use super::ast::statement::Statement; use super::ast::Program; +use crate::lex::lexer::Lexer; use crate::lex::token::TokenVariant::*; use crate::parse::ast::nodes::{ ArrayAccessNode, BinaryOperator, BlockNode, CallNode, ConditionalBlock, FnHeader, FnNode, - IfNode, MemberAccessNode, SimpleLiteral, TypedIdentifier, + IfNode, MemberAccessNode, SimpleLiteral, StrPart, TypedIdentifier, }; use crate::{check, consume, consume_if, inner, lex::token::Token}; use anyhow::{anyhow, Result}; @@ -267,6 +268,7 @@ impl<T: Iterator<Item = Token>> Parser<T> { self.tokens.next().unwrap(), Ident ))), + StrOpen => Ok(Expression::StrLiteral(Box::new(self.str()?))), GroupOpen => Ok(Expression::Group(Box::new(self.group()?))), BlockOpen => Ok(Expression::Block(Box::new(self.generic_block()?))), ArrayOpen => Ok(Expression::ArrayLiteral(self.array()?)), @@ -303,6 +305,34 @@ impl<T: Iterator<Item = Token>> Parser<T> { Ok(ArrayNode { elements }) } + fn str(&mut self) -> Result<StrNode> { + let mut parts = Vec::new(); + + consume!(self, StrOpen)?; + + loop { + let token = self.tokens.next().expect("Unclosed str."); + + let part = match token.variant { + Str(literal) => StrPart::Literal(literal), + StrEmbed(code) => { + let embed_lexer = Lexer::new(&code); + let mut embed_parser = Parser::new(embed_lexer); + + let node = embed_parser.expression()?; + + StrPart::Embed(node) + } + StrClose => break, + _ => unreachable!(), + }; + + parts.push(part); + } + + Ok(StrNode { parts }) + } + fn function(&mut self) -> Result<FnNode> { consume!(self, KeywordFn)?; let token = self.tokens.next().expect("Expected function header."); |
