macro processor: fix bug: interpret @#includepath at node level instead of at the Driver level

issue#70
Houtan Bastani 2019-10-02 17:08:57 +02:00
parent db52e02158
commit 310f3936fe
No known key found for this signature in database
GPG Key ID: 000094FB955BE169
5 changed files with 15 additions and 25 deletions

View File

@ -61,15 +61,15 @@ Include::interpretAndGetName() const
return "";
}
string
IncludePath::interpretAndGetPath() const
void
IncludePath::interpret(ostream &output, bool no_line_macro)
{
try
{
StringPtr msp = dynamic_pointer_cast<String>(expr->eval());
if (!msp)
throw StackTrace("File name does not evaluate to a string");
return *msp;
paths.emplace_back(*msp);
}
catch (StackTrace &ex)
{
@ -80,7 +80,6 @@ IncludePath::interpretAndGetPath() const
{
error(StackTrace("@#includepath", e.what(), location));
}
return "";
}
void

View File

@ -84,17 +84,11 @@ namespace macro
{
private:
const ExpressionPtr expr;
vector<string> &paths;
public:
IncludePath(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
// Not interpretable because we want the class to be immutable (for use with shared_ptr)
// If it were interpretable, the name would need to be stored in a non-const variable
// rendering the class mutable
inline void interpret(ostream &output, bool no_line_macro) override
{
error(StackTrace("@#includepath", "should never be interpreted", location));
}
string interpretAndGetPath() const;
IncludePath(ExpressionPtr expr_arg, Environment &env_arg, vector<string> &paths_arg, Tokenizer::location location_arg) :
Directive(env_arg, move(location_arg)), expr{move(expr_arg)}, paths{paths_arg} { }
void interpret(ostream &output, bool no_line_macro) override;
};

View File

@ -55,7 +55,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
else
command_line_defines_with_endl << "@#define " << define.first << " = \"" << define.second << "\"" << endl;
}
Driver m(env, true);
Driver m(env, paths, true);
istream is(command_line_defines_with_endl.rdbuf());
m.parse("command_line_defines", "command_line_defines", is, output, debug, vector<pair<string, string>>{}, paths);
}
@ -82,10 +82,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
}
auto ip = dynamic_pointer_cast<Include>(statement);
auto ipp = dynamic_pointer_cast<IncludePath>(statement);
if (ipp)
paths.emplace_back(ipp->interpretAndGetPath());
else if (ip)
if (ip)
{
string filename = ip->interpretAndGetName();
ifstream incfile(filename, ios::binary);
@ -111,7 +108,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
if (pos != string::npos)
basename.erase(pos);
Driver m(env, no_line_macro);
Driver m(env, paths, no_line_macro);
m.parse(filename, basename, incfile, output, debug, vector<pair<string, string>>{}, paths);
}
else

View File

@ -63,15 +63,15 @@ namespace macro
{
public:
Environment &env;
//! The paths to search when looking for .mod files
vector<string> &paths;
private:
bool no_line_macro;
vector<DirectivePtr> statements;
stack<vector<DirectivePtr>> directive_stack;
//! The paths to search when looking for .mod files
vector<string> paths;
public:
Driver(Environment &env_arg, bool no_line_macro_arg) :
env{env_arg}, no_line_macro(no_line_macro_arg) { }
Driver(Environment &env_arg, vector<string> &paths_arg, bool no_line_macro_arg) :
env{env_arg}, paths{paths_arg}, no_line_macro(no_line_macro_arg) { }
Driver(const Driver &) = delete;
Driver(Driver &&) = delete;
Driver & operator=(const Driver &) = delete;

View File

@ -128,7 +128,7 @@ directive : directive_one_line EOL
directive_one_line : INCLUDE expr
{ $$ = make_shared<Include>($2, driver.env, @$); }
| INCLUDEPATH expr
{ $$ = make_shared<IncludePath>($2, driver.env, @$); }
{ $$ = make_shared<IncludePath>($2, driver.env, driver.paths, @$); }
| DEFINE symbol EQUAL expr
{ $$ = make_shared<Define>($2, $4, driver.env, @$); }
| DEFINE function EQUAL expr