schema_editor/comdel/parser/ast_nodes.h

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