Function calling now works, only need return

This commit is contained in:
2026-03-01 13:39:27 +11:00
parent dc09883e46
commit bf71a0dfac
3 changed files with 59 additions and 27 deletions

View File

@@ -1407,53 +1407,60 @@ static inline ResultType(Nothing, charptr) parseDef(SolsParser* parser) {
}
static inline ResultType(Nothing, charptr) parseFunctionCall(SolsParser* parser) {
ResultType(SolsNode, charptr) node = createSolsNode(SNT_FUNCTION_CALL);
if (node.error) {
return Error(Nothing, charptr, node.as.error);
}
ResultType(SolsToken, Nothing) idToken = parserPeek(parser, -1);
if (idToken.error) {
return Error(Nothing, charptr, "Couldn't get id token for some odd reason");
// The identifier (function name) was already parsed as a node right before '('
if (parser->currentParent->children.count < 1 ||
parser->currentParent->children.at[parser->currentParent->children.count - 1].type != SNT_IDENTIFIER) {
return Error(Nothing, charptr, "Expecting identifier before '(' for function call");
}
node.as.success.as.idName = idToken.as.success.as.idName;
SolsNode callee = parser->currentParent->children.at[parser->currentParent->children.count - 1];
parser->currentParent->children.count--; // remove callee identifier node; we'll replace it with the call node
// create a node for each expression between commas
node.as.success.as.idName = callee.as.idName;
node.as.success.line = callee.line;
// Empty argument list: foo()
ResultType(SolsToken, Nothing) peek = parserPeek(parser, 1);
if (peek.error) {
return Error(Nothing, charptr, "Expecting ')' or a value");
}
SolsTokens tokens;
if (peek.as.success.type == STT_CLOSE_PAREN) {
parserConsume(parser); // consume ')'
addChildToSolsNode(parser->currentParent, node.as.success);
return Success(Nothing, charptr, {});
}
// Parse each argument expression separated by commas until ')'
for (;;) {
ResultType(SolsTokens, charptr) resultTokens = createSolsTokens();
if (resultTokens.error) {
return Error(Nothing, charptr, resultTokens.as.error);
}
tokens = resultTokens.as.success;
SolsTokens tokens = resultTokens.as.success;
size_t curlys = 0;
size_t parens = 0;
for (;;) {
peek = parserPeek(parser, 1);
if (peek.error) {
return Error(Nothing, charptr, "Expecting ')'");
}
if (peek.as.success.type == STT_OPEN_PAREN) {
parens++;
}
if (peek.as.success.type == STT_OPEN_PAREN) parens++;
if (peek.as.success.type == STT_CLOSE_PAREN) {
if (parens == 0) {
break;
}
if (parens == 0) break;
parens--;
}
if (peek.as.success.type == STT_OPEN_CURLY) {
curlys++;
}
if (peek.as.success.type == STT_CLOSE_CURLY) {
curlys--;
}
if (peek.as.success.type == STT_OPEN_CURLY) curlys++;
if (peek.as.success.type == STT_CLOSE_CURLY) curlys--;
if (curlys == 0 && parens == 0 && peek.as.success.type == STT_COMMA) {
break;
@@ -1468,6 +1475,7 @@ static inline ResultType(Nothing, charptr) parseFunctionCall(SolsParser* parser)
return Error(Nothing, charptr, newParser.as.error);
}
newParser.as.success.currentParent = &newParser.as.success.output;
ResultType(Nothing, charptr) parsed = parse(&newParser.as.success);
if (parsed.error) {
addToParserErrors(parser, parsed.as.error);
@@ -1477,8 +1485,11 @@ static inline ResultType(Nothing, charptr) parseFunctionCall(SolsParser* parser)
if (newParser.as.success.output.children.count < 1) {
return Error(Nothing, charptr, "Expecting a value before ',' or ')'");
}
// One argument expression -> one AST node
addChildToSolsNode(&node.as.success, newParser.as.success.output.children.at[0]);
// Consume ',' or ')'
peek = parserConsume(parser);
if (peek.error) {
return Error(Nothing, charptr, "Expecting ')' or ','");
@@ -1486,11 +1497,13 @@ static inline ResultType(Nothing, charptr) parseFunctionCall(SolsParser* parser)
if (peek.as.success.type == STT_CLOSE_PAREN) {
break;
}
addChildToSolsNode(parser->currentParent, node.as.success);
if (peek.as.success.type != STT_COMMA) {
return Error(Nothing, charptr, "Expecting ',' or ')'");
}
}
// Add the fully-built call node once
addChildToSolsNode(parser->currentParent, node.as.success);
return Success(Nothing, charptr, {});
}