#ifndef AST_NODE_H #define AST_NODE_H #include "token.h" #include "color.h" #include "source_error.h" #include #include #include /***************************************************************************** * BASE TYPES * *****************************************************************************/ /** * AST base class, all AST node classes extend this class. Class contains basic * information about nodes location in file. */ class AstNode { public: /** Contains information about where in source file given node is located */ Span span; AstNode() = default; AstNode(AstNode &&) = default; AstNode &operator=(AstNode &&) = default; AstNode(const AstNode &) = default; AstNode &operator=(const AstNode &) = default; }; /** * AST base enum class, * Used to represent AST enums * */ template struct EnumNode : public AstNode { EnumNode() = default; explicit EnumNode(T value) : value(value) {} T value; }; /** Represents string * value contains quote-marks ("" or '' depending on string type) * */ struct StringNode : public AstNode { /** String including quote-marks*/ std::string value; /** Returns string without quote-marks */ std::string asString(); }; /** Represents identifiers */ struct IdentifierNode : public AstNode { std::string value; }; /** Represents all numbers used * All numbers must fit into long long int * */ struct NumberNode : public AstNode { long long int value = 0; explicit NumberNode(const std::string &expression); NumberNode() = default; }; /** Represents color * color comes in two formats #RRGGBB or #RRGGBBAA (AA representing opacity) * */ struct ColorNode : public AstNode { Color color; explicit ColorNode(const std::string &expression); ColorNode() = default; }; /** Represents ordered number pair */ struct NumberPairNode : public AstNode { NumberNode first; NumberNode second; NumberPairNode(NumberNode first, NumberNode second) : first(first), second(second) {} NumberPairNode() = default; }; /** Represents generic value * Because attributes can contain different value types, * this allows us to use one generic type for all attributes * */ class ValueNode : public AstNode { public: enum ValueType { /** Stores same content as NumberNode */ INT, /** Stores same content as StringNode */ STRING, /** Stores true or false */ BOOL, /** Stores wire nam or null */ WIRE, /** Default type assigned when node value is of type IdentifierNode and more correct type is assigned later */ IDENTIFIER, /** Stores memory name or null */ MEMORY, /** Stores null */ NIL, /** Store same content as ColorNode */ COLOR, }; private: /** Type determines what is stored inside ValueNode */ EnumNode type = EnumNode(NIL); /** All possible values for ValueNode are stored inside optionals */ std::optional intValue = std::nullopt; std::optional stringValue = std::nullopt; std::optional boolValue = std::nullopt; std::optional identifierValue = std::nullopt; std::optional colorValue = std::nullopt; public: ValueNode() = default; ValueType getType() const; /** Checks ValueNode is of requested type and returns it or returns default value for given type*/ long long int asInt(); std::string asString(); std::string asIdentifier(); Color asColor(); bool asBool(); /** Returns true if ValueNode is of given valueType */ bool is(ValueType valueType); /** Static methods used to generate ValueNodes of requested type */ static ValueNode ofBool(bool _value); static ValueNode ofInt(long long _value); static ValueNode ofString(std::string _value); static ValueNode ofIdentifier(std::string _value); static ValueNode ofMemory(std::optional _value); static ValueNode ofNull(); static ValueNode ofColor(Color color); static ValueNode ofWire(std::optional _value); }; /** Represents an identifier-value pair*/ struct PropertyNode : public AstNode { IdentifierNode key; ValueNode value; PropertyNode() = default; PropertyNode(IdentifierNode key, ValueNode value): key(key), value(value) {} }; /** Represents a string-value pair */ struct StringPropertyNode : public AstNode { StringNode key; ValueNode value; StringPropertyNode() = default; StringPropertyNode(StringNode key, ValueNode value): key(key), value(value) {} }; /***************************************************************************** * RULE TYPES * *****************************************************************************/ struct IfStatementNode; /** Represents validation rule * Rules are made from a list of * if - else if statements * */ struct RuleNode : public AstNode { std::vector statements; }; /** Represents condition inside if statement * Every condition is made from optional negation operator ! * Function called and list of function parameters * */ struct ConditionNode { bool negated; IdentifierNode functionName; std::vector params; }; /** Represents action executed inside if statement * */ struct ActionNode : public AstNode { /** There are two types of action determined by action type */ enum ActionType { /** Error actions represent invalid state and cause validation to fail */ ERROR, /** Warning actions represent states that can cause issue when simulating * model but models created with it are still valid * */ WARNING }; EnumNode type; /** Message used if condition is fulfilled */ StringNode message; }; /** If statements represents one validation check inside rule */ struct IfStatementNode : public AstNode { ConditionNode condition; ActionNode action; }; /***************************************************************************** * ATTRIBUTE TYPES * *****************************************************************************/ /** Represents popup dialog used to modified attribute inside which it is defined * */ struct PopupNode : public AstNode { /** Determines type of popup*/ enum PopupType { /** Automatic popup is opened when component or connection containing it is defined */ AUTOMATIC, /** On demand popups are opened on user request usually from context menus*/ ON_DEMAND }; std::optional> type; /** Title of popup */ std::optional title; /** Text of popup */ std::optional text; /** If popup contains an enumeration*/ bool enumerated; std::vector enumeration; /** Validation rules for given popup */ std::vector rules; }; /** Represents component or connection attribute * Attributes are values that can programmatically be changed * if popup is defined * */ struct AttributeNode : public AstNode { /** Type of attribute */ ValueNode::ValueType type; /** Name of attribute */ IdentifierNode name; /** Default type of attribute */ std::optional defaultValue; /** Popup used to change attribute value */ std::optional popup; }; /***************************************************************************** * DISPLAY TYPES * *****************************************************************************/ struct DisplayItemNode; /** Represents how a component or bus is rendered * Display is made from an list of display items * */ struct DisplayNode : public AstNode { std::vector items; }; /** DisplayItem represents one rendered item * in source code items are defined similar to json objects * eg. * @code rect { * x: 100; * y: 100; * w: 100; * h: 100; * fillColor: #123456 * } * */ struct DisplayItemNode : public AstNode { /** Contains type of display item */ IdentifierNode type; /** Contains all property nodes */ std::vector values; /** Returns value of requested property * If requested property doesn't exists default value is returned (eg. asInt is called but PropertyNode contains string) * If value of requested property is different than expected nullopt is retured * */ std::optional asInt(const std::string &property, long long int _default = 0); std::optional asColor(const std::string &property, Color _default = Color(0, 0, 0)); std::optional asString(const std::string &property, std::string _default = ""); private: std::optional getProperty(const std::string &property); }; /***************************************************************************** * LIBRARY TYPES * *****************************************************************************/ /** Represents AddressSpaces * Address spaces are defined with their name and address range * */ struct AddressSpaceNode : public AstNode { IdentifierNode name; /** Range represent which addresses are available for components that use memory space [first, second> */ NumberPairNode range; }; /** Pins are used to create component-component or component-bus connections */ struct PinNode : public AstNode { /** Determines pin type, pin types currently only affect how pins are rendered */ enum PinType { IN_OUT, IN, OUT }; /** Name of pin */ IdentifierNode name; /** Type of pin */ EnumNode type; /** Tooltip content displayed on hover over pin */ std::optional tooltip; /** If present this means pin must be connected to another component or bus to create connection * Connection contains error message shown * */ std::optional connection; /** Determines how the pin is displayed */ std::optional display; /** If pin connection is optional it requires list of wires used to populate comdel model */ std::optional> wires; }; /** * Represents COMDEL component * */ struct ComponentNode : public AstNode { /** Determines type of component */ enum ComponentType { /** Generic component */ OTHER, /** Represents processor, all processors have implicit attribute _memory if type memory * used when generating COMDEL model to connect memories and processors */ PROCESSOR, /** Represents memory, all components of type memory can be selected in _memory attribute of processor */ MEMORY }; /** Component name */ IdentifierNode name; /** Tooltip displayed on hover */ std::optional tooltip; /** Contains path to COMDEL source containing current component */ std::optional source; /** Type of component */ EnumNode type; /** List of component level rules */ std::vector rules; /** Default used to name instances */ std::optional instanceName; /** Count determines number of instances allowed in a schema */ std::optional count; /** Display determines how component is rendered */ std::optional display; /** List of all pins */ std::vector pins; /** List of all attributes */ std::vector attributes; }; /** WireNode represents COMDEL wire * */ struct WireNode : public AstNode { /** Determines type of wires */ enum WireType { /** Generic wire */ WIRE, /** wired_and can have multiple sources, that are ANDed together */ WIRED_AND, /** wired_and can have multiple sources, that are ORed together */ WIRED_OR, /** r_wire can remain unconnected */ R_WIRE }; EnumNode type; /** Name of wire */ IdentifierNode name; /** Number of bits inside of a wire */ NumberNode size; /** If wire is visible or hidden, this determines how wires are generated in COMDEL */ bool hidden = false; /** If wire isn't connected to anything it is replaced with terminate with terminateWith value */ bool hasTerminateWith; ValueNode terminateWith; }; /** Buses dont exist in COMDEL but they are useful * as they allow us to connect multiple COMDEL wires together * */ struct BusNode : public AstNode { enum BusType { /** This busses connect two components */ AUTOMATIC, /** * This busses allow us to connect multiple component together using one bus * */ REGULAR, /** This busses connect two components, * they differ from automatic as they allow us to connect same pins multiple times */ SINGLE_AUTOMATIC }; EnumNode type; IdentifierNode name; /** Default used to name instances */ std::optional instanceName; /** Tooltip displayed on hover */ std::optional tooltip; /** Count determines number of instances allowed in a schema */ std::optional count; /** Display determines how component is rendered */ std::optional display; /** List of all COMDEL wires contained in bus */ std::vector wires; }; /** Represents ComponentConnection key in Connection node * (eg. componentName.pinName) * */ struct ConnectionComponentNode : public AstNode { IdentifierNode component; IdentifierNode pin; }; /** Represents Connection node * Connection can be between component and bus in which second is null, * or between two components * */ struct ConnectionNode : public AstNode { ConnectionComponentNode first; std::optional second; IdentifierNode bus; std::vector attributes; /** If connection is of type component-component it contains two pairs of wires */ std::vector firstWires; std::optional> secondWires; }; /** LibraryNode represent library instance */ struct LibraryNode : public AstNode { /** Name of library */ std::optional name; /** Library info contains generic information about library */ std::optional libraryInfo; /** Contains text that is added to top of COMDEL file */ std::optional header; /** Contains path to component directory */ std::optional componentDirectory; /** Contains text that is added to top of System component in COMDEL file */ std::optional componentHeader; std::vector addressSpaces; std::vector components; std::vector buses; std::vector connections; /** Contains properties used to translate dialog and error messages */ std::vector messages; }; /***************************************************************************** * LIBRARY TYPES * *****************************************************************************/ /** Represents instance of attribute in component or connection instance */ struct InstanceAttributeNode : public AstNode { IdentifierNode name; ValueNode value; }; /** Represents instance of a component or a bus */ struct InstanceNode : public AstNode { /** Contains instance name */ IdentifierNode name; /** Contains component name */ IdentifierNode component; /** Contains position of component instance */ std::optional position; std::vector attributes; /** Contains size of bus instances */ std::optional size; }; /** Represents ComponentConnection of a selected instance */ struct ConnectionComponentInstanceNode : public AstNode { /** Name of component instance */ IdentifierNode instance; /** Name of pin */ IdentifierNode pin; }; /** Represents Connection instance */ struct ConnectionInstanceNode : public AstNode { ConnectionComponentInstanceNode first; std::optional second; IdentifierNode bus; std::vector attributes; }; /** Represent schema instance */ struct SchemaNode : public AstNode { /** Contains path to library source */ std::optional source; /** Contains list of instances */ std::vector instances; /** Contains list of connection */ std::vector connections; /** Contains library */ std::optional library; }; #endif // AST_NODE_H