summaryrefslogtreecommitdiff
path: root/src/parse/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse/mod.rs')
-rw-r--r--src/parse/mod.rs37
1 files changed, 35 insertions, 2 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs
index a66660e5..4483ed76 100644
--- a/src/parse/mod.rs
+++ b/src/parse/mod.rs
@@ -82,6 +82,11 @@ fn node(p: &mut Parser, at_start: bool) -> Option<Node> {
Token::Raw(t) => Node::Raw(raw(p, t)),
Token::UnicodeEscape(t) => Node::Text(unicode_escape(p, t)),
+ // Keywords.
+ Token::Let => {
+ return Some(Node::Expr(expr_let(p)?));
+ }
+
// Comments.
Token::LineComment(_) | Token::BlockComment(_) => {
p.eat();
@@ -329,7 +334,7 @@ fn value(p: &mut Parser) -> Option<Expr> {
Some(Token::Angle(val, unit)) => Expr::Angle(val, unit),
Some(Token::Percent(p)) => Expr::Percent(p),
Some(Token::Hex(hex)) => Expr::Color(color(p, hex)),
- Some(Token::Str(token)) => Expr::Str(str(p, token)),
+ Some(Token::Str(token)) => Expr::Str(string(p, token)),
// No value.
_ => {
@@ -377,7 +382,7 @@ fn color(p: &mut Parser, hex: &str) -> RgbaColor {
}
/// Parse a string.
-fn str(p: &mut Parser, token: TokenStr) -> String {
+fn string(p: &mut Parser, token: TokenStr) -> String {
if !token.terminated {
p.diag_expected_at("quote", p.peek_span().end);
}
@@ -385,5 +390,33 @@ fn str(p: &mut Parser, token: TokenStr) -> String {
resolve::resolve_string(token.string)
}
+/// Parse a let expresion.
+fn expr_let(p: &mut Parser) -> Option<Expr> {
+ p.push_mode(TokenMode::Code);
+ p.start_group(Group::Terminated);
+ p.eat_assert(Token::Let);
+
+ let pat = p.span_if(ident);
+ let mut rhs = None;
+
+ if pat.is_some() {
+ if p.eat_if(Token::Eq) {
+ if let Some(expr) = p.span_if(expr) {
+ rhs = Some(Box::new(expr));
+ }
+ }
+ } else {
+ p.diag_expected("identifier");
+ }
+
+ while !p.eof() {
+ p.diag_unexpected();
+ }
+
+ p.pop_mode();
+ p.end_group();
+ pat.map(|pat| Expr::Let(ExprLet { pat, expr: rhs }))
+}
+
#[cfg(test)]
mod tests;