Refactored state

This commit is contained in:
Borna Rajkovic committed 2022-04-24 22:21:45 +02:00
1 parent 9e2b0f6c3c
commit d6c1023df2
23 files changed
+697 -215

No files matched your search

+86 -1
View File
@@ -1,8 +1,12 @@
#include "astnode.h"
/*************************** AST NODE ********************************/
AstNode::~AstNode() = default;
NumberNode::NumberNode(std::string expression) {
/*************************** NUMBER NODE ********************************/
NumberNode::NumberNode(const std::string& expression) {
if(expression.size() > 2) {
if(expression.substr(0, 2) == "0x") {
this->value = std::stoll(expression, 0, 16);
@@ -15,3 +19,84 @@ NumberNode::NumberNode(std::string expression) {
this->value = std::stoll(expression, 0, 10);
}
}
/*************************** STRING NODE ********************************/
std::string StringNode::asString() {
return value.substr(1, value.length() - 2);
}
/*************************** VALUE NODE ********************************/
long long ValueNode::asInt() {
if(is(INT)) {
return intValue.value();
}
return 0;
}
std::string ValueNode::asString() {
if(is(STRING)) {
return stringValue.value();
}
return "";
}
std::string ValueNode::asIdentifier() {
if(is(IDENTIFIER) || is(WIRE)) {
return identifierValue.value();
}
return "";
}
bool ValueNode::asBool() {
if(is(BOOL)) {
return boolValue.value();
}
return false;
}
bool ValueNode::is(ValueNode::ValueType valueType) {
return type.value == valueType;
}
ValueNode ValueNode::ofBool(bool _value) {
ValueNode value;
value.type = EnumNode(BOOL);
value.boolValue = std::optional<bool>(_value);
return value;
}
ValueNode ValueNode::ofInt(long long int _value) {
ValueNode value;
value.type = EnumNode(INT);
value.intValue = std::optional<long long>(_value);
return value;
}
ValueNode ValueNode::ofString(std::string _value) {
ValueNode value;
value.type = EnumNode(STRING);
value.stringValue = std::optional<std::string>(_value);
return value;
}
ValueNode ValueNode::ofIdentifier(std::string _value) {
ValueNode value;
value.type = EnumNode(IDENTIFIER);
value.identifierValue = std::optional<std::string>(_value);
return value;
}
ValueNode ValueNode::ofNull() {
ValueNode value;
value.type = EnumNode(NIL);
return value;
}
ValueNode ValueNode::ofWire(std::string _value) {
ValueNode value;
value.type = EnumNode(WIRE);
value.identifierValue = std::optional<std::string>(_value);
return value;
}
+38 -104
View File
@@ -16,24 +16,27 @@ public:
AstNode() = default;
virtual ~AstNode(); // this is defined in Ast.cpp just so that the
// compiler doesn't complain about not knowing which
// object file to include the vtable in
AstNode(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() {
return value.substr(1, value.length() - 2);
}
std::string asString();
};
struct IdentifierNode: public AstNode
@@ -43,7 +46,7 @@ struct IdentifierNode: public AstNode
struct NumberNode: public AstNode {
long long int value;
NumberNode(std::string expression);
explicit NumberNode(const std::string& expression);
NumberNode(): value(0) {}
};
@@ -54,7 +57,7 @@ struct CountNode: public AstNode
NumberNode second;
CountNode(NumberNode first, NumberNode second): first(first), second(second) {}
CountNode() {}
CountNode() = default;
};
@@ -65,7 +68,6 @@ struct AddressSpaceNode: public AstNode
NumberNode end;
};
class ValueNode: public AstNode
{
public:
@@ -78,89 +80,32 @@ public:
NIL,
};
private:
ValueType type;
EnumNode<ValueType> type;
std::optional<long long> intValue;
std::optional<std::string> stringValue;
std::optional<bool> boolValue;
std::optional<std::string> identifierValue;
public:
ValueNode() {};
ValueNode() = default;;
ValueType getType() {
return type;
}
long long asInt() {
if(is(INT)) {
return intValue.value();
}
throw "cannot convert type to int";
}
std::string asString() {
if(is(STRING)) {
return stringValue.value();
}
throw "cannot convert type to string";
}
std::string asIdentifier() {
if(is(IDENTIFIER) || is(WIRE)) {
return identifierValue.value();
}
throw "cannot convert type to identifier";
}
bool asBool() {
if(is(BOOL)) {
return boolValue.value();
}
throw "cannot convert type to bool";
return type.value;
}
long long asInt();
std::string asString();
std::string asIdentifier();
bool asBool();
bool is(ValueType type) {
return this->type == type;
}
bool is(ValueType valueType);
static ValueNode ofBool(bool _value) {
ValueNode value;
value.type = BOOL;
value.boolValue = std::optional<bool>(_value);
return value;
}
static ValueNode ofInt(long long _value) {
ValueNode value;
value.type = INT;
value.intValue = std::optional<long long>(_value);
return value;
}
static ValueNode ofString(std::string _value) {
ValueNode value;
value.type = STRING;
value.stringValue = std::optional<std::string>(_value);
return value;
}
static ValueNode ofIdentifier(std::string _value) {
ValueNode value;
value.type = IDENTIFIER;
value.identifierValue = std::optional<std::string>(_value);
return value;
}
static ValueNode ofNull() {
ValueNode value;
value.type = NIL;
return value;
}
static ValueNode ofWire(std::string _value) {
ValueNode value;
value.type = WIRE;
value.identifierValue = std::optional<std::string>(_value);
return value;
}
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 ofNull();
static ValueNode ofWire(std::string _value);
};
struct ConditionNode
@@ -177,7 +122,7 @@ public:
WARNING
};
ActionType type;
EnumNode<ActionType> type;
StringNode message;
};
@@ -188,14 +133,11 @@ struct IfStatementNode: public AstNode
ActionNode action;
};
struct RuleNode: public AstNode
{
std::vector<IfStatementNode> statements;
};
struct EnumerationNode: public AstNode
{
StringNode key;
@@ -209,7 +151,7 @@ struct PopupNode: public AstNode
ON_DEMAND
};
std::optional<PopupType> type;
std::optional<EnumNode<PopupType>> type;
std::optional<StringNode> title;
std::optional<StringNode> text;
@@ -225,20 +167,17 @@ struct PropertyNode: public AstNode
ValueNode value;
};
struct DisplayItemNode: public AstNode
{
IdentifierNode type;
std::vector<PropertyNode> values;
};
struct DisplayNode: public AstNode
{
std::vector<DisplayItemNode> items;
};
struct PinConnectionNode: public AstNode
{
enum ConnectionType {
@@ -247,10 +186,9 @@ struct PinConnectionNode: public AstNode
};
StringNode message;
ConnectionType type;
EnumNode<ConnectionType> type;
};
struct PinNode: public AstNode
{
enum PinType {
@@ -260,14 +198,13 @@ struct PinNode: public AstNode
};
IdentifierNode name;
PinType type;
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 {
@@ -276,17 +213,16 @@ struct WireNode: public AstNode
WIRED_OR,
R_WIRE
};
WireType type;
EnumNode<WireType> type;
IdentifierNode name;
NumberNode size;
bool hidden;
bool hasTermination;
long long isUnterminated;
bool hasTerminateWith;
ValueNode terminateWith;
};
struct AttributeNode: public AstNode
{
ValueNode::ValueType type;
@@ -324,7 +260,7 @@ struct ComponentNode: public AstNode
IdentifierNode name;
std::optional<StringNode> tooltip;
std::optional<StringNode> source;
ComponentType type;
EnumNode<ComponentType> type;
std::vector<RuleNode> rules;
std::optional<StringNode> instanceName;
std::optional<CountNode> count;
@@ -333,7 +269,6 @@ struct ComponentNode: public AstNode
std::vector<AttributeNode> attributes;
};
struct BusNode: public AstNode
{
enum BusType {
@@ -341,7 +276,7 @@ struct BusNode: public AstNode
REGULAR
};
BusType type;
EnumNode<BusType> type;
IdentifierNode name;
std::optional<StringNode> tooltip;
std::optional<CountNode> count;
@@ -367,8 +302,6 @@ struct LibraryNode: public AstNode
};
// SCHEMA models
struct WireInstanceNode: public AstNode
{
IdentifierNode name;
@@ -393,7 +326,8 @@ struct InstanceNode: public AstNode
std::optional<NumberNode> size;
};
struct ConnectionComponentInstance {
struct ConnectionComponentInstance: public AstNode
{
IdentifierNode instance;
IdentifierNode pin;
};
+106 -56
View File
@@ -409,15 +409,7 @@ PResult<ComponentNode> ComdelParser::parseComponent()
ASSIGN_OR_RETURN_IF_ERR(component.name, parseIdentifier());
if(check(TokenType::CT_PROCESSOR)) {
bump();
component.type = ComponentNode::PROCESSOR;
} else if(check(TokenType::CT_MEMORY)) {
bump();
component.type = ComponentNode::MEMORY;
} else {
component.type = ComponentNode::OTHER;
}
auto type = parseComponentType();
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
@@ -452,6 +444,23 @@ PResult<ComponentNode> ComdelParser::parseComponent()
return spanner(component);
}
PResult<EnumNode<ComponentNode::ComponentType>> ComdelParser::parseComponentType() {
EnumNode<ComponentNode::ComponentType> type;
auto spanner = getSpanner();
if(check(TokenType::CT_PROCESSOR)) {
bump();
type = EnumNode(ComponentNode::PROCESSOR);
} else if(check(TokenType::CT_MEMORY)) {
bump();
type = EnumNode(ComponentNode::MEMORY);
} else {
type = EnumNode(ComponentNode::OTHER);
}
return spanner(type);
}
/****************************************************************************
*
@@ -509,18 +518,10 @@ PResult<BusNode> ComdelParser::parseBus() {
ASSIGN_OR_RETURN_IF_ERR(bus.name, parseIdentifier());
if(check(TokenType::IDENTIFIER)) {
auto tokenType = parseIdentifier();
if(tokenType.value().value == "automatic") {
bus.type = BusNode::AUTOMATIC;
} else if(tokenType.value().value == "regular") {
bus.type = BusNode::REGULAR;
} else {
return PError(SourceError{current().span, "expected 'automatic' or 'regular'"});
}
} else {
return PError(SourceError{current().span, "expected 'automatic' or 'regular'"});
}
auto type = parseBusType();
RETURN_IF_ERR(type);
bus.type = *type;
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
@@ -553,10 +554,28 @@ PResult<BusNode> ComdelParser::parseBus() {
return spanner(bus);
}
PResult<EnumNode<BusNode::BusType>> ComdelParser::parseBusType() {
PResult<EnumNode<BusNode::BusType>> type;
if(check(TokenType::IDENTIFIER)) {
auto tokenType = parseIdentifier();
if(tokenType.value().value == "automatic") {
type = EnumNode(BusNode::AUTOMATIC);
} else if(tokenType.value().value == "regular") {
type = EnumNode(BusNode::REGULAR);
} else {
type = PError(SourceError{current().span, "expected 'automatic' or 'regular'"});
}
} else {
type = PError(SourceError{current().span, "expected 'automatic' or 'regular'"});
}
return type;
}
/****************************************************************************
*
* WireNode := NAME(<SIZE>){0,1} TYPE)*
* WireNode := NAME(<SIZE>){0,1} TYPE [hidden | terminated_with (#number | null)])*
*
****************************************************************************/
PResult<WireNode> ComdelParser::parseWire() {
@@ -574,20 +593,42 @@ PResult<WireNode> ComdelParser::parseWire() {
}
// default
wire.type = WireNode::WIRE;
wire.type = EnumNode(WireNode::WIRE);
if(check(TokenType::WIRE_DEFAULT)) {
bump();
wire.type = WireNode::WIRE;
wire.type = EnumNode(WireNode::WIRE);
} else if(check(TokenType::WIRE_AND)) {
bump();
wire.type = WireNode::WIRED_AND;
wire.type = EnumNode(WireNode::WIRED_AND);
} else if(check(TokenType::WIRE_OR)) {
bump();
wire.type = WireNode::WIRED_OR;
wire.type = EnumNode(WireNode::WIRED_OR);
} else if(check(TokenType::R_WIRE)) {
bump();
wire.type = WireNode::R_WIRE;
wire.type = EnumNode(WireNode::R_WIRE);
}
while(true) {
if(check(TokenType::HIDDEN)) {
bump();
wire.hidden = true;
} else if(check(TokenType::TERMINATE_WITH)) {
bump();
wire.hasTerminateWith = true;
if(check(TokenType::NIL)) {
bump();
wire.terminateWith = ValueNode::ofNull();
} else if(check(TokenType::NUMBER)) {
auto number = parseNumber();
wire.terminateWith = ValueNode::ofInt(number->value);
} else {
auto token = current();
return PError(SourceError{token.span, "unexpected token"});
}
} else {
break;
}
}
return spanner(wire);
@@ -613,13 +654,13 @@ PResult<PinNode> ComdelParser::parsePin() {
if(check(TokenType::PIN_IN)) {
bump();
pin.type = PinNode::IN;
pin.type = EnumNode(PinNode::IN);
} else if(check(TokenType::PIN_OUT)) {
bump();
pin.type = PinNode::OUT;
pin.type = EnumNode(PinNode::OUT);
} else if(check(TokenType::PIN_IN_OUT)) {
bump();
pin.type = PinNode::IN_OUT;
pin.type = EnumNode(PinNode::IN_OUT);
} else {
return unexpected();
}
@@ -662,18 +703,7 @@ PResult<PinConnectionNode> ComdelParser::parsePinConnection() {
RETURN_IF_NOT_TOKEN(TokenType::KW_CONNECTION);
if(check(TokenType::IDENTIFIER)) {
auto type = parseIdentifier();
if(type.value().value == "check_only") {
connection.type = PinConnectionNode::CHECK_ONLY;
} else if(type.value().value == "automatically") {
connection.type = PinConnectionNode::AUTOMATICALLY;
} else {
return PError(SourceError{current().span, "expected identifiers 'check_only' or 'automatically'"});
}
} else {
return PError(SourceError{current().span, "expected identifiers 'check_only' or 'automatically'"});
}
ASSIGN_OR_RETURN_IF_ERR(connection.type, parseConnectionType());
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
ASSIGN_OR_RETURN_IF_ERR(connection.message, parseString());
@@ -682,6 +712,26 @@ PResult<PinConnectionNode> ComdelParser::parsePinConnection() {
return spanner(connection);
}
PResult<EnumNode<PinConnectionNode::ConnectionType>> ComdelParser::parseConnectionType() {
auto spanner = getSpanner();
EnumNode<PinConnectionNode::ConnectionType> type;
if(check(TokenType::IDENTIFIER)) {
auto identifier = parseIdentifier();
if(identifier.value().value == "check_only") {
type = EnumNode(PinConnectionNode::CHECK_ONLY);
} else if(identifier.value().value == "automatically") {
type = EnumNode(PinConnectionNode::AUTOMATICALLY);
} else {
return PError(SourceError{current().span, "expected identifiers 'check_only' or 'automatically'"});
}
} else {
return PError(SourceError{current().span, "expected identifiers 'check_only' or 'automatically'"});
}
return spanner(type);
}
/****************************************************************************
*
@@ -808,16 +858,16 @@ PResult<PopupNode> ComdelParser::parsePopup() {
RETURN_IF_NOT_TOKEN(TokenType::KW_POPUP);
if(check(TokenType::IDENTIFIER)) {
auto type = parseIdentifier();
if(type.value().value == "automatic") {
popup.type = PopupNode::AUTOMATIC;
} else if(type.value().value == "on_demand") {
popup.type = PopupNode::ON_DEMAND;
auto identifier = parseIdentifier();
if(identifier.value().value == "automatic") {
popup.type = EnumNode(PopupNode::AUTOMATIC);
} else if(identifier.value().value == "on_demand") {
popup.type = EnumNode(PopupNode::ON_DEMAND);
} else {
return PError(SourceError{current().span, "expected type 'automatic', 'on_demand'"});
}
} else {
popup.type = PopupNode::ON_DEMAND;
popup.type = EnumNode(PopupNode::ON_DEMAND);
}
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
@@ -975,9 +1025,9 @@ PResult<IfStatementNode> ComdelParser::parseIfStatement() {
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
if(check(TokenType::ERROR)) {
ifStatement.action.type = ActionNode::ERROR;
ifStatement.action.type = EnumNode(ActionNode::ERROR);
} else if(check(TokenType::WARNING)) {
ifStatement.action.type = ActionNode::WARNING;
ifStatement.action.type = EnumNode(ActionNode::WARNING);
} else {
return unexpected();
}
@@ -1029,21 +1079,21 @@ std::optional<SchemaNode> ComdelParser::parseSchema() {
auto source = parseString();
schema.source = *source;
} else {
errors.push_back(SourceError{current().span, "expected `@source`"});
errors.emplace_back(current().span, "expected `@source`");
return std::nullopt;
}
} else {
errors.push_back(SourceError{current().span, "expected `@source`"});
errors.emplace_back(current().span, "expected `@source`");
return std::nullopt;
}
if(!check(TokenType::KW_SCHEMA)) {
errors.push_back(SourceError{current().span, "expected `@schema`"});
errors.emplace_back(current().span, "expected `@schema`");
return std::nullopt;
}
bump();
if(!check(TokenType::LBRACE)) {
errors.push_back(SourceError{current().span, "expected `{`"});
errors.emplace_back(current().span, "expected `{`");
return std::nullopt;
}
bump();
@@ -1065,14 +1115,14 @@ std::optional<SchemaNode> ComdelParser::parseSchema() {
}
}
if(!check(TokenType::RBRACE)) {
errors.push_back(SourceError{current().span, "expected `}`"});
errors.emplace_back(current().span, "expected `}`");
return std::nullopt;
} else {
bump();
}
if(!check(TokenType::END_OF_FILE)) {
errors.push_back(SourceError{current().span, "expected `EOF`"});
errors.emplace_back(current().span, "expected `EOF`");
}
if (errors.size())
+6
View File
@@ -97,6 +97,12 @@ public:
std::optional<SchemaNode> parseSchema();
std::optional<LibraryNode> parse();
const std::vector<SourceError>& getErrors();
PResult<EnumNode<ComponentNode::ComponentType>> parseComponentType();
PResult<EnumNode<BusNode::BusType>> parseBusType();
PResult<EnumNode<PinConnectionNode::ConnectionType>> parseConnectionType();
};
#endif // COMDEL_PARSER_H
-6
View File
@@ -1,6 +0,0 @@
#include "parser_util.h"
parser_util::parser_util()
{
}
-11
View File
@@ -1,11 +0,0 @@
#ifndef PARSER_UTIL_H
#define PARSER_UTIL_H
class parser_util
{
public:
parser_util();
};
#endif // PARSER_UTIL_H
+4
View File
@@ -124,6 +124,10 @@ enum class TokenType {
ERROR,
WARNING,
// WIRE SETTINGS
HIDDEN,
TERMINATE_WITH,
// OTHER
END_OF_FILE
};
+4 -4
View File
@@ -134,10 +134,10 @@ TokenTables::TokenTables() {
add( TokenType::WARNING, "warning", TOKENIZABLE),
// Built-in functions (they are also keywords)
/*
* TODO
*/
// WireNode settings types
add( TokenType::HIDDEN, "hidden", TOKENIZABLE),
add( TokenType::TERMINATE_WITH, "terminate_with", TOKENIZABLE),
// Miscelaneous
add( TokenType::END_OF_FILE, "eof" );
}