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

📄 runner.h

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

#ifndef RUNNER_H_
#define RUNNER_H_

#include "program.h"
#include "error.h"
#include "file.h"
#include "result.h"
#include "runnerline.h"

#include <stack>
#include <vector>
#include <map>

class Element {
public:
	Element (ProgramPos ppos) :
		ppos (ppos)
	{ }
	ProgramPos getpos () { return ppos; }
private:
	ProgramPos ppos;
};

class ForElement : public Element {
public:
	ForElement (const std::string & nvar, ProgramPos pos) :
		Element (pos),
		varname (nvar)
	{ }
	virtual bool next ()= 0;
	bool isvar (const std::string & nvar)
	{ return varname == nvar; }
	virtual ~ForElement () { }
private:
	ForElement (const ForElement &); // Forbidden
	ForElement & operator = (const ForElement &); // Forbidden
	std::string varname;
};

class ForElementNumber : public ForElement {
public:
	ForElementNumber (const std::string & nvar,
			ProgramPos pos,
		        BlNumber initial, BlNumber nmax, BlNumber nstep) :
		ForElement (nvar, pos),
		max (nmax),
		step (nstep)
	{
		varaddr= addrvarnumber (nvar);
		* varaddr= initial;
	}
	bool next ()
	{
		* varaddr+= step;
		if (step >= 0)
			return * varaddr <= max;
		else
			return *varaddr >= max;
	}
private:
        BlNumber * varaddr, max, step;
};

class ForElementInteger : public ForElement {
public:
	ForElementInteger (const std::string & nvar,
			ProgramPos pos,
			BlInteger initial, BlInteger nmax, BlInteger nstep) :
		ForElement (nvar, pos),
		max (nmax),
		step (nstep)
	{
		varaddr= addrvarinteger (nvar);
		* varaddr= initial;
	}
	bool next ()
	{
		* varaddr+= step;
		if (step >= 0)
			return * varaddr <= max;
		else
			return * varaddr >= max;
	}
private:
	BlInteger * varaddr, max, step;
};

class RepeatElement : public Element {
public:
	RepeatElement (ProgramPos pos) :
		Element (pos)
	{ }
};

class WhileElement : public Element {
public:
	WhileElement (ProgramPos pos) :
		Element (pos)
	{ }
};

class LocalLevel {
public:
	LocalLevel ();
	LocalLevel (const LocalLevel & ll);
	~LocalLevel ();
	LocalLevel & operator= (const LocalLevel & ll);
	void addlocal (const std::string & name);
	void freelocals ();
private:
	class Internal;
	Internal * pi;
};

class GosubElement : public Element, public LocalLevel {
public:
	GosubElement (ProgramPos pos) :
		Element (pos)
	{ }
	GosubElement (LocalLevel & ll) :
		Element (0),
		LocalLevel (ll)
	{ }
};

class GosubStack {
public:
	void push (ProgramPos pos)
	{
		st.push (GosubElement (pos) );
	}
	void push (LocalLevel & ll)
	{
		st.push (GosubElement (ll) );
	}
	void pop (ProgramPos & ppos)
	{
		if (st.empty () )
			throw ErrReturnWithoutGosub;
		GosubElement go= st.top ();
		ppos= go.getpos ();
		go.freelocals ();
		st.pop ();
	}
	void addlocal (const std::string & name)
	{
		if (st.empty () )
			throw ErrMisplacedLocal;
		GosubElement go= st.top ();
		go.addlocal (name);
	}
private:
	std::stack <GosubElement> st;
};

class Runner {
public:
	Runner (Program & prog);
        ~Runner ();
        void getline (std::string & line);
	void runline (CodeLine & codeline);
	void run ();
	void interactive ();

	BlErrNo geterr () const { return berrLast.geterr (); }
	ProgramPos geterrpos () const { return berrLast.getpos (); }
	BlLineNumber geterrline () const
		{ return berrLast.getpos ().getnum (); }
	void clearerror () { berrLast= BlError (); }
	void seterror (const BlError & er) { berrLast= er; }

	//ProgramPos getposactual () const { return posactual; }
	ProgramPos getposactual () const { return runnerline.getposactual (); }
	//void setposactual (ProgramPos pos) { posactual= pos; }
	//void setchunkactual (BlChunk chunk) { posactual.setchunk (chunk); }

	void setstatus (StatusProgram stat) { status= stat; }
	void run_to (BlLineNumber line)
	{
		posgoto= line;
		status= ProgramReadyToRun;
	}
	void run_to (ProgramPos pos)
	{
		posgoto= pos;
		status= ProgramReadyToRun;
	}
	void jump_to (BlLineNumber line)
	{
		posgoto= line;
		status= ProgramJump;
	}
	void jump_to (ProgramPos pos)
	{
		posgoto= pos;
		status= ProgramJump;
	}

	void push_for (ForElement * pfe)
	{
		forstack.push (pfe);
	}
	//bool for_empty () const { return forstack.empty (); }
	ForElement & for_top ()
	{
		if (forstack.empty () )
			throw ErrNextWithoutFor;
		return * forstack.top ();
	}
	void for_pop () { delete forstack.top (); forstack.pop (); }

	void gosub_pop (ProgramPos & pos) { gosubstack.pop (pos); }
	void gosub_addlocal (const std::string & str)
		{ gosubstack.addlocal (str); }
	void gosub_push (LocalLevel & ll)
		{ gosubstack.push (ll); }

	bool repeat_empty () const { return repeatstack.empty (); }
	void repeat_pop () { repeatstack.pop (); }
	RepeatElement & repeat_top () { return repeatstack.top (); }
	void repeat_push (const RepeatElement & re) { repeatstack.push (re); }

	bool in_wend () { return fInWend; }
	void in_wend (bool f) { fInWend= f; }
	bool while_empty () { return whilestack.empty (); }
	void while_pop () { whilestack.pop (); }
	WhileElement & while_top () { return whilestack.top (); }
	void while_push (const WhileElement & we) { whilestack.push (we); }
	
	void tron (bool fLine, BlChannel blc)
	{
		fTron= true;
		fTronLine= fLine;
		blcTron= blc;
	}
	void troff () { fTron= false; }
	void jump_break ()
	{
		if (! posbreak)
			throw ErrNoContinue;
		posgoto= posbreak;
		posbreak= 0;
		status= ProgramJump;
	}
	void set_break (ProgramPos pos) { posbreak= pos; }

	BlLineNumber & getdatanumline () { return datanumline; }
	BlChunk & getdatachunk () { return datachunk; }
	unsigned short & getdataelem () { return dataelem; }

	void seterrorgoto (BlLineNumber line) { blnErrorGoto= line; }
	BlLineNumber geterrorgoto () { return blnErrorGoto; }
	void assign_channel_var
		(const std::string & var, const std::string & value,
			BlFile::Align align)
	{
		for (ChanFile::iterator it= chanfile.begin ();
			it != chanfile.end ();
			++it)
		{
			it->second->assign (var, value, align);
		}
	}

        typedef std::map <BlChannel,BlFile *> ChanFile;
        bool isfileopen (BlChannel channel) const
        	{ return chanfile.find (channel) != chanfile.end (); }
        BlFile & getfile (BlChannel channel);
        void setfile (BlChannel channel, BlFile * npfile);
        void close_all ();
        void closechannel (BlChannel channel);
	void setreadline (BlLineNumber bln);
        void goto_line (BlLineNumber dest);
        void gosub_line (BlLineNumber dest, ProgramPos posgosub);
	enum BreakState { BreakStop, BreakCont, BreakGosub };
	void setbreakstate (BreakState newstate)
	{
		breakstate= newstate;
	}
	BreakState getbreakstate () { return breakstate; }
	void setbreakgosub (BlLineNumber bln)
	{
		breakstate= BreakGosub;
		breakgosubline= bln;
	}
	BlLineNumber getbreakgosub () { return breakgosubline; }
	void setauto (BlLineNumber line, BlLineNumber inc)
	{ blnAuto= line; blnAutoInc= inc; }
private:
	Program & program;
	StatusProgram status;
	bool fTron, fTronLine;
	BlChannel blcTron;
	bool fInElse;
        bool fInWend;
	//ProgramPos posactual;
	ProgramPos posgoto;

	BlLineNumber datanumline;
	BlChunk datachunk;
	unsigned short dataelem;
	CodeLine line;
	RunnerLine runnerline;
        ChanFile chanfile;
	BlCode codprev;
        BlError berrLast;
        BlLineNumber blnErrorGoto;

	BreakState breakstate;
	BlLineNumber breakgosubline;
	ProgramPos posbreak;

	BlLineNumber blnAuto, blnAutoInc;

	std::stack <ForElement *, std::vector <ForElement *> > forstack;
	GosubStack gosubstack;
	std::stack <RepeatElement> repeatstack;
        std::stack <WhileElement> whilestack;

        void tronline (BlLineNumber n);
        bool checkstatus (CodeLine & line, const CodeLine & line0);
        bool processline (const std::string & line);
};

#endif

// Fin de runner.h

⌨️ 快捷键说明

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