Skip to content
← Back

src/syntax/parsers/expressions/list.ghul

1
namespace Syntax.Parsers.Expressions is
2
use IO.Std;
3
4
use Source;
5
6
class LIST(expression_parser: Parser[Trees.Expressions.Expression]): Base[Trees.Expressions.LIST] is
7
super();
8
9
description: string => "expression list";
10
11
parse(context: CONTEXT) -> Trees.Expressions.LIST is
12
let start = context.location;
13
let expressions = Collections.LIST[Trees.Expressions.Expression]();
14
15
do
16
context.allow_tuple_element = true;
17
let expression = expression_parser.parse(context);
18
context.allow_tuple_element = false;
19
20
// The expression parser chain bottoms out at a poisoned
21
// placeholder rather than null, but that's an invariant of
22
// the current wiring, not a contract: guard here so a
23
// future element parser without that override can't put
24
// a null in the list.
25
if !expression? then
26
break;
27
fi
28
29
expressions.add(expression);
30
31
if context.current.token != Lexical.TOKEN.COMMA then
32
return Trees.Expressions.LIST(start::expression.location, expressions);
33
fi
34
35
context.next_token();
36
37
// Trailing comma: stop when a closing bracket follows.
38
// The same parser drives list literals (`[a, b,]`),
39
// tuple literals (`(a, b,)`) and call argument lists
40
// (`f(a, b,)`), so one check covers all three.
41
if
42
context.current.token == Lexical.TOKEN.SQUARE_CLOSE \/
43
context.current.token == Lexical.TOKEN.PAREN_CLOSE
44
then
45
return Trees.Expressions.LIST(start::context.location, expressions);
46
fi
47
od
48
49
return Trees.Expressions.LIST(start::context.location, expressions);
50
si
51
si
52
si