diff --git a/build.lua b/build.lua index 14a7db0..2d00166 100644 --- a/build.lua +++ b/build.lua @@ -21,8 +21,9 @@ runCommand('rm -r build') runCommand('mkdir build') local files = { - 'src/lexer.c', 'src/helper.c', + 'src/lexer.c', + 'src/parser.c', 'src/main.c', } diff --git a/src/helper.c b/src/helper.c index 02a34f2..d6415a1 100644 --- a/src/helper.c +++ b/src/helper.c @@ -20,3 +20,17 @@ int noom_streql(const char* stra, noom_uint_t lena, const char* strb, noom_uint_ return 1; } + +#include // TODO: remove + +void* noom_alloc(noom_uint_t size) { + return malloc(size); +} + +void noom_free(void* ptr) { + free(ptr); +} + +void* noom_realloc(void* ptr, noom_uint_t size) { + return realloc(ptr, size); +} diff --git a/src/helper.h b/src/helper.h index 1ce78b3..9702158 100644 --- a/src/helper.h +++ b/src/helper.h @@ -2,3 +2,7 @@ int noom_startswith(const char* str, char* compare); int noom_streql(const char* stra, noom_uint_t lena, const char* strb, noom_uint_t lenb); // rename to something better? + +void* noom_alloc(noom_uint_t size); +void noom_free(void* ptr); +void* noom_realloc(void* ptr, noom_uint_t size); diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..6acb6e8 --- /dev/null +++ b/src/parser.c @@ -0,0 +1,93 @@ +#include "parser.h" +#include "helper.h" + +int noomP_peek(noomP_Parser* parser, noomL_Token* token) { + while (1) { + int success = noomL_lex(parser->code, parser->lex_offset, token); + if (!success) return -1; // TODO: proper error propogation and stuff + + if (token->type == NOOML_TOKEN_WHITESPACE) { + // peek changes state, but only if it's one of these useless tokens anyway. + parser->lex_offset += token->length; + continue; + } + + return 0; + } +} + +void noomP_skip(noomP_Parser* parser, noomL_Token* token) { // expects you to alr know the token + if (token->type == NOOML_TOKEN_EOF) return; + + parser->lex_offset += token->length; +} + +noomP_Node* noomP_allocNode(noomP_Parser* parser) { + noomP_Node* node = noom_alloc(sizeof(noomP_Node)); + if (node == 0) return 0; + + node->previous_node = parser->last_node; + + node->subnodec = 0; + node->subnodes = noom_alloc(sizeof(noomP_Node*) * 2); + node->subnode_cap = 2; + if (node->subnodes == 0) { + noom_free(node); + return 0; + } + + parser->last_node = node; + + return node; +} + +int noomP_addSubnode(noomP_Node* node, noomP_Node* subnode) { + if (node->subnodec == node->subnode_cap) { + node->subnode_cap = node->subnode_cap * 2; + node->subnodes = noom_realloc(node->subnodes, sizeof(noomP_Node*) * node->subnode_cap); + + if (node->subnodes == 0) return -1; + } + + node->subnodes[node->subnodec++] = subnode; + + return 0; +} + +noomP_Node* noomP_parseStatement(noomP_Parser* parser) { + return 0; +} + +int noomP_parse(const char* code, const char* filename, noomP_Node** outpointer) { + noomP_Parser parser; + noomP_initParser(&parser, code, filename); + + noomL_Token token; + noomP_Node* node = noomP_allocNode(&parser); + + node->type = NOOMP_NODE_PROGRAM; + + while (1) { + noomP_peek(&parser, &token); + if (token.type == NOOML_TOKEN_EOF) return 0; + + noomP_Node* child = noomP_parseStatement(&parser); + if (child == 0) return -1; + + noomP_addSubnode(node, child); + } + + node->type = NOOMP_NODE_PROGRAM; + node->subnodec = 0; + + return 0; +} + +int noomP_initParser(noomP_Parser* parser, const char* code, const char* filename) { + parser->code = code; + parser->filename = filename; + parser->lex_offset = 0; + parser->last_node = (void *)0; + + return 0; +} diff --git a/src/parser.h b/src/parser.h new file mode 100644 index 0000000..8bb75ed --- /dev/null +++ b/src/parser.h @@ -0,0 +1,35 @@ +#include "types.h" +#include "lexer.h" + +typedef enum noomP_NodeType { + NOOMP_NODE_PROGRAM, +} noomP_NodeType; + +typedef struct noomP_Node { + noomP_NodeType type; + + noom_uint_t subnodec; + noom_uint_t subnode_cap; + struct noomP_Node** subnodes; + + struct noomP_Node* previous_node; +} noomP_Node; + +typedef struct noomP_Parser { // todo: track location in code with line/column? + const char* code; + const char* filename; + noom_uint_t lex_offset; + + noomP_Node* last_node; +} noomP_Parser; + +int noomP_peek(noomP_Parser* parser, noomL_Token* token); +void noomP_skip(noomP_Parser* parser, noomL_Token* token); + +noomP_Node* noomP_allocNode(noomP_Parser* parser); + +noomP_Node* noomP_parseStatement(noomP_Parser* parser); +int noomP_parse(const char* code, const char* filename, noomP_Node** outpointer); + +int noomP_initParser(noomP_Parser* parser, const char* code, const char* filename); +