Skip to content
← Back

src/syntax/process/synthesise_top_level_entry.ghul

1
namespace Syntax.Process is
2
use Source;
3
use Logging;
4
use Trees;
5
6
// Synthesises a global entry point from a file's top-level statements.
7
//
8
// A file with no namespace may carry bare statements at file scope. The
9
// parser collects them, in source order, onto the root definition list;
10
// this rewriter wraps them into a global function named after the
11
// configured entry point, so every downstream phase sees an ordinary
12
// function. Runs before expand_namespaces, which then wraps the
13
// synthesised function into the file's root namespace alongside any other
14
// global definitions.
15
//
16
// Top-level statements and namespaces are mutually exclusive in a file:
17
// a file that carries both is a compile error and no entry is synthesised.
18
class SYNTHESISE_TOP_LEVEL_ENTRY(_ir_context: IR.CONTEXT, _logger: Logger) is
19
apply(node: Node) is
20
if !isa Definitions.LIST(node) then
21
return;
22
fi
23
24
let list = cast Definitions.LIST(node);
25
let statements = list.top_level_statements;
26
27
if !statements? then
28
return;
29
fi
30
31
list.top_level_statements = null;
32
33
for definition in list do
34
if isa Definitions.NAMESPACE(definition) then
35
_logger.error(
36
statements.location,
37
"top-level statements cannot appear in a file with a namespace"
38
);
39
40
return;
41
fi
42
od
43
44
list.add(_synthesise_entry(statements));
45
si
46
47
_synthesise_entry(statements: Statements.LIST) -> Definitions.FUNCTION =>
48
let location = statements.location in
49
Definitions.FUNCTION(
50
location,
51
// The entry has no declaration the source names, so its
52
// identifier carries an internal location: a name at the
53
// statement span would record a hover use covering the whole
54
// region, and any hover on a non-symbol position there would
55
// report the synthesised entry.
56
Identifiers.Identifier(LOCATION.internal, _ir_context.entry_point_name),
57
TypeExpressions.LIST(location, Collections.LIST[TypeExpressions.TypeExpression](0)),
58
Variables.LIST(location, Collections.LIST[Variables.VARIABLE](0)),
59
TypeExpressions.INFER(location),
60
Modifiers.LIST(location, null, null),
61
Bodies.BLOCK(location, statements)
62
);
63
si
64
si