better structure etc
This commit is contained in:
@@ -8,7 +8,7 @@ int main(int argc, char **argv){
|
|||||||
|
|
||||||
nb_append(&cmd, "gcc");
|
nb_append(&cmd, "gcc");
|
||||||
nb_append(&cmd, "-Wall -Wextra");
|
nb_append(&cmd, "-Wall -Wextra");
|
||||||
nb_append(&cmd, "vm.c");
|
nb_append(&cmd, "./src/vm.c");
|
||||||
nb_append(&cmd, "-o vm");
|
nb_append(&cmd, "-o vm");
|
||||||
nb_cmd(&cmd);
|
nb_cmd(&cmd);
|
||||||
|
|
||||||
|
|||||||
4
examples/main.hl
Normal file
4
examples/main.hl
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
print(((1+2923)*3)/5)
|
||||||
|
|
||||||
|
print("hello world")
|
||||||
119
parser.c
119
parser.c
@@ -1,119 +0,0 @@
|
|||||||
#include <assert.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#define NB_IMPLEMENTATION
|
|
||||||
#include "lexer.h"
|
|
||||||
#include "nb.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Token *left;
|
|
||||||
Token *right;
|
|
||||||
size_t prec;
|
|
||||||
symbols op;
|
|
||||||
} ASTNode;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ASTNode *nodes;
|
|
||||||
size_t size;
|
|
||||||
} ASTTree;
|
|
||||||
|
|
||||||
Token *copy_single_token(const Token *src, size_t i) {
|
|
||||||
Token *t = calloc(1, sizeof(Token));
|
|
||||||
assert(t);
|
|
||||||
|
|
||||||
t->size = 1;
|
|
||||||
t->type = malloc(sizeof(int));
|
|
||||||
t->text = malloc(sizeof(char*));
|
|
||||||
assert(t->type && t->text);
|
|
||||||
|
|
||||||
t->type[0] = src->type[i];
|
|
||||||
t->text[0] = strdup(src->text[i]);
|
|
||||||
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t find_prev_token(const Token *tok, size_t start) {
|
|
||||||
for (ssize_t i = (ssize_t)start; i >= 0; --i) {
|
|
||||||
if (tok->type[i] != TOKEN_SPACE &&
|
|
||||||
tok->type[i] != TOKEN_NEWLINE &&
|
|
||||||
tok->type[i] != TOKEN_EOF) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t find_next_token(const Token *tok, size_t start) {
|
|
||||||
for (size_t i = start; i < tok->size; ++i) {
|
|
||||||
if (tok->type[i] != TOKEN_SPACE &&
|
|
||||||
tok->type[i] != TOKEN_NEWLINE &&
|
|
||||||
tok->type[i] != TOKEN_EOF) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t token_precedence(Token token, size_t idx){
|
|
||||||
switch (token.type[idx]) {
|
|
||||||
case TOKEN_PLUS:
|
|
||||||
return 1;
|
|
||||||
break;
|
|
||||||
case TOKEN_MINUS:
|
|
||||||
return 1;
|
|
||||||
break;
|
|
||||||
case TOKEN_MUL:
|
|
||||||
return 2;
|
|
||||||
break;
|
|
||||||
case TOKEN_DIV:
|
|
||||||
return 3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTTree ast_walk(Token token) {
|
|
||||||
ASTTree ops = {0};
|
|
||||||
|
|
||||||
ops.nodes = calloc(token.size, sizeof(ASTNode));
|
|
||||||
assert(ops.nodes);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < token.size; ++i) {
|
|
||||||
switch (token_precedence(token, i) > 0) {
|
|
||||||
case true: {
|
|
||||||
ssize_t l = find_prev_token(&token, i - 1);
|
|
||||||
ssize_t r = find_next_token(&token, i + 1);
|
|
||||||
assert(l >= 0 && r >= 0);
|
|
||||||
|
|
||||||
ASTNode op = {0};
|
|
||||||
op.left = copy_single_token(&token, l);
|
|
||||||
op.right = copy_single_token(&token, r);
|
|
||||||
op.prec = token_precedence(token, i);
|
|
||||||
op.op = token.type[i];
|
|
||||||
ops.nodes[ops.size++] = op;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ops;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv){
|
|
||||||
Token to_tokenize = {0};
|
|
||||||
if (argc > 1) {
|
|
||||||
to_tokenize = tokenize_all(nb_read_file(argv[1]));
|
|
||||||
}
|
|
||||||
for (size_t i=0; i<to_tokenize.size; ++i){
|
|
||||||
printf("Type: %s\nText: %s\n\n", token_type_to_string(to_tokenize.type[i]), to_tokenize.text[i]);
|
|
||||||
}
|
|
||||||
ASTTree walked = ast_walk(to_tokenize);
|
|
||||||
for (int i=0; i<walked.size;++i){
|
|
||||||
printf("op: %s, left: %s, right: %s, prec %zu\n\n", token_type_to_string(walked.nodes[i].op), walked.nodes[i].left->text[0], walked.nodes[i].right->text[0], walked.nodes[i].prec);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
150
simpleparser.c
150
simpleparser.c
@@ -1,150 +0,0 @@
|
|||||||
#include "lexer.h"
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char* left;
|
|
||||||
char* right;
|
|
||||||
symbols node;
|
|
||||||
size_t cursor;
|
|
||||||
size_t prec;
|
|
||||||
} ASTNode;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ASTNode* nodes;
|
|
||||||
size_t size;
|
|
||||||
size_t capacity;
|
|
||||||
} ASTTree;
|
|
||||||
|
|
||||||
void tree_init(ASTTree* a){
|
|
||||||
if (a->capacity == 0) a->capacity = 128;
|
|
||||||
a->nodes = malloc(sizeof(*a->nodes)*a->capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
void construct_nodes(ASTTree* a, Token t){
|
|
||||||
if (a->capacity == 0) tree_init(a);
|
|
||||||
if (a->size >= a->capacity) {
|
|
||||||
a->capacity *=2;
|
|
||||||
a->nodes = realloc(a->nodes, sizeof(*a->nodes)*a->capacity);
|
|
||||||
}
|
|
||||||
size_t nc = 0;
|
|
||||||
for (size_t i=0; i<t.size; ++i){
|
|
||||||
switch (t.type[i]){
|
|
||||||
case TOKEN_PLUS:
|
|
||||||
assert(i > 0 && i < t.size - 1);
|
|
||||||
a->nodes[nc].node = TOKEN_PLUS;
|
|
||||||
a->nodes[nc].left = t.text[i-1];
|
|
||||||
a->nodes[nc].right = t.text[i+1];
|
|
||||||
a->nodes[nc].prec = 1;
|
|
||||||
a->nodes[nc].cursor = nc;
|
|
||||||
nc++;
|
|
||||||
break;
|
|
||||||
case TOKEN_MINUS:
|
|
||||||
assert(i > 0 && i < t.size - 1);
|
|
||||||
a->nodes[nc].node = TOKEN_MINUS;
|
|
||||||
a->nodes[nc].left = t.text[i-1];
|
|
||||||
a->nodes[nc].right = t.text[i+1];
|
|
||||||
a->nodes[nc].prec = 1;
|
|
||||||
a->nodes[nc].cursor = nc;
|
|
||||||
nc++;
|
|
||||||
break;
|
|
||||||
case TOKEN_DIV:
|
|
||||||
assert(i > 0 && i < t.size - 1);
|
|
||||||
a->nodes[nc].node = TOKEN_DIV;
|
|
||||||
a->nodes[nc].left = t.text[i-1];
|
|
||||||
a->nodes[nc].right = t.text[i+1];
|
|
||||||
a->nodes[nc].prec = 2;
|
|
||||||
a->nodes[nc].cursor = nc;
|
|
||||||
nc++;
|
|
||||||
break;
|
|
||||||
case TOKEN_MUL:
|
|
||||||
assert(i > 0 && i < t.size - 1);
|
|
||||||
a->nodes[nc].node = TOKEN_MUL;
|
|
||||||
a->nodes[nc].left = t.text[i-1];
|
|
||||||
a->nodes[nc].right = t.text[i+1];
|
|
||||||
a->nodes[nc].prec = 2;
|
|
||||||
a->nodes[nc].cursor = nc;
|
|
||||||
nc++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a->size = nc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// void eval(ASTTree *tree){
|
|
||||||
// for (size_t i=0; i<tree->size; ++i){
|
|
||||||
// ASTNode curr = tree->nodes[i];
|
|
||||||
// size_t n = tree->size;
|
|
||||||
// float total = 0.0f;
|
|
||||||
// switch (curr.node){
|
|
||||||
// case TOKEN_PLUS:
|
|
||||||
// if (tree->size > 1){
|
|
||||||
// for (size_t i=0; i<tree->size; ++i){
|
|
||||||
// total += atof(tree->nodes[i].left) + atof(tree->nodes[i].right);
|
|
||||||
// }
|
|
||||||
// // for (size_t i=0; i<n; i++ && n--){
|
|
||||||
// // total -=
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
// for (size_t i=0; i<tree->size && (tree->size%i != 0); ++i){
|
|
||||||
// // total -= atof(tree->nodes[i].right);
|
|
||||||
// printf("%zu\n", i);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// printf("%f\n", total);
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
void eval(ASTTree* tree) {
|
|
||||||
if (!tree || !tree->nodes || tree->size == 0) {
|
|
||||||
fprintf(stderr, "Invalid or empty ASTTree\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float total = 0.0f;
|
|
||||||
int initialized = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < tree->size; ++i) {
|
|
||||||
ASTNode* curr = &tree->nodes[i];
|
|
||||||
|
|
||||||
switch (curr->node) {
|
|
||||||
case TOKEN_PLUS:
|
|
||||||
if (!initialized && curr->left) {
|
|
||||||
total = atof(curr->left);
|
|
||||||
initialized = 1;
|
|
||||||
}
|
|
||||||
if (curr->right)
|
|
||||||
total += atof(curr->right);
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Unknown token at node %zu\n", i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Result: %.2f\n", total);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv){
|
|
||||||
// Token tokens = tokenize_all("1+2 3-4 1/2 2*7"); //invalid syntax
|
|
||||||
Token tokens = tokenize_all("1+2+3+4"); //invalid syntax
|
|
||||||
ASTTree tree = {0};
|
|
||||||
construct_nodes(&tree, tokens);
|
|
||||||
eval(&tree);
|
|
||||||
// for (size_t i=0; i<tree.size; ++i){
|
|
||||||
// ASTNode curr = tree.nodes[i];
|
|
||||||
// printf("token: %s\n", token_type_to_string(curr.node));
|
|
||||||
// printf("left: %s right: %s\n", curr.left, curr.right);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ char *token_type_to_string(symbols type) {
|
|||||||
case TOKEN_SEMI: return "TOKEN_SEMI";
|
case TOKEN_SEMI: return "TOKEN_SEMI";
|
||||||
case TOKEN_COLON: return "TOKEN_COLON";
|
case TOKEN_COLON: return "TOKEN_COLON";
|
||||||
case TOKEN_UNKNOWN: return "TOKEN_UNKNOWN";
|
case TOKEN_UNKNOWN: return "TOKEN_UNKNOWN";
|
||||||
// default: return "UNKNOWN_SYMBOL";
|
default: return "UNKNOWN_SYMBOL";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,9 +44,9 @@ typedef struct {
|
|||||||
} Symbol;
|
} Symbol;
|
||||||
|
|
||||||
|
|
||||||
static Symbol builtins[] = {
|
// static Symbol builtins[] = {
|
||||||
{ "print", 1, 1, { TOKEN_UNKNOWN }, TOKEN_EOF, SYM_FUNC, true },
|
// { "print", 1, 1, { TOKEN_UNKNOWN }, TOKEN_EOF, SYM_FUNC, true },
|
||||||
};
|
// };
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -56,12 +56,12 @@ typedef struct {
|
|||||||
} SymbolTable;
|
} SymbolTable;
|
||||||
|
|
||||||
|
|
||||||
static int builtin_num = sizeof(builtins)/sizeof(builtins[0]);
|
// static int builtin_num = sizeof(builtins)/sizeof(builtins[0]);
|
||||||
|
|
||||||
static SymbolTable global_env = {
|
// static SymbolTable global_env = {
|
||||||
.size = sizeof(builtins)/sizeof(builtins[0]),
|
// .size = sizeof(builtins)/sizeof(builtins[0]),
|
||||||
.capacity = sizeof(builtins)/sizeof(builtins[0]),
|
// .capacity = sizeof(builtins)/sizeof(builtins[0]),
|
||||||
.symbols = builtins};
|
// .symbols = builtins};
|
||||||
|
|
||||||
|
|
||||||
Symbol *symbol_lookup(SymbolTable *table, const char *n){
|
Symbol *symbol_lookup(SymbolTable *table, const char *n){
|
||||||
Reference in New Issue
Block a user