Skip to content
← Back

src/syntax/parsers/definitions/pragma.ghul

1
namespace Syntax.Parsers.Definitions is
2
use Collections.MutableMap;
3
use Collections.MAP;
4
5
use Syntax.Parsers.Expressions.PRECEDENCE;
6
7
use Source;
8
9
use Logging;
10
11
enum PrecedenceRestoreStatus is
12
NO_RESTORE_NEEDED,
13
REMOVE_PRECEDENCE,
14
RESTORE_PRECEDENCE
15
si
16
17
class PRAGMA(
18
pragma_parser: Parser[Trees.Pragmas.PRAGMA],
19
definition_parser: Parser[Trees.Definitions.Definition],
20
precedence_map: MutableMap[string,PRECEDENCE]
21
): Base[Trees.Definitions.PRAGMA] is
22
// FIXME: use enum parse
23
_precedence_names: MutableMap[string,PRECEDENCE];
24
25
super();
26
27
init(..) is
28
_precedence_names = MAP[string,PRECEDENCE]();
29
30
_precedence_names.add("user-1", PRECEDENCE.USER_1);
31
_precedence_names.add("boolean", PRECEDENCE.BOOLEAN);
32
_precedence_names.add("user-2", PRECEDENCE.USER_2);
33
_precedence_names.add("relational", PRECEDENCE.RELATIONAL);
34
_precedence_names.add("user-3", PRECEDENCE.USER_3);
35
_precedence_names.add("range", PRECEDENCE.RANGE);
36
_precedence_names.add("user-4", PRECEDENCE.USER_4);
37
_precedence_names.add("shift", PRECEDENCE.SHIFT);
38
_precedence_names.add("user-5", PRECEDENCE.USER_5);
39
_precedence_names.add("bitwise", PRECEDENCE.BITWISE);
40
_precedence_names.add("user-6", PRECEDENCE.USER_6);
41
_precedence_names.add("addition", PRECEDENCE.ADDITION);
42
_precedence_names.add("user-7", PRECEDENCE.USER_7);
43
_precedence_names.add("multiplication", PRECEDENCE.MULTIPLICATION);
44
_precedence_names.add("user-8", PRECEDENCE.USER_8);
45
_precedence_names.add("member", PRECEDENCE.MEMBER);
46
_precedence_names.add("primary", PRECEDENCE.PRIMARY);
47
si
48
49
parse(context: CONTEXT) -> Trees.Definitions.PRAGMA? is
50
let pragma = pragma_parser.parse(context);
51
52
// FIXME: factor this out
53
if pragma? /\ !pragma.is_poisoned then
54
let operator_name: string? mut = null;
55
let precedence_to_restore: PRECEDENCE mut = _;
56
57
let restore_status mut = PrecedenceRestoreStatus.NO_RESTORE_NEEDED;
58
59
if
60
pragma.is_name_equal_to("precedence")
61
then
62
let is_precedence_valid mut = true;
63
64
operator_name = pragma.try_get_string_literal_at(0);
65
let precedence_name = pragma.try_get_string_literal_at(1);
66
67
if !operator_name? then
68
context.error(pragma.location, "expected operator name argument");
69
70
is_precedence_valid = false;
71
fi
72
73
let precedence_to_set: PRECEDENCE mut = _;
74
75
if !precedence_name? then
76
context.error(pragma.location, "expected operator precedence argument");
77
78
is_precedence_valid = false;
79
elif !_precedence_names.try_get_value(precedence_name, precedence_to_set ref) then
80
context.error(pragma.location, "unknown precedence name {precedence_name}");
81
82
is_precedence_valid = false;
83
fi
84
85
if is_precedence_valid then
86
if
87
cast int(precedence_to_set) < cast int(PRECEDENCE.USER_1) \/
88
cast int(precedence_to_set) > cast int(PRECEDENCE.USER_8)
89
then
90
context.error(pragma.location, "precedence must be between user-1 and user-8");
91
is_precedence_valid = false;
92
fi
93
fi
94
95
if is_precedence_valid /\ operator_name? then
96
if precedence_map.try_get_value(operator_name, precedence_to_restore ref) then
97
restore_status = PrecedenceRestoreStatus.RESTORE_PRECEDENCE;
98
else
99
restore_status = PrecedenceRestoreStatus.REMOVE_PRECEDENCE;
100
fi
101
102
precedence_map[operator_name] = precedence_to_set;
103
fi
104
fi
105
106
let definition = definition_parser.parse(context);
107
108
if operator_name? then
109
if restore_status == PrecedenceRestoreStatus.RESTORE_PRECEDENCE then
110
precedence_map[operator_name] = precedence_to_restore;
111
elif restore_status == PrecedenceRestoreStatus.REMOVE_PRECEDENCE then
112
precedence_map.remove(operator_name);
113
fi
114
fi
115
116
if definition? /\ !definition.is_poisoned then
117
return Trees.Definitions.PRAGMA(pragma.location::definition.location, pragma, definition);
118
fi
119
fi
120
121
return null;
122
si
123
si
124
si