forked from NeoFlock/noom
parsing things
This commit is contained in:
44
src/main.c
44
src/main.c
@@ -1,11 +1,42 @@
|
|||||||
#include <stdio.h> // for now
|
#include <stdio.h> // for now
|
||||||
#include "lexer.h"
|
// #include "lexer.h"
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
void tab(noom_uint_t amount) {
|
||||||
|
amount *= 2;
|
||||||
|
for (noom_uint_t i = 0; i < amount; i++) {
|
||||||
|
putchar(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_node(noomP_Node* node, noom_uint_t depth) {
|
||||||
|
tab(depth);
|
||||||
|
printf("{\n");
|
||||||
|
|
||||||
|
tab(depth+1);
|
||||||
|
printf("type: %d\n", node->type);
|
||||||
|
|
||||||
|
tab(depth+1);
|
||||||
|
printf("location: %lld\n", node->source_offset);
|
||||||
|
|
||||||
|
tab(depth+1);
|
||||||
|
printf("subnodes:\n");
|
||||||
|
|
||||||
|
for (noom_uint_t i = 0; i < node->subnodec; i++) {
|
||||||
|
print_node(node->subnodes[i], depth + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
tab(depth);
|
||||||
|
printf("}\n");
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
// uhh uhhh uhhhhh
|
// uhh uhhh uhhhhh
|
||||||
const char* code = "local a = 5;";
|
const char* code = "local a = 5";
|
||||||
noom_uint_t pos = 0;
|
noom_uint_t pos = 0;
|
||||||
|
|
||||||
|
printf("LEX OUTPUT:\n");
|
||||||
|
|
||||||
noomL_Token token;
|
noomL_Token token;
|
||||||
while (1) {
|
while (1) {
|
||||||
noomL_lex(code, pos, &token);
|
noomL_lex(code, pos, &token);
|
||||||
@@ -19,6 +50,15 @@ int main(int argc, char** argv) {
|
|||||||
if (token.type == NOOML_TOKEN_EOF) break;
|
if (token.type == NOOML_TOKEN_EOF) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// time for parser testing
|
||||||
|
printf("\nPARSE OUTPUT:\n");
|
||||||
|
|
||||||
|
noomP_Node *program;
|
||||||
|
|
||||||
|
int success = noomP_parse(code, "shitass", &program);
|
||||||
|
if (success != 0) return success;
|
||||||
|
|
||||||
|
print_node(program, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
95
src/parser.c
95
src/parser.c
@@ -4,7 +4,7 @@
|
|||||||
int noomP_peek(noomP_Parser* parser, noomL_Token* token) {
|
int noomP_peek(noomP_Parser* parser, noomL_Token* token) {
|
||||||
while (1) {
|
while (1) {
|
||||||
int success = noomL_lex(parser->code, parser->lex_offset, token);
|
int success = noomL_lex(parser->code, parser->lex_offset, token);
|
||||||
if (!success) return -1; // TODO: proper error propogation and stuff
|
if (success != 0) return -1; // TODO: proper error propogation and stuff
|
||||||
|
|
||||||
if (token->type == NOOML_TOKEN_WHITESPACE) {
|
if (token->type == NOOML_TOKEN_WHITESPACE) {
|
||||||
// peek changes state, but only if it's one of these useless tokens anyway.
|
// peek changes state, but only if it's one of these useless tokens anyway.
|
||||||
@@ -54,7 +54,95 @@ int noomP_addSubnode(noomP_Node* node, noomP_Node* subnode) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
noomP_Node* noomP_parseExpression(noomP_Parser* parser) {
|
||||||
|
noomL_Token token;
|
||||||
|
noomP_peek(parser, &token);
|
||||||
|
|
||||||
|
if (token.type == NOOML_TOKEN_NUMBER) {
|
||||||
|
// uhh figure it out, future me!
|
||||||
|
noomP_skip(parser, &token);
|
||||||
|
|
||||||
|
noomP_Node* numNode = noomP_allocNode(parser);
|
||||||
|
if (numNode == 0) return 0;
|
||||||
|
|
||||||
|
numNode->type = NOOMP_NODE_NUMBERLITERAL;
|
||||||
|
numNode->source_offset = token.offset;
|
||||||
|
|
||||||
|
return numNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
noomP_Node* noomP_parseStatement(noomP_Parser* parser) {
|
noomP_Node* noomP_parseStatement(noomP_Parser* parser) {
|
||||||
|
noomL_Token token;
|
||||||
|
noomP_peek(parser, &token);
|
||||||
|
|
||||||
|
if (token.type == NOOML_TOKEN_KEYWORD) {
|
||||||
|
if (noom_streql(parser->code + token.offset, token.length, "local", 5)) {
|
||||||
|
noomP_skip(parser, &token);
|
||||||
|
|
||||||
|
noomP_Node* localNode = noomP_allocNode(parser);
|
||||||
|
if (localNode == 0) return 0; // no memory :(
|
||||||
|
|
||||||
|
localNode->source_offset = token.offset;
|
||||||
|
localNode->type = NOOMP_NODE_LOCALDECLARATION;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
noomP_peek(parser, &token);
|
||||||
|
|
||||||
|
if (token.type != NOOML_TOKEN_IDENTIFIER) return 0;
|
||||||
|
noomP_skip(parser, &token);
|
||||||
|
|
||||||
|
noomP_Node* varname = noomP_allocNode(parser);
|
||||||
|
if (varname == 0) return 0;
|
||||||
|
|
||||||
|
varname->type = NOOMP_NODE_VARNAME;
|
||||||
|
varname->source_offset = token.offset;
|
||||||
|
|
||||||
|
noomP_addSubnode(localNode, varname);
|
||||||
|
|
||||||
|
noomP_peek(parser, &token);
|
||||||
|
|
||||||
|
if (token.type == NOOML_TOKEN_SYMBOL) {
|
||||||
|
if (noom_streql(parser->code + token.offset, token.length, "=", 1)) {
|
||||||
|
noomP_skip(parser, &token);
|
||||||
|
break;
|
||||||
|
} else if (noom_streql(parser->code + token.offset, token.length, ",", 1)) {
|
||||||
|
noomP_skip(parser, &token);
|
||||||
|
} else {
|
||||||
|
return 0; // unexpected token
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0; // unexpected token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// equals has already been eaten by loop (thank you loop)
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
noomP_Node *expr = noomP_parseExpression(parser);
|
||||||
|
if (expr == 0) return 0;
|
||||||
|
|
||||||
|
noomP_addSubnode(localNode, expr);
|
||||||
|
|
||||||
|
noomP_peek(parser, &token);
|
||||||
|
|
||||||
|
if (token.type == NOOML_TOKEN_SYMBOL) {
|
||||||
|
if (noom_streql(parser->code + token.offset, token.length, ",", 1)) {
|
||||||
|
noomP_skip(parser, &token);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return localNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +152,9 @@ int noomP_parse(const char* code, const char* filename, noomP_Node** outpointer)
|
|||||||
|
|
||||||
noomL_Token token;
|
noomL_Token token;
|
||||||
noomP_Node* node = noomP_allocNode(&parser);
|
noomP_Node* node = noomP_allocNode(&parser);
|
||||||
|
if (node == 0) return -1;
|
||||||
|
|
||||||
|
node->source_offset = parser.lex_offset;
|
||||||
node->type = NOOMP_NODE_PROGRAM;
|
node->type = NOOMP_NODE_PROGRAM;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -77,8 +167,7 @@ int noomP_parse(const char* code, const char* filename, noomP_Node** outpointer)
|
|||||||
noomP_addSubnode(node, child);
|
noomP_addSubnode(node, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
node->type = NOOMP_NODE_PROGRAM;
|
*outpointer = node;
|
||||||
node->subnodec = 0;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,15 @@
|
|||||||
|
|
||||||
typedef enum noomP_NodeType {
|
typedef enum noomP_NodeType {
|
||||||
NOOMP_NODE_PROGRAM,
|
NOOMP_NODE_PROGRAM,
|
||||||
|
NOOMP_NODE_VARNAME,
|
||||||
|
NOOMP_NODE_NUMBERLITERAL,
|
||||||
|
NOOMP_NODE_LOCALDECLARATION,
|
||||||
} noomP_NodeType;
|
} noomP_NodeType;
|
||||||
|
|
||||||
typedef struct noomP_Node {
|
typedef struct noomP_Node {
|
||||||
noomP_NodeType type;
|
noomP_NodeType type;
|
||||||
|
|
||||||
|
noom_uint_t source_offset;
|
||||||
|
|
||||||
noom_uint_t subnodec;
|
noom_uint_t subnodec;
|
||||||
noom_uint_t subnode_cap;
|
noom_uint_t subnode_cap;
|
||||||
struct noomP_Node** subnodes;
|
struct noomP_Node** subnodes;
|
||||||
@@ -29,6 +33,8 @@ void noomP_skip(noomP_Parser* parser, noomL_Token* token);
|
|||||||
noomP_Node* noomP_allocNode(noomP_Parser* parser);
|
noomP_Node* noomP_allocNode(noomP_Parser* parser);
|
||||||
|
|
||||||
noomP_Node* noomP_parseStatement(noomP_Parser* parser);
|
noomP_Node* noomP_parseStatement(noomP_Parser* parser);
|
||||||
|
noomP_Node* noomP_parseExpression(noomP_Parser* parser);
|
||||||
|
|
||||||
int noomP_parse(const char* code, const char* filename, noomP_Node** outpointer);
|
int noomP_parse(const char* code, const char* filename, noomP_Node** outpointer);
|
||||||
|
|
||||||
int noomP_initParser(noomP_Parser* parser, const char* code, const char* filename);
|
int noomP_initParser(noomP_Parser* parser, const char* code, const char* filename);
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
typedef unsigned long long int noom_uint_t;
|
typedef unsigned long long int noom_uint_t;
|
||||||
|
typedef signed long long int noom_int_t;
|
||||||
|
|||||||
Reference in New Issue
Block a user