From 3d1e82b20ea784c2abb1440e73d53ddb58c7ea5d Mon Sep 17 00:00:00 2001
From: Chris Wong <lambda.fairy@gmail.com>
Date: Sun, 16 Jul 2017 22:13:26 +1200
Subject: [PATCH] Implement let expressions

---
 maud_macros/src/parse.rs | 29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/maud_macros/src/parse.rs b/maud_macros/src/parse.rs
index f00f8fb..f2aa746 100644
--- a/maud_macros/src/parse.rs
+++ b/maud_macros/src/parse.rs
@@ -159,7 +159,28 @@ impl Parser {
     ///
     /// The leading `@let` should already be consumed.
     fn let_expr(&mut self, render: &mut Renderer) -> ParseResult<()> {
-        self.error("unimplemented")
+        let mut pat = Vec::new();
+        loop {
+            match self.next() {
+                Some(TokenTree { kind: TokenNode::Op('=', _), .. }) => break,
+                Some(token) => pat.push(token),
+                None => return self.error("unexpected end of @let expression"),
+            }
+        }
+        let mut expr = Vec::new();
+        let body;
+        loop {
+            match self.next() {
+                Some(TokenTree { kind: TokenNode::Group(Delimiter::Brace, block), .. }) => {
+                    body = self.block(block, render)?;
+                    break;
+                },
+                Some(token) => expr.push(token),
+                None => return self.error("unexpected end of @let expression"),
+            }
+        }
+        render.emit_let(pat.into_iter().collect(), expr.into_iter().collect(), body);
+        Ok(())
     }
 
     /// Parses and renders an element node.
@@ -187,9 +208,9 @@ impl Parser {
 
     /// Parses and renders the attributes of an element.
     fn attrs(&mut self, render: &mut Renderer) -> ParseResult<()> {
-        let mut classes_static: Vec<String> = Vec::new();
-        let mut classes_toggled: Vec<(TokenStream, String)> = Vec::new();
-        let mut ids: Vec<String> = Vec::new();
+        let mut classes_static = Vec::new();
+        let mut classes_toggled = Vec::new();
+        let mut ids = Vec::new();
         loop {
             let start_position = self.input.save();
             let maybe_name = self.namespaced_name();