/*
 * *****************************************************************************
 *
 * 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);
	bc_vec_init(&l->str, sizeof(char), NULL);
}

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

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

BcStatus bc_lex_next(BcLex *l) {

	BcStatus s;

	assert(l);

	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 && text);
	l->buf = text;
	l->i = 0;
	l->len = strlen(text);
	l->t = l->last = BC_LEX_INVALID;
	return bc_lex_next(l);
}
