diff --git a/src/parser/SolsNode.h b/src/parser/SolsNode.h index 5e2aef7..3990321 100644 --- a/src/parser/SolsNode.h +++ b/src/parser/SolsNode.h @@ -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; diff --git a/src/parser/parser.c b/src/parser/parser.c index ff194ce..5655842 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -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) {