#include <lexer.hpp>
namespace TokenType = Enum::Token::Type;
TokenManager::TokenManager(size_t script_size, bool verbose) : max_token_size(0), idx(0)
{
size_t token_size = sizeof(Token);
tokens = new Tokens();
pool = (TokenPool *)calloc(script_size, token_size);
head = pool;
undefined_info = getTokenInfo(TokenType::Undefined);
this->verbose = verbose;
}
Token *TokenManager::at(size_t i)
{
return head + i;
}
Token *TokenManager::nextToken(Token *tk)
{
if (!verbose) {
return (tk + 1 < pool) ? tk + 1 : NULL;
}
Token *next_tk = (tk + 1 < pool) ? tk + 1 : NULL;
/* refetch is necessary when verbose mode */
while (next_tk != NULL && next_tk->info.type == TokenType::WhiteSpace) {
next_tk = (next_tk + 1 < pool) ? next_tk + 1 : NULL;
}
return next_tk;
}
Token *TokenManager::previousToken(Token *tk)
{
if (!verbose) {
return (tk != head) ? tk - 1 : NULL;
}
Token *prev_tk = (tk != head) ? tk - 1 : NULL;
/* refetch is necessary when verbose mode */
while (prev_tk != NULL && prev_tk->info.type == TokenType::WhiteSpace) {
prev_tk = (prev_tk != head) ? prev_tk - 1 : NULL;
}
return prev_tk;
}
Token *TokenManager::beforePreviousToken(Token *tk)
{
if (!verbose) {
return (tk != head && (tk-1) != head) ? tk - 2 : NULL;
}
Token *prev_tk = (tk != head) ? tk - 1 : NULL;
while (prev_tk != NULL && prev_tk->info.type == TokenType::WhiteSpace) {
prev_tk = (prev_tk != head) ? prev_tk - 1 : NULL;
}
Token *before_prev_tk = (prev_tk != head) ? prev_tk - 1 : NULL;
while (before_prev_tk != NULL && before_prev_tk->info.type == TokenType::WhiteSpace) {
before_prev_tk = (before_prev_tk != head) ? before_prev_tk - 1 : NULL;
}
return before_prev_tk;
}
Token *TokenManager::lastToken(void)
{
return (head != pool) ? pool-1 : NULL;
}
Token *TokenManager::beforeLastToken(void)
{
return (head + 2 <= pool) ? pool-2 : NULL;
}
size_t TokenManager::size(void)
{
return (pool - head);
}
void TokenManager::dump(void)
{
size_t size = pool - head;
for (size_t i = 0; i < size; i++) {
Token *tk = (head + i);
fprintf(stdout, "[%-12s] : %12s \n", tk->_data, tk->info.name);
}
}
Token *TokenManager::getTokenByBase(Token *base, int offset)
{
Tokens *tks = this->tokens;
size_t size = tks->size();
int wanted_idx = -1;
for (size_t i = 0; i < size; i++) {
if (tks->at(i) == base) {
wanted_idx = i + offset;
}
}
return (0 <= wanted_idx && (size_t)wanted_idx < size) ?
tks->at(wanted_idx) : NULL;
}
Token *TokenManager::getTokenByIdx(size_t idx)
{
size_t size = tokens->size();
return (idx < size) ? tokens->at(idx) : NULL;
}
Token *TokenManager::beforePreviousToken(void)
{
size_t current_idx = this->idx;
size_t size = tokens->size();
int wanted_idx = current_idx - 2;
return (0 <= wanted_idx && (size_t)wanted_idx < size) ?
this->beforePreviousToken(tokens->at(current_idx)) : NULL;
}
Token *TokenManager::previousToken(void)
{
size_t current_idx = this->idx;
size_t size = tokens->size();
int wanted_idx = current_idx - 1;
return (0 <= wanted_idx && (size_t)wanted_idx < size) ?
this->previousToken(tokens->at(current_idx)) : NULL;
}
Token *TokenManager::currentToken(void)
{
size_t current_idx = this->idx;
size_t size = tokens->size();
return (current_idx < size) ? tokens->at(current_idx) : NULL;
}
Token *TokenManager::nextToken(void)
{
size_t current_idx = this->idx;
size_t size = tokens->size();
int wanted_idx = current_idx + 1;
return (0 <= wanted_idx && (size_t)wanted_idx < size) ?
this->nextToken(tokens->at(current_idx)) : NULL;
}
Token *TokenManager::next(void)
{
this->idx++;
return currentToken();
}
bool TokenManager::end(void)
{
return (idx >= tokens->size()) ? true : false;
}
void TokenManager::remove(size_t idx)
{
this->tokens->erase(this->tokens->begin() + idx);
}
Token *TokenManager::back(void)
{
this->idx--;
return currentToken();
}
ScriptManager::ScriptManager(char *script) :
_script(script), raw_script(script), idx(0)
{
script_size = strlen(script) + 1;
}
bool ScriptManager::compare(int start, int len, std::string target)
{
size_t current_idx = this->idx;
int s = current_idx + start;
int e = s + len;
if (0 <= s && (size_t)e < script_size) {
char buffer[len + 1];
memset(buffer, 0, len + 1);
memcpy(buffer, raw_script + s, len);
return std::string(buffer) == target;
}
return false;
}