Skip to content
← Back

src/syntax/parsers/bodies/body.ghul

1
namespace Syntax.Parsers.Bodies is
2
use IO.Std;
3
4
5
class BODY(
6
expression_parser: Parser[Trees.Expressions.Expression],
7
statement_parser: Parser[Trees.Statements.Statement],
8
statement_list_parser: Parser[Trees.Statements.LIST],
9
identifier_qualified_parser: Parser[Trees.Identifiers.Identifier]
10
): Base[Trees.Bodies.Body] is
11
description: string => "function body";
12
13
super();
14
15
init(..) is
16
add_parsers();
17
si
18
19
add_parsers() is
20
add_parser(
21
(context: CONTEXT) is
22
context.next_token(Lexical.TOKEN.ARROW_FAT);
23
24
// `=> throw E` stubs out a body that always diverges.
25
// `throw` is a statement, not an expression, so wrap
26
// it the way `if`/`case` bodies are wrapped; the body
27
// takes its type from the declared return type (or
28
// settles void when that is inferred).
29
if context.current.token == Lexical.TOKEN.THROW then
30
let statement = statement_parser.parse(context)!;
31
return Trees.Bodies.EXPRESSION(statement.location, Trees.Expressions.STATEMENT(statement.location, statement));
32
fi
33
34
let expression = expression_parser.parse(context)!;
35
return Trees.Bodies.EXPRESSION(expression.location, expression);
36
si,
37
Lexical.TOKEN.ARROW_FAT
38
);
39
40
add_parser(
41
(context: CONTEXT) is
42
let start = context.location;
43
context.next_token(Lexical.TOKEN.IS);
44
let statement_list = statement_list_parser.parse(context)!;
45
let end = context.location;
46
context.next_token(Lexical.TOKEN.SI);
47
return Trees.Bodies.BLOCK(start::end, statement_list);
48
si,
49
Lexical.TOKEN.IS
50
);
51
52
add_parser(
53
(context: CONTEXT) is
54
let start = context.location;
55
context.next_token(Lexical.TOKEN.INNATE);
56
let identifier = identifier_qualified_parser.parse(context)!;
57
return Trees.Bodies.INNATE(start::identifier.location, identifier);
58
si,
59
Lexical.TOKEN.INNATE
60
);
61
si
62
63
other_token(context: CONTEXT) -> Trees.Bodies.Body =>
64
Trees.Bodies.NULL(context.location);
65
si
66
si