diff --git a/src/imp/gen_map_get.rs b/src/imp/gen_map_get.rs index e65409ae..f20ecdb4 100644 --- a/src/imp/gen_map_get.rs +++ b/src/imp/gen_map_get.rs @@ -107,7 +107,7 @@ impl Expr { go(lhs, substitutions, id); go(rhs, substitutions, id); } - Expr::Lst { els } | Expr::Tup { els } => { + Expr::Lst { els } | Expr::Tup { els } | Expr::Sup { els } => { for el in els { go(el, substitutions, id); } diff --git a/src/imp/mod.rs b/src/imp/mod.rs index 013ada4e..1131232a 100644 --- a/src/imp/mod.rs +++ b/src/imp/mod.rs @@ -28,6 +28,8 @@ pub enum Expr { Lst { els: Vec }, // "(" ... ")" Tup { els: Vec }, + // "{" {els} "}" + Sup { els: Vec }, // {name} "{" {kwargs} "}" Constructor { name: Name, args: Vec, kwargs: Vec<(Name, Expr)> }, // "[" {term} "for" {bind} "in" {iter} ("if" {cond})? "]" @@ -53,6 +55,8 @@ pub enum AssignPattern { Var(Name), // "(" ... ")" Tup(Vec), + // "{" ... "}" + Sup(Vec), // {name} "[" {expr} "]" MapSet(Name, Expr), } diff --git a/src/imp/order_kwargs.rs b/src/imp/order_kwargs.rs index f24976a5..43c433f6 100644 --- a/src/imp/order_kwargs.rs +++ b/src/imp/order_kwargs.rs @@ -104,7 +104,7 @@ impl Expr { lhs.order_kwargs(book)?; rhs.order_kwargs(book)?; } - Expr::Lst { els } | Expr::Tup { els } => { + Expr::Lst { els } | Expr::Tup { els } | Expr::Sup { els } => { for el in els { el.order_kwargs(book)?; } diff --git a/src/imp/parser.rs b/src/imp/parser.rs index 112903bc..47bd6159 100644 --- a/src/imp/parser.rs +++ b/src/imp/parser.rs @@ -87,16 +87,18 @@ impl<'a> PyParser<'a> { } '{' => { self.consume("{")?; - let mut entries = Vec::new(); - loop { - entries.push(self.parse_map_entry()?); - if self.skip_starts_with("}") { - break; - } - self.consume(",")?; - } - self.consume("}")?; - Expr::MapInit { entries } + let head = self.parse_infix_or_lambda()?; + if self.skip_starts_with(":") { self.parse_map_init(head)? } else { self.parse_sup(head)? } + // let mut entries = Vec::new(); + // loop { + // entries.push(self.parse_map_entry()?); + // if self.skip_starts_with("}") { + // break; + // } + // self.consume(",")?; + // } + // self.consume("}")?; + // Expr::MapInit { entries } } '[' => self.list_or_comprehension()?, '`' => Expr::Num { val: self.parse_symbol()? }, @@ -126,6 +128,39 @@ impl<'a> PyParser<'a> { Ok(res) } + fn parse_map_init(&mut self, head: Expr) -> Result { + let mut entries = Vec::new(); + let map_key = match head { + Expr::Num { val } => MapKey(val), + _ => self.expected("Number keyword")?, + }; + self.consume(":")?; + let val = self.parse_expression()?; + entries.push((map_key, val)); + self.try_consume(","); + loop { + if self.skip_starts_with("}") { + break; + } + entries.push(self.parse_map_entry()?); + self.consume(",")?; + } + self.consume("}")?; + Ok(Expr::MapInit { entries }) + } + + fn parse_sup(&mut self, head: Expr) -> Result { + let mut els = vec![head]; + loop { + if self.skip_starts_with("}") { + break; + } + els.push(self.parse_infix_or_lambda()?); + } + self.consume("}")?; + Ok(Expr::Sup { els }) + } + fn data_kwarg(&mut self) -> Result<(Name, Expr), String> { let nam = self.parse_bend_name()?; self.consume(":")?; @@ -355,7 +390,7 @@ impl<'a> PyParser<'a> { } fn parse_in_place(&mut self, indent: &mut Indent) -> Result { - if self.starts_with("(") { + if self.starts_with("(") || self.starts_with("{") { self.parse_assignment(indent) } else { let name = self.parse_bend_name()?; @@ -602,6 +637,9 @@ impl<'a> PyParser<'a> { } else { Ok(AssignPattern::Tup(binds)) } + } else if self.skip_starts_with("{") { + let binds = self.list_like(|p| p.parse_bend_name(), "{", "}", "", false, 2)?; + Ok(AssignPattern::Sup(binds)) } else { self.parse_bend_name().map(AssignPattern::Var) } diff --git a/src/imp/to_fun.rs b/src/imp/to_fun.rs index 7ed9a75d..547009e9 100644 --- a/src/imp/to_fun.rs +++ b/src/imp/to_fun.rs @@ -21,6 +21,11 @@ impl AssignPattern { fun::Tag::Static, names.into_iter().map(|name| fun::Pattern::Var(Some(name))).collect(), ), + AssignPattern::Sup(names) => fun::Pattern::Fan( + fun::FanKind::Dup, + fun::Tag::Auto, + names.into_iter().map(|name| fun::Pattern::Var(Some(name))).collect(), + ), AssignPattern::MapSet(..) => unreachable!(), } } @@ -119,6 +124,11 @@ impl Expr { tag: fun::Tag::Static, els: els.into_iter().map(Self::to_fun).collect(), }, + Expr::Sup { els } => fun::Term::Fan { + fan: fun::FanKind::Dup, + tag: fun::Tag::Auto, + els: els.into_iter().map(Self::to_fun).collect(), + }, Expr::Constructor { name, args, kwargs } => { assert!(kwargs.is_empty()); let args = args.into_iter().map(Self::to_fun);