Implemented domain
This commit is contained in:
		
							parent
							
								
									f4450494d8
								
							
						
					
					
						commit
						e416743908
					
				| @ -15,12 +15,17 @@ SOURCES += \ | |||||||
|     comdel/domain/comdelgenerator.cpp \ |     comdel/domain/comdelgenerator.cpp \ | ||||||
|     comdel/domain/component.cpp \ |     comdel/domain/component.cpp \ | ||||||
|     comdel/domain/connection.cpp \ |     comdel/domain/connection.cpp \ | ||||||
|  |     comdel/domain/connectioninstance.cpp \ | ||||||
|     comdel/domain/display.cpp \ |     comdel/domain/display.cpp \ | ||||||
|     comdel/domain/functionsignature.cpp \ |     comdel/domain/functionsignature.cpp \ | ||||||
|  |     comdel/domain/instance.cpp \ | ||||||
|  |     comdel/domain/instanceattribute.cpp \ | ||||||
|     comdel/domain/library.cpp \ |     comdel/domain/library.cpp \ | ||||||
|     comdel/domain/pin.cpp \ |     comdel/domain/pin.cpp \ | ||||||
|     comdel/domain/rule.cpp \ |     comdel/domain/rule.cpp \ | ||||||
|  |     comdel/domain/schema.cpp \ | ||||||
|     comdel/domain/value.cpp \ |     comdel/domain/value.cpp \ | ||||||
|  |     comdel/domain/wireinstance.cpp \ | ||||||
|     comdel/parser/assert.cpp \ |     comdel/parser/assert.cpp \ | ||||||
|     comdel/parser/astnode.cpp \ |     comdel/parser/astnode.cpp \ | ||||||
|     comdel/parser/comdellexer.cpp \ |     comdel/parser/comdellexer.cpp \ | ||||||
| @ -40,12 +45,17 @@ HEADERS += \ | |||||||
|     comdel/domain/comdelgenerator.h \ |     comdel/domain/comdelgenerator.h \ | ||||||
|     comdel/domain/component.h \ |     comdel/domain/component.h \ | ||||||
|     comdel/domain/connection.h \ |     comdel/domain/connection.h \ | ||||||
|  |     comdel/domain/connectioninstance.h \ | ||||||
|     comdel/domain/display.h \ |     comdel/domain/display.h \ | ||||||
|     comdel/domain/functionsignature.h \ |     comdel/domain/functionsignature.h \ | ||||||
|  |     comdel/domain/instance.h \ | ||||||
|  |     comdel/domain/instanceattribute.h \ | ||||||
|     comdel/domain/library.h \ |     comdel/domain/library.h \ | ||||||
|     comdel/domain/pin.h \ |     comdel/domain/pin.h \ | ||||||
|     comdel/domain/rule.h \ |     comdel/domain/rule.h \ | ||||||
|  |     comdel/domain/schema.h \ | ||||||
|     comdel/domain/value.h \ |     comdel/domain/value.h \ | ||||||
|  |     comdel/domain/wireinstance.h \ | ||||||
|     comdel/parser/assert.h \ |     comdel/parser/assert.h \ | ||||||
|     comdel/parser/astnode.h \ |     comdel/parser/astnode.h \ | ||||||
|     comdel/parser/comdellexer.h \ |     comdel/parser/comdellexer.h \ | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <!DOCTYPE QtCreatorProject> | <!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> | <qtcreator> | ||||||
|  <data> |  <data> | ||||||
|   <variable>EnvironmentId</variable> |   <variable>EnvironmentId</variable> | ||||||
|  | |||||||
| @ -2,8 +2,33 @@ | |||||||
| 
 | 
 | ||||||
| namespace domain { | namespace domain { | ||||||
| 
 | 
 | ||||||
| Bus::Bus(std::string name, std::string tooltip, BusType type, std::pair<int, int> count, std::optional<Display> display) | Wire::Wire(std::string name, WireType type, int width, bool hidden, bool hasTermination, long long ifUnterminated) | ||||||
|     : name(name), tooltip(tooltip), type(type), count(count), display(display) |     : 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() { | std::string Bus::getName() { | ||||||
| @ -21,6 +46,9 @@ std::pair<int, int> Bus::getCount() { | |||||||
| std::optional<Display> Bus::getDisplay() { | std::optional<Display> Bus::getDisplay() { | ||||||
|     return display; |     return display; | ||||||
| } | } | ||||||
|  | std::vector<Wire> Bus::getWires() { | ||||||
|  |     return wires; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| } // namespace domain
 | } // namespace domain
 | ||||||
|  | |||||||
| @ -5,16 +5,48 @@ | |||||||
| 
 | 
 | ||||||
| #include <string> | #include <string> | ||||||
| #include <optional> | #include <optional> | ||||||
|  | #include <vector> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| namespace domain { | 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 | class Bus | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     enum BusType { |     enum BusType { | ||||||
|         AUTOMATIC, |         AUTOMATIC, | ||||||
|         REGULAR |         REGULAR, | ||||||
|  |         AUTOMATIC_SINGLE | ||||||
|     }; |     }; | ||||||
| private: | private: | ||||||
|     std::string name; |     std::string name; | ||||||
| @ -23,16 +55,17 @@ private: | |||||||
| 
 | 
 | ||||||
|     std::pair<int, int> count; |     std::pair<int, int> count; | ||||||
|     std::optional<Display> display; |     std::optional<Display> display; | ||||||
|  |     std::vector<Wire> wires; | ||||||
| 
 | 
 | ||||||
| public: | 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 getName(); | ||||||
|     std::string getTooltip(); |     std::string getTooltip(); | ||||||
|     BusType getType(); |     BusType getType(); | ||||||
|     std::pair<int, int> getCount(); |     std::pair<int, int> getCount(); | ||||||
|  |     std::vector<Wire> getWires(); | ||||||
|     std::optional<Display> getDisplay(); |     std::optional<Display> getDisplay(); | ||||||
| 
 |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace domain
 | } // namespace domain
 | ||||||
|  | |||||||
| @ -20,6 +20,21 @@ Action::ActionType toType(ActionNode::ActionType type) { | |||||||
|     return Action::WARNING; |     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) { | Value::ValueType toType(ValueNode::ValueType type) { | ||||||
|     switch (type) { |     switch (type) { | ||||||
|     case ValueNode::BOOL: |     case ValueNode::BOOL: | ||||||
| @ -86,31 +101,31 @@ ComdelGenerator::ComdelGenerator(std::vector<FunctionSignature> signatures) | |||||||
|     : signatures(signatures) |     : signatures(signatures) | ||||||
| {} | {} | ||||||
| 
 | 
 | ||||||
| std::optional<Library> ComdelGenerator::loadLibrary(LibraryNode node, ParseContext* parseContext, std::ostream& stream) | std::optional<Library> ComdelGenerator::loadLibrary(LibraryNode node) | ||||||
| { | { | ||||||
|     // library fields
 |     // library fields
 | ||||||
|     if(!node.name) { |     if(!node.name) { | ||||||
|         errors.push_back(SourceError{node.span, "missing @name"}); |         errors.push_back(SourceError{node.span, "missing @name"}); | ||||||
|         return nullopt; |         return nullopt; | ||||||
|  |     } else { | ||||||
|  |         name = node.name->asString(); | ||||||
|     } |     } | ||||||
|     std::string name = node.name->asString(); |  | ||||||
| 
 | 
 | ||||||
|     if(!node.componentDirectory) { |     if(!node.componentDirectory) { | ||||||
|         errors.push_back(SourceError{node.span, "missing @componentDirectory"}); |         errors.push_back(SourceError{node.span, "missing @componentDirectory"}); | ||||||
|         return nullopt; |         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) { |     for(auto& as: node.addressSpaces) { | ||||||
|         addressSpaces.push_back(*loadAddressSpace(as)); |         addressSpaces.push_back(*loadAddressSpace(as)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::vector<Component> components; |  | ||||||
|     for(auto& comp: node.components) { |     for(auto& comp: node.components) { | ||||||
|         std::optional<Component> component; |         std::optional<Component> component; | ||||||
|         component = loadComponent(comp); |         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++) { |     for(uint i=0; i<node.buses.size(); i++) { | ||||||
|         auto bus = loadBus(node.buses[i]); |         auto bus = loadBus(node.buses[i]); | ||||||
|         if(!bus) { |         if(bus) { | ||||||
|             return nullopt; |             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); |         count = std::make_pair<int, int>(node.count->first.value, node.count->second.value); | ||||||
|     } |     } | ||||||
|     if(count.first > count.second || count.first < 0) { |     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; |         return nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -173,12 +184,11 @@ std::optional<Bus> ComdelGenerator::loadBus(BusNode node) | |||||||
|         errors.push_back(SourceError{node.span, "missing @display"}); |         errors.push_back(SourceError{node.span, "missing @display"}); | ||||||
|         return nullopt; |         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"}); |         errors.push_back(SourceError{node.span, "automatic bus cannot have a @display"}); | ||||||
|         return nullopt; |         return nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     optional<Display> display; |     optional<Display> display; | ||||||
|     if(Bus::REGULAR) { |     if(Bus::REGULAR) { | ||||||
|         display = loadDisplay(*node.display); |         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) | std::optional<Connection> ComdelGenerator::loadConnection(ConnectionNode node) | ||||||
| { | { | ||||||
|  |     push(ComdelContext("connection", false, true, false)); | ||||||
|  | 
 | ||||||
|     std::string component = node.component.value; |     std::string component = node.component.value; | ||||||
|     std::string pin = node.pin.value; |     std::string pin = node.pin.value; | ||||||
|     std::string bus = node.bus.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; |     std::vector<Attribute> attributes; | ||||||
|     for(uint i=0; i<node.attributes.size(); i++) { |     for(uint i=0; i<node.attributes.size(); i++) { | ||||||
|         auto attr = loadAttribute(node.attributes[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++) { |     for(uint i=0; i<node.wires.size(); i++) { | ||||||
|         if(attributeNames.count(node.wires[i].value)) { |         if(attributeNames.count(node.wires[i].value)) { | ||||||
|             wires.push_back(Value::fromReference(node.wires[i].value, Value::ATTRIBUTE_REFERENCE)); |             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)); |             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); |     return Connection(component, pin, bus, attributes, wires); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::optional<Component> ComdelGenerator::loadComponent(ComponentNode node) | std::optional<Component> ComdelGenerator::loadComponent(ComponentNode node) | ||||||
| { | { | ||||||
|  |     push(ComdelContext(node.name.value, true, false, false)); | ||||||
|  | 
 | ||||||
|     std::string name = node.name.value; |     std::string name = node.name.value; | ||||||
| 
 | 
 | ||||||
|     if(!node.tooltip) { |     if(!node.tooltip) { | ||||||
|         errors.push_back(SourceError{node.span, "missing @tooltip"}); |         errors.push_back(SourceError{node.span, "missing @tooltip"}); | ||||||
|  |         pop(); | ||||||
|         return nullopt; |         return nullopt; | ||||||
|     } |     } | ||||||
|     std::string tooltip = node.tooltip->asString(); |     std::string tooltip = node.tooltip->asString(); | ||||||
| 
 | 
 | ||||||
|     if(!node.source) { |     if(!node.source) { | ||||||
|         errors.push_back(SourceError{node.span, "missing @source"}); |         errors.push_back(SourceError{node.span, "missing @source"}); | ||||||
|  |         pop(); | ||||||
|         return nullopt; |         return nullopt; | ||||||
|     } |     } | ||||||
|     std::string source = node.source->asString(); |     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; |     std::vector<Rule> rules; | ||||||
|     for(auto& r: node.rules) { |     for(auto& r: node.rules) { | ||||||
|         std::optional<Rule> rule = loadRule(r); |         std::optional<Rule> rule = loadRule(r); | ||||||
| @ -264,6 +314,7 @@ std::optional<Component> ComdelGenerator::loadComponent(ComponentNode node) | |||||||
| 
 | 
 | ||||||
|     if(!node.instanceName) { |     if(!node.instanceName) { | ||||||
|         errors.push_back(SourceError{node.span, "missing @instanceName"}); |         errors.push_back(SourceError{node.span, "missing @instanceName"}); | ||||||
|  |         pop(); | ||||||
|         return nullopt; |         return nullopt; | ||||||
|     } |     } | ||||||
|     std::string instanceName = node.instanceName->asString(); |     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) { |     if(count.first > count.second || count.first < 0) { | ||||||
|         errors.push_back(SourceError{node.count->first.span, "invalid @size"}); |         errors.push_back(SourceError{node.count->first.span, "invalid @size"}); | ||||||
|  |         pop(); | ||||||
|         return nullopt; |         return nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if(!node.display) { |     if(!node.display) { | ||||||
|         errors.push_back(SourceError{node.span, "missing @display"}); |         errors.push_back(SourceError{node.span, "missing @display"}); | ||||||
|  |         pop(); | ||||||
|         return nullopt; |         return nullopt; | ||||||
|     } |     } | ||||||
|     optional<Display> display = loadDisplay(*node.display); |     optional<Display> display = loadDisplay(*node.display); | ||||||
|     if(!display) { |     if(!display) { | ||||||
|  |         pop(); | ||||||
|         return nullopt; |         return nullopt; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -290,13 +344,27 @@ std::optional<Component> ComdelGenerator::loadComponent(ComponentNode node) | |||||||
|     for(uint i=0; i<node.pins.size(); i++) { |     for(uint i=0; i<node.pins.size(); i++) { | ||||||
|         auto pin = loadPin(node.pins[i]); |         auto pin = loadPin(node.pins[i]); | ||||||
|         if(!pin) { |         if(!pin) { | ||||||
|  |             pop(); | ||||||
|             return nullopt; |             return nullopt; | ||||||
|         } |         } | ||||||
|  |         pins.push_back(*pin); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     pop(); | ||||||
|     return Component(name, tooltip, source, type, rules, instanceName, count, *display, pins, attributes); |     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) | optional<Pin> ComdelGenerator::loadPin(PinNode node) | ||||||
| { | { | ||||||
|     std::string name = node.name.value; |     std::string name = node.name.value; | ||||||
| @ -344,22 +412,41 @@ PinConnection ComdelGenerator::loadPinConnection(PinConnectionNode node) | |||||||
| std::optional<Attribute> ComdelGenerator::loadAttribute(AttributeNode node) | std::optional<Attribute> ComdelGenerator::loadAttribute(AttributeNode node) | ||||||
| { | { | ||||||
|     std::string name = node.name.value; |     std::string name = node.name.value; | ||||||
|  |     pushAdditional(name); | ||||||
|     Value value; |     Value value; | ||||||
|     if(node.type == ValueNode::INT) { | 
 | ||||||
|         value = Value::fromInt(node.defaultValue->asInt()); |     if(current().inComponent) { | ||||||
|     } else if (node.type == ValueNode::BOOL) { |         if(node.type == ValueNode::INT) { | ||||||
|         value = Value::fromBool(node.defaultValue->asBool()); |             value = Value::fromInt(node.defaultValue->asInt()); | ||||||
|     } else if (node.type == ValueNode::STRING) { |         } else if (node.type == ValueNode::BOOL) { | ||||||
|         value = Value::fromString(node.defaultValue->asString()); |             value = Value::fromBool(node.defaultValue->asBool()); | ||||||
|     } else if (node.type == ValueNode::WIRE) { |         } else if (node.type == ValueNode::STRING) { | ||||||
|         value = Value::fromReference(node.defaultValue->asIdentifier(), Value::WIRE_REFERENCE); |             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; |     std::optional<Popup> popup; | ||||||
|     if(node.popup) { |     if(node.popup) { | ||||||
|         popup = loadPopup(*node.popup, name, value.getType()); |         popup = loadPopup(*node.popup, name, value.getType()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     pop(); | ||||||
|     return Attribute(name, value, popup); |     return Attribute(name, value, popup); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -367,6 +454,11 @@ std::optional<Popup> ComdelGenerator::loadPopup(PopupNode node, std::string name | |||||||
| { | { | ||||||
|     auto popupType = toType(*node.type); |     auto popupType = toType(*node.type); | ||||||
| 
 | 
 | ||||||
|  |     pushAdditional(name); | ||||||
|  | 
 | ||||||
|  |     current().attributes.clear(); | ||||||
|  |     current().attributes.push_back(Attribute(name, Value::ofType(type))); | ||||||
|  | 
 | ||||||
|     if(!node.title) { |     if(!node.title) { | ||||||
|         errors.push_back(SourceError{node.span, "missing @title"}); |         errors.push_back(SourceError{node.span, "missing @title"}); | ||||||
|         return nullopt; |         return nullopt; | ||||||
| @ -379,9 +471,6 @@ std::optional<Popup> ComdelGenerator::loadPopup(PopupNode node, std::string name | |||||||
|     } |     } | ||||||
|     std::string text = node.text->asString(); |     std::string text = node.text->asString(); | ||||||
| 
 | 
 | ||||||
|     std::vector<Attribute> attributes; |  | ||||||
|     attributes.push_back(Attribute(name, Value::ofType(type))); |  | ||||||
| 
 |  | ||||||
|     std::vector<Rule> rules; |     std::vector<Rule> rules; | ||||||
|     for(auto& r: node.rules) { |     for(auto& r: node.rules) { | ||||||
|         std::optional<Rule> rule = loadRule(r); |         std::optional<Rule> rule = loadRule(r); | ||||||
| @ -394,14 +483,29 @@ std::optional<Popup> ComdelGenerator::loadPopup(PopupNode node, std::string name | |||||||
|     if(node.enumerated) { |     if(node.enumerated) { | ||||||
|         for(uint i=0; i<node.enumeration.size(); i++) { |         for(uint i=0; i<node.enumeration.size(); i++) { | ||||||
|             if(toType(node.enumeration[i].value.getType()) != type) { |             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(), |             auto value = toType(node.enumeration[i].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); |     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].name == function) { | ||||||
|             if(signatures[i].params.size() == node.params.size()) { |             if(signatures[i].params.size() == node.params.size()) { | ||||||
|                 std::vector<Value> params; |                 std::vector<Value> params; | ||||||
|                 for(int j=0; j<signatures[i].params[i]; j++) { |                 for(uint j=0; j<signatures[i].params.size(); j++) { | ||||||
|                     params.push_back(toType(node.params[i])); |                     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; |     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
 | } // namespace domain
 | ||||||
|  | |||||||
| @ -2,6 +2,9 @@ | |||||||
| #define DOMAIN_COMDELGENERATOR_H | #define DOMAIN_COMDELGENERATOR_H | ||||||
| 
 | 
 | ||||||
| #include "library.h" | #include "library.h" | ||||||
|  | #include "schema.h" | ||||||
|  | 
 | ||||||
|  | #include <set> | ||||||
| 
 | 
 | ||||||
| #include <comdel/parser/astnode.h> | #include <comdel/parser/astnode.h> | ||||||
| #include <comdel/parser/parsecontext.h> | #include <comdel/parser/parsecontext.h> | ||||||
| @ -9,8 +12,53 @@ | |||||||
| 
 | 
 | ||||||
| namespace domain { | 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 | 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<SourceError> errors; | ||||||
|     std::vector<FunctionSignature> signatures; |     std::vector<FunctionSignature> signatures; | ||||||
| 
 | 
 | ||||||
| @ -21,11 +69,66 @@ class ComdelGenerator | |||||||
|     std::optional<Condition> loadCondition(ConditionNode node); |     std::optional<Condition> loadCondition(ConditionNode node); | ||||||
|     std::optional<Popup> loadPopup(PopupNode node, std::string name, Value::ValueType type); |     std::optional<Popup> loadPopup(PopupNode node, std::string name, Value::ValueType type); | ||||||
|     std::optional<Display> loadDisplay(DisplayNode node); |     std::optional<Display> loadDisplay(DisplayNode node); | ||||||
|  |     std::optional<Wire> loadWire(WireNode node); | ||||||
|     std::optional<Pin> loadPin(PinNode pins); |     std::optional<Pin> loadPin(PinNode pins); | ||||||
|     PinConnection loadPinConnection(PinConnectionNode node); |     PinConnection loadPinConnection(PinConnectionNode node); | ||||||
|     std::optional<Connection> loadConnection(ConnectionNode node); |     std::optional<Connection> loadConnection(ConnectionNode node); | ||||||
|     std::optional<Bus> loadBus(BusNode 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: | public: | ||||||
|     ComdelGenerator(std::vector<FunctionSignature> signatures); |     ComdelGenerator(std::vector<FunctionSignature> signatures); | ||||||
| 
 | 
 | ||||||
| @ -33,7 +136,9 @@ public: | |||||||
|         return errors; |         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
 | } // namespace domain
 | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								comdel/domain/comdelvalidator.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								comdel/domain/comdelvalidator.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -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
 | ||||||
							
								
								
									
										34
									
								
								comdel/domain/comdelvalidator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								comdel/domain/comdelvalidator.h
									
									
									
									
									
										Normal file
									
								
							| @ -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(); |     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() { | std::vector<Attribute> Component::getAttributes() { | ||||||
|     return attributes; |     return attributes; | ||||||
| } | } | ||||||
| @ -55,8 +64,16 @@ Attribute Component::getAttribute(std::string attribute) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     throw std::exception(); |     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
 | } // namespace domain
 | ||||||
|  | |||||||
| @ -55,6 +55,9 @@ public: | |||||||
| 
 | 
 | ||||||
|     std::vector<Attribute> getAttributes(); |     std::vector<Attribute> getAttributes(); | ||||||
|     Attribute getAttribute(std::string attribute); |     Attribute getAttribute(std::string attribute); | ||||||
|  |     bool hasAttribute(std::string name, Value::ValueType type); | ||||||
|  | 
 | ||||||
|  |     bool hasPin(std::string name); | ||||||
| 
 | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -36,4 +36,13 @@ Attribute Connection::getAttribute(std::string name) { | |||||||
|     throw std::exception(); |     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
 | } // namespace domain
 | ||||||
|  | |||||||
| @ -29,6 +29,7 @@ public: | |||||||
|     std::vector<Value> getWires(); |     std::vector<Value> getWires(); | ||||||
| 
 | 
 | ||||||
|     Attribute getAttribute(std::string name); |     Attribute getAttribute(std::string name); | ||||||
|  |     bool hasAttribute(std::string name); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace domain
 | } // namespace domain
 | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								comdel/domain/connectioninstance.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								comdel/domain/connectioninstance.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -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
 | ||||||
							
								
								
									
										46
									
								
								comdel/domain/connectioninstance.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								comdel/domain/connectioninstance.h
									
									
									
									
									
										Normal file
									
								
							| @ -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
 | ||||||
							
								
								
									
										17
									
								
								comdel/domain/instance.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								comdel/domain/instance.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -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
 | ||||||
							
								
								
									
										54
									
								
								comdel/domain/instance.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								comdel/domain/instance.h
									
									
									
									
									
										Normal file
									
								
							| @ -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
 | ||||||
							
								
								
									
										9
									
								
								comdel/domain/instanceattribute.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								comdel/domain/instanceattribute.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -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
 | ||||||
							
								
								
									
										26
									
								
								comdel/domain/instanceattribute.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								comdel/domain/instanceattribute.h
									
									
									
									
									
										Normal file
									
								
							| @ -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; |     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) { | AddressSpace &Library::getAddressSpace(std::string addressSpace) { | ||||||
|     for(uint i=0; i<addressSpaces.size(); i++) { |     for(uint i=0; i<addressSpaces.size(); i++) { | ||||||
|         if(addressSpaces[i].getName() == addressSpace) { |         if(addressSpaces[i].getName() == addressSpace) { | ||||||
| @ -71,6 +89,10 @@ std::optional<Connection> Library::getConnection(std::string component, std::str | |||||||
|     } |     } | ||||||
|     return nullopt; |     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) { | std::string Library::getMessage(std::string key) { | ||||||
|     return messages[key]; |     return messages[key]; | ||||||
| } | } | ||||||
|  | |||||||
| @ -43,6 +43,10 @@ public: | |||||||
|     std::vector<Bus> getBuses(); |     std::vector<Bus> getBuses(); | ||||||
|     std::vector<Connection> getConnections(); |     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(); |     std::map<std::string, std::string> getMessages(); | ||||||
| 
 | 
 | ||||||
|     AddressSpace &getAddressSpace(std::string name); |     AddressSpace &getAddressSpace(std::string name); | ||||||
| @ -51,6 +55,8 @@ public: | |||||||
|     std::optional<Connection> getConnection(std::string component, std::string pin, std::string bus); |     std::optional<Connection> getConnection(std::string component, std::string pin, std::string bus); | ||||||
|     std::string getMessage(std::string key); |     std::string getMessage(std::string key); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace domain
 | } // namespace domain
 | ||||||
|  | |||||||
							
								
								
									
										9
									
								
								comdel/domain/schema.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								comdel/domain/schema.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | #include "schema.h" | ||||||
|  | 
 | ||||||
|  | namespace domain { | ||||||
|  | 
 | ||||||
|  | Schema::Schema() | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace domain
 | ||||||
							
								
								
									
										47
									
								
								comdel/domain/schema.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								comdel/domain/schema.h
									
									
									
									
									
										Normal file
									
								
							| @ -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(); |     throw std::exception(); | ||||||
| } | } | ||||||
| std::string Value::asReference() { | 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; |         return reference; | ||||||
|     } |     } | ||||||
|     throw std::exception(); |     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 Value::fromInt(long long value) { | ||||||
|     Value val; |     Value val; | ||||||
|     val.type = Value::INT; |     val.type = Value::INT; | ||||||
|  | |||||||
| @ -45,6 +45,11 @@ public: | |||||||
|     std::string asReference(); |     std::string asReference(); | ||||||
|     AddressSpace asAddressSpace(); |     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 fromInt(long long value); | ||||||
|     static Value fromString(std::string value); |     static Value fromString(std::string value); | ||||||
|     static Value fromBool(bool value); |     static Value fromBool(bool value); | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								comdel/domain/wireinstance.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								comdel/domain/wireinstance.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | #include "wireinstance.h" | ||||||
|  | 
 | ||||||
|  | namespace domain { | ||||||
|  | 
 | ||||||
|  | WireInstance::WireInstance(std::string name, Display display) | ||||||
|  |     : name(name), display(display) | ||||||
|  | {} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } // namespace domain
 | ||||||
							
								
								
									
										23
									
								
								comdel/domain/wireinstance.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								comdel/domain/wireinstance.h
									
									
									
									
									
										Normal file
									
								
							| @ -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"; |         throw "cannot convert type to string"; | ||||||
|     } |     } | ||||||
|     std::string asIdentifier() { |     std::string asIdentifier() { | ||||||
|         if(is(IDENTIFIER)) { |         if(is(IDENTIFIER) || is(WIRE)) { | ||||||
|             return identifierValue.value(); |             return identifierValue.value(); | ||||||
|         } |         } | ||||||
|         throw "cannot convert type to identifier"; |         throw "cannot convert type to identifier"; | ||||||
| @ -271,13 +271,11 @@ struct WireNode: public AstNode | |||||||
|     WireType type; |     WireType type; | ||||||
|     IdentifierNode name; |     IdentifierNode name; | ||||||
|     NumberNode size; |     NumberNode size; | ||||||
| /*
 |  | ||||||
|     bool isTerminatedWith; |  | ||||||
|     long terminatedWith; |  | ||||||
| 
 | 
 | ||||||
|     bool isIfUntrminated; |     bool hidden; | ||||||
|     long ifUnterminated; | 
 | ||||||
| */ |     bool hasTermination; | ||||||
|  |     long long isUnterminated; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -144,7 +144,7 @@ ComdelParser::parseList(std::optional<TokenType> openDelim, | |||||||
|         vec.push_back(*item); |         vec.push_back(*item); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return std::move(vec); |     return vec; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const std::vector<SourceError> &ComdelParser::getErrors() | const std::vector<SourceError> &ComdelParser::getErrors() | ||||||
| @ -703,7 +703,7 @@ PResult<AttributeNode> ComdelParser::parseAttribute() { | |||||||
|     } else if(check(TokenType::BOOL_TYPE)) { |     } else if(check(TokenType::BOOL_TYPE)) { | ||||||
|         attribute.type = ValueNode::BOOL; |         attribute.type = ValueNode::BOOL; | ||||||
|     } else if(check(TokenType::WIRE_TYPE)) { |     } else if(check(TokenType::WIRE_TYPE)) { | ||||||
|         attribute.type = ValueNode::IDENTIFIER; |         attribute.type = ValueNode::WIRE; | ||||||
|     } else { |     } else { | ||||||
|         return unexpected(); |         return unexpected(); | ||||||
|     } |     } | ||||||
| @ -729,7 +729,7 @@ PResult<AttributeNode> ComdelParser::parseAttribute() { | |||||||
|     } else if(attribute.type == ValueNode::STRING) { |     } else if(attribute.type == ValueNode::STRING) { | ||||||
|         if(check(TokenType::STRING)) { |         if(check(TokenType::STRING)) { | ||||||
|             auto string = parseString(); |             auto string = parseString(); | ||||||
|             attribute.defaultValue = ValueNode::ofString(string->value); |             attribute.defaultValue = ValueNode::ofString(string->asString()); | ||||||
|         }  else { |         }  else { | ||||||
|             return unexpected(); |             return unexpected(); | ||||||
|         } |         } | ||||||
| @ -740,6 +740,13 @@ PResult<AttributeNode> ComdelParser::parseAttribute() { | |||||||
|         }  else { |         }  else { | ||||||
|             return unexpected(); |             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)) { |     if(check(TokenType::LBRACE)) { | ||||||
| @ -964,7 +971,7 @@ PResult<ValueNode> ComdelParser::parseValue() { | |||||||
|     if(check(TokenType::IDENTIFIER)) { |     if(check(TokenType::IDENTIFIER)) { | ||||||
|         value = ValueNode::ofIdentifier(parseIdentifier()->value); |         value = ValueNode::ofIdentifier(parseIdentifier()->value); | ||||||
|     } else if(check(TokenType::STRING)) { |     } else if(check(TokenType::STRING)) { | ||||||
|         value = ValueNode::ofString(parseString()->value); |         value = ValueNode::ofString(parseString()->asString()); | ||||||
|     } else if(check(TokenType::NUMBER)) { |     } else if(check(TokenType::NUMBER)) { | ||||||
|         value = ValueNode::ofInt(parseNumber()->value); |         value = ValueNode::ofInt(parseNumber()->value); | ||||||
|     } else if(check(TokenType::TRUE)) { |     } else if(check(TokenType::TRUE)) { | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								main.cpp
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								main.cpp
									
									
									
									
									
								
							| @ -23,13 +23,28 @@ int main(int argc, char *argv[]) | |||||||
| 
 | 
 | ||||||
|     if(schema) { |     if(schema) { | ||||||
|         std::vector<domain::FunctionSignature> signatures; |         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); |         domain::ComdelGenerator generator(signatures); | ||||||
|         generator.loadLibrary(*schema->library, &parseContext, std::cout); |         auto library = generator.loadLibrary(*schema->library); | ||||||
| 
 | 
 | ||||||
|         for (auto& error : generator.getErrors()) { |         for (auto& error : generator.getErrors()) { | ||||||
|             parseContext.formatError(error, std::cout, "ERROR: "); |             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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user