This commit is contained in:
Borna Rajković 2022-05-07 13:20:09 +02:00
parent dde9bb8af8
commit 344fe7cfa6
8 changed files with 128 additions and 192 deletions

View File

@ -14,25 +14,15 @@ void Schema::setSchema(domain::Schema* schema)
scene.clear(); scene.clear();
this->schema = schema; this->schema = schema;
if(schema != nullptr) { if(schema != nullptr) {
for(auto &instance: schema->instances) { for(auto &instance: schema->componentInstances) {
ComponentWrapper *group = nullptr; ComponentWrapper *component = ComponentWrapper::ofComponent(&instance);
auto component = dynamic_cast<domain::ComponentInstance*>(instance); component->setPos(instance.position.first, instance.position.second);
if(component) { scene.addItem(component);
group = ComponentWrapper::ofComponent(component);
} }
auto bus = dynamic_cast<domain::BusInstance*>(instance); for(auto &instance: schema->busInstances) {
if(bus) { ComponentWrapper *bus = ComponentWrapper::ofBus(&instance);
group = ComponentWrapper::ofBus(bus); bus->setPos(instance.position.first, instance.position.second);
} scene.addItem(bus);
if(group != nullptr) {
group->setPos(instance->position.first, instance->position.second);
scene.addItem(group);
}
}
for(auto &wire: schema->wires) {
auto group = ComponentWrapper::ofWire(wire);
group->setPos(wire->position.first, wire->position.second);
scene.addItem(group);
} }
} }
} }

View File

@ -8,13 +8,10 @@ std::vector<ValidationError> ComdelValidator::validateSchema(Schema &schema, Val
context.instance = nullptr; context.instance = nullptr;
context.attribute = nullptr; context.attribute = nullptr;
for(auto &inst: schema.instances) { for(auto &instance: schema.componentInstances) {
auto *instance = dynamic_cast<ComponentInstance*>(inst); auto result = validateComponent(&instance, context);
if(instance) {
auto result = validateComponent(instance, context);
errors.insert(errors.end(), result.begin(), result.end()); errors.insert(errors.end(), result.begin(), result.end());
} }
}
return errors; return errors;
} }

View File

@ -3,16 +3,16 @@
namespace domain { namespace domain {
ConnectionInstance::ConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute*> attributes, WireInstance *wire, Connection connection) ConnectionInstance::ConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute*> attributes, Connection connection)
: instance(instance), attributes(attributes), connection(connection), wire(wire) : instance(instance), attributes(attributes), connection(connection)
{} {}
BusConnectionInstance::BusConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute*> attributes, BusInstance *bus, WireInstance *wire, Connection connection) BusConnectionInstance::BusConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute*> attributes, BusInstance *bus, Connection connection)
: ConnectionInstance(instance, attributes, wire, connection), bus(bus) : ConnectionInstance(instance, attributes, connection), bus(bus)
{} {}
DirectConnectionInstance::DirectConnectionInstance(ComponentInstance *instance, ComponentInstance *secondInstance, std::vector<InstanceAttribute*> attributes, BusInstance *bus, WireInstance *wire, Connection connection) DirectConnectionInstance::DirectConnectionInstance(ComponentInstance *instance, ComponentInstance *secondInstance, std::vector<InstanceAttribute*> attributes, BusInstance *bus, Connection connection)
: ConnectionInstance(instance, attributes, wire, connection), secondInstance(secondInstance), bus(bus) : ConnectionInstance(instance, attributes, connection), secondInstance(secondInstance), bus(bus)
{} {}
} // namespace domain } // namespace domain

View File

@ -14,13 +14,12 @@ class ConnectionInstance
public: public:
ComponentInstance *instance; ComponentInstance *instance;
Connection connection; Connection connection;
WireInstance *wire;
virtual ~ConnectionInstance() = default; virtual ~ConnectionInstance() = default;
std::vector<InstanceAttribute*> attributes; std::vector<InstanceAttribute*> attributes;
ConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute*> attributes, WireInstance *wire, Connection connection); ConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute*> attributes, Connection connection);
}; };
@ -29,7 +28,7 @@ class BusConnectionInstance: public ConnectionInstance
public: public:
BusInstance *bus; BusInstance *bus;
BusConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute*> attributes, BusInstance *bus, WireInstance *wire, Connection connection); BusConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute*> attributes, BusInstance *bus, Connection connection);
}; };
@ -39,7 +38,7 @@ public:
BusInstance *bus; BusInstance *bus;
ComponentInstance *secondInstance; ComponentInstance *secondInstance;
DirectConnectionInstance(ComponentInstance *instance, ComponentInstance *secondsInstance, std::vector<InstanceAttribute*> attributes, BusInstance *bus, WireInstance *wire, Connection connection); DirectConnectionInstance(ComponentInstance *instance, ComponentInstance *secondsInstance, std::vector<InstanceAttribute*> attributes, BusInstance *bus, Connection connection);
}; };

View File

@ -14,28 +14,21 @@ class Schema
public: public:
Schema(); Schema();
std::vector<Instance*> instances;
std::vector<ConnectionInstance*> connections;
std::vector<WireInstance*> wires;
WireInstance *getWire(std::string name) { std::vector<BusInstance> busInstances;
for(auto wire: wires) { std::vector<ComponentInstance> componentInstances;
if (wire->name == name) {
return wire; std::vector<ConnectionInstance> connections;
Instance *getInstance(std::string& name) {
for(auto& instance: busInstances) {
if (instance.name == name) {
return &instance;
} }
} }
return nullptr; for(auto& instance: componentInstances) {
} if (instance.name == name) {
return &instance;
bool hasWire(std::string name) {
return getWire(name) != NULL;
}
Instance *getInstance(std::string name) {
for(auto instance: instances) {
if (instance->name == name) {
return instance;
} }
} }
return nullptr; return nullptr;

View File

@ -1,6 +1,7 @@
#include "schemacreator.h" #include "schemacreator.h"
#include<set> #include<set>
#include <utility>
namespace domain { namespace domain {
@ -100,21 +101,21 @@ Popup::PopupType toType(PopupNode::PopupType type)
} }
SchemaCreator::SchemaCreator(std::vector<FunctionSignature> signatures) SchemaCreator::SchemaCreator(std::vector<FunctionSignature> signatures)
: signatures(signatures) : signatures(std::move(signatures))
{} {}
std::optional<Library> SchemaCreator::loadLibrary(LibraryNode node) std::optional<Library> SchemaCreator::loadLibrary(LibraryNode node)
{ {
// library fields // library fields
if(!node.name) { if(!node.name) {
errors.push_back(SourceError{node.span, "missing @name"}); errors.emplace_back(node.span, "missing @name");
return nullopt; return nullopt;
} else { } else {
name = node.name->asString(); name = node.name->asString();
} }
if(!node.componentDirectory) { if(!node.componentDirectory) {
errors.push_back(SourceError{node.span, "missing @componentDirectory"}); errors.emplace_back(node.span, "missing @componentDirectory");
return nullopt; return nullopt;
} else { } else {
componentDirectory = node.componentDirectory->asString(); componentDirectory = node.componentDirectory->asString();
@ -136,25 +137,25 @@ std::optional<Library> SchemaCreator::loadLibrary(LibraryNode node)
} }
} }
for(uint i=0; i<node.buses.size(); i++) { for(auto& buse : node.buses) {
auto bus = loadBus(node.buses[i]); auto bus = loadBus(buse);
if(bus) { if(bus) {
buses.push_back(*bus); buses.push_back(*bus);
} }
} }
for(uint i=0; i<node.connections.size(); i++) { for(auto& connection : node.connections) {
auto conn = loadConnection(node.connections[i]); auto conn = loadConnection(connection);
if(conn) { if(conn) {
connections.push_back(*conn); connections.push_back(*conn);
} }
} }
for(uint i=0; i<node.messages.size(); i++) { for(auto & message : node.messages) {
if(!node.messages[i].value.is(ValueNode::STRING)) { if(!message.value.is(ValueNode::STRING)) {
errors.push_back(SourceError{node.messages[i].value.span, "expected `string`"}); errors.emplace_back(message.value.span, "expected `string`");
} else { } else {
messages[node.messages[i].key.value] = node.messages[i].value.asString(); messages[message.key.value] = message.value.asString();
} }
} }
@ -170,24 +171,24 @@ std::optional<Bus> SchemaCreator::loadBus(BusNode node)
count = std::make_pair<int, int>(node.count->first.value, node.count->second.value); count = std::make_pair<int, int>(node.count->first.value, node.count->second.value);
} }
if(count.first > count.second || count.first < 0) { if(count.first > count.second || count.first < 0) {
errors.push_back(SourceError{node.count->span, "invalid @size"}); errors.emplace_back(node.count->span, "invalid @size");
return nullopt; return nullopt;
} }
auto type = toType(node.type.value); auto type = toType(node.type.value);
if(!node.tooltip && type == Bus::REGULAR) { if(!node.tooltip && type == Bus::REGULAR) {
errors.push_back(SourceError{node.span, "missing @tooltip"}); errors.emplace_back(node.span, "missing @tooltip");
return nullopt; return nullopt;
} }
std::string tooltip = node.tooltip->asString(); std::string tooltip = node.tooltip->asString();
if(!node.display && type == Bus::REGULAR) { if(!node.display && type == Bus::REGULAR) {
errors.push_back(SourceError{node.span, "missing @display"}); errors.emplace_back(node.span, "missing @display");
return nullopt; return nullopt;
} }
if(node.display && (type == Bus::AUTOMATIC || type == Bus::AUTOMATIC_SINGLE)) { if(node.display && (type == Bus::AUTOMATIC || type == Bus::AUTOMATIC_SINGLE)) {
errors.push_back(SourceError{node.span, "automatic bus cannot have a @display"}); errors.emplace_back(node.span, "automatic bus cannot have a @display");
return nullopt; return nullopt;
} }
@ -200,7 +201,7 @@ std::optional<Bus> SchemaCreator::loadBus(BusNode node)
} }
if(node.wires.size() == 0) { if(node.wires.size() == 0) {
errors.push_back(SourceError{node.span, "missing @wires"}); errors.emplace_back(node.span, "missing @wires");
return nullopt; return nullopt;
} }
std::vector<Wire> wires; std::vector<Wire> wires;
@ -379,14 +380,14 @@ std::optional<Component> SchemaCreator::loadComponent(ComponentNode node)
std::string name = node.name.value; std::string name = node.name.value;
if(!node.tooltip) { if(!node.tooltip) {
errors.push_back(SourceError{node.span, "missing @tooltip"}); errors.emplace_back(node.span, "missing @tooltip");
pop(); pop();
return nullopt; return nullopt;
} }
std::string tooltip = node.tooltip->asString(); std::string tooltip = node.tooltip->asString();
if(!node.source) { if(!node.source) {
errors.push_back(SourceError{node.span, "missing @source"}); errors.emplace_back(node.span, "missing @source");
pop(); pop();
return nullopt; return nullopt;
} }
@ -413,7 +414,7 @@ std::optional<Component> SchemaCreator::loadComponent(ComponentNode node)
} }
if(!node.instanceName) { if(!node.instanceName) {
errors.push_back(SourceError{node.span, "missing @instanceName"}); errors.emplace_back(node.span, "missing @instanceName");
pop(); pop();
return nullopt; return nullopt;
} }
@ -424,13 +425,13 @@ std::optional<Component> SchemaCreator::loadComponent(ComponentNode node)
count = std::make_pair<int, int>(node.count->first.value, node.count->second.value); count = std::make_pair<int, int>(node.count->first.value, node.count->second.value);
} }
if(count.first > count.second || count.first < 0) { if(count.first > count.second || count.first < 0) {
errors.push_back(SourceError{node.count->first.span, "invalid @size"}); errors.emplace_back(node.count->first.span, "invalid @size");
pop(); pop();
return nullopt; return nullopt;
} }
if(!node.display) { if(!node.display) {
errors.push_back(SourceError{node.span, "missing @display"}); errors.emplace_back(node.span, "missing @display");
pop(); pop();
return nullopt; return nullopt;
} }
@ -441,8 +442,8 @@ std::optional<Component> SchemaCreator::loadComponent(ComponentNode node)
} }
std::vector<Pin> pins; std::vector<Pin> pins;
for(uint i=0; i<node.pins.size(); i++) { for(auto &p : node.pins) {
auto pin = loadPin(node.pins[i]); auto pin = loadPin(p);
if(!pin) { if(!pin) {
pop(); pop();
return nullopt; return nullopt;
@ -471,13 +472,13 @@ optional<Pin> SchemaCreator::loadPin(PinNode node)
Pin::PinType type = toType(node.type.value); Pin::PinType type = toType(node.type.value);
if(!node.tooltip) { if(!node.tooltip) {
errors.push_back(SourceError{node.span, "missing @tooltip"}); errors.emplace_back(node.span, "missing @tooltip");
return nullopt; return nullopt;
} }
std::string tooltip = node.tooltip->asString(); std::string tooltip = node.tooltip->asString();
if(!node.display) { if(!node.display) {
errors.push_back(SourceError{node.span, "missing @display"}); errors.emplace_back(node.span, "missing @display");
return nullopt; return nullopt;
} }
std::vector<Attribute> attributes; std::vector<Attribute> attributes;
@ -487,7 +488,7 @@ optional<Pin> SchemaCreator::loadPin(PinNode node)
} }
if(!node.connection) { if(!node.connection) {
errors.push_back(SourceError{node.span, "missing @connection"}); errors.emplace_back(node.span, "missing @connection");
return nullopt; return nullopt;
} }
auto connection = loadPinConnection(*node.connection); auto connection = loadPinConnection(*node.connection);
@ -548,7 +549,7 @@ std::optional<Display> SchemaCreator::loadDisplay(DisplayNode node)
h = getIntProperty(item, "h"); h = getIntProperty(item, "h");
displayItem.pin = ui::Pin(x, y, w, h); displayItem.pin = ui::Pin(x, y, w, h);
} else { } else {
errors.push_back(SourceError{item.type.span, "unsupported display type"}); errors.emplace_back(item.type.span, "unsupported display type");
} }
items.push_back(displayItem); items.push_back(displayItem);
} }
@ -560,7 +561,7 @@ PinConnection SchemaCreator::loadPinConnection(PinConnectionNode node)
{ {
std::string message = node.message.asString(); std::string message = node.message.asString();
PinConnection::ConnectionType type = toType(node.type.value); PinConnection::ConnectionType type = toType(node.type.value);
return PinConnection(message, type); return {message, type};
} }
std::optional<Attribute> SchemaCreator::loadAttribute(AttributeNode node) std::optional<Attribute> SchemaCreator::loadAttribute(AttributeNode node)
@ -577,7 +578,7 @@ std::optional<Attribute> SchemaCreator::loadAttribute(AttributeNode node)
} else if (node.type == ValueNode::STRING) { } else if (node.type == ValueNode::STRING) {
value = Value::fromString(node.defaultValue->asString()); value = Value::fromString(node.defaultValue->asString());
} else { } else {
errors.push_back(SourceError{node.name.span, "unsupported type"}); errors.emplace_back(node.name.span, "unsupported type");
} }
} }
if(current().inConnection) { // TODO remove identifier if(current().inConnection) { // TODO remove identifier
@ -586,14 +587,14 @@ std::optional<Attribute> SchemaCreator::loadAttribute(AttributeNode node)
value = Value::fromReference(node.defaultValue->asIdentifier(), Value::WIRE_REFERENCE); value = Value::fromReference(node.defaultValue->asIdentifier(), Value::WIRE_REFERENCE);
} else { } else {
value = Value::fromReference("", Value::WIRE_REFERENCE); value = Value::fromReference("", Value::WIRE_REFERENCE);
errors.push_back(SourceError{node.span, "unknown identifier"}); errors.emplace_back(node.span, "unknown identifier");
} }
} else { } else {
errors.push_back(SourceError{node.name.span, "unsupported type"}); errors.emplace_back(node.name.span, "unsupported type");
} }
} }
current().attributes.push_back(Attribute(name, value)); current().attributes.emplace_back(name, value);
std::optional<Popup> popup; std::optional<Popup> popup;
if(node.popup) { if(node.popup) {
@ -611,16 +612,16 @@ std::optional<Popup> SchemaCreator::loadPopup(PopupNode node, std::string name,
pushAdditional(name); pushAdditional(name);
current().attributes.clear(); current().attributes.clear();
current().attributes.push_back(Attribute(name, Value::ofType(type))); current().attributes.emplace_back(name, Value::ofType(type));
if(!node.title) { if(!node.title) {
errors.push_back(SourceError{node.span, "missing @title"}); errors.emplace_back(node.span, "missing @title");
return nullopt; return nullopt;
} }
std::string title = node.title->asString(); std::string title = node.title->asString();
if(!node.text) { if(!node.text) {
errors.push_back(SourceError{node.span, "missing @text"}); errors.emplace_back(node.span, "missing @text");
return nullopt; return nullopt;
} }
std::string text = node.text->asString(); std::string text = node.text->asString();
@ -635,34 +636,34 @@ std::optional<Popup> SchemaCreator::loadPopup(PopupNode node, std::string name,
std::vector<Enumeration> enumeration; std::vector<Enumeration> enumeration;
if(node.enumerated) { if(node.enumerated) {
for(uint i=0; i<node.enumeration.size(); i++) { for(auto& enumNode : node.enumeration) {
if(type == Value::INT || type == Value::STRING || type == Value::BOOL) { if(type == Value::INT || type == Value::STRING || type == Value::BOOL) {
auto value = toType(node.enumeration[i].value); auto value = toType(enumNode.value);
if(value.getType() == type) { if(value.getType() == type) {
enumeration.push_back(Enumeration(node.enumeration[i].key.asString(), value)); enumeration.emplace_back(enumNode.key.asString(), value);
} else { } else {
errors.push_back(SourceError{node.enumeration[i].span, "wrong type"}); errors.emplace_back(enumNode.span, "wrong type");
} }
} else if(type == Value::WIRE_REFERENCE) { } else if(type == Value::WIRE_REFERENCE) {
auto value = toType(node.enumeration[i].value); auto value = toType(enumNode.value);
if(value.isType(Value::UNDEFINED)) { if(value.isType(Value::UNDEFINED)) {
if(current().doesWireExists(value.asReference())) { if(current().doesWireExists(value.asReference())) {
value = Value::fromReference(value.asReference(), Value::WIRE_REFERENCE); value = Value::fromReference(value.asReference(), Value::WIRE_REFERENCE);
} else { } else {
errors.push_back(SourceError{node.enumeration[i].span, "unknown wire"}); errors.emplace_back(enumNode.span, "unknown wire");
} }
} }
if(value.isType(Value::WIRE_REFERENCE) || value.isType(Value::INT) || value.isType(Value::NIL)) { if(value.isType(Value::WIRE_REFERENCE) || value.isType(Value::INT) || value.isType(Value::NIL)) {
enumeration.push_back(Enumeration(node.enumeration[i].key.asString(), value)); enumeration.emplace_back(enumNode.key.asString(), value);
} else { } else {
errors.push_back(SourceError{node.enumeration[i].span, "wrong type"}); errors.emplace_back(enumNode.span, "wrong type");
} }
} }
} }
} else { } else {
if(type == Value::WIRE_REFERENCE && !current().inConnection) { if(type == Value::WIRE_REFERENCE && !current().inConnection) {
errors.push_back(SourceError{node.span, "@enumeration is required for attributes of type wire"}); errors.emplace_back(node.span, "@enumeration is required for attributes of type wire");
} }
} }
@ -678,7 +679,7 @@ std::optional<Rule> SchemaCreator::loadRule(RuleNode node)
for(auto& stmt: node.statements) { for(auto& stmt: node.statements) {
auto condition = loadCondition(stmt.condition); auto condition = loadCondition(stmt.condition);
if(condition) { if(condition) {
statements.push_back(IfStatement(*condition, Action(toType(stmt.action.type.value), stmt.action.message.asString()))); statements.emplace_back(*condition, Action(toType(stmt.action.type.value), stmt.action.message.asString()));
} else { } else {
return nullopt; return nullopt;
} }
@ -691,19 +692,19 @@ std::optional<Condition> SchemaCreator::loadCondition(ConditionNode node)
{ {
std::string function = node.functionName.value; std::string function = node.functionName.value;
for(uint i=0; i<signatures.size(); i++) { for(auto & signature : signatures) {
if(signatures[i].name == function) { if(signature.name == function) {
if(signatures[i].params.size() == node.params.size()) { if(signature.params.size() == node.params.size()) {
std::vector<Value> params; std::vector<Value> params;
for(uint j=0; j<signatures[i].params.size(); j++) { for(uint j=0; j<signature.params.size(); j++) {
bool exists = false; bool exists = false;
auto type = toType(node.params[j]); auto type = toType(node.params[j]);
if (type.getType() == Value::UNDEFINED) { if (type.getType() == Value::UNDEFINED) {
if(current().doesAttributeExists(type.asReference(), signatures[i].params[j])) { if(current().doesAttributeExists(type.asReference(), signature.params[j])) {
exists = true; exists = true;
type = Value::fromReference(type.asReference(), Value::ATTRIBUTE_REFERENCE); type = Value::fromReference(type.asReference(), Value::ATTRIBUTE_REFERENCE);
} }
if(signatures[i].params[j] == Value::ADDRESS_SPACE) { if(signature.params[j] == Value::ADDRESS_SPACE) {
if(hasAddressSpace(type.asReference())) { if(hasAddressSpace(type.asReference())) {
exists = true; exists = true;
type = Value::fromReference(type.asReference(), Value::ADDRESS_SPACE_REFERENCE); type = Value::fromReference(type.asReference(), Value::ADDRESS_SPACE_REFERENCE);
@ -711,76 +712,69 @@ std::optional<Condition> SchemaCreator::loadCondition(ConditionNode node)
} }
if(!exists) { if(!exists) {
errors.push_back(SourceError{node.functionName.span, "unknown reference " + type.asReference()}); errors.emplace_back(node.functionName.span, "unknown reference " + type.asReference());
} }
} }
params.push_back(type); params.push_back(type);
} }
return Condition(function, params, node.negated); return Condition(function, params, node.negated);
} else { } else {
errors.push_back(SourceError{node.functionName.span, "wrong number of parameters"}); errors.emplace_back(node.functionName.span, "wrong number of parameters");
} }
} }
} }
errors.push_back(SourceError{node.functionName.span, "unknown function name"}); errors.emplace_back(node.functionName.span, "unknown function name");
return nullopt; return nullopt;
} }
Schema* SchemaCreator::loadSchema(SchemaNode node, Library &library) Schema* SchemaCreator::loadSchema(SchemaNode node, Library &library)
{ {
Schema *schema = new Schema(); auto *schema = new Schema();
for(auto &instance: node.instances) { for(auto &instance: node.instances) {
if(library.hasComponent(instance.component.value)) { if(library.hasComponent(instance.component.value)) {
schema->instances.push_back(loadComponentInstance(instance, library)); schema->componentInstances.push_back(loadComponentInstance(instance, library));
} }
if(library.hasBus(instance.component.value)) { if(library.hasBus(instance.component.value)) {
schema->instances.push_back(loadBusInstance(instance, library)); schema->busInstances.push_back(loadBusInstance(instance, library));
}
}
for(auto &wire: node.wires) {
auto w = loadWireInstance(wire);
if(w) {
schema->wires.push_back(*w);
} }
} }
for(auto &conn: node.connections) { for(auto &conn: node.connections) {
auto firstComponent = dynamic_cast<ComponentInstance*>(schema->getInstance(conn.first.instance.value)); auto firstComponent = dynamic_cast<ComponentInstance*>(schema->getInstance(conn.first.instance.value));
if(firstComponent == NULL) { if(firstComponent == nullptr) {
errors.push_back(SourceError{conn.first.instance.span, "unknown component"}); errors.emplace_back(conn.first.instance.span, "unknown component");
continue; continue;
} }
if(!firstComponent->component.hasPin(conn.first.pin.value)) { if(!firstComponent->component.hasPin(conn.first.pin.value)) {
errors.push_back(SourceError{conn.first.pin.span, "unknown pin"}); errors.emplace_back(conn.first.pin.span, "unknown pin");
continue; continue;
} }
ComponentInstance *secondComponent = NULL; ComponentInstance *secondComponent = nullptr;
if(conn.second.has_value()) { if(conn.second.has_value()) {
secondComponent = dynamic_cast<ComponentInstance*>(schema->getInstance(conn.second->instance.value)); secondComponent = dynamic_cast<ComponentInstance*>(schema->getInstance(conn.second->instance.value));
if(secondComponent == NULL) { if(secondComponent == nullptr) {
errors.push_back(SourceError{conn.second->instance.span, "unknown component"}); errors.emplace_back(conn.second->instance.span, "unknown component");
continue; continue;
} }
if(!secondComponent->component.hasPin(conn.second->pin.value)) { if(!secondComponent->component.hasPin(conn.second->pin.value)) {
errors.push_back(SourceError{conn.second->pin.span, "unknown pin"}); errors.emplace_back(conn.second->pin.span, "unknown pin");
continue; 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 == nullptr) {
errors.push_back(SourceError{conn.bus.span, "unknown bus"}); errors.emplace_back(conn.bus.span, "unknown bus");
continue; continue;
} }
std::optional<Connection> connection = std::nullopt; std::optional<Connection> connection = std::nullopt;
if(secondComponent != NULL) { if(secondComponent != nullptr) {
ConnectionComponent firstConn{firstComponent->component.getName(), conn.first.pin.value}; ConnectionComponent firstConn{firstComponent->component.getName(), conn.first.pin.value};
ConnectionComponent secondConn{secondComponent->component.getName(), conn.second->pin.value}; ConnectionComponent secondConn{secondComponent->component.getName(), conn.second->pin.value};
@ -789,7 +783,7 @@ Schema* SchemaCreator::loadSchema(SchemaNode node, Library &library)
secondConn)) { secondConn)) {
connection = *library.getConnection(firstConn, bus->bus.getName(), secondConn); connection = *library.getConnection(firstConn, bus->bus.getName(), secondConn);
} else { } else {
errors.push_back(SourceError{conn.span, "unknown connection"}); errors.emplace_back(conn.span, "unknown connection");
continue; continue;
} }
} else { } else {
@ -799,21 +793,15 @@ Schema* SchemaCreator::loadSchema(SchemaNode node, Library &library)
bus->bus.getName())) { bus->bus.getName())) {
connection = *library.getConnection(firstConn, bus->bus.getName()); connection = *library.getConnection(firstConn, bus->bus.getName());
} else { } else {
errors.push_back(SourceError{conn.span, "unknown connection"}); errors.emplace_back(conn.span, "unknown connection");
continue; continue;
} }
} }
if(!conn.wire) { if(!conn.wire) {
errors.push_back(SourceError{conn.span, "missing @wire"}); errors.emplace_back(conn.span, "missing @wire");
continue; continue;
} }
if(!schema->hasWire(conn.wire->value)) {
errors.push_back(SourceError{conn.wire->span, "unknown wire"});
continue;
}
auto wire = schema->getWire(conn.wire->value);
std::vector<InstanceAttribute*> attributes; std::vector<InstanceAttribute*> attributes;
for(auto& attr: conn.attributes) { for(auto& attr: conn.attributes) {
@ -827,26 +815,26 @@ Schema* SchemaCreator::loadSchema(SchemaNode node, Library &library)
} }
} }
if(value.isType(Value::UNDEFINED)) { if(value.isType(Value::UNDEFINED)) {
errors.push_back(SourceError{attr.span, "invalid value"}); errors.emplace_back(attr.span, "invalid value");
} }
attributes.push_back(new InstanceAttribute(attribute.getName(), toType(attr.value), attribute)); attributes.push_back(new InstanceAttribute(attribute.getName(), toType(attr.value), attribute));
} else { } else {
errors.push_back(SourceError(attr.name.span, "unknown attribute")); errors.emplace_back(attr.name.span, "unknown attribute");
} }
} }
if(secondComponent == NULL) { if(secondComponent == nullptr) {
schema->connections.push_back(new BusConnectionInstance(firstComponent, attributes, bus, wire, *connection)); schema->connections.push_back(BusConnectionInstance(firstComponent, attributes, bus, *connection));
} else { } else {
schema->connections.push_back(new DirectConnectionInstance(firstComponent, secondComponent, attributes, bus, wire, *connection)); schema->connections.push_back(DirectConnectionInstance(firstComponent, secondComponent, attributes, bus, *connection));
} }
} }
return schema; return schema;
} }
ComponentInstance *SchemaCreator::loadComponentInstance(InstanceNode instance, Library &library) { ComponentInstance SchemaCreator::loadComponentInstance(InstanceNode instance, Library &library) {
auto name = instance.name.value; auto name = instance.name.value;
auto position = std::make_pair(instance.position->first.value, instance.position->second.value); auto position = std::make_pair(instance.position->first.value, instance.position->second.value);
@ -858,15 +846,15 @@ ComponentInstance *SchemaCreator::loadComponentInstance(InstanceNode instance, L
for(auto& attr: instance.attributes) { for(auto& attr: instance.attributes) {
if(component.hasAttribute(attr.name.value, toType(attr.value.getType()))) { if(component.hasAttribute(attr.name.value, toType(attr.value.getType()))) {
auto attribute = component.getAttribute(attr.name.value); auto attribute = component.getAttribute(attr.name.value);
attributes.push_back(new InstanceAttribute(attribute.getName(), toType(attr.value), attribute)); attributes.emplace_back(new InstanceAttribute(attribute.getName(), toType(attr.value), attribute));
} else { } else {
errors.push_back(SourceError(attr.name.span, "unknown attribute")); errors.emplace_back(SourceError(attr.name.span, "unknown attribute"));
} }
} }
return new ComponentInstance(name, attributes, position, component); return {name, attributes, position, component};
} }
BusInstance *SchemaCreator::loadBusInstance(InstanceNode instance, Library &library) { BusInstance SchemaCreator::loadBusInstance(InstanceNode instance, Library &library) {
auto name = instance.name.value; auto name = instance.name.value;
auto position = std::make_pair(instance.position->first.value, instance.position->second.value); auto position = std::make_pair(instance.position->first.value, instance.position->second.value);
@ -878,25 +866,7 @@ BusInstance *SchemaCreator::loadBusInstance(InstanceNode instance, Library &libr
size = instance.size->value; size = instance.size->value;
} }
return new BusInstance(name, position, bus, size); return {name, position, bus, static_cast<int>(size)};
} }
std::optional<WireInstance*> SchemaCreator::loadWireInstance(WireInstanceNode node) {
if(!node.display) {
errors.push_back(SourceError{node.span, "missing @text"});
return nullopt;
}
auto display = loadDisplay(*node.display);
if(!display) {
return nullopt;
}
std::pair<int, int> position = std::make_pair(0, 0);
if(node.position) {
position = std::make_pair(node.position->first.value, node.position->second.value);
}
return std::optional<WireInstance*>(new WireInstance(node.name.value, *display, position));
}
} // namespace domain } // namespace domain

View File

@ -75,9 +75,8 @@ class SchemaCreator
std::optional<Connection> loadConnection(ConnectionNode node); std::optional<Connection> loadConnection(ConnectionNode node);
std::optional<Bus> loadBus(BusNode node); std::optional<Bus> loadBus(BusNode node);
ComponentInstance *loadComponentInstance(InstanceNode instance, Library &library); ComponentInstance loadComponentInstance(InstanceNode instance, Library &library);
BusInstance *loadBusInstance(InstanceNode instance, Library &library); BusInstance loadBusInstance(InstanceNode instance, Library &library);
std::optional<WireInstance*> loadWireInstance(WireInstanceNode node);
std::optional<Bus> getBus(std::string name) { std::optional<Bus> getBus(std::string name) {
for(auto &bus: buses) { for(auto &bus: buses) {

View File

@ -156,40 +156,28 @@ void MainWindow::onStoreScheme() {
buffer << "@schema {" << std::endl; buffer << "@schema {" << std::endl;
for(auto &instance: schema->instances) { for(auto &componentInstance: schema->componentInstances) {
auto componentInstance = dynamic_cast<domain::ComponentInstance*>(instance); buffer << "\t" << "@instance " << componentInstance.name << " " << componentInstance.component.getName() << " {" << std::endl;
if(componentInstance != nullptr) { buffer << "\t\t" << "@position (" << componentInstance.position.first << ", " << componentInstance.position.second << ")" << std::endl;
buffer << "\t" << "@instance " << componentInstance->name << " " << componentInstance->component.getName() << " {" << std::endl;
buffer << "\t\t" << "@position (" << componentInstance->position.first << ", " << componentInstance->position.second << ")" << std::endl;
for(auto &attribute: instance->attributes) { for(auto &attribute: componentInstance.attributes) {
buffer << "\t\t" << "@attribute " << attribute->name << " " << attribute->value.stringify() << std::endl; buffer << "\t\t" << "@attribute " << attribute->name << " " << attribute->value.stringify() << std::endl;
} }
buffer << "\t}" << std::endl << std::endl; buffer << "\t}" << std::endl << std::endl;
} }
auto busInstance = dynamic_cast<domain::BusInstance*>(instance); for(auto &busInstance: schema->busInstances) {
if(busInstance != nullptr) { buffer << "\t" << "@instance " << busInstance.name << " " << busInstance.bus.getName() << " {" << std::endl;
buffer << "\t" << "@instance " << busInstance->name << " " << busInstance->bus.getName() << " {" << std::endl; buffer << "\t\t" << "@position (" << busInstance.position.first << ", " << busInstance.position.second << ")" << std::endl;
buffer << "\t\t" << "@position (" << busInstance->position.first << ", " << busInstance->position.second << ")" << std::endl; buffer << "\t\t" << "@size " << busInstance.size << std::endl;
buffer << "\t\t" << "@size " << busInstance->size << std::endl;
buffer << "\t}" << std::endl << std::endl; buffer << "\t}" << std::endl << std::endl;
} }
}
for(auto &wire: schema->wires) {
buffer << "\t" << "@wire " << wire->name << " {" << std::endl;
buffer << "\t\t" << "@position (" << wire->position.first << ", " << wire->position.second << ")" << std::endl;
buffer << "\t\t" << "@display {}" << std::endl;
buffer << "\t" << "}" << std::endl;
}
for(auto &conn: schema->connections) { for(auto &conn: schema->connections) {
auto busConn = dynamic_cast<domain::BusConnectionInstance*>(conn); auto busConn = dynamic_cast<domain::BusConnectionInstance*>(&conn);
if(busConn) { if(busConn) {
buffer << "\t" << "@connection (" << busConn->instance->name << "." << busConn->connection.getComponent().pin << ", " << busConn->bus->name << ") {" << std::endl; buffer << "\t" << "@connection (" << busConn->instance->name << "." << busConn->connection.getComponent().pin << ", " << busConn->bus->name << ") {" << std::endl;
buffer << "\t\t"<< "@wire " << busConn->wire->name << std::endl;
buffer << "\t" << "}" << std::endl; buffer << "\t" << "}" << std::endl;
} }
} }