ADD_KEYWORD(vargv,TK_VARGV);
ADD_KEYWORD(true,TK_TRUE);
ADD_KEYWORD(false,TK_FALSE);
+ ADD_KEYWORD(static,TK_STATIC);
+ ADD_KEYWORD(enum,TK_ENUM);
+ ADD_KEYWORD(const,TK_CONST);
_readf = rg;
_up = up;
SQInteger t = _readf(_up);
if(t > MAX_CHAR) Error(_SC("Invalid character"));
if(t != 0) {
- _currdata = t;
+ _currdata = (LexChar)t;
return;
}
_currdata = SQUIRREL_EOB;
}
-const SQChar *SQLexer::Tok2Str(int tok)
+const SQChar *SQLexer::Tok2Str(SQInteger tok)
{
SQObjectPtr itr, key, val;
- int nitr;
- while((nitr = _keywords->Next(itr, key, val)) != -1) {
+ SQInteger nitr;
+ while((nitr = _keywords->Next(false,itr, key, val)) != -1) {
itr = (SQInteger)nitr;
- if(((int)_integer(val)) == tok)
+ if(((SQInteger)_integer(val)) == tok)
return _stringval(key);
}
return NULL;
while(!done) {
switch(CUR_CHAR) {
case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
- //case _SC('/'): { NEXT(); if(CUR_CHAR == _SC('*')) { nest++; NEXT(); }}; continue;
case _SC('\n'): _currentline++; NEXT(); continue;
case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
default: NEXT();
}
}
-int SQLexer::Lex()
+SQInteger SQLexer::Lex()
{
_lasttokenline = _currentline;
while(CUR_CHAR != SQUIRREL_EOB) {
if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
else { NEXT(); RETURN_TOKEN(TK_NE); }
case _SC('@'): {
- int stype;
+ SQInteger stype;
NEXT();
if(CUR_CHAR != _SC('"'))
Error(_SC("string expected"));
}
case _SC('"'):
case _SC('\''): {
- int stype;
+ SQInteger stype;
if((stype=ReadString(CUR_CHAR,false))!=-1){
RETURN_TOKEN(stype);
}
}
case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):
- {int ret = CUR_CHAR;
+ {SQInteger ret = CUR_CHAR;
NEXT(); RETURN_TOKEN(ret); }
case _SC('.'):
NEXT();
return 0;
default:{
if (scisdigit(CUR_CHAR)) {
- int ret = ReadNumber();
+ SQInteger ret = ReadNumber();
RETURN_TOKEN(ret);
}
else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
- int t = ReadID();
+ SQInteger t = ReadID();
RETURN_TOKEN(t);
}
else {
- int c = CUR_CHAR;
- if (sciscntrl(c)) Error(_SC("unexpected character(control)"));
+ SQInteger c = CUR_CHAR;
+ if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
NEXT();
RETURN_TOKEN(c);
}
return 0;
}
-int SQLexer::GetIDType(SQChar *s)
+SQInteger SQLexer::GetIDType(SQChar *s)
{
SQObjectPtr t;
if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {
- return int(_integer(t));
+ return SQInteger(_integer(t));
}
return TK_IDENTIFIER;
}
-int SQLexer::ReadString(int ndelim,bool verbatim)
+SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
{
INIT_TEMP_STRING();
NEXT();
case _SC('\n'):
if(!verbatim) Error(_SC("newline in a constant"));
APPEND_CHAR(CUR_CHAR); NEXT();
+ _currentline++;
break;
case _SC('\\'):
if(verbatim) {
switch(CUR_CHAR) {
case _SC('x'): NEXT(); {
if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
- const int maxdigits = 4;
+ const SQInteger maxdigits = 4;
SQChar temp[maxdigits+1];
- int n = 0;
+ SQInteger n = 0;
while(isxdigit(CUR_CHAR) && n < maxdigits) {
temp[n] = CUR_CHAR;
n++;
}
}
TERMINATE_BUFFER();
- int len = _longstr.size()-1;
+ SQInteger len = _longstr.size()-1;
if(ndelim == _SC('\'')) {
if(len == 0) Error(_SC("empty constant"));
if(len > 1) Error(_SC("constant too long"));
return TK_STRING_LITERAL;
}
-int isexponent(int c) { return c == 'e' || c=='E'; }
+void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res)
+{
+ *res = 0;
+ while(*s != 0)
+ {
+ if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0');
+ else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10);
+ else { assert(0); }
+ }
+}
-int SQLexer::ReadNumber()
+void LexInteger(const SQChar *s,SQUnsignedInteger *res)
+{
+ *res = 0;
+ while(*s != 0)
+ {
+ *res = (*res)*10+((*s++)-'0');
+ }
+}
+
+SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); }
+
+void LexOctal(const SQChar *s,SQUnsignedInteger *res)
+{
+ *res = 0;
+ while(*s != 0)
+ {
+ if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0');
+ else { assert(0); }
+ }
+}
+
+SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; }
+
+
+#define MAX_HEX_DIGITS (sizeof(SQInteger)*2)
+SQInteger SQLexer::ReadNumber()
{
#define TINT 1
#define TFLOAT 2
#define THEX 3
#define TSCIENTIFIC 4
- int type = TINT, firstchar = CUR_CHAR;
- bool isfloat = false;
+#define TOCTAL 5
+ SQInteger type = TINT, firstchar = CUR_CHAR;
SQChar *sTemp;
INIT_TEMP_STRING();
NEXT();
- if(firstchar == _SC('0') && toupper(CUR_CHAR) == _SC('X')) {
- NEXT();
- type = THEX;
- while(isxdigit(CUR_CHAR)) {
- APPEND_CHAR(CUR_CHAR);
+ if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) {
+ if(scisodigit(CUR_CHAR)) {
+ type = TOCTAL;
+ while(scisodigit(CUR_CHAR)) {
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ }
+ if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number"));
+ }
+ else {
NEXT();
+ type = THEX;
+ while(isxdigit(CUR_CHAR)) {
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ }
+ if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));
}
- if(_longstr.size() > 8) Error(_SC("Hex number over 8 digits"));
}
else {
- APPEND_CHAR(firstchar);
+ APPEND_CHAR((int)firstchar);
while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
if(CUR_CHAR == _SC('.')) type = TFLOAT;
if(isexponent(CUR_CHAR)) {
_fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
return TK_FLOAT;
case TINT:
- _nvalue = (SQInteger)scatoi(&_longstr[0]);
+ LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
return TK_INTEGER;
case THEX:
- *((unsigned long *)&_nvalue) = scstrtoul(&_longstr[0],&sTemp,16);
+ LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
+ return TK_INTEGER;
+ case TOCTAL:
+ LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
return TK_INTEGER;
}
return 0;
}
-int SQLexer::ReadID()
+SQInteger SQLexer::ReadID()
{
- int res, size = 0;
+ SQInteger res;
INIT_TEMP_STRING();
do {
APPEND_CHAR(CUR_CHAR);
} while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
TERMINATE_BUFFER();
res = GetIDType(&_longstr[0]);
- if(res == TK_IDENTIFIER) {
+ if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
_svalue = &_longstr[0];
}
return res;