Added support for direct buses
This commit is contained in:
parent
7fcfb8c977
commit
c65d12a2a1
|
@ -224,18 +224,22 @@ std::optional<Connection> ComdelGenerator::loadConnection(ConnectionNode node)
|
||||||
{
|
{
|
||||||
push(ComdelContext("connection", false, true, false));
|
push(ComdelContext("connection", false, true, false));
|
||||||
|
|
||||||
std::string component = node.component.value;
|
|
||||||
std::string pin = node.pin.value;
|
|
||||||
std::string bus = node.bus.value;
|
std::string bus = node.bus.value;
|
||||||
|
auto busInstance = getBus(bus);
|
||||||
|
if(!busInstance) {
|
||||||
|
errors.emplace_back(node.span, "bus does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
auto componentInstance = getComponentPin(component, pin);
|
if(busInstance->getType() == Bus::REGULAR) {
|
||||||
|
ConnectionComponent first{node.first.component.value, node.first.pin.value};
|
||||||
|
|
||||||
|
auto componentInstance = getComponentPin(first.component, first.pin);
|
||||||
if(!componentInstance) {
|
if(!componentInstance) {
|
||||||
errors.emplace_back(node.span, "pin does not exist");
|
errors.emplace_back(node.span, "pin does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto busInstance = getBus(bus);
|
if(node.second.has_value()) {
|
||||||
if(!busInstance) {
|
errors.emplace_back(node.span, "regular bus doesn't allow direct connections");
|
||||||
errors.emplace_back(node.span, "bus does not exist");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<std::string> wireNames;
|
std::set<std::string> wireNames;
|
||||||
|
@ -245,8 +249,8 @@ std::optional<Connection> ComdelGenerator::loadConnection(ConnectionNode node)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Attribute> attributes;
|
std::vector<Attribute> attributes;
|
||||||
for(uint i=0; i<node.attributes.size(); i++) {
|
for(auto & attribute : node.attributes) {
|
||||||
auto attr = loadAttribute(node.attributes[i]);
|
auto attr = loadAttribute(attribute);
|
||||||
if(!attr) {
|
if(!attr) {
|
||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
|
@ -259,27 +263,112 @@ std::optional<Connection> ComdelGenerator::loadConnection(ConnectionNode node)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Value> wires;
|
std::vector<Value> wires;
|
||||||
for(uint i=0; i<node.wires.size(); i++) {
|
for(auto & firstWire : node.firstWires) {
|
||||||
if(node.wires[i].is(ValueNode::NIL)) {
|
if(firstWire.is(ValueNode::NIL)) {
|
||||||
wires.push_back(Value::fromNull());
|
wires.push_back(Value::fromNull());
|
||||||
} else if(node.wires[i].is(ValueNode::INT)) {
|
} else if(firstWire.is(ValueNode::INT)) {
|
||||||
wires.push_back(Value::fromInt(node.wires[i].asInt()));
|
wires.push_back(Value::fromInt(firstWire.asInt()));
|
||||||
} else if(node.wires[i].is(ValueNode::IDENTIFIER)) {
|
} else if(firstWire.is(ValueNode::IDENTIFIER)) {
|
||||||
if(attributeNames.count(node.wires[i].asIdentifier())) {
|
if(attributeNames.count(firstWire.asIdentifier())) {
|
||||||
wires.push_back(Value::fromReference(node.wires[i].asIdentifier(), Value::ATTRIBUTE_REFERENCE));
|
wires.push_back(Value::fromReference(firstWire.asIdentifier(), Value::ATTRIBUTE_REFERENCE));
|
||||||
} else if(wireNames.count(node.wires[i].asIdentifier())) {
|
} else if(wireNames.count(firstWire.asIdentifier())) {
|
||||||
wires.push_back(Value::fromReference(node.wires[i].asIdentifier(), Value::WIRE_REFERENCE));
|
wires.push_back(Value::fromReference(firstWire.asIdentifier(), Value::WIRE_REFERENCE));
|
||||||
} else {
|
} else {
|
||||||
errors.emplace_back(node.wires[i].span, "unknown identifier");
|
errors.emplace_back(firstWire.span, "unknown identifier");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
errors.emplace_back(node.wires[i].span, "unknown value type");
|
errors.emplace_back(firstWire.span, "unknown value type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pop();
|
pop();
|
||||||
|
|
||||||
return Connection(component, pin, bus, attributes, wires);
|
return Connection(first, nullopt, bus, attributes, wires, nullopt);
|
||||||
|
} else if(busInstance->getType() == Bus::AUTOMATIC || busInstance->getType() == Bus::AUTOMATIC_SINGLE) {
|
||||||
|
ConnectionComponent first{node.first.component.value, node.first.pin.value};
|
||||||
|
|
||||||
|
if(!node.second.has_value()) {
|
||||||
|
errors.emplace_back(node.span, "missing second component");
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectionComponent second{node.second->component.value, node.second->pin.value};
|
||||||
|
|
||||||
|
auto firstComponentInstance = getComponentPin(first.component, first.pin);
|
||||||
|
if(!firstComponentInstance) {
|
||||||
|
errors.emplace_back(node.span, "pin does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto secondComponentInstance = getComponentPin(second.component, second.pin);
|
||||||
|
if(!secondComponentInstance) {
|
||||||
|
errors.emplace_back(node.span, "pin does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> wireNames;
|
||||||
|
for(auto &wire: busInstance->getWires()) {
|
||||||
|
wireNames.insert(wire.getName());
|
||||||
|
current().wires.push_back(wire.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Attribute> attributes;
|
||||||
|
for(auto & attribute : node.attributes) {
|
||||||
|
auto attr = loadAttribute(attribute);
|
||||||
|
if(!attr) {
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
attributes.push_back(*attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> attributeNames;
|
||||||
|
for(auto attribute: attributes) {
|
||||||
|
attributeNames.insert(attribute.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Value> firstWires;
|
||||||
|
for(auto & firstWire : node.firstWires) {
|
||||||
|
if(firstWire.is(ValueNode::NIL)) {
|
||||||
|
firstWires.push_back(Value::fromNull());
|
||||||
|
} else if(firstWire.is(ValueNode::INT)) {
|
||||||
|
firstWires.push_back(Value::fromInt(firstWire.asInt()));
|
||||||
|
} else if(firstWire.is(ValueNode::IDENTIFIER)) {
|
||||||
|
if(attributeNames.count(firstWire.asIdentifier())) {
|
||||||
|
firstWires.push_back(Value::fromReference(firstWire.asIdentifier(), Value::ATTRIBUTE_REFERENCE));
|
||||||
|
} else if(wireNames.count(firstWire.asIdentifier())) {
|
||||||
|
firstWires.push_back(Value::fromReference(firstWire.asIdentifier(), Value::WIRE_REFERENCE));
|
||||||
|
} else {
|
||||||
|
errors.emplace_back(firstWire.span, "unknown identifier");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errors.emplace_back(firstWire.span, "unknown value type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<Value> secondWires;
|
||||||
|
for(auto & secondWire : *node.secondWires) {
|
||||||
|
if(secondWire.is(ValueNode::NIL)) {
|
||||||
|
secondWires.push_back(Value::fromNull());
|
||||||
|
} else if(secondWire.is(ValueNode::INT)) {
|
||||||
|
secondWires.push_back(Value::fromInt(secondWire.asInt()));
|
||||||
|
} else if(secondWire.is(ValueNode::IDENTIFIER)) {
|
||||||
|
if(attributeNames.count(secondWire.asIdentifier())) {
|
||||||
|
secondWires.push_back(Value::fromReference(secondWire.asIdentifier(), Value::ATTRIBUTE_REFERENCE));
|
||||||
|
} else if(wireNames.count(secondWire.asIdentifier())) {
|
||||||
|
secondWires.push_back(Value::fromReference(secondWire.asIdentifier(), Value::WIRE_REFERENCE));
|
||||||
|
} else {
|
||||||
|
errors.emplace_back(secondWire.span, "unknown identifier");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errors.emplace_back(secondWire.span, "unknown value type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pop();
|
||||||
|
|
||||||
|
return Connection(first, second, bus, attributes, firstWires, secondWires);
|
||||||
|
}
|
||||||
|
pop();
|
||||||
|
errors.emplace_back(node.span, "unsupported connection type");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Component> ComdelGenerator::loadComponent(ComponentNode node)
|
std::optional<Component> ComdelGenerator::loadComponent(ComponentNode node)
|
||||||
|
@ -659,25 +748,60 @@ std::optional<Schema> ComdelGenerator::loadSchema(SchemaNode node, Library &libr
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto &conn: node.connections) {
|
for(auto &conn: node.connections) {
|
||||||
auto component = dynamic_cast<ComponentInstance*>(schema.getInstance(conn.instance.value));
|
auto firstComponent = dynamic_cast<ComponentInstance*>(schema.getInstance(conn.first.instance.value));
|
||||||
if(component == NULL) {
|
if(firstComponent == NULL) {
|
||||||
errors.push_back(SourceError{conn.instance.span, "unknown component"});
|
errors.push_back(SourceError{conn.first.instance.span, "unknown component"});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(!component->component.hasPin(conn.pin.value)) {
|
if(!firstComponent->component.hasPin(conn.first.pin.value)) {
|
||||||
errors.push_back(SourceError{conn.pin.span, "unknown pin"});
|
errors.push_back(SourceError{conn.first.pin.span, "unknown pin"});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ComponentInstance *secondComponent = NULL;
|
||||||
|
if(conn.second.has_value()) {
|
||||||
|
secondComponent = dynamic_cast<ComponentInstance*>(schema.getInstance(conn.second->instance.value));
|
||||||
|
if(secondComponent == NULL) {
|
||||||
|
errors.push_back(SourceError{conn.second->instance.span, "unknown component"});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!secondComponent->component.hasPin(conn.second->pin.value)) {
|
||||||
|
errors.push_back(SourceError{conn.second->pin.span, "unknown pin"});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto bus = dynamic_cast<BusInstance*>(schema.getInstance(conn.bus.value));
|
auto bus = dynamic_cast<BusInstance*>(schema.getInstance(conn.bus.value));
|
||||||
if(bus == NULL) {
|
if(bus == NULL) {
|
||||||
errors.push_back(SourceError{conn.bus.span, "unknown bus"});
|
errors.push_back(SourceError{conn.bus.span, "unknown bus"});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(!library.hasConnection(component->component.getName(), conn.pin.value, bus->bus.getName())) {
|
|
||||||
|
std::optional<Connection> connection = std::nullopt;
|
||||||
|
if(secondComponent != NULL) {
|
||||||
|
ConnectionComponent firstConn{firstComponent->component.getName(), conn.first.pin.value};
|
||||||
|
ConnectionComponent secondConn{secondComponent->component.getName(), conn.second->pin.value};
|
||||||
|
|
||||||
|
if(library.hasConnection(firstConn,
|
||||||
|
bus->bus.getName(),
|
||||||
|
secondConn)) {
|
||||||
|
connection = *library.getConnection(firstConn, bus->bus.getName(), secondConn);
|
||||||
|
} else {
|
||||||
errors.push_back(SourceError{conn.span, "unknown connection"});
|
errors.push_back(SourceError{conn.span, "unknown connection"});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto connection = *library.getConnection(component->component.getName(), conn.pin.value, bus->bus.getName());
|
} else {
|
||||||
|
ConnectionComponent firstConn{firstComponent->name, conn.first.pin.value};
|
||||||
|
|
||||||
|
if(library.hasConnection(firstConn,
|
||||||
|
bus->bus.getName())) {
|
||||||
|
connection = *library.getConnection(firstConn, bus->bus.getName());
|
||||||
|
} else {
|
||||||
|
errors.push_back(SourceError{conn.span, "unknown connection"});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!conn.wire) {
|
if(!conn.wire) {
|
||||||
errors.push_back(SourceError{conn.span, "missing @wire"});
|
errors.push_back(SourceError{conn.span, "missing @wire"});
|
||||||
|
@ -692,8 +816,8 @@ std::optional<Schema> ComdelGenerator::loadSchema(SchemaNode node, Library &libr
|
||||||
|
|
||||||
std::vector<InstanceAttribute*> attributes;
|
std::vector<InstanceAttribute*> attributes;
|
||||||
for(auto& attr: conn.attributes) {
|
for(auto& attr: conn.attributes) {
|
||||||
if(connection.hasAttribute(attr.name.value)) {
|
if(connection->hasAttribute(attr.name.value)) {
|
||||||
auto attribute = connection.getAttribute(attr.name.value);
|
auto attribute = connection->getAttribute(attr.name.value);
|
||||||
auto value = toType(attr.value);
|
auto value = toType(attr.value);
|
||||||
|
|
||||||
for(auto& en: attribute.getPopup()->getEnumeration()) {
|
for(auto& en: attribute.getPopup()->getEnumeration()) {
|
||||||
|
@ -711,7 +835,11 @@ std::optional<Schema> ComdelGenerator::loadSchema(SchemaNode node, Library &libr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
schema.connections.push_back(new BusConnectionInstance(component, attributes, bus, wire, connection));
|
if(secondComponent == NULL) {
|
||||||
|
schema.connections.push_back(new BusConnectionInstance(firstComponent, attributes, bus, wire, *connection));
|
||||||
|
} else {
|
||||||
|
schema.connections.push_back(new DirectConnectionInstance(firstComponent, secondComponent, attributes, bus, wire, *connection));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return schema;
|
return schema;
|
||||||
|
|
|
@ -2,20 +2,19 @@
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
Connection::Connection(std::string component, std::string pin, std::string bus, std::vector<Attribute> attributes, std::vector<Value> wires)
|
Connection::Connection(ConnectionComponent first, std::optional<ConnectionComponent> second,
|
||||||
: component(component), pin(pin), bus(bus), attributes(attributes), wires(wires)
|
std::string bus, std::vector<Attribute> attributes,
|
||||||
|
std::vector<Value> firstWires, std::optional<std::vector<Value>> secondWires)
|
||||||
|
: first(first), second(second), bus(bus), attributes(attributes), firstWires(firstWires), secondWires(secondWires)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool Connection::isConnecting(std::string component, std::string pin, std::string bus) {
|
ConnectionComponent Connection::getComponent() {
|
||||||
return this->component == component && this->pin == pin && this->bus == bus;
|
return first;
|
||||||
|
}
|
||||||
|
std::optional<ConnectionComponent> Connection::getSecondComponent() {
|
||||||
|
return second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Connection::getComponent() {
|
|
||||||
return component;
|
|
||||||
}
|
|
||||||
std::string Connection::getPin() {
|
|
||||||
return pin;
|
|
||||||
}
|
|
||||||
std::string Connection::getBus() {
|
std::string Connection::getBus() {
|
||||||
return bus;
|
return bus;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +23,10 @@ std::vector<Attribute> Connection::getAttributes() {
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
std::vector<Value> Connection::getWires() {
|
std::vector<Value> Connection::getWires() {
|
||||||
return wires;
|
return firstWires;
|
||||||
|
}
|
||||||
|
std::optional<std::vector<Value>> Connection::getSecondWires() {
|
||||||
|
return secondWires;
|
||||||
}
|
}
|
||||||
|
|
||||||
Attribute Connection::getAttribute(std::string name) {
|
Attribute Connection::getAttribute(std::string name) {
|
||||||
|
@ -45,4 +47,20 @@ bool Connection::hasAttribute(std::string name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Connection::isConnecting(ConnectionComponent component) {
|
||||||
|
return first == component || (second.has_value() && *second == component);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Connection::isConnecting(ConnectionComponent component, std::string bus) {
|
||||||
|
return this->bus == bus && (first == component || (second.has_value() && *second == component));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Connection::isConnecting(ConnectionComponent component, std::string bus, ConnectionComponent secondComponent) {
|
||||||
|
if(!second.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (this->first == component && this->bus == bus && this->second == secondComponent) ||
|
||||||
|
(this->first == secondComponent && this->bus == bus && this->second == component);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -8,25 +8,49 @@
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
class Connection
|
struct ConnectionComponent
|
||||||
{
|
{
|
||||||
std::string component;
|
std::string component;
|
||||||
std::string pin;
|
std::string pin;
|
||||||
|
|
||||||
|
bool operator==(const ConnectionComponent& rhs) const
|
||||||
|
{
|
||||||
|
return (component == rhs.component) && (pin == rhs.pin);
|
||||||
|
}
|
||||||
|
bool operator!=(const ConnectionComponent& rhs) const
|
||||||
|
{
|
||||||
|
return !operator==(rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Connection
|
||||||
|
{
|
||||||
|
ConnectionComponent first;
|
||||||
|
std::optional<ConnectionComponent> second;
|
||||||
std::string bus;
|
std::string bus;
|
||||||
|
|
||||||
std::vector<Attribute> attributes;
|
std::vector<Attribute> attributes;
|
||||||
std::vector<Value> wires;
|
|
||||||
|
std::vector<Value> firstWires;
|
||||||
|
std::optional<std::vector<Value>> secondWires;
|
||||||
public:
|
public:
|
||||||
Connection(std::string component, std::string pin, std::string bus, std::vector<Attribute> attributes, std::vector<Value> wires);
|
Connection(ConnectionComponent first, std::optional<ConnectionComponent> second,
|
||||||
|
std::string bus, std::vector<Attribute> attributes,
|
||||||
|
std::vector<Value> firstWires, std::optional<std::vector<Value>> secondWires);
|
||||||
|
|
||||||
bool isConnecting(std::string component, std::string pin, std::string bus);
|
bool isConnecting(ConnectionComponent first);
|
||||||
|
bool isConnecting(ConnectionComponent first, std::string bus);
|
||||||
|
bool isConnecting(ConnectionComponent first, std::string bus, ConnectionComponent second);
|
||||||
|
|
||||||
|
|
||||||
|
ConnectionComponent getComponent();
|
||||||
|
std::optional<ConnectionComponent> getSecondComponent();
|
||||||
|
|
||||||
std::string getComponent();
|
|
||||||
std::string getPin();
|
|
||||||
std::string getBus();
|
std::string getBus();
|
||||||
|
|
||||||
std::vector<Attribute> getAttributes();
|
std::vector<Attribute> getAttributes();
|
||||||
|
|
||||||
std::vector<Value> getWires();
|
std::vector<Value> getWires();
|
||||||
|
std::optional<std::vector<Value>> getSecondWires();
|
||||||
|
|
||||||
Attribute getAttribute(std::string name);
|
Attribute getAttribute(std::string name);
|
||||||
bool hasAttribute(std::string name);
|
bool hasAttribute(std::string name);
|
||||||
|
|
|
@ -81,16 +81,29 @@ Bus &Library::getBus(std::string bus) {
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
|
|
||||||
}
|
}
|
||||||
std::optional<Connection> Library::getConnection(std::string component, std::string pin, std::string bus) {
|
|
||||||
|
bool Library::hasConnection(ConnectionComponent component, std::string bus) {
|
||||||
|
return getConnection(component, bus).has_value();
|
||||||
|
}
|
||||||
|
std::optional<Connection> Library::getConnection(ConnectionComponent component, std::string bus) {
|
||||||
for(uint i=0; i<connections.size(); i++) {
|
for(uint i=0; i<connections.size(); i++) {
|
||||||
if(connections[i].isConnecting(component, pin, bus)) {
|
if(connections[i].isConnecting(component, bus)) {
|
||||||
return connections[i];
|
return connections[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
bool Library::hasConnection(std::string component, std::string pin, std::string bus) {
|
|
||||||
return getConnection(component, pin, bus).has_value();
|
bool Library::hasConnection(ConnectionComponent component, std::string bus, ConnectionComponent secondComponent) {
|
||||||
|
return getConnection(component, bus, secondComponent).has_value();
|
||||||
|
}
|
||||||
|
std::optional<Connection> Library::getConnection(ConnectionComponent component, std::string bus, ConnectionComponent secondComponent) {
|
||||||
|
for(uint i=0; i<connections.size(); i++) {
|
||||||
|
if(connections[i].isConnecting(component, bus, secondComponent)) {
|
||||||
|
return connections[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Library::getMessage(std::string key) {
|
std::string Library::getMessage(std::string key) {
|
||||||
|
|
|
@ -45,18 +45,19 @@ public:
|
||||||
|
|
||||||
bool hasComponent(std::string name);
|
bool hasComponent(std::string name);
|
||||||
bool hasBus(std::string name);
|
bool hasBus(std::string name);
|
||||||
bool hasConnection(std::string component, std::string pin, std::string bus);
|
|
||||||
|
|
||||||
std::map<std::string, std::string> getMessages();
|
std::map<std::string, std::string> getMessages();
|
||||||
|
|
||||||
AddressSpace &getAddressSpace(std::string name);
|
AddressSpace &getAddressSpace(std::string name);
|
||||||
Component &getComponent(std::string name);
|
Component &getComponent(std::string name);
|
||||||
Bus &getBus(std::string bus);
|
Bus &getBus(std::string bus);
|
||||||
std::optional<Connection> getConnection(std::string component, std::string pin, std::string bus);
|
|
||||||
std::string getMessage(std::string key);
|
std::string getMessage(std::string key);
|
||||||
|
|
||||||
|
bool hasConnection(ConnectionComponent component, std::string bus);
|
||||||
|
std::optional<Connection> getConnection(ConnectionComponent component, std::string bus);
|
||||||
|
|
||||||
|
bool hasConnection(ConnectionComponent component, std::string bus, ConnectionComponent secondComponent);
|
||||||
|
std::optional<Connection> getConnection(ConnectionComponent component, std::string bus, ConnectionComponent secondComponent);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -170,7 +170,7 @@ struct ConditionNode
|
||||||
std::vector<ValueNode> params;
|
std::vector<ValueNode> params;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ActionNode: AstNode {
|
class ActionNode: public AstNode {
|
||||||
public:
|
public:
|
||||||
enum ActionType {
|
enum ActionType {
|
||||||
ERROR,
|
ERROR,
|
||||||
|
@ -182,27 +182,27 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct IfStatementNode: AstNode
|
struct IfStatementNode: public AstNode
|
||||||
{
|
{
|
||||||
ConditionNode condition;
|
ConditionNode condition;
|
||||||
ActionNode action;
|
ActionNode action;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct RuleNode: AstNode
|
struct RuleNode: public AstNode
|
||||||
{
|
{
|
||||||
std::vector<IfStatementNode> statements;
|
std::vector<IfStatementNode> statements;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct EnumerationNode: AstNode
|
struct EnumerationNode: public AstNode
|
||||||
{
|
{
|
||||||
StringNode key;
|
StringNode key;
|
||||||
ValueNode value;
|
ValueNode value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PopupNode: AstNode
|
struct PopupNode: public AstNode
|
||||||
{
|
{
|
||||||
enum PopupType {
|
enum PopupType {
|
||||||
AUTOMATIC,
|
AUTOMATIC,
|
||||||
|
@ -226,20 +226,20 @@ struct PropertyNode: public AstNode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct DisplayItemNode: AstNode
|
struct DisplayItemNode: public AstNode
|
||||||
{
|
{
|
||||||
IdentifierNode type;
|
IdentifierNode type;
|
||||||
std::vector<PropertyNode> values;
|
std::vector<PropertyNode> values;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct DisplayNode: AstNode
|
struct DisplayNode: public AstNode
|
||||||
{
|
{
|
||||||
std::vector<DisplayItemNode> items;
|
std::vector<DisplayItemNode> items;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct PinConnectionNode: AstNode
|
struct PinConnectionNode: public AstNode
|
||||||
{
|
{
|
||||||
enum ConnectionType {
|
enum ConnectionType {
|
||||||
CHECK_ONLY,
|
CHECK_ONLY,
|
||||||
|
@ -251,7 +251,7 @@ struct PinConnectionNode: AstNode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct PinNode: AstNode
|
struct PinNode: public AstNode
|
||||||
{
|
{
|
||||||
enum PinType {
|
enum PinType {
|
||||||
IN_OUT,
|
IN_OUT,
|
||||||
|
@ -287,7 +287,7 @@ struct WireNode: public AstNode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct AttributeNode: AstNode
|
struct AttributeNode: public AstNode
|
||||||
{
|
{
|
||||||
ValueNode::ValueType type;
|
ValueNode::ValueType type;
|
||||||
IdentifierNode name;
|
IdentifierNode name;
|
||||||
|
@ -295,17 +295,25 @@ struct AttributeNode: AstNode
|
||||||
std::optional<PopupNode> popup;
|
std::optional<PopupNode> popup;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConnectionNode: AstNode
|
struct ConnectionComponentNode: public AstNode
|
||||||
{
|
{
|
||||||
IdentifierNode component;
|
IdentifierNode component;
|
||||||
IdentifierNode pin;
|
IdentifierNode pin;
|
||||||
IdentifierNode bus;
|
|
||||||
std::vector<AttributeNode> attributes;
|
|
||||||
std::vector<ValueNode> wires;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ConnectionNode: public AstNode
|
||||||
|
{
|
||||||
|
ConnectionComponentNode first;
|
||||||
|
std::optional<ConnectionComponentNode> second;
|
||||||
|
|
||||||
struct ComponentNode: AstNode
|
IdentifierNode bus;
|
||||||
|
std::vector<AttributeNode> attributes;
|
||||||
|
|
||||||
|
std::vector<ValueNode> firstWires;
|
||||||
|
std::optional<std::vector<ValueNode>> secondWires;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ComponentNode: public AstNode
|
||||||
{
|
{
|
||||||
enum ComponentType {
|
enum ComponentType {
|
||||||
OTHER,
|
OTHER,
|
||||||
|
@ -326,7 +334,7 @@ struct ComponentNode: AstNode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct BusNode: AstNode
|
struct BusNode: public AstNode
|
||||||
{
|
{
|
||||||
enum BusType {
|
enum BusType {
|
||||||
AUTOMATIC,
|
AUTOMATIC,
|
||||||
|
@ -342,7 +350,7 @@ struct BusNode: AstNode
|
||||||
std::vector<WireNode> wires;
|
std::vector<WireNode> wires;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LibraryNode: AstNode
|
struct LibraryNode: public AstNode
|
||||||
{
|
{
|
||||||
std::optional<StringNode> name;
|
std::optional<StringNode> name;
|
||||||
std::optional<StringNode> libraryInfo;
|
std::optional<StringNode> libraryInfo;
|
||||||
|
@ -361,20 +369,20 @@ struct LibraryNode: AstNode
|
||||||
// SCHEMA models
|
// SCHEMA models
|
||||||
|
|
||||||
|
|
||||||
struct WireInstanceNode: AstNode
|
struct WireInstanceNode: public AstNode
|
||||||
{
|
{
|
||||||
IdentifierNode name;
|
IdentifierNode name;
|
||||||
std::optional<CountNode> position;
|
std::optional<CountNode> position;
|
||||||
std::optional<DisplayNode> display;
|
std::optional<DisplayNode> display;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InstanceAttributeNode: AstNode
|
struct InstanceAttributeNode: public AstNode
|
||||||
{
|
{
|
||||||
IdentifierNode name;
|
IdentifierNode name;
|
||||||
ValueNode value;
|
ValueNode value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InstanceNode: AstNode
|
struct InstanceNode: public AstNode
|
||||||
{
|
{
|
||||||
IdentifierNode name;
|
IdentifierNode name;
|
||||||
IdentifierNode component;
|
IdentifierNode component;
|
||||||
|
@ -385,11 +393,16 @@ struct InstanceNode: AstNode
|
||||||
std::optional<NumberNode> size;
|
std::optional<NumberNode> size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ConnectionComponentInstance {
|
||||||
struct ConnectionInstanceNode: AstNode
|
|
||||||
{
|
|
||||||
IdentifierNode instance;
|
IdentifierNode instance;
|
||||||
IdentifierNode pin;
|
IdentifierNode pin;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConnectionInstanceNode: public AstNode
|
||||||
|
{
|
||||||
|
ConnectionComponentInstance first;
|
||||||
|
std::optional<ConnectionComponentInstance> second;
|
||||||
|
|
||||||
IdentifierNode bus;
|
IdentifierNode bus;
|
||||||
std::optional<IdentifierNode> wire;
|
std::optional<IdentifierNode> wire;
|
||||||
|
|
||||||
|
@ -397,7 +410,7 @@ struct ConnectionInstanceNode: AstNode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct SchemaNode: AstNode
|
struct SchemaNode: public AstNode
|
||||||
{
|
{
|
||||||
std::optional<StringNode> source;
|
std::optional<StringNode> source;
|
||||||
|
|
||||||
|
|
|
@ -865,24 +865,44 @@ PResult<ConnectionNode> ComdelParser::parseConnection() {
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::KW_CONNECTION);
|
RETURN_IF_NOT_TOKEN(TokenType::KW_CONNECTION);
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
||||||
ASSIGN_OR_RETURN_IF_ERR(connection.component, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(connection.first.component, parseIdentifier());
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::DOT);
|
RETURN_IF_NOT_TOKEN(TokenType::DOT);
|
||||||
ASSIGN_OR_RETURN_IF_ERR(connection.pin, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(connection.first.pin, parseIdentifier());
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::COMMA);
|
RETURN_IF_NOT_TOKEN(TokenType::COMMA);
|
||||||
ASSIGN_OR_RETURN_IF_ERR(connection.bus, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(connection.bus, parseIdentifier());
|
||||||
|
|
||||||
|
if(check(TokenType::COMMA)) {
|
||||||
|
auto conn = ConnectionComponentNode{};
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::COMMA);
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
||||||
|
ASSIGN_OR_RETURN_IF_ERR(conn.component, parseIdentifier());
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::DOT);
|
||||||
|
ASSIGN_OR_RETURN_IF_ERR(conn.pin, parseIdentifier());
|
||||||
|
connection.second = conn;
|
||||||
|
}
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::RPAREN);
|
RETURN_IF_NOT_TOKEN(TokenType::RPAREN);
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
||||||
|
int wireCount = 0;
|
||||||
|
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
if (check(TokenType::KW_ATTRIBUTE)) {
|
if (check(TokenType::KW_ATTRIBUTE)) {
|
||||||
APPEND_OR_RETURN_IF_ERR(connection.attributes, parseAttribute());
|
APPEND_OR_RETURN_IF_ERR(connection.attributes, parseAttribute());
|
||||||
} else if(check(TokenType::KW_WIRES)) {
|
} else if(check(TokenType::KW_WIRES)) {
|
||||||
bump();
|
bump();
|
||||||
auto wires = parseList<ValueNode>(std::optional<TokenType>(TokenType::LBRACE), TokenType::RBRACE, std::optional<TokenType>(TokenType::COMMA), false,
|
auto wires = parseList<ValueNode>(TokenType::LBRACE, TokenType::RBRACE, TokenType::COMMA, false,
|
||||||
[this] { return parseConnectionWire(); });
|
[this] { return parseConnectionWire(); });
|
||||||
RETURN_IF_ERR(wires);
|
RETURN_IF_ERR(wires);
|
||||||
connection.wires = *wires;
|
if(wireCount == 0) {
|
||||||
|
connection.firstWires = *wires;
|
||||||
|
} else if(wireCount == 1 && connection.second.has_value()) {
|
||||||
|
connection.secondWires = *wires;
|
||||||
|
} else {
|
||||||
|
return unexpected();
|
||||||
|
}
|
||||||
|
wireCount++;
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
return unexpected();
|
||||||
}
|
}
|
||||||
|
@ -1158,11 +1178,21 @@ PResult<ConnectionInstanceNode> ComdelParser::parseConnectionInstance() {
|
||||||
ConnectionInstanceNode connection;
|
ConnectionInstanceNode connection;
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
||||||
ASSIGN_OR_RETURN_IF_ERR(connection.instance, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(connection.first.instance, parseIdentifier());
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::DOT);
|
RETURN_IF_NOT_TOKEN(TokenType::DOT);
|
||||||
ASSIGN_OR_RETURN_IF_ERR(connection.pin, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(connection.first.pin, parseIdentifier());
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::COMMA);
|
RETURN_IF_NOT_TOKEN(TokenType::COMMA);
|
||||||
ASSIGN_OR_RETURN_IF_ERR(connection.bus, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(connection.bus, parseIdentifier());
|
||||||
|
|
||||||
|
if(check(TokenType::COMMA)) {
|
||||||
|
bump();
|
||||||
|
ConnectionComponentInstance second;
|
||||||
|
ASSIGN_OR_RETURN_IF_ERR(second.instance, parseIdentifier());
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::DOT);
|
||||||
|
ASSIGN_OR_RETURN_IF_ERR(second.pin, parseIdentifier());
|
||||||
|
connection.second = second;
|
||||||
|
}
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::RPAREN);
|
RETURN_IF_NOT_TOKEN(TokenType::RPAREN);
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
Loading…
Reference in New Issue