about summary refs log tree commit diff
path: root/src/parse/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse/parser.rs')
-rw-r--r--src/parse/parser.rs34
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.");