From 437023fe6551b7e989f18eef8e85b840a19b8303 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sat, 21 Feb 2026 17:01:48 +1100 Subject: [PATCH] start parser --- build.c | 1 + src/parser/SolsNode.c | 60 +++++++++++++++++++++++++++++++++++++++++++ src/parser/SolsNode.h | 56 ++++++++++++++++++++++++++++++++++++++++ src/parser/parser.h | 6 +++++ 4 files changed, 123 insertions(+) create mode 100644 src/parser/SolsNode.c create mode 100644 src/parser/SolsNode.h create mode 100644 src/parser/parser.h diff --git a/build.c b/build.c index b5949a6..0ad320b 100755 --- a/build.c +++ b/build.c @@ -39,6 +39,7 @@ exit #include "src/lexer/lexer.c" // -- PARSER -- +#include "src/parser/SolsNode.c" // -- CODEGEN -- diff --git a/src/parser/SolsNode.c b/src/parser/SolsNode.c new file mode 100644 index 0000000..b9bb640 --- /dev/null +++ b/src/parser/SolsNode.c @@ -0,0 +1,60 @@ +#include "SolsNode.h" + +#include + +#include "../include/error.h" +#include "../lexer/SolsLiteral.h" +#include "../lexer/SolsType.h" + +ResultType(SolsNode, charptr) createSolsNode(SolsNodeType type, ...) { + va_list args; + va_start(args, type); + + SolsNode node = { + .type = type, + .children.capacity = 32, + .children.count = 0, + .children.at = malloc(sizeof(SolsNode) * 32) + }; + + if (node.children.at == NULL) { + return Error(SolsNode, charptr, "Failed to allocate memory for children (in createSolsNode() function)"); + } + + switch (type) { + case SNT_LITERAL: { + node.as.literal = va_arg(args, SolsLiteral); + break; + } + case SNT_TYPE: { + node.as.type = va_arg(args, SolsType); + break; + } + case SNT_IDENTIFIER: { + node.as.idName = va_arg(args, char*); + break; + } + case SNT_GROUND: { + node.as.inlineGround = va_arg(args, char*); + break; + } + default: break; + } + + va_end(args); + return Success(SolsNode, charptr, node); +} + +ResultType(Nothing, charptr) addChildToSolsNode(SolsNode* parent, SolsNode child) { + if (parent->children.count + 1 >= parent->children.capacity) { + parent->children.capacity *= 2; + SolsNode* tmp = realloc(parent->children.at, sizeof(SolsNode) * parent->children.capacity); + if (tmp == NULL) { + return Error(Nothing, charptr, "Failed to increase memory for children (in addChildToSolsNode() function)"); + } + parent->children.at = tmp; + } + parent->children.at[parent->children.capacity] = child; + parent->children.capacity++; + return Success(Nothing, charptr, {}); +} diff --git a/src/parser/SolsNode.h b/src/parser/SolsNode.h new file mode 100644 index 0000000..3d6eb52 --- /dev/null +++ b/src/parser/SolsNode.h @@ -0,0 +1,56 @@ +#ifndef SOLSNODE_H +#define SOLSNODE_H + +#include + +#include "../include/error.h" + +#include "../lexer/SolsType.h" +#include "../lexer/SolsLiteral.h" + +typedef enum SolsNodeType { + SNT_IDENTIFIER, SNT_LITERAL, SNT_TYPE, SNT_CODE_BLOCK, SNT_OP_ADD, SNT_OP_SUB, SNT_OP_MUL, SNT_OP_DIV, SNT_OP_ADDTO, SNT_OP_SUBTO, SNT_OP_MULTO, SNT_OP_DIVTO, SNT_OP_INCREMENT, SNT_OP_DECREMENT, SNT_OP_SET, SNT_OP_GREATER, SNT_OP_LESSER, SNT_OP_EQUAL, SNT_OP_INEQUAL, SNT_OP_EQGREATER, SNT_OP_EQLESSER, SNT_DEF, SNT_STRUCT, SNT_PUTS, SNT_IF, SNT_WHILE, SNT_NEW, SNT_GROUND, SNT_ROOT +} SolsNodeType; + +struct SolsNode; + +// Represents an AST node. +// Most node types use the .type and .children fields, however some nodes require storing +// more data, inside the .as union. +// Those tokens are: +// SNT_LITERAL: A literal value. Uses field .as.literal +// SNT_TYPE: A type descriptor. Uses field .as.type +// SNT_IDENTIFIER: An identifier. Uses field .as.idName +// SNT_GROUND: Ground code embedded inside Solstice. Uses field .as.inlineGround +typedef struct SolsNode { + SolsNodeType type; + union { + SolsLiteral literal; + SolsType type; + char* idName; + char* inlineGround; + } as; + struct { + size_t count; + size_t capacity; + struct SolsNode* at; + } children; +} SolsNode; + +Result(SolsNode, charptr); + +// Creates a SolsNode. If the type passed in is SNT_LITERAL, SNT_TYPE, SNT_IDENTIFIER or +// SNT_KW_GROUND, the function expects another argument, corresponding to the data type +// the token holds. See the SolsNode struct for more information. +// Returns: +// Success: The created SolsNode +// Failure: char* detailing what went wrong (usually memory failure) +ResultType(SolsNode, charptr) createSolsNode(SolsNodeType type, ...); + +// Adds a child to a SolsNode. +// Returns: +// Success: Nothing +// Failure: char* detailing what went wrong (usually memory failure) +ResultType(Nothing, charptr) addChildToSolsNode(SolsNode* parent, SolsNode child); + +#endif diff --git a/src/parser/parser.h b/src/parser/parser.h new file mode 100644 index 0000000..aee73f5 --- /dev/null +++ b/src/parser/parser.h @@ -0,0 +1,6 @@ +#ifndef PARSER_H +#define PARSER_H + +#include "SolsNode.h" + +#endif