Updated support for single automatic bus

This commit is contained in:
Borna Rajković committed 2022-05-08 14:50:56 +02:00
1 parent 9ff6633777
commit fb8aafb2a9
9 files changed
+152 -39

No files matched your search

+6
View File
@@ -1,6 +1,7 @@
#ifndef DOMAIN_ATTRIBUTE_H
#define DOMAIN_ATTRIBUTE_H
#include <utility>
#include <vector>
#include "rule.h"
@@ -45,6 +46,11 @@ public:
bool isEnumerated();
std::vector<Enumeration> &getEnumeration();
void setEnumeration(std::vector<Enumeration> enums) {
enumerated = true;
enumeration = std::move(enums);
}
};
class Attribute
+1 -1
View File
@@ -47,7 +47,7 @@ public:
enum BusType {
AUTOMATIC,
REGULAR,
AUTOMATIC_SINGLE
SINGLE_AUTOMATIC
};
private:
std::string name;
+2 -2
View File
@@ -14,8 +14,8 @@ class PinConnection
{
public:
enum ConnectionType {
CHECK_ONLY,
AUTOMATICALLY
REQUIRED,
OPTIONAL
};
private:
+66 -12
View File
@@ -69,6 +69,8 @@ Value toType(ValueNode node) {
Bus::BusType toType(BusNode::BusType type) {
if(type == BusNode::AUTOMATIC) {
return Bus::AUTOMATIC;
} else if(type == BusNode::SINGLE_AUTOMATIC) {
return Bus::SINGLE_AUTOMATIC;
}
return Bus::REGULAR;
}
@@ -85,10 +87,10 @@ Pin::PinType toType(PinNode::PinType type) {
PinConnection::ConnectionType toType(PinConnectionNode::ConnectionType type)
{
if(type == PinConnectionNode::AUTOMATICALLY) {
return PinConnection::AUTOMATICALLY;
if(type == PinConnectionNode::OPTIONAL) {
return PinConnection::OPTIONAL;
}
return PinConnection::CHECK_ONLY;
return PinConnection::REQUIRED;
}
@@ -187,7 +189,7 @@ std::optional<Bus> SchemaCreator::loadBus(BusNode node)
errors.emplace_back(node.span, "missing @display");
return nullopt;
}
if(node.display && (type == Bus::AUTOMATIC || type == Bus::AUTOMATIC_SINGLE)) {
if(node.display && (type == Bus::AUTOMATIC || type == Bus::SINGLE_AUTOMATIC)) {
errors.emplace_back(node.span, "automatic bus cannot have a @display");
return nullopt;
}
@@ -212,6 +214,11 @@ std::optional<Bus> SchemaCreator::loadBus(BusNode node)
}
}
if(type == Bus::SINGLE_AUTOMATIC && wires.size() != 1) {
errors.emplace_back(node.span, "singleAutomatic bus must have exactly 1 wire defined");
return nullopt;
}
return Bus(name, tooltip, type, count, wires, display);
}
@@ -223,7 +230,7 @@ std::optional<AddressSpace> SchemaCreator::loadAddressSpace(AddressSpaceNode nod
std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
{
push(ComdelContext("connection", false, true, false));
push(ComdelContext("connection", false, true, false, false));
std::string bus = node.bus.value;
auto busInstance = getBus(bus);
@@ -231,6 +238,10 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
errors.emplace_back(node.span, "bus does not exist");
}
if(busInstance->getType() == Bus::SINGLE_AUTOMATIC) {
current().inSingleAutomaticConnection = true;
}
if(busInstance->getType() == Bus::REGULAR) {
ConnectionComponent first{node.first.component.value, node.first.pin.value};
@@ -285,7 +296,7 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
pop();
return Connection(first, nullopt, bus, attributes, wires, nullopt);
} else if(busInstance->getType() == Bus::AUTOMATIC || busInstance->getType() == Bus::AUTOMATIC_SINGLE) {
} else if(busInstance->getType() == Bus::AUTOMATIC || busInstance->getType() == Bus::SINGLE_AUTOMATIC) {
ConnectionComponent first{node.first.component.value, node.first.pin.value};
if(!node.second.has_value()) {
@@ -310,6 +321,10 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
current().wires.push_back(wire.getName());
}
if(node.attributes.size() != 2 && busInstance->getType() == Bus::SINGLE_AUTOMATIC) {
errors.emplace_back(node.span, "singleAutomatic must contain 2 attributes");
}
std::vector<Attribute> attributes;
for(auto & attribute : node.attributes) {
auto attr = loadAttribute(attribute);
@@ -330,7 +345,9 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
firstWires.push_back(Value::fromNull());
} else if(firstWire.is(ValueNode::INT)) {
firstWires.push_back(Value::fromInt(firstWire.asInt()));
} else if(firstWire.is(ValueNode::IDENTIFIER)) {
} else if(firstWire.is(ValueNode::STRING) && busInstance->getType() == Bus::SINGLE_AUTOMATIC) {
firstWires.push_back(Value::fromString(firstWire.asString()));
} else if(firstWire.is(ValueNode::IDENTIFIER) && busInstance->getType() == Bus::AUTOMATIC) {
if(attributeNames.count(firstWire.asIdentifier())) {
firstWires.push_back(Value::fromReference(firstWire.asIdentifier(), Value::ATTRIBUTE_REFERENCE));
} else if(wireNames.count(firstWire.asIdentifier())) {
@@ -339,7 +356,7 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
errors.emplace_back(firstWire.span, "unknown identifier");
}
} else {
errors.emplace_back(firstWire.span, "unknown value type");
errors.emplace_back(firstWire.span, "unsupported value type");
}
}
@@ -350,7 +367,9 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
secondWires.push_back(Value::fromNull());
} else if(secondWire.is(ValueNode::INT)) {
secondWires.push_back(Value::fromInt(secondWire.asInt()));
} else if(secondWire.is(ValueNode::IDENTIFIER)) {
} else if(secondWire.is(ValueNode::STRING) && busInstance->getType() == Bus::SINGLE_AUTOMATIC) {
secondWires.push_back(Value::fromString(secondWire.asString()));
} else if(secondWire.is(ValueNode::IDENTIFIER) && busInstance->getType() == Bus::AUTOMATIC) {
if(attributeNames.count(secondWire.asIdentifier())) {
secondWires.push_back(Value::fromReference(secondWire.asIdentifier(), Value::ATTRIBUTE_REFERENCE));
} else if(wireNames.count(secondWire.asIdentifier())) {
@@ -359,7 +378,25 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
errors.emplace_back(secondWire.span, "unknown identifier");
}
} else {
errors.emplace_back(secondWire.span, "unknown value type");
errors.emplace_back(secondWire.span, "unsupported value type");
}
}
if(busInstance->getType() == Bus::SINGLE_AUTOMATIC && attributes.size() == 2) {
if(!attributes[0].getPopup().has_value()) {
errors.emplace_back(node.attributes[0].span, "@popup is required");
} else if(attributes[0].getDefault().getType() != Value::STRING) {
errors.emplace_back(node.attributes[0].span, "@attribute must be of type string");
} else {
attributes[0].getPopup()->setEnumeration(createWireEnumeration(firstWires));
}
if(!attributes[1].getPopup().has_value()) {
errors.emplace_back(node.attributes[1].span, "@popup is required");
} else if(attributes[1].getDefault().getType() != Value::STRING) {
errors.emplace_back(node.attributes[1].span, "@attribute must be of type string");
} else {
attributes[1].getPopup()->setEnumeration(createWireEnumeration(secondWires));
}
}
@@ -375,7 +412,7 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
std::optional<Component> SchemaCreator::loadComponent(ComponentNode node)
{
push(ComdelContext(node.name.value, true, false, false));
push(ComdelContext(node.name.value, true, false, false, false));
std::string name = node.name.value;
@@ -581,7 +618,7 @@ std::optional<Attribute> SchemaCreator::loadAttribute(AttributeNode node)
errors.emplace_back(node.name.span, "unsupported type");
}
}
if(current().inConnection) { // TODO remove identifier
if(current().inConnection && !current().inSingleAutomaticConnection) { // TODO remove identifier
if (node.type == ValueNode::WIRE || node.type == ValueNode::IDENTIFIER) {
if(current().doesWireExists(node.defaultValue->asIdentifier())) {
value = Value::fromReference(node.defaultValue->asIdentifier(), Value::WIRE_REFERENCE);
@@ -593,6 +630,13 @@ std::optional<Attribute> SchemaCreator::loadAttribute(AttributeNode node)
errors.emplace_back(node.name.span, "unsupported type");
}
}
if(current().inSingleAutomaticConnection) {
if (node.type == ValueNode::STRING) {
value = Value::fromString(node.defaultValue->asString());
} else {
errors.emplace_back(node.name.span, "unsupported type");
}
}
current().attributes.emplace_back(name, value);
@@ -864,4 +908,14 @@ std::shared_ptr<BusInstance> SchemaCreator::loadBusInstance(InstanceNode instanc
return std::make_shared<BusInstance>(name, position, bus, static_cast<int>(size));
}
vector<Enumeration> SchemaCreator::createWireEnumeration(vector<Value> wireValues) {
vector<Enumeration> wires;
for(auto& wire: wireValues) {
if(wire.isType(Value::STRING)) {
wires.emplace_back(wire.asString(), wire);
}
}
return wires;
}
} // namespace domain
+6 -3
View File
@@ -18,10 +18,11 @@ struct ComdelContext {
std::string name;
bool inComponent;
bool inConnection;
bool inSingleAutomaticConnection;
bool inBus;
ComdelContext(std::string name, bool inComponent, bool inConnection, bool inBus)
: name(name), inComponent(inComponent), inConnection(inConnection), inBus(inBus)
ComdelContext(std::string name, bool inComponent, bool inConnection, bool inSingleAutomaticConnection, bool inBus)
: name(name), inComponent(inComponent), inConnection(inConnection), inSingleAutomaticConnection(inSingleAutomaticConnection), inBus(inBus)
{}
bool doesAttributeExists(std::string name, Value::ValueType type) {
@@ -117,7 +118,7 @@ class SchemaCreator
this->context.push_back(current());
current().name = name;
} else {
ComdelContext con(name, false, false, false);
ComdelContext con(name, false, false, false, false);
push(con);
}
}
@@ -138,6 +139,8 @@ public:
std::optional<Library> loadLibrary(LibraryNode node);
Schema* loadSchema(SchemaNode node, Library &library);
vector <Enumeration> createWireEnumeration(vector <Value> vector1);
};
} // namespace domain