4 #include "sqpcheader.h" 9 #include "sqcompiler.h" 12 #define CUR_CHAR (_currdata) 13 #define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;} 14 #define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB) 15 #define NEXT() {Next();_currentcolumn++;} 16 #define INIT_TEMP_STRING() { _longstr.resize(0);} 17 #define APPEND_CHAR(c) { _longstr.push_back(c);} 18 #define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));} 19 #define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id)) 27 void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,
void *ed)
32 _keywords = SQTable::Create(ss, 26);
74 _lasttokenline = _currentline = 1;
80 void SQLexer::Error(
const SQChar *err)
82 _errfunc(_errtarget,err);
87 SQInteger t = _readf(_up);
88 if(t > MAX_CHAR) Error(_SC(
"Invalid character"));
90 _currdata = (LexChar)t;
93 _currdata = SQUIRREL_EOB;
96 const SQChar *SQLexer::Tok2Str(SQInteger tok)
98 SQObjectPtr itr, key, val;
100 while((nitr = _keywords->Next(
false,itr, key, val)) != -1) {
101 itr = (SQInteger)nitr;
102 if(((SQInteger)_integer(val)) == tok)
103 return _stringval(key);
108 void SQLexer::LexBlockComment()
113 case _SC(
'*'): {
NEXT();
if(
CUR_CHAR == _SC(
'/')) { done =
true;
NEXT(); }};
continue;
114 case _SC(
'\n'): _currentline++;
NEXT();
continue;
115 case SQUIRREL_EOB: Error(_SC(
"missing \"*/\" in comment"));
121 SQInteger SQLexer::Lex()
123 _lasttokenline = _currentline;
126 case _SC(
'\t'):
case _SC(
'\r'):
case _SC(
' '):
NEXT();
continue;
129 _prevtoken=_curtoken;
187 Error(_SC(
"string expected"));
188 if((stype=ReadString(
'"',
true))!=-1) {
191 Error(_SC(
"error parsing the string"));
196 if((stype=ReadString(
CUR_CHAR,
false))!=-1){
199 Error(_SC(
"error parsing the string"));
201 case _SC(
'{'):
case _SC(
'}'):
case _SC(
'('):
case _SC(
')'):
case _SC(
'['):
case _SC(
']'):
202 case _SC(
';'):
case _SC(
','):
case _SC(
'?'):
case _SC(
'^'):
case _SC(
'~'):
209 if (
CUR_CHAR != _SC(
'.')){ Error(_SC(
"invalid token '..'")); }
246 SQInteger ret = ReadNumber();
250 SQInteger t = ReadID();
255 if (sciscntrl((
int)c)) Error(_SC(
"unexpected character(control)"));
266 SQInteger SQLexer::GetIDType(
SQChar *s)
269 if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {
270 return SQInteger(_integer(t));
272 return TK_IDENTIFIER;
276 SQInteger SQLexer::ReadString(SQInteger ndelim,
bool verbatim)
285 Error(_SC(
"unfinished string"));
288 if(!verbatim) Error(_SC(
"newline in a constant"));
299 case _SC(
'x'):
NEXT(); {
300 if(!isxdigit(
CUR_CHAR)) Error(_SC(
"hexadecimal number expected"));
301 const SQInteger maxdigits = 4;
304 while(isxdigit(
CUR_CHAR) && n < maxdigits) {
326 Error(_SC(
"unrecognised escaper char"));
346 SQInteger len = _longstr.size()-1;
347 if(ndelim == _SC(
'\'')) {
348 if(len == 0) Error(_SC(
"empty constant"));
349 if(len > 1) Error(_SC(
"constant too long"));
350 _nvalue = _longstr[0];
353 _svalue = &_longstr[0];
354 return TK_STRING_LITERAL;
362 if(scisdigit(*s)) *res = (*res)*16+((*s++)-
'0');
363 else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-
'A'+10);
373 *res = (*res)*10+((*s++)-
'0');
377 SQInteger
scisodigit(SQInteger c) {
return c >= _SC(
'0') && c <= _SC(
'7'); }
384 if(
scisodigit(*s)) *res = (*res)*8+((*s++)-
'0');
389 SQInteger
isexponent(SQInteger c) {
return c ==
'e' || c==
'E'; }
392 #define MAX_HEX_DIGITS (sizeof(SQInteger)*2) 393 SQInteger SQLexer::ReadNumber()
398 #define TSCIENTIFIC 4 411 if(scisdigit(
CUR_CHAR)) Error(_SC(
"invalid octal number"));
420 if(_longstr.size() >
MAX_HEX_DIGITS) Error(_SC(
"too many digits for an Hex number"));
429 if(type !=
TFLOAT) Error(_SC(
"invalid numeric format"));
437 if(!scisdigit(
CUR_CHAR)) Error(_SC(
"exponent expected"));
448 _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
451 LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
457 LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
463 SQInteger SQLexer::ReadID()
472 res = GetIDType(&_longstr[0]);
473 if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
474 _svalue = &_longstr[0];
SQInteger scisodigit(SQInteger c)
#define INIT_TEMP_STRING()
#define ADD_KEYWORD(key, id)
void LexHexadecimal(const SQChar *s, SQUnsignedInteger *res)
#define TERMINATE_BUFFER()
void LexInteger(const SQChar *s, SQUnsignedInteger *res)
SQInteger isexponent(SQInteger c)
void LexOctal(const SQChar *s, SQUnsignedInteger *res)
const wxChar null(_T('\0'))