WIP parser

This commit is contained in:
zongor 2026-03-31 23:16:29 -07:00
parent 373caf7b5e
commit 8fd281e463
6 changed files with 278 additions and 196 deletions

24
libc.c
View File

@ -84,7 +84,7 @@ aaloc(Arena *arena, u32 size)
pos = arena->count; pos = arena->count;
arena->count += size; arena->count += size;
return &arena->tape[pos]; return (void *)&arena->tape[pos];
} }
u32 u32
@ -94,3 +94,25 @@ afree(Arena *arena)
arena->count = 0; arena->count = 0;
return freed; return freed;
} }
char *
ascpy(Arena *arena, const char *start, u32 length)
{
char *str;
if(!start) return nil;
str = (char *)aalloc(arena, length + 1);
if(!str) return nil;
scpy(str, start, length);
return str;
}
void *
amcpy(Arena *arena, void *from, u32 length)
{
void *ptr;
if(!from) return nil;
ptr = aalloc(arena, length);
if(!ptr) return nil;
mcpy(ptr, from, length);
return ptr;
}

2
libc.h
View File

@ -84,5 +84,7 @@ u32 slen(const char *str);
u32 snlen(const char *str, u32 max_len); u32 snlen(const char *str, u32 max_len);
void *aalloc(Arena *arena, u32 size); void *aalloc(Arena *arena, u32 size);
u32 afree(Arena *arena); u32 afree(Arena *arena);
char *ascpy(Arena *arena, const char *start, u32 length);
void *amcpy(Arena *arena, void *from, u32 length);
#endif #endif

98
list.c Normal file
View File

@ -0,0 +1,98 @@
#include "list.h"
List *
new_list(Arena *arena)
{
List *l = aalloc(arena, sizeof(List));
if (!l) return nil;
l->head = nil;
l->tail = nil;
l->count = 0;
return l;
}
void *
node_value(Node *n)
{
return (void *)((u8 *)n + sizeof(Node));
}
void *
list_push(Arena *arena, List *list, void *data, u32 data_size)
{
void *ptr = aalloc(arena, sizeof(Node) + data_size);
Node *node = (Node *)ptr;
if (!node) return nil;
node->next = nil;
if (!list->head) {
list->head = list->tail = node;
} else {
list->tail->next = node;
list->tail = node;
}
list->count++;
void *dest = node_value(node);
if (data && data_size > 0) {
mcpy(dest, data, data_size);
}
return dest;
}
void
list_foreach(List *list, list_iter_fn func)
{
if (!list || !func) return;
Node *curr = list->head;
while (curr) {
func(node_value(curr));
curr = curr->next;
}
}
void *
list_get(List *list, u32 index)
{
if (!list || index >= list->count) return nil;
Node *curr = list->head;
// Walk to the desired index
for (u32 i = 0; i < index; i++) {
curr = curr->next;
}
return node_value(curr);
}
void
list_set(List *list, u32 index, const void *data, u32 size)
{
void *target = list_get(list, index);
if (target) {
mcpy(target, data, size);
}
}
void *
list_find(List *list, compare_fn compare, const void *target)
{
if (!list || !compare) return nil;
Node *curr = list->head;
while (curr) {
void *data = node_value(curr);
if (compare(data, target)) {
return data;
}
curr = curr->next;
}
return nil;
}

29
list.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef UNDAR_LIST_H
#define UNDAR_LIST_H
#include "libc.h"
typedef struct node_s Node;
struct node_s {
struct node_s *next;
};
typedef struct list_s List;
struct list_s {
Node *head;
Node *tail;
u32 count;
};
typedef bool (*compare_fn)(const void *data, const void *target);
typedef void (*list_iter_fn)(void *data);
List *new_list(Arena *arena);
void *node_value(Node *n);
void *list_push(Arena *arena, List *list, void *data, u32 data_size);
void list_foreach(List *list, list_iter_fn func);
void *list_find(List *list, compare_fn compare, const void *target);
void *list_get(List *list, u32 index);
void list_set(List *list, u32 index, const void *data, u32 size);
#endif

228
parser.c
View File

@ -15,158 +15,132 @@ advance()
} }
} }
bool /****************************************************
push(TokenStack *ts, Token t) * Scope
***************************************************/
void
scope_push(Arena *arena)
{ {
if(ts->count >= ts->capacity) return false; Scope *child = aalloc(arena, sizeof(Scope));
ts->stack[ts->count++] = t; child->symbols = new_list(arena);
return true; child->parent = parser.current_scope;
parser.current_scope = child;
} }
Token void
pop(TokenStack *ts) scope_pop(Arena *arena)
{ {
if(ts->count == 0) return (Token){TOKEN_ERROR, nil, -1, -1}; Scope *prev = parser.current_scope->parent;
return ts->stack[--ts->count]; parser.current_scope = prev;
} }
Token Symbol *
top(TokenStack *ts) scope_get_symbol(Scope *scope, const char *name, u32 name_length)
{ {
if(ts->count == 0) return (Token){TOKEN_ERROR, nil, -1, -1}; if (!scope) return nil;
return ts->stack[ts->count - 1];
}
bool u32 count = scope->symbols->count;
enqueue(TokenQueue *tq, Token t) for (u32 i = 0; i < count; i++) {
{ Symbol *sym = list_get(scope->symbols, i);
if(tq->count >= tq->capacity) return false; if (sleq(sym->name, name, name_length)) {
return sym;
tq->queue[tq->end] = t; }
tq->end = (tq->end + 1) % tq->capacity; // Wrap around
tq->count++;
return true;
}
Token
dequeue(TokenQueue *tq)
{
if(tq->count == 0) return (Token){TOKEN_ERROR, NULL, -1, -1};
Token t = tq->queue[tq->start];
tq->start = (tq->start + 1) % tq->capacity; // Wrap around
tq->count--;
return t;
}
Token
peek_queue(TokenQueue *tq)
{
if(tq->count == 0) return (Token){TOKEN_ERROR, NULL, -1, -1};
return tq->queue[tq->start];
}
u32
idx_from_arena(Arena *arena, void *p)
{
return (u32)((u8 *)p - arena->tape);
}
void *
ptr_from_arena(Arena *arena, u32 i)
{
return &arena->tape[i];
}
ArenaList *
al_create(Arena *arena, u32 size)
{
ArenaList *meta = aalloc(arena, sizeof(ArenaList));
if(!meta) return nil;
meta->size = size + sizeof(u32);
meta->arena = arena;
meta->head = 0;
meta->tail = 0;
return meta;
}
void *
al_append(ArenaList *list, void **out_payload)
{
void *node = aalloc(list->arena, list->size);
if(!node) return nil;
u32 idx = idx_from_arena(list->arena, node);
void *payload = node; /* Payload starts at offset 0 */
void *cdr_ptr = (u8 *)node + (list->size - sizeof(u32));
*(u32 *)cdr_ptr = 0;
if(list->tail != 0) {
void *prev_node = ptr_from_arena(list->arena, list->tail);
void *prev_cdr = (u8 *)prev_node + (list->size - sizeof(u32));
*(u32 *)prev_cdr = idx;
} else {
list->head = idx;
} }
list->tail = idx; return scope_get_symbol(scope->parent, name, name_length);
if(out_payload) *out_payload = payload;
return payload;
} }
void * Symbol *
al_head(ArenaList *list) scope_add_symbol(Arena *arena, const char *name, u32 name_length, SymbolType type, u32 size)
{ {
if(list->head == 0) return nil; Symbol *sym = scope_get_symbol(parser.current_scope, name, name_length);
return ptr_from_arena(list->arena, list->head); if (sym != nil) return sym;
}
void * sym = aalloc(arena, sizeof(Symbol));
al_tail(ArenaList *list) scpy(sym->name, name, slen(name));
{ sym->name_length = slen(name);
if(list->tail == 0) return nil; sym->type = type;
return ptr_from_arena(list->arena, list->tail); sym->secondary_type = VOID; // Default
} sym->size = size;
sym->ref = 0;
SymbolLink * if (type == PLEX || type == METHOD || type == TRAIT) {
symbol_table_find(ArenaList *table, const char *name) sym->args = new_list(arena);
{ sym->fields = new_list(arena);
void *current = al_head(table);
Arena *arena = table->arena;
while(current != nil) {
SymbolLink *link = (SymbolLink *)current;
if(seq(link->s.name.start, name)) return link;
u32 next_idx = link->cdr;
current = (next_idx == 0) ? nil : ptr_from_arena(arena, next_idx);
} }
return nil;
list_push(arena, parser.current_scope->symbols, sym, sizeof(Symbol));
return sym;
} }
/**************************************************** /****************************************************
* Parser * Parser
***************************************************/ ***************************************************/
bool
parse_trait()
{
return true;
}
bool bool
expression() parse_plex()
{ {
Token operator_stack[256]; return true;
TokenStack operators = {0}; }
operators.stack = operator_stack;
operators.capacity = 256;
Token output_queue[256]; bool
TokenQueue output = {0}; parse_function()
output.queue = output_queue; {
output.capacity = 256; return true;
}
bool
parse_if()
{
return true;
}
bool
parse_loop()
{
return true;
}
bool
parse_while()
{
return true;
}
bool
parse_for()
{
return true;
}
bool
parse_return()
{
return true;
}
bool
parse_assignment()
{
return true;
}
bool
parse_expression()
{
return true;
}
bool
parse_statement()
{
return true; return true;
} }

View File

@ -2,102 +2,59 @@
#define UNDAR_PARSER_H #define UNDAR_PARSER_H
#include "libc.h" #include "libc.h"
#include "list.h"
#include "lexer.h" #include "lexer.h"
typedef enum symbol_type_e { typedef enum symbol_type_e {
VOID, VOID,
BOOL, BOOL,
BYTE,
INT,
NAT,
REAL,
STR,
U8,
I8, I8,
I16, I16,
I32,
U8,
U16, U16,
I32,
U32, U32,
F8,
F16,
F32, F32,
STR,
ARRAY, ARRAY,
FUNCTION, FUNCTION,
PLEX, PLEX,
METHOD, METHOD,
TRAIT, TRAIT,
CONST,
} SymbolType; } SymbolType;
typedef struct arena_list_s ArenaList;
typedef struct symbol_s Symbol; typedef struct symbol_s Symbol;
typedef struct symbol_link_s SymbolLink; typedef struct scope_s Scope;
typedef struct token_stack_s TokenStack;
typedef struct queue_s TokenQueue;
typedef struct parser_s Parser; typedef struct parser_s Parser;
#define MAX_SYMBOL_NAME_LENGTH 64
struct symbol_s { struct symbol_s {
Token name; char name[MAX_SYMBOL_NAME_LENGTH]; /* ptr to name */
SymbolType type; u8 name_length; /* length of the name, max 64 */
u32 size; SymbolType type; /* the type for this symbol */
i32 scope; SymbolType secondary_type; /* return type for functions/methods, or const if type/plex */
union type_def { u32 ref; /* either constant value or pointer to other thing */
struct trait_def { u32 size; /* either size of the plex or length of the array/list/etc. */
u32 field_ref_start; /* reference to field list of symbols */ List *args; /* function params or plex constructor args */
u32 methods_ref_start; /* zero if none */ List *fields; /* either plex variable fields, or method signatures */
} trait;
struct plex_def {
u32 field_ref_start; /* reference to field list of symbols */
u32 methods_ref_start; /* zero if none */
} plex;
struct function_def {
SymbolType return_type;
u32 arguments_ref_start; /* reference to field list of symbols */
} function;
struct array_def {
SymbolType type;
u32 length; /* zero means "unbounded" */
} array;
struct field_def {
u32 offset;
} field;
} def;
}; };
struct symbol_link_s { struct scope_s {
Symbol s; Scope *parent; /* pointer to this scopes parent to "bubble up"*/
u32 cdr; /* zero means "end of list" */ List *symbols; /* list of symbols that live in this scope */
};
struct arena_list_s {
Arena *arena;
u32 head;
u32 tail;
u32 size;
u32 count;
i32 parent;
};
struct token_stack_s {
Token *stack;
i32 capacity;
i32 count;
};
struct queue_s {
Token *queue;
i32 capacity;
i32 start;
i32 end;
i32 count;
}; };
struct parser_s { struct parser_s {
Scope *current_scope;
Token current; Token current;
Token previous; Token previous;
}; };
bool push(TokenStack *ts, Token t);
Token pop(TokenStack *ts);
Token top(TokenStack *ts);
bool enqueue(TokenQueue *tq, Token t);
Token dequeue(TokenQueue *tq);
Token peek_queue(TokenQueue *tq);
bool compile(char *source); bool compile(char *source);
#endif #endif