Added single automatic connection dialog + bugfixes
This commit is contained in:
parent
3172d7e4cf
commit
9b7ede933a
|
@ -37,5 +37,5 @@ add_executable(SchemeEditor
|
||||||
comdel/parser/comdellexer.cpp
|
comdel/parser/comdellexer.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
mainwindow.ui
|
mainwindow.ui
|
||||||
comdel/domain/comdel_validator.cpp comdel/domain/comdel_validator.h comdel/display/attribute_dialog.cpp comdel/display/attribute_dialog.h comdel/display/name_dialog.cpp comdel/display/name_dialog.h comdel/domain/comdel_generator.cpp comdel/domain/comdel_generator.h comdel/display/library_list.cpp comdel/display/library_list.h application.cpp application.h)
|
comdel/domain/comdel_validator.cpp comdel/domain/comdel_validator.h comdel/display/attribute_dialog.cpp comdel/display/attribute_dialog.h comdel/display/name_dialog.cpp comdel/display/name_dialog.h comdel/domain/comdel_generator.cpp comdel/domain/comdel_generator.h comdel/display/library_list.cpp comdel/display/library_list.h application.cpp application.h comdel/display/single_automatic_dialog.cpp comdel/display/single_automatic_dialog.h)
|
||||||
target_link_libraries(SchemeEditor Qt5::Core Qt5::Gui Qt5::Widgets)
|
target_link_libraries(SchemeEditor Qt5::Core Qt5::Gui Qt5::Widgets)
|
||||||
|
|
|
@ -157,7 +157,7 @@ std::vector<domain::ValidationError> Application::validateSchema() {
|
||||||
std::vector<domain::ValidationError> Application::generateComdel(std::ostringstream &output) {
|
std::vector<domain::ValidationError> Application::generateComdel(std::ostringstream &output) {
|
||||||
|
|
||||||
auto errors = validateSchema();
|
auto errors = validateSchema();
|
||||||
if (Application::hasErrors(errors)) {
|
if (!Application::hasErrors(errors)) {
|
||||||
// as long as all validation errors are warning we continue with build
|
// as long as all validation errors are warning we continue with build
|
||||||
domain::generate_comdel(schema, library.value(), output);
|
domain::generate_comdel(schema, library.value(), output);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "schema_display.h"
|
#include "schema_display.h"
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "attribute_dialog.h"
|
#include "attribute_dialog.h"
|
||||||
|
#include "single_automatic_dialog.h"
|
||||||
|
|
||||||
#include <QDrag>
|
#include <QDrag>
|
||||||
#include <QDragEnterEvent>
|
#include <QDragEnterEvent>
|
||||||
|
@ -87,27 +88,9 @@ namespace display {
|
||||||
if (event->mimeData()->hasFormat("comdel/component")) {
|
if (event->mimeData()->hasFormat("comdel/component")) {
|
||||||
auto component = library->getComponent(event->mimeData()->data("comdel/component").toStdString());
|
auto component = library->getComponent(event->mimeData()->data("comdel/component").toStdString());
|
||||||
|
|
||||||
auto attributes = std::vector<domain::InstanceAttribute>();
|
auto attributes = populateAttributes(component.getAttributes());
|
||||||
for (auto attr: component.getAttributes()) {
|
if(attributes.size() != component.getAttributes().size()) {
|
||||||
domain::InstanceAttribute attribute(attr.getName(), attr.getDefault(), attr);
|
return;
|
||||||
if(attr.getPopup().has_value() && attr.getPopup()->getType() == domain::Popup::AUTOMATIC) {
|
|
||||||
if(attr.getDefault().isType(domain::Value::MEMORY_REFERENCE)) {
|
|
||||||
auto dialog = new MemoryDialog(&attribute, schema->componentInstances);
|
|
||||||
if(dialog->exec() == QDialog::Rejected) {
|
|
||||||
// if any dialog isn't set, whole creation is rejected
|
|
||||||
event->ignore();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
auto dialog = new AttributeDialog(&attribute);
|
|
||||||
if(dialog->exec() == QDialog::Rejected) {
|
|
||||||
// if any dialog isn't set, whole creation is rejected
|
|
||||||
event->ignore();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
attributes.push_back(attribute);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto currentPos = this->mapToScene(event->pos()).toPoint();
|
auto currentPos = this->mapToScene(event->pos()).toPoint();
|
||||||
|
@ -152,15 +135,18 @@ namespace display {
|
||||||
auto busInstances = getAvailableConnectionBusses(instance, pin);
|
auto busInstances = getAvailableConnectionBusses(instance, pin);
|
||||||
|
|
||||||
for (auto &bus: busInstances) {
|
for (auto &bus: busInstances) {
|
||||||
|
if(buses[bus->name] == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
auto rect = buses[bus->name]->boundingRect();
|
auto rect = buses[bus->name]->boundingRect();
|
||||||
rect = QRectF(buses[bus->name]->x(), buses[bus->name]->y(), rect.width(), rect.height());
|
rect = QRectF(buses[bus->name]->x(), buses[bus->name]->y(), rect.width(), rect.height());
|
||||||
|
|
||||||
if (rect.contains(endPoint)) {
|
if (rect.contains(endPoint)) {
|
||||||
auto con = library->getConnection({instance->component.getName(), pin.getName()}, bus->bus.getName());
|
auto con = library->getConnection({instance->component.getName(), pin.getName()}, bus->bus.getName());
|
||||||
if (con.has_value()) {
|
if (con.has_value()) {
|
||||||
std::vector<domain::InstanceAttribute> attributes;
|
auto attributes = populateAttributes(con->getAttributes());
|
||||||
for (auto attr: con->getAttributes()) {
|
if(attributes.size() != con->getAttributes().size()) {
|
||||||
attributes.emplace_back(attr.getName(), attr.getDefault(), attr);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto conInstance = std::make_shared<domain::BusConnectionInstance>(instance, attributes, bus, *con);
|
auto conInstance = std::make_shared<domain::BusConnectionInstance>(instance, attributes, bus, *con);
|
||||||
|
@ -189,13 +175,16 @@ namespace display {
|
||||||
auto con = library->getConnection({instance->component.getName(), pin.getName()},
|
auto con = library->getConnection({instance->component.getName(), pin.getName()},
|
||||||
{name, pinInstance.pin});
|
{name, pinInstance.pin});
|
||||||
if (con.has_value()) {
|
if (con.has_value()) {
|
||||||
auto bus = library->getBus(con->getBus());
|
auto busInstance = Application::instance()->addBus(library->getBus(con->getBus()), 0, 0);
|
||||||
auto busInstance = std::make_shared<domain::BusInstance>(bus.getName(), bus);
|
|
||||||
schema->busInstances.push_back(busInstance);
|
|
||||||
|
|
||||||
std::vector<domain::InstanceAttribute> attributes;
|
std::vector<domain::InstanceAttribute> attributes;
|
||||||
for (auto attr: con->getAttributes()) {
|
if(library->getBus(con->getBus()).getType() == domain::Bus::SINGLE_AUTOMATIC) {
|
||||||
attributes.emplace_back(attr.getName(), attr.getDefault(), attr);
|
attributes = populateSingleAutomaticConnection(*con);
|
||||||
|
} else {
|
||||||
|
attributes = populateAttributes(con->getAttributes());
|
||||||
|
}
|
||||||
|
if(attributes.size() != con->getAttributes().size()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto conInstance = std::make_shared<domain::DirectConnectionInstance>(instance,
|
auto conInstance = std::make_shared<domain::DirectConnectionInstance>(instance,
|
||||||
|
@ -294,4 +283,46 @@ namespace display {
|
||||||
return instances;
|
return instances;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<domain::InstanceAttribute> Schema::populateAttributes(std::vector<domain::Attribute>& attributes) {
|
||||||
|
std::vector<domain::InstanceAttribute> instanceAttributes;
|
||||||
|
|
||||||
|
for (auto attr: attributes) {
|
||||||
|
domain::InstanceAttribute attribute(attr.getName(), attr.getDefault(), attr);
|
||||||
|
if(attr.getPopup().has_value() && attr.getPopup()->getType() == domain::Popup::AUTOMATIC) {
|
||||||
|
if(attr.getDefault().isType(domain::Value::MEMORY_REFERENCE)) {
|
||||||
|
auto dialog = new MemoryDialog(&attribute, schema->componentInstances);
|
||||||
|
if(dialog->exec() == QDialog::Rejected) {
|
||||||
|
// if any dialog isn't set, whole creation is rejected
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto dialog = new AttributeDialog(&attribute);
|
||||||
|
if(dialog->exec() == QDialog::Rejected) {
|
||||||
|
// if any dialog isn't set, whole creation is rejected
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
instanceAttributes.push_back(attribute);
|
||||||
|
}
|
||||||
|
return instanceAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<domain::InstanceAttribute> Schema::populateSingleAutomaticConnection(domain::Connection connection) {
|
||||||
|
std::vector<domain::InstanceAttribute> instanceAttributes;
|
||||||
|
|
||||||
|
for (auto attr: connection.getAttributes()) {
|
||||||
|
instanceAttributes.emplace_back(attr.getName(), attr.getDefault(), attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dialog = new display::SingleAutomaticDialog(instanceAttributes);
|
||||||
|
if(dialog->exec() == QDialog::Rejected) {
|
||||||
|
// if dialog is rejected, whole creation is rejected
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return instanceAttributes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace display
|
} // namespace display
|
||||||
|
|
|
@ -73,6 +73,10 @@ namespace display {
|
||||||
|
|
||||||
std::vector<domain::ConnectionComponent>
|
std::vector<domain::ConnectionComponent>
|
||||||
getAvailableConnectionPins(domain::ComponentInstance *instance, domain::Pin &pin);
|
getAvailableConnectionPins(domain::ComponentInstance *instance, domain::Pin &pin);
|
||||||
|
|
||||||
|
std::vector<domain::InstanceAttribute> populateAttributes(std::vector<domain::Attribute>& attributes);
|
||||||
|
|
||||||
|
std::vector<domain::InstanceAttribute> populateSingleAutomaticConnection(domain::Connection connection);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace display
|
} // namespace display
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
//
|
||||||
|
// Created by bbr on 05.06.22..
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "single_automatic_dialog.h"
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
namespace display {
|
||||||
|
SingleAutomaticDialog::SingleAutomaticDialog(std::vector<domain::InstanceAttribute> &values): attributes(values) {
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
setWindowTitle(QString::fromStdString("Postavi poveznicu"));
|
||||||
|
|
||||||
|
firstValue = values[0].value;
|
||||||
|
secondValue = values[1].value;
|
||||||
|
|
||||||
|
auto *parentLayout = new QVBoxLayout(this);
|
||||||
|
auto *contentLayout = new QHBoxLayout(this);
|
||||||
|
auto *firstLayout = new QVBoxLayout(this);
|
||||||
|
auto *secondLayout = new QVBoxLayout(this);
|
||||||
|
|
||||||
|
parentLayout->addLayout(contentLayout);
|
||||||
|
contentLayout->addLayout(firstLayout);
|
||||||
|
contentLayout->addLayout(secondLayout);
|
||||||
|
this->setLayout(parentLayout);
|
||||||
|
|
||||||
|
setupValues(firstLayout, values[0], &SingleAutomaticDialog::onFirstEnumerationChanged);
|
||||||
|
setupValues(secondLayout, values[1], &SingleAutomaticDialog::onSecondEnumerationChanged);
|
||||||
|
|
||||||
|
auto button = new QPushButton("Ažuriraj");
|
||||||
|
connect(button, &QPushButton::clicked, this, &SingleAutomaticDialog::onUpdate);
|
||||||
|
parentLayout->addWidget(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleAutomaticDialog::setupValues(QVBoxLayout *layout, domain::InstanceAttribute &attribute, void (display::SingleAutomaticDialog::* handler)(int)) {
|
||||||
|
|
||||||
|
auto popup = *attribute.attribute.getPopup();
|
||||||
|
|
||||||
|
layout->addWidget(new QLabel(popup.getTitle().c_str()));
|
||||||
|
layout->addWidget(new QLabel(popup.getText().c_str()));
|
||||||
|
|
||||||
|
auto *combo = new QComboBox(this);
|
||||||
|
auto enumeration = attribute.attribute.getPopup()->getEnumeration();
|
||||||
|
for (auto entry: enumeration) {
|
||||||
|
combo->addItem(QString::fromStdString(entry.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this,handler);
|
||||||
|
layout->addWidget(combo);
|
||||||
|
|
||||||
|
for (int i = 0; i < enumeration.size(); i++) {
|
||||||
|
if (attribute.value.equals(enumeration[i].getValue())) {
|
||||||
|
combo->setCurrentIndex(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleAutomaticDialog::onFirstEnumerationChanged(int index) {
|
||||||
|
firstValue = attributes[0].attribute.getPopup()->getEnumeration()[index].getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleAutomaticDialog::onSecondEnumerationChanged(int index) {
|
||||||
|
secondValue = attributes[1].attribute.getPopup()->getEnumeration()[index].getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleAutomaticDialog::onUpdate() {
|
||||||
|
attributes[0].value = firstValue;
|
||||||
|
attributes[1].value = secondValue;
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // display
|
|
@ -0,0 +1,35 @@
|
||||||
|
//
|
||||||
|
// Created by bbr on 05.06.22..
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SCHEMEEDITOR_SINGLE_AUTOMATIC_DIALOG_H
|
||||||
|
#define SCHEMEEDITOR_SINGLE_AUTOMATIC_DIALOG_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include "comdel/domain/value.h"
|
||||||
|
#include "comdel/domain/instance_attribute.h"
|
||||||
|
|
||||||
|
namespace display {
|
||||||
|
|
||||||
|
class SingleAutomaticDialog: public QDialog {
|
||||||
|
domain::Value firstValue;
|
||||||
|
domain::Value secondValue;
|
||||||
|
std::vector<domain::InstanceAttribute> &attributes;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SingleAutomaticDialog(std::vector<domain::InstanceAttribute>& values);
|
||||||
|
|
||||||
|
void setupValues(QVBoxLayout *layout, domain::InstanceAttribute &attribute, void (display::SingleAutomaticDialog::* handler)(int));
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void onFirstEnumerationChanged(int index);
|
||||||
|
void onSecondEnumerationChanged(int index);
|
||||||
|
void onUpdate();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // display
|
||||||
|
|
||||||
|
#endif //SCHEMEEDITOR_SINGLE_AUTOMATIC_DIALOG_H
|
|
@ -59,4 +59,8 @@ namespace domain {
|
||||||
return popup;
|
return popup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Attribute::setPupup(std::optional<Popup> popup) {
|
||||||
|
this->popup = popup;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace domain {
|
||||||
|
|
||||||
void setEnumeration(std::vector<Enumeration> enums) {
|
void setEnumeration(std::vector<Enumeration> enums) {
|
||||||
enumerated = true;
|
enumerated = true;
|
||||||
enumeration = std::move(enums);
|
enumeration = enums;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -71,6 +71,7 @@ namespace domain {
|
||||||
Value getDefault();
|
Value getDefault();
|
||||||
|
|
||||||
std::optional<Popup> getPopup();
|
std::optional<Popup> getPopup();
|
||||||
|
void setPupup(std::optional<Popup> popup);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -62,7 +62,7 @@ namespace domain {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Attribute> Component::getAttributes() {
|
std::vector<Attribute>& Component::getAttributes() {
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace domain {
|
||||||
|
|
||||||
Pin getPin(std::string pin);
|
Pin getPin(std::string pin);
|
||||||
|
|
||||||
std::vector<Attribute> getAttributes();
|
std::vector<Attribute>& getAttributes();
|
||||||
|
|
||||||
Attribute getAttribute(std::string attribute);
|
Attribute getAttribute(std::string attribute);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace domain {
|
||||||
return bus;
|
return bus;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Attribute> Connection::getAttributes() {
|
std::vector<Attribute>& Connection::getAttributes() {
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace domain {
|
||||||
|
|
||||||
std::string getBus();
|
std::string getBus();
|
||||||
|
|
||||||
std::vector<Attribute> getAttributes();
|
std::vector<Attribute>& getAttributes();
|
||||||
|
|
||||||
std::vector<Value> getWires();
|
std::vector<Value> getWires();
|
||||||
|
|
||||||
|
|
|
@ -438,7 +438,9 @@ namespace domain {
|
||||||
} else if (attributes[0].getDefault().getType() != Value::STRING) {
|
} else if (attributes[0].getDefault().getType() != Value::STRING) {
|
||||||
errors.emplace_back(node.attributes[0].span, "@attribute must be of type string");
|
errors.emplace_back(node.attributes[0].span, "@attribute must be of type string");
|
||||||
} else {
|
} else {
|
||||||
attributes[0].getPopup()->setEnumeration(createWireEnumeration(firstWires));
|
domain::Popup popup = *attributes[0].getPopup();
|
||||||
|
popup.setEnumeration(createWireEnumeration(firstWires));
|
||||||
|
attributes[0].setPupup(popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!attributes[1].getPopup().has_value()) {
|
if (!attributes[1].getPopup().has_value()) {
|
||||||
|
@ -446,7 +448,9 @@ namespace domain {
|
||||||
} else if (attributes[1].getDefault().getType() != Value::STRING) {
|
} else if (attributes[1].getDefault().getType() != Value::STRING) {
|
||||||
errors.emplace_back(node.attributes[1].span, "@attribute must be of type string");
|
errors.emplace_back(node.attributes[1].span, "@attribute must be of type string");
|
||||||
} else {
|
} else {
|
||||||
attributes[1].getPopup()->setEnumeration(createWireEnumeration(secondWires));
|
domain::Popup popup = *attributes[1].getPopup();
|
||||||
|
popup.setEnumeration(createWireEnumeration(secondWires));
|
||||||
|
attributes[1].setPupup(popup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,12 +939,22 @@ namespace domain {
|
||||||
auto attribute = connection->getAttribute(attr.name.value);
|
auto attribute = connection->getAttribute(attr.name.value);
|
||||||
auto value = toType(attr.value);
|
auto value = toType(attr.value);
|
||||||
|
|
||||||
|
bool valueFound = false;
|
||||||
|
|
||||||
|
// all connection attributes must be of type enumeration
|
||||||
for (auto &en: attribute.getPopup()->getEnumeration()) {
|
for (auto &en: attribute.getPopup()->getEnumeration()) {
|
||||||
if (en.getValue().asReference() == value.asReference()) {
|
if (en.getValue().equals(value)) {
|
||||||
value = Value::fromReference(value.asReference(), Value::WIRE_REFERENCE);
|
valueFound = true;
|
||||||
|
break;
|
||||||
|
} else if(value.isType(Value::UNDEFINED)) {
|
||||||
|
if(en.getValue().isType(Value::WIRE_REFERENCE) && en.getValue().asReference() == value.asReference()) {
|
||||||
|
value = Value::fromReference(value.asReference(), Value::WIRE_REFERENCE);
|
||||||
|
valueFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (value.isType(Value::UNDEFINED)) {
|
if (!valueFound) {
|
||||||
errors.emplace_back(attr.span, "invalid value");
|
errors.emplace_back(attr.span, "invalid value");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,12 +50,11 @@ bool ComdelParser::consume(TokenType tokenType) {
|
||||||
do{}while(0)
|
do{}while(0)
|
||||||
|
|
||||||
void ComdelParser::bump() {
|
void ComdelParser::bump() {
|
||||||
if (tokens[position].type == TokenType::END_OF_FILE) {
|
if (tokens[position].type != TokenType::END_OF_FILE) {
|
||||||
ATLAS_ASSERT_FAIL("Internal parser error, called bump after EOF");
|
++position;
|
||||||
} else {
|
} else {
|
||||||
tokens[++position];
|
ATLAS_ASSERT_FAIL("Internal parser error, called bump after EOF");
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedTokens.clear();
|
expectedTokens.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1348,7 +1347,7 @@ PResult<ValueNode> ComdelParser::parseConnectionWire() {
|
||||||
bump();
|
bump();
|
||||||
return spanner(ValueNode::ofNull());
|
return spanner(ValueNode::ofNull());
|
||||||
} else if (check(TokenType::STRING)) {
|
} else if (check(TokenType::STRING)) {
|
||||||
return spanner(ValueNode::ofString(parseString()->value));
|
return spanner(ValueNode::ofString(parseString()->asString()));
|
||||||
} else if (check(TokenType::IDENTIFIER)) {
|
} else if (check(TokenType::IDENTIFIER)) {
|
||||||
return spanner(ValueNode::ofIdentifier(parseIdentifier()->value));
|
return spanner(ValueNode::ofIdentifier(parseIdentifier()->value));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
// Version 0.0.1
|
|
||||||
#include "libraries\frisc\vjezba1\FRISC.cdl"
|
|
||||||
#include "libraries\frisc\vjezba1\memory.cdl"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
component System
|
|
||||||
{
|
|
||||||
clock 100MHz;
|
|
||||||
//bus
|
|
||||||
wire<32> ADR;
|
|
||||||
wire<32> DATA;
|
|
||||||
wire READ;
|
|
||||||
wire WRITE;
|
|
||||||
wired_and WAIT;
|
|
||||||
wired_and INT0;
|
|
||||||
wired_and INT1;
|
|
||||||
wired_and INT2;
|
|
||||||
wired_and INT3;
|
|
||||||
wire<3> SIZE;
|
|
||||||
wire --IACK;
|
|
||||||
wire --BREQ;
|
|
||||||
wire --BACK;
|
|
||||||
|
|
||||||
|
|
||||||
// components --------------------------------------------
|
|
||||||
subcomponent Memorija mem<false, 1, 1024, 8, 1024>(ADR, DATA, READ, WRITE, SIZE, WAIT, 94534054858378, 0, null, null);
|
|
||||||
subcomponent FRISC procesor_002(ADR, DATA, READ, WRITE, SIZE, WAIT, INT0, INT1, INT2, INT3, --IACK, 1, *, 94534054858378, 0, null, null);
|
|
||||||
subcomponent FRISC procesor_001(ADR, DATA, READ, WRITE, SIZE, WAIT, INT0, INT1, INT2, INT3, --IACK, 1, *, 94534054858378, 0, null, null);
|
|
||||||
subcomponent FRISC procesor_000(ADR, DATA, READ, WRITE, SIZE, WAIT, INT0, INT1, INT2, INT3, --IACK, 1, *, 94534054858378, 0, null, null);
|
|
||||||
subcomponent FRISC procesor(ADR, DATA, READ, WRITE, SIZE, WAIT, INT0, INT1, INT2, INT3, --IACK, 1, *, 94534054858378, 0, null, null);
|
|
||||||
|
|
||||||
display {
|
|
||||||
component { x: 0; y: 0; ref: "procesor_002"; }
|
|
||||||
component { x: 0; y: 250; ref: "mem"; }
|
|
||||||
component { x: -89; y: 74; ref: "procesor_001"; }
|
|
||||||
component { x: -175; y: 195; ref: "procesor_000"; }
|
|
||||||
component { x: -195; y: 63; ref: "procesor"; }
|
|
||||||
|
|
||||||
// bus bus
|
|
||||||
|
|
||||||
rectangle {
|
|
||||||
x: 0; y: 200;
|
|
||||||
w: 100; h: 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
line {x1:50; y1:116; x2:50; y2:210;}
|
|
||||||
line {x1:50; y1:234; x2:50; y2:210;}
|
|
||||||
line {x1:-39; y1:190; x2:50; y2:210;}
|
|
||||||
line {x1:-145; y1:179; x2:50; y2:210;}
|
|
||||||
line {x1:-125; y1:311; x2:50; y2:210;}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,13 +8,12 @@
|
||||||
@address pomocniAS(0xFFFF0000,0xFFFFFFFF)
|
@address pomocniAS(0xFFFF0000,0xFFFFFFFF)
|
||||||
|
|
||||||
@messages {
|
@messages {
|
||||||
Ok: "OK";
|
ok: "OK";
|
||||||
Yes: "Da";
|
yes: "Da";
|
||||||
No: "Ne";
|
no: "Ne";
|
||||||
Cancel: "Otkaži";
|
cancel: "Odustani";
|
||||||
noneBusLine: "nespojen";
|
noneBusLine: "nespojen";
|
||||||
noneValue: "nema vrijednosti";
|
noneValue: "nema vrijednosti";
|
||||||
generalPinNotConnected: "Opći pin nije spojen niti na jednu sabirnicu";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@component FRISC processor {
|
@component FRISC processor {
|
||||||
|
@ -229,7 +228,7 @@
|
||||||
@title "Početna adresa DMA-kontrolera"
|
@title "Početna adresa DMA-kontrolera"
|
||||||
@text "Zadajte početnu adresu DMA-kontrolera"
|
@text "Zadajte početnu adresu DMA-kontrolera"
|
||||||
@rule {
|
@rule {
|
||||||
if(contains_address(glavniAS, pocetnaAdresa)) {
|
if(!contains_address(glavniAS, pocetnaAdresa)) {
|
||||||
error("Početna adresa memorije je izvan 32 bitnog adresnog prostora")
|
error("Početna adresa memorije je izvan 32 bitnog adresnog prostora")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,7 +238,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@rule {
|
@rule {
|
||||||
if(unique(glavniAS, pocetnaAdresa, 32)) {
|
if(!unique(glavniAS, pocetnaAdresa, 32)) {
|
||||||
error("Adrese memorije nisu jedinstvene u adresnom prostoru (preklapaju se s nekom drugom komponentom)")
|
error("Adrese memorije nisu jedinstvene u adresnom prostoru (preklapaju se s nekom drugom komponentom)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,7 +343,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@bus directRam automatic {
|
@bus directRam singleAutomatic {
|
||||||
@instanceName directRam
|
@instanceName directRam
|
||||||
@wires {
|
@wires {
|
||||||
INT
|
INT
|
||||||
|
@ -381,6 +380,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@connection (FRISC.memDirect, directRam, Memorija.memDirect) {
|
@connection (FRISC.memDirect, directRam, Memorija.memDirect) {
|
||||||
@wires{INT}
|
@attribute procConn string default "INT" {
|
||||||
@wires{INT}
|
@popup automatic {
|
||||||
|
@title "Frisc INT"
|
||||||
|
@text "Processor interupt 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@attribute memConn string default "INT" {
|
||||||
|
@popup automatic {
|
||||||
|
@title "Mem INT"
|
||||||
|
@text "Memory interupt 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@wires{"INT", null, 1, "INT2"}
|
||||||
|
@wires{"INT", null, 1, "INT2"}
|
||||||
}
|
}
|
|
@ -2,13 +2,28 @@
|
||||||
|
|
||||||
@schema {
|
@schema {
|
||||||
@instance procesor FRISC {
|
@instance procesor FRISC {
|
||||||
@position (-112, -89)
|
@position (-464, -314)
|
||||||
@attribute _memory memorija2
|
@attribute _memory null
|
||||||
}
|
}
|
||||||
|
|
||||||
@instance procesor FRISC {
|
@instance dma DMA {
|
||||||
@position (112, -89)
|
@position (-269, 46)
|
||||||
@attribute _memory null
|
@attribute pocetnaAdresa 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@instance glavnaSabirnica glavnaSabirnica {
|
||||||
|
@position (-579, -160)
|
||||||
|
@size 100
|
||||||
|
}
|
||||||
|
|
||||||
|
@instance PIOSabirnica PIOSabirnica {
|
||||||
|
@position (0, 0)
|
||||||
|
@size 0
|
||||||
|
}
|
||||||
|
|
||||||
|
@connection (dma.glavniPin, glavnaSabirnica) {
|
||||||
|
@attribute interupt INT2
|
||||||
|
}
|
||||||
|
@connection (dma.glavniPin, PIOSabirnica, procesor.glavniPin) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ void MainWindow::onGenerateComdel() {
|
||||||
formatErrors(validationErrors, buff);
|
formatErrors(validationErrors, buff);
|
||||||
log->appendPlainText(QString::fromStdString(buff.str()));
|
log->appendPlainText(QString::fromStdString(buff.str()));
|
||||||
|
|
||||||
if(Application::hasErrors(validationErrors)) {
|
if(!Application::hasErrors(validationErrors)) {
|
||||||
std::ofstream out(filename.toStdString(), std::ios::out | std::ios::binary);
|
std::ofstream out(filename.toStdString(), std::ios::out | std::ios::binary);
|
||||||
out<<output.str();
|
out<<output.str();
|
||||||
out.close();
|
out.close();
|
||||||
|
|
Loading…
Reference in New Issue