#include <windows.h>
#include "AScript.h"
#include "Parser.h"
#include "Module_builtins.h"
#include "Module_os.h"
#include "Module_time.h"
#include "Module_string.h"

int _tmain(int argc, const TCHAR *argv[])
{
	::init_gen_rand(1234);	// initialize random generator SFMT
	AScript::Signal sig;
	AScript::Parser parser;
	AScript::EnvironmentRoot env;
	env.SetupBuiltIn(sig, argc, argv);
	AScript::Module___builtins__::MixIn(env, sig);
	AScript::Module_os::Import(env, sig);
	AScript::Module_time::Import(env, sig);
	AScript::Module_string::Import(env, sig);
	if (argc >= 2) {
		AScript::File file;
		file.Open(sig, argv[1], _T("rt"));
		if (sig.IsSignalled()) {
			env.PutString(sig.GetErrString().c_str());
			env.PutString(_T("\n"));
			return 1;
		}
		parser.Exec(env, sig, file, true);
		if (sig.IsSignalled()) {
			env.PutString(sig.GetErrString().c_str());
			env.PutString(_T("\n"));
			sig.ClearSignal();
		}
		file.Close();
		return 0;
	}
	env.SetEchoFlag(true);
	env.PutPrompt(false);
	for (;;) {
		int ch = ::fgetc(stdin);
		AScript::Expr *pExpr = parser.ParseChar(env, sig, ch);
		if (sig.IsSignalled()) {
			env.PutString(sig.GetErrString().c_str());
			env.PutString(_T("\n"));
			sig.ClearSignal();
		} else if (pExpr != NULL) {
			AScript::Value result = pExpr->Exec(env, sig);
			if (sig.IsSignalled()) {
				env.PutString(sig.GetErrString().c_str());
				env.PutString(_T("\n"));
				sig.ClearSignal();
			} else if (!env.GetEchoFlag()) {
				// nothing to do
			} else if (result.IsValid()) {
				env.PutString(result.ToString(sig).c_str());
				env.PutString(_T("\n"));
			}
			delete pExpr;
		}
		if (ch < 0) break;
		if (ch == _T('\n')) env.PutPrompt(parser.IsContinued());
	}
	return 0;
}
