Refactored state
This commit is contained in:
1 parent
9e2b0f6c3c
commit
d6c1023df2
23 files changed
+697
-215
No files matched your search
@@ -9,10 +9,10 @@ AddressSpace::AddressSpace(std::string name, long long start, long long end):
|
||||
std::string AddressSpace::getName() {
|
||||
return name;
|
||||
}
|
||||
long long AddressSpace::getStart() {
|
||||
long long AddressSpace::getStart() const {
|
||||
return start;
|
||||
}
|
||||
long long AddressSpace::getEnd() {
|
||||
long long AddressSpace::getEnd() const {
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ public:
|
||||
AddressSpace(std::string name, long long start, long long end);
|
||||
|
||||
std::string getName();
|
||||
long long getStart();
|
||||
long long getEnd();
|
||||
long long getStart() const;
|
||||
long long getEnd() const;
|
||||
|
||||
bool contains(long long int address);
|
||||
bool contains(long long int start, long long int end);
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace domain {
|
||||
|
||||
Wire::Wire(std::string name, WireType type, int width, bool hidden, bool hasTermination, long long ifUnterminated)
|
||||
: name(name), type(type), width(width), hidden(hidden), hasTermination(hasTermination), ifUnterminated(ifUnterminated)
|
||||
Wire::Wire(std::string name, WireType type, int width, bool hidden, bool hasTerminate, Value terminateWith)
|
||||
: name(name), type(type), width(width), hidden(hidden), hasTerminate(hasTerminate), terminateWith(terminateWith)
|
||||
{}
|
||||
|
||||
std::string Wire::getName() {
|
||||
@@ -15,18 +15,17 @@ int Wire::getWidth() {
|
||||
bool Wire::isHidden() {
|
||||
return hidden;
|
||||
}
|
||||
bool Wire::getHasTermination() {
|
||||
return hasTermination;
|
||||
|
||||
bool Wire::hasTerminateWith() {
|
||||
return hasTerminate;
|
||||
}
|
||||
long long Wire::getIfUnterminated() {
|
||||
return ifUnterminated;
|
||||
Value Wire::getTerminateWith() {
|
||||
return terminateWith;
|
||||
}
|
||||
Wire::WireType Wire::getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Bus::Bus(std::string name, std::string tooltip, BusType type, std::pair<int, int> count, std::vector<Wire> wires, std::optional<Display> display)
|
||||
: name(name), tooltip(tooltip), type(type), count(count), wires(wires), display(display)
|
||||
{}
|
||||
|
||||
+6
-5
@@ -2,6 +2,7 @@
|
||||
#define DOMAIN_BUS_H
|
||||
|
||||
#include "display.h"
|
||||
#include "value.h"
|
||||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
@@ -26,17 +27,17 @@ private:
|
||||
WireType type;
|
||||
int width;
|
||||
bool hidden;
|
||||
bool hasTermination;
|
||||
long long ifUnterminated;
|
||||
bool hasTerminate;
|
||||
Value terminateWith;
|
||||
|
||||
public:
|
||||
Wire(std::string name, WireType type, int width, bool hidden, bool hasTermination, long long ifUnterminated);
|
||||
Wire(std::string name, WireType type, int width, bool hidden, bool hasTerminate, Value terminateWith);
|
||||
|
||||
std::string getName();
|
||||
int getWidth();
|
||||
bool isHidden();
|
||||
bool getHasTermination();
|
||||
long long getIfUnterminated();
|
||||
bool hasTerminateWith();
|
||||
Value getTerminateWith();
|
||||
WireType getType();
|
||||
};
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ public:
|
||||
Connection connection;
|
||||
WireInstance *wire;
|
||||
|
||||
virtual ~ConnectionInstance() = default;
|
||||
|
||||
std::vector<InstanceAttribute*> attributes;
|
||||
|
||||
ConnectionInstance(ComponentInstance *instance, std::vector<InstanceAttribute*> attributes, WireInstance *wire, Connection connection);
|
||||
|
||||
@@ -174,7 +174,7 @@ std::optional<Bus> SchemaCreator::loadBus(BusNode node)
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
auto type = toType(node.type);
|
||||
auto type = toType(node.type.value);
|
||||
|
||||
if(!node.tooltip && type == Bus::REGULAR) {
|
||||
errors.push_back(SourceError{node.span, "missing @tooltip"});
|
||||
@@ -392,7 +392,7 @@ std::optional<Component> SchemaCreator::loadComponent(ComponentNode node)
|
||||
}
|
||||
std::string source = node.source->asString();
|
||||
|
||||
Component::ComponentType type = toType(node.type);
|
||||
Component::ComponentType type = toType(node.type.value);
|
||||
|
||||
std::vector<Attribute> attributes;
|
||||
for(auto& a: node.attributes) {
|
||||
@@ -457,18 +457,18 @@ std::optional<Component> SchemaCreator::loadComponent(ComponentNode node)
|
||||
std::optional<Wire> SchemaCreator::loadWire(WireNode node) {
|
||||
return Wire(
|
||||
node.name.value,
|
||||
toType(node.type),
|
||||
toType(node.type.value),
|
||||
node.size.value,
|
||||
node.hidden,
|
||||
node.hasTermination,
|
||||
node.isUnterminated
|
||||
node.hasTerminateWith,
|
||||
toType(node.terminateWith)
|
||||
);
|
||||
}
|
||||
|
||||
optional<Pin> SchemaCreator::loadPin(PinNode node)
|
||||
{
|
||||
std::string name = node.name.value;
|
||||
Pin::PinType type = toType(node.type);
|
||||
Pin::PinType type = toType(node.type.value);
|
||||
|
||||
if(!node.tooltip) {
|
||||
errors.push_back(SourceError{node.span, "missing @tooltip"});
|
||||
@@ -559,7 +559,7 @@ std::optional<Display> SchemaCreator::loadDisplay(DisplayNode node)
|
||||
PinConnection SchemaCreator::loadPinConnection(PinConnectionNode node)
|
||||
{
|
||||
std::string message = node.message.asString();
|
||||
PinConnection::ConnectionType type = toType(node.type);
|
||||
PinConnection::ConnectionType type = toType(node.type.value);
|
||||
return PinConnection(message, type);
|
||||
}
|
||||
|
||||
@@ -606,7 +606,7 @@ std::optional<Attribute> SchemaCreator::loadAttribute(AttributeNode node)
|
||||
|
||||
std::optional<Popup> SchemaCreator::loadPopup(PopupNode node, std::string name, Value::ValueType type)
|
||||
{
|
||||
auto popupType = toType(*node.type);
|
||||
auto popupType = toType(node.type.value().value);
|
||||
|
||||
pushAdditional(name);
|
||||
|
||||
@@ -678,7 +678,7 @@ std::optional<Rule> SchemaCreator::loadRule(RuleNode node)
|
||||
for(auto& stmt: node.statements) {
|
||||
auto condition = loadCondition(stmt.condition);
|
||||
if(condition) {
|
||||
statements.push_back(IfStatement(*condition, Action(toType(stmt.action.type), stmt.action.message.asString())));
|
||||
statements.push_back(IfStatement(*condition, Action(toType(stmt.action.type.value), stmt.action.message.asString())));
|
||||
} else {
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
@@ -137,4 +137,23 @@ Value Value::fromNull() {
|
||||
return val;
|
||||
}
|
||||
|
||||
std::string Value::stringify() {
|
||||
switch (type) {
|
||||
case INT:
|
||||
return std::to_string(intValue);
|
||||
case BOOL:
|
||||
return boolValue ? "true" : "false";
|
||||
case STRING:
|
||||
return "\"" + stringValue + "\"";
|
||||
case NIL:
|
||||
return "null";
|
||||
case WIRE_REFERENCE:
|
||||
case ADDRESS_SPACE_REFERENCE:
|
||||
case ATTRIBUTE_REFERENCE:
|
||||
return reference;
|
||||
default:
|
||||
throw std::exception();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace domain
|
||||
@@ -55,6 +55,8 @@ public:
|
||||
void setBool(bool value);
|
||||
void setReference(std::string value);
|
||||
|
||||
std::string stringify();
|
||||
|
||||
static Value fromInt(long long value);
|
||||
static Value fromString(std::string value);
|
||||
static Value fromBool(bool value);
|
||||
|
||||
@@ -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
@@ -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
@@ -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())
|
||||
|
||||
@@ -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
|
||||
@@ -1,6 +0,0 @@
|
||||
#include "parser_util.h"
|
||||
|
||||
parser_util::parser_util()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef PARSER_UTIL_H
|
||||
#define PARSER_UTIL_H
|
||||
|
||||
|
||||
class parser_util
|
||||
{
|
||||
public:
|
||||
parser_util();
|
||||
};
|
||||
|
||||
#endif // PARSER_UTIL_H
|
||||
@@ -124,6 +124,10 @@ enum class TokenType {
|
||||
ERROR,
|
||||
WARNING,
|
||||
|
||||
// WIRE SETTINGS
|
||||
HIDDEN,
|
||||
TERMINATE_WITH,
|
||||
|
||||
// OTHER
|
||||
END_OF_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" );
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user