554 lines
17 KiB
C++
554 lines
17 KiB
C++
#ifndef AST_NODE_H
|
|
#define AST_NODE_H
|
|
|
|
#include "token.h"
|
|
#include "color.h"
|
|
#include "source_error.h"
|
|
#include <optional>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
/*****************************************************************************
|
|
* 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<typename T>
|
|
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<ValueType> type = EnumNode(NIL);
|
|
/** All possible values for ValueNode are stored inside optionals */
|
|
std::optional<long long> intValue = std::nullopt;
|
|
std::optional<std::string> stringValue = std::nullopt;
|
|
std::optional<bool> boolValue = std::nullopt;
|
|
std::optional<std::string> identifierValue = std::nullopt;
|
|
std::optional<Color> 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<std::string> _value);
|
|
static ValueNode ofNull();
|
|
static ValueNode ofColor(Color color);
|
|
static ValueNode ofWire(std::optional<std::string> _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<IfStatementNode> 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<ValueNode> 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<ActionType> 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<EnumNode<PopupType>> type;
|
|
/** Title of popup */
|
|
std::optional<StringNode> title;
|
|
/** Text of popup */
|
|
std::optional<StringNode> text;
|
|
|
|
/** If popup contains an enumeration*/
|
|
bool enumerated;
|
|
std::vector<StringPropertyNode> enumeration;
|
|
|
|
/** Validation rules for given popup */
|
|
std::vector<RuleNode> 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;
|
|
/** Display name */
|
|
std::optional<StringNode> displayName;
|
|
/** Default type of attribute */
|
|
std::optional<ValueNode> defaultValue;
|
|
/** Popup used to change attribute value */
|
|
std::optional<PopupNode> 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<DisplayItemNode> 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<PropertyNode> 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<long long int> asInt(const std::string &property, long long int _default = 0);
|
|
std::optional<Color> asColor(const std::string &property, Color _default = Color(0, 0, 0));
|
|
std::optional<std::string> asString(const std::string &property, std::string _default = "");
|
|
|
|
private:
|
|
std::optional<PropertyNode> 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<PinType> type;
|
|
/** Tooltip content displayed on hover over pin */
|
|
std::optional<StringNode> tooltip;
|
|
/** If present this means pin must be connected to another component or bus to create connection
|
|
* Connection contains error message shown
|
|
* */
|
|
std::optional<StringNode> connection;
|
|
/** Determines how the pin is displayed */
|
|
std::optional<DisplayNode> display;
|
|
/** If pin connection is optional it requires list of wires used to populate comdel model */
|
|
std::optional<std::vector<ValueNode>> 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;
|
|
/** Component name */
|
|
std::optional<StringNode> displayName;
|
|
/** Tooltip displayed on hover */
|
|
std::optional<StringNode> tooltip;
|
|
/** Contains path to COMDEL source containing current component */
|
|
std::optional<StringNode> source;
|
|
/** Type of component */
|
|
EnumNode<ComponentType> type;
|
|
/** List of component level rules */
|
|
std::vector<RuleNode> rules;
|
|
/** Default used to name instances */
|
|
std::optional<IdentifierNode> instanceName;
|
|
/** Count determines number of instances allowed in a schema */
|
|
std::optional<NumberPairNode> count;
|
|
/** Display determines how component is rendered */
|
|
std::optional<DisplayNode> display;
|
|
/** List of all pins */
|
|
std::vector<PinNode> pins;
|
|
/** List of all attributes */
|
|
std::vector<AttributeNode> 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<WireType> 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 = false;
|
|
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<BusType> type;
|
|
/** Bus name */
|
|
IdentifierNode name;
|
|
/** Display name */
|
|
std::optional<StringNode> displayName;
|
|
/** Default used to name instances */
|
|
std::optional<IdentifierNode> instanceName;
|
|
/** Tooltip displayed on hover */
|
|
std::optional<StringNode> tooltip;
|
|
/** Count determines number of instances allowed in a schema */
|
|
std::optional<NumberPairNode> count;
|
|
/** Display determines how component is rendered */
|
|
std::optional<DisplayNode> display;
|
|
|
|
/** List of all COMDEL wires contained in bus */
|
|
std::vector<WireNode> 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<ConnectionComponentNode> second;
|
|
|
|
IdentifierNode bus;
|
|
std::vector<AttributeNode> attributes;
|
|
|
|
/** If connection is of type component-component it contains two pairs of wires */
|
|
std::vector<ValueNode> firstWires;
|
|
std::optional<std::vector<ValueNode>> secondWires;
|
|
};
|
|
|
|
/** LibraryNode represent library instance */
|
|
struct LibraryNode : public AstNode {
|
|
/** Name of library */
|
|
std::optional<StringNode> name;
|
|
/** Library info contains generic information about library */
|
|
std::optional<StringNode> libraryInfo;
|
|
/** Contains text that is added to top of COMDEL file */
|
|
std::optional<StringNode> header;
|
|
/** Contains path to component directory */
|
|
std::optional<StringNode> componentDirectory;
|
|
/** Contains text that is added to top of System component in COMDEL file */
|
|
std::optional<StringNode> componentHeader;
|
|
|
|
std::vector<AddressSpaceNode> addressSpaces;
|
|
|
|
std::vector<ComponentNode> components;
|
|
std::vector<BusNode> buses;
|
|
std::vector<ConnectionNode> connections;
|
|
|
|
/** Contains properties used to translate dialog and error messages */
|
|
std::vector<PropertyNode> 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<NumberPairNode> position;
|
|
std::vector<InstanceAttributeNode> attributes;
|
|
|
|
/** Contains size of bus instances */
|
|
std::optional<NumberNode> 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<ConnectionComponentInstanceNode> second;
|
|
|
|
IdentifierNode bus;
|
|
|
|
std::vector<InstanceAttributeNode> attributes;
|
|
};
|
|
|
|
/** Represent schema instance */
|
|
struct SchemaNode : public AstNode {
|
|
/** Contains path to library source */
|
|
std::optional<StringNode> source;
|
|
|
|
/** Contains list of instances */
|
|
std::vector<InstanceNode> instances;
|
|
/** Contains list of connection */
|
|
std::vector<ConnectionInstanceNode> connections;
|
|
|
|
/** Contains library */
|
|
std::optional<LibraryNode> library;
|
|
};
|
|
|
|
#endif // AST_NODE_H
|