Basic refactor
This commit is contained in:
parent
aac972c6ca
commit
0c4afe87d9
|
@ -14,29 +14,28 @@ add_executable(SchemeEditor
|
||||||
comdel/domain/value.cpp
|
comdel/domain/value.cpp
|
||||||
comdel/domain/schema.cpp
|
comdel/domain/schema.cpp
|
||||||
comdel/domain/component.cpp
|
comdel/domain/component.cpp
|
||||||
comdel/domain/connectioninstance.cpp
|
comdel/domain/connection_instance.cpp
|
||||||
comdel/domain/rule.cpp
|
comdel/domain/rule.cpp
|
||||||
comdel/domain/wireinstance.cpp
|
|
||||||
comdel/domain/attribute.cpp
|
comdel/domain/attribute.cpp
|
||||||
comdel/domain/bus.cpp
|
comdel/domain/bus.cpp
|
||||||
comdel/domain/pin.cpp
|
comdel/domain/pin.cpp
|
||||||
comdel/domain/display.cpp
|
comdel/domain/display.cpp
|
||||||
comdel/domain/library.cpp
|
comdel/domain/library.cpp
|
||||||
comdel/domain/functionsignature.cpp
|
comdel/domain/function_signature.cpp
|
||||||
comdel/domain/addressspace.cpp
|
comdel/domain/address_space.cpp
|
||||||
comdel/domain/instanceattribute.cpp
|
comdel/domain/instance_attribute.cpp
|
||||||
comdel/domain/connection.cpp
|
comdel/domain/connection.cpp
|
||||||
comdel/domain/instance.cpp
|
comdel/domain/instance.cpp
|
||||||
comdel/domain/schemacreator.cpp
|
comdel/domain/schema_creator.cpp
|
||||||
comdel/parser/comdelparser.cpp
|
comdel/parser/comdel_parser.cpp
|
||||||
comdel/parser/token.cpp
|
comdel/parser/token.cpp
|
||||||
comdel/parser/sourceerror.cpp
|
comdel/parser/source_error.cpp
|
||||||
comdel/parser/parsecontext.cpp
|
comdel/parser/parse_context.cpp
|
||||||
comdel/parser/tokenstype.cpp
|
comdel/parser/tokens_type.cpp
|
||||||
comdel/parser/astnode.cpp
|
comdel/parser/ast_nodes.cpp
|
||||||
comdel/parser/parserutil.cpp
|
comdel/parser/parser_util.cpp
|
||||||
comdel/parser/comdellexer.cpp
|
comdel/parser/comdellexer.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
mainwindow.ui
|
mainwindow.ui
|
||||||
comdel/domain/comdelvalidator.cpp comdel/domain/comdelvalidator.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)
|
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)
|
||||||
target_link_libraries(SchemeEditor Qt5::Core Qt5::Gui Qt5::Widgets)
|
target_link_libraries(SchemeEditor Qt5::Core Qt5::Gui Qt5::Widgets)
|
||||||
|
|
|
@ -57,10 +57,207 @@ void AttributeDialog::onUpdate() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AttributeDialog::AttributeDialog(domain::InstanceAttribute *attribute) {
|
||||||
|
|
||||||
|
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
attributeValue = attribute;
|
||||||
|
|
||||||
|
this->setWindowTitle(QString::fromStdString("Izmjeni " + attribute->attribute.getName()));
|
||||||
|
|
||||||
|
auto layout = new QVBoxLayout(this);
|
||||||
|
this->setLayout(layout);
|
||||||
|
auto popup = *attribute->attribute.getPopup();
|
||||||
|
|
||||||
|
layout->addWidget(new QLabel(popup.getTitle().c_str()));
|
||||||
|
layout->addWidget(new QLabel(popup.getText().c_str()));
|
||||||
|
|
||||||
|
auto type = attribute->attribute.getDefault().getType();
|
||||||
|
value = attribute->value;
|
||||||
|
|
||||||
|
if (attribute->attribute.getPopup()->isEnumerated()) {
|
||||||
|
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,
|
||||||
|
&AttributeDialog::onEnumerationChanged);
|
||||||
|
layout->addWidget(combo);
|
||||||
|
|
||||||
|
for (int i = 0; i < enumeration.size(); i++) {
|
||||||
|
if (attributeValue->value.equals(enumeration[i].getValue())) {
|
||||||
|
combo->setCurrentIndex(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (!(type == domain::Value::ValueType::WIRE_REFERENCE || type == domain::Value::ValueType::BOOL)) {
|
||||||
|
|
||||||
|
auto edit = new QLineEdit(this);
|
||||||
|
connect(edit, &QLineEdit::textChanged, this, &AttributeDialog::onTextChanged);
|
||||||
|
layout->addWidget(edit);
|
||||||
|
|
||||||
|
switch (attribute->attribute.getDefault().getType()) {
|
||||||
|
case domain::Value::ValueType::INT:
|
||||||
|
edit->setValidator(new QIntValidator(-10000000, 10000000, edit));
|
||||||
|
edit->insert(std::to_string(attribute->value.asInt()).c_str());
|
||||||
|
break;
|
||||||
|
case domain::Value::ValueType::STRING:
|
||||||
|
edit->insert(attribute->value.asString().c_str());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (type == domain::Value::ValueType::BOOL) {
|
||||||
|
auto *group = new QGroupBox(this);
|
||||||
|
|
||||||
|
auto *radioLayout = new QHBoxLayout(group);
|
||||||
|
group->setLayout(radioLayout);
|
||||||
|
|
||||||
|
auto isTrue = new QRadioButton("true", group);
|
||||||
|
connect(isTrue, &QRadioButton::clicked, [this]() {
|
||||||
|
this->value = domain::Value::fromBool(true);
|
||||||
|
});
|
||||||
|
auto isFalse = new QRadioButton("false", group);
|
||||||
|
connect(isFalse, &QRadioButton::clicked, [this]() {
|
||||||
|
this->value = domain::Value::fromBool(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (attribute->value.asBool()) {
|
||||||
|
isTrue->setChecked(true);
|
||||||
|
} else {
|
||||||
|
isFalse->setChecked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
radioLayout->addWidget(isTrue);
|
||||||
|
radioLayout->addWidget(isFalse);
|
||||||
|
layout->addWidget(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto button = new QPushButton("Ažuriraj");
|
||||||
|
connect(button, &QPushButton::clicked, this, &AttributeDialog::onUpdate);
|
||||||
|
|
||||||
|
layout->addWidget(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttributeDialog::onTextChanged(const QString &string) {
|
||||||
|
switch (value.getType()) {
|
||||||
|
case domain::Value::STRING:
|
||||||
|
value.setString(string.toStdString());
|
||||||
|
break;
|
||||||
|
case domain::Value::INT:
|
||||||
|
value = domain::Value::fromInt(parseInt(string.toStdString()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttributeDialog::onEnumerationChanged(int index) {
|
||||||
|
value = attributeValue->attribute.getPopup()->getEnumeration()[index].getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MemoryDialog::onUpdate() {
|
void MemoryDialog::onUpdate() {
|
||||||
attributeValue->value = value;
|
attributeValue->value = value;
|
||||||
accept();
|
accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MemoryDialog::MemoryDialog(domain::InstanceAttribute *attribute,
|
||||||
|
std::vector<std::shared_ptr<domain::ComponentInstance>> instances) {
|
||||||
|
memoryInstances = std::vector<std::string>();
|
||||||
|
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
attributeValue = attribute;
|
||||||
|
|
||||||
|
this->setWindowTitle(QString::fromStdString("Izmjeni " + attribute->attribute.getName()));
|
||||||
|
|
||||||
|
for (auto &instance: instances) {
|
||||||
|
if (instance->component.getType() == domain::Component::MEMORY) {
|
||||||
|
memoryInstances.push_back(instance->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto layout = new QVBoxLayout(this);
|
||||||
|
this->setLayout(layout);
|
||||||
|
auto popup = *attribute->attribute.getPopup();
|
||||||
|
|
||||||
|
layout->addWidget(new QLabel(popup.getTitle().c_str()));
|
||||||
|
layout->addWidget(new QLabel(popup.getText().c_str()));
|
||||||
|
|
||||||
|
value = attribute->value;
|
||||||
|
|
||||||
|
auto *combo = new QComboBox(this);
|
||||||
|
for (auto &entry: memoryInstances) {
|
||||||
|
combo->addItem(QString::fromStdString(entry));
|
||||||
|
}
|
||||||
|
combo->addItem("null");
|
||||||
|
|
||||||
|
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MemoryDialog::onMemoryChanged);
|
||||||
|
layout->addWidget(combo);
|
||||||
|
|
||||||
|
combo->setCurrentIndex(memoryInstances.size());
|
||||||
|
for (int i = 0; i < memoryInstances.size(); i++) {
|
||||||
|
if (attributeValue->value.asMemoryReference().has_value() &&
|
||||||
|
attributeValue->value.asMemoryReference() == memoryInstances[i]) {
|
||||||
|
combo->setCurrentIndex(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto button = new QPushButton("Ažuriraj");
|
||||||
|
connect(button, &QPushButton::clicked, this, &MemoryDialog::onUpdate);
|
||||||
|
|
||||||
|
layout->addWidget(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryDialog::onMemoryChanged(int index) {
|
||||||
|
if (index == memoryInstances.size()) {
|
||||||
|
value = domain::Value::fromMemoryReference(std::nullopt);
|
||||||
|
} else {
|
||||||
|
value = domain::Value::fromMemoryReference(memoryInstances[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorDialog::ErrorDialog(std::vector<domain::ValidationError> errors) {
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
this->setWindowTitle("Greške");
|
||||||
|
|
||||||
|
auto layout = new QVBoxLayout(this);
|
||||||
|
this->setLayout(layout);
|
||||||
|
|
||||||
|
for (auto &err: errors) {
|
||||||
|
layout->addWidget(new QLabel(QString::fromStdString(err.message), this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WarningDialog::WarningDialog(domain::ValidationError error) {
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
this->setWindowTitle("Upozorenje");
|
||||||
|
|
||||||
|
auto layout = new QVBoxLayout(this);
|
||||||
|
this->setLayout(layout);
|
||||||
|
|
||||||
|
layout->addWidget(new QLabel(QString::fromStdString(error.message), this));
|
||||||
|
|
||||||
|
auto buttonLayout = new QHBoxLayout(this);
|
||||||
|
|
||||||
|
auto okButton = new QPushButton("U redu", this);
|
||||||
|
auto cancelButton = new QPushButton("Odustani", this);
|
||||||
|
|
||||||
|
connect(okButton, &QPushButton::clicked, [this]() { accept(); });
|
||||||
|
connect(cancelButton, &QPushButton::clicked, [this]() { reject(); });
|
||||||
|
|
||||||
|
buttonLayout->addWidget(okButton);
|
||||||
|
buttonLayout->addWidget(cancelButton);
|
||||||
|
|
||||||
|
layout->addItem(buttonLayout);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -11,10 +11,10 @@
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <comdel/domain/instanceattribute.h>
|
#include <comdel/domain/instance_attribute.h>
|
||||||
|
|
||||||
#include <comdel/domain/value.h>
|
#include <comdel/domain/value.h>
|
||||||
#include "comdel/domain/comdelvalidator.h"
|
#include "comdel/domain/comdel_validator.h"
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
|
@ -25,14 +25,14 @@ class AttributeDialog: public QDialog {
|
||||||
try {
|
try {
|
||||||
if (expression.size() > 2) {
|
if (expression.size() > 2) {
|
||||||
if (expression.substr(0, 2) == "0x") {
|
if (expression.substr(0, 2) == "0x") {
|
||||||
return std::stoll(expression, 0, 16);
|
return std::stoll(expression, nullptr, 16);
|
||||||
} else if (expression.substr(0, 2) == "0b") {
|
} else if (expression.substr(0, 2) == "0b") {
|
||||||
return std::stoll(expression, 0, 2);
|
return std::stoll(expression, nullptr, 2);
|
||||||
} else {
|
} else {
|
||||||
return std::stoll(expression, 0, 10);
|
return std::stoll(expression, nullptr, 10);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return std::stoll(expression, 0, 10);
|
return std::stoll(expression, nullptr, 10);
|
||||||
}
|
}
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -42,103 +42,13 @@ class AttributeDialog: public QDialog {
|
||||||
domain::InstanceAttribute *attributeValue;
|
domain::InstanceAttribute *attributeValue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AttributeDialog(domain::InstanceAttribute *attribute) {
|
AttributeDialog(domain::InstanceAttribute *attribute);
|
||||||
|
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
|
|
||||||
attributeValue = attribute;
|
|
||||||
|
|
||||||
this->setWindowTitle(QString::fromStdString("Izmjeni " + attribute->attribute.getName()));
|
|
||||||
|
|
||||||
auto layout = new QVBoxLayout(this);
|
|
||||||
this->setLayout(layout);
|
|
||||||
auto popup = *attribute->attribute.getPopup();
|
|
||||||
|
|
||||||
layout->addWidget(new QLabel(popup.getTitle().c_str()));
|
|
||||||
layout->addWidget(new QLabel(popup.getText().c_str()));
|
|
||||||
|
|
||||||
auto type = attribute->attribute.getDefault().getType();
|
|
||||||
value = attribute->value;
|
|
||||||
|
|
||||||
if(attribute->attribute.getPopup()->isEnumerated()) {
|
|
||||||
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, &AttributeDialog::onEnumerationChanged);
|
|
||||||
layout->addWidget(combo);
|
|
||||||
|
|
||||||
for(int i=0; i<enumeration.size(); i++) {
|
|
||||||
if(attributeValue->value.equals(enumeration[i].getValue())) {
|
|
||||||
combo->setCurrentIndex(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(!(type == domain::Value::ValueType::WIRE_REFERENCE || type == domain::Value::ValueType::BOOL)) {
|
|
||||||
|
|
||||||
auto edit = new QLineEdit(this);
|
|
||||||
connect(edit, &QLineEdit::textChanged, this, &AttributeDialog::onTextChanged);
|
|
||||||
layout->addWidget(edit);
|
|
||||||
|
|
||||||
switch (attribute->attribute.getDefault().getType()) {
|
|
||||||
case domain::Value::ValueType::INT:
|
|
||||||
edit->setValidator(new QIntValidator(-10000000, 10000000, edit));
|
|
||||||
edit->insert(std::to_string(attribute->value.asInt()).c_str());
|
|
||||||
break;
|
|
||||||
case domain::Value::ValueType::STRING:
|
|
||||||
edit->insert(attribute->value.asString().c_str());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(type == domain::Value::ValueType::BOOL) {
|
|
||||||
auto *group = new QGroupBox(this);
|
|
||||||
|
|
||||||
auto *radioLayout = new QHBoxLayout(group);
|
|
||||||
group->setLayout(radioLayout);
|
|
||||||
|
|
||||||
auto isTrue = new QRadioButton("true", group);
|
|
||||||
connect(isTrue, &QRadioButton::clicked, [this]() {
|
|
||||||
this->value = domain::Value::fromBool(true);
|
|
||||||
});
|
|
||||||
auto isFalse = new QRadioButton("false", group);
|
|
||||||
connect(isFalse, &QRadioButton::clicked, [this]() {
|
|
||||||
this->value = domain::Value::fromBool(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
if(attribute->value.asBool()) {
|
|
||||||
isTrue->setChecked(true);
|
|
||||||
} else {
|
|
||||||
isFalse->setChecked(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
radioLayout->addWidget(isTrue);
|
|
||||||
radioLayout->addWidget(isFalse);
|
|
||||||
layout->addWidget(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto button = new QPushButton("Ažuriraj");
|
|
||||||
connect(button, &QPushButton::clicked, this, &AttributeDialog::onUpdate);
|
|
||||||
|
|
||||||
layout->addWidget(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onTextChanged(const QString& string) {
|
|
||||||
switch (value.getType()) {
|
|
||||||
case domain::Value::STRING:
|
|
||||||
value.setString(string.toStdString());
|
|
||||||
break;
|
|
||||||
case domain::Value::INT:
|
|
||||||
value = domain::Value::fromInt(parseInt(string.toStdString()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void onEnumerationChanged(int index) {
|
void onTextChanged(const QString &string);
|
||||||
value = attributeValue->attribute.getPopup()->getEnumeration()[index].getValue();
|
|
||||||
}
|
void onEnumerationChanged(int index);
|
||||||
|
|
||||||
void onUpdate();
|
void onUpdate();
|
||||||
|
|
||||||
|
@ -152,62 +62,12 @@ public slots:
|
||||||
std::vector<std::string> memoryInstances;
|
std::vector<std::string> memoryInstances;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MemoryDialog(domain::InstanceAttribute *attribute, std::vector<std::shared_ptr<domain::ComponentInstance>> instances) {
|
MemoryDialog(domain::InstanceAttribute *attribute,
|
||||||
memoryInstances = std::vector<std::string>();
|
std::vector<std::shared_ptr<domain::ComponentInstance>> instances);
|
||||||
|
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
|
|
||||||
attributeValue = attribute;
|
|
||||||
|
|
||||||
this->setWindowTitle(QString::fromStdString("Izmjeni " + attribute->attribute.getName()));
|
|
||||||
|
|
||||||
for(auto& instance: instances) {
|
|
||||||
if(instance->component.getType() == domain::Component::MEMORY) {
|
|
||||||
memoryInstances.push_back(instance->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto layout = new QVBoxLayout(this);
|
|
||||||
this->setLayout(layout);
|
|
||||||
auto popup = *attribute->attribute.getPopup();
|
|
||||||
|
|
||||||
layout->addWidget(new QLabel(popup.getTitle().c_str()));
|
|
||||||
layout->addWidget(new QLabel(popup.getText().c_str()));
|
|
||||||
|
|
||||||
value = attribute->value;
|
|
||||||
|
|
||||||
auto* combo = new QComboBox(this);
|
|
||||||
for(auto& entry: memoryInstances) {
|
|
||||||
combo->addItem(QString::fromStdString(entry));
|
|
||||||
}
|
|
||||||
combo->addItem("null");
|
|
||||||
|
|
||||||
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MemoryDialog::onMemoryChanged);
|
|
||||||
layout->addWidget(combo);
|
|
||||||
|
|
||||||
combo->setCurrentIndex(memoryInstances.size());
|
|
||||||
for(int i=0; i<memoryInstances.size(); i++) {
|
|
||||||
if(attributeValue->value.asMemoryReference().has_value() && attributeValue->value.asMemoryReference() == memoryInstances[i]) {
|
|
||||||
combo->setCurrentIndex(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto button = new QPushButton("Ažuriraj");
|
|
||||||
connect(button, &QPushButton::clicked, this, &MemoryDialog::onUpdate);
|
|
||||||
|
|
||||||
layout->addWidget(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void onMemoryChanged(int index) {
|
void onMemoryChanged(int index);
|
||||||
if(index == memoryInstances.size()) {
|
|
||||||
value = domain::Value::fromMemoryReference(std::nullopt);
|
|
||||||
} else {
|
|
||||||
value = domain::Value::fromMemoryReference(memoryInstances[index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void onUpdate();
|
void onUpdate();
|
||||||
|
|
||||||
|
@ -215,54 +75,15 @@ public slots:
|
||||||
|
|
||||||
|
|
||||||
class ErrorDialog : public QDialog {
|
class ErrorDialog : public QDialog {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ErrorDialog(std::vector<domain::ValidationError> errors) {
|
ErrorDialog(std::vector<domain::ValidationError> errors);
|
||||||
|
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
|
|
||||||
this->setWindowTitle("Greške");
|
|
||||||
|
|
||||||
auto layout = new QVBoxLayout(this);
|
|
||||||
this->setLayout(layout);
|
|
||||||
|
|
||||||
for(auto& err: errors) {
|
|
||||||
layout->addWidget(new QLabel(QString::fromStdString(err.message), this));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class WarningDialog : public QDialog {
|
class WarningDialog : public QDialog {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WarningDialog(domain::ValidationError error) {
|
WarningDialog(domain::ValidationError error);
|
||||||
|
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
|
|
||||||
this->setWindowTitle("Upozorenje");
|
|
||||||
|
|
||||||
auto layout = new QVBoxLayout(this);
|
|
||||||
this->setLayout(layout);
|
|
||||||
|
|
||||||
layout->addWidget(new QLabel(QString::fromStdString(error.message), this));
|
|
||||||
|
|
||||||
auto buttonLayout = new QHBoxLayout(this);
|
|
||||||
|
|
||||||
auto okButton = new QPushButton("U redu", this);
|
|
||||||
auto cancelButton = new QPushButton("Odustani", this);
|
|
||||||
|
|
||||||
connect(okButton, &QPushButton::clicked, [this]() { accept(); });
|
|
||||||
connect(cancelButton, &QPushButton::clicked, [this]() { reject(); });
|
|
||||||
|
|
||||||
buttonLayout->addWidget(okButton);
|
|
||||||
buttonLayout->addWidget(cancelButton);
|
|
||||||
|
|
||||||
layout->addItem(buttonLayout);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //ATTRIBUTE_DIALOG_H
|
#endif //ATTRIBUTE_DIALOG_H
|
||||||
|
|
|
@ -23,7 +23,8 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
auto action = menu.addAction(QString::fromStdString("Izmjeni " + attr->name),
|
auto action = menu.addAction(QString::fromStdString("Izmjeni " + attr->name),
|
||||||
[attr]() {
|
[attr]() {
|
||||||
if (attr->value.getType() == domain::Value::MEMORY_REFERENCE) {
|
if (attr->value.getType() == domain::Value::MEMORY_REFERENCE) {
|
||||||
auto dialog = new MemoryDialog(attr, MainWindow::getSchema()->componentInstances);
|
auto dialog = new MemoryDialog(attr,
|
||||||
|
MainWindow::getSchema()->componentInstances);
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
} else {
|
} else {
|
||||||
auto dialog = new AttributeDialog(attr);
|
auto dialog = new AttributeDialog(attr);
|
||||||
|
@ -35,6 +36,11 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
menu.exec(event->screenPos());
|
menu.exec(event->screenPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component::Component(const std::shared_ptr<domain::ComponentInstance> &instance): instance(instance) {
|
||||||
|
setFlag(ItemSendsGeometryChanges, true);
|
||||||
|
instance->component.getDisplay().render(this);
|
||||||
|
}
|
||||||
|
|
||||||
void Pin::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
void Pin::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
QMenu menu;
|
QMenu menu;
|
||||||
menu.addAction("Connect pin", [&]() {});
|
menu.addAction("Connect pin", [&]() {});
|
||||||
|
@ -46,7 +52,9 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
auto view = dynamic_cast<Schema *>(this->scene()->views()[0]);
|
auto view = dynamic_cast<Schema *>(this->scene()->views()[0]);
|
||||||
view->state = Schema::CREATING_CONNECTION;
|
view->state = Schema::CREATING_CONNECTION;
|
||||||
view->context.pin = this;
|
view->context.pin = this;
|
||||||
view->context.startingPoint = dynamic_cast<ComponentGroup*>(this->parentItem())->pos() + QPointF(pin.getDisplayPin().getConnectionX(), pin.getDisplayPin().getConnectionY());
|
view->context.startingPoint = dynamic_cast<ComponentGroup *>(this->parentItem())->pos() +
|
||||||
|
QPointF(pin.getDisplayPin().getConnectionX(),
|
||||||
|
pin.getDisplayPin().getConnectionY());
|
||||||
view->context.line = new QGraphicsLineItem(QLineF(view->context.startingPoint, event->scenePos()));
|
view->context.line = new QGraphicsLineItem(QLineF(view->context.startingPoint, event->scenePos()));
|
||||||
this->scene()->addItem(view->context.line);
|
this->scene()->addItem(view->context.line);
|
||||||
|
|
||||||
|
@ -73,6 +81,14 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
domain::Pin &Pin::getPin() {
|
||||||
|
return pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
domain::ComponentInstance *Pin::getComponentInstance() {
|
||||||
|
return componentInstance.get();
|
||||||
|
}
|
||||||
|
|
||||||
void Bus::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
void Bus::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
QMenu menu;
|
QMenu menu;
|
||||||
menu.addAction("Izmjeni ime", [this]() {
|
menu.addAction("Izmjeni ime", [this]() {
|
||||||
|
@ -82,6 +98,14 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
menu.exec(event->screenPos());
|
menu.exec(event->screenPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bus::Bus(const std::shared_ptr<domain::BusInstance> &instance): busInstance(instance) {
|
||||||
|
instance->bus.getDisplayBus()->render(this, instance->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
domain::BusInstance *Bus::getBusInstance() {
|
||||||
|
{ return busInstance.get(); }
|
||||||
|
}
|
||||||
|
|
||||||
QVariant BusGroup::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) {
|
QVariant BusGroup::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) {
|
||||||
if (change == ItemPositionChange && scene()) {
|
if (change == ItemPositionChange && scene()) {
|
||||||
// value is the new position.
|
// value is the new position.
|
||||||
|
@ -121,6 +145,31 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
return QGraphicsItem::itemChange(change, value);
|
return QGraphicsItem::itemChange(change, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<domain::ComponentInstance> ComponentGroup::getComponentInstance() {
|
||||||
|
return componentInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<display::Pin *> &ComponentGroup::getPins() {
|
||||||
|
return pins;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComponentGroup::ComponentGroup(const std::shared_ptr<domain::ComponentInstance> &instance): componentInstance(
|
||||||
|
instance) {
|
||||||
|
setFlag(ItemIsMovable, true);
|
||||||
|
setFlag(ItemSendsGeometryChanges, true);
|
||||||
|
|
||||||
|
setHandlesChildEvents(false);
|
||||||
|
|
||||||
|
addToGroup(new display::Component(instance));
|
||||||
|
|
||||||
|
for (auto &pin: instance->component.getPins()) {
|
||||||
|
pins.push_back(new display::Pin(pin, componentInstance));
|
||||||
|
addToGroup(pins.back());
|
||||||
|
}
|
||||||
|
|
||||||
|
setPos(instance->position.first, instance->position.second);
|
||||||
|
}
|
||||||
|
|
||||||
void BusConnection::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
void BusConnection::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
QMenu menu;
|
QMenu menu;
|
||||||
menu.addAction("Ukloni poveznicu", [this]() {});
|
menu.addAction("Ukloni poveznicu", [this]() {});
|
||||||
|
@ -139,6 +188,30 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
menu.exec(event->screenPos());
|
menu.exec(event->screenPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BusConnection::BusConnection(domain::BusConnectionInstance *connection, ComponentGroup *component, BusGroup *bus): connection(
|
||||||
|
connection), component(component), bus(bus) {
|
||||||
|
updateConnection();
|
||||||
|
|
||||||
|
setHandlesChildEvents(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BusConnection::updateConnection() {
|
||||||
|
auto busPosition = bus->boundingRect();
|
||||||
|
auto pin = connection->instance->component.getPin(
|
||||||
|
connection->connection.getComponent().pin).getDisplayPin();
|
||||||
|
|
||||||
|
setLine(connection->instance->position.first + pin.getConnectionX(),
|
||||||
|
connection->instance->position.second + pin.getConnectionY(),
|
||||||
|
connection->bus->position.first + busPosition.width() / 2,
|
||||||
|
connection->bus->position.second + busPosition.height() / 2);
|
||||||
|
|
||||||
|
connection->start.first = connection->instance->position.first + pin.getConnectionX();
|
||||||
|
connection->start.second = connection->instance->position.second + pin.getConnectionY();
|
||||||
|
connection->end.first = connection->bus->position.first + busPosition.width() / 2;
|
||||||
|
connection->end.second = connection->bus->position.second + busPosition.height() / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DirectConnection::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
void DirectConnection::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
QMenu menu;
|
QMenu menu;
|
||||||
menu.addAction("Ukloni poveznicu", [this]() {});
|
menu.addAction("Ukloni poveznicu", [this]() {});
|
||||||
|
@ -157,4 +230,27 @@ void Component::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
|
||||||
menu.exec(event->screenPos());
|
menu.exec(event->screenPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DirectConnection::DirectConnection(domain::DirectConnectionInstance *connection, ComponentGroup *first,
|
||||||
|
ComponentGroup *second): connection(connection), first(first), second(second) {
|
||||||
|
updateConnection();
|
||||||
|
setHandlesChildEvents(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectConnection::updateConnection() {
|
||||||
|
auto pin1 = connection->instance->component.getPin(
|
||||||
|
connection->connection.getComponent().pin).getDisplayPin();
|
||||||
|
auto pin2 = connection->secondInstance->component.getPin(
|
||||||
|
connection->connection.getSecondComponent()->pin).getDisplayPin();
|
||||||
|
|
||||||
|
setLine(connection->instance->position.first + pin1.getConnectionX(),
|
||||||
|
connection->instance->position.second + pin1.getConnectionY(),
|
||||||
|
connection->secondInstance->position.first + pin2.getConnectionX(),
|
||||||
|
connection->secondInstance->position.second + pin2.getConnectionY());
|
||||||
|
|
||||||
|
connection->start.first = connection->instance->position.first + pin1.getConnectionX();
|
||||||
|
connection->start.second = connection->instance->position.second + pin1.getConnectionY();
|
||||||
|
connection->end.first = connection->secondInstance->position.first + pin2.getConnectionX();
|
||||||
|
connection->end.second = connection->secondInstance->position.second + pin2.getConnectionY();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace display
|
} // namespace display
|
||||||
|
|
|
@ -2,99 +2,80 @@
|
||||||
#define DISPLAY_COMPONENT_H
|
#define DISPLAY_COMPONENT_H
|
||||||
|
|
||||||
#include <comdel/domain/instance.h>
|
#include <comdel/domain/instance.h>
|
||||||
#include <comdel/domain/wireinstance.h>
|
|
||||||
|
|
||||||
#include <QGraphicsItemGroup>
|
#include <QGraphicsItemGroup>
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
#include "comdel/domain/connectioninstance.h"
|
#include <utility>
|
||||||
|
#include "comdel/domain/connection_instance.h"
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
class Pin: public QGraphicsItemGroup
|
class Pin : public QGraphicsItemGroup {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
domain::Pin pin;
|
domain::Pin pin;
|
||||||
std::shared_ptr<domain::ComponentInstance> componentInstance;
|
std::shared_ptr<domain::ComponentInstance> componentInstance;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Pin(domain::Pin pin, std::shared_ptr<domain::ComponentInstance> componentInstance): pin(pin), componentInstance(componentInstance) {
|
Pin(domain::Pin pin, std::shared_ptr<domain::ComponentInstance> componentInstance) : pin(pin),
|
||||||
|
componentInstance(std::move(
|
||||||
|
componentInstance)) {
|
||||||
pin.getDisplayPin().render(this);
|
pin.getDisplayPin().render(this);
|
||||||
|
this->setToolTip(QString::fromStdString(pin.getTooltip()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
||||||
|
|
||||||
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
|
|
||||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
|
|
||||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
|
|
||||||
domain::Pin& getPin() {
|
domain::Pin &getPin();
|
||||||
return pin;
|
|
||||||
}
|
|
||||||
|
|
||||||
domain::ComponentInstance* getComponentInstance() {
|
domain::ComponentInstance *getComponentInstance();
|
||||||
return componentInstance.get();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Component: public QGraphicsItemGroup
|
class Component : public QGraphicsItemGroup {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<domain::ComponentInstance> instance;
|
std::shared_ptr<domain::ComponentInstance> instance;
|
||||||
public:
|
public:
|
||||||
Component(const std::shared_ptr<domain::ComponentInstance>& instance): instance(instance) {
|
explicit Component(const std::shared_ptr<domain::ComponentInstance> &instance);
|
||||||
setFlag(ItemSendsGeometryChanges, true);
|
|
||||||
|
|
||||||
instance->component.getDisplay().render(this);
|
|
||||||
}
|
|
||||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Bus: public QGraphicsItemGroup
|
class Bus : public QGraphicsItemGroup {
|
||||||
{
|
|
||||||
std::shared_ptr<domain::BusInstance> busInstance;
|
std::shared_ptr<domain::BusInstance> busInstance;
|
||||||
public:
|
public:
|
||||||
Bus(const std::shared_ptr<domain::BusInstance>& instance): busInstance(instance) {
|
explicit Bus(const std::shared_ptr<domain::BusInstance> &instance);
|
||||||
instance->bus.getDisplayBus()->render(this, instance->size);
|
|
||||||
}
|
domain::BusInstance *getBusInstance();
|
||||||
domain::BusInstance *getBusInstance() { return busInstance.get(); }
|
|
||||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComponentGroup: public QGraphicsItemGroup
|
class ComponentGroup : public QGraphicsItemGroup {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<domain::ComponentInstance> componentInstance;
|
std::shared_ptr<domain::ComponentInstance> componentInstance;
|
||||||
std::vector<display::Pin *> pins;
|
std::vector<display::Pin *> pins;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
std::shared_ptr<domain::ComponentInstance> getComponentInstance() { return componentInstance; }
|
std::shared_ptr<domain::ComponentInstance> getComponentInstance();
|
||||||
std::vector<display::Pin*>& getPins() { return pins; }
|
|
||||||
|
|
||||||
explicit ComponentGroup(const std::shared_ptr<domain::ComponentInstance>& instance): componentInstance(instance) {
|
std::vector<display::Pin *> &getPins();
|
||||||
setFlag(ItemIsMovable, true);
|
|
||||||
setFlag(ItemSendsGeometryChanges, true);
|
|
||||||
|
|
||||||
setHandlesChildEvents(false);
|
explicit ComponentGroup(const std::shared_ptr<domain::ComponentInstance> &instance);
|
||||||
|
|
||||||
addToGroup(new display::Component(instance));
|
|
||||||
|
|
||||||
for(auto &pin: instance->component.getPins()) {
|
|
||||||
pins.push_back(new display::Pin(pin, componentInstance));
|
|
||||||
addToGroup(pins.back());
|
|
||||||
}
|
|
||||||
|
|
||||||
setPos(instance->position.first, instance->position.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BusGroup: public QGraphicsItemGroup
|
class BusGroup : public QGraphicsItemGroup {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<domain::BusInstance> busInstance;
|
std::shared_ptr<domain::BusInstance> busInstance;
|
||||||
display::Bus *bus;
|
display::Bus *bus;
|
||||||
|
@ -102,69 +83,35 @@ private:
|
||||||
public:
|
public:
|
||||||
explicit BusGroup(const std::shared_ptr<domain::BusInstance> &instance);
|
explicit BusGroup(const std::shared_ptr<domain::BusInstance> &instance);
|
||||||
|
|
||||||
display::Bus* getBus() { return bus; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BusConnection: public QGraphicsLineItem
|
class BusConnection : public QGraphicsLineItem {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
domain::BusConnectionInstance *connection;
|
domain::BusConnectionInstance *connection;
|
||||||
ComponentGroup *component;
|
ComponentGroup *component;
|
||||||
BusGroup *bus;
|
BusGroup *bus;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BusConnection(domain::BusConnectionInstance* connection, ComponentGroup *component, BusGroup *bus): connection(connection), component(component), bus(bus) {
|
BusConnection(domain::BusConnectionInstance *connection, ComponentGroup *component, BusGroup *bus);
|
||||||
updateConnection();
|
|
||||||
|
|
||||||
setHandlesChildEvents(false);
|
void updateConnection();
|
||||||
}
|
|
||||||
|
|
||||||
void updateConnection() {
|
|
||||||
auto busPosition = bus->boundingRect();
|
|
||||||
auto pin = connection->instance->component.getPin(connection->connection.getComponent().pin).getDisplayPin();
|
|
||||||
|
|
||||||
setLine(connection->instance->position.first + pin.getConnectionX(), connection->instance->position.second + pin.getConnectionY(), connection->bus->position.first + busPosition.width()/2, connection->bus->position.second + busPosition.height()/2);
|
|
||||||
|
|
||||||
connection->start.first = connection->instance->position.first + pin.getConnectionX();
|
|
||||||
connection->start.second = connection->instance->position.second + pin.getConnectionY();
|
|
||||||
connection->end.first = connection->bus->position.first + busPosition.width()/2;
|
|
||||||
connection->end.second = connection->bus->position.second + busPosition.height()/2;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class DirectConnection: public QGraphicsLineItem
|
class DirectConnection : public QGraphicsLineItem {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
domain::DirectConnectionInstance *connection;
|
domain::DirectConnectionInstance *connection;
|
||||||
ComponentGroup *first;
|
ComponentGroup *first;
|
||||||
ComponentGroup *second;
|
ComponentGroup *second;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DirectConnection(domain::DirectConnectionInstance* connection, ComponentGroup *first, ComponentGroup *second): connection(connection), first(first), second(second) {
|
DirectConnection(domain::DirectConnectionInstance *connection, ComponentGroup *first, ComponentGroup *second);
|
||||||
updateConnection();
|
|
||||||
setHandlesChildEvents(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateConnection() {
|
void updateConnection();
|
||||||
auto pin1 = connection->instance->component.getPin(connection->connection.getComponent().pin).getDisplayPin();
|
|
||||||
auto pin2 = connection->secondInstance->component.getPin(connection->connection.getSecondComponent()->pin).getDisplayPin();
|
|
||||||
|
|
||||||
setLine(connection->instance->position.first + pin1.getConnectionX(), connection->instance->position.second + pin1.getConnectionY(),
|
|
||||||
connection->secondInstance->position.first + pin2.getConnectionX(), connection->secondInstance->position.second + pin2.getConnectionY());
|
|
||||||
|
|
||||||
connection->start.first = connection->instance->position.first + pin1.getConnectionX();
|
|
||||||
connection->start.second = connection->instance->position.second + pin1.getConnectionY();
|
|
||||||
connection->end.first = connection->secondInstance->position.first + pin2.getConnectionX();
|
|
||||||
connection->end.second = connection->secondInstance->position.second + pin2.getConnectionY();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
Library::Library()
|
Library::Library() {
|
||||||
{
|
|
||||||
auto layout = new QVBoxLayout();
|
auto layout = new QVBoxLayout();
|
||||||
this->setLayout(layout);
|
this->setLayout(layout);
|
||||||
|
|
||||||
|
@ -34,7 +33,8 @@ void Library::setLibrary(std::optional<domain::Library> library) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &component: library->getComponents()) {
|
for (auto &component: library->getComponents()) {
|
||||||
auto item = new LibraryListItem{component.getName(), "comdel/component", component.getName(), componentList};
|
auto item = new LibraryListItem{component.getName(), "comdel/component", component.getName(),
|
||||||
|
componentList};
|
||||||
item->setToolTip(QString::fromStdString(component.getTooltip()));
|
item->setToolTip(QString::fromStdString(component.getTooltip()));
|
||||||
componentList->addItem(item);
|
componentList->addItem(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
class Library: public QWidget
|
class Library : public QWidget {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Library();
|
Library();
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,8 @@ namespace display {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
LibraryListItem::LibraryListItem(std::string title, std::string mimeType, std::string value, QListWidget *parent): QListWidgetItem(parent), mimeType(mimeType), value(value) {
|
LibraryListItem::LibraryListItem(std::string title, std::string mimeType, std::string value, QListWidget *parent)
|
||||||
|
: QListWidgetItem(parent), mimeType(mimeType), value(value) {
|
||||||
setText(QString::fromStdString(title));
|
setText(QString::fromStdString(title));
|
||||||
}
|
}
|
||||||
} // display
|
} // display
|
|
@ -3,3 +3,40 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "name_dialog.h"
|
#include "name_dialog.h"
|
||||||
|
|
||||||
|
display::NameDialog::NameDialog(domain::ComponentInstance *instance) : componentInstance(instance) {
|
||||||
|
auto *layout = new QVBoxLayout(this);
|
||||||
|
layout->addWidget(new QLabel("Izmjeni ime", this));
|
||||||
|
|
||||||
|
edit = new QLineEdit(this);
|
||||||
|
edit->insert(instance->name.c_str());
|
||||||
|
layout->addWidget(edit);
|
||||||
|
this->setWindowTitle("Izmjeni ime");
|
||||||
|
auto *button = new QPushButton("Ažuriraj", this);
|
||||||
|
connect(button, &QPushButton::clicked, this, &NameDialog::onNameChange);
|
||||||
|
layout->addWidget(button);
|
||||||
|
this->setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
display::NameDialog::NameDialog(domain::BusInstance *instance): busInstance(instance) {
|
||||||
|
auto *layout = new QVBoxLayout(this);
|
||||||
|
layout->addWidget(new QLabel("Izmjeni ime", this));
|
||||||
|
|
||||||
|
edit = new QLineEdit(this);
|
||||||
|
edit->insert(instance->name.c_str());
|
||||||
|
layout->addWidget(edit);
|
||||||
|
this->setWindowTitle("Izmjeni ime");
|
||||||
|
auto *button = new QPushButton("Ažuriraj", this);
|
||||||
|
connect(button, &QPushButton::clicked, this, &NameDialog::onNameChange);
|
||||||
|
layout->addWidget(button);
|
||||||
|
this->setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void display::NameDialog::onNameChange() {
|
||||||
|
if (componentInstance != nullptr) {
|
||||||
|
componentInstance->name = this->edit->text().toStdString();
|
||||||
|
} else if (busInstance != nullptr) {
|
||||||
|
busInstance->name = this->edit->text().toStdString();
|
||||||
|
}
|
||||||
|
this->close();
|
||||||
|
}
|
||||||
|
|
|
@ -19,43 +19,13 @@ class NameDialog: public QDialog {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
NameDialog(domain::ComponentInstance *instance): componentInstance(instance) {
|
NameDialog(domain::ComponentInstance *instance);
|
||||||
auto *layout = new QVBoxLayout(this);
|
|
||||||
layout->addWidget(new QLabel("Izmjeni ime", this));
|
|
||||||
|
|
||||||
edit = new QLineEdit(this);
|
NameDialog(domain::BusInstance *instance);
|
||||||
edit->insert(instance->name.c_str());
|
|
||||||
layout->addWidget(edit);
|
|
||||||
this->setWindowTitle("Izmjeni ime");
|
|
||||||
auto *button = new QPushButton("Ažuriraj", this);
|
|
||||||
connect(button, &QPushButton::clicked, this, &NameDialog::onNameChange);
|
|
||||||
layout->addWidget(button);
|
|
||||||
this->setLayout(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
NameDialog(domain::BusInstance *instance): busInstance(instance) {
|
|
||||||
auto *layout = new QVBoxLayout(this);
|
|
||||||
layout->addWidget(new QLabel("Izmjeni ime", this));
|
|
||||||
|
|
||||||
edit = new QLineEdit(this);
|
|
||||||
edit->insert(instance->name.c_str());
|
|
||||||
layout->addWidget(edit);
|
|
||||||
this->setWindowTitle("Izmjeni ime");
|
|
||||||
auto *button = new QPushButton("Ažuriraj", this);
|
|
||||||
connect(button, &QPushButton::clicked, this, &NameDialog::onNameChange);
|
|
||||||
layout->addWidget(button);
|
|
||||||
this->setLayout(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onNameChange() {
|
|
||||||
if(componentInstance != nullptr) {
|
void onNameChange();
|
||||||
componentInstance->name = this->edit->text().toStdString();
|
|
||||||
} else if(busInstance != nullptr) {
|
|
||||||
busInstance->name = this->edit->text().toStdString();
|
|
||||||
}
|
|
||||||
this->close();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
|
|
||||||
namespace display {
|
namespace display {
|
||||||
|
|
||||||
Schema::Schema()
|
Schema::Schema() {
|
||||||
{
|
|
||||||
this->selectedBrush.setColor(QColor::fromRgb(20, 20, 125));
|
this->selectedBrush.setColor(QColor::fromRgb(20, 20, 125));
|
||||||
this->selectedPen.setColor(QColor::fromRgb(20, 20, 125));
|
this->selectedPen.setColor(QColor::fromRgb(20, 20, 125));
|
||||||
|
|
||||||
|
@ -17,8 +16,7 @@ Schema::Schema()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Schema::setSchema(domain::Schema* _schema, domain::Library* _library)
|
void Schema::setSchema(domain::Schema *_schema, domain::Library *_library) {
|
||||||
{
|
|
||||||
components.clear();
|
components.clear();
|
||||||
buses.clear();
|
buses.clear();
|
||||||
|
|
||||||
|
@ -47,13 +45,15 @@ void Schema::setSchema(domain::Schema* _schema, domain::Library* _library)
|
||||||
for (auto &connection: schema->connections) {
|
for (auto &connection: schema->connections) {
|
||||||
auto busInstance = dynamic_cast<domain::BusConnectionInstance *>(connection.get());
|
auto busInstance = dynamic_cast<domain::BusConnectionInstance *>(connection.get());
|
||||||
if (busInstance != nullptr) {
|
if (busInstance != nullptr) {
|
||||||
auto con = new display::BusConnection(busInstance, components[busInstance->instance->name], buses[busInstance->bus->name]);
|
auto con = new display::BusConnection(busInstance, components[busInstance->instance->name],
|
||||||
|
buses[busInstance->bus->name]);
|
||||||
busConnections.push_back(con);
|
busConnections.push_back(con);
|
||||||
scene.addItem(con);
|
scene.addItem(con);
|
||||||
}
|
}
|
||||||
auto directInstance = dynamic_cast<domain::DirectConnectionInstance *>(connection.get());
|
auto directInstance = dynamic_cast<domain::DirectConnectionInstance *>(connection.get());
|
||||||
if (directInstance != nullptr) {
|
if (directInstance != nullptr) {
|
||||||
auto con = new display::DirectConnection(directInstance, components[directInstance->instance->name], components[directInstance->secondInstance->name]);
|
auto con = new display::DirectConnection(directInstance, components[directInstance->instance->name],
|
||||||
|
components[directInstance->secondInstance->name]);
|
||||||
directConnections.push_back(con);
|
directConnections.push_back(con);
|
||||||
scene.addItem(con);
|
scene.addItem(con);
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,9 @@ void Schema::updateConnections() {
|
||||||
|
|
||||||
auto currentPos = this->mapToScene(event->pos());
|
auto currentPos = this->mapToScene(event->pos());
|
||||||
|
|
||||||
auto instance = std::make_shared<domain::ComponentInstance>(component.getInstanceName(), attributes, std::make_pair(currentPos.x(), currentPos.y()), component);
|
auto instance = std::make_shared<domain::ComponentInstance>(component.getInstanceName(), attributes,
|
||||||
|
std::make_pair(currentPos.x(), currentPos.y()),
|
||||||
|
component);
|
||||||
schema->componentInstances.push_back(instance);
|
schema->componentInstances.push_back(instance);
|
||||||
|
|
||||||
auto group = new display::ComponentGroup(instance);
|
auto group = new display::ComponentGroup(instance);
|
||||||
|
@ -110,7 +112,8 @@ void Schema::updateConnections() {
|
||||||
|
|
||||||
auto currentPos = this->mapToScene(event->pos());
|
auto currentPos = this->mapToScene(event->pos());
|
||||||
|
|
||||||
auto instance = std::make_shared<domain::BusInstance>(bus.getName(), std::make_pair(currentPos.x(), currentPos.y()), bus);
|
auto instance = std::make_shared<domain::BusInstance>(bus.getName(),
|
||||||
|
std::make_pair(currentPos.x(), currentPos.y()), bus);
|
||||||
schema->busInstances.push_back(instance);
|
schema->busInstances.push_back(instance);
|
||||||
|
|
||||||
auto group = new display::BusGroup(instance);
|
auto group = new display::BusGroup(instance);
|
||||||
|
@ -166,7 +169,8 @@ void Schema::updateConnections() {
|
||||||
|
|
||||||
if (rect.contains(endPoint)) {
|
if (rect.contains(endPoint)) {
|
||||||
auto name = components[pinInstance.component]->getComponentInstance()->component.getName();
|
auto name = components[pinInstance.component]->getComponentInstance()->component.getName();
|
||||||
auto con = library->getConnection({instance->component.getName(), pin.getName()}, {name, pinInstance.pin});
|
auto con = library->getConnection({instance->component.getName(), pin.getName()},
|
||||||
|
{name, pinInstance.pin});
|
||||||
if (con.has_value()) {
|
if (con.has_value()) {
|
||||||
auto bus = library->getBus(con->getBus());
|
auto bus = library->getBus(con->getBus());
|
||||||
auto busInstance = std::make_shared<domain::BusInstance>(bus.getName(), bus);
|
auto busInstance = std::make_shared<domain::BusInstance>(bus.getName(), bus);
|
||||||
|
@ -177,11 +181,16 @@ void Schema::updateConnections() {
|
||||||
attributes.emplace_back(attr.getName(), attr.getDefault(), attr);
|
attributes.emplace_back(attr.getName(), attr.getDefault(), attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto conInstance = std::make_shared<domain::DirectConnectionInstance>(instance, components[pinInstance.component]->getComponentInstance().get(), attributes, busInstance.get(), *con);
|
auto conInstance = std::make_shared<domain::DirectConnectionInstance>(instance,
|
||||||
|
components[pinInstance.component]->getComponentInstance().get(),
|
||||||
|
attributes, busInstance.get(),
|
||||||
|
*con);
|
||||||
schema->connections.push_back(conInstance);
|
schema->connections.push_back(conInstance);
|
||||||
|
|
||||||
if (conInstance != nullptr) {
|
if (conInstance != nullptr) {
|
||||||
auto c = new display::DirectConnection(conInstance.get(), components[conInstance->instance->name], components[conInstance->secondInstance->name]);
|
auto c = new display::DirectConnection(conInstance.get(),
|
||||||
|
components[conInstance->instance->name],
|
||||||
|
components[conInstance->secondInstance->name]);
|
||||||
directConnections.push_back(c);
|
directConnections.push_back(c);
|
||||||
scene.addItem(c);
|
scene.addItem(c);
|
||||||
}
|
}
|
||||||
|
@ -220,7 +229,8 @@ void Schema::updateConnections() {
|
||||||
scene.addItem(rect);
|
scene.addItem(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<domain::ConnectionComponent> pinInstances = getAvailableConnectionPins(domainPin->getComponentInstance(), domainPin->getPin());
|
std::vector<domain::ConnectionComponent> pinInstances = getAvailableConnectionPins(
|
||||||
|
domainPin->getComponentInstance(), domainPin->getPin());
|
||||||
|
|
||||||
for (auto &pinInstance: pinInstances) {
|
for (auto &pinInstance: pinInstances) {
|
||||||
auto &instance = pins[pinInstance];
|
auto &instance = pins[pinInstance];
|
||||||
|
@ -239,17 +249,20 @@ void Schema::updateConnections() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<domain::BusInstance*> Schema::getAvailableConnectionBusses(domain::ComponentInstance *instance, domain::Pin &pin) {
|
std::vector<domain::BusInstance *>
|
||||||
|
Schema::getAvailableConnectionBusses(domain::ComponentInstance *instance, domain::Pin &pin) {
|
||||||
std::vector<domain::BusInstance *> instances;
|
std::vector<domain::BusInstance *> instances;
|
||||||
for (const auto &bus: schema->busInstances) {
|
for (const auto &bus: schema->busInstances) {
|
||||||
if(library->hasConnection(domain::ConnectionComponent{instance->component.getName(), pin.getName()}, bus->bus.getName())) {
|
if (library->hasConnection(domain::ConnectionComponent{instance->component.getName(), pin.getName()},
|
||||||
|
bus->bus.getName())) {
|
||||||
instances.push_back(bus.get());
|
instances.push_back(bus.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return instances;
|
return instances;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<domain::ConnectionComponent> Schema::getAvailableConnectionPins(domain::ComponentInstance *instance, domain::Pin &pin) {
|
std::vector<domain::ConnectionComponent>
|
||||||
|
Schema::getAvailableConnectionPins(domain::ComponentInstance *instance, domain::Pin &pin) {
|
||||||
std::vector<domain::ConnectionComponent> instances;
|
std::vector<domain::ConnectionComponent> instances;
|
||||||
domain::ConnectionComponent source{instance->component.getName(), pin.getName()};
|
domain::ConnectionComponent source{instance->component.getName(), pin.getName()};
|
||||||
for (const auto &entry: pins) {
|
for (const auto &entry: pins) {
|
||||||
|
|
|
@ -14,8 +14,7 @@ namespace display {
|
||||||
|
|
||||||
class BusConnection;
|
class BusConnection;
|
||||||
|
|
||||||
class Schema: public QGraphicsView
|
class Schema : public QGraphicsView {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -58,7 +57,9 @@ public:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||||
|
|
||||||
void dropEvent(QDropEvent *event) override;
|
void dropEvent(QDropEvent *event) override;
|
||||||
|
|
||||||
void dragMoveEvent(QDragMoveEvent *event) override;
|
void dragMoveEvent(QDragMoveEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -67,9 +68,11 @@ private:
|
||||||
domain::Schema *schema;
|
domain::Schema *schema;
|
||||||
domain::Library *library;
|
domain::Library *library;
|
||||||
|
|
||||||
std::vector<domain::BusInstance*> getAvailableConnectionBusses(domain::ComponentInstance *instance, domain::Pin &pin);
|
std::vector<domain::BusInstance *>
|
||||||
|
getAvailableConnectionBusses(domain::ComponentInstance *instance, domain::Pin &pin);
|
||||||
|
|
||||||
std::vector<domain::ConnectionComponent> getAvailableConnectionPins(domain::ComponentInstance *instance, domain::Pin &pin);
|
std::vector<domain::ConnectionComponent>
|
||||||
|
getAvailableConnectionPins(domain::ComponentInstance *instance, domain::Pin &pin);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace display
|
} // namespace display
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include <algorithm>
|
||||||
|
#include "address_space.h"
|
||||||
|
|
||||||
|
namespace domain {
|
||||||
|
|
||||||
|
AddressSpace::AddressSpace(std::string name, long long start, long long end) :
|
||||||
|
name(name), start(start), end(end) {}
|
||||||
|
|
||||||
|
std::string AddressSpace::getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long AddressSpace::getStart() const {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long AddressSpace::getEnd() const {
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AddressSpace::contains(long long int address) {
|
||||||
|
return address >= start && address < end;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AddressSpace::contains(long long int pstart, long long int pend) {
|
||||||
|
return pstart >= start && pend < end;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace domain
|
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef DOMAIN_ADDRESS_SPACE_H
|
||||||
|
#define DOMAIN_ADDRESS_SPACE_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace domain {
|
||||||
|
|
||||||
|
class AddressSpace {
|
||||||
|
std::string name;
|
||||||
|
long long start;
|
||||||
|
long long end;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AddressSpace(std::string name, long long start, long long end);
|
||||||
|
|
||||||
|
std::string getName();
|
||||||
|
|
||||||
|
long long getStart() const;
|
||||||
|
|
||||||
|
long long getEnd() const;
|
||||||
|
|
||||||
|
bool contains(long long int address);
|
||||||
|
|
||||||
|
bool contains(long long int start, long long int end);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace domain
|
||||||
|
|
||||||
|
#endif // DOMAIN_ADDRESS_SPACE_H
|
|
@ -1,28 +0,0 @@
|
||||||
#include <algorithm>
|
|
||||||
#include "addressspace.h"
|
|
||||||
|
|
||||||
namespace domain {
|
|
||||||
|
|
||||||
AddressSpace::AddressSpace(std::string name, long long start, long long end):
|
|
||||||
name(name), start(start), end(end)
|
|
||||||
{}
|
|
||||||
|
|
||||||
std::string AddressSpace::getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
long long AddressSpace::getStart() const {
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
long long AddressSpace::getEnd() const {
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AddressSpace::contains(long long int address) {
|
|
||||||
return address >= start && address < end;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AddressSpace::contains(long long int pstart, long long int pend) {
|
|
||||||
return pstart >= start && pend < end;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace domain
|
|
|
@ -1,27 +0,0 @@
|
||||||
#ifndef DOMAIN_ADDRESS_SPACE_H
|
|
||||||
#define DOMAIN_ADDRESS_SPACE_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace domain {
|
|
||||||
|
|
||||||
class AddressSpace
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
long long start;
|
|
||||||
long long end;
|
|
||||||
|
|
||||||
public:
|
|
||||||
AddressSpace(std::string name, long long start, long long end);
|
|
||||||
|
|
||||||
std::string getName();
|
|
||||||
long long getStart() const;
|
|
||||||
long long getEnd() const;
|
|
||||||
|
|
||||||
bool contains(long long int address);
|
|
||||||
bool contains(long long int start, long long int end);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace domain
|
|
||||||
|
|
||||||
#endif // DOMAIN_ADDRESS_SPACE_H
|
|
|
@ -3,30 +3,34 @@
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
Enumeration::Enumeration(std::string name, Value value)
|
Enumeration::Enumeration(std::string name, Value value)
|
||||||
: name(name), value(value)
|
: name(name), value(value) {}
|
||||||
{}
|
|
||||||
|
|
||||||
std::string &Enumeration::getName() {
|
std::string &Enumeration::getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value Enumeration::getValue() {
|
Value Enumeration::getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Popup::Popup(std::string title, std::string text, PopupType type, std::vector<Rule> rules, std::vector<Enumeration> enumeration)
|
Popup::Popup(std::string title, std::string text, PopupType type, std::vector<Rule> rules,
|
||||||
: title(title), text(text), type(type), rules(rules), enumerated(enumeration.size() > 0), enumeration(enumeration)
|
std::vector<Enumeration> enumeration)
|
||||||
{}
|
: title(title), text(text), type(type), rules(rules), enumerated(enumeration.size() > 0),
|
||||||
|
enumeration(enumeration) {}
|
||||||
|
|
||||||
std::string Popup::getTitle() {
|
std::string Popup::getTitle() {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Popup::getText() {
|
std::string Popup::getText() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
Popup::PopupType Popup::getType() {
|
Popup::PopupType Popup::getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Rule> Popup::getRules() {
|
std::vector<Rule> Popup::getRules() {
|
||||||
return rules;
|
return rules;
|
||||||
}
|
}
|
||||||
|
@ -34,21 +38,23 @@ std::vector<Rule> Popup::getRules() {
|
||||||
bool Popup::isEnumerated() {
|
bool Popup::isEnumerated() {
|
||||||
return enumerated;
|
return enumerated;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Enumeration> &Popup::getEnumeration() {
|
std::vector<Enumeration> &Popup::getEnumeration() {
|
||||||
return enumeration;
|
return enumeration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Attribute::Attribute(std::string name, Value defaultValue, std::optional<Popup> popup)
|
Attribute::Attribute(std::string name, Value defaultValue, std::optional<Popup> popup)
|
||||||
: name(name), defaultValue(defaultValue), popup(popup)
|
: name(name), defaultValue(defaultValue), popup(popup) {}
|
||||||
{}
|
|
||||||
|
|
||||||
std::string Attribute::getName() {
|
std::string Attribute::getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value Attribute::getDefault() {
|
Value Attribute::getDefault() {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Popup> Attribute::getPopup() {
|
std::optional<Popup> Attribute::getPopup() {
|
||||||
return popup;
|
return popup;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ public:
|
||||||
Enumeration(std::string name, Value value);
|
Enumeration(std::string name, Value value);
|
||||||
|
|
||||||
std::string &getName();
|
std::string &getName();
|
||||||
|
|
||||||
Value getValue();
|
Value getValue();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,14 +37,19 @@ private:
|
||||||
std::vector<Rule> rules;
|
std::vector<Rule> rules;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Popup(std::string title, std::string text, PopupType type, std::vector<Rule> rules, std::vector<Enumeration> enumeration);
|
Popup(std::string title, std::string text, PopupType type, std::vector<Rule> rules,
|
||||||
|
std::vector<Enumeration> enumeration);
|
||||||
|
|
||||||
std::string getTitle();
|
std::string getTitle();
|
||||||
|
|
||||||
std::string getText();
|
std::string getText();
|
||||||
|
|
||||||
PopupType getType();
|
PopupType getType();
|
||||||
|
|
||||||
std::vector<Rule> getRules();
|
std::vector<Rule> getRules();
|
||||||
|
|
||||||
bool isEnumerated();
|
bool isEnumerated();
|
||||||
|
|
||||||
std::vector<Enumeration> &getEnumeration();
|
std::vector<Enumeration> &getEnumeration();
|
||||||
|
|
||||||
void setEnumeration(std::vector<Enumeration> enums) {
|
void setEnumeration(std::vector<Enumeration> enums) {
|
||||||
|
@ -53,8 +59,7 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Attribute
|
class Attribute {
|
||||||
{
|
|
||||||
std::string name;
|
std::string name;
|
||||||
Value defaultValue;
|
Value defaultValue;
|
||||||
std::optional<Popup> popup;
|
std::optional<Popup> popup;
|
||||||
|
@ -62,7 +67,9 @@ public:
|
||||||
Attribute(std::string name, Value defaultValue, std::optional<Popup> popup = std::nullopt);
|
Attribute(std::string name, Value defaultValue, std::optional<Popup> popup = std::nullopt);
|
||||||
|
|
||||||
std::string getName();
|
std::string getName();
|
||||||
|
|
||||||
Value getDefault();
|
Value getDefault();
|
||||||
|
|
||||||
std::optional<Popup> getPopup();
|
std::optional<Popup> getPopup();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,17 @@
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
Wire::Wire(std::string name, WireType type, int width, bool hidden, bool hasTerminate, Value terminateWith)
|
Wire::Wire(std::string name, WireType type, int width, bool hidden, bool hasTerminate, Value terminateWith)
|
||||||
: name(name), type(type), width(width), hidden(hidden), hasTerminate(hasTerminate), terminateWith(terminateWith)
|
: name(name), type(type), width(width), hidden(hidden), hasTerminate(hasTerminate),
|
||||||
{}
|
terminateWith(terminateWith) {}
|
||||||
|
|
||||||
std::string Wire::getName() {
|
std::string Wire::getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Wire::getWidth() {
|
int Wire::getWidth() {
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Wire::isHidden() {
|
bool Wire::isHidden() {
|
||||||
return hidden;
|
return hidden;
|
||||||
}
|
}
|
||||||
|
@ -19,32 +21,39 @@ bool Wire::isHidden() {
|
||||||
bool Wire::hasTerminateWith() {
|
bool Wire::hasTerminateWith() {
|
||||||
return hasTerminate;
|
return hasTerminate;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value Wire::getTerminateWith() {
|
Value Wire::getTerminateWith() {
|
||||||
return terminateWith;
|
return terminateWith;
|
||||||
}
|
}
|
||||||
|
|
||||||
Wire::WireType Wire::getType() {
|
Wire::WireType Wire::getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bus::Bus(std::string name, std::string tooltip, BusType type, std::pair<int, int> count, std::vector<Wire> wires, std::optional<ui::Bus> displayBus)
|
Bus::Bus(std::string name, std::string tooltip, BusType type, std::pair<int, int> count, std::vector<Wire> wires,
|
||||||
: name(name), tooltip(tooltip), type(type), count(count), wires(wires), displayBus(displayBus)
|
std::optional<ui::Bus> displayBus)
|
||||||
{}
|
: name(name), tooltip(tooltip), type(type), count(count), wires(wires), displayBus(displayBus) {}
|
||||||
|
|
||||||
std::string Bus::getName() {
|
std::string Bus::getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Bus::getTooltip() {
|
std::string Bus::getTooltip() {
|
||||||
return tooltip;
|
return tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bus::BusType Bus::getType() {
|
Bus::BusType Bus::getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<int, int> Bus::getCount() {
|
std::pair<int, int> Bus::getCount() {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Wire> Bus::getWires() {
|
std::vector<Wire> Bus::getWires() {
|
||||||
return wires;
|
return wires;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ui::Bus> Bus::getDisplayBus() {
|
std::optional<ui::Bus> Bus::getDisplayBus() {
|
||||||
return displayBus;
|
return displayBus;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,7 @@
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
class Wire
|
class Wire {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
enum WireType {
|
enum WireType {
|
||||||
WIRE_DEFAULT,
|
WIRE_DEFAULT,
|
||||||
|
@ -34,15 +33,19 @@ public:
|
||||||
Wire(std::string name, WireType type, int width, bool hidden, bool hasTerminate, Value terminateWith);
|
Wire(std::string name, WireType type, int width, bool hidden, bool hasTerminate, Value terminateWith);
|
||||||
|
|
||||||
std::string getName();
|
std::string getName();
|
||||||
|
|
||||||
int getWidth();
|
int getWidth();
|
||||||
|
|
||||||
bool isHidden();
|
bool isHidden();
|
||||||
|
|
||||||
bool hasTerminateWith();
|
bool hasTerminateWith();
|
||||||
|
|
||||||
Value getTerminateWith();
|
Value getTerminateWith();
|
||||||
|
|
||||||
WireType getType();
|
WireType getType();
|
||||||
};
|
};
|
||||||
|
|
||||||
class Bus
|
class Bus {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
enum BusType {
|
enum BusType {
|
||||||
AUTOMATIC,
|
AUTOMATIC,
|
||||||
|
@ -59,13 +62,19 @@ private:
|
||||||
std::vector<Wire> wires;
|
std::vector<Wire> wires;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Bus(std::string name, std::string tooltip, BusType type, std::pair<int, int> count, std::vector<Wire> wires, std::optional<ui::Bus> display = std::nullopt);
|
Bus(std::string name, std::string tooltip, BusType type, std::pair<int, int> count, std::vector<Wire> wires,
|
||||||
|
std::optional<ui::Bus> display = std::nullopt);
|
||||||
|
|
||||||
std::string getName();
|
std::string getName();
|
||||||
|
|
||||||
std::string getTooltip();
|
std::string getTooltip();
|
||||||
|
|
||||||
BusType getType();
|
BusType getType();
|
||||||
|
|
||||||
std::pair<int, int> getCount();
|
std::pair<int, int> getCount();
|
||||||
|
|
||||||
std::vector<Wire> getWires();
|
std::vector<Wire> getWires();
|
||||||
|
|
||||||
std::optional<ui::Bus> getDisplayBus();
|
std::optional<ui::Bus> getDisplayBus();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,16 @@
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
void generateSchemaFile(std::string& librarySource, Schema *schema, std::ostream &buffer) {
|
void generate_schema(std::string &librarySource, Schema *schema, std::ostream &buffer) {
|
||||||
buffer << "@source " << librarySource << std::endl << std::endl;
|
buffer << "@source \"" << librarySource << "\"" << std::endl << std::endl;
|
||||||
|
|
||||||
buffer << "@schema {" << std::endl;
|
buffer << "@schema {" << std::endl;
|
||||||
|
|
||||||
for (auto &componentInstance: schema->componentInstances) {
|
for (auto &componentInstance: schema->componentInstances) {
|
||||||
buffer << "\t" << "@instance " << componentInstance->name << " " << componentInstance->component.getName() << " {" << std::endl;
|
buffer << "\t" << "@instance " << componentInstance->name << " " << componentInstance->component.getName()
|
||||||
buffer << "\t\t" << "@position (" << componentInstance->position.first << ", " << componentInstance->position.second << ")" << std::endl;
|
<< " {" << std::endl;
|
||||||
|
buffer << "\t\t" << "@position (" << componentInstance->position.first << ", "
|
||||||
|
<< componentInstance->position.second << ")" << std::endl;
|
||||||
|
|
||||||
for (auto &attribute: componentInstance->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;
|
||||||
|
@ -24,8 +26,10 @@ void generateSchemaFile(std::string& librarySource, Schema *schema, std::ostream
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &busInstance: schema->busInstances) {
|
for (auto &busInstance: schema->busInstances) {
|
||||||
buffer << "\t" << "@instance " << busInstance->name << " " << busInstance->bus.getName() << " {" << std::endl;
|
buffer << "\t" << "@instance " << busInstance->name << " " << busInstance->bus.getName() << " {"
|
||||||
buffer << "\t\t" << "@position (" << busInstance->position.first << ", " << busInstance->position.second << ")" << std::endl;
|
<< 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;
|
||||||
}
|
}
|
||||||
|
@ -33,23 +37,27 @@ void generateSchemaFile(std::string& librarySource, Schema *schema, std::ostream
|
||||||
for (auto &conn: schema->connections) {
|
for (auto &conn: schema->connections) {
|
||||||
auto busConn = dynamic_cast<domain::BusConnectionInstance *>(conn.get());
|
auto busConn = dynamic_cast<domain::BusConnectionInstance *>(conn.get());
|
||||||
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;
|
||||||
|
|
||||||
for (auto attribute: busConn->attributes) {
|
for (auto attribute: busConn->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;
|
buffer << "\t" << "}" << std::endl;
|
||||||
}
|
}
|
||||||
auto dirConn = dynamic_cast<domain::DirectConnectionInstance *>(conn.get());
|
auto dirConn = dynamic_cast<domain::DirectConnectionInstance *>(conn.get());
|
||||||
if (dirConn) {
|
if (dirConn) {
|
||||||
buffer << "\t" << "@connection (" << dirConn->instance->name << "." << dirConn->connection.getComponent().pin << ", "
|
buffer << "\t" << "@connection (" << dirConn->instance->name << "."
|
||||||
|
<< dirConn->connection.getComponent().pin << ", "
|
||||||
<< dirConn->bus->name << ", "
|
<< dirConn->bus->name << ", "
|
||||||
<< dirConn->secondInstance->name << "." << dirConn->connection.getSecondComponent()->pin
|
<< dirConn->secondInstance->name << "." << dirConn->connection.getSecondComponent()->pin
|
||||||
<< ") {" << std::endl;
|
<< ") {" << std::endl;
|
||||||
|
|
||||||
for (auto attribute: dirConn->attributes) {
|
for (auto attribute: dirConn->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;
|
buffer << "\t" << "}" << std::endl;
|
||||||
|
@ -67,7 +75,7 @@ void generateSubComponents(Schema *schema, map <string, string> &wires, ostream
|
||||||
|
|
||||||
void generateDisplay(Schema *schema, ostream &buffer);
|
void generateDisplay(Schema *schema, ostream &buffer);
|
||||||
|
|
||||||
void generateComdelFile(Schema *schema, Library &library, std::ostream &buffer) {
|
void generate_comdel(Schema *schema, Library &library, std::ostream &buffer) {
|
||||||
buffer << library.getHeader() << std::endl;
|
buffer << library.getHeader() << std::endl;
|
||||||
|
|
||||||
std::set<std::string> imports = createImports(schema);
|
std::set<std::string> imports = createImports(schema);
|
||||||
|
@ -94,13 +102,15 @@ void generateComdelFile(Schema *schema, Library &library, std::ostream &buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateBus(BusInstance *bus, ostream &buffer);
|
void generateBus(BusInstance *bus, ostream &buffer);
|
||||||
|
|
||||||
void generateConnection(ConnectionInstance *connection, ostream &buffer);
|
void generateConnection(ConnectionInstance *connection, ostream &buffer);
|
||||||
|
|
||||||
void generateDisplay(Schema *schema, ostream &buffer) {
|
void generateDisplay(Schema *schema, ostream &buffer) {
|
||||||
buffer << "\n\tdisplay {\n";
|
buffer << "\n\tdisplay {\n";
|
||||||
|
|
||||||
for (auto &component: schema->componentInstances) {
|
for (auto &component: schema->componentInstances) {
|
||||||
buffer << "\t\tcomponent { x: " << component->position.first << "; y: " << component->position.second << "; ref: \"" << component->name << "\"; }" << std::endl;
|
buffer << "\t\tcomponent { x: " << component->position.first << "; y: " << component->position.second
|
||||||
|
<< "; ref: \"" << component->name << "\"; }" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &bus: schema->busInstances) {
|
for (auto &bus: schema->busInstances) {
|
||||||
|
@ -185,7 +195,9 @@ std::set<std::string> createImports(Schema *schema) {
|
||||||
return importSet;
|
return importSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateAutomaticPin(DirectConnectionInstance *connection, string name, string pin, map<string, string> wireNames, stringstream &buffer);
|
void
|
||||||
|
generateAutomaticPin(DirectConnectionInstance *connection, string name, string pin, map<string, string> wireNames,
|
||||||
|
stringstream &buffer);
|
||||||
|
|
||||||
void generateSingleAutomaticPin(DirectConnectionInstance *instance, string name, string pin,
|
void generateSingleAutomaticPin(DirectConnectionInstance *instance, string name, string pin,
|
||||||
map<string, string> &wireNames,
|
map<string, string> &wireNames,
|
||||||
|
@ -292,7 +304,8 @@ void generateComponent(Schema *schema, map <string, string> &wires, ostream &buf
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateSingleAutomaticPin(DirectConnectionInstance *connection, string name, string pin, map <string, string> &wireNames, stringstream &buffer) {
|
void generateSingleAutomaticPin(DirectConnectionInstance *connection, string name, string pin,
|
||||||
|
map<string, string> &wireNames, stringstream &buffer) {
|
||||||
std::vector<Value> wires;
|
std::vector<Value> wires;
|
||||||
std::string selected;
|
std::string selected;
|
||||||
std::vector<Value> defaults;
|
std::vector<Value> defaults;
|
||||||
|
@ -309,7 +322,8 @@ void generateSingleAutomaticPin(DirectConnectionInstance *connection, string nam
|
||||||
for (int i = 0; i < wires.size(); i++) {
|
for (int i = 0; i < wires.size(); i++) {
|
||||||
if (wires[i].isType(Value::STRING)) {
|
if (wires[i].isType(Value::STRING)) {
|
||||||
if (wires[i].asString() == selected) {
|
if (wires[i].asString() == selected) {
|
||||||
buffer << wireNames[connection->bus->name + "." + connection->bus->bus.getWires()[0].getName()] << ", ";
|
buffer << wireNames[connection->bus->name + "." + connection->bus->bus.getWires()[0].getName()]
|
||||||
|
<< ", ";
|
||||||
} else {
|
} else {
|
||||||
buffer << defaults[i].stringify();
|
buffer << defaults[i].stringify();
|
||||||
}
|
}
|
||||||
|
@ -319,7 +333,9 @@ void generateSingleAutomaticPin(DirectConnectionInstance *connection, string nam
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateAutomaticPin(DirectConnectionInstance *connection, string name, string pin, map<string, string> wireNames, stringstream &buffer) {
|
void
|
||||||
|
generateAutomaticPin(DirectConnectionInstance *connection, string name, string pin, map<string, string> wireNames,
|
||||||
|
stringstream &buffer) {
|
||||||
std::vector<Value> wires;
|
std::vector<Value> wires;
|
||||||
if (connection->instance->name == name && connection->connection.getComponent().pin == pin) {
|
if (connection->instance->name == name && connection->connection.getComponent().pin == pin) {
|
||||||
wires = connection->connection.getWires();
|
wires = connection->connection.getWires();
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
void generateSchemaFile(std::string& librarySource, Schema *schema, std::ostream &buffer);
|
void generate_schema(std::string &librarySource, Schema *schema, std::ostream &buffer);
|
||||||
|
|
||||||
void generateComdelFile(Schema *schema, Library &library, std::ostream &buffer);
|
void generate_comdel(Schema *schema, Library &library, std::ostream &buffer);
|
||||||
|
|
||||||
} // domain
|
} // domain
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,206 @@
|
||||||
|
#include "comdel_validator.h"
|
||||||
|
#include "library.h"
|
||||||
|
|
||||||
|
namespace domain {
|
||||||
|
|
||||||
|
std::vector<ValidationError> ComdelValidator::validateSchema(Schema &schema, ValidationContext context) {
|
||||||
|
std::vector<ValidationError> errors;
|
||||||
|
|
||||||
|
context.instance = nullptr;
|
||||||
|
context.attribute = nullptr;
|
||||||
|
|
||||||
|
for (auto &instance: schema.componentInstances) {
|
||||||
|
auto result = validateComponent(instance.get(), context);
|
||||||
|
errors.insert(errors.end(), result.begin(), result.end());
|
||||||
|
}
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ValidationError>
|
||||||
|
ComdelValidator::validateInstanceCount(Schema &schema, Library &library, ValidationContext context) {
|
||||||
|
std::vector<ValidationError> errors;
|
||||||
|
|
||||||
|
// validate instance count
|
||||||
|
std::map<std::string, int> instanceMap;
|
||||||
|
for (auto &inst: schema.componentInstances) {
|
||||||
|
instanceMap[inst->component.getName()]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto comp: library.getComponents()) {
|
||||||
|
int count = instanceMap[comp.getName()];
|
||||||
|
|
||||||
|
context.attributes["componentName"] = Value::fromString(comp.getName());
|
||||||
|
context.attributes["min"] = Value::fromInt(comp.getCount().first);
|
||||||
|
context.attributes["max"] = Value::fromInt(comp.getCount().second);
|
||||||
|
context.attributes["count"] = Value::fromInt(count);
|
||||||
|
|
||||||
|
if (count < comp.getCount().first) {
|
||||||
|
auto message = populateMessage(
|
||||||
|
"Not enough instances of component '{componentName}' required at least {min}, found {count}",
|
||||||
|
context);
|
||||||
|
errors.push_back(ValidationError{nullptr, nullptr, Action::ERROR, message});
|
||||||
|
} else if (count > comp.getCount().second) {
|
||||||
|
auto message = populateMessage(
|
||||||
|
"To many instances of component '{componentName}' allow at most {max}, found {count}", context);
|
||||||
|
errors.push_back(ValidationError{nullptr, nullptr, Action::ERROR, message});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// validate bus instance count
|
||||||
|
std::map<std::string, int> busInstanceMap;
|
||||||
|
for (auto &inst: schema.busInstances) {
|
||||||
|
busInstanceMap[inst->bus.getName()]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto bus: library.getBuses()) {
|
||||||
|
int count = busInstanceMap[bus.getName()];
|
||||||
|
|
||||||
|
context.attributes["busName"] = Value::fromString(bus.getName());
|
||||||
|
context.attributes["min"] = Value::fromInt(bus.getCount().first);
|
||||||
|
context.attributes["max"] = Value::fromInt(bus.getCount().second);
|
||||||
|
context.attributes["count"] = Value::fromInt(count);
|
||||||
|
|
||||||
|
if (count < bus.getCount().first) {
|
||||||
|
auto message = populateMessage(
|
||||||
|
"Not enough instances of bus '{busName}' required at least {min}, found {count}", context);
|
||||||
|
errors.push_back(ValidationError{nullptr, nullptr, Action::ERROR, message});
|
||||||
|
} else if (count > bus.getCount().second) {
|
||||||
|
auto message = populateMessage(
|
||||||
|
"To many instances of bus '{busName}' allow at most {max}, found {count}", context);
|
||||||
|
errors.push_back(ValidationError{nullptr, nullptr, Action::ERROR, message});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ValidationError>
|
||||||
|
ComdelValidator::validatePinConnections(Schema &schema, Library &library, ValidationContext context) {
|
||||||
|
std::vector<ValidationError> errors;
|
||||||
|
|
||||||
|
for (auto &inst: schema.componentInstances) {
|
||||||
|
for (auto &pin: inst->component.getPins()) {
|
||||||
|
if (pin.getConnection().getType() == PinConnection::REQUIRED) {
|
||||||
|
if (!connectionExists(schema, inst, pin)) {
|
||||||
|
context.instance = inst.get();
|
||||||
|
context.attributes["instanceName"] = Value::fromString(inst->name);
|
||||||
|
auto message = populateMessage(pin.getConnection().getMessage(), context);
|
||||||
|
errors.push_back(ValidationError{nullptr, nullptr, Action::ERROR, message});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ValidationError>
|
||||||
|
ComdelValidator::validateComponent(ComponentInstance *instance, ValidationContext context) {
|
||||||
|
std::vector<ValidationError> errors;
|
||||||
|
|
||||||
|
context.instance = instance;
|
||||||
|
context.attributes.clear();
|
||||||
|
|
||||||
|
for (auto &attribute: instance->attributes) {
|
||||||
|
context.attributes[attribute.name] = attribute.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &rule: instance->component.getRules()) {
|
||||||
|
auto result = validateRule(rule, context);
|
||||||
|
if (result) {
|
||||||
|
errors.push_back(*result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &attribute: instance->attributes) {
|
||||||
|
auto result = validateAttribute(&attribute, context);
|
||||||
|
errors.insert(errors.end(), result.begin(), result.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ValidationError>
|
||||||
|
ComdelValidator::validateAttribute(InstanceAttribute *attribute, ValidationContext context) {
|
||||||
|
std::vector<ValidationError> errors;
|
||||||
|
if (attribute->attribute.getPopup()) {
|
||||||
|
Popup popup = *attribute->attribute.getPopup();
|
||||||
|
context.attribute = attribute;
|
||||||
|
context.attributes = std::map<std::string, Value>{{attribute->name, attribute->value}};
|
||||||
|
|
||||||
|
for (auto &rule: popup.getRules()) {
|
||||||
|
auto result = validateRule(rule, context);
|
||||||
|
if (result) {
|
||||||
|
errors.push_back(*result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<ValidationError> ComdelValidator::validateRule(Rule rule, ValidationContext context) {
|
||||||
|
RuleContext ruleContext;
|
||||||
|
ruleContext.addressSpaces = context.addressSpaces;
|
||||||
|
ruleContext.attributes = context.attributes;
|
||||||
|
ruleContext.function = validators;
|
||||||
|
auto action = rule.evaluate(ruleContext);
|
||||||
|
if (action) {
|
||||||
|
std::string message = this->populateMessage(action->getMessage(), context);
|
||||||
|
return ValidationError{context.instance, context.attribute, action->getType(), message};
|
||||||
|
}
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ComdelValidator::populateMessage(string source, ValidationContext context) {
|
||||||
|
for (auto &[key, value]: context.attributes) {
|
||||||
|
source = replacePlaceholder(source, key, value);
|
||||||
|
}
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
string ComdelValidator::replacePlaceholder(string source, string key, Value value) {
|
||||||
|
key = "{" + key + "}";
|
||||||
|
auto placeholderValue = value.string();
|
||||||
|
|
||||||
|
auto found = source.find(key);
|
||||||
|
while (found != string::npos) {
|
||||||
|
source.replace(found, key.length(), placeholderValue);
|
||||||
|
found = source.find(key);
|
||||||
|
}
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ComdelValidator::connectionExists(Schema &schema, shared_ptr<ComponentInstance> &component, Pin &pin) {
|
||||||
|
for (auto conn: schema.connections) {
|
||||||
|
auto busConnection = dynamic_cast<BusConnectionInstance *>(conn.get());
|
||||||
|
if (busConnection != nullptr) {
|
||||||
|
if (busConnection->instance->name == component->name &&
|
||||||
|
busConnection->connection.getComponent().pin == pin.getName()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto directConnection = dynamic_cast<DirectConnectionInstance *>(conn.get());
|
||||||
|
if (directConnection != nullptr) {
|
||||||
|
if (directConnection->instance->name == component->name &&
|
||||||
|
busConnection->connection.getComponent().pin == pin.getName()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (directConnection->secondInstance->name == component->name &&
|
||||||
|
busConnection->connection.getSecondComponent()->pin == pin.getName()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComdelValidator::ComdelValidator(std::vector<FunctionValidator *> validators) {
|
||||||
|
for (auto *validator: validators) {
|
||||||
|
validator->clear();
|
||||||
|
this->validators.insert(std::make_pair(validator->getName(), validator));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
#ifndef COMDEL_VALIDATOR_H
|
||||||
|
#define COMDEL_VALIDATOR_H
|
||||||
|
|
||||||
|
#include "instance.h"
|
||||||
|
#include "schema.h"
|
||||||
|
#include "library.h"
|
||||||
|
|
||||||
|
namespace domain {
|
||||||
|
|
||||||
|
struct ValidationError {
|
||||||
|
ComponentInstance *instance;
|
||||||
|
InstanceAttribute *attribute;
|
||||||
|
Action::ActionType type;
|
||||||
|
std::string message;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ValidationContext {
|
||||||
|
ComponentInstance *instance;
|
||||||
|
InstanceAttribute *attribute;
|
||||||
|
std::map<std::string, AddressSpace> addressSpaces;
|
||||||
|
std::map<std::string, Value> attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ComdelValidator {
|
||||||
|
public:
|
||||||
|
std::vector<ValidationError> validateSchema(Schema &schema, ValidationContext context);
|
||||||
|
|
||||||
|
std::vector<ValidationError> validateComponent(ComponentInstance *instance, ValidationContext context);
|
||||||
|
|
||||||
|
std::vector<ValidationError> validateAttribute(InstanceAttribute *attribute, ValidationContext context);
|
||||||
|
|
||||||
|
std::optional<ValidationError> validateRule(Rule rule, ValidationContext context);
|
||||||
|
|
||||||
|
std::vector<ValidationError> validateInstanceCount(Schema &schema, Library &library, ValidationContext context);
|
||||||
|
|
||||||
|
std::vector<ValidationError>
|
||||||
|
validatePinConnections(Schema &schema, Library &library, ValidationContext context);
|
||||||
|
|
||||||
|
ComdelValidator(std::vector<FunctionValidator *> validators);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<std::string, FunctionValidator *> validators;
|
||||||
|
|
||||||
|
std::string populateMessage(string message, ValidationContext context);
|
||||||
|
|
||||||
|
string replacePlaceholder(string message, const string name, Value value);
|
||||||
|
|
||||||
|
bool connectionExists(Schema &schema, shared_ptr<ComponentInstance> &component, Pin &pin);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif //COMDEL_VALIDATOR_H
|
|
@ -1,187 +0,0 @@
|
||||||
#include "comdelvalidator.h"
|
|
||||||
#include "library.h"
|
|
||||||
|
|
||||||
namespace domain {
|
|
||||||
|
|
||||||
std::vector<ValidationError> ComdelValidator::validateSchema(Schema &schema, ValidationContext context) {
|
|
||||||
std::vector<ValidationError> errors;
|
|
||||||
|
|
||||||
context.instance = nullptr;
|
|
||||||
context.attribute = nullptr;
|
|
||||||
|
|
||||||
for(auto &instance: schema.componentInstances) {
|
|
||||||
auto result = validateComponent(instance.get(), context);
|
|
||||||
errors.insert(errors.end(), result.begin(), result.end());
|
|
||||||
}
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<ValidationError> ComdelValidator::validateInstanceCount(Schema& schema, Library& library, ValidationContext context) {
|
|
||||||
std::vector<ValidationError> errors;
|
|
||||||
|
|
||||||
// validate instance count
|
|
||||||
std::map<std::string, int> instanceMap;
|
|
||||||
for(auto& inst: schema.componentInstances) {
|
|
||||||
instanceMap[inst->component.getName()]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto comp: library.getComponents()) {
|
|
||||||
int count = instanceMap[comp.getName()];
|
|
||||||
|
|
||||||
context.attributes["componentName"] = Value::fromString(comp.getName());
|
|
||||||
context.attributes["min"] = Value::fromInt(comp.getCount().first);
|
|
||||||
context.attributes["max"] = Value::fromInt(comp.getCount().second);
|
|
||||||
context.attributes["count"] = Value::fromInt(count);
|
|
||||||
|
|
||||||
if(count < comp.getCount().first) {
|
|
||||||
auto message = populateMessage("Not enough instances of component '{componentName}' required at least {min}, found {count}", context);
|
|
||||||
errors.push_back(ValidationError{nullptr, nullptr, Action::ERROR, message});
|
|
||||||
} else if(count > comp.getCount().second) {
|
|
||||||
auto message = populateMessage("To many instances of component '{componentName}' allow at most {max}, found {count}", context);
|
|
||||||
errors.push_back(ValidationError{nullptr, nullptr, Action::ERROR, message});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// validate bus instance count
|
|
||||||
std::map<std::string, int> busInstanceMap;
|
|
||||||
for(auto& inst: schema.busInstances) {
|
|
||||||
busInstanceMap[inst->bus.getName()]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto bus: library.getBuses()) {
|
|
||||||
int count = busInstanceMap[bus.getName()];
|
|
||||||
|
|
||||||
context.attributes["busName"] = Value::fromString(bus.getName());
|
|
||||||
context.attributes["min"] = Value::fromInt(bus.getCount().first);
|
|
||||||
context.attributes["max"] = Value::fromInt(bus.getCount().second);
|
|
||||||
context.attributes["count"] = Value::fromInt(count);
|
|
||||||
|
|
||||||
if(count < bus.getCount().first) {
|
|
||||||
auto message = populateMessage("Not enough instances of bus '{busName}' required at least {min}, found {count}", context);
|
|
||||||
errors.push_back(ValidationError{nullptr, nullptr, Action::ERROR, message});
|
|
||||||
} else if(count > bus.getCount().second) {
|
|
||||||
auto message = populateMessage("To many instances of bus '{busName}' allow at most {max}, found {count}", context);
|
|
||||||
errors.push_back(ValidationError{nullptr, nullptr, Action::ERROR, message});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<ValidationError> ComdelValidator::validatePinConnections(Schema &schema, Library &library, ValidationContext context) {
|
|
||||||
std::vector<ValidationError> errors;
|
|
||||||
|
|
||||||
for(auto& inst: schema.componentInstances) {
|
|
||||||
for(auto& pin: inst->component.getPins()) {
|
|
||||||
if(pin.getConnection().getType() == PinConnection::REQUIRED) {
|
|
||||||
if(!connectionExists(schema, inst, pin)) {
|
|
||||||
context.instance = inst.get();
|
|
||||||
context.attributes["instanceName"] = Value::fromString(inst->name);
|
|
||||||
auto message = populateMessage(pin.getConnection().getMessage(), context);
|
|
||||||
errors.push_back(ValidationError{nullptr, nullptr, Action::ERROR, message});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<ValidationError> ComdelValidator::validateComponent(ComponentInstance* instance, ValidationContext context) {
|
|
||||||
std::vector<ValidationError> errors;
|
|
||||||
|
|
||||||
context.instance = instance;
|
|
||||||
context.attributes.clear();
|
|
||||||
|
|
||||||
for(auto &attribute: instance->attributes) {
|
|
||||||
context.attributes[attribute.name] = attribute.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto &rule: instance->component.getRules()) {
|
|
||||||
auto result = validateRule(rule, context);
|
|
||||||
if(result) {
|
|
||||||
errors.push_back(*result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto &attribute: instance->attributes) {
|
|
||||||
auto result = validateAttribute(&attribute, context);
|
|
||||||
errors.insert(errors.end(), result.begin(), result.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<ValidationError> ComdelValidator::validateAttribute(InstanceAttribute *attribute, ValidationContext context) {
|
|
||||||
std::vector<ValidationError> errors;
|
|
||||||
if(attribute->attribute.getPopup()) {
|
|
||||||
Popup popup = *attribute->attribute.getPopup();
|
|
||||||
context.attribute = attribute;
|
|
||||||
context.attributes = std::map<std::string, Value>{{attribute->name, attribute->value}};
|
|
||||||
|
|
||||||
for(auto &rule: popup.getRules()) {
|
|
||||||
auto result = validateRule(rule, context);
|
|
||||||
if(result) {
|
|
||||||
errors.push_back(*result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<ValidationError> ComdelValidator::validateRule(Rule rule, ValidationContext context) {
|
|
||||||
RuleContext ruleContext;
|
|
||||||
ruleContext.addressSpaces = context.addressSpaces;
|
|
||||||
ruleContext.attributes = context.attributes;
|
|
||||||
ruleContext.function = validators;
|
|
||||||
auto action = rule.evaluate(ruleContext);
|
|
||||||
if (action) {
|
|
||||||
std::string message = this->populateMessage(action->getMessage(), context);
|
|
||||||
return ValidationError{context.instance, context.attribute, action->getType(), message};
|
|
||||||
}
|
|
||||||
return nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ComdelValidator::populateMessage(string source, ValidationContext context) {
|
|
||||||
for(auto &[key, value]: context.attributes) {
|
|
||||||
source = replacePlaceholder(source, key, value);
|
|
||||||
}
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
string ComdelValidator::replacePlaceholder(string source, string key, Value value) {
|
|
||||||
key = "{" + key + "}";
|
|
||||||
auto placeholderValue = value.string();
|
|
||||||
|
|
||||||
auto found = source.find(key);
|
|
||||||
while(found != string::npos) {
|
|
||||||
source.replace(found, key.length(), placeholderValue);
|
|
||||||
found = source.find(key);
|
|
||||||
}
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ComdelValidator::connectionExists(Schema &schema, shared_ptr<ComponentInstance> &component, Pin &pin) {
|
|
||||||
for(auto conn: schema.connections) {
|
|
||||||
auto busConnection = dynamic_cast<BusConnectionInstance*>(conn.get());
|
|
||||||
if(busConnection != nullptr) {
|
|
||||||
if(busConnection->instance->name == component->name && busConnection->connection.getComponent().pin == pin.getName()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto directConnection = dynamic_cast<DirectConnectionInstance*>(conn.get());
|
|
||||||
if(directConnection != nullptr) {
|
|
||||||
if(directConnection->instance->name == component->name && busConnection->connection.getComponent().pin == pin.getName()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if(directConnection->secondInstance->name == component->name && busConnection->connection.getSecondComponent()->pin == pin.getName()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
#ifndef COMDEL_VALIDATOR_H
|
|
||||||
#define COMDEL_VALIDATOR_H
|
|
||||||
|
|
||||||
#include "instance.h"
|
|
||||||
#include "schema.h"
|
|
||||||
#include "library.h"
|
|
||||||
|
|
||||||
namespace domain {
|
|
||||||
|
|
||||||
struct ValidationError
|
|
||||||
{
|
|
||||||
ComponentInstance *instance;
|
|
||||||
InstanceAttribute *attribute;
|
|
||||||
Action::ActionType type;
|
|
||||||
std::string message;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ValidationContext {
|
|
||||||
ComponentInstance *instance;
|
|
||||||
InstanceAttribute *attribute;
|
|
||||||
std::map<std::string, AddressSpace> addressSpaces;
|
|
||||||
std::map<std::string, Value> attributes;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ComdelValidator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::vector<ValidationError> validateSchema(Schema& schema, ValidationContext context);
|
|
||||||
std::vector<ValidationError> validateComponent(ComponentInstance *instance, ValidationContext context);
|
|
||||||
std::vector<ValidationError> validateAttribute(InstanceAttribute *attribute, ValidationContext context);
|
|
||||||
std::optional<ValidationError> validateRule(Rule rule, ValidationContext context);
|
|
||||||
|
|
||||||
std::vector<ValidationError> validateInstanceCount(Schema &schema, Library& library, ValidationContext context);
|
|
||||||
std::vector<ValidationError> validatePinConnections(Schema &schema, Library& library, ValidationContext context);
|
|
||||||
|
|
||||||
ComdelValidator(std::vector<FunctionValidator*> validators) {
|
|
||||||
for(auto* validator: validators) {
|
|
||||||
validator->clear();
|
|
||||||
this->validators.insert(std::make_pair(validator->getName(), validator));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::map<std::string, FunctionValidator*> validators;
|
|
||||||
|
|
||||||
std::string populateMessage(string message, ValidationContext context);
|
|
||||||
|
|
||||||
string replacePlaceholder(string message, const string name, Value value);
|
|
||||||
|
|
||||||
bool connectionExists(Schema &schema, shared_ptr <ComponentInstance> &component, Pin &pin);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif //COMDEL_VALIDATOR_H
|
|
|
@ -5,30 +5,37 @@ namespace domain {
|
||||||
Component::Component(string name, string tooltip, string source, ComponentType type,
|
Component::Component(string name, string tooltip, string source, ComponentType type,
|
||||||
vector<Rule> rules, string instanceName, pair<int, int> count, Display display,
|
vector<Rule> rules, string instanceName, pair<int, int> count, Display display,
|
||||||
vector<Pin> pins, vector<Attribute> attributes)
|
vector<Pin> pins, vector<Attribute> attributes)
|
||||||
: name(name), tooltip(tooltip), source(source), type(type), rules(rules), instanceName(instanceName), count(count), display(display), pins(pins), attributes(attributes)
|
: name(name), tooltip(tooltip), source(source), type(type), rules(rules), instanceName(instanceName),
|
||||||
{}
|
count(count), display(display), pins(pins), attributes(attributes) {}
|
||||||
|
|
||||||
std::string Component::getName() {
|
std::string Component::getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Component::getTooltip() {
|
std::string Component::getTooltip() {
|
||||||
return tooltip;
|
return tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Component::getSource() {
|
std::string Component::getSource() {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
Component::ComponentType Component::getType() {
|
Component::ComponentType Component::getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Rule> Component::getRules() {
|
std::vector<Rule> Component::getRules() {
|
||||||
return rules;
|
return rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Component::getInstanceName() {
|
std::string Component::getInstanceName() {
|
||||||
return instanceName;
|
return instanceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<int, int> Component::getCount() {
|
std::pair<int, int> Component::getCount() {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
Display Component::getDisplay() {
|
Display Component::getDisplay() {
|
||||||
return display;
|
return display;
|
||||||
}
|
}
|
||||||
|
@ -36,10 +43,11 @@ Display Component::getDisplay() {
|
||||||
std::vector<Pin> Component::getPins() {
|
std::vector<Pin> Component::getPins() {
|
||||||
return pins;
|
return pins;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pin Component::getPin(std::string pin) {
|
Pin Component::getPin(std::string pin) {
|
||||||
for(uint i=0; i<pins.size(); i++) {
|
for (auto & p: pins) {
|
||||||
if(pins[i].getName() == pin) {
|
if (p.getName() == pin) {
|
||||||
return pins[i];
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
|
@ -57,23 +65,29 @@ bool Component::hasPin(std::string name) {
|
||||||
std::vector<Attribute> Component::getAttributes() {
|
std::vector<Attribute> Component::getAttributes() {
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
Attribute Component::getAttribute(std::string attribute) {
|
Attribute Component::getAttribute(std::string attribute) {
|
||||||
for(uint i=0; i<attributes.size(); i++) {
|
for (auto & attr : attributes) {
|
||||||
if(attributes[i].getName() == attribute) {
|
if (attr.getName() == attribute) {
|
||||||
return attributes[i];
|
return attr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Component::hasAttribute(std::string name, Value::ValueType type) {
|
bool Component::hasAttribute(std::string name, Value::ValueType type) {
|
||||||
for(uint i=0; i<attributes.size(); i++) {
|
for (auto & attribute : attributes) {
|
||||||
if(attributes[i].getName() == name && attributes[i].getDefault().getType() == type) {
|
if (attribute.getName() == name && attribute.getDefault().getType() == type) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(attributes[i].getName() == name && (type == Value::NIL && (attributes[i].getDefault().getType() == Value::MEMORY_REFERENCE || attributes[i].getDefault().getType() == Value::WIRE_REFERENCE))) {
|
if (attribute.getName() == name && (type == Value::NIL &&
|
||||||
|
(attribute.getDefault().getType() == Value::MEMORY_REFERENCE ||
|
||||||
|
attribute.getDefault().getType() == Value::WIRE_REFERENCE))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(attributes[i].getName() == name && (type == Value::UNDEFINED && (attributes[i].getDefault().getType() == Value::MEMORY_REFERENCE || attributes[i].getDefault().getType() == Value::WIRE_REFERENCE))) {
|
if (attribute.getName() == name && (type == Value::UNDEFINED &&
|
||||||
|
(attribute.getDefault().getType() == Value::MEMORY_REFERENCE ||
|
||||||
|
attribute.getDefault().getType() == Value::WIRE_REFERENCE))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,5 +95,4 @@ bool Component::hasAttribute(std::string name, Value::ValueType type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -13,8 +13,7 @@ namespace domain {
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class Component
|
class Component {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
enum ComponentType {
|
enum ComponentType {
|
||||||
OTHER,
|
OTHER,
|
||||||
|
@ -42,19 +41,29 @@ public:
|
||||||
vector<Pin> pins, vector<Attribute> attributes);
|
vector<Pin> pins, vector<Attribute> attributes);
|
||||||
|
|
||||||
std::string getName();
|
std::string getName();
|
||||||
|
|
||||||
std::string getTooltip();
|
std::string getTooltip();
|
||||||
|
|
||||||
std::string getSource();
|
std::string getSource();
|
||||||
|
|
||||||
ComponentType getType();
|
ComponentType getType();
|
||||||
|
|
||||||
std::vector<Rule> getRules();
|
std::vector<Rule> getRules();
|
||||||
|
|
||||||
std::string getInstanceName();
|
std::string getInstanceName();
|
||||||
|
|
||||||
std::pair<int, int> getCount();
|
std::pair<int, int> getCount();
|
||||||
|
|
||||||
Display getDisplay();
|
Display getDisplay();
|
||||||
|
|
||||||
std::vector<Pin> getPins();
|
std::vector<Pin> getPins();
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
bool hasAttribute(std::string name, Value::ValueType type);
|
bool hasAttribute(std::string name, Value::ValueType type);
|
||||||
|
|
||||||
bool hasPin(std::string name);
|
bool hasPin(std::string name);
|
||||||
|
|
|
@ -5,12 +5,13 @@ namespace domain {
|
||||||
Connection::Connection(ConnectionComponent first, std::optional<ConnectionComponent> second,
|
Connection::Connection(ConnectionComponent first, std::optional<ConnectionComponent> second,
|
||||||
std::string bus, std::vector<Attribute> attributes,
|
std::string bus, std::vector<Attribute> attributes,
|
||||||
std::vector<Value> firstWires, std::optional<std::vector<Value>> secondWires)
|
std::vector<Value> firstWires, std::optional<std::vector<Value>> secondWires)
|
||||||
: first(first), second(second), bus(bus), attributes(attributes), firstWires(firstWires), secondWires(secondWires)
|
: first(first), second(second), bus(bus), attributes(attributes), firstWires(firstWires),
|
||||||
{}
|
secondWires(secondWires) {}
|
||||||
|
|
||||||
ConnectionComponent Connection::getComponent() {
|
ConnectionComponent Connection::getComponent() {
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ConnectionComponent> Connection::getSecondComponent() {
|
std::optional<ConnectionComponent> Connection::getSecondComponent() {
|
||||||
return second;
|
return second;
|
||||||
}
|
}
|
||||||
|
@ -22,9 +23,11 @@ std::string Connection::getBus() {
|
||||||
std::vector<Attribute> Connection::getAttributes() {
|
std::vector<Attribute> Connection::getAttributes() {
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Value> Connection::getWires() {
|
std::vector<Value> Connection::getWires() {
|
||||||
return firstWires;
|
return firstWires;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::vector<Value>> Connection::getSecondWires() {
|
std::optional<std::vector<Value>> Connection::getSecondWires() {
|
||||||
return secondWires;
|
return secondWires;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,21 +8,19 @@
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
struct ConnectionComponent
|
struct ConnectionComponent {
|
||||||
{
|
|
||||||
std::string component;
|
std::string component;
|
||||||
std::string pin;
|
std::string pin;
|
||||||
|
|
||||||
bool operator==(const ConnectionComponent& rhs) const
|
bool operator==(const ConnectionComponent &rhs) const {
|
||||||
{
|
|
||||||
return (component == rhs.component) && (pin == rhs.pin);
|
return (component == rhs.component) && (pin == rhs.pin);
|
||||||
}
|
}
|
||||||
bool operator!=(const ConnectionComponent& rhs) const
|
|
||||||
{
|
bool operator!=(const ConnectionComponent &rhs) const {
|
||||||
return !operator==(rhs);
|
return !operator==(rhs);
|
||||||
}
|
}
|
||||||
bool operator<(const ConnectionComponent& rhs) const
|
|
||||||
{
|
bool operator<(const ConnectionComponent &rhs) const {
|
||||||
if (component < rhs.component) {
|
if (component < rhs.component) {
|
||||||
return true;
|
return true;
|
||||||
} else if (component == rhs.component) {
|
} else if (component == rhs.component) {
|
||||||
|
@ -34,8 +32,7 @@ struct ConnectionComponent
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Connection
|
class Connection {
|
||||||
{
|
|
||||||
ConnectionComponent first;
|
ConnectionComponent first;
|
||||||
std::optional<ConnectionComponent> second;
|
std::optional<ConnectionComponent> second;
|
||||||
std::string bus;
|
std::string bus;
|
||||||
|
@ -49,12 +46,16 @@ public:
|
||||||
std::vector<Value> firstWires, std::optional<std::vector<Value>> secondWires);
|
std::vector<Value> firstWires, std::optional<std::vector<Value>> secondWires);
|
||||||
|
|
||||||
bool isConnecting(ConnectionComponent first);
|
bool isConnecting(ConnectionComponent first);
|
||||||
|
|
||||||
bool isConnecting(ConnectionComponent first, std::string bus);
|
bool isConnecting(ConnectionComponent first, std::string bus);
|
||||||
|
|
||||||
bool isConnecting(ConnectionComponent first, std::string bus, ConnectionComponent second);
|
bool isConnecting(ConnectionComponent first, std::string bus, ConnectionComponent second);
|
||||||
|
|
||||||
bool isConnecting(ConnectionComponent first, ConnectionComponent second);
|
bool isConnecting(ConnectionComponent first, ConnectionComponent second);
|
||||||
|
|
||||||
|
|
||||||
ConnectionComponent getComponent();
|
ConnectionComponent getComponent();
|
||||||
|
|
||||||
std::optional<ConnectionComponent> getSecondComponent();
|
std::optional<ConnectionComponent> getSecondComponent();
|
||||||
|
|
||||||
std::string getBus();
|
std::string getBus();
|
||||||
|
@ -62,9 +63,11 @@ public:
|
||||||
std::vector<Attribute> getAttributes();
|
std::vector<Attribute> getAttributes();
|
||||||
|
|
||||||
std::vector<Value> getWires();
|
std::vector<Value> getWires();
|
||||||
|
|
||||||
std::optional<std::vector<Value>> getSecondWires();
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "connection_instance.h"
|
||||||
|
|
||||||
|
namespace domain {
|
||||||
|
|
||||||
|
|
||||||
|
ConnectionInstance::ConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute> attributes,
|
||||||
|
Connection connection)
|
||||||
|
: instance(instance), attributes(attributes), connection(connection) {}
|
||||||
|
|
||||||
|
InstanceAttribute ConnectionInstance::getAttribute(string attribute) {
|
||||||
|
for (auto &attr: attributes) {
|
||||||
|
if (attr.name == attribute) {
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw std::exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BusConnectionInstance::BusConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute> attributes,
|
||||||
|
BusInstance *bus, Connection connection)
|
||||||
|
: ConnectionInstance(instance, attributes, connection), bus(bus) {}
|
||||||
|
|
||||||
|
DirectConnectionInstance::DirectConnectionInstance(ComponentInstance *instance, ComponentInstance *secondInstance,
|
||||||
|
std::vector<InstanceAttribute> attributes, BusInstance *bus,
|
||||||
|
Connection connection)
|
||||||
|
: ConnectionInstance(instance, attributes, connection), secondInstance(secondInstance), bus(bus) {}
|
||||||
|
|
||||||
|
} // namespace domain
|
|
@ -0,0 +1,49 @@
|
||||||
|
#ifndef DOMAIN_CONNECTION_INSTANCE_H
|
||||||
|
#define DOMAIN_CONNECTION_INSTANCE_H
|
||||||
|
|
||||||
|
#include "connection.h"
|
||||||
|
#include "instance.h"
|
||||||
|
|
||||||
|
namespace domain {
|
||||||
|
|
||||||
|
class ConnectionInstance {
|
||||||
|
public:
|
||||||
|
ComponentInstance *instance;
|
||||||
|
Connection connection;
|
||||||
|
|
||||||
|
virtual ~ConnectionInstance() = default;
|
||||||
|
|
||||||
|
std::vector<InstanceAttribute> attributes;
|
||||||
|
|
||||||
|
std::pair<int, int> start;
|
||||||
|
std::pair<int, int> end;
|
||||||
|
|
||||||
|
ConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute> attributes,
|
||||||
|
Connection connection);
|
||||||
|
|
||||||
|
InstanceAttribute getAttribute(string attribute);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class BusConnectionInstance : public ConnectionInstance {
|
||||||
|
public:
|
||||||
|
BusInstance *bus;
|
||||||
|
|
||||||
|
BusConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute> attributes, BusInstance *bus,
|
||||||
|
Connection connection);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class DirectConnectionInstance : public ConnectionInstance {
|
||||||
|
public:
|
||||||
|
BusInstance *bus;
|
||||||
|
ComponentInstance *secondInstance;
|
||||||
|
|
||||||
|
DirectConnectionInstance(ComponentInstance *instance, ComponentInstance *secondsInstance,
|
||||||
|
std::vector<InstanceAttribute> attributes, BusInstance *bus, Connection connection);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace domain
|
||||||
|
|
||||||
|
#endif // DOMAIN_CONNECTIONINSTANCE_H
|
|
@ -1,28 +0,0 @@
|
||||||
#include "connectioninstance.h"
|
|
||||||
|
|
||||||
namespace domain {
|
|
||||||
|
|
||||||
|
|
||||||
ConnectionInstance::ConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute> attributes, Connection connection)
|
|
||||||
: instance(instance), attributes(attributes), connection(connection)
|
|
||||||
{}
|
|
||||||
|
|
||||||
InstanceAttribute ConnectionInstance::getAttribute(string attribute) {
|
|
||||||
for(auto& attr: attributes) {
|
|
||||||
if(attr.name == attribute) {
|
|
||||||
return attr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw std::exception();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BusConnectionInstance::BusConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute> attributes, BusInstance *bus, Connection connection)
|
|
||||||
: ConnectionInstance(instance, attributes, connection), bus(bus)
|
|
||||||
{}
|
|
||||||
|
|
||||||
DirectConnectionInstance::DirectConnectionInstance(ComponentInstance *instance, ComponentInstance *secondInstance, std::vector<InstanceAttribute> attributes, BusInstance *bus, Connection connection)
|
|
||||||
: ConnectionInstance(instance, attributes, connection), secondInstance(secondInstance), bus(bus)
|
|
||||||
{}
|
|
||||||
|
|
||||||
} // namespace domain
|
|
|
@ -1,50 +0,0 @@
|
||||||
#ifndef DOMAIN_CONNECTION_INSTANCE_H
|
|
||||||
#define DOMAIN_CONNECTION_INSTANCE_H
|
|
||||||
|
|
||||||
#include "connection.h"
|
|
||||||
#include "instance.h"
|
|
||||||
#include "wireinstance.h"
|
|
||||||
|
|
||||||
namespace domain {
|
|
||||||
|
|
||||||
class ConnectionInstance
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ComponentInstance *instance;
|
|
||||||
Connection connection;
|
|
||||||
|
|
||||||
virtual ~ConnectionInstance() = default;
|
|
||||||
|
|
||||||
std::vector<InstanceAttribute> attributes;
|
|
||||||
|
|
||||||
std::pair<int, int> start;
|
|
||||||
std::pair<int, int> end;
|
|
||||||
|
|
||||||
ConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute> attributes, Connection connection);
|
|
||||||
|
|
||||||
InstanceAttribute getAttribute(string attribute);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class BusConnectionInstance: public ConnectionInstance
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BusInstance *bus;
|
|
||||||
|
|
||||||
BusConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute> attributes, BusInstance *bus, Connection connection);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class DirectConnectionInstance: public ConnectionInstance
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BusInstance *bus;
|
|
||||||
ComponentInstance *secondInstance;
|
|
||||||
|
|
||||||
DirectConnectionInstance(ComponentInstance *instance, ComponentInstance *secondsInstance, std::vector<InstanceAttribute> attributes, BusInstance *bus, Connection connection);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace domain
|
|
||||||
|
|
||||||
#endif // DOMAIN_CONNECTIONINSTANCE_H
|
|
|
@ -4,4 +4,170 @@ namespace domain {
|
||||||
|
|
||||||
Display::Display(std::vector<ui::Item> items) : items(items) {}
|
Display::Display(std::vector<ui::Item> items) : items(items) {}
|
||||||
|
|
||||||
|
void Display::render(QGraphicsItemGroup *group) {
|
||||||
|
for (auto &item: items) {
|
||||||
|
item.render(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display::comdel(std::ostream &buffer, int x, int y, int size) {
|
||||||
|
for (auto &item: items) {
|
||||||
|
item.comdel(buffer, x, y, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Rect::render(QGraphicsItemGroup *group) {
|
||||||
|
group->addToGroup(new QGraphicsRectItem(x, y, w, h));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Rect::comdel(std::ostream &buffer, int x, int y) {
|
||||||
|
buffer << "\t\trectangle {\n";
|
||||||
|
buffer << "\t\t\tx: " << (this->x + x) << "; y: " << (this->y + y) << ";\n";
|
||||||
|
buffer << "\t\t\tw: " << w << "; h: " << h << ";\n";
|
||||||
|
buffer << "\t\t}\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Line::render(QGraphicsItemGroup *group) {
|
||||||
|
group->addToGroup(new QGraphicsLineItem(x1, y1, x2, y2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Line::comdel(std::ostream &buffer, int x, int y) {
|
||||||
|
buffer << "\t\tline {\n";
|
||||||
|
buffer << "\t\t\tx1: " << (x1 + x) << "; y1: " << (y1 + y) << ";\n";
|
||||||
|
buffer << "\t\t\tx2: " << (x2 + x) << "; y2: " << (y2 + y) << ";\n";
|
||||||
|
buffer << "\t\t}\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Bus::render(QGraphicsItemGroup *group, int size) {
|
||||||
|
if (orientation == HORIZONTAL) {
|
||||||
|
group->addToGroup(new QGraphicsRectItem(x, y, size, h));
|
||||||
|
} else {
|
||||||
|
group->addToGroup(new QGraphicsRectItem(x, y, w, size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui::Bus::getDefaultSize() {
|
||||||
|
if (orientation == HORIZONTAL) {
|
||||||
|
return w;
|
||||||
|
} else {
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Bus::comdel(std::ostream &buffer, int x, int y, int size) {
|
||||||
|
buffer << "\t\trectangle {\n";
|
||||||
|
buffer << "\t\t\tx: " << (this->x + x) << "; y: " << (this->y + y) << ";\n";
|
||||||
|
if (orientation == HORIZONTAL) {
|
||||||
|
buffer << "\t\t\tw: " << size << "; h: " << h << ";\n";
|
||||||
|
} else {
|
||||||
|
buffer << "\t\t\tw: " << w << "; h: " << size << ";\n";
|
||||||
|
}
|
||||||
|
buffer << "\t\t}\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Pin::renderIn(QGraphicsItemGroup *group) {
|
||||||
|
QPolygon polygon;
|
||||||
|
|
||||||
|
switch (orientation) {
|
||||||
|
case PinOrientation::TOP:
|
||||||
|
polygon << QPoint(x, y) << QPoint(x, y + h) << QPoint(x + w, y + h) << QPoint(x + w, y)
|
||||||
|
<< QPoint(x + w / 2, y + h / 2);
|
||||||
|
break;
|
||||||
|
case PinOrientation::BOTTOM:
|
||||||
|
polygon << QPoint(x, y) << QPoint(x, y + h) << QPoint(x + w / 2, y + h / 2)
|
||||||
|
<< QPoint(x + w, y + h) << QPoint(x + w, y);
|
||||||
|
break;
|
||||||
|
case PinOrientation::LEFT:
|
||||||
|
polygon << QPoint(x, y) << QPoint(x + w / 2, y + h / 2) << QPoint(x, y + h)
|
||||||
|
<< QPoint(x + w, y + h) << QPoint(x + w, y);
|
||||||
|
break;
|
||||||
|
case PinOrientation::RIGHT:
|
||||||
|
polygon << QPoint(x, y) << QPoint(x, y + h) << QPoint(x + w, y + h)
|
||||||
|
<< QPoint(x + w / 2, y + h / 2) << QPoint(x + w, y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
group->addToGroup(new QGraphicsPolygonItem(polygon));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Pin::renderOut(QGraphicsItemGroup *group) {
|
||||||
|
QPolygon polygon;
|
||||||
|
|
||||||
|
switch (orientation) {
|
||||||
|
case PinOrientation::TOP:
|
||||||
|
polygon << QPoint(x, y + h / 2) << QPoint(x, y + h) << QPoint(x + w, y + h)
|
||||||
|
<< QPoint(x + w, y + h / 2) << QPoint(x + w / 2, y);
|
||||||
|
break;
|
||||||
|
case PinOrientation::BOTTOM:
|
||||||
|
polygon << QPoint(x, y) << QPoint(x, y + h / 2) << QPoint(x + w / 2, y + h)
|
||||||
|
<< QPoint(x + w, y + h / 2) << QPoint(x + w, y);
|
||||||
|
break;
|
||||||
|
case PinOrientation::LEFT:
|
||||||
|
polygon << QPoint(x + w, y) << QPoint(x + w / 2, y) << QPoint(x, y + h / 2)
|
||||||
|
<< QPoint(x + w / 2, y + h) << QPoint(x + w, y + w);
|
||||||
|
break;
|
||||||
|
case PinOrientation::RIGHT:
|
||||||
|
polygon << QPoint(x, y) << QPoint(x, y + h) << QPoint(x + w / 2, y + h)
|
||||||
|
<< QPoint(x + w, y + h / 2) << QPoint(x + w / 2, y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
group->addToGroup(new QGraphicsPolygonItem(polygon));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Pin::renderInOut(QGraphicsItemGroup *group) {
|
||||||
|
group->addToGroup(new QGraphicsRectItem(x, y, w, h));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Pin::render(QGraphicsItemGroup *group) {
|
||||||
|
switch (pinType) {
|
||||||
|
case PinType::IN:
|
||||||
|
renderIn(group);
|
||||||
|
break;
|
||||||
|
case PinType::OUT:
|
||||||
|
renderOut(group);
|
||||||
|
break;
|
||||||
|
case PinType::IN_OUT:
|
||||||
|
renderInOut(group);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui::Pin::getConnectionX() {
|
||||||
|
switch (orientation) {
|
||||||
|
case ui::PinOrientation::TOP:
|
||||||
|
case ui::PinOrientation::BOTTOM:
|
||||||
|
return x + w / 2;
|
||||||
|
case ui::PinOrientation::LEFT:
|
||||||
|
return x;
|
||||||
|
case ui::PinOrientation::RIGHT:
|
||||||
|
return x + w;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui::Pin::getConnectionY() {
|
||||||
|
switch (orientation) {
|
||||||
|
case ui::PinOrientation::LEFT:
|
||||||
|
case ui::PinOrientation::RIGHT:
|
||||||
|
return y + h / 2;
|
||||||
|
case ui::PinOrientation::TOP:
|
||||||
|
return y;
|
||||||
|
case ui::PinOrientation::BOTTOM:
|
||||||
|
return y + h;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Item::render(QGraphicsItemGroup *group, int size) {
|
||||||
|
if (rect) rect->render(group);
|
||||||
|
if (line) line->render(group);
|
||||||
|
if (pin) pin->render(group);
|
||||||
|
if (bus) bus->render(group, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Item::comdel(std::ostream &buffer, int x, int y, int size) {
|
||||||
|
if (rect) rect->comdel(buffer, x, y);
|
||||||
|
if (line) line->comdel(buffer, x, y);
|
||||||
|
// pins aren't exported
|
||||||
|
if (bus) bus->comdel(buffer, x, y, size);
|
||||||
|
}
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -16,16 +16,9 @@ public:
|
||||||
|
|
||||||
Rect(int x, int y, int w, int h) : x(x), y(y), w(w), h(h) {}
|
Rect(int x, int y, int w, int h) : x(x), y(y), w(w), h(h) {}
|
||||||
|
|
||||||
void render(QGraphicsItemGroup *group) {
|
void render(QGraphicsItemGroup *group);
|
||||||
group->addToGroup(new QGraphicsRectItem(x,y,w,h));
|
|
||||||
}
|
|
||||||
|
|
||||||
void comdel(std::ostream &buffer, int x, int y) {
|
void comdel(std::ostream &buffer, int x, int y);
|
||||||
buffer << "\t\trectangle {\n";
|
|
||||||
buffer << "\t\t\tx: " << (this->x + x) << "; y: " << (this->y + y) << ";\n";
|
|
||||||
buffer << "\t\t\tw: " << w << "; h: " << h << ";\n";
|
|
||||||
buffer << "\t\t}\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,18 +28,14 @@ public:
|
||||||
|
|
||||||
Line(int x1, int y1, int x2, int y2) : x1(x1), y1(y1), x2(x2), y2(y2) {}
|
Line(int x1, int y1, int x2, int y2) : x1(x1), y1(y1), x2(x2), y2(y2) {}
|
||||||
|
|
||||||
void render(QGraphicsItemGroup *group) {
|
void render(QGraphicsItemGroup *group);
|
||||||
group->addToGroup(new QGraphicsLineItem(x1, y1, x2, y2));
|
|
||||||
}
|
|
||||||
|
|
||||||
void comdel(std::ostream &buffer, int x, int y) {
|
void comdel(std::ostream &buffer, int x, int y);
|
||||||
buffer << "\t\tline {\n";
|
|
||||||
buffer << "\t\t\tx1: " << (x1 + x) << "; y1: " << (y1 + y) << ";\n";
|
|
||||||
buffer << "\t\t\tx2: " << (x2 + x) << "; y2: " << (y2 + y) << ";\n";
|
|
||||||
buffer << "\t\t}\n\n";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PinType {
|
||||||
|
IN, OUT, IN_OUT
|
||||||
|
};
|
||||||
enum PinOrientation {
|
enum PinOrientation {
|
||||||
LEFT, RIGHT, TOP, BOTTOM
|
LEFT, RIGHT, TOP, BOTTOM
|
||||||
};
|
};
|
||||||
|
@ -54,139 +43,42 @@ enum BusOrientation {
|
||||||
VERTICAL, HORIZONTAL
|
VERTICAL, HORIZONTAL
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PinType {
|
|
||||||
IN, OUT, IN_OUT
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Bus {
|
class Bus {
|
||||||
public:
|
public:
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
BusOrientation orientation;
|
BusOrientation orientation;
|
||||||
|
|
||||||
Bus(int x, int y, int w, int h, BusOrientation orientation): x(x), y(y), w(w), h(h), orientation(orientation) {}
|
Bus(int x, int y, int w, int h, BusOrientation orientation) : x(x), y(y), w(w), h(h),
|
||||||
|
orientation(orientation) {}
|
||||||
|
|
||||||
void render(QGraphicsItemGroup *group, int size) {
|
void render(QGraphicsItemGroup *group, int size);
|
||||||
if(orientation == HORIZONTAL) {
|
|
||||||
group->addToGroup(new QGraphicsRectItem(x,y,size, h));
|
|
||||||
} else {
|
|
||||||
group->addToGroup(new QGraphicsRectItem(x,y,w,size));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int getDefaultSize() {
|
int getDefaultSize();
|
||||||
if(orientation == HORIZONTAL) {
|
|
||||||
return w;
|
|
||||||
} else {
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void comdel(std::ostream &buffer, int x, int y, int size) {
|
void comdel(std::ostream &buffer, int x, int y, int size);
|
||||||
buffer << "\t\trectangle {\n";
|
|
||||||
buffer << "\t\t\tx: " << (this->x + x) << "; y: " << (this->y + y) << ";\n";
|
|
||||||
if(orientation == HORIZONTAL) {
|
|
||||||
buffer << "\t\t\tw: " << size << "; h: " << h << ";\n";
|
|
||||||
} else {
|
|
||||||
buffer << "\t\t\tw: " << w << "; h: " << size << ";\n";
|
|
||||||
}
|
|
||||||
buffer << "\t\t}\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Pin {
|
class Pin {
|
||||||
public:
|
public:
|
||||||
PinOrientation orientation;
|
PinOrientation orientation;
|
||||||
PinType pinType;
|
PinType pinType;
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
|
|
||||||
Pin(int x, int y, int w, int h, PinOrientation orientation, PinType pinType): x(x), y(y), w(w), h(h), orientation(orientation), pinType(pinType) {}
|
Pin(int x, int y, int w, int h, PinOrientation orientation, PinType pinType) : x(x), y(y), w(w), h(h),
|
||||||
|
orientation(orientation),
|
||||||
|
pinType(pinType) {}
|
||||||
|
|
||||||
void renderIn(QGraphicsItemGroup *group) {
|
public:
|
||||||
QPolygon polygon;
|
void render(QGraphicsItemGroup *group);
|
||||||
|
|
||||||
switch (orientation) {
|
int getConnectionX();
|
||||||
case PinOrientation::TOP:
|
int getConnectionY();
|
||||||
polygon << QPoint(x, y) << QPoint(x, y+h) << QPoint(x+w, y+h) << QPoint(x+w, y) << QPoint(x+w/2, y+h/2);
|
|
||||||
break;
|
|
||||||
case PinOrientation::BOTTOM:
|
|
||||||
polygon << QPoint(x, y) << QPoint(x, y+h) << QPoint(x+w/2, y+h/2) << QPoint(x+w, y+h) << QPoint(x+w, y);
|
|
||||||
break;
|
|
||||||
case PinOrientation::LEFT:
|
|
||||||
polygon << QPoint(x, y) << QPoint(x+w/2, y+h/2) << QPoint(x, y+h) << QPoint(x+w, y+h) << QPoint(x+w, y);
|
|
||||||
break;
|
|
||||||
case PinOrientation::RIGHT:
|
|
||||||
polygon << QPoint(x, y) << QPoint(x, y+h) << QPoint(x+w, y+h) << QPoint(x+w/2, y+h/2) << QPoint(x+w, y);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
group->addToGroup(new QGraphicsPolygonItem(polygon));
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderOut(QGraphicsItemGroup *group) {
|
private:
|
||||||
QPolygon polygon;
|
void renderIn(QGraphicsItemGroup *group);
|
||||||
|
void renderOut(QGraphicsItemGroup *group);
|
||||||
switch (orientation) {
|
void renderInOut(QGraphicsItemGroup *group);
|
||||||
case PinOrientation::TOP:
|
|
||||||
polygon << QPoint(x, y+h/2) << QPoint(x, y+h) << QPoint(x+w, y+h) << QPoint(x+w, y+h/2) << QPoint(x+w/2, y);
|
|
||||||
break;
|
|
||||||
case PinOrientation::BOTTOM:
|
|
||||||
polygon << QPoint(x, y) << QPoint(x, y+h/2) << QPoint(x+w/2, y+h) << QPoint(x+w, y+h/2) << QPoint(x+w, y);
|
|
||||||
break;
|
|
||||||
case PinOrientation::LEFT:
|
|
||||||
polygon << QPoint(x+w, y) << QPoint(x+w/2, y) << QPoint(x, y+h/2) << QPoint(x+w/2, y+h) << QPoint(x+w, y+w);
|
|
||||||
break;
|
|
||||||
case PinOrientation::RIGHT:
|
|
||||||
polygon << QPoint(x, y) << QPoint(x, y+h) << QPoint(x+w/2, y+h) << QPoint(x+w, y+h/2) << QPoint(x+w/2, y);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
group->addToGroup(new QGraphicsPolygonItem(polygon));
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderInOut(QGraphicsItemGroup *group) {
|
|
||||||
group->addToGroup(new QGraphicsRectItem(x, y ,w, h));
|
|
||||||
}
|
|
||||||
|
|
||||||
void render(QGraphicsItemGroup *group) {
|
|
||||||
switch (pinType) {
|
|
||||||
case PinType::IN:
|
|
||||||
renderIn(group);
|
|
||||||
break;
|
|
||||||
case PinType::OUT:
|
|
||||||
renderOut(group);
|
|
||||||
break;
|
|
||||||
case PinType::IN_OUT:
|
|
||||||
renderInOut(group);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int getConnectionX() {
|
|
||||||
switch (orientation) {
|
|
||||||
case ui::PinOrientation::TOP:
|
|
||||||
case ui::PinOrientation::BOTTOM:
|
|
||||||
return x+w/2;
|
|
||||||
case ui::PinOrientation::LEFT:
|
|
||||||
return x;
|
|
||||||
case ui::PinOrientation::RIGHT:
|
|
||||||
return x+w;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getConnectionY() {
|
|
||||||
switch (orientation) {
|
|
||||||
case ui::PinOrientation::LEFT:
|
|
||||||
case ui::PinOrientation::RIGHT:
|
|
||||||
return y+h/2;
|
|
||||||
case ui::PinOrientation::TOP:
|
|
||||||
return y;
|
|
||||||
case ui::PinOrientation::BOTTOM:
|
|
||||||
return y+h;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,45 +86,25 @@ class Item {
|
||||||
public:
|
public:
|
||||||
Item() : rect(std::nullopt), line(std::nullopt), pin(std::nullopt), bus(std::nullopt) {}
|
Item() : rect(std::nullopt), line(std::nullopt), pin(std::nullopt), bus(std::nullopt) {}
|
||||||
|
|
||||||
void render(QGraphicsItemGroup *group, int size = 0) {
|
|
||||||
if(rect) rect->render(group);
|
|
||||||
if(line) line->render(group);
|
|
||||||
if(pin) pin->render(group);
|
|
||||||
if(bus) bus->render(group, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<Rect> rect = std::nullopt;
|
std::optional<Rect> rect = std::nullopt;
|
||||||
std::optional<Line> line = std::nullopt;
|
std::optional<Line> line = std::nullopt;
|
||||||
std::optional<Pin> pin = std::nullopt;
|
std::optional<Pin> pin = std::nullopt;
|
||||||
std::optional<Bus> bus = std::nullopt;
|
std::optional<Bus> bus = std::nullopt;
|
||||||
|
|
||||||
void comdel(std::ostream &buffer, int x, int y, int size = 0) {
|
void render(QGraphicsItemGroup *group, int size = 0);
|
||||||
if(rect) rect->comdel(buffer, x, y);
|
void comdel(std::ostream &buffer, int x, int y, int size = 0);
|
||||||
if(line) line->comdel(buffer, x, y);
|
|
||||||
// pins aren't exported
|
|
||||||
if(bus) bus->comdel(buffer, x, y, size);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Display
|
class Display {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Display(std::vector<ui::Item> items);
|
Display(std::vector<ui::Item> items);
|
||||||
|
|
||||||
void render(QGraphicsItemGroup *group) {
|
void render(QGraphicsItemGroup *group);
|
||||||
for(auto &item: items) {
|
|
||||||
item.render(group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void comdel(std::ostream &buffer, int x, int y, int size = 0) {
|
void comdel(std::ostream &buffer, int x, int y, int size = 0);
|
||||||
for(auto &item: items) {
|
|
||||||
item.comdel(buffer, x, y, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<ui::Item> &getItems() { return items; }
|
std::vector<ui::Item> &getItems() { return items; }
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
#include <map>
|
||||||
|
#include <utility>
|
||||||
|
#include "function_signature.h"
|
||||||
|
|
||||||
|
namespace domain {
|
||||||
|
|
||||||
|
class DivisibleValidator : public FunctionValidator {
|
||||||
|
public:
|
||||||
|
DivisibleValidator() : FunctionValidator("divisible", {Value::INT, Value::INT}) {}
|
||||||
|
|
||||||
|
bool validate(std::vector<Value> values) override {
|
||||||
|
if (validateSignature(values)) {
|
||||||
|
long long first = values[0].asInt();
|
||||||
|
long long second = values[1].asInt();
|
||||||
|
return (first % second) == 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() override {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class LessThenValidator : public FunctionValidator {
|
||||||
|
public:
|
||||||
|
LessThenValidator() : FunctionValidator("less_then", {Value::INT, Value::INT}) {}
|
||||||
|
|
||||||
|
bool validate(std::vector<Value> values) override {
|
||||||
|
if (validateSignature(values)) {
|
||||||
|
long long first = values[0].asInt();
|
||||||
|
long long second = values[1].asInt();
|
||||||
|
return first < second;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() override {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class GreaterThenValidator : public FunctionValidator {
|
||||||
|
public:
|
||||||
|
GreaterThenValidator() : FunctionValidator("greater_then", {Value::INT, Value::INT}) {}
|
||||||
|
|
||||||
|
bool validate(std::vector<Value> values) override {
|
||||||
|
if (validateSignature(values)) {
|
||||||
|
long long first = values[0].asInt();
|
||||||
|
long long second = values[1].asInt();
|
||||||
|
return first > second;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() override {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ContainsAddressValidator : public FunctionValidator {
|
||||||
|
public:
|
||||||
|
ContainsAddressValidator() : FunctionValidator("contains_address", {Value::ADDRESS_SPACE, Value::INT}) {}
|
||||||
|
|
||||||
|
bool validate(std::vector<Value> values) override {
|
||||||
|
if (validateSignature(values)) {
|
||||||
|
AddressSpace space = values[0].asAddressSpace();
|
||||||
|
long long address = values[1].asInt();
|
||||||
|
return space.contains(address);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() override {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ContainsValidator : public FunctionValidator {
|
||||||
|
public:
|
||||||
|
ContainsValidator() : FunctionValidator("contains", {Value::ADDRESS_SPACE, Value::INT, Value::INT}) {}
|
||||||
|
|
||||||
|
bool validate(std::vector<Value> values) override {
|
||||||
|
if (validateSignature(values)) {
|
||||||
|
AddressSpace space = values[0].asAddressSpace();
|
||||||
|
long long start = values[1].asInt();
|
||||||
|
long long size = values[1].asInt();
|
||||||
|
return space.contains(start, start + size);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() override {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class UniqueValidator : public FunctionValidator {
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<std::string, std::vector<std::pair<long long int, long long int>>> spaces;
|
||||||
|
|
||||||
|
bool overlaps(long long int start1, long long int end1, long long int start2, long long int end2) {
|
||||||
|
return std::max((long long int) 0, std::min(end1, end2) - std::max(start1, start2)) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
UniqueValidator() : FunctionValidator("unique", {Value::ADDRESS_SPACE, Value::INT, Value::INT}) {}
|
||||||
|
|
||||||
|
bool validate(std::vector<Value> values) override {
|
||||||
|
if (validateSignature(values)) {
|
||||||
|
std::string space = values[0].asAddressSpace().getName();
|
||||||
|
long long int start = values[1].asInt();
|
||||||
|
long long int end = start + values[2].asInt();
|
||||||
|
if (spaces.count(space) == 0) {
|
||||||
|
spaces.insert(std::make_pair(space, std::vector<std::pair<long long int, long long int>>{}));
|
||||||
|
}
|
||||||
|
for (auto &s: spaces[space]) {
|
||||||
|
if (overlaps(s.first, s.second, start, end)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spaces[space].push_back(std::make_pair(start, end));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() override {
|
||||||
|
spaces.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<FunctionValidator *> getSupportedValidators() {
|
||||||
|
std::vector<FunctionValidator *> validators;
|
||||||
|
|
||||||
|
validators.push_back(new DivisibleValidator());
|
||||||
|
validators.push_back(new LessThenValidator());
|
||||||
|
validators.push_back(new GreaterThenValidator());
|
||||||
|
validators.push_back(new ContainsAddressValidator());
|
||||||
|
validators.push_back(new ContainsValidator());
|
||||||
|
validators.push_back(new UniqueValidator());
|
||||||
|
|
||||||
|
return validators;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FunctionValidator::FunctionValidator(std::string name, std::vector<Value::ValueType> signature)
|
||||||
|
: name(std::move(name)), signature(std::move(signature)) {}
|
||||||
|
|
||||||
|
std::string FunctionValidator::getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Value::ValueType> FunctionValidator::getSignature() {
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FunctionValidator::validateSignature(std::vector<Value> _signature) {
|
||||||
|
if (this->signature.size() != _signature.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < this->signature.size(); i++) {
|
||||||
|
if (this->signature[i] != _signature[i].getType()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace domain
|
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef DOMAIN_FUNCTION_VALIDATOR_H
|
||||||
|
#define DOMAIN_FUNCTION_VALIDATOR_H
|
||||||
|
|
||||||
|
#include<functional>
|
||||||
|
#include<vector>
|
||||||
|
|
||||||
|
#include "value.h"
|
||||||
|
|
||||||
|
namespace domain {
|
||||||
|
|
||||||
|
class FunctionValidator {
|
||||||
|
private:
|
||||||
|
std::string name;
|
||||||
|
std::vector<Value::ValueType> signature;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FunctionValidator(std::string name, std::vector<Value::ValueType> signature);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
std::string getName();
|
||||||
|
|
||||||
|
std::vector<Value::ValueType> getSignature();
|
||||||
|
|
||||||
|
bool validateSignature(std::vector<Value> signature);
|
||||||
|
|
||||||
|
virtual bool validate(std::vector<Value> values) = 0;
|
||||||
|
|
||||||
|
virtual void clear() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<FunctionValidator *> getSupportedValidators();
|
||||||
|
|
||||||
|
} // namespace domain
|
||||||
|
|
||||||
|
#endif // DOMAIN_FUNCTION_VALIDATOR_H
|
|
@ -1,138 +0,0 @@
|
||||||
#include <map>
|
|
||||||
#include "functionsignature.h"
|
|
||||||
|
|
||||||
namespace domain {
|
|
||||||
|
|
||||||
class DivisibleValidator: public FunctionValidator {
|
|
||||||
public:
|
|
||||||
DivisibleValidator(): FunctionValidator("divisible", {Value::INT, Value::INT}) {}
|
|
||||||
|
|
||||||
bool validate(std::vector<Value> values) override {
|
|
||||||
if(validateSignature(values)) {
|
|
||||||
long long first = values[0].asInt();
|
|
||||||
long long second = values[1].asInt();
|
|
||||||
return (first % second) == 0;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void clear() override {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class LessThenValidator: public FunctionValidator {
|
|
||||||
public:
|
|
||||||
LessThenValidator(): FunctionValidator("less_then", {Value::INT, Value::INT}) {}
|
|
||||||
|
|
||||||
bool validate(std::vector<Value> values) override {
|
|
||||||
if(validateSignature(values)) {
|
|
||||||
long long first = values[0].asInt();
|
|
||||||
long long second = values[1].asInt();
|
|
||||||
return first < second;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void clear() override {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class GreaterThenValidator: public FunctionValidator {
|
|
||||||
public:
|
|
||||||
GreaterThenValidator(): FunctionValidator("greater_then", {Value::INT, Value::INT}) {}
|
|
||||||
|
|
||||||
bool validate(std::vector<Value> values) override {
|
|
||||||
if(validateSignature(values)) {
|
|
||||||
long long first = values[0].asInt();
|
|
||||||
long long second = values[1].asInt();
|
|
||||||
return first > second;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void clear() override {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ContainsAddressValidator: public FunctionValidator {
|
|
||||||
public:
|
|
||||||
ContainsAddressValidator(): FunctionValidator("contains_address", {Value::ADDRESS_SPACE, Value::INT}) {}
|
|
||||||
|
|
||||||
bool validate(std::vector<Value> values) override {
|
|
||||||
if(validateSignature(values)) {
|
|
||||||
AddressSpace space = values[0].asAddressSpace();
|
|
||||||
long long address = values[1].asInt();
|
|
||||||
return space.contains(address);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void clear() override {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ContainsValidator: public FunctionValidator {
|
|
||||||
public:
|
|
||||||
ContainsValidator(): FunctionValidator("contains", {Value::ADDRESS_SPACE, Value::INT, Value::INT}) {}
|
|
||||||
|
|
||||||
bool validate(std::vector<Value> values) override {
|
|
||||||
if(validateSignature(values)) {
|
|
||||||
AddressSpace space = values[0].asAddressSpace();
|
|
||||||
long long start = values[1].asInt();
|
|
||||||
long long size = values[1].asInt();
|
|
||||||
return space.contains(start, start + size);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void clear() override {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class UniqueValidator: public FunctionValidator {
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::map<std::string, std::vector<std::pair<long long int, long long int>>> spaces;
|
|
||||||
|
|
||||||
bool overlaps(long long int start1, long long int end1, long long int start2, long long int end2) {
|
|
||||||
return std::max((long long int)0, std::min(end1, end2) - std::max(start1, start2)) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
UniqueValidator(): FunctionValidator("unique", {Value::ADDRESS_SPACE, Value::INT, Value::INT}) {}
|
|
||||||
|
|
||||||
bool validate(std::vector<Value> values) override {
|
|
||||||
if(validateSignature(values)) {
|
|
||||||
std::string space = values[0].asAddressSpace().getName();
|
|
||||||
long long int start = values[1].asInt();
|
|
||||||
long long int end = start + values[2].asInt();
|
|
||||||
if(spaces.count(space) == 0) {
|
|
||||||
spaces.insert(std::make_pair(space, std::vector<std::pair<long long int, long long int>>{}));
|
|
||||||
}
|
|
||||||
for(auto& s: spaces[space]) {
|
|
||||||
if(overlaps(s.first, s.second, start, end)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spaces[space].push_back(std::make_pair(start, end));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void clear() override {
|
|
||||||
spaces.clear();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<FunctionValidator*> getSupportedValidators() {
|
|
||||||
std::vector<FunctionValidator*> validators;
|
|
||||||
|
|
||||||
validators.push_back(new DivisibleValidator());
|
|
||||||
validators.push_back(new LessThenValidator());
|
|
||||||
validators.push_back(new GreaterThenValidator());
|
|
||||||
validators.push_back(new ContainsAddressValidator());
|
|
||||||
validators.push_back(new ContainsValidator());
|
|
||||||
validators.push_back(new UniqueValidator());
|
|
||||||
|
|
||||||
return validators;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace domain
|
|
|
@ -1,53 +0,0 @@
|
||||||
#ifndef DOMAIN_FUNCTION_VALIDATOR_H
|
|
||||||
#define DOMAIN_FUNCTION_VALIDATOR_H
|
|
||||||
|
|
||||||
#include<functional>
|
|
||||||
#include<vector>
|
|
||||||
|
|
||||||
#include "value.h"
|
|
||||||
|
|
||||||
namespace domain {
|
|
||||||
|
|
||||||
class FunctionValidator {
|
|
||||||
private:
|
|
||||||
std::string name;
|
|
||||||
std::vector<Value::ValueType> signature;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
FunctionValidator(std::string name, std::vector<Value::ValueType> signature) {
|
|
||||||
this->name = name;
|
|
||||||
this->signature = signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
std::string getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Value::ValueType> getSignature() {
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool validateSignature(std::vector<Value> signature) {
|
|
||||||
if(this->signature.size() != signature.size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i=0; i<this->signature.size(); i++) {
|
|
||||||
if(this->signature[i] != signature[i].getType()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool validate(std::vector<Value> values) = 0;
|
|
||||||
virtual void clear() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<FunctionValidator*> getSupportedValidators();
|
|
||||||
|
|
||||||
} // namespace domain
|
|
||||||
|
|
||||||
#endif // DOMAIN_FUNCTION_VALIDATOR_H
|
|
|
@ -3,8 +3,7 @@
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
BusInstance::BusInstance(std::string name, std::pair<int, int> position, Bus bus, int size)
|
BusInstance::BusInstance(std::string name, std::pair<int, int> position, Bus bus, int size)
|
||||||
: name(name), position(position), bus(bus), size(size)
|
: name(name), position(position), bus(bus), size(size) {
|
||||||
{
|
|
||||||
if (size < 0 && bus.getDisplayBus().has_value()) {
|
if (size < 0 && bus.getDisplayBus().has_value()) {
|
||||||
this->size = bus.getDisplayBus()->getDefaultSize();
|
this->size = bus.getDisplayBus()->getDefaultSize();
|
||||||
}
|
}
|
||||||
|
@ -12,9 +11,9 @@ BusInstance::BusInstance(std::string name, std::pair<int, int> position, Bus bus
|
||||||
|
|
||||||
BusInstance::BusInstance(std::string name, Bus bus) : name(name), bus(bus), position(0, 0), size(0) {}
|
BusInstance::BusInstance(std::string name, Bus bus) : name(name), bus(bus), position(0, 0), size(0) {}
|
||||||
|
|
||||||
ComponentInstance::ComponentInstance(std::string name, std::vector<InstanceAttribute> attributes, std::pair<int, int> position, Component component)
|
ComponentInstance::ComponentInstance(std::string name, std::vector<InstanceAttribute> attributes,
|
||||||
: name(name), attributes(std::move(attributes)), position(position), component(component)
|
std::pair<int, int> position, Component component)
|
||||||
{}
|
: name(name), attributes(std::move(attributes)), position(position), component(component) {}
|
||||||
|
|
||||||
|
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -3,17 +3,15 @@
|
||||||
|
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
#include "component.h"
|
#include "component.h"
|
||||||
#include "instanceattribute.h"
|
#include "instance_attribute.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
class BusInstance
|
class BusInstance {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
std::string name;
|
std::string name;
|
||||||
std::pair<int, int> position;
|
std::pair<int, int> position;
|
||||||
|
@ -28,8 +26,7 @@ public:
|
||||||
virtual ~BusInstance() = default;
|
virtual ~BusInstance() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComponentInstance
|
class ComponentInstance {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<InstanceAttribute> attributes;
|
std::vector<InstanceAttribute> attributes;
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include "instance_attribute.h"
|
||||||
|
|
||||||
|
namespace domain {
|
||||||
|
|
||||||
|
InstanceAttribute::InstanceAttribute(std::string name, Value value, Attribute attribute)
|
||||||
|
: name(name), value(value), attribute(attribute) {}
|
||||||
|
|
||||||
|
} // namespace domain
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef DOMAIN_INSTANCE_ATTRIBUTE_H
|
||||||
|
#define DOMAIN_INSTANCE_ATTRIBUTE_H
|
||||||
|
|
||||||
|
#include "attribute.h"
|
||||||
|
#include "value.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace domain {
|
||||||
|
|
||||||
|
class InstanceAttribute {
|
||||||
|
public:
|
||||||
|
InstanceAttribute(std::string name, Value value, Attribute attribute);
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
Value value;
|
||||||
|
Attribute attribute;
|
||||||
|
|
||||||
|
~InstanceAttribute() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace domain
|
||||||
|
|
||||||
|
#endif // DOMAIN_INSTANCE_ATTRIBUTE_H
|
|
@ -1,9 +0,0 @@
|
||||||
#include "instanceattribute.h"
|
|
||||||
|
|
||||||
namespace domain {
|
|
||||||
|
|
||||||
InstanceAttribute::InstanceAttribute(std::string name, Value value, Attribute attribute)
|
|
||||||
: name(name), value(value), attribute(attribute)
|
|
||||||
{}
|
|
||||||
|
|
||||||
} // namespace domain
|
|
|
@ -1,27 +0,0 @@
|
||||||
#ifndef DOMAIN_INSTANCE_ATTRIBUTE_H
|
|
||||||
#define DOMAIN_INSTANCE_ATTRIBUTE_H
|
|
||||||
|
|
||||||
#include "attribute.h"
|
|
||||||
#include "value.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace domain {
|
|
||||||
|
|
||||||
class InstanceAttribute
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
InstanceAttribute(std::string name, Value value, Attribute attribute);
|
|
||||||
|
|
||||||
std::string name = "";
|
|
||||||
Value value;
|
|
||||||
Attribute attribute;
|
|
||||||
|
|
||||||
~InstanceAttribute() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace domain
|
|
||||||
|
|
||||||
#endif // DOMAIN_INSTANCE_ATTRIBUTE_H
|
|
|
@ -2,24 +2,30 @@
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
Library::Library(string name, string libraryInfo, string header, string componentDirectory, std::optional<std::string> componentHeader,
|
Library::Library(string name, string libraryInfo, string header, string componentDirectory,
|
||||||
vector<AddressSpace> addressSpaces, vector<Component> components, vector<Bus> buses, vector<Connection> connections, map<string, string> messages)
|
std::optional<std::string> componentHeader,
|
||||||
: name(name), libraryInfo(libraryInfo), header(header), componentDirectory(componentDirectory), componentHeader(componentHeader), addressSpaces(addressSpaces),
|
vector<AddressSpace> addressSpaces, vector<Component> components, vector<Bus> buses,
|
||||||
components(components), buses(buses), connections(connections), messages(messages)
|
vector<Connection> connections, map<string, string> messages)
|
||||||
{}
|
: name(name), libraryInfo(libraryInfo), header(header), componentDirectory(componentDirectory),
|
||||||
|
componentHeader(componentHeader), addressSpaces(addressSpaces),
|
||||||
|
components(components), buses(buses), connections(connections), messages(messages) {}
|
||||||
|
|
||||||
std::string Library::getName() {
|
std::string Library::getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Library::getLibraryInfo() {
|
std::string Library::getLibraryInfo() {
|
||||||
return libraryInfo;
|
return libraryInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Library::getHeader() {
|
std::string Library::getHeader() {
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Library::getComponentDirectory() {
|
std::string Library::getComponentDirectory() {
|
||||||
return componentDirectory;
|
return componentDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> Library::getComponentHeader() {
|
std::optional<std::string> Library::getComponentHeader() {
|
||||||
return componentHeader;
|
return componentHeader;
|
||||||
}
|
}
|
||||||
|
@ -27,12 +33,15 @@ std::optional<std::string> Library::getComponentHeader() {
|
||||||
std::vector<AddressSpace> Library::getAddressSpaces() {
|
std::vector<AddressSpace> Library::getAddressSpaces() {
|
||||||
return addressSpaces;
|
return addressSpaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Component> Library::getComponents() {
|
std::vector<Component> Library::getComponents() {
|
||||||
return components;
|
return components;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Bus> Library::getBuses() {
|
std::vector<Bus> Library::getBuses() {
|
||||||
return buses;
|
return buses;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Connection> Library::getConnections() {
|
std::vector<Connection> Library::getConnections() {
|
||||||
return connections;
|
return connections;
|
||||||
}
|
}
|
||||||
|
@ -49,6 +58,7 @@ bool Library::hasComponent(std::string name) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Library::hasBus(std::string name) {
|
bool Library::hasBus(std::string name) {
|
||||||
for (uint i = 0; i < buses.size(); i++) {
|
for (uint i = 0; i < buses.size(); i++) {
|
||||||
if (buses[i].getName() == name) {
|
if (buses[i].getName() == name) {
|
||||||
|
@ -67,6 +77,7 @@ AddressSpace &Library::getAddressSpace(std::string addressSpace) {
|
||||||
}
|
}
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
Component &Library::getComponent(std::string component) {
|
Component &Library::getComponent(std::string component) {
|
||||||
for (uint i = 0; i < components.size(); i++) {
|
for (uint i = 0; i < components.size(); i++) {
|
||||||
if (components[i].getName() == component) {
|
if (components[i].getName() == component) {
|
||||||
|
@ -75,6 +86,7 @@ Component &Library::getComponent(std::string component) {
|
||||||
}
|
}
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
Bus &Library::getBus(std::string bus) {
|
Bus &Library::getBus(std::string bus) {
|
||||||
for (uint i = 0; i < buses.size(); i++) {
|
for (uint i = 0; i < buses.size(); i++) {
|
||||||
if (buses[i].getName() == bus) {
|
if (buses[i].getName() == bus) {
|
||||||
|
@ -88,6 +100,7 @@ Bus &Library::getBus(std::string bus) {
|
||||||
bool Library::hasConnection(ConnectionComponent component, std::string bus) {
|
bool Library::hasConnection(ConnectionComponent component, std::string bus) {
|
||||||
return getConnection(component, bus).has_value();
|
return getConnection(component, bus).has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Connection> Library::getConnection(ConnectionComponent component, std::string bus) {
|
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, bus)) {
|
if (connections[i].isConnecting(component, bus)) {
|
||||||
|
@ -100,7 +113,9 @@ std::optional<Connection> Library::getConnection(ConnectionComponent component,
|
||||||
bool Library::hasConnection(ConnectionComponent component, std::string bus, ConnectionComponent secondComponent) {
|
bool Library::hasConnection(ConnectionComponent component, std::string bus, ConnectionComponent secondComponent) {
|
||||||
return getConnection(component, bus, secondComponent).has_value();
|
return getConnection(component, bus, secondComponent).has_value();
|
||||||
}
|
}
|
||||||
std::optional<Connection> Library::getConnection(ConnectionComponent component, std::string bus, ConnectionComponent secondComponent) {
|
|
||||||
|
std::optional<Connection>
|
||||||
|
Library::getConnection(ConnectionComponent component, std::string bus, ConnectionComponent secondComponent) {
|
||||||
for (uint i = 0; i < connections.size(); i++) {
|
for (uint i = 0; i < connections.size(); i++) {
|
||||||
if (connections[i].isConnecting(component, bus, secondComponent)) {
|
if (connections[i].isConnecting(component, bus, secondComponent)) {
|
||||||
return connections[i];
|
return connections[i];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef DOMAIN_LIBRARY_H
|
#ifndef DOMAIN_LIBRARY_H
|
||||||
#define DOMAIN_LIBRARY_H
|
#define DOMAIN_LIBRARY_H
|
||||||
|
|
||||||
#include "addressspace.h"
|
#include "address_space.h"
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
#include "component.h"
|
#include "component.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
@ -10,13 +10,11 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class Library
|
class Library {
|
||||||
{
|
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string libraryInfo;
|
std::string libraryInfo;
|
||||||
std::string header;
|
std::string header;
|
||||||
|
@ -31,37 +29,53 @@ class Library
|
||||||
std::map<std::string, std::string> messages;
|
std::map<std::string, std::string> messages;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Library(string name, string libraryInfo, string header, string componentDirectory, std::optional<string> componentHeader,
|
Library(string name, string libraryInfo, string header, string componentDirectory,
|
||||||
vector<AddressSpace> addressSpaces, vector<Component> components, vector<Bus> buses, vector<Connection> connection, map<string, string> messages);
|
std::optional<string> componentHeader,
|
||||||
|
vector<AddressSpace> addressSpaces, vector<Component> components, vector<Bus> buses,
|
||||||
|
vector<Connection> connection, map<string, string> messages);
|
||||||
|
|
||||||
std::string getName();
|
std::string getName();
|
||||||
|
|
||||||
std::string getLibraryInfo();
|
std::string getLibraryInfo();
|
||||||
|
|
||||||
std::string getHeader();
|
std::string getHeader();
|
||||||
|
|
||||||
std::string getComponentDirectory();
|
std::string getComponentDirectory();
|
||||||
|
|
||||||
std::optional<std::string> getComponentHeader();
|
std::optional<std::string> getComponentHeader();
|
||||||
|
|
||||||
std::vector<AddressSpace> getAddressSpaces();
|
std::vector<AddressSpace> getAddressSpaces();
|
||||||
|
|
||||||
std::vector<Component> getComponents();
|
std::vector<Component> getComponents();
|
||||||
|
|
||||||
std::vector<Bus> getBuses();
|
std::vector<Bus> getBuses();
|
||||||
|
|
||||||
std::vector<Connection> getConnections();
|
std::vector<Connection> getConnections();
|
||||||
|
|
||||||
bool hasComponent(std::string name);
|
bool hasComponent(std::string name);
|
||||||
|
|
||||||
bool hasBus(std::string name);
|
bool hasBus(std::string name);
|
||||||
|
|
||||||
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::string getMessage(std::string key);
|
std::string getMessage(std::string key);
|
||||||
|
|
||||||
bool hasConnection(ConnectionComponent component, std::string bus);
|
bool hasConnection(ConnectionComponent component, std::string bus);
|
||||||
|
|
||||||
std::optional<Connection> getConnection(ConnectionComponent component, std::string bus);
|
std::optional<Connection> getConnection(ConnectionComponent component, std::string bus);
|
||||||
|
|
||||||
bool hasConnection(ConnectionComponent component, std::string bus, ConnectionComponent secondComponent);
|
bool hasConnection(ConnectionComponent component, std::string bus, ConnectionComponent secondComponent);
|
||||||
|
|
||||||
std::optional<Connection> getConnection(ConnectionComponent component, std::string bus, ConnectionComponent secondComponent);
|
std::optional<Connection> getConnection(ConnectionComponent component, std::string bus, ConnectionComponent secondComponent);
|
||||||
|
|
||||||
bool hasConnection(ConnectionComponent component, ConnectionComponent secondComponent);
|
bool hasConnection(ConnectionComponent component, ConnectionComponent secondComponent);
|
||||||
|
|
||||||
std::optional<Connection> getConnection(ConnectionComponent component, ConnectionComponent secondComponent);
|
std::optional<Connection> getConnection(ConnectionComponent component, ConnectionComponent secondComponent);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,36 +3,41 @@
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
PinConnection::PinConnection(std::string message, ConnectionType type)
|
PinConnection::PinConnection(std::string message, ConnectionType type)
|
||||||
: message(message), type(type)
|
: message(message), type(type) {}
|
||||||
{}
|
|
||||||
|
|
||||||
PinConnection::ConnectionType PinConnection::getType() {
|
PinConnection::ConnectionType PinConnection::getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string PinConnection::getMessage() {
|
std::string PinConnection::getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Pin::Pin(std::string name, PinType type, std::string tooltip, PinConnection connection, domain::ui::Pin pin, std::optional<std::vector<Value>> wires)
|
Pin::Pin(std::string name, PinType type, std::string tooltip, PinConnection connection, domain::ui::Pin pin,
|
||||||
: name(name), type(type), tooltip(tooltip), connection(connection), displayPin(pin), wires(wires)
|
std::optional<std::vector<Value>> wires)
|
||||||
{}
|
: name(name), type(type), tooltip(tooltip), connection(connection), displayPin(pin), wires(wires) {}
|
||||||
|
|
||||||
std::string &Pin::getName() {
|
std::string &Pin::getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pin::PinType Pin::getType() {
|
Pin::PinType Pin::getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Pin::getTooltip() {
|
std::string Pin::getTooltip() {
|
||||||
return tooltip;
|
return tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui::Pin &Pin::getDisplayPin() {
|
ui::Pin &Pin::getDisplayPin() {
|
||||||
return displayPin;
|
return displayPin;
|
||||||
}
|
}
|
||||||
|
|
||||||
PinConnection &Pin::getConnection() {
|
PinConnection &Pin::getConnection() {
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::vector<Value>> &Pin::getWires() {
|
std::optional<std::vector<Value>> &Pin::getWires() {
|
||||||
return wires;
|
return wires;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,9 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
class PinConnection
|
class PinConnection {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
enum ConnectionType {
|
enum ConnectionType {
|
||||||
REQUIRED,
|
REQUIRED,
|
||||||
|
@ -26,11 +24,11 @@ public:
|
||||||
PinConnection(std::string message, ConnectionType type);
|
PinConnection(std::string message, ConnectionType type);
|
||||||
|
|
||||||
ConnectionType getType();
|
ConnectionType getType();
|
||||||
|
|
||||||
std::string getMessage();
|
std::string getMessage();
|
||||||
};
|
};
|
||||||
|
|
||||||
class Pin
|
class Pin {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
enum PinType {
|
enum PinType {
|
||||||
IN_OUT,
|
IN_OUT,
|
||||||
|
@ -48,13 +46,19 @@ private:
|
||||||
std::optional<std::vector<Value>> wires;
|
std::optional<std::vector<Value>> wires;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Pin(std::string name, PinType type, std::string tooltip, PinConnection connection, domain::ui::Pin pin, std::optional<std::vector<Value>> wires);
|
Pin(std::string name, PinType type, std::string tooltip, PinConnection connection, domain::ui::Pin pin,
|
||||||
|
std::optional<std::vector<Value>> wires);
|
||||||
|
|
||||||
std::string &getName();
|
std::string &getName();
|
||||||
|
|
||||||
PinType getType();
|
PinType getType();
|
||||||
|
|
||||||
std::string getTooltip();
|
std::string getTooltip();
|
||||||
|
|
||||||
ui::Pin &getDisplayPin();
|
ui::Pin &getDisplayPin();
|
||||||
|
|
||||||
PinConnection &getConnection();
|
PinConnection &getConnection();
|
||||||
|
|
||||||
std::optional<std::vector<Value>> &getWires();
|
std::optional<std::vector<Value>> &getWires();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
#include "rule.h"
|
#include "rule.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
Condition::Condition(std::string function, std::vector<Value> params, bool negated)
|
Condition::Condition(std::string function, std::vector<Value> params, bool negated)
|
||||||
: negated(negated), function(function), params(params)
|
: negated(negated), function(std::move(function)), params(std::move(params)) {}
|
||||||
{}
|
|
||||||
|
|
||||||
bool Condition::evaluate(RuleContext &context) {
|
bool Condition::evaluate(RuleContext &context) {
|
||||||
std::vector<Value> request;
|
std::vector<Value> request;
|
||||||
for(unsigned int i=0; i<params.size(); i++) {
|
for (auto & param : params) {
|
||||||
if(params[i].isType(Value::ADDRESS_SPACE_REFERENCE)) {
|
if (param.isType(Value::ADDRESS_SPACE_REFERENCE)) {
|
||||||
request.push_back(Value::fromAddressSpace(context.addressSpaces.at(params[i].asReference())));
|
request.push_back(Value::fromAddressSpace(context.addressSpaces.at(param.asReference())));
|
||||||
} else if(params[i].isType(Value::ATTRIBUTE_REFERENCE)) {
|
} else if (param.isType(Value::ATTRIBUTE_REFERENCE)) {
|
||||||
request.push_back(context.attributes[params[i].asReference()]);
|
request.push_back(context.attributes[param.asReference()]);
|
||||||
} else {
|
} else {
|
||||||
request.push_back(params[i]);
|
request.push_back(param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool result = context.function[function]->validate(request);
|
bool result = context.function[function]->validate(request);
|
||||||
|
@ -23,20 +24,19 @@ bool Condition::evaluate(RuleContext &context) {
|
||||||
|
|
||||||
|
|
||||||
Action::Action(ActionType type, std::string message)
|
Action::Action(ActionType type, std::string message)
|
||||||
: type(type), message(message)
|
: type(type), message(std::move(message)) {}
|
||||||
{}
|
|
||||||
|
|
||||||
Action::ActionType Action::getType() {
|
Action::ActionType Action::getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Action::getMessage() {
|
std::string Action::getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
IfStatement::IfStatement(Condition condition, Action action)
|
IfStatement::IfStatement(Condition condition, Action action)
|
||||||
: condition(condition), action(action)
|
: condition(std::move(condition)), action(std::move(action)) {}
|
||||||
{}
|
|
||||||
|
|
||||||
std::optional<Action> IfStatement::evaluate(RuleContext &context) {
|
std::optional<Action> IfStatement::evaluate(RuleContext &context) {
|
||||||
if (condition.evaluate(context)) {
|
if (condition.evaluate(context)) {
|
||||||
|
@ -46,12 +46,11 @@ std::optional<Action> IfStatement::evaluate(RuleContext &context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Rule::Rule(std::vector<IfStatement> statements)
|
Rule::Rule(std::vector<IfStatement> statements)
|
||||||
: statements(statements)
|
: statements(std::move(statements)) {}
|
||||||
{}
|
|
||||||
|
|
||||||
std::optional<Action> Rule::evaluate(RuleContext &context) {
|
std::optional<Action> Rule::evaluate(RuleContext &context) {
|
||||||
for(unsigned int i=0; i<statements.size(); i++) {
|
for (auto & statement : statements) {
|
||||||
auto response = statements[i].evaluate(context);
|
auto response = statement.evaluate(context);
|
||||||
if (response) {
|
if (response) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#ifndef DOMAIN_RULE_H
|
#ifndef DOMAIN_RULE_H
|
||||||
#define DOMAIN_RULE_H
|
#define DOMAIN_RULE_H
|
||||||
|
|
||||||
#include "addressspace.h"
|
#include "address_space.h"
|
||||||
#include "value.h"
|
#include "value.h"
|
||||||
#include "functionsignature.h"
|
#include "function_signature.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -44,6 +44,7 @@ public:
|
||||||
Action(ActionType type, std::string message);
|
Action(ActionType type, std::string message);
|
||||||
|
|
||||||
ActionType getType();
|
ActionType getType();
|
||||||
|
|
||||||
std::string getMessage();
|
std::string getMessage();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,11 +57,10 @@ public:
|
||||||
std::optional<Action> evaluate(RuleContext &context);
|
std::optional<Action> evaluate(RuleContext &context);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Rule
|
class Rule {
|
||||||
{
|
|
||||||
std::vector<IfStatement> statements;
|
std::vector<IfStatement> statements;
|
||||||
public:
|
public:
|
||||||
Rule(std::vector<IfStatement> statements);
|
explicit Rule(std::vector<IfStatement> statements);
|
||||||
|
|
||||||
std::optional<Action> evaluate(RuleContext &context);
|
std::optional<Action> evaluate(RuleContext &context);
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
namespace domain {
|
namespace domain {
|
||||||
|
|
||||||
Schema::Schema()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Schema::hasConnection(string &component, string &pin) {
|
bool Schema::hasConnection(string &component, string &pin) {
|
||||||
return getConnection(component, pin) != nullptr;
|
return getConnection(component, pin) != nullptr;
|
||||||
}
|
}
|
||||||
|
@ -25,4 +21,22 @@ ConnectionInstance* Schema::getConnection(string& component, string& pin) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BusInstance *Schema::getBusInstance(string &name) {
|
||||||
|
for (auto &instance: busInstances) {
|
||||||
|
if (instance->name == name) {
|
||||||
|
return instance.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComponentInstance *Schema::getComponentInstance(string &name) {
|
||||||
|
for (auto &instance: componentInstances) {
|
||||||
|
if (instance->name == name) {
|
||||||
|
return instance.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
#ifndef DOMAIN_SCHEMA_H
|
#ifndef DOMAIN_SCHEMA_H
|
||||||
#define DOMAIN_SCHEMA_H
|
#define DOMAIN_SCHEMA_H
|
||||||
|
|
||||||
#include "connectioninstance.h"
|
#include "connection_instance.h"
|
||||||
#include "instance.h"
|
#include "instance.h"
|
||||||
#include "wireinstance.h"
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -11,33 +10,16 @@ namespace domain {
|
||||||
|
|
||||||
class Schema {
|
class Schema {
|
||||||
public:
|
public:
|
||||||
Schema();
|
Schema() = default;
|
||||||
|
|
||||||
std::vector<shared_ptr<BusInstance>> busInstances;
|
std::vector<shared_ptr<BusInstance>> busInstances;
|
||||||
std::vector<shared_ptr<ComponentInstance>> componentInstances;
|
std::vector<shared_ptr<ComponentInstance>> componentInstances;
|
||||||
|
|
||||||
std::vector<shared_ptr<ConnectionInstance>> connections;
|
std::vector<shared_ptr<ConnectionInstance>> connections;
|
||||||
|
|
||||||
BusInstance *getBusInstance(std::string &name) {
|
BusInstance *getBusInstance(std::string &name);
|
||||||
for (auto &instance: busInstances) {
|
ComponentInstance *getComponentInstance(std::string &name);
|
||||||
if (instance->name == name) {
|
|
||||||
return instance.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ComponentInstance *getComponentInstance(std::string &name) {
|
|
||||||
for (auto &instance: componentInstances) {
|
|
||||||
if (instance->name == name) {
|
|
||||||
return instance.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasConnection(string &component, string &pin);
|
bool hasConnection(string &component, string &pin);
|
||||||
|
|
||||||
ConnectionInstance *getConnection(string &component, string &pin);
|
ConnectionInstance *getConnection(string &component, string &pin);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,93 @@
|
||||||
|
#ifndef DOMAIN_COMDEL_GENERATOR_H
|
||||||
|
#define DOMAIN_COMDEL_GENERATOR_H
|
||||||
|
|
||||||
|
#include "library.h"
|
||||||
|
#include "schema.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <comdel/parser/ast_nodes.h>
|
||||||
|
#include <comdel/parser/parse_context.h>
|
||||||
|
#include <comdel/parser/presult.h>
|
||||||
|
|
||||||
|
namespace domain {
|
||||||
|
|
||||||
|
struct ComdelContext {
|
||||||
|
std::vector<Attribute> attributes;
|
||||||
|
std::vector<std::string> wires;
|
||||||
|
std::string name;
|
||||||
|
bool inComponent;
|
||||||
|
bool inConnection;
|
||||||
|
bool inSingleAutomaticConnection;
|
||||||
|
bool inBus;
|
||||||
|
|
||||||
|
ComdelContext(std::string name, bool inComponent, bool inConnection, bool inSingleAutomaticConnection, bool inBus);
|
||||||
|
|
||||||
|
bool doesAttributeExists(std::string name, Value::ValueType type);
|
||||||
|
bool doesWireExists(std::string name);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class SchemaCreator {
|
||||||
|
std::vector<ComdelContext> context;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
std::string libraryInfo;
|
||||||
|
std::string header;
|
||||||
|
std::string componentDirectory;
|
||||||
|
std::optional<std::string> componentHeader = nullopt;
|
||||||
|
std::vector<AddressSpace> addressSpaces;
|
||||||
|
std::vector<Component> components;
|
||||||
|
std::vector<Bus> buses;
|
||||||
|
std::vector<Connection> connections;
|
||||||
|
std::map<std::string, std::string> messages;
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<SourceError> errors;
|
||||||
|
std::vector<FunctionValidator *> validators;
|
||||||
|
|
||||||
|
|
||||||
|
std::optional<AddressSpace> loadAddressSpace(AddressSpaceNode node);
|
||||||
|
std::optional<Component> loadComponent(ComponentNode node);
|
||||||
|
std::optional<Attribute> loadAttribute(AttributeNode node);
|
||||||
|
std::optional<Rule> loadRule(RuleNode node);
|
||||||
|
std::optional<Condition> loadCondition(ConditionNode node);
|
||||||
|
std::optional<Popup> loadPopup(PopupNode node, std::string name, Value::ValueType type);
|
||||||
|
std::optional<Display> loadDisplay(DisplayNode node);
|
||||||
|
std::optional<Wire> loadWire(WireNode node);
|
||||||
|
std::optional<Pin> loadPin(PinNode pins);
|
||||||
|
|
||||||
|
PinConnection loadPinConnection(PinConnectionNode node);
|
||||||
|
|
||||||
|
std::optional<Connection> loadConnection(ConnectionNode node);
|
||||||
|
std::optional<Bus> loadBus(BusNode node);
|
||||||
|
|
||||||
|
std::shared_ptr<ComponentInstance> loadComponentInstance(InstanceNode instance, Library &library);
|
||||||
|
std::shared_ptr<BusInstance> loadBusInstance(InstanceNode instance, Library &library);
|
||||||
|
|
||||||
|
std::optional<Bus> getBus(std::string name);
|
||||||
|
std::optional<Pin> getComponentPin(std::string name, std::string pin);
|
||||||
|
bool hasAddressSpace(std::string name);
|
||||||
|
|
||||||
|
void push(ComdelContext context);
|
||||||
|
void pushAdditional(std::string name);
|
||||||
|
ComdelContext ¤t();
|
||||||
|
void pop();
|
||||||
|
|
||||||
|
std::optional<Attribute> createMemoryAttribute();
|
||||||
|
vector<Enumeration> createWireEnumeration(vector<Value> enumeration);
|
||||||
|
std::optional<Popup> createMemoryPopup();
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SchemaCreator(std::vector<FunctionValidator *> validators);
|
||||||
|
|
||||||
|
std::vector<SourceError> getErrors();
|
||||||
|
|
||||||
|
std::optional<Library> loadLibrary(LibraryNode node);
|
||||||
|
Schema *loadSchema(SchemaNode node, Library &library);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace domain
|
||||||
|
|
||||||
|
#endif // DOMAIN_COMDEL_GENERATOR_H
|
File diff suppressed because it is too large
Load Diff
|
@ -1,153 +0,0 @@
|
||||||
#ifndef DOMAIN_COMDEL_GENERATOR_H
|
|
||||||
#define DOMAIN_COMDEL_GENERATOR_H
|
|
||||||
|
|
||||||
#include "library.h"
|
|
||||||
#include "schema.h"
|
|
||||||
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
#include <comdel/parser/astnode.h>
|
|
||||||
#include <comdel/parser/parsecontext.h>
|
|
||||||
#include <comdel/parser/presult.h>
|
|
||||||
|
|
||||||
namespace domain {
|
|
||||||
|
|
||||||
struct ComdelContext {
|
|
||||||
std::vector<Attribute> attributes;
|
|
||||||
std::vector<std::string> wires;
|
|
||||||
std::string name;
|
|
||||||
bool inComponent;
|
|
||||||
bool inConnection;
|
|
||||||
bool inSingleAutomaticConnection;
|
|
||||||
bool inBus;
|
|
||||||
|
|
||||||
ComdelContext(std::string name, bool inComponent, bool inConnection, bool inSingleAutomaticConnection, bool inBus)
|
|
||||||
: name(name), inComponent(inComponent), inConnection(inConnection), inSingleAutomaticConnection(inSingleAutomaticConnection), inBus(inBus)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool doesAttributeExists(std::string name, Value::ValueType type) {
|
|
||||||
for(auto &attribute: attributes) {
|
|
||||||
if(attribute.getDefault().getType() == type && attribute.getName() == name) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool doesWireExists(std::string name) {
|
|
||||||
for(auto &w: wires) {
|
|
||||||
if(w == name) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class SchemaCreator
|
|
||||||
{
|
|
||||||
std::vector<ComdelContext> context;
|
|
||||||
|
|
||||||
std::string name;
|
|
||||||
std::string libraryInfo;
|
|
||||||
std::string header;
|
|
||||||
std::string componentDirectory;
|
|
||||||
std::optional<std::string> componentHeader = nullopt;
|
|
||||||
std::vector<AddressSpace> addressSpaces;
|
|
||||||
std::vector<Component> components;
|
|
||||||
std::vector<Bus> buses;
|
|
||||||
std::vector<Connection> connections;
|
|
||||||
std::map<std::string, std::string> messages;
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<SourceError> errors;
|
|
||||||
std::vector<FunctionValidator*> validators;
|
|
||||||
|
|
||||||
std::optional<AddressSpace> loadAddressSpace(AddressSpaceNode node);
|
|
||||||
std::optional<Component> loadComponent(ComponentNode node);
|
|
||||||
std::optional<Attribute> loadAttribute(AttributeNode node);
|
|
||||||
std::optional<Rule> loadRule(RuleNode node);
|
|
||||||
std::optional<Condition> loadCondition(ConditionNode node);
|
|
||||||
std::optional<Popup> loadPopup(PopupNode node, std::string name, Value::ValueType type);
|
|
||||||
std::optional<Display> loadDisplay(DisplayNode node);
|
|
||||||
std::optional<Wire> loadWire(WireNode node);
|
|
||||||
std::optional<Pin> loadPin(PinNode pins);
|
|
||||||
PinConnection loadPinConnection(PinConnectionNode node);
|
|
||||||
std::optional<Connection> loadConnection(ConnectionNode node);
|
|
||||||
std::optional<Bus> loadBus(BusNode node);
|
|
||||||
|
|
||||||
std::shared_ptr<ComponentInstance> loadComponentInstance(InstanceNode instance, Library &library);
|
|
||||||
std::shared_ptr<BusInstance> loadBusInstance(InstanceNode instance, Library &library);
|
|
||||||
|
|
||||||
std::optional<Attribute> createMemoryAttribute();
|
|
||||||
|
|
||||||
std::optional<Bus> getBus(std::string name) {
|
|
||||||
for(auto &bus: buses) {
|
|
||||||
if(bus.getName() == name) {
|
|
||||||
return bus;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<Pin> getComponentPin(std::string name, std::string pin) {
|
|
||||||
for(auto &c: components) {
|
|
||||||
if(c.getName() == name) {
|
|
||||||
for(auto &p: c.getPins()) {
|
|
||||||
if(p.getName() == pin) {
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasAddressSpace(std::string name) {
|
|
||||||
for(auto &as: addressSpaces) {
|
|
||||||
if(as.getName() == name) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void push(ComdelContext context) {
|
|
||||||
this->context.push_back(context);
|
|
||||||
}
|
|
||||||
void pushAdditional(std::string name) {
|
|
||||||
if(!this->context.empty()) {
|
|
||||||
this->context.push_back(current());
|
|
||||||
current().name = name;
|
|
||||||
} else {
|
|
||||||
ComdelContext con(name, false, false, false, false);
|
|
||||||
push(con);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ComdelContext ¤t() {
|
|
||||||
return this->context[this->context.size() - 1];
|
|
||||||
}
|
|
||||||
void pop() {
|
|
||||||
this->context.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
SchemaCreator(std::vector<FunctionValidator*> validators);
|
|
||||||
|
|
||||||
std::vector<SourceError> getErrors() {
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<Library> loadLibrary(LibraryNode node);
|
|
||||||
|
|
||||||
Schema* loadSchema(SchemaNode node, Library &library);
|
|
||||||
|
|
||||||
vector <Enumeration> createWireEnumeration(vector<Value> vector1);
|
|
||||||
|
|
||||||
std::optional<Popup> createMemoryPopup();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace domain
|
|
||||||
|
|
||||||
#endif // DOMAIN_COMDEL_GENERATOR_H
|
|
|
@ -24,6 +24,12 @@ std::string Value::string() {
|
||||||
return "AddressSpace::" + reference;
|
return "AddressSpace::" + reference;
|
||||||
case ATTRIBUTE_REFERENCE:
|
case ATTRIBUTE_REFERENCE:
|
||||||
return "Attribute::" + reference;
|
return "Attribute::" + reference;
|
||||||
|
case MEMORY_REFERENCE:
|
||||||
|
if (memoryReference.has_value()) {
|
||||||
|
return "Memory::" + *memoryReference;
|
||||||
|
} else {
|
||||||
|
return "Memory::null";
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
@ -33,8 +39,9 @@ std::string Value::string() {
|
||||||
Value::ValueType Value::getType() {
|
Value::ValueType Value::getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
bool Value::isType(Value::ValueType type) {
|
|
||||||
return this->type == type;
|
bool Value::isType(Value::ValueType _type) {
|
||||||
|
return type == _type;
|
||||||
}
|
}
|
||||||
|
|
||||||
long long Value::asInt() {
|
long long Value::asInt() {
|
||||||
|
@ -43,32 +50,36 @@ long long Value::asInt() {
|
||||||
}
|
}
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Value::asString() {
|
std::string Value::asString() {
|
||||||
if (isType(Value::STRING)) {
|
if (isType(Value::STRING)) {
|
||||||
return stringValue;
|
return stringValue;
|
||||||
}
|
}
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Value::asBool() {
|
bool Value::asBool() {
|
||||||
if (isType(Value::BOOL)) {
|
if (isType(Value::BOOL)) {
|
||||||
return boolValue;
|
return boolValue;
|
||||||
}
|
}
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressSpace Value::asAddressSpace() {
|
AddressSpace Value::asAddressSpace() {
|
||||||
if (isType(Value::ADDRESS_SPACE)) {
|
if (isType(Value::ADDRESS_SPACE)) {
|
||||||
return *addressSpace;
|
return *addressSpace;
|
||||||
}
|
}
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Value::asReference() {
|
std::string Value::asReference() {
|
||||||
if(isType(Value::WIRE_REFERENCE) || isType(Value::ADDRESS_SPACE_REFERENCE) || isType(Value::ATTRIBUTE_REFERENCE) || isType(Value::UNDEFINED)) {
|
if (isType(Value::WIRE_REFERENCE) || isType(Value::ADDRESS_SPACE_REFERENCE) ||
|
||||||
|
isType(Value::ATTRIBUTE_REFERENCE) || isType(Value::UNDEFINED)) {
|
||||||
return reference;
|
return reference;
|
||||||
}
|
}
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::optional<std::string> Value::asMemoryReference() {
|
std::optional<std::string> Value::asMemoryReference() {
|
||||||
return memoryReference;
|
return memoryReference;
|
||||||
}
|
}
|
||||||
|
@ -84,18 +95,21 @@ void Value::setInt(long long value) {
|
||||||
}
|
}
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Value::setString(std::string value) {
|
void Value::setString(std::string value) {
|
||||||
if (isType(Value::STRING)) {
|
if (isType(Value::STRING)) {
|
||||||
this->stringValue = value;
|
this->stringValue = value;
|
||||||
}
|
}
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Value::setBool(bool value) {
|
void Value::setBool(bool value) {
|
||||||
if (isType(Value::BOOL)) {
|
if (isType(Value::BOOL)) {
|
||||||
this->boolValue = value;
|
this->boolValue = value;
|
||||||
}
|
}
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Value::setReference(std::string value) {
|
void Value::setReference(std::string value) {
|
||||||
if (isType(Value::WIRE_REFERENCE)) {
|
if (isType(Value::WIRE_REFERENCE)) {
|
||||||
this->reference = value;
|
this->reference = value;
|
||||||
|
@ -110,24 +124,28 @@ Value Value::fromInt(long long value) {
|
||||||
val.intValue = value;
|
val.intValue = value;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value Value::fromString(std::string value) {
|
Value Value::fromString(std::string value) {
|
||||||
Value val;
|
Value val;
|
||||||
val.type = Value::STRING;
|
val.type = Value::STRING;
|
||||||
val.stringValue = value;
|
val.stringValue = value;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value Value::fromBool(bool value) {
|
Value Value::fromBool(bool value) {
|
||||||
Value val;
|
Value val;
|
||||||
val.type = Value::BOOL;
|
val.type = Value::BOOL;
|
||||||
val.boolValue = value;
|
val.boolValue = value;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value Value::fromAddressSpace(AddressSpace addressSpace) {
|
Value Value::fromAddressSpace(AddressSpace addressSpace) {
|
||||||
Value val;
|
Value val;
|
||||||
val.type = Value::ADDRESS_SPACE;
|
val.type = Value::ADDRESS_SPACE;
|
||||||
val.addressSpace = addressSpace;
|
val.addressSpace = addressSpace;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value Value::fromReference(std::string value, Value::ValueType type) {
|
Value Value::fromReference(std::string value, Value::ValueType type) {
|
||||||
Value val;
|
Value val;
|
||||||
val.type = type;
|
val.type = type;
|
||||||
|
@ -135,18 +153,19 @@ Value Value::fromReference(std::string value, Value::ValueType type) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value Value::ofType(Value::ValueType type) {
|
|
||||||
Value val;
|
|
||||||
val.type = type;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
Value Value::fromNull() {
|
Value Value::fromNull() {
|
||||||
Value val;
|
Value val;
|
||||||
val.type = Value::NIL;
|
val.type = Value::NIL;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value Value::fromMemoryReference(std::optional<std::string> value) {
|
||||||
|
Value val;
|
||||||
|
val.type = MEMORY_REFERENCE;
|
||||||
|
val.memoryReference = value;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
std::string Value::stringify() {
|
std::string Value::stringify() {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case INT:
|
case INT:
|
||||||
|
@ -172,17 +191,9 @@ std::string Value::stringify() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Value Value::fromMemoryReference(std::optional<std::string> value) {
|
Value Value::ofType(Value::ValueType type) {
|
||||||
Value val;
|
Value val;
|
||||||
val.type = MEMORY_REFERENCE;
|
val.type = type;
|
||||||
val.memoryReference = value;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
Value Value::fromMemory(domain::ComponentInstance *memory) {
|
|
||||||
Value val;
|
|
||||||
val.type = MEMORY;
|
|
||||||
val.memory = memory;
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef DOMAIN_VALUE_H
|
#ifndef DOMAIN_VALUE_H
|
||||||
#define DOMAIN_VALUE_H
|
#define DOMAIN_VALUE_H
|
||||||
|
|
||||||
#include "addressspace.h"
|
#include "address_space.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
@ -11,8 +11,7 @@ namespace domain {
|
||||||
|
|
||||||
class ComponentInstance;
|
class ComponentInstance;
|
||||||
|
|
||||||
class Value
|
class Value {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
enum ValueType {
|
enum ValueType {
|
||||||
INT,
|
INT,
|
||||||
|
@ -42,7 +41,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Value() {}
|
Value() = default;
|
||||||
|
|
||||||
bool equals(Value value) {
|
bool equals(Value value) {
|
||||||
if (value.getType() == type) {
|
if (value.getType() == type) {
|
||||||
|
@ -74,32 +73,48 @@ public:
|
||||||
std::string string();
|
std::string string();
|
||||||
|
|
||||||
ValueType getType();
|
ValueType getType();
|
||||||
|
|
||||||
bool isType(ValueType type);
|
bool isType(ValueType type);
|
||||||
|
|
||||||
long long asInt();
|
long long asInt();
|
||||||
|
|
||||||
std::string asString();
|
std::string asString();
|
||||||
|
|
||||||
bool asBool();
|
bool asBool();
|
||||||
|
|
||||||
std::string asReference();
|
std::string asReference();
|
||||||
|
|
||||||
std::optional<std::string> asMemoryReference();
|
std::optional<std::string> asMemoryReference();
|
||||||
|
|
||||||
domain::ComponentInstance *asMemory();
|
domain::ComponentInstance *asMemory();
|
||||||
|
|
||||||
AddressSpace asAddressSpace();
|
AddressSpace asAddressSpace();
|
||||||
|
|
||||||
void setInt(long long intValue);
|
void setInt(long long intValue);
|
||||||
|
|
||||||
void setString(std::string value);
|
void setString(std::string value);
|
||||||
|
|
||||||
void setBool(bool value);
|
void setBool(bool value);
|
||||||
|
|
||||||
void setReference(std::string value);
|
void setReference(std::string value);
|
||||||
|
|
||||||
std::string stringify();
|
std::string stringify();
|
||||||
|
|
||||||
static Value fromInt(long long value);
|
static Value fromInt(long long value);
|
||||||
|
|
||||||
static Value fromString(std::string value);
|
static Value fromString(std::string value);
|
||||||
|
|
||||||
static Value fromBool(bool value);
|
static Value fromBool(bool value);
|
||||||
|
|
||||||
static Value fromNull();
|
static Value fromNull();
|
||||||
|
|
||||||
static Value fromAddressSpace(AddressSpace addressSpace);
|
static Value fromAddressSpace(AddressSpace addressSpace);
|
||||||
|
|
||||||
static Value fromReference(std::string value, ValueType type);
|
static Value fromReference(std::string value, ValueType type);
|
||||||
static Value ofType(ValueType type);
|
|
||||||
static Value fromMemoryReference(std::optional<std::string> memoryReference);
|
static Value fromMemoryReference(std::optional<std::string> memoryReference);
|
||||||
static Value fromMemory(domain::ComponentInstance *memory);
|
|
||||||
|
static Value ofType(ValueType type);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
#include "wireinstance.h"
|
|
||||||
|
|
||||||
namespace domain {
|
|
||||||
|
|
||||||
WireInstance::WireInstance(std::string name, Display display, std::pair<int, int> position)
|
|
||||||
: name(name), display(display), position(position)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace domain
|
|
|
@ -1,24 +0,0 @@
|
||||||
#ifndef DOMAIN_WIRE_INSTANCE_H
|
|
||||||
#define DOMAIN_WIRE_INSTANCE_H
|
|
||||||
|
|
||||||
#include "display.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace domain {
|
|
||||||
|
|
||||||
class WireInstance
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::string name;
|
|
||||||
Display display;
|
|
||||||
std::pair<int, int> position;
|
|
||||||
|
|
||||||
WireInstance(std::string name, Display display, std::pair<int, int> position);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace domain
|
|
||||||
|
|
||||||
#endif // DOMAIN_WIREINSTANCE_H
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "astnode.h"
|
#include "ast_nodes.h"
|
||||||
|
|
||||||
/*************************** AST NODE ********************************/
|
/*************************** AST NODE ********************************/
|
||||||
|
|
||||||
|
@ -9,14 +9,14 @@ AstNode::~AstNode() = default;
|
||||||
NumberNode::NumberNode(const std::string &expression) {
|
NumberNode::NumberNode(const std::string &expression) {
|
||||||
if (expression.size() > 2) {
|
if (expression.size() > 2) {
|
||||||
if (expression.substr(0, 2) == "0x") {
|
if (expression.substr(0, 2) == "0x") {
|
||||||
this->value = std::stoll(expression, 0, 16);
|
this->value = std::stoll(expression, nullptr, 16);
|
||||||
} else if (expression.substr(0, 2) == "0b") {
|
} else if (expression.substr(0, 2) == "0b") {
|
||||||
this->value = std::stoll(expression, 0, 2);
|
this->value = std::stoll(expression, nullptr, 2);
|
||||||
} else {
|
} else {
|
||||||
this->value = std::stoll(expression, 0, 10);
|
this->value = std::stoll(expression, nullptr, 10);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this->value = std::stoll(expression, 0, 10);
|
this->value = std::stoll(expression, nullptr, 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
#define AST_NODE_H
|
#define AST_NODE_H
|
||||||
|
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "sourceerror.h"
|
#include "source_error.h"
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,57 +21,59 @@ public:
|
||||||
virtual ~AstNode();
|
virtual ~AstNode();
|
||||||
|
|
||||||
AstNode(AstNode &&) = default;
|
AstNode(AstNode &&) = default;
|
||||||
|
|
||||||
AstNode &operator=(AstNode &&) = default;
|
AstNode &operator=(AstNode &&) = default;
|
||||||
|
|
||||||
AstNode(const AstNode &) = default;
|
AstNode(const AstNode &) = default;
|
||||||
|
|
||||||
AstNode &operator=(const AstNode &) = default;
|
AstNode &operator=(const AstNode &) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct EnumNode: public AstNode
|
struct EnumNode : public AstNode {
|
||||||
{
|
|
||||||
EnumNode() = default;
|
EnumNode() = default;
|
||||||
|
|
||||||
explicit EnumNode(T value) : value(value) {}
|
explicit EnumNode(T value) : value(value) {}
|
||||||
|
|
||||||
T value;
|
T value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StringNode: public AstNode
|
struct StringNode : public AstNode {
|
||||||
{
|
|
||||||
std::string value;
|
std::string value;
|
||||||
|
|
||||||
std::string asString();
|
std::string asString();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IdentifierNode: public AstNode
|
struct IdentifierNode : public AstNode {
|
||||||
{
|
|
||||||
std::string value;
|
std::string value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NumberNode : public AstNode {
|
struct NumberNode : public AstNode {
|
||||||
long long int value;
|
long long int value;
|
||||||
|
|
||||||
explicit NumberNode(const std::string &expression);
|
explicit NumberNode(const std::string &expression);
|
||||||
|
|
||||||
NumberNode() : value(0) {}
|
NumberNode() : value(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CountNode: public AstNode
|
struct CountNode : public AstNode {
|
||||||
{
|
|
||||||
NumberNode first;
|
NumberNode first;
|
||||||
NumberNode second;
|
NumberNode second;
|
||||||
|
|
||||||
CountNode(NumberNode first, NumberNode second): first(first), second(second) {}
|
CountNode(NumberNode first, NumberNode second) : first(std::move(first)), second(std::move(second)) {}
|
||||||
|
|
||||||
CountNode() = default;
|
CountNode() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct AddressSpaceNode: public AstNode
|
struct AddressSpaceNode : public AstNode {
|
||||||
{
|
|
||||||
IdentifierNode name;
|
IdentifierNode name;
|
||||||
NumberNode start;
|
NumberNode start;
|
||||||
NumberNode end;
|
NumberNode end;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ValueNode: public AstNode
|
class ValueNode : public AstNode {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
enum ValueType {
|
enum ValueType {
|
||||||
INT,
|
INT,
|
||||||
|
@ -92,27 +95,36 @@ private:
|
||||||
public:
|
public:
|
||||||
ValueNode() = default;
|
ValueNode() = default;
|
||||||
|
|
||||||
ValueType getType() {
|
ValueType getType() const {
|
||||||
return type.value;
|
return type.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
long long asInt();
|
long long asInt();
|
||||||
|
|
||||||
std::string asString();
|
std::string asString();
|
||||||
|
|
||||||
std::string asIdentifier();
|
std::string asIdentifier();
|
||||||
|
|
||||||
bool asBool();
|
bool asBool();
|
||||||
|
|
||||||
bool is(ValueType valueType);
|
bool is(ValueType valueType);
|
||||||
|
|
||||||
static ValueNode ofBool(bool _value);
|
static ValueNode ofBool(bool _value);
|
||||||
|
|
||||||
static ValueNode ofInt(long long _value);
|
static ValueNode ofInt(long long _value);
|
||||||
|
|
||||||
static ValueNode ofString(std::string _value);
|
static ValueNode ofString(std::string _value);
|
||||||
|
|
||||||
static ValueNode ofIdentifier(std::string _value);
|
static ValueNode ofIdentifier(std::string _value);
|
||||||
|
|
||||||
static ValueNode ofMemory(std::optional<std::string> _value);
|
static ValueNode ofMemory(std::optional<std::string> _value);
|
||||||
|
|
||||||
static ValueNode ofNull();
|
static ValueNode ofNull();
|
||||||
|
|
||||||
static ValueNode ofWire(std::optional<std::string> _value);
|
static ValueNode ofWire(std::optional<std::string> _value);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConditionNode
|
struct ConditionNode {
|
||||||
{
|
|
||||||
bool negated;
|
bool negated;
|
||||||
IdentifierNode functionName;
|
IdentifierNode functionName;
|
||||||
std::vector<ValueNode> params;
|
std::vector<ValueNode> params;
|
||||||
|
@ -130,25 +142,21 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct IfStatementNode: public AstNode
|
struct IfStatementNode : public AstNode {
|
||||||
{
|
|
||||||
ConditionNode condition;
|
ConditionNode condition;
|
||||||
ActionNode action;
|
ActionNode action;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RuleNode: public AstNode
|
struct RuleNode : public AstNode {
|
||||||
{
|
|
||||||
std::vector<IfStatementNode> statements;
|
std::vector<IfStatementNode> statements;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EnumerationNode: public AstNode
|
struct EnumerationNode : public AstNode {
|
||||||
{
|
|
||||||
StringNode key;
|
StringNode key;
|
||||||
ValueNode value;
|
ValueNode value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PopupNode: public AstNode
|
struct PopupNode : public AstNode {
|
||||||
{
|
|
||||||
enum PopupType {
|
enum PopupType {
|
||||||
AUTOMATIC,
|
AUTOMATIC,
|
||||||
ON_DEMAND
|
ON_DEMAND
|
||||||
|
@ -164,14 +172,12 @@ struct PopupNode: public AstNode
|
||||||
std::vector<RuleNode> rules;
|
std::vector<RuleNode> rules;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PropertyNode: public AstNode
|
struct PropertyNode : public AstNode {
|
||||||
{
|
|
||||||
IdentifierNode key;
|
IdentifierNode key;
|
||||||
ValueNode value;
|
ValueNode value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DisplayItemNode: public AstNode
|
struct DisplayItemNode : public AstNode {
|
||||||
{
|
|
||||||
IdentifierNode type;
|
IdentifierNode type;
|
||||||
std::vector<PropertyNode> values;
|
std::vector<PropertyNode> values;
|
||||||
|
|
||||||
|
@ -222,13 +228,11 @@ struct DisplayItemNode: public AstNode
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DisplayNode: public AstNode
|
struct DisplayNode : public AstNode {
|
||||||
{
|
|
||||||
std::vector<DisplayItemNode> items;
|
std::vector<DisplayItemNode> items;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PinConnectionNode: public AstNode
|
struct PinConnectionNode : public AstNode {
|
||||||
{
|
|
||||||
enum ConnectionType {
|
enum ConnectionType {
|
||||||
REQUIRED,
|
REQUIRED,
|
||||||
OPTIONAL
|
OPTIONAL
|
||||||
|
@ -238,8 +242,7 @@ struct PinConnectionNode: public AstNode
|
||||||
EnumNode<ConnectionType> type;
|
EnumNode<ConnectionType> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PinNode: public AstNode
|
struct PinNode : public AstNode {
|
||||||
{
|
|
||||||
enum PinType {
|
enum PinType {
|
||||||
IN_OUT,
|
IN_OUT,
|
||||||
IN,
|
IN,
|
||||||
|
@ -254,8 +257,7 @@ struct PinNode: public AstNode
|
||||||
std::optional<std::vector<ValueNode>> wires;
|
std::optional<std::vector<ValueNode>> wires;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WireNode: public AstNode
|
struct WireNode : public AstNode {
|
||||||
{
|
|
||||||
enum WireType {
|
enum WireType {
|
||||||
WIRE,
|
WIRE,
|
||||||
WIRED_AND,
|
WIRED_AND,
|
||||||
|
@ -272,22 +274,19 @@ struct WireNode: public AstNode
|
||||||
ValueNode terminateWith;
|
ValueNode terminateWith;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AttributeNode: public AstNode
|
struct AttributeNode : public AstNode {
|
||||||
{
|
|
||||||
ValueNode::ValueType type;
|
ValueNode::ValueType type;
|
||||||
IdentifierNode name;
|
IdentifierNode name;
|
||||||
std::optional<ValueNode> defaultValue;
|
std::optional<ValueNode> defaultValue;
|
||||||
std::optional<PopupNode> popup;
|
std::optional<PopupNode> popup;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConnectionComponentNode: public AstNode
|
struct ConnectionComponentNode : public AstNode {
|
||||||
{
|
|
||||||
IdentifierNode component;
|
IdentifierNode component;
|
||||||
IdentifierNode pin;
|
IdentifierNode pin;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConnectionNode: public AstNode
|
struct ConnectionNode : public AstNode {
|
||||||
{
|
|
||||||
ConnectionComponentNode first;
|
ConnectionComponentNode first;
|
||||||
std::optional<ConnectionComponentNode> second;
|
std::optional<ConnectionComponentNode> second;
|
||||||
|
|
||||||
|
@ -298,8 +297,7 @@ struct ConnectionNode: public AstNode
|
||||||
std::optional<std::vector<ValueNode>> secondWires;
|
std::optional<std::vector<ValueNode>> secondWires;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ComponentNode: public AstNode
|
struct ComponentNode : public AstNode {
|
||||||
{
|
|
||||||
enum ComponentType {
|
enum ComponentType {
|
||||||
OTHER,
|
OTHER,
|
||||||
PROCESSOR,
|
PROCESSOR,
|
||||||
|
@ -318,8 +316,7 @@ struct ComponentNode: public AstNode
|
||||||
std::vector<AttributeNode> attributes;
|
std::vector<AttributeNode> attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BusNode: public AstNode
|
struct BusNode : public AstNode {
|
||||||
{
|
|
||||||
enum BusType {
|
enum BusType {
|
||||||
AUTOMATIC,
|
AUTOMATIC,
|
||||||
REGULAR,
|
REGULAR,
|
||||||
|
@ -335,8 +332,7 @@ struct BusNode: public AstNode
|
||||||
std::vector<WireNode> wires;
|
std::vector<WireNode> wires;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LibraryNode: public AstNode
|
struct LibraryNode : public AstNode {
|
||||||
{
|
|
||||||
std::optional<StringNode> name;
|
std::optional<StringNode> name;
|
||||||
std::optional<StringNode> libraryInfo;
|
std::optional<StringNode> libraryInfo;
|
||||||
std::optional<StringNode> header;
|
std::optional<StringNode> header;
|
||||||
|
@ -353,14 +349,12 @@ struct LibraryNode: public AstNode
|
||||||
};
|
};
|
||||||
|
|
||||||
// SCHEMA models
|
// SCHEMA models
|
||||||
struct InstanceAttributeNode: public AstNode
|
struct InstanceAttributeNode : public AstNode {
|
||||||
{
|
|
||||||
IdentifierNode name;
|
IdentifierNode name;
|
||||||
ValueNode value;
|
ValueNode value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InstanceNode: public AstNode
|
struct InstanceNode : public AstNode {
|
||||||
{
|
|
||||||
IdentifierNode name;
|
IdentifierNode name;
|
||||||
IdentifierNode component;
|
IdentifierNode component;
|
||||||
|
|
||||||
|
@ -370,14 +364,12 @@ struct InstanceNode: public AstNode
|
||||||
std::optional<NumberNode> size;
|
std::optional<NumberNode> size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConnectionComponentInstance: public AstNode
|
struct ConnectionComponentInstance : public AstNode {
|
||||||
{
|
|
||||||
IdentifierNode instance;
|
IdentifierNode instance;
|
||||||
IdentifierNode pin;
|
IdentifierNode pin;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConnectionInstanceNode: public AstNode
|
struct ConnectionInstanceNode : public AstNode {
|
||||||
{
|
|
||||||
ConnectionComponentInstance first;
|
ConnectionComponentInstance first;
|
||||||
std::optional<ConnectionComponentInstance> second;
|
std::optional<ConnectionComponentInstance> second;
|
||||||
|
|
||||||
|
@ -387,8 +379,7 @@ struct ConnectionInstanceNode: public AstNode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct SchemaNode: public AstNode
|
struct SchemaNode : public AstNode {
|
||||||
{
|
|
||||||
std::optional<StringNode> source;
|
std::optional<StringNode> source;
|
||||||
|
|
||||||
std::vector<InstanceNode> instances;
|
std::vector<InstanceNode> instances;
|
|
@ -1,7 +1,7 @@
|
||||||
#include "comdelparser.h"
|
#include "comdel_parser.h"
|
||||||
|
|
||||||
#include "poly.h"
|
#include "poly.h"
|
||||||
#include "tokenstype.h"
|
#include "tokens_type.h"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -9,9 +9,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
ComdelParser::ComdelParser(std::vector<Token> tokens)
|
ComdelParser::ComdelParser(std::vector<Token> tokens)
|
||||||
: tokens(std::move(tokens))
|
: tokens(std::move(tokens)), position(0) {}
|
||||||
, position(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// Tries to consume a token, returns an error otherwise.
|
// Tries to consume a token, returns an error otherwise.
|
||||||
// Unlike the regular consume() call this should be used
|
// Unlike the regular consume() call this should be used
|
||||||
|
@ -27,8 +25,7 @@ ComdelParser::ComdelParser(std::vector<Token> tokens)
|
||||||
// Checks if the current token matches the argument.
|
// Checks if the current token matches the argument.
|
||||||
// Otherwise, adds the token to the list of expected tokens (used in
|
// Otherwise, adds the token to the list of expected tokens (used in
|
||||||
// error message).
|
// error message).
|
||||||
bool ComdelParser::check(TokenType tokenType)
|
bool ComdelParser::check(TokenType tokenType) {
|
||||||
{
|
|
||||||
if (current().type == tokenType)
|
if (current().type == tokenType)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -94,7 +91,7 @@ PError ComdelParser::unexpected() {
|
||||||
else
|
else
|
||||||
ss << ".";
|
ss << ".";
|
||||||
}
|
}
|
||||||
return PError({current().span, ss.str()});
|
return {{current().span, ss.str()}};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses a list of 'nodes' separated by 'separator'. Parsed nodes
|
// Parses a list of 'nodes' separated by 'separator'. Parsed nodes
|
||||||
|
@ -107,18 +104,18 @@ PError ComdelParser::unexpected() {
|
||||||
//
|
//
|
||||||
// 'closeDelim' is mandatory, and it will be consumed.
|
// 'closeDelim' is mandatory, and it will be consumed.
|
||||||
//
|
//
|
||||||
// Function 'parse_f' should only parse a single node of type T.
|
// Function 'parse_f' should only parseLibrary a single node of type T.
|
||||||
//
|
//
|
||||||
// Parameter allowTrailing==true means that the list should end with
|
// Parameter allowTrailing==true means that the list should end with
|
||||||
// 'separator' and otherwise the list should end with 'node'. This
|
// 'separator' and otherwise the list should end with 'node'. This
|
||||||
// parameter is false in every call-site!
|
// parameter is false in every call-site!
|
||||||
template<typename T> PResult<std::vector<T>>
|
template<typename T>
|
||||||
|
PResult<std::vector<T>>
|
||||||
ComdelParser::parseList(std::optional<TokenType> openDelim,
|
ComdelParser::parseList(std::optional<TokenType> openDelim,
|
||||||
TokenType closeDelim,
|
TokenType closeDelim,
|
||||||
std::optional<TokenType> separator,
|
std::optional<TokenType> separator,
|
||||||
bool allowTrailing,
|
bool allowTrailing,
|
||||||
const std::function<PResult<T>()>& parse_f)
|
const std::function<PResult<T>()> &parse_f) {
|
||||||
{
|
|
||||||
std::vector<T> vec;
|
std::vector<T> vec;
|
||||||
|
|
||||||
if (openDelim) {
|
if (openDelim) {
|
||||||
|
@ -169,8 +166,7 @@ void ComdelParser::skipUntilNextKeyword() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<SourceError> &ComdelParser::getErrors()
|
const std::vector<SourceError> &ComdelParser::getErrors() {
|
||||||
{
|
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,9 +180,8 @@ Span &ComdelParser::getPreviousSpan() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// See comment for Spanner
|
// See comment for Spanner
|
||||||
Spanner ComdelParser::getSpanner()
|
Spanner ComdelParser::getSpanner() {
|
||||||
{
|
return {current().span, getPreviousSpan()};
|
||||||
return Spanner(current().span, getPreviousSpan());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// utility for reading strings
|
// utility for reading strings
|
||||||
|
@ -196,7 +191,7 @@ Spanner ComdelParser::getSpanner()
|
||||||
if (!assign_or_return_if_err_temp_) { \
|
if (!assign_or_return_if_err_temp_) { \
|
||||||
err = PError(assign_or_return_if_err_temp_.error()); \
|
err = PError(assign_or_return_if_err_temp_.error()); \
|
||||||
} else { \
|
} else { \
|
||||||
var = *assign_or_return_if_err_temp_; \
|
(var) = *assign_or_return_if_err_temp_; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -207,7 +202,7 @@ Spanner ComdelParser::getSpanner()
|
||||||
if (!assign_or_return_if_err_temp_) { \
|
if (!assign_or_return_if_err_temp_) { \
|
||||||
err = PError(assign_or_return_if_err_temp_.error()); \
|
err = PError(assign_or_return_if_err_temp_.error()); \
|
||||||
} else { \
|
} else { \
|
||||||
var.push_back(*assign_or_return_if_err_temp_); \
|
(var).push_back(*assign_or_return_if_err_temp_); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -218,7 +213,7 @@ Spanner ComdelParser::getSpanner()
|
||||||
if (!assign_or_return_if_err_temp_) { \
|
if (!assign_or_return_if_err_temp_) { \
|
||||||
return PError(assign_or_return_if_err_temp_.error()); \
|
return PError(assign_or_return_if_err_temp_.error()); \
|
||||||
} else { \
|
} else { \
|
||||||
var.push_back(*assign_or_return_if_err_temp_); \
|
(var).push_back(*assign_or_return_if_err_temp_); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -229,8 +224,7 @@ Spanner ComdelParser::getSpanner()
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
std::optional<LibraryNode> ComdelParser::parse()
|
std::optional<LibraryNode> ComdelParser::parseLibrary() {
|
||||||
{
|
|
||||||
|
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
LibraryNode library{};
|
LibraryNode library{};
|
||||||
|
@ -262,11 +256,14 @@ std::optional<LibraryNode> ComdelParser::parse()
|
||||||
APPEND_OR_SET_ERR(library.connections, parseConnection());
|
APPEND_OR_SET_ERR(library.connections, parseConnection());
|
||||||
} else if (check(TokenType::KW_MESSAGES)) {
|
} else if (check(TokenType::KW_MESSAGES)) {
|
||||||
bump();
|
bump();
|
||||||
ASSIGN_OR_SET_ERR(library.messages, parseList<PropertyNode>(std::optional<TokenType>(TokenType::LBRACE),
|
ASSIGN_OR_SET_ERR(library.messages, parseList<PropertyNode>(TokenType::LBRACE,
|
||||||
TokenType::RBRACE,
|
TokenType::RBRACE,
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
false,
|
false,
|
||||||
[this]{return parseProperty(std::optional<TokenType>(TokenType::STRING));}
|
[this] { return parseProperty(
|
||||||
|
std::optional<TokenType>(
|
||||||
|
TokenType::STRING));
|
||||||
|
}
|
||||||
));
|
));
|
||||||
if (!err.has_value()) {
|
if (!err.has_value()) {
|
||||||
skipUntilNextKeyword();
|
skipUntilNextKeyword();
|
||||||
|
@ -282,7 +279,7 @@ std::optional<LibraryNode> ComdelParser::parse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errors.size())
|
if (!errors.empty())
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
return spanner(library);
|
return spanner(library);
|
||||||
|
@ -293,8 +290,7 @@ std::optional<LibraryNode> ComdelParser::parse()
|
||||||
* StringNode := "\"" + CONTENT + "\""
|
* StringNode := "\"" + CONTENT + "\""
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
PResult<StringNode> ComdelParser::parseString()
|
PResult<StringNode> ComdelParser::parseString() {
|
||||||
{
|
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
if (check(TokenType::STRING)) {
|
if (check(TokenType::STRING)) {
|
||||||
StringNode node;
|
StringNode node;
|
||||||
|
@ -312,8 +308,7 @@ PResult<StringNode> ComdelParser::parseString()
|
||||||
* IdentifierNode := IDENTIFIER
|
* IdentifierNode := IDENTIFIER
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
PResult<IdentifierNode> ComdelParser::parseIdentifier()
|
PResult<IdentifierNode> ComdelParser::parseIdentifier() {
|
||||||
{
|
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
if (check(TokenType::IDENTIFIER)) {
|
if (check(TokenType::IDENTIFIER)) {
|
||||||
IdentifierNode node;
|
IdentifierNode node;
|
||||||
|
@ -330,8 +325,7 @@ PResult<IdentifierNode> ComdelParser::parseIdentifier()
|
||||||
* NumberNode := ('0x' | '0b'){0,1}[0-9]*
|
* NumberNode := ('0x' | '0b'){0,1}[0-9]*
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
PResult<NumberNode> ComdelParser::parseNumber()
|
PResult<NumberNode> ComdelParser::parseNumber() {
|
||||||
{
|
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
if (check(TokenType::NUMBER)) {
|
if (check(TokenType::NUMBER)) {
|
||||||
NumberNode node{current().text};
|
NumberNode node{current().text};
|
||||||
|
@ -348,8 +342,7 @@ PResult<NumberNode> ComdelParser::parseNumber()
|
||||||
* CountNode := "@size (" + NumberNode + "," + NumberNode + ")"
|
* CountNode := "@size (" + NumberNode + "," + NumberNode + ")"
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
PResult<CountNode> ComdelParser::parseCount()
|
PResult<CountNode> ComdelParser::parseCount() {
|
||||||
{
|
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::KW_COUNT);
|
RETURN_IF_NOT_TOKEN(TokenType::KW_COUNT);
|
||||||
|
|
||||||
|
@ -373,8 +366,7 @@ PResult<CountNode> ComdelParser::parseCount()
|
||||||
* PropertyNode := key: value;
|
* PropertyNode := key: value;
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
PResult<PropertyNode> ComdelParser::parseProperty(std::optional<TokenType> valueType = std::nullopt)
|
PResult<PropertyNode> ComdelParser::parseProperty(std::optional<TokenType> valueType = std::nullopt) {
|
||||||
{
|
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
IdentifierNode key;
|
IdentifierNode key;
|
||||||
ASSIGN_OR_RETURN_IF_ERR(key, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(key, parseIdentifier());
|
||||||
|
@ -407,8 +399,7 @@ PResult<PropertyNode> ComdelParser::parseProperty(std::optional<TokenType> value
|
||||||
* AddressSpaceNode := "@address" + IDENTIFIER "(" + NUMBER + "," + NUMBER + ")"
|
* AddressSpaceNode := "@address" + IDENTIFIER "(" + NUMBER + "," + NUMBER + ")"
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
PResult<AddressSpaceNode> ComdelParser::parseAddress()
|
PResult<AddressSpaceNode> ComdelParser::parseAddress() {
|
||||||
{
|
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
|
|
||||||
AddressSpaceNode addressSpace{};
|
AddressSpaceNode addressSpace{};
|
||||||
|
@ -431,8 +422,7 @@ PResult<AddressSpaceNode> ComdelParser::parseAddress()
|
||||||
* ComponentNode := "@component" + IDENTIFIER + ("processor" | "memory") { COMPONENT_BLOCK }
|
* ComponentNode := "@component" + IDENTIFIER + ("processor" | "memory") { COMPONENT_BLOCK }
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
PResult<ComponentNode> ComdelParser::parseComponent()
|
PResult<ComponentNode> ComdelParser::parseComponent() {
|
||||||
{
|
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
|
|
||||||
ComponentNode component{};
|
ComponentNode component{};
|
||||||
|
@ -440,7 +430,6 @@ PResult<ComponentNode> ComdelParser::parseComponent()
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::KW_COMPONENT);
|
RETURN_IF_NOT_TOKEN(TokenType::KW_COMPONENT);
|
||||||
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(component.name, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(component.name, parseIdentifier());
|
||||||
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(component.type, parseComponentType());
|
ASSIGN_OR_RETURN_IF_ERR(component.type, parseComponentType());
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
@ -557,11 +546,7 @@ PResult<BusNode> ComdelParser::parseBus() {
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::KW_BUS);
|
RETURN_IF_NOT_TOKEN(TokenType::KW_BUS);
|
||||||
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(bus.name, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(bus.name, parseIdentifier());
|
||||||
|
ASSIGN_OR_RETURN_IF_ERR(bus.type, parseBusType());
|
||||||
auto type = parseBusType();
|
|
||||||
RETURN_IF_ERR(type);
|
|
||||||
|
|
||||||
bus.type = *type;
|
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
||||||
|
@ -729,7 +714,10 @@ PResult<PinNode> ComdelParser::parsePin() {
|
||||||
ASSIGN_OR_SET_ERR(pin.connection, parsePinConnection());
|
ASSIGN_OR_SET_ERR(pin.connection, parsePinConnection());
|
||||||
} 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);
|
||||||
pin.wires = *wires;
|
pin.wires = *wires;
|
||||||
|
@ -957,9 +945,9 @@ PResult<PopupNode> ComdelParser::parsePopup() {
|
||||||
popup.enumerated = true;
|
popup.enumerated = true;
|
||||||
ASSIGN_OR_SET_ERR(popup.enumeration,
|
ASSIGN_OR_SET_ERR(popup.enumeration,
|
||||||
parseList<EnumerationNode>(
|
parseList<EnumerationNode>(
|
||||||
std::optional<TokenType>(TokenType::LBRACE),
|
TokenType::LBRACE,
|
||||||
TokenType::RBRACE,
|
TokenType::RBRACE,
|
||||||
std::optional<TokenType>(TokenType::COMMA),
|
TokenType::COMMA,
|
||||||
true,
|
true,
|
||||||
[this] { return parseEnumeration(); }
|
[this] { return parseEnumeration(); }
|
||||||
)
|
)
|
||||||
|
@ -1100,7 +1088,7 @@ PResult<IfStatementNode> ComdelParser::parseIfStatement() {
|
||||||
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(ifStatement.condition.functionName, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(ifStatement.condition.functionName, parseIdentifier());
|
||||||
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(ifStatement.condition.params, parseList<ValueNode>(std::optional<TokenType>(TokenType::LPAREN),
|
ASSIGN_OR_RETURN_IF_ERR(ifStatement.condition.params, parseList<ValueNode>(TokenType::LPAREN,
|
||||||
TokenType::RPAREN,
|
TokenType::RPAREN,
|
||||||
TokenType::COMMA,
|
TokenType::COMMA,
|
||||||
false,
|
false,
|
||||||
|
@ -1215,7 +1203,7 @@ std::optional<SchemaNode> ComdelParser::parseSchema() {
|
||||||
errors.emplace_back(current().span, "expected `EOF`");
|
errors.emplace_back(current().span, "expected `EOF`");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errors.size())
|
if (!errors.empty())
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
return spanner(schema);
|
return spanner(schema);
|
||||||
|
@ -1226,8 +1214,7 @@ std::optional<SchemaNode> ComdelParser::parseSchema() {
|
||||||
* CountNode := "@position (" + NumberNode + "," + NumberNode + ")"
|
* CountNode := "@position (" + NumberNode + "," + NumberNode + ")"
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
PResult<CountNode> ComdelParser::parsePosition()
|
PResult<CountNode> ComdelParser::parsePosition() {
|
||||||
{
|
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::KW_POSITION);
|
RETURN_IF_NOT_TOKEN(TokenType::KW_POSITION);
|
||||||
|
|
||||||
|
@ -1285,6 +1272,7 @@ PResult<InstanceNode> ComdelParser::parseInstance() {
|
||||||
|
|
||||||
return spanner(instance);
|
return spanner(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
PResult<InstanceAttributeNode> ComdelParser::parseInstanceAttribute() {
|
PResult<InstanceAttributeNode> ComdelParser::parseInstanceAttribute() {
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::KW_ATTRIBUTE);
|
RETURN_IF_NOT_TOKEN(TokenType::KW_ATTRIBUTE);
|
||||||
|
@ -1295,6 +1283,7 @@ PResult<InstanceAttributeNode> ComdelParser::parseInstanceAttribute() {
|
||||||
|
|
||||||
return spanner(attribute);
|
return spanner(attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
PResult<ConnectionInstanceNode> ComdelParser::parseConnectionInstance() {
|
PResult<ConnectionInstanceNode> ComdelParser::parseConnectionInstance() {
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::KW_CONNECTION);
|
RETURN_IF_NOT_TOKEN(TokenType::KW_CONNECTION);
|
|
@ -1,10 +1,10 @@
|
||||||
#ifndef COMDEL_PARSER_H
|
#ifndef COMDEL_PARSER_H
|
||||||
#define COMDEL_PARSER_H
|
#define COMDEL_PARSER_H
|
||||||
|
|
||||||
#include "sourceerror.h"
|
#include "source_error.h"
|
||||||
#include "presult.h"
|
#include "presult.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "astnode.h"
|
#include "ast_nodes.h"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -23,18 +23,16 @@ class Spanner {
|
||||||
public:
|
public:
|
||||||
const Span lo; // the low end of the span, beginning of the node
|
const Span lo; // the low end of the span, beginning of the node
|
||||||
|
|
||||||
|
|
||||||
Spanner(Span lo, Span &prevSpan) : lo(lo), prevSpan(prevSpan) {}
|
Spanner(Span lo, Span &prevSpan) : lo(lo), prevSpan(prevSpan) {}
|
||||||
|
|
||||||
template<typename T, typename = std::enable_if<std::is_base_of<AstNode, T>::value>>
|
template<typename T, typename = std::enable_if<std::is_base_of<AstNode, T>::value>>
|
||||||
typename std::remove_reference_t<T> operator()(T &&astNode) const {
|
typename std::remove_reference_t<T> operator()(T &&astNode) const {
|
||||||
astNode.span = lo.to(prevSpan);
|
astNode.span = lo.to(prevSpan);
|
||||||
return std::move(astNode);
|
return std::forward<T>(astNode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComdelParser
|
class ComdelParser {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
std::vector<Token> tokens;
|
std::vector<Token> tokens;
|
||||||
std::set<TokenType> expectedTokens;
|
std::set<TokenType> expectedTokens;
|
||||||
|
@ -47,6 +45,7 @@ private:
|
||||||
void bump();
|
void bump();
|
||||||
|
|
||||||
bool consume(TokenType tokenType);
|
bool consume(TokenType tokenType);
|
||||||
|
|
||||||
bool check(TokenType tokenType);
|
bool check(TokenType tokenType);
|
||||||
|
|
||||||
void skipUntilNextKeyword();
|
void skipUntilNextKeyword();
|
||||||
|
@ -64,46 +63,72 @@ private:
|
||||||
|
|
||||||
Spanner getSpanner();
|
Spanner getSpanner();
|
||||||
|
|
||||||
|
// used to parse library and schema
|
||||||
PResult<StringNode> parseString();
|
PResult<StringNode> parseString();
|
||||||
|
|
||||||
PResult<IdentifierNode> parseIdentifier();
|
PResult<IdentifierNode> parseIdentifier();
|
||||||
|
|
||||||
PResult<NumberNode> parseNumber();
|
PResult<NumberNode> parseNumber();
|
||||||
|
|
||||||
PResult<CountNode> parseCount();
|
PResult<CountNode> parseCount();
|
||||||
|
|
||||||
PResult<PropertyNode> parseProperty(std::optional<TokenType> valueType);
|
PResult<PropertyNode> parseProperty(std::optional<TokenType> valueType);
|
||||||
|
|
||||||
PResult<EnumerationNode> parseEnumeration();
|
PResult<EnumerationNode> parseEnumeration();
|
||||||
|
|
||||||
PResult<ValueNode> parseConnectionWire();
|
PResult<ValueNode> parseConnectionWire();
|
||||||
|
|
||||||
PResult<ComponentNode> parseComponent();
|
PResult<ComponentNode> parseComponent();
|
||||||
|
|
||||||
PResult<AddressSpaceNode> parseAddress();
|
PResult<AddressSpaceNode> parseAddress();
|
||||||
|
|
||||||
PResult<PinNode> parsePin();
|
PResult<PinNode> parsePin();
|
||||||
|
|
||||||
PResult<DisplayNode> parseDisplay();
|
PResult<DisplayNode> parseDisplay();
|
||||||
|
|
||||||
PResult<PinConnectionNode> parsePinConnection();
|
PResult<PinConnectionNode> parsePinConnection();
|
||||||
|
|
||||||
PResult<AttributeNode> parseAttribute();
|
PResult<AttributeNode> parseAttribute();
|
||||||
|
|
||||||
PResult<PopupNode> parsePopup();
|
PResult<PopupNode> parsePopup();
|
||||||
|
|
||||||
PResult<RuleNode> parseRule();
|
PResult<RuleNode> parseRule();
|
||||||
|
|
||||||
PResult<BusNode> parseBus();
|
PResult<BusNode> parseBus();
|
||||||
|
|
||||||
PResult<WireNode> parseWire();
|
PResult<WireNode> parseWire();
|
||||||
|
|
||||||
PResult<ConnectionNode> parseConnection();
|
PResult<ConnectionNode> parseConnection();
|
||||||
|
|
||||||
PResult<DisplayItemNode> parseDisplayItem();
|
PResult<DisplayItemNode> parseDisplayItem();
|
||||||
|
|
||||||
PResult<IfStatementNode> parseIfStatement();
|
PResult<IfStatementNode> parseIfStatement();
|
||||||
|
|
||||||
PResult<ValueNode> parseValue();
|
PResult<ValueNode> parseValue();
|
||||||
|
|
||||||
|
// used to parse schema
|
||||||
PResult<CountNode> parsePosition();
|
PResult<CountNode> parsePosition();
|
||||||
PResult<InstanceNode> parseInstance();
|
|
||||||
PResult<InstanceAttributeNode> parseInstanceAttribute();
|
|
||||||
PResult<ConnectionInstanceNode> parseConnectionInstance();
|
|
||||||
|
|
||||||
public:
|
PResult<InstanceNode> parseInstance();
|
||||||
ComdelParser(std::vector<Token> tokens);
|
|
||||||
std::optional<SchemaNode> parseSchema();
|
PResult<InstanceAttributeNode> parseInstanceAttribute();
|
||||||
std::optional<LibraryNode> parse();
|
|
||||||
const std::vector<SourceError>& getErrors();
|
PResult<ConnectionInstanceNode> parseConnectionInstance();
|
||||||
|
|
||||||
PResult<EnumNode<ComponentNode::ComponentType>> parseComponentType();
|
PResult<EnumNode<ComponentNode::ComponentType>> parseComponentType();
|
||||||
|
|
||||||
PResult<EnumNode<BusNode::BusType>> parseBusType();
|
PResult<EnumNode<BusNode::BusType>> parseBusType();
|
||||||
|
|
||||||
PResult<EnumNode<PinConnectionNode::ConnectionType>> parseConnectionType();
|
PResult<EnumNode<PinConnectionNode::ConnectionType>> parseConnectionType();
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ComdelParser(std::vector<Token> tokens);
|
||||||
|
|
||||||
|
std::optional<SchemaNode> parseSchema();
|
||||||
|
|
||||||
|
std::optional<LibraryNode> parseLibrary();
|
||||||
|
|
||||||
|
const std::vector<SourceError> &getErrors();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // COMDEL_PARSER_H
|
#endif // COMDEL_PARSER_H
|
|
@ -1,6 +1,6 @@
|
||||||
#include "comdellexer.h"
|
#include "comdellexer.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "tokenstype.h"
|
#include "tokens_type.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
@ -42,8 +42,7 @@ ComdelLexer::ComdelLexer(std::string fileName, std::string source,
|
||||||
// TODO Update this
|
// TODO Update this
|
||||||
fileId(this->parseContext->addFile(fileName, this->source)),
|
fileId(this->parseContext->addFile(fileName, this->source)),
|
||||||
position(this->fileId, 1, 1, 0),
|
position(this->fileId, 1, 1, 0),
|
||||||
ch(this->source[0])
|
ch(this->source[0]) {}
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
LexerResult ComdelLexer::tokenize() {
|
LexerResult ComdelLexer::tokenize() {
|
||||||
|
@ -181,8 +180,7 @@ PResult<TokenType> ComdelLexer::takeString() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PResult<TokenType> ComdelLexer::takeRawString()
|
PResult<TokenType> ComdelLexer::takeRawString() {
|
||||||
{
|
|
||||||
Position lo = position;
|
Position lo = position;
|
||||||
|
|
||||||
if (ch != '`')
|
if (ch != '`')
|
||||||
|
@ -237,20 +235,15 @@ bool ComdelLexer::skipMultilineComment() {
|
||||||
|
|
||||||
|
|
||||||
PResult<TokenType> ComdelLexer::nextTokenType() {
|
PResult<TokenType> ComdelLexer::nextTokenType() {
|
||||||
if (isWhitespace(ch))
|
if (isWhitespace(ch)) {
|
||||||
{
|
|
||||||
skipWhitespace();
|
skipWhitespace();
|
||||||
return TokenType::WHITESPACE;
|
return TokenType::WHITESPACE;
|
||||||
}
|
} else if (identifierStart(ch)) {
|
||||||
else if (identifierStart(ch))
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
while (identifierContinue(ch))
|
while (identifierContinue(ch))
|
||||||
bump();
|
bump();
|
||||||
return TokenType::IDENTIFIER;
|
return TokenType::IDENTIFIER;
|
||||||
}
|
} else if (numberStart(ch)) {
|
||||||
else if (numberStart(ch))
|
|
||||||
{
|
|
||||||
if (ch == '-') {
|
if (ch == '-') {
|
||||||
bump();
|
bump();
|
||||||
}
|
}
|
||||||
|
@ -266,27 +259,16 @@ PResult<TokenType> ComdelLexer::nextTokenType() {
|
||||||
"illegal digit or letter found at the end of number"});
|
"illegal digit or letter found at the end of number"});
|
||||||
}
|
}
|
||||||
return TokenType::NUMBER;
|
return TokenType::NUMBER;
|
||||||
}
|
} else if (ch == '!') {
|
||||||
else if (ch == '!')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
return TokenType::NOT;
|
return TokenType::NOT;
|
||||||
}
|
} else if (ch == '<') {
|
||||||
|
|
||||||
else if (ch == '<')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
return TokenType::LT;
|
return TokenType::LT;
|
||||||
}
|
} else if (ch == '>') {
|
||||||
|
|
||||||
else if (ch == '>')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
return TokenType::GT;
|
return TokenType::GT;
|
||||||
}
|
} else if (ch == '#') {
|
||||||
|
|
||||||
else if (ch == '#')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
|
|
||||||
if (digitIsValid(ch, Radix::HEX_NUMBER)) {
|
if (digitIsValid(ch, Radix::HEX_NUMBER)) {
|
||||||
|
@ -304,65 +286,42 @@ PResult<TokenType> ComdelLexer::nextTokenType() {
|
||||||
return PError({Span(tokenBegin, position),
|
return PError({Span(tokenBegin, position),
|
||||||
"unexpected #"});
|
"unexpected #"});
|
||||||
}
|
}
|
||||||
}
|
} else if (ch == '@') {
|
||||||
else if (ch == '@')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
while (identifierContinue(ch))
|
while (identifierContinue(ch))
|
||||||
bump();
|
bump();
|
||||||
return TokenType::KEYWORD;
|
return TokenType::KEYWORD;
|
||||||
}
|
} else if (ch == '"') {
|
||||||
else if (ch == '"')
|
|
||||||
{
|
|
||||||
return takeString();
|
return takeString();
|
||||||
}
|
} else if (ch == '`') {
|
||||||
else if (ch == '`')
|
|
||||||
{
|
|
||||||
return takeRawString();
|
return takeRawString();
|
||||||
}
|
} else if (ch == '(') {
|
||||||
else if (ch == '(')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
return TokenType::LPAREN;
|
return TokenType::LPAREN;
|
||||||
}
|
} else if (ch == ')') {
|
||||||
else if (ch == ')')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
return TokenType::RPAREN;
|
return TokenType::RPAREN;
|
||||||
}
|
} else if (ch == '[') {
|
||||||
else if (ch == '[')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
return TokenType::LBRACKET;
|
return TokenType::LBRACKET;
|
||||||
}
|
} else if (ch == ']') {
|
||||||
else if (ch == ']')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
return TokenType::RBRACKET;
|
return TokenType::RBRACKET;
|
||||||
}
|
} else if (ch == '{') {
|
||||||
else if (ch == '{')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
return TokenType::LBRACE;
|
return TokenType::LBRACE;
|
||||||
}
|
} else if (ch == '}') {
|
||||||
else if (ch == '}')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
return TokenType::RBRACE;
|
return TokenType::RBRACE;
|
||||||
}
|
} else if (ch == '/') {
|
||||||
else if (ch == '/')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
if (ch == '/')
|
if (ch == '/') {
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
skipComment();
|
skipComment();
|
||||||
return TokenType::COMMENT;
|
return TokenType::COMMENT;
|
||||||
} else if (ch == '*')
|
} else if (ch == '*') {
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
if (!skipMultilineComment())
|
if (!skipMultilineComment()) {
|
||||||
{
|
|
||||||
return PError({Span(tokenBegin, position),
|
return PError({Span(tokenBegin, position),
|
||||||
"unterminated multiline comment"});
|
"unterminated multiline comment"});
|
||||||
}
|
}
|
||||||
|
@ -370,34 +329,22 @@ PResult<TokenType> ComdelLexer::nextTokenType() {
|
||||||
}
|
}
|
||||||
return PError({Span(tokenBegin, position),
|
return PError({Span(tokenBegin, position),
|
||||||
"unexpected /"});
|
"unexpected /"});
|
||||||
}
|
} else if (ch == '.') {
|
||||||
else if (ch == '.')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
return TokenType::DOT;
|
return TokenType::DOT;
|
||||||
}
|
} else if (ch == ':') {
|
||||||
else if (ch == ':')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
return TokenType::COLON;
|
return TokenType::COLON;
|
||||||
}
|
} else if (ch == ';') {
|
||||||
else if (ch == ';')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
return TokenType::SEMICOLON;
|
return TokenType::SEMICOLON;
|
||||||
}
|
} else if (ch == ',') {
|
||||||
else if (ch == ',')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
return TokenType::COMMA;
|
return TokenType::COMMA;
|
||||||
}
|
} else if (ch == '=') {
|
||||||
else if (ch == '=')
|
|
||||||
{
|
|
||||||
bump();
|
bump();
|
||||||
return TokenType::EQUALS;
|
return TokenType::EQUALS;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
std::stringstream message;
|
std::stringstream message;
|
||||||
message << "unexpected character `" << ch << "`";
|
message << "unexpected character `" << ch << "`";
|
||||||
bump();
|
bump();
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#ifndef COMDEL_LEXER_H
|
#ifndef COMDEL_LEXER_H
|
||||||
#define COMDEL_LEXER_H
|
#define COMDEL_LEXER_H
|
||||||
|
|
||||||
#include "parsecontext.h"
|
#include "parse_context.h"
|
||||||
#include "presult.h"
|
#include "presult.h"
|
||||||
#include "sourceerror.h"
|
#include "source_error.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,8 +16,7 @@ struct LexerResult {
|
||||||
std::vector<SourceError> errors;
|
std::vector<SourceError> errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComdelLexer
|
class ComdelLexer {
|
||||||
{
|
|
||||||
|
|
||||||
enum Radix {
|
enum Radix {
|
||||||
BIN_NUMBER = 2,
|
BIN_NUMBER = 2,
|
||||||
|
@ -33,14 +32,18 @@ class ComdelLexer
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ComdelLexer(std::string fileName, std::string source, ParseContext *parseContext);
|
ComdelLexer(std::string fileName, std::string source, ParseContext *parseContext);
|
||||||
|
|
||||||
LexerResult tokenize();
|
LexerResult tokenize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void skipWhitespace();
|
void skipWhitespace();
|
||||||
|
|
||||||
unsigned takeNumberInRadix(Radix radix);
|
unsigned takeNumberInRadix(Radix radix);
|
||||||
|
|
||||||
unsigned takeHexColor();
|
unsigned takeHexColor();
|
||||||
|
|
||||||
bool digitIsValid(char ch, Radix radix);
|
bool digitIsValid(char ch, Radix radix);
|
||||||
|
|
||||||
Radix takeRadix();
|
Radix takeRadix();
|
||||||
|
|
||||||
PResult<TokenType> nextTokenType();
|
PResult<TokenType> nextTokenType();
|
||||||
|
@ -50,13 +53,17 @@ private:
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
void skipComment();
|
void skipComment();
|
||||||
|
|
||||||
bool skipMultilineComment();
|
bool skipMultilineComment();
|
||||||
|
|
||||||
PResult<TokenType> takeString();
|
PResult<TokenType> takeString();
|
||||||
|
|
||||||
PResult<TokenType> takeRawString();
|
PResult<TokenType> takeRawString();
|
||||||
|
|
||||||
void bump(unsigned count = 1);
|
void bump(unsigned count = 1);
|
||||||
|
|
||||||
char peek();
|
char peek();
|
||||||
|
|
||||||
bool eof();
|
bool eof();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -128,27 +128,33 @@ namespace tl {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace tl {
|
namespace tl {
|
||||||
template <class T, class E> class expected;
|
template<class T, class E>
|
||||||
|
class expected;
|
||||||
|
|
||||||
#ifndef TL_MONOSTATE_INPLACE_MUTEX
|
#ifndef TL_MONOSTATE_INPLACE_MUTEX
|
||||||
#define TL_MONOSTATE_INPLACE_MUTEX
|
#define TL_MONOSTATE_INPLACE_MUTEX
|
||||||
|
|
||||||
/// \brief Used to represent an expected with no data
|
/// \brief Used to represent an expected with no data
|
||||||
class monostate {};
|
class monostate {
|
||||||
|
};
|
||||||
|
|
||||||
/// \brief A tag type to tell expected to construct its value in-place
|
/// \brief A tag type to tell expected to construct its value in-place
|
||||||
struct in_place_t {
|
struct in_place_t {
|
||||||
explicit in_place_t() = default;
|
explicit in_place_t() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief A tag to tell expected to construct its value in-place
|
/// \brief A tag to tell expected to construct its value in-place
|
||||||
static constexpr in_place_t in_place{};
|
static constexpr in_place_t in_place{};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Used as a wrapper to store the unexpected value
|
/// Used as a wrapper to store the unexpected value
|
||||||
template <class E> class unexpected {
|
template<class E>
|
||||||
|
class unexpected {
|
||||||
public:
|
public:
|
||||||
static_assert(!std::is_same<E, void>::value, "E must not be void");
|
static_assert(!std::is_same<E, void>::value, "E must not be void");
|
||||||
|
|
||||||
unexpected() = delete;
|
unexpected() = delete;
|
||||||
|
|
||||||
constexpr unexpected(const E &e) : m_val(e) {}
|
constexpr unexpected(const E &e) : m_val(e) {}
|
||||||
|
|
||||||
constexpr unexpected(E &&e) : m_val(std::move(e)) {}
|
constexpr unexpected(E &&e) : m_val(std::move(e)) {}
|
||||||
|
@ -160,6 +166,7 @@ public:
|
||||||
TL_EXPECTED_11_CONSTEXPR E &value() &{ return m_val; }
|
TL_EXPECTED_11_CONSTEXPR E &value() &{ return m_val; }
|
||||||
/// \group unexpected_value
|
/// \group unexpected_value
|
||||||
TL_EXPECTED_11_CONSTEXPR E &&value() &&{ return std::move(m_val); }
|
TL_EXPECTED_11_CONSTEXPR E &&value() &&{ return std::move(m_val); }
|
||||||
|
|
||||||
/// \exclude
|
/// \exclude
|
||||||
constexpr const E &&value() const &&{ return std::move(m_val); }
|
constexpr const E &&value() const &&{ return std::move(m_val); }
|
||||||
|
|
||||||
|
@ -174,26 +181,31 @@ template <class E>
|
||||||
constexpr bool operator==(const unexpected<E> &lhs, const unexpected<E> &rhs) {
|
constexpr bool operator==(const unexpected<E> &lhs, const unexpected<E> &rhs) {
|
||||||
return lhs.value() == rhs.value();
|
return lhs.value() == rhs.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group unexpected_relop
|
/// \group unexpected_relop
|
||||||
template<class E>
|
template<class E>
|
||||||
constexpr bool operator!=(const unexpected<E> &lhs, const unexpected<E> &rhs) {
|
constexpr bool operator!=(const unexpected<E> &lhs, const unexpected<E> &rhs) {
|
||||||
return lhs.value() != rhs.value();
|
return lhs.value() != rhs.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group unexpected_relop
|
/// \group unexpected_relop
|
||||||
template<class E>
|
template<class E>
|
||||||
constexpr bool operator<(const unexpected<E> &lhs, const unexpected<E> &rhs) {
|
constexpr bool operator<(const unexpected<E> &lhs, const unexpected<E> &rhs) {
|
||||||
return lhs.value() < rhs.value();
|
return lhs.value() < rhs.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group unexpected_relop
|
/// \group unexpected_relop
|
||||||
template<class E>
|
template<class E>
|
||||||
constexpr bool operator<=(const unexpected<E> &lhs, const unexpected<E> &rhs) {
|
constexpr bool operator<=(const unexpected<E> &lhs, const unexpected<E> &rhs) {
|
||||||
return lhs.value() <= rhs.value();
|
return lhs.value() <= rhs.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group unexpected_relop
|
/// \group unexpected_relop
|
||||||
template<class E>
|
template<class E>
|
||||||
constexpr bool operator>(const unexpected<E> &lhs, const unexpected<E> &rhs) {
|
constexpr bool operator>(const unexpected<E> &lhs, const unexpected<E> &rhs) {
|
||||||
return lhs.value() > rhs.value();
|
return lhs.value() > rhs.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group unexpected_relop
|
/// \group unexpected_relop
|
||||||
template<class E>
|
template<class E>
|
||||||
constexpr bool operator>=(const unexpected<E> &lhs, const unexpected<E> &rhs) {
|
constexpr bool operator>=(const unexpected<E> &lhs, const unexpected<E> &rhs) {
|
||||||
|
@ -214,6 +226,7 @@ unexpected<typename std::decay<E>::type> make_unexpected(E &&e) {
|
||||||
struct unexpect_t {
|
struct unexpect_t {
|
||||||
unexpect_t() = default;
|
unexpect_t() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief A tag to tell expected to construct the unexpected value
|
/// \brief A tag to tell expected to construct the unexpected value
|
||||||
static constexpr unexpect_t unexpect{};
|
static constexpr unexpect_t unexpect{};
|
||||||
|
|
||||||
|
@ -246,11 +259,16 @@ template <bool B, class T, class F>
|
||||||
using conditional_t = typename std::conditional<B, T, F>::type;
|
using conditional_t = typename std::conditional<B, T, F>::type;
|
||||||
|
|
||||||
// std::conjunction from C++17
|
// std::conjunction from C++17
|
||||||
template <class...> struct conjunction : std::true_type {};
|
template<class...>
|
||||||
template <class B> struct conjunction<B> : B {};
|
struct conjunction : std::true_type {
|
||||||
|
};
|
||||||
|
template<class B>
|
||||||
|
struct conjunction<B> : B {
|
||||||
|
};
|
||||||
template<class B, class... Bs>
|
template<class B, class... Bs>
|
||||||
struct conjunction<B, Bs...>
|
struct conjunction<B, Bs...>
|
||||||
: std::conditional<bool(B::value), conjunction<Bs...>, B>::type {};
|
: std::conditional<bool(B::value), conjunction<Bs...>, B>::type {
|
||||||
|
};
|
||||||
|
|
||||||
// std::invoke from C++17
|
// std::invoke from C++17
|
||||||
// https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround
|
// https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround
|
||||||
|
@ -272,7 +290,8 @@ constexpr auto invoke(Fn &&f, Args &&... args) noexcept(
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::invoke_result from C++17
|
// std::invoke_result from C++17
|
||||||
template <class F, class, class... Us> struct invoke_result_impl;
|
template<class F, class, class... Us>
|
||||||
|
struct invoke_result_impl;
|
||||||
|
|
||||||
template<class F, class... Us>
|
template<class F, class... Us>
|
||||||
struct invoke_result_impl<
|
struct invoke_result_impl<
|
||||||
|
@ -289,9 +308,12 @@ using invoke_result_t = typename invoke_result<F, Us...>::type;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Trait for checking if a type is a tl::expected
|
// Trait for checking if a type is a tl::expected
|
||||||
template <class T> struct is_expected_impl : std::false_type {};
|
template<class T>
|
||||||
|
struct is_expected_impl : std::false_type {
|
||||||
|
};
|
||||||
template<class T, class E>
|
template<class T, class E>
|
||||||
struct is_expected_impl<expected<T, E>> : std::true_type {};
|
struct is_expected_impl<expected<T, E>> : std::true_type {
|
||||||
|
};
|
||||||
template<class T> using is_expected = is_expected_impl<decay_t<T>>;
|
template<class T> using is_expected = is_expected_impl<decay_t<T>>;
|
||||||
|
|
||||||
template<class T, class E, class U>
|
template<class T, class E, class U>
|
||||||
|
@ -339,7 +361,8 @@ using is_move_assignable_or_void =
|
||||||
|
|
||||||
/// \exclude
|
/// \exclude
|
||||||
namespace detail {
|
namespace detail {
|
||||||
struct no_init_t {};
|
struct no_init_t {
|
||||||
|
};
|
||||||
static constexpr no_init_t no_init{};
|
static constexpr no_init_t no_init{};
|
||||||
|
|
||||||
// Implements the storage of the values, and ensures that the destructor is
|
// Implements the storage of the values, and ensures that the destructor is
|
||||||
|
@ -352,6 +375,7 @@ template <class T, class E, bool = std::is_trivially_destructible<T>::value,
|
||||||
bool = std::is_trivially_destructible<E>::value>
|
bool = std::is_trivially_destructible<E>::value>
|
||||||
struct expected_storage_base {
|
struct expected_storage_base {
|
||||||
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
||||||
|
|
||||||
constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {}
|
constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {}
|
||||||
|
|
||||||
template<class... Args,
|
template<class... Args,
|
||||||
|
@ -366,6 +390,7 @@ struct expected_storage_base {
|
||||||
constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
|
constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
|
||||||
Args &&... args)
|
Args &&... args)
|
||||||
: m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
|
: m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
|
||||||
|
|
||||||
template<class... Args,
|
template<class... Args,
|
||||||
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
|
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
|
||||||
nullptr>
|
nullptr>
|
||||||
|
@ -387,6 +412,7 @@ struct expected_storage_base {
|
||||||
m_unexpect.~unexpected<E>();
|
m_unexpect.~unexpected<E>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
union {
|
union {
|
||||||
T m_val;
|
T m_val;
|
||||||
unexpected<E> m_unexpect;
|
unexpected<E> m_unexpect;
|
||||||
|
@ -397,8 +423,10 @@ struct expected_storage_base {
|
||||||
|
|
||||||
// This specialization is for when both `T` and `E` are trivially-destructible,
|
// This specialization is for when both `T` and `E` are trivially-destructible,
|
||||||
// so the destructor of the `expected` can be trivial.
|
// so the destructor of the `expected` can be trivial.
|
||||||
template <class T, class E> struct expected_storage_base<T, E, true, true> {
|
template<class T, class E>
|
||||||
|
struct expected_storage_base<T, E, true, true> {
|
||||||
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
||||||
|
|
||||||
constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {}
|
constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {}
|
||||||
|
|
||||||
template<class... Args,
|
template<class... Args,
|
||||||
|
@ -413,6 +441,7 @@ template <class T, class E> struct expected_storage_base<T, E, true, true> {
|
||||||
constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
|
constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
|
||||||
Args &&... args)
|
Args &&... args)
|
||||||
: m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
|
: m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
|
||||||
|
|
||||||
template<class... Args,
|
template<class... Args,
|
||||||
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
|
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
|
||||||
nullptr>
|
nullptr>
|
||||||
|
@ -428,6 +457,7 @@ template <class T, class E> struct expected_storage_base<T, E, true, true> {
|
||||||
: m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
|
: m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
|
||||||
|
|
||||||
~expected_storage_base() = default;
|
~expected_storage_base() = default;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
T m_val;
|
T m_val;
|
||||||
unexpected<E> m_unexpect;
|
unexpected<E> m_unexpect;
|
||||||
|
@ -437,8 +467,10 @@ template <class T, class E> struct expected_storage_base<T, E, true, true> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// T is trivial, E is not.
|
// T is trivial, E is not.
|
||||||
template <class T, class E> struct expected_storage_base<T, E, true, false> {
|
template<class T, class E>
|
||||||
|
struct expected_storage_base<T, E, true, false> {
|
||||||
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
||||||
|
|
||||||
TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base(no_init_t)
|
TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base(no_init_t)
|
||||||
: m_no_init(), m_has_val(false) {}
|
: m_no_init(), m_has_val(false) {}
|
||||||
|
|
||||||
|
@ -454,6 +486,7 @@ template <class T, class E> struct expected_storage_base<T, E, true, false> {
|
||||||
constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
|
constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
|
||||||
Args &&... args)
|
Args &&... args)
|
||||||
: m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
|
: m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
|
||||||
|
|
||||||
template<class... Args,
|
template<class... Args,
|
||||||
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
|
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
|
||||||
nullptr>
|
nullptr>
|
||||||
|
@ -483,8 +516,10 @@ template <class T, class E> struct expected_storage_base<T, E, true, false> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// E is trivial, T is not.
|
// E is trivial, T is not.
|
||||||
template <class T, class E> struct expected_storage_base<T, E, false, true> {
|
template<class T, class E>
|
||||||
|
struct expected_storage_base<T, E, false, true> {
|
||||||
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
||||||
|
|
||||||
constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {}
|
constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {}
|
||||||
|
|
||||||
template<class... Args,
|
template<class... Args,
|
||||||
|
@ -499,6 +534,7 @@ template <class T, class E> struct expected_storage_base<T, E, false, true> {
|
||||||
constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
|
constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
|
||||||
Args &&... args)
|
Args &&... args)
|
||||||
: m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
|
: m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
|
||||||
|
|
||||||
template<class... Args,
|
template<class... Args,
|
||||||
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
|
detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
|
||||||
nullptr>
|
nullptr>
|
||||||
|
@ -518,6 +554,7 @@ template <class T, class E> struct expected_storage_base<T, E, false, true> {
|
||||||
m_val.~T();
|
m_val.~T();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
union {
|
union {
|
||||||
T m_val;
|
T m_val;
|
||||||
unexpected<E> m_unexpect;
|
unexpected<E> m_unexpect;
|
||||||
|
@ -527,8 +564,10 @@ template <class T, class E> struct expected_storage_base<T, E, false, true> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// `T` is `void`, `E` is trivially-destructible
|
// `T` is `void`, `E` is trivially-destructible
|
||||||
template <class E> struct expected_storage_base<void, E, false, true> {
|
template<class E>
|
||||||
|
struct expected_storage_base<void, E, false, true> {
|
||||||
TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base() : m_has_val(true) {}
|
TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base() : m_has_val(true) {}
|
||||||
|
|
||||||
constexpr expected_storage_base(no_init_t) : m_val(), m_has_val(false) {}
|
constexpr expected_storage_base(no_init_t) : m_val(), m_has_val(false) {}
|
||||||
|
|
||||||
constexpr expected_storage_base(in_place_t) : m_has_val(true) {}
|
constexpr expected_storage_base(in_place_t) : m_has_val(true) {}
|
||||||
|
@ -548,7 +587,9 @@ template <class E> struct expected_storage_base<void, E, false, true> {
|
||||||
: m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
|
: m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
|
||||||
|
|
||||||
~expected_storage_base() = default;
|
~expected_storage_base() = default;
|
||||||
struct dummy {};
|
|
||||||
|
struct dummy {
|
||||||
|
};
|
||||||
union {
|
union {
|
||||||
unexpected<E> m_unexpect;
|
unexpected<E> m_unexpect;
|
||||||
dummy m_val;
|
dummy m_val;
|
||||||
|
@ -557,8 +598,10 @@ template <class E> struct expected_storage_base<void, E, false, true> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// `T` is `void`, `E` is not trivially-destructible
|
// `T` is `void`, `E` is not trivially-destructible
|
||||||
template <class E> struct expected_storage_base<void, E, false, false> {
|
template<class E>
|
||||||
|
struct expected_storage_base<void, E, false, false> {
|
||||||
constexpr expected_storage_base() : m_dummy(), m_has_val(true) {}
|
constexpr expected_storage_base() : m_dummy(), m_has_val(true) {}
|
||||||
|
|
||||||
constexpr expected_storage_base(no_init_t) : m_dummy(), m_has_val(false) {}
|
constexpr expected_storage_base(no_init_t) : m_dummy(), m_has_val(false) {}
|
||||||
|
|
||||||
constexpr expected_storage_base(in_place_t) : m_dummy(), m_has_val(true) {}
|
constexpr expected_storage_base(in_place_t) : m_dummy(), m_has_val(true) {}
|
||||||
|
@ -596,17 +639,20 @@ template <class T, class E>
|
||||||
struct expected_operations_base : expected_storage_base<T, E> {
|
struct expected_operations_base : expected_storage_base<T, E> {
|
||||||
using expected_storage_base<T, E>::expected_storage_base;
|
using expected_storage_base<T, E>::expected_storage_base;
|
||||||
|
|
||||||
template <class... Args> void construct(Args &&... args) noexcept {
|
template<class... Args>
|
||||||
|
void construct(Args &&... args) noexcept {
|
||||||
new(std::addressof(this->m_val)) T(std::forward<Args>(args)...);
|
new(std::addressof(this->m_val)) T(std::forward<Args>(args)...);
|
||||||
this->m_has_val = true;
|
this->m_has_val = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Rhs> void construct_with(Rhs &&rhs) noexcept {
|
template<class Rhs>
|
||||||
|
void construct_with(Rhs &&rhs) noexcept {
|
||||||
new(std::addressof(this->m_val)) T(std::forward<Rhs>(rhs).get());
|
new(std::addressof(this->m_val)) T(std::forward<Rhs>(rhs).get());
|
||||||
this->m_has_val = true;
|
this->m_has_val = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... Args> void construct_error(Args &&... args) noexcept {
|
template<class... Args>
|
||||||
|
void construct_error(Args &&... args) noexcept {
|
||||||
new(std::addressof(this->m_unexpect))
|
new(std::addressof(this->m_unexpect))
|
||||||
unexpected<E>(std::forward<Args>(args)...);
|
unexpected<E>(std::forward<Args>(args)...);
|
||||||
this->m_has_val = false;
|
this->m_has_val = false;
|
||||||
|
@ -728,7 +774,8 @@ struct expected_operations_base : expected_storage_base<T, E> {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The common part of move/copy assigning
|
// The common part of move/copy assigning
|
||||||
template <class Rhs> void assign_common(Rhs &&rhs) {
|
template<class Rhs>
|
||||||
|
void assign_common(Rhs &&rhs) {
|
||||||
if (this->m_has_val) {
|
if (this->m_has_val) {
|
||||||
if (rhs.m_has_val) {
|
if (rhs.m_has_val) {
|
||||||
get() = std::forward<Rhs>(rhs).get();
|
get() = std::forward<Rhs>(rhs).get();
|
||||||
|
@ -746,23 +793,33 @@ struct expected_operations_base : expected_storage_base<T, E> {
|
||||||
bool has_value() const { return this->m_has_val; }
|
bool has_value() const { return this->m_has_val; }
|
||||||
|
|
||||||
TL_EXPECTED_11_CONSTEXPR T &get() &{ return this->m_val; }
|
TL_EXPECTED_11_CONSTEXPR T &get() &{ return this->m_val; }
|
||||||
|
|
||||||
constexpr const T &get() const &{ return this->m_val; }
|
constexpr const T &get() const &{ return this->m_val; }
|
||||||
|
|
||||||
TL_EXPECTED_11_CONSTEXPR T &&get() &&{ return std::move(this->m_val); }
|
TL_EXPECTED_11_CONSTEXPR T &&get() &&{ return std::move(this->m_val); }
|
||||||
|
|
||||||
#ifndef TL_EXPECTED_NO_CONSTRR
|
#ifndef TL_EXPECTED_NO_CONSTRR
|
||||||
|
|
||||||
constexpr const T &&get() const &&{ return std::move(this->m_val); }
|
constexpr const T &&get() const &&{ return std::move(this->m_val); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() &{
|
TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() &{
|
||||||
return this->m_unexpect;
|
return this->m_unexpect;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr const unexpected<E> &geterr() const &{ return this->m_unexpect; }
|
constexpr const unexpected<E> &geterr() const &{ return this->m_unexpect; }
|
||||||
|
|
||||||
TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() &&{
|
TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() &&{
|
||||||
return std::move(this->m_unexpect);
|
return std::move(this->m_unexpect);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TL_EXPECTED_NO_CONSTRR
|
#ifndef TL_EXPECTED_NO_CONSTRR
|
||||||
|
|
||||||
constexpr const unexpected<E> &&geterr() const &&{
|
constexpr const unexpected<E> &&geterr() const &&{
|
||||||
return std::move(this->m_unexpect);
|
return std::move(this->m_unexpect);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TL_EXPECTED_11_CONSTEXPR void destroy_val() {
|
TL_EXPECTED_11_CONSTEXPR void destroy_val() {
|
||||||
|
@ -776,21 +833,25 @@ template <class E>
|
||||||
struct expected_operations_base<void, E> : expected_storage_base<void, E> {
|
struct expected_operations_base<void, E> : expected_storage_base<void, E> {
|
||||||
using expected_storage_base<void, E>::expected_storage_base;
|
using expected_storage_base<void, E>::expected_storage_base;
|
||||||
|
|
||||||
template <class... Args> void construct() noexcept { this->m_has_val = true; }
|
template<class... Args>
|
||||||
|
void construct() noexcept { this->m_has_val = true; }
|
||||||
|
|
||||||
// This function doesn't use its argument, but needs it so that code in
|
// This function doesn't use its argument, but needs it so that code in
|
||||||
// levels above this can work independently of whether T is void
|
// levels above this can work independently of whether T is void
|
||||||
template <class Rhs> void construct_with(Rhs &&) noexcept {
|
template<class Rhs>
|
||||||
|
void construct_with(Rhs &&) noexcept {
|
||||||
this->m_has_val = true;
|
this->m_has_val = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... Args> void construct_error(Args &&... args) noexcept {
|
template<class... Args>
|
||||||
|
void construct_error(Args &&... args) noexcept {
|
||||||
new(std::addressof(this->m_unexpect))
|
new(std::addressof(this->m_unexpect))
|
||||||
unexpected<E>(std::forward<Args>(args)...);
|
unexpected<E>(std::forward<Args>(args)...);
|
||||||
this->m_has_val = false;
|
this->m_has_val = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Rhs> void assign(Rhs &&rhs) noexcept {
|
template<class Rhs>
|
||||||
|
void assign(Rhs &&rhs) noexcept {
|
||||||
if (!this->m_has_val) {
|
if (!this->m_has_val) {
|
||||||
if (rhs.m_has_val) {
|
if (rhs.m_has_val) {
|
||||||
geterr().~unexpected<E>();
|
geterr().~unexpected<E>();
|
||||||
|
@ -810,14 +871,19 @@ struct expected_operations_base<void, E> : expected_storage_base<void, E> {
|
||||||
TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() &{
|
TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() &{
|
||||||
return this->m_unexpect;
|
return this->m_unexpect;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr const unexpected<E> &geterr() const &{ return this->m_unexpect; }
|
constexpr const unexpected<E> &geterr() const &{ return this->m_unexpect; }
|
||||||
|
|
||||||
TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() &&{
|
TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() &&{
|
||||||
return std::move(this->m_unexpect);
|
return std::move(this->m_unexpect);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TL_EXPECTED_NO_CONSTRR
|
#ifndef TL_EXPECTED_NO_CONSTRR
|
||||||
|
|
||||||
constexpr const unexpected<E> &&geterr() const &&{
|
constexpr const unexpected<E> &&geterr() const &&{
|
||||||
return std::move(this->m_unexpect);
|
return std::move(this->m_unexpect);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TL_EXPECTED_11_CONSTEXPR void destroy_val() {
|
TL_EXPECTED_11_CONSTEXPR void destroy_val() {
|
||||||
|
@ -840,6 +906,7 @@ struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
|
||||||
using expected_operations_base<T, E>::expected_operations_base;
|
using expected_operations_base<T, E>::expected_operations_base;
|
||||||
|
|
||||||
expected_copy_base() = default;
|
expected_copy_base() = default;
|
||||||
|
|
||||||
expected_copy_base(const expected_copy_base &rhs)
|
expected_copy_base(const expected_copy_base &rhs)
|
||||||
: expected_operations_base<T, E>(no_init) {
|
: expected_operations_base<T, E>(no_init) {
|
||||||
if (rhs.has_value()) {
|
if (rhs.has_value()) {
|
||||||
|
@ -850,7 +917,9 @@ struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
|
||||||
}
|
}
|
||||||
|
|
||||||
expected_copy_base(expected_copy_base &&rhs) = default;
|
expected_copy_base(expected_copy_base &&rhs) = default;
|
||||||
|
|
||||||
expected_copy_base &operator=(const expected_copy_base &rhs) = default;
|
expected_copy_base &operator=(const expected_copy_base &rhs) = default;
|
||||||
|
|
||||||
expected_copy_base &operator=(expected_copy_base &&rhs) = default;
|
expected_copy_base &operator=(expected_copy_base &&rhs) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -869,11 +938,13 @@ struct expected_move_base : expected_copy_base<T, E> {
|
||||||
#else
|
#else
|
||||||
template <class T, class E, bool = false> struct expected_move_base;
|
template <class T, class E, bool = false> struct expected_move_base;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<class T, class E>
|
template<class T, class E>
|
||||||
struct expected_move_base<T, E, false> : expected_copy_base<T, E> {
|
struct expected_move_base<T, E, false> : expected_copy_base<T, E> {
|
||||||
using expected_copy_base<T, E>::expected_copy_base;
|
using expected_copy_base<T, E>::expected_copy_base;
|
||||||
|
|
||||||
expected_move_base() = default;
|
expected_move_base() = default;
|
||||||
|
|
||||||
expected_move_base(const expected_move_base &rhs) = default;
|
expected_move_base(const expected_move_base &rhs) = default;
|
||||||
|
|
||||||
expected_move_base(expected_move_base &&rhs) noexcept(
|
expected_move_base(expected_move_base &&rhs) noexcept(
|
||||||
|
@ -885,7 +956,9 @@ struct expected_move_base<T, E, false> : expected_copy_base<T, E> {
|
||||||
this->construct_error(std::move(rhs.geterr()));
|
this->construct_error(std::move(rhs.geterr()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expected_move_base &operator=(const expected_move_base &rhs) = default;
|
expected_move_base &operator=(const expected_move_base &rhs) = default;
|
||||||
|
|
||||||
expected_move_base &operator=(expected_move_base &&rhs) = default;
|
expected_move_base &operator=(expected_move_base &&rhs) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -907,13 +980,16 @@ struct expected_copy_assign_base<T, E, false> : expected_move_base<T, E> {
|
||||||
using expected_move_base<T, E>::expected_move_base;
|
using expected_move_base<T, E>::expected_move_base;
|
||||||
|
|
||||||
expected_copy_assign_base() = default;
|
expected_copy_assign_base() = default;
|
||||||
|
|
||||||
expected_copy_assign_base(const expected_copy_assign_base &rhs) = default;
|
expected_copy_assign_base(const expected_copy_assign_base &rhs) = default;
|
||||||
|
|
||||||
expected_copy_assign_base(expected_copy_assign_base &&rhs) = default;
|
expected_copy_assign_base(expected_copy_assign_base &&rhs) = default;
|
||||||
|
|
||||||
expected_copy_assign_base &operator=(const expected_copy_assign_base &rhs) {
|
expected_copy_assign_base &operator=(const expected_copy_assign_base &rhs) {
|
||||||
this->assign(rhs);
|
this->assign(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
expected_copy_assign_base &
|
expected_copy_assign_base &
|
||||||
operator=(expected_copy_assign_base &&rhs) = default;
|
operator=(expected_copy_assign_base &&rhs) = default;
|
||||||
};
|
};
|
||||||
|
@ -945,6 +1021,7 @@ struct expected_move_assign_base<T, E, false>
|
||||||
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
|
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
|
||||||
|
|
||||||
expected_move_assign_base() = default;
|
expected_move_assign_base() = default;
|
||||||
|
|
||||||
expected_move_assign_base(const expected_move_assign_base &rhs) = default;
|
expected_move_assign_base(const expected_move_assign_base &rhs) = default;
|
||||||
|
|
||||||
expected_move_assign_base(expected_move_assign_base &&rhs) = default;
|
expected_move_assign_base(expected_move_assign_base &&rhs) = default;
|
||||||
|
@ -970,10 +1047,14 @@ template <class T, class E,
|
||||||
std::is_move_constructible<E>::value)>
|
std::is_move_constructible<E>::value)>
|
||||||
struct expected_delete_ctor_base {
|
struct expected_delete_ctor_base {
|
||||||
expected_delete_ctor_base() = default;
|
expected_delete_ctor_base() = default;
|
||||||
|
|
||||||
expected_delete_ctor_base(const expected_delete_ctor_base &) = default;
|
expected_delete_ctor_base(const expected_delete_ctor_base &) = default;
|
||||||
|
|
||||||
expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = default;
|
expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = default;
|
||||||
|
|
||||||
expected_delete_ctor_base &
|
expected_delete_ctor_base &
|
||||||
operator=(const expected_delete_ctor_base &) = default;
|
operator=(const expected_delete_ctor_base &) = default;
|
||||||
|
|
||||||
expected_delete_ctor_base &
|
expected_delete_ctor_base &
|
||||||
operator=(expected_delete_ctor_base &&) noexcept = default;
|
operator=(expected_delete_ctor_base &&) noexcept = default;
|
||||||
};
|
};
|
||||||
|
@ -981,10 +1062,14 @@ struct expected_delete_ctor_base {
|
||||||
template<class T, class E>
|
template<class T, class E>
|
||||||
struct expected_delete_ctor_base<T, E, true, false> {
|
struct expected_delete_ctor_base<T, E, true, false> {
|
||||||
expected_delete_ctor_base() = default;
|
expected_delete_ctor_base() = default;
|
||||||
|
|
||||||
expected_delete_ctor_base(const expected_delete_ctor_base &) = default;
|
expected_delete_ctor_base(const expected_delete_ctor_base &) = default;
|
||||||
|
|
||||||
expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = delete;
|
expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = delete;
|
||||||
|
|
||||||
expected_delete_ctor_base &
|
expected_delete_ctor_base &
|
||||||
operator=(const expected_delete_ctor_base &) = default;
|
operator=(const expected_delete_ctor_base &) = default;
|
||||||
|
|
||||||
expected_delete_ctor_base &
|
expected_delete_ctor_base &
|
||||||
operator=(expected_delete_ctor_base &&) noexcept = default;
|
operator=(expected_delete_ctor_base &&) noexcept = default;
|
||||||
};
|
};
|
||||||
|
@ -992,10 +1077,14 @@ struct expected_delete_ctor_base<T, E, true, false> {
|
||||||
template<class T, class E>
|
template<class T, class E>
|
||||||
struct expected_delete_ctor_base<T, E, false, true> {
|
struct expected_delete_ctor_base<T, E, false, true> {
|
||||||
expected_delete_ctor_base() = default;
|
expected_delete_ctor_base() = default;
|
||||||
|
|
||||||
expected_delete_ctor_base(const expected_delete_ctor_base &) = delete;
|
expected_delete_ctor_base(const expected_delete_ctor_base &) = delete;
|
||||||
|
|
||||||
expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = default;
|
expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = default;
|
||||||
|
|
||||||
expected_delete_ctor_base &
|
expected_delete_ctor_base &
|
||||||
operator=(const expected_delete_ctor_base &) = default;
|
operator=(const expected_delete_ctor_base &) = default;
|
||||||
|
|
||||||
expected_delete_ctor_base &
|
expected_delete_ctor_base &
|
||||||
operator=(expected_delete_ctor_base &&) noexcept = default;
|
operator=(expected_delete_ctor_base &&) noexcept = default;
|
||||||
};
|
};
|
||||||
|
@ -1003,10 +1092,14 @@ struct expected_delete_ctor_base<T, E, false, true> {
|
||||||
template<class T, class E>
|
template<class T, class E>
|
||||||
struct expected_delete_ctor_base<T, E, false, false> {
|
struct expected_delete_ctor_base<T, E, false, false> {
|
||||||
expected_delete_ctor_base() = default;
|
expected_delete_ctor_base() = default;
|
||||||
|
|
||||||
expected_delete_ctor_base(const expected_delete_ctor_base &) = delete;
|
expected_delete_ctor_base(const expected_delete_ctor_base &) = delete;
|
||||||
|
|
||||||
expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = delete;
|
expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = delete;
|
||||||
|
|
||||||
expected_delete_ctor_base &
|
expected_delete_ctor_base &
|
||||||
operator=(const expected_delete_ctor_base &) = default;
|
operator=(const expected_delete_ctor_base &) = default;
|
||||||
|
|
||||||
expected_delete_ctor_base &
|
expected_delete_ctor_base &
|
||||||
operator=(expected_delete_ctor_base &&) noexcept = default;
|
operator=(expected_delete_ctor_base &&) noexcept = default;
|
||||||
};
|
};
|
||||||
|
@ -1025,11 +1118,15 @@ template <class T, class E,
|
||||||
std::is_move_assignable<E>::value)>
|
std::is_move_assignable<E>::value)>
|
||||||
struct expected_delete_assign_base {
|
struct expected_delete_assign_base {
|
||||||
expected_delete_assign_base() = default;
|
expected_delete_assign_base() = default;
|
||||||
|
|
||||||
expected_delete_assign_base(const expected_delete_assign_base &) = default;
|
expected_delete_assign_base(const expected_delete_assign_base &) = default;
|
||||||
|
|
||||||
expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
|
expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
|
||||||
default;
|
default;
|
||||||
|
|
||||||
expected_delete_assign_base &
|
expected_delete_assign_base &
|
||||||
operator=(const expected_delete_assign_base &) = default;
|
operator=(const expected_delete_assign_base &) = default;
|
||||||
|
|
||||||
expected_delete_assign_base &
|
expected_delete_assign_base &
|
||||||
operator=(expected_delete_assign_base &&) noexcept = default;
|
operator=(expected_delete_assign_base &&) noexcept = default;
|
||||||
};
|
};
|
||||||
|
@ -1037,11 +1134,15 @@ struct expected_delete_assign_base {
|
||||||
template<class T, class E>
|
template<class T, class E>
|
||||||
struct expected_delete_assign_base<T, E, true, false> {
|
struct expected_delete_assign_base<T, E, true, false> {
|
||||||
expected_delete_assign_base() = default;
|
expected_delete_assign_base() = default;
|
||||||
|
|
||||||
expected_delete_assign_base(const expected_delete_assign_base &) = default;
|
expected_delete_assign_base(const expected_delete_assign_base &) = default;
|
||||||
|
|
||||||
expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
|
expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
|
||||||
default;
|
default;
|
||||||
|
|
||||||
expected_delete_assign_base &
|
expected_delete_assign_base &
|
||||||
operator=(const expected_delete_assign_base &) = default;
|
operator=(const expected_delete_assign_base &) = default;
|
||||||
|
|
||||||
expected_delete_assign_base &
|
expected_delete_assign_base &
|
||||||
operator=(expected_delete_assign_base &&) noexcept = delete;
|
operator=(expected_delete_assign_base &&) noexcept = delete;
|
||||||
};
|
};
|
||||||
|
@ -1049,11 +1150,15 @@ struct expected_delete_assign_base<T, E, true, false> {
|
||||||
template<class T, class E>
|
template<class T, class E>
|
||||||
struct expected_delete_assign_base<T, E, false, true> {
|
struct expected_delete_assign_base<T, E, false, true> {
|
||||||
expected_delete_assign_base() = default;
|
expected_delete_assign_base() = default;
|
||||||
|
|
||||||
expected_delete_assign_base(const expected_delete_assign_base &) = default;
|
expected_delete_assign_base(const expected_delete_assign_base &) = default;
|
||||||
|
|
||||||
expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
|
expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
|
||||||
default;
|
default;
|
||||||
|
|
||||||
expected_delete_assign_base &
|
expected_delete_assign_base &
|
||||||
operator=(const expected_delete_assign_base &) = delete;
|
operator=(const expected_delete_assign_base &) = delete;
|
||||||
|
|
||||||
expected_delete_assign_base &
|
expected_delete_assign_base &
|
||||||
operator=(expected_delete_assign_base &&) noexcept = default;
|
operator=(expected_delete_assign_base &&) noexcept = default;
|
||||||
};
|
};
|
||||||
|
@ -1061,11 +1166,15 @@ struct expected_delete_assign_base<T, E, false, true> {
|
||||||
template<class T, class E>
|
template<class T, class E>
|
||||||
struct expected_delete_assign_base<T, E, false, false> {
|
struct expected_delete_assign_base<T, E, false, false> {
|
||||||
expected_delete_assign_base() = default;
|
expected_delete_assign_base() = default;
|
||||||
|
|
||||||
expected_delete_assign_base(const expected_delete_assign_base &) = default;
|
expected_delete_assign_base(const expected_delete_assign_base &) = default;
|
||||||
|
|
||||||
expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
|
expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
|
||||||
default;
|
default;
|
||||||
|
|
||||||
expected_delete_assign_base &
|
expected_delete_assign_base &
|
||||||
operator=(const expected_delete_assign_base &) = delete;
|
operator=(const expected_delete_assign_base &) = delete;
|
||||||
|
|
||||||
expected_delete_assign_base &
|
expected_delete_assign_base &
|
||||||
operator=(expected_delete_assign_base &&) noexcept = delete;
|
operator=(expected_delete_assign_base &&) noexcept = delete;
|
||||||
};
|
};
|
||||||
|
@ -1084,12 +1193,16 @@ template <class T, class E,
|
||||||
std::is_default_constructible<T>::value || std::is_void<T>::value>
|
std::is_default_constructible<T>::value || std::is_void<T>::value>
|
||||||
struct expected_default_ctor_base {
|
struct expected_default_ctor_base {
|
||||||
constexpr expected_default_ctor_base() noexcept = default;
|
constexpr expected_default_ctor_base() noexcept = default;
|
||||||
|
|
||||||
constexpr expected_default_ctor_base(
|
constexpr expected_default_ctor_base(
|
||||||
expected_default_ctor_base const &) noexcept = default;
|
expected_default_ctor_base const &) noexcept = default;
|
||||||
|
|
||||||
constexpr expected_default_ctor_base(expected_default_ctor_base &&) noexcept =
|
constexpr expected_default_ctor_base(expected_default_ctor_base &&) noexcept =
|
||||||
default;
|
default;
|
||||||
|
|
||||||
expected_default_ctor_base &
|
expected_default_ctor_base &
|
||||||
operator=(expected_default_ctor_base const &) noexcept = default;
|
operator=(expected_default_ctor_base const &) noexcept = default;
|
||||||
|
|
||||||
expected_default_ctor_base &
|
expected_default_ctor_base &
|
||||||
operator=(expected_default_ctor_base &&) noexcept = default;
|
operator=(expected_default_ctor_base &&) noexcept = default;
|
||||||
|
|
||||||
|
@ -1097,14 +1210,19 @@ struct expected_default_ctor_base {
|
||||||
};
|
};
|
||||||
|
|
||||||
// This specialization is for when T is not default constructible
|
// This specialization is for when T is not default constructible
|
||||||
template <class T, class E> struct expected_default_ctor_base<T, E, false> {
|
template<class T, class E>
|
||||||
|
struct expected_default_ctor_base<T, E, false> {
|
||||||
constexpr expected_default_ctor_base() noexcept = delete;
|
constexpr expected_default_ctor_base() noexcept = delete;
|
||||||
|
|
||||||
constexpr expected_default_ctor_base(
|
constexpr expected_default_ctor_base(
|
||||||
expected_default_ctor_base const &) noexcept = default;
|
expected_default_ctor_base const &) noexcept = default;
|
||||||
|
|
||||||
constexpr expected_default_ctor_base(expected_default_ctor_base &&) noexcept =
|
constexpr expected_default_ctor_base(expected_default_ctor_base &&) noexcept =
|
||||||
default;
|
default;
|
||||||
|
|
||||||
expected_default_ctor_base &
|
expected_default_ctor_base &
|
||||||
operator=(expected_default_ctor_base const &) noexcept = default;
|
operator=(expected_default_ctor_base const &) noexcept = default;
|
||||||
|
|
||||||
expected_default_ctor_base &
|
expected_default_ctor_base &
|
||||||
operator=(expected_default_ctor_base &&) noexcept = default;
|
operator=(expected_default_ctor_base &&) noexcept = default;
|
||||||
|
|
||||||
|
@ -1112,7 +1230,8 @@ template <class T, class E> struct expected_default_ctor_base<T, E, false> {
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <class E> class bad_expected_access : public std::exception {
|
template<class E>
|
||||||
|
class bad_expected_access : public std::exception {
|
||||||
public:
|
public:
|
||||||
explicit bad_expected_access(E e) : m_val(std::move(e)) {}
|
explicit bad_expected_access(E e) : m_val(std::move(e)) {}
|
||||||
|
|
||||||
|
@ -1121,8 +1240,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
const E &error() const &{ return m_val; }
|
const E &error() const &{ return m_val; }
|
||||||
|
|
||||||
E &error() &{ return m_val; }
|
E &error() &{ return m_val; }
|
||||||
|
|
||||||
const E &&error() const &&{ return std::move(m_val); }
|
const E &&error() const &&{ return std::move(m_val); }
|
||||||
|
|
||||||
E &&error() &&{ return std::move(m_val); }
|
E &&error() &&{ return std::move(m_val); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1151,8 +1273,11 @@ class expected : private detail::expected_move_assign_base<T, E>,
|
||||||
static_assert(!std::is_reference<E>::value, "E must not be a reference");
|
static_assert(!std::is_reference<E>::value, "E must not be a reference");
|
||||||
|
|
||||||
T *valptr() { return std::addressof(this->m_val); }
|
T *valptr() { return std::addressof(this->m_val); }
|
||||||
|
|
||||||
const T *valptr() const { return std::addressof(this->m_val); }
|
const T *valptr() const { return std::addressof(this->m_val); }
|
||||||
|
|
||||||
unexpected<E> *errptr() { return std::addressof(this->m_unexpect); }
|
unexpected<E> *errptr() { return std::addressof(this->m_unexpect); }
|
||||||
|
|
||||||
const unexpected<E> *errptr() const { return std::addressof(this->m_unexpect); }
|
const unexpected<E> *errptr() const { return std::addressof(this->m_unexpect); }
|
||||||
|
|
||||||
template<class U = T,
|
template<class U = T,
|
||||||
|
@ -1160,6 +1285,7 @@ class expected : private detail::expected_move_assign_base<T, E>,
|
||||||
U &val() {
|
U &val() {
|
||||||
return this->m_val;
|
return this->m_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
unexpected<E> &err() { return this->m_unexpect; }
|
unexpected<E> &err() { return this->m_unexpect; }
|
||||||
|
|
||||||
template<class U = T,
|
template<class U = T,
|
||||||
|
@ -1167,6 +1293,7 @@ class expected : private detail::expected_move_assign_base<T, E>,
|
||||||
const U &val() const {
|
const U &val() const {
|
||||||
return this->m_val;
|
return this->m_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unexpected<E> &err() const { return this->m_unexpect; }
|
const unexpected<E> &err() const { return this->m_unexpect; }
|
||||||
|
|
||||||
using impl_base = detail::expected_move_assign_base<T, E>;
|
using impl_base = detail::expected_move_assign_base<T, E>;
|
||||||
|
@ -1179,6 +1306,7 @@ public:
|
||||||
|
|
||||||
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
|
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
|
||||||
!defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
|
!defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
|
||||||
|
|
||||||
/// \group and_then
|
/// \group and_then
|
||||||
/// Carries out some operation which returns an expected on the stored object
|
/// Carries out some operation which returns an expected on the stored object
|
||||||
/// if there is one. \requires `std::invoke(std::forward<F>(f), value())`
|
/// if there is one. \requires `std::invoke(std::forward<F>(f), value())`
|
||||||
|
@ -1188,28 +1316,34 @@ public:
|
||||||
/// otherwise the return value of `std::invoke(std::forward<F>(f), value())`
|
/// otherwise the return value of `std::invoke(std::forward<F>(f), value())`
|
||||||
/// is returned.
|
/// is returned.
|
||||||
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &;
|
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &;
|
||||||
template <class F> TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & {
|
template<class F>
|
||||||
|
TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) &{
|
||||||
return and_then_impl(*this, std::forward<F>(f));
|
return and_then_impl(*this, std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group and_then
|
/// \group and_then
|
||||||
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &&;
|
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &&;
|
||||||
template <class F> TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && {
|
template<class F>
|
||||||
|
TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) &&{
|
||||||
return and_then_impl(std::move(*this), std::forward<F>(f));
|
return and_then_impl(std::move(*this), std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group and_then
|
/// \group and_then
|
||||||
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &;
|
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &;
|
||||||
template <class F> constexpr auto and_then(F &&f) const & {
|
template<class F>
|
||||||
|
constexpr auto and_then(F &&f) const &{
|
||||||
return and_then_impl(*this, std::forward<F>(f));
|
return and_then_impl(*this, std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TL_EXPECTED_NO_CONSTRR
|
#ifndef TL_EXPECTED_NO_CONSTRR
|
||||||
|
|
||||||
/// \group and_then
|
/// \group and_then
|
||||||
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &&;
|
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &&;
|
||||||
template <class F> constexpr auto and_then(F &&f) const && {
|
template<class F>
|
||||||
|
constexpr auto and_then(F &&f) const &&{
|
||||||
return and_then_impl(std::move(*this), std::forward<F>(f));
|
return and_then_impl(std::move(*this), std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -1257,6 +1391,7 @@ public:
|
||||||
|
|
||||||
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
|
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
|
||||||
!defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
|
!defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
|
||||||
|
|
||||||
/// \brief Carries out some operation on the stored object if there is one.
|
/// \brief Carries out some operation on the stored object if there is one.
|
||||||
/// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
|
/// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
|
||||||
/// value())`. If `U` is `void`, returns an `expected<monostate,E>, otherwise
|
/// value())`. If `U` is `void`, returns an `expected<monostate,E>, otherwise
|
||||||
|
@ -1267,27 +1402,32 @@ public:
|
||||||
///
|
///
|
||||||
/// \group map
|
/// \group map
|
||||||
/// \synopsis template <class F> constexpr auto map(F &&f) &;
|
/// \synopsis template <class F> constexpr auto map(F &&f) &;
|
||||||
template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) & {
|
template<class F>
|
||||||
|
TL_EXPECTED_11_CONSTEXPR auto map(F &&f) &{
|
||||||
return expected_map_impl(*this, std::forward<F>(f));
|
return expected_map_impl(*this, std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group map
|
/// \group map
|
||||||
/// \synopsis template <class F> constexpr auto map(F &&f) &&;
|
/// \synopsis template <class F> constexpr auto map(F &&f) &&;
|
||||||
template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) && {
|
template<class F>
|
||||||
|
TL_EXPECTED_11_CONSTEXPR auto map(F &&f) &&{
|
||||||
return expected_map_impl(std::move(*this), std::forward<F>(f));
|
return expected_map_impl(std::move(*this), std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group map
|
/// \group map
|
||||||
/// \synopsis template <class F> constexpr auto map(F &&f) const &;
|
/// \synopsis template <class F> constexpr auto map(F &&f) const &;
|
||||||
template <class F> constexpr auto map(F &&f) const & {
|
template<class F>
|
||||||
|
constexpr auto map(F &&f) const &{
|
||||||
return expected_map_impl(*this, std::forward<F>(f));
|
return expected_map_impl(*this, std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group map
|
/// \group map
|
||||||
/// \synopsis template <class F> constexpr auto map(F &&f) const &&;
|
/// \synopsis template <class F> constexpr auto map(F &&f) const &&;
|
||||||
template <class F> constexpr auto map(F &&f) const && {
|
template<class F>
|
||||||
|
constexpr auto map(F &&f) const &&{
|
||||||
return expected_map_impl(std::move(*this), std::forward<F>(f));
|
return expected_map_impl(std::move(*this), std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/// \brief Carries out some operation on the stored object if there is one.
|
/// \brief Carries out some operation on the stored object if there is one.
|
||||||
/// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
|
/// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
|
||||||
|
@ -1338,6 +1478,7 @@ public:
|
||||||
|
|
||||||
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
|
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
|
||||||
!defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
|
!defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
|
||||||
|
|
||||||
/// \brief Carries out some operation on the stored unexpected object if there
|
/// \brief Carries out some operation on the stored unexpected object if there
|
||||||
/// is one.
|
/// is one.
|
||||||
/// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
|
/// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
|
||||||
|
@ -1349,27 +1490,32 @@ public:
|
||||||
///
|
///
|
||||||
/// \group map_error
|
/// \group map_error
|
||||||
/// \synopsis template <class F> constexpr auto map_error(F &&f) &;
|
/// \synopsis template <class F> constexpr auto map_error(F &&f) &;
|
||||||
template <class F> TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) & {
|
template<class F>
|
||||||
|
TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) &{
|
||||||
return map_error_impl(*this, std::forward<F>(f));
|
return map_error_impl(*this, std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group map_error
|
/// \group map_error
|
||||||
/// \synopsis template <class F> constexpr auto map_error(F &&f) &&;
|
/// \synopsis template <class F> constexpr auto map_error(F &&f) &&;
|
||||||
template <class F> TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) && {
|
template<class F>
|
||||||
|
TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) &&{
|
||||||
return map_error_impl(std::move(*this), std::forward<F>(f));
|
return map_error_impl(std::move(*this), std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group map_error
|
/// \group map_error
|
||||||
/// \synopsis template <class F> constexpr auto map_error(F &&f) const &;
|
/// \synopsis template <class F> constexpr auto map_error(F &&f) const &;
|
||||||
template <class F> constexpr auto map_error(F &&f) const & {
|
template<class F>
|
||||||
|
constexpr auto map_error(F &&f) const &{
|
||||||
return map_error_impl(*this, std::forward<F>(f));
|
return map_error_impl(*this, std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group map_error
|
/// \group map_error
|
||||||
/// \synopsis template <class F> constexpr auto map_error(F &&f) const &&;
|
/// \synopsis template <class F> constexpr auto map_error(F &&f) const &&;
|
||||||
template <class F> constexpr auto map_error(F &&f) const && {
|
template<class F>
|
||||||
|
constexpr auto map_error(F &&f) const &&{
|
||||||
return map_error_impl(std::move(*this), std::forward<F>(f));
|
return map_error_impl(std::move(*this), std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/// \brief Carries out some operation on the stored unexpected object if there
|
/// \brief Carries out some operation on the stored unexpected object if there
|
||||||
/// is one.
|
/// is one.
|
||||||
|
@ -1426,27 +1572,38 @@ public:
|
||||||
/// `std::nullopt`. Otherwise, returns `std::forward<F>(f)(E)`.
|
/// `std::nullopt`. Otherwise, returns `std::forward<F>(f)(E)`.
|
||||||
///
|
///
|
||||||
/// \group or_else
|
/// \group or_else
|
||||||
template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) & {
|
template<class F>
|
||||||
|
expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) &{
|
||||||
return or_else_impl(*this, std::forward<F>(f));
|
return or_else_impl(*this, std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) && {
|
template<class F>
|
||||||
|
expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) &&{
|
||||||
return or_else_impl(std::move(*this), std::forward<F>(f));
|
return or_else_impl(std::move(*this), std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F> expected constexpr or_else(F &&f) const & {
|
template<class F>
|
||||||
|
expected constexpr or_else(F &&f) const &{
|
||||||
return or_else_impl(*this, std::forward<F>(f));
|
return or_else_impl(*this, std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TL_EXPECTED_NO_CONSTRR
|
#ifndef TL_EXPECTED_NO_CONSTRR
|
||||||
template <class F> expected constexpr or_else(F &&f) const && {
|
|
||||||
|
template<class F>
|
||||||
|
expected constexpr or_else(F &&f) const &&{
|
||||||
return or_else_impl(std::move(*this), std::forward<F>(f));
|
return or_else_impl(std::move(*this), std::forward<F>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr expected() = default;
|
constexpr expected() = default;
|
||||||
|
|
||||||
constexpr expected(const expected &rhs) = default;
|
constexpr expected(const expected &rhs) = default;
|
||||||
|
|
||||||
constexpr expected(expected &&rhs) = default;
|
constexpr expected(expected &&rhs) = default;
|
||||||
|
|
||||||
expected &operator=(const expected &rhs) = default;
|
expected &operator=(const expected &rhs) = default;
|
||||||
|
|
||||||
expected &operator=(expected &&rhs) = default;
|
expected &operator=(expected &&rhs) = default;
|
||||||
|
|
||||||
template<class... Args,
|
template<class... Args,
|
||||||
|
@ -1805,18 +1962,21 @@ public:
|
||||||
constexpr const U &operator*() const &{
|
constexpr const U &operator*() const &{
|
||||||
return val();
|
return val();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group deref
|
/// \group deref
|
||||||
template<class U = T,
|
template<class U = T,
|
||||||
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
||||||
TL_EXPECTED_11_CONSTEXPR U &operator*() &{
|
TL_EXPECTED_11_CONSTEXPR U &operator*() &{
|
||||||
return val();
|
return val();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group deref
|
/// \group deref
|
||||||
template<class U = T,
|
template<class U = T,
|
||||||
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
||||||
constexpr const U &&operator*() const &&{
|
constexpr const U &&operator*() const &&{
|
||||||
return std::move(val());
|
return std::move(val());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group deref
|
/// \group deref
|
||||||
template<class U = T,
|
template<class U = T,
|
||||||
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
||||||
|
@ -1827,6 +1987,7 @@ public:
|
||||||
/// \returns whether or not the optional has a value
|
/// \returns whether or not the optional has a value
|
||||||
/// \group has_value
|
/// \group has_value
|
||||||
constexpr bool has_value() const noexcept { return this->m_has_val; }
|
constexpr bool has_value() const noexcept { return this->m_has_val; }
|
||||||
|
|
||||||
/// \group has_value
|
/// \group has_value
|
||||||
constexpr explicit operator bool() const noexcept { return this->m_has_val; }
|
constexpr explicit operator bool() const noexcept { return this->m_has_val; }
|
||||||
|
|
||||||
|
@ -1841,6 +2002,7 @@ public:
|
||||||
detail::throw_exception(bad_expected_access<E>(err().value()));
|
detail::throw_exception(bad_expected_access<E>(err().value()));
|
||||||
return val();
|
return val();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group value
|
/// \group value
|
||||||
template<class U = T,
|
template<class U = T,
|
||||||
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
||||||
|
@ -1849,6 +2011,7 @@ public:
|
||||||
detail::throw_exception(bad_expected_access<E>(err().value()));
|
detail::throw_exception(bad_expected_access<E>(err().value()));
|
||||||
return val();
|
return val();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group value
|
/// \group value
|
||||||
template<class U = T,
|
template<class U = T,
|
||||||
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
||||||
|
@ -1857,6 +2020,7 @@ public:
|
||||||
detail::throw_exception(bad_expected_access<E>(err().value()));
|
detail::throw_exception(bad_expected_access<E>(err().value()));
|
||||||
return std::move(val());
|
return std::move(val());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group value
|
/// \group value
|
||||||
template<class U = T,
|
template<class U = T,
|
||||||
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
||||||
|
@ -1872,6 +2036,7 @@ public:
|
||||||
constexpr const E &error() const &{ return err().value(); }
|
constexpr const E &error() const &{ return err().value(); }
|
||||||
/// \group error
|
/// \group error
|
||||||
TL_EXPECTED_11_CONSTEXPR E &error() &{ return err().value(); }
|
TL_EXPECTED_11_CONSTEXPR E &error() &{ return err().value(); }
|
||||||
|
|
||||||
/// \group error
|
/// \group error
|
||||||
constexpr const E &&error() const &&{ return std::move(err().value()); }
|
constexpr const E &&error() const &&{ return std::move(err().value()); }
|
||||||
/// \group error
|
/// \group error
|
||||||
|
@ -1879,14 +2044,17 @@ public:
|
||||||
|
|
||||||
/// \returns the stored value if there is one, otherwise returns `u`
|
/// \returns the stored value if there is one, otherwise returns `u`
|
||||||
/// \group value_or
|
/// \group value_or
|
||||||
template <class U> constexpr T value_or(U &&v) const & {
|
template<class U>
|
||||||
|
constexpr T value_or(U &&v) const &{
|
||||||
static_assert(std::is_copy_constructible<T>::value &&
|
static_assert(std::is_copy_constructible<T>::value &&
|
||||||
std::is_convertible<U &&, T>::value,
|
std::is_convertible<U &&, T>::value,
|
||||||
"T must be copy-constructible and convertible to from U&&");
|
"T must be copy-constructible and convertible to from U&&");
|
||||||
return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
|
return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \group value_or
|
/// \group value_or
|
||||||
template <class U> TL_EXPECTED_11_CONSTEXPR T value_or(U &&v) && {
|
template<class U>
|
||||||
|
TL_EXPECTED_11_CONSTEXPR T value_or(U &&v) &&{
|
||||||
static_assert(std::is_move_constructible<T>::value &&
|
static_assert(std::is_move_constructible<T>::value &&
|
||||||
std::is_convertible<U &&, T>::value,
|
std::is_convertible<U &&, T>::value,
|
||||||
"T must be move-constructible and convertible to from U&&");
|
"T must be move-constructible and convertible to from U&&");
|
||||||
|
@ -1901,6 +2069,7 @@ template <class Exp> using err_t = typename detail::decay_t<Exp>::error_type;
|
||||||
template<class Exp, class Ret> using ret_t = expected<Ret, err_t<Exp>>;
|
template<class Exp, class Ret> using ret_t = expected<Ret, err_t<Exp>>;
|
||||||
|
|
||||||
#ifdef TL_EXPECTED_CXX14
|
#ifdef TL_EXPECTED_CXX14
|
||||||
|
|
||||||
template<class Exp, class F,
|
template<class Exp, class F,
|
||||||
detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
|
detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
|
||||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||||
|
@ -1922,6 +2091,7 @@ constexpr auto and_then_impl(Exp &&exp, F &&f) {
|
||||||
return exp.has_value() ? detail::invoke(std::forward<F>(f))
|
return exp.has_value() ? detail::invoke(std::forward<F>(f))
|
||||||
: Ret(unexpect, std::forward<Exp>(exp).error());
|
: Ret(unexpect, std::forward<Exp>(exp).error());
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
template <class> struct TC;
|
template <class> struct TC;
|
||||||
template <class Exp, class F,
|
template <class Exp, class F,
|
||||||
|
@ -1948,6 +2118,7 @@ constexpr auto and_then_impl(Exp &&exp, F &&f) -> Ret {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TL_EXPECTED_CXX14
|
#ifdef TL_EXPECTED_CXX14
|
||||||
|
|
||||||
template<class Exp, class F,
|
template<class Exp, class F,
|
||||||
detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
|
detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
|
||||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||||
|
@ -1998,6 +2169,7 @@ auto expected_map_impl(Exp &&exp, F &&f) {
|
||||||
|
|
||||||
return result(unexpect, std::forward<Exp>(exp).error());
|
return result(unexpect, std::forward<Exp>(exp).error());
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
template <class Exp, class F,
|
template <class Exp, class F,
|
||||||
detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
|
detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
|
||||||
|
@ -2059,6 +2231,7 @@ auto expected_map_impl(Exp &&exp, F &&f) -> expected<void, err_t<Exp>> {
|
||||||
|
|
||||||
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
|
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
|
||||||
!defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
|
!defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
|
||||||
|
|
||||||
template<class Exp, class F,
|
template<class Exp, class F,
|
||||||
detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
|
detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
|
||||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||||
|
@ -2071,6 +2244,7 @@ constexpr auto map_error_impl(Exp &&exp, F &&f) {
|
||||||
: result(unexpect, detail::invoke(std::forward<F>(f),
|
: result(unexpect, detail::invoke(std::forward<F>(f),
|
||||||
std::forward<Exp>(exp).error()));
|
std::forward<Exp>(exp).error()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Exp, class F,
|
template<class Exp, class F,
|
||||||
detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
|
detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
|
||||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||||
|
@ -2085,6 +2259,7 @@ auto map_error_impl(Exp &&exp, F &&f) {
|
||||||
detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
|
detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
|
||||||
return result(unexpect, monostate{});
|
return result(unexpect, monostate{});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Exp, class F,
|
template<class Exp, class F,
|
||||||
detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
|
detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
|
||||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||||
|
@ -2097,6 +2272,7 @@ constexpr auto map_error_impl(Exp &&exp, F &&f) {
|
||||||
: result(unexpect, detail::invoke(std::forward<F>(f),
|
: result(unexpect, detail::invoke(std::forward<F>(f),
|
||||||
std::forward<Exp>(exp).error()));
|
std::forward<Exp>(exp).error()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Exp, class F,
|
template<class Exp, class F,
|
||||||
detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
|
detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
|
||||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||||
|
@ -2111,6 +2287,7 @@ auto map_error_impl(Exp &&exp, F &&f) {
|
||||||
detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
|
detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
|
||||||
return result(unexpect, monostate{});
|
return result(unexpect, monostate{});
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
template <class Exp, class F,
|
template <class Exp, class F,
|
||||||
detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
|
detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
|
||||||
|
@ -2174,6 +2351,7 @@ auto map_error_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate> {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TL_EXPECTED_CXX14
|
#ifdef TL_EXPECTED_CXX14
|
||||||
|
|
||||||
template<class Exp, class F,
|
template<class Exp, class F,
|
||||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||||
std::declval<Exp>().error())),
|
std::declval<Exp>().error())),
|
||||||
|
@ -2195,6 +2373,7 @@ detail::decay_t<Exp> or_else_impl(Exp &&exp, F &&f) {
|
||||||
: (detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error()),
|
: (detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error()),
|
||||||
std::forward<Exp>(exp));
|
std::forward<Exp>(exp));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
template <class Exp, class F,
|
template <class Exp, class F,
|
||||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||||
|
@ -2227,6 +2406,7 @@ constexpr bool operator==(const expected<T, E> &lhs,
|
||||||
? false
|
? false
|
||||||
: (!lhs.has_value() ? lhs.error() == rhs.error() : *lhs == *rhs);
|
: (!lhs.has_value() ? lhs.error() == rhs.error() : *lhs == *rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class E, class U, class F>
|
template<class T, class E, class U, class F>
|
||||||
constexpr bool operator!=(const expected<T, E> &lhs,
|
constexpr bool operator!=(const expected<T, E> &lhs,
|
||||||
const expected<U, F> &rhs) {
|
const expected<U, F> &rhs) {
|
||||||
|
@ -2239,14 +2419,17 @@ template <class T, class E, class U>
|
||||||
constexpr bool operator==(const expected<T, E> &x, const U &v) {
|
constexpr bool operator==(const expected<T, E> &x, const U &v) {
|
||||||
return x.has_value() ? *x == v : false;
|
return x.has_value() ? *x == v : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class E, class U>
|
template<class T, class E, class U>
|
||||||
constexpr bool operator==(const U &v, const expected<T, E> &x) {
|
constexpr bool operator==(const U &v, const expected<T, E> &x) {
|
||||||
return x.has_value() ? *x == v : false;
|
return x.has_value() ? *x == v : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class E, class U>
|
template<class T, class E, class U>
|
||||||
constexpr bool operator!=(const expected<T, E> &x, const U &v) {
|
constexpr bool operator!=(const expected<T, E> &x, const U &v) {
|
||||||
return x.has_value() ? *x != v : true;
|
return x.has_value() ? *x != v : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class E, class U>
|
template<class T, class E, class U>
|
||||||
constexpr bool operator!=(const U &v, const expected<T, E> &x) {
|
constexpr bool operator!=(const U &v, const expected<T, E> &x) {
|
||||||
return x.has_value() ? *x != v : true;
|
return x.has_value() ? *x != v : true;
|
||||||
|
@ -2256,14 +2439,17 @@ template <class T, class E>
|
||||||
constexpr bool operator==(const expected<T, E> &x, const unexpected<E> &e) {
|
constexpr bool operator==(const expected<T, E> &x, const unexpected<E> &e) {
|
||||||
return x.has_value() ? false : x.error() == e.value();
|
return x.has_value() ? false : x.error() == e.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class E>
|
template<class T, class E>
|
||||||
constexpr bool operator==(const unexpected<E> &e, const expected<T, E> &x) {
|
constexpr bool operator==(const unexpected<E> &e, const expected<T, E> &x) {
|
||||||
return x.has_value() ? false : x.error() == e.value();
|
return x.has_value() ? false : x.error() == e.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class E>
|
template<class T, class E>
|
||||||
constexpr bool operator!=(const expected<T, E> &x, const unexpected<E> &e) {
|
constexpr bool operator!=(const expected<T, E> &x, const unexpected<E> &e) {
|
||||||
return x.has_value() ? true : x.error() != e.value();
|
return x.has_value() ? true : x.error() != e.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class E>
|
template<class T, class E>
|
||||||
constexpr bool operator!=(const unexpected<E> &e, const expected<T, E> &x) {
|
constexpr bool operator!=(const unexpected<E> &e, const expected<T, E> &x) {
|
||||||
return x.has_value() ? true : x.error() != e.value();
|
return x.has_value() ? true : x.error() != e.value();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "parsecontext.h"
|
#include "parse_context.h"
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -6,26 +6,24 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
|
||||||
ParseContext::ParseContext()
|
ParseContext::ParseContext() {
|
||||||
{
|
|
||||||
applicationDir = std::string();
|
applicationDir = std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ParseContext::addFile(const std::string &fileName,
|
unsigned ParseContext::addFile(const std::string &fileName,
|
||||||
const std::string& source)
|
const std::string &source) {
|
||||||
{
|
fileMap.emplace_back(fileName, source);
|
||||||
fileMap.push_back(SourceFile(fileName, source));
|
|
||||||
return fileMap.size();
|
return fileMap.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceFile& ParseContext::getFile(unsigned fileId)
|
SourceFile &ParseContext::getFile(unsigned fileId) {
|
||||||
{
|
|
||||||
return fileMap[fileId - 1];
|
return fileMap[fileId - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct pad {
|
struct pad {
|
||||||
char ch; int count;
|
char ch;
|
||||||
|
int count;
|
||||||
|
|
||||||
pad(char ch, int count) : ch(ch), count(count) {}
|
pad(char ch, int count) : ch(ch), count(count) {}
|
||||||
};
|
};
|
||||||
|
@ -42,14 +40,11 @@ std::ostream& operator<<(std::ostream& stream, const pad& p) {
|
||||||
|
|
||||||
void ParseContext::formatError(const SourceError &sourceError,
|
void ParseContext::formatError(const SourceError &sourceError,
|
||||||
std::ostream &stream,
|
std::ostream &stream,
|
||||||
const std::string& ErrorOrWarning)
|
const std::string &errorOrWarning) {
|
||||||
{
|
|
||||||
ATLAS_ASSERT(sourceError.span.lo.col != 0
|
ATLAS_ASSERT(sourceError.span.lo.col != 0
|
||||||
&& sourceError.span.hi.col != 0);
|
&& sourceError.span.hi.col != 0);
|
||||||
|
|
||||||
SourceFile sourceFile = getFile(sourceError.span.lo.fileId);
|
stream << errorOrWarning << sourceError.message << std::endl;
|
||||||
|
|
||||||
stream << ErrorOrWarning << sourceError.message << std::endl;
|
|
||||||
|
|
||||||
Span span = sourceError.span;
|
Span span = sourceError.span;
|
||||||
|
|
||||||
|
@ -100,20 +95,16 @@ void ParseContext::formatError(const SourceError& sourceError,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SourceFile::SourceFile(std::string fileName, std::string source)
|
SourceFile::SourceFile(std::string fileName, std::string source)
|
||||||
: fileName(std::move(fileName)), source(std::move(source))
|
: fileName(std::move(fileName)), source(std::move(source)) {
|
||||||
{
|
|
||||||
lineOffsets.push_back(0);
|
lineOffsets.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& SourceFile::getFileName() const
|
const std::string &SourceFile::getFileName() const {
|
||||||
{
|
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string SourceFile::getLine(unsigned line) const
|
std::string SourceFile::getLine(unsigned line) const {
|
||||||
{
|
|
||||||
auto lineOffset = lineOffsets[line - 1];
|
auto lineOffset = lineOffsets[line - 1];
|
||||||
auto nextLF = source.find('\n', lineOffset);
|
auto nextLF = source.find('\n', lineOffset);
|
||||||
auto nextCR = source.find('\r', lineOffset);
|
auto nextCR = source.find('\r', lineOffset);
|
||||||
|
@ -122,7 +113,6 @@ const std::string SourceFile::getLine(unsigned line) const
|
||||||
return source.substr(lineOffset, nl - lineOffset);
|
return source.substr(lineOffset, nl - lineOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SourceFile::addLineOffset(unsigned offset)
|
void SourceFile::addLineOffset(unsigned offset) {
|
||||||
{
|
|
||||||
lineOffsets.push_back(offset);
|
lineOffsets.push_back(offset);
|
||||||
}
|
}
|
|
@ -2,30 +2,28 @@
|
||||||
#define PARSE_CONTEXT_H
|
#define PARSE_CONTEXT_H
|
||||||
|
|
||||||
|
|
||||||
#include "sourceerror.h"
|
#include "source_error.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
class SourceFile {
|
class SourceFile {
|
||||||
std::string fileName;
|
std::string fileName;
|
||||||
std::string source;
|
std::string source;
|
||||||
std::vector<unsigned> lineOffsets;
|
std::vector<unsigned> lineOffsets;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// qqq source je CIJELI comdel fajl,
|
|
||||||
// za inicijalizaciju source se koristi std::move, a možda treba biti referenca???
|
|
||||||
SourceFile(std::string fileName, std::string source);
|
SourceFile(std::string fileName, std::string source);
|
||||||
|
|
||||||
const std::string &getFileName() const;
|
const std::string &getFileName() const;
|
||||||
const std::string getLine(unsigned line) const;
|
|
||||||
|
std::string getLine(unsigned line) const;
|
||||||
|
|
||||||
void addLineOffset(unsigned offset);
|
void addLineOffset(unsigned offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ParseContext
|
class ParseContext {
|
||||||
{
|
|
||||||
std::string applicationDir;
|
std::string applicationDir;
|
||||||
std::vector<SourceFile> fileMap;
|
std::vector<SourceFile> fileMap;
|
||||||
|
|
||||||
|
@ -33,9 +31,10 @@ public:
|
||||||
ParseContext();
|
ParseContext();
|
||||||
|
|
||||||
unsigned addFile(const std::string &fileName, const std::string &source);
|
unsigned addFile(const std::string &fileName, const std::string &source);
|
||||||
|
|
||||||
SourceFile &getFile(unsigned file);
|
SourceFile &getFile(unsigned file);
|
||||||
|
|
||||||
void formatError(const SourceError &sourceError, std::ostream &stream, const std::string& ErrorOrWarning);
|
void formatError(const SourceError &sourceError, std::ostream &stream, const std::string &errorOrWarning);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
#include "comdellexer.h"
|
#include "comdellexer.h"
|
||||||
#include "comdelparser.h"
|
#include "comdel_parser.h"
|
||||||
#include "parserutil.h"
|
#include "parser_util.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
std::optional<LibraryNode> loadLibraryFromFile(ParseContext * parseContext,
|
std::optional<LibraryNode> load_library_from_file(ParseContext *parseContext,
|
||||||
const char *name,
|
const char *name,
|
||||||
std::ostream& stream)
|
std::ostream &stream) {
|
||||||
{
|
|
||||||
std::ifstream in(name, std::ios::in | std::ios::binary);
|
std::ifstream in(name, std::ios::in | std::ios::binary);
|
||||||
if (!in) {
|
if (!in) {
|
||||||
stream << "ERROR: cannot open file '" << name
|
stream << "ERROR: cannot open file '" << name
|
||||||
|
@ -23,15 +22,15 @@ std::optional<LibraryNode> loadLibraryFromFile(ParseContext * parseContext,
|
||||||
ComdelLexer lexer(name, source, parseContext);
|
ComdelLexer lexer(name, source, parseContext);
|
||||||
LexerResult lexerResult = lexer.tokenize();
|
LexerResult lexerResult = lexer.tokenize();
|
||||||
|
|
||||||
if (lexerResult.errors.size()) {
|
if (!lexerResult.errors.empty()) {
|
||||||
for (auto &error: lexerResult.errors) {
|
for (auto &error: lexerResult.errors) {
|
||||||
parseContext->formatError(error, stream, "ERROR: ");
|
parseContext->formatError(error, stream, "ERROR: ");
|
||||||
}
|
}
|
||||||
return std::nullopt; // if lexer has found errors => don't parse
|
return std::nullopt; // if lexer has found errors => don't parseLibrary
|
||||||
}
|
}
|
||||||
|
|
||||||
ComdelParser parser(lexerResult.tokens);
|
ComdelParser parser(lexerResult.tokens);
|
||||||
auto unit = parser.parse();
|
auto unit = parser.parseLibrary();
|
||||||
if (!unit) {
|
if (!unit) {
|
||||||
for (auto &error: parser.getErrors()) {
|
for (auto &error: parser.getErrors()) {
|
||||||
parseContext->formatError(error, stream, "ERROR: ");
|
parseContext->formatError(error, stream, "ERROR: ");
|
||||||
|
@ -43,10 +42,9 @@ std::optional<LibraryNode> loadLibraryFromFile(ParseContext * parseContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::optional<SchemaNode> loadSchemaFromFile(ParseContext * parseContext,
|
std::optional<SchemaNode> load_schema_from_file(ParseContext *parseContext,
|
||||||
const char *name,
|
const char *name,
|
||||||
std::ostream& stream)
|
std::ostream &stream) {
|
||||||
{
|
|
||||||
std::ifstream in(name, std::ios::in | std::ios::binary);
|
std::ifstream in(name, std::ios::in | std::ios::binary);
|
||||||
if (!in) {
|
if (!in) {
|
||||||
stream << "ERROR: cannot open file '" << name
|
stream << "ERROR: cannot open file '" << name
|
||||||
|
@ -59,11 +57,11 @@ std::optional<SchemaNode> loadSchemaFromFile(ParseContext * parseContext,
|
||||||
ComdelLexer lexer(name, source, parseContext);
|
ComdelLexer lexer(name, source, parseContext);
|
||||||
LexerResult lexerResult = lexer.tokenize();
|
LexerResult lexerResult = lexer.tokenize();
|
||||||
|
|
||||||
if (lexerResult.errors.size()) {
|
if (!lexerResult.errors.empty()) {
|
||||||
for (auto &error: lexerResult.errors) {
|
for (auto &error: lexerResult.errors) {
|
||||||
parseContext->formatError(error, stream, "ERROR: ");
|
parseContext->formatError(error, stream, "ERROR: ");
|
||||||
}
|
}
|
||||||
return std::nullopt; // if lexer has found errors => don't parse
|
return std::nullopt; // if lexer has found errors => don't parseLibrary
|
||||||
}
|
}
|
||||||
|
|
||||||
ComdelParser parser(lexerResult.tokens);
|
ComdelParser parser(lexerResult.tokens);
|
||||||
|
@ -78,12 +76,12 @@ std::optional<SchemaNode> loadSchemaFromFile(ParseContext * parseContext,
|
||||||
if (unit->source) {
|
if (unit->source) {
|
||||||
QFileInfo info(name);
|
QFileInfo info(name);
|
||||||
auto filepath = info.absolutePath();
|
auto filepath = info.absolutePath();
|
||||||
QDir dir;
|
QDir::setCurrent(filepath);
|
||||||
dir.setCurrent(filepath);
|
|
||||||
|
|
||||||
|
QDir dir;
|
||||||
auto libraryPath = dir.absoluteFilePath(QString::fromStdString(unit->source->asString()));
|
auto libraryPath = dir.absoluteFilePath(QString::fromStdString(unit->source->asString()));
|
||||||
|
|
||||||
unit->library = loadLibraryFromFile(parseContext, libraryPath.toUtf8().data(), stream);
|
unit->library = load_library_from_file(parseContext, libraryPath.toUtf8().data(), stream);
|
||||||
if (unit->library == std::nullopt) {
|
if (unit->library == std::nullopt) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef PARSER_UTIL_H
|
||||||
|
#define PARSER_UTIL_H
|
||||||
|
|
||||||
|
#include "ast_nodes.h"
|
||||||
|
#include "parse_context.h"
|
||||||
|
|
||||||
|
std::optional<LibraryNode> load_library_from_file(ParseContext *parseContext,
|
||||||
|
const char *name,
|
||||||
|
std::ostream &stream);
|
||||||
|
|
||||||
|
std::optional<SchemaNode> load_schema_from_file(ParseContext *parseContext,
|
||||||
|
const char *name,
|
||||||
|
std::ostream &stream);
|
||||||
|
|
||||||
|
#endif // PARSER_UTIL_H
|
|
@ -1,15 +0,0 @@
|
||||||
#ifndef PARSER_UTIL_H
|
|
||||||
#define PARSER_UTIL_H
|
|
||||||
|
|
||||||
#include "astnode.h"
|
|
||||||
#include "parsecontext.h"
|
|
||||||
|
|
||||||
std::optional<LibraryNode> loadLibraryFromFile(ParseContext * parseContext,
|
|
||||||
const char* name,
|
|
||||||
std::ostream& stream);
|
|
||||||
|
|
||||||
std::optional<SchemaNode> loadSchemaFromFile(ParseContext * parseContext,
|
|
||||||
const char* name,
|
|
||||||
std::ostream& stream);
|
|
||||||
|
|
||||||
#endif // PARSERUTIL_H
|
|
|
@ -30,34 +30,28 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
||||||
namespace detail
|
namespace detail {
|
||||||
{
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Implementation detail classes
|
// Implementation detail classes
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct default_copy
|
struct default_copy {
|
||||||
{
|
T *operator()(const T &t) const {
|
||||||
T* operator()(const T& t) const
|
|
||||||
{
|
|
||||||
return new T(t);
|
return new T(t);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct default_delete
|
struct default_delete {
|
||||||
{
|
void operator()(const T *t) const {
|
||||||
void operator()(const T* t) const
|
|
||||||
{
|
|
||||||
delete t;
|
delete t;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct control_block
|
struct control_block {
|
||||||
{
|
|
||||||
virtual ~control_block() = default;
|
virtual ~control_block() = default;
|
||||||
|
|
||||||
virtual std::unique_ptr<control_block> clone() const = 0;
|
virtual std::unique_ptr<control_block> clone() const = 0;
|
||||||
|
@ -66,76 +60,63 @@ namespace detail
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T, class U = T>
|
template<class T, class U = T>
|
||||||
class direct_control_block : public control_block<T>
|
class direct_control_block : public control_block<T> {
|
||||||
{
|
|
||||||
static_assert(!std::is_reference<U>::value, "");
|
static_assert(!std::is_reference<U>::value, "");
|
||||||
U u_;
|
U u_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<class... Ts>
|
template<class... Ts>
|
||||||
explicit direct_control_block(Ts&&... ts) : u_(U(std::forward<Ts>(ts)...))
|
explicit direct_control_block(Ts &&... ts) : u_(U(std::forward<Ts>(ts)...)) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<control_block<T>> clone() const override
|
std::unique_ptr<control_block<T>> clone() const override {
|
||||||
{
|
|
||||||
return std::make_unique<direct_control_block>(*this);
|
return std::make_unique<direct_control_block>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
T* ptr() override
|
T *ptr() override {
|
||||||
{
|
|
||||||
return std::addressof(u_);
|
return std::addressof(u_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T, class U, class C = default_copy<U>,
|
template<class T, class U, class C = default_copy<U>,
|
||||||
class D = default_delete<U>>
|
class D = default_delete<U>>
|
||||||
class pointer_control_block : public control_block<T>, public C
|
class pointer_control_block : public control_block<T>, public C {
|
||||||
{
|
|
||||||
std::unique_ptr<U, D> p_;
|
std::unique_ptr<U, D> p_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit pointer_control_block(U *u, C c = C{}, D d = D{})
|
explicit pointer_control_block(U *u, C c = C{}, D d = D{})
|
||||||
: C(std::move(c)), p_(u, std::move(d))
|
: C(std::move(c)), p_(u, std::move(d)) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit pointer_control_block(std::unique_ptr<U, D> p, C c = C{})
|
explicit pointer_control_block(std::unique_ptr<U, D> p, C c = C{})
|
||||||
: C(std::move(c)), p_(std::move(p))
|
: C(std::move(c)), p_(std::move(p)) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<control_block<T>> clone() const override
|
std::unique_ptr<control_block<T>> clone() const override {
|
||||||
{
|
|
||||||
assert(p_);
|
assert(p_);
|
||||||
return std::make_unique<pointer_control_block>(
|
return std::make_unique<pointer_control_block>(
|
||||||
C::operator()(*p_), static_cast<const C &>(*this), p_.get_deleter());
|
C::operator()(*p_), static_cast<const C &>(*this), p_.get_deleter());
|
||||||
}
|
}
|
||||||
|
|
||||||
T* ptr() override
|
T *ptr() override {
|
||||||
{
|
|
||||||
return p_.get();
|
return p_.get();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T, class U>
|
template<class T, class U>
|
||||||
class delegating_control_block : public control_block<T>
|
class delegating_control_block : public control_block<T> {
|
||||||
{
|
|
||||||
std::unique_ptr<control_block<U>> delegate_;
|
std::unique_ptr<control_block<U>> delegate_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit delegating_control_block(std::unique_ptr<control_block<U>> b)
|
explicit delegating_control_block(std::unique_ptr<control_block<U>> b)
|
||||||
: delegate_(std::move(b))
|
: delegate_(std::move(b)) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<control_block<T>> clone() const override
|
std::unique_ptr<control_block<T>> clone() const override {
|
||||||
{
|
|
||||||
return std::make_unique<delegating_control_block>(delegate_->clone());
|
return std::make_unique<delegating_control_block>(delegate_->clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
T* ptr() override
|
T *ptr() override {
|
||||||
{
|
|
||||||
return static_cast<T *>(delegate_->ptr());
|
return static_cast<T *>(delegate_->ptr());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -143,13 +124,11 @@ namespace detail
|
||||||
|
|
||||||
} // end namespace detail
|
} // end namespace detail
|
||||||
|
|
||||||
class bad_poly_construction : std::exception
|
class bad_poly_construction : std::exception {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
bad_poly_construction() noexcept = default;
|
bad_poly_construction() noexcept = default;
|
||||||
|
|
||||||
const char* what() const noexcept override
|
const char *what() const noexcept override {
|
||||||
{
|
|
||||||
return "Dynamic and static type mismatch in poly "
|
return "Dynamic and static type mismatch in poly "
|
||||||
"construction";
|
"construction";
|
||||||
}
|
}
|
||||||
|
@ -159,13 +138,11 @@ template <class T>
|
||||||
class poly;
|
class poly;
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct is_poly : std::false_type
|
struct is_poly : std::false_type {
|
||||||
{
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct is_poly<poly<T>> : std::true_type
|
struct is_poly<poly<T>> : std::true_type {
|
||||||
{
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -174,18 +151,20 @@ struct is_poly<poly<T>> : std::true_type
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class poly
|
class poly {
|
||||||
{
|
|
||||||
static_assert(!std::is_union<T>::value, "");
|
static_assert(!std::is_union<T>::value, "");
|
||||||
static_assert(std::is_class<T>::value, "");
|
static_assert(std::is_class<T>::value, "");
|
||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
friend class poly;
|
friend
|
||||||
|
class poly;
|
||||||
|
|
||||||
template<class T_, class U, class... Ts>
|
template<class T_, class U, class... Ts>
|
||||||
friend poly<T_> make_poly(Ts &&... ts);
|
friend poly<T_> make_poly(Ts &&... ts);
|
||||||
|
|
||||||
template<class T_, class... Ts>
|
template<class T_, class... Ts>
|
||||||
friend poly<T_> make_poly(Ts &&... ts);
|
friend poly<T_> make_poly(Ts &&... ts);
|
||||||
|
|
||||||
template<class T_, class U>
|
template<class T_, class U>
|
||||||
friend poly<T_> poly_cast(poly<U> p);
|
friend poly<T_> poly_cast(poly<U> p);
|
||||||
|
|
||||||
|
@ -204,17 +183,14 @@ public:
|
||||||
// Constructors
|
// Constructors
|
||||||
//
|
//
|
||||||
|
|
||||||
poly()
|
poly() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class U, class C = detail::default_copy<U>,
|
template<class U, class C = detail::default_copy<U>,
|
||||||
class D = detail::default_delete<U>,
|
class D = detail::default_delete<U>,
|
||||||
class V = std::enable_if_t<std::is_convertible<U *, T *>::value>>
|
class V = std::enable_if_t<std::is_convertible<U *, T *>::value>>
|
||||||
explicit poly(U* u, C copier = C{}, D deleter = D{})
|
explicit poly(U *u, C copier = C{}, D deleter = D{}) {
|
||||||
{
|
if (!u) {
|
||||||
if (!u)
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,10 +212,8 @@ public:
|
||||||
// Copy-constructors
|
// Copy-constructors
|
||||||
//
|
//
|
||||||
|
|
||||||
poly(const poly& p)
|
poly(const poly &p) {
|
||||||
{
|
if (!p) {
|
||||||
if (!p)
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto tmp_cb = p.cb_->clone();
|
auto tmp_cb = p.cb_->clone();
|
||||||
|
@ -251,8 +225,7 @@ public:
|
||||||
// Move-constructors
|
// Move-constructors
|
||||||
//
|
//
|
||||||
|
|
||||||
poly(poly&& p) noexcept
|
poly(poly &&p) noexcept {
|
||||||
{
|
|
||||||
ptr_ = p.ptr_;
|
ptr_ = p.ptr_;
|
||||||
cb_ = std::move(p.cb_);
|
cb_ = std::move(p.cb_);
|
||||||
p.ptr_ = nullptr;
|
p.ptr_ = nullptr;
|
||||||
|
@ -265,8 +238,7 @@ public:
|
||||||
template<class U,
|
template<class U,
|
||||||
class V = std::enable_if_t<!std::is_same<T, U>::value &&
|
class V = std::enable_if_t<!std::is_same<T, U>::value &&
|
||||||
std::is_convertible<U *, T *>::value>>
|
std::is_convertible<U *, T *>::value>>
|
||||||
poly(const poly<U>& p)
|
poly(const poly<U> &p) {
|
||||||
{
|
|
||||||
poly<U> tmp(p);
|
poly<U> tmp(p);
|
||||||
ptr_ = tmp.ptr_;
|
ptr_ = tmp.ptr_;
|
||||||
cb_ = std::make_unique<detail::delegating_control_block<T, U>>(
|
cb_ = std::make_unique<detail::delegating_control_block<T, U>>(
|
||||||
|
@ -276,8 +248,7 @@ public:
|
||||||
template<class U,
|
template<class U,
|
||||||
class V = std::enable_if_t<!std::is_same<T, U>::value &&
|
class V = std::enable_if_t<!std::is_same<T, U>::value &&
|
||||||
std::is_convertible<U *, T *>::value>>
|
std::is_convertible<U *, T *>::value>>
|
||||||
poly(poly<U>&& p)
|
poly(poly<U> &&p) {
|
||||||
{
|
|
||||||
ptr_ = p.ptr_;
|
ptr_ = p.ptr_;
|
||||||
cb_ = std::make_unique<detail::delegating_control_block<T, U>>(
|
cb_ = std::make_unique<detail::delegating_control_block<T, U>>(
|
||||||
std::move(p.cb_));
|
std::move(p.cb_));
|
||||||
|
@ -294,8 +265,7 @@ public:
|
||||||
poly(U &&u)
|
poly(U &&u)
|
||||||
: cb_(std::make_unique<
|
: cb_(std::make_unique<
|
||||||
detail::direct_control_block<T, std::decay_t<U>>>(
|
detail::direct_control_block<T, std::decay_t<U>>>(
|
||||||
std::forward<U>(u)))
|
std::forward<U>(u))) {
|
||||||
{
|
|
||||||
ptr_ = cb_->ptr();
|
ptr_ = cb_->ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,15 +273,12 @@ public:
|
||||||
// Assignment
|
// Assignment
|
||||||
//
|
//
|
||||||
|
|
||||||
poly& operator=(const poly& p)
|
poly &operator=(const poly &p) {
|
||||||
{
|
if (std::addressof(p) == this) {
|
||||||
if (std::addressof(p) == this)
|
|
||||||
{
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p)
|
if (!p) {
|
||||||
{
|
|
||||||
cb_.reset();
|
cb_.reset();
|
||||||
ptr_ = nullptr;
|
ptr_ = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -328,10 +295,8 @@ public:
|
||||||
// Move-assignment
|
// Move-assignment
|
||||||
//
|
//
|
||||||
|
|
||||||
poly& operator=(poly&& p) noexcept
|
poly &operator=(poly &&p) noexcept {
|
||||||
{
|
if (std::addressof(p) == this) {
|
||||||
if (std::addressof(p) == this)
|
|
||||||
{
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,8 +311,7 @@ public:
|
||||||
// Modifiers
|
// Modifiers
|
||||||
//
|
//
|
||||||
|
|
||||||
void swap(poly& p) noexcept
|
void swap(poly &p) noexcept {
|
||||||
{
|
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(ptr_, p.ptr_);
|
swap(ptr_, p.ptr_);
|
||||||
swap(cb_, p.cb_);
|
swap(cb_, p.cb_);
|
||||||
|
@ -358,31 +322,26 @@ public:
|
||||||
// Observers
|
// Observers
|
||||||
//
|
//
|
||||||
|
|
||||||
explicit operator bool() const
|
explicit operator bool() const {
|
||||||
{
|
|
||||||
return (bool) cb_;
|
return (bool) cb_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T* operator->() const
|
const T *operator->() const {
|
||||||
{
|
|
||||||
assert(ptr_);
|
assert(ptr_);
|
||||||
return ptr_;
|
return ptr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& operator*() const
|
const T &operator*() const {
|
||||||
{
|
|
||||||
assert(*this);
|
assert(*this);
|
||||||
return *ptr_;
|
return *ptr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* operator->()
|
T *operator->() {
|
||||||
{
|
|
||||||
assert(*this);
|
assert(*this);
|
||||||
return ptr_;
|
return ptr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
T& operator*()
|
T &operator*() {
|
||||||
{
|
|
||||||
assert(*this);
|
assert(*this);
|
||||||
return *ptr_;
|
return *ptr_;
|
||||||
}
|
}
|
||||||
|
@ -392,17 +351,16 @@ public:
|
||||||
// poly creation
|
// poly creation
|
||||||
//
|
//
|
||||||
template<class T, class... Ts>
|
template<class T, class... Ts>
|
||||||
poly<T> make_poly(Ts&&... ts)
|
poly<T> make_poly(Ts &&... ts) {
|
||||||
{
|
|
||||||
poly<T> p;
|
poly<T> p;
|
||||||
p.cb_ = std::make_unique<detail::direct_control_block<T, T>>(
|
p.cb_ = std::make_unique<detail::direct_control_block<T, T>>(
|
||||||
std::forward<Ts>(ts)...);
|
std::forward<Ts>(ts)...);
|
||||||
p.ptr_ = p.cb_->ptr();
|
p.ptr_ = p.cb_->ptr();
|
||||||
return std::move(p);
|
return std::move(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class U, class... Ts>
|
template<class T, class U, class... Ts>
|
||||||
poly<T> make_poly(Ts&&... ts)
|
poly<T> make_poly(Ts &&... ts) {
|
||||||
{
|
|
||||||
poly<T> p;
|
poly<T> p;
|
||||||
p.cb_ = std::make_unique<detail::direct_control_block<T, U>>(
|
p.cb_ = std::make_unique<detail::direct_control_block<T, U>>(
|
||||||
std::forward<Ts>(ts)...);
|
std::forward<Ts>(ts)...);
|
||||||
|
@ -414,8 +372,7 @@ template <class T, class U>
|
||||||
const T *poly_view(const poly<U> &p) {
|
const T *poly_view(const poly<U> &p) {
|
||||||
if (p) {
|
if (p) {
|
||||||
return dynamic_cast<const T *>(&*p);
|
return dynamic_cast<const T *>(&*p);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -424,8 +381,7 @@ template <class T, class U>
|
||||||
T *poly_view(poly<U> &p) {
|
T *poly_view(poly<U> &p) {
|
||||||
if (p) {
|
if (p) {
|
||||||
return dynamic_cast<T *>(&*p);
|
return dynamic_cast<T *>(&*p);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define PRESULT_H
|
#define PRESULT_H
|
||||||
|
|
||||||
#include "expected.h"
|
#include "expected.h"
|
||||||
#include "sourceerror.h"
|
#include "source_error.h"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
|
@ -40,11 +40,10 @@ struct PResult : tl::expected<T, SourceError> {
|
||||||
/// if U is convertible to T
|
/// if U is convertible to T
|
||||||
template<typename U, class V = std::enable_if_t<std::is_convertible<std::decay_t<U>, T>::value>>
|
template<typename U, class V = std::enable_if_t<std::is_convertible<std::decay_t<U>, T>::value>>
|
||||||
PResult(PResult<U> presult) :
|
PResult(PResult<U> presult) :
|
||||||
tl::expected<T, SourceError>(presult ? PResult<T>(*presult) : PError(presult.error()))
|
tl::expected<T, SourceError>(presult ? PResult<T>(*presult) : PError(presult.error())) {}
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Alternative to PResult that is returned from parse* functions
|
/// Alternative to PResult that is returned from parseLibrary* functions
|
||||||
/// that only consume one token so they can fail without affecting
|
/// that only consume one token so they can fail without affecting
|
||||||
/// the parser state
|
/// the parser state
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#include "source_error.h"
|
||||||
|
|
||||||
|
|
||||||
|
SourceError::SourceError(Span span, std::string message)
|
||||||
|
: span(span), message(std::move(message)) {}
|
|
@ -1,6 +0,0 @@
|
||||||
#include "sourceerror.h"
|
|
||||||
|
|
||||||
|
|
||||||
SourceError::SourceError(Span span, std::string message)
|
|
||||||
: span(std::move(span)), message(std::move(message))
|
|
||||||
{}
|
|
|
@ -4,32 +4,23 @@
|
||||||
|
|
||||||
|
|
||||||
Position::Position()
|
Position::Position()
|
||||||
: fileId(0), line(0), col(0), offset(0)
|
: fileId(0), line(0), col(0), offset(0) {}
|
||||||
{}
|
|
||||||
|
|
||||||
Position::Position(unsigned file, unsigned line, unsigned col, unsigned offset)
|
Position::Position(unsigned file, unsigned line, unsigned col, unsigned offset)
|
||||||
: fileId(file), line(line), col(col), offset(offset)
|
: fileId(file), line(line), col(col), offset(offset) {}
|
||||||
{}
|
|
||||||
|
|
||||||
Span::Span()
|
Span::Span()
|
||||||
: lo(0, 0, 0, 0), hi(0, 0, 0, 0)
|
: lo(0, 0, 0, 0), hi(0, 0, 0, 0) {}
|
||||||
{}
|
|
||||||
|
|
||||||
Span::Span(Position begin, Position end)
|
Span::Span(Position begin, Position end)
|
||||||
: lo(begin), hi(end)
|
: lo(begin), hi(end) {}
|
||||||
{}
|
|
||||||
|
|
||||||
Span::Span(Position begin)
|
Span::Span(Position begin)
|
||||||
: Span(begin, Position(begin.fileId, begin.line, begin.col+1, begin.offset+1))
|
: Span(begin, Position(begin.fileId, begin.line, begin.col + 1, begin.offset + 1)) {}
|
||||||
{}
|
|
||||||
|
|
||||||
Span Span::to(const Span &span) const
|
Span Span::to(const Span &span) const {
|
||||||
{
|
return {this->lo, span.hi};
|
||||||
return Span(this->lo, span.hi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::Token(TokenType type, Span span, std::string text)
|
Token::Token(TokenType type, Span span, std::string text)
|
||||||
: type(type)
|
: type(type), span(span), text(std::move(text)) {}
|
||||||
, span(std::move(span))
|
|
||||||
, text(std::move(text))
|
|
||||||
{}
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ struct Position {
|
||||||
unsigned offset;
|
unsigned offset;
|
||||||
|
|
||||||
Position();
|
Position();
|
||||||
|
|
||||||
Position(unsigned fileId, unsigned line, unsigned col, unsigned offset);
|
Position(unsigned fileId, unsigned line, unsigned col, unsigned offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,7 +24,9 @@ struct Span {
|
||||||
Position hi;
|
Position hi;
|
||||||
|
|
||||||
Span();
|
Span();
|
||||||
|
|
||||||
Span(Position lo, Position hi);
|
Span(Position lo, Position hi);
|
||||||
|
|
||||||
Span(Position lo);
|
Span(Position lo);
|
||||||
|
|
||||||
Span to(const Span &span) const;
|
Span to(const Span &span) const;
|
||||||
|
|
|
@ -0,0 +1,173 @@
|
||||||
|
#include "tokens_type.h"
|
||||||
|
|
||||||
|
enum TokenClass {
|
||||||
|
KEYWORD_NAME = 4,
|
||||||
|
TOKENIZABLE = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct TokenInfo {
|
||||||
|
std::string text;
|
||||||
|
unsigned short attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct TokenTables {
|
||||||
|
std::unordered_map<TokenType, TokenInfo> allTokensInfo;
|
||||||
|
std::unordered_map<std::string, TokenType> keywords;
|
||||||
|
|
||||||
|
TokenType tokenize(std::string value, TokenType initial);
|
||||||
|
|
||||||
|
bool is_keyword(TokenType token);
|
||||||
|
|
||||||
|
void add(TokenType tokenType, const std::string &txt,
|
||||||
|
unsigned short attribs = 0);
|
||||||
|
|
||||||
|
TokenTables();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static TokenTables tokenTables;
|
||||||
|
|
||||||
|
void TokenTables::add(TokenType tokenType, const std::string &txt,
|
||||||
|
unsigned short attribs) {
|
||||||
|
allTokensInfo[tokenType] = TokenInfo{txt, attribs};
|
||||||
|
if (attribs & KEYWORD_NAME)
|
||||||
|
keywords[txt] = tokenType;
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenTables::TokenTables() {
|
||||||
|
|
||||||
|
add(TokenType::IDENTIFIER, "identifier");
|
||||||
|
add(TokenType::KEYWORD, "keyword", KEYWORD_NAME);
|
||||||
|
|
||||||
|
// Literals (bool is not here, it has two keywords: false and true)
|
||||||
|
add(TokenType::NUMBER, "number");
|
||||||
|
add(TokenType::STRING, "string");
|
||||||
|
add(TokenType::COLOR, "color");
|
||||||
|
|
||||||
|
// Parentheses of all kinds
|
||||||
|
add(TokenType::LPAREN, "(");
|
||||||
|
add(TokenType::RPAREN, ")");
|
||||||
|
add(TokenType::LBRACKET, "[");
|
||||||
|
add(TokenType::RBRACKET, "]");
|
||||||
|
add(TokenType::LBRACE, "{");
|
||||||
|
add(TokenType::RBRACE, "}");
|
||||||
|
add(TokenType::LT, "<");
|
||||||
|
add(TokenType::GT, ">");
|
||||||
|
|
||||||
|
// assignments
|
||||||
|
add(TokenType::EQUALS, "=");
|
||||||
|
|
||||||
|
// miscellaneous
|
||||||
|
add(TokenType::DOT, ".");
|
||||||
|
add(TokenType::COLON, ":");
|
||||||
|
add(TokenType::SEMICOLON, ";");
|
||||||
|
add(TokenType::COMMA, ",");
|
||||||
|
add(TokenType::WHITESPACE, "whitespace");
|
||||||
|
add(TokenType::COMMENT, "comment");
|
||||||
|
|
||||||
|
add(TokenType::TRUE, "true", TOKENIZABLE);
|
||||||
|
add(TokenType::FALSE, "false", TOKENIZABLE);
|
||||||
|
|
||||||
|
add(TokenType::IF, "if", TOKENIZABLE);
|
||||||
|
add(TokenType::ELSE, "else", TOKENIZABLE);
|
||||||
|
|
||||||
|
add(TokenType::DEFAULT, "default", TOKENIZABLE);
|
||||||
|
add(TokenType::NIL, "null", TOKENIZABLE);
|
||||||
|
|
||||||
|
// all keywords
|
||||||
|
add(TokenType::KW_NAME, "@name", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_INFO, "@info", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_HEADER, "@header", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_COMPONENT_HEADER, "@componentHeader", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_DIRECTORY, "@directory", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_LIBRARY, "@library", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_ADDRESS, "@address", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_COMPONENT, "@component", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_MESSAGES, "@messages", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_INSTANCE_NAME, "@instanceName", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_COUNT, "@count", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_DISPLAY, "@display", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_PIN, "@pin", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_TOOLTIP, "@tooltip", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_CONNECTION, "@connection", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_ATTRIBUTE, "@attribute", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_SOURCE, "@source", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_POPUP, "@popup", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_RULE, "@rule", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_TITLE, "@title", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_TEXT, "@text", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_BUS, "@bus", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_WIRES, "@wires", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_ENUMERATED, "@enumerated", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_WIRE, "@wire", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_INSTANCE, "@instance", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_SCHEMA, "@schema", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_POSITION, "@position", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
add(TokenType::KW_SIZE, "@size", TOKENIZABLE | KEYWORD_NAME);
|
||||||
|
|
||||||
|
// All types
|
||||||
|
add(TokenType::INT_TYPE, "int", TOKENIZABLE);
|
||||||
|
add(TokenType::STRING_TYPE, "string", TOKENIZABLE);
|
||||||
|
add(TokenType::BOOL_TYPE, "bool", TOKENIZABLE);
|
||||||
|
add(TokenType::WIRE_TYPE, "wire", TOKENIZABLE);
|
||||||
|
|
||||||
|
// WireNode types
|
||||||
|
add(TokenType::WIRE_DEFAULT, "normal_wire", TOKENIZABLE);
|
||||||
|
add(TokenType::WIRE_AND, "wired_and", TOKENIZABLE);
|
||||||
|
add(TokenType::WIRE_OR, "wired_or", TOKENIZABLE);
|
||||||
|
add(TokenType::R_WIRE, "r_wire", TOKENIZABLE);
|
||||||
|
|
||||||
|
// ComponentNode types
|
||||||
|
add(TokenType::CT_MEMORY, "memory", TOKENIZABLE);
|
||||||
|
add(TokenType::CT_PROCESSOR, "processor", TOKENIZABLE);
|
||||||
|
|
||||||
|
// PinNode type
|
||||||
|
add(TokenType::PIN_IN, "in", TOKENIZABLE);
|
||||||
|
add(TokenType::PIN_OUT, "out", TOKENIZABLE);
|
||||||
|
add(TokenType::PIN_IN_OUT, "inOut", TOKENIZABLE);
|
||||||
|
|
||||||
|
// ActionNode types
|
||||||
|
add(TokenType::ERROR, "error", TOKENIZABLE);
|
||||||
|
add(TokenType::WARNING, "warning", TOKENIZABLE);
|
||||||
|
|
||||||
|
|
||||||
|
// WireNode settings types
|
||||||
|
add(TokenType::HIDDEN, "hidden", TOKENIZABLE);
|
||||||
|
add(TokenType::TERMINATE_WITH, "terminate_with", TOKENIZABLE);
|
||||||
|
|
||||||
|
// Miscelaneous
|
||||||
|
add(TokenType::END_OF_FILE, "eof");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::string &tokenTypeToString(TokenType tokenType) {
|
||||||
|
return tokenTables.allTokensInfo[tokenType].text;
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenType TokenTables::tokenize(std::string value, TokenType initial) {
|
||||||
|
for (auto &[key, param]: allTokensInfo) {
|
||||||
|
if (param.attributes & TOKENIZABLE && param.text == value) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TokenTables::is_keyword(TokenType token) {
|
||||||
|
for (auto &[key, param]: allTokensInfo) {
|
||||||
|
if (param.attributes & KEYWORD_NAME && key == token) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenType from_token(std::string value, TokenType initial) {
|
||||||
|
return tokenTables.tokenize(value, initial);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_keyword(TokenType tokenType) {
|
||||||
|
return tokenTables.is_keyword(tokenType);
|
||||||
|
}
|
|
@ -1,176 +0,0 @@
|
||||||
#include "tokenstype.h"
|
|
||||||
|
|
||||||
enum TokenClass {
|
|
||||||
BUILT_IN_FUNC = 1,
|
|
||||||
DATA_TYPE = 2,
|
|
||||||
KEYWORD_NAME = 4,
|
|
||||||
TOKENIZABLE = 8
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct TokenInfo {
|
|
||||||
std::string text;
|
|
||||||
unsigned short attributes;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct TokenTables {
|
|
||||||
std::unordered_map<TokenType, TokenInfo> allTokensInfo;
|
|
||||||
std::unordered_map<std::string, TokenType> keywords;
|
|
||||||
|
|
||||||
TokenType tokenize(std::string value, TokenType initial);
|
|
||||||
bool is_keyword(TokenType token);
|
|
||||||
|
|
||||||
void add(TokenType tokenType, const std::string& txt,
|
|
||||||
unsigned short attribs = 0);
|
|
||||||
|
|
||||||
TokenTables();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static TokenTables tokenTables;
|
|
||||||
|
|
||||||
void TokenTables::add (TokenType tokenType, const std::string& txt,
|
|
||||||
unsigned short attribs)
|
|
||||||
{
|
|
||||||
allTokensInfo[tokenType] = TokenInfo{txt, attribs};
|
|
||||||
if(attribs & KEYWORD_NAME)
|
|
||||||
keywords[txt] = tokenType;
|
|
||||||
}
|
|
||||||
|
|
||||||
TokenTables::TokenTables() {
|
|
||||||
|
|
||||||
add( TokenType::IDENTIFIER, "identifier" );
|
|
||||||
add( TokenType::KEYWORD, "keyword" , KEYWORD_NAME);
|
|
||||||
|
|
||||||
// Literals (bool is not here, it has two keywords: false and true)
|
|
||||||
add( TokenType::NUMBER, "number");
|
|
||||||
add( TokenType::STRING, "string");
|
|
||||||
add( TokenType::COLOR, "color");
|
|
||||||
|
|
||||||
// Parentheses of all kinds
|
|
||||||
add( TokenType::LPAREN, "(" );
|
|
||||||
add( TokenType::RPAREN, ")" );
|
|
||||||
add( TokenType::LBRACKET, "[" );
|
|
||||||
add( TokenType::RBRACKET, "]" );
|
|
||||||
add( TokenType::LBRACE, "{" );
|
|
||||||
add( TokenType::RBRACE, "}" );
|
|
||||||
add( TokenType::LT, "<" );
|
|
||||||
add( TokenType::GT, ">" );
|
|
||||||
|
|
||||||
// assignments
|
|
||||||
add( TokenType::EQUALS, "=" );
|
|
||||||
|
|
||||||
// miscellaneous
|
|
||||||
add( TokenType::DOT, "." );
|
|
||||||
add( TokenType::COLON, ":" );
|
|
||||||
add( TokenType::SEMICOLON, ";" );
|
|
||||||
add( TokenType::COMMA, "," );
|
|
||||||
add( TokenType::WHITESPACE, "whitespace" );
|
|
||||||
add( TokenType::COMMENT, "comment" );
|
|
||||||
|
|
||||||
add( TokenType::TRUE, "true", TOKENIZABLE ),
|
|
||||||
add( TokenType::FALSE, "false", TOKENIZABLE),
|
|
||||||
|
|
||||||
add( TokenType::IF, "if", TOKENIZABLE ),
|
|
||||||
add( TokenType::ELSE, "else", TOKENIZABLE),
|
|
||||||
|
|
||||||
add( TokenType::DEFAULT, "default", TOKENIZABLE),
|
|
||||||
add( TokenType::NIL, "null", TOKENIZABLE),
|
|
||||||
|
|
||||||
// all keywords
|
|
||||||
add( TokenType::KW_NAME, "@name", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_INFO, "@info", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_HEADER, "@header", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_COMPONENT_HEADER, "@componentHeader", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_DIRECTORY, "@directory", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_LIBRARY, "@library", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_ADDRESS, "@address", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_COMPONENT, "@component", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_MESSAGES, "@messages", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_INSTANCE_NAME, "@instanceName", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_COUNT, "@count", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_DISPLAY, "@display", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_PIN, "@pin", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_TOOLTIP, "@tooltip", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_CONNECTION, "@connection", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_ATTRIBUTE, "@attribute", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_SOURCE, "@source", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_POPUP, "@popup", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_RULE, "@rule", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_TITLE, "@title", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_TEXT, "@text", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_BUS, "@bus", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_WIRES, "@wires", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_ENUMERATED, "@enumerated", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_WIRE, "@wire", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_INSTANCE, "@instance", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_SCHEMA, "@schema", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_POSITION, "@position", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
add( TokenType::KW_SIZE, "@size", TOKENIZABLE | KEYWORD_NAME),
|
|
||||||
|
|
||||||
// All types
|
|
||||||
add( TokenType::INT_TYPE, "int", TOKENIZABLE),
|
|
||||||
add( TokenType::STRING_TYPE, "string", TOKENIZABLE),
|
|
||||||
add( TokenType::BOOL_TYPE, "bool", TOKENIZABLE),
|
|
||||||
add( TokenType::WIRE_TYPE, "wire", TOKENIZABLE),
|
|
||||||
|
|
||||||
// WireNode types
|
|
||||||
add( TokenType::WIRE_DEFAULT, "normal_wire", TOKENIZABLE),
|
|
||||||
add( TokenType::WIRE_AND, "wired_and", TOKENIZABLE),
|
|
||||||
add( TokenType::WIRE_OR, "wired_or", TOKENIZABLE),
|
|
||||||
add( TokenType::R_WIRE, "r_wire", TOKENIZABLE),
|
|
||||||
|
|
||||||
// ComponentNode types
|
|
||||||
add( TokenType::CT_MEMORY, "memory", TOKENIZABLE),
|
|
||||||
add( TokenType::CT_PROCESSOR, "processor", TOKENIZABLE),
|
|
||||||
|
|
||||||
// PinNode type
|
|
||||||
add( TokenType::PIN_IN, "in", TOKENIZABLE),
|
|
||||||
add( TokenType::PIN_OUT, "out", TOKENIZABLE),
|
|
||||||
add( TokenType::PIN_IN_OUT, "inOut", TOKENIZABLE),
|
|
||||||
|
|
||||||
// ActionNode types
|
|
||||||
add( TokenType::ERROR, "error", TOKENIZABLE),
|
|
||||||
add( TokenType::WARNING, "warning", TOKENIZABLE),
|
|
||||||
|
|
||||||
|
|
||||||
// WireNode settings types
|
|
||||||
add( TokenType::HIDDEN, "hidden", TOKENIZABLE),
|
|
||||||
add( TokenType::TERMINATE_WITH, "terminate_with", TOKENIZABLE),
|
|
||||||
|
|
||||||
// Miscelaneous
|
|
||||||
add( TokenType::END_OF_FILE, "eof" );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const std::string &tokenTypeToString(TokenType tokenType) {
|
|
||||||
return tokenTables.allTokensInfo[tokenType].text;
|
|
||||||
}
|
|
||||||
|
|
||||||
TokenType TokenTables::tokenize(std::string value, TokenType initial) {
|
|
||||||
for(auto& [key, param]: allTokensInfo) {
|
|
||||||
if(param.attributes & TOKENIZABLE && param.text == value) {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TokenTables::is_keyword(TokenType token) {
|
|
||||||
for(auto& [key, param]: allTokensInfo) {
|
|
||||||
if(param.attributes & KEYWORD_NAME && key == token) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TokenType from_token(std::string value, TokenType initial) {
|
|
||||||
return tokenTables.tokenize(value, initial);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_keyword(TokenType tokenType) {
|
|
||||||
return tokenTables.is_keyword(tokenType);
|
|
||||||
}
|
|
|
@ -7,10 +7,6 @@
|
||||||
component System
|
component System
|
||||||
{
|
{
|
||||||
clock 100MHz;
|
clock 100MHz;
|
||||||
//directRam
|
|
||||||
wire INT;
|
|
||||||
|
|
||||||
|
|
||||||
//glavnaSabirnica
|
//glavnaSabirnica
|
||||||
wire<32> ADR;
|
wire<32> ADR;
|
||||||
wire<32> DATA;
|
wire<32> DATA;
|
||||||
|
@ -27,27 +23,31 @@ component System
|
||||||
wire --BACK;
|
wire --BACK;
|
||||||
|
|
||||||
|
|
||||||
|
//directRam
|
||||||
|
wire INT;
|
||||||
|
|
||||||
|
|
||||||
// components --------------------------------------------
|
// components --------------------------------------------
|
||||||
subcomponent Memorija memorija<false, 1, 65536, 8, 0>(ADR, DATA, READ, WRITE, SIZE, WAIT, INT);
|
subcomponent Memorija memorija<false, 1, 65536, 8, 0>(ADR, DATA, READ, WRITE, SIZE, WAIT, INT);
|
||||||
subcomponent FRISC procesor(ADR, DATA, READ, WRITE, SIZE, WAIT, INT0, INT1, INT2, INT3, --IACK, 1, *, INT) uses memorija;
|
subcomponent FRISC procesor(ADR, DATA, READ, WRITE, SIZE, WAIT, INT0, INT1, INT2, INT3, --IACK, 1, *, INT) uses memorija;
|
||||||
|
|
||||||
display {
|
display {
|
||||||
component { x: -12; y: 68; ref: "memorija"; }
|
component { x: -582; y: -296; ref: "procesor"; }
|
||||||
component { x: -206; y: -76; ref: "procesor"; }
|
component { x: -446; y: -12; ref: "memorija"; }
|
||||||
|
|
||||||
// directRam bus
|
|
||||||
|
|
||||||
|
|
||||||
// glavnaSabirnica bus
|
// glavnaSabirnica bus
|
||||||
|
|
||||||
rectangle {
|
rectangle {
|
||||||
x: -222; y: 130;
|
x: -581; y: -37;
|
||||||
w: 100; h: 20;
|
w: 100; h: 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
line {x1:-28; y1:96; x2:-90; y2:-26;}
|
// directRam bus
|
||||||
line {x1:38; y1:52; x2:-171; y2:140;}
|
|
||||||
line {x1:-156; y1:40; x2:-171; y2:140;}
|
|
||||||
|
line {x1:-532; y1:-180; x2:-530; y2:-26;}
|
||||||
|
line {x1:-462; y1:16; x2:-466; y2:-246;}
|
||||||
|
line {x1:-396; y1:-28; x2:-530; y2:-26;}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,13 @@
|
||||||
@source "/home/bbr/Documents/Personal/FER/schema_editor/examples/simplified FRISC model/frisc_library.csl"
|
@source "/home/bbr/Documents/Personal/FER/schema_editor/examples/simplified FRISC model/frisc_library.csl"
|
||||||
|
|
||||||
@schema {
|
@schema {
|
||||||
|
@instance procesor FRISC {
|
||||||
|
@position (-76, -97)
|
||||||
|
@attribute _memory memorija
|
||||||
|
}
|
||||||
|
|
||||||
@instance memorija Memorija {
|
@instance memorija Memorija {
|
||||||
@position (-12, 68)
|
@position (52, 119)
|
||||||
@attribute sinkroniziran false
|
@attribute sinkroniziran false
|
||||||
@attribute brzina 1
|
@attribute brzina 1
|
||||||
@attribute kapacitet 65536
|
@attribute kapacitet 65536
|
||||||
|
@ -10,9 +15,9 @@
|
||||||
@attribute pocetnaAdresa 0
|
@attribute pocetnaAdresa 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@instance procesor FRISC {
|
@instance glavnaSabirnica glavnaSabirnica {
|
||||||
@position (-206, -76)
|
@position (-78, 88)
|
||||||
@attribute _memory memorija
|
@size 100
|
||||||
}
|
}
|
||||||
|
|
||||||
@instance directRam directRam {
|
@instance directRam directRam {
|
||||||
|
@ -20,15 +25,10 @@
|
||||||
@size 0
|
@size 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@instance glavnaSabirnica glavnaSabirnica {
|
|
||||||
@position (-222, 130)
|
|
||||||
@size 50
|
|
||||||
}
|
|
||||||
|
|
||||||
@connection (memorija.memDirect, directRam, procesor.memDirect) {
|
|
||||||
}
|
|
||||||
@connection (memorija.glavniPin, glavnaSabirnica) {
|
@connection (memorija.glavniPin, glavnaSabirnica) {
|
||||||
}
|
}
|
||||||
@connection (procesor.glavniPin, glavnaSabirnica) {
|
@connection (procesor.glavniPin, glavnaSabirnica) {
|
||||||
}
|
}
|
||||||
|
@connection (memorija.memDirect, directRam, procesor.memDirect) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
#include <comdel/parser/parsecontext.h>
|
#include <comdel/parser/parse_context.h>
|
||||||
#include <comdel/parser/parserutil.h>
|
#include <comdel/parser/parser_util.h>
|
||||||
#include <comdel/domain/schemacreator.h>
|
#include <comdel/domain/schema_creator.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
#include <comdel/domain/comdelvalidator.h>
|
#include <comdel/domain/comdel_validator.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <comdel/domain/comdel_generator.h>
|
#include <comdel/domain/comdel_generator.h>
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ void MainWindow::onLoadLibrary() {
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
ParseContext parseContext;
|
ParseContext parseContext;
|
||||||
auto libraryNode = loadLibraryFromFile(&parseContext, filename.toStdString().c_str(), buffer);
|
auto libraryNode = load_library_from_file(&parseContext, filename.toStdString().c_str(), buffer);
|
||||||
if(libraryNode) {
|
if(libraryNode) {
|
||||||
domain::SchemaCreator generator(validators);
|
domain::SchemaCreator generator(validators);
|
||||||
library = generator.loadLibrary(*libraryNode);
|
library = generator.loadLibrary(*libraryNode);
|
||||||
|
@ -119,13 +119,13 @@ void MainWindow::onLoadSchema() {
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
ParseContext parseContext;
|
ParseContext parseContext;
|
||||||
auto schemaNode = loadSchemaFromFile(&parseContext, filename.toStdString().c_str(), buffer);
|
auto schemaNode = load_schema_from_file(&parseContext, filename.toStdString().c_str(), buffer);
|
||||||
|
|
||||||
if(schemaNode) {
|
if(schemaNode) {
|
||||||
domain::SchemaCreator generator(validators);
|
domain::SchemaCreator generator(validators);
|
||||||
library = generator.loadLibrary(*schemaNode->library);
|
library = generator.loadLibrary(*schemaNode->library);
|
||||||
|
|
||||||
librarySource = schemaNode->source->value;
|
librarySource = schemaNode->source->asString();
|
||||||
|
|
||||||
for (auto& error : generator.getErrors()) {
|
for (auto& error : generator.getErrors()) {
|
||||||
parseContext.formatError(error, buffer, "ERROR: ");
|
parseContext.formatError(error, buffer, "ERROR: ");
|
||||||
|
@ -163,7 +163,7 @@ void MainWindow::onStoreScheme() {
|
||||||
|
|
||||||
std::ostringstream buffer;
|
std::ostringstream buffer;
|
||||||
|
|
||||||
domain::generateSchemaFile(librarySource, schema, buffer);
|
domain::generate_schema(librarySource, schema, buffer);
|
||||||
|
|
||||||
std::ofstream out(filename.toStdString(), std::ios::out | std::ios::binary);
|
std::ofstream out(filename.toStdString(), std::ios::out | std::ios::binary);
|
||||||
out<<buffer.str();
|
out<<buffer.str();
|
||||||
|
@ -180,7 +180,7 @@ void MainWindow::onGenerateComdel() {
|
||||||
|
|
||||||
std::ostringstream buffer;
|
std::ostringstream buffer;
|
||||||
|
|
||||||
domain::generateComdelFile(schema, library.value(), buffer);
|
domain::generate_comdel(schema, library.value(), buffer);
|
||||||
|
|
||||||
std::ofstream out(filename.toStdString(), std::ios::out | std::ios::binary);
|
std::ofstream out(filename.toStdString(), std::ios::out | std::ios::binary);
|
||||||
out<<buffer.str();
|
out<<buffer.str();
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include <comdel/domain/library.h>
|
#include <comdel/domain/library.h>
|
||||||
#include <comdel/domain/schema.h>
|
#include <comdel/domain/schema.h>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
#include <comdel/domain/comdelvalidator.h>
|
#include <comdel/domain/comdel_validator.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
namespace Ui { class MainWindow; }
|
namespace Ui { class MainWindow; }
|
||||||
|
|
Loading…
Reference in New Issue