summaryrefslogtreecommitdiff
path: root/src/syntax
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-01-12 18:55:12 +0100
committerLaurenz <laurmaedje@gmail.com>2021-01-12 18:55:12 +0100
commitd2ba1b705ed7a532266294aa100f19423bb07f4d (patch)
tree1f06bf618f2190a3aabc26d69f0fb819e970341c /src/syntax
parent105cda0e698fe86266d706f4e3bacc081e65c2aa (diff)
Group and block expressions, unary plus 🧩
Diffstat (limited to 'src/syntax')
-rw-r--r--src/syntax/expr.rs50
-rw-r--r--src/syntax/node.rs48
2 files changed, 50 insertions, 48 deletions
diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs
index cb09041c..09472df4 100644
--- a/src/syntax/expr.rs
+++ b/src/syntax/expr.rs
@@ -40,6 +40,10 @@ pub enum Expr {
Dict(ExprDict),
/// A template expression: `[*Hi* there!]`.
Template(ExprTemplate),
+ /// A grouped expression: `(1 + 2)`.
+ Group(Box<Expr>),
+ /// A block expression: `{1 + 2}`.
+ Block(Box<Expr>),
}
impl Pretty for Expr {
@@ -54,24 +58,31 @@ impl Pretty for Expr {
Self::Angle(v, u) => write!(p, "{}{}", v, u).unwrap(),
Self::Percent(v) => write!(p, "{}%", v).unwrap(),
Self::Color(v) => write!(p, "{}", v).unwrap(),
- Self::Str(s) => write!(p, "{:?}", &s).unwrap(),
- Self::Call(call) => call.pretty(p),
- Self::Unary(unary) => unary.pretty(p),
- Self::Binary(binary) => binary.pretty(p),
- Self::Array(array) => array.pretty(p),
- Self::Dict(dict) => dict.pretty(p),
- Self::Template(template) => pretty_template_expr(template, p),
+ Self::Str(v) => write!(p, "{:?}", &v).unwrap(),
+ Self::Call(v) => v.pretty(p),
+ Self::Unary(v) => v.pretty(p),
+ Self::Binary(v) => v.pretty(p),
+ Self::Array(v) => v.pretty(p),
+ Self::Dict(v) => v.pretty(p),
+ Self::Template(v) => {
+ p.push_str("[");
+ v.pretty(p);
+ p.push_str("]");
+ }
+ Self::Group(v) => {
+ p.push_str("(");
+ v.pretty(p);
+ p.push_str(")");
+ }
+ Self::Block(v) => {
+ p.push_str("{");
+ v.pretty(p);
+ p.push_str("}");
+ }
}
}
}
-/// Pretty print a template in an expression context.
-pub fn pretty_template_expr(tree: &Tree, p: &mut Printer) {
- p.push_str("[");
- tree.pretty(p);
- p.push_str("]");
-}
-
/// An invocation of a function: `[foo ...]`, `foo(...)`.
#[derive(Debug, Clone, PartialEq)]
pub struct ExprCall {
@@ -197,6 +208,8 @@ impl Pretty for ExprUnary {
/// A unary operator.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum UnOp {
+ /// The plus operator: `+`.
+ Pos,
/// The negation operator: `-`.
Neg,
}
@@ -204,6 +217,7 @@ pub enum UnOp {
impl Pretty for UnOp {
fn pretty(&self, p: &mut Printer) {
p.push_str(match self {
+ Self::Pos => "+",
Self::Neg => "-",
});
}
@@ -302,7 +316,11 @@ mod tests {
fn test_pretty_print_expressions() {
// Unary and binary operations.
test_pretty("{1 +}", "{1}");
+ test_pretty("{1++1}", "{1 + +1}");
+ test_pretty("{+-1}", "{+-1}");
test_pretty("{1 + func(-2)}", "{1 + func(-2)}");
+ test_pretty("{1+2*3}", "{1 + 2 * 3}");
+ test_pretty("{(1+2)*3}", "{(1 + 2) * 3}");
// Array.
test_pretty("(-5,)", "(-5,)");
@@ -314,6 +332,10 @@ mod tests {
// Content expression.
test_pretty("[v [[f]], 1]", "[v [[f]], 1]");
+
+ // Parens and blocks.
+ test_pretty("{(1)}", "{(1)}");
+ test_pretty("{{1}}", "{{1}}");
}
#[test]
diff --git a/src/syntax/node.rs b/src/syntax/node.rs
index e7091a40..5c4c22b7 100644
--- a/src/syntax/node.rs
+++ b/src/syntax/node.rs
@@ -34,29 +34,14 @@ impl Pretty for Node {
Self::Text(text) => p.push_str(&text),
Self::Heading(heading) => heading.pretty(p),
Self::Raw(raw) => raw.pretty(p),
- Self::Expr(expr) => pretty_expr_node(expr, p),
- }
- }
-}
-
-/// Pretty print an expression in a node context.
-pub fn pretty_expr_node(expr: &Expr, p: &mut Printer) {
- match expr {
- // Prefer bracket calls over expression blocks with just a single paren
- // call.
- //
- // Example: Transforms "{v()}" => "[v]".
- Expr::Call(call) => pretty_bracket_call(call, p, false),
-
- // Remove unncessary nesting of content and expression blocks.
- //
- // Example: Transforms "{[Hi]}" => "Hi".
- Expr::Template(template) => template.pretty(p),
-
- _ => {
- p.push_str("{");
- expr.pretty(p);
- p.push_str("}");
+ Self::Expr(expr) => {
+ if let Expr::Call(call) = expr {
+ // Format bracket calls appropriately.
+ pretty_bracket_call(call, p, false)
+ } else {
+ expr.pretty(p);
+ }
+ }
}
}
}
@@ -178,18 +163,13 @@ mod tests {
use super::super::tests::test_pretty;
#[test]
- fn test_pretty_print_removes_nesting() {
- // Nesting does not matter.
- test_pretty("{{x}}", "{x}");
- test_pretty("{{{x}}}", "{x}");
- }
-
- #[test]
- fn test_pretty_print_prefers_bracket_calls() {
- // All reduces to a simple bracket call.
- test_pretty("{v()}", "[v]");
+ fn test_pretty_print_bracket_calls() {
+ // Top-level call expression formatted as bracket call.
test_pretty("[v]", "[v]");
- test_pretty("{[[v]]}", "[v]");
+
+ // Blocks are preserved.
+ test_pretty("{v()}", "{v()}");
+ test_pretty("{[[v]]}", "{[[v]]}");
}
#[test]