Fix the interpretation of @#elseif clauses within an @#ifdef or @#ifndef
parent
df8d8ef116
commit
5d564eed07
|
@ -245,8 +245,23 @@ For::interpret(ostream &output, vector<filesystem::path> &paths)
|
||||||
void
|
void
|
||||||
If::interpret(ostream &output, vector<filesystem::path> &paths)
|
If::interpret(ostream &output, vector<filesystem::path> &paths)
|
||||||
{
|
{
|
||||||
|
bool first_clause = true;
|
||||||
for (const auto & [expr, body] : expr_and_body)
|
for (const auto & [expr, body] : expr_and_body)
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
if ((ifdef || ifndef) && first_clause)
|
||||||
|
{
|
||||||
|
first_clause = false;
|
||||||
|
VariablePtr vp = dynamic_pointer_cast<Variable>(expr);
|
||||||
|
assert(vp);
|
||||||
|
if ((ifdef && env.isVariableDefined(vp->getName()))
|
||||||
|
|| (ifndef && !env.isVariableDefined(vp->getName())))
|
||||||
|
{
|
||||||
|
interpretBody(body, output, paths);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
auto tmp = expr->eval();
|
auto tmp = expr->eval();
|
||||||
RealPtr dp = dynamic_pointer_cast<Real>(tmp);
|
RealPtr dp = dynamic_pointer_cast<Real>(tmp);
|
||||||
|
@ -260,6 +275,7 @@ If::interpret(ostream &output, vector<filesystem::path> &paths)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (StackTrace &ex)
|
catch (StackTrace &ex)
|
||||||
{
|
{
|
||||||
ex.push("@#if", location);
|
ex.push("@#if", location);
|
||||||
|
@ -286,31 +302,3 @@ If::interpretBody(const vector<DirectivePtr> &body, ostream &output, vector<file
|
||||||
statement->interpret(output, paths);
|
statement->interpret(output, paths);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Ifdef::interpret(ostream &output, vector<filesystem::path> &paths)
|
|
||||||
{
|
|
||||||
for (const auto & [expr, body] : expr_and_body)
|
|
||||||
if (VariablePtr vp = dynamic_pointer_cast<Variable>(expr);
|
|
||||||
dynamic_pointer_cast<BaseType>(expr)
|
|
||||||
|| (vp && env.isVariableDefined(vp->getName())))
|
|
||||||
{
|
|
||||||
interpretBody(body, output, paths);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
printEndLineInfo(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Ifndef::interpret(ostream &output, vector<filesystem::path> &paths)
|
|
||||||
{
|
|
||||||
for (const auto & [expr, body] : expr_and_body)
|
|
||||||
if (VariablePtr vp = dynamic_pointer_cast<Variable>(expr);
|
|
||||||
dynamic_pointer_cast<BaseType>(expr)
|
|
||||||
|| (vp && !env.isVariableDefined(vp->getName())))
|
|
||||||
{
|
|
||||||
interpretBody(body, output, paths);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
printEndLineInfo(output);
|
|
||||||
}
|
|
||||||
|
|
|
@ -175,24 +175,25 @@ namespace macro
|
||||||
* If there is an `else` statement it is the last element in the vector. Its condition is true.
|
* If there is an `else` statement it is the last element in the vector. Its condition is true.
|
||||||
*/
|
*/
|
||||||
const vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body;
|
const vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body;
|
||||||
|
const bool ifdef, ifndef;
|
||||||
public:
|
public:
|
||||||
If(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
|
If(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
|
||||||
Environment &env_arg, Tokenizer::location location_arg) :
|
Environment &env_arg, Tokenizer::location location_arg,
|
||||||
Directive(env_arg, move(location_arg)), expr_and_body{move(expr_and_body_arg)} { }
|
bool ifdef_arg = false, bool ifndef_arg = false) :
|
||||||
|
Directive(env_arg, move(location_arg)), expr_and_body{move(expr_and_body_arg)},
|
||||||
|
ifdef{ifdef_arg}, ifndef{ifndef_arg} { }
|
||||||
void interpret(ostream &output, vector<filesystem::path> &paths) override;
|
void interpret(ostream &output, vector<filesystem::path> &paths) override;
|
||||||
protected:
|
protected:
|
||||||
void interpretBody(const vector<DirectivePtr> &body, ostream &output,
|
void interpretBody(const vector<DirectivePtr> &body, ostream &output,
|
||||||
vector<filesystem::path> &paths);
|
vector<filesystem::path> &paths);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Ifdef : public If
|
class Ifdef : public If
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Ifdef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
|
Ifdef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
|
||||||
Environment &env_arg, Tokenizer::location location_arg) :
|
Environment &env_arg, Tokenizer::location location_arg) :
|
||||||
If(move(expr_and_body_arg), env_arg, move(location_arg)) { }
|
If(move(expr_and_body_arg), env_arg, move(location_arg), true, false) { }
|
||||||
void interpret(ostream &output, vector<filesystem::path> &paths) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -201,8 +202,7 @@ namespace macro
|
||||||
public:
|
public:
|
||||||
Ifndef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
|
Ifndef(vector<pair<ExpressionPtr, vector<DirectivePtr>>> expr_and_body_arg,
|
||||||
Environment &env_arg, Tokenizer::location location_arg) :
|
Environment &env_arg, Tokenizer::location location_arg) :
|
||||||
If(move(expr_and_body_arg), env_arg, move(location_arg)) { }
|
If(move(expr_and_body_arg), env_arg, move(location_arg), false, true) { }
|
||||||
void interpret(ostream &output, vector<filesystem::path> &paths) override;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue