This commit is contained in:
imaqtkatt 2024-05-12 20:15:05 -03:00
parent 204024500c
commit 7c403e9ddf
5 changed files with 65 additions and 13 deletions

View File

@ -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);
}

View File

@ -28,6 +28,8 @@ pub enum Expr {
Lst { els: Vec<Expr> },
// "(" ... ")"
Tup { els: Vec<Expr> },
// "{" {els} "}"
Sup { els: Vec<Expr> },
// {name} "{" {kwargs} "}"
Constructor { name: Name, args: Vec<Expr>, kwargs: Vec<(Name, Expr)> },
// "[" {term} "for" {bind} "in" {iter} ("if" {cond})? "]"
@ -53,6 +55,8 @@ pub enum AssignPattern {
Var(Name),
// "(" ... ")"
Tup(Vec<Name>),
// "{" ... "}"
Sup(Vec<Name>),
// {name} "[" {expr} "]"
MapSet(Name, Expr),
}

View File

@ -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)?;
}

View File

@ -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<Expr, String> {
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<Expr, String> {
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<Stmt, String> {
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)
}

View File

@ -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);