Skip to content
← Back

src/syntax/parsers/pragmas/pragma.ghul

1
namespace Syntax.Parsers.Pragmas is
2
3
use Source
4
5
use Logging
6
7
class PRAGMA(
8
qualified_identifier_parser: Parser[Trees.Identifiers.Identifier],
9
expression_parser: Parser[Trees.Expressions.Expression]
10
): Base[Trees.Pragmas.PRAGMA] is
11
super()
12
13
parse(context: CONTEXT) -> Trees.Pragmas.PRAGMA? is
14
let start = context.location
15
16
// `@@` reaches this parser only from the file root, where
17
// the definition-list parser routes a leading `@@` here for a
18
// whole-file pragma; everywhere else a `@@` is rejected before
19
// dispatch and a lone `@` opens the ordinary forms.
20
if context.current.token == Lexical.TOKEN.AT_AT then
21
context.next_token()
22
elif !context.next_token(Lexical.TOKEN.AT) then
23
return null
24
fi
25
26
let name = qualified_identifier_parser.parse(context)
27
28
if !name? then
29
return null
30
fi
31
32
let positional = Collections.LIST[Trees.Expressions.Expression]()
33
let named = Collections.LIST[Trees.Pragmas.NAMED_ARGUMENT]()
34
35
if context.next_token(Lexical.TOKEN.PAREN_OPEN) then
36
if context.current.token != Lexical.TOKEN.PAREN_CLOSE then
37
do
38
let expression = expression_parser.parse(context)!
39
40
let identifier_expression = cast Trees.Expressions.IDENTIFIER?(expression)
41
42
if
43
identifier_expression? /\
44
identifier_expression.is_unqualified_identifier /\
45
context.current.token == Lexical.TOKEN.ASSIGN
46
then
47
context.next_token()
48
49
let value = expression_parser.parse(context)!
50
51
named.add(
52
Trees.Pragmas.NAMED_ARGUMENT(identifier_expression.identifier, value)
53
)
54
else
55
positional.add(expression)
56
fi
57
58
if context.current.token != Lexical.TOKEN.COMMA then
59
break
60
fi
61
62
context.next_token()
63
64
// Trailing comma before the closing parenthesis.
65
if context.current.token == Lexical.TOKEN.PAREN_CLOSE then
66
break
67
fi
68
od
69
fi
70
71
context.next_token(Lexical.TOKEN.PAREN_CLOSE)
72
fi
73
74
return Trees.Pragmas.PRAGMA(
75
start::context.location,
76
name,
77
Trees.Expressions.LIST(start::context.location, positional),
78
named
79
)
80
si
81
si
82
si