Added support for integers and null to connections
This commit is contained in:
parent
9bd68ecf23
commit
dfc7bf48dc
|
@ -58,6 +58,8 @@ Value toType(ValueNode node) {
|
||||||
return Value::fromInt(node.asInt());
|
return Value::fromInt(node.asInt());
|
||||||
} else if(node.getType() == ValueNode::STRING) {
|
} else if(node.getType() == ValueNode::STRING) {
|
||||||
return Value::fromString(node.asString());
|
return Value::fromString(node.asString());
|
||||||
|
} else if(node.getType() == ValueNode::NIL) {
|
||||||
|
return Value::fromNull();
|
||||||
}
|
}
|
||||||
return Value::fromReference(node.asIdentifier(), Value::UNDEFINED);
|
return Value::fromReference(node.asIdentifier(), Value::UNDEFINED);
|
||||||
}
|
}
|
||||||
|
@ -228,12 +230,12 @@ std::optional<Connection> ComdelGenerator::loadConnection(ConnectionNode node)
|
||||||
|
|
||||||
auto componentInstance = getComponentPin(component, pin);
|
auto componentInstance = getComponentPin(component, pin);
|
||||||
if(!componentInstance) {
|
if(!componentInstance) {
|
||||||
errors.push_back(SourceError(node.span, "pin does not exist"));
|
errors.emplace_back(node.span, "pin does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto busInstance = getBus(bus);
|
auto busInstance = getBus(bus);
|
||||||
if(!busInstance) {
|
if(!busInstance) {
|
||||||
errors.push_back(SourceError(node.span, "bus does not exist"));
|
errors.emplace_back(node.span, "bus does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<std::string> wireNames;
|
std::set<std::string> wireNames;
|
||||||
|
@ -258,12 +260,20 @@ std::optional<Connection> ComdelGenerator::loadConnection(ConnectionNode node)
|
||||||
|
|
||||||
std::vector<Value> wires;
|
std::vector<Value> wires;
|
||||||
for(uint i=0; i<node.wires.size(); i++) {
|
for(uint i=0; i<node.wires.size(); i++) {
|
||||||
if(attributeNames.count(node.wires[i].value)) {
|
if(node.wires[i].is(ValueNode::NIL)) {
|
||||||
wires.push_back(Value::fromReference(node.wires[i].value, Value::ATTRIBUTE_REFERENCE));
|
wires.push_back(Value::fromNull());
|
||||||
} else if(wireNames.count(node.wires[i].value)) {
|
} else if(node.wires[i].is(ValueNode::INT)) {
|
||||||
wires.push_back(Value::fromReference(node.wires[i].value, Value::WIRE_REFERENCE));
|
wires.push_back(Value::fromInt(node.wires[i].asInt()));
|
||||||
|
} else if(node.wires[i].is(ValueNode::IDENTIFIER)) {
|
||||||
|
if(attributeNames.count(node.wires[i].asIdentifier())) {
|
||||||
|
wires.push_back(Value::fromReference(node.wires[i].asIdentifier(), Value::ATTRIBUTE_REFERENCE));
|
||||||
|
} else if(wireNames.count(node.wires[i].asIdentifier())) {
|
||||||
|
wires.push_back(Value::fromReference(node.wires[i].asIdentifier(), Value::WIRE_REFERENCE));
|
||||||
|
} else {
|
||||||
|
errors.emplace_back(node.wires[i].span, "unknown identifier");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
errors.push_back(SourceError(node.wires[i].span, "unknown identifier"));
|
errors.emplace_back(node.wires[i].span, "unknown value type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,26 +530,34 @@ std::optional<Popup> ComdelGenerator::loadPopup(PopupNode node, std::string name
|
||||||
std::vector<Enumeration> enumeration;
|
std::vector<Enumeration> enumeration;
|
||||||
if(node.enumerated) {
|
if(node.enumerated) {
|
||||||
for(uint i=0; i<node.enumeration.size(); i++) {
|
for(uint i=0; i<node.enumeration.size(); i++) {
|
||||||
if(toType(node.enumeration[i].value.getType()) != type) {
|
if(type == Value::INT || type == Value::STRING || type == Value::BOOL) {
|
||||||
|
auto value = toType(node.enumeration[i].value);
|
||||||
|
if(value.getType() == type) {
|
||||||
|
enumeration.push_back(Enumeration(node.enumeration[i].key.asString(), value));
|
||||||
|
} else {
|
||||||
|
errors.push_back(SourceError{node.enumeration[i].span, "wrong type"});
|
||||||
|
}
|
||||||
|
} else if(type == Value::WIRE_REFERENCE) {
|
||||||
|
auto value = toType(node.enumeration[i].value);
|
||||||
|
if(value.isType(Value::UNDEFINED)) {
|
||||||
|
if(current().doesWireExists(value.asReference())) {
|
||||||
|
value = Value::fromReference(value.asReference(), Value::WIRE_REFERENCE);
|
||||||
|
} else {
|
||||||
|
errors.push_back(SourceError{node.enumeration[i].span, "unknown wire"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(value.isType(Value::WIRE_REFERENCE) || value.isType(Value::INT) || value.isType(Value::NIL)) {
|
||||||
|
enumeration.push_back(Enumeration(node.enumeration[i].key.asString(), value));
|
||||||
|
} else {
|
||||||
|
errors.push_back(SourceError{node.enumeration[i].span, "wrong type"});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
auto value = toType(node.enumeration[i].value);
|
|
||||||
|
|
||||||
if(value.isType(Value::UNDEFINED) && current().doesWireExists(value.asReference())) {
|
|
||||||
value = Value::fromReference(value.asReference(), Value::WIRE_REFERENCE);
|
|
||||||
} else {
|
|
||||||
errors.push_back(SourceError{node.enumeration[i].span, "unknown wire"});
|
|
||||||
}
|
|
||||||
if(value.getType() != type) {
|
|
||||||
errors.push_back(SourceError{node.enumeration[i].span, "wrong type"});
|
|
||||||
}
|
|
||||||
enumeration.push_back(Enumeration(node.enumeration[i].key.asString(), value));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(type == Value::WIRE_REFERENCE && !current().inConnection) {
|
if(type == Value::WIRE_REFERENCE && !current().inConnection) {
|
||||||
errors.push_back(SourceError{node.span, "@enumeration is required for attributes of type wire"});
|
errors.push_back(SourceError{node.span, "@enumeration is required for attributes of type wire"});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pop();
|
pop();
|
||||||
|
|
|
@ -105,4 +105,10 @@ Value Value::ofType(Value::ValueType type) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value Value::fromNull() {
|
||||||
|
Value val;
|
||||||
|
val.type = Value::NIL;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace domain
|
} // namespace domain
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
ADDRESS_SPACE,
|
ADDRESS_SPACE,
|
||||||
ATTRIBUTE_REFERENCE,
|
ATTRIBUTE_REFERENCE,
|
||||||
WIRE_REFERENCE,
|
WIRE_REFERENCE,
|
||||||
|
NIL,
|
||||||
UNDEFINED,
|
UNDEFINED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -54,6 +55,7 @@ public:
|
||||||
static Value fromInt(long long value);
|
static Value fromInt(long long value);
|
||||||
static Value fromString(std::string value);
|
static Value fromString(std::string value);
|
||||||
static Value fromBool(bool value);
|
static Value fromBool(bool value);
|
||||||
|
static Value fromNull();
|
||||||
static Value fromAddressSpace(AddressSpace addressSpace);
|
static Value fromAddressSpace(AddressSpace addressSpace);
|
||||||
static Value fromReference(std::string value, ValueType type);
|
static Value fromReference(std::string value, ValueType type);
|
||||||
static Value ofType(ValueType type);
|
static Value ofType(ValueType type);
|
||||||
|
|
|
@ -74,7 +74,8 @@ public:
|
||||||
STRING,
|
STRING,
|
||||||
BOOL,
|
BOOL,
|
||||||
WIRE,
|
WIRE,
|
||||||
IDENTIFIER
|
IDENTIFIER,
|
||||||
|
NIL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,6 +149,12 @@ public:
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ValueNode ofNull() {
|
||||||
|
ValueNode value;
|
||||||
|
value.type = NIL;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
static ValueNode ofWire(std::string _value) {
|
static ValueNode ofWire(std::string _value) {
|
||||||
ValueNode value;
|
ValueNode value;
|
||||||
value.type = WIRE;
|
value.type = WIRE;
|
||||||
|
@ -293,7 +300,7 @@ struct ConnectionNode: AstNode
|
||||||
IdentifierNode pin;
|
IdentifierNode pin;
|
||||||
IdentifierNode bus;
|
IdentifierNode bus;
|
||||||
std::vector<AttributeNode> attributes;
|
std::vector<AttributeNode> attributes;
|
||||||
std::vector<IdentifierNode> wires;
|
std::vector<ValueNode> wires;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ inline bool identifierContinue(char ch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool numberStart(char ch) {
|
inline bool numberStart(char ch) {
|
||||||
return isdigit(ch);
|
return isdigit(ch) || ch == '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isWhitespace(char ch) {
|
inline bool isWhitespace(char ch) {
|
||||||
|
@ -64,10 +64,10 @@ LexerResult ComdelLexer::tokenize() {
|
||||||
|
|
||||||
tokenType = from_token(text, tokenType.value());
|
tokenType = from_token(text, tokenType.value());
|
||||||
|
|
||||||
tokens.push_back(Token(*tokenType, Span(tokenBegin, position), text));
|
tokens.emplace_back(*tokenType, Span(tokenBegin, position), text);
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens.push_back(Token( TokenType::END_OF_FILE, Span(position), ""));
|
tokens.emplace_back( TokenType::END_OF_FILE, Span(position), "");
|
||||||
|
|
||||||
return LexerResult { tokens, errors };
|
return LexerResult { tokens, errors };
|
||||||
}
|
}
|
||||||
|
@ -251,6 +251,9 @@ PResult<TokenType> ComdelLexer::nextTokenType() {
|
||||||
}
|
}
|
||||||
else if (numberStart(ch))
|
else if (numberStart(ch))
|
||||||
{
|
{
|
||||||
|
if(ch == '-') {
|
||||||
|
bump();
|
||||||
|
}
|
||||||
unsigned takenDigits;
|
unsigned takenDigits;
|
||||||
Radix radix = takeRadix();
|
Radix radix = takeRadix();
|
||||||
takenDigits = takeNumberInRadix(radix);
|
takenDigits = takeNumberInRadix(radix);
|
||||||
|
@ -393,15 +396,6 @@ PResult<TokenType> ComdelLexer::nextTokenType() {
|
||||||
bump();
|
bump();
|
||||||
return TokenType::EQUALS;
|
return TokenType::EQUALS;
|
||||||
}
|
}
|
||||||
else if (ch == '<')
|
|
||||||
{
|
|
||||||
bump();
|
|
||||||
return TokenType::LT;
|
|
||||||
}
|
|
||||||
else if (ch == '>')
|
|
||||||
{
|
|
||||||
return TokenType::GT;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::stringstream message;
|
std::stringstream message;
|
||||||
|
|
|
@ -711,8 +711,10 @@ PResult<AttributeNode> ComdelParser::parseAttribute() {
|
||||||
|
|
||||||
if(attribute.type == ValueNode::BOOL) {
|
if(attribute.type == ValueNode::BOOL) {
|
||||||
if(check(TokenType::TRUE)) {
|
if(check(TokenType::TRUE)) {
|
||||||
|
bump();
|
||||||
attribute.defaultValue = ValueNode::ofBool(true);
|
attribute.defaultValue = ValueNode::ofBool(true);
|
||||||
} else if(check(TokenType::FALSE)) {
|
} else if(check(TokenType::FALSE)) {
|
||||||
|
bump();
|
||||||
attribute.defaultValue = ValueNode::ofBool(false);
|
attribute.defaultValue = ValueNode::ofBool(false);
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
return unexpected();
|
||||||
|
@ -742,7 +744,10 @@ PResult<AttributeNode> ComdelParser::parseAttribute() {
|
||||||
if(check(TokenType::IDENTIFIER)) {
|
if(check(TokenType::IDENTIFIER)) {
|
||||||
auto identifier = parseIdentifier();
|
auto identifier = parseIdentifier();
|
||||||
attribute.defaultValue = ValueNode::ofWire(identifier->value);
|
attribute.defaultValue = ValueNode::ofWire(identifier->value);
|
||||||
} else {
|
} else if(check(TokenType::NIL)) {
|
||||||
|
bump();
|
||||||
|
attribute.defaultValue = ValueNode::ofNull();
|
||||||
|
} else {
|
||||||
return unexpected();
|
return unexpected();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -868,8 +873,8 @@ PResult<ConnectionNode> ComdelParser::parseConnection() {
|
||||||
APPEND_OR_RETURN_IF_ERR(connection.attributes, parseAttribute());
|
APPEND_OR_RETURN_IF_ERR(connection.attributes, parseAttribute());
|
||||||
} else if(check(TokenType::KW_WIRES)) {
|
} else if(check(TokenType::KW_WIRES)) {
|
||||||
bump();
|
bump();
|
||||||
auto wires = parseList<IdentifierNode>(std::optional<TokenType>(TokenType::LBRACE), TokenType::RBRACE, std::optional<TokenType>(TokenType::COMMA), false,
|
auto wires = parseList<ValueNode>(std::optional<TokenType>(TokenType::LBRACE), TokenType::RBRACE, std::optional<TokenType>(TokenType::COMMA), false,
|
||||||
[this] { return parseIdentifier(); });
|
[this] { return parseConnectionWire(); });
|
||||||
RETURN_IF_ERR(wires);
|
RETURN_IF_ERR(wires);
|
||||||
connection.wires = *wires;
|
connection.wires = *wires;
|
||||||
} else {
|
} else {
|
||||||
|
@ -973,9 +978,14 @@ PResult<ValueNode> ComdelParser::parseValue() {
|
||||||
} else if(check(TokenType::NUMBER)) {
|
} else if(check(TokenType::NUMBER)) {
|
||||||
value = ValueNode::ofInt(parseNumber()->value);
|
value = ValueNode::ofInt(parseNumber()->value);
|
||||||
} else if(check(TokenType::TRUE)) {
|
} else if(check(TokenType::TRUE)) {
|
||||||
|
bump();
|
||||||
value = ValueNode::ofBool(true);
|
value = ValueNode::ofBool(true);
|
||||||
} else if(check(TokenType::FALSE)) {
|
} else if(check(TokenType::FALSE)) {
|
||||||
|
bump();
|
||||||
value = ValueNode::ofBool(false);
|
value = ValueNode::ofBool(false);
|
||||||
|
} else if(check(TokenType::NIL)) {
|
||||||
|
bump();
|
||||||
|
value = ValueNode::ofNull();
|
||||||
} else {
|
} else {
|
||||||
return unexpected();
|
return unexpected();
|
||||||
}
|
}
|
||||||
|
@ -1167,3 +1177,16 @@ PResult<ConnectionInstanceNode> ComdelParser::parseConnectionInstance() {
|
||||||
return spanner(connection);
|
return spanner(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PResult<ValueNode> ComdelParser::parseConnectionWire() {
|
||||||
|
if(check(TokenType::NUMBER)) {
|
||||||
|
return ValueNode::ofInt(parseNumber()->value);
|
||||||
|
} else if(check(TokenType::NIL)) {
|
||||||
|
bump();
|
||||||
|
return ValueNode::ofNull();
|
||||||
|
} else if(check(TokenType::IDENTIFIER)) {
|
||||||
|
return ValueNode::ofIdentifier(parseIdentifier()->value);
|
||||||
|
} else {
|
||||||
|
return unexpected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ private:
|
||||||
PResult<PropertyNode> parseProperty(std::optional<TokenType> valueType);
|
PResult<PropertyNode> parseProperty(std::optional<TokenType> valueType);
|
||||||
PResult<EnumerationNode> parseEnumeration();
|
PResult<EnumerationNode> parseEnumeration();
|
||||||
|
|
||||||
|
PResult<ValueNode> parseConnectionWire();
|
||||||
PResult<ComponentNode> parseComponent();
|
PResult<ComponentNode> parseComponent();
|
||||||
PResult<AddressSpaceNode> parseAddress();
|
PResult<AddressSpaceNode> parseAddress();
|
||||||
PResult<PinNode> parsePin();
|
PResult<PinNode> parsePin();
|
||||||
|
@ -84,6 +85,7 @@ private:
|
||||||
PResult<IfStatementNode> parseIfStatement();
|
PResult<IfStatementNode> parseIfStatement();
|
||||||
PResult<ValueNode> parseValue();
|
PResult<ValueNode> parseValue();
|
||||||
|
|
||||||
|
|
||||||
PResult<WireInstanceNode> parseWireInstance();
|
PResult<WireInstanceNode> parseWireInstance();
|
||||||
PResult<CountNode> parsePosition();
|
PResult<CountNode> parsePosition();
|
||||||
PResult<InstanceNode> parseInstance();
|
PResult<InstanceNode> parseInstance();
|
||||||
|
|
|
@ -65,6 +65,9 @@ enum class TokenType {
|
||||||
TRUE,
|
TRUE,
|
||||||
FALSE,
|
FALSE,
|
||||||
|
|
||||||
|
// NULL
|
||||||
|
NIL,
|
||||||
|
|
||||||
// KEYWORDS
|
// KEYWORDS
|
||||||
KW_NAME,
|
KW_NAME,
|
||||||
KW_INFO,
|
KW_INFO,
|
||||||
|
|
|
@ -76,6 +76,7 @@ TokenTables::TokenTables() {
|
||||||
add( TokenType::ELSE, "else", TOKENIZABLE),
|
add( TokenType::ELSE, "else", TOKENIZABLE),
|
||||||
|
|
||||||
add( TokenType::DEFAULT, "default", TOKENIZABLE),
|
add( TokenType::DEFAULT, "default", TOKENIZABLE),
|
||||||
|
add( TokenType::NIL, "null", TOKENIZABLE),
|
||||||
|
|
||||||
// all keywords
|
// all keywords
|
||||||
add( TokenType::KW_NAME, "@name", TOKENIZABLE),
|
add( TokenType::KW_NAME, "@name", TOKENIZABLE),
|
||||||
|
|
|
@ -63,14 +63,14 @@ void MainWindow::onTestModal() {
|
||||||
library = generator.loadLibrary(*schemaNode->library);
|
library = generator.loadLibrary(*schemaNode->library);
|
||||||
|
|
||||||
for (auto& error : generator.getErrors()) {
|
for (auto& error : generator.getErrors()) {
|
||||||
parseContext.formatError(error, std::cout, "ERROR: ");
|
parseContext.formatError(error, std::cout, "GENERATOR ERROR: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(library) {
|
if(library) {
|
||||||
schema = generator.loadSchema(*schemaNode, *library);
|
schema = generator.loadSchema(*schemaNode, *library);
|
||||||
|
|
||||||
for (auto& error : generator.getErrors()) {
|
for (auto& error : generator.getErrors()) {
|
||||||
parseContext.formatError(error, std::cout, "ERROR: ");
|
parseContext.formatError(error, std::cout, "LIBRARY ERROR: ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue