basic VM working
This commit is contained in:
194
parser3.c
194
parser3.c
@@ -1,4 +1,6 @@
|
||||
#include "./lexer.h"
|
||||
#define NB_IMPLEMENTATION
|
||||
#include "./nb.h"
|
||||
|
||||
int get_prec(symbols op){
|
||||
switch (op) {
|
||||
@@ -24,18 +26,194 @@ bool is_left_asc(symbols op){
|
||||
}
|
||||
}
|
||||
|
||||
void build_rpn();
|
||||
Token *global_tok = NULL;
|
||||
|
||||
typedef enum {
|
||||
SYM_VAR,
|
||||
SYM_FUNC,
|
||||
} SymbolKind;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
size_t ret_count;
|
||||
size_t arg_count;
|
||||
symbols arg_types[16];
|
||||
symbols ret_type;
|
||||
SymbolKind symbol_kind;
|
||||
bool builtin;
|
||||
} Symbol;
|
||||
|
||||
|
||||
static Symbol builtins[] = {
|
||||
{ "print", 1, 1, { TOKEN_UNKNOWN }, TOKEN_EOF, SYM_FUNC, true },
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
Symbol *symbols;
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
} SymbolTable;
|
||||
|
||||
int main(void){
|
||||
const char ts[] = "\"hello\" hi + 2";
|
||||
const char math[] = "((1+2)*6)/18"; // = 1
|
||||
Token tk = tokenize_all(math);
|
||||
for (size_t i=0; i<tk.size; ++i){
|
||||
printf("TokenNum: %zu Type: %s Value: %s\n", i, tk.tktype[i], tk.text[i]);
|
||||
|
||||
static int builtin_num = sizeof(builtins)/sizeof(builtins[0]);
|
||||
|
||||
static SymbolTable global_env = {
|
||||
.size = sizeof(builtins)/sizeof(builtins[0]),
|
||||
.capacity = sizeof(builtins)/sizeof(builtins[0]),
|
||||
.symbols = builtins};
|
||||
|
||||
|
||||
Symbol *symbol_lookup(SymbolTable *table, const char *n){
|
||||
for (size_t i=0; i<table->size; ++i){
|
||||
if(strcmp(n, table->symbols[i].name) == 0){
|
||||
return &table->symbols[i];
|
||||
}
|
||||
}
|
||||
// printf("token count: %zu\n", tk.size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// fn add(x: int, y: int) int {
|
||||
// return x+y;
|
||||
// }
|
||||
|
||||
|
||||
void symbol_table_init(SymbolTable *table, size_t initial_capacity) {
|
||||
table->symbols = malloc(sizeof(Symbol) * initial_capacity);
|
||||
if (!table->symbols) {
|
||||
fprintf(stderr, "symbol_table_init: malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
table->size = 0;
|
||||
table->capacity = initial_capacity;
|
||||
}
|
||||
|
||||
void symbol_table_add(SymbolTable *table, Symbol sym) {
|
||||
if (table->size >= table->capacity) {
|
||||
table->capacity = (table->capacity == 0) ? 8 : table->capacity * 2;
|
||||
table->symbols = realloc(table->symbols, sizeof(Symbol) * table->capacity);
|
||||
if (!table->symbols) {
|
||||
fprintf(stderr, "symbol_table_add: realloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
table->symbols[table->size++] = sym;
|
||||
}
|
||||
|
||||
|
||||
void symbol_table_free(SymbolTable *table) {
|
||||
free(table->symbols);
|
||||
table->symbols = NULL;
|
||||
table->size = 0;
|
||||
table->capacity = 0;
|
||||
}
|
||||
|
||||
|
||||
Token build_rpn(Token *inp, SymbolTable *symtab) {
|
||||
Token output;
|
||||
Token stack;
|
||||
|
||||
token_init(&output, 16);
|
||||
token_init(&stack, 16);
|
||||
|
||||
for (size_t i = 0; i < inp->size; ++i) {
|
||||
symbols type = inp->type[i];
|
||||
const char *text = inp->text[i];
|
||||
|
||||
if (type == TOKEN_IDENTIFIER && i + 1 < inp->size && inp->type[i + 1] == TOKEN_LPAREN) {
|
||||
Symbol *found = symbol_lookup(symtab, text);
|
||||
if (!found) {
|
||||
Symbol sym = {
|
||||
.name = strdup(text),
|
||||
.arg_count = 0,
|
||||
.ret_type = TOKEN_EOF,
|
||||
.symbol_kind = SYM_FUNC,
|
||||
.builtin = false
|
||||
};
|
||||
symbol_table_add(symtab, sym);
|
||||
}
|
||||
token_push(&stack, type, text, inp->behaviour[i], 0);
|
||||
} else if (type == TOKEN_IDENTIFIER) {
|
||||
Symbol *found = symbol_lookup(symtab, text);
|
||||
if (!found) {
|
||||
Symbol sym = {
|
||||
.name = strdup(text),
|
||||
.arg_count = 0,
|
||||
.ret_type = TOKEN_UNKNOWN,
|
||||
.symbol_kind = SYM_VAR,
|
||||
.builtin = false
|
||||
};
|
||||
symbol_table_add(symtab, sym);
|
||||
}
|
||||
token_push(&output, type, text, inp->behaviour[i], 0);
|
||||
} else if (type == TOKEN_LPAREN) {
|
||||
token_push(&stack, type, text, inp->behaviour[i], 0);
|
||||
} else if (type == TOKEN_RPAREN) {
|
||||
while (stack.size > 0 && stack.type[stack.size - 1] != TOKEN_LPAREN) {
|
||||
token_push(&output, stack.type[stack.size - 1],
|
||||
stack.text[stack.size - 1],
|
||||
stack.behaviour[stack.size - 1], 0);
|
||||
stack.size--;
|
||||
}
|
||||
if (stack.size > 0 && stack.type[stack.size - 1] == TOKEN_LPAREN)
|
||||
stack.size--;
|
||||
if (stack.size > 0 && stack.type[stack.size - 1] == TOKEN_IDENTIFIER) {
|
||||
token_push(&output, stack.type[stack.size - 1],
|
||||
stack.text[stack.size - 1],
|
||||
stack.behaviour[stack.size - 1], 0);
|
||||
stack.size--;
|
||||
}
|
||||
} else if (type == TOKEN_INTEGER || type == TOKEN_FLOAT || type == TOKEN_STRING) {
|
||||
token_push(&output, type, text, inp->behaviour[i], 0);
|
||||
} else if (is_left_asc(type)) {
|
||||
while (stack.size > 0 && stack.type[stack.size - 1] != TOKEN_LPAREN &&
|
||||
(get_prec(stack.type[stack.size - 1]) > get_prec(type) ||
|
||||
get_prec(stack.type[stack.size - 1]) == get_prec(type)) &&
|
||||
is_left_asc(type)) {
|
||||
token_push(&output, stack.type[stack.size - 1],
|
||||
stack.text[stack.size - 1],
|
||||
stack.behaviour[stack.size - 1], 0);
|
||||
stack.size--;
|
||||
}
|
||||
token_push(&stack, type, text, inp->behaviour[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
while (stack.size > 0) {
|
||||
token_push(&output, stack.type[stack.size - 1],
|
||||
stack.text[stack.size - 1],
|
||||
stack.behaviour[stack.size - 1], 0);
|
||||
stack.size--;
|
||||
}
|
||||
|
||||
token_push(&output, TOKEN_EOF, "EOF", BHV_UNDEFINED, 0);
|
||||
return output;
|
||||
}
|
||||
|
||||
void print_token(Token *tk){
|
||||
for (size_t i=0; i<tk->size; ++i){
|
||||
printf("TokenNum: %zu Type: %s Value: %s\n", i, tk->tktype[i], tk->text[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv){
|
||||
if (argc < 2) return -1;
|
||||
const char ts[] = "\"hello\" hi + 2 2.312";
|
||||
const char math[] = "print(((1+2)*6)/18)"; // = 1
|
||||
const char print[] = "print(\"hello\")";
|
||||
const char simple[] = "1 + ( 3 + 3 )/4+4*3";
|
||||
|
||||
|
||||
char* read = nb_read_file(argv[1]);
|
||||
Token tk = tokenize_all(read);
|
||||
printf("INPUT: %s\n", read);
|
||||
SymbolTable table = {0};
|
||||
symbol_table_init(&table, 32);
|
||||
|
||||
|
||||
Token rpn = build_rpn(&tk, &table);
|
||||
print_token(&rpn);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user