Parse structs

This commit is contained in:
2026-04-09 15:39:17 +10:00
parent 6988f314b0
commit 00d6ed83fb

View File

@@ -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);