178 lines
3.1 KiB
C
178 lines
3.1 KiB
C
#include "parser.h"
|
|
|
|
Parser parser;
|
|
|
|
bool
|
|
advance()
|
|
{
|
|
parser.previous = parser.current;
|
|
|
|
for(;;) {
|
|
parser.current = next_token();
|
|
if(parser.current.type != TOKEN_ERROR) return true;
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool
|
|
push(TokenStack *ts, Token t)
|
|
{
|
|
if(ts->count >= ts->capacity) return false;
|
|
ts->stack[ts->count++] = t;
|
|
return true;
|
|
}
|
|
|
|
Token
|
|
pop(TokenStack *ts)
|
|
{
|
|
if(ts->count == 0) return (Token){TOKEN_ERROR, nil, -1, -1};
|
|
return ts->stack[--ts->count];
|
|
}
|
|
|
|
Token
|
|
top(TokenStack *ts)
|
|
{
|
|
if(ts->count == 0) return (Token){TOKEN_ERROR, nil, -1, -1};
|
|
return ts->stack[ts->count - 1];
|
|
}
|
|
|
|
bool
|
|
enqueue(TokenQueue *tq, Token t)
|
|
{
|
|
if(tq->count >= tq->capacity) return false;
|
|
|
|
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;
|
|
|
|
if(out_payload) *out_payload = payload;
|
|
return payload;
|
|
}
|
|
|
|
void *
|
|
al_head(ArenaList *list)
|
|
{
|
|
if(list->head == 0) return nil;
|
|
return ptr_from_arena(list->arena, list->head);
|
|
}
|
|
|
|
void *
|
|
al_tail(ArenaList *list)
|
|
{
|
|
if(list->tail == 0) return nil;
|
|
return ptr_from_arena(list->arena, list->tail);
|
|
}
|
|
|
|
SymbolLink *
|
|
symbol_table_find(ArenaList *table, const char *name)
|
|
{
|
|
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;
|
|
}
|
|
|
|
/****************************************************
|
|
* Parser
|
|
***************************************************/
|
|
|
|
bool
|
|
expression()
|
|
{
|
|
Token operator_stack[256];
|
|
TokenStack operators = {0};
|
|
operators.stack = operator_stack;
|
|
operators.capacity = 256;
|
|
|
|
Token output_queue[256];
|
|
TokenQueue output = {0};
|
|
output.queue = output_queue;
|
|
output.capacity = 256;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
compile(char *source)
|
|
{
|
|
return true;
|
|
}
|