📄 runnerline.cpp
字号:
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 + -