⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blassic.cpp

📁 由一个古老的BASIC解释器改进而成, 保留了ANSI C固有的艺术美感.
💻 CPP
字号:
//	blassic.cpp

#include <assert.h>

#include <string>
#include <iostream>

#include "blassic.h"

#include "token.h"
#include "keyword.h"
#include "var.h"
//#include "codeline.h"
//#include "program.h"
#include "runner.h"
#include "cursor.h"
#include "file.h"
#include "graphics.h"
#include "sysvar.h"
#include "trace.h"
#include "util.h"

#include <fstream>
//#include <iomanip>
#include <sstream>
#include <signal.h>

#include "error.h"

#ifndef _Windows
#include <unistd.h>
#endif

#if defined __BORLANDC__ && defined _Windows
        #include <condefs.h>
#else
        #define USEUNIT(a)
#endif

USEUNIT("codeline.cpp");
USEUNIT("error.cpp");
USEUNIT("keyword.cpp");
USEUNIT("program.cpp");
USEUNIT("runner.cpp");
USEUNIT("token.cpp");
USEUNIT("var.cpp");
USEUNIT("dim.cpp");
USEUNIT("file.cpp");
USEUNIT("cursor.cpp");
USEUNIT("graphics.cpp");
USEUNIT("sysvar.cpp");
USEUNIT("version.cpp");
USEUNIT("trace.cpp");
USEUNIT("socket.cpp");
USEUNIT("runnerline.cpp");
USEUNIT("function.cpp");
USEUNIT("key.cpp");
USEUNIT("charset.cpp");
USEUNIT("edit.cpp");
//---------------------------------------------------------------------------

//************************************************
//	Global variables
//************************************************

bool fInterrupted= false;

const std::string strPrompt ("Ok\n");

//************************************************
//	Local functions and classes
//************************************************

namespace {

void handle_sigint (int)
{
	fInterrupted= true;
        #ifdef __WIN32__
        signal (SIGINT, handle_sigint);
        signal (SIGBREAK, handle_sigint);
        #endif
}

void init_signal_handlers ()
{
	TraceFunc tr ("init_signal_handlers");
        #ifdef __WIN32__

        signal (SIGINT, handle_sigint);
        signal (SIGBREAK, handle_sigint);

        #else

	struct sigaction act;
	act.sa_handler= handle_sigint;
	act.sa_flags= 0;
	sigaction (SIGINT, & act, 0);

	signal (SIGUSR1, TraceFunc::show);

        #endif
}

class Initializer {
public:
        Initializer (const char * progname) :
        	detached_graphics (false),
        	detached_text (false)
	{
		TraceFunc tr ("Initializer::Initializer");

		initconsole ();
		graphics::initialize (progname);
	}
        ~Initializer ()
	{
		TraceFunc tr ("Initializer::~Initializer");

		if (! detached_graphics)
			graphics::uninitialize ();
		if (! detached_text)
			quitconsole ();
	}
	void detachgraphics () { detached_graphics= true; }
	void detachtext () { detached_text= true; }
private:
	bool detached_graphics;
	bool detached_text;
};

std::vector <std::string> args;

void setprogramargs (char * * argv, size_t n)
{
	TraceFunc tr ("setprogramargs");

	sysvar::set16 (sysvar::NumArgs, short (n) );
	args.clear ();
	std::copy (argv, argv + n, std::back_inserter (args) );
}

} // namespace

void setprogramargs (const std::vector <std::string> & nargs)
{
	TraceFunc tr ("setprogramargs");

	sysvar::set16 (sysvar::NumArgs, short (nargs.size () ) );
	args= nargs;
}

std::string getprogramarg (size_t n)
{
	//if (n >= num_args)
	if (n >= args.size () )
		return std::string ();
	//return std::string (args [n]);
	return args [n];
}

int blassic (int argc, char * * argv)
{
        using std::cin;
        using std::cout;
        using std::cerr;
        using std::endl;
        using std::flush;

	TraceFunc tr ("blassic");

        //cout << std::setprecision (16);
       	init_signal_handlers ();
	sysvar::init ();
	Initializer initializer (argv [0] );

	CodeLine code;
	Program program;
	Runner runner (program);

	int n= 1;
	while (n < argc)
	{
		if (strcmp (argv [n], "-e") == 0)
		{
			if (++n == argc)
				throw "Option e needs argument";
			std::string line;
			line= argv [n];
			code.scan (line);
			if (code.number () != 0)
			{
				program.insert (code);
				try
				{
					runner.run ();
				}
				catch (BlError & be)
				{
					cerr << be;
				}
				return 0;
			}
			try
			{
				runner.runline (code);
			}
			catch (BlError & be)
			{
				cerr << be;
			}
			return 0;
		}
		else if (strcmp (argv [n], "-a") == 0)
		{
			if (++n == argc)
				throw "Option a needs argument";
			std::istringstream iss (argv [n]);
			BlLineNumber ini;
			iss >> ini;
			char c= char (iss.get () );
			if (! iss.eof () )
			{
				if (c != ',')
					throw "Bad parameter";
				BlLineNumber inc;
				iss >> inc;
				if (! iss)
					throw "Bad parameter";
				iss >> c;
				if (! iss.eof () )
					throw "Bad parameter";
				sysvar::set32 (sysvar::AutoInc, inc);
			}
			sysvar::set32 (sysvar::AutoInit, ini);
			++n;
		}
		else if (strcmp (argv [n], "-d") == 0)
		{
			#ifdef __WIN32__

			FreeConsole ();

			#else

			switch (fork () )
			{
			case pid_t (-1):
				throw "Error en fork";
			case pid_t (0):
				//cerr << "child" << flush;
				for (int i= 0; i < 3; ++i)
					if (isatty (i) )
						close (i);
				initializer.detachtext ();
				break;
			default:
				//cerr << "parent" << flush;
				initializer.detachgraphics ();
				return 0;
			}

			#endif

			++n;
		}
		else if (strcmp (argv [n], "-m") == 0)
		{
			if (++n == argc)
				throw "Option m needs argument";
			int mode= atoi (argv [n] );
			std::string str (argv [n] );
			std::string::size_type x= str.find ('x');
			if (x != std::string::npos)
			{
				int mode2= atoi (str.c_str () + x + 1);
				graphics::setmode (mode, mode2, false);
			}
			else
				if (mode != 0)
					graphics::setmode (mode);
			++n;
		}
		else
		{
			try
			{
				short narg= short (argc - n - 1);
				setprogramargs (argv + n + 1, narg);
				program.load (argv [n] );
				runner.run ();
			}
			catch (BlError & be)
			{
				cerr << be;
			}
			return 0;
		}
	}

	runner.interactive ();

	return 0;
}

//************************************************
//		main
//************************************************

int main (int argc, char * * argv)
{
	using std::cerr;
	using std::endl;

	TraceFunc tr ("main");
        int r;

	try {
		r= blassic (argc, argv);
		std::ostringstream oss;
		oss << "Returning " << r << " without exception.";
		tr.message (oss.str () );
	}
	catch (BlErrNo ben) {
		cerr << ErrStr (ben) << endl;
		tr.message (ErrStr (ben) );
		r= 127;
	}
	catch (BlError & be) {
		cerr << be;
		tr.message (util::to_string (be) );
		r= 127;
	}
	catch (std::exception & e)
	{
		cerr << e.what () << endl;
		tr.message (e.what () );
		r= 127;
	}
	catch (Exit & e) {
		r= e.code ();
		tr.message (util::to_string (r) );
	}
	catch (const char * str) {
		cerr << str << endl;
		tr.message (str);
		r= 127;
	}
	catch (...) {
		cerr << "Unexpected error." << endl;
		tr.message ("Unexpected error.");
		r= 127;
        }
	return r;
}

// Fin de blassic.cpp

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -