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

📄 runnerline.cpp

📁 由一个古老的BASIC解释器改进而成, 保留了ANSI C固有的艺术美感.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			break;
		}
		str= std::string ("0 ") + str;
		{
			CodeLine code;
			code.scan (str);
			RunnerLine runline (runner, code, program);
			runline.expect (result);
			if (runline.token.code != keyENDLINE)
				throw ErrSyntax;
		}
		if (! result.is_numeric () )
			throw ErrMismatch;
		break;
	default:
		throw ErrNotImplemented;
	}
}

void RunnerLine::valeof (BlResult & result)
{
	getparenarg (result);
	BlChannel channel= BlChannel (result.number () );
	BlFile & file= getfile (channel);
	result= BlInteger (file.eof () ? -1 : 0);
}

void RunnerLine::valvarptr (BlResult & result)
{
	expecttoken ('(');
	expecttoken (keyIDENTIFIER);
	std::string varname (token.str);
	VarType type= typeofvar (varname);
	size_t addr= 0;
	gettoken ();
	switch (token.code)
	{
	case ')':
		// Simple
		switch (type)
		{
		case VarNumber:
			addr= reinterpret_cast <size_t>
				(addrvarnumber (varname) );
			break;
		case VarInteger:
			addr= reinterpret_cast <size_t>
				(addrvarinteger (varname) );
                        break;
		case VarString:
			addr= reinterpret_cast <size_t>
				(addrvarstring (varname) );
			break;
		default:
			throw ErrBlassicInternal;
		}
		result= 0;
		gettoken ();
		break;
	case '(':
		// Array
		{
		Dimension dims= expectdims ();
		result= 0;
		requiretoken (')');
		switch (type)
		{
		case VarNumber:
			addr= reinterpret_cast <size_t>
				(addrdimnumber (varname, dims) );
			break;
		case VarInteger:
			addr= reinterpret_cast <size_t>
				(addrdiminteger (varname, dims) );
			break;
		case VarString:
			addr= reinterpret_cast <size_t>
				(addrdimstring (varname, dims) );
			break;
		default:
			throw ErrBlassicInternal;
		}
		gettoken ();
		}
		break;
	default:
		throw ErrSyntax;
	}
	result= BlNumber (addr);
}

void RunnerLine::valsgn (BlResult & result)
{
	getparenarg (result);
	BlNumber d= result.number ();
	result= d < 0 ? -1 : d > 0 ? 1 : 0;
}

void RunnerLine::valcvi (BlResult & result)
{
        getparenarg (result);
        std::string str (result.str () );
        if (str.size () < 2)
                throw ErrFunctionCall;
	result= BlInteger (short ( (unsigned char) str [0] ) |
		short ( ( (unsigned char) str [1] ) << 8) );
}

void RunnerLine::valcvs (BlResult & result)
{
	#define SIZE_S 4
	COMPILE_ASSERT (sizeof (float) == 4);
	getparenarg (result);
	std::string str (result.str () );
	if (str.size () < SIZE_S)
		throw ErrFunctionCall;
	BlNumber bn= BlNumber
		(* reinterpret_cast <const float *> (str.data () ) );
	result= bn;
	#undef SIZE_S
}

void RunnerLine::valcvd (BlResult & result)
{
	#define SIZE_D 8
	COMPILE_ASSERT (sizeof (double) == 8);
	getparenarg (result);
	std::string str (result.str () );
	if (str.size () < SIZE_D)
		throw ErrFunctionCall;
	BlNumber bn= BlNumber (* reinterpret_cast <const double *> (str.data () ) );
	result= bn;
	#undef SIZE_D
}

void RunnerLine::valcvl (BlResult & result)
{
        getparenarg (result);
        std::string str (result.str () );
        if (str.size () < 4)
                throw ErrFunctionCall;
	result=
                long ( (unsigned char) str [0] ) |
                long ( ( (unsigned char) str [1] ) << 8) |
                long ( ( (unsigned char) str [2] ) << 16) |
                long ( ( (unsigned char) str [3] ) << 24);
}

void RunnerLine::valmin (BlResult & result)
{
        expecttoken ('(');
        BlNumber bnMin= expectnum ();
        while (token.code == ',')
                bnMin= std::min (bnMin, expectnum () );
        requiretoken (')');
        gettoken ();
        result= bnMin;
}

void RunnerLine::valmax (BlResult & result)
{
        expecttoken ('(');
        BlNumber bnMax= expectnum ();
        while (token.code == ',')
                bnMax= std::max (bnMax, expectnum () );
        requiretoken (')');
        gettoken ();
        result= bnMax;
}

void RunnerLine::valmid_s (BlResult & result)
{
	expecttoken ('(');
	std::string str= expectstring ();
	requiretoken (',');
	BlNumber blfrom= expectnum ();
	size_t from= size_t (blfrom) - 1;
	size_t len;
	if (token.code == ',')
	{
		BlNumber bllen= expectnum ();
		len= size_t (bllen);
	}
	else
		len= std::string::npos;
	requiretoken (')');
	if (from >= str.size () )
		result= std::string ();
	else
		result= str.substr (from, len);
	gettoken ();
}

void RunnerLine::valleft_s (BlResult & result)
{
	expecttoken ('(');
	std::string str= expectstring ();
	requiretoken (',');
	BlNumber blfrom= expectnum ();
	requiretoken (')');
	size_t from= size_t (blfrom);
	result= str.substr (0, from);
	gettoken ();
}

void RunnerLine::valright_s (BlResult & result)
{
	expecttoken ('(');
	std::string str= expectstring ();
	requiretoken (',');
	BlNumber blfrom= expectnum ();
	requiretoken (')');
	size_t from= size_t (blfrom);
	size_t l= str.size ();
	if (from < l)
		result= str.substr (str.size () - from);
	else
		result= str;
	gettoken ();
}

void RunnerLine::valchr_s (BlResult & result)
{
	getparenarg (result);
	result= std::string (1, (unsigned char) result.number () );
}

void RunnerLine::valenviron_s (BlResult & result)
{
	getparenarg (result);
	char * str= getenv (result.str ().c_str () );
	if (str)
		result= std::string (str);
	else
		result= std::string ();
}

void RunnerLine::valstring_s (BlResult & result)
{
	expecttoken ('(');
	expect (result);
	size_t rep= result.integer ();
	requiretoken (',');
	expect (result);
	requiretoken (')');
	gettoken ();
	BlChar charrep= '\0';
	switch (result.type () )
	{
	case VarNumber:
		charrep= BlChar ( (unsigned int) result.number () );
		break;
	case VarInteger:
		charrep= BlChar (result.integer () );
		break;
	case VarString:
		{
			const std::string & aux= result.str ();
			if (aux.empty () )
				charrep= '\0';
			else
				charrep= aux [0];
		}
		break;
	default:
		throw ErrBlassicInternal;
	}
	result= std::string (rep, charrep);
}

void RunnerLine::valosfamily_s (BlResult & result)
{
	gettoken ();
	result= std::string (os_family);
}

void RunnerLine::valosname_s (BlResult & result)
{
	gettoken ();

	#ifdef _Windows

	result= "Windows";

	#elif defined __unix__

	struct utsname buf;
	if (uname (&buf) != 0)
		result= "unknown";
	else
		result= buf.sysname;

	#else

	result= "unknown";

	#endif
}

void RunnerLine::valhex_s (BlResult & result)
{
	expecttoken ('(');
	expect (result);
	BlInteger n= result.integer ();
	size_t w= 0;
	if (token.code == ',')
	{
		expect (result);
		w= result.integer ();
	}
	requiretoken (')');
	gettoken ();
	std::ostringstream oss;
	oss.setf (std::ios::uppercase);
	oss << std::hex <<
		std::setw (w) << std::setfill ('0') <<
		n;
	result= oss.str ();
}

void RunnerLine::valspace_s (BlResult & result)
{
        getparenarg (result);
        result= std::string (size_t (result.number () ), ' ');
}

void RunnerLine::valupper_s (BlResult & result)
{
        getparenarg (result);
        std::string & str= result.str ();
        std::transform (str.begin (), str.end (), str.begin (), toupper);
}

void RunnerLine::vallower_s (BlResult & result)
{
        getparenarg (result);
        std::string & str= result.str ();
        std::transform (str.begin (), str.end (), str.begin (), tolower);
}

void RunnerLine::valstr_s (BlResult & result)
{
        getparenarg (result);
        std::ostringstream oss;
        oss << std::setprecision (10) << result.number ();
        result= oss.str ();
}

void RunnerLine::valoct_s (BlResult & result)
{
	expecttoken ('(');
	BlNumber n= expectnum ();
	size_t w= 0;
	if (token.code == ',')
	{
		BlNumber blw= expectnum ();
		w= size_t (blw);
	}
	requiretoken (')');
	gettoken ();
	std::ostringstream oss;
	oss.setf (std::ios::uppercase);
	oss << std::oct <<
                std::setw (w) << std::setfill ('0') <<
		(unsigned long) n;
	result= oss.str ();
}

void RunnerLine::valbin_s (BlResult & result)
{
	expecttoken ('(');
	BlNumber bn= expectnum ();
	size_t w= 0;
	if (token.code == ',')
	{
		BlNumber blw= expectnum ();
		w= size_t (blw);
	}
	requiretoken (')');
	gettoken ();
        unsigned long n= (unsigned long) bn;
        std::string str;
        while (n)
        {
                str= ( (n & 1) ? '1' : '0') + str;
                n/= 2;
        }
        if (str.empty () )
                str= std::string (1, '0');
        if (w > 0 && str.size () < w)
                str= std::string (w - str.size (), '0') + str;
	result= str;
}

void RunnerLine::valinkey_s (BlResult & result)
{
        gettoken ();
        result= inkey ();
}

void RunnerLine::valprogramarg_s (BlResult & result)
{
	getparenarg (result);
	result= getprogramarg (size_t (result.number () - 1) );
}

void RunnerLine::valdate_s (BlResult & result)
{
        using std::setw;
        using std::setfill;

	gettoken ();
	std::time_t t= time (NULL);
	struct std::tm * ptm= std::localtime (& t);
	std::ostringstream oss;
	oss << setw (2) << setfill ('0') << (ptm->tm_mon + 1) << '-' <<
		setw (2) << setfill ('0') << ptm->tm_mday << '-' <<
		(ptm->tm_year + 1900);
	result= oss.str ();
}

void RunnerLine::valtime_s (BlResult & result)
{
        using std::setw;
        using std::setfill;

	gettoken ();
	std::time_t t= time (NULL);
	struct std::tm * ptm= std::localtime (& t);
	std::ostringstream oss;
	oss << setw (2) << setfill ('0') << ptm->tm_hour << ':' <<
		setw (2) << setfill ('0') << ptm->tm_min << ':' <<
		setw (2) << setfill ('0') << ptm->tm_sec;
	result= oss.str ();
}

void RunnerLine::valinput_s (BlResult & result)
{
	expecttoken ('(');
	BlNumber bn= expectnum ();
	BlChannel channel= 0;
	switch (token.code)
	{
	case ')':
		break;
	case ',':
		gettoken ();
		if (token.code == '#')
			channel= expectchannel ();
		requiretoken (')');
		break;
	default:
		throw ErrSyntax;
	}
	gettoken ();
	BlFile & in= getfile (channel);
	result= in.read (size_t (bn) );
}

void RunnerLine::valmki_s (BlResult & result)
{
        getparenarg (result);
        BlNumber bn= result.number ();
        unsigned short s= (unsigned short) short (bn);
        std::string str;
        str= char (s & 255);
        str+= char (s >> 8);
        result= str;
}

void RunnerLine::valmks_s (BlResult & result)
{
	getparenarg (result);
	float f= result.number ();
	std::string str (reinterpret_cast <char *> (& f), sizeof (float) );
	result= str;
}

void RunnerLine::valmkd_s (BlResult & result)
{
	getparenarg (result);
	double f= result.number ();
	std::string str (reinterpret_cast <char *> (& f), sizeof (double) );
	result= str;
}

void RunnerLine::valmkl_s (BlResult & result)
{
        getparenarg (result);
        BlNumber bn= result.number ();
        unsigned int s= (unsigned int) int (bn);
        std::string str;
        str= char (s & 255);
        str+= char ( (s >> 8) & 255);
        str+= char ( (s >> 16) & 255);
        str+= char ( (s >> 24) & 255);
        result= str;
}

void RunnerLine::valtrim (BlResult & result)
{
	using std::string;

	bool tleft= false, tright= false;
	switch (token.code)
	{
	case keyTRIM_S:
		tleft= true; tright= true;
		break;
	case keyLTRIM_S:
		tleft= true;
		break;
	case keyRTRIM_S:
		tright= true;
		break;
	default:
		cerr << "Llamada erronea a valtrim" << endl;
		throw ErrBlassicInternal;
	}
	getparenarg (result);
	string str= result.str ();
	if (tleft)
	{
		string::size_type
			inipos= str.find_first_not_of (' ');
		if (inipos > 0)
			if (inipos == string::npos)
				str= string ();
			else
				//str= str.substr (inipos);
				str.erase (0, inipos);
	}
	if (tright)
	{
		string::size_type
			endpos=  str.find_last_not_of (' ');
		if (endpos != string::npos)
			//str= str.substr (0, endpos + 1);
			str.erase (endpos + 1);
		else str= string ();
	}
	result= str;
}

void RunnerLine::valfn (BlResult & result)
{
        expecttoken (keyIDENTIFIER);
	std::string fname= token.str;
        Function f= Function::get (fname);
        gettoken ();
        // Abusamos de GosubElement para aprovechar la gestion
        // de variables locales.
        //GosubElement ge (0);
        // Ya no
	LocalLevel ll;
        const ParameterList & param= f.getparam ();
        size_t l= param.size ();
        if (l != 0)
        {
		requiretoken ('(');
                for (size_t i= 0; i < l; ++i)
                {
                        BlResult aux;
                        expect (result);
                        //const std::string & var= param [i];
                        std::string var= param [i];
                        ll.addlocal (var);
                        VarType type= typeofvar (var);
                        switch (type)
                        {
                        case VarNumber:
                                assignvarnumber (var, result.number () );
                                break;
			case VarInteger:
				assignvarinteger (var, result.integer () );
				break;
                        case VarString:
                                assignvarstring (var, result.str () );
                                break;
                        default:
                                throw ErrBlassicInternal;
                        }
                        if (i < l - 1)
				requiretoken (',');
                }
		requiretoken (')');
                gettoken ();
        }

⌨️ 快捷键说明

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