parser start, no clue if i'm doing it right
This commit is contained in:
@@ -21,8 +21,9 @@ runCommand('rm -r build')
|
|||||||
runCommand('mkdir build')
|
runCommand('mkdir build')
|
||||||
|
|
||||||
local files = {
|
local files = {
|
||||||
'src/lexer.c',
|
|
||||||
'src/helper.c',
|
'src/helper.c',
|
||||||
|
'src/lexer.c',
|
||||||
|
'src/parser.c',
|
||||||
'src/main.c',
|
'src/main.c',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
src/helper.c
14
src/helper.c
@@ -20,3 +20,17 @@ int noom_streql(const char* stra, noom_uint_t lena, const char* strb, noom_uint_
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <stdlib.h> // 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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,3 +2,7 @@
|
|||||||
|
|
||||||
int noom_startswith(const char* str, char* compare);
|
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?
|
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);
|
||||||
|
|||||||
93
src/parser.c
Normal file
93
src/parser.c
Normal file
@@ -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;
|
||||||
|
}
|
||||||
35
src/parser.h
Normal file
35
src/parser.h
Normal file
@@ -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);
|
||||||
|
|
||||||
Reference in New Issue
Block a user