Parse object member access

This commit is contained in:
2026-04-10 10:00:24 +10:00
parent a2fc138ba1
commit 5841a7a999
2 changed files with 31 additions and 2 deletions

View File

@@ -21,7 +21,7 @@ typedef enum SolsNodeType {
SNT_DEF, SNT_LAMBDA, SNT_FUNCTION_CALL, SNT_RETURN,
SNT_USE, SNT_STRUCT,
SNT_PUTS, SNT_IF, SNT_WHILE, SNT_NEW,
SNT_GROUND, SNT_ROOT, SNT_EXPR_IN_PAREN
SNT_GROUND, SNT_ROOT, SNT_EXPR_IN_PAREN, SNT_DOT
} SolsNodeType;
struct SolsNode;

View File

@@ -1823,6 +1823,32 @@ ResultType(Nothing, charptr) parseNew(SolsParser* parser) {
return Success(Nothing, charptr, {});
}
ResultType(Nothing, charptr) parseDot(SolsParser* parser) {
ResultType(SolsNode, charptr) newNode = createSolsNode(SNT_DOT);
if (newNode.error) {
return Error(Nothing, charptr, newNode.as.error);
}
if (parser->currentParent->children.count < 1) {
return Error(Nothing, charptr, "Expecting value before '.'");
}
SolsNode left = parser->currentParent->children.at[parser->currentParent->children.count - 1];
ResultType(SolsToken, Nothing) right = parserConsume(parser);
if (right.error || right.as.success.type != STT_IDENTIFIER) {
return Error(Nothing, charptr, "Expecting identifier after '.'");
}
addChildToSolsNode(&newNode.as.success, left);
addChildToSolsNode(&newNode.as.success, ({
ResultType(SolsNode, charptr) _result = createSolsNode(SNT_IDENTIFIER, right.as.success.as.idName);
if (_result.error) {
return Error(Nothing, charptr, _result.as.error);
}
_result.as.success;
}));
addChildToSolsNode(parser->currentParent, newNode.as.success);
return Success(Nothing, charptr, {});
}
ResultType(Nothing, charptr) parse(SolsParser* parser) {
parser->currentParent = &parser->output;
for (;;) {
@@ -1857,13 +1883,16 @@ ResultType(Nothing, charptr) parse(SolsParser* parser) {
case STT_OPEN_CURLY: PARSER_HANDLE(CodeBlock);
case STT_CLOSE_CURLY: PARSER_HANDLE(CloseCurly);
case STT_OPEN_PAREN: {
if (parser->output.children.count > 0 && parser->output.children.at[parser->output.children.count - 1].type == SNT_IDENTIFIER) {
if (parser->output.children.count > 0 &&
(parser->output.children.at[parser->output.children.count - 1].type == SNT_IDENTIFIER
|| parser->output.children.at[parser->output.children.count - 1].type == SNT_DOT)) {
PARSER_HANDLE(FunctionCall);
} else {
PARSER_HANDLE(OpenParen);
}
}
case STT_CLOSE_PAREN: PARSER_HANDLE(CloseParen);
case STT_DOT: PARSER_HANDLE(Dot);
}
}
if (parser->errors.count > 0) {