Added support for memory attribute
This commit is contained in:
1 parent
bb423c2184
commit
59b19062ff
14 files changed
+293
-70
No files matched your search
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user