summaryrefslogtreecommitdiff
path: root/src/parse
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-10-04 22:36:20 +0200
committerLaurenz <laurmaedje@gmail.com>2020-10-04 22:36:20 +0200
commit605ab104c5e041c345007020d277b4c6267debe6 (patch)
treec18f3333a0c0e0527ad1039a498cb210300f7fd9 /src/parse
parentef8aa763faa59fd62c90c6d6245e8d2c5eece35e (diff)
Better argument parsing 🥙
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/mod.rs20
-rw-r--r--src/parse/tests.rs74
2 files changed, 49 insertions, 45 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs
index ca2375f2..7fbbf141 100644
--- a/src/parse/mod.rs
+++ b/src/parse/mod.rs
@@ -163,14 +163,14 @@ fn bracket_call(p: &mut Parser) -> ExprCall {
if p.peek() == Some(Token::LeftBracket) {
let expr = p.span(|p| Expr::Lit(Lit::Content(bracket_body(p))));
inner.span.expand(expr.span);
- inner.v.args.0.push(LitDictEntry { key: None, expr });
+ inner.v.args.v.0.push(LitDictEntry { key: None, expr });
}
while let Some(mut top) = outer.pop() {
let span = inner.span;
let node = inner.map(Expr::Call).map(SynNode::Expr);
let expr = Expr::Lit(Lit::Content(vec![node])).span_with(span);
- top.v.args.0.push(LitDictEntry { key: None, expr });
+ top.v.args.v.0.push(LitDictEntry { key: None, expr });
inner = top;
}
@@ -194,14 +194,16 @@ fn bracket_subheader(p: &mut Parser) -> ExprCall {
p.skip_white();
let args = if p.eat_if(Token::Colon) {
- dict_contents(p).0
+ p.span(|p| dict_contents(p).0)
} else {
// Ignore the rest if there's no colon.
- if !p.eof() {
- p.diag_expected_at("colon", p.pos());
- }
- p.eat_while(|_| true);
- LitDict::new()
+ p.span(|p| {
+ if !p.eof() {
+ p.diag_expected_at("colon", p.pos());
+ }
+ p.eat_while(|_| true);
+ LitDict::new()
+ })
};
p.end_group();
@@ -221,7 +223,7 @@ fn bracket_body(p: &mut Parser) -> SynTree {
/// Parse a parenthesized function call.
fn paren_call(p: &mut Parser, name: Spanned<Ident>) -> ExprCall {
p.start_group(Group::Paren);
- let args = dict_contents(p).0;
+ let args = p.span(|p| dict_contents(p).0);
p.end_group();
ExprCall { name, args }
}
diff --git a/src/parse/tests.rs b/src/parse/tests.rs
index 6738998a..108b4b29 100644
--- a/src/parse/tests.rs
+++ b/src/parse/tests.rs
@@ -76,6 +76,37 @@ fn Str(string: &str) -> Expr {
Expr::Lit(Lit::Str(string.to_string()))
}
+macro_rules! Call {
+ (@$name:expr $(, $span:expr)? $(; $($tts:tt)*)?) => {{
+ let name = Into::<Spanned<&str>>::into($name);
+ #[allow(unused)]
+ let mut span = Span::ZERO;
+ $(span = $span.into();)?
+ ExprCall {
+ name: name.map(|n| Ident(n.to_string())),
+ args: Dict![@$($($tts)*)?].span_with(span),
+ }
+ }};
+ ($($tts:tt)*) => { Expr::Call(Call![@$($tts)*]) };
+}
+fn Unary(op: impl Into<Spanned<UnOp>>, expr: impl Into<Spanned<Expr>>) -> Expr {
+ Expr::Unary(ExprUnary {
+ op: op.into(),
+ expr: expr.into().map(Box::new),
+ })
+}
+fn Binary(
+ op: impl Into<Spanned<BinOp>>,
+ lhs: impl Into<Spanned<Expr>>,
+ rhs: impl Into<Spanned<Expr>>,
+) -> Expr {
+ Expr::Binary(ExprBinary {
+ lhs: lhs.into().map(Box::new),
+ op: op.into(),
+ rhs: rhs.into().map(Box::new),
+ })
+}
+
macro_rules! Dict {
(@dict=$dict:expr,) => {};
(@dict=$dict:expr, $key:expr => $expr:expr $(, $($tts:tt)*)?) => {{
@@ -91,7 +122,7 @@ macro_rules! Dict {
Dict![@dict=$dict, $($($tts)*)?];
};
(@$($tts:tt)*) => {{
- #[allow(unused_mut)]
+ #[allow(unused)]
let mut dict = LitDict::new();
Dict![@dict=dict, $($tts)*];
dict
@@ -106,35 +137,6 @@ macro_rules! Tree {
($($tts:tt)*) => { Expr::Lit(Lit::Content(Tree![@$($tts)*])) };
}
-macro_rules! Call {
- (@$name:expr $(; $($tts:tt)*)?) => {{
- let name = Into::<Spanned<&str>>::into($name);
- ExprCall {
- name: name.map(|n| Ident(n.to_string())),
- args: Dict![@$($($tts)*)?],
- }
- }};
- ($($tts:tt)*) => { Expr::Call(Call![@$($tts)*]) };
-}
-
-fn Unary(op: impl Into<Spanned<UnOp>>, expr: impl Into<Spanned<Expr>>) -> Expr {
- Expr::Unary(ExprUnary {
- op: op.into(),
- expr: expr.into().map(Box::new),
- })
-}
-fn Binary(
- op: impl Into<Spanned<BinOp>>,
- lhs: impl Into<Spanned<Expr>>,
- rhs: impl Into<Spanned<Expr>>,
-) -> Expr {
- Expr::Binary(ExprBinary {
- lhs: lhs.into().map(Box::new),
- op: op.into(),
- rhs: rhs.into().map(Box::new),
- })
-}
-
// ------------------------------------ Test Macros ----------------------------------- //
// Test syntax trees with or without spans.
@@ -387,7 +389,7 @@ fn test_parse_function_bodies() {
// Spanned.
ts!(" [box][Oh my]" =>
s(0, 1, S),
- s(1, 13, F!(s(2, 5, "box");
+ s(1, 13, F!(s(2, 5, "box"), 5 .. 5;
s(6, 13, Tree![
s(7, 9, T("Oh")), s(9, 10, S), s(10, 12, T("my")),
])
@@ -431,7 +433,7 @@ fn test_parse_values() {
s(13, 13, "expected closing bracket"));
// Spanned.
- ts!("[val: 1.4]" => s(0, 10, F!(s(1, 4, "val"); s(6, 9, Float(1.4)))));
+ ts!("[val: 1.4]" => s(0, 10, F!(s(1, 4, "val"), 5 .. 9; s(6, 9, Float(1.4)))));
}
#[test]
@@ -468,7 +470,7 @@ fn test_parse_expressions() {
// Spanned.
ts!("[val: 1 + 3]" => s(0, 12, F!(
- s(1, 4, "val"); s(6, 11, Binary(
+ s(1, 4, "val"), 5 .. 11; s(6, 11, Binary(
s(8, 9, Add),
s(6, 7, Int(1)),
s(10, 11, Int(3))
@@ -476,7 +478,7 @@ fn test_parse_expressions() {
)));
// Span of parenthesized expression contains parens.
- ts!("[val: (1)]" => s(0, 10, F!(s(1, 4, "val"); s(6, 9, Int(1)))));
+ ts!("[val: (1)]" => s(0, 10, F!(s(1, 4, "val"), 5 .. 9; s(6, 9, Int(1)))));
// Invalid expressions.
v!("4pt--" => Len(Length::pt(4.0)));
@@ -504,8 +506,8 @@ fn test_parse_dicts() {
// Spanned with spacing around keyword arguments.
ts!("[val: \n hi \n = /* //\n */ \"s\n\"]" => s(0, 30, F!(
- s(1, 4, "val");
- s(8, 10, "hi") => s(25, 29, Str("s\n"))
+ s(1, 4, "val"),
+ 5 .. 29; s(8, 10, "hi") => s(25, 29, Str("s\n"))
)));
e!("[val: \n hi \n = /* //\n */ \"s\n\"]" => );
}