1
0
Fork 0
mirror of https://github.com/suchmememanyskill/TegraExplorer.git synced 2025-02-22 16:35:56 +00:00
TegraExplorer/source/tegraexplorer/script/lexer.c
suchmememanyskill ba0ded0f8b start of tsV2
2020-11-06 21:19:29 +01:00

195 lines
No EOL
3.9 KiB
C

#include "lexer.h"
#include "parser.h"
#include "args.h"
#include "../utils/utils.h"
#include "../../mem/heap.h"
#include <string.h>
static inline int isValidWord(char c) {
char r = c | 0x20;
return (r >= 'a' && r <= 'z');
}
static inline int isValidVar(char c) {
char r = c | 0x20;
return ((r >= 'a' && r <= 'z') || (r >= '0' && r <= '9'));
}
static inline int isValidNum(char c) {
return (c >= '0' && c <= '9');
}
static inline int isValidHexNum(char c) {
char r = c | 0x20;
return (isValidNum(r) || (r >= 'a' && r <= 'f'));
}
#define makeLexarToken(token, var) (lexarToken_t) {token, {var}}
#define makeLexarIntToken(intVar) (lexarToken_t) {IntLit, .val = intVar}
typedef struct {
u8 tokenC;
u16 tokenN;
} lexarTranslation_t;
lexarTranslation_t lexarTranslations[] = {
{'(', LBracket},
{')', RBracket},
{'{', LCBracket},
{'}', RCBracket},
{',', Seperator},
{'+', Plus},
{'-', Minus},
{'*', Multiply},
{'/', Division},
{'%', Mod},
{'<', Smaller},
{'>', Bigger},
{'=', Equal},
{'!', Not},
{'[', LSBracket},
{']', RSBracket},
{'\0', 0},
};
char lexarDebugGetTokenC(u16 tokenN) {
for (int i = 0; lexarTranslations[i].tokenC; i++) {
if (lexarTranslations[i].tokenN == tokenN) {
return lexarTranslations[i].tokenC;
}
}
return '?';
}
lexarVector_t lexarVectorInit(int startSize) {
lexarVector_t l = { 0 };
l.tokens = calloc(startSize, sizeof(lexarVector_t));
l.len = startSize;
l.stored = 0;
return l;
}
void lexarVectorAdd(lexarVector_t* vec, lexarToken_t token) {
if (vec->stored >= vec->len) {
vec->len *= 2;
//vec->tokens = realloc(vec->tokens, vec->len * sizeof(lexarToken_t));
void *temp = calloc(vec->len, sizeof(lexarToken_t));
memcpy(temp, vec->tokens, vec->len / 2 * sizeof(lexarToken_t));
free(vec->tokens);
vec->tokens = temp;
}
vec->tokens[vec->stored++] = token;
}
void lexarVectorClear(lexarVector_t* vec) {
for (int i = 0; i < vec->stored; i++) {
if (vec->tokens[i].token == Variable || vec->tokens[i].token == StrLit)
if (vec->tokens[i].text != NULL)
free(vec->tokens[i].text);
}
free(vec->tokens);
}
#define ELIFC(c) else if (*in == c)
lexarVector_t lexarGo(const char* in) {
lexarVector_t vec = lexarVectorInit(16);
while (*in) {
if (isValidWord(*in)) {
char* startWord = in;
in++;
while (isValidVar(*in))
in++;
lexarVectorAdd(&vec, makeLexarToken(Variable, utils_copyStringSize(startWord, in - startWord)));
continue;
}
else if (isValidNum(*in) || (*in == '-' && isValidNum(in[1]))) {
int parse = 0;
u8 negative = (*in == '-');
if (negative)
in++;
if (*in == '0' && (in[1] | 0x20) == 'x') {
in += 2;
while (isValidHexNum(*in)) {
parse = parse * 16 + (*in & 0x0F) + (*in >= 'A' ? 9 : 0);
in++;
}
}
else while (isValidNum(*in)) {
parse = parse * 10 + *in++ - '0';
}
if (negative)
parse *= -1;
lexarVectorAdd(&vec, makeLexarIntToken(parse));
continue;
}
ELIFC('"') {
char* startStr = ++in;
while (*in != '"')
in++;
lexarVectorAdd(&vec, makeLexarToken(StrLit, utils_copyStringSize(startStr, in - startStr)));
in++;
continue;
}
ELIFC('#') {
while (*in != '\n')
in++;
in++;
continue;
}
ELIFC('&') {
if (in[1] == '&') {
lexarVectorAdd(&vec, makeLexarToken(LogicAND, 0));
in++;
}
else {
lexarVectorAdd(&vec, makeLexarToken(AND, 0));
}
in++;
continue;
}
ELIFC('|') {
if (in[1] == '|') {
lexarVectorAdd(&vec, makeLexarToken(LogicOR, 0));
in++;
}
else {
lexarVectorAdd(&vec, makeLexarToken(OR, 0));
}
in++;
continue;
}
int val = 0;
for (int i = 0; lexarTranslations[i].tokenC; i++) {
if (lexarTranslations[i].tokenC == *in) {
val = lexarTranslations[i].tokenN;
break;
}
}
in++;
if (*in == '=' && val >= Smaller && val <= Not) {
val++;
in++;
}
if (val != Invalid)
lexarVectorAdd(&vec, makeLexarToken(val, 0));
}
return vec;
}