2021-12-21 01:18:22 +01:00
|
|
|
#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,
|
2021-12-23 21:42:09 +01:00
|
|
|
[OpAnd] = 0,
|
|
|
|
[OpOr] = 0,
|
|
|
|
[OpEq] = 1,
|
|
|
|
[OpLt] = 1,
|
|
|
|
[OpGt] = 1,
|
|
|
|
[OpLe] = 1,
|
|
|
|
[OpGe] = 1,
|
|
|
|
[OpAdd] = 2,
|
|
|
|
[OpSub] = 2,
|
|
|
|
[OpMul] = 3,
|
|
|
|
[OpDiv] = 3,
|
2021-12-21 01:18:22 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const char *op_str[OperatorEnumSize] = {
|
|
|
|
[OpLCurl] = "{",
|
|
|
|
[OpRCurl] = "}",
|
|
|
|
[OpLParen] = "(",
|
|
|
|
[OpRParen] = ")",
|
|
|
|
[OpComma] = ",",
|
|
|
|
[OpAdd] = "+",
|
|
|
|
[OpSub] = "-",
|
|
|
|
[OpMul] = "*",
|
|
|
|
[OpDiv] = "/",
|
2021-12-23 21:06:49 +01:00
|
|
|
[OpNot] = "!",
|
2021-12-21 01:18:22 +01:00
|
|
|
[OpNewLn] = "\\n",
|
|
|
|
[OpEOF] = "EOF",
|
2021-12-23 21:06:49 +01:00
|
|
|
[OpEq] = "==",
|
|
|
|
[OpLt] = "<",
|
|
|
|
[OpGt] = ">",
|
|
|
|
[OpLe] = "<=",
|
|
|
|
[OpGe] = ">=",
|
2021-12-23 21:42:09 +01:00
|
|
|
[OpAnd] = "&&",
|
|
|
|
[OpOr] = "||",
|
2021-12-21 01:18:22 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const char *tok_str[TokKindEnumSize] = {
|
|
|
|
[TokAssign] = "=",
|
|
|
|
[TokDeclare] = ":=",
|
|
|
|
[TokIf] = "if",
|
2021-12-23 19:58:00 +01:00
|
|
|
[TokElse] = "else",
|
2021-12-21 01:18:22 +01:00
|
|
|
[TokWhile] = "while",
|
|
|
|
};
|
|
|
|
|
2021-12-21 11:40:49 +01:00
|
|
|
#define TOKLIST_MEMPOOL_INIT_CAP 32768
|
2021-12-21 01:18:22 +01:00
|
|
|
|
|
|
|
static inline TokListItem *toklist_alloc_item(TokList *l) {
|
2021-12-21 11:40:49 +01:00
|
|
|
TokListItem *itm = pool_alloc(l->p, sizeof(TokListItem));
|
2021-12-21 01:18:22 +01:00
|
|
|
itm->prev = itm->next = NULL;
|
|
|
|
return itm;
|
|
|
|
}
|
|
|
|
|
|
|
|
void toklist_init(TokList *l) {
|
|
|
|
l->begin = l->end = NULL;
|
2021-12-21 11:40:49 +01:00
|
|
|
l->p = pool_new(TOKLIST_MEMPOOL_INIT_CAP);
|
2021-12-21 01:18:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void toklist_term(TokList *l) {
|
2021-12-21 11:40:49 +01:00
|
|
|
pool_term(l->p);
|
2021-12-21 01:18:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2021-12-23 21:06:49 +01:00
|
|
|
case TypeBool:
|
|
|
|
printf(": " C_ICYAN "%s" C_RESET, i->tok.Val.Bool ? "true" : "false");
|
|
|
|
break;
|
2021-12-23 21:26:53 +01:00
|
|
|
case TypeChar:
|
|
|
|
printf(": " C_ICYAN "'%c'" C_RESET, i->tok.Val.Char);
|
|
|
|
break;
|
2021-12-21 01:18:22 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|