Updated support for single automatic bus
This commit is contained in:
parent
9ff6633777
commit
fb8aafb2a9
|
@ -1,6 +1,7 @@
|
||||||
#ifndef DOMAIN_ATTRIBUTE_H
|
#ifndef DOMAIN_ATTRIBUTE_H
|
||||||
#define DOMAIN_ATTRIBUTE_H
|
#define DOMAIN_ATTRIBUTE_H
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "rule.h"
|
#include "rule.h"
|
||||||
|
@ -45,6 +46,11 @@ public:
|
||||||
bool isEnumerated();
|
bool isEnumerated();
|
||||||
std::vector<Enumeration> &getEnumeration();
|
std::vector<Enumeration> &getEnumeration();
|
||||||
|
|
||||||
|
void setEnumeration(std::vector<Enumeration> enums) {
|
||||||
|
enumerated = true;
|
||||||
|
enumeration = std::move(enums);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Attribute
|
class Attribute
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
enum BusType {
|
enum BusType {
|
||||||
AUTOMATIC,
|
AUTOMATIC,
|
||||||
REGULAR,
|
REGULAR,
|
||||||
AUTOMATIC_SINGLE
|
SINGLE_AUTOMATIC
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
|
@ -14,8 +14,8 @@ class PinConnection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum ConnectionType {
|
enum ConnectionType {
|
||||||
CHECK_ONLY,
|
REQUIRED,
|
||||||
AUTOMATICALLY
|
OPTIONAL
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -69,6 +69,8 @@ Value toType(ValueNode node) {
|
||||||
Bus::BusType toType(BusNode::BusType type) {
|
Bus::BusType toType(BusNode::BusType type) {
|
||||||
if(type == BusNode::AUTOMATIC) {
|
if(type == BusNode::AUTOMATIC) {
|
||||||
return Bus::AUTOMATIC;
|
return Bus::AUTOMATIC;
|
||||||
|
} else if(type == BusNode::SINGLE_AUTOMATIC) {
|
||||||
|
return Bus::SINGLE_AUTOMATIC;
|
||||||
}
|
}
|
||||||
return Bus::REGULAR;
|
return Bus::REGULAR;
|
||||||
}
|
}
|
||||||
|
@ -85,10 +87,10 @@ Pin::PinType toType(PinNode::PinType type) {
|
||||||
|
|
||||||
PinConnection::ConnectionType toType(PinConnectionNode::ConnectionType type)
|
PinConnection::ConnectionType toType(PinConnectionNode::ConnectionType type)
|
||||||
{
|
{
|
||||||
if(type == PinConnectionNode::AUTOMATICALLY) {
|
if(type == PinConnectionNode::OPTIONAL) {
|
||||||
return PinConnection::AUTOMATICALLY;
|
return PinConnection::OPTIONAL;
|
||||||
}
|
}
|
||||||
return PinConnection::CHECK_ONLY;
|
return PinConnection::REQUIRED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -187,7 +189,7 @@ std::optional<Bus> SchemaCreator::loadBus(BusNode node)
|
||||||
errors.emplace_back(node.span, "missing @display");
|
errors.emplace_back(node.span, "missing @display");
|
||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
if(node.display && (type == Bus::AUTOMATIC || type == Bus::AUTOMATIC_SINGLE)) {
|
if(node.display && (type == Bus::AUTOMATIC || type == Bus::SINGLE_AUTOMATIC)) {
|
||||||
errors.emplace_back(node.span, "automatic bus cannot have a @display");
|
errors.emplace_back(node.span, "automatic bus cannot have a @display");
|
||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
|
@ -212,6 +214,11 @@ std::optional<Bus> SchemaCreator::loadBus(BusNode node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(type == Bus::SINGLE_AUTOMATIC && wires.size() != 1) {
|
||||||
|
errors.emplace_back(node.span, "singleAutomatic bus must have exactly 1 wire defined");
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
return Bus(name, tooltip, type, count, wires, display);
|
return Bus(name, tooltip, type, count, wires, display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +230,7 @@ std::optional<AddressSpace> SchemaCreator::loadAddressSpace(AddressSpaceNode nod
|
||||||
|
|
||||||
std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
|
std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
|
||||||
{
|
{
|
||||||
push(ComdelContext("connection", false, true, false));
|
push(ComdelContext("connection", false, true, false, false));
|
||||||
|
|
||||||
std::string bus = node.bus.value;
|
std::string bus = node.bus.value;
|
||||||
auto busInstance = getBus(bus);
|
auto busInstance = getBus(bus);
|
||||||
|
@ -231,6 +238,10 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
|
||||||
errors.emplace_back(node.span, "bus does not exist");
|
errors.emplace_back(node.span, "bus does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(busInstance->getType() == Bus::SINGLE_AUTOMATIC) {
|
||||||
|
current().inSingleAutomaticConnection = true;
|
||||||
|
}
|
||||||
|
|
||||||
if(busInstance->getType() == Bus::REGULAR) {
|
if(busInstance->getType() == Bus::REGULAR) {
|
||||||
ConnectionComponent first{node.first.component.value, node.first.pin.value};
|
ConnectionComponent first{node.first.component.value, node.first.pin.value};
|
||||||
|
|
||||||
|
@ -285,7 +296,7 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
|
||||||
pop();
|
pop();
|
||||||
|
|
||||||
return Connection(first, nullopt, bus, attributes, wires, nullopt);
|
return Connection(first, nullopt, bus, attributes, wires, nullopt);
|
||||||
} else if(busInstance->getType() == Bus::AUTOMATIC || busInstance->getType() == Bus::AUTOMATIC_SINGLE) {
|
} else if(busInstance->getType() == Bus::AUTOMATIC || busInstance->getType() == Bus::SINGLE_AUTOMATIC) {
|
||||||
ConnectionComponent first{node.first.component.value, node.first.pin.value};
|
ConnectionComponent first{node.first.component.value, node.first.pin.value};
|
||||||
|
|
||||||
if(!node.second.has_value()) {
|
if(!node.second.has_value()) {
|
||||||
|
@ -310,6 +321,10 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
|
||||||
current().wires.push_back(wire.getName());
|
current().wires.push_back(wire.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(node.attributes.size() != 2 && busInstance->getType() == Bus::SINGLE_AUTOMATIC) {
|
||||||
|
errors.emplace_back(node.span, "singleAutomatic must contain 2 attributes");
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Attribute> attributes;
|
std::vector<Attribute> attributes;
|
||||||
for(auto & attribute : node.attributes) {
|
for(auto & attribute : node.attributes) {
|
||||||
auto attr = loadAttribute(attribute);
|
auto attr = loadAttribute(attribute);
|
||||||
|
@ -330,7 +345,9 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
|
||||||
firstWires.push_back(Value::fromNull());
|
firstWires.push_back(Value::fromNull());
|
||||||
} else if(firstWire.is(ValueNode::INT)) {
|
} else if(firstWire.is(ValueNode::INT)) {
|
||||||
firstWires.push_back(Value::fromInt(firstWire.asInt()));
|
firstWires.push_back(Value::fromInt(firstWire.asInt()));
|
||||||
} else if(firstWire.is(ValueNode::IDENTIFIER)) {
|
} else if(firstWire.is(ValueNode::STRING) && busInstance->getType() == Bus::SINGLE_AUTOMATIC) {
|
||||||
|
firstWires.push_back(Value::fromString(firstWire.asString()));
|
||||||
|
} else if(firstWire.is(ValueNode::IDENTIFIER) && busInstance->getType() == Bus::AUTOMATIC) {
|
||||||
if(attributeNames.count(firstWire.asIdentifier())) {
|
if(attributeNames.count(firstWire.asIdentifier())) {
|
||||||
firstWires.push_back(Value::fromReference(firstWire.asIdentifier(), Value::ATTRIBUTE_REFERENCE));
|
firstWires.push_back(Value::fromReference(firstWire.asIdentifier(), Value::ATTRIBUTE_REFERENCE));
|
||||||
} else if(wireNames.count(firstWire.asIdentifier())) {
|
} else if(wireNames.count(firstWire.asIdentifier())) {
|
||||||
|
@ -339,7 +356,7 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
|
||||||
errors.emplace_back(firstWire.span, "unknown identifier");
|
errors.emplace_back(firstWire.span, "unknown identifier");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
errors.emplace_back(firstWire.span, "unknown value type");
|
errors.emplace_back(firstWire.span, "unsupported value type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,7 +367,9 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
|
||||||
secondWires.push_back(Value::fromNull());
|
secondWires.push_back(Value::fromNull());
|
||||||
} else if(secondWire.is(ValueNode::INT)) {
|
} else if(secondWire.is(ValueNode::INT)) {
|
||||||
secondWires.push_back(Value::fromInt(secondWire.asInt()));
|
secondWires.push_back(Value::fromInt(secondWire.asInt()));
|
||||||
} else if(secondWire.is(ValueNode::IDENTIFIER)) {
|
} else if(secondWire.is(ValueNode::STRING) && busInstance->getType() == Bus::SINGLE_AUTOMATIC) {
|
||||||
|
secondWires.push_back(Value::fromString(secondWire.asString()));
|
||||||
|
} else if(secondWire.is(ValueNode::IDENTIFIER) && busInstance->getType() == Bus::AUTOMATIC) {
|
||||||
if(attributeNames.count(secondWire.asIdentifier())) {
|
if(attributeNames.count(secondWire.asIdentifier())) {
|
||||||
secondWires.push_back(Value::fromReference(secondWire.asIdentifier(), Value::ATTRIBUTE_REFERENCE));
|
secondWires.push_back(Value::fromReference(secondWire.asIdentifier(), Value::ATTRIBUTE_REFERENCE));
|
||||||
} else if(wireNames.count(secondWire.asIdentifier())) {
|
} else if(wireNames.count(secondWire.asIdentifier())) {
|
||||||
|
@ -359,7 +378,25 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
|
||||||
errors.emplace_back(secondWire.span, "unknown identifier");
|
errors.emplace_back(secondWire.span, "unknown identifier");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
errors.emplace_back(secondWire.span, "unknown value type");
|
errors.emplace_back(secondWire.span, "unsupported value type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(busInstance->getType() == Bus::SINGLE_AUTOMATIC && attributes.size() == 2) {
|
||||||
|
if(!attributes[0].getPopup().has_value()) {
|
||||||
|
errors.emplace_back(node.attributes[0].span, "@popup is required");
|
||||||
|
} else if(attributes[0].getDefault().getType() != Value::STRING) {
|
||||||
|
errors.emplace_back(node.attributes[0].span, "@attribute must be of type string");
|
||||||
|
} else {
|
||||||
|
attributes[0].getPopup()->setEnumeration(createWireEnumeration(firstWires));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!attributes[1].getPopup().has_value()) {
|
||||||
|
errors.emplace_back(node.attributes[1].span, "@popup is required");
|
||||||
|
} else if(attributes[1].getDefault().getType() != Value::STRING) {
|
||||||
|
errors.emplace_back(node.attributes[1].span, "@attribute must be of type string");
|
||||||
|
} else {
|
||||||
|
attributes[1].getPopup()->setEnumeration(createWireEnumeration(secondWires));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,7 +412,7 @@ std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node)
|
||||||
|
|
||||||
std::optional<Component> SchemaCreator::loadComponent(ComponentNode node)
|
std::optional<Component> SchemaCreator::loadComponent(ComponentNode node)
|
||||||
{
|
{
|
||||||
push(ComdelContext(node.name.value, true, false, false));
|
push(ComdelContext(node.name.value, true, false, false, false));
|
||||||
|
|
||||||
std::string name = node.name.value;
|
std::string name = node.name.value;
|
||||||
|
|
||||||
|
@ -581,7 +618,7 @@ std::optional<Attribute> SchemaCreator::loadAttribute(AttributeNode node)
|
||||||
errors.emplace_back(node.name.span, "unsupported type");
|
errors.emplace_back(node.name.span, "unsupported type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(current().inConnection) { // TODO remove identifier
|
if(current().inConnection && !current().inSingleAutomaticConnection) { // TODO remove identifier
|
||||||
if (node.type == ValueNode::WIRE || node.type == ValueNode::IDENTIFIER) {
|
if (node.type == ValueNode::WIRE || node.type == ValueNode::IDENTIFIER) {
|
||||||
if(current().doesWireExists(node.defaultValue->asIdentifier())) {
|
if(current().doesWireExists(node.defaultValue->asIdentifier())) {
|
||||||
value = Value::fromReference(node.defaultValue->asIdentifier(), Value::WIRE_REFERENCE);
|
value = Value::fromReference(node.defaultValue->asIdentifier(), Value::WIRE_REFERENCE);
|
||||||
|
@ -593,6 +630,13 @@ std::optional<Attribute> SchemaCreator::loadAttribute(AttributeNode node)
|
||||||
errors.emplace_back(node.name.span, "unsupported type");
|
errors.emplace_back(node.name.span, "unsupported type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(current().inSingleAutomaticConnection) {
|
||||||
|
if (node.type == ValueNode::STRING) {
|
||||||
|
value = Value::fromString(node.defaultValue->asString());
|
||||||
|
} else {
|
||||||
|
errors.emplace_back(node.name.span, "unsupported type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
current().attributes.emplace_back(name, value);
|
current().attributes.emplace_back(name, value);
|
||||||
|
|
||||||
|
@ -864,4 +908,14 @@ std::shared_ptr<BusInstance> SchemaCreator::loadBusInstance(InstanceNode instanc
|
||||||
return std::make_shared<BusInstance>(name, position, bus, static_cast<int>(size));
|
return std::make_shared<BusInstance>(name, position, bus, static_cast<int>(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<Enumeration> SchemaCreator::createWireEnumeration(vector<Value> wireValues) {
|
||||||
|
vector<Enumeration> wires;
|
||||||
|
for(auto& wire: wireValues) {
|
||||||
|
if(wire.isType(Value::STRING)) {
|
||||||
|
wires.emplace_back(wire.asString(), wire);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wires;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -18,10 +18,11 @@ struct ComdelContext {
|
||||||
std::string name;
|
std::string name;
|
||||||
bool inComponent;
|
bool inComponent;
|
||||||
bool inConnection;
|
bool inConnection;
|
||||||
|
bool inSingleAutomaticConnection;
|
||||||
bool inBus;
|
bool inBus;
|
||||||
|
|
||||||
ComdelContext(std::string name, bool inComponent, bool inConnection, bool inBus)
|
ComdelContext(std::string name, bool inComponent, bool inConnection, bool inSingleAutomaticConnection, bool inBus)
|
||||||
: name(name), inComponent(inComponent), inConnection(inConnection), inBus(inBus)
|
: name(name), inComponent(inComponent), inConnection(inConnection), inSingleAutomaticConnection(inSingleAutomaticConnection), inBus(inBus)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool doesAttributeExists(std::string name, Value::ValueType type) {
|
bool doesAttributeExists(std::string name, Value::ValueType type) {
|
||||||
|
@ -117,7 +118,7 @@ class SchemaCreator
|
||||||
this->context.push_back(current());
|
this->context.push_back(current());
|
||||||
current().name = name;
|
current().name = name;
|
||||||
} else {
|
} else {
|
||||||
ComdelContext con(name, false, false, false);
|
ComdelContext con(name, false, false, false, false);
|
||||||
push(con);
|
push(con);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,6 +139,8 @@ public:
|
||||||
std::optional<Library> loadLibrary(LibraryNode node);
|
std::optional<Library> loadLibrary(LibraryNode node);
|
||||||
|
|
||||||
Schema* loadSchema(SchemaNode node, Library &library);
|
Schema* loadSchema(SchemaNode node, Library &library);
|
||||||
|
|
||||||
|
vector <Enumeration> createWireEnumeration(vector <Value> vector1);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -181,8 +181,8 @@ struct DisplayNode: public AstNode
|
||||||
struct PinConnectionNode: public AstNode
|
struct PinConnectionNode: public AstNode
|
||||||
{
|
{
|
||||||
enum ConnectionType {
|
enum ConnectionType {
|
||||||
CHECK_ONLY,
|
REQUIRED,
|
||||||
AUTOMATICALLY
|
OPTIONAL
|
||||||
};
|
};
|
||||||
|
|
||||||
StringNode message;
|
StringNode message;
|
||||||
|
@ -273,7 +273,8 @@ struct BusNode: public AstNode
|
||||||
{
|
{
|
||||||
enum BusType {
|
enum BusType {
|
||||||
AUTOMATIC,
|
AUTOMATIC,
|
||||||
REGULAR
|
REGULAR,
|
||||||
|
SINGLE_AUTOMATIC
|
||||||
};
|
};
|
||||||
|
|
||||||
EnumNode<BusType> type;
|
EnumNode<BusType> type;
|
||||||
|
|
|
@ -465,6 +465,7 @@ PResult<ComponentNode> ComdelParser::parseComponent()
|
||||||
APPEND_OR_SET_ERR(component.rules, parseRule());
|
APPEND_OR_SET_ERR(component.rules, parseRule());
|
||||||
} else {
|
} else {
|
||||||
err = unexpected();
|
err = unexpected();
|
||||||
|
bump();
|
||||||
}
|
}
|
||||||
if(!err.has_value()) {
|
if(!err.has_value()) {
|
||||||
errors.push_back(err.error());
|
errors.push_back(err.error());
|
||||||
|
@ -583,6 +584,7 @@ PResult<BusNode> ComdelParser::parseBus() {
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::RBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::RBRACE);
|
||||||
} else {
|
} else {
|
||||||
err = unexpected();
|
err = unexpected();
|
||||||
|
bump();
|
||||||
}
|
}
|
||||||
if(!err.has_value()) {
|
if(!err.has_value()) {
|
||||||
errors.push_back(err.error());
|
errors.push_back(err.error());
|
||||||
|
@ -607,11 +609,13 @@ PResult<EnumNode<BusNode::BusType>> ComdelParser::parseBusType() {
|
||||||
type = EnumNode(BusNode::AUTOMATIC);
|
type = EnumNode(BusNode::AUTOMATIC);
|
||||||
} else if(tokenType.value().value == "regular") {
|
} else if(tokenType.value().value == "regular") {
|
||||||
type = EnumNode(BusNode::REGULAR);
|
type = EnumNode(BusNode::REGULAR);
|
||||||
|
} else if(tokenType.value().value == "singleAutomatic") {
|
||||||
|
type = EnumNode(BusNode::SINGLE_AUTOMATIC);
|
||||||
} else {
|
} else {
|
||||||
type = PError(SourceError{current().span, "expected 'automatic' or 'regular'"});
|
type = PError(SourceError{current().span, "expected 'automatic', 'singleAutomatic' or 'regular'"});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
type = PError(SourceError{current().span, "expected 'automatic' or 'regular'"});
|
type = PError(SourceError{current().span, "expected 'automatic', 'singleAutomatic' or 'regular'"});
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
@ -728,6 +732,7 @@ PResult<PinNode> ComdelParser::parsePin() {
|
||||||
pin.wires = *wires;
|
pin.wires = *wires;
|
||||||
} else {
|
} else {
|
||||||
err = unexpected();
|
err = unexpected();
|
||||||
|
bump();
|
||||||
}
|
}
|
||||||
if(!err.has_value()) {
|
if(!err.has_value()) {
|
||||||
errors.push_back(err.error());
|
errors.push_back(err.error());
|
||||||
|
@ -771,15 +776,15 @@ PResult<EnumNode<PinConnectionNode::ConnectionType>> ComdelParser::parseConnecti
|
||||||
|
|
||||||
if(check(TokenType::IDENTIFIER)) {
|
if(check(TokenType::IDENTIFIER)) {
|
||||||
auto identifier = parseIdentifier();
|
auto identifier = parseIdentifier();
|
||||||
if(identifier.value().value == "check_only") {
|
if(identifier.value().value == "required") {
|
||||||
type = EnumNode(PinConnectionNode::CHECK_ONLY);
|
type = EnumNode(PinConnectionNode::REQUIRED);
|
||||||
} else if(identifier.value().value == "automatically") {
|
} else if(identifier.value().value == "optional") {
|
||||||
type = EnumNode(PinConnectionNode::AUTOMATICALLY);
|
type = EnumNode(PinConnectionNode::OPTIONAL);
|
||||||
} else {
|
} else {
|
||||||
return PError(SourceError{current().span, "expected identifiers 'check_only' or 'automatically'"});
|
return PError(SourceError{current().span, "expected connection type 'required' or 'optional'"});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return PError(SourceError{current().span, "expected identifiers 'check_only' or 'automatically'"});
|
return PError(SourceError{current().span, "expected connection type 'required' or 'optional'"});
|
||||||
}
|
}
|
||||||
|
|
||||||
return spanner(type);
|
return spanner(type);
|
||||||
|
@ -948,6 +953,7 @@ PResult<PopupNode> ComdelParser::parsePopup() {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
err = unexpected();
|
err = unexpected();
|
||||||
|
bump();
|
||||||
}
|
}
|
||||||
if(!err.has_value()) {
|
if(!err.has_value()) {
|
||||||
errors.push_back(err.error());
|
errors.push_back(err.error());
|
||||||
|
@ -965,7 +971,7 @@ PResult<PopupNode> ComdelParser::parsePopup() {
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
* ConnectionNode := "@connection (" + COMPONENT + "." + PIN + "," + BUS) {" + CONNECTION + "}"
|
* ConnectionNode := "@connection (" + COMPONENT + "." + PIN + "," + BUS [ + "," + COMPONENT2 + "." + "PIN2"] + ") {" + CONNECTION + "}"
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
PResult<ConnectionNode> ComdelParser::parseConnection() {
|
PResult<ConnectionNode> ComdelParser::parseConnection() {
|
||||||
|
@ -984,7 +990,6 @@ PResult<ConnectionNode> ComdelParser::parseConnection() {
|
||||||
if(check(TokenType::COMMA)) {
|
if(check(TokenType::COMMA)) {
|
||||||
auto conn = ConnectionComponentNode{};
|
auto conn = ConnectionComponentNode{};
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::COMMA);
|
RETURN_IF_NOT_TOKEN(TokenType::COMMA);
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(conn.component, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(conn.component, parseIdentifier());
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::DOT);
|
RETURN_IF_NOT_TOKEN(TokenType::DOT);
|
||||||
ASSIGN_OR_RETURN_IF_ERR(conn.pin, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(conn.pin, parseIdentifier());
|
||||||
|
@ -1016,6 +1021,7 @@ PResult<ConnectionNode> ComdelParser::parseConnection() {
|
||||||
wireCount++;
|
wireCount++;
|
||||||
} else {
|
} else {
|
||||||
err = unexpected();
|
err = unexpected();
|
||||||
|
bump();
|
||||||
}
|
}
|
||||||
if(!err.has_value()) {
|
if(!err.has_value()) {
|
||||||
errors.push_back(err.error());
|
errors.push_back(err.error());
|
||||||
|
@ -1251,6 +1257,7 @@ PResult<InstanceNode> ComdelParser::parseInstance() {
|
||||||
instance.size = *number;
|
instance.size = *number;
|
||||||
} else {
|
} else {
|
||||||
err = unexpected();
|
err = unexpected();
|
||||||
|
bump();
|
||||||
}
|
}
|
||||||
if(!err.has_value()) {
|
if(!err.has_value()) {
|
||||||
errors.push_back(err.error());
|
errors.push_back(err.error());
|
||||||
|
@ -1324,13 +1331,16 @@ PResult<ConnectionInstanceNode> ComdelParser::parseConnectionInstance() {
|
||||||
}
|
}
|
||||||
|
|
||||||
PResult<ValueNode> ComdelParser::parseConnectionWire() {
|
PResult<ValueNode> ComdelParser::parseConnectionWire() {
|
||||||
|
auto spanner = getSpanner();
|
||||||
if(check(TokenType::NUMBER)) {
|
if(check(TokenType::NUMBER)) {
|
||||||
return ValueNode::ofInt(parseNumber()->value);
|
return spanner(ValueNode::ofInt(parseNumber()->value));
|
||||||
} else if(check(TokenType::NIL)) {
|
} else if(check(TokenType::NIL)) {
|
||||||
bump();
|
bump();
|
||||||
return ValueNode::ofNull();
|
return spanner(ValueNode::ofNull());
|
||||||
|
} else if(check(TokenType::STRING)) {
|
||||||
|
return spanner(ValueNode::ofString(parseString()->value));
|
||||||
} else if(check(TokenType::IDENTIFIER)) {
|
} else if(check(TokenType::IDENTIFIER)) {
|
||||||
return ValueNode::ofIdentifier(parseIdentifier()->value);
|
return spanner(ValueNode::ofIdentifier(parseIdentifier()->value));
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
return unexpected();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
@component FRISC processor {
|
@component FRISC processor {
|
||||||
@instanceName "procesor"
|
@instanceName "procesor"
|
||||||
@tooltip "procesor FRISC, mora postojati jedan"
|
@tooltip "Procesor FRISC, mora postojati jedan"
|
||||||
@count (1, 1)
|
@count (1, 1)
|
||||||
@source "FRISC.cdl"
|
@source "FRISC.cdl"
|
||||||
@display {
|
@display {
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
}
|
}
|
||||||
@pin glavniPin inOut {
|
@pin glavniPin inOut {
|
||||||
@tooltip "pin za spajanje na glavnu sabirnicu"
|
@tooltip "pin za spajanje na glavnu sabirnicu"
|
||||||
@connection check_only("COMDEL se ne može stvoriti. FRISC nije spojen na sabirnicu")
|
@connection required("COMDEL se ne može stvoriti. FRISC nije spojen na sabirnicu")
|
||||||
@display {
|
@display {
|
||||||
/*
|
/*
|
||||||
pin {
|
pin {
|
||||||
|
@ -146,7 +146,7 @@
|
||||||
|
|
||||||
@pin glavniPin inOut {
|
@pin glavniPin inOut {
|
||||||
@tooltip "pin za spajanje na glavnu sabirnicu"
|
@tooltip "pin za spajanje na glavnu sabirnicu"
|
||||||
@connection check_only("COMDEL se ne može stvoriti. Memorija nije spojena na sabirnicu")
|
@connection required("COMDEL se ne može stvoriti. Memorija nije spojena na sabirnicu")
|
||||||
@display {
|
@display {
|
||||||
/*
|
/*
|
||||||
pin {
|
pin {
|
||||||
|
@ -214,7 +214,7 @@
|
||||||
|
|
||||||
@pin glavniPin in {
|
@pin glavniPin in {
|
||||||
@tooltip "pin za spajanje na glavnu sabirnicu"
|
@tooltip "pin za spajanje na glavnu sabirnicu"
|
||||||
@connection check_only("COMDEL se ne može stvoriti. DMA nije spojena na sabirnicu")
|
@connection required("COMDEL se ne može stvoriti. DMA nije spojena na sabirnicu")
|
||||||
@display {
|
@display {
|
||||||
/*
|
/*
|
||||||
pin {
|
pin {
|
||||||
|
@ -235,7 +235,7 @@
|
||||||
|
|
||||||
@pin dodatnaPoveznica in {
|
@pin dodatnaPoveznica in {
|
||||||
@tooltip "pin za spajanje na pomocnu sabirnicu"
|
@tooltip "pin za spajanje na pomocnu sabirnicu"
|
||||||
@connection check_only("COMDEL se ne može stvoriti. DMA nije spojen na nesto!")
|
@connection optional("COMDEL se ne može stvoriti. DMA nije spojen na nesto!")
|
||||||
@display {
|
@display {
|
||||||
pin {
|
pin {
|
||||||
x: 0; y: 0; w: 0; h: 0;
|
x: 0; y: 0; w: 0; h: 0;
|
||||||
|
@ -285,6 +285,14 @@
|
||||||
STROBE
|
STROBE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@bus Test singleAutomatic {
|
||||||
|
@tooltip "sabirnica za spajanje FRISC a s memorijama i UI/jedinicama"
|
||||||
|
@count (1,1)
|
||||||
|
|
||||||
|
@wires {
|
||||||
|
CONNECTOR,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@connection (FRISC.glavniPin, glavnaSabirnica) {
|
@connection (FRISC.glavniPin, glavnaSabirnica) {
|
||||||
@wires{ADR, DATA, READ, WRITE, SIZE, WAIT, INT0, INT1, INT2, INT3, IACK, 1, null}
|
@wires{ADR, DATA, READ, WRITE, SIZE, WAIT, INT0, INT1, INT2, INT3, IACK, 1, null}
|
||||||
|
@ -307,4 +315,28 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@wires{ADR, DATA, READ, WRITE, SIZE, WAIT, interupt, BREQ, BACK}
|
@wires{ADR, DATA, READ, WRITE, SIZE, WAIT, interupt, BREQ, BACK}
|
||||||
|
}
|
||||||
|
|
||||||
|
@connection (DMA.glavniPin, PIOSabirnica, FRISC.glavniPin) {
|
||||||
|
@wires{PIO_DATA, READY, STROBE}
|
||||||
|
@wires{PIO_DATA, READY, STROBE}
|
||||||
|
}
|
||||||
|
|
||||||
|
@connection (FRISC.glavniPin, Test, Memorija.glavniPin) {
|
||||||
|
@wires{null, "READY", null}
|
||||||
|
@wires{"PIO_DATA", null, null}
|
||||||
|
|
||||||
|
@attribute dmaPoveznica string default "" {
|
||||||
|
@popup automatic {
|
||||||
|
@title "Spoji DMA kraj"
|
||||||
|
@text "Odaberite poveznicu za dma kraja"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@attribute mmaPoveznica string default "" {
|
||||||
|
@popup automatic {
|
||||||
|
@title "Spoji MMA kraj"
|
||||||
|
@text "Odaberite poveznicu za mma kraja"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -17,7 +17,14 @@
|
||||||
@size 100
|
@size 100
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@instance testBus Test {}
|
||||||
|
|
||||||
@connection (proc.glavniPin, bus) {}
|
@connection (proc.glavniPin, bus) {}
|
||||||
|
|
||||||
@connection (mem.glavniPin, bus) {}
|
@connection (mem.glavniPin, bus) {}
|
||||||
|
|
||||||
|
@connection (proc.glavniPin, testBus, mem.glavniPin) {
|
||||||
|
@attribute dmaPoveznica "READY"
|
||||||
|
@attribute mmaPoveznica "PIO_DATA"
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue