#ifndef AST_NODE_H #define AST_NODE_H #include "token.h" #include "source_error.h" #include #include #include /** * 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 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 type; std::optional intValue; std::optional stringValue; std::optional boolValue; std::optional 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 _value); static ValueNode ofNull(); static ValueNode ofWire(std::optional _value); }; struct ConditionNode { bool negated; IdentifierNode functionName; std::vector params; }; class ActionNode : public AstNode { public: enum ActionType { ERROR, WARNING }; EnumNode type; StringNode message; }; struct IfStatementNode : public AstNode { ConditionNode condition; ActionNode action; }; struct RuleNode : public AstNode { std::vector statements; }; struct EnumerationNode : public AstNode { StringNode key; ValueNode value; }; struct PopupNode : public AstNode { enum PopupType { AUTOMATIC, ON_DEMAND }; std::optional> type; std::optional title; std::optional text; bool enumerated; std::vector enumeration; std::vector rules; }; struct PropertyNode : public AstNode { IdentifierNode key; ValueNode value; }; struct DisplayItemNode : public AstNode { IdentifierNode type; std::vector values; long long int asInt(std::vector *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 *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 *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 items; }; struct PinConnectionNode : public AstNode { enum ConnectionType { REQUIRED, OPTIONAL }; StringNode message; EnumNode type; }; struct PinNode : public AstNode { enum PinType { IN_OUT, IN, OUT }; IdentifierNode name; EnumNode type; std::optional tooltip; std::optional connection; std::optional display; std::optional> wires; }; struct WireNode : public AstNode { enum WireType { WIRE, WIRED_AND, WIRED_OR, R_WIRE }; EnumNode type; IdentifierNode name; NumberNode size; bool hidden = false; bool hasTerminateWith; ValueNode terminateWith; }; struct AttributeNode : public AstNode { ValueNode::ValueType type; IdentifierNode name; std::optional defaultValue; std::optional popup; }; struct ConnectionComponentNode : public AstNode { IdentifierNode component; IdentifierNode pin; }; struct ConnectionNode : public AstNode { ConnectionComponentNode first; std::optional second; IdentifierNode bus; std::vector attributes; std::vector firstWires; std::optional> secondWires; }; struct ComponentNode : public AstNode { enum ComponentType { OTHER, PROCESSOR, MEMORY }; IdentifierNode name; std::optional tooltip; std::optional source; EnumNode type; std::vector rules; std::optional instanceName; std::optional count; std::optional display; std::vector pins; std::vector attributes; }; struct BusNode : public AstNode { enum BusType { AUTOMATIC, REGULAR, SINGLE_AUTOMATIC }; EnumNode type; IdentifierNode name; std::optional tooltip; std::optional count; std::optional display; std::vector wires; }; struct LibraryNode : public AstNode { std::optional name; std::optional libraryInfo; std::optional header; std::optional componentDirectory; std::optional componentHeader; std::vector addressSpaces; std::vector components; std::vector buses; std::vector connections; std::vector messages; }; // SCHEMA models struct InstanceAttributeNode : public AstNode { IdentifierNode name; ValueNode value; }; struct InstanceNode : public AstNode { IdentifierNode name; IdentifierNode component; std::optional position; std::vector attributes; std::optional size; }; struct ConnectionComponentInstance : public AstNode { IdentifierNode instance; IdentifierNode pin; }; struct ConnectionInstanceNode : public AstNode { ConnectionComponentInstance first; std::optional second; IdentifierNode bus; std::vector attributes; }; struct SchemaNode : public AstNode { std::optional source; std::vector instances; std::vector connections; std::optional library; }; #endif // AST_NODE_H