Skip to content
Snippets Groups Projects
Commit 54a389ac authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Take into account suggestions of Emmanuel

This includes an important change in the code since one cannot
reuse a variable name in a nested block (this means that if a variable
is declared, one cannot declare a variable with a same name even in a
nested block, while the first variable exists).
parent 0f977561
No related branches found
No related tags found
1 merge request!147Take into account suggestions of Emmanuel
...@@ -180,9 +180,9 @@ In ~pugs~, all these "parameters" are set through a ...@@ -180,9 +180,9 @@ In ~pugs~, all these "parameters" are set through a
DSL[fn:DSL-def]. Thus, when ~pugs~ is launched, it actually executes a DSL[fn:DSL-def]. Thus, when ~pugs~ is launched, it actually executes a
provided script. A ~C++~ function is associated to each instruction of provided script. A ~C++~ function is associated to each instruction of
the script. The ~C++~ components of ~pugs~ are completely unaware one of the script. The ~C++~ components of ~pugs~ are completely unaware one of
the others. ~pugs~ interpreter is responsible of data flow between the the others. ~pugs~ interpreter is responsible for the data flow between
components: it manages the data transfer between those ~C++~ components the components: it manages the data transfer between those ~C++~
and ensures that the workflow is properly defined. components and ensures that the workflow is properly defined.
**** Why? **** Why?
...@@ -224,7 +224,7 @@ methods or their settings. ...@@ -224,7 +224,7 @@ methods or their settings.
Using directly the general purpose language (~C~, ~C++~, ~Fortran~,...) used Using directly the general purpose language (~C~, ~C++~, ~Fortran~,...) used
to write the code can be tempting. It has the advantage that no to write the code can be tempting. It has the advantage that no
particular treatment is necessary to build a parser (to read data particular treatment is necessary to build a parser (to read data
files or a script), but it presents several drawbacks. files or scripts), but it presents several drawbacks.
- The first one is probably that it allows too much freedom. While - The first one is probably that it allows too much freedom. While
defining the model and numerical options, the user has generally defining the model and numerical options, the user has generally
...@@ -239,7 +239,7 @@ files or a script), but it presents several drawbacks. ...@@ -239,7 +239,7 @@ files or a script), but it presents several drawbacks.
- Another difficulty is related to the fact that code's internal API - Another difficulty is related to the fact that code's internal API
is likely to change permanently in a research code. Thus valid is likely to change permanently in a research code. Thus valid
constructions or settings may become rapidly obsolete. In other constructions or settings may become rapidly obsolete. In other
words keeping up to date embedded "data file" might be difficult. words keeping up to date embedded "data files" might be difficult.
- Finally it requires recompilation of pieces of code (which can be - Finally it requires recompilation of pieces of code (which can be
large in some cases) even if one is just changing a simple large in some cases) even if one is just changing a simple
parameter. parameter.
...@@ -391,7 +391,7 @@ it is generally to decide not to offer them.\\ ...@@ -391,7 +391,7 @@ it is generally to decide not to offer them.\\
If the grammar of ~pugs~ is still likely to be extended, it should *never* If the grammar of ~pugs~ is still likely to be extended, it should *never*
integrate low-level instructions. Low-level instructions give too much integrate low-level instructions. Low-level instructions give too much
freedom and thus are a source of errors. Several things are already freedom and thus are a source of errors. Several things are already
done to forbid this kind of evolution. The constness of high-level done to forbid this kind of evolution. The immutability of high-level
data is a good illustration. For instance, meshes or discrete data is a good illustration. For instance, meshes or discrete
functions *cannot* be modified. This is not only a security to protect functions *cannot* be modified. This is not only a security to protect
the user from doing "dangerous" manipulations, but it also permits to the user from doing "dangerous" manipulations, but it also permits to
...@@ -584,31 +584,27 @@ we give a few examples. ...@@ -584,31 +584,27 @@ we give a few examples.
#+END_SRC #+END_SRC
#+results: out-of-scope-variable-use #+results: out-of-scope-variable-use
**** Variable name can be reused in an enclosed scope **** Variable name *cannot* be reused in an enclosed scope
#+NAME: nested-scope-variable-example #+NAME: nested-scope-variable-example
#+BEGIN_SRC pugs :exports both :results output #+BEGIN_SRC pugs-error :exports both :results output
let n:N, n = 0; // global variable
{
cout << "global scope n = " << n << "\n";
let n:N, n = 1; // scope level 1 variable
{ {
cout << "scope level 1 n = " << n << "\n"; let n:N, n = 1;
let n:N, n = 2; // scope level 2 variable
cout << "scope level 2 n = " << n << "\n";
} }
{ {
cout << "scope level 1 n = " << n << "\n"; let n:N, n = 2;
let n:N, n = 4; // scope level 2.2 variable
cout << "scope level 2.2 n = " << n << "\n";
} }
cout << "scope level 1 n = " << n << "\n"; let n:N, n = 3;
{
let n:N, n = 4;
} }
cout << "global scope n = " << n << "\n";
#+END_SRC #+END_SRC
#+results: nested-scope-variable-example #+results: nested-scope-variable-example
This example is self explanatory. Obviously such constructions are This example is self explanatory. The same variable name can be used
generally *bad ideas*. This kind of constructions can appear in loops in unrelated blocks (this is useful in loops for instance). However,
where the variables defined in blocks follow the same lifetime rules. it cannot be reused if a variable has already been declared with the
same one in an embedding scope. This is a difference with ~C++~, the
reason is that this kind of construction is dangerous and difficult to
read.
*** Basic types<<basic-types>> *** Basic types<<basic-types>>
...@@ -1602,7 +1598,7 @@ types. These can be meshes (the ~mesh~ type), output streams (the ...@@ -1602,7 +1598,7 @@ types. These can be meshes (the ~mesh~ type), output streams (the
One can already see that the complexity of these types may vary a lot. One can already see that the complexity of these types may vary a lot.
The main difference between these types and basic types is that, The main difference between these types and basic types is that,
high-level types are not available in directly the language but they high-level types are not available directly in the language but they
are loaded on demand (using the ~import~ keyword in the preamble of the are loaded on demand (using the ~import~ keyword in the preamble of the
script). script).
...@@ -1620,8 +1616,8 @@ operators can never be applied to variables of this kind ...@@ -1620,8 +1616,8 @@ operators can never be applied to variables of this kind
| ~/=~ | assignment by quotient | | ~/=~ | assignment by quotient |
We conclude by stating that if access operator ~[]~ can eventually be We conclude by stating that if access operator ~[]~ can eventually be
overloaded for high-level types, it should be done with care. It is defined for high-level types, it should be done with care. It is not
not recommended. recommended.
Finally, the last difference lies in the fact that high-level types Finally, the last difference lies in the fact that high-level types
use shallow copies and not value copies as it is the case for basic use shallow copies and not value copies as it is the case for basic
...@@ -2763,7 +2759,8 @@ Physical Point("XMAXYMIN") = {5}; ...@@ -2763,7 +2759,8 @@ Physical Point("XMAXYMIN") = {5};
Physical Point("XMAXYMAX") = {6}; Physical Point("XMAXYMAX") = {6};
#+END_SRC #+END_SRC
#+BEGIN_SRC shell :exports results :results none Here is an example of ~gmsh~ use that produces a mesh at format ~msh2~.
#+BEGIN_SRC shell :exports both :results none
gmsh -2 hybrid-2d.geo -format msh2 gmsh -2 hybrid-2d.geo -format msh2
#+END_SRC #+END_SRC
...@@ -2949,7 +2946,7 @@ The result of the previous script is given in Figure ...@@ -2949,7 +2946,7 @@ The result of the previous script is given in Figure
***** ~relax: mesh*mesh*R -> mesh~ <<relax-function>> ***** ~relax: mesh*mesh*R -> mesh~ <<relax-function>>
This function is a simple utility that computes a ~mesh~ as the /mean/ of This function is a simple utility that computes a ~mesh~ as the /mean/ of
two other mesh that share the same connectivity. The coordinates of two other meshes that share the same connectivity. The coordinates of
the vertices of the relaxed mesh $\mathcal{M}_2$, are given by the vertices of the relaxed mesh $\mathcal{M}_2$, are given by
\begin{equation*} \begin{equation*}
\forall r\in\mathcal{R},\quad\mathbf{x}_r^{\mathcal{M}_2} = (1-\theta) \mathbf{x}_r^{\mathcal{M}_0} + \theta \mathbf{x}_r^{\mathcal{M}_1}. \forall r\in\mathcal{R},\quad\mathbf{x}_r^{\mathcal{M}_2} = (1-\theta) \mathbf{x}_r^{\mathcal{M}_0} + \theta \mathbf{x}_r^{\mathcal{M}_1}.
...@@ -3118,7 +3115,7 @@ Here is the list of the functions ...@@ -3118,7 +3115,7 @@ Here is the list of the functions
These functions are defined for $\mathbb{P}_0(\mathbb{R})$ data and the These functions are defined for $\mathbb{P}_0(\mathbb{R})$ data and the
return value is also a $\mathbb{P}_0(\mathbb{R})$ function. These return value is also a $\mathbb{P}_0(\mathbb{R})$ function. These
functions require that the two arguments are defined one the *same functions require that the two arguments are defined on the *same
mesh*. The result is obtained by applying the function cell by cell. mesh*. The result is obtained by applying the function cell by cell.
Here is the function list Here is the function list
...@@ -3476,6 +3473,24 @@ $\vec{\mathbb{P}}_0(\mathbb{R})$ of dimension 1 (since passing a single ...@@ -3476,6 +3473,24 @@ $\vec{\mathbb{P}}_0(\mathbb{R})$ of dimension 1 (since passing a single
function as a list of user function, the previous function function as a list of user function, the previous function
[[integrate-classic]], would be used). [[integrate-classic]], would be used).
#+BEGIN_SRC pugs :exports both :results none
import mesh;
import scheme;
import math;
let m:mesh, m = readGmsh("hybrid-2d.msh");
let u:R^2 -> R, x -> cos(x[0]*x[1]);
let v:R^2 -> R, x -> x[0]*x[1];
let w:R^2 -> R, x -> x[0]+x[1];
let u1h:Vh, u1h = integrate(m, Gauss(5), P0Vector(), u);
let u2h:Vh, u2h = integrate(m, Gauss(5), u);
let u3h:Vh, u3h = integrate(m, Gauss(5), P0Vector(), (u,v,w));
#+END_SRC
In this example one observes the difference between ~u1h~ and ~u2h~. The
first one is a $\vec{\mathbb{P}}_0(\mathbb{R})$ where the vector size
is 1, and ~u2h~ is a $\mathbb{P}_0(\mathbb{R})$.
****** ~integrate: mesh*(zone)*quadrature*function -> Vh~ ****** ~integrate: mesh*(zone)*quadrature*function -> Vh~
This function is an enhancement of the function defined in This function is an enhancement of the function defined in
...@@ -3731,7 +3746,7 @@ descriptors that are provided by the ~scheme~ module. ...@@ -3731,7 +3746,7 @@ descriptors that are provided by the ~scheme~ module.
#+BEGIN_note #+BEGIN_note
These functions provide *descriptors*, these are not related to a These functions provide *descriptors*, these are not related to a
particular implementation. The way they are used in different particular implementation. The way they are used in different
functions dependents of the context or the numerical method itself. functions may vary.
#+END_note #+END_note
#+BEGIN_note #+BEGIN_note
...@@ -3842,9 +3857,9 @@ to supported elements. ...@@ -3842,9 +3857,9 @@ to supported elements.
This function is a special function whose purpose is to transport This function is a special function whose purpose is to transport
lagrangian quantities from one mesh to the other. Obviously, this lagrangian quantities from one mesh to the other. Obviously, this
function make lots of sense in the case of lagrangian calculations. function makes a lot of sense in the case of lagrangian calculations.
This is a zero cost function, since discrete functions are *constants* This is a zero cost function, since discrete functions are *constant*
in ~pugs~, it consists in associating the data of the given discrete in ~pugs~, it consists in associating the data of the given discrete
function to the provided ~mesh~. In other words, the underlying array of function to the provided ~mesh~. In other words, the underlying array of
values is shared by the two discrete functions, which are associated values is shared by the two discrete functions, which are associated
...@@ -3875,13 +3890,13 @@ this order: ...@@ -3875,13 +3890,13 @@ this order:
- the sound speed $c$ of type $\mathbb{P}_0(\mathbb{R})$, - the sound speed $c$ of type $\mathbb{P}_0(\mathbb{R})$,
- the pressure $p$ of type $\mathbb{P}_0(\mathbb{R})$, - the pressure $p$ of type $\mathbb{P}_0(\mathbb{R})$,
- a list of boundary conditions, - a list of boundary conditions,
- and a time step of type ~R~. - and a time step of type $\mathbb{R}$.
Observe that ~pugs~ checks the types of the parameters and that all Observe that ~pugs~ checks the types of the parameters and that all
discrete functions are defined on the same mesh. discrete functions are defined on the same mesh.
The functions return a compound type made of The functions return a compound type made of
- the new ~mesh~ $\mathcal{M}$, - the new ~mesh~ $\mathcal{M}$,
- the new mass density ~\rho~ of type $\mathbb{P}_0(\mathbb{R})$ defined - the new mass density $\rho$ of type $\mathbb{P}_0(\mathbb{R})$ defined
on $\mathcal{M}$, on $\mathcal{M}$,
- the new velocity $\mathbf{u}$ of type $\mathbb{P}_0(\mathbb{R}^d)$ in - the new velocity $\mathbf{u}$ of type $\mathbb{P}_0(\mathbb{R}^d)$ in
dimension $d$, defined on the mesh $\mathcal{M}$, dimension $d$, defined on the mesh $\mathcal{M}$,
...@@ -4080,7 +4095,7 @@ depends on the compilation options of the code. ...@@ -4080,7 +4095,7 @@ depends on the compilation options of the code.
****** ~getLSOptions: void -> string~ ****** ~getLSOptions: void -> string~
This function show the current tuning of the global linear solver This function shows the current tuning of the global linear solver
#+NAME: get-ls-options-example #+NAME: get-ls-options-example
#+BEGIN_SRC pugs :exports both :results output #+BEGIN_SRC pugs :exports both :results output
import linear_solver; import linear_solver;
...@@ -4142,7 +4157,7 @@ different. ...@@ -4142,7 +4157,7 @@ different.
Variables of this type manage outputs: which format is used and Variables of this type manage outputs: which format is used and
eventually the writing policy. This policy sets for instance the time eventually the writing policy. This policy sets for instance the time
period of for time dependent post processing. period for time-dependent post processing.
**** ~writer~ provided functions **** ~writer~ provided functions
...@@ -4231,7 +4246,7 @@ Let us illustrate it by an important second example. ...@@ -4231,7 +4246,7 @@ Let us illustrate it by an important second example.
Running this code produces the gnuplot file displayed in Figure Running this code produces the gnuplot file displayed in Figure
[[fig:writer-example2]]. One sees that ~f~ is the $\mathbb{P}_0(\mathbb{R})$ [[fig:writer-example2]]. One sees that ~f~ is the $\mathbb{P}_0(\mathbb{R})$
function corresponding to the function $x \to x$ and not to the function function corresponding to the function $x \to x$ and not to the function
$x -> |\cos(\pi x)|$. This later function is plotted in Figure $x \to |\cos(\pi x)|$. This later function is plotted in Figure
[[fig:writer-example2-2]] since ~output_list~ is set with the updated value [[fig:writer-example2-2]] since ~output_list~ is set with the updated value
of ~fh~. of ~fh~.
...@@ -4248,7 +4263,7 @@ of ~fh~. ...@@ -4248,7 +4263,7 @@ of ~fh~.
plot '<(sed "" $PUGS_SOURCE_DIR/doc/writer-example2.gnu)' u 1:2 lw 2 t "f" w l, '<(sed "" $PUGS_SOURCE_DIR/doc/writer-example2.gnu)' u 1:3 lw 2 t "g" w l, '<(sed "" $PUGS_SOURCE_DIR/doc/writer-example2.gnu)' u 1:4 lw 2 t "sin(pi*f)" w l plot '<(sed "" $PUGS_SOURCE_DIR/doc/writer-example2.gnu)' u 1:2 lw 2 t "f" w l, '<(sed "" $PUGS_SOURCE_DIR/doc/writer-example2.gnu)' u 1:3 lw 2 t "g" w l, '<(sed "" $PUGS_SOURCE_DIR/doc/writer-example2.gnu)' u 1:4 lw 2 t "sin(pi*f)" w l
#+END_SRC #+END_SRC
#+CAPTION: Illustration of the life time of variables. The output for ~fh~ corresponds to its value when ~output_list~ is created: the interpolation of $x -> x$. #+CAPTION: Illustration of the life time of variables. The output for ~fh~ corresponds to its value when ~output_list~ is created: the interpolation of $x \to x$.
#+NAME: fig:writer-example2 #+NAME: fig:writer-example2
#+ATTR_LATEX: :width 0.38\textwidth #+ATTR_LATEX: :width 0.38\textwidth
#+ATTR_HTML: :width 300px; #+ATTR_HTML: :width 300px;
...@@ -4275,7 +4290,7 @@ of ~fh~. ...@@ -4275,7 +4290,7 @@ of ~fh~.
***** ~gnuplot~ writers <<gnuplot-writers>> ***** ~gnuplot~ writers <<gnuplot-writers>>
There is two ~gnuplot~ writers. One is dedicated to output of dimension There are two ~gnuplot~ writers. One is dedicated to output of dimension
1 results (~gnuplot_1d_writer~) and the other allows post processing in 1 results (~gnuplot_1d_writer~) and the other allows post processing in
dimension 1 and 2 (~gnuplot_writer~). dimension 1 and 2 (~gnuplot_writer~).
......
...@@ -32,12 +32,14 @@ ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable> ...@@ -32,12 +32,14 @@ ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable>
throw ParseError(error_message.str(), std::vector{n.children[0]->begin()}); throw ParseError(error_message.str(), std::vector{n.children[0]->begin()});
} }
auto [i_symbol, success] = symbol_table->add(symbol, n.children[0]->begin()); if (auto [i_symbol, found] = symbol_table->find(symbol, n.children[0]->begin()); found) {
if (not success) {
std::ostringstream error_message; std::ostringstream error_message;
error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << "' was already defined!"; error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << "' was already defined at line "
<< i_symbol->attributes().position().line;
throw ParseError(error_message.str(), std::vector{n.children[0]->begin()}); throw ParseError(error_message.str(), std::vector{n.children[0]->begin()});
} }
auto [i_symbol, success] = symbol_table->add(symbol, n.children[0]->begin());
Assert(success);
for (auto& child : n.children) { for (auto& child : n.children) {
this->buildSymbolTable(*child, local_symbol_table); this->buildSymbolTable(*child, local_symbol_table);
...@@ -59,13 +61,13 @@ ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable> ...@@ -59,13 +61,13 @@ ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable>
throw ParseError(error_message.str(), std::vector{argument_node.begin()}); throw ParseError(error_message.str(), std::vector{argument_node.begin()});
} }
auto [i_symbol, success] = symbol_table->add(argument_node.string(), argument_node.begin()); if (auto [i_symbol, found] = symbol_table->find(argument_node.string(), argument_node.begin()); found) {
if (not success) {
std::ostringstream error_message; std::ostringstream error_message;
error_message << "symbol '" << rang::fg::red << argument_node.string() << rang::fg::reset error_message << "symbol '" << rang::fg::red << argument_node.string() << rang::fg::reset
<< "' was already defined!"; << "' was already defined at line " << i_symbol->attributes().position().line;
throw ParseError(error_message.str(), std::vector{argument_node.begin()}); throw ParseError(error_message.str(), std::vector{argument_node.begin()});
} }
symbol_table->add(argument_node.string(), argument_node.begin());
}; };
if (n.children[0]->is_type<language::name>()) { if (n.children[0]->is_type<language::name>()) {
...@@ -91,7 +93,7 @@ ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable> ...@@ -91,7 +93,7 @@ ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable>
if (not success) { if (not success) {
std::ostringstream error_message; std::ostringstream error_message;
error_message << "symbol '" << rang::fg::red << argument_node.string() << rang::fg::reset error_message << "symbol '" << rang::fg::red << argument_node.string() << rang::fg::reset
<< "' was already defined!"; << "' was already defined at line " << i_symbol->attributes().position().line;
throw ParseError(error_message.str(), std::vector{argument_node.begin()}); throw ParseError(error_message.str(), std::vector{argument_node.begin()});
} }
// Symbols will be initialized at call // Symbols will be initialized at call
......
...@@ -17,11 +17,11 @@ TEST_CASE("ASTSymbolTableBuilder", "[language]") ...@@ -17,11 +17,11 @@ TEST_CASE("ASTSymbolTableBuilder", "[language]")
SECTION("Build symbols") SECTION("Build symbols")
{ {
std::string_view data = R"( std::string_view data = R"(
let n:N, n = 2;
{ {
let m:N, m = n; let m:N, m = 2;
let n:R, n = m/3.; let n:R, n = m/3.;
} }
let n:N, n = 2;
)"; )";
string_input input{data, "test.pgs"}; string_input input{data, "test.pgs"};
...@@ -92,7 +92,22 @@ let n:N, n = 1; ...@@ -92,7 +92,22 @@ let n:N, n = 1;
string_input input{data, "test.pgs"}; string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input); auto ast = ASTBuilder::build(input);
REQUIRE_THROWS_WITH(ASTSymbolTableBuilder{*ast}, "symbol 'n' was already defined!"); REQUIRE_THROWS_WITH(ASTSymbolTableBuilder{*ast}, "symbol 'n' was already defined at line 2");
}
SECTION("Re-declared symbol (nested scope)")
{
std::string_view data = R"(
let n:N, n = 0;
{
let n:N, n = 1;
}
)";
string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input);
REQUIRE_THROWS_WITH(ASTSymbolTableBuilder{*ast}, "symbol 'n' was already defined at line 2");
} }
SECTION("Re-declared symbol (function)") SECTION("Re-declared symbol (function)")
...@@ -105,7 +120,7 @@ let f : R -> R, x -> 1; ...@@ -105,7 +120,7 @@ let f : R -> R, x -> 1;
string_input input{data, "test.pgs"}; string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input); auto ast = ASTBuilder::build(input);
REQUIRE_THROWS_WITH(ASTSymbolTableBuilder{*ast}, "symbol 'f' was already defined!"); REQUIRE_THROWS_WITH(ASTSymbolTableBuilder{*ast}, "symbol 'f' was already defined at line 2");
} }
SECTION("Re-declared symbol (builtin function)") SECTION("Re-declared symbol (builtin function)")
...@@ -140,13 +155,14 @@ let cos: R -> R, x->2*x; ...@@ -140,13 +155,14 @@ let cos: R -> R, x->2*x;
SECTION("Re-declared parameter (function)") SECTION("Re-declared parameter (function)")
{ {
std::string_view data = R"( std::string_view data = R"(
let f : R*R*N -> R, (x,y,x) -> 1; let f : R*R*N -> R,
(x,y,x) -> 1;
)"; )";
string_input input{data, "test.pgs"}; string_input input{data, "test.pgs"};
auto ast = ASTBuilder::build(input); auto ast = ASTBuilder::build(input);
REQUIRE_THROWS_WITH(ASTSymbolTableBuilder{*ast}, "symbol 'x' was already defined!"); REQUIRE_THROWS_WITH(ASTSymbolTableBuilder{*ast}, "symbol 'x' was already defined at line 3");
} }
} }
} }
...@@ -105,21 +105,6 @@ do { ...@@ -105,21 +105,6 @@ do {
CHECK_WHILE_PROCESSOR_RESULT(data, "i", 12ul); CHECK_WHILE_PROCESSOR_RESULT(data, "i", 12ul);
} }
SECTION("do-while lifetime variable")
{
std::string_view data = R"(
let i:N, i = 3;
let j:N, j = 0;
do {
j = 5;
let j:N, j = 2;
i = j;
} while(false);
)";
CHECK_WHILE_PROCESSOR_RESULT(data, "i", 2ul);
CHECK_WHILE_PROCESSOR_RESULT(data, "j", 5ul);
}
SECTION("empty do-while symbol table untouched") SECTION("empty do-while symbol table untouched")
{ {
std::string_view data = R"( std::string_view data = R"(
......
...@@ -101,21 +101,6 @@ while(i<10) { ...@@ -101,21 +101,6 @@ while(i<10) {
CHECK_WHILE_PROCESSOR_RESULT(data, "i", 12ul); CHECK_WHILE_PROCESSOR_RESULT(data, "i", 12ul);
} }
SECTION("while lifetime variable")
{
std::string_view data = R"(
let i:N, i = 3;
let j:N, j = 0;
while(i != 2) {
j = 5;
let j:N, j = 2;
i = j;
}
)";
CHECK_WHILE_PROCESSOR_RESULT(data, "i", 2ul);
CHECK_WHILE_PROCESSOR_RESULT(data, "j", 5ul);
}
SECTION("while symbol table untouched") SECTION("while symbol table untouched")
{ {
std::string_view data = R"( std::string_view data = R"(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment