63af3e907b
The unification of memory pools also fixed some memory leaks and hopefully reduced the mallocs of identifier strings significantly by giving them the same pool as the token stream.
124 lines
2.7 KiB
C
124 lines
2.7 KiB
C
#include "tok.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "util.h"
|
|
|
|
int8_t op_prec[OperatorEnumSize] = {
|
|
[OpEOF] = PREC_DELIM,
|
|
[OpNewLn] = PREC_DELIM,
|
|
[OpLCurl] = PREC_DELIM,
|
|
[OpRParen] = PREC_DELIM,
|
|
[OpComma] = PREC_DELIM,
|
|
[OpAdd] = 0,
|
|
[OpSub] = 0,
|
|
[OpMul] = 1,
|
|
[OpDiv] = 1,
|
|
};
|
|
|
|
const char *op_str[OperatorEnumSize] = {
|
|
[OpLCurl] = "{",
|
|
[OpRCurl] = "}",
|
|
[OpLParen] = "(",
|
|
[OpRParen] = ")",
|
|
[OpComma] = ",",
|
|
[OpAdd] = "+",
|
|
[OpSub] = "-",
|
|
[OpMul] = "*",
|
|
[OpDiv] = "/",
|
|
[OpNewLn] = "\\n",
|
|
[OpEOF] = "EOF",
|
|
};
|
|
|
|
const char *tok_str[TokKindEnumSize] = {
|
|
[TokAssign] = "=",
|
|
[TokDeclare] = ":=",
|
|
[TokIf] = "if",
|
|
[TokWhile] = "while",
|
|
};
|
|
|
|
#define TOKLIST_MEMPOOL_INIT_CAP 32768
|
|
|
|
static inline TokListItem *toklist_alloc_item(TokList *l) {
|
|
TokListItem *itm = pool_alloc(l->p, sizeof(TokListItem));
|
|
itm->prev = itm->next = NULL;
|
|
return itm;
|
|
}
|
|
|
|
void toklist_init(TokList *l) {
|
|
l->begin = l->end = NULL;
|
|
l->p = pool_new(TOKLIST_MEMPOOL_INIT_CAP);
|
|
}
|
|
|
|
void toklist_term(TokList *l) {
|
|
pool_term(l->p);
|
|
}
|
|
|
|
void toklist_append(TokList *l, Tok t) {
|
|
TokListItem *itm = toklist_alloc_item(l);
|
|
itm->tok = t;
|
|
if (l->begin == NULL) {
|
|
l->begin = l->end = itm;
|
|
return;
|
|
}
|
|
l->end->next = itm;
|
|
itm->prev = l->end;
|
|
l->end = itm;
|
|
}
|
|
|
|
void toklist_del(TokList *l, TokListItem *from, TokListItem *to) {
|
|
if (from == l->begin) {
|
|
l->begin = to->next;
|
|
if (to->next)
|
|
to->next->prev = NULL;
|
|
} else
|
|
from->prev->next = to->next;
|
|
|
|
if (to == l->end) {
|
|
l->end = from->prev;
|
|
if (from->prev)
|
|
from->prev->next = NULL;
|
|
} else
|
|
to->next->prev = from->prev;
|
|
}
|
|
|
|
void print_toks(TokList *l) {
|
|
for (TokListItem *i = l->begin; i != NULL; i = i->next) {
|
|
printf("( ");
|
|
switch (i->tok.kind) {
|
|
case TokOp:
|
|
printf(C_IYELLOW "Op" C_RESET);
|
|
printf(": " C_ICYAN "%s" C_RESET, op_str[i->tok.Op]);
|
|
break;
|
|
case TokVal:
|
|
printf(C_IYELLOW "Val" C_RESET);
|
|
switch (i->tok.Val.type.kind) {
|
|
case TypeFloat:
|
|
printf(": " C_ICYAN "%f" C_RESET, i->tok.Val.Float);
|
|
break;
|
|
case TypeInt:
|
|
printf(": " C_ICYAN "%zd" C_RESET, i->tok.Val.Int);
|
|
break;
|
|
default:
|
|
printf(" " C_ICYAN "(unknown type)" C_RESET);
|
|
break;
|
|
}
|
|
break;
|
|
case TokIdent:
|
|
printf(C_IYELLOW "Ident" C_RESET);
|
|
if (i->tok.Ident.kind == IdentName)
|
|
printf(": " C_ICYAN "Name" C_RESET ": " C_IGREEN "'%s'" C_RESET, i->tok.Ident.Name);
|
|
else if (i->tok.Ident.kind == IdentAddr)
|
|
printf(": " C_ICYAN "Addr" C_RESET ": " C_IGREEN "%zu" C_RESET, i->tok.Ident.Addr);
|
|
break;
|
|
default:
|
|
if (tok_str[i->tok.kind]) {
|
|
printf(C_IYELLOW "%s" C_RESET, tok_str[i->tok.kind]);
|
|
}
|
|
}
|
|
printf(" | %zu:%zu )\n", i->tok.ln, i->tok.col);
|
|
}
|
|
|
|
}
|