[sc-699] Require , in list-like things in imp syntax

This commit is contained in:
Nicolas Abril 2024-05-17 18:08:51 +02:00
parent 8a137b0d87
commit 1585d2d5bc
9 changed files with 66 additions and 28 deletions

View File

@ -44,6 +44,7 @@
"inodes",
"insta",
"interner",
"ints",
"itertools",
"ITRS",
"kwarg",

View File

@ -16,7 +16,7 @@ def and(a, b):
def all(tree):
fold tree:
case Tree/Node:
return and(tree.lft tree.rgt)
return and(tree.lft, tree.rgt)
case Tree/Leaf:
return tree.val

View File

@ -96,6 +96,7 @@ impl<'a> PyParser<'a> {
let ini_idx = *self.index();
let base = match head {
// Tuple or parenthesized expression
'(' => {
self.advance_one();
let head = self.parse_expr(false)?;
@ -114,41 +115,49 @@ impl<'a> PyParser<'a> {
head
}
}
// Map or Sup
'{' => {
self.advance_one();
self.skip_trivia();
if self.try_consume_exactly("}") {
return Ok(Expr::MapInit { entries: Vec::new() });
// Empty map
if self.try_consume("}") {
return Ok(Expr::MapInit { entries: vec![] });
}
let head = self.parse_expr(false)?;
self.skip_trivia();
if self.starts_with(":") { self.parse_map_init(head)? } else { self.parse_sup(head)? }
}
// List or Comprehension
'[' => self.list_or_comprehension()?,
// Symbol
'`' => Expr::Num { val: Num::U24(self.parse_quoted_symbol()?) },
// String
'\"' => {
let str = self.parse_quoted_string()?;
let val = STRINGS.get(str);
Expr::Str { val }
}
// Char
'\'' => {
let chr = self.parse_quoted_char()?;
Expr::Num { val: Num::U24(chr as u32 & 0x00ff_ffff) }
}
// Unscoped var
'$' => {
self.advance_one();
let nam = self.parse_bend_name()?;
Expr::Chn { nam }
}
// Era
'*' => {
self.advance_one();
Expr::Eraser
}
// Number
c if is_num_char(c) => {
let val = self.parse_number()?;
Expr::Num { val }
}
// var or postfix
// var
_ => {
let nam = self.labelled(|p| p.parse_bend_name(), "expression")?;
Expr::Var { nam }
@ -178,7 +187,9 @@ impl<'a> PyParser<'a> {
} else {
args.push(arg);
}
self.try_consume(",");
if !self.starts_with(")") {
self.consume(",")?;
}
}
if args.is_empty() && kwargs.is_empty() {
return Ok(base);
@ -202,7 +213,7 @@ impl<'a> PyParser<'a> {
// ctr
if self.starts_with("{") {
if let Expr::Var { nam } = base {
let kwargs = self.list_like(|p| p.data_kwarg(), "{", "}", ",", false, 0)?;
let kwargs = self.list_like(|p| p.data_kwarg(), "{", "}", ",", true, 0)?;
return Ok(Expr::Constructor { name: nam, args: Vec::new(), kwargs });
} else {
return self.expected_spanned("Constructor name", ini_idx, end_idx);
@ -218,15 +229,18 @@ impl<'a> PyParser<'a> {
self.consume(":")?;
let val = self.parse_expr(false)?;
entries.push((head, val));
self.try_consume(",");
let tail = self.list_like(|p| p.parse_map_entry(), "", "}", ",", false, 0)?;
self.skip_trivia();
if !self.starts_with("}") {
self.consume(",")?;
}
let tail = self.list_like(|p| p.parse_map_entry(), "", "}", ",", true, 0)?;
entries.extend(tail);
Ok(Expr::MapInit { entries })
}
fn parse_sup(&mut self, head: Expr) -> ParseResult<Expr> {
let mut els = vec![head];
let tail = self.list_like(|p| p.parse_expr(false), "", "}", ",", false, 1)?;
let tail = self.list_like(|p| p.parse_expr(false), "", "}", ",", true, 1)?;
els.extend(tail);
Ok(Expr::Sup { els })
}
@ -274,8 +288,11 @@ impl<'a> PyParser<'a> {
} else {
// List
let mut head = vec![head];
self.try_consume(",");
let tail = self.list_like(|p| p.parse_expr(false), "", "]", ",", false, 0)?;
self.skip_trivia();
if !self.starts_with("]") {
self.consume(",")?;
}
let tail = self.list_like(|p| p.parse_expr(false), "", "]", ",", true, 0)?;
head.extend(tail);
Ok(Expr::Lst { els: head })
}
@ -685,7 +702,9 @@ impl<'a> PyParser<'a> {
while !self.starts_with(":") {
with.push(self.parse_bend_name()?);
self.skip_trivia_inline();
self.try_consume_exactly(",");
if !self.starts_with(":") {
self.consume_exactly(",")?;
}
self.skip_trivia_inline();
}
with
@ -721,7 +740,7 @@ impl<'a> PyParser<'a> {
/// "else" ":"
/// <base>
fn parse_bend(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
let args = self.list_like(|p| p.parse_match_arg(), "", ":", ",", false, 1)?;
let args = self.list_like(|p| p.parse_match_arg(), "", ":", ",", true, 1)?;
let (bind, init) = args.into_iter().unzip();
self.consume_new_line()?;
indent.enter_level();
@ -822,7 +841,7 @@ impl<'a> PyParser<'a> {
}
// Dup pattern
if self.starts_with("{") {
let binds = self.list_like(|p| p.parse_assign_pattern(), "{", "}", "", false, 2)?;
let binds = self.list_like(|p| p.parse_assign_pattern(), "{", "}", ",", true, 2)?;
return Ok(AssignPattern::Sup(binds));
}
@ -892,7 +911,7 @@ impl<'a> PyParser<'a> {
let name = self.parse_bend_name()?;
self.skip_trivia_inline();
let params = if self.starts_with("(") {
self.list_like(|p| p.parse_bend_name(), "(", ")", ",", false, 0)?
self.list_like(|p| p.parse_bend_name(), "(", ")", ",", true, 0)?
} else {
vec![]
};
@ -932,7 +951,7 @@ impl<'a> PyParser<'a> {
let mut fields = Vec::new();
self.skip_trivia_inline();
if self.starts_with("{") {
fields = self.list_like(|p| p.parse_variant_field(), "{", "}", ",", false, 0)?;
fields = self.list_like(|p| p.parse_variant_field(), "{", "}", ",", true, 0)?;
}
variants.push(Variant { name: ctr_name, fields });
if !self.is_eof() {
@ -957,7 +976,7 @@ impl<'a> PyParser<'a> {
let name = self.parse_top_level_name()?;
self.skip_trivia_inline();
let fields = if self.starts_with("{") {
self.list_like(|p| p.parse_variant_field(), "{", "}", ",", false, 0)?
self.list_like(|p| p.parse_variant_field(), "{", "}", ",", true, 0)?
} else {
vec![]
};

View File

@ -53,17 +53,17 @@ def swt(n):
def fld(list):
fold list:
case List/cons:
case List/Cons:
return 1;
case List/nil:
case List/Nil:
return 2;
def bnd():
bend x = 0:
when x < 10:
return List/cons(x fork(x + 1));
return List/Cons(x, fork(x + 1));
else:
return List/nil();
return List/Nil();
def era():
* = (2 + 3)

View File

@ -1,7 +1,7 @@
def main:
y = 1
fold x = [0 0 0] with y:
fold x = [0, 0, 0] with y:
case List/Cons:
return List/Cons(x.head + y x.tail(y + 1))
return List/Cons(x.head + y, x.tail(y + 1))
case List/Nil:
return List/Nil

View File

@ -1,2 +0,0 @@
def main:
return []

View File

@ -0,0 +1,11 @@
def list:
return []
def map:
return {}
def str:
return ""
def main:
return []

View File

@ -26,14 +26,18 @@ input_file: tests/golden_tests/parse_file/imp_program.bend
(swt) = λ%arg0 use n = %arg0; switch n = n { 0: 42; _ n-1: 1; }
(fld) = λ%arg0 use list = %arg0; fold list = list { List/cons: 1; List/nil: 2; }
(fld) = λ%arg0 use list = %arg0; fold list = list { List/Cons: 1; List/Nil: 2; }
(bnd) = bend x = 0, { when (< x 10): (List/cons x (fork (+ x 1))); else: List/nil }
(bnd) = bend x = 0, { when (< x 10): (List/Cons x (fork (+ x 1))); else: List/Nil }
(era) = let * = (+ 2 3); let the_expr_killer = *; (the_expr_killer 9)
(main) = do IO { ask x = IO.read; x }
(List/Cons) = λhead λtail λList/Cons λList/Nil (List/Cons head tail)
(List/Nil) = λList/Cons λList/Nil List/Nil
(Map/Node) = λvalue λleft λright λMap/Node λMap/Leaf (Map/Node value left right)
(Map/Leaf) = λMap/Node λMap/Leaf Map/Leaf

View File

@ -0,0 +1,5 @@
---
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/imp_empty_literals.bend
---
λ* λa a