summaryrefslogtreecommitdiff
path: root/src/syntax
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-01-30 12:09:26 +0100
committerLaurenz <laurmaedje@gmail.com>2021-01-30 12:09:26 +0100
commit89eb8bae49edb71d9a9279a2210bb1ccaf4dd707 (patch)
tree160b1a2ff41b5bba8a58f882df9d10c9eb036cf2 /src/syntax
parentac24075469f171fe83a976b9a97b9b1ea078a7e3 (diff)
New syntax 💎
- Everything everywhere! - Blocks with curly braces: {} - Templates with brackets: [] - Function templates with hashtag: `#[f]` - Headings with equals sign: `= Introduction`
Diffstat (limited to 'src/syntax')
-rw-r--r--src/syntax/expr.rs33
-rw-r--r--src/syntax/mod.rs25
-rw-r--r--src/syntax/node.rs6
-rw-r--r--src/syntax/token.rs10
4 files changed, 41 insertions, 33 deletions
diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs
index ca55bdd0..7a055cc7 100644
--- a/src/syntax/expr.rs
+++ b/src/syntax/expr.rs
@@ -43,7 +43,7 @@ pub enum Expr {
Unary(ExprUnary),
/// A binary operation: `a + b`.
Binary(ExprBinary),
- /// An invocation of a function: `foo(...)`, `[foo ...]`.
+ /// An invocation of a function: `foo(...)`, `#[foo ...]`.
Call(ExprCall),
/// A let expression: `#let x = 1`.
Let(ExprLet),
@@ -75,11 +75,7 @@ impl Pretty for Expr {
Self::Str(v) => write!(p, "{:?}", &v).unwrap(),
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::Template(v) => pretty_template(v, p),
Self::Group(v) => {
p.push_str("(");
v.v.pretty(p);
@@ -146,6 +142,17 @@ impl Pretty for Named {
/// A template expression: `[*Hi* there!]`.
pub type ExprTemplate = Tree;
+/// Pretty print a template.
+pub fn pretty_template(template: &ExprTemplate, p: &mut Printer) {
+ if let [Spanned { v: Node::Expr(Expr::Call(call)), .. }] = template.as_slice() {
+ pretty_func_template(call, p, false)
+ } else {
+ p.push_str("[");
+ template.pretty(p);
+ p.push_str("]");
+ }
+}
+
/// A grouped expression: `(1 + 2)`.
pub type ExprGroup = SpanBox<Expr>;
@@ -400,7 +407,7 @@ pub enum Associativity {
Right,
}
-/// An invocation of a function: `foo(...)`, `[foo ...]`.
+/// An invocation of a function: `foo(...)`, `#[foo ...]`.
#[derive(Debug, Clone, PartialEq)]
pub struct ExprCall {
/// The callee of the function.
@@ -418,12 +425,12 @@ impl Pretty for ExprCall {
}
}
-/// Pretty print a bracketed function call, with body or chaining when possible.
-pub fn pretty_bracket_call(call: &ExprCall, p: &mut Printer, chained: bool) {
+/// Pretty print a function template, with body or chaining when possible.
+pub fn pretty_func_template(call: &ExprCall, p: &mut Printer, chained: bool) {
if chained {
p.push_str(" | ");
} else {
- p.push_str("[");
+ p.push_str("#[");
}
// Function name.
@@ -431,7 +438,7 @@ pub fn pretty_bracket_call(call: &ExprCall, p: &mut Printer, chained: bool) {
// Find out whether this can be written with a body or as a chain.
//
- // Example: Transforms "[v [Hi]]" => "[v][Hi]".
+ // Example: Transforms "#[v [Hi]]" => "#[v][Hi]".
if let [head @ .., Argument::Pos(Spanned { v: Expr::Template(template), .. })] =
call.args.v.as_slice()
{
@@ -443,9 +450,9 @@ pub fn pretty_bracket_call(call: &ExprCall, p: &mut Printer, chained: bool) {
// Find out whether this can written as a chain.
//
- // Example: Transforms "[v][[f]]" => "[v | f]".
+ // Example: Transforms "#[v][[f]]" => "#[v | f]".
if let [Spanned { v: Node::Expr(Expr::Call(call)), .. }] = template.as_slice() {
- return pretty_bracket_call(call, p, true);
+ return pretty_func_template(call, p, true);
} else {
p.push_str("][");
template.pretty(p);
diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs
index d1fc6b77..41fba134 100644
--- a/src/syntax/mod.rs
+++ b/src/syntax/mod.rs
@@ -60,7 +60,7 @@ mod tests {
roundtrip("hi");
// Heading.
- roundtrip("# *Ok*");
+ roundtrip("= *Ok*");
// Raw.
roundtrip("`lang 1`");
@@ -94,9 +94,9 @@ mod tests {
roundtrip("{(a: 1, b: 2)}");
// Templates.
- roundtrip("{[]}");
- roundtrip("{[*Ok*]}");
- roundtrip("{[[f]]}");
+ roundtrip("[]");
+ roundtrip("[*Ok*]");
+ roundtrip("{[f]}");
// Groups.
roundtrip("{(1)}");
@@ -105,6 +105,7 @@ mod tests {
roundtrip("{}");
roundtrip("{1}");
roundtrip("{ #let x = 1; x += 2; x + 1 }");
+ roundtrip("[{}]");
// Operators.
roundtrip("{-x}");
@@ -116,14 +117,14 @@ mod tests {
roundtrip("{v(1)}");
roundtrip("{v(a: 1, b)}");
- // Bracket calls.
- roundtrip("[v]");
- roundtrip("[v 1]");
- roundtrip("[v 1, 2][*Ok*]");
- roundtrip("[v 1 | f 2]");
- roundtrip("{[[v]]}");
- test("[v 1, [[f 2]]]", "[v 1 | f 2]");
- test("[v 1, 2][[f 3]]", "[v 1, 2 | f 3]");
+ // Function templates.
+ roundtrip("#[v]");
+ roundtrip("#[v 1]");
+ roundtrip("#[v 1, 2][*Ok*]");
+ roundtrip("#[v 1 | f 2]");
+ roundtrip("{#[v]}");
+ test("#[v 1, #[f 2]]", "#[v 1 | f 2]");
+ test("#[v 1, 2][#[f 3]]", "#[v 1, 2 | f 3]");
// Keywords.
roundtrip("#let x = 1 + 2");
diff --git a/src/syntax/node.rs b/src/syntax/node.rs
index db3b6510..d45e5952 100644
--- a/src/syntax/node.rs
+++ b/src/syntax/node.rs
@@ -36,8 +36,8 @@ impl Pretty for Node {
Self::Raw(raw) => raw.pretty(p),
Self::Expr(expr) => {
if let Expr::Call(call) = expr {
- // Format bracket calls appropriately.
- pretty_bracket_call(call, p, false)
+ // Format function templates appropriately.
+ pretty_func_template(call, p, false)
} else {
expr.pretty(p);
}
@@ -58,7 +58,7 @@ pub struct NodeHeading {
impl Pretty for NodeHeading {
fn pretty(&self, p: &mut Printer) {
for _ in 0 ..= self.level.v {
- p.push_str("#");
+ p.push_str("=");
}
self.contents.pretty(p);
}
diff --git a/src/syntax/token.rs b/src/syntax/token.rs
index 43797f75..c4b9ec8f 100644
--- a/src/syntax/token.rs
+++ b/src/syntax/token.rs
@@ -6,6 +6,8 @@ use crate::geom::{AngularUnit, LengthUnit};
pub enum Token<'s> {
/// A left square bracket: `[`.
LeftBracket,
+ /// A hashtag followed by a left square bracket: `#[`.
+ HashBracket,
/// A right square bracket: `]`.
RightBracket,
/// A left curly brace: `{`.
@@ -20,8 +22,8 @@ pub enum Token<'s> {
Star,
/// An underscore: `_`.
Underscore,
- /// A hashtag: `#`.
- Hash,
+ /// A single equals sign: `=`.
+ Eq,
/// A tilde: `~`.
Tilde,
/// A backslash followed by nothing or whitespace: `\`.
@@ -40,8 +42,6 @@ pub enum Token<'s> {
Hyph,
/// A slash: `/`.
Slash,
- /// A single equals sign: `=`.
- Eq,
/// Two equals signs: `==`.
EqEq,
/// An exclamation mark followed by an equals sign: `!=`.
@@ -191,6 +191,7 @@ impl<'s> Token<'s> {
pub fn name(self) -> &'static str {
match self {
Self::LeftBracket => "opening bracket",
+ Self::HashBracket => "start of function template",
Self::RightBracket => "closing bracket",
Self::LeftBrace => "opening brace",
Self::RightBrace => "closing brace",
@@ -198,7 +199,6 @@ impl<'s> Token<'s> {
Self::RightParen => "closing paren",
Self::Star => "star",
Self::Underscore => "underscore",
- Self::Hash => "hashtag",
Self::Tilde => "tilde",
Self::Backslash => "backslash",
Self::Comma => "comma",