/*
 * *****************************************************************************
 *
 * Copyright (c) 2018-2019 Gavin D. Howard and contributors.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * *****************************************************************************
 *
 * Common code for the lexers.
 *
 */

#include <assert.h>
#include <ctype.h>
#include <stdbool.h>
#include <string.h>

#include <status.h>
#include <lex.h>
#include <vm.h>
#include <bc.h>

BcStatus bc_lex_invalidChar(BcLex *l, char c) {
	l->t = BC_LEX_INVALID;
	return bc_lex_verr(l, BC_ERROR_PARSE_CHAR, c);
}

void bc_lex_lineComment(BcLex *l) {
	l->t = BC_LEX_WHITESPACE;
	while (l->i < l->len && l->buf[l->i] != '\n') l->i += 1;
}

BcStatus bc_lex_comment(BcLex *l) {

	size_t i, nlines = 0;
	const char *buf = l->buf;
	bool end = false;
	char c;

	l->i += 1;
	l->t = BC_LEX_WHITESPACE;

	for (i = l->i; !end; i += !end) {

		for (; (c = buf[i]) && c != '*'; ++i) nlines += (c == '\n');

		if (BC_ERR(!c || buf[i + 1] == '\0')) {
			l->i = i;
			return bc_lex_err(l, BC_ERROR_PARSE_COMMENT);
		}

		end = buf[i + 1] == '/';
	}

	l->i = i + 2;
	l->line += nlines;

	return BC_STATUS_SUCCESS;
}

void bc_lex_whitespace(BcLex *l) {
	char c;
	l->t = BC_LEX_WHITESPACE;
	for (c = l->buf[l->i]; c != '\n' && isspace(c); c = l->buf[++l->i]);
}

void bc_lex_commonTokens(BcLex *l, char c) {
	if (!c) l->t = BC_LEX_EOF;
	else if (c == '\n') l->t = BC_LEX_NLINE;
	else bc_lex_whitespace(l);
}

static size_t bc_lex_num(BcLex *l, char start, bool int_only) {

	const char *buf = l->buf + l->i;
	size_t i;
	char c;
	bool last_pt, pt = (start == '.');

	for (i = 0; (c = buf[i]) && (BC_LEX_NUM_CHAR(c, pt, int_only) ||
	                             (c == '\\' && buf[i + 1] == '\n')); ++i)
	{
		if (c == '\\') {

			if (buf[i + 1] == '\n') {

				i += 2;

				// Make sure to eat whitespace at the beginning of the line.
				while(isspace(buf[i]) && buf[i] != '\n') i += 1;

				c = buf[i];

				if (!BC_LEX_NUM_CHAR(c, pt, int_only)) break;
			}
			else break;
		}

		last_pt = (c == '.');
		if (pt && last_pt) break;
		pt = pt || last_pt;

		bc_vec_push(&l->str, &c);
	}

	return i;
}

BcStatus bc_lex_number(BcLex *l, char start) {

	l->t = BC_LEX_NUMBER;

	bc_vec_npop(&l->str, l->str.len);
	bc_vec_push(&l->str, &start);

	l->i += bc_lex_num(l, start, false);

#if BC_ENABLE_EXTRA_MATH
	{
		char c = l->buf[l->i];

		if (c == 'e') {

#if BC_ENABLED
			if (BC_IS_POSIX) {
				BcStatus s = bc_lex_err(l, BC_ERROR_POSIX_EXP_NUM);
				if (BC_ERR(s)) return s;
			}
#endif // BC_ENABLED

			bc_vec_push(&l->str, &c);
			l->i += 1;
			c = l->buf[l->i];

			if (c == BC_LEX_NEG_CHAR) {
				bc_vec_push(&l->str, &c);
				l->i += 1;
				c = l->buf[l->i];
			}

			if (BC_ERR(!BC_LEX_NUM_CHAR(c, false, true)))
				return bc_lex_verr(l, BC_ERROR_PARSE_CHAR, c);

			l->i += bc_lex_num(l, 0, true);
		}
	}
#endif // BC_ENABLE_EXTRA_MATH

	bc_vec_pushByte(&l->str, '\0');

	return BC_STATUS_SUCCESS;
}

void bc_lex_name(BcLex *l) {

	size_t i = 0;
	const char *buf = l->buf + l->i - 1;
	char c = buf[i];

	l->t = BC_LEX_NAME;

	while ((c >= 'a' && c <= 'z') || isdigit(c) || c == '_') c = buf[++i];

	bc_vec_string(&l->str, i, buf);

	// Increment the index. We minus 1 because it has already been incremented.
	l->i += i - 1;
}

void bc_lex_init(BcLex *l) {
	assert(l != NULL);
	bc_vec_init(&l->str, sizeof(char), NULL);
}

void bc_lex_free(BcLex *l) {
	assert(l != NULL);
	bc_vec_free(&l->str);
}

void bc_lex_file(BcLex *l, const char *file) {
	assert(l != NULL && file != NULL);
	l->line = 1;
	vm->file = file;
}

BcStatus bc_lex_next(BcLex *l) {

	BcStatus s;

	assert(l != NULL);

	l->last = l->t;
	l->line += (l->i != 0 && l->buf[l->i - 1] == '\n');

	if (BC_ERR(l->last == BC_LEX_EOF)) return bc_lex_err(l, BC_ERROR_PARSE_EOF);

	l->t = BC_LEX_EOF;

	if (l->i == l->len) return BC_STATUS_SUCCESS;

	// Loop until failure or we don't have whitespace. This
	// is so the parser doesn't get inundated with whitespace.
	do {
		s = vm->next(l);
	} while (BC_NO_ERR(!s) && l->t == BC_LEX_WHITESPACE);

	return s;
}

BcStatus bc_lex_text(BcLex *l, const char *text) {
	assert(l != NULL && text != NULL);
	l->buf = text;
	l->i = 0;
	l->len = strlen(text);
	l->t = l->last = BC_LEX_INVALID;
	return bc_lex_next(l);
}
