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
if !context.next_token(Lexical.TOKEN.AT) then
17
return null;
18
fi
19
20
let name = qualified_identifier_parser.parse(context);
21
22
if !name? then
23
return null;
24
fi
25
26
let positional = Collections.LIST[Trees.Expressions.Expression]();
27
let named = Collections.LIST[Trees.Pragmas.NAMED_ARGUMENT]();
28
29
if context.next_token(Lexical.TOKEN.PAREN_OPEN) then
30
if context.current.token != Lexical.TOKEN.PAREN_CLOSE then
31
do
32
let expression = expression_parser.parse(context)!;
33
34
let identifier_expression = cast Trees.Expressions.IDENTIFIER?(expression);
35
36
if
37
identifier_expression? /\
38
identifier_expression.is_unqualified_identifier /\
39
context.current.token == Lexical.TOKEN.ASSIGN
40
then
41
context.next_token();
42
43
let value = expression_parser.parse(context)!;
44
45
named.add(
46
Trees.Pragmas.NAMED_ARGUMENT(identifier_expression.identifier, value)
47
);
48
else
49
positional.add(expression);
50
fi
51
52
if context.current.token != Lexical.TOKEN.COMMA then
53
break;
54
fi
55
56
context.next_token();
57
58
// Trailing comma before the closing parenthesis.
59
if context.current.token == Lexical.TOKEN.PAREN_CLOSE then
60
break;
61
fi
62
od
63
fi
64
65
context.next_token(Lexical.TOKEN.PAREN_CLOSE);
66
fi
67
68
return Trees.Pragmas.PRAGMA(
69
start::context.location,
70
name,
71
Trees.Expressions.LIST(start::context.location, positional),
72
named
73
);
74
si
75
si
76
si