/*
 * sys module program copyright (C) 2009 - 2013 H.Niwa
 */

/*
 * 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 2, 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <errno.h>
#include <setjmp.h>
#include <sys/time.h>
#include <math.h>
#include <libgen.h>
#include <setjmp.h>
#include <string.h>


#ifndef __MINGW32__ 

#include <libgen.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#endif /* __MINGW32__ */

#if HAVE_ICONV_H
#include <iconv.h>
#endif /* HAVE_ICONV_H */

#ifndef __MINGW32__ 
#include <sys/times.h>

#if HAVE_LIBREADLINE
#include <readline/readline.h>
#include <readline/history.h>
#endif /* HAVE_LIBREADLINE */

#include <sys/utsname.h>
#endif /* __MINGW32__ */

#include <string>
#include <complex>

#include "syserr.h"

#include "bin_node.h"
#include "gc.h"
#include "var.h"
#include "pred.h"
#include "context.h"
#include "unify.h"
#include "builtin.h"
#include "sysmodule.h"
#include "expression.h"
#include "let.h"
#include "func.h"
#include "token.h"
#include "module.h"
#include "code.h"
#include "timeout.h"
#include "help.h"
#include "sleep.h"
#include "complx.h"
#include "lisp.h"
#include "ncurlib.h"
#include "compiler.h"
#include "checkreserved.h"
#include "regexheader.h"
#include "checksrc.h"
#include "winsock2util.h"
#include "win.h"
#include "httpclient.h"
#include "ode.h"

#define MAXPATHLEN 4096

extern int TraceFlag;
extern jmp_buf program_jb;


extern Node* UTF8Char(char* str);
extern Node* SJISChar(char* str);
extern Node* EUCChar(char* str);

extern FILE* MksTemp(char* templ);


int CmdArgs(Context* cx, Node* goalscar, List* module);
int DlibPath(Context* cx, Node* goalscar, List* module);
int PrintResultOn(Context* cx, Node* goalscar, List* module);
int PrintResultOff(Context* cx, Node* goalscar, List* module);
int CutAll(Context* cx, Node* goalscar, List* module);
int Write(Context* cx, Node* goalscar, List* module);
int WriteNl(Context* cx, Node* goalscar, List* module);

int dois(Context* cx, Node* n, List* module);
int eq(Context* cx, Node* n, List* module);
int noteq(Context* cx, Node* n, List* module);
int isNil(Context* cx, Node* n, List* module);
int isAtom(Context* cx, Node* n, List* module);
int isList(Context* cx, Node* n, List* module);
int isPred(Context* cx, Node* n, List* module);
int isVar(Context* cx, Node* n, List* module);
int isUndefVar(Context* cx, Node* n, List* module);
int isFloat(Context* cx, Node* n, List* module);
int isInteger(Context* cx, Node* n, List* module);

int isTrue(Context* cx, Node* goalscar, List* module);
int isFalse(Context* cx, Node* goalscar, List* module);
int isUnknown(Context* cx, Node* goalscar, List* module);

int isRegistered(Context* cx, Node* goalscar, List* module);
int isUnregistered(Context* cx, Node* goalscar, List* module);

int isObj(Context* cx, Node* goalscar, List* module);

int Max(Context* cx, Node* goalscar, List* module);
int Min(Context* cx, Node* goalscar, List* module);
int Maxf(Context* cx, Node* goalscar, List* module);
int Minf(Context* cx, Node* goalscar, List* module);
int Sum(Context* cx, Node* goalscar, List* module);
int Sumf(Context* cx, Node* goalscar, List* module);
int Avg(Context* cx, Node* goalscar, List* module);
int Avgf(Context* cx, Node* goalscar, List* module);


int DoOpenR(Context* cx, Node* goalscar, List* module);
int DoOpenW(Context* cx, Node* goalscar, List* module);
int DoOpenWP(Context* cx, Node* goalscar, List* module);

int DoGetc(Context* cx, Node* goalscar, List* module);
int DoPutc(Context* cx, Node* goalscar, List* module);
int GetLine(Context* cx, Node* goalscar, List* module);
int SyntaxLine(Context* cx, Node* goalscar, List* module);
int TmpFile(Context* cx, Node* goalscar, List* module);
int Line(Context* cx, Node* goalscar, List* module);
int DoFlush(Context* cx, Node* goalscar, List* module);

#ifdef HAVE_REGEX_H
int DoRegex(Context* cx, Node* goalscar, List* module);
int DoSub(Context* cx, Node* goalscar, List* module);
int DoGSub(Context* cx, Node* goalscar, List* module);
int DoGrep(Context* cx, Node* goalscar, List* module);
int DoGrep_i(Context* cx, Node* goalscar, List* module);
int DoGrep_v(Context* cx, Node* goalscar, List* module);
#endif /* HAVE_REGEX_H */

int Split(Context* cx, Node* goalscar, List* module);
int SplitStr(Context* cx, Node* goalscar, List* module);
int SplitLine(Context* cx, Node* goalscar, List* module);
int Toupper(Context* cx, Node* goalscar, List* module);
int Tolower(Context* cx, Node* goalscar, List* module);
int Length(Context* cx, Node* goalscar, List* module);
int Random(Context* cx, Node* goalscar, List* module);

int Char(Context* cx, Node* goalscar, List* module);
int Concat(Context* cx, Node* goalscar, List* module);
int ConcatCode(Context* cx, Node* goalscar, List* module);
int LeftStr(Context* cx, Node* goalscar, List* module);
int RightStr(Context* cx, Node* goalscar, List* module);
int SubStr(Context* cx, Node* goalscar, List* module);
int InsertStr(Context* cx, Node* goalscar, List* module);
int ReplaceStr(Context* cx, Node* goalscar, List* module);

int SetCode(Context* cx, Node* goalscar, List* module);
int CodeCharPrd(Context* cx, Node* goalscar, List* module);
int UTF8CharPrd(Context* cx, Node* goalscar, List* module);
int EUCCharPrd(Context* cx, Node* goalscar, List* module);
int SJISCharPrd(Context* cx, Node* goalscar, List* module);

int And(Context* cx, Node* goalscar, List* module);
int Or(Context* cx, Node* goalscar, List* module);
int Xor(Context* cx, Node* goalscar, List* module);
int BitNot(Context* cx, Node* goalscar, List* module);
int ShiftL(Context* cx, Node* goalscar, List* module);
int ShiftR(Context* cx, Node* goalscar, List* module);

int DoMkPred(Context* cx, Node* goalscar, List* module);
int DoMkPredList(Context* cx, Node* goalscar, List* module);

int DoCountNode(Context* cx, Node* goalscar, List* module);

int GetTime(Context* cx, Node* goalscar, List* module);
int Time(Context* cx, Node* goalscar, List* module);
int Date(Context* cx, Node* goalscar, List* module);
int Sleep(Context* cx, Node* goalscar, List* module);
int USleep(Context* cx, Node* goalscar, List* module);
int Pause(Context* cx, Node* goalscar, List* module);

int BaseName(Context* cx, Node* goalscar, List* module);
int DirName(Context* cx, Node* goalscar, List* module);
int Suffix(Context* cx, Node* goalscar, List* module);

int ClearScreen(Context* cx, Node* goalscar, List* module);
#ifndef __MINGW32__
int Uname(Context* cx, Node* goalscar, List* module);
#endif

int SortAscending(Context* cx, Node* goalscar, List* module);
int SortDescending(Context* cx, Node* goalscar, List* module);

int FindList(Context* cx, Node* goalscar, List* module);

int Trim(Context* cx, Node* goalscar, List* module);
int LeftTrim(Context* cx, Node* goalscar, List* module);
int RightTrim(Context* cx, Node* goalscar, List* module);
int Chop(Context* cx, Node* goalscar, List* module);
int Chomp(Context* cx, Node* goalscar, List* module);
int StrReverse(Context* cx, Node* goalscar, List* module);
int StrRepeat(Context* cx, Node* goalscar, List* module);
int StrShiftRight(Context* cx, Node* goalscar, List* module);
int StrShiftLeft(Context* cx, Node* goalscar, List* module);
int StrRotateRight(Context* cx, Node* goalscar, List* module);
int StrRotateLeft(Context* cx, Node* goalscar, List* module);
int StrSort(Context* cx, Node* goalscar, List* module);
int StrSortReverse(Context* cx, Node* goalscar, List* module);
int StrLen(Context* cx, Node* goalscar, List* module);
int StrByte(Context* cx, Node* goalscar, List* module);
int StrFry(Context* cx, Node* goalscar, List* module);
int StrDelcntl(Context* cx, Node* goalscar, List* module);
int Seq(Context* cx, Node* goalscar, List* module);
int Padding(Context* cx, Node* goalscar, List* module);
int CRLF2LF(Context* cx, Node* n, List* module);
int LF2CRLF(Context* cx, Node* n, List* module);

int EqOR(Context* cx, Node* goalscar, List* module);
int Switch(Context* cx, Node* goalscar, List* module);

int DoAppend(Context* cx, Node* goalscar, List* module);
int DoReverse(Context* cx, Node* goalscar, List* module);
int DoMember(Context* cx, Node* goalscar, List* module);

int CheckObj(Context* cx, Node* goalscar, List* module);

int DoGetenv(Context* cx, Node* goalscar, List* module);

int UrlEncode(Context* cx, Node* goalscar, List* module);
int UrlDecode(Context* cx, Node* goalscar, List* module);

int HtmlEncode(Context* cx, Node* goalscar, List* module);
int HtmlDecode(Context* cx, Node* goalscar, List* module);

int HtmlTags(Context* cx, Node* goalscar, List* module);
int HtmlSection(Context* cx, Node* goalscar, List* module);
int EraseAllTags(Context* cx, Node* goalscar, List* module);
int EraseTags(Context* cx, Node* goalscar, List* module);
int EraseCoomentTags(Context* cx, Node* goalscar, List* module);
int SplitTags(Context* cx, Node* goalscar, List* module);

int PulloutStr(Context* cx, Node* goalscar, List* module);
int EraseStr(Context* cx, Node* goalscar, List* module);

int FileGet(Context* cx, Node* goalscar, List* module);
int HttpGet(Context* cx, Node* goalscar, List* module);
int HttpHead(Context* cx, Node* goalscar, List* module);
int HttpPost(Context* cx, Node* goalscar, List* module);

int StrCode(Context* cx, Node* goalscar, List* module);

#if HAVE_ICONV_H
int DoIconv(Context* cx, Node* goalscar, List* module);
#endif /* HAVE_ICONV_H */

int Flatten(Context* cx, Node* goalscar, List* module);

int CheckSrc(Context* cx, Node* goalscar, List* module);

int readCSV(Context* cx, Node* goalscar, List* module);
int writeCSV(Context* cx, Node* goalscar, List* module);
int readFile(Context* cx, Node* goalscar, List* module);
int writeFile(Context* cx, Node* goalscar, List* module);
int readRecord(Context* cx, Node* goalscar, List* module);
int writeRecord(Context* cx, Node* goalscar, List* module);


// program start time
struct ProgTime progtime;


// lib path
Node*	dlibpathnode = Nil;

int FuncArg(Context* cx, Node*& args, Node* goalscar, List* module)
{
	Node* retn;
	int rn;
			
	cxpush(cx, goalscar);
	cxpush(cx, args);
	cxpush(cx, module);
	if ((rn=FuncPred(cx, args, module, retn))>0) {
		cxpop(cx);
		cxpop(cx);
		cxpop(cx);
		args = retn->Val();
	} else {
		cxpop(cx);
		cxpop(cx);
		cxpop(cx);
	}
	return rn;
}

void GetLibPath(const char* dlibpath)
{
	if (dlibpath == NULL) {
		dlibpath = "";
	}
	dlibpathnode = Nil;
	if (dlibpath != NULL) {
		int	i, j;
		char*	pathbuf = new char[strlen(dlibpath)];
		
		for (i = 0, j = 0; i <= strlen(dlibpath); i++, j++) {
			switch (dlibpath[i]) {
#ifdef __MINGW32__
			case ';' :	// semicolon
#else 
			case ':' :	
#endif
			case 0 :
				pathbuf[j] = 0;
				dlibpathnode = Append(dlibpathnode, 
							MkList(mka(pathbuf)));
				j = -1;
				break;
			default :
				pathbuf[j] = dlibpath[i];
				break;
			}
		}
		delete pathbuf;
	}

}

void GetLibPath()
{
	const char* dlibpath = getenv(DLIBPATH);
	if (dlibpath == NULL) {
		dlibpath = ".";
	}
	GetLibPath(dlibpath);
}

int Parm0(Context* cx, Node* goalscar, List* module, const char* msg1)
{
	if (goalscar->Cdr() != Nil) {
		syserr(msg1);
		return 0;
	}
	return 1;
}

int Parm1(Context* cx, Node* goalscar, List* module, const char* msg1, 
	const char* msg2, Node* &parm1)
{
	Node* g = goalscar->Cdr();
	if (ListLength(g) != 1) {
		syserr(msg1);
		return 0;
	}

	parm1 = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, parm1, goalscar, module)) <= 0) {
		syserr(msg2);
		return 0;
	}

	return 1;
}

int Parm2(Context* cx, Node* goalscar, List* module, const char* msg1, 
	const char* msg2, Node* &parm1, Node* &parm2)
{
	Node* g = goalscar->Cdr();
	if (ListLength(g) != 2) {
		syserr(msg1);
		return 0;
	}

	parm1 = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, parm1, goalscar, module)) <= 0) {
		syserr(msg2);
		return 0;
	}

	g = g->Cdr();
	parm2 = g->Car()->Val();

	if ((rn = FuncArg(cx, parm2, goalscar, module)) <= 0) {
		syserr(msg2);
		return 0;
	}

	return 1;
}

int Parm3(Context* cx, Node* goalscar, List* module, const char* msg1, 
	const char* msg2, Node* &parm1, Node* &parm2, Node* &parm3)
{
	Node* g = goalscar->Cdr();
	if (ListLength(g) != 3) {
		syserr(msg1);
		return 0;
	}

	parm1 = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, parm1, goalscar, module)) <= 0) {
		syserr(msg2);
		return 0;
	}

	g = g->Cdr();
	parm2 = g->Car()->Val();

	if ((rn = FuncArg(cx, parm2, goalscar, module)) <= 0) {
		syserr(msg2);
		return 0;
	}

	g = g->Cdr();
	parm3 = g->Car()->Val();

	if ((rn = FuncArg(cx, parm3, goalscar, module)) <= 0) {
		syserr(msg2);
		return 0;
	}

	return 1;
}

int Parm4(Context* cx, Node* goalscar, List* module, const char* msg1, 
	const char* msg2, Node* &parm1, Node* &parm2, Node* &parm3, Node* &parm4)
{
	Node* g = goalscar->Cdr();
	if (ListLength(g) != 4) {
		syserr(msg1);
		return 0;
	}

	parm1 = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, parm1, goalscar, module)) <= 0) {
		syserr(msg2);
		return 0;
	}

	g = g->Cdr();
	parm2 = g->Car()->Val();

	if ((rn = FuncArg(cx, parm2, goalscar, module)) <= 0) {
		syserr(msg2);
		return 0;
	}

	g = g->Cdr();
	parm3 = g->Car()->Val();

	if ((rn = FuncArg(cx, parm3, goalscar, module)) <= 0) {
		syserr(msg2);
		return 0;
	}

	g = g->Cdr();
	parm4 = g->Car()->Val();

	if ((rn = FuncArg(cx, parm4, goalscar, module)) <= 0) {
		syserr(msg2);
		return 0;
	}

	return 1;
}

int sysmodule(Context* cx, Node* goalscar, Node* goalscdr, 
				Node* goals, List* module, int& r)
{
	Node* retn;
	int	rn;

	std::string	s;

	if (goalscar->Val()->Car()->kind() == ATOM) {
		((Atom*)(goalscar->Val()->Car()))->toString(s);

		if (s == "args") {
			r = CmdArgs(cx, goalscar, module);
			return 1;
		} else if (s == "DLIBPATH") {
			r = DlibPath(cx, goalscar, module);
			return 1;
		} else if (s == "PrintResultOn") {
			r = PrintResultOn(cx, goalscar, module);
			return 1;
		} else if (s == "PrintResultOff") {
			r = PrintResultOff(cx, goalscar, module);
			return 1;
#if 0
		} else if (s == "cutall") {
			r = CutAll(cx, goalscar, module);
			return 1;
#endif
		} else if (s == "mkpred") {
			r = DoMkPred(cx, goalscar, module);
			return 1;
		} else if (s == "mkpredlist") {
			r = DoMkPredList(cx, goalscar, module);
			return 1;
		} else if (s == "writenl") {
			WriteNl(cx, goalscar, module);
			r = 1;
			return 1;
		} else if (s == "writeln") {
			WriteNl(cx, goalscar, module);
			r = 1;
			return 1;
		} else if (s == "print") {
			WriteNl(cx, goalscar, module);
			r = 1;
			return 1;
		} else if (s == "write") {
			Write(cx, goalscar, module);
			r = 1;
			return 1;
		} else if (s == "isNil") {
			r = isNil(cx, goalscar, module);
			return 1;
		} else if (s == "isAtom") {
			r = isAtom(cx, goalscar, module);
			return 1;
		} else if (s == "isList") {
			r = isList(cx, goalscar, module);
			return 1;
		} else if (s == "isPred") {
			r = isPred(cx, goalscar, module);
			return 1;
		} else if (s == "isVar") {
			r = isVar(cx, goalscar, module);
			return 1;
		} else if (s == "isUndefVar") {
			r = isUndefVar(cx, goalscar, module);
			return 1;
		} else if (s == "isFloat") {
			r = isFloat(cx, goalscar, module);
			return 1;
		} else if (s == "isInteger") {
			r = isInteger(cx, goalscar, module);
			return 1;
#if !defined(__MINGW32__) && !defined(__sun)
		} else if (s == "isInf") {
			r = isInf(cx, goalscar, module);
			return 1;
		} else if (s == "isNan") {
			r = isNan(cx, goalscar, module);
			return 1;
		} else if (s == "finte") {
			r = Finite(cx, goalscar, module);
			return 1;
#endif
		} else if (s == "isTrue") {
			r = isTrue(cx, goalscar, module);
			return 1;
		} else if (s == "isFalse") {
			r = isFalse(cx, goalscar, module);
			return 1;
		} else if (s == "isUnknown") {
			r = isUnknown(cx, goalscar, module);
			return 1;
		} else if (s == "isRegistered") {
			r = isRegistered(cx, goalscar, module);
			return 1;
		} else if (s == "isUnregistered") {
			r = isUnregistered(cx, goalscar, module);
			return 1;
		} else if (s == "isObj") {
			r = isObj(cx, goalscar, module);
			return 1;
		} else if (s == "max") {
			r = Max(cx, goalscar, module);
			return 1;
		} else if (s == "min") {
			r = Min(cx, goalscar, module);
			return 1;
		} else if (s == "maxf") {
			r = Maxf(cx, goalscar, module);
			return 1;
		} else if (s == "minf") {
			r = Minf(cx, goalscar, module);
			return 1;
		} else if (s == "sum") {
			r = Sum(cx, goalscar, module);
			return 1;
		} else if (s == "sumf") {
			r = Sumf(cx, goalscar, module);
			return 1;
		} else if (s == "avg") {
			r = Avg(cx, goalscar, module);
			return 1;
		} else if (s == "avgf") {
			r = Avgf(cx, goalscar, module);
			return 1;
#ifdef HAVE_REGEX_H
		} else if (s == "regex") {
			r = DoRegex(cx, goalscar, module);
			return 1;
		} else if (s == "sub") {
			r = DoSub(cx, goalscar, module);
			return 1;
		} else if (s == "gsub") {
			r = DoGSub(cx, goalscar, module);
			return 1;
		} else if (s == "grep") {
			r = DoGrep(cx, goalscar, module);
			return 1;
		} else if (s == "grepi") {
			r = DoGrep_i(cx, goalscar, module);
			return 1;
		} else if (s == "grepv") {
			r = DoGrep_v(cx, goalscar, module);
			return 1;
#endif /* HAVE_REGEX_H */
		} else if (s == "split") {
			r = Split(cx, goalscar, module);
			return 1;
		} else if (s == "splitstr") {
			r = SplitStr(cx, goalscar, module);
			return 1;
		} else if (s == "splitline") {
			r = SplitLine(cx, goalscar, module);
			return 1;
		} else if (s == "toupper") {
			r = Toupper(cx, goalscar, module);
			return 1;
		} else if (s == "tolower") {
			r = Tolower(cx, goalscar, module);
			return 1;
		} else if (s == "length") {
			r = Length(cx, goalscar, module);
			return 1;
		} else if (s == "random") {
			r = Random(cx, goalscar, module);
			return 1;

		} else if (s == "real") {
			r = CReal(cx, goalscar, module);
			return 1;
		} else if (s == "image") {
			r = CImage(cx, goalscar, module);
			return 1;
		} else if (s == "arg") {
			r = CArg(cx, goalscar, module);
			return 1;
		} else if (s == "norm") {
			r = CNorm(cx, goalscar, module);
			return 1;
		} else if (s == "conj") {
			r = CConj(cx, goalscar, module);
			return 1;
		} else if (s == "polar") {
			r = CPolar(cx, goalscar, module);
			return 1;

#if 0
		} else if (s == "sin") {
			r = Sin(cx, goalscar, module);
			return 1;
		} else if (s == "cos") {
			r = Cos(cx, goalscar, module);
			return 1;
		} else if (s == "tan") {
			r = Tan(cx, goalscar, module);
			return 1;
		} else if (s == "asin") {
			r = ASin(cx, goalscar, module);
			return 1;
		} else if (s == "acos") {
			r = ACos(cx, goalscar, module);
			return 1;
		} else if (s == "atan") {
			r = ATan(cx, goalscar, module);
			return 1;
		} else if (s == "atan2") {
			r = ATan2(cx, goalscar, module);
			return 1;
		} else if (s == "sinh") {
			r = Sinh(cx, goalscar, module);
			return 1;
		} else if (s == "cosh") {
			r = Cosh(cx, goalscar, module);
			return 1;
		} else if (s == "tanh") {
			r = Tanh(cx, goalscar, module);
			return 1;
		} else if (s == "asinh") {
			r = ASinh(cx, goalscar, module);
			return 1;
		} else if (s == "acosh") {
			r = ACosh(cx, goalscar, module);
			return 1;
		} else if (s == "atanh") {
			r = ATanh(cx, goalscar, module);
			return 1;
		} else if (s == "log") {
			r = Log(cx, goalscar, module);
			return 1;
		} else if (s == "log10") {
			r = Log10(cx, goalscar, module);
			return 1;
		} else if (s == "exp") {
			r = Exp(cx, goalscar, module);
			return 1;
		} else if (s == "exp2") {
			r = Exp2(cx, goalscar, module);
			return 1;
		} else if (s == "exp10") {
			r = Exp10(cx, goalscar, module);
			return 1;
		} else if (s == "pow") {
			r = Pow(cx, goalscar, module);
			return 1;
		} else if (s == "sqrt") {
			r = Sqrt(cx, goalscar, module);
			return 1;
		} else if (s == "abs") {
			r = Abs(cx, goalscar, module);
			return 1;
#else
		} else if (s == "sin") {
			r = CSin(cx, goalscar, module);
			return 1;
		} else if (s == "cos") {
			r = CCos(cx, goalscar, module);
			return 1;
		} else if (s == "tan") {
			r = CTan(cx, goalscar, module);
			return 1;
		} else if (s == "asin") {
			r = CASin(cx, goalscar, module);
			return 1;
		} else if (s == "acos") {
			r = CACos(cx, goalscar, module);
			return 1;
		} else if (s == "atan") {
			r = CATan(cx, goalscar, module);
			return 1;
		} else if (s == "atan2") {
			r = ATan2(cx, goalscar, module);
			return 1;
		} else if (s == "sinh") {
			r = CSinh(cx, goalscar, module);
			return 1;
		} else if (s == "cosh") {
			r = CCosh(cx, goalscar, module);
			return 1;
		} else if (s == "tanh") {
			r = CTanh(cx, goalscar, module);
			return 1;
		} else if (s == "asinh") {
			r = CASinh(cx, goalscar, module);
			return 1;
		} else if (s == "acosh") {
			r = CACosh(cx, goalscar, module);
			return 1;
		} else if (s == "atanh") {
			r = CATanh(cx, goalscar, module);
			return 1;
		} else if (s == "log") {
			r = CLog(cx, goalscar, module);
			return 1;
		} else if (s == "log10") {
			r = CLog10(cx, goalscar, module);
			return 1;
		} else if (s == "exp") {
			r = CExp(cx, goalscar, module);
			return 1;
		} else if (s == "exp2") {
			r = CExp2(cx, goalscar, module);
			return 1;
		} else if (s == "exp10") {
			r = CExp10(cx, goalscar, module);
			return 1;
		} else if (s == "pow") {
			r = CPow(cx, goalscar, module);
			return 1;
		} else if (s == "sqrt") {
			r = CSqrt(cx, goalscar, module);
			return 1;
		} else if (s == "abs") {
			r = CAbs(cx, goalscar, module);
			return 1;
#endif

		} else if (s == "PI") {
			r = PI(cx, goalscar, module);
			return 1;
		} else if (s == "e") {
			r = E(cx, goalscar, module);
			return 1;
		} else if (s == "int") {
			r = Int(cx, goalscar, module);
			return 1;
		} else if (s == "floor") {
			r = Floor(cx, goalscar, module);
			return 1;
		} else if (s == "ceil") {
			r = Ceil(cx, goalscar, module);
			return 1;
		} else if (s == "trunc") {
			r = Trunc(cx, goalscar, module);
			return 1;
		} else if (s == "car") {
			r = Car(cx, goalscar, module);
			return 1;
		} else if (s == "cdr") {
			r = Cdr(cx, goalscar, module);
			return 1;

		} else if (s == "caar") {
			r = Caar(cx, goalscar, module);
			return 1;
		} else if (s == "cadr") {
			r = Cadr(cx, goalscar, module);
			return 1;
		} else if (s == "cdar") {
			r = Cdar(cx, goalscar, module);
			return 1;
		} else if (s == "cddr") {
			r = Cddr(cx, goalscar, module);
			return 1;

		} else if (s == "caaar") {
			r = Caaar(cx, goalscar, module);
			return 1;
		} else if (s == "caadr") {
			r = Caadr(cx, goalscar, module);
			return 1;
		} else if (s == "cadar") {
			r = Cadar(cx, goalscar, module);
			return 1;
		} else if (s == "caddr") {
			r = Caddr(cx, goalscar, module);
			return 1;
		} else if (s == "cdaar") {
			r = Cdaar(cx, goalscar, module);
			return 1;
		} else if (s == "cdadr") {
			r = Cdadr(cx, goalscar, module);
			return 1;
		} else if (s == "cddar") {
			r = Cddar(cx, goalscar, module);
			return 1;
		} else if (s == "cdddr") {
			r = Cdddr(cx, goalscar, module);
			return 1;

		} else if (s == "caaaar") {
			r = Caaaar(cx, goalscar, module);
			return 1;
		} else if (s == "caaadr") {
			r = Caaadr(cx, goalscar, module);
			return 1;
		} else if (s == "caadar") {
			r = Caadar(cx, goalscar, module);
			return 1;
		} else if (s == "caaddr") {
			r = Caaddr(cx, goalscar, module);
			return 1;
		} else if (s == "cadaar") {
			r = Cadaar(cx, goalscar, module);
			return 1;
		} else if (s == "cadadr") {
			r = Cadadr(cx, goalscar, module);
			return 1;
		} else if (s == "caddar") {
			r = Caddar(cx, goalscar, module);
			return 1;
		} else if (s == "cadddr") {
			r = Cadddr(cx, goalscar, module);
			return 1;
		} else if (s == "cdaaar") {
			r = Cdaaar(cx, goalscar, module);
			return 1;
		} else if (s == "cdaadr") {
			r = Cdaadr(cx, goalscar, module);
			return 1;
		} else if (s == "cdadar") {
			r = Cdadar(cx, goalscar, module);
			return 1;
		} else if (s == "cdaddr") {
			r = Cdaddr(cx, goalscar, module);
			return 1;
		} else if (s == "cddaar") {
			r = Cddaar(cx, goalscar, module);
			return 1;
		} else if (s == "cddadr") {
			r = Cddadr(cx, goalscar, module);
			return 1;
		} else if (s == "cdddar") {
			r = Cdddar(cx, goalscar, module);
			return 1;
		} else if (s == "cddddr") {
			r = Cddddr(cx, goalscar, module);
			return 1;

		} else if (s == "cons") {
			r = Cons(cx, goalscar, module);
			return 1;
		} else if (s == "nth") {
			r = Nth(cx, goalscar, module);
			return 1;
		} else if (s == "setnth") {
			r = SetNth(cx, goalscar, module);
			return 1;
		} else if (s == "code") {
			r = SetCode(cx, goalscar, module);
			return 1;
		} else if (s == "char") {
			r = CodeCharPrd(cx, goalscar, module);
			return 1;
		} else if (s == "byte") {
			r = Char(cx, goalscar, module);
			return 1;
		} else if (s == "asciichar") {
			r = Char(cx, goalscar, module);
			return 1;
		} else if (s == "utf8char") {
			r = UTF8CharPrd(cx, goalscar, module);
			return 1;
		} else if (s == "eucchar") {
			r = EUCCharPrd(cx, goalscar, module);
			return 1;
		} else if (s == "sjischar") {
			r = SJISCharPrd(cx, goalscar, module);
			return 1;
		} else if (s == "concat") {
			r = Concat(cx, goalscar, module);
			return 1;
		} else if (s == "concatcode") {
			r = ConcatCode(cx, goalscar, module);
			return 1;
		} else if (s == "leftstr") {
			r = LeftStr(cx, goalscar, module);
			return 1;
		} else if (s == "rightstr") {
			r = RightStr(cx, goalscar, module);
			return 1;
		} else if (s == "substr") {
			r = SubStr(cx, goalscar, module);
			return 1;
		} else if (s == "insertstr") {
			r = InsertStr(cx, goalscar, module);
			return 1;
		} else if (s == "replacestr") {
			r = ReplaceStr(cx, goalscar, module);
			return 1;
		} else if (s == "bitand") {
			r = And(cx, goalscar, module);
			return 1;
		} else if (s == "bitor") {
			r = Or(cx, goalscar, module);
			return 1;
		} else if (s == "bitxor") {
			r = Xor(cx, goalscar, module);
			return 1;
		} else if (s == "bitnot") {
			r = BitNot(cx, goalscar, module);
			return 1;
		} else if (s == "shiftl") {
			r = ShiftL(cx, goalscar, module);
			return 1;
		} else if (s == "shiftr") {
			r = ShiftR(cx, goalscar, module);
			return 1;
		} else if (s == "eq") {
			r = eq(cx, goalscar, module);
			return 1;
		} else if (s == "noteq") {
			r = noteq(cx, goalscar, module);
			return 1;
		} else if (s == "is") {
			r = eq(cx, goalscar, module);
			return 1;
		} else if (s == "EqOR") {
			r = EqOR(cx, goalscar, module);
			return 1;
		} else if (s == "switch") {
			r = Switch(cx, goalscar, module);
			return 1;
		} else if (s == "getc") {
			r = DoGetc(cx, goalscar, module);
			return 1;
		} else if (s == "putc") {
			r = DoPutc(cx, goalscar, module);
			r = 1;
			return 1;
		} else if (s == "getline") {
			r = GetLine(cx, goalscar, module);
			return 1;
		} else if (s == "syntax") {
			r = SyntaxLine(cx, goalscar, module);
			return 1;
		} else if (s == "tmpfile") {
			r = TmpFile(cx, goalscar, module);
			return 1;
		} else if (s == "line") {
			r = Line(cx, goalscar, module);
			return 1;
		} else if (s == "flush") {
			r = DoFlush(cx, goalscar, module);
			return 1;
		} else if (s == "openr") {
			r = DoOpenR(cx, goalscar, module);
			return 1;
		} else if (s == "openw") {
			r = DoOpenW(cx, goalscar, module);
			return 1;
		} else if (s == "openwp") {
			r = DoOpenWP(cx, goalscar, module);
			return 1;
		} else if (s == "gettime") {
			r = GetTime(cx, goalscar, module);
			return 1;
		} else if (s == "time") {
			r = Time(cx, goalscar, module);
			return 1;
		} else if (s == "date") {
			r = Date(cx, goalscar, module);
			return 1;
		} else if (s == "sleep") {
			r = Sleep(cx, goalscar, module);
			return 1;
		} else if (s == "usleep") {
			r = USleep(cx, goalscar, module);
			return 1;
		} else if (s == "pause") {
			r = Pause(cx, goalscar, module);
			return 1;
		} else if (s == "basename") {
			r = BaseName(cx, goalscar, module);
			return 1;
		} else if (s == "dirname") {
			r = DirName(cx, goalscar, module);
			return 1;
		} else if (s == "suffix") {
			r = Suffix(cx, goalscar, module);
			return 1;
		} else if (s == "clear") {
			r = ClearScreen(cx, goalscar, module);
			return 1;
#ifndef __MINGW32__	
		} else if (s == "uname") {
			r = Uname(cx, goalscar, module);
			return 1;
#endif
		} else if (s == "sort") {
			r = SortAscending(cx, goalscar, module);
			return 1;
		} else if (s == "sortascend") {
			r = SortAscending(cx, goalscar, module);
			return 1;
		} else if (s == "sortdescend") {
			r = SortDescending(cx, goalscar, module);
			return 1;
		} else if (s == "findlist") {
			r = FindList(cx, goalscar, module);
			return 1;
		} else if (s == "trim") {
			r = Trim(cx, goalscar, module);
			return 1;
		} else if (s == "lefttrim") {
			r = LeftTrim(cx, goalscar, module);
			return 1;
		} else if (s == "righttrim") {
			r = RightTrim(cx, goalscar, module);
			return 1;
		} else if (s == "chop") {
			r = Chop(cx, goalscar, module);
			return 1;
		} else if (s == "chomp") {
			r = Chomp(cx, goalscar, module);
			return 1;
		} else if (s == "strreverse") {
			r = StrReverse(cx, goalscar, module);
			return 1;
		} else if (s == "strrepeat") {
			r = StrRepeat(cx, goalscar, module);
			return 1;
		} else if (s == "strshiftright") {
			r = StrShiftRight(cx, goalscar, module);
			return 1;
		} else if (s == "strshiftleft") {
			r = StrShiftLeft(cx, goalscar, module);
			return 1;
		} else if (s == "strrotateright") {
			r = StrRotateRight(cx, goalscar, module);
			return 1;
		} else if (s == "strrotateleft") {
			r = StrRotateLeft(cx, goalscar, module);
			return 1;
		} else if (s == "strsort") {
			r = StrSort(cx, goalscar, module);
			return 1;
		} else if (s == "strsortreverse") {
			r = StrSortReverse(cx, goalscar, module);
			return 1;
		} else if (s == "strlen") {
			r = StrLen(cx, goalscar, module);
			return 1;
		} else if (s == "strbyte") {
			r = StrByte(cx, goalscar, module);
			return 1;
		} else if (s == "strfry") {
			r = StrFry(cx, goalscar, module);
			return 1;
		} else if (s == "strdelcntl") {
			r = StrDelcntl(cx, goalscar, module);
			return 1;
		} else if (s == "seq") {
			r = Seq(cx, goalscar, module);
			return 1;
		} else if (s == "padding") {
			r = Padding(cx, goalscar, module);
			return 1;
		} else if (s == "CRLF2LF") {
			r = CRLF2LF(cx, goalscar, module);
			return 1;
		} else if (s == "LF2CRLF") {
			r = LF2CRLF(cx, goalscar, module);
			return 1;
		} else if (s == "append") {
			r = DoAppend(cx, goalscar, module);
			return 1;
		} else if (s == "reverse") {
			r = DoReverse(cx, goalscar, module);
			return 1;
		} else if (s == "member") {
			r = DoMember(cx, goalscar, module);
			return 1;
		} else if (s == "checkObj") {
			r = CheckObj(cx, goalscar, module);
			return 1;
		} else if (s == "getenv") {
			r = DoGetenv(cx, goalscar, module);
			return 1;
		} else if (s == "urlencode") {
			r = UrlEncode(cx, goalscar, module);
			return 1;
		} else if (s == "urldecode") {
			r = UrlDecode(cx, goalscar, module);
			return 1;
		} else if (s == "htmlencode") {
			r = HtmlEncode(cx, goalscar, module);
			return 1;
		} else if (s == "htmldecode") {
			r = HtmlDecode(cx, goalscar, module);
			return 1;
		} else if (s == "htmltags") {
			r = HtmlTags(cx, goalscar, module);
			return 1;
		} else if (s == "htmlsection") {
			r = HtmlSection(cx, goalscar, module);
			return 1;
		} else if (s == "htmlsplit") {
			r = HtmlSplit(cx, goalscar, module);
			return 1;
		} else if (s == "htmlleft") {
			r = HtmlLeft(cx, goalscar, module);
			return 1;
		} else if (s == "htmlright") {
			r = HtmlRight(cx, goalscar, module);
			return 1;
		} else if (s == "erasealltags") {
			r = EraseAllTags(cx, goalscar, module);
			return 1;
		} else if (s == "erasetags") {
			r = EraseTags(cx, goalscar, module);
			return 1;
		} else if (s == "eraseCommenttags") {
			r = EraseCommentTags(cx, goalscar, module);
			return 1;
		} else if (s == "splittags") {
			r = SplitTags(cx, goalscar, module);
			return 1;
		} else if (s == "pulloutstr") {
			r = PulloutStr(cx, goalscar, module);
			return 1;
		} else if (s == "erasestr") {
			r = EraseStr(cx, goalscar, module);
			return 1;
		} else if (s == "fileget") {
			r = FileGet(cx, goalscar, module);
			return 1;
		} else if (s == "httpget") {
			r = HttpGet(cx, goalscar, module);
			return 1;
		} else if (s == "httphead") {
			r = HttpHead(cx, goalscar, module);
			return 1;
		} else if (s == "httppost") {
			r = HttpPost(cx, goalscar, module);
			return 1;
		} else if (s == "strcode") {
			r = StrCode(cx, goalscar, module);
			return 1;
#if HAVE_ICONV_H
		} else if (s == "iconv") {
			r = DoIconv(cx, goalscar, module);
			return 1;
#endif /* HAVE_ICONV_H */
		} else if (s == "flatten") {
			r = Flatten(cx, goalscar, module);
			return 1;
		} else if (s == "ODE") {
			r = DoODE(cx, goalscar, module);
			return 1;
		} else if (s == "integral") {
			r = Integral(cx, goalscar, module);
			return 1;
		} else if (s == "ODEdiff") {
			r = ODEdiff(cx, goalscar, module);
			return 1;
		} else if (s == "ODEprint") {
			r = ODEprint(cx, goalscar, module);
			return 1;
		} else if (s == "ODEprintf") {
			r = ODEprintf(cx, goalscar, module);
			return 1;
		} else if (s == "ODEcmd") {
			r = ODEcmd(cx, goalscar, module);
			return 1;
		} else if (s == "CHECKSRC") {
			r = CheckSrc(cx, goalscar, module);
			return 1;
		} else if (s == "readCSV") {
			r = readCSV(cx, goalscar, module);
			return 1;
		} else if (s == "writeCSV") {
			r = writeCSV(cx, goalscar, module);
			return 1;
		} else if (s == "readFile") {
			r = readFile(cx, goalscar, module);
			return 1;
		} else if (s == "writeFile") {
			r = writeFile(cx, goalscar, module);
			return 1;
		} else if (s == "readRecord") {
			r = readRecord(cx, goalscar, module);
			return 1;
		} else if (s == "writeRecord") {
			r = writeRecord(cx, goalscar, module);
			return 1;
		} else if (s == "countnode") {
			r = DoCountNode(cx, goalscar, module);
			return 1;
		} else if (s == "gc") {
			r = 1;
			GC();
			return 1;
		}
	}
	r = -1;
	syserr("::sys %s: The predicate that did not exist in the sys module is used. \n"
			, s.c_str());
	return 1;
}

int CmdArgs(Context* cx, Node* goalscar, List* module)
{
	extern int	pargc;
	extern char**	pargv;

	Node* nvar = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <args VAR> \n", 
		"args: failed in the evaluation of the argument. \n",
		nvar)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <args VAR> \n");
		return 0;
	}

	Node*	n = Nil;

	for (int i=1; i < pargc; i++) {
		n = Append(n, MkList(mka(pargv[i])));
	}

	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)(nvar->Val()))->Set(n);

	PushStack(cx, Nil, Nil, env);
	return 1;
	
}

int DlibPath(Context* cx, Node* goalscar, List* module)
{
	extern int	pargc;
	extern char**	pargv;

	Node* nvar = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <DLIBPATH VAR> \n",
		"DLIBPATH: failed in the evaluation of the argument. \n",
		nvar)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		if (nvar->kind() == ATOM) {	// set DLIBPATH
			std::string sdpath;
			
			((Atom*)nvar)->toString(sdpath);
			GetLibPath((char*)sdpath.c_str());
#ifndef __MINGW32__
			setenv(DLIBPATH, (char*)sdpath.c_str(), 1);
#else
			std::string s;
			s = DLIBPATH;
			s = s + "=";
			s = s + sdpath;
			putenv((char*)s.c_str());
#endif
			return 1;
		}
		syserr("DLIBPATH: argument of args should be a variable or an atom. \n");
		return 0;		
	}

	GetLibPath();

	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)(nvar->Val()))->Set(Dup(dlibpathnode));

	PushStack(cx, Nil, Nil, env);
	return 1;
	
}

int PrintResultOn(Context* cx, Node* goalscar, List* module)
{
	extern  int resultflg;
	
	if (!Parm0(cx, goalscar, module, "usage : <PrintResultOn> \n")) {
		return 0;
	}

	resultflg = 1;
	
	return 1;	
}

int PrintResultOff(Context* cx, Node* goalscar, List* module)
{
	extern  int resultflg;

	if (!Parm0(cx, goalscar, module, "usage : <PrintResultOff> \n")) {
		return 0;
	}

	resultflg = 0;
	
	return 1;	
}

int CutAll(Context* cx, Node* goalscar, List* module)
{
	if (!Parm0(cx, goalscar, module, "usage : <cutall> \n")) {
		return 0;
	}

	cx->CutAll();
	
	return 1;
}


int DoMkPred(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* n1 = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <mkpred VAR LIST> \n",
		"mkpred: failed in the evaluation of the argument. \n",
		nvar, n1)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <mkpred VAR LIST> \n");
		return 0;
	}

	Node* prd = MkPred(n1);
		
	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(prd);
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

static Node* mkpredlist(Node* n)
{
	if (n->kind() != LIST) {
		return Nil;
	}
	return Cons(MkPred(((List*)n)->Car()), mkpredlist(((List*)n)->Cdr()));
}

int DoMkPredList(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* n1 = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <mkpredlist VAR LIST> \n",
		"mkpredlist: failed in the evaluation of the argument. \n",
		nvar, n1)) {
			return 0;
	}

	Node* prd = mkpredlist(n1);

	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(prd);
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

int Write(Context* cx, Node* goalscar, List* module)
{
	Node*	n = goalscar->Cdr()->Val();
	int rn;

	if ((rn = FuncArg(cx, n, goalscar, module)) <= 0) {
//		syserr("write: failed in the evaluation of the argument. \n");
//		return 0;
	}

	n->Car()->print(cx->ioout);
	n->Cdr()->printcdr(cx->ioout);

	return 1;
}

int WriteNl(Context* cx, Node* goalscar, List* module)
{
	int rn;

	if (ListLength(goalscar) != 1) {
		if ((rn=Write(cx, goalscar, module)) <= 0) {
			syserr("writenl: failed in the evaluation of the argument. \n");
			return 0;
		}
	}
	
	fprintf(cx->ioout, "\n");
	return 1;
}

int dois(Context* cx, Node* goalscar, List* module)
{
	Node*	env = Nil->Cons(Nil);
	
	Node* n = goalscar->Cdr()->Val();
	if (ListLength(n) != 2) {
		syserr("usage : <is LIST1 LIST2>\n");
		return 0;
	}
	Node* n1 = n->Car();
	Node* n2 = n->Cdr()->Car();

	if (Unification(n1, n2, env, cx)) {
		PushStack(cx, Nil, Nil, env);
		return 1;
	}
	return -1;
}

int eq(Context* cx, Node* goalscar, List* module)
{
	Node*	env = Nil->Cons(Nil);
	
	Node* n = goalscar->Cdr()->Val();
	if (ListLength(n) != 2) {
		syserr("usage : <eq LIST1 LIST2>\n");
		return 0;
	}
	Node* n1 = n->Car();
	Node* n2 = n->Cdr()->Car();

	if (Unification(n1, n2, env, cx)) {
		PushStack(cx, Nil, Nil, env);
		return 1;
	}
	return -1;
}

int noteq(Context* cx, Node* goalscar, List* module)
{
	Node*	env = Nil->Cons(Nil);
	
	Node* n = goalscar->Cdr()->Val();
	if (ListLength(n) != 2) {
		syserr("usage : <noteq LIST1 LIST2>\n");
		return 0;
	}
	Node* n1 = n->Car();
	Node* n2 = n->Cdr()->Car();

	if (Unification(n1, n2, env, cx)) {
		PushStack(cx, Nil, Nil, env);
		return -1;
	}
	return 1;
}

int isNil(Context* cx, Node* goalscar, List* module)
{
	Node* n = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <isNil ARG> \n",
		"isNil: failed in the evaluation of the argument. \n",
		n)) {
			return 0;
	}

	if (n == Nil) {
		return 1;
	} else {
		return -1;
	}
}

int isAtom(Context* cx, Node* goalscar, List* module)
{
	Node* n = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <isAtom ARG> \n",
		"isAtom: failed in the evaluation of the argument. \n",
		n)) {
			return 0;
	}

	if (n->kind() == ATOM) {
		return 1;
	} else {
		return -1;
	}
}

int isList(Context* cx, Node* goalscar, List* module)
{
	Node* n = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <isList ARG> \n",
		"isList: failed in the evaluation of the argument. \n",
		n)) {
			return 0;
	}

	if (n->kind() == LIST) {
		return 1;
	} else {
		return -1;
	}
}

int isPred(Context* cx, Node* goalscar, List* module)
{
	Node* n = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <isPred ARG> \n",
		"isPred: failed in the evaluation of the argument. \n",
		n)) {
			return 0;
	}

	if (n->kind() == PRED) {
		return 1;
	} else {
		return -1;
	}
}

int isVar(Context* cx, Node* goalscar, List* module)
{
	Node* n = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <isVar ARG> \n",
		"isVar: failed in the evaluation of the argument. \n",
		n)) {
			return 0;
	}

	if ((n->kind() == VAR) || (n->kind() == UNDEF)) {
		return 1;
	} else {
		return -1;
	}

}

int isUndefVar(Context* cx, Node* goalscar, List* module)
{
	Node* n = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <isUndefVar ARG> \n",
		"isUndefVar: failed in the evaluation of the argument. \n",
		n)) {
			return 0;
	}

	if (n->kind() == UNDEF) {
		return 1;
	} else {
		return -1;
	}
}

int isFloat(Context* cx, Node* goalscar, List* module)
{
	long double d = 0.0;
	Node* n = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <isFloat ARG> \n",
		"isFloat: failed in the evaluation of the argument. \n",
		n)) {
			return 0;
	}

	if (n->kind() != ATOM) {
		return -1;
	}
	if (((Atom*)n)->toFloat(d)) {
		return 1;
	} else {
		return -1;
	}

}

int isInteger(Context* cx, Node* goalscar, List* module)
{
	long long d = 0;
	Node* n = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <isFloat ARG> \n",
		"isFloat: failed in the evaluation of the argument. \n",
		n)) {
			return 0;
	}

	if (n->kind() != ATOM) {
		return -1;
	}
	if (((Atom*)n)->toInt(d)) {
		return 1;
	} else {
		return -1;
	}
}


int isTrue(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 1) {
		return -1;
	}

	Node* gl = goalscar->Cdr()->Car()->Val();

	Context *cx2 = new Context(cx->module, cx->modulename);
	cx2->selfname = cx->selfname;
	cx2->ioin = cx->ioin;
	cx2->ioout = cx->ioout;
	cx2->tokenflag = cx->tokenflag;
	cx2->token = cx->token;

	cx2->ode = cx->ode;
	cx2->integral = cx->integral;
	
	cxpush(cx2, gl);

	int r;
	if ((r=Unify(cx2, gl, module))) {
		cx->Merge(cx2);
	}

	cxpop(cx2);

	delete cx2;
	cx2 = 0;

	return r;
}

int isFalse(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 1) {
		return -1;
	}

	Node* gl = goalscar->Cdr()->Car()->Val();

	Context *cx2 = new Context(cx->module, cx->modulename);
	cx2->selfname = cx->selfname;
	cx2->ioin = cx->ioin;
	cx2->ioout = cx->ioout;
	cx2->tokenflag = cx->tokenflag;
	cx2->token = cx->token;

	cx2->ode = cx->ode;
	cx2->integral = cx->integral;

	cxpush(cx2, gl);

	int r;
	if ((r=Unify(cx2, gl, module))) {
		cx->Merge(cx2);
	}

	cxpop(cx2);

	delete cx2;
	cx2 = 0;

	if (r > 0) {
		return -1;
	} else if (r == 0) {
		return 1;
	}
	return r;
}

int isUnknown(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) != 1) {
		return -1;
	}

	Node* gl = goalscar->Cdr()->Car()->Val();

	Context *cx2 = new Context(cx->module, cx->modulename);
	cx2->selfname = cx->selfname;
	cx2->ioin = cx->ioin;
	cx2->ioout = cx->ioout;
	cx2->tokenflag = cx->tokenflag;
	cx2->token = cx->token;

	cx2->ode = cx->ode;
	cx2->integral = cx->integral;

	cxpush(cx2, gl);

	int r;
	if ((r=Unify(cx2, gl, module))) {
		cx->Merge(cx2);
	}

	cxpop(cx2);

	delete cx2;
	cx2 = 0;

	if (r > 0) {
		return -1;
	} else if (r == 0) {
		return -1;
	}
	return 1;
}


int isRegistered(Context* cx, Node* goalscar, List* module)
{
	Node* nval = Nil;
	Node* nlist = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <isRegistered VAL LIST>\n",
		"isRegistered: failed in the evaluation of the argument. \n",
		nval, nlist)) {
			return 0;
	}

	if ((nlist->kind() != LIST) && (nlist != Nil)){
		syserr("usage : <isRegistered VAL LIST>\n");
		return 0;
	}

	for ( ; nlist->kind() != ATOM; nlist=nlist->Cdr()) {
		if (nlist->Car()->Eq(nval)) {
			return 1;
		}
	}
	return -1;
}

int isUnregistered(Context* cx, Node* goalscar, List* module)
{
	Node* nval = Nil;
	Node* nlist = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <isUnregistered VAL LIST>\n",
		"isUnregistered: failed in the evaluation of the argument. \n",
		nval, nlist)) {
			return 0;
	}

	if ((nlist->kind() != LIST) && (nlist != Nil)) {
		syserr("usage : <isUnregistered VAL LIST>\n");
		return 0;
	}

	for ( ; nlist->kind() != ATOM; nlist=nlist->Cdr()) {
		if (nlist->Car()->Eq(nval)) {
			return -1;
		}
	}
	return 1;
}

int Max(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int ll = ListLength(g);
	if (ll < 2) {
		syserr("usage : <max VAR LIST> \n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("max: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <max VAR LIST> \n");
		return 0;
	}

	Node* nlist = g->Cdr()->Val();
	if ((ll == 2) && (nlist->Car()->kind() == LIST)) {
		nlist = nlist->Car();
	}
		
	if ((nlist->kind() != LIST) && (nlist != Nil)) {
		syserr("usage : <max VAR LIST> \n");
		return 0;
	}

	long long max=0, num;
	Node* n;
	n = nlist;

	if ((n->Car()->kind() != ATOM) || !((Atom*)(n->Car()))->toInt(max)) {
		syserr("max: argument have to be number. \n");
		return 0;
	}

	for ( ; n->kind() != ATOM; n = n->Cdr()) {
		int rn;
		Node* np = n->Car();

		if ((rn = FuncArg(cx, np, goalscar, module)) <= 0) {
			syserr("max: failed in the evaluation of the argument. \n");
			return 0;
		}

		np = np->Val();

		if ((np->Car()->kind() != ATOM) 
				|| !((Atom*)np->Car())->toInt(num)) {
			syserr("max: argument have to be number. \n");
			return 0;
		}
		if (num > max) {
			max = num;
		}
	}

	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(max));

	PushStack(cx, Nil, Nil, env);
	
	return 1;

}

int Min(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int ll = ListLength(g);
	if (ll < 2) {
		syserr("usage : <min VAR LIST> \n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("min: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <min VAR LIST> \n");
		return 0;
	}

	Node* nlist = g->Cdr()->Val();
	if ((ll == 2) && (nlist->Car()->kind() == LIST)) {
		nlist = nlist->Car();
	}
		
	if ((nlist->kind() != LIST) && (nlist != Nil)) {
		syserr("usage : <min VAR LIST> \n");
		return 0;
	}

	long long min=0, num;
	Node* n;
	n = nlist;

	if ((n->Car()->kind() != ATOM) || !((Atom*)(n->Car()))->toInt(min)) {
		syserr("min: argument have to be number. \n");
		return 0;
	}

	for ( ; n->kind() != ATOM; n = n->Cdr()) {
		int rn;
		Node* np = n->Car();
		
		if ((rn = FuncArg(cx, np, goalscar, module)) <= 0) {
			syserr("min: failed in the evaluation of the argument. \n");
			return 0;
		}

		np = np->Val();
		if ((np->Car()->kind() != ATOM) 
				|| !((Atom*)np->Car())->toInt(num)) {
			syserr("min: argument have to be number. \n");
			return 0;
		}
		if (num < min) {
			min = num;
		}
	}

	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(min));

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}


int Maxf(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int ll = ListLength(g);
	if (ll < 2) {
		syserr("usage : <maxf VAR LIST> \n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("maxf: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <maxf VAR LIST> \n");
		return 0;
	}

	Node* nlist = g->Cdr()->Val();
	if ((ll == 2) && (nlist->Car()->kind() == LIST)) {
		nlist = nlist->Car();
	}
		
	if ((nlist->kind() != LIST) && (nlist != Nil)) {
		syserr("usage : <maxf VAR LIST> \n");
		return 0;
	}

	long double max=0, num;
	Node* n;
	n = nlist;

	if ((n->Car()->kind() != ATOM) || !((Atom*)(n->Car()))->toFloat(max)) {
		syserr("maxf: argument have to be number. \n");
		return 0;
	}

	for ( ; n->kind() != ATOM; n = n->Cdr()) {
		int rn;
		Node* np = n->Car();
		
		if ((rn = FuncArg(cx, np, goalscar, module)) <= 0) {
			syserr("maxf: failed in the evaluation of the argument. \n");
			return 0;
		}

		np = np->Val();
		if ((np->Car()->kind() != ATOM) 
				|| !((Atom*)np->Car())->toFloat(num)) {
			syserr("maxf: argument have to be number. \n");
			return 0;
		}
		if (num > max) {
			max = num;
		}
	}

	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(max));

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int Minf(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int ll = ListLength(g);
	if (ll < 2) {
		syserr("usage : <minf VAR LIST> \n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("minf: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <minf VAR LIST> \n");
		return 0;
	}

	Node* nlist = g->Cdr()->Val();
	if ((ll == 2) && (nlist->Car()->kind() == LIST)) {
		nlist = nlist->Car();
	}
		
	if ((nlist->kind() != LIST) && (nlist != Nil)) {
		syserr("usage : <minf VAR LIST> \n");
		return 0;
	}

	long double min=0, num;
	Node* n;
	n = nlist;

	if ((n->Car()->kind() != ATOM) || !((Atom*)(n->Car()))->toFloat(min)) {
		syserr("minf: argument have to be number. \n");
		return 0;
	}

	for ( ; n->kind() != ATOM; n = n->Cdr()) {
		int rn;
		Node* np = n->Car();
		
		if ((rn = FuncArg(cx, np, goalscar, module)) <= 0) {
			syserr("minf: failed in the evaluation of the argument. \n");
			return 0;
		}

		np = np->Val();
		if ((np->Car()->kind() != ATOM) 
				|| !((Atom*)np->Car())->toFloat(num)) {
			syserr("minf: argument have to be number. \n");
			return 0;
		}
		if (num < min) {
			min = num;
		}
	}

	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(min));

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int Sum(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int ll = ListLength(g);
	if (ll < 2) {
		syserr("usage : <sum VAR LIST ...> \n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("sum: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <sum VAR LIST ...> \n");
		return 0;
	}

	Node* nlist = g->Cdr()->Val();
	if ((ll == 2) && (nlist->Car()->kind() == LIST)) {
		nlist = nlist->Car();
	}
		
	if ((nlist->kind() != LIST) && (nlist != Nil)) {
		syserr("usage : <sum VAR LIST ...> \n");
		return 0;
	}

	long long sum = 0, num;
	Node* n;
	n = nlist;

	for (n = nlist; n->kind() != ATOM; n = n->Cdr()) {
		int rn;
		Node* np = n->Car();
		
		if ((rn = FuncArg(cx, np, goalscar, module)) <= 0) {
			syserr("sum: failed in the evaluation of the argument. \n");
			return 0;
		}

		np = np->Val();
		if ((np->kind() != ATOM) 
				|| !((Atom*)np)->toInt(num)) {
			syserr("sum: argument have to be number. \n");
			return 0;
		}
		sum += num;
	}

	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(sum));

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int Sumf(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int ll = ListLength(g);
	if (ll < 2) {
		syserr("usage : <sumf VAR LIST ...> \n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("sumf: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <sumf VAR LIST ...> \n");
		return 0;
	}

	Node* nlist = g->Cdr()->Val();
	if ((ll == 2) && (nlist->Car()->kind() == LIST)) {
		nlist = nlist->Car();
	}
		
	if ((nlist->kind() != LIST) && (nlist != Nil)) {
		syserr("usage : <sumf VAR LIST ...> \n");
		return 0;
	}

	long double sum = 0, num;
	Node* n;
	n = nlist;

	for (n = nlist; n->kind() != ATOM; n = n->Cdr()) {
		int rn;
		Node* np = n->Car();
		
		if ((rn = FuncArg(cx, np, goalscar, module)) <= 0) {
			syserr("sumf: failed in the evaluation of the argument. \n");
			return 0;
		}

		np = np->Val();
		if ((np->kind() != ATOM) 
				|| !((Atom*)np)->toFloat(num)) {
			syserr("sumf: argument have to be number. \n");
			return 0;
		}
		sum += num;
	}

	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(sum));

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int Avg(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int ll = ListLength(g);
	if (ll < 2) {
		syserr("usage : <avg VAR LIST ...> \n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("avg: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <avg VAR LIST ...> \n");
		return 0;
	}

	Node* nlist = g->Cdr()->Val();
	if ((ll == 2) && (nlist->Car()->kind() == LIST)) {
		nlist = nlist->Car();
	}
		
	if ((nlist->kind() != LIST) && (nlist != Nil)) {
		syserr("usage : <avg VAR LIST ...> \n");
		return 0;
	}

	int count = 0;
	long long sum = 0, num;
	Node* n;
	n = nlist;

	for (n = nlist; n->kind() != ATOM; n = n->Cdr()) {
		int rn;
		Node* np = n->Car();
		
		if ((rn = FuncArg(cx, np, goalscar, module)) <= 0) {
			syserr("avg: failed in the evaluation of the argument. \n");
			return 0;
		}

		np = np->Val();
		if ((np->kind() != ATOM) 
				|| !((Atom*)np)->toInt(num)) {
			syserr("avg: argument have to be number. \n");
			return 0;
		}
		sum += num;
		count++;
	}

	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(sum/count));

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int Avgf(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int ll = ListLength(g);
	if (ll < 2) {
		syserr("usage : <avgf VAR LIST ...> \n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("avgf: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <avgf VAR LIST ...> \n");
		return 0;
	}

	Node* nlist = g->Cdr()->Val();
	if ((ll == 2) && (nlist->Car()->kind() == LIST)) {
		nlist = nlist->Car();
	}
		
	if ((nlist->kind() != LIST) && (nlist != Nil)) {
		syserr("usage : <avgf VAR LIST ...> \n");
		return 0;
	}

	int count = 0;
	long double sum = 0, num;
	Node* n;
	n = nlist;

	for (n = nlist; n->kind() != ATOM; n = n->Cdr()) {
		int rn;
		Node* np = n->Car();
		
		if ((rn = FuncArg(cx, np, goalscar, module)) <= 0) {
			syserr("avgf: failed in the evaluation of the argument. \n");
			return 0;
		}

		np = np->Val();
		if ((np->kind() != ATOM) 
				|| !((Atom*)np)->toFloat(num)) {
			syserr("avgf: argument have to be number. \n");
			return 0;
		}
		sum += num;
		count++;
	}

	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(sum/count));

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int DoOpenR(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) < 2) {
		syserr("usage : <openr FILENAME [PRED]>\n");
		return 0;
	}

	Node* fname = goalscar->Cdr()->Car()->Val();

	int rn;

	if ((rn = FuncArg(cx, fname, goalscar, module)) <= 0) {
		syserr("openr: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (fname->kind() != ATOM) {
		syserr("usage : <openr FILENAME [PRED]>\n");
		return 0;
	}

	if (fname == Nil) {
		syserr("usage : <openr FILENAME [PRED]>\n");
		return 0;
	}
	
	std::string sfname;
	((Atom*)fname)->toString(sfname);

	FILE* fd;
	fd = fopen(sfname.c_str(), "rb");
	if (fd == NULL) {
		return 0;
	}
	

	Node*	gl = goalscar->Cdr()->Cdr();

	Context *cx2 = new Context(cx->module, cx->modulename);
	cx2->selfname = cx->selfname;
	cx2->ioin = fd;
	cx2->ioout = cx->ioout;
	cx2->tokenflag = cx->tokenflag;
	cx2->token = cx->token;

	cx2->ode = cx->ode;
	cx2->integral = cx->integral;

	cxpush(cx2, gl);

	int r;
	r=Unify(cx2, gl, cx->module);

	cxpop(cx2);

	if (cx2->ioin != stdin) {
		fclose(cx2->ioin);
	}

	delete cx2;
	cx2 = 0;

	return r;
}

int DoOpenW(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) < 2) {
		syserr("usage : <openw FILENAME [PRED]>\n");
		return 0;
	}

	Node* fname = goalscar->Cdr()->Car()->Val();

	int rn;

	if ((rn = FuncArg(cx, fname, goalscar, module)) <= 0) {
		syserr("openw: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (fname->kind() != ATOM) {
		syserr("usage : <openw FILENAME [PRED]>\n");
		return 0;
	}

	if (fname == Nil) {
		syserr("usage : <openw FILENAME [PRED]>\n");
		return 0;
	}
	
	std::string sfname;
	((Atom*)fname)->toString(sfname);
	FILE* fd;
	fd = fopen(sfname.c_str(), "w");
	if (fd == NULL) {
		return 0;
	}


	Node*	gl = goalscar->Cdr()->Cdr();

	Context *cx2 = new Context(cx->module, cx->modulename);
	cx2->selfname = cx->selfname;
	cx2->ioin = cx->ioin;
	cx2->ioout = fd;
	cx2->tokenflag = cx->tokenflag;
	cx2->token = cx->token;

	cx2->ode = cx->ode;
	cx2->integral = cx->integral;

	cxpush(cx2, gl);

	int r;
	r=Unify(cx2, gl, cx->module);

	cxpop(cx2);

	if (cx2->ioout != stdout) {
		fclose(cx2->ioout);
	}

	delete cx2;
	cx2 = 0;

	return r;
}

int DoOpenWP(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) < 2) {
		syserr("usage : <openwp FILENAME [PRED]>\n");
		return 0;
	}

	Node* fname = goalscar->Cdr()->Car()->Val();

	int rn;

	if ((rn = FuncArg(cx, fname, goalscar, module)) <= 0) {
		syserr("openwp: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (fname->kind() != ATOM) {
		syserr("usage : <openwp FILENAME [PRED]>\n");
		return 0;
	}

	if (fname == Nil) {
		syserr("usage : <openwp FILENAME [PRED]>\n");
		return 0;
	}
	
	std::string sfname;
	((Atom*)fname)->toString(sfname);
	FILE* fd;
	fd = fopen(sfname.c_str(), "w+");
	if (fd == NULL) {
		return 0;
	}

	Node*	gl = goalscar->Cdr()->Cdr();

	Context *cx2 = new Context(cx->module, cx->modulename);
	cx2->selfname = cx->selfname;
	cx2->ioin = cx->ioin;
	cx2->ioout = fd;
	cx2->tokenflag = cx->tokenflag;
	cx2->token = cx->token;

	cx2->ode = cx->ode;
	cx2->integral = cx->integral;

	cxpush(cx2, gl);

	int r;
	r=Unify(cx2, gl, cx->module);

	cxpop(cx2);

	if (cx2->ioout != stdout) {
		fclose(cx2->ioout);
	}

	delete cx2;
	cx2 = 0;

	return r;
}

int DoGetc(Context* cx, Node* goalscar, List* module)
{
	Node* v = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <getc VAR> \n", 
		"getc: failed in the evaluation of the argument. \n",
		v)) {
			return 0;
	}

	if (cx->ioin == stdin) {
		syserr("File is not opened");
		return 0;
	}

	if (v->kind() == UNDEF) {
		Node* env = Nil->Cons(Nil);

		int c = fgetc(cx->ioin);

		if (c == EOF) {
			return -1;
		}

		char ca[2];
		ca[0] = c;
		ca[1] = 0;		
		SetEnv(env, v);
		((Undef*)v)->Set(mka(ca));
		PushStack(cx, Nil, Nil, env);
		
		return 1;
	} else if (v->kind() == ATOM) {
		int c = fgetc(cx->ioin);

		if (c == EOF) {
			return -1;
		}

		std::string s;
		((Atom*)v)->toString(s);
		
		return ((s.c_str())[0] == c);
	} else {
		syserr("usage : <getc VAR> \n");
		return 0;
	}
			
	syserr("usage : <getc VAR> \n");
	return 0;
}

int DoPutc(Context* cx, Node* goalscar, List* module)
{
	Node* g = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <putc STRINGS>\n", 
		"putc: failed in the evaluation of the argument. \n", 
		g)) {
			return 0;
	}

	if (g->kind() == ATOM) {
		std::string s;
		((Atom*)g->Car())->toString(s);
		putc(s.c_str()[0], cx->ioout);
		return 1;
	}
	syserr("usage : <putc STRINGS>\n");
	return 0;
				
}

#define MAXCLINE	4096000

int GetLine(Context* cx, Node* goalscar, List* module)
{
	char*	cline;
	
	Node* g = goalscar->Cdr()->Val();
	int ll = ListLength(g);
	if (ll < 1) {
		syserr("usage : <getline VAR [PRED]>\n");
		return 0;
	}
	Node* nvar = g->Car();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("getline: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("getline : the first argument is not a variable.");
		return 0;
	}

	Node* npred;
	if (ll >= 2) {
		npred = g->Cdr();
	}

#if HAVE_LIBREADLINE && !defined(__MINGW32__)
	if ((cx->ioin == stdin) && isatty(0)) {
		cline = readline(NULL);
		if (cline != 0) {
			add_history(cline);
		} else {
			cline = (char*)malloc(2);
			cline[0] = 0;
		}
	} else {
		cline = (char*)malloc(MAXCLINE);
		if (fgets(cline, MAXCLINE, cx->ioin) == NULL) {
			free(cline);
			return 0;
		}
		cline[MAXCLINE-1] = 0;
	}
#else
	cline = (char*)malloc(MAXCLINE);
	if (fgets(cline, MAXCLINE-1, cx->ioin) == NULL) {
		free(cline);
		return 0;
	}
	cline[MAXCLINE-1] = 0;
#endif /* __MINGW32__ */

	int n = strlen(cline);
	for (int i = n-1; i >= 0; i--) {
		int c = cline[i];
		if ((c == '\n') || (c == '\r')) {
			cline[i] = 0;
		} else {
			break;
		}
	}
	
	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(cline));

	PushStack(cx, Nil, Nil, env);

	if (ll >= 2) {
		static char tmpfilename[MAXPATHLEN];
		strncpy(tmpfilename, tmppath, MAXPATHLEN);
		strcat(tmpfilename, "/descXXXXXX");
		FILE* fd = MksTemp(tmpfilename);
		if (fd == NULL) {
			printf("tmpfile : cannot open tmp file \n");
			return 0;
		}
		
		int rn;
		Context* cx2 = new Context(cx->module, cx->modulename);
		cx2->selfname = cx->selfname;
		cx2->inherit = cx->inherit;
		cx2->ioin = cx->ioin;
		cx2->ioout = cx->ioout;
		cx2->tokenflag = cx->tokenflag;

		cx2->ode = cx->ode;
		cx2->integral = cx->integral;

		cx2->ioin = fd;

		fprintf(cx2->ioin, "%s", cline);
		free(cline);

		rewind(cx2->ioin);

		cxpush(cx2, goalscar);
		cxpush(cx2, nvar);
		cxpush(cx2, npred);
		cxpush(cx2, env);
//PrintNode("getline npred ", npred);
		if ((rn=Unify(cx2, npred, cx->module))>0) {
			cx->Merge(cx2);

			fclose(cx2->ioin);
			cxpop(cx2);
			cxpop(cx2);
			cxpop(cx2);
			cxpop(cx2);
			delete cx2;
			cx2 = 0;

			PushStack(cx, Nil, Nil, env);

			unlink(tmpfilename);
//printf("getline trace 0 : %d \n", rn);
			return rn;
		} else {
			fclose(cx2->ioin);
			cxpop(cx2);
			cxpop(cx2);
			cxpop(cx2);
			cxpop(cx2);
			delete cx2;
			cx2 = 0;

			unlink(tmpfilename);
//printf("getline trace 1 : %d \n", rn);
			return rn;
		}

	}

	return 1;
}

int SyntaxLine(Context* cx, Node* goalscar, List* module)
{
	std::string	sline;
	
	Node* g = goalscar->Cdr()->Val();
	int ll = ListLength(g);
	if (ll < 2) {
		syserr("usage : <syntax VAR PRED>\n");
		return 0;
	}
	Node* nval = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nval, goalscar, module)) <= 0) {
		syserr("syntax: failed in the evaluation of the argument. \n");
		return 0;
	}

	Node* npred;

	npred = g->Cdr();
	
	{
		static char tmpfilename[MAXPATHLEN];
		strncpy(tmpfilename, tmppath, MAXPATHLEN);
		strcat(tmpfilename, "/descXXXXXX");
		FILE* fd = MksTemp(tmpfilename);
		if (fd == NULL) {
			syserr("tmpfile : cannot open tmp file \n");
			return 0;
		}
		
		int rn;
		Context* cx2 = new Context(cx->module, cx->modulename);
		cx2->selfname = cx->selfname;
		cx2->inherit = cx->inherit;
		cx2->ioin = cx->ioin;
		cx2->ioout = cx->ioout;
		cx2->tokenflag = cx->tokenflag;

		cx2->ode = cx->ode;
		cx2->integral = cx->integral;

		cx2->ioin = fd;

//		fprintf(cx2->ioin, "%s", sline.c_str());
		nval->print(cx2->ioin);		

		rewind(cx2->ioin);

		cxpush(cx2, goalscar);
		cxpush(cx2, npred);
//PrintNode("syntax npred 1 ", npred);

		if ((rn=Unify(cx2, npred, cx->module))>0) {

//PrintNode("syntax npred 2 ", npred->Val());
			cx->Merge(cx2);

			fclose(cx2->ioin);
			cxpop(cx2);
			cxpop(cx2);
			delete cx2;
			cx2 = 0;

			unlink(tmpfilename);
//printf("syntax trace 0 : %d \n", rn);
			return rn;
		} else {
			fclose(cx2->ioin);
			cxpop(cx2);
			cxpop(cx2);
			delete cx2;
			cx2 = 0;

			unlink(tmpfilename);
//printf("syntax trace 1 : %d \n", rn);
			return rn;
		}

	}

	return 1;
}


int TmpFile(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <tmpfile VAR>\n",
		"tmpfile: failed in the evaluation of the argument. \n",
		nvar)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <tmpfile VAR>\n");
		return 0;
	}

	static char tmpfilename[MAXPATHLEN];
	strncpy(tmpfilename, tmppath, MAXPATHLEN);
	strcat(tmpfilename, "/descXXXXXX");
	FILE* fd = MksTemp(tmpfilename);
	if (fd == NULL) {
		printf("tmpfile : cannot open tmp file \n");
		return 0;
	}

	fclose(fd);
	
	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka((char*)tmpfilename));

	unlink(tmpfilename);

	return 1;
}

int Line(Context* cx, Node* goalscar, List* module)
{
	long long	LineNo = 1;
	long	TelSav;
	int	c;

	Node* nvar = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <line VAR>\n",
		"line: failed in the evaluation of the argument. \n",
		nvar)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		// syserr("usage : <line VAR>\n");
		return 1;
	}

	TelSav = ftell(cx->ioin);
	rewind(cx->ioin);
	while(TelSav != ftell(cx->ioin)){
		c = fgetc(cx->ioin);
		if(c == '\n') {
			LineNo++;
		}
		if (c == EOF) break;
	}
	fseek(cx->ioin, TelSav, 0);

	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(LineNo));

	return 1;

}

int GetlineEval()
{
	char*	cline;
	std::string scline;
	int 	i;
	
	for(;;) {
		int assertflg = 0;
		
#if HAVE_LIBREADLINE && !defined(__MINGW32__)
		cline = readline("? ");
		if (cline != 0) {
			add_history(cline);
		} else {
			cline = (char*)malloc(2);
			cline[0] = 0;
		}
#else
		printf("? ");
		cline = (char*)malloc(MAXCLINE);
		if (fgets(cline, MAXCLINE-1, stdin) == NULL) {
			free(cline);
			return 0;
		}
		cline[MAXCLINE-1] = 0;
#endif /* HAVE_LIBREADLINE && !defined(__MINGW32__) */

		for (i = 0; i < strlen(cline); i++) {
			int rc = 1;
			if (cline[i] == ' ') {
				continue;
			}
			char* spc = CharSpace();
			if (cline[i] == spc[0]) {
				int j;
				for (j = 1; j < strlen(spc); j++) {
					if ((i+j < strlen(cline)) &&
							(cline[i+j] != spc[j])) {
						break;
					}
				}
				if (j == strlen(spc)) {
					i = i+j;
					continue;
				}
				rc = 1;
			}
			if (rc) {
				break;
			}
		}
		if (cline[i] == '/') {
			assertflg = 1;
			cline[i] = ' ';
		}
				
		// save tmpline
		static char tmpfilename[MAXPATHLEN];
		strncpy(tmpfilename, tmppath, MAXPATHLEN);
		strcat(tmpfilename, "/descXXXXXX");
		FILE* fd = MksTemp((char*)tmpfilename);
		if (fd == NULL) {
			printf("getline : cannot open tmp file \n");
			return 0;
		}

#ifndef __MINGW32__
		if (tmpfilename[0] != 0) {
			unlink(tmpfilename);
		}
#endif
		extern FILE* RdFp;
		FILE* fdsave = RdFp;
		RdFp = fd;

		// if '<>' is none in cline, added it.
		std::string sline = cline;

		sline += " ;";

//printf("getlieneval %s \n", sline.c_str());

		std::string sline2 = "";

		for (i = 0; i < sline.length()-1; i++) {
			if (sline[i] == ' ') {
				continue;
			}
			if ((sline[i] == '<') || (sline[i] == ';')) {
				break;
			}
			if ((sline[i] == ':') && (sline[i+1] == ':')) {
				i++;
				char* spc = CharSpace();
				int nspc = strlen(spc);
				for ( ; i < sline.length(); i++) {
					if (isspace(sline[i])) {
						continue;
					}
					if (strncmp(&sline[i], spc, nspc) == 0) {
						i += nspc - 1;
						continue;
					}
					break;
				}
				sline2 = "::";
				for (i++; i < sline.length(); i++) {
					if (isspace(sline[i])) {
						i++;
						break;
					}
					if (sline[i] == '<') {
						break;
					}
					if (strncmp(&sline[i], spc, nspc) == 0) {
						i = i+nspc;
						break;
					}
					sline2 += sline[i];
				}

				if (sline[i] == '<') {
					break;
				}
			}
					

			sline2 += "<";
			sline2 = sline2 + sline.substr(i);

			for (int j = sline2.length(); j >= 0; j--) {
				if (sline2[j] == ';') {
					sline2[j] = '>';
					sline2 = sline2 + ";";
					break;
				}
			}
			sline = sline2;
			break;
		}

		if (assertflg) {
			fprintf(RdFp, "%s\n", sline.c_str());
		} else {
			fprintf(RdFp, "?%s\n", sline.c_str());
		}
		
		// eval
		// save tmpline
		rewind(RdFp);

		jmp_buf savejb;
		memcpy(&savejb, &program_jb, sizeof(jmp_buf));

		extern  int     NwccMain();	
		NwccMain();

		memcpy(&program_jb, &savejb, sizeof(jmp_buf));

		fclose(RdFp);
		RdFp = fdsave;
		
		free(cline);
#ifdef __MINGW32__
		extern char lasttemp[];
		extern FILE* lastfd;
		if (lasttemp[0] != 0) {
			if (lastfd != NULL) {
				fclose(lastfd);
			}
			unlink(lasttemp);
		}
		lasttemp[0] = 0;
		lastfd = NULL;
#endif

	}
}


static int CheckDelimiterOne(char* str, int i, char* delm, int j)
{
	int k, ns, nd;

	ns = CharLen(str[i]);
	nd = CharLen(delm[j]);
	if (i+ns > strlen(str)) {
		return 0;
	}
	if (j+nd > strlen(delm)) {
		return 0;
	}
	
	if (ns == nd) {
		for (k = 0; k < nd; k++) {
			if (str[i+k] != delm[j+k]) {
				return 0;
			}
		}
		return 1;
	} else {
		return 0;
	}				
}

static int CheckDelimiter(char* str, int i, char* delm)
{
	int j, nd;

	for (j = 0; j < strlen(delm); j += nd) {
		nd = CharLen(delm[j]);
		if (j+nd > strlen(delm)) {
			return 0;
		}

		if (CheckDelimiterOne(str, i, delm, j)) {
			return 1;
		}
	}
	return 0;
}

Node* dosplit(std::string &str, std::string &Delimiters)
{
	// skip space
	std::string tmpstr = "";
	int i, j, ns=1;
	Node* arg = Nil;
	
	for (i=0; i < str.length(); i += ns) {
		ns = CharLen(str[i]);
		if (i+ns > str.length()) {
			break;
		}
		if (!CheckDelimiter((char*)str.c_str(), i, 
				(char*)Delimiters.c_str())) {
			break;
		}
	}

	// appended terms
	for (; i < str.length(); i += ns) {
		ns = CharLen(str[i]);
		if (i+ns > str.length()) {
			break;
		}
		if (CheckDelimiter((char*)str.c_str(), i, 
					(char*)Delimiters.c_str())) {
			if (tmpstr != "") {
				arg = Append(arg, MkList(mka((char*)tmpstr.c_str())));
				tmpstr = "";
			}
		} else {
			for (j = 0; j < ns; j++) {
				tmpstr = tmpstr + str[i+j];
			}
		}
	}
	if (tmpstr != "") {
		arg = Append(arg, MkList(mka((char*)tmpstr.c_str())));
	}

	return arg;
}

Node* splitlist(Node* nd, std::string &Delimiters)
{
	Node* n = Nil;
	
	if (nd == Nil) {
		return nd;
	} else if (nd->kind() == ATOM) {
		std::string str = "";
		
		((Atom*)nd)->toString(str);
		n = dosplit(str, Delimiters);

		return n;
	} else if (nd->kind() == LIST) {
		n = Append(splitlist(nd->Car(), Delimiters), 
				splitlist(nd->Cdr(), Delimiters));
		return n;

	} else {
		return nd;
	}
		
}

int Split(Context* cx, Node* goalscar, List* module)
{
	std::string Delimiters = " \t";

	Delimiters = Delimiters + CharSpace();

	Node* g = goalscar->Cdr()->Val();
	int ll = ListLength(g);
	if ((ll != 2) && (ll != 3)) {
		syserr("usage : <split VAR STRINGS> or <split VAR STRINGS DELIMITERS>\n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("split: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <split VAR STRINGS> or <split VAR STRINGS DELIMITERS>\n");
		return 0;
	}

	Node* nstr = g->Cdr()->Car()->Val();

	if ((rn = FuncArg(cx, nstr, goalscar, module)) <= 0) {
		syserr("split: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (g->Cdr()->Cdr() != Nil) {
		Node* ndelim = g->Cdr()->Cdr()->Car()->Val();
		if (ndelim->kind() != ATOM) {
			syserr("usage : <split VAR STRINGS> or <split VAR STRINGS DELIMITERS>\n");
			return 0;
		}
		((Atom*)ndelim)->toString(Delimiters);
	}

	Node* arg = splitlist(nstr, Delimiters);
	
	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(arg);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
				
}

Node* dosplitstr(std::string &str, std::string &Delimiters, int& contflg)
{
	std::string tmpstr = "";
	int i, j, ns=1;
	Node* arg = Nil;
	std::string qt = "";

	if (contflg == 1) {
		qt = "\"";
	} else if (contflg == 2) {
		qt = "'";
	}

	i = 0;
	if (contflg > 0) {
		int ii = str.find(qt, 0);
		if (ii == std::string::npos) {
			return MkList(mka((char*)str.c_str()));
		} else {
			tmpstr = tmpstr + str.substr(i, ii-i+1);
			i = ii + 1;
			contflg = 0;
		}
	}
		
	// skip space
	for ( ; i < str.length(); i += ns) {
		ns = CharLen(str[i]);
		if (i+ns > str.length()) {
			break;
		}
		if (!CheckDelimiter((char*)str.c_str(), i, 
				(char*)Delimiters.c_str())) {
			break;
		}
	}

	// appended terms
	for (; i < str.length(); i += ns) {
		ns = CharLen(str[i]);
		if (i+ns > str.length()) {
			break;
		}

		if (str[i] == '"') {
			int ii = str.find("\"", i+1);
			if (ii == std::string::npos) {
				tmpstr = tmpstr + str.substr(i, str.length()-i);
				contflg = 1;
				break;
			} else {
				tmpstr = tmpstr + str.substr(i, ii-i+1);
				i = ii;
				continue;
			}
		} else if (str[i] == '\'') {
			int ii = str.find("'", i+1);
			if (ii == std::string::npos) {
				tmpstr = tmpstr + str.substr(i, str.length()-i);
				contflg = 2;
				break;
			} else {
				tmpstr = tmpstr + str.substr(i, ii-i+1);
				i = ii;
				continue;
			}
			
		} else if (CheckDelimiter((char*)str.c_str(), i, 
					(char*)Delimiters.c_str())) {
			if (tmpstr != "") {
				arg = Append(arg, MkList(mka((char*)tmpstr.c_str())));
				tmpstr = "";
			}
		} else {
			for (j = 0; j < ns; j++) {
				tmpstr = tmpstr + str[i+j];
			}
		}
	}
	if (tmpstr != "") {
		arg = Append(arg, MkList(mka((char*)tmpstr.c_str())));
	}

	return arg;
}

Node* splitstrlist(Node* nd, std::string &Delimiters, int& contflg)
{
	Node* n = Nil;
	
	if (nd == Nil) {
		return nd;
	} else if (nd->kind() == ATOM) {
		std::string str = "";
		
		((Atom*)nd)->toString(str);
		n = dosplitstr(str, Delimiters, contflg);

		return n;
	} else if (nd->kind() == LIST) {
		Node* n1 = splitstrlist(nd->Car(), Delimiters, contflg);
		Node* n2 = splitstrlist(nd->Cdr(), Delimiters, contflg);
		n = Append(n1, n2);
				
		return n;

	} else {
		return nd;
	}
		
}

int SplitStr(Context* cx, Node* goalscar, List* module)
{
	std::string Delimiters = " \t";

	Delimiters = Delimiters + CharSpace();

	Node* g = goalscar->Cdr()->Val();
	int ll = ListLength(g);
	if ((ll != 2) && (ll != 3)) {
		syserr("usage : <splitstr VAR STRINGS> or <splitstr VAR STRINGS DELIMITERS>\n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("splitstr: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <splitstr VAR STRINGS> or <splitstr VAR STRINGS DELIMITERS>\n");
		return 0;
	}

	Node* nstr = g->Cdr()->Car()->Val();

	if ((rn = FuncArg(cx, nstr, goalscar, module)) <= 0) {
		syserr("splitstr: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (g->Cdr()->Cdr() != Nil) {
		Node* ndelim = g->Cdr()->Cdr()->Car()->Val();
		if (ndelim->kind() != ATOM) {
			syserr("usage : <splitstr VAR STRINGS> or <splitstr VAR STRINGS DELIMITERS>\n");
			return 0;
		}
		((Atom*)ndelim)->toString(Delimiters);
	}

	int contflg = 0;
	Node* arg = splitstrlist(nstr, Delimiters, contflg);
	
	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(arg);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
				
}

Node* dosplitline(std::string &str)
{
	// skip space
	std::string tmpstr = "";
	int i, j, ns;
	Node* arg = Nil;

	// appended terms
	for (i= 0; i < str.length(); i += ns) {
		ns = CharLen(str[i]);
		if (i+ns > str.length()) {
			break;
		}
		if ((str[i] == '\n') || (str[i] == '\r')) {
			if ((str.length()-1 < i) && 
				((str[i+1] == '\n') || (str[i+1] == '\r'))) {
					i++;
			}
			if (tmpstr != "") {
				arg = Append(arg, MkList(mka((char*)tmpstr.c_str())));
				tmpstr = "";
			}
		} else {
			for (j = 0; j < ns; j++) {
				tmpstr = tmpstr + str[i+j];
			}
		}
	}
	if (tmpstr != "") {
		arg = Append(arg, MkList(mka((char*)tmpstr.c_str())));
	}

	return arg;
}

Node* splitlinelist(Node* nd)
{
	Node* n = Nil;
	
	if (nd == Nil) {
		return nd;
	} else if (nd->kind() == ATOM) {
		std::string str = "";
		
		((Atom*)nd)->toString(str);
		n = dosplitline(str);
		
		return n;
	} else if (nd->kind() == LIST) {
		n = Append(splitlinelist(nd->Car()), 
				splitlinelist(nd->Cdr()));
		return n;

	} else {
		return nd;
	}
		
}

int SplitLine(Context* cx, Node* goalscar, List* module)
{
	std::string Delimiters = " \t";

	Delimiters = Delimiters + CharSpace();

	Node* g = goalscar->Cdr()->Val();
	int ll = ListLength(g);
	if ((ll != 2) && (ll != 3)) {
		syserr("usage : <splitline VAR STRINGS>\n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("split: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <splitline VAR STRINGS>\n");
		return 0;
	}

	Node* nstr = g->Cdr()->Car()->Val();

	if ((rn = FuncArg(cx, nstr, goalscar, module)) <= 0) {
		syserr("split: failed in the evaluation of the argument. \n");
		return 0;
	}

	Node* arg = splitlinelist(nstr);
	
	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(arg);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
				
}

int Toupper(Context* cx, Node* goalscar, List* module)
{
	char* output;
	
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <toupper VAR STRINGS> \n",
		"toupper: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <toupper VAR STRINGS> \n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <toupper VAR STRINGS> \n");
		return 0;
	}

	std::string str;
	((Atom*)nstr)->toString(str);

	output = (char*)malloc(str.length()+1);

	CodeToupper((char*)str.c_str(), output);

	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(output));

	free(output);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}


int Tolower(Context* cx, Node* goalscar, List* module)
{
	char* output;
	
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <tolower VAR STRINGS> \n",
		"tolower: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <tolower VAR STRINGS> \n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <tolower VAR STRINGS> \n");
		return 0;
	}
	std::string str;
	((Atom*)nstr)->toString(str);

	output = (char*)malloc(str.length()+1);

	CodeTolower((char*)str.c_str(), output);

	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(output));

	free(output);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
				
}

int Length(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <length VAR STRINGS>\n",
		"length: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <length VAR STRINGS>\n");
		return 0;
	}

	long long n;
	if (nstr->kind() == LIST) {
		n = ListLength(nstr);
	} else if (nstr == Nil) {
		n = 0;
	} else {
		n = 1;
	}

	Node* env = Nil->Cons(Nil);
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(n));

	PushStack(cx, Nil, Nil, env);
	
	return 1;
				
}


int Random(Context* cx, Node* goalscar, List* module)
{
	long long five31=5^31;

	Node* v = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <random VAR>\n", 
		"random: failed in the evaluation of the argument. \n",
		v)) {
			return 0;
	}

	if (ListLength(goalscar->Cdr()) != 1) {
		syserr("usage : <random VAR>\n");
		return 0;
	}

	if (v->kind() == UNDEF) {
		long long rd;
		Node* env = Nil->Cons(Nil);
#ifndef __MINGW32__
		rd = (long long)random();
		rd = (rd * five31 + (long long)random()) & 0x7fffffffffffffffLL;
#else
		rd = (long long)rand();
		rd = (rd * five31 + (long long)rand()) & 0x7fffffffffffffffLL;
#endif /* __MINGW32__ */

		SetEnv(env, v);
		((Undef*)v)->Set(mka(rd));
		PushStack(cx, Nil, Nil, env);
		
		return 1;
	} else {
		syserr("usage : <random VAR>\n");
		return 0;
	}
			
	syserr("usage : <random VAR>\n");
	return 0;
}


int Char(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <char VAR STRINGS>\n",
		"char: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <char VAR STRING>\n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <char VAR STRING>\n");
		return 0;
	}

	std::string s;
	((Atom*)nstr)->toString(s);
	Node*	n=Nil;

	int i;
	for (i = 0; i < s.length(); ) {
		std::string sc = "";
		int l = CharLen(s[i]);
		int j;
		for (j = 0; j < l; j++) {
			sc = sc + s[i];
		}
		n = Append(n, MkList(mka((const char*)sc.c_str())));
		i = i + l;
	}

	
	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(n);
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

Node* concatlist(Node* nd)
{
	std::string s="", s1="", s2="";
	Node *n1=Nil, *n2=Nil;
	
	if (nd == Nil) {
		return mka("");
	} else if (nd->kind() == ATOM) {
		return nd;
	} else if (nd->kind() == LIST) {
		n1 = concatlist(nd->Car());
		((Atom*)n1)->toString(s1);
		n2 = concatlist(nd->Cdr());
		((Atom*)n2)->toString(s2);

		s = s1 + s2;
		return mka(s);
	} else {
		return mka("");
	}
}

int Concat(Context* cx, Node* goalscar, List* module)
{
	Node* env;
	
	Node* nvar = Nil;
	Node* nlist = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <concat VAR STRING-LIST>\n",
		"concat: failed in the evaluation of the argument. \n",
		nvar, nlist)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <concat VAR STRING-LIST>\n");
		return 0;
	}

	if (nlist->kind() == ATOM) {
		env = Nil->Cons(Nil);

		SetEnv(env, nvar);
		((Undef*)nvar)->Set(nlist);
		PushStack(cx, Nil, Nil, env);
		
		return 1;
	}
		
	Node*	n = concatlist(nlist);

	env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(n);
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

Node* concatcodelist(Node* nd)
{
	std::string s="", s1="", s2="";
	Node *n1=Nil, *n2=Nil;
	long long i1=0;
	int i;
	
	if (nd == Nil) {
		return mka("");
	} else if (nd->kind() == ATOM) {
		if (!((Atom*)nd)->toInt(i1)) {
			return nd;
		}

		char *code = (char*)&i1;

#ifdef __BIG_ENDIAN__
		for (i = 0; i < 8; i++) {
#else /* __BIG_ENDIAN__ */
		for (i = 7; i >= 0; i--) {
#endif /* __BIG_ENDIAN__ */
			if (code[i] != 0) {
				s = s + code[i];
			}
		}
		return mka(s);
	} else if (nd->kind() == LIST) {
		n1 = concatcodelist(nd->Car());
		((Atom*)n1)->toString(s1);
		n2 = concatcodelist(nd->Cdr());
		((Atom*)n2)->toString(s2);

		s = s1 + s2;
		return mka(s);
	} else {
		return mka("");
	}
}

int ConcatCode(Context* cx, Node* goalscar, List* module)
{
	Node* env;
	
	Node* nvar = Nil;
	Node* nlist = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <concatcode VAR STRING-LIST>\n",
		"concatcode: failed in the evaluation of the argument. \n",
		nvar, nlist)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <concatcode VAR CODE-LIST>\n");
		return 0;
	}

	Node*	n = concatcodelist(nlist);

	env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(n);
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

int LeftStr(Context* cx, Node* goalscar, List* module)
{
	Node* env;
	
	Node* nvar = Nil;
	Node* nstr = Nil;
	Node* nn   = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <leftstr VAR STRING NUM>\n",
		"leftstr: failed in the evaluation of the argument. \n",
		nvar, nstr, nn)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <leftstr VAR STRING NUM>\n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <leftstr VAR STRING NUM>\n");
		return 0;
	}

	if (nn->kind() != ATOM) {
		syserr("usage : <leftstr VAR STRING NUM>\n");
		return 0;
	}

	std::string s;
	((Atom*)nstr)->toString(s);
	
	long long n;
	if (!((Atom*)nn)->toInt(n)) {
		syserr("usage : <leftstr VAR STRING NUM>\n");
		return 0;
	}

	if (n < 0) {
		n = 0;
	}
	if (n > s.length()) {
		n = s.length();
	}

	int i, j;
	for (i=j=0; i < s.length(); ) {
		if (j >= n) {
			break;
		}
		int l = CharLen(s[i]);
		i = i + l;
		j++;
		if (i > s.length()) {
			i = s.length();
			break;
		}
	}
		
	s = s.substr(0, i);
	
	env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka((char*)s.c_str()));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

int RightStr(Context* cx, Node* goalscar, List* module)
{
	Node* env;
	
	Node* nvar = Nil;
	Node* nstr = Nil;
	Node* nn   = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <rightstr VAR STRING NUM>\n",
		"rightstr: failed in the evaluation of the argument. \n",
		nvar, nstr, nn)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <rightstr VAR STRING NUM>\n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <rightstr VAR STRING NUM>\n");
		return 0;
	}
	
	if (nn->kind() != ATOM) {
		syserr("usage : <rightstr VAR STRING NUM>\n");
		return 0;
	}

	std::string s;
	((Atom*)nstr)->toString(s);

	long long n;
	if (!((Atom*)nn)->toInt(n)) {
		syserr("usage : <rightstr VAR STRING NUM>\n");
		return 0;
	}

	if (n < 0) {
		n = 0;
	}

	int len = CodeLen((char*)s.c_str()) - n;
	if (len < 0) {
		len = 0;
	}
	int i, j;
	for (i=j=0; i < s.length(); ) {
		if (j >= len) {
			break;
		}
		int l = CharLen(s[i]);
		i = i + l;
		j++;
		if (i > s.length()) {
			i = s.length();
			break;
		}
	}

	s = s.substr(i, s.length()-i);
	
	env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka((char*)s.c_str()));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

int SubStr(Context* cx, Node* goalscar, List* module)
{
	Node* env;
	
	Node* nvar = Nil;
	Node* nstr = Nil;
	Node* nn1  = Nil;
	Node* nn2  = Nil;
	if (!Parm4(cx, goalscar, module, "usage : <substr VAR STRING NUM LEN>\n",
		"substr: failed in the evaluation of the argument. \n",
		nvar, nstr, nn1, nn2)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <substr VAR STRING NUM LEN>\n");
		return 0;
	}


	if (nstr->kind() != ATOM) {
		syserr("usage : <substr VAR STRING NUM LEN>\n");
		return 0;
	}
	

	if (nn1->kind() != ATOM) {
		syserr("usage : <substr VAR STRING NUM LEN>\n");
		return 0;
	}


	if (nn2->kind() != ATOM) {
		syserr("usage : <substr VAR STRING NUM LEN>\n");
		return 0;
	}

	std::string s;
	((Atom*)nstr)->toString(s);

	long long n1;
	if (!((Atom*)nn1)->toInt(n1)) {
		syserr("usage : <substr VAR STRING NUM LEN>\n");
		return 0;
	}
	if (n1 < 0) {
		n1 = 0;
	}

	long long n2;
	if (!((Atom*)nn2)->toInt(n2)) {
		syserr("usage : <substr VAR STRING NUM LEN>\n");
		return 0;
	}
	if (n2 < 0) {
		n2 = 0;
	}

	int len = CodeLen((char*)s.c_str());	
	if (n1 > len) {
		n1 = len;
	}
	if (n1+n2 > len) {
		n2 = len-n1;
	}

	int np1=0, np2=0;
	int j;
	for (np1=j=0; np1 < s.length(); ) {
		if (j >= n1) {
			break;
		}
		int l = CharLen(s[np1]);
		np1 = np1 + l;
		j++;
		if (np1 > s.length()) {
			np1 = s.length();
			break;
		}
	}

	for (np2=np1,j=0; np2 < s.length(); ) {
		if (j >= n2) {
			break;
		}
		int l = CharLen(s[np2]);
		np2 = np2 + l;
		j++;
		if (np2 > s.length()) {
			np2 = s.length();
			break;
		}
	}
	np2 = np2-np1;

	s = s.substr(np1, np2);
	
	env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka((char*)s.c_str()));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

int InsertStr(Context* cx, Node* goalscar, List* module)
{
	Node* env;
	
	Node* nvar  = Nil;
	Node* nstr1 = Nil;
	Node* nn    = Nil;
	Node* nstr2 = Nil;
	if (!Parm4(cx, goalscar, module, "usage : <insertstr VAR STRING NUM INS-STR>\n",
		"insertstr: failed in the evaluation of the argument. \n",
		nvar, nstr1, nn, nstr2)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <insertstr VAR STRING NUM INS-STR>\n");
		return 0;
	}

	if (nstr1->kind() != ATOM) {
		syserr("usage : <insertstr VAR STRING NUM INS-STR>\n");
		return 0;
	}

	
	if (nn->kind() != ATOM) {
		syserr("usage : <insertstr VAR STRING NUM INS-STR>\n");
		return 0;
	}

	if (nstr2->kind() != ATOM) {
		syserr("usage : <insertstr VAR STRING NUM INS-STR>\n");
		return 0;
	}

	std::string s1;
	((Atom*)nstr1)->toString(s1);

	long long n;
	if (!((Atom*)nn)->toInt(n)) {
		syserr("usage : <insertstr VAR STRING NUM INS-STR>\n");
		return 0;
	}

	if (n < 0) {
		n = 0;
	}
	
	int len = CodeLen((char*)s1.c_str());
	if (n > len) {
		n = len;
	}
	
	std::string s2;
	((Atom*)nstr2)->toString(s2);

	int i, j;
	for (i=j=0; i < s1.length(); ) {
		if (j >= n) {
			break;
		}
		int l = CharLen(s1[i]);
		i = i + l;
		j++;
	}

	s1 = s1.insert(i, s2);
	
	env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka((char*)s1.c_str()));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

Node* replacestrlist(Node* nstr, std::string &str1, std::string &str2)
{

	if (nstr == Nil) {
		return nstr;
	} else if (nstr->kind() == ATOM) {
		Node* n = Nil;
		int idx = 0;
		std::string str="";

		((Atom*)nstr)->toString(str);
	
		for (;;) {
			int loc = str.find(str1, idx);
			if (loc == std::string::npos) {
				break;
			}
			str.replace(loc, str1.length(), str2);
			idx = loc + str2.length();
		}

		n = mka(str);

		return n;
	} else if (nstr->kind() != LIST) {
		return nstr;
	}

	Node* ncar = nstr->Car();
	Node* ncdr = nstr->Cdr();

	Node* n1 = replacestrlist(ncar, str1, str2);
	Node* n2 = replacestrlist(ncdr, str1, str2);

	return Cons(n1, n2);
}

int ReplaceStr(Context* cx, Node* goalscar, List* module)
{
	Node* nvar  = Nil;
	Node* nstr  = Nil;
	Node* nstr1 = Nil;
	Node* nstr2 = Nil;
	if (!Parm4(cx, goalscar, module, "usage : <replacestr VAR STR STR1 STR2>\n",
		"replacestr: failed in the evaluation of the argument. \n",
		nvar, nstr, nstr1, nstr2)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <replacestr VAR STR STR1 STR2>\n");
		return 0;
	}

	if (nstr1->kind() != ATOM) {
		syserr("usage : <replacestr VAR STR STR1 STR2>\n");
		return 0;
	}

	if (nstr2->kind() != ATOM) {
		syserr("usage : <replacestr VAR STR STR1 STR2>\n");
		return 0;
	}

	std::string str1="", str2="";
	((Atom*)nstr1)->toString(str1);
	((Atom*)nstr2)->toString(str2);
	
	Node* n = replacestrlist(nstr, str1, str2);
	
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);

	return 1;
}


int SetCode(Context* cx, Node* goalscar, List* module)
{
	extern std::string code;
	
	Node* ncode = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <code VAR> or <code CODE>\n",
		"code: failed in the evaluation of the argument. \n",
		ncode)) {
			return 0;
	}

	std::string scode;

	if (ncode->kind() == UNDEF) {
		Node* env = Nil->Cons(Nil);

		SetEnv(env, ncode);
		((Undef*)ncode)->Set(mka((char*)code.c_str()));
		PushStack(cx, Nil, Nil, env);

		return 1;
	}
	if (ncode->kind() != ATOM) {
		syserr("usage : <code VAR> or <code CODE>\n");
		return 0;
	}
	
	((Atom*)ncode)->toString(scode);
	if ((scode == "EUCJP") || (scode == "EUC-JP")|| (scode == "EUC")) {
		code = "EUC";
	} else if ((scode == "SJIS") || (scode == "SHIFT-JIS")) {
		code = "SJIS";
	} else if ((scode == "UTF8") || (scode == "UTF-8")) {
		code = "UTF8";
	}
	return 1;	
}


int CodeCharPrd(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <char VAR STRINGS>\n",
		"char: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}


	if (nvar->kind() != UNDEF) {
		syserr("usage : <char VAR STRING>\n");
		return 0;
	}
	
	if (nstr->kind() != ATOM) {
		syserr("usage : <char VAR STRING>\n");
		return 0;
	}

	std::string s;
	((Atom*)nstr)->toString(s);
	Node*	n=Nil;

	n = CodeChar((char*)s.c_str());
	
	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(n);
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


int UTF8CharPrd(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <utf8char VAR STRING>\n",
		"utf8char: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <utf8char VAR STRING>\n");
		return 0;
	}
	
	if (nstr->kind() != ATOM) {
		syserr("usage : <utf8char VAR STRING>\n");
		return 0;
	}

	std::string s;
	((Atom*)nstr)->toString(s);
	Node*	n=Nil;

	n = UTF8Char((char*)s.c_str());
	
	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(n);
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

int EUCCharPrd(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <eucchar VAR STRING>\n",
		"eucchar: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <eucchar VAR STRING>\n");
		return 0;
	}
	
	if (nstr->kind() != ATOM) {
		syserr("usage : <eucchar VAR STRING>\n");
		return 0;
	}

	std::string s;
	((Atom*)nstr)->toString(s);
	Node*	n=Nil;

	n = EUCChar((char*)s.c_str());
	
	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(n);
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

int SJISCharPrd(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <sjischar VAR STRING>\n",
		"sjischar: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <sjischar VAR STRING>\n");
		return 0;
	}
	
	if (nstr->kind() != ATOM) {
		syserr("usage : <sjischar VAR STRING>\n");
		return 0;
	}

	std::string s;
	((Atom*)nstr)->toString(s);
	Node*	n=Nil;

	n = SJISChar((char*)s.c_str());
	
	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(n);
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

int And(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* n1   = Nil;
	Node* n2   = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <bitand VAR NUM1 NUM2>\n",
		"bitand: failed in the evaluation of the argument. \n",
		nvar, n1, n2)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <bitand VAR NUM1 NUM2>\n");
		return 0;
	}

	if (n1->kind() != ATOM) {
		syserr("usage : <bitand VAR NUM1 NUM2>\n");
		return 0;
	}
	
	if (n2->kind() != ATOM) {
		syserr("usage : <bitand VAR NUM1 NUM2>\n");
		return 0;
	}
	
	long long nn1, nn2;
	if (!((Atom*)n1)->toInt(nn1)) {
		syserr("usage : <bitand VAR NUM1 NUM2>\n");
		return 0;
	}
	
	if (!((Atom*)n2)->toInt(nn2)) {
		syserr("usage : <bitand VAR NUM1 NUM2>\n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);

	long long nn3 = nn1 & nn2;
	
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(nn3));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int Or(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* n1   = Nil;
	Node* n2   = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <bitor VAR NUM1 NUM2>\n",
		"bitor: failed in the evaluation of the argument. \n",
		nvar, n1, n2)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <bitor VAR NUM1 NUM2>\n");
		return 0;
	}

	if (n1->kind() != ATOM) {
		syserr("usage : <bitor VAR NUM1 NUM2>\n");
		return 0;
	}
	
	if (n2->kind() != ATOM) {
		syserr("usage : <bitor VAR NUM1 NUM2>\n");
		return 0;
	}
	
	long long nn1, nn2;
	if (!((Atom*)n1)->toInt(nn1)) {
		syserr("usage : <bitor VAR NUM1 NUM2>\n");
		return 0;
	}
	
	if (!((Atom*)n2)->toInt(nn2)) {
		syserr("usage : <bitor VAR NUM1 NUM2>\n");
		return 0;
	}
	
	long long nn3 = nn1 | nn2;
	
	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(nn3));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int Xor(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* n1   = Nil;
	Node* n2   = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <bitxor VAR NUM1 NUM2>\n",
		"bitxor: failed in the evaluation of the argument. \n",
		nvar, n1, n2)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <bitxor VAR NUM1 NUM2>\n");
		return 0;
	}

	if (n1->kind() != ATOM) {
		syserr("usage : <bitxor VAR NUM1 NUM2>\n");
		return 0;
	}
	
	if (n2->kind() != ATOM) {
		syserr("usage : <bitxor VAR NUM1 NUM2>\n");
		return 0;
	}
	
	long long nn1, nn2;
	if (!((Atom*)n1)->toInt(nn1)) {
		syserr("usage : <bitxor VAR NUM1 NUM2>\n");
		return 0;
	}
	
	if (!((Atom*)n2)->toInt(nn2)) {
		syserr("usage : <bitxor VAR NUM1 NUM2>\n");
		return 0;
	}
	
	long long nn3 = nn1 ^ nn2;

	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(nn3));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int BitNot(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* n1 = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <bitnot VAR NUM>\n",
		"bitnot: failed in the evaluation of the argument. \n",
		nvar, n1)) {
			return 0;
	}


	if (nvar->kind() != UNDEF) {
		syserr("usage : <bitnot VAR NUM>\n");
		return 0;
	}

	if (n1->kind() != ATOM) {
		syserr("usage : <bitnot VAR NUM>\n");
		return 0;
	}
	
	long long nn1;

	if (!((Atom*)n1)->toInt(nn1)) {
		syserr("usage : <bitnot VAR NUM>\n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(~nn1));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

int ShiftL(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* n1   = Nil;
	Node* nsft   = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <shiftl VAR NUM SHIFT>\n",
		"shiftl: failed in the evaluation of the argument. \n",
		nvar, n1, nsft)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <shiftl VAR NUM SHIFT>\n");
		return 0;
	}

	if (n1->kind() != ATOM) {
		syserr("usage : <shiftl VAR NUM SHIFT>\n");
		return 0;
	}
	
	if (nsft->kind() != ATOM) {
		syserr("usage : <shiftl VAR NUM SHIFT>\n");
		return 0;
	}
	
	long long nn1, nnsft;
	if (!((Atom*)n1)->toInt(nn1)) {
		syserr("usage : <shiftl VAR NUM SHIFT>\n");
		return 0;
	}
	
	if (!((Atom*)nsft)->toInt(nnsft)) {
		syserr("usage : <shiftl VAR NUM SHIFT>\n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(nn1<<nnsft));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

int ShiftR(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* n1   = Nil;
	Node* nsft   = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <shiftr VAR NUM SHIFT>\n",
		"shiftr: failed in the evaluation of the argument. \n",
		nvar, n1, nsft)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <shiftr VAR NUM SHIFT>\n");
		return 0;
	}

	if (n1->kind() != ATOM) {
		syserr("usage : <shiftr VAR NUM SHIFT>\n");
		return 0;
	}
	
	if (nsft->kind() != ATOM) {
		syserr("usage : <shiftr VAR NUM SHIFT>\n");
		return 0;
	}
	
	long long nn1, nnsft;
	if (!((Atom*)n1)->toInt(nn1)) {
		syserr("usage : <shiftr VAR NUM SHIFT>\n");
		return 0;
	}
	
	if (!((Atom*)nsft)->toInt(nnsft)) {
		syserr("usage : <shiftr VAR NUM SHIFT>\n");
		return 0;
	}
	
	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(nn1>>nnsft));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}


#ifdef HAVE_REGEX_H

int DoRegex(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	
	if (ListLength(g) != 5) {
		syserr("usage : <regex pattern strings forestr matchstr reststr> \n");
		return 0;
	}

	Node* nptn = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nptn, goalscar, module)) <= 0) {
		syserr("regex: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nptn->kind() != ATOM) {
		syserr("usage : <regex pattern strings forestr matchstr reststr> \n");
		return 0;
	}
	Node* nlist = g->Cdr()->Car()->Val();

	if ((rn = FuncArg(cx, nlist, goalscar, module)) <= 0) {
		syserr("regex: failed in the evaluation of the argument. \n");
		return 0;
	}

	if ((nlist->kind() != ATOM) && (nlist->kind() != LIST))  {
		syserr("usage : <regex pattern strings forestr matchstr reststr> \n");
		return 0;
	}
	Node* nfore = g->Cdr()->Cdr()->Car()->Val();

	if ((rn = FuncArg(cx, nfore, goalscar, module)) <= 0) {
		syserr("regex: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nfore->kind() != UNDEF) {
		syserr("usage : <regex pattern strings forestr matchstr reststr> \n");
		return 0;
	}
	Node* nmatch = g->Cdr()->Cdr()->Cdr()->Car()->Val();

	if ((rn = FuncArg(cx, nmatch, goalscar, module)) <= 0) {
		syserr("regex: failed in the evaluation of the argument. \n");
		return 0;
	}
	
	if (nmatch->kind() != UNDEF) {
		syserr("usage : <regex pattern strings forestr matchstr reststr> \n");
		return 0;
	}

	Node* nrest = g->Cdr()->Cdr()->Cdr()->Cdr()->Car()->Val();

	if ((rn = FuncArg(cx, nrest, goalscar, module)) <= 0) {
		syserr("regex: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nrest->kind() != UNDEF) {
		syserr("usage : <regex pattern strings forestr matchstr reststr> \n");
		return 0;
	}

	Node* nstr = concatlist(nlist);
	
	std::string	str, ptn,  fore, match, rest;

	((Atom*)nstr)->toString(str);
	((Atom*)nptn)->toString(ptn);

	Node* env = Nil->Cons(Nil);

	if (!Regex(ptn, str, fore, match, rest)) {
		return -1;
	}
	 
	SetEnv(env, nfore);
	((Undef*)nfore)->Set(mka((char*)fore.c_str()));

	SetEnv(env, nmatch);
	((Undef*)nmatch)->Set(mka((char*)match.c_str()));

	SetEnv(env, nrest);
	((Undef*)nrest)->Set(mka((char*)rest.c_str()));

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int DoSub(Context* cx, Node* goalscar, List* module)
{
	Node* nptn     = Nil;
	Node* nlist    = Nil;
	Node* nreplace = Nil;
	Node* noutput  = Nil;
	if (!Parm4(cx, goalscar, module, "usage : <sub pattern strings replacestr outputstr>\n",
		"sub: failed in the evaluation of the argument. \n",
		nptn, nlist, nreplace, noutput)) {
			return 0;
	}
	if (nptn->kind() != ATOM) {
		syserr("usage : <sub pattern strings replacestr outputstr>\n");
		return 0;
	}

	if ((nlist->kind() != ATOM) && (nlist->kind() != LIST)) {
		syserr("usage : <sub pattern strings replacestr outputstr>\n");
		return 0;
	}
	
	if (nreplace->kind() != ATOM) {
		syserr("usage : <sub pattern strings replacestr outputstr>\n");
		return 0;
	}
	
	if (noutput->kind() != UNDEF) {
		syserr("usage : <sub pattern strings replacestr outputstr>\n");
		return 0;
	}

	Node* nstr = concatlist(nlist);

	std::string	str, ptn,  replace, output;

	((Atom*)nptn)->toString(ptn);
	((Atom*)nstr)->toString(str);
	((Atom*)nreplace)->toString(replace);

	Node* env = Nil->Cons(Nil);

	if (!Sub(ptn, str, replace, output)) {
		return -1;
	}
	 
	SetEnv(env, noutput);
	((Undef*)noutput)->Set(mka((char*)output.c_str()));

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int DoGSub(Context* cx, Node* goalscar, List* module)
{
	Node* nptn     = Nil;
	Node* nlist    = Nil;
	Node* nreplace = Nil;
	Node* noutput  = Nil;
	if (!Parm4(cx, goalscar, module, "usage : <gsub pattern strings replacestr outputstr>\n",
		"gsub: failed in the evaluation of the argument. \n",
		nptn, nlist, nreplace, noutput)) {
			return 0;
	}
	if (nptn->kind() != ATOM) {
		syserr("usage : <gsub pattern strings replacestr outputstr>\n");
		return 0;
	}

	if ((nlist->kind() != ATOM) && (nlist->kind() != LIST)){
		syserr("usage : <gsub pattern strings replacestr outputstr>\n");
		return 0;
	}

	if (nreplace->kind() != ATOM) {
		syserr("usage : <gsub pattern strings replacestr outputstr>\n");
		return 0;
	}
	
	if (noutput->kind() != UNDEF) {
		syserr("usage : <gsub pattern strings replacestr outputstr>\n");
		return 0;
	}

	Node* nstr = concatlist(nlist);

	std::string	str, ptn,  replace, output;

	((Atom*)nptn)->toString(ptn);
	((Atom*)nstr)->toString(str);
	((Atom*)nreplace)->toString(replace);

	Node* env = Nil->Cons(Nil);

	if (!GSub(ptn, str, replace, output)) {
		return -1;
	}
	 
	SetEnv(env, noutput);
	((Undef*)noutput)->Set(mka((char*)output.c_str()));

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int GrepStrList(Node* &rlist, Node* nlist, std::string &ptn)
{
	int r = 0, r1 = 0, r2 = 0;
	std::string str1="", str2="";

	if (nlist == Nil) {
		rlist = Nil;
		return -1;
	} else if (nlist->kind() == ATOM) {
		((Atom*)nlist)->toString(str1);
		r = GrepStr(ptn, str1);
		if (r == 1) {
			rlist = Cons(nlist, Nil);
			return 1;
		} else {
			rlist = Nil;
			return -1;
		}
	} else if (nlist->kind() == LIST) {
		Node* rlist1 = Nil;
		Node* rlist2 = Nil;
		r1 = GrepStrList(rlist1, nlist->Car(), ptn);
		r2 = GrepStrList(rlist2, nlist->Cdr(), ptn);
		if ((r1 == -1) && (r2 == -1)) {
			rlist = Nil;
			return -1;
		} else if (r1 == -1) {
			rlist = rlist2;
			return 1;
		} else if (r2 == -1) {
			rlist = rlist1;
			return 1;
		} else {
			rlist = Cons(rlist1, rlist2);
			return 1;
		}
	} else {
		rlist = Nil;
		return -1;
	}
}

int DoGrep(Context* cx, Node* goalscar, List* module)
{
	Node* nvar  = Nil;
	Node* nlist = Nil;
	Node* nptn  = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <grep VAR LIST pattern> \n",
		"grep: failed in the evaluation of the argument. \n",
		nvar, nlist, nptn)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <grep VAR LIST pattern> \n");
		return 0;
	}

	if ((nlist->kind() != ATOM) && (nlist->kind() != LIST)) {
		syserr("usage : <grep VAR LIST pattern> \n");
		return 0;
	}

	if (nptn->kind() != ATOM) {
		syserr("usage : <grep VAR LIST pattern> \n");
		return 0;
	}

	Node* rlist = Nil;
	std::string ptn="";
	
	((Atom*)nptn)->toString(ptn);

	if (GrepStrList(rlist, nlist, ptn) != 1) {
		rlist = Nil;
	}
	 
	Node* env = Nil->Cons(Nil);
	
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(rlist);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int Grep_iStrList(Node* &rlist, Node* nlist, std::string &ptn)
{
	int r = 0, r1 = 0, r2 = 0;
	std::string str1="", str2="";

	if (nlist == Nil) {
		rlist = Nil;
		return -1;
	} else if (nlist->kind() == ATOM) {
		((Atom*)nlist)->toString(str1);
		r = Grep_iStr(ptn, str1);
		if (r == 1) {
			rlist = Cons(nlist, Nil);
			return 1;
		} else {
			rlist = Nil;
			return -1;
		}
	} else if (nlist->kind() == LIST) {
		Node* rlist1 = Nil;
		Node* rlist2 = Nil;
		r1 = Grep_iStrList(rlist1, nlist->Car(), ptn);
		r2 = Grep_iStrList(rlist2, nlist->Cdr(), ptn);
		if ((r1 == -1) && (r2 == -1)) {
			rlist = Nil;
			return -1;
		} else if (r1 == -1) {
			rlist = rlist2;
			return 1;
		} else if (r2 == -1) {
			rlist = rlist1;
			return 1;
		} else {
			rlist = Cons(rlist1, rlist2);
			return 1;
		}
	} else {
		rlist = Nil;
		return -1;
	}
}

int DoGrep_i(Context* cx, Node* goalscar, List* module)
{
	Node* nvar  = Nil;
	Node* nlist = Nil;
	Node* nptn  = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <grepi VAR LIST pattern> \n",
		"grepi: failed in the evaluation of the argument. \n",
		nvar, nlist, nptn)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <grepi VAR LIST pattern> \n");
		return 0;
	}

	if ((nlist->kind() != ATOM) && (nlist->kind() != LIST)) {
		syserr("usage : <grepi VAR LIST pattern> \n");
		return 0;
	}

	if (nptn->kind() != ATOM) {
		syserr("usage : <grepi VAR LIST pattern> \n");
		return 0;
	}

	Node* rlist = Nil;
	std::string ptn="";
	
	((Atom*)nptn)->toString(ptn);

	if (Grep_iStrList(rlist, nlist, ptn) != 1) {
		rlist = Nil;
	}
	 
	Node* env = Nil->Cons(Nil);
	
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(rlist);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int Grep_vStrList(Node* &rlist, Node* nlist, std::string &ptn)
{
	int r = 0, r1 = 0, r2 = 0;
	std::string str1="", str2="";

	if (nlist == Nil) {
		rlist = Nil;
		return -1;
	} else if (nlist->kind() == ATOM) {
		((Atom*)nlist)->toString(str1);
		r = Grep_vStr(ptn, str1);
		if (r == 1) {
			rlist = Cons(nlist, Nil);
			return 1;
		} else {
			rlist = Nil;
			return -1;
		}
	} else if (nlist->kind() == LIST) {
		Node* rlist1 = Nil;
		Node* rlist2 = Nil;
		r1 = Grep_vStrList(rlist1, nlist->Car(), ptn);
		r2 = Grep_vStrList(rlist2, nlist->Cdr(), ptn);
		if ((r1 == -1) && (r2 == -1)) {
			rlist = Nil;
			return -1;
		} else if (r1 == -1) {
			rlist = rlist2;
			return 1;
		} else if (r2 == -1) {
			rlist = rlist1;
			return 1;
		} else {
			rlist = Cons(rlist1, rlist2);
			return 1;
		}
	} else {
		rlist = Nil;
		return -1;
	}
}

int DoGrep_v(Context* cx, Node* goalscar, List* module)
{
	Node* nvar  = Nil;
	Node* nlist = Nil;
	Node* nptn  = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <grepv VAR LIST pattern> \n",
		"grepv: failed in the evaluation of the argument. \n",
		nvar, nlist, nptn)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <grepv VAR LIST pattern> \n");
		return 0;
	}

	if ((nlist->kind() != ATOM) && (nlist->kind() != LIST)) {
		syserr("usage : <grepv VAR LIST pattern> \n");
		return 0;
	}

	if (nptn->kind() != ATOM) {
		syserr("usage : <grepv VAR LIST pattern> \n");
		return 0;
	}
	
	Node* rlist = Nil;
	std::string ptn="";
	
	((Atom*)nptn)->toString(ptn);

	if (Grep_vStrList(rlist, nlist, ptn) != 1) {
		rlist = Nil;
	}
	 
	Node* env = Nil->Cons(Nil);
	
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(rlist);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

#endif /* HAVE_REGEX_H */


int DoCountNode(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <countnode VAR>\n", 
		"countnode: failed in the evaluation of the argument. \n", 
		nvar)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <countnode VAR>\n");
		return 0;
	}

	Node* env = Nil->Cons(Nil);

	long long n = CountNode();
	
	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(n));
	PushStack(cx, Nil, Nil, env);
		
	return 1;
}

int GetTime(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <gettime VAR>\n",
		"gettime: failed in the evaluation of the argument. \n",
		nvar)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <gettime VAR>\n");
		return 0;
	}

	struct timeval tv;
	gettimeofday (&tv, NULL);
	long long val = tv.tv_sec*1000000+tv.tv_usec;
	
	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(mka(val));
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int Time(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <time VAR>\n",
		"time: failed in the evaluation of the argument. \n",
		nvar)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <time VAR>\n");
		return 0;
	}

	struct timeval tv;
	gettimeofday (&tv, NULL);
	long long val = tv.tv_sec*1000000+tv.tv_usec - progtime.start_time;
	long double fval = (long double)val / 1000000.0;
	Node* env = Nil->Cons(Nil);

#ifndef __MINGW32__
	long clk_tck = sysconf(_SC_CLK_TCK);
	struct tms tmsbuf;
	times(&tmsbuf);
	long double fuval = (long double)(tmsbuf.tms_utime - progtime.start_utime)
				/ clk_tck;
	fuval += (long double)(tmsbuf.tms_cutime - progtime.start_cutime)
				/ clk_tck;
	long double fsval = (long double)(tmsbuf.tms_stime - progtime.start_stime)
				/ clk_tck;
	fsval += (long double)(tmsbuf.tms_cstime - progtime.start_cstime)
				/ clk_tck;

	Node* l = MkList(mka(fuval), mka(fsval), mka(fval));
#else
	Node* l = MkList(mka(fval));
#endif

	SetEnv(env, nvar);
	((Undef*)nvar)->Set(l);
	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int Date(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <date VAR>\n",
		"date: failed in the evaluation of the argument. \n",
		nvar)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <date VAR>\n");
		return 0;
	}

	struct timeval tv;
	gettimeofday (&tv, NULL);
	
	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	char* t = strdup(ctime((const time_t*)&tv.tv_sec));
	t[strlen(t)-1] = 0;
	
	((Undef*)nvar)->Set(mka(t));

	free(t);

	PushStack(cx, Nil, Nil, env);
		
	return 1;

}

int Sleep(Context* cx, Node* goalscar, List* module)
{
	Node* nval = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <sleep SEC>\n",
		"sleep: failed in the evaluation of the argument. \n",
		nval)) {
			return 0;
	}

	if (nval->kind() != ATOM) {
		syserr("usage : <sleep SEC>\n");
		return 0;
	}

	long long t;
	if (!((Atom*)nval)->toInt(t)) {
		syserr("usage : <sleep SEC>\n");
		return 0;
	}
		

	CallSleep(t);
			
	return 1;

}

int USleep(Context* cx, Node* goalscar, List* module)
{
	Node* nval = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <usleep USEC>\n",
		"usleep: failed in the evaluation of the argument. \n",
		nval)) {
			return 0;
	}

	if (nval->kind() != ATOM) {
		syserr("usage : <usleep USEC>\n");
		return 0;
	}

	long long t;
	if (!((Atom*)nval)->toInt(t)) {
		syserr("usage : <usleep USEC>\n");
		return 0;
	}
		

	CalluSleep(t);
			
	return 1;

}


int DoFlush(Context* cx, Node* goalscar, List* module)
{
	if (!Parm0(cx, goalscar, module, "usage : <flush> \n")) {
		return 0;
	}

//	fflush(stdin);
	
//	fflush(cx->ioin);
	fflush(cx->ioout);

	return 1;

}

int Pause(Context* cx, Node* goalscar, List* module)
{
	if (!Parm0(cx, goalscar, module, "usage : <pause> \n")) {
		return 0;
	}

	fflush(stdin);
	
	char* buf = (char*)malloc(4096);

	char* rsc = fgets(buf, 4096-1, stdin);
	buf[4096-1] = 0;
	
	free(buf);

	return 1;

}

int BaseName(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* npath = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <basename VAR PATH>\n",
		"basename: failed in the evaluation of the argument. \n",
		nvar, npath)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <basename VAR PATH>\n");
		return 0;
	}

	if (npath->kind() != ATOM) {
		syserr("usage : <basename VAR PATH>\n");
		return 0;
	}

	std::string spath;
	
	((Atom*)npath)->toString(spath);

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	char* cpath = strdup(spath.c_str());
	((Undef*)nvar)->Set(mka(basename(cpath)));
	free(cpath);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int DirName(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* npath = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <dirname VAR PATH>\n",
		"dirname: failed in the evaluation of the argument. \n",
		nvar, npath)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <dirname VAR PATH>\n");
		return 0;
	}

	if (npath->kind() != ATOM) {
		syserr("usage : <dirname VAR PATH>\n");
		return 0;
	}

	std::string spath;
	
	((Atom*)npath)->toString(spath);

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	char* cpath = strdup(spath.c_str());
	((Undef*)nvar)->Set(mka(dirname(cpath)));
	free(cpath);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int Suffix(Context* cx, Node* goalscar, List* module)
{
	Node* nvar  = Nil;
	Node* npath = Nil;
	Node* nsuffix = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <suffix VAR PATH SUFFIX>\n",
		"suffix: failed in the evaluation of the argument. \n",
		nvar, npath, nsuffix)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <suffix VAR PATH SUFFIX>\n");
		return 0;
	}

	if (npath->kind() != ATOM) {
		syserr("usage : <suffix VAR PATH SUFFIX>\n");
		return 0;
	}

	if (nsuffix->kind() != ATOM) {
		syserr("usage : <suffix VAR PATH SUFFIX>\n");
		return 0;
	}

	std::string spath, ssuffix;
	
	((Atom*)npath)->toString(spath);
	((Atom*)nsuffix)->toString(ssuffix);

	int i, l = spath.length()-1;
	for (i = l; i >= 0; i--) {
		if (spath[i] == '.') {
			spath = spath.substr(0, i+1) + ssuffix;
			break;
		}
	}
	if (i == 0) {
		spath = spath + '.';
		spath = spath + ssuffix;
	}


	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(mka((char*)spath.c_str()));

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int ClearScreen(Context* cx, Node* goalscar, List* module)
{
	if (!Parm0(cx, goalscar, module, "usage : <clear>\n")) {
		return 0;
	}

#ifndef __MINGW32__
	printf("\x1b[2J");
#else  /* __MINGW32__ */
	clswin();
#endif /* __MINGW32__ */

	return 1;
}


#ifndef __MINGW32__
int Uname(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <uname VAR>\n",
		"uname: failed in the evaluation of the argument. \n",
		nvar)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <uname VAR>\n");
		return 0;
	}

	struct utsname u;
	uname(&u);
	
	Node* n = MkList(mka(u.sysname), mka(u.nodename),
			 mka(u.release), mka(u.version),
			 mka(u.machine));
	
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}
#endif


void sortascending_sub(Node*& nmap, Node* nlist)
{
	int	len = ListLength(nlist);
	Node*	nl[len];
	int	i, j;

	for (i = 0; i < len; i++) {
		nl[i] = nlist->Car();
		nlist = nlist->Cdr();
	}

	for (i = 0; i < len-1; i++) {
		for (j = i+1; j < len; j++) {
			if (ModuleCompare(nl[i], nl[j]) > 0) {
				Node* tmp = nl[i];
				nl[i] = nl[j];
				nl[j] = tmp;
			}
		}
	}

	nmap = Nil;
	for (i = len-1; i >= 0; i--) {
		nmap = Cons(nl[i], nmap);
	}

}

void sortdescending_sub(Node*& nmap, Node* nlist)
{
	int	len = ListLength(nlist);
	Node*	nl[len];
	int	i, j;

	for (i = 0; i < len; i++) {
		nl[i] = nlist->Car();
		nlist = nlist->Cdr();
	}

	for (i = 0; i < len-1; i++) {
		for (j = i+1; j < len; j++) {
			if (ModuleCompare(nl[i], nl[j]) < 0) {
				Node* tmp = nl[i];
				nl[i] = nl[j];
				nl[j] = tmp;
			}
		}
	}

	nmap = Nil;
	for (i = len-1; i >= 0; i--) {
		nmap = Cons(nl[i], nmap);
	}

}

int SortAscending(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nlist = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <sortascend VAR LIST>\n",
		"sortascend: failed in the evaluation of the argument. \n",
		nvar, nlist)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <sortascend VAR LIST>\n");
		return 0;
	}

	if ((nlist->kind() != LIST) && (nlist != Nil)) {
		syserr("usage : <sortascend VAR LIST>\n");
		return 0;
	}

	Node* nmap = Nil;
	sortascending_sub(nmap, nlist);

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(nmap);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}


int SortDescending(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nlist = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <sortdescend VAR LIST>\n", 
		"sortascend: failed in the evaluation of the argument. \n",
		nvar, nlist)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <sortdescend VAR LIST>\n");
		return 0;
	}

	if ((nlist->kind() != LIST) && (nlist != Nil)) {
		syserr("usage : <sortdescend VAR LIST>\n");
		return 0;
	}

	Node* nmap = Nil;
	sortdescending_sub(nmap, nlist);

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(nmap);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}


int FindList(Context* cx, Node* goalscar, List* module)
{
	Node* nvar  = Nil;
	Node* nkeyval = Nil;
	Node* nlist = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <findlist VAR KEYVAL LIST>\n",
		"findlist: failed in the evaluation of the argument. \n",
		nvar, nkeyval, nlist)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <findlist VAR KEYVAL LIST>\n");
		return 0;
	}

	Node* n;
	Node* nc = Nil;
	int r = -1;
	for (n = nlist; n->kind() != ATOM; n = n->Cdr()) {
		nc = n->Car()->Val();
		if (nc->kind() != LIST) {
			continue;
		}
		if (nc->Car()->Eq(nkeyval)) {
			r = 1;
			break;
		}
	}

	if (r == -1) {
		return -1;
	}
		
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(nc);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

int isObj(Context* cx, Node* goalscar, List* module)
{
	Node* n = goalscar->Cdr()->Val();

	if (ListLength(n) != 1) {
		return -1;
	}

	Node* nobj = n->Car();
	
	int rn;

	if ((rn = FuncArg(cx, nobj, goalscar, module)) <= 0) {
		syserr("isObj: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nobj->kind() != ATOM) {
		return -1;
	}

	Node* np = Nil;
	for (np = module->Car(); np->kind() != ATOM; np = np->Cdr()) {
		Node* nl = np->Car();

		if ((nl->Car()->kind() != PRED) || 
				(nl->Car()->Car()->kind() != PRED)) {
			continue;
		}
		if (nl->Car()->Car()->Car()->Eq(nobj)) {
			return 1;
		}
	}

	return -1;
}

Node* dotrim(std::string &str)
{
	std::string rstr = "", rstr2 = "";

	int i, j;
	for (i = 0; i < str.length(); i++) {
		if (isspace(str[i])) {
			continue;
		}

		char* spc = CharSpace();
		int  nspc = strlen(spc);
		if (spc[0] != str[i]) {
			break;
		} else {
			int k;
			if (i+nspc >= str.length()) {
				break;
			}
			if (strncmp(spc, str.c_str()+i, nspc) != 0) {
				break;
			}
			i = i + nspc - 1;
		}
	}	

	for (j = str.length()-1; j >= 0; j--) {
		if (isspace(str[j])) {
			continue;
		}

		char* spc = CharSpace();
		int  nspc = strlen(spc);
		if (j+1-nspc < 0) {
			break;
		} else {
			if (strncmp(spc, str.c_str()+j+1-nspc, nspc) != 0) {
				break;
			}
			j = j + 1 - nspc;
		}
	}

	rstr = str.substr(i, j-i+1);		

	int spcflg = 0;
		
	for (i = 0; i < rstr.length(); i++) {
		if (!isspace(rstr[i])) {
			char* spc = CharSpace();
			int  nspc = strlen(spc);
			if (spc[0] != rstr[i]) {
				rstr2 += rstr[i];
				spcflg = 0;
				continue;
			} else {
				int k;
				if (i+nspc >= rstr.length()) {
					rstr2 += rstr[i];
					spcflg = 0;
					continue;
				}
				if (strncmp(spc, rstr.c_str()+i, nspc) == 0) {
					i = i + nspc - 1;
					if (spcflg == 0) {
						rstr2 += ' ';
						spcflg = 1;
					}
				} else {
					rstr2 += rstr[i];
					spcflg = 0;
				}
			}
		} else {
			if (spcflg == 0) {
				rstr2 += ' ';
				spcflg = 1;
			}
		}
	}	

	if (rstr2 == "") {
		return Nil;
	} else {
		Node* n = mka(rstr2);
		return n;
	}
}

Node* trimlist(Node* nd)
{
	Node* n = Nil;
	std::string str1 = "";
	std::string str2 = "";
	
	if (nd == Nil) {
		return nd;
	} else if (nd->kind() == ATOM) {
		std::string str = "";
		
		((Atom*)nd)->toString(str);
		n = dotrim(str);
		return n;
	} else if (nd->kind() == LIST) {
		Node* n1 = trimlist(nd->Car());
		Node* n2 = trimlist(nd->Cdr());

		if (n1 == Nil) {
			return n2;
		} else {
			n = Cons(n1, n2);
			return n;
		}
	} else {
		return nd;
	}
}


int Trim(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <trim VAR STRINGS>\n",
		"trim: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <trim VAR STRINGS>\n");
		return 0;
	}

	Node* n = trimlist(nstr);
	
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

Node* dolefttrim(std::string &str)
{
	std::string rstr = "";

	int i, j;
	for (i = 0; i < str.length(); i++) {
		if (isspace(str[i])) {
			continue;
		}

		char* spc = CharSpace();
		int  nspc = strlen(spc);
		if (spc[0] != str[i]) {
			break;
		} else {
			int k;
			if (i+nspc >= str.length()) {
				break;
			}
			if (strncmp(spc, str.c_str()+i, nspc) != 0) {
				break;
			}
			i = i + nspc - 1;
		}
	}	

	rstr = str.substr(i);		

	return mka(rstr);
}

Node* lefttrimlist(Node* nd)
{
	Node* n = Nil;
	std::string str1 = "";
	std::string str2 = "";
	
	if (nd == Nil) {
		return nd;
	} else if (nd->kind() == ATOM) {
		std::string str = "";
		
		((Atom*)nd)->toString(str);
		n = dolefttrim(str);
		return n;
	} else if (nd->kind() == LIST) {
		Node* n1 = lefttrimlist(nd->Car());
		Node* n2 = lefttrimlist(nd->Cdr());
		if (n1->kind() == ATOM) {
			((Atom*)n1)->toString(str1);
			if (n2->kind() == ATOM) {
				((Atom*)n2)->toString(str2);
				if ((str1 == "") && (str2 == "")) {
					return n1;
				} else if (str1 == "") {
					return n2;
				} else if (str2 == "") {
					return n1;
				}
			} else {
				if (str1 == "") {
					return n2;
				}
			}
		} else if (n2->kind() == ATOM) {
			((Atom*)n2)->toString(str2);

			if (str2 == "") {
				return n1;
			}
		}

		n = Cons(n1, n2);
		return n;
	} else {
		return nd;
	}
}


int LeftTrim(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <lefttrim VAR STRINGS>\n",
		"lefttrim: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <lefttrim VAR STRINGS>\n");
		return 0;
	}

	Node* n = lefttrimlist(nstr);	
	
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

Node* dorighttrim(std::string &str)
{
	std::string rstr = "";

	int j;
	for (j = str.length()-1; j >= 0; j--) {
		if (isspace(str[j])) {
			continue;
		}

		char* spc = CharSpace();
		int  nspc = strlen(spc);
		if (j+1-nspc < 0) {
			break;
		} else {
			if (strncmp(spc, str.c_str()+j+1-nspc, nspc) != 0) {
				break;
			}
			j = j + 1 - nspc;
		}
	}

	rstr = str.substr(0, j+1);		

	return mka(rstr);
}


Node* righttrimlist(Node* nd)
{
	Node* n = Nil;
	std::string str1 = "";
	std::string str2 = "";
	
	if (nd == Nil) {
		return nd;
	} else if (nd->kind() == ATOM) {
		std::string str = "";
		
		((Atom*)nd)->toString(str);
		n = dorighttrim(str);
		return n;
	} else if (nd->kind() == LIST) {
		Node* n1 = righttrimlist(nd->Car());
		Node* n2 = righttrimlist(nd->Cdr());
		if (n1->kind() == ATOM) {
			((Atom*)n1)->toString(str1);
			if (n2->kind() == ATOM) {
				((Atom*)n2)->toString(str2);
				if ((str1 == "") && (str2 == "")) {
					return n1;
				} else if (str1 == "") {
					return n2;
				} else if (str2 == "") {
					return n1;
				}
			} else {
				if (str1 == "") {
					return n2;
				}
			}
		} else if (n2->kind() == ATOM) {
			((Atom*)n2)->toString(str2);

			if (str2 == "") {
				return n1;
			}
		}

		n = Cons(n1, n2);
		return n;
	} else {
		return nd;
	}
}

int RightTrim(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <righttrim VAR STRINGS>\n",
		"righttrim: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <righttrim VAR STRINGS>\n");
		return 0;
	}

	Node* n = righttrimlist(nstr);	
	
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);
	
	return 1;
}

Node* dochop(std::string &str)
{
	std::string rstr = "";

	int i, j=0;
	for (i = 0; i < str.length(); i++) {
		j = i;

		int len = CharLen(str[i]);
		if (len == 1) {
			continue;
		}
		if (i+len > str.length()) {
			break;
		}

		i = i + len - 1;
	}		

	rstr = str.substr(0, j);		

	return mka(rstr);
}

Node* choplist(Node* nd)
{
	Node* n = Nil;
	std::string str1 = "";
	std::string str2 = "";
	
	if (nd == Nil) {
		return nd;
	} else if (nd->kind() == ATOM) {
		std::string str = "";
		
		((Atom*)nd)->toString(str);
		n = dochop(str);
		return n;
	} else if (nd->kind() == LIST) {
		Node* n1 = choplist(nd->Car());
		Node* n2 = choplist(nd->Cdr());
		if (n1->kind() == ATOM) {
			((Atom*)n1)->toString(str1);
			if (n2->kind() == ATOM) {
				((Atom*)n2)->toString(str2);
				if ((str1 == "") && (str2 == "")) {
					return n1;
				} else if (str1 == "") {
					return n2;
				} else if (str2 == "") {
					return n1;
				}
			} else {
				if (str1 == "") {
					return n2;
				}
			}
		} else if (n2->kind() == ATOM) {
			((Atom*)n2)->toString(str2);

			if (str2 == "") {
				return n1;
			}
		}

		n = Cons(n1, n2);
		return n;
	} else {
		return nd;
	}
}

int Chop(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <chop VAR STRINGS>\n",
		"chop: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <chop VAR STRINGS>\n");
		return 0;
	}

	Node* n = choplist(nstr);	
	
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);

	return 1;
}

Node* dochomp(std::string &str)
{
	std::string rstr = "";

	int i;
	for (i = str.length()-1; i >= 0; i--) {
		if ((str[i] != 0x0a) && (str[i] != 0x0d)) {
			break;
		}
	}

	rstr = str.substr(0, i+1);

	return mka(rstr);
}


Node* chomplist(Node* nd)
{
	Node* n = Nil;
	std::string str1 = "";
	std::string str2 = "";
	
	if (nd == Nil) {
		return nd;
	} else if (nd->kind() == ATOM) {
		std::string str = "";
		
		((Atom*)nd)->toString(str);
		n = dochomp(str);
		return n;
	} else if (nd->kind() == LIST) {
		Node* n1 = chomplist(nd->Car());
		Node* n2 = chomplist(nd->Cdr());
		if (n1->kind() == ATOM) {
			((Atom*)n1)->toString(str1);
			if (n2->kind() == ATOM) {
				((Atom*)n2)->toString(str2);
				if ((str1 == "") && (str2 == "")) {
					return n1;
				} else if (str1 == "") {
					return n2;
				} else if (str2 == "") {
					return n1;
				}
			} else {
				if (str1 == "") {
					return n2;
				}
			}
		} else if (n2->kind() == ATOM) {
			((Atom*)n2)->toString(str2);

			if (str2 == "") {
				return n1;
			}
		}

		n = Cons(n1, n2);
		return n;
	} else {
		return nd;
	}
}

int Chomp(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <chomp VAR STRINGS>\n",
		"chomp: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <chomp VAR STRINGS>\n");
		return 0;
	}
	
	Node* n = chomplist(nstr);

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);

	return 1;
}


int StrReverse(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <strreverse VAR STRINGS>\n",
		"strreverse: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <strreverse VAR STRINGS>\n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <strreverse VAR STRINGS>\n");
		return 0;
	}
	
	std::string str, rstr="";

	((Atom*)nstr)->toString(str);

	int i;
	int len = str.length();
	for (i = 0; i < len; i++) {
		int l = CharLen(str[i]);
		if (i+l > len) {
			break;
		}
		
		int j;
		for (j = l-1; j >= 0; j--) {
			rstr = str[i+j] + rstr;
		}
		i = i + l - 1;
	}

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(mka((char*)rstr.c_str()));

	PushStack(cx, Nil, Nil, env);

	return 1;
}

int StrRepeat(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int	arglen = ListLength(g);

	if (arglen != 3) {
		syserr("usage : <strrepeat VAR STRINGS NUM>\n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("strrepeat: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <strrepeat VAR STRINGS NUM>\n");
		return 0;
	}

	g = g->Cdr();
	Node* nstr = g->Car()->Val();
	if ((rn = FuncArg(cx, nstr, goalscar, module)) <= 0) {
		syserr("strrepeat: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <strrepeat VAR STRINGS NUM>\n");
		return 0;
	}
	
	g = g->Cdr();
	Node* nnum = g->Car()->Val();
	if ((rn = FuncArg(cx, nnum, goalscar, module)) <= 0) {
		syserr("strrepeat: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nnum->kind() != ATOM) {
		syserr("usage : <strrepeat VAR STRINGS NUM>\n");
		return 0;
	}

	long long num;
	if (!((Atom*)nnum)->toInt(num)) {
		syserr("usage : <strrepeat VAR STRINGS NUM>\n");
		return 0;
	}
	if (num < 0) {
		return -1;
	}
				
	std::string str, rstr="";

	((Atom*)nstr)->toString(str);

	int i;
	for (i = 0; i < num; i++) {
		rstr += str;
	}

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(mka((char*)rstr.c_str()));

	PushStack(cx, Nil, Nil, env);

	return 1;
}


int StrShiftRight(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int	arglen = ListLength(g);

	if ((arglen != 2) && (arglen != 3)) {
		syserr("usage : <strshiftright VAR STRINGS [NUM]>\n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("strshiftright: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <strshiftright VAR STRINGS [NUM]>\n");
		return 0;
	}

	g = g->Cdr();
	Node* nstr = g->Car()->Val();
	if ((rn = FuncArg(cx, nstr, goalscar, module)) <= 0) {
		syserr("strshiftright: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <strshiftright VAR STRINGS [NUM]>\n");
		return 0;
	}

	long long num = 1;
	if (arglen == 3) {
		g = g->Cdr();
		Node* nnum = g->Car()->Val();
		if ((rn = FuncArg(cx, nnum, goalscar, module)) <= 0) {
			syserr("strshiftright: failed in the evaluation of the argument. \n");
			return 0;
		}

		if (nstr->kind() != ATOM) {
			syserr("usage : <strshiftright VAR STRINGS [NUM]>\n");
			return 0;
		}

		if (!((Atom*)nnum)->toInt(num)) {
			syserr("usage : <strshiftright VAR STRINGS [NUM]>\n");
			return 0;
		}
		if (num < 0) {
			return -1;
		}
	}			

	std::string str, rstr="";

	((Atom*)nstr)->toString(str);

	int i;
	int len = CodeLen((char*)str.c_str());
	if (len < num) {
		for (i = 0; i < len; i++) {
			rstr = " " + rstr;
		}
	} else {
		for (i = 0; i < num; i++) {
			str = " " + str;
		}
		int j, l, p;
		for (j = 0, p = 0; j < len; j++) {
			l = CharLen(str[p]);
			if (p+l > str.length()) {
				break;
			}
			int k;
			for (k = 0; k < l; k++) {
				rstr = rstr + str[p+k];
			}
			p += l;
		}
	}
			
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(mka((char*)rstr.c_str()));

	PushStack(cx, Nil, Nil, env);

	return 1;
}

int StrShiftLeft(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int	arglen = ListLength(g);

	if ((arglen != 2) && (arglen != 3)) {
		syserr("usage : <strshiftleft VAR STRINGS [NUM]>\n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("strshiftleft: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <strshiftleft VAR STRINGS [NUM]>\n");
		return 0;
	}

	g = g->Cdr();
	Node* nstr = g->Car()->Val();
	if ((rn = FuncArg(cx, nstr, goalscar, module)) <= 0) {
		syserr("strshiftleft: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <strshiftleft VAR STRINGS [NUM]>\n");
		return 0;
	}

	long long num = 1;
	if (arglen == 3) {
		g = g->Cdr();
		Node* nnum = g->Car()->Val();
		if ((rn = FuncArg(cx, nnum, goalscar, module)) <= 0) {
			syserr("strshiftleft: failed in the evaluation of the argument. \n");
			return 0;
		}

		if (nstr->kind() != ATOM) {
			syserr("usage : <strshiftleft VAR STRINGS [NUM]>\n");
			return 0;
		}

		if (!((Atom*)nnum)->toInt(num)) {
			syserr("usage : <strshiftleft VAR STRINGS [NUM]>\n");
			return 0;
		}
		if (num < 0) {
			return -1;
		}
	}			

	std::string str, rstr="";

	((Atom*)nstr)->toString(str);

	int i;
	int len = CodeLen((char*)str.c_str());
	if (len < num) {
		for (i = 0; i < len; i++) {
			rstr = " " + rstr;
		}
	} else {
		for (i = 0; i < num; i++) {
			str = str + " ";
		}
		int j, l, p;
		for (j = 0, p = 0; j < num; j++) {
			l = CharLen(str[p]);
			if (p+l > str.length()) {
				break;
			}
			p += l;
		}
		rstr = str.substr(p);
	}
			
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(mka((char*)rstr.c_str()));

	PushStack(cx, Nil, Nil, env);

	return 1;
}

int StrRotateRight(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int	arglen = ListLength(g);

	if ((arglen != 2) && (arglen != 3)) {
		syserr("usage : <strrotateright VAR STRINGS [NUM]>\n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("strrotateright: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <strrotateright VAR STRINGS [NUM]>\n");
		return 0;
	}

	g = g->Cdr();
	Node* nstr = g->Car()->Val();
	if ((rn = FuncArg(cx, nstr, goalscar, module)) <= 0) {
		syserr("strrotateright: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <strrotateright VAR STRINGS [NUM]>\n");
		return 0;
	}

	long long num = 1;
	if (arglen == 3) {
		g = g->Cdr();
		Node* nnum = g->Car()->Val();
		if ((rn = FuncArg(cx, nnum, goalscar, module)) <= 0) {
			syserr("strrotateright: failed in the evaluation of the argument. \n");
			return 0;
		}

		if (nstr->kind() != ATOM) {
			syserr("usage : <strrotateright VAR STRINGS [NUM]>\n");
			return 0;
		}

		if (!((Atom*)nnum)->toInt(num)) {
			syserr("usage : <strrotateright VAR STRINGS [NUM]>\n");
			return 0;
		}
		if (num < 0) {
			return -1;
		}
	}			

	std::string str, rstr="";

	((Atom*)nstr)->toString(str);

	int i;
	int len = CodeLen((char*)str.c_str());
	if (len < num) {
		num = num % len;
	}
	num = len - num;
	
	int j, l, p;
	for (j = 0, p = 0; j < num; j++) {
		l = CharLen(str[p]);
		if (p+l > str.length()) {
			break;
		}
		p += l;
	}
	rstr = str.substr(p) + str.substr(0, p);
			
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(mka((char*)rstr.c_str()));

	PushStack(cx, Nil, Nil, env);

	return 1;
}


int StrRotateLeft(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int	arglen = ListLength(g);

	if ((arglen != 2) && (arglen != 3)) {
		syserr("usage : <strrotateleft VAR STRINGS [NUM]>\n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("strrotateleft: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <strrotateleft VAR STRINGS [NUM]>\n");
		return 0;
	}

	g = g->Cdr();
	Node* nstr = g->Car()->Val();
	if ((rn = FuncArg(cx, nstr, goalscar, module)) <= 0) {
		syserr("strrotateleft: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <strrotateleft VAR STRINGS [NUM]>\n");
		return 0;
	}

	long long num = 1;
	if (arglen == 3) {
		g = g->Cdr();
		Node* nnum = g->Car()->Val();
		if ((rn = FuncArg(cx, nnum, goalscar, module)) <= 0) {
			syserr("strrotateleft: failed in the evaluation of the argument. \n");
			return 0;
		}

		if (nstr->kind() != ATOM) {
			syserr("usage : <strrotateleft VAR STRINGS [NUM]>\n");
			return 0;
		}

		if (!((Atom*)nnum)->toInt(num)) {
			syserr("usage : <strrotateleft VAR STRINGS [NUM]>\n");
			return 0;
		}
		if (num < 0) {
			return -1;
		}
	}			

	std::string str, rstr="";

	((Atom*)nstr)->toString(str);

	int i;
	int len = CodeLen((char*)str.c_str());
	if (len < num) {
		num = num % len;
	}

	int j, l, p;
	for (j = 0, p = 0; j < num; j++) {
		l = CharLen(str[p]);
		if (p+l > str.length()) {
			break;
		}
		p += l;
	}
	rstr = str.substr(p) + str.substr(0, p);
			
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(mka((char*)rstr.c_str()));

	PushStack(cx, Nil, Nil, env);

	return 1;
}

int StrSort(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <strsort VAR STRINGS>\n",
		"strsort: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <strsort VAR STRINGS>\n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <strsort VAR STRINGS>\n");
		return 0;
	}
	
	std::string str, rstr="";

	((Atom*)nstr)->toString(str);

	int len = CodeLen((char*)str.c_str());
	unsigned long long* lls = new unsigned long long[len];

	int i, j, p;
	for (i = 0, p = 0; i < len; i++) {
		int n = CharLen(str[p]);
		lls[i] = 0;
		int k;
		for (k = 0; k < n; k++) {
			lls[i] <<= 8;
			lls[i] += (unsigned long long)(str[p+k] & 0xff);
		}
		p = p + n;
	}

	for (i = 0; i < len-1; i++) {
		for (j = i+1; j < len; j++) {
			if (lls[i] > lls[j]) {
				unsigned long long c = lls[i];
				lls[i] = lls[j];
				lls[j] = c;
			}
		}
	}

	for (i = 0; i < len; i++) {
		std::string nstr = "";
		for (j = 0; j < sizeof(unsigned long long); j++) {
			unsigned long long c = lls[i] % 256;
			if (c == 0) {
				continue;
			}
			nstr = (char)c + nstr;
			lls[i] /= 256;
		}
		rstr += nstr;
	}

	delete [] lls;

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(mka((char*)rstr.c_str()));

	PushStack(cx, Nil, Nil, env);

	return 1;
}

int StrSortReverse(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <strsortreverse VAR STRINGS>\n",
		"strsortreverse: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <strsortreverse VAR STRINGS>\n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <strsortreverse VAR STRINGS>\n");
		return 0;
	}
	
	std::string str, rstr="";

	((Atom*)nstr)->toString(str);

	int len = CodeLen((char*)str.c_str());
	unsigned long long* lls = new unsigned long long[len];

	int i, j, p;
	for (i = 0, p = 0; i < len; i++) {
		int n = CharLen(str[p]);
		lls[i] = 0;
		int k;
		for (k = 0; k < n; k++) {
			lls[i] <<= 8;
			lls[i] += (unsigned long long)(str[p+k] & 0xff);
		}
		p = p + n;
	}

	for (i = 0; i < len-1; i++) {
		for (j = i+1; j < len; j++) {
			if (lls[i] < lls[j]) {
				unsigned long long c = lls[i];
				lls[i] = lls[j];
				lls[j] = c;
			}
		}
	}

	for (i = 0; i < len; i++) {
		std::string nstr = "";
		for (j = 0; j < sizeof(unsigned long long); j++) {
			unsigned long long c = lls[i] % 256;
			if (c == 0) {
				break;
			}
			nstr = (char)c + nstr;
			lls[i] /= 256;
		}
		rstr += nstr;
	}

	delete [] lls;

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(mka((char*)rstr.c_str()));

	PushStack(cx, Nil, Nil, env);

	return 1;
}


int StrLen(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <strlen VAR STRINGS>\n",
		"strlen: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <strlen VAR STRINGS>\n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <strlen VAR STRINGS>\n");
		return 0;
	}
	
	std::string str;

	((Atom*)nstr)->toString(str);

	long long len = CodeLen((char*)str.c_str());

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(mka(len));

	PushStack(cx, Nil, Nil, env);

	return 1;
}

int StrByte(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <strbyte VAR STRINGS>\n",
		"strbyte: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <strbyte VAR STRINGS>\n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <strbyte VAR STRINGS>\n");
		return 0;
	}
	
	std::string str;

	((Atom*)nstr)->toString(str);

	long long len = strlen((char*)str.c_str());

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(mka(len));

	PushStack(cx, Nil, Nil, env);

	return 1;
}

int StrFry(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <strfry VAR STRINGS>\n",
		"strfry: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <strfry VAR STRINGS>\n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <strfry VAR STRINGS>\n");
		return 0;
	}
	
	std::string str, rstr="";

	((Atom*)nstr)->toString(str);

	int len = CodeLen((char*)str.c_str());
	int slen = strlen((char*)str.c_str());

	long long buf[len];
	
	int i, j, rd;
	for (i = j = 0; i < len; i++) {
		if (j >= slen) {
			break;
		}
		
		int l = CharLen(str[j]);
		int k;
		long long shift = 1;
		buf[i] = 0;
		for (k=0; k < l; k++) {
			buf[i] = buf[i] + ((int)str[j+k] & 0xff) * shift;
			shift = shift * 256;
		}
		j = j + l;
	}

	for (i = 0; i < len; i++) {
#ifndef __MINGW32__
		rd = random();
#else
		rd = rand();
#endif /* __MINGW32__ */
		rd = rd % len;

		long long tmp = buf[i];
		buf[i] = buf[rd];
		buf[rd] = tmp;
	}

	for (i = 0; i < len; i++) {
		int k;
		while(buf[i] != 0) {
			rstr = rstr + (char)(buf[i] & 0xff);
			buf[i] = buf[i] / 256;
		}
	}
	
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(mka(rstr.c_str()));

	PushStack(cx, Nil, Nil, env);

	return 1;
}


int StrDelcntl(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <strdelcntl VAR STRINGS>\n",
		"strdelcntl: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <strdelcntl VAR STRINGS>\n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <strdelcntl VAR STRINGS>\n");
		return 0;
	}
	
	std::string str, rstr="";

	((Atom*)nstr)->toString(str);

	int len = CodeLen((char*)str.c_str());
	int slen = strlen((char*)str.c_str());

	int i, j, rd;
	for (i = j = 0; i < len; i++) {
		if (j >= slen) {
			break;
		}
		
		int l = CharLen(str[j]);
		if ((l != 1) || (str[j] >= ' ')) {
			int k;
			for (k=0; k < l; k++) {
				rstr = rstr + str[j+k];
			}
		}
		j = j + l;
	}

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(mka(rstr.c_str()));

	PushStack(cx, Nil, Nil, env);

	return 1;
}

int Seq(Context* cx, Node* goalscar, List* module)
{
	Node* nvar  = Nil;
	Node* ninit = Nil;
	Node* nlast = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <seq VAR INIT LAST>\n",
		"seq: failed in the evaluation of the argument. \n",
		nvar, ninit, nlast)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <seq VAR INIT LAST>\n");
		return 0;
	}

	if (ninit->kind() != ATOM) {
		syserr("usage : <seq VAR INIT LAST>\n");
		return 0;
	}
	
	if (nlast->kind() != ATOM) {
		syserr("usage : <seq VAR INIT LAST>\n");
		return 0;
	}
	
	long long init, last;

	((Atom*)ninit)->toInt(init);
	((Atom*)nlast)->toInt(last);

	Node* n = Nil;
	long long i;
	if (init < last) {
		n = MkList(mka(last));
		for (i = last-1; i >= init; i--) {
			n = Cons(mka(i), n);
		}
	} else {
		n = MkList(mka(last));
		for (i = last+1; i <= init; i++) {
			n = Cons(mka(i), n);
		}
	}

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);

	return 1;
}

int Padding(Context* cx, Node* goalscar, List* module)
{
	Node* nvar  = Nil;
	Node* nnum  = Nil;
	Node* nitem = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <padding VAR NUM ITEM>\n", 
		"padding: failed in the evaluation of the argument. \n",
		nvar, nnum, nitem)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <padding VAR NUM ITEM>\n");
		return 0;
	}

	if (nnum->kind() != ATOM) {
		syserr("usage : <padding VAR NUM ITEM>\n");

		return 0;
	}

	long long num;
	if (!((Atom*)(nnum->Car()))->toInt(num)) {
		syserr("usage : <padding VAR NUM ITEM>\n");

		return 0;
	}

	Node* n = Nil;
	long long i;

	for (i = 0; i < num; i++) {
		n = Cons(nitem, n);
	}

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);

	return 1;
}

int EqOR(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) < 1) {
		syserr("usage : <EqOr COMPARISON_VAL VAL1 VAL2 ...>\n");
		return 0;
	}
	
	Node* g    = goalscar->Cdr()->Val();
	Node* nval = g->Car()->Val();
	Node* nvals= g->Cdr()->Val();

	int rn;

	Node* np;
	for (np = nvals->Car(); nvals->kind() != ATOM; 
				nvals = nvals->Cdr(), np = nvals->Car()) {
		Node* env = Nil->Cons(Nil);
		if (Unification(nval, np, env, cx)) {
			PushStack(cx, Nil, Nil, env);
			return 1;
		}
	} 
	return -1;
}

int Switch(Context* cx, Node* goalscar, List* module)
{
	if (ListLength(goalscar->Cdr()) < 1) {
		syserr("usage : <switch COMPARISON_VAL VAL1 PRED1 VAL2 PRED2 ...>\n");
		return 0;
	}
	
	Node* g    = goalscar->Cdr()->Val();
	Node* nval = g->Car()->Val();
	Node* nvals= g->Cdr()->Val();

	int rn;

	Node* np;
	Node* npred;
	for (np = nvals->Car(); nvals->kind() != ATOM; 
			nvals = nvals->Cdr()->Cdr(), np = nvals->Car()) {
		Node* env = Nil->Cons(Nil);
		if (Unification(nval, np, env, cx)) {
			PushStack(cx, Nil, Nil, env);

			npred = nvals->Cdr()->Car();

			Context* cx2 = new Context(cx->module, cx->modulename);
			cx2->selfname = cx->selfname;
			cx2->inherit = cx->inherit;
			cx2->ioin = cx->ioin;
			cx2->ioout = cx->ioout;
			cx2->tokenflag = cx->tokenflag;

			cx2->ode = cx->ode;
			cx2->integral = cx->integral;

			cxpush(cx2, goalscar);
			cxpush(cx2, npred);

			if ((rn=Unify(cx2, npred, cx->module))>0) {
				cx->Merge(cx2);

				cxpop(cx2);
				cxpop(cx2);
				delete cx2;
				cx2 = 0;

				return rn;
			} else {
				cxpop(cx2);
				cxpop(cx2);
				delete cx2;
				cx2 = 0;

				return rn;
			}
		}
	} 
	return -1;
}

int CheckObj(Context* cx, Node* goalscar, List* module)
{
	Node* nobj = Nil;
	if (!Parm1(cx, goalscar, module, "usage : <checkObj OBJECTNAME>\n",
		"checkObj: failed in the evaluation of the argument. \n",
		nobj)) {
			return 0;
	}

	if (nobj->kind() != ATOM) {
		return -1;
	}

	Node* md;
	Node* nvar = MkPred(nobj);
	for (md = Module->Car(); md != Nil; md = md->Cdr()) {
		if (ModuleCompare(md->Car()->Car()->Car(), nvar) == 0) {
			return 1;
		}
	}

	return -1;
}

int DoAppend(Context* cx, Node* goalscar, List* module)
{
	Node* nvar   = Nil;
	Node* nlist1 = Nil;
	Node* nlist2 = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <append VAR LIST1 LIST2>\n",
		"append: failed in the evaluation of the argument. \n",
		nvar, nlist1, nlist2)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <append VAR LIST1 LIST2>\n");
		return 0;
	}

	if ((nlist1->kind() != LIST) && (nlist1 != Nil)) {
		syserr("usage : <append VAR LIST1 LIST2>\n");
		return 0;
	}

	if ((nlist2->kind() != LIST) && (nlist2 != Nil)) {
		syserr("usage : <append VAR LIST1 LIST2>\n");
		return 0;
	}

	Node* n = Append(nlist1, nlist2);

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, n);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);

	return 1;
}

Node* Reverse(Node* nlist1)
{
	if (nlist1->kind() != LIST) {
		return nlist1;
	}
	
	Node* n = Nil;

	for ( ; nlist1->kind() != ATOM; nlist1 = nlist1->Cdr()) {
		n = Cons(nlist1->Car(), n);
	}

	return n;
}

int DoReverse(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nlist1 = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <reverse VAR LIST>\n",
		"reverse: failed in the evaluation of the argument. \n",
		nvar, nlist1)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <reverse VAR LIST>\n");
		return 0;
	}

	if ((nlist1->kind() != LIST) && (nlist1 != Nil)) {
		syserr("usage : <reverse VAR LIST>\n");
		return 0;
	}

	Node* n = Reverse(nlist1);

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, n);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);

	return 1;
}


int DoMember(Context* cx, Node* goalscar, List* module)
{
	Node* nlist1 = Nil;
	Node* nlist2 = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <member ARG LIST2>\n",
		"member: failed in the evaluation of the argument. \n",
		nlist1, nlist2)) {
			return 0;
	}

	if ((nlist2->kind() != LIST) && (nlist2 != Nil)) {
		syserr("usage : <member ARG LIST2>\n");
		return 0;
	}

	for (; nlist2->kind() != ATOM; nlist2 = nlist2->Cdr()) {
		Node* n = nlist2->Car();
		
		if (n->Eq(nlist1)) {
			return 1;
		}
	}
	return -1;
}

int DoGetenv(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nname = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <getenv VAR name>\n",
		"getenv: failed in the evaluation of the argument. \n",
		nvar, nname)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <getenv VAR name>\n");
		return 0;
	}

	if (nname->kind() != ATOM) {
		syserr("usage : <getenv VAR name>\n");
		return 0;
	}

	std::string name;
	((Atom*)nname)->toString(name);
	
	char* val = getenv(name.c_str());
	if (val == NULL) {
		return -1;
	}

	Node* nval = mka(val);

	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)(nvar->Val()))->Set(nval);

	PushStack(cx, Nil, Nil, env);
	return 1;
}


int FileGet(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nfilename = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <fileget VAR filename>\n",
		"fileget: failed in the evaluation of the argument. \n",
		nvar, nfilename)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <fileget VAR filename>\n");
		return 0;
	}

	if (nfilename->kind() != ATOM) {
		syserr("usage : <fileget VAR filename>\n");
		return 0;
	}

	std::string str = "", sfilename = "";

	((Atom*)nfilename)->toString(sfilename);

	FILE* fd = fopen(sfilename.c_str(), "r");
	if (fd == NULL)	{
		fprintf(stderr, "can't open %s\n", sfilename.c_str());
		return -1;
	}

	int c;
	for (;;) {
		c = fgetc(fd);
		if (c == EOF) {
			break;
		}
		str += c;
	}

	fclose(fd);
	
	Node* n = mka(str);

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);

	return 1;
}



void pulloutstr2(std::string &resultstr, std::string &str, 
			std::string &str1, std::string &str2)
{
	int i, j, k, l;

	resultstr = "";	
	if ((str == "") || (str1 == "") || (str2 == "")) {
		return;
	}
		
	for (i = 0; i < str.length();) {
		i = str.find(str1, i);

		if (i == std::string::npos) {
			return;
		}

		for (j = i + str1.length(); j < str.length(); j++) {
			k = str.find(str2, j+1);
			if (k == std::string::npos) {
				return;
			}

			l = k + str2.length();
			resultstr = str.substr(i, l-i);
			break;
		}
		i = l + 1;
	}

}

Node* pullout2list(Node* nd, std::string &str1, std::string &str2)
{

	if (nd == Nil) {
		return nd;
	} else if (nd->kind() == ATOM) {
		std::string resultstr = "", str = "";
		
		((Atom*)nd)->toString(str);
		pulloutstr2(resultstr, str, str1, str2);
		
		Node* n = mka(resultstr.c_str());

		return n;

	} else if (nd->kind() == LIST) {
		Node* n = Cons(pullout2list(nd->Car(), str1, str2), 
				pullout2list(nd->Cdr(), str1, str2));

		return n;

	} else {
		return nd;
	}
		
}

int PulloutStr(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int	arglen = ListLength(g);

	if (arglen != 4) {
		syserr("usage : <pulloutstr VAR STR STR1 STR2>\n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("pulloutstr: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <pulloutstr VAR STR STR1 STR2>\n");
		return 0;
	}

	g = g->Cdr();
	Node* nstr = g->Car()->Val();
	if ((rn = FuncArg(cx, nstr, goalscar, module)) <= 0) {
		syserr("pulloutstr: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nstr->kind() != ATOM) {
		syserr("usage : <pulloutstr VAR STR STR1 STR2>\n");
		return 0;
	}


	g = g->Cdr();
	Node* nstr1 = g->Car()->Val();
	if ((rn = FuncArg(cx, nstr1, goalscar, module)) <= 0) {
		syserr("pulloutstr: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nstr1->kind() != ATOM) {
		syserr("usage : <pulloutstr VAR STR STR1 STR2>\n");
		return 0;
	}

	g = g->Cdr();
	Node* nstr2 = g->Car()->Val();
	if ((rn = FuncArg(cx, nstr2, goalscar, module)) <= 0) {
		syserr("pulloutstr: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nstr2->kind() != ATOM) {
		syserr("usage : <pulloutstr VAR STR STR1 STR2>\n");
		return 0;
	}

	Node* n = Nil;
	std::string str1="", str2="";
	((Atom*)nstr1)->toString(str1);
	((Atom*)nstr2)->toString(str2);

	n = pullout2list(nstr, str1, str2);

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);

	return 1;
}

void erasestr(std::string &resultstr, std::string &str, std::string &str1)
{
	int i=0, j=0;
	resultstr = "";
	
	if ((str == "") || (str1 == "")) {
		resultstr = str;
		return;
	}
		
	for (i = 0; i < str.length();) {
		i = str.find(str1, i);
		if (i == std::string::npos) {
			resultstr += str.substr(j);
			return;
		} else if (j != i){
			resultstr += str.substr(j, i-j);
		}

		j = i + str1.length();
		i = j+1;
	}
}

void erasestr2(std::string &resultstr, std::string &str, 
			std::string &str1, std::string &str2)
{
	int i=0, j=0, k=0;
	resultstr = "";
	
	if ((str == "") || (str1 == "") || (str2 == "")) {
		resultstr = str;
		return;
	}
		
	for (i = 0; i < str.length();) {
		i = str.find(str1, i);
		if (i == std::string::npos) {
			resultstr += str.substr(k);
			return;
		} else if (k != i){
			resultstr += str.substr(k, i-k);
		}

		j = i + str1.length()+1;
		k = str.find(str2, j);
		if (k == std::string::npos) {
			return;
		}
		k = k + str2.length();
		i = k+1;
	}
}


Node* erasestrlist(Node* nd, std::string &str1)
{
	Node*	n = Nil;
	
	if (nd == Nil) {
		return nd;
	} else if (nd->kind() == ATOM) {
		std::string resultstr = "", str = "";
		
		((Atom*)nd)->toString(str);
		erasestr(resultstr, str, str1);
		
		n = mka(resultstr.c_str());

		return n;

	} else if (nd->kind() == LIST) {
		n = Cons(erasestrlist(nd->Car(), str1), 
				erasestrlist(nd->Cdr(), str1));

		return n;

	} else {
		return nd;
	}
		
}

Node* erasestr2list(Node* nd, std::string &str1, std::string &str2)
{
	Node*	n = Nil;
	
	if (nd == Nil) {
		return nd;
	} else if (nd->kind() == ATOM) {
		std::string resultstr = "", str = "";
		
		((Atom*)nd)->toString(str);
		erasestr2(resultstr, str, str1, str2);
		
		n = mka(resultstr.c_str());

		return n;

	} else if (nd->kind() == LIST) {
		n = Cons(erasestr2list(nd->Car(), str1, str2), 
				erasestr2list(nd->Cdr(), str1, str2));

		return n;

	} else {
		return nd;
	}
		
}

int EraseStr(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int	arglen = ListLength(g);

	if ((arglen != 3) && (arglen != 4)) {
		syserr("usage : <erasestrs VAR STR str1 [str2]>\n");
		return 0;
	}

	Node* nvar = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("erasestrs: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <erasestrs VAR STR str1 [str2]>\n");
		return 0;
	}

	g = g->Cdr();
	Node* nstr = g->Car()->Val();
	if ((rn = FuncArg(cx, nstr, goalscar, module)) <= 0) {
		syserr("erasestrs: failed in the evaluation of the argument. \n");
		return 0;
	}

	g = g->Cdr();
	Node* nstr1 = g->Car()->Val();
	if ((rn = FuncArg(cx, nstr1, goalscar, module)) <= 0) {
		syserr("erasestrs: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nstr1->kind() != ATOM) {
		syserr("usage : <erasestrs VAR STR str1 [str2]>\n");
		return 0;
	}
	
	Node* n = Nil;
	std::string str1="", str2="";
	((Atom*)nstr1)->toString(str1);

	if (arglen == 3) {

		n = erasestrlist(nstr, str1);

	} else if (arglen == 4) {

		g = g->Cdr();
		Node* nstr2 = g->Car()->Val();
		if ((rn = FuncArg(cx, nstr2, goalscar, module)) <= 0) {
			syserr("erasestrs: failed in the evaluation of the argument. \n");
			return 0;
		}

		if (nstr2->kind() != ATOM) {
			syserr("usage : <erasestrs VAR STR str1 [str2]>\n");
			return 0;
		}

		((Atom*)nstr2)->toString(str2);

		n = erasestr2list(nstr, str1, str2);
	}

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);

	return 1;
}

Node* flatten(Node* nd)
{
	if (nd->kind() != LIST) {
		return nd;
	}

	Node* ncar = nd->Car();
	Node* ncdr = nd->Cdr();

	Node* n1 = flatten(ncar);
	Node* n2 = flatten(ncdr);

	if (n1->kind() == LIST) {
		return Append(n1, n2);
	} else {
		return Cons(n1, n2);
	}
}

int Flatten(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nlist = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <flatten VAR list>\n",
		"flatten: failed in the evaluation of the argument. \n",
		nvar, nlist)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <flatten VAR list>\n");
		return 0;
	}


	Node* n = flatten(nlist);
	
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);

	return 1;
}

void strcode(std::string &code, std::string &str)
{
	int	i;
	int	nsjis = 0, neuc = 0, nutf8 = 0;
	int	nascii = 0;

	code = "ASCII";

	int len = str.length();

	for (i = 0; i < len; i++) {
	
		int c = (str[i] & 0xff);
		if ((c == 0x1b) && (str[i+1] == '$')) {
			code = "ISO-2022-JP";
			return;
		}
		if (c >= 0x80) {
			nascii--;
		}
//printf("c %x\n", c);
	}

	if (nascii == 0) {
		code = "ASCII";
		return;
	}
	
	for (i = 0; i < len; i++) {

		int c = (str[i] & 0xff);

		if (c < 0x80) {
			continue;
		}

		//check SJIS
		if ((c >= 0xa1) && (c <= 0xdf)) {
			// nothing			
		} else if (((c >= 0x81) && (c <= 0x9f)) ||
				((c >= 0xe0) && (c <= 0xef))) {
			if (i+1 >= len) {
				nsjis--;
				break;
			} else if (i+2 < len) {
				if ((str[i+1] & 0xf0) < 0x80) {
					nsjis++;
				}
			}
			if (c == 0x82) {
				nsjis++;
			}			

			i++;
			int c2 = (str[i] & 0xff);
			if (((c2 >= 0x40) && (c2 <= 0x7e)) ||
					((c2 >= 0x80) && (c2 <= 0xfc))) {
				// nothing			
			} else {
				nsjis--;
			}
		} else {
			nsjis--;
		}
	}

	for (i = 0; i < len; i++) {
		int c = (str[i] & 0xff);
		if (c < 0x80) {
			continue;
		}

		// check EUC-JP		
		if ((c == 0x8e) || (c == 0x8f) || 
				((c >= 0xa1) && (c <= 0xfe))) {
			if (i+1 >= len) {
				neuc--;
				break;
			}
			if (c == 0xa4) {
				neuc++;
			}
			
			i++;
			int c2 = (str[i] & 0xff);
			if ((c2 >= 0xa1) && (c2 <= 0xfe)) {
				if (c == 0x8f) {
					if (i+1 >= len) {
						neuc--;
						break;
					}

					i++;
					int c3 = str[i];
					if ((c3 >= 0xa1) && (c3 <= 0xfe)) {
					} else {
						neuc--;
					}
				}
			} else {
				neuc--;
			}
		} else {
			neuc--;
		}
	}

	for (i = 0; i < len; i++) {
		int c = (str[i] & 0xff);
		if (c < 0x80) {
			continue;
		}

		// check UTF-8	
		if (c >= 0xfc) {
			if (i+6 < len) {
				if (str[i] == str[i+6]) {
					nutf8++;
				}
			} else if (i+5 >= len) {
				nutf8--;
				break;
			}

			i++;
			int c2 = (str[i] & 0xff);
			if ((c2 >= 0x80) && (c2 <= 0xbf)) {
			} else {
				nutf8--;
			}
			i++;
			int c3 = (str[i] & 0xff);
			if ((c3 >= 0x80) && (c3 <= 0xbf)) {
			} else {
				nutf8--;
			}
			i++;
			int c4 = (str[i] & 0xff);
			if ((c4 >= 0x80) && (c4 <= 0xbf)) {
			} else {
				nutf8--;
			}
			i++;
			int c5 = (str[i] & 0xff);
			if ((c5 >= 0x80) && (c5 <= 0xbf)) {
			} else {
				nutf8--;
			}
			i++;
			int c6 = (str[i] & 0xff);
			if ((c6 >= 0x80) && (c6 <= 0xbf)) {
			} else {
				nutf8--;
			}
		} else if (c >= 0xf8) {
			if (i+5 < len) {
				if (str[i] == str[i+5]) {
					nutf8++;
				}
			} else if (i+4 >= len) {
				nutf8--;
				break;
			}

			i++;
			int c2 = (str[i] & 0xff);
			if ((c2 >= 0x80) && (c2 <= 0xbf)) {
			} else {
				nutf8--;
			}
			i++;
			int c3 = (str[i] & 0xff);
			if ((c3 >= 0x80) && (c3 <= 0xbf)) {
			} else {
				nutf8--;
			}
			i++;
			int c4 = (str[i] & 0xff);
			if ((c4 >= 0x80) && (c4 <= 0xbf)) {
			} else {
				nutf8--;
			}
			i++;
			int c5 = (str[i] & 0xff);
			if ((c5 >= 0x80) && (c5 <= 0xbf)) {
			} else {
				nutf8--;
			}
		} else if (c >= 0xf0) {
			if (i+4 < len) {
				if (str[i] == str[i+4]) {
					nutf8++;
				}
			} else if (i+3 >= len) {
				nutf8--;
				break;
			}

			i++;
			int c2 = (str[i] & 0xff);
			if ((c2 >= 0x80) && (c2 <= 0xbf)) {
			} else {
				nutf8--;
			}
			i++;
			int c3 = (str[i] & 0xff);
			if ((c3 >= 0x80) && (c3 <= 0xbf)) {
			} else {
				nutf8--;
			}
			i++;
			int c4 = (str[i] & 0xff);
			if ((c4 >= 0x80) && (c4 <= 0xbf)) {
			} else {
				nutf8--;
			}
		} else if (c >= 0xe0) {
			if (i+3 < len) {
				if (str[i] == str[i+3]) {
					nutf8++;
				}
			} else if (i+2 >= len) {
				nutf8--;
				break;
			}
			if (c == 0xe3) {
				nutf8++;
			}
			
			i++;
			int c2 = (str[i] & 0xff);
			if ((c2 >= 0x80) && (c2 <= 0xbf)) {
			} else {
				nutf8--;
			}
			i++;
			int c3 = (str[i] & 0xff);
			if ((c3 >= 0x80) && (c3 <= 0xbf)) {
			} else {
				nutf8--;
			}
		} else if (c >= 0xc2) {
			if (i+2 < len) {
				if (str[i] == str[i+2]) {
					nutf8++;
				}
			} else if (i+1 >= len) {
				nutf8--;
				break;
			}

			i++;
			int c2 = (str[i] & 0xff);
			if ((c2 >= 0x80) && (c2 <= 0xbf)) {
			} else {
				nutf8--;
			}
		} else {
			nutf8--;
		}
	}
	
	if ((nsjis > nutf8) && (nsjis > neuc)) {
		code = "SJIS";
	} else if ((neuc > nutf8) && (neuc > nsjis)) {
		code = "EUC-JP";
	} else if ((nutf8 >= neuc) && (nutf8 >= nsjis)) {
		code = "UTF-8";
	}

//	printf("nsjis %d neuc %d nutf8 %d\n", nsjis, neuc, nutf8);
}

int StrCode(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nstr = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <strcode VAR STR>\n",
		"strcode: failed in the evaluation of the argument. \n",
		nvar, nstr)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <strcode VAR STR>\n");
		return 0;
	}

	Node* n = Nil;
	std::string str="", str1="";
	((Atom*)nstr)->toString(str1);

	strcode(str, str1);
	
	n = mka(str);
	
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(n);

	PushStack(cx, Nil, Nil, env);

	return 1;
}


#if HAVE_ICONV_H

void doiconv(std::string &tostr, std::string &fromstr, 
		std::string &tocode, std::string &fromcode)
{
	int i;
	
	tostr = "";

	iconv_t cd = iconv_open(tocode.c_str(), fromcode.c_str());
	if (cd == (iconv_t)-1) {
		fprintf(stderr, "code error : iconv_open %s %s\n", 
				tocode.c_str(), fromcode.c_str());
		return;
	}

	char* sbuf = (char*)malloc(fromstr.length()*6+1);
	if (sbuf == NULL) {
		fprintf(stderr, "can't get memory\n");
		return;
	}

	memset(sbuf, 0, fromstr.length()*6+1);
	sbuf[0] = 0;

	size_t fromleft = fromstr.length(), toleft = fromleft*6;
	char *fp = (char*)fromstr.c_str(), *tp = sbuf;
	while(fromleft > 0) {
#if defined(__sun)
		if (iconv(cd, (const char**)&fp, &fromleft, &tp, &toleft) == -1) {
#else 
		if (iconv(cd, &fp, &fromleft, &tp, &toleft) == -1) {
#endif 
//			fprintf(stderr, "code error : iconv %s %s\n", 
//				tocode.c_str(), fromcode.c_str());
			fp++;
			fromleft--;
		}
	}

	tostr = sbuf;

	iconv_close(cd);

	free(sbuf);

}

Node* doiconvlist(Node* nd, std::string &tocode, std::string &fromcode)
{
	if (nd == Nil) {
		return nd;
	} else if (nd->kind() == ATOM) {
		std::string tostr="", fromstr="";
		((Atom*)nd)->toString(fromstr);

		if (tocode != fromcode) {		
			doiconv(tostr, fromstr, tocode, fromcode);
			return mka(tostr);
		} else {
			return mka(fromstr);
		}

	} else if (nd->kind() == LIST) {
		return Cons(doiconvlist(nd->Car(), tocode, fromcode), 
				doiconvlist(nd->Cdr(), tocode, fromcode));
	} else {
		return nd;
	}
}

int DoIconv(Context* cx, Node* goalscar, List* module)
{
	Node* g = goalscar->Cdr()->Val();
	int	arglen = ListLength(g);

	if ((arglen < 2) || (arglen > 4)) {
		syserr("usage : <iconv VAR_tostr fromstr [tocode [fromcode]]>\n");
		return 0;
	}

	Node* nvar_tostr = g->Car()->Val();
	int rn;

	if ((rn = FuncArg(cx, nvar_tostr, goalscar, module)) <= 0) {
		syserr("iconv: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar_tostr->kind() != UNDEF) {
		syserr("usage : <iconv VAR_tostr fromstr [tocode [fromcode]]>\n");
		return 0;
	}

	g = g->Cdr();
	Node* nfromstr = g->Car()->Val();
	if ((rn = FuncArg(cx, nfromstr, goalscar, module)) <= 0) {
		syserr("iconv: failed in the evaluation of the argument. \n");
		return 0;
	}

	Node* ntocode = Nil;
	if (arglen >= 3) {
		g = g->Cdr();
		ntocode = g->Car()->Val();
		if ((rn = FuncArg(cx, ntocode, goalscar, module)) <= 0) {
			syserr("iconv: failed in the evaluation of the argument. \n");
			return 0;
		}
		
		if (ntocode->kind() != ATOM) {
			syserr("usage : <iconv VAR_tostr fromstr [tocode [fromcode]]>\n");
			return 0;
		}
	} else {
		extern std::string code;
		if (code == "UTF8") {
			ntocode = mka("UTF-8");
		} else if (code == "EUC") {
			ntocode = mka("EUC-JP");
		} else if (code == "SJIS") {
			ntocode = mka("SJIS");
		} else {
			ntocode = mka("ASCII");
		}
	}

	Node* nfromcode = Nil;
	if (arglen >= 4) {
		g = g->Cdr();
		nfromcode = g->Car()->Val();
		if ((rn = FuncArg(cx, nfromcode, goalscar, module)) <= 0) {
			syserr("iconv: failed in the evaluation of the argument. \n");
			return 0;
		}

		if (nfromcode->kind() != ATOM) {
			syserr("usage : <iconv VAR_tostr fromstr [tocode [fromcode]]>\n");
			return 0;
		}
	} else {
		std::string fromcode = "";
		std::string* fromstr = ((Atom*)nfromstr)->string();
		 
		strcode(fromcode, *fromstr);

		nfromcode = mka(fromcode);
	}

	std::string tocode="", fromcode="";
	((Atom*)ntocode)->toString(tocode);
	((Atom*)nfromcode)->toString(fromcode);

	Node* n = doiconvlist(nfromstr, tocode, fromcode);
		
	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar_tostr);

	((Undef*)nvar_tostr)->Set(n);

	PushStack(cx, Nil, Nil, env);

	return 1;
}


#endif /* HAVE_ICONV_H */


static void csvencode(std::string& so, std::string& si) 
{
	int	i;
	int	flg = 1, dot = 0;

	if (si == "\"\"") {
		so = si;
		return;
	}

	dot = 0;
	flg = 1;	
	for (i = 0; i < si.length(); i++) {
		if (si[i] == '.') {
			dot++;
			if (dot > 1) {
				flg = 0;
				break;
			}
			continue;
		} 
		if (!isdigit(si[i])) {
			flg = 0;
			break;
		}
	}
	if (flg) {
		so = si;
		return;
	}

	so = "\"";
	for (i = 0; i < si.length(); i++) {
		if (si[i] == '"') {
			so = so + "\"\"";
		} else {
			so = so + si[i];
		}
	}
	so = so + "\"";
}

static void csvdecode(std::string& so, std::string& si) 
{
	std::string stmp = "";
	if ((si[0] == '"') && (si[si.length()-1] == '"')) {
		stmp = si.substr(1, si.length()-2);
	} else {
		stmp = si;
	}

	int	i;
	so = "";
	for (i = 0; i < stmp.length(); i++) {
		if (stmp[i] == '"') {
			if ((i < stmp.length()-1) && (stmp[i+1] == '"')) {
				so = so + '"';
				i++;
			} else {
				so = so + stmp[i];
			}
		} else {
			so = so + stmp[i];
		}
	}
}

static Node* csvlist(std::string& str, char delimiter)
{
	Node*	nd = Nil;
	int	i, j;
	std::string s = "";
	std::string sspace = CharSpace();
	int	sspacelen = sspace.length();

	for (i = 0; i < str.length(); i++) {
		if (str[i] == 0) {
			nd = Append(nd, MkList(mka(s.c_str())));
			break;
		}
		
		s = "";
		int escflg = 0;
		for (j = i; j < str.length(); j++) {
			if (str[i] == '"') {
				if (j == i) {
					escflg = 1;
					j++;
				}
				if (str[j] == '"') {
					escflg = 0;
					j++;
				}
				if (!escflg && (str[j] == delimiter)) {
					break;
				} else {
					s = s + str[j];
				}
				
			} else {
				if (str[j] == delimiter) {
					break;
				}
				s = s + str[j];
			}
		}
		i = j;
		nd = Append(nd, MkList(mka(s.c_str())));
	}
	return nd;
}

static Node* readcsv(const char* fname, char delimiter)
{
	int	i;
	Node* nd = Nil;
	FILE* fd;
	char* csvbuff = (char*)malloc(1024*1024);
	if (csvbuff == NULL) {
		fprintf(stderr, "can't alloc memory");
		return Nil;
	}
	
	fd = fopen(fname, "r");
	if (fd == NULL) {
		fprintf(stderr, "can't open %s\n", fname);
		return Nil;
	}

	while (fgets(csvbuff, 1024*1024-1, fd) != NULL) {
		csvbuff[1024*1024-2] = 0;
		for (i = 0; i < 1024*1024-1; i++) {
			if ((csvbuff[i] == 0x0d) || (csvbuff[i] == 0x0a) ||
					(csvbuff[i] == 0)) {
				csvbuff[i] = 0;
				break;
			}
		}
	
		std::string si = csvbuff, so = "";
		csvdecode(so, si);
		nd = Append(nd, MkList(csvlist(so, delimiter)));
		
	}

	fclose(fd);
	free(csvbuff);

	return nd;
}

int readCSV(Context* cx, Node* goalscar, List* module)
{
	int len = ListLength(goalscar->Cdr());
	if ((len != 2) && (len != 3)) {
		syserr("usage: ::sys <readCSV VAR FILENAME [DELIMITER]>\n");
		return 0;
	}

	Node* g    = goalscar->Cdr()->Val();

	int rn;

	Node* nvar = g->Car()->Val();
	if ((rn = FuncArg(cx, nvar, goalscar, module)) <= 0) {
		syserr("readCSV: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage: ::sys <readCSV VAR FILENAME [DELIMITER]>\n");
		return 0;
	}

	g = g->Cdr();
	Node* nfname = g->Car()->Val();
	if ((rn = FuncArg(cx, nfname, goalscar, module)) <= 0) {
		syserr("readCSV: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nfname->kind() != ATOM) {
		syserr("usage: ::sys <readCSV VAR FILENAME [DELIMITER]>\n");
		return 0;
	}

	char delimiter = ',';
	if (len == 3) {
		g = g->Cdr();
		Node* ndelimiter = g->Car()->Val();
		if ((rn = FuncArg(cx, ndelimiter, goalscar, module)) <= 0) {
			syserr("readCSV: failed in the evaluation of the argument. \n");
			return 0;
		}

		if (ndelimiter->kind() != ATOM) {
			syserr("usage: ::sys <readCSV VAR FILENAME [DELIMITER]>\n");
			return 0;
		}

		std::string sd = "";
		((Atom*)ndelimiter)->toString(sd);
		if (sd.length() != 1) {
			syserr("usage: ::sys <readCSV VAR FILENAME [DELIMITER]>\n");
			return 0;
		}

		delimiter = sd[0];
	}
	
	std::string sfname = "";
	((Atom*)nfname)->toString(sfname);
	
	Node* nlist = readcsv(sfname.c_str(), delimiter);

	Node* env = Nil->Cons(Nil);

	SetEnv(env, nvar);
	((Undef*)(nvar->Val()))->Set(nlist);

	PushStack(cx, Nil, Nil, env);
	return 1;
}

static void csvlist_encode(Node* &nout, Node* nin)
{
	if (nin->kind() == ATOM) {
		std::string sin = "", sout = "";
		((Atom*)nin)->toString(sin);
		csvencode(sout, sin);
		nout = mka(sout);
	} else if (nin->kind() == LIST) {
		Node* n1 = Nil;
		Node* n2 = Nil;
		csvlist_encode(n1, nin->Car());
		csvlist_encode(n2, nin->Cdr());
		nout = Cons(n1, n2);
	} else {
		nout = nin;
	}
}

static void writecsv(const char* fname, Node* csvdata, char delimiter)
{
	int	i;
	FILE* fd;
	
	fd = fopen(fname, "w");
	if (fd == NULL) {
		fprintf(stderr, "can't open %s\n", fname);
		return;
	}

	Node* ncsv = Nil; 
	csvlist_encode(ncsv, csvdata);

	if (ncsv->kind() != LIST) {
		ncsv->print(fd);		
	} else {
		Node* n1=Nil;
		Node* n2=Nil;
		for (n1 = ncsv->Car(); ncsv->kind() != ATOM; 
				ncsv=ncsv->Cdr(), n1=ncsv->Car()) {
			if (n1->kind() != LIST) {
				n1->print(fd);
			} else {
				for (n2=n1->Car(); n1->kind() != ATOM;
						n1=n1->Cdr(), n2=n1->Car()) {
					n2->print(fd);
					if (n1->Cdr()->kind() != ATOM) {
						fprintf(fd, "%c", delimiter);
					}
				}
			}	
			fprintf(fd, "\r\n");
		}
	}

	fclose(fd);

	return;
}

int writeCSV(Context* cx, Node* goalscar, List* module)
{
	int len = ListLength(goalscar->Cdr());
	if ((len != 2) && (len != 3)) {
		syserr("usage: ::sys <writeCSV FILENAME CSVDATA [DELIMITER]>\n");
		return 0;
	}

	Node* g    = goalscar->Cdr()->Val();

	int rn;

	Node* nfname = g->Car()->Val();
	if ((rn = FuncArg(cx, nfname, goalscar, module)) <= 0) {
		syserr("writeCSV: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nfname->kind() != ATOM) {
		syserr("usage: ::sys <writeCSV FILENAME CSVDATA [DELIMITER]>\n");
		return 0;
	}

	g = g->Cdr();
	Node* ncsvdata = g->Car()->Val();
	if ((rn = FuncArg(cx, ncsvdata, goalscar, module)) <= 0) {
		syserr("writeCSV: failed in the evaluation of the argument. \n");
		return 0;
	}

	char delimiter = ',';
	if (len == 3) {
		g = g->Cdr();
		Node* ndelimiter = g->Car()->Val();
		if ((rn = FuncArg(cx, ndelimiter, goalscar, module)) <= 0) {
			syserr("writeCSV: failed in the evaluation of the argument. \n");
			return 0;
		}

		if (ndelimiter->kind() != ATOM) {
			syserr("usage: ::sys <writeCSV FILENAME CSVDATA [DELIMITER]>\n");
			return 0;
		}

		std::string sdelimiter = "";
		((Atom*)ndelimiter)->toString(sdelimiter);

		if (sdelimiter.length() != 1) {
			syserr("usage: ::sys <writeCSV FILENAME CSVDATA [DELIMITER]>\n");
			return 0;
		}
		
		delimiter = sdelimiter[0];
	}
	
	std::string sfname = "";
	((Atom*)nfname)->toString(sfname);
	
	writecsv(sfname.c_str(), ncsvdata, delimiter);

	return 1;
}


void readfile(const char* fname, Node* &nstr)
{
	std::string str = "";
	
	FILE* fd = fopen(fname, "r");
	if (fd == NULL)	{
		fprintf(stderr, "can't open %s\n", fname);
		return;
	}

	int c;
	for (;;) {
		c = fgetc(fd);
		if (c == EOF) {
			break;
		}
		str += c;
	}

	fclose(fd);

	nstr = mka(str);
}

int readFile(Context* cx, Node* goalscar, List* module)
{
	Node* nvar = Nil;
	Node* nfilename = Nil;
	if (!Parm2(cx, goalscar, module, "usage : <strcode VAR STR>\n",
		"strcode: failed in the evaluation of the argument. \n",
		nvar, nfilename)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <readFile VAR filename>\n");
		return 0;
	}

	if (nfilename->kind() != ATOM) {
		syserr("usage : <readFile VAR filename>\n");
		return 0;
	}

	std::string str = "", sfilename = "";

	((Atom*)nfilename)->toString(sfilename);

	Node* nstr = Nil;

	readfile(sfilename.c_str(), nstr);

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(nstr);

	PushStack(cx, Nil, Nil, env);

	return 1;
}


void writefilesub(FILE* fd, Node* ndata, Node* ndelimiter)
{
	if (ndata == Nil) {
		return;
	} else if (ndata->kind() != LIST) {
		ndata->print(fd);
		return;
	}
	Node* ncar = ndata->Car();
	writefilesub(fd, ncar, ndelimiter);
	ndelimiter->print(fd);
	
	Node* ncdr = ndata->Cdr();
	writefilesub(fd, ncdr, ndelimiter);
	
}

void writefile(const char* fname, Node* ndata, Node* ndelimiter)
{
	FILE* fd;

	fd = fopen(fname, "w");
	if (fd == NULL) {
		fprintf(stderr, "can't open %s\n", fname);
		return;
	}

	writefilesub(fd, ndata, ndelimiter);

	fclose(fd);
}

int writeFile(Context* cx, Node* goalscar, List* module)
{
	int len = ListLength(goalscar->Cdr());
	if ((len != 2) && (len != 3)) {
		syserr("usage: ::sys <writeFile FILENAME LIST [DELIMITER]>\n");
		return 0;
	}

	Node* g = goalscar->Cdr()->Val();

	int rn;

	Node* nfname = g->Car()->Val();
	if ((rn = FuncArg(cx, nfname, goalscar, module)) <= 0) {
		syserr("writeFile: failed in the evaluation of the argument. \n");
		return 0;
	}

	if (nfname->kind() != ATOM) {
		syserr("usage: ::sys <writeFile FILENAME LIST [DELIMITER]>\n");
		return 0;
	}

	g = g->Cdr();
	Node* ndata = g->Car()->Val();
	if ((rn = FuncArg(cx, ndata, goalscar, module)) <= 0) {
		syserr("writeFile: failed in the evaluation of the argument. \n");
		return 0;
	}
	
	Node* ndelimiter = mka("");
	if (len == 3) {
		g = g->Cdr();
		ndelimiter = g->Car()->Val();
		if ((rn = FuncArg(cx, ndelimiter, goalscar, module)) <= 0) {
			syserr("writeFile: failed in the evaluation of the argument. \n");
			return 0;
		}

		if (ndelimiter->kind() != ATOM) {
			syserr("usage: ::sys <writeFile FILENAME LIST [DELIMITER]>\n");
			return 0;
		}
	}
	
	std::string sfname = "";
	((Atom*)nfname)->toString(sfname);
	
	writefile(sfname.c_str(), ndata, ndelimiter);

	return 1;
}

void readrecordsub(Node* &n, char* sbuff, Node* nlist)
{
	if (nlist == Nil) {
		return;
	}
	
	Node* nl = nlist->Car();
	if (nl->kind() != ATOM) {
		n = Append(n, MkList(mka("")));
		readrecordsub(n, sbuff, nlist->Cdr());
        	return;
        }
                
	long long  len = 0;
	if (!((Atom*)nl)->toInt(len)) {
		n = Append(n, MkList(mka("")));
		readrecordsub(n, sbuff, nlist->Cdr());
        	return;
	}
	
	int  i, bytelen = 0;
	int  slen = strlen(sbuff);
	if (slen == 0) {
		n = Append(n, MkList(mka("")));
		readrecordsub(n, sbuff, nlist->Cdr());
        	return;
        }

	std::string s = "";

	for (i = 0; len > 0; len--, i++) {
		if (i >= slen) {
			break;
		}
		
		int l = CharLen((unsigned char)sbuff[i]);

		if (i+l > slen) {
			break;
		}

		int j;
		for (j = 0; j < l; j++) {
			if (i+j >= slen) {
				break;
			}

			s += sbuff[i+j];

			bytelen = j;
		}

		i += bytelen;

	}		

	n = Append(n, MkList(mka(s)));

	readrecordsub(n, sbuff+i, nlist->Cdr());

}

void readrecord(const char* fname, Node* &nrcd, Node* nlist)
{
	std::string str = "";
	nrcd = Nil;
	
	FILE* fd = fopen(fname, "r");
	if (fd == NULL)	{
		fprintf(stderr, "can't open %s\n", fname);
		return;
	}

	char* sbuff = (char*)malloc(1024*1024);
	if (sbuff == NULL) {
		fprintf(stderr, "can't get memory\n");
		return;
	}

	while (fgets(sbuff, 1024*1024, fd) != NULL) {
		sbuff[1024*1024-1] = 0;
		int i;
		int l = strlen(sbuff);
		for (i = 0; i < l; i++) {
			if ((sbuff[i] == 0x0d) || (sbuff[i] == 0x0a)) {
				sbuff[i] = 0;
			}
		}
		if (strlen(sbuff) <= 0) {
			continue;
		}
		Node* n = Nil;
		readrecordsub(n, sbuff, nlist);
		nrcd = Append(nrcd, MkList(n));
	}

	free(sbuff);

	fclose(fd);

}

int readRecord(Context* cx, Node* goalscar, List* module)
{
	Node* nvar   = Nil;
	Node* nfilename = Nil;
	Node* nlist  = Nil;
	if (!Parm3(cx, goalscar, module, "usage : <readRecord VAR filename NUM_LIST> \n",
		"readRecord: failed in the evaluation of the argument. \n",
		nvar, nfilename, nlist)) {
			return 0;
	}

	if (nvar->kind() != UNDEF) {
		syserr("usage : <readRecord VAR filename NUM_LIST> \n");
		return 0;
	}

	if (nfilename->kind() != ATOM) {
		syserr("usage : <readRecord VAR filename NUM_LIST> \n");
		return 0;
	}

	if (nlist->kind() != LIST) {
		syserr("usage : <readRecord VAR filename NUM_LIST> \n");
		return 0;
	}

	std::string str = "", sfilename = "";

	((Atom*)nfilename)->toString(sfilename);

	Node* nrcd = Nil;

	readrecord(sfilename.c_str(), nrcd, nlist);

	Node* env = Nil->Cons(Nil);
	 
	SetEnv(env, nvar);

	((Undef*)nvar)->Set(nrcd);

	PushStack(cx, Nil, Nil, env);

	return 1;
}

void writerecordsub2(FILE* fd, Node* ndatalist, Node* nnumlist)
{
	if (nnumlist->kind() != LIST) {
		return;
	}
	
	Node* nnl = nnumlist->Car();
	Node* ndl = ndatalist->Car();
	if (nnl->kind() != ATOM) {
		writerecordsub2(fd, ndatalist->Cdr(), nnumlist->Cdr());
        	return;
        }
                
	long long  len = 0;
	if (!((Atom*)nnl)->toInt(len)) {
		writerecordsub2(fd, ndatalist->Cdr(), nnumlist->Cdr());
        	return;
	}

	if (ndl->kind() != ATOM) {
		writerecordsub2(fd, ndatalist->Cdr(), nnumlist->Cdr());
		return;
	}
			
	std::string s;	
	((Atom*)ndl)->toString(s);
	const char* sbuff = s.c_str();
	int slen = CodeLen((char*)sbuff);
	
	int  i;

	if (len < slen) {
		for (i = 0; i < len; i++) {
			fputc('*', fd);
		}
	} else {
		int sl = 0;	
		for (i = 0; sl < len; i++, sl++) {
//printf("sl %d len %d slen %d \n", sl, len, slen);
			if (sl >= slen) {
				fputc(' ', fd);
				continue;
			} 
			int l = CharLen((unsigned char)sbuff[i]);

			char prs[l+1];
			int j;
			for (j = 0; j < l; j++) {
				prs[j] = sbuff[i + j];
			}
			prs[l] = 0;

			fputs(prs, fd);
			i += l-1;
		}

	}		

	writerecordsub2(fd, ndatalist->Cdr(), nnumlist->Cdr());

}

void writerecordsub(FILE* fd, Node* ndatalist, Node* nnumlist)
{
	if (ndatalist->kind() != LIST) {
		return;
	}

	Node* n = Nil;

	for (n = ndatalist; n->kind() == LIST; n = n->Cdr()) {
		writerecordsub2(fd, n->Car(), nnumlist);
		fprintf(fd, "\n");
	}
}

void writerecord(char* fname, Node* ndatalist, Node* nnumlist)
{
	FILE* fd;

	fd = fopen(fname, "w");
	if (fd == NULL) {
		fprintf(stderr, "can't open %s\n", fname);
		return;
	}

	writerecordsub(fd, ndatalist, nnumlist);

	fclose(fd);
}

int writeRecord(Context* cx, Node* goalscar, List* module)
{
	Node* nfname   = Nil;
	Node* ndatalist = Nil;
	Node* nnumlist  = Nil;
	if (!Parm3(cx, goalscar, module, "usage: <writeRecord FILENAME DATA_LIST NUM_LIST>\n",
		"writeRecord: failed in the evaluation of the argument. \n",
		nfname, ndatalist, nnumlist)) {
			return 0;
	}

	if (nfname->kind() != ATOM) {
		syserr("usage: ::sys <writeRecord FILENAME DATA_LIST NUM_LIST>\n");
		return 0;
	}

	if (ndatalist->kind() != LIST) {
		syserr("usage: ::sys <writeRecord FILENAME DATA_LIST NUM_LIST>\n");
		return 0;
	}

	if (nnumlist->kind() != LIST) {
		syserr("usage: ::sys <writeRecord FILENAME DATA_LIST NUM_LIST>\n");
		return 0;
	}
	
	std::string sfname = "";
	((Atom*)nfname)->toString(sfname);
	
	writerecord((char*)sfname.c_str(), ndatalist, nnumlist);

	return 1;
}


