Implemented domain
This commit is contained in:
parent
f4450494d8
commit
e416743908
|
@ -15,12 +15,17 @@ SOURCES += \
|
|||
comdel/domain/comdelgenerator.cpp \
|
||||
comdel/domain/component.cpp \
|
||||
comdel/domain/connection.cpp \
|
||||
comdel/domain/connectioninstance.cpp \
|
||||
comdel/domain/display.cpp \
|
||||
comdel/domain/functionsignature.cpp \
|
||||
comdel/domain/instance.cpp \
|
||||
comdel/domain/instanceattribute.cpp \
|
||||
comdel/domain/library.cpp \
|
||||
comdel/domain/pin.cpp \
|
||||
comdel/domain/rule.cpp \
|
||||
comdel/domain/schema.cpp \
|
||||
comdel/domain/value.cpp \
|
||||
comdel/domain/wireinstance.cpp \
|
||||
comdel/parser/assert.cpp \
|
||||
comdel/parser/astnode.cpp \
|
||||
comdel/parser/comdellexer.cpp \
|
||||
|
@ -40,12 +45,17 @@ HEADERS += \
|
|||
comdel/domain/comdelgenerator.h \
|
||||
comdel/domain/component.h \
|
||||
comdel/domain/connection.h \
|
||||
comdel/domain/connectioninstance.h \
|
||||
comdel/domain/display.h \
|
||||
comdel/domain/functionsignature.h \
|
||||
comdel/domain/instance.h \
|
||||
comdel/domain/instanceattribute.h \
|
||||
comdel/domain/library.h \
|
||||
comdel/domain/pin.h \
|
||||
comdel/domain/rule.h \
|
||||
comdel/domain/schema.h \
|
||||
comdel/domain/value.h \
|
||||
comdel/domain/wireinstance.h \
|
||||
comdel/parser/assert.h \
|
||||
comdel/parser/astnode.h \
|
||||
comdel/parser/comdellexer.h \
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 6.0.2, 2022-03-30T08:39:47. -->
|
||||
<!-- Written by QtCreator 6.0.2, 2022-04-05T08:22:13. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
|
|
|
@ -2,8 +2,33 @@
|
|||
|
||||
namespace domain {
|
||||
|
||||
Bus::Bus(std::string name, std::string tooltip, BusType type, std::pair<int, int> count, std::optional<Display> display)
|
||||
: name(name), tooltip(tooltip), type(type), count(count), display(display)
|
||||
Wire::Wire(std::string name, WireType type, int width, bool hidden, bool hasTermination, long long ifUnterminated)
|
||||
: name(name), type(type), width(width), hidden(hidden), hasTermination(hasTermination), ifUnterminated(ifUnterminated)
|
||||
{}
|
||||
|
||||
std::string Wire::getName() {
|
||||
return name;
|
||||
}
|
||||
int Wire::getWidth() {
|
||||
return width;
|
||||
}
|
||||
bool Wire::isHidden() {
|
||||
return hidden;
|
||||
}
|
||||
bool Wire::getHasTermination() {
|
||||
return hasTermination;
|
||||
}
|
||||
long long Wire::getIfUnterminated() {
|
||||
return ifUnterminated;
|
||||
}
|
||||
Wire::WireType Wire::getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Bus::Bus(std::string name, std::string tooltip, BusType type, std::pair<int, int> count, std::vector<Wire> wires, std::optional<Display> display)
|
||||
: name(name), tooltip(tooltip), type(type), count(count), wires(wires), display(display)
|
||||
{}
|
||||
|
||||
std::string Bus::getName() {
|
||||
|
@ -21,6 +46,9 @@ std::pair<int, int> Bus::getCount() {
|
|||
std::optional<Display> Bus::getDisplay() {
|
||||
return display;
|
||||
}
|
||||
std::vector<Wire> Bus::getWires() {
|
||||
return wires;
|
||||
}
|
||||
|
||||
|
||||
} // namespace domain
|
||||
|
|
|
@ -5,16 +5,48 @@
|
|||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace domain {
|
||||
|
||||
class Wire
|
||||
{
|
||||
public:
|
||||
enum WireType {
|
||||
WIRE_DEFAULT,
|
||||
WIRED_AND,
|
||||
WIRED_OR,
|
||||
R_WIRE
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
WireType type;
|
||||
int width;
|
||||
bool hidden;
|
||||
bool hasTermination;
|
||||
long long ifUnterminated;
|
||||
|
||||
public:
|
||||
Wire(std::string name, WireType type, int width, bool hidden, bool hasTermination, long long ifUnterminated);
|
||||
|
||||
std::string getName();
|
||||
int getWidth();
|
||||
bool isHidden();
|
||||
bool getHasTermination();
|
||||
long long getIfUnterminated();
|
||||
WireType getType();
|
||||
};
|
||||
|
||||
class Bus
|
||||
{
|
||||
public:
|
||||
enum BusType {
|
||||
AUTOMATIC,
|
||||
REGULAR
|
||||
REGULAR,
|
||||
AUTOMATIC_SINGLE
|
||||
};
|
||||
private:
|
||||
std::string name;
|
||||
|
@ -23,16 +55,17 @@ private:
|
|||
|
||||
std::pair<int, int> count;
|
||||
std::optional<Display> display;
|
||||
std::vector<Wire> wires;
|
||||
|
||||
public:
|
||||
Bus(std::string name, std::string tooltip, BusType type, std::pair<int, int> count, std::optional<Display> display = std::nullopt);
|
||||
Bus(std::string name, std::string tooltip, BusType type, std::pair<int, int> count, std::vector<Wire> wires, std::optional<Display> display = std::nullopt);
|
||||
|
||||
std::string getName();
|
||||
std::string getTooltip();
|
||||
BusType getType();
|
||||
std::pair<int, int> getCount();
|
||||
std::vector<Wire> getWires();
|
||||
std::optional<Display> getDisplay();
|
||||
|
||||
};
|
||||
|
||||
} // namespace domain
|
||||
|
|
|
@ -20,6 +20,21 @@ Action::ActionType toType(ActionNode::ActionType type) {
|
|||
return Action::WARNING;
|
||||
}
|
||||
|
||||
Wire::WireType toType(WireNode::WireType type) {
|
||||
switch (type) {
|
||||
case WireNode::R_WIRE:
|
||||
return Wire::R_WIRE;
|
||||
case WireNode::WIRE:
|
||||
return Wire::WIRE_DEFAULT;
|
||||
case WireNode::WIRED_AND:
|
||||
return Wire::WIRED_AND;
|
||||
case WireNode::WIRED_OR:
|
||||
return Wire::WIRED_OR;
|
||||
default:
|
||||
return Wire::WIRE_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
Value::ValueType toType(ValueNode::ValueType type) {
|
||||
switch (type) {
|
||||
case ValueNode::BOOL:
|
||||
|
@ -86,31 +101,31 @@ ComdelGenerator::ComdelGenerator(std::vector<FunctionSignature> signatures)
|
|||
: signatures(signatures)
|
||||
{}
|
||||
|
||||
std::optional<Library> ComdelGenerator::loadLibrary(LibraryNode node, ParseContext* parseContext, std::ostream& stream)
|
||||
std::optional<Library> ComdelGenerator::loadLibrary(LibraryNode node)
|
||||
{
|
||||
// library fields
|
||||
if(!node.name) {
|
||||
errors.push_back(SourceError{node.span, "missing @name"});
|
||||
return nullopt;
|
||||
} else {
|
||||
name = node.name->asString();
|
||||
}
|
||||
std::string name = node.name->asString();
|
||||
|
||||
if(!node.componentDirectory) {
|
||||
errors.push_back(SourceError{node.span, "missing @componentDirectory"});
|
||||
return nullopt;
|
||||
} else {
|
||||
componentDirectory = node.componentDirectory->asString();
|
||||
}
|
||||
std::string componentDirectory = node.componentDirectory->asString();
|
||||
|
||||
std::string header = node.header ? node.header->asString() : "";
|
||||
header = node.header ? node.header->asString() : "";
|
||||
|
||||
std::string libraryInfo = node.libraryInfo ? node.libraryInfo->asString() : "";
|
||||
libraryInfo = node.libraryInfo ? node.libraryInfo->asString() : "";
|
||||
|
||||
std::vector<AddressSpace> addressSpaces;
|
||||
for(auto& as: node.addressSpaces) {
|
||||
addressSpaces.push_back(*loadAddressSpace(as));
|
||||
}
|
||||
|
||||
std::vector<Component> components;
|
||||
for(auto& comp: node.components) {
|
||||
std::optional<Component> component;
|
||||
component = loadComponent(comp);
|
||||
|
@ -119,29 +134,25 @@ std::optional<Library> ComdelGenerator::loadLibrary(LibraryNode node, ParseConte
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<Connection> connections;
|
||||
for(uint i=0; i<node.connections.size(); i++) {
|
||||
auto conn = loadConnection(node.connections[i]);
|
||||
if(!conn) {
|
||||
return nullopt;
|
||||
}
|
||||
connections.push_back(*conn);
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> messages;
|
||||
for(uint i=0; i<node.messages.size(); i++) {
|
||||
if(!node.messages[i].value.is(ValueNode::STRING)) {
|
||||
errors.push_back(SourceError{node.messages[i].key.span, "expected `string`"});
|
||||
return nullopt;
|
||||
}
|
||||
messages[node.messages[i].key.value] = node.messages[i].value.asString();
|
||||
}
|
||||
|
||||
std::vector<Bus> buses;
|
||||
for(uint i=0; i<node.buses.size(); i++) {
|
||||
auto bus = loadBus(node.buses[i]);
|
||||
if(!bus) {
|
||||
return nullopt;
|
||||
if(bus) {
|
||||
buses.push_back(*bus);
|
||||
}
|
||||
}
|
||||
|
||||
for(uint i=0; i<node.connections.size(); i++) {
|
||||
auto conn = loadConnection(node.connections[i]);
|
||||
if(conn) {
|
||||
connections.push_back(*conn);
|
||||
}
|
||||
}
|
||||
|
||||
for(uint i=0; i<node.messages.size(); i++) {
|
||||
if(!node.messages[i].value.is(ValueNode::STRING)) {
|
||||
errors.push_back(SourceError{node.messages[i].span, "expected `string`"});
|
||||
} else {
|
||||
messages[node.messages[i].key.value] = node.messages[i].value.asString();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,7 +168,7 @@ std::optional<Bus> ComdelGenerator::loadBus(BusNode node)
|
|||
count = std::make_pair<int, int>(node.count->first.value, node.count->second.value);
|
||||
}
|
||||
if(count.first > count.second || count.first < 0) {
|
||||
errors.push_back(SourceError{node.count->span, "invalid @size (min, max) := min <= max && min >= 0"});
|
||||
errors.push_back(SourceError{node.count->span, "invalid @size"});
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
|
@ -173,12 +184,11 @@ std::optional<Bus> ComdelGenerator::loadBus(BusNode node)
|
|||
errors.push_back(SourceError{node.span, "missing @display"});
|
||||
return nullopt;
|
||||
}
|
||||
if(node.display && type == Bus::AUTOMATIC) {
|
||||
if(node.display && (type == Bus::AUTOMATIC || type == Bus::AUTOMATIC_SINGLE)) {
|
||||
errors.push_back(SourceError{node.span, "automatic bus cannot have a @display"});
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
|
||||
optional<Display> display;
|
||||
if(Bus::REGULAR) {
|
||||
display = loadDisplay(*node.display);
|
||||
|
@ -187,7 +197,19 @@ std::optional<Bus> ComdelGenerator::loadBus(BusNode node)
|
|||
}
|
||||
}
|
||||
|
||||
return Bus(name, tooltip, type, count, display);
|
||||
if(node.wires.size() == 0) {
|
||||
errors.push_back(SourceError{node.span, "missing @wires"});
|
||||
return nullopt;
|
||||
}
|
||||
std::vector<Wire> wires;
|
||||
for(auto& _wire: node.wires) {
|
||||
auto wire = loadWire(_wire);
|
||||
if(wire) {
|
||||
wires.push_back(*wire);
|
||||
}
|
||||
}
|
||||
|
||||
return Bus(name, tooltip, type, count, wires, display);
|
||||
}
|
||||
|
||||
|
||||
|
@ -198,10 +220,28 @@ std::optional<AddressSpace> ComdelGenerator::loadAddressSpace(AddressSpaceNode n
|
|||
|
||||
std::optional<Connection> ComdelGenerator::loadConnection(ConnectionNode node)
|
||||
{
|
||||
push(ComdelContext("connection", false, true, false));
|
||||
|
||||
std::string component = node.component.value;
|
||||
std::string pin = node.pin.value;
|
||||
std::string bus = node.bus.value;
|
||||
|
||||
auto componentInstance = getComponentPin(component, pin);
|
||||
if(!componentInstance) {
|
||||
errors.push_back(SourceError(node.span, "pin does not exist"));
|
||||
}
|
||||
|
||||
auto busInstance = getBus(bus);
|
||||
if(!busInstance) {
|
||||
errors.push_back(SourceError(node.span, "bus does not exist"));
|
||||
}
|
||||
|
||||
std::set<std::string> wireNames;
|
||||
for(auto &wire: busInstance->getWires()) {
|
||||
wireNames.insert(wire.getName());
|
||||
current().wires.push_back(wire.getName());
|
||||
}
|
||||
|
||||
std::vector<Attribute> attributes;
|
||||
for(uint i=0; i<node.attributes.size(); i++) {
|
||||
auto attr = loadAttribute(node.attributes[i]);
|
||||
|
@ -220,26 +260,34 @@ std::optional<Connection> ComdelGenerator::loadConnection(ConnectionNode node)
|
|||
for(uint i=0; i<node.wires.size(); i++) {
|
||||
if(attributeNames.count(node.wires[i].value)) {
|
||||
wires.push_back(Value::fromReference(node.wires[i].value, Value::ATTRIBUTE_REFERENCE));
|
||||
} else {
|
||||
} else if(wireNames.count(node.wires[i].value)) {
|
||||
wires.push_back(Value::fromReference(node.wires[i].value, Value::WIRE_REFERENCE));
|
||||
} else {
|
||||
errors.push_back(SourceError(node.wires[i].span, "unknown identifier"));
|
||||
}
|
||||
}
|
||||
|
||||
pop();
|
||||
|
||||
return Connection(component, pin, bus, attributes, wires);
|
||||
}
|
||||
|
||||
std::optional<Component> ComdelGenerator::loadComponent(ComponentNode node)
|
||||
{
|
||||
push(ComdelContext(node.name.value, true, false, false));
|
||||
|
||||
std::string name = node.name.value;
|
||||
|
||||
if(!node.tooltip) {
|
||||
errors.push_back(SourceError{node.span, "missing @tooltip"});
|
||||
pop();
|
||||
return nullopt;
|
||||
}
|
||||
std::string tooltip = node.tooltip->asString();
|
||||
|
||||
if(!node.source) {
|
||||
errors.push_back(SourceError{node.span, "missing @source"});
|
||||
pop();
|
||||
return nullopt;
|
||||
}
|
||||
std::string source = node.source->asString();
|
||||
|
@ -254,6 +302,8 @@ std::optional<Component> ComdelGenerator::loadComponent(ComponentNode node)
|
|||
}
|
||||
}
|
||||
|
||||
context[context.size() -1 ].attributes = attributes;
|
||||
|
||||
std::vector<Rule> rules;
|
||||
for(auto& r: node.rules) {
|
||||
std::optional<Rule> rule = loadRule(r);
|
||||
|
@ -264,6 +314,7 @@ std::optional<Component> ComdelGenerator::loadComponent(ComponentNode node)
|
|||
|
||||
if(!node.instanceName) {
|
||||
errors.push_back(SourceError{node.span, "missing @instanceName"});
|
||||
pop();
|
||||
return nullopt;
|
||||
}
|
||||
std::string instanceName = node.instanceName->asString();
|
||||
|
@ -274,15 +325,18 @@ std::optional<Component> ComdelGenerator::loadComponent(ComponentNode node)
|
|||
}
|
||||
if(count.first > count.second || count.first < 0) {
|
||||
errors.push_back(SourceError{node.count->first.span, "invalid @size"});
|
||||
pop();
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
if(!node.display) {
|
||||
errors.push_back(SourceError{node.span, "missing @display"});
|
||||
pop();
|
||||
return nullopt;
|
||||
}
|
||||
optional<Display> display = loadDisplay(*node.display);
|
||||
if(!display) {
|
||||
pop();
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
|
@ -290,13 +344,27 @@ std::optional<Component> ComdelGenerator::loadComponent(ComponentNode node)
|
|||
for(uint i=0; i<node.pins.size(); i++) {
|
||||
auto pin = loadPin(node.pins[i]);
|
||||
if(!pin) {
|
||||
pop();
|
||||
return nullopt;
|
||||
}
|
||||
pins.push_back(*pin);
|
||||
}
|
||||
|
||||
pop();
|
||||
return Component(name, tooltip, source, type, rules, instanceName, count, *display, pins, attributes);
|
||||
}
|
||||
|
||||
std::optional<Wire> ComdelGenerator::loadWire(WireNode node) {
|
||||
return Wire(
|
||||
node.name.value,
|
||||
toType(node.type),
|
||||
node.size.value,
|
||||
node.hidden,
|
||||
node.hasTermination,
|
||||
node.isUnterminated
|
||||
);
|
||||
}
|
||||
|
||||
optional<Pin> ComdelGenerator::loadPin(PinNode node)
|
||||
{
|
||||
std::string name = node.name.value;
|
||||
|
@ -344,22 +412,41 @@ PinConnection ComdelGenerator::loadPinConnection(PinConnectionNode node)
|
|||
std::optional<Attribute> ComdelGenerator::loadAttribute(AttributeNode node)
|
||||
{
|
||||
std::string name = node.name.value;
|
||||
pushAdditional(name);
|
||||
Value value;
|
||||
if(node.type == ValueNode::INT) {
|
||||
value = Value::fromInt(node.defaultValue->asInt());
|
||||
} else if (node.type == ValueNode::BOOL) {
|
||||
value = Value::fromBool(node.defaultValue->asBool());
|
||||
} else if (node.type == ValueNode::STRING) {
|
||||
value = Value::fromString(node.defaultValue->asString());
|
||||
} else if (node.type == ValueNode::WIRE) {
|
||||
value = Value::fromReference(node.defaultValue->asIdentifier(), Value::WIRE_REFERENCE);
|
||||
|
||||
if(current().inComponent) {
|
||||
if(node.type == ValueNode::INT) {
|
||||
value = Value::fromInt(node.defaultValue->asInt());
|
||||
} else if (node.type == ValueNode::BOOL) {
|
||||
value = Value::fromBool(node.defaultValue->asBool());
|
||||
} else if (node.type == ValueNode::STRING) {
|
||||
value = Value::fromString(node.defaultValue->asString());
|
||||
} else {
|
||||
errors.push_back(SourceError{node.name.span, "unsupported type"});
|
||||
}
|
||||
}
|
||||
if(current().inConnection) { // TODO remove identifier
|
||||
if (node.type == ValueNode::WIRE || node.type == ValueNode::IDENTIFIER) {
|
||||
if(current().doesWireExists(node.defaultValue->asIdentifier())) {
|
||||
value = Value::fromReference(node.defaultValue->asIdentifier(), Value::WIRE_REFERENCE);
|
||||
} else {
|
||||
value = Value::fromReference("", Value::WIRE_REFERENCE);
|
||||
errors.push_back(SourceError{node.span, "unknown identifier"});
|
||||
}
|
||||
} else {
|
||||
errors.push_back(SourceError{node.name.span, "unsupported type"});
|
||||
}
|
||||
}
|
||||
|
||||
current().attributes.push_back(Attribute(name, value));
|
||||
|
||||
std::optional<Popup> popup;
|
||||
if(node.popup) {
|
||||
popup = loadPopup(*node.popup, name, value.getType());
|
||||
}
|
||||
|
||||
pop();
|
||||
return Attribute(name, value, popup);
|
||||
}
|
||||
|
||||
|
@ -367,6 +454,11 @@ std::optional<Popup> ComdelGenerator::loadPopup(PopupNode node, std::string name
|
|||
{
|
||||
auto popupType = toType(*node.type);
|
||||
|
||||
pushAdditional(name);
|
||||
|
||||
current().attributes.clear();
|
||||
current().attributes.push_back(Attribute(name, Value::ofType(type)));
|
||||
|
||||
if(!node.title) {
|
||||
errors.push_back(SourceError{node.span, "missing @title"});
|
||||
return nullopt;
|
||||
|
@ -379,9 +471,6 @@ std::optional<Popup> ComdelGenerator::loadPopup(PopupNode node, std::string name
|
|||
}
|
||||
std::string text = node.text->asString();
|
||||
|
||||
std::vector<Attribute> attributes;
|
||||
attributes.push_back(Attribute(name, Value::ofType(type)));
|
||||
|
||||
std::vector<Rule> rules;
|
||||
for(auto& r: node.rules) {
|
||||
std::optional<Rule> rule = loadRule(r);
|
||||
|
@ -394,14 +483,29 @@ std::optional<Popup> ComdelGenerator::loadPopup(PopupNode node, std::string name
|
|||
if(node.enumerated) {
|
||||
for(uint i=0; i<node.enumeration.size(); i++) {
|
||||
if(toType(node.enumeration[i].value.getType()) != type) {
|
||||
errors.push_back(SourceError{node.enumeration[i].span, "wrong type"});
|
||||
return nullopt;
|
||||
|
||||
}
|
||||
enumeration.push_back(Enumeration(node.enumeration[i].key.asString(),
|
||||
toType(node.enumeration[i].value)));
|
||||
auto value = toType(node.enumeration[i].value);
|
||||
|
||||
if(value.isType(Value::UNDEFINED) && current().doesWireExists(value.asReference())) {
|
||||
value = Value::fromReference(value.asReference(), Value::WIRE_REFERENCE);
|
||||
} else {
|
||||
errors.push_back(SourceError{node.enumeration[i].span, "unknown wire"});
|
||||
}
|
||||
if(value.getType() != type) {
|
||||
errors.push_back(SourceError{node.enumeration[i].span, "wrong type"});
|
||||
}
|
||||
enumeration.push_back(Enumeration(node.enumeration[i].key.asString(), value));
|
||||
}
|
||||
} else {
|
||||
if(type == Value::WIRE_REFERENCE && !current().inConnection) {
|
||||
errors.push_back(SourceError{node.span, "@enumeration is required for atributes of type wire"});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pop();
|
||||
|
||||
return Popup(title, text, popupType, rules, enumeration);
|
||||
}
|
||||
|
||||
|
@ -429,17 +533,165 @@ std::optional<Condition> ComdelGenerator::loadCondition(ConditionNode node)
|
|||
if(signatures[i].name == function) {
|
||||
if(signatures[i].params.size() == node.params.size()) {
|
||||
std::vector<Value> params;
|
||||
for(int j=0; j<signatures[i].params[i]; j++) {
|
||||
params.push_back(toType(node.params[i]));
|
||||
for(uint j=0; j<signatures[i].params.size(); j++) {
|
||||
bool exists = false;
|
||||
auto type = toType(node.params[j]);
|
||||
if (type.getType() == Value::UNDEFINED) {
|
||||
if(current().doesAttributeExists(type.asReference(), signatures[i].params[j])) {
|
||||
exists = true;
|
||||
type = Value::fromReference(type.asReference(), Value::ATTRIBUTE_REFERENCE);
|
||||
}
|
||||
if(signatures[i].params[j] == Value::ADDRESS_SPACE) {
|
||||
if(hasAddressSpace(type.asReference())) {
|
||||
exists = true;
|
||||
type = Value::fromReference(type.asReference(), Value::ADDRESS_SPACE);
|
||||
}
|
||||
}
|
||||
|
||||
if(!exists) {
|
||||
errors.push_back(SourceError{node.functionName.span, "unknown reference " + type.asReference()});
|
||||
}
|
||||
}
|
||||
params.push_back(type);
|
||||
}
|
||||
return Condition(function,params, node.negated);
|
||||
return Condition(function, params, node.negated);
|
||||
} else {
|
||||
errors.push_back(SourceError{node.functionName.span, "wrong number of parametars"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
errors.push_back(SourceError{node.functionName.span, "unknown function name"});
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
|
||||
std::optional<Schema> ComdelGenerator::loadSchema(SchemaNode node, Library &library)
|
||||
{
|
||||
Schema schema;
|
||||
|
||||
for(auto &instance: node.instances) {
|
||||
if(library.hasComponent(instance.component.value)) {
|
||||
schema.instances.push_back(loadComponentInstance(instance, library));
|
||||
}
|
||||
if(library.hasBus(instance.component.value)) {
|
||||
schema.instances.push_back(loadBusInstance(instance, library));
|
||||
}
|
||||
}
|
||||
|
||||
for(auto &wire: node.wires) {
|
||||
auto w = loadWireInstance(wire);
|
||||
if(w) {
|
||||
schema.wires.push_back(*w);
|
||||
}
|
||||
}
|
||||
|
||||
for(auto &conn: node.connections) {
|
||||
auto component = dynamic_cast<ComponentInstance*>(schema.getInstance(conn.instance.value));
|
||||
if(component == NULL) {
|
||||
errors.push_back(SourceError{conn.instance.span, "unknown component"});
|
||||
continue;
|
||||
}
|
||||
if(!component->component.hasPin(conn.pin.value)) {
|
||||
errors.push_back(SourceError{conn.pin.span, "unknown pin"});
|
||||
continue;
|
||||
}
|
||||
auto bus = dynamic_cast<BusInstance*>(schema.getInstance(conn.bus.value));
|
||||
if(bus == NULL) {
|
||||
errors.push_back(SourceError{conn.bus.span, "unknown bus"});
|
||||
continue;
|
||||
}
|
||||
if(!library.hasConnection(component->component.getName(), conn.pin.value, bus->bus.getName())) {
|
||||
errors.push_back(SourceError{conn.span, "unknown connection"});
|
||||
continue;
|
||||
}
|
||||
auto connection = *library.getConnection(component->component.getName(), conn.pin.value, bus->bus.getName());
|
||||
|
||||
if(!conn.wire) {
|
||||
errors.push_back(SourceError{conn.span, "missing @wire"});
|
||||
continue;
|
||||
}
|
||||
if(!schema.hasWire(conn.wire->value)) {
|
||||
errors.push_back(SourceError{conn.wire->span, "unknown wire"});
|
||||
continue;
|
||||
}
|
||||
|
||||
auto wire = schema.getWire(conn.wire->value);
|
||||
|
||||
std::vector<InstanceAttribute*> attributes;
|
||||
for(auto& attr: conn.attributes) {
|
||||
if(connection.hasAttribute(attr.name.value)) {
|
||||
auto attribute = connection.getAttribute(attr.name.value);
|
||||
auto value = toType(attr.value);
|
||||
|
||||
for(auto& en: attribute.getPopup()->getEnumeration()) {
|
||||
if(en.getValue().asReference() == value.asReference()) {
|
||||
value = Value::fromReference(value.asReference(), Value::WIRE_REFERENCE);
|
||||
}
|
||||
}
|
||||
if(value.isType(Value::UNDEFINED)) {
|
||||
errors.push_back(SourceError{attr.span, "invalid value"});
|
||||
}
|
||||
|
||||
attributes.push_back(new InstanceAttribute(attribute.getName(), toType(attr.value), attribute));
|
||||
} else {
|
||||
errors.push_back(SourceError(attr.name.span, "unknown attribute"));
|
||||
}
|
||||
}
|
||||
|
||||
schema.connections.push_back(new BusConnectionInstance(component, attributes, bus, wire, connection));
|
||||
}
|
||||
|
||||
return schema;
|
||||
}
|
||||
|
||||
ComponentInstance *ComdelGenerator::loadComponentInstance(InstanceNode instance, Library &library) {
|
||||
|
||||
auto name = instance.name.value;
|
||||
auto position = std::make_pair(instance.position->first.value, instance.position->second.value);
|
||||
|
||||
auto component = library.getComponent(instance.component.value);
|
||||
|
||||
// validate attributes
|
||||
std::vector<InstanceAttribute*> attributes;
|
||||
for(auto& attr: instance.attributes) {
|
||||
if(component.hasAttribute(attr.name.value, toType(attr.value.getType()))) {
|
||||
auto attribute = component.getAttribute(attr.name.value);
|
||||
attributes.push_back(new InstanceAttribute(attribute.getName(), toType(attr.value), attribute));
|
||||
} else {
|
||||
errors.push_back(SourceError(attr.name.span, "unknown attribute"));
|
||||
}
|
||||
}
|
||||
|
||||
return new ComponentInstance(name, attributes, position, component);
|
||||
}
|
||||
BusInstance *ComdelGenerator::loadBusInstance(InstanceNode instance, Library &library) {
|
||||
|
||||
auto name = instance.name.value;
|
||||
auto position = std::make_pair(instance.position->first.value, instance.position->second.value);
|
||||
|
||||
auto bus = library.getBus(instance.component.value);
|
||||
|
||||
long long size = 0;
|
||||
if(instance.size) {
|
||||
size = instance.size->value;
|
||||
}
|
||||
|
||||
return new BusInstance(name, position, bus, size);
|
||||
}
|
||||
|
||||
std::optional<WireInstance*> ComdelGenerator::loadWireInstance(WireInstanceNode node) {
|
||||
|
||||
if(!node.display) {
|
||||
errors.push_back(SourceError{node.span, "missing @text"});
|
||||
return nullopt;
|
||||
}
|
||||
auto display = loadDisplay(*node.display);
|
||||
if(!display) {
|
||||
return nullopt;
|
||||
}
|
||||
return std::optional<WireInstance*>(new WireInstance(node.name.value, *display));
|
||||
}
|
||||
|
||||
|
||||
} // namespace domain
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
#define DOMAIN_COMDELGENERATOR_H
|
||||
|
||||
#include "library.h"
|
||||
#include "schema.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <comdel/parser/astnode.h>
|
||||
#include <comdel/parser/parsecontext.h>
|
||||
|
@ -9,8 +12,53 @@
|
|||
|
||||
namespace domain {
|
||||
|
||||
struct ComdelContext {
|
||||
std::vector<Attribute> attributes;
|
||||
std::vector<std::string> wires;
|
||||
std::string name;
|
||||
bool inComponent;
|
||||
bool inConnection;
|
||||
bool inBus;
|
||||
|
||||
ComdelContext(std::string name, bool inComponent, bool inConnection, bool inBus)
|
||||
: name(name), inComponent(inComponent), inConnection(inConnection), 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 ComdelGenerator
|
||||
{
|
||||
std::vector<ComdelContext> context;
|
||||
|
||||
std::string name;
|
||||
std::string libraryInfo;
|
||||
std::string header;
|
||||
std::string componentDirectory;
|
||||
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<FunctionSignature> signatures;
|
||||
|
||||
|
@ -21,11 +69,66 @@ class ComdelGenerator
|
|||
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);
|
||||
|
||||
ComponentInstance *loadComponentInstance(InstanceNode instance, Library &library);
|
||||
BusInstance *loadBusInstance(InstanceNode instance, Library &library);
|
||||
std::optional<WireInstance*> loadWireInstance(WireInstanceNode node);
|
||||
|
||||
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.size() > 0) {
|
||||
this->context.push_back(current());
|
||||
current().name = name;
|
||||
} else {
|
||||
ComdelContext con(name, false, false, false);
|
||||
push(con);
|
||||
}
|
||||
}
|
||||
ComdelContext ¤t() {
|
||||
return this->context[this->context.size() - 1];
|
||||
}
|
||||
void pop() {
|
||||
this->context.pop_back();
|
||||
}
|
||||
|
||||
public:
|
||||
ComdelGenerator(std::vector<FunctionSignature> signatures);
|
||||
|
||||
|
@ -33,7 +136,9 @@ public:
|
|||
return errors;
|
||||
}
|
||||
|
||||
std::optional<Library> loadLibrary(LibraryNode node, ParseContext* parseContext, std::ostream& stream);
|
||||
std::optional<Library> loadLibrary(LibraryNode node);
|
||||
|
||||
std::optional<Schema> loadSchema(SchemaNode node, Library &library);
|
||||
};
|
||||
|
||||
} // namespace domain
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#include "comdelvalidator.h"
|
||||
|
||||
namespace domain {
|
||||
|
||||
ComdelValidator::ComdelValidator(std::vector<FunctionSignature> signatures)
|
||||
: signatures(signatures)
|
||||
{}
|
||||
|
||||
std::vector<SourceError> ComdelValidator::getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
void validateLibrary(Library library, ParseContext* parseContext, std::ostream& stream) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace domain
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef DOMAIN_COMDELVALIDATOR_H
|
||||
#define DOMAIN_COMDELVALIDATOR_H
|
||||
|
||||
#include "functionsignature.h"
|
||||
#include "library.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <comdel/parser/parsecontext.h>
|
||||
#include <comdel/parser/sourceerror.h>
|
||||
|
||||
namespace domain {
|
||||
|
||||
class ComdelValidator
|
||||
{
|
||||
private:
|
||||
std::vector<SourceError> errors;
|
||||
std::vector<FunctionSignature> signatures;
|
||||
|
||||
public:
|
||||
|
||||
ComdelValidator(std::vector<FunctionSignature> signatures);
|
||||
|
||||
std::vector<SourceError> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
void validateLibrary(Library library, ParseContext* parseContext, std::ostream& stream);
|
||||
|
||||
};
|
||||
|
||||
} // namespace domain
|
||||
|
||||
#endif // DOMAIN_COMDELVALIDATOR_H
|
|
@ -45,6 +45,15 @@ Pin Component::getPin(std::string pin) {
|
|||
throw std::exception();
|
||||
}
|
||||
|
||||
bool Component::hasPin(std::string name) {
|
||||
for(auto pin: pins) {
|
||||
if(pin.getName() == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<Attribute> Component::getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
@ -55,8 +64,16 @@ Attribute Component::getAttribute(std::string attribute) {
|
|||
}
|
||||
}
|
||||
throw std::exception();
|
||||
|
||||
}
|
||||
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) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace domain
|
||||
|
|
|
@ -55,6 +55,9 @@ public:
|
|||
|
||||
std::vector<Attribute> getAttributes();
|
||||
Attribute getAttribute(std::string attribute);
|
||||
bool hasAttribute(std::string name, Value::ValueType type);
|
||||
|
||||
bool hasPin(std::string name);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -36,4 +36,13 @@ Attribute Connection::getAttribute(std::string name) {
|
|||
throw std::exception();
|
||||
}
|
||||
|
||||
bool Connection::hasAttribute(std::string name) {
|
||||
for(uint i=0; i<attributes.size(); i++) {
|
||||
if(attributes[i].getName() == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace domain
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
std::vector<Value> getWires();
|
||||
|
||||
Attribute getAttribute(std::string name);
|
||||
bool hasAttribute(std::string name);
|
||||
};
|
||||
|
||||
} // namespace domain
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#include "connectioninstance.h"
|
||||
|
||||
namespace domain {
|
||||
|
||||
|
||||
ConnectionInstance::ConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute*> attributes, WireInstance *wire, Connection connection)
|
||||
: instance(instance), attributes(attributes), connection(connection), wire(wire)
|
||||
{}
|
||||
|
||||
BusConnectionInstance::BusConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute*> attributes, BusInstance *bus, WireInstance *wire, Connection connection)
|
||||
: ConnectionInstance(instance, attributes, wire, connection), bus(bus)
|
||||
{}
|
||||
|
||||
DirectConnectionInstance::DirectConnectionInstance(ComponentInstance *instance, ComponentInstance *secondsInstance, std::vector<InstanceAttribute*> attributes, BusInstance *bus, WireInstance *wire, Connection connection)
|
||||
: ConnectionInstance(instance, attributes, wire, connection), secondInstance(secondInstance), bus(bus)
|
||||
{}
|
||||
|
||||
} // namespace domain
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef DOMAIN_CONNECTIONINSTANCE_H
|
||||
#define DOMAIN_CONNECTIONINSTANCE_H
|
||||
|
||||
#include "connection.h"
|
||||
#include "instance.h"
|
||||
#include "wireinstance.h"
|
||||
|
||||
|
||||
|
||||
namespace domain {
|
||||
|
||||
class ConnectionInstance
|
||||
{
|
||||
public:
|
||||
ComponentInstance *instance;
|
||||
Connection connection;
|
||||
WireInstance *wire;
|
||||
|
||||
std::vector<InstanceAttribute*> attributes;
|
||||
|
||||
ConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute*> attributes, WireInstance *wire, Connection connection);
|
||||
};
|
||||
|
||||
|
||||
class BusConnectionInstance: public ConnectionInstance
|
||||
{
|
||||
public:
|
||||
BusInstance *bus;
|
||||
|
||||
BusConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute*> attributes, BusInstance *bus, WireInstance *wire, Connection connection);
|
||||
};
|
||||
|
||||
|
||||
class DirectConnectionInstance: public ConnectionInstance
|
||||
{
|
||||
public:
|
||||
BusInstance *bus;
|
||||
ComponentInstance *secondInstance;
|
||||
|
||||
DirectConnectionInstance(ComponentInstance *instance, ComponentInstance *secondsInstance, std::vector<InstanceAttribute*> attributes, BusInstance *bus, WireInstance *wire, Connection connection);
|
||||
};
|
||||
|
||||
|
||||
} // namespace domain
|
||||
|
||||
#endif // DOMAIN_CONNECTIONINSTANCE_H
|
|
@ -0,0 +1,17 @@
|
|||
#include "instance.h"
|
||||
|
||||
namespace domain {
|
||||
|
||||
|
||||
Instance::Instance(std::string name, std::vector<InstanceAttribute*> attributes, std::pair<int, int> position)
|
||||
: name(name), attributes(attributes), position(position)
|
||||
{}
|
||||
BusInstance::BusInstance(std::string name, std::pair<int, int> position, Bus bus, int size)
|
||||
: Instance(name, vector<InstanceAttribute*>(), position), bus(bus), size(size)
|
||||
{}
|
||||
ComponentInstance::ComponentInstance(std::string name, std::vector<InstanceAttribute*> attributes, std::pair<int, int> position, Component component)
|
||||
: Instance(name, attributes, position), component(component)
|
||||
{}
|
||||
|
||||
|
||||
} // namespace domain
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef DOMAIN_INSTANCE_H
|
||||
#define DOMAIN_INSTANCE_H
|
||||
|
||||
#include "bus.h"
|
||||
#include "component.h"
|
||||
#include "instanceattribute.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
||||
namespace domain {
|
||||
|
||||
class Instance
|
||||
{
|
||||
public:
|
||||
std::string name;
|
||||
std::vector<InstanceAttribute*> attributes;
|
||||
std::pair<int, int> position;
|
||||
|
||||
virtual ~Instance() {};
|
||||
|
||||
Instance(std::string name, std::vector<InstanceAttribute*> attributes, std::pair<int, int> position);
|
||||
};
|
||||
|
||||
class BusInstance: public Instance
|
||||
{
|
||||
public:
|
||||
Bus bus;
|
||||
int size;
|
||||
|
||||
BusInstance(std::string name, std::pair<int, int> position, Bus bus, int size);
|
||||
|
||||
virtual ~BusInstance() {
|
||||
Instance::~Instance();
|
||||
}
|
||||
};
|
||||
|
||||
class ComponentInstance: public Instance
|
||||
{
|
||||
public:
|
||||
Component component;
|
||||
|
||||
ComponentInstance(std::string name, std::vector<InstanceAttribute*> attributes, std::pair<int, int> position, Component component);
|
||||
|
||||
virtual ~ComponentInstance() {
|
||||
Instance::~Instance();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace domain
|
||||
|
||||
#endif // DOMAIN_INSTANCE_H
|
|
@ -0,0 +1,9 @@
|
|||
#include "instanceattribute.h"
|
||||
|
||||
namespace domain {
|
||||
|
||||
InstanceAttribute::InstanceAttribute(std::string name, Value value, Attribute attribute)
|
||||
: name(name), value(value), attribute(attribute)
|
||||
{}
|
||||
|
||||
} // namespace domain
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef DOMAIN_INSTANCEATTRIBUTE_H
|
||||
#define DOMAIN_INSTANCEATTRIBUTE_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;
|
||||
|
||||
};
|
||||
|
||||
} // namespace domain
|
||||
|
||||
#endif // DOMAIN_INSTANCEATTRIBUTE_H
|
|
@ -38,6 +38,24 @@ std::map<std::string, std::string> Library::getMessages() {
|
|||
return messages;
|
||||
}
|
||||
|
||||
bool Library::hasComponent(std::string name) {
|
||||
for(uint i=0; i<components.size(); i++) {
|
||||
if(components[i].getName() == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool Library::hasBus(std::string name) {
|
||||
for(uint i=0; i<buses.size(); i++) {
|
||||
if(buses[i].getName() == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
AddressSpace &Library::getAddressSpace(std::string addressSpace) {
|
||||
for(uint i=0; i<addressSpaces.size(); i++) {
|
||||
if(addressSpaces[i].getName() == addressSpace) {
|
||||
|
@ -71,6 +89,10 @@ std::optional<Connection> Library::getConnection(std::string component, std::str
|
|||
}
|
||||
return nullopt;
|
||||
}
|
||||
bool Library::hasConnection(std::string component, std::string pin, std::string bus) {
|
||||
return getConnection(component, pin, bus).has_value();
|
||||
}
|
||||
|
||||
std::string Library::getMessage(std::string key) {
|
||||
return messages[key];
|
||||
}
|
||||
|
|
|
@ -43,6 +43,10 @@ public:
|
|||
std::vector<Bus> getBuses();
|
||||
std::vector<Connection> getConnections();
|
||||
|
||||
bool hasComponent(std::string name);
|
||||
bool hasBus(std::string name);
|
||||
bool hasConnection(std::string component, std::string pin, std::string bus);
|
||||
|
||||
std::map<std::string, std::string> getMessages();
|
||||
|
||||
AddressSpace &getAddressSpace(std::string name);
|
||||
|
@ -51,6 +55,8 @@ public:
|
|||
std::optional<Connection> getConnection(std::string component, std::string pin, std::string bus);
|
||||
std::string getMessage(std::string key);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // namespace domain
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
#include "schema.h"
|
||||
|
||||
namespace domain {
|
||||
|
||||
Schema::Schema()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace domain
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef DOMAIN_SCHEMA_H
|
||||
#define DOMAIN_SCHEMA_H
|
||||
|
||||
#include "connectioninstance.h"
|
||||
#include "instance.h"
|
||||
#include "wireinstance.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace domain {
|
||||
|
||||
class Schema
|
||||
{
|
||||
public:
|
||||
Schema();
|
||||
|
||||
std::vector<Instance*> instances;
|
||||
std::vector<ConnectionInstance*> connections;
|
||||
std::vector<WireInstance*> wires;
|
||||
|
||||
WireInstance *getWire(std::string name) {
|
||||
for(auto wire: wires) {
|
||||
if (wire->name == name) {
|
||||
return wire;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool hasWire(std::string name) {
|
||||
return getWire(name) != NULL;
|
||||
}
|
||||
|
||||
|
||||
Instance *getInstance(std::string name) {
|
||||
for(auto instance: instances) {
|
||||
if (instance->name == name) {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace domain
|
||||
|
||||
#endif // DOMAIN_SCHEMA_H
|
|
@ -36,12 +36,38 @@ AddressSpace Value::asAddressSpace() {
|
|||
throw std::exception();
|
||||
}
|
||||
std::string Value::asReference() {
|
||||
if(isType(Value::WIRE_REFERENCE) || isType(Value::ATTRIBUTE_REFERENCE)) {
|
||||
if(isType(Value::WIRE_REFERENCE) || isType(Value::ATTRIBUTE_REFERENCE) || isType(Value::UNDEFINED)) {
|
||||
return reference;
|
||||
}
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
void Value::setInt(long long value) {
|
||||
if(isType(Value::INT)) {
|
||||
this->intValue = value;
|
||||
}
|
||||
throw std::exception();
|
||||
}
|
||||
void Value::setString(std::string value) {
|
||||
if(isType(Value::STRING)) {
|
||||
this->stringValue = value;
|
||||
}
|
||||
throw std::exception();
|
||||
}
|
||||
void Value::setBool(bool value) {
|
||||
if(isType(Value::BOOL)) {
|
||||
this->boolValue = value;
|
||||
}
|
||||
throw std::exception();
|
||||
}
|
||||
void Value::setReference(std::string value) {
|
||||
if(isType(Value::WIRE_REFERENCE)) {
|
||||
this->reference = value;
|
||||
}
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
|
||||
Value Value::fromInt(long long value) {
|
||||
Value val;
|
||||
val.type = Value::INT;
|
||||
|
|
|
@ -45,6 +45,11 @@ public:
|
|||
std::string asReference();
|
||||
AddressSpace asAddressSpace();
|
||||
|
||||
void setInt(long long intValue);
|
||||
void setString(std::string value);
|
||||
void setBool(bool value);
|
||||
void setReference(std::string value);
|
||||
|
||||
static Value fromInt(long long value);
|
||||
static Value fromString(std::string value);
|
||||
static Value fromBool(bool value);
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#include "wireinstance.h"
|
||||
|
||||
namespace domain {
|
||||
|
||||
WireInstance::WireInstance(std::string name, Display display)
|
||||
: name(name), display(display)
|
||||
{}
|
||||
|
||||
|
||||
} // namespace domain
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef DOMAIN_WIREINSTANCE_H
|
||||
#define DOMAIN_WIREINSTANCE_H
|
||||
|
||||
#include "display.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
namespace domain {
|
||||
|
||||
class WireInstance
|
||||
{
|
||||
public:
|
||||
std::string name;
|
||||
Display display;
|
||||
|
||||
WireInstance(std::string name, Display display);
|
||||
};
|
||||
|
||||
} // namespace domain
|
||||
|
||||
#endif // DOMAIN_WIREINSTANCE_H
|
|
@ -104,7 +104,7 @@ public:
|
|||
throw "cannot convert type to string";
|
||||
}
|
||||
std::string asIdentifier() {
|
||||
if(is(IDENTIFIER)) {
|
||||
if(is(IDENTIFIER) || is(WIRE)) {
|
||||
return identifierValue.value();
|
||||
}
|
||||
throw "cannot convert type to identifier";
|
||||
|
@ -271,13 +271,11 @@ struct WireNode: public AstNode
|
|||
WireType type;
|
||||
IdentifierNode name;
|
||||
NumberNode size;
|
||||
/*
|
||||
bool isTerminatedWith;
|
||||
long terminatedWith;
|
||||
|
||||
bool isIfUntrminated;
|
||||
long ifUnterminated;
|
||||
*/
|
||||
bool hidden;
|
||||
|
||||
bool hasTermination;
|
||||
long long isUnterminated;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ ComdelParser::parseList(std::optional<TokenType> openDelim,
|
|||
vec.push_back(*item);
|
||||
}
|
||||
|
||||
return std::move(vec);
|
||||
return vec;
|
||||
}
|
||||
|
||||
const std::vector<SourceError> &ComdelParser::getErrors()
|
||||
|
@ -703,7 +703,7 @@ PResult<AttributeNode> ComdelParser::parseAttribute() {
|
|||
} else if(check(TokenType::BOOL_TYPE)) {
|
||||
attribute.type = ValueNode::BOOL;
|
||||
} else if(check(TokenType::WIRE_TYPE)) {
|
||||
attribute.type = ValueNode::IDENTIFIER;
|
||||
attribute.type = ValueNode::WIRE;
|
||||
} else {
|
||||
return unexpected();
|
||||
}
|
||||
|
@ -729,7 +729,7 @@ PResult<AttributeNode> ComdelParser::parseAttribute() {
|
|||
} else if(attribute.type == ValueNode::STRING) {
|
||||
if(check(TokenType::STRING)) {
|
||||
auto string = parseString();
|
||||
attribute.defaultValue = ValueNode::ofString(string->value);
|
||||
attribute.defaultValue = ValueNode::ofString(string->asString());
|
||||
} else {
|
||||
return unexpected();
|
||||
}
|
||||
|
@ -740,6 +740,13 @@ PResult<AttributeNode> ComdelParser::parseAttribute() {
|
|||
} else {
|
||||
return unexpected();
|
||||
}
|
||||
} else if(attribute.type == ValueNode::WIRE) {
|
||||
if(check(TokenType::IDENTIFIER)) {
|
||||
auto identifier = parseIdentifier();
|
||||
attribute.defaultValue = ValueNode::ofWire(identifier->value);
|
||||
} else {
|
||||
return unexpected();
|
||||
}
|
||||
}
|
||||
|
||||
if(check(TokenType::LBRACE)) {
|
||||
|
@ -964,7 +971,7 @@ PResult<ValueNode> ComdelParser::parseValue() {
|
|||
if(check(TokenType::IDENTIFIER)) {
|
||||
value = ValueNode::ofIdentifier(parseIdentifier()->value);
|
||||
} else if(check(TokenType::STRING)) {
|
||||
value = ValueNode::ofString(parseString()->value);
|
||||
value = ValueNode::ofString(parseString()->asString());
|
||||
} else if(check(TokenType::NUMBER)) {
|
||||
value = ValueNode::ofInt(parseNumber()->value);
|
||||
} else if(check(TokenType::TRUE)) {
|
||||
|
|
17
main.cpp
17
main.cpp
|
@ -23,13 +23,28 @@ int main(int argc, char *argv[])
|
|||
|
||||
if(schema) {
|
||||
std::vector<domain::FunctionSignature> signatures;
|
||||
|
||||
signatures.push_back(domain::FunctionSignature("divisible", std::vector<domain::Value::ValueType>{domain::Value::INT, domain::Value::INT}));
|
||||
signatures.push_back(domain::FunctionSignature("less_then", std::vector<domain::Value::ValueType>{domain::Value::INT, domain::Value::INT}));
|
||||
signatures.push_back(domain::FunctionSignature("greater_then", std::vector<domain::Value::ValueType>{domain::Value::INT, domain::Value::INT}));
|
||||
signatures.push_back(domain::FunctionSignature("contains_address", std::vector<domain::Value::ValueType>{domain::Value::ADDRESS_SPACE, domain::Value::INT}));
|
||||
signatures.push_back(domain::FunctionSignature("contains", std::vector<domain::Value::ValueType>{domain::Value::ADDRESS_SPACE, domain::Value::INT, domain::Value::INT}));
|
||||
signatures.push_back(domain::FunctionSignature("unique", std::vector<domain::Value::ValueType>{domain::Value::ADDRESS_SPACE, domain::Value::INT, domain::Value::INT}));
|
||||
|
||||
domain::ComdelGenerator generator(signatures);
|
||||
generator.loadLibrary(*schema->library, &parseContext, std::cout);
|
||||
auto library = generator.loadLibrary(*schema->library);
|
||||
|
||||
for (auto& error : generator.getErrors()) {
|
||||
parseContext.formatError(error, std::cout, "ERROR: ");
|
||||
}
|
||||
|
||||
if(library) {
|
||||
auto instance = generator.loadSchema(*schema, *library);
|
||||
|
||||
for (auto& error : generator.getErrors()) {
|
||||
parseContext.formatError(error, std::cout, "ERROR: ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue