TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Interprete_bloc.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Interprete_bloc.h>
17#include <Type_Verifie.h>
18
19// `export <Type> <name>` is a TRUST-specific prefix on forward
20// declarations — it tells Interprete_bloc::lire to add the resulting
21// object to the parent Interprete_bloc's scope instead of the local
22// one, so the name survives Read_file's sub-block destruction. There
23// is no dedicated C++ class for it; the parsing is inlined below.
24// trustify recognises the `export` keyword directly in
25// Dataset_Parser.ReadFromTokens — it treats `export <Type> <name>`
26// as a regular forward declaration and stashes the `export` token on
27// the resulting Declaration_Parser for round-trip emission.
28
29Implemente_instanciable_sans_constructeur_ni_destructeur(Interprete_bloc,"Interprete_bloc",Liste_bloc);
30
31// See Interprete_bloc::interprete_courant()
32static OBS_PTR(Interprete_bloc) interprete_courant_;
33
34/*! @brief Returns the Interprete_bloc currently being read from the data set.
35 *
36 * The current interpreter changes
37 * when an object of type Interprete_bloc is created or destroyed
38 * (for example when entering or leaving a { } block).
39 *
40 */
42{
43 return interprete_courant_.valeur();
44}
45
46Interprete_bloc::Interprete_bloc()
47{
48 // If a current interpreter exists, it becomes the parent
49 // of the interpreter being constructed:
50 if (interprete_courant_) pere_ = interprete_courant_;
51
52 interprete_courant_ = *this;
53}
54
55Interprete_bloc::~Interprete_bloc()
56{
57 // Restore the value of the previous current interpreter
58 interprete_courant_ = pere_;
59}
60
62{
64 return os;
65}
66
68{
70 return is;
71}
72
73/*! @brief Interprets a block of instructions read from input is.
74 *
75 * If the block begins with {, the opening brace is assumed to have already been read.
76 * The block ends with }, end of file, or the keyword FIN depending on bloc_type
77 * (see mon_main.cpp for example).
78 * If verifie_sans_interpreter!=0, no objects are created and no interpreter
79 * is started; only the consistency of braces is checked (same number of { as }).
80 *
81 */
82Entree& Interprete_bloc::interpreter_bloc(Entree& is, Bloc_Type bloc_type, int verifie_sans_interpreter)
83{
84 // The output level for journal messages
85 const int jlevel = 3;
86 Journal(jlevel) << "Interprete_bloc::interpreter_bloc bloc_type=" << (int) bloc_type << finl;
87 Motcle motlu;
88 is >> motlu;
89 while (1)
90 {
91 // Are we at the end of the block?
92 if (is.eof())
93 {
94 // Some .data files do not end with FIN; reaching eof without finding "FIN" is also accepted.
95 if (bloc_type == BLOC_EOF || bloc_type == FIN)
96 {
97 Journal(jlevel) << "Interprete_bloc: end of file => end of bloc" << finl;
98 break;
99 }
100 else
101 {
102 Cerr << "Error in Interprete_bloc: unexpected end of file\n" << "check for missig \"}\" or missing FIN keyword" << finl;
104 }
105 }
106 // Other possible endings:
107 if (motlu == "}" || motlu == "FIN|END")
108 {
109 if ((motlu == "}" && bloc_type == ACCOLADE) || (motlu == "FIN|END" && bloc_type == FIN))
110 {
111 Journal(jlevel) << "Interprete_bloc: reading " << motlu << " => end of bloc" << finl;
112 break;
113 }
114 else
115 {
116 if (motlu == "}")
117 Cerr << "Error in Interprete_bloc: extra \"}\" in data file" << finl;
118 else
119 Cerr << "Error in Interprete_bloc: unexpected FIN, check for missing \"}\"" << finl;
121 }
122 }
123
124 // Is it a comment?
125 if (motlu == "#")
126 {
127 Nom commentaire("# ");
128 Nom nom_lu;
129 int countleft = 8; // Keep the first 8 words of the comment
130 do
131 {
132 is >> nom_lu;
133 if (is.eof())
134 break;
135 if ((countleft--) > 0)
136 {
137 commentaire += nom_lu;
138 commentaire += " ";
139 }
140 }
141 while (nom_lu != "#");
142 if (is.eof())
143 {
144 Cerr << "Error in Interprete_bloc: end of file while reading a comment :\n" << commentaire << "..." << finl;
145 }
146 // Next keyword to interpret:
147 motlu = nom_lu;
148 }
149 else if (motlu == "{")
150 {
151 Journal(jlevel) << "Interprete_bloc: reading { => creating new Interprete_bloc" << finl;
152 // Is it the beginning of a block?
153 // New interpreter:
154 Interprete_bloc inter;
155 inter.interpreter_bloc(is, ACCOLADE, verifie_sans_interpreter);
156 }
157 else
158 {
159 if (verifie_sans_interpreter)
160 {
161 // If we only want to verify the number of braces,
162 // it is enough to ignore the keyword... recursively open
163 // new interpreters when { is encountered and close them
164 // when } is found. If a } is missing at the end, we get the message
165 // "check for missing }" and if there is an extra one we get
166 // the message "extra }"
167 Journal(jlevel) << "Interprete_bloc: just checking {} => ignore keyword " << motlu << finl;
168 verifie(motlu);
169 }
170 else
171 {
172 // In the following block, if there is a read error on is, it is an error:
174 int export_object = 0;
175 if (motlu == "export")
176 {
177 Journal(jlevel) << "Exporting object, reading object type..." << finl;
178 export_object = 1;
179 is >> motlu;
180 }
181 // The keyword must be an instantiable object type
182 Journal(jlevel) << "Interprete_bloc: reading " << motlu << " => trying to instanciate object" << finl;
183 DerObjU objet;
184 objet.typer(motlu);
185
186 if (sub_type(Interprete, objet.valeur()))
187 {
188 // If it is an interpreter, call the interpreter method of the object:
189 Journal(jlevel) << " Calling object.interpreter()" << finl;
190 Interprete& inter = ref_cast(Interprete, objet.valeur());
191 inter.interpreter(is);
192 }
193 else
194 {
195 // Not an interpreter; read the object name and store it
196 Journal(jlevel) << " Reading object name" << finl;
197 Nom nom_objet;
198 is >> nom_objet;
199 Journal(jlevel) << " Storing object " << nom_objet << " of type " << motlu << finl;
200 if (!export_object || !pere_)
201 ajouter(nom_objet, objet);
202 else
203 pere_->ajouter(nom_objet, objet);
204 }
206 }
207 }
208 is >> motlu;
209 }
210 return is;
211}
212
213/*! @brief Returns the Objet_U corresponding to nom contained in this interprete_bloc. If the object does not exist, exit() (no search in the parent).
214 *
215 */
217{
218 const int i = les_noms_.search(nom);
219 if (i < 0)
220 {
221 Cerr << "Internal error in Interprete::objet_local() : object '" << nom << "' does not exist" << finl;
223 }
224 return operator[](i);
225}
226
227/*! @brief Returns a flag indicating whether an object with this name is registered in this interpreter (does not check the parent).
228 *
229 */
231{
232 const int i = les_noms_.search(nom);
233 return (i >= 0);
234}
235
236/*! @brief Adds object ob to the interpreter's object list and names it with nom.
237 *
238 * If the object already exists, exit().
239 *
240 */
241Objet_U& Interprete_bloc::ajouter(const Nom& nom, DerObjU& ob)
242{
243 Journal(3) << "Interprete::ajouter(" << nom << ") of type " << ob->que_suis_je() << finl;
244 if (les_noms_.search(nom) >= 0)
245 {
246 Cerr << "Error in Interprete::ajouter: object " << nom << " already exists." << finl;
248 }
249 les_noms_.add(nom);
250 Objet_U& obu = add_deplace(ob);
251 obu.nommer(nom);
252 return obu;
253}
254
255/*! @brief Searches for the requested object in the current Interprete_bloc (Interprete_bloc::interprete_courant()) and in all
256 *
257 * its successive parents. If the object does not exist, exit().
258 *
259 */
261{
263 while (ptr)
264 {
265 Interprete_bloc& interp = ptr.valeur();
266 if (interp.objet_local_existant(nom))
267 {
268 Objet_U& objet = interp.objet_local(nom);
269 return objet;
270 }
271 ptr = interp.pere_;
272 }
273 // Object not found!
274 Cerr << "Error in Interprete::objet: object " << nom << " does not exist." << finl;
276 return objet_global(nom); // Pour le compilo
277}
278
279/*! @brief Returns a flag indicating whether an object with this name exists in interprete_courant() or one of its parents.
280 *
281 */
283{
285 while (ptr)
286 {
287 Interprete_bloc& interp = ptr.valeur();
288 if (interp.objet_local_existant(nom))
289 return 1;
290 ptr = interp.pere_;
291 }
292 // Object not found!
293 return 0;
294}
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
@ ERROR_EXIT
Definition Entree.h:93
@ ERROR_CONTINUE
Definition Entree.h:93
virtual void set_error_action(Error_Action)
Changes the error behaviour of the input; see error_handle_() and get_error_action().
Definition Entree.cpp:379
virtual int eof()
Definition Entree.cpp:256
Interprets a block of instructions in the data set.
OBS_PTR(Interprete_bloc) pere_
Objet_U & ajouter(const Nom &nom, DerObjU &object_to_add)
Adds object ob to the interpreter's object list and names it with nom.
Entree & interpreter_bloc(Entree &is, Bloc_Type bloc_type, int verifier_sans_interpreter)
Interprets a block of instructions read from input is.
static int objet_global_existant(const Nom &nom)
Returns a flag indicating whether an object with this name exists in interprete_courant() or one of i...
Objet_U & objet_local(const Nom &nom)
Returns the Objet_U corresponding to nom contained in this interprete_bloc. If the object does not ex...
static Interprete_bloc & interprete_courant()
Returns the Interprete_bloc currently being read from the data set.
int objet_local_existant(const Nom &nom)
Returns a flag indicating whether an object with this name is registered in this interpreter (does no...
static Objet_U & objet_global(const Nom &nom)
Searches for the requested object in the current Interprete_bloc (Interprete_bloc::interprete_courant...
Base class for "interpreter" objects.
Definition Interprete.h:38
virtual Entree & interpreter(Entree &)=0
The Liste_bloc and Liste_bloc_curseur classes represent a list of Deriv<Objet_U> elements and an asso...
Definition Liste_bloc.h:25
Objet_U & operator[](int)
Access operator to the i-th element of the list.
Objet_U & valeur()
Definition Liste_bloc.h:32
Objet_U & add_deplace(DerObjU &)
Adds an Objet_U to the list. to_add is released on exit.
A character string (Nom) in uppercase.
Definition Motcle.h:26
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
Objet_U * typer(const char *nom_type)
Tries to create an instance of type "type".
friend class Entree
Definition Objet_U.h:71
virtual void nommer(const Nom &)
Assigns a name to the Objet_U. Virtual method to override.
Definition Objet_U.cpp:327
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
Objet_U()
Default constructor: assigns a unique identifier to the object (object_id_) and registers the object ...
Definition Objet_U.cpp:54
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
static Sortie & Journal(int message_level=0)
Returns a static Sortie object used as an event journal.
Definition Process.cpp:592
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
Base class for output streams.
Definition Sortie.h:52
const Objet_U & valeur() const