Files
hlang/parser3.c

220 lines
6.1 KiB
C
Raw Normal View History

2025-11-05 14:28:45 +03:00
#include "./lexer.h"
2025-11-05 23:14:59 +03:00
#define NB_IMPLEMENTATION
#include "./nb.h"
2025-11-05 14:28:45 +03:00
2025-11-05 16:03:14 +03:00
int get_prec(symbols op){
switch (op) {
case TOKEN_MUL:
case TOKEN_DIV:
return 2; break;
case TOKEN_PLUS:
case TOKEN_MINUS:
return 1; break;
default: return 0;
}
}
// parse
bool is_left_asc(symbols op){
switch (op) {
case TOKEN_MUL:
case TOKEN_DIV:
case TOKEN_PLUS:
case TOKEN_MINUS:
return true; break;
default: return false;
}
}
2025-11-05 23:14:59 +03:00
Token *global_tok = NULL;
2025-11-05 16:03:14 +03:00
2025-11-05 23:14:59 +03:00
typedef enum {
SYM_VAR,
SYM_FUNC,
} SymbolKind;
2025-11-05 16:03:14 +03:00
2025-11-05 23:14:59 +03:00
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;
2025-11-05 16:03:14 +03:00
2025-11-05 23:14:59 +03:00
static Symbol builtins[] = {
{ "print", 1, 1, { TOKEN_UNKNOWN }, TOKEN_EOF, SYM_FUNC, true },
};
2025-11-05 14:28:45 +03:00
2025-11-05 23:14:59 +03:00
typedef struct {
Symbol *symbols;
size_t size;
size_t capacity;
} SymbolTable;
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];
}
}
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]);
2025-11-05 14:28:45 +03:00
}
2025-11-05 23:14:59 +03:00
}
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);
2025-11-05 14:28:45 +03:00
}