393 lines
8.6 KiB
C++
393 lines
8.6 KiB
C++
#ifndef AST_NODE_H
|
|
#define AST_NODE_H
|
|
|
|
#include "token.h"
|
|
#include "source_error.h"
|
|
#include <optional>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
/**
|
|
* AST base class, all AST node classes extend this class. Class contains basic
|
|
* information about nodes location in file.
|
|
*/
|
|
class AstNode {
|
|
public:
|
|
|
|
Span span;
|
|
|
|
AstNode() = default;
|
|
|
|
virtual ~AstNode();
|
|
|
|
AstNode(AstNode &&) = default;
|
|
|
|
AstNode &operator=(AstNode &&) = default;
|
|
|
|
AstNode(const AstNode &) = default;
|
|
|
|
AstNode &operator=(const AstNode &) = default;
|
|
};
|
|
|
|
template<typename T>
|
|
struct EnumNode : public AstNode {
|
|
EnumNode() = default;
|
|
|
|
explicit EnumNode(T value) : value(value) {}
|
|
|
|
T value;
|
|
};
|
|
|
|
struct StringNode : public AstNode {
|
|
std::string value;
|
|
|
|
std::string asString();
|
|
};
|
|
|
|
struct IdentifierNode : public AstNode {
|
|
std::string value;
|
|
};
|
|
|
|
struct NumberNode : public AstNode {
|
|
long long int value;
|
|
|
|
explicit NumberNode(const std::string &expression);
|
|
|
|
NumberNode() : value(0) {}
|
|
};
|
|
|
|
|
|
struct CountNode : public AstNode {
|
|
NumberNode first;
|
|
NumberNode second;
|
|
|
|
CountNode(NumberNode first, NumberNode second) : first(std::move(first)), second(std::move(second)) {}
|
|
|
|
CountNode() = default;
|
|
};
|
|
|
|
|
|
struct AddressSpaceNode : public AstNode {
|
|
IdentifierNode name;
|
|
NumberNode start;
|
|
NumberNode end;
|
|
};
|
|
|
|
class ValueNode : public AstNode {
|
|
public:
|
|
enum ValueType {
|
|
INT,
|
|
STRING,
|
|
BOOL,
|
|
WIRE,
|
|
IDENTIFIER,
|
|
MEMORY,
|
|
NIL,
|
|
};
|
|
|
|
private:
|
|
EnumNode<ValueType> type;
|
|
std::optional<long long> intValue;
|
|
std::optional<std::string> stringValue;
|
|
std::optional<bool> boolValue;
|
|
std::optional<std::string> identifierValue;
|
|
|
|
public:
|
|
ValueNode() = default;
|
|
|
|
ValueType getType() const {
|
|
return type.value;
|
|
}
|
|
|
|
long long asInt();
|
|
|
|
std::string asString();
|
|
|
|
std::string asIdentifier();
|
|
|
|
bool asBool();
|
|
|
|
bool is(ValueType valueType);
|
|
|
|
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 ofWire(std::optional<std::string> _value);
|
|
};
|
|
|
|
struct ConditionNode {
|
|
bool negated;
|
|
IdentifierNode functionName;
|
|
std::vector<ValueNode> params;
|
|
};
|
|
|
|
class ActionNode : public AstNode {
|
|
public:
|
|
enum ActionType {
|
|
ERROR,
|
|
WARNING
|
|
};
|
|
|
|
EnumNode<ActionType> type;
|
|
StringNode message;
|
|
};
|
|
|
|
|
|
struct IfStatementNode : public AstNode {
|
|
ConditionNode condition;
|
|
ActionNode action;
|
|
};
|
|
|
|
struct RuleNode : public AstNode {
|
|
std::vector<IfStatementNode> statements;
|
|
};
|
|
|
|
struct EnumerationNode : public AstNode {
|
|
StringNode key;
|
|
ValueNode value;
|
|
};
|
|
|
|
struct PopupNode : public AstNode {
|
|
enum PopupType {
|
|
AUTOMATIC,
|
|
ON_DEMAND
|
|
};
|
|
|
|
std::optional<EnumNode<PopupType>> type;
|
|
std::optional<StringNode> title;
|
|
std::optional<StringNode> text;
|
|
|
|
bool enumerated;
|
|
std::vector<EnumerationNode> enumeration;
|
|
|
|
std::vector<RuleNode> rules;
|
|
};
|
|
|
|
struct PropertyNode : public AstNode {
|
|
IdentifierNode key;
|
|
ValueNode value;
|
|
};
|
|
|
|
struct DisplayItemNode : public AstNode {
|
|
IdentifierNode type;
|
|
std::vector<PropertyNode> values;
|
|
|
|
long long int asInt(std::vector<SourceError> *errors, const std::string &property, long long int _default = 0) {
|
|
for (auto &prop: values) {
|
|
if (prop.key.value == property) {
|
|
if (prop.value.is(ValueNode::INT)) {
|
|
return prop.value.asInt();
|
|
} else {
|
|
if (errors != nullptr) {
|
|
errors->emplace_back(prop.value.span, "expected number");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return _default;
|
|
}
|
|
|
|
std::string asIdentifier(std::vector<SourceError> *errors, const std::string &property, std::string _default = "") {
|
|
for (auto &prop: values) {
|
|
if (prop.key.value == property) {
|
|
if (prop.value.is(ValueNode::IDENTIFIER)) {
|
|
return prop.value.asIdentifier();
|
|
} else {
|
|
if (errors != nullptr) {
|
|
errors->emplace_back(prop.value.span, "expected identifier");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return _default;
|
|
}
|
|
|
|
|
|
std::string asString(std::vector<SourceError> *errors, const std::string &property, std::string _default = "") {
|
|
for (auto &prop: values) {
|
|
if (prop.key.value == property) {
|
|
if (prop.value.is(ValueNode::STRING)) {
|
|
return prop.value.asString();
|
|
} else {
|
|
if (errors != nullptr) {
|
|
errors->emplace_back(prop.value.span, "expected string");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return _default;
|
|
}
|
|
};
|
|
|
|
struct DisplayNode : public AstNode {
|
|
std::vector<DisplayItemNode> items;
|
|
};
|
|
|
|
struct PinConnectionNode : public AstNode {
|
|
enum ConnectionType {
|
|
REQUIRED,
|
|
OPTIONAL
|
|
};
|
|
|
|
StringNode message;
|
|
EnumNode<ConnectionType> type;
|
|
};
|
|
|
|
struct PinNode : public AstNode {
|
|
enum PinType {
|
|
IN_OUT,
|
|
IN,
|
|
OUT
|
|
};
|
|
|
|
IdentifierNode name;
|
|
EnumNode<PinType> type;
|
|
std::optional<StringNode> tooltip;
|
|
std::optional<PinConnectionNode> connection;
|
|
std::optional<DisplayNode> display;
|
|
std::optional<std::vector<ValueNode>> wires;
|
|
};
|
|
|
|
struct WireNode : public AstNode {
|
|
enum WireType {
|
|
WIRE,
|
|
WIRED_AND,
|
|
WIRED_OR,
|
|
R_WIRE
|
|
};
|
|
EnumNode<WireType> type;
|
|
IdentifierNode name;
|
|
NumberNode size;
|
|
|
|
bool hidden = false;
|
|
|
|
bool hasTerminateWith;
|
|
ValueNode terminateWith;
|
|
};
|
|
|
|
struct AttributeNode : public AstNode {
|
|
ValueNode::ValueType type;
|
|
IdentifierNode name;
|
|
std::optional<ValueNode> defaultValue;
|
|
std::optional<PopupNode> popup;
|
|
};
|
|
|
|
struct ConnectionComponentNode : public AstNode {
|
|
IdentifierNode component;
|
|
IdentifierNode pin;
|
|
};
|
|
|
|
struct ConnectionNode : public AstNode {
|
|
ConnectionComponentNode first;
|
|
std::optional<ConnectionComponentNode> second;
|
|
|
|
IdentifierNode bus;
|
|
std::vector<AttributeNode> attributes;
|
|
|
|
std::vector<ValueNode> firstWires;
|
|
std::optional<std::vector<ValueNode>> secondWires;
|
|
};
|
|
|
|
struct ComponentNode : public AstNode {
|
|
enum ComponentType {
|
|
OTHER,
|
|
PROCESSOR,
|
|
MEMORY
|
|
};
|
|
|
|
IdentifierNode name;
|
|
std::optional<StringNode> tooltip;
|
|
std::optional<StringNode> source;
|
|
EnumNode<ComponentType> type;
|
|
std::vector<RuleNode> rules;
|
|
std::optional<IdentifierNode> instanceName;
|
|
std::optional<CountNode> count;
|
|
std::optional<DisplayNode> display;
|
|
std::vector<PinNode> pins;
|
|
std::vector<AttributeNode> attributes;
|
|
};
|
|
|
|
struct BusNode : public AstNode {
|
|
enum BusType {
|
|
AUTOMATIC,
|
|
REGULAR,
|
|
SINGLE_AUTOMATIC
|
|
};
|
|
|
|
EnumNode<BusType> type;
|
|
IdentifierNode name;
|
|
std::optional<IdentifierNode> instanceName;
|
|
std::optional<StringNode> tooltip;
|
|
std::optional<CountNode> count;
|
|
std::optional<DisplayNode> display;
|
|
|
|
std::vector<WireNode> wires;
|
|
};
|
|
|
|
struct LibraryNode : public AstNode {
|
|
std::optional<StringNode> name;
|
|
std::optional<StringNode> libraryInfo;
|
|
std::optional<StringNode> header;
|
|
std::optional<StringNode> componentDirectory;
|
|
std::optional<StringNode> componentHeader;
|
|
|
|
std::vector<AddressSpaceNode> addressSpaces;
|
|
|
|
std::vector<ComponentNode> components;
|
|
std::vector<BusNode> buses;
|
|
std::vector<ConnectionNode> connections;
|
|
|
|
std::vector<PropertyNode> messages;
|
|
};
|
|
|
|
// SCHEMA models
|
|
struct InstanceAttributeNode : public AstNode {
|
|
IdentifierNode name;
|
|
ValueNode value;
|
|
};
|
|
|
|
struct InstanceNode : public AstNode {
|
|
IdentifierNode name;
|
|
IdentifierNode component;
|
|
|
|
std::optional<CountNode> position;
|
|
std::vector<InstanceAttributeNode> attributes;
|
|
|
|
std::optional<NumberNode> size;
|
|
};
|
|
|
|
struct ConnectionComponentInstance : public AstNode {
|
|
IdentifierNode instance;
|
|
IdentifierNode pin;
|
|
};
|
|
|
|
struct ConnectionInstanceNode : public AstNode {
|
|
ConnectionComponentInstance first;
|
|
std::optional<ConnectionComponentInstance> second;
|
|
|
|
IdentifierNode bus;
|
|
|
|
std::vector<InstanceAttributeNode> attributes;
|
|
};
|
|
|
|
|
|
struct SchemaNode : public AstNode {
|
|
std::optional<StringNode> source;
|
|
|
|
std::vector<InstanceNode> instances;
|
|
std::vector<ConnectionInstanceNode> connections;
|
|
|
|
std::optional<LibraryNode> library;
|
|
};
|
|
|
|
#endif // AST_NODE_H
|