Added support for memory attribute

This commit is contained in:
Borna Rajković committed 2022-05-15 23:55:03 +02:00
1 parent bb423c2184
commit 59b19062ff
14 files changed
+293 -70

No files matched your search

+84 -50
View File
@@ -175,71 +175,105 @@ void generateSingleAutomaticPin(DirectConnectionInstance *instance, string name,
map <string, string> &wireNames,
stringstream &buffer);
void generateSubComponents(Schema *schema, map<string, string> &wires, ostream &buffer) {
void generateComponent(Schema *schema, map <string, string> &wires, ostream &buffer,
shared_ptr <ComponentInstance> &component);
void generateSubComponents(Schema *schema, map<string, string> &wires, ostream &buffer) {
buffer << "\t// components --------------------------------------------" << std::endl;
for(auto& component: schema->componentInstances) {
buffer << "\tsubcomponent " << component->component.getName() << " " << component->name;
if(!component->attributes.empty()) {
buffer << "<";
buffer << component->attributes[0].value.stringify();
for(int i=1; i<component->attributes.size(); i++) {
buffer << ", " << component->attributes[i].value.stringify();
}
buffer << ">";
if(component->component.getType() == Component::MEMORY) {
generateComponent(schema, wires, buffer, component);
}
}
for(auto& component: schema->componentInstances) {
if(component->component.getType() != Component::MEMORY) {
generateComponent(schema, wires, buffer, component);
}
}
}
stringstream tempOutput;
void generateComponent(Schema *schema, map <string, string> &wires, ostream &buffer,
shared_ptr <ComponentInstance> &component) {
buffer << "\tsubcomponent " << component->component.getName() << " " << component->name;
for(auto &pin: component->component.getPins()) {
if(schema->hasConnection(component->name, pin.getName())) {
auto conn = schema->getConnection(component->name, pin.getName());
auto busConn = dynamic_cast<BusConnectionInstance*>(conn);
if(busConn != nullptr) {
for(auto wire: busConn->connection.getWires()) {
if(wire.isType(Value::ATTRIBUTE_REFERENCE)) {
auto attribute = busConn->getAttribute(wire.asReference());
if(wire.isType(Value::WIRE_REFERENCE)) {
tempOutput << wires[busConn->bus->name + "." + attribute.value.asReference()] << ", ";
} else if(wire.isType(Value::NIL)) {
tempOutput << "*, ";
} else {
tempOutput << attribute.value.stringify() << ", ";
}
std::optional<InstanceAttribute> memory;
std::vector<InstanceAttribute> attributes;
for(auto& attr: component->attributes) {
if(attr.name != "_memory") {
attributes.push_back(attr);
} else if(attr.name == "_memory" && attr.value.asMemoryReference().has_value()) {
memory = attr;
}
}
if(!attributes.empty()) {
buffer << "<";
buffer << attributes[0].value.stringify();
for(int i=1; i<attributes.size(); i++) {
buffer << ", " << attributes[i].value.stringify();
}
buffer << ">";
}
stringstream tempOutput;
for(auto &pin: component->component.getPins()) {
if(schema->hasConnection(component->name, pin.getName())) {
auto conn = schema->getConnection(component->name, pin.getName());
auto busConn = dynamic_cast<BusConnectionInstance*>(conn);
if(busConn != nullptr) {
for(auto wire: busConn->connection.getWires()) {
if(wire.isType(Value::ATTRIBUTE_REFERENCE)) {
auto attribute = busConn->getAttribute(wire.asReference());
if(wire.isType(Value::WIRE_REFERENCE)) {
tempOutput << wires[busConn->bus->name + "." + attribute.value.asReference()] << ", ";
} else if(wire.isType(Value::NIL)) {
tempOutput << "*, ";
} else {
if(wire.isType(Value::WIRE_REFERENCE)) {
tempOutput << wires[busConn->bus->name + "." + wire.asReference()] << ", ";
} else if(wire.isType(Value::NIL)) {
tempOutput << "*, ";
} else {
tempOutput << wire.stringify() << ", ";
}
tempOutput << attribute.value.stringify() << ", ";
}
} else {
if(wire.isType(Value::WIRE_REFERENCE)) {
tempOutput << wires[busConn->bus->name + "." + wire.asReference()] << ", ";
} else if(wire.isType(Value::NIL)) {
tempOutput << "*, ";
} else {
tempOutput << wire.stringify() << ", ";
}
}
}
auto dirConn = dynamic_cast<DirectConnectionInstance*>(conn);
if(dirConn != nullptr) {
if(dirConn->bus->bus.getType() == Bus::AUTOMATIC) {
generateAutomaticPin(dirConn, component->name, pin.getName(), wires, tempOutput);
} else {
generateSingleAutomaticPin(dirConn, component->name, pin.getName(), wires, tempOutput);
}
}
} else {
// if no connection exists than defaults must exist
for(auto& wire: *pin.getWires()) {
tempOutput << wire.stringify() << ", ";
}
auto dirConn = dynamic_cast<DirectConnectionInstance*>(conn);
if(dirConn != nullptr) {
if(dirConn->bus->bus.getType() == Bus::AUTOMATIC) {
generateAutomaticPin(dirConn, component->name, pin.getName(), wires, tempOutput);
} else {
generateSingleAutomaticPin(dirConn, component->name, pin.getName(), wires, tempOutput);
}
}
} else {
// if no connection exists than defaults must exist
for(auto& wire: *pin.getWires()) {
tempOutput << wire.stringify() << ", ";
}
}
auto wireList = tempOutput.str();
wireList.pop_back();
wireList.pop_back(); // remove last COMMA(", ")
buffer << "(" << wireList << ");" << std::endl;
}
auto wireList = tempOutput.str();
wireList.pop_back();
wireList.pop_back(); // remove last COMMA(", ")
buffer << "(" << wireList << ")";
if(memory.has_value()) {
buffer << " uses " << *memory->value.asMemoryReference();
}
buffer << ";" << std::endl;
}
void generateSingleAutomaticPin(DirectConnectionInstance *connection, string name, string pin, map <string, string> &wireNames, stringstream &buffer) {
+7 -1
View File
@@ -67,7 +67,13 @@ Attribute Component::getAttribute(std::string attribute) {
}
bool Component::hasAttribute(std::string name, Value::ValueType type) {
for(uint i=0; i<attributes.size(); i++) {
if(attributes[i].getName() == name && attributes[i].getDefault().getType() == type) {
if(attributes[i].getName() == name && attributes[i].getDefault().getType() == type) {
return true;
}
if(attributes[i].getName() == name && (type == Value::NIL && (attributes[i].getDefault().getType() == Value::MEMORY_REFERENCE || attributes[i].getDefault().getType() == Value::WIRE_REFERENCE))) {
return true;
}
if(attributes[i].getName() == name && (type == Value::UNDEFINED && (attributes[i].getDefault().getType() == Value::MEMORY_REFERENCE || attributes[i].getDefault().getType() == Value::WIRE_REFERENCE))) {
return true;
}
}
+33 -2
View File
@@ -40,19 +40,31 @@ Value::ValueType toType(ValueNode::ValueType type) {
switch (type) {
case ValueNode::BOOL:
return Value::BOOL;
case ValueNode::MEMORY:
return Value::MEMORY_REFERENCE;
case ValueNode::WIRE:
return Value::WIRE_REFERENCE;
case ValueNode::STRING:
return Value::STRING;
case ValueNode::INT:
return Value::INT;
case ValueNode::NIL:
return Value::NIL;
default:
return Value::UNDEFINED;
}
}
Value toType(ValueNode node) {
Value toType(ValueNode node, Value::ValueType type = Value::ValueType::UNDEFINED) {
if(type == Value::MEMORY_REFERENCE) {
if(node.getType() == ValueNode::NIL) {
return Value::fromMemoryReference(nullopt);
} else {
return Value::fromMemoryReference(node.asIdentifier());
}
}
if(node.getType() == ValueNode::BOOL) {
return Value::fromBool(node.asBool());
} else if(node.getType() == ValueNode::INT) {
@@ -439,6 +451,9 @@ std::optional<Component> SchemaCreator::loadComponent(ComponentNode node)
attributes.push_back(*attribute);
}
}
if(type == Component::PROCESSOR) {
attributes.push_back(*createMemoryAttribute());
}
context[context.size() -1 ].attributes = attributes;
@@ -885,12 +900,20 @@ shared_ptr<ComponentInstance> SchemaCreator::loadComponentInstance(InstanceNode
for(auto& attr: instance.attributes) {
if(component.hasAttribute(attr.name.value, toType(attr.value.getType()))) {
auto attribute = component.getAttribute(attr.name.value);
attributes.emplace_back(attribute.getName(), toType(attr.value), attribute);
attributes.emplace_back(attribute.getName(), toType(attr.value, attribute.getDefault().getType()), attribute);
} else {
errors.emplace_back(SourceError(attr.name.span, "unknown attribute"));
}
}
if(attributes.size() < component.getAttributes().size()) {
for(auto& attr: component.getAttributes()) {
if(std::count_if(attributes.begin(), attributes.end(), [&attr](InstanceAttribute& attribute){ return attr.getName() == attribute.name; }) == 0) {
errors.emplace_back(SourceError(instance.span, "missing attribute '" + attr.getName() + "'"));
}
}
}
return std::make_shared<ComponentInstance>(name, attributes, position, component);
}
std::shared_ptr<BusInstance> SchemaCreator::loadBusInstance(InstanceNode instance, Library &library) {
@@ -918,4 +941,12 @@ vector<Enumeration> SchemaCreator::createWireEnumeration(vector<Value> wireValue
return wires;
}
std::optional<Attribute> SchemaCreator::createMemoryAttribute() {
return Attribute("_memory", Value::fromMemoryReference(nullopt), createMemoryPopup());
}
std::optional<Popup> SchemaCreator::createMemoryPopup() {
return Popup("Postavi memoriju", "Postavi memoriju za izabrani procesor", Popup::AUTOMATIC, vector<Rule>{}, vector<Enumeration>{});
}
} // namespace domain
+5 -1
View File
@@ -79,6 +79,8 @@ class SchemaCreator
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) {
@@ -140,7 +142,9 @@ public:
Schema* loadSchema(SchemaNode node, Library &library);
vector <Enumeration> createWireEnumeration(vector <Value> vector1);
vector <Enumeration> createWireEnumeration(vector<Value> vector1);
std::optional<Popup> createMemoryPopup();
};
} // namespace domain
+31 -1
View File
@@ -68,6 +68,16 @@ std::string Value::asReference() {
throw std::exception();
}
std::optional<std::string> Value::asMemoryReference() {
return memoryReference;
}
domain::ComponentInstance *Value::asMemory() {
return memory;
}
void Value::setInt(long long value) {
if(isType(Value::INT)) {
this->intValue = value;
@@ -124,11 +134,11 @@ Value Value::fromReference(std::string value, Value::ValueType type) {
val.reference = value;
return val;
}
Value Value::ofType(Value::ValueType type) {
Value val;
val.type = type;
return val;
}
Value Value::fromNull() {
@@ -151,9 +161,29 @@ std::string Value::stringify() {
case ADDRESS_SPACE_REFERENCE:
case ATTRIBUTE_REFERENCE:
return reference;
case MEMORY_REFERENCE:
if(memoryReference->empty()) {
return "null";
} else {
return memoryReference.value();
}
default:
throw std::exception();
}
}
Value Value::fromMemoryReference(std::optional<std::string> value) {
Value val;
val.type = MEMORY_REFERENCE;
val.memoryReference = value;
return val;
}
Value Value::fromMemory(domain::ComponentInstance *memory) {
Value val;
val.type = MEMORY;
val.memory = memory;
return val;
}
} // namespace domain
+15
View File
@@ -9,6 +9,8 @@
namespace domain {
class ComponentInstance;
class Value
{
public:
@@ -19,6 +21,8 @@ public:
ADDRESS_SPACE,
ADDRESS_SPACE_REFERENCE,
ATTRIBUTE_REFERENCE,
MEMORY_REFERENCE,
MEMORY,
WIRE_REFERENCE,
NIL,
UNDEFINED,
@@ -30,6 +34,9 @@ private:
bool boolValue;
std::optional<AddressSpace> addressSpace;
std::string reference;
domain::ComponentInstance *memory;
std::optional<std::string> memoryReference;
ValueType type;
@@ -53,6 +60,10 @@ public:
case ATTRIBUTE_REFERENCE:
case ADDRESS_SPACE_REFERENCE:
return value.asReference() == reference;
case MEMORY_REFERENCE:
return value.asMemoryReference() == memoryReference;
case MEMORY:
return value.asMemory() == memory;
case BOOL:
return value.asBool() == boolValue;
default:
@@ -71,6 +82,8 @@ public:
std::string asString();
bool asBool();
std::string asReference();
std::optional<std::string> asMemoryReference();
domain::ComponentInstance* asMemory();
AddressSpace asAddressSpace();
void setInt(long long intValue);
@@ -87,6 +100,8 @@ public:
static Value fromAddressSpace(AddressSpace addressSpace);
static Value fromReference(std::string value, ValueType type);
static Value ofType(ValueType type);
static Value fromMemoryReference(std::optional<std::string> memoryReference);
static Value fromMemory(domain::ComponentInstance *memory);
};
} // namespace domain