This commit is contained in:
Borna Rajkovic committed 2022-03-29 23:49:32 +02:00
1 parent 4c921759ef
commit 18d84727ab
35 files changed
+362 -636

No files matched your search

+297 -9
View File
@@ -2,6 +2,8 @@
#define ASTNODE_H
#include "token.h"
#include <optional>
#include <vector>
/**
* AST base class, all AST node classes extand this class. Class contains basic
@@ -26,26 +28,24 @@ public:
};
class StringNode: public AstNode {
public:
struct StringNode: public AstNode
{
std::string value;
};
class IdentifierNode: public AstNode {
public:
struct IdentifierNode: public AstNode
{
std::string value;
};
class NumberNode: public AstNode {
public:
struct NumberNode: public AstNode {
long long int value;
NumberNode(std::string expression);
NumberNode(): value(0) {}
};
class CountNode: public AstNode {
public:
struct CountNode: public AstNode
{
NumberNode first;
NumberNode second;
@@ -53,4 +53,292 @@ public:
CountNode() {}
};
struct AddressSpace: public AstNode
{
IdentifierNode name;
NumberNode start;
NumberNode end;
};
class Value: AstNode
{
public:
enum ValueType {
INT,
STRING,
BOOL,
IDENTIFIER
};
private:
ValueType type;
std::optional<long long> intValue;
std::optional<std::string> stringValue;
std::optional<bool> boolValue;
std::optional<std::string> identifierValue;
public:
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)) {
return identifierValue.value();
}
throw "cannot convert type to identifier";
}
bool asBool() {
if(is(BOOL)) {
return boolValue.value();
}
throw "cannot convert type to bool";
}
bool is(ValueType type) {
return this->type == type;
}
static Value ofBool(bool _value) {
Value value;
value.type = BOOL;
value.boolValue = std::optional<bool>(_value);
return value;
}
static Value ofInt(long long _value) {
Value value;
value.type = INT;
value.intValue = std::optional<long long>(_value);
return value;
}
static Value ofString(std::string _value) {
Value value;
value.type = STRING;
value.stringValue = std::optional<std::string>(_value);
return value;
}
static Value ofIdentifier(std::string _value) {
Value value;
value.type = IDENTIFIER;
value.identifierValue = std::optional<std::string>(_value);
return value;
}
};
struct Condition
{
bool negated;
IdentifierNode functionName;
std::vector<Value> params;
};
class Action: AstNode {
public:
enum ActionType {
ERROR,
WARNING
};
ActionType type;
StringNode message;
};
struct IfStmt: AstNode
{
Condition condition;
Action action;
};
struct Rule: AstNode
{
std::vector<IfStmt> statements;
};
struct EnumerationNode: AstNode
{
StringNode key;
Value value;
};
struct Popup: AstNode
{
enum PopupType {
AUTOMATIC,
ON_DEMAND
};
PopupType type;
StringNode title;
StringNode text;
bool enumerated;
std::vector<EnumerationNode> enumeration;
std::vector<Rule> rules;
};
struct PropertyNode: public AstNode
{
IdentifierNode key;
Value value;
};
struct DisplayItemNode: AstNode
{
IdentifierNode type;
std::vector<PropertyNode> values;
};
struct DisplayNode: AstNode
{
std::vector<DisplayItemNode> items;
};
struct PinConnectionNode: AstNode
{
enum ConnectionType {
CHECK_ONLY,
AUTOMATICALLY
};
StringNode message;
ConnectionType type;
};
struct PinNode: AstNode
{
enum PinType {
IN_OUT,
IN,
OUT
};
IdentifierNode name;
PinType type;
StringNode tooltip;
PinConnectionNode connection;
DisplayNode display;
};
struct WireNode: public AstNode
{
enum WireType {
WIRE,
WIRED_AND,
WIRED_OR,
R_WIRE
};
WireType type;
IdentifierNode name;
NumberNode size;
/*
bool isTerminatedWith;
long terminatedWith;
bool isIfUntrminated;
long ifUnterminated;
*/
};
struct AttributeNode: AstNode
{
Value::ValueType type;
IdentifierNode name;
std::optional<Value> defaultValue;
std::optional<Popup> popup;
};
struct ConnectionNode: AstNode
{
IdentifierNode component;
IdentifierNode pin;
IdentifierNode bus;
std::vector<AttributeNode> attributes;
std::vector<IdentifierNode> wires;
};
struct ComponentNode: AstNode
{
enum ComponentType {
OTHER,
PROCESSOR,
MEMORY
};
IdentifierNode name;
StringNode tooltip;
StringNode source;
ComponentType type;
std::vector<Rule> rules;
StringNode instanceName;
CountNode count;
DisplayNode display;
std::vector<PinNode> pin;
std::vector<AttributeNode> attributes;
};
struct BusNode: AstNode
{
enum BusType {
AUTOMATIC,
REGULAR
};
BusType type;
IdentifierNode name;
StringNode tooltip;
CountNode count;
DisplayNode display;
std::vector<WireNode> wires;
};
struct LibraryNode: AstNode
{
StringNode name;
StringNode libraryInfo;
StringNode header;
StringNode componentDirectory;
std::vector<AddressSpace> addressSpaces;
std::vector<ComponentNode> components;
std::vector<BusNode> buses;
std::vector<ConnectionNode> connections;
std::vector<PropertyNode> messages;
};
#endif // ASTNODE_H
+46 -46
View File
@@ -207,11 +207,11 @@ Spanner ComdelParser::getSpanner()
*
****************************************************************************/
std::optional<Library> ComdelParser::parse()
std::optional<LibraryNode> ComdelParser::parse()
{
auto spanner = getSpanner();
Library library{};
LibraryNode library{};
while ( ! check(TokenType::END_OF_FILE) ) {
PResult<poly<AstNode>> err;
@@ -398,14 +398,14 @@ PResult<AddressSpace> ComdelParser::parseAddress()
/****************************************************************************
*
* Component := "@component" + IDENTIFIER + ("processor" | "memory") { COMPONENT_BLOCK }
* ComponentNode := "@component" + IDENTIFIER + ("processor" | "memory") { COMPONENT_BLOCK }
*
****************************************************************************/
PResult<Component> ComdelParser::parseComponent()
PResult<ComponentNode> ComdelParser::parseComponent()
{
auto spanner = getSpanner();
Component component{};
ComponentNode component{};
RETURN_IF_NOT_TOKEN(TokenType::KW_COMPONENT);
@@ -413,12 +413,12 @@ PResult<Component> ComdelParser::parseComponent()
if(check(TokenType::CT_PROCESSOR)) {
bump();
component.type = Component::PROCESSOR;
component.type = ComponentNode::PROCESSOR;
} else if(check(TokenType::CT_MEMORY)) {
bump();
component.type = Component::MEMORY;
component.type = ComponentNode::MEMORY;
} else {
component.type = Component::OTHER;
component.type = ComponentNode::OTHER;
}
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
@@ -457,17 +457,17 @@ PResult<Component> ComdelParser::parseComponent()
/****************************************************************************
*
* Display := "@display {" + (DISPLAY_ITEM)* + "}"
* DisplayNode := "@display {" + (DISPLAY_ITEM)* + "}"
*
****************************************************************************/
PResult<Display> ComdelParser::parseDisplay() {
PResult<DisplayNode> ComdelParser::parseDisplay() {
auto spanner = getSpanner();
RETURN_IF_NOT_TOKEN(TokenType::KW_DISPLAY);
Display display;
DisplayNode display;
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
while(!check(TokenType::RBRACE)) {
PResult<DisplayItem> item;
PResult<DisplayItemNode> item;
item = parseDisplayItem();
RETURN_IF_ERR(item);
display.items.push_back(*item);
@@ -478,12 +478,12 @@ PResult<Display> ComdelParser::parseDisplay() {
/****************************************************************************
*
* DisplayItem := "TYPE {(KEY + ":" + VALUE + ";")*}
* DisplayItemNode := "TYPE {(KEY + ":" + VALUE + ";")*}
*
****************************************************************************/
PResult<DisplayItem> ComdelParser::parseDisplayItem() {
PResult<DisplayItemNode> ComdelParser::parseDisplayItem() {
auto spanner = getSpanner();
DisplayItem displayItem;
DisplayItemNode displayItem;
ASSIGN_OR_RETURN_IF_ERR(displayItem.type, parseIdentifier());
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
@@ -500,12 +500,12 @@ PResult<DisplayItem> ComdelParser::parseDisplayItem() {
/****************************************************************************
*
* Bus := "@bus " + NAME + TYPE + "{" + POPUP + "}"
* BusNode := "@bus " + NAME + TYPE + "{" + POPUP + "}"
*
****************************************************************************/
PResult<Bus> ComdelParser::parseBus() {
PResult<BusNode> ComdelParser::parseBus() {
auto spanner = getSpanner();
Bus bus;
BusNode bus;
RETURN_IF_NOT_TOKEN(TokenType::KW_BUS);
@@ -514,9 +514,9 @@ PResult<Bus> ComdelParser::parseBus() {
if(check(TokenType::IDENTIFIER)) {
auto tokenType = parseIdentifier();
if(tokenType.value().value == "automatic") {
bus.type = Bus::AUTOMATIC;
bus.type = BusNode::AUTOMATIC;
} else if(tokenType.value().value == "regular") {
bus.type = Bus::REGULAR;
bus.type = BusNode::REGULAR;
} else {
return PError(SourceError{current().span, "expected 'automatic' or 'regular'"});
}
@@ -558,12 +558,12 @@ PResult<Bus> ComdelParser::parseBus() {
/****************************************************************************
*
* Wire := NAME(<SIZE>){0,1} TYPE)*
* WireNode := NAME(<SIZE>){0,1} TYPE)*
*
****************************************************************************/
PResult<Wire> ComdelParser::parseWire() {
PResult<WireNode> ComdelParser::parseWire() {
auto spanner = getSpanner();
Wire wire;
WireNode wire;
ASSIGN_OR_RETURN_IF_ERR(wire.name, parseIdentifier());
@@ -576,20 +576,20 @@ PResult<Wire> ComdelParser::parseWire() {
}
// default
wire.type = Wire::WIRE;
wire.type = WireNode::WIRE;
if(check(TokenType::WIRE_DEFAULT)) {
bump();
wire.type = Wire::WIRE;
wire.type = WireNode::WIRE;
} else if(check(TokenType::WIRE_AND)) {
bump();
wire.type = Wire::WIRED_AND;
wire.type = WireNode::WIRED_AND;
} else if(check(TokenType::WIRE_OR)) {
bump();
wire.type = Wire::WIRED_OR;
wire.type = WireNode::WIRED_OR;
} else if(check(TokenType::R_WIRE)) {
bump();
wire.type = Wire::R_WIRE;
wire.type = WireNode::R_WIRE;
}
return spanner(wire);
@@ -598,30 +598,30 @@ PResult<Wire> ComdelParser::parseWire() {
/****************************************************************************
*
* Pin := "@pin" NAME TYPE "{"
* PinNode := "@pin" NAME TYPE "{"
"@tooltip" MESSAGE
"@connection" TYPE "(" MESSAGE ")"
Display
DisplayNode
}
*
****************************************************************************/
PResult<Pin> ComdelParser::parsePin() {
PResult<PinNode> ComdelParser::parsePin() {
auto spanner = getSpanner();
RETURN_IF_NOT_TOKEN(TokenType::KW_PIN);
Pin pin{};
PinNode pin{};
ASSIGN_OR_RETURN_IF_ERR(pin.name, parseIdentifier());
if(check(TokenType::PIN_IN)) {
bump();
pin.type = Pin::IN;
pin.type = PinNode::IN;
} else if(check(TokenType::PIN_OUT)) {
bump();
pin.type = Pin::OUT;
pin.type = PinNode::OUT;
} else if(check(TokenType::PIN_IN_OUT)) {
bump();
pin.type = Pin::IN_OUT;
pin.type = PinNode::IN_OUT;
} else {
return unexpected();
}
@@ -649,21 +649,21 @@ PResult<Pin> ComdelParser::parsePin() {
/****************************************************************************
*
* PinConnection := "@connection " + ("check_only" | "automatically") + "(" + MESSAGE + ")"
* PinConnectionNode := "@connection " + ("check_only" | "automatically") + "(" + MESSAGE + ")"
*
****************************************************************************/
PResult<PinConnection> ComdelParser::parsePinConnection() {
PResult<PinConnectionNode> ComdelParser::parsePinConnection() {
auto spanner = getSpanner();
PinConnection connection{};
PinConnectionNode connection{};
RETURN_IF_NOT_TOKEN(TokenType::KW_CONNECTION);
if(check(TokenType::IDENTIFIER)) {
auto type = parseIdentifier();
if(type.value().value == "check_only") {
connection.type = PinConnection::CHECK_ONLY;
connection.type = PinConnectionNode::CHECK_ONLY;
} else if(type.value().value == "automatically") {
connection.type = PinConnection::AUTOMATICALLY;
connection.type = PinConnectionNode::AUTOMATICALLY;
} else {
return PError(SourceError{current().span, "expected identifiers 'check_only' or 'automatically'"});
}
@@ -681,12 +681,12 @@ PResult<PinConnection> ComdelParser::parsePinConnection() {
/****************************************************************************
*
* Attribute := "@attribute " + NAME + TYPE ("default" + VALUE){0,1} ("{" POPUP "}"){0,1}
* AttributeNode := "@attribute " + NAME + TYPE ("default" + VALUE){0,1} ("{" POPUP "}"){0,1}
*
****************************************************************************/
PResult<Attribute> ComdelParser::parseAttribute() {
PResult<AttributeNode> ComdelParser::parseAttribute() {
auto spanner = getSpanner();
Attribute attribute;
AttributeNode attribute;
RETURN_IF_NOT_TOKEN(TokenType::KW_ATTRIBUTE);
@@ -839,12 +839,12 @@ PResult<Popup> ComdelParser::parsePopup() {
/****************************************************************************
*
* Connection := "@connection (" + COMPONENT + "." + PIN + "," + BUS) {" + CONNECTION + "}"
* ConnectionNode := "@connection (" + COMPONENT + "." + PIN + "," + BUS) {" + CONNECTION + "}"
*
****************************************************************************/
PResult<Connection> ComdelParser::parseConnection() {
PResult<ConnectionNode> ComdelParser::parseConnection() {
auto spanner = getSpanner();
Connection connection;
ConnectionNode connection;
RETURN_IF_NOT_TOKEN(TokenType::KW_CONNECTION);
+11 -12
View File
@@ -4,13 +4,12 @@
#include "sourceerror.h"
#include "presult.h"
#include "token.h"
#include "astnode.h"
#include <optional>
#include <set>
#include <vector>
#include <domain/library/library.h>
/// Records the current span and can later be called on
/// an ast node to apply the entire span to that node
///
@@ -71,24 +70,24 @@ private:
PResult<PropertyNode> parseProperty(std::optional<TokenType> valueType);
PResult<EnumerationNode> parseEnumeration();
PResult<Component> parseComponent();
PResult<ComponentNode> parseComponent();
PResult<AddressSpace> parseAddress();
PResult<Pin> parsePin();
PResult<Display> parseDisplay();
PResult<PinConnection> parsePinConnection();
PResult<Attribute> parseAttribute();
PResult<PinNode> parsePin();
PResult<DisplayNode> parseDisplay();
PResult<PinConnectionNode> parsePinConnection();
PResult<AttributeNode> parseAttribute();
PResult<Popup> parsePopup();
PResult<Rule> parseRule();
PResult<Bus> parseBus();
PResult<Wire> parseWire();
PResult<Connection> parseConnection();
PResult<DisplayItem> parseDisplayItem();
PResult<BusNode> parseBus();
PResult<WireNode> parseWire();
PResult<ConnectionNode> parseConnection();
PResult<DisplayItemNode> parseDisplayItem();
PResult<IfStmt> parseIfStatement();
PResult<Value> parseValue();
public:
ComdelParser(std::vector<Token> tokens);
std::optional<Library> parse();
std::optional<LibraryNode> parse();
const std::vector<SourceError>& getErrors();
};
+1 -1
View File
@@ -6,7 +6,7 @@
#include <fstream>
#include <string>
std::optional<Library> loadLibraryFromFile(ParseContext * parseContext,
std::optional<LibraryNode> loadLibraryFromFile(ParseContext * parseContext,
const char* name,
std::ostream& stream)
{
+2 -3
View File
@@ -1,11 +1,10 @@
#ifndef PARSERUTIL_H
#define PARSERUTIL_H
#include "astnode.h"
#include "parsecontext.h"
#include <domain/library/library.h>
std::optional<Library> loadLibraryFromFile(ParseContext * parseContext,
std::optional<LibraryNode> loadLibraryFromFile(ParseContext * parseContext,
const char* name,
std::ostream& stream);
+3 -3
View File
@@ -113,17 +113,17 @@ TokenTables::TokenTables() {
add( TokenType::BOOL_TYPE, "bool", TOKENIZABLE),
add( TokenType::WIRE_TYPE, "wire", TOKENIZABLE),
// Wire types
// WireNode types
add( TokenType::WIRE_DEFAULT, "normal_wire", TOKENIZABLE),
add( TokenType::WIRE_AND, "wired_and", TOKENIZABLE),
add( TokenType::WIRE_OR, "wired_or", TOKENIZABLE),
add( TokenType::R_WIRE, "r_wire", TOKENIZABLE),
// Component types
// ComponentNode types
add( TokenType::CT_MEMORY, "memory", TOKENIZABLE),
add( TokenType::CT_PROCESSOR, "processor", TOKENIZABLE),
// Pin type
// PinNode type
add( TokenType::PIN_IN, "in", TOKENIZABLE),
add( TokenType::PIN_OUT, "out", TOKENIZABLE),
add( TokenType::PIN_IN_OUT, "inOut", TOKENIZABLE),