forked from solstice/solstice
Parse structs
This commit is contained in:
@@ -1673,6 +1673,145 @@ static inline ResultType(Nothing, charptr) parseCloseParen(SolsParser* parser) {
|
||||
return Error(Nothing, charptr, "Extra closing parentheses");
|
||||
}
|
||||
|
||||
static inline ResultType(Nothing, charptr) parseStruct(SolsParser* parser) {
|
||||
// Get struct name
|
||||
SolsNode structNode = ({
|
||||
ResultType(SolsNode, charptr) _result = createSolsNode(SNT_STRUCT);
|
||||
if (_result.error) {
|
||||
return Error(Nothing, charptr, _result.as.error);
|
||||
}
|
||||
_result.as.success;
|
||||
});
|
||||
ResultType(SolsToken, Nothing) nameTok = parserConsume(parser);
|
||||
if (nameTok.error || nameTok.as.success.type != STT_IDENTIFIER) {
|
||||
return Error(Nothing, charptr, "Expecting identifier after 'struct'");
|
||||
}
|
||||
structNode.as.idName = nameTok.as.success.as.idName;
|
||||
ResultType(SolsToken, Nothing) openCurly = parserConsume(parser);
|
||||
if (openCurly.error || openCurly.as.success.type != STT_OPEN_CURLY) {
|
||||
return Error(Nothing, charptr, "Expecting '{' after struct identifier");
|
||||
}
|
||||
// Ignore new lines between struct and opening curly brace
|
||||
for (;;) {
|
||||
ResultType(SolsToken, Nothing) token = parserPeek(parser, 0);
|
||||
if (token.error) {
|
||||
return Error(Nothing, charptr, "Expecting '{' after 'struct'");
|
||||
}
|
||||
if (token.as.success.type == STT_LINE_END) {
|
||||
parserConsume(parser);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (;;) {
|
||||
bool done = false;
|
||||
// Skip newlines between struct values
|
||||
for (;;) {
|
||||
ResultType(SolsToken, Nothing) token = parserPeek(parser, 0);
|
||||
if (token.error) {
|
||||
return Error(Nothing, charptr, "Expecting '}' to end struct");
|
||||
}
|
||||
if (token.as.success.type == STT_LINE_END) {
|
||||
parserConsume(parser);
|
||||
}
|
||||
else if (token.as.success.type == STT_CLOSE_CURLY) {
|
||||
done = true;
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
parserConsume(parser);
|
||||
if (done) break;
|
||||
|
||||
// key = value\n
|
||||
SolsToken keyTok = ({
|
||||
ResultType(SolsToken, Nothing) _result = parserConsume(parser);
|
||||
if (_result.error) {
|
||||
return Error(Nothing, charptr, "Expecting struct key");
|
||||
}
|
||||
_result.as.success;
|
||||
});
|
||||
if (keyTok.type != STT_IDENTIFIER) {
|
||||
return Error(Nothing, charptr, "Expecting struct key");
|
||||
}
|
||||
SolsToken setTok = ({
|
||||
ResultType(SolsToken, Nothing) _result = parserConsume(parser);
|
||||
if (_result.error) {
|
||||
return Error(Nothing, charptr, "Expecting '=' after struct key");
|
||||
}
|
||||
_result.as.success;
|
||||
});
|
||||
if (setTok.type != STT_OP_SET) {
|
||||
return Error(Nothing, charptr, "Expecting '=' after struct key");
|
||||
}
|
||||
parserConsume(parser);
|
||||
SolsTokens tokens = ({
|
||||
ResultType(SolsTokens, charptr) _result = createSolsTokens();
|
||||
if (_result.error) {
|
||||
return Error(Nothing, charptr, _result.as.error);
|
||||
}
|
||||
_result.as.success;
|
||||
});
|
||||
// Collect tokens for value
|
||||
if (parserPeek(parser, 0).error) {
|
||||
return Error(Nothing, charptr, "Expecting value after '='");
|
||||
}
|
||||
for (;;) {
|
||||
ResultType(SolsToken, Nothing) token = parserPeek(parser, 0);
|
||||
if (token.error) {
|
||||
break;
|
||||
}
|
||||
if (getPrecedence(&token.as.success) <= STP_NEWLINE) {
|
||||
break;
|
||||
}
|
||||
addTokenToSolsTokens(&tokens, token.as.success);
|
||||
parserConsume(parser);
|
||||
}
|
||||
// Parse value
|
||||
SolsParser newParser = ({
|
||||
ResultType(SolsParser, charptr) _result = createSolsParser(&tokens);
|
||||
if (_result.error) {
|
||||
return Error(Nothing, charptr, _result.as.error);
|
||||
}
|
||||
_result.as.success;
|
||||
});
|
||||
newParser.currentParent = &newParser.output;
|
||||
ResultType(Nothing, charptr) parsed = parse(&newParser);
|
||||
if (parsed.error) {
|
||||
addToParserErrors(parser, parsed.as.error);
|
||||
}
|
||||
// Construct set node
|
||||
SolsNode setNode = ({
|
||||
ResultType(SolsNode, charptr) _result = createSolsNode(SNT_OP_SET);
|
||||
if (_result.error) {
|
||||
return Error(Nothing, charptr, _result.as.error);
|
||||
}
|
||||
_result.as.success;
|
||||
});
|
||||
addChildToSolsNode(&setNode, ({
|
||||
ResultType(SolsNode, charptr) _result = createSolsNode(SNT_IDENTIFIER, keyTok.as.idName);
|
||||
if (_result.error) {
|
||||
return Error(Nothing, charptr, _result.as.error);
|
||||
}
|
||||
_result.as.success;
|
||||
}));
|
||||
addChildToSolsNode(&setNode, newParser.output.children.at[0]);
|
||||
|
||||
// Add set node to struct node
|
||||
addChildToSolsNode(&structNode, setNode);
|
||||
|
||||
// Consume newline
|
||||
ResultType(SolsToken, Nothing) newline = parserConsume(parser);
|
||||
if (newline.error) {
|
||||
return Error(Nothing, charptr, "Expecting newline after struct value");
|
||||
}
|
||||
}
|
||||
// Add struct node to parent
|
||||
addChildToSolsNode(parser->currentParent, structNode);
|
||||
return Success(Nothing, charptr, {});
|
||||
}
|
||||
|
||||
ResultType(Nothing, charptr) parse(SolsParser* parser) {
|
||||
parser->currentParent = &parser->output;
|
||||
for (;;) {
|
||||
@@ -1689,6 +1828,7 @@ ResultType(Nothing, charptr) parse(SolsParser* parser) {
|
||||
case STT_KW_GROUND: PARSER_HANDLE(InlineGround);
|
||||
case STT_KW_LAMBDA: PARSER_HANDLE(Lambda);
|
||||
case STT_KW_RETURN: PARSER_HANDLE(Return);
|
||||
case STT_KW_STRUCT: PARSER_HANDLE(Struct);
|
||||
case STT_KW_USE: PARSER_HANDLE(Use);
|
||||
case STT_KW_DEF: PARSER_HANDLE(Def);
|
||||
case STT_OP_SET: PARSER_HANDLE(Set);
|
||||
|
||||
Reference in New Issue
Block a user