diff --git a/src/parser/SolsNode.c b/src/parser/SolsNode.c index 70a8161..76b7a11 100644 --- a/src/parser/SolsNode.c +++ b/src/parser/SolsNode.c @@ -55,7 +55,6 @@ ResultType(Nothing, charptr) addChildToSolsNode(SolsNode* parent, SolsNode child } parent->children.at = tmp; } - printf("capacity: %zu, count: %zu\n", parent->children.capacity, parent->children.count); parent->children.at[parent->children.count] = child; parent->children.count++; return Success(Nothing, charptr, {}); diff --git a/src/parser/parser.c b/src/parser/parser.c index 079d092..a7434d8 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -4,6 +4,24 @@ #include "../include/estr.h" #include "../include/ansii.h" +SolsTokenPrecedence getPrecedence(SolsToken *token) { + switch (token->type) { + case STT_LINE_END: return STP_NEWLINE; + case STT_KW_PUTS: return STP_PUTS; + case STT_OP_ADDTO: + case STT_OP_SUBTO: + case STT_OP_MULTO: + case STT_OP_DIVTO: + case STT_OP_INCREMENT: + case STT_OP_DECREMENT: + case STT_OP_SET: return STP_SET; + // FIXME figure out how to do functions + case STT_OP_MUL: case STT_OP_DIV: return STP_MUL; + case STT_OP_ADD: case STT_OP_SUB: return STP_ADD; + default: return STP_OTHER; + } +} + ResultType(SolsParser, charptr) createSolsParser(SolsTokens* input) { ResultType(SolsNode, charptr) node = createSolsNode(SNT_ROOT); if (node.error) { @@ -25,6 +43,20 @@ ResultType(SolsParser, charptr) createSolsParser(SolsTokens* input) { return Success(SolsParser, charptr, parser); } +void addToParserErrors(SolsParser* parser, char* errors) { + if (parser->errors.count + 1 >= parser->errors.capacity) { + parser->errors.capacity *= 2; + char** tmp = realloc(parser->errors.at, sizeof(char*) * parser->errors.capacity); + if (tmp == NULL) { + parser->errors.at[parser->errors.count - 1] = "Failed to allocate more memory for addToParserErrors function"; + return; + } + parser->errors.at = tmp; + } + parser->errors.at[parser->errors.count] = errors; + parser->errors.count++; +} + void createParserError(SolsParser* parser, char* what) { ResultType(SolsToken, Nothing) prevToken = Error(SolsToken, Nothing, {}); @@ -109,6 +141,7 @@ static inline ResultType(Nothing, charptr) parseIdentifier(SolsParser* parser) { addChildToSolsNode(parser->currentParent, node.as.success); return Success(Nothing, charptr, {}); } + static inline ResultType(Nothing, charptr) parseLiteral(SolsParser* parser) { ResultType(SolsToken, Nothing) peek = parserPeek(parser, 0); if (peek.error) { @@ -125,7 +158,45 @@ static inline ResultType(Nothing, charptr) parseLiteral(SolsParser* parser) { } static inline ResultType(Nothing, charptr) parsePuts(SolsParser* parser) { - return Error(Nothing, charptr, "Not an error, just curious what errors look like"); + + // Collect tokens for node + ResultType(SolsTokens, charptr) tokens = createSolsTokens(); + if (tokens.error) { + return Error(Nothing, charptr, tokens.as.error); + } + + for (;;) { + ResultType(SolsToken, Nothing) peek = parserPeek(parser, 1); + if (peek.error) break; + if (getPrecedence(&peek.as.success) <= STP_PUTS) { + break; + } + parserConsume(parser); + addTokenToSolsTokens(&tokens.as.success, peek.as.success); + } + + // Create node + ResultType(SolsNode, charptr) node = createSolsNode(SNT_PUTS); + if (node.error) return Error(Nothing, charptr, node.as.error); + + // Parse selected tokens + ResultType(SolsParser, charptr) putsParser = createSolsParser(&tokens.as.success); + if (putsParser.error) return Error(Nothing, charptr, putsParser.as.error); + putsParser.as.success.currentParent = &putsParser.as.success.output; + ResultType(Nothing, charptr) parsed = parse(&putsParser.as.success); + + // Copy nodes into the sols node + for (size_t i = 0; i < putsParser.as.success.output.children.count; i++) { + addChildToSolsNode(&node.as.success, putsParser.as.success.output.children.at[i]); + } + + // Add any error messages from parsing + if (parsed.error) { + addToParserErrors(parser, parsed.as.error); + } + + addChildToSolsNode(parser->currentParent, node.as.success); + return Success(Nothing, charptr, {}); } diff --git a/src/parser/parser.h b/src/parser/parser.h index 3e49296..e1368c1 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -6,6 +6,24 @@ #include "../include/error.h" #include "../include/nothing.h" +// Defines precedence for different tokens. +// Lower number means higher priority. +// Any operation involving same or higher precedence than +// the current token's precedence should be processed first +// (i.e. placed further down the tree) +typedef enum SolsTokenPrecedence { + STP_NEWLINE = 0, + STP_PUTS = 1, + STP_SET = 2, + STP_FUNCTION = 3, + STP_MUL = 4, + STP_ADD = 5, + STP_OTHER = 7, +} SolsTokenPrecedence; + +// Gets the precedence of the provided token. +SolsTokenPrecedence getPrecedence(SolsToken* token); + // Holds information about the parser. // .input is lexed tokens, produced by a lexer. // .current is the token currently being parsed.