mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-26 10:35:38 +00:00
verilog: save and restore overwritten macro arguments
This commit is contained in:
parent
a055145b95
commit
3156226233
4 changed files with 54 additions and 4 deletions
|
@ -36,6 +36,7 @@
|
|||
#include "verilog_frontend.h"
|
||||
#include "kernel/log.h"
|
||||
#include <assert.h>
|
||||
#include <stack>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -334,6 +335,11 @@ define_map_t::add(const std::string &name, const std::string &txt, const arg_map
|
|||
defines[name] = std::unique_ptr<define_body_t>(new define_body_t(txt, args));
|
||||
}
|
||||
|
||||
void define_map_t::add(const std::string &name, const define_body_t &body)
|
||||
{
|
||||
defines[name] = std::unique_ptr<define_body_t>(new define_body_t(body));
|
||||
}
|
||||
|
||||
void define_map_t::merge(const define_map_t &map)
|
||||
{
|
||||
for (const auto &pr : map.defines) {
|
||||
|
@ -440,7 +446,17 @@ static bool read_argument(std::string &dest)
|
|||
}
|
||||
}
|
||||
|
||||
static bool try_expand_macro(define_map_t &defines, std::string &tok)
|
||||
using macro_arg_stack_t = std::stack<std::pair<std::string, define_body_t>>;
|
||||
|
||||
static void restore_macro_arg(define_map_t &defines, macro_arg_stack_t ¯o_arg_stack)
|
||||
{
|
||||
log_assert(!macro_arg_stack.empty());
|
||||
auto &overwritten_arg = macro_arg_stack.top();
|
||||
defines.add(overwritten_arg.first, overwritten_arg.second);
|
||||
macro_arg_stack.pop();
|
||||
}
|
||||
|
||||
static bool try_expand_macro(define_map_t &defines, macro_arg_stack_t ¯o_arg_stack, std::string &tok)
|
||||
{
|
||||
if (tok == "`\"") {
|
||||
std::string literal("\"");
|
||||
|
@ -450,7 +466,7 @@ static bool try_expand_macro(define_map_t &defines, std::string &tok)
|
|||
if (ntok == "`\"") {
|
||||
insert_input(literal+"\"");
|
||||
return true;
|
||||
} else if (!try_expand_macro(defines, ntok)) {
|
||||
} else if (!try_expand_macro(defines, macro_arg_stack, ntok)) {
|
||||
literal += ntok;
|
||||
}
|
||||
}
|
||||
|
@ -495,6 +511,10 @@ static bool try_expand_macro(define_map_t &defines, std::string &tok)
|
|||
args.push_back(arg);
|
||||
}
|
||||
for (const auto &pr : body->args.get_vals(name, args)) {
|
||||
if (const define_body_t *existing = defines.find(pr.first)) {
|
||||
macro_arg_stack.push({pr.first, *existing});
|
||||
insert_input("`__restore_macro_arg ");
|
||||
}
|
||||
defines.add(pr.first, pr.second);
|
||||
}
|
||||
} else {
|
||||
|
@ -725,6 +745,7 @@ frontend_verilog_preproc(std::istream &f,
|
|||
defines.merge(pre_defines);
|
||||
defines.merge(global_defines_cache);
|
||||
|
||||
macro_arg_stack_t macro_arg_stack;
|
||||
std::vector<std::string> filename_stack;
|
||||
// We are inside pass_level levels of satisfied ifdefs, and then within
|
||||
// fail_level levels of unsatisfied ifdefs. The unsatisfied ones are
|
||||
|
@ -828,7 +849,7 @@ frontend_verilog_preproc(std::istream &f,
|
|||
if (tok == "`include") {
|
||||
skip_spaces();
|
||||
std::string fn = next_token(true);
|
||||
while (try_expand_macro(defines, fn)) {
|
||||
while (try_expand_macro(defines, macro_arg_stack, fn)) {
|
||||
fn = next_token();
|
||||
}
|
||||
while (1) {
|
||||
|
@ -935,7 +956,12 @@ frontend_verilog_preproc(std::istream &f,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (try_expand_macro(defines, tok))
|
||||
if (tok == "`__restore_macro_arg") {
|
||||
restore_macro_arg(defines, macro_arg_stack);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (try_expand_macro(defines, macro_arg_stack, tok))
|
||||
continue;
|
||||
|
||||
output_code.push_back(tok);
|
||||
|
|
|
@ -42,6 +42,7 @@ struct define_map_t
|
|||
|
||||
// Add a definition, overwriting any existing definition for name.
|
||||
void add(const std::string &name, const std::string &txt, const arg_map_t *args = nullptr);
|
||||
void add(const std::string &name, const define_body_t &body);
|
||||
|
||||
// Merge in another map of definitions (which take precedence
|
||||
// over anything currently defined).
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue