mirror of
https://github.com/YosysHQ/yosys.git
synced 2026-09-05 19:36:55 +02:00
frontends: trivial twine damage
This commit is contained in:
@@ -37,6 +37,14 @@ IdString read_idstring(std::istream &f)
|
||||
return RTLIL::escape_id(str);
|
||||
}
|
||||
|
||||
IdString resolve_sym(Design *design, const std::string &tok)
|
||||
{
|
||||
IdString ref = design->twines.ref_from_token(tok);
|
||||
if (ref == IdString::Null)
|
||||
log_error("Bad map file: '%s' is not a live name reference of this yosys run\n", tok.c_str());
|
||||
return ref;
|
||||
}
|
||||
|
||||
struct Xaiger2Frontend : public Frontend {
|
||||
Xaiger2Frontend() : Frontend("xaiger2", "(experimental) read XAIGER file")
|
||||
{
|
||||
|
||||
@@ -34,14 +34,14 @@ AST::Binding::Binding(RTLIL::IdString target_type,
|
||||
}
|
||||
|
||||
std::string
|
||||
AST::Binding::describe() const
|
||||
AST::Binding::describe(const RTLIL::Design *design) const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "directive to bind " << ast_node->str
|
||||
<< " to " << target_name.str();
|
||||
<< " to " << design->twines.str(target_name);
|
||||
if (!target_type.empty())
|
||||
oss << " (target type: "
|
||||
<< target_type.str()
|
||||
<< design->twines.str(target_type)
|
||||
<< ")";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace AST
|
||||
RTLIL::IdString target_name,
|
||||
const AstNode &cell);
|
||||
|
||||
std::string describe() const override;
|
||||
std::string describe(const RTLIL::Design *design) const override;
|
||||
|
||||
private:
|
||||
// The syntax-level representation of the cell to be bound.
|
||||
|
||||
+37
-29
@@ -57,7 +57,7 @@ static bool read_next_line(char *&buffer, size_t &buffer_size, int &line_count,
|
||||
}
|
||||
}
|
||||
|
||||
static std::pair<RTLIL::IdString, int> wideports_split(std::string name)
|
||||
static std::pair<std::string, int> wideports_split(std::string name)
|
||||
{
|
||||
int pos = -1;
|
||||
|
||||
@@ -78,10 +78,10 @@ static std::pair<RTLIL::IdString, int> wideports_split(std::string name)
|
||||
}
|
||||
|
||||
if (pos >= 0)
|
||||
return std::pair<RTLIL::IdString, int>("\\" + name.substr(0, pos), atoi(name.c_str() + pos+1));
|
||||
return std::pair<std::string, int>("\\" + name.substr(0, pos), atoi(name.c_str() + pos+1));
|
||||
|
||||
failed:
|
||||
return std::pair<RTLIL::IdString, int>(RTLIL::IdString(), 0);
|
||||
return std::pair<std::string, int>(std::string(), 0);
|
||||
}
|
||||
|
||||
void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool run_clean, bool sop_mode, bool wideports)
|
||||
@@ -115,11 +115,11 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
||||
}
|
||||
}
|
||||
|
||||
IdString wire_id = RTLIL::escape_id(wire_name);
|
||||
Wire *wire = module->wire(wire_id);
|
||||
IdString wire_ref = design->twines.add(RTLIL::escape_id(wire_name));
|
||||
Wire *wire = module->wire(wire_ref);
|
||||
|
||||
if (wire == nullptr)
|
||||
wire = module->addWire(wire_id);
|
||||
wire = module->addWire(wire_ref);
|
||||
|
||||
return wire;
|
||||
};
|
||||
@@ -167,11 +167,12 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
||||
if (module != nullptr)
|
||||
goto error;
|
||||
module = new RTLIL::Module;
|
||||
module->design = design;
|
||||
lastcell = nullptr;
|
||||
char *name = strtok(NULL, " \t\r\n");
|
||||
if (name == nullptr)
|
||||
goto error;
|
||||
module->name = RTLIL::escape_id(name);
|
||||
module->name = design->twines.add(RTLIL::escape_id(name));
|
||||
obj_attributes = &module->attributes;
|
||||
obj_parameters = nullptr;
|
||||
if (design->module(module->name))
|
||||
@@ -202,8 +203,9 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
||||
wire->port_output = !isinput;
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
RTLIL::IdString other_name = name.str() + stringf("[%d]", i);
|
||||
RTLIL::Wire *other_wire = module->wire(other_name);
|
||||
std::string other_name = design->twines.str(name) + stringf("[%d]", i);
|
||||
IdString other_ref = design->twines.find(other_name);
|
||||
RTLIL::Wire *other_wire = module->wire(other_ref);
|
||||
if (other_wire) {
|
||||
other_wire->port_input = false;
|
||||
other_wire->port_output = false;
|
||||
@@ -232,9 +234,9 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
||||
for (auto cell : remove_cells)
|
||||
module->remove(cell);
|
||||
|
||||
Wire *true_wire = module->wire(ID($true));
|
||||
Wire *false_wire = module->wire(ID($false));
|
||||
Wire *undef_wire = module->wire(ID($undef));
|
||||
Wire *true_wire = module->wire(ID::lookup("$true"));
|
||||
Wire *false_wire = module->wire(ID::lookup("$false"));
|
||||
Wire *undef_wire = module->wire(ID::lookup("$undef"));
|
||||
|
||||
if (true_wire != nullptr)
|
||||
module->rename(true_wire, stringf("$true$%d", ++blif_maxnum));
|
||||
@@ -271,20 +273,22 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
||||
char *p;
|
||||
while ((p = strtok(NULL, " \t\r\n")) != NULL)
|
||||
{
|
||||
RTLIL::IdString wire_name(stringf("\\%s", p));
|
||||
RTLIL::Wire *wire = module->wire(wire_name);
|
||||
std::string wire_name_str = stringf("\\%s", p);
|
||||
IdString wire_ref = design->twines.add(std::string{wire_name_str});
|
||||
RTLIL::Wire *wire = module->wire(wire_ref);
|
||||
if (wire == nullptr)
|
||||
wire = module->addWire(wire_name);
|
||||
wire = module->addWire(wire_ref);
|
||||
if (!strcmp(cmd, ".inputs"))
|
||||
wire->port_input = true;
|
||||
else
|
||||
wire->port_output = true;
|
||||
|
||||
if (wideports) {
|
||||
std::pair<RTLIL::IdString, int> wp = wideports_split(p);
|
||||
std::pair<std::string, int> wp = wideports_split(p);
|
||||
if (!wp.first.empty() && wp.second >= 0) {
|
||||
wideports_cache[wp.first].first = std::max(wideports_cache[wp.first].first, wp.second + 1);
|
||||
wideports_cache[wp.first].second = !strcmp(cmd, ".inputs");
|
||||
IdString wp_ref = design->twines.add(std::string(wp.first));
|
||||
wideports_cache[wp_ref].first = std::max(wideports_cache[wp_ref].first, wp.second + 1);
|
||||
wideports_cache[wp_ref].second = !strcmp(cmd, ".inputs");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -312,7 +316,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
||||
if (!strcmp(cmd, ".attr") || !strcmp(cmd, ".param")) {
|
||||
char *n = strtok(NULL, " \t\r\n");
|
||||
char *v = strtok(NULL, "\r\n");
|
||||
IdString id_n = RTLIL::escape_id(n);
|
||||
IdString id_n = design->twines.add(RTLIL::escape_id(n));
|
||||
Const const_v;
|
||||
if (v[0] == '"') {
|
||||
std::string str(v+1);
|
||||
@@ -372,7 +376,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
||||
cell = module->addDlatchGate(NEW_ID, blif_wire(clock), blif_wire(d), blif_wire(q), false);
|
||||
else {
|
||||
no_latch_clock:
|
||||
if (dff_name.empty()) {
|
||||
if (dff_name == IdString::Null) {
|
||||
cell = module->addFfGate(NEW_ID, blif_wire(d), blif_wire(q));
|
||||
} else {
|
||||
cell = module->addCell(NEW_ID, dff_name);
|
||||
@@ -393,9 +397,9 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
||||
if (p == NULL)
|
||||
goto error;
|
||||
|
||||
IdString celltype = RTLIL::escape_id(p);
|
||||
IdString celltype = design->twines.add(RTLIL::escape_id(p));
|
||||
RTLIL::Cell *cell = module->addCell(NEW_ID, celltype);
|
||||
RTLIL::Module *cell_mod = design->module(celltype);
|
||||
RTLIL::Module *cell_mod = design->module(cell->type);
|
||||
|
||||
dict<RTLIL::IdString, dict<int, SigBit>> cell_wideports_cache;
|
||||
|
||||
@@ -407,13 +411,17 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
||||
*(q++) = 0;
|
||||
|
||||
if (wideports) {
|
||||
std::pair<RTLIL::IdString, int> wp = wideports_split(p);
|
||||
if (wp.first.empty())
|
||||
cell->setPort(RTLIL::escape_id(p), *q ? blif_wire(q) : SigSpec());
|
||||
else
|
||||
cell_wideports_cache[wp.first][wp.second] = blif_wire(q);
|
||||
std::pair<std::string, int> wp = wideports_split(p);
|
||||
if (wp.first.empty()) {
|
||||
IdString port_ref = design->twines.add(RTLIL::escape_id(p));
|
||||
cell->setPort(port_ref, *q ? blif_wire(q) : SigSpec());
|
||||
} else {
|
||||
IdString wp_ref = design->twines.add(std::string(wp.first));
|
||||
cell_wideports_cache[wp_ref][wp.second] = blif_wire(q);
|
||||
}
|
||||
} else {
|
||||
cell->setPort(RTLIL::escape_id(p), *q ? blif_wire(q) : SigSpec());
|
||||
IdString port_ref = design->twines.add(RTLIL::escape_id(p));
|
||||
cell->setPort(port_ref, *q ? blif_wire(q) : SigSpec());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -686,7 +694,7 @@ struct BlifFrontend : public Frontend {
|
||||
}
|
||||
extra_args(f, filename, args, argidx);
|
||||
|
||||
parse_blif(design, *f, "", true, sop_mode, wideports);
|
||||
parse_blif(design, *f, IdString::Null, true, sop_mode, wideports);
|
||||
}
|
||||
} BlifFrontend;
|
||||
|
||||
|
||||
+49
-48
@@ -274,14 +274,14 @@ Const json_parse_attr_param_value(JsonNode *node)
|
||||
return value;
|
||||
}
|
||||
|
||||
void json_parse_attr_param(dict<IdString, Const> &results, JsonNode *node)
|
||||
void json_parse_attr_param(RTLIL::Design *design, dict<IdString, Const> &results, JsonNode *node)
|
||||
{
|
||||
if (node->type != 'D')
|
||||
log_error("JSON attributes or parameters node is not a dictionary.\n");
|
||||
|
||||
for (auto it : node->data_dict)
|
||||
{
|
||||
IdString key = RTLIL::escape_id(it.first.c_str());
|
||||
IdString key = design->twines.add(RTLIL::escape_id(it.first.c_str()));
|
||||
Const value = json_parse_attr_param_value(it.second);
|
||||
results[key] = value;
|
||||
}
|
||||
@@ -292,7 +292,8 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
||||
log("Importing module %s from JSON tree.\n", modname);
|
||||
|
||||
Module *module = new RTLIL::Module;
|
||||
module->name = RTLIL::escape_id(modname.c_str());
|
||||
module->design = design;
|
||||
module->name = design->twines.add(RTLIL::escape_id(modname));
|
||||
|
||||
if (design->module(module->name))
|
||||
log_error("Re-definition of module %s.\n", module->name.unescape());
|
||||
@@ -300,10 +301,10 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
||||
design->add(module);
|
||||
|
||||
if (node->data_dict.count("attributes"))
|
||||
json_parse_attr_param(module->attributes, node->data_dict.at("attributes"));
|
||||
json_parse_attr_param(design, module->attributes, node->data_dict.at("attributes"));
|
||||
|
||||
if (node->data_dict.count("parameter_default_values"))
|
||||
json_parse_attr_param(module->parameter_default_values, node->data_dict.at("parameter_default_values"));
|
||||
json_parse_attr_param(design, module->parameter_default_values, node->data_dict.at("parameter_default_values"));
|
||||
|
||||
dict<int, SigBit> signal_bits;
|
||||
|
||||
@@ -316,31 +317,31 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
||||
|
||||
for (int port_id = 1; port_id <= GetSize(ports_node->data_dict_keys); port_id++)
|
||||
{
|
||||
IdString port_name = RTLIL::escape_id(ports_node->data_dict_keys[port_id-1].c_str());
|
||||
IdString port_ref = design->twines.add(RTLIL::escape_id(ports_node->data_dict_keys[port_id-1]));
|
||||
JsonNode *port_node = ports_node->data_dict.at(ports_node->data_dict_keys[port_id-1]);
|
||||
|
||||
if (port_node->type != 'D')
|
||||
log_error("JSON port node '%s' is not a dictionary.\n", port_name.unescape());
|
||||
log_error("JSON port node '%s' is not a dictionary.\n", PooledName(design, port_ref).unescape());
|
||||
|
||||
if (port_node->data_dict.count("direction") == 0)
|
||||
log_error("JSON port node '%s' has no direction attribute.\n", port_name.unescape());
|
||||
log_error("JSON port node '%s' has no direction attribute.\n", PooledName(design, port_ref).unescape());
|
||||
|
||||
if (port_node->data_dict.count("bits") == 0)
|
||||
log_error("JSON port node '%s' has no bits attribute.\n", port_name.unescape());
|
||||
log_error("JSON port node '%s' has no bits attribute.\n", PooledName(design, port_ref).unescape());
|
||||
|
||||
JsonNode *port_direction_node = port_node->data_dict.at("direction");
|
||||
JsonNode *port_bits_node = port_node->data_dict.at("bits");
|
||||
|
||||
if (port_direction_node->type != 'S')
|
||||
log_error("JSON port node '%s' has non-string direction attribute.\n", port_name.unescape());
|
||||
log_error("JSON port node '%s' has non-string direction attribute.\n", PooledName(design, port_ref).unescape());
|
||||
|
||||
if (port_bits_node->type != 'A')
|
||||
log_error("JSON port node '%s' has non-array bits attribute.\n", port_name.unescape());
|
||||
log_error("JSON port node '%s' has non-array bits attribute.\n", PooledName(design, port_ref).unescape());
|
||||
|
||||
Wire *port_wire = module->wire(port_name);
|
||||
Wire *port_wire = module->wire(port_ref);
|
||||
|
||||
if (port_wire == nullptr)
|
||||
port_wire = module->addWire(port_name, GetSize(port_bits_node->data_array));
|
||||
port_wire = module->addWire(port_ref, GetSize(port_bits_node->data_array));
|
||||
|
||||
if (port_node->data_dict.count("upto") != 0) {
|
||||
JsonNode *val = port_node->data_dict.at("upto");
|
||||
@@ -370,7 +371,7 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
||||
port_wire->port_input = true;
|
||||
port_wire->port_output = true;
|
||||
} else
|
||||
log_error("JSON port node '%s' has invalid '%s' direction attribute.\n", port_name.unescape(), port_direction_node->data_string);
|
||||
log_error("JSON port node '%s' has invalid '%s' direction attribute.\n", PooledName(design, port_ref).unescape(), port_direction_node->data_string);
|
||||
|
||||
port_wire->port_id = port_id;
|
||||
|
||||
@@ -390,7 +391,7 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
||||
module->connect(sigbit, State::Sz);
|
||||
else
|
||||
log_error("JSON port node '%s' has invalid '%s' bit string value on bit %d.\n",
|
||||
port_name.unescape(), bitval_node->data_string.c_str(), i);
|
||||
PooledName(design, port_ref).unescape(), bitval_node->data_string.c_str(), i);
|
||||
} else
|
||||
if (bitval_node->type == 'N') {
|
||||
int bitidx = bitval_node->data_number;
|
||||
@@ -405,7 +406,7 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
||||
signal_bits[bitidx] = sigbit;
|
||||
}
|
||||
} else
|
||||
log_error("JSON port node '%s' has invalid bit value on bit %d.\n", port_name.unescape(), i);
|
||||
log_error("JSON port node '%s' has invalid bit value on bit %d.\n", PooledName(design, port_ref).unescape(), i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,24 +422,24 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
||||
|
||||
for (auto &net : netnames_node->data_dict)
|
||||
{
|
||||
IdString net_name = RTLIL::escape_id(net.first.c_str());
|
||||
IdString net_ref = design->twines.add(RTLIL::escape_id(net.first));
|
||||
JsonNode *net_node = net.second;
|
||||
|
||||
if (net_node->type != 'D')
|
||||
log_error("JSON netname node '%s' is not a dictionary.\n", net_name.unescape());
|
||||
log_error("JSON netname node '%s' is not a dictionary.\n", PooledName(design, net_ref).unescape());
|
||||
|
||||
if (net_node->data_dict.count("bits") == 0)
|
||||
log_error("JSON netname node '%s' has no bits attribute.\n", net_name.unescape());
|
||||
log_error("JSON netname node '%s' has no bits attribute.\n", PooledName(design, net_ref).unescape());
|
||||
|
||||
JsonNode *bits_node = net_node->data_dict.at("bits");
|
||||
|
||||
if (bits_node->type != 'A')
|
||||
log_error("JSON netname node '%s' has non-array bits attribute.\n", net_name.unescape());
|
||||
log_error("JSON netname node '%s' has non-array bits attribute.\n", PooledName(design, net_ref).unescape());
|
||||
|
||||
Wire *wire = module->wire(net_name);
|
||||
Wire *wire = module->wire(net_ref);
|
||||
|
||||
if (wire == nullptr)
|
||||
wire = module->addWire(net_name, GetSize(bits_node->data_array));
|
||||
wire = module->addWire(net_ref, GetSize(bits_node->data_array));
|
||||
|
||||
if (net_node->data_dict.count("upto") != 0) {
|
||||
JsonNode *val = net_node->data_dict.at("upto");
|
||||
@@ -468,7 +469,7 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
||||
module->connect(sigbit, State::Sz);
|
||||
else
|
||||
log_error("JSON netname node '%s' has invalid '%s' bit string value on bit %d.\n",
|
||||
net_name.unescape(), bitval_node->data_string.c_str(), i);
|
||||
PooledName(design, net_ref).unescape(), bitval_node->data_string.c_str(), i);
|
||||
} else
|
||||
if (bitval_node->type == 'N') {
|
||||
int bitidx = bitval_node->data_number;
|
||||
@@ -479,11 +480,11 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
||||
signal_bits[bitidx] = sigbit;
|
||||
}
|
||||
} else
|
||||
log_error("JSON netname node '%s' has invalid bit value on bit %d.\n", net_name.unescape(), i);
|
||||
log_error("JSON netname node '%s' has invalid bit value on bit %d.\n", PooledName(design, net_ref).unescape(), i);
|
||||
}
|
||||
|
||||
if (net_node->data_dict.count("attributes"))
|
||||
json_parse_attr_param(wire->attributes, net_node->data_dict.at("attributes"));
|
||||
json_parse_attr_param(design, wire->attributes, net_node->data_dict.at("attributes"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,39 +497,39 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
||||
|
||||
for (auto &cell_node_it : cells_node->data_dict)
|
||||
{
|
||||
IdString cell_name = RTLIL::escape_id(cell_node_it.first.c_str());
|
||||
IdString cell_ref = design->twines.add(RTLIL::escape_id(cell_node_it.first));
|
||||
JsonNode *cell_node = cell_node_it.second;
|
||||
|
||||
if (cell_node->type != 'D')
|
||||
log_error("JSON cells node '%s' is not a dictionary.\n", cell_name.unescape());
|
||||
log_error("JSON cells node '%s' is not a dictionary.\n", PooledName(design, cell_ref).unescape());
|
||||
|
||||
if (cell_node->data_dict.count("type") == 0)
|
||||
log_error("JSON cells node '%s' has no type attribute.\n", cell_name.unescape());
|
||||
log_error("JSON cells node '%s' has no type attribute.\n", PooledName(design, cell_ref).unescape());
|
||||
|
||||
JsonNode *type_node = cell_node->data_dict.at("type");
|
||||
|
||||
if (type_node->type != 'S')
|
||||
log_error("JSON cells node '%s' has a non-string type.\n", cell_name.unescape());
|
||||
log_error("JSON cells node '%s' has a non-string type.\n", PooledName(design, cell_ref).unescape());
|
||||
|
||||
IdString cell_type = RTLIL::escape_id(type_node->data_string.c_str());
|
||||
IdString cell_type = design->twines.add(RTLIL::escape_id(type_node->data_string));
|
||||
|
||||
Cell *cell = module->addCell(cell_name, cell_type);
|
||||
Cell *cell = module->addCell(cell_ref, cell_type);
|
||||
|
||||
if (cell_node->data_dict.count("connections") == 0)
|
||||
log_error("JSON cells node '%s' has no connections attribute.\n", cell_name.unescape());
|
||||
log_error("JSON cells node '%s' has no connections attribute.\n", PooledName(design, cell_ref).unescape());
|
||||
|
||||
JsonNode *connections_node = cell_node->data_dict.at("connections");
|
||||
|
||||
if (connections_node->type != 'D')
|
||||
log_error("JSON cells node '%s' has non-dictionary connections attribute.\n", cell_name.unescape());
|
||||
log_error("JSON cells node '%s' has non-dictionary connections attribute.\n", PooledName(design, cell_ref).unescape());
|
||||
|
||||
for (auto &conn_it : connections_node->data_dict)
|
||||
{
|
||||
IdString conn_name = RTLIL::escape_id(conn_it.first.c_str());
|
||||
IdString conn_ref = design->twines.add(RTLIL::escape_id(conn_it.first));
|
||||
JsonNode *conn_node = conn_it.second;
|
||||
|
||||
if (conn_node->type != 'A')
|
||||
log_error("JSON cells node '%s' connection '%s' is not an array.\n", cell_name.unescape(), conn_name.unescape());
|
||||
log_error("JSON cells node '%s' connection '%s' is not an array.\n", PooledName(design, cell_ref).unescape(), PooledName(design, conn_ref).unescape());
|
||||
|
||||
SigSpec sig;
|
||||
|
||||
@@ -547,7 +548,7 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
||||
sig.append(State::Sz);
|
||||
else
|
||||
log_error("JSON cells node '%s' connection '%s' has invalid '%s' bit string value on bit %d.\n",
|
||||
cell_name.unescape(), conn_name.unescape(), bitval_node->data_string.c_str(), i);
|
||||
PooledName(design, cell_ref).unescape(), PooledName(design, conn_ref).unescape(), bitval_node->data_string.c_str(), i);
|
||||
} else
|
||||
if (bitval_node->type == 'N') {
|
||||
int bitidx = bitval_node->data_number;
|
||||
@@ -556,18 +557,18 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
||||
sig.append(signal_bits.at(bitidx));
|
||||
} else
|
||||
log_error("JSON cells node '%s' connection '%s' has invalid bit value on bit %d.\n",
|
||||
cell_name.unescape(), conn_name.unescape(), i);
|
||||
PooledName(design, cell_ref).unescape(), PooledName(design, conn_ref).unescape(), i);
|
||||
|
||||
}
|
||||
|
||||
cell->setPort(conn_name, sig);
|
||||
cell->setPort(conn_ref, sig);
|
||||
}
|
||||
|
||||
if (cell_node->data_dict.count("attributes"))
|
||||
json_parse_attr_param(cell->attributes, cell_node->data_dict.at("attributes"));
|
||||
json_parse_attr_param(design, cell->attributes, cell_node->data_dict.at("attributes"));
|
||||
|
||||
if (cell_node->data_dict.count("parameters"))
|
||||
json_parse_attr_param(cell->parameters, cell_node->data_dict.at("parameters"));
|
||||
json_parse_attr_param(design, cell->parameters, cell_node->data_dict.at("parameters"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,27 +581,27 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
||||
|
||||
for (auto &memory_node_it : memories_node->data_dict)
|
||||
{
|
||||
IdString memory_name = RTLIL::escape_id(memory_node_it.first.c_str());
|
||||
JsonNode *memory_node = memory_node_it.second;
|
||||
|
||||
RTLIL::Memory *mem = new RTLIL::Memory;
|
||||
mem->name = memory_name;
|
||||
mem->name = design->twines.add(RTLIL::escape_id(memory_node_it.first));
|
||||
mem->module = module;
|
||||
|
||||
if (memory_node->type != 'D')
|
||||
log_error("JSON memory node '%s' is not a dictionary.\n", memory_name.unescape());
|
||||
log_error("JSON memory node '%s' is not a dictionary.\n", mem->name.unescape());
|
||||
|
||||
if (memory_node->data_dict.count("width") == 0)
|
||||
log_error("JSON memory node '%s' has no width attribute.\n", memory_name.unescape());
|
||||
log_error("JSON memory node '%s' has no width attribute.\n", mem->name.unescape());
|
||||
JsonNode *width_node = memory_node->data_dict.at("width");
|
||||
if (width_node->type != 'N')
|
||||
log_error("JSON memory node '%s' has a non-number width.\n", memory_name.unescape());
|
||||
log_error("JSON memory node '%s' has a non-number width.\n", mem->name.unescape());
|
||||
mem->width = width_node->data_number;
|
||||
|
||||
if (memory_node->data_dict.count("size") == 0)
|
||||
log_error("JSON memory node '%s' has no size attribute.\n", memory_name.unescape());
|
||||
log_error("JSON memory node '%s' has no size attribute.\n", mem->name.unescape());
|
||||
JsonNode *size_node = memory_node->data_dict.at("size");
|
||||
if (size_node->type != 'N')
|
||||
log_error("JSON memory node '%s' has a non-number size.\n", memory_name.unescape());
|
||||
log_error("JSON memory node '%s' has a non-number size.\n", mem->name.unescape());
|
||||
mem->size = size_node->data_number;
|
||||
|
||||
mem->start_offset = 0;
|
||||
@@ -611,7 +612,7 @@ void json_import(Design *design, string &modname, JsonNode *node)
|
||||
}
|
||||
|
||||
if (memory_node->data_dict.count("attributes"))
|
||||
json_parse_attr_param(mem->attributes, memory_node->data_dict.at("attributes"));
|
||||
json_parse_attr_param(design, mem->attributes, memory_node->data_dict.at("attributes"));
|
||||
|
||||
module->memories[mem->name] = mem;
|
||||
}
|
||||
|
||||
@@ -47,11 +47,13 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *&
|
||||
return *(expr++) == '0' ? RTLIL::State::S0 : RTLIL::State::S1;
|
||||
|
||||
std::string id = RTLIL::escape_id(std::string(expr, id_len));
|
||||
if (!module->wires_.count(id))
|
||||
IdString wire_ref = module->design->twines.find(id);
|
||||
RTLIL::Wire *w = module->wire(wire_ref);
|
||||
if (!w)
|
||||
log_error("Can't resolve wire name %s in %s.\n", RTLIL::unescape_id(id), module);
|
||||
|
||||
expr += id_len;
|
||||
return module->wires_.at(id);
|
||||
return w;
|
||||
}
|
||||
|
||||
static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack, token_t next_token)
|
||||
@@ -196,8 +198,10 @@ static void create_latch_ff_wires(RTLIL::Module *module, const LibertyAst *node)
|
||||
|
||||
static std::pair<RTLIL::SigSpec, RTLIL::SigSpec> find_latch_ff_wires(RTLIL::Module *module, const LibertyAst *node)
|
||||
{
|
||||
auto* iq_wire = module->wire(RTLIL::escape_id(node->args.at(0)));
|
||||
auto* iqn_wire = module->wire(RTLIL::escape_id(node->args.at(1)));
|
||||
IdString iq_ref = module->design->twines.find(RTLIL::escape_id(node->args.at(0)));
|
||||
IdString iqn_ref = module->design->twines.find(RTLIL::escape_id(node->args.at(1)));
|
||||
auto* iq_wire = module->wire(iq_ref);
|
||||
auto* iqn_wire = module->wire(iqn_ref);
|
||||
log_assert(iq_wire && iqn_wire);
|
||||
return std::make_pair(iq_wire, iqn_wire);
|
||||
}
|
||||
@@ -239,7 +243,7 @@ static void create_ff(RTLIL::Module *module, const LibertyAst *node)
|
||||
module->addNotGate(NEW_ID, q_sig, out_sig);
|
||||
}
|
||||
|
||||
RTLIL::Cell* cell = module->addCell(NEW_ID, "");
|
||||
RTLIL::Cell* cell = module->addCell(NEW_ID, IdString::Null);
|
||||
cell->setPort(ID::D, data_sig);
|
||||
cell->setPort(ID::Q, q_sig);
|
||||
cell->setPort(ID::C, clk_sig);
|
||||
@@ -505,8 +509,10 @@ struct LibertyFrontend : public Frontend {
|
||||
parse_type_map(type_map, cell);
|
||||
|
||||
RTLIL::Module *module = new RTLIL::Module;
|
||||
module->design = design;
|
||||
std::string cell_name = RTLIL::escape_id(cell->args.at(0));
|
||||
module->name = cell_name;
|
||||
IdString cell_name_ref = design->twines.add(std::string{cell_name});
|
||||
module->name = cell_name_ref;
|
||||
|
||||
if (flag_lib)
|
||||
module->set_bool_attribute(ID::blackbox);
|
||||
@@ -519,7 +525,7 @@ struct LibertyFrontend : public Frontend {
|
||||
module->attributes[ID::area] = area->value;
|
||||
|
||||
for (auto &attr : attributes)
|
||||
module->attributes[attr] = 1;
|
||||
module->attributes[design->twines.add(std::string(attr))] = 1;
|
||||
|
||||
bool simple_comb_cell = true, has_outputs = false;
|
||||
|
||||
@@ -626,7 +632,8 @@ struct LibertyFrontend : public Frontend {
|
||||
if (flag_lib && dir->value == "internal")
|
||||
continue;
|
||||
|
||||
RTLIL::Wire *wire = module->wires_.at(RTLIL::escape_id(node->args.at(0)));
|
||||
IdString wire_ref = module->design->twines.find(RTLIL::escape_id(node->args.at(0)));
|
||||
RTLIL::Wire *wire = module->wire(wire_ref);
|
||||
log_assert(wire);
|
||||
|
||||
const LibertyAst *capacitance = node->find("capacitance");
|
||||
@@ -710,8 +717,8 @@ struct LibertyFrontend : public Frontend {
|
||||
}
|
||||
}
|
||||
|
||||
if (design->has(cell_name)) {
|
||||
Module *existing_mod = design->module(cell_name);
|
||||
if (design->has(cell_name_ref)) {
|
||||
Module *existing_mod = design->module(cell_name_ref);
|
||||
if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute(ID::blackbox)) {
|
||||
log_error("Re-definition of cell/module %s!\n", RTLIL::unescape_id(cell_name));
|
||||
} else if (flag_nooverwrite) {
|
||||
|
||||
@@ -491,6 +491,136 @@ struct RTLILFrontendWorker {
|
||||
expect_eol();
|
||||
}
|
||||
|
||||
bool static_ids_match(const std::vector<size_t> &ordered_ids)
|
||||
{
|
||||
for (size_t id : ordered_ids) {
|
||||
if (id >= STATIC_TWINE_END)
|
||||
continue;
|
||||
const TwineDesc &desc = twine_descs.at(id);
|
||||
IdString found;
|
||||
if (desc.kind == TwineDesc::Leaf)
|
||||
found = design->twines.find(Twine{Twine::Leaf{desc.text}});
|
||||
else
|
||||
found = design->twines.find(Twine{Twine::Suffix{
|
||||
IdString(desc.parent), desc.text}});
|
||||
if (found == IdString::Null || found.untag().raw() != id)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
IdString resolve_file_twine(size_t id, bool is_public = false)
|
||||
{
|
||||
return materialize_file_twine(id).tag(is_public);
|
||||
}
|
||||
|
||||
IdString materialize_file_twine(size_t id)
|
||||
{
|
||||
auto rit = twine_remap.find(id);
|
||||
if (rit != twine_remap.end())
|
||||
return rit->second;
|
||||
auto dit = twine_descs.find(id);
|
||||
if (dit == twine_descs.end()) {
|
||||
if (id < STATIC_TWINE_END)
|
||||
return IdString(id);
|
||||
error("Unknown twine reference @%zu at line %d", id, line_num);
|
||||
}
|
||||
TwineDesc &desc = dit->second;
|
||||
if (desc.materializing)
|
||||
error("Cyclic twine reference @%zu at line %d", id, line_num);
|
||||
desc.materializing = true;
|
||||
IdString ref;
|
||||
switch (desc.kind) {
|
||||
case TwineDesc::Leaf:
|
||||
ref = design->twines.add(Twine::Leaf{desc.text});
|
||||
break;
|
||||
case TwineDesc::Suffix:
|
||||
ref = design->twines.add(Twine::Suffix{
|
||||
materialize_file_twine(desc.parent),
|
||||
desc.text});
|
||||
break;
|
||||
}
|
||||
desc.materializing = false;
|
||||
twine_remap[id] = ref;
|
||||
return ref;
|
||||
}
|
||||
|
||||
std::optional<IdString> try_parse_twine_handle()
|
||||
{
|
||||
bool is_public;
|
||||
size_t prefix = IdString::handle_token_prefix(line, is_public);
|
||||
if (prefix == 0)
|
||||
return std::nullopt;
|
||||
line = line.substr(prefix);
|
||||
return resolve_file_twine(parse_integer(), is_public);
|
||||
}
|
||||
|
||||
std::optional<IdString> try_parse_twine()
|
||||
{
|
||||
if (std::optional<IdString> handle = try_parse_twine_handle())
|
||||
return handle;
|
||||
std::optional<std::string> id = try_parse_id();
|
||||
if (!id)
|
||||
return std::nullopt;
|
||||
return design->twines.add(std::move(*id));
|
||||
}
|
||||
|
||||
IdString parse_twine()
|
||||
{
|
||||
std::optional<IdString> t = try_parse_twine();
|
||||
if (!t)
|
||||
error("Expected twine reference or ID, got `%s'.", error_token());
|
||||
return *t;
|
||||
}
|
||||
|
||||
void parse_twines()
|
||||
{
|
||||
expect_eol();
|
||||
while (true) {
|
||||
if (try_parse_keyword("end"))
|
||||
break;
|
||||
if (try_parse_keyword("leaf")) {
|
||||
size_t file_id = parse_integer();
|
||||
TwineDesc &desc = twine_descs[file_id];
|
||||
desc.kind = TwineDesc::Leaf;
|
||||
desc.text = parse_string();
|
||||
expect_eol();
|
||||
continue;
|
||||
}
|
||||
if (try_parse_keyword("suffix")) {
|
||||
size_t file_id = parse_integer();
|
||||
TwineDesc &desc = twine_descs[file_id];
|
||||
desc.kind = TwineDesc::Suffix;
|
||||
desc.parent = parse_integer();
|
||||
desc.text = parse_string();
|
||||
expect_eol();
|
||||
continue;
|
||||
}
|
||||
error("Expected `leaf` or `suffix` inside twines block, got `%s'.",
|
||||
error_token());
|
||||
}
|
||||
std::vector<size_t> ordered_ids;
|
||||
ordered_ids.reserve(twine_descs.size());
|
||||
for (auto &it : twine_descs)
|
||||
ordered_ids.push_back(it.first);
|
||||
std::sort(ordered_ids.begin(), ordered_ids.end());
|
||||
if (static_ids_match(ordered_ids)) {
|
||||
std::vector<size_t> dynamic_ids;
|
||||
dynamic_ids.reserve(ordered_ids.size());
|
||||
for (size_t id : ordered_ids) {
|
||||
if (id < STATIC_TWINE_END)
|
||||
twine_descs.erase(id);
|
||||
else
|
||||
dynamic_ids.push_back(id);
|
||||
}
|
||||
ordered_ids.swap(dynamic_ids);
|
||||
}
|
||||
for (size_t id : ordered_ids)
|
||||
materialize_file_twine(id);
|
||||
twine_descs.clear();
|
||||
expect_eol();
|
||||
}
|
||||
|
||||
void parse_parameter()
|
||||
{
|
||||
RTLIL::IdString id = parse_id();
|
||||
|
||||
@@ -549,9 +549,11 @@ struct VerilogFrontend : public Frontend {
|
||||
|
||||
for (auto &child : parse_state.current_ast->children) {
|
||||
if (child->type == AST::AST_MODULE)
|
||||
for (auto &attr : attributes)
|
||||
if (child->attributes.count(attr) == 0)
|
||||
child->attributes[attr] = AST::AstNode::mkconst_int(top_loc, 1, false);
|
||||
for (auto &attr : attributes) {
|
||||
IdString attr_id = AST::intern_attr_name(attr);
|
||||
if (child->attributes.count(attr_id) == 0)
|
||||
child->attributes[attr_id] = AST::AstNode::mkconst_int(top_loc, 1, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (flag_nodpi)
|
||||
|
||||
@@ -69,10 +69,10 @@
|
||||
struct ParseState {
|
||||
int port_counter;
|
||||
dict<std::string, int> port_stubs;
|
||||
std::unique_ptr<dict<IdString, std::unique_ptr<AstNode>>> attr_list;
|
||||
dict<IdString, std::unique_ptr<AstNode>> default_attr_list;
|
||||
std::stack<std::unique_ptr<dict<IdString, std::unique_ptr<AstNode>>>> attr_list_stack;
|
||||
std::unique_ptr<dict<IdString, std::unique_ptr<AstNode>>> albuf;
|
||||
std::unique_ptr<dict<std::string, std::unique_ptr<AstNode>>> attr_list;
|
||||
dict<std::string, std::unique_ptr<AstNode>> default_attr_list;
|
||||
std::stack<std::unique_ptr<dict<std::string, std::unique_ptr<AstNode>>>> attr_list_stack;
|
||||
std::unique_ptr<dict<std::string, std::unique_ptr<AstNode>>> albuf;
|
||||
std::vector<UserTypeMap> user_type_stack;
|
||||
dict<std::string, AstNode*> pkg_user_types;
|
||||
std::vector<AstNode*> ast_stack;
|
||||
@@ -98,15 +98,15 @@
|
||||
bool isInLocalScope(const std::string *name);
|
||||
void rewriteGenForDeclInit(AstNode *loop);
|
||||
void ensureAsgnExprAllowed(const parser::location_type loc, bool sv_mode);
|
||||
const AstNode *addIncOrDecStmt(std::unique_ptr<dict<IdString, std::unique_ptr<AstNode>>> stmt_attr,
|
||||
const AstNode *addIncOrDecStmt(std::unique_ptr<dict<std::string, std::unique_ptr<AstNode>>> stmt_attr,
|
||||
std::unique_ptr<AstNode> lhs,
|
||||
std::unique_ptr<dict<IdString, std::unique_ptr<AstNode>>> op_attr, AST::AstNodeType op,
|
||||
std::unique_ptr<dict<std::string, std::unique_ptr<AstNode>>> op_attr, AST::AstNodeType op,
|
||||
parser::location_type loc);
|
||||
std::unique_ptr<AstNode> addIncOrDecExpr(std::unique_ptr<AstNode> lhs,
|
||||
std::unique_ptr<dict<IdString, std::unique_ptr<AstNode>>> attr,
|
||||
std::unique_ptr<dict<std::string, std::unique_ptr<AstNode>>> attr,
|
||||
AST::AstNodeType op, parser::location_type loc, bool undo, bool sv_mode);
|
||||
// add a binary operator assignment statement, e.g., a += b
|
||||
std::unique_ptr<AstNode> addAsgnBinopStmt(std::unique_ptr<dict<IdString, std::unique_ptr<AstNode>>> attr,
|
||||
std::unique_ptr<AstNode> addAsgnBinopStmt(std::unique_ptr<dict<std::string, std::unique_ptr<AstNode>>> attr,
|
||||
std::unique_ptr<AstNode> eq_lhs, AST::AstNodeType op, std::unique_ptr<AstNode> rhs);
|
||||
};
|
||||
struct ParseMode {
|
||||
@@ -154,17 +154,17 @@
|
||||
return Location(begin.begin, end.end);
|
||||
}
|
||||
|
||||
static void append_attr(AstNode *ast, std::unique_ptr<dict<IdString, std::unique_ptr<AstNode>>> al)
|
||||
static void append_attr(AstNode *ast, std::unique_ptr<dict<std::string, std::unique_ptr<AstNode>>> al)
|
||||
{
|
||||
for (auto &it : *al) {
|
||||
ast->attributes[it.first] = std::move(it.second);
|
||||
ast->attributes[AST::intern_attr_name(it.first)] = std::move(it.second);
|
||||
}
|
||||
}
|
||||
|
||||
static void append_attr_clone(AstNode *ast, std::unique_ptr<dict<IdString, std::unique_ptr<AstNode>>> &al)
|
||||
static void append_attr_clone(AstNode *ast, std::unique_ptr<dict<std::string, std::unique_ptr<AstNode>>> &al)
|
||||
{
|
||||
for (auto &it : *al) {
|
||||
ast->attributes[it.first] = it.second->clone();
|
||||
ast->attributes[AST::intern_attr_name(it.first)] = it.second->clone();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,9 +361,9 @@
|
||||
}
|
||||
|
||||
// add a pre/post-increment/decrement statement
|
||||
const AstNode *ParseState::addIncOrDecStmt(std::unique_ptr<dict<IdString, std::unique_ptr<AstNode>>> stmt_attr,
|
||||
const AstNode *ParseState::addIncOrDecStmt(std::unique_ptr<dict<std::string, std::unique_ptr<AstNode>>> stmt_attr,
|
||||
std::unique_ptr<AstNode> lhs,
|
||||
std::unique_ptr<dict<IdString, std::unique_ptr<AstNode>>> op_attr, AST::AstNodeType op,
|
||||
std::unique_ptr<dict<std::string, std::unique_ptr<AstNode>>> op_attr, AST::AstNodeType op,
|
||||
Location loc)
|
||||
{
|
||||
auto one = AstNode::mkconst_int(loc, 1, true);
|
||||
@@ -380,7 +380,7 @@
|
||||
|
||||
// create a pre/post-increment/decrement expression, and add the corresponding statement
|
||||
std::unique_ptr<AstNode> ParseState::addIncOrDecExpr(std::unique_ptr<AstNode> lhs,
|
||||
std::unique_ptr<dict<IdString,
|
||||
std::unique_ptr<dict<std::string,
|
||||
std::unique_ptr<AstNode>>> attr,
|
||||
AST::AstNodeType op, Location loc, bool undo, bool sv_mode)
|
||||
{
|
||||
@@ -397,7 +397,7 @@
|
||||
}
|
||||
|
||||
// add a binary operator assignment statement, e.g., a += b
|
||||
std::unique_ptr<AstNode> ParseState::addAsgnBinopStmt(std::unique_ptr<dict<IdString, std::unique_ptr<AstNode>>> attr,
|
||||
std::unique_ptr<AstNode> ParseState::addAsgnBinopStmt(std::unique_ptr<dict<std::string, std::unique_ptr<AstNode>>> attr,
|
||||
std::unique_ptr<AstNode> eq_lhs, AST::AstNodeType op, std::unique_ptr<AstNode> rhs)
|
||||
{
|
||||
Location loc = location_range(eq_lhs->location, rhs->location);
|
||||
@@ -462,7 +462,7 @@
|
||||
|
||||
using string_t = std::unique_ptr<std::string>;
|
||||
using ast_t = std::unique_ptr<YOSYS_NAMESPACE_PREFIX AST::AstNode>;
|
||||
using al_t = std::unique_ptr<YOSYS_NAMESPACE_PREFIX dict<YOSYS_NAMESPACE_PREFIX RTLIL::IdString, std::unique_ptr<YOSYS_NAMESPACE_PREFIX AST::AstNode>>>;
|
||||
using al_t = std::unique_ptr<YOSYS_NAMESPACE_PREFIX dict<std::string, std::unique_ptr<YOSYS_NAMESPACE_PREFIX AST::AstNode>>>;
|
||||
using specify_target_ptr_t = std::unique_ptr<struct specify_target>;
|
||||
using specify_triple_ptr_t = std::unique_ptr<struct specify_triple>;
|
||||
using specify_rise_fall_ptr_t = std::unique_ptr<struct specify_rise_fall>;
|
||||
@@ -617,7 +617,7 @@ attr:
|
||||
{
|
||||
if (extra->attr_list)
|
||||
extra->attr_list_stack.push(std::move(extra->attr_list));
|
||||
extra->attr_list = std::make_unique<dict<IdString, std::unique_ptr<AstNode>>>();
|
||||
extra->attr_list = std::make_unique<dict<std::string, std::unique_ptr<AstNode>>>();
|
||||
for (auto &it : extra->default_attr_list)
|
||||
(*extra->attr_list)[it.first] = it.second->clone();
|
||||
} attr_opt {
|
||||
@@ -639,7 +639,7 @@ defattr:
|
||||
DEFATTR_BEGIN {
|
||||
if (extra->attr_list != nullptr)
|
||||
extra->attr_list_stack.push(std::move(extra->attr_list));
|
||||
extra->attr_list = std::make_unique<dict<IdString, std::unique_ptr<AstNode>>>();
|
||||
extra->attr_list = std::make_unique<dict<std::string, std::unique_ptr<AstNode>>>();
|
||||
extra->default_attr_list.clear();
|
||||
} opt_attr_list {
|
||||
extra->attr_list->swap(extra->default_attr_list);
|
||||
@@ -1302,7 +1302,7 @@ task_func_port:
|
||||
if (!extra->astbuf1) {
|
||||
if (!mode->sv)
|
||||
err_at_loc(@$, "task/function argument direction missing");
|
||||
extra->albuf = std::make_unique<dict<IdString, std::unique_ptr<AstNode>>>();
|
||||
extra->albuf = std::make_unique<dict<std::string, std::unique_ptr<AstNode>>>();
|
||||
extra->astbuf1 = std::make_unique<AstNode>(@$, AST_WIRE);
|
||||
extra->current_wire_rand = false;
|
||||
extra->current_wire_const = false;
|
||||
@@ -2911,7 +2911,7 @@ behavioral_stmt:
|
||||
// we have to undangle it from the stack
|
||||
patch_block_on_stack = true;
|
||||
} else if (outer->get_bool_attribute(ID::full_case))
|
||||
(*$1)[ID::full_case] = AstNode::mkconst_int(@$, 1, false);
|
||||
(*$1)[ID::str(ID::full_case)] = AstNode::mkconst_int(@$, 1, false);
|
||||
}
|
||||
auto expr = std::make_unique<AstNode>(@$, AST_REDUCE_BOOL, std::move($4));
|
||||
if (!node) {
|
||||
@@ -2957,22 +2957,22 @@ if_attr:
|
||||
AstNode *context = extra->ast_stack.back();
|
||||
if (context && context->type == AST_BLOCK && context->get_bool_attribute(ID::promoted_if))
|
||||
err_at_loc(@2, "unique0 keyword cannot be used for 'else if' branch.");
|
||||
(*$1)[ID::parallel_case] = AstNode::mkconst_int(@$, 1, false);
|
||||
(*$1)[ID::str(ID::parallel_case)] = AstNode::mkconst_int(@$, 1, false);
|
||||
$$ = std::move($1);
|
||||
} |
|
||||
attr TOK_PRIORITY {
|
||||
AstNode *context = extra->ast_stack.back();
|
||||
if (context && context->type == AST_BLOCK && context->get_bool_attribute(ID::promoted_if))
|
||||
err_at_loc(@2, "priority keyword cannot be used for 'else if' branch.");
|
||||
(*$1)[ID::full_case] = AstNode::mkconst_int(@$, 1, false);
|
||||
(*$1)[ID::str(ID::full_case)] = AstNode::mkconst_int(@$, 1, false);
|
||||
$$ = std::move($1);
|
||||
} |
|
||||
attr TOK_UNIQUE {
|
||||
AstNode *context = extra->ast_stack.back();
|
||||
if (context && context->type == AST_BLOCK && context->get_bool_attribute(ID::promoted_if))
|
||||
err_at_loc(@2, "unique keyword cannot be used for 'else if' branch.");
|
||||
(*$1)[ID::full_case] = AstNode::mkconst_int(@$, 1, false);
|
||||
(*$1)[ID::parallel_case] = AstNode::mkconst_int(@$, 1, false);
|
||||
(*$1)[ID::str(ID::full_case)] = AstNode::mkconst_int(@$, 1, false);
|
||||
(*$1)[ID::str(ID::parallel_case)] = AstNode::mkconst_int(@$, 1, false);
|
||||
$$ = std::move($1);
|
||||
};
|
||||
|
||||
@@ -2981,16 +2981,16 @@ case_attr:
|
||||
$$ = std::move($1);
|
||||
} |
|
||||
attr TOK_UNIQUE0 {
|
||||
(*$1)[ID::parallel_case] = AstNode::mkconst_int(@$, 1, false);
|
||||
(*$1)[ID::str(ID::parallel_case)] = AstNode::mkconst_int(@$, 1, false);
|
||||
$$ = std::move($1);
|
||||
} |
|
||||
attr TOK_PRIORITY {
|
||||
(*$1)[ID::full_case] = AstNode::mkconst_int(@$, 1, false);
|
||||
(*$1)[ID::str(ID::full_case)] = AstNode::mkconst_int(@$, 1, false);
|
||||
$$ = std::move($1);
|
||||
} |
|
||||
attr TOK_UNIQUE {
|
||||
(*$1)[ID::full_case] = AstNode::mkconst_int(@$, 1, false);
|
||||
(*$1)[ID::parallel_case] = AstNode::mkconst_int(@$, 1, false);
|
||||
(*$1)[ID::str(ID::full_case)] = AstNode::mkconst_int(@$, 1, false);
|
||||
(*$1)[ID::str(ID::parallel_case)] = AstNode::mkconst_int(@$, 1, false);
|
||||
$$ = std::move($1);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user