Token refactor
This commit is contained in:
parent
48e1c48579
commit
4c921759ef
|
@ -62,6 +62,8 @@ LexerResult ComdelLexer::tokenize() {
|
||||||
std::string text = source.substr(tokenBegin.offset,
|
std::string text = source.substr(tokenBegin.offset,
|
||||||
position.offset - tokenBegin.offset);
|
position.offset - tokenBegin.offset);
|
||||||
|
|
||||||
|
tokenType = from_token(text, tokenType.value());
|
||||||
|
|
||||||
tokens.push_back(Token(*tokenType, Span(tokenBegin, position), text));
|
tokens.push_back(Token(*tokenType, Span(tokenBegin, position), text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -215,45 +215,34 @@ std::optional<Library> ComdelParser::parse()
|
||||||
|
|
||||||
while ( ! check(TokenType::END_OF_FILE) ) {
|
while ( ! check(TokenType::END_OF_FILE) ) {
|
||||||
PResult<poly<AstNode>> err;
|
PResult<poly<AstNode>> err;
|
||||||
if (check(TokenType::KEYWORD)) {
|
if(check(TokenType::KW_NAME)){
|
||||||
auto keyword = KeywordType::determineType(current().text);
|
|
||||||
bump();
|
bump();
|
||||||
switch (keyword) {
|
|
||||||
case KeywordType::NAME:
|
|
||||||
ASSIGN_OR_SET_ERR(library.name, parseString());
|
ASSIGN_OR_SET_ERR(library.name, parseString());
|
||||||
break;
|
} else if(check(TokenType::KW_HEADER)) {
|
||||||
case KeywordType::HEADER:
|
bump();
|
||||||
ASSIGN_OR_SET_ERR(library.header, parseString());
|
ASSIGN_OR_SET_ERR(library.header, parseString());
|
||||||
break;
|
} else if(check(TokenType::KW_DIRECTORY)) {
|
||||||
case KeywordType::DIRECTORY:
|
bump();
|
||||||
ASSIGN_OR_SET_ERR(library.componentDirectory, parseString());
|
ASSIGN_OR_SET_ERR(library.componentDirectory, parseString());
|
||||||
break;
|
} else if(check(TokenType::KW_INFO)) {
|
||||||
case KeywordType::INFO:
|
bump();
|
||||||
ASSIGN_OR_SET_ERR(library.libraryInfo, parseString());
|
ASSIGN_OR_SET_ERR(library.libraryInfo, parseString());
|
||||||
break;
|
} else if(check(TokenType::KW_ADDRESS)) {
|
||||||
case KeywordType::ADDRESS:
|
|
||||||
APPEND_OR_SET_ERR(library.addressSpaces, parseAddress());
|
APPEND_OR_SET_ERR(library.addressSpaces, parseAddress());
|
||||||
break;
|
} else if(check(TokenType::KW_COMPONENT)) {
|
||||||
case KeywordType::COMPONENT:
|
|
||||||
APPEND_OR_SET_ERR(library.components, parseComponent());
|
APPEND_OR_SET_ERR(library.components, parseComponent());
|
||||||
break;
|
} else if(check(TokenType::KW_BUS)) {
|
||||||
case KeywordType::BUS:
|
|
||||||
APPEND_OR_SET_ERR(library.buses, parseBus());
|
APPEND_OR_SET_ERR(library.buses, parseBus());
|
||||||
break;
|
} else if(check(TokenType::KW_CONNECTION)) {
|
||||||
case KeywordType::CONNECTION:
|
|
||||||
APPEND_OR_SET_ERR(library.connections, parseConnection());
|
APPEND_OR_SET_ERR(library.connections, parseConnection());
|
||||||
break;
|
} else if(check(TokenType::KW_MESSAGES)) {
|
||||||
case KeywordType::MESSAGES:
|
bump();
|
||||||
ASSIGN_OR_SET_ERR(library.messages, parseList<PropertyNode>(std::optional<TokenType>(TokenType::LBRACE),
|
ASSIGN_OR_SET_ERR(library.messages, parseList<PropertyNode>(std::optional<TokenType>(TokenType::LBRACE),
|
||||||
TokenType::RBRACE,
|
TokenType::RBRACE,
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
false,
|
false,
|
||||||
[this]{return parseProperty(std::optional<TokenType>(TokenType::STRING));}
|
[this]{return parseProperty(std::optional<TokenType>(TokenType::STRING));}
|
||||||
));
|
));
|
||||||
break;
|
|
||||||
default:
|
|
||||||
err = unexpected();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
err = unexpected();
|
err = unexpected();
|
||||||
}
|
}
|
||||||
|
@ -324,30 +313,6 @@ PResult<NumberNode> ComdelParser::parseNumber()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
*
|
|
||||||
* Used for skipping block while testing
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
void ComdelParser::parseBlock()
|
|
||||||
{
|
|
||||||
int depth = 0;
|
|
||||||
if(consume(TokenType::LBRACE)) {
|
|
||||||
depth++;
|
|
||||||
}
|
|
||||||
while(depth != 0) {
|
|
||||||
if(consume(TokenType::LBRACE)) {
|
|
||||||
depth++;
|
|
||||||
} else if(consume(TokenType::RBRACE)) {
|
|
||||||
depth--;
|
|
||||||
} else {
|
|
||||||
bump();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
* CountNode := "@size (" + NumberNode + "," + NumberNode + ")"
|
* CountNode := "@size (" + NumberNode + "," + NumberNode + ")"
|
||||||
|
@ -356,6 +321,8 @@ void ComdelParser::parseBlock()
|
||||||
PResult<CountNode> ComdelParser::parseCount()
|
PResult<CountNode> ComdelParser::parseCount()
|
||||||
{
|
{
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::KW_COUNT);
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
||||||
auto first = parseNumber();
|
auto first = parseNumber();
|
||||||
if(!first.has_value()) {
|
if(!first.has_value()) {
|
||||||
|
@ -383,22 +350,18 @@ PResult<PropertyNode> ComdelParser::parseProperty(std::optional<TokenType> value
|
||||||
ASSIGN_OR_RETURN_IF_ERR(key, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(key, parseIdentifier());
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::COLON);
|
RETURN_IF_NOT_TOKEN(TokenType::COLON);
|
||||||
Value value;
|
|
||||||
|
|
||||||
if(valueType.has_value()) {
|
if(valueType.has_value()) {
|
||||||
if(!check(*valueType)) {
|
if(valueType == TokenType::BOOL_TYPE) {
|
||||||
|
if(!(check(TokenType::TRUE) || check(TokenType::FALSE))) {
|
||||||
|
return unexpected();
|
||||||
|
}
|
||||||
|
} else if(!check(*valueType)) {
|
||||||
return unexpected();
|
return unexpected();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(check(TokenType::NUMBER)) {
|
Value value;
|
||||||
value = Value::ofInt(parseNumber().value().value);
|
ASSIGN_OR_RETURN_IF_ERR(value, parseValue());
|
||||||
} else if(check(TokenType::STRING)) {
|
|
||||||
value = Value::ofString(parseString().value().value);
|
|
||||||
} else if(check(TokenType::IDENTIFIER)) {
|
|
||||||
value = Value::ofIdentifier(parseIdentifier().value().value);
|
|
||||||
} else {
|
|
||||||
return unexpected();
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::SEMICOLON);
|
RETURN_IF_NOT_TOKEN(TokenType::SEMICOLON);
|
||||||
|
|
||||||
|
@ -420,6 +383,8 @@ PResult<AddressSpace> ComdelParser::parseAddress()
|
||||||
|
|
||||||
AddressSpace addressSpace{};
|
AddressSpace addressSpace{};
|
||||||
|
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::KW_ADDRESS);
|
||||||
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(addressSpace.name, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(addressSpace.name, parseIdentifier());
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
||||||
ASSIGN_OR_RETURN_IF_ERR(addressSpace.start, parseNumber());
|
ASSIGN_OR_RETURN_IF_ERR(addressSpace.start, parseNumber());
|
||||||
|
@ -442,17 +407,16 @@ PResult<Component> ComdelParser::parseComponent()
|
||||||
|
|
||||||
Component component{};
|
Component component{};
|
||||||
|
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::KW_COMPONENT);
|
||||||
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(component.name, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(component.name, parseIdentifier());
|
||||||
|
|
||||||
if(check(TokenType::IDENTIFIER)) {
|
if(check(TokenType::CT_PROCESSOR)) {
|
||||||
auto tokenType = parseIdentifier();
|
bump();
|
||||||
if(tokenType.value().value == "processor") {
|
|
||||||
component.type = Component::PROCESSOR;
|
component.type = Component::PROCESSOR;
|
||||||
} else if(tokenType.value().value == "memory") {
|
} else if(check(TokenType::CT_MEMORY)) {
|
||||||
|
bump();
|
||||||
component.type = Component::MEMORY;
|
component.type = Component::MEMORY;
|
||||||
} else {
|
|
||||||
return PError(SourceError{current().span, "expected 'processor' or 'memory'"});
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
component.type = Component::OTHER;
|
component.type = Component::OTHER;
|
||||||
}
|
}
|
||||||
|
@ -461,37 +425,25 @@ PResult<Component> ComdelParser::parseComponent()
|
||||||
|
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
PResult<poly<AstNode>> err;
|
PResult<poly<AstNode>> err;
|
||||||
if (check(TokenType::KEYWORD)) {
|
if(check(TokenType::KW_INSTANCE_NAME)) {
|
||||||
auto keyword = KeywordType::determineType(current().text);
|
|
||||||
bump();
|
bump();
|
||||||
switch (keyword) {
|
|
||||||
case KeywordType::INSTANCE_NAME:
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(component.instanceName, parseString());
|
ASSIGN_OR_RETURN_IF_ERR(component.instanceName, parseString());
|
||||||
break;
|
} else if(check(TokenType::KW_TOOLTIP)) {
|
||||||
case KeywordType::TOOLTIP:
|
bump();
|
||||||
ASSIGN_OR_RETURN_IF_ERR(component.tooltip, parseString());
|
ASSIGN_OR_RETURN_IF_ERR(component.tooltip, parseString());
|
||||||
break;
|
} else if(check(TokenType::KW_SOURCE)) {
|
||||||
case KeywordType::SOURCE:
|
bump();
|
||||||
ASSIGN_OR_RETURN_IF_ERR(component.source, parseString());
|
ASSIGN_OR_RETURN_IF_ERR(component.source, parseString());
|
||||||
break;
|
} else if(check(TokenType::KW_COUNT)) {
|
||||||
case KeywordType::COUNT:
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(component.count, parseCount());
|
ASSIGN_OR_RETURN_IF_ERR(component.count, parseCount());
|
||||||
break;
|
} else if(check(TokenType::KW_DISPLAY)) {
|
||||||
case KeywordType::DISPLAY:
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(component.display, parseDisplay());
|
ASSIGN_OR_RETURN_IF_ERR(component.display, parseDisplay());
|
||||||
break;
|
} else if(check(TokenType::KW_PIN)) {
|
||||||
case KeywordType::PIN:
|
|
||||||
APPEND_OR_RETURN_IF_ERR(component.pin, parsePin());
|
APPEND_OR_RETURN_IF_ERR(component.pin, parsePin());
|
||||||
break;
|
} else if(check(TokenType::KW_ATTRIBUTE)) {
|
||||||
case KeywordType::ATTRIBUTE:
|
|
||||||
APPEND_OR_RETURN_IF_ERR(component.attributes, parseAttribute());
|
APPEND_OR_RETURN_IF_ERR(component.attributes, parseAttribute());
|
||||||
break;
|
} else if(check(TokenType::KW_RULE)) {
|
||||||
case KeywordType::RULE:
|
|
||||||
APPEND_OR_RETURN_IF_ERR(component.rules, parseRule());
|
APPEND_OR_RETURN_IF_ERR(component.rules, parseRule());
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return unexpected();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
return unexpected();
|
||||||
}
|
}
|
||||||
|
@ -510,6 +462,8 @@ PResult<Component> ComdelParser::parseComponent()
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
PResult<Display> ComdelParser::parseDisplay() {
|
PResult<Display> ComdelParser::parseDisplay() {
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
|
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::KW_DISPLAY);
|
||||||
Display display;
|
Display display;
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
|
@ -553,6 +507,8 @@ PResult<Bus> ComdelParser::parseBus() {
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
Bus bus;
|
Bus bus;
|
||||||
|
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::KW_BUS);
|
||||||
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(bus.name, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(bus.name, parseIdentifier());
|
||||||
|
|
||||||
if(check(TokenType::IDENTIFIER)) {
|
if(check(TokenType::IDENTIFIER)) {
|
||||||
|
@ -571,20 +527,15 @@ PResult<Bus> ComdelParser::parseBus() {
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
if (check(TokenType::KEYWORD)) {
|
if(check(TokenType::KW_TOOLTIP)) {
|
||||||
auto keyword = KeywordType::determineType(current().text);
|
|
||||||
bump();
|
bump();
|
||||||
switch (keyword) {
|
|
||||||
case KeywordType::TOOLTIP:
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(bus.tooltip, parseString());
|
ASSIGN_OR_RETURN_IF_ERR(bus.tooltip, parseString());
|
||||||
break;
|
} else if(check(TokenType::KW_COUNT)) {
|
||||||
case KeywordType::COUNT:
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(bus.count, parseCount());
|
ASSIGN_OR_RETURN_IF_ERR(bus.count, parseCount());
|
||||||
break;
|
} else if(check(TokenType::KW_DISPLAY)) {
|
||||||
case KeywordType::DISPLAY:
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(bus.display, parseDisplay());
|
ASSIGN_OR_RETURN_IF_ERR(bus.display, parseDisplay());
|
||||||
break;
|
} else if(check(TokenType::KW_WIRES)) {
|
||||||
case KeywordType::WIRES:
|
bump();
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
while(check(TokenType::IDENTIFIER)) {
|
while(check(TokenType::IDENTIFIER)) {
|
||||||
APPEND_OR_RETURN_IF_ERR(bus.wires, parseWire());
|
APPEND_OR_RETURN_IF_ERR(bus.wires, parseWire());
|
||||||
|
@ -594,10 +545,6 @@ PResult<Bus> ComdelParser::parseBus() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::RBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::RBRACE);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return unexpected();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
return unexpected();
|
||||||
}
|
}
|
||||||
|
@ -628,24 +575,21 @@ PResult<Wire> ComdelParser::parseWire() {
|
||||||
wire.size.value = 1;
|
wire.size.value = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(check(TokenType::IDENTIFIER)) {
|
// default
|
||||||
IdentifierNode identifier;
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(identifier, parseIdentifier());
|
|
||||||
|
|
||||||
if(identifier.value == "wire") {
|
|
||||||
wire.type = Wire::WIRE;
|
wire.type = Wire::WIRE;
|
||||||
} else if(identifier.value == "wired_and") {
|
|
||||||
|
if(check(TokenType::WIRE_DEFAULT)) {
|
||||||
|
bump();
|
||||||
|
wire.type = Wire::WIRE;
|
||||||
|
} else if(check(TokenType::WIRE_AND)) {
|
||||||
|
bump();
|
||||||
wire.type = Wire::WIRED_AND;
|
wire.type = Wire::WIRED_AND;
|
||||||
} else if(identifier.value == "wired_or") {
|
} else if(check(TokenType::WIRE_OR)) {
|
||||||
|
bump();
|
||||||
wire.type = Wire::WIRED_OR;
|
wire.type = Wire::WIRED_OR;
|
||||||
}else if(identifier.value == "r_wire") {
|
} else if(check(TokenType::R_WIRE)) {
|
||||||
|
bump();
|
||||||
wire.type = Wire::R_WIRE;
|
wire.type = Wire::R_WIRE;
|
||||||
} else {
|
|
||||||
return PError(SourceError{current().span, "expected 'wire', 'wired_and', 'wired_or' or 'r_wire'"});
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
wire.type = Wire::WIRE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return spanner(wire);
|
return spanner(wire);
|
||||||
|
@ -664,43 +608,34 @@ PResult<Wire> ComdelParser::parseWire() {
|
||||||
PResult<Pin> ComdelParser::parsePin() {
|
PResult<Pin> ComdelParser::parsePin() {
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
|
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::KW_PIN);
|
||||||
Pin pin{};
|
Pin pin{};
|
||||||
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(pin.name, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(pin.name, parseIdentifier());
|
||||||
if(check(TokenType::IDENTIFIER)) {
|
|
||||||
auto type = parseIdentifier();
|
if(check(TokenType::PIN_IN)) {
|
||||||
if(type.value().value == "InOut") {
|
bump();
|
||||||
pin.type = Pin::IN_OUT;
|
|
||||||
} else if(type.value().value == "In") {
|
|
||||||
pin.type = Pin::IN;
|
pin.type = Pin::IN;
|
||||||
} else if(type.value().value == "Out") {
|
} else if(check(TokenType::PIN_OUT)) {
|
||||||
|
bump();
|
||||||
pin.type = Pin::OUT;
|
pin.type = Pin::OUT;
|
||||||
} else {
|
} else if(check(TokenType::PIN_IN_OUT)) {
|
||||||
return PError(SourceError{type.value().span, "expected 'InOut', 'In', or 'Out'"});
|
bump();
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pin.type = Pin::IN_OUT;
|
pin.type = Pin::IN_OUT;
|
||||||
|
} else {
|
||||||
|
return unexpected();
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
if (check(TokenType::KEYWORD)) {
|
if (check(TokenType::KW_TOOLTIP)) {
|
||||||
auto keyword = KeywordType::determineType(current().text);
|
|
||||||
bump();
|
bump();
|
||||||
switch (keyword) {
|
|
||||||
case KeywordType::TOOLTIP:
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(pin.tooltip, parseString());
|
ASSIGN_OR_RETURN_IF_ERR(pin.tooltip, parseString());
|
||||||
break;
|
} else if (check(TokenType::KW_DISPLAY)) {
|
||||||
case KeywordType::DISPLAY:
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(pin.display, parseDisplay());
|
ASSIGN_OR_RETURN_IF_ERR(pin.display, parseDisplay());
|
||||||
break;
|
} else if (check(TokenType::KW_CONNECTION)) {
|
||||||
case KeywordType::CONNECTION:
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(pin.connection, parsePinConnection());
|
ASSIGN_OR_RETURN_IF_ERR(pin.connection, parsePinConnection());
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return unexpected();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
return unexpected();
|
||||||
}
|
}
|
||||||
|
@ -721,11 +656,13 @@ PResult<PinConnection> ComdelParser::parsePinConnection() {
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
PinConnection connection{};
|
PinConnection connection{};
|
||||||
|
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::KW_CONNECTION);
|
||||||
|
|
||||||
if(check(TokenType::IDENTIFIER)) {
|
if(check(TokenType::IDENTIFIER)) {
|
||||||
auto type = parseIdentifier();
|
auto type = parseIdentifier();
|
||||||
if(type.value().value == "check_only") {
|
if(type.value().value == "check_only") {
|
||||||
connection.type = PinConnection::CHECK_ONLY;
|
connection.type = PinConnection::CHECK_ONLY;
|
||||||
} else if(type.value().value == "In") {
|
} else if(type.value().value == "automatically") {
|
||||||
connection.type = PinConnection::AUTOMATICALLY;
|
connection.type = PinConnection::AUTOMATICALLY;
|
||||||
} else {
|
} else {
|
||||||
return PError(SourceError{current().span, "expected identifiers 'check_only' or 'automatically'"});
|
return PError(SourceError{current().span, "expected identifiers 'check_only' or 'automatically'"});
|
||||||
|
@ -751,65 +688,57 @@ PResult<Attribute> ComdelParser::parseAttribute() {
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
Attribute attribute;
|
Attribute attribute;
|
||||||
|
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::KW_ATTRIBUTE);
|
||||||
|
|
||||||
if(check(TokenType::IDENTIFIER)) {
|
if(check(TokenType::IDENTIFIER)) {
|
||||||
ASSIGN_OR_RETURN_IF_ERR(attribute.name, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(attribute.name, parseIdentifier());
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
return unexpected();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(check(TokenType::IDENTIFIER)) {
|
if(check(TokenType::INT_TYPE)) {
|
||||||
auto type = parseIdentifier();
|
|
||||||
if(type.value().value == "int") {
|
|
||||||
attribute.type = Value::INT;
|
attribute.type = Value::INT;
|
||||||
} else if(type.value().value == "string") {
|
} else if(check(TokenType::STRING_TYPE)) {
|
||||||
attribute.type = Value::STRING;
|
attribute.type = Value::STRING;
|
||||||
} else if(type.value().value == "bool") {
|
} else if(check(TokenType::BOOL_TYPE)) {
|
||||||
attribute.type = Value::BOOL;
|
attribute.type = Value::BOOL;
|
||||||
} else if(type.value().value == "wire") {
|
} else if(check(TokenType::WIRE_TYPE)) {
|
||||||
attribute.type = Value::IDENTIFIER;
|
attribute.type = Value::IDENTIFIER;
|
||||||
} else {
|
} else {
|
||||||
return PError(SourceError{current().span, "expected type 'int', 'bool', 'string', 'wire'"});
|
return unexpected();
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return PError(SourceError{current().span, "expected type 'int', 'bool', 'string', 'wire'"});
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!(check(TokenType::IDENTIFIER) && current().text == "default")) {
|
|
||||||
return PError(SourceError{current().span, "expected 'default'"});
|
|
||||||
}
|
}
|
||||||
bump();
|
bump();
|
||||||
|
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::DEFAULT);
|
||||||
|
|
||||||
if(attribute.type == Value::BOOL) {
|
if(attribute.type == Value::BOOL) {
|
||||||
IdentifierNode identifier;
|
if(check(TokenType::TRUE)) {
|
||||||
ASSIGN_OR_RETURN_IF_ERR(identifier, parseIdentifier());
|
|
||||||
if(identifier.value == "true") {
|
|
||||||
attribute.defaultValue = Value::ofBool(true);
|
attribute.defaultValue = Value::ofBool(true);
|
||||||
} else if(identifier.value == "false") {
|
} else if(check(TokenType::FALSE)) {
|
||||||
attribute.defaultValue = Value::ofBool(false);
|
attribute.defaultValue = Value::ofBool(false);
|
||||||
} else {
|
} else {
|
||||||
return PError(SourceError{current().span, "expected value 'true' or 'false'"});
|
return unexpected();
|
||||||
}
|
}
|
||||||
} else if(attribute.type == Value::INT) {
|
} else if(attribute.type == Value::INT) {
|
||||||
if(check(TokenType::NUMBER)) {
|
if(check(TokenType::NUMBER)) {
|
||||||
auto number = parseNumber();
|
auto number = parseNumber();
|
||||||
attribute.defaultValue = Value::ofInt(number.value().value);
|
attribute.defaultValue = Value::ofInt(number->value);
|
||||||
} else {
|
} else {
|
||||||
return PError(SourceError{current().span, "expected number"});
|
return unexpected();
|
||||||
}
|
}
|
||||||
} else if(attribute.type == Value::STRING) {
|
} else if(attribute.type == Value::STRING) {
|
||||||
if(check(TokenType::STRING)) {
|
if(check(TokenType::STRING)) {
|
||||||
auto string = parseString();
|
auto string = parseString();
|
||||||
attribute.defaultValue = Value::ofString(string.value().value);
|
attribute.defaultValue = Value::ofString(string->value);
|
||||||
} else {
|
} else {
|
||||||
return PError(SourceError{current().span, "expected string"});
|
return unexpected();
|
||||||
}
|
}
|
||||||
} else if(attribute.type == Value::IDENTIFIER) {
|
} else if(attribute.type == Value::IDENTIFIER) {
|
||||||
if(check(TokenType::IDENTIFIER)) {
|
if(check(TokenType::IDENTIFIER)) {
|
||||||
auto identifier = parseIdentifier();
|
auto identifier = parseIdentifier();
|
||||||
attribute.defaultValue = Value::ofIdentifier(identifier.value().value);
|
attribute.defaultValue = Value::ofIdentifier(identifier->value);
|
||||||
} else {
|
} else {
|
||||||
return PError(SourceError{current().span, "expected wire"});
|
return unexpected();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -817,10 +746,9 @@ PResult<Attribute> ComdelParser::parseAttribute() {
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
Popup popup;
|
Popup popup;
|
||||||
|
|
||||||
if(!(check(TokenType::KEYWORD) && current().text == "@popup")) {
|
if(!check(TokenType::KW_POPUP)) {
|
||||||
return PError(SourceError{current().span, "expected '@popup'"});
|
return unexpected();
|
||||||
}
|
}
|
||||||
bump();
|
|
||||||
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(popup, parsePopup());
|
ASSIGN_OR_RETURN_IF_ERR(popup, parsePopup());
|
||||||
attribute.popup = std::optional<Popup>(popup);
|
attribute.popup = std::optional<Popup>(popup);
|
||||||
|
@ -838,19 +766,12 @@ PResult<Attribute> ComdelParser::parseAttribute() {
|
||||||
PResult<EnumerationNode> ComdelParser::parseEnumeration() {
|
PResult<EnumerationNode> ComdelParser::parseEnumeration() {
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
StringNode key;
|
StringNode key;
|
||||||
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(key, parseString());
|
ASSIGN_OR_RETURN_IF_ERR(key, parseString());
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::EQUALS);
|
RETURN_IF_NOT_TOKEN(TokenType::EQUALS);
|
||||||
|
|
||||||
Value value;
|
Value value;
|
||||||
if(check(TokenType::NUMBER)) {
|
ASSIGN_OR_RETURN_IF_ERR(value, parseValue());
|
||||||
value = Value::ofInt(parseNumber().value().value);
|
|
||||||
} else if(check(TokenType::STRING)) {
|
|
||||||
value = Value::ofString(parseString().value().value);
|
|
||||||
} else if(check(TokenType::IDENTIFIER)) {
|
|
||||||
value = Value::ofIdentifier(parseIdentifier().value().value);
|
|
||||||
} else {
|
|
||||||
return unexpected();
|
|
||||||
}
|
|
||||||
|
|
||||||
EnumerationNode node;
|
EnumerationNode node;
|
||||||
node.key = key;
|
node.key = key;
|
||||||
|
@ -868,6 +789,8 @@ PResult<Popup> ComdelParser::parsePopup() {
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
Popup popup;
|
Popup popup;
|
||||||
|
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::KW_POPUP);
|
||||||
|
|
||||||
if(check(TokenType::IDENTIFIER)) {
|
if(check(TokenType::IDENTIFIER)) {
|
||||||
auto type = parseIdentifier();
|
auto type = parseIdentifier();
|
||||||
if(type.value().value == "automatic") {
|
if(type.value().value == "automatic") {
|
||||||
|
@ -884,21 +807,16 @@ PResult<Popup> ComdelParser::parsePopup() {
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
PResult<poly<AstNode>> err;
|
if(check(TokenType::KW_TITLE)) {
|
||||||
if (check(TokenType::KEYWORD)) {
|
|
||||||
auto keyword = KeywordType::determineType(current().text);
|
|
||||||
bump();
|
bump();
|
||||||
switch (keyword) {
|
|
||||||
case KeywordType::TITLE:
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(popup.title, parseString());
|
ASSIGN_OR_RETURN_IF_ERR(popup.title, parseString());
|
||||||
break;
|
} else if(check(TokenType::KW_TEXT)) {
|
||||||
case KeywordType::TEXT:
|
bump();
|
||||||
ASSIGN_OR_RETURN_IF_ERR(popup.text, parseString());
|
ASSIGN_OR_RETURN_IF_ERR(popup.text, parseString());
|
||||||
break;
|
} else if(check(TokenType::KW_RULE)) {
|
||||||
case KeywordType::RULE:
|
|
||||||
APPEND_OR_RETURN_IF_ERR(popup.rules, parseRule());
|
APPEND_OR_RETURN_IF_ERR(popup.rules, parseRule());
|
||||||
break;
|
} else if(check(TokenType::KW_ENUMERATED)) {
|
||||||
case KeywordType::ENUMERATED:
|
bump();
|
||||||
popup.enumerated = true;
|
popup.enumerated = true;
|
||||||
ASSIGN_OR_RETURN_IF_ERR(popup.enumeration,
|
ASSIGN_OR_RETURN_IF_ERR(popup.enumeration,
|
||||||
parseList<EnumerationNode>(
|
parseList<EnumerationNode>(
|
||||||
|
@ -909,10 +827,6 @@ PResult<Popup> ComdelParser::parsePopup() {
|
||||||
[this]{ return parseEnumeration();}
|
[this]{ return parseEnumeration();}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return unexpected();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
return unexpected();
|
||||||
}
|
}
|
||||||
|
@ -932,6 +846,8 @@ PResult<Connection> ComdelParser::parseConnection() {
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
Connection connection;
|
Connection connection;
|
||||||
|
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::KW_CONNECTION);
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
||||||
ASSIGN_OR_RETURN_IF_ERR(connection.component, parseIdentifier());
|
ASSIGN_OR_RETURN_IF_ERR(connection.component, parseIdentifier());
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::DOT);
|
RETURN_IF_NOT_TOKEN(TokenType::DOT);
|
||||||
|
@ -943,24 +859,14 @@ PResult<Connection> ComdelParser::parseConnection() {
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
if (check(TokenType::KEYWORD)) {
|
if (check(TokenType::KW_ATTRIBUTE)) {
|
||||||
auto keyword = KeywordType::determineType(current().text);
|
|
||||||
bump();
|
|
||||||
switch (keyword) {
|
|
||||||
case KeywordType::ATTRIBUTE:
|
|
||||||
APPEND_OR_RETURN_IF_ERR(connection.attributes, parseAttribute());
|
APPEND_OR_RETURN_IF_ERR(connection.attributes, parseAttribute());
|
||||||
break;
|
} else if(check(TokenType::KW_WIRES)) {
|
||||||
case KeywordType::WIRES:
|
bump();
|
||||||
{
|
|
||||||
auto wires = parseList<IdentifierNode>(std::optional<TokenType>(TokenType::LBRACE), TokenType::RBRACE, std::optional<TokenType>(TokenType::COMMA), false,
|
auto wires = parseList<IdentifierNode>(std::optional<TokenType>(TokenType::LBRACE), TokenType::RBRACE, std::optional<TokenType>(TokenType::COMMA), false,
|
||||||
[this] { return parseIdentifier(); });
|
[this] { return parseIdentifier(); });
|
||||||
RETURN_IF_ERR(wires);
|
RETURN_IF_ERR(wires);
|
||||||
connection.wires = *wires;
|
connection.wires = *wires;
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return unexpected();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
return unexpected();
|
||||||
}
|
}
|
||||||
|
@ -981,17 +887,16 @@ PResult<Rule> ComdelParser::parseRule() {
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
Rule rule;
|
Rule rule;
|
||||||
|
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::KW_RULE);
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
||||||
while(!check(TokenType::RBRACE)) {
|
while(!check(TokenType::RBRACE)) {
|
||||||
APPEND_OR_RETURN_IF_ERR(rule.statements, parseIfStatement());
|
APPEND_OR_RETURN_IF_ERR(rule.statements, parseIfStatement());
|
||||||
if(check(TokenType::IDENTIFIER)) {
|
if(check(TokenType::RBRACE)) {
|
||||||
IdentifierNode node;
|
break;
|
||||||
ASSIGN_OR_RETURN_IF_ERR(node, parseIdentifier());
|
|
||||||
if(node.value != "else") {
|
|
||||||
return PError(SourceError{node.span, "expected 'else'"});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
RETURN_IF_NOT_TOKEN(TokenType::ELSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::RBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::RBRACE);
|
||||||
|
@ -1009,11 +914,7 @@ PResult<IfStmt> ComdelParser::parseIfStatement() {
|
||||||
auto spanner = getSpanner();
|
auto spanner = getSpanner();
|
||||||
IfStmt ifStatement;
|
IfStmt ifStatement;
|
||||||
|
|
||||||
IdentifierNode node;
|
RETURN_IF_NOT_TOKEN(TokenType::IF);
|
||||||
ASSIGN_OR_RETURN_IF_ERR(node, parseIdentifier());
|
|
||||||
if(node.value != "if") {
|
|
||||||
return unexpected();
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
||||||
|
|
||||||
|
@ -1037,17 +938,14 @@ PResult<IfStmt> ComdelParser::parseIfStatement() {
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
|
||||||
|
|
||||||
if(check(TokenType::IDENTIFIER)) {
|
if(check(TokenType::ERROR)) {
|
||||||
IdentifierNode action;
|
|
||||||
ASSIGN_OR_RETURN_IF_ERR(action, parseIdentifier());
|
|
||||||
if(action.value == "error") {
|
|
||||||
ifStatement.action.type = Action::ERROR;
|
ifStatement.action.type = Action::ERROR;
|
||||||
} else if(action.value == "warning") {
|
} else if(check(TokenType::WARNING)) {
|
||||||
ifStatement.action.type = Action::WARNING;
|
ifStatement.action.type = Action::WARNING;
|
||||||
} else {
|
} else {
|
||||||
return PError(SourceError{action.span, "expected 'error' of 'warning'"});
|
return unexpected();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
bump();
|
||||||
|
|
||||||
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
|
||||||
ASSIGN_OR_RETURN_IF_ERR(ifStatement.action.message, parseString());
|
ASSIGN_OR_RETURN_IF_ERR(ifStatement.action.message, parseString());
|
||||||
|
@ -1069,6 +967,12 @@ PResult<Value> ComdelParser::parseValue() {
|
||||||
value = Value::ofString(parseString()->value);
|
value = Value::ofString(parseString()->value);
|
||||||
} else if(check(TokenType::NUMBER)) {
|
} else if(check(TokenType::NUMBER)) {
|
||||||
value = Value::ofInt(parseNumber()->value);
|
value = Value::ofInt(parseNumber()->value);
|
||||||
|
} else if(check(TokenType::TRUE)) {
|
||||||
|
value = Value::ofBool(true);
|
||||||
|
} else if(check(TokenType::FALSE)) {
|
||||||
|
value = Value::ofBool(false);
|
||||||
|
} else {
|
||||||
|
return unexpected();
|
||||||
}
|
}
|
||||||
|
|
||||||
return spanner(value);
|
return spanner(value);
|
||||||
|
|
|
@ -33,35 +33,3 @@ Token::Token(TokenType type, Span span, std::string text)
|
||||||
, span(std::move(span))
|
, span(std::move(span))
|
||||||
, text(std::move(text))
|
, text(std::move(text))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
const std::map<std::string, KeywordType::Type> KeywordType::keywords = {
|
|
||||||
{"@name", NAME},
|
|
||||||
{"@info", INFO},
|
|
||||||
{"@header", HEADER},
|
|
||||||
{"@directory", DIRECTORY},
|
|
||||||
{"@library", LIBRARY},
|
|
||||||
{"@address", ADDRESS},
|
|
||||||
{"@component", COMPONENT},
|
|
||||||
{"@messages", MESSAGES},
|
|
||||||
{"@instanceName", INSTANCE_NAME},
|
|
||||||
{"@count", COUNT},
|
|
||||||
{"@display", DISPLAY},
|
|
||||||
{"@pin", PIN},
|
|
||||||
{"@tooltip", TOOLTIP},
|
|
||||||
{"@connection", CONNECTION},
|
|
||||||
{"@attribute", ATTRIBUTE},
|
|
||||||
{"@source", SOURCE},
|
|
||||||
{"@popup", POPUP},
|
|
||||||
{"@rule", RULE},
|
|
||||||
{"@title", TITLE},
|
|
||||||
{"@text", TEXT},
|
|
||||||
{"@bus", BUS},
|
|
||||||
{"@wires", WIRES},
|
|
||||||
{"@enumerated", ENUMERATED},
|
|
||||||
{"@wire", WIRE},
|
|
||||||
{"@instance", INSTANCE},
|
|
||||||
{"@schema", SCHEMA},
|
|
||||||
{"@position", POSITION},
|
|
||||||
{"@size", SIZE}
|
|
||||||
};
|
|
||||||
|
|
|
@ -56,68 +56,73 @@ enum class TokenType {
|
||||||
COMMENT,
|
COMMENT,
|
||||||
WHITESPACE,
|
WHITESPACE,
|
||||||
|
|
||||||
END_OF_FILE
|
IF,
|
||||||
};
|
ELSE,
|
||||||
|
|
||||||
enum class ValueType {
|
DEFAULT,
|
||||||
// TYPES
|
|
||||||
BOOL,
|
|
||||||
INT,
|
|
||||||
STRING,
|
|
||||||
COLOR,
|
|
||||||
WIRE,
|
|
||||||
ADDRESS_SPACE,
|
|
||||||
};
|
|
||||||
|
|
||||||
class KeywordType {
|
// BOOLEAN VALUE
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum Type {
|
|
||||||
// KEYWORDS
|
// KEYWORDS
|
||||||
NAME,
|
KW_NAME,
|
||||||
INFO,
|
KW_INFO,
|
||||||
HEADER,
|
KW_HEADER,
|
||||||
DIRECTORY,
|
KW_DIRECTORY,
|
||||||
LIBRARY,
|
KW_LIBRARY,
|
||||||
ADDRESS,
|
KW_ADDRESS,
|
||||||
COMPONENT,
|
KW_COMPONENT,
|
||||||
MESSAGES,
|
KW_MESSAGES,
|
||||||
INSTANCE_NAME,
|
KW_INSTANCE_NAME,
|
||||||
COUNT,
|
KW_COUNT,
|
||||||
DISPLAY,
|
KW_DISPLAY,
|
||||||
PIN,
|
KW_PIN,
|
||||||
TOOLTIP,
|
KW_TOOLTIP,
|
||||||
CONNECTION,
|
KW_CONNECTION,
|
||||||
ATTRIBUTE,
|
KW_ATTRIBUTE,
|
||||||
SOURCE,
|
KW_SOURCE,
|
||||||
POPUP,
|
KW_POPUP,
|
||||||
RULE,
|
KW_RULE,
|
||||||
TITLE,
|
KW_TITLE,
|
||||||
TEXT,
|
KW_TEXT,
|
||||||
BUS,
|
KW_BUS,
|
||||||
WIRES,
|
KW_WIRES,
|
||||||
ENUMERATED,
|
KW_ENUMERATED,
|
||||||
WIRE,
|
KW_WIRE,
|
||||||
INSTANCE,
|
KW_INSTANCE,
|
||||||
SCHEMA,
|
KW_SCHEMA,
|
||||||
POSITION,
|
KW_POSITION,
|
||||||
SIZE,
|
KW_SIZE,
|
||||||
UNKNOWN
|
KW_UNKNOWN,
|
||||||
};
|
|
||||||
|
|
||||||
|
// TYPES
|
||||||
|
INT_TYPE,
|
||||||
|
BOOL_TYPE,
|
||||||
|
STRING_TYPE,
|
||||||
|
WIRE_TYPE,
|
||||||
|
|
||||||
static KeywordType::Type determineType(std::string type) {
|
// WIRE TYPES
|
||||||
if(keywords.count(type) == 0) {
|
WIRE_DEFAULT,
|
||||||
return UNKNOWN;
|
WIRE_AND,
|
||||||
}
|
WIRE_OR,
|
||||||
return keywords.at(type);
|
R_WIRE,
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
// PIN_TYPES
|
||||||
|
PIN_IN,
|
||||||
|
PIN_OUT,
|
||||||
|
PIN_IN_OUT,
|
||||||
|
|
||||||
const static std::map<std::string, KeywordType::Type> keywords;
|
// COMPONENT TYPES
|
||||||
|
CT_MEMORY,
|
||||||
|
CT_PROCESSOR,
|
||||||
|
|
||||||
|
// ACTION TYPES
|
||||||
|
ERROR,
|
||||||
|
WARNING,
|
||||||
|
|
||||||
|
// OTHER
|
||||||
|
END_OF_FILE
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Token {
|
struct Token {
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
enum TokenClass {
|
enum TokenClass {
|
||||||
BUILT_IN_FUNC = 1,
|
BUILT_IN_FUNC = 1,
|
||||||
DATA_TYPE = 2,
|
DATA_TYPE = 2,
|
||||||
KEYWORD_NAME = 4
|
KEYWORD_NAME = 4,
|
||||||
|
TOKENIZABLE = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +19,8 @@ struct TokenTables {
|
||||||
std::unordered_map<TokenType, TokenInfo> allTokensInfo;
|
std::unordered_map<TokenType, TokenInfo> allTokensInfo;
|
||||||
std::unordered_map<std::string, TokenType> keywords;
|
std::unordered_map<std::string, TokenType> keywords;
|
||||||
|
|
||||||
|
TokenType tokenize(std::string value, TokenType initial);
|
||||||
|
|
||||||
void add(TokenType tokenType, const std::string& txt,
|
void add(TokenType tokenType, const std::string& txt,
|
||||||
unsigned short attribs = 0);
|
unsigned short attribs = 0);
|
||||||
|
|
||||||
|
@ -41,9 +44,9 @@ TokenTables::TokenTables() {
|
||||||
add( TokenType::KEYWORD, "keyword" );
|
add( TokenType::KEYWORD, "keyword" );
|
||||||
|
|
||||||
// Literals (bool is not here, it has two keywords: false and true)
|
// Literals (bool is not here, it has two keywords: false and true)
|
||||||
add( TokenType::NUMBER, "number" );
|
add( TokenType::NUMBER, "number");
|
||||||
add( TokenType::STRING, "string" );
|
add( TokenType::STRING, "string");
|
||||||
add( TokenType::COLOR, "color" );
|
add( TokenType::COLOR, "color");
|
||||||
|
|
||||||
// Parentheses of all kinds
|
// Parentheses of all kinds
|
||||||
add( TokenType::LPAREN, "(" );
|
add( TokenType::LPAREN, "(" );
|
||||||
|
@ -55,7 +58,7 @@ TokenTables::TokenTables() {
|
||||||
add( TokenType::LT, "<" );
|
add( TokenType::LT, "<" );
|
||||||
add( TokenType::GT, ">" );
|
add( TokenType::GT, ">" );
|
||||||
|
|
||||||
// assignments and resizes
|
// assignments
|
||||||
add( TokenType::EQUALS, "=" );
|
add( TokenType::EQUALS, "=" );
|
||||||
|
|
||||||
// miscellaneous
|
// miscellaneous
|
||||||
|
@ -66,6 +69,69 @@ TokenTables::TokenTables() {
|
||||||
add( TokenType::WHITESPACE, "whitespace" );
|
add( TokenType::WHITESPACE, "whitespace" );
|
||||||
add( TokenType::COMMENT, "comment" );
|
add( TokenType::COMMENT, "comment" );
|
||||||
|
|
||||||
|
add( TokenType::TRUE, "true", TOKENIZABLE ),
|
||||||
|
add( TokenType::FALSE, "false", TOKENIZABLE),
|
||||||
|
|
||||||
|
add( TokenType::IF, "if", TOKENIZABLE ),
|
||||||
|
add( TokenType::ELSE, "else", TOKENIZABLE),
|
||||||
|
|
||||||
|
add( TokenType::DEFAULT, "default", TOKENIZABLE),
|
||||||
|
|
||||||
|
// all keywords
|
||||||
|
add( TokenType::KW_NAME, "@name", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_INFO, "@info", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_HEADER, "@header", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_DIRECTORY, "@directory", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_LIBRARY, "@library", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_ADDRESS, "@address", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_COMPONENT, "@component", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_MESSAGES, "@messages", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_INSTANCE_NAME, "@instanceName", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_COUNT, "@count", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_DISPLAY, "@display", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_PIN, "@pin", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_TOOLTIP, "@tooltip", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_CONNECTION, "@connection", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_ATTRIBUTE, "@attribute", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_SOURCE, "@source", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_POPUP, "@popup", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_RULE, "@rule", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_TITLE, "@title", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_TEXT, "@text", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_BUS, "@bus", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_WIRES, "@wires", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_ENUMERATED, "@enumerated", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_WIRE, "@wire", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_INSTANCE, "@instance", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_SCHEMA, "@schema", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_POSITION, "@position", TOKENIZABLE),
|
||||||
|
add( TokenType::KW_SIZE, "@size", TOKENIZABLE),
|
||||||
|
|
||||||
|
// All types
|
||||||
|
add( TokenType::INT_TYPE, "int", TOKENIZABLE),
|
||||||
|
add( TokenType::STRING_TYPE, "string", TOKENIZABLE),
|
||||||
|
add( TokenType::BOOL_TYPE, "bool", TOKENIZABLE),
|
||||||
|
add( TokenType::WIRE_TYPE, "wire", TOKENIZABLE),
|
||||||
|
|
||||||
|
// Wire 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
|
||||||
|
add( TokenType::CT_MEMORY, "memory", TOKENIZABLE),
|
||||||
|
add( TokenType::CT_PROCESSOR, "processor", TOKENIZABLE),
|
||||||
|
|
||||||
|
// Pin type
|
||||||
|
add( TokenType::PIN_IN, "in", TOKENIZABLE),
|
||||||
|
add( TokenType::PIN_OUT, "out", TOKENIZABLE),
|
||||||
|
add( TokenType::PIN_IN_OUT, "inOut", TOKENIZABLE),
|
||||||
|
|
||||||
|
// Action types
|
||||||
|
add( TokenType::ERROR, "error", TOKENIZABLE),
|
||||||
|
add( TokenType::WARNING, "warning", TOKENIZABLE),
|
||||||
|
|
||||||
|
|
||||||
// Built-in functions (they are also keywords)
|
// Built-in functions (they are also keywords)
|
||||||
/*
|
/*
|
||||||
|
@ -76,11 +142,23 @@ TokenTables::TokenTables() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const std::string &tokenTypeToString(TokenType tokenType) {
|
const std::string &tokenTypeToString(TokenType tokenType) {
|
||||||
return tokenTables.allTokensInfo[tokenType].text;
|
return tokenTables.allTokensInfo[tokenType].text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TokenType TokenTables::tokenize(std::string value, TokenType initial) {
|
||||||
|
for(auto& [key, param]: allTokensInfo) {
|
||||||
|
if(param.attributes & TOKENIZABLE && param.text == value) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenType from_token(std::string value, TokenType initial) {
|
||||||
|
return tokenTables.tokenize(value, initial);
|
||||||
|
}
|
||||||
|
|
||||||
bool isBuiltInFunc(TokenType tokenType)
|
bool isBuiltInFunc(TokenType tokenType)
|
||||||
{
|
{
|
||||||
return tokenTables.allTokensInfo[tokenType].attributes & BUILT_IN_FUNC;
|
return tokenTables.allTokensInfo[tokenType].attributes & BUILT_IN_FUNC;
|
||||||
|
|
|
@ -11,5 +11,6 @@ const std::string& tokenTypeToString(TokenType tokenType);
|
||||||
bool isBuiltInFunc(TokenType tokenType);
|
bool isBuiltInFunc(TokenType tokenType);
|
||||||
bool isDataType(TokenType tokenType);
|
bool isDataType(TokenType tokenType);
|
||||||
|
|
||||||
|
TokenType from_token(std::string value, TokenType initial);
|
||||||
|
|
||||||
#endif // TOKENSTYPE_H
|
#endif // TOKENSTYPE_H
|
||||||
|
|
Loading…
Reference in New Issue