/* yForth? - A Forth interpreter written in ANSI C
 * Copyright (C) 2012 Luca Padovani
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * ------------------------------------------------------------------------
 * Module name: 
 * Abstract:
 */

#include <stdlib.h>
#include "core.h"
#include "search.h"

/**************************************************************************/
/* VARIABLES **************************************************************/
/**************************************************************************/

struct vocabulary *list[WORD_LISTS];
Cell top;		/* indice primo vocabolario sulla pila */
struct vocabulary *voc;	/* ptr al vocabolario usato per le definzioni */
struct vocabulary *forth_wid;

/**************************************************************************/
/* WORDS ******************************************************************/
/**************************************************************************/

void _definitions() {
	voc = list[top];
}

void _forth_wordlist() {
	*--sp = (Cell) forth_wid;
}

void _get_current() {
	*--sp = (Cell) voc;
}

void _get_order() {
	register Cell i;
	for (i = 0; i <= top; i++) *--sp = (Cell) list[i];
	*--sp = top;
}

void _search_wordlist() {
	register struct vocabulary *wid = (struct vocabulary *) *sp++;
	register Cell len = *sp++;
	register Char *addr = (Char *) *sp;
	register struct word_def *xt = search_wordlist(addr, len, wid);
	set_find_stack(addr, xt);
	if (!*sp) *++sp = 0;
}

void _set_current() {
	voc = (struct vocabulary *) *sp++;
}

void _set_order() {
	register Cell n = *sp++;
	register int i;
	for (i = 0; i < n; i++)
		if (i < WORD_LISTS) list[i] = (struct vocabulary *) *sp++;
		else sp++;
	top = n - 1;
}

void _wordlist() {
	register struct vocabulary *v;
	register int i;
	_align();
	v = (struct vocabulary *) _dp;
	_dp += sizeof(struct vocabulary);
	for (i = 0; i < VOC_HASH; i++) v->voc[i] = NULL;
	*--sp = (Cell) v;
}


/**************************************************************************/
/* AUXILIARY FUNCTIONS ****************************************************/
/**************************************************************************/

void save_vocabulary(struct voc_marker *vm) {
	register int i;
	for (i = 0; i < WORD_LISTS; i++) {
		vm->list[i] = list[i];
		if (list[i]) vm->v_list[i] = *list[i];
	}
	vm->top = top;
	vm->voc = voc;
	vm->_dp = _dp;
	vm->last = _last;
}

void load_vocabulary(struct voc_marker *vm) {
	register int i;
	for (i = 0; i < WORD_LISTS; i++) {
		list[i] = vm->list[i];
		if (list[i]) *list[i] = vm->v_list[i];
	}
	top = vm->top;
	voc = vm->voc;
	_dp = vm->_dp;
	_last = vm->last;
}
