; this is sample script
; 2002/03/14 by Gaku - simple calc

struct node {
	next;
	name;
	value;
};

gHead  = null;
gTail  = null;
gNow   = null;

gTable = array(0);

main();

sub append (name)
{
	p = node(null, name, 0);

	if (null == gHead) {
		gHead = p;
	} else {
		gTail.next = p;
	}
	gTail = p;

	return p;
}

sub search (name)
{
	p = gHead;

	loop {
		if (null == p) {
			p = append(name);
			break;
		}

		if (name == p.name) {
			break;
		}

		p = p.next;
	}

	gNow = p;

	return p.value;
}

sub getToken ()
{
	if (0 == gTable) {
		buf = gets(stdin);
		if (null == buf) {
			return null;
		}
		gTable = scan('\d+|\w+|=|+|-|*|/|\n|\S+', buf);
		if (0 == gTable) {
			return null;
		}
		gTable = reverse(gTable);
	}

	token = pop(gTable);

	if (0 != match('\d+', token)) {
		return int(token);
	}

	if (0 != match('\w+', token)) {
		return search(token);
	}

	if (0 != match('=|+|-|*|/|\n', token)) {
		return token;
	}

	push(gTable, token);

	return null;
}

sub sigTerm ()
{
	token = getToken();

	if ("+" == token) {
		return getToken();
	}

	if ("-" == token) {
		return - getToken();
	}

	return token;
}

sub mulTerm ()
{
	value = sigTerm();

	loop {
		token = getToken();
		if ("*" == token) {
			value = value * sigTerm();
		} else if ("/" == token) {
			value = value / sigTerm();
		} else {
			push(gTable, token);
			break;
		}
	}

	return value;
}

sub addTerm ()
{
	value = mulTerm();

	loop {
		token = getToken();
		if ("+" == token) {
			value = value + mulTerm();
		} else if ("-" == token) {
			value = value - mulTerm();
		} else {
			push(gTable, token);
			break;
		}
	}

	return value;
}

sub movTerm ()
{
	value = addTerm();

	token = getToken();
	if ("=" == token) {
		p       = gNow;
		value   = addTerm();
		p.value = value;
	} else {
		push(gTable, token);
	}

	return value;
}

sub main()
{
	print("this is simple calc.\n");

	loop {
		print(">");
		print(" = ", movTerm(), "\n");

		if ("\n" != getToken()) {
			break;
		}
	}
}
