18
18
19
19
#include " language.h"
20
20
21
+ #include < util/invariant.h>
22
+ #include < util/namespace.h>
23
+
21
24
struct language_entryt
22
25
{
23
26
language_factoryt factory;
@@ -28,6 +31,10 @@ struct language_entryt
28
31
typedef std::list<language_entryt> languagest;
29
32
languagest languages;
30
33
34
+ // / Register a language
35
+ // / Note: registering a language is required for using the functions
36
+ // / in language_util.h
37
+ // / \param factory: a language factory, e.g. `new_ansi_c_language`
31
38
void register_language (language_factoryt factory)
32
39
{
33
40
languages.push_back (language_entryt ());
@@ -37,17 +44,60 @@ void register_language(language_factoryt factory)
37
44
languages.back ().mode =l->id ();
38
45
}
39
46
47
+ // / Get the language corresponding to the given mode
48
+ // / \param mode: the mode, e.g. `ID_C`
49
+ // / \return the language or `nullptr` if the language has not been registered
40
50
std::unique_ptr<languaget> get_language_from_mode (const irep_idt &mode)
41
51
{
42
- for (languagest::const_iterator it=languages.begin ();
43
- it!=languages.end ();
44
- it++)
45
- if (mode==it->mode )
46
- return it->factory ();
52
+ for (const auto &language : languages)
53
+ if (mode == language.mode )
54
+ return language.factory ();
47
55
48
56
return nullptr ;
49
57
}
50
58
59
+ // / Get the mode of the given identifier's symbol
60
+ // / \param ns: a namespace
61
+ // / \param identifier: an identifier
62
+ // / \return the mode, e.g. `ID_C`, if the identifier is in the given
63
+ // / symbol table, or `ID_unknown` otherwise
64
+ const irep_idt &
65
+ get_mode_from_identifier (const namespacet &ns, const irep_idt &identifier)
66
+ {
67
+ if (identifier.empty ())
68
+ return ID_unknown;
69
+ const symbolt *symbol;
70
+ if (ns.lookup (identifier, symbol))
71
+ return ID_unknown;
72
+ return symbol->mode ;
73
+ }
74
+
75
+ // / Get the language corresponding to the mode of the given identifier's symbol
76
+ // / \param ns: a namespace
77
+ // / \param identifier: an identifier
78
+ // / \return the corresponding language if the mode is not `ID_unknown`, or
79
+ // / the default language otherwise;
80
+ // / Note: It is assumed as an invariant that languages of symbols in the symbol
81
+ // / table have been registered.
82
+ std::unique_ptr<languaget>
83
+ get_language_from_identifier (const namespacet &ns, const irep_idt &identifier)
84
+ {
85
+ const irep_idt &mode = get_mode_from_identifier (ns, identifier);
86
+ if (mode == ID_unknown)
87
+ return get_default_language ();
88
+
89
+ std::unique_ptr<languaget> language = get_language_from_mode (mode);
90
+ INVARIANT (
91
+ language,
92
+ " symbol `" + id2string (identifier) + " ' has unknown mode '" +
93
+ id2string (mode) + " '" );
94
+ return language;
95
+ }
96
+
97
+ // / Get the language corresponding to the registered file name extensions
98
+ // / \param filename: a filename
99
+ // / \return the corresponding language or `nullptr` if the extension cannot
100
+ // / be resolved to any registered language
51
101
std::unique_ptr<languaget> get_language_from_filename (
52
102
const std::string &filename)
53
103
{
@@ -83,8 +133,10 @@ std::unique_ptr<languaget> get_language_from_filename(
83
133
return nullptr ;
84
134
}
85
135
136
+ // / Returns the default language
137
+ // / \return the first registered language
86
138
std::unique_ptr<languaget> get_default_language ()
87
139
{
88
- assert (!languages.empty ());
140
+ PRECONDITION (!languages.empty ());
89
141
return languages.front ().factory ();
90
142
}
0 commit comments