This commit is contained in:
2026-02-24 13:21:08 +11:00
parent ca3aec6962
commit d4017b7c18
3 changed files with 90 additions and 2 deletions

View File

@@ -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, {});

View File

@@ -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, {});
}

View File

@@ -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.