summaryrefslogtreecommitdiffstats
path: root/squirrel_3_0_1_stable/squirrel/sqlexer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'squirrel_3_0_1_stable/squirrel/sqlexer.cpp')
-rw-r--r--squirrel_3_0_1_stable/squirrel/sqlexer.cpp978
1 files changed, 489 insertions, 489 deletions
diff --git a/squirrel_3_0_1_stable/squirrel/sqlexer.cpp b/squirrel_3_0_1_stable/squirrel/sqlexer.cpp
index ab17ba619..ec1704b71 100644
--- a/squirrel_3_0_1_stable/squirrel/sqlexer.cpp
+++ b/squirrel_3_0_1_stable/squirrel/sqlexer.cpp
@@ -1,489 +1,489 @@
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <ctype.h>
-#include <stdlib.h>
-#include "sqtable.h"
-#include "sqstring.h"
-#include "sqcompiler.h"
-#include "sqlexer.h"
-
-#define CUR_CHAR (_currdata)
-#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;}
-#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB)
-#define NEXT() {Next();_currentcolumn++;}
-#define INIT_TEMP_STRING() { _longstr.resize(0);}
-#define APPEND_CHAR(c) { _longstr.push_back(c);}
-#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));}
-#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id))
-
-SQLexer::SQLexer(){}
-SQLexer::~SQLexer()
-{
- _keywords->Release();
-}
-
-void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
-{
- _errfunc = efunc;
- _errtarget = ed;
- _sharedstate = ss;
- _keywords = SQTable::Create(ss, 26);
- ADD_KEYWORD(while, TK_WHILE);
- ADD_KEYWORD(do, TK_DO);
- ADD_KEYWORD(if, TK_IF);
- ADD_KEYWORD(else, TK_ELSE);
- ADD_KEYWORD(break, TK_BREAK);
- ADD_KEYWORD(continue, TK_CONTINUE);
- ADD_KEYWORD(return, TK_RETURN);
- ADD_KEYWORD(null, TK_NULL);
- ADD_KEYWORD(function, TK_FUNCTION);
- ADD_KEYWORD(local, TK_LOCAL);
- ADD_KEYWORD(for, TK_FOR);
- ADD_KEYWORD(foreach, TK_FOREACH);
- ADD_KEYWORD(in, TK_IN);
- ADD_KEYWORD(typeof, TK_TYPEOF);
- ADD_KEYWORD(base, TK_BASE);
- ADD_KEYWORD(delete, TK_DELETE);
- ADD_KEYWORD(try, TK_TRY);
- ADD_KEYWORD(catch, TK_CATCH);
- ADD_KEYWORD(throw, TK_THROW);
- ADD_KEYWORD(clone, TK_CLONE);
- ADD_KEYWORD(yield, TK_YIELD);
- ADD_KEYWORD(resume, TK_RESUME);
- ADD_KEYWORD(switch, TK_SWITCH);
- ADD_KEYWORD(case, TK_CASE);
- ADD_KEYWORD(default, TK_DEFAULT);
- ADD_KEYWORD(this, TK_THIS);
- ADD_KEYWORD(class,TK_CLASS);
- ADD_KEYWORD(extends,TK_EXTENDS);
- ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
- ADD_KEYWORD(instanceof,TK_INSTANCEOF);
- 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;
- _lasttokenline = _currentline = 1;
- _currentcolumn = 0;
- _prevtoken = -1;
- _reached_eof = SQFalse;
- Next();
-}
-
-void SQLexer::Error(const SQChar *err)
-{
- _errfunc(_errtarget,err);
-}
-
-void SQLexer::Next()
-{
- SQInteger t = _readf(_up);
- if(t > MAX_CHAR) Error(_SC("Invalid character"));
- if(t != 0) {
- _currdata = (LexChar)t;
- return;
- }
- _currdata = SQUIRREL_EOB;
- _reached_eof = SQTrue;
-}
-
-const SQChar *SQLexer::Tok2Str(SQInteger tok)
-{
- SQObjectPtr itr, key, val;
- SQInteger nitr;
- while((nitr = _keywords->Next(false,itr, key, val)) != -1) {
- itr = (SQInteger)nitr;
- if(((SQInteger)_integer(val)) == tok)
- return _stringval(key);
- }
- return NULL;
-}
-
-void SQLexer::LexBlockComment()
-{
- bool done = false;
- while(!done) {
- switch(CUR_CHAR) {
- case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
- case _SC('\n'): _currentline++; NEXT(); continue;
- case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
- default: NEXT();
- }
- }
-}
-void SQLexer::LexLineComment()
-{
- do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
-}
-
-SQInteger SQLexer::Lex()
-{
- _lasttokenline = _currentline;
- while(CUR_CHAR != SQUIRREL_EOB) {
- switch(CUR_CHAR){
- case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;
- case _SC('\n'):
- _currentline++;
- _prevtoken=_curtoken;
- _curtoken=_SC('\n');
- NEXT();
- _currentcolumn=1;
- continue;
- case _SC('#'): LexLineComment(); continue;
- case _SC('/'):
- NEXT();
- switch(CUR_CHAR){
- case _SC('*'):
- NEXT();
- LexBlockComment();
- continue;
- case _SC('/'):
- LexLineComment();
- continue;
- case _SC('='):
- NEXT();
- RETURN_TOKEN(TK_DIVEQ);
- continue;
- case _SC('>'):
- NEXT();
- RETURN_TOKEN(TK_ATTR_CLOSE);
- continue;
- default:
- RETURN_TOKEN('/');
- }
- case _SC('='):
- NEXT();
- if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }
- else { NEXT(); RETURN_TOKEN(TK_EQ); }
- case _SC('<'):
- NEXT();
- switch(CUR_CHAR) {
- case _SC('='):
- NEXT();
- if(CUR_CHAR == _SC('>')) {
- NEXT();
- RETURN_TOKEN(TK_3WAYSCMP);
- }
- RETURN_TOKEN(TK_LE)
- break;
- case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break;
- case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break;
- case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break;
- }
- RETURN_TOKEN('<');
- case _SC('>'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}
- else if(CUR_CHAR == _SC('>')){
- NEXT();
- if(CUR_CHAR == _SC('>')){
- NEXT();
- RETURN_TOKEN(TK_USHIFTR);
- }
- RETURN_TOKEN(TK_SHIFTR);
- }
- else { RETURN_TOKEN('>') }
- case _SC('!'):
- NEXT();
- if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
- else { NEXT(); RETURN_TOKEN(TK_NE); }
- case _SC('@'): {
- SQInteger stype;
- NEXT();
- if(CUR_CHAR != _SC('"')) {
- RETURN_TOKEN('@');
- }
- if((stype=ReadString('"',true))!=-1) {
- RETURN_TOKEN(stype);
- }
- Error(_SC("error parsing the string"));
- }
- case _SC('"'):
- case _SC('\''): {
- SQInteger stype;
- if((stype=ReadString(CUR_CHAR,false))!=-1){
- RETURN_TOKEN(stype);
- }
- Error(_SC("error parsing the string"));
- }
- case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
- case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):
- {SQInteger ret = CUR_CHAR;
- NEXT(); RETURN_TOKEN(ret); }
- case _SC('.'):
- NEXT();
- if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
- NEXT();
- if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
- NEXT();
- RETURN_TOKEN(TK_VARPARAMS);
- case _SC('&'):
- NEXT();
- if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
- else { NEXT(); RETURN_TOKEN(TK_AND); }
- case _SC('|'):
- NEXT();
- if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }
- else { NEXT(); RETURN_TOKEN(TK_OR); }
- case _SC(':'):
- NEXT();
- if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }
- else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }
- case _SC('*'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}
- else RETURN_TOKEN('*');
- case _SC('%'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}
- else RETURN_TOKEN('%');
- case _SC('-'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}
- else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}
- else RETURN_TOKEN('-');
- case _SC('+'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}
- else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}
- else RETURN_TOKEN('+');
- case SQUIRREL_EOB:
- return 0;
- default:{
- if (scisdigit(CUR_CHAR)) {
- SQInteger ret = ReadNumber();
- RETURN_TOKEN(ret);
- }
- else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
- SQInteger t = ReadID();
- RETURN_TOKEN(t);
- }
- else {
- SQInteger c = CUR_CHAR;
- if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
- NEXT();
- RETURN_TOKEN(c);
- }
- RETURN_TOKEN(0);
- }
- }
- }
- return 0;
-}
-
-SQInteger SQLexer::GetIDType(SQChar *s)
-{
- SQObjectPtr t;
- if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {
- return SQInteger(_integer(t));
- }
- return TK_IDENTIFIER;
-}
-
-
-SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
-{
- INIT_TEMP_STRING();
- NEXT();
- if(IS_EOB()) return -1;
- for(;;) {
- while(CUR_CHAR != ndelim) {
- switch(CUR_CHAR) {
- case SQUIRREL_EOB:
- Error(_SC("unfinished string"));
- return -1;
- case _SC('\n'):
- if(!verbatim) Error(_SC("newline in a constant"));
- APPEND_CHAR(CUR_CHAR); NEXT();
- _currentline++;
- break;
- case _SC('\\'):
- if(verbatim) {
- APPEND_CHAR('\\'); NEXT();
- }
- else {
- NEXT();
- switch(CUR_CHAR) {
- case _SC('x'): NEXT(); {
- if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
- const SQInteger maxdigits = 4;
- SQChar temp[maxdigits+1];
- SQInteger n = 0;
- while(isxdigit(CUR_CHAR) && n < maxdigits) {
- temp[n] = CUR_CHAR;
- n++;
- NEXT();
- }
- temp[n] = 0;
- SQChar *sTemp;
- APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));
- }
- break;
- case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;
- case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;
- case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;
- case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;
- case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;
- case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;
- case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;
- case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;
- case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;
- case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
- case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
- default:
- Error(_SC("unrecognised escaper char"));
- break;
- }
- }
- break;
- default:
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- }
- NEXT();
- if(verbatim && CUR_CHAR == '"') { //double quotation
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- else {
- break;
- }
- }
- TERMINATE_BUFFER();
- SQInteger len = _longstr.size()-1;
- if(ndelim == _SC('\'')) {
- if(len == 0) Error(_SC("empty constant"));
- if(len > 1) Error(_SC("constant too long"));
- _nvalue = _longstr[0];
- return TK_INTEGER;
- }
- _svalue = &_longstr[0];
- return TK_STRING_LITERAL;
-}
-
-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); }
- }
-}
-
-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
-#define TOCTAL 5
- SQInteger type = TINT, firstchar = CUR_CHAR;
- SQChar *sTemp;
- INIT_TEMP_STRING();
- NEXT();
- 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"));
- }
- }
- else {
- APPEND_CHAR((int)firstchar);
- while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
- if(CUR_CHAR == _SC('.')) type = TFLOAT;
- if(isexponent(CUR_CHAR)) {
- if(type != TFLOAT) Error(_SC("invalid numeric format"));
- type = TSCIENTIFIC;
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- if(CUR_CHAR == '+' || CUR_CHAR == '-'){
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
- }
-
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- }
- TERMINATE_BUFFER();
- switch(type) {
- case TSCIENTIFIC:
- case TFLOAT:
- _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
- return TK_FLOAT;
- case TINT:
- LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
- return TK_INTEGER;
- case THEX:
- LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
- return TK_INTEGER;
- case TOCTAL:
- LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
- return TK_INTEGER;
- }
- return 0;
-}
-
-SQInteger SQLexer::ReadID()
-{
- SQInteger res;
- INIT_TEMP_STRING();
- do {
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
- TERMINATE_BUFFER();
- res = GetIDType(&_longstr[0]);
- if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
- _svalue = &_longstr[0];
- }
- return res;
-}
+/*
+ see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include "sqtable.h"
+#include "sqstring.h"
+#include "sqcompiler.h"
+#include "sqlexer.h"
+
+#define CUR_CHAR (_currdata)
+#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;}
+#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB)
+#define NEXT() {Next();_currentcolumn++;}
+#define INIT_TEMP_STRING() { _longstr.resize(0);}
+#define APPEND_CHAR(c) { _longstr.push_back(c);}
+#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));}
+#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id))
+
+SQLexer::SQLexer(){}
+SQLexer::~SQLexer()
+{
+ _keywords->Release();
+}
+
+void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
+{
+ _errfunc = efunc;
+ _errtarget = ed;
+ _sharedstate = ss;
+ _keywords = SQTable::Create(ss, 26);
+ ADD_KEYWORD(while, TK_WHILE);
+ ADD_KEYWORD(do, TK_DO);
+ ADD_KEYWORD(if, TK_IF);
+ ADD_KEYWORD(else, TK_ELSE);
+ ADD_KEYWORD(break, TK_BREAK);
+ ADD_KEYWORD(continue, TK_CONTINUE);
+ ADD_KEYWORD(return, TK_RETURN);
+ ADD_KEYWORD(null, TK_NULL);
+ ADD_KEYWORD(function, TK_FUNCTION);
+ ADD_KEYWORD(local, TK_LOCAL);
+ ADD_KEYWORD(for, TK_FOR);
+ ADD_KEYWORD(foreach, TK_FOREACH);
+ ADD_KEYWORD(in, TK_IN);
+ ADD_KEYWORD(typeof, TK_TYPEOF);
+ ADD_KEYWORD(base, TK_BASE);
+ ADD_KEYWORD(delete, TK_DELETE);
+ ADD_KEYWORD(try, TK_TRY);
+ ADD_KEYWORD(catch, TK_CATCH);
+ ADD_KEYWORD(throw, TK_THROW);
+ ADD_KEYWORD(clone, TK_CLONE);
+ ADD_KEYWORD(yield, TK_YIELD);
+ ADD_KEYWORD(resume, TK_RESUME);
+ ADD_KEYWORD(switch, TK_SWITCH);
+ ADD_KEYWORD(case, TK_CASE);
+ ADD_KEYWORD(default, TK_DEFAULT);
+ ADD_KEYWORD(this, TK_THIS);
+ ADD_KEYWORD(class,TK_CLASS);
+ ADD_KEYWORD(extends,TK_EXTENDS);
+ ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
+ ADD_KEYWORD(instanceof,TK_INSTANCEOF);
+ 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;
+ _lasttokenline = _currentline = 1;
+ _currentcolumn = 0;
+ _prevtoken = -1;
+ _reached_eof = SQFalse;
+ Next();
+}
+
+void SQLexer::Error(const SQChar *err)
+{
+ _errfunc(_errtarget,err);
+}
+
+void SQLexer::Next()
+{
+ SQInteger t = _readf(_up);
+ if(t > MAX_CHAR) Error(_SC("Invalid character"));
+ if(t != 0) {
+ _currdata = (LexChar)t;
+ return;
+ }
+ _currdata = SQUIRREL_EOB;
+ _reached_eof = SQTrue;
+}
+
+const SQChar *SQLexer::Tok2Str(SQInteger tok)
+{
+ SQObjectPtr itr, key, val;
+ SQInteger nitr;
+ while((nitr = _keywords->Next(false,itr, key, val)) != -1) {
+ itr = (SQInteger)nitr;
+ if(((SQInteger)_integer(val)) == tok)
+ return _stringval(key);
+ }
+ return NULL;
+}
+
+void SQLexer::LexBlockComment()
+{
+ bool done = false;
+ while(!done) {
+ switch(CUR_CHAR) {
+ case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
+ case _SC('\n'): _currentline++; NEXT(); continue;
+ case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
+ default: NEXT();
+ }
+ }
+}
+void SQLexer::LexLineComment()
+{
+ do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
+}
+
+SQInteger SQLexer::Lex()
+{
+ _lasttokenline = _currentline;
+ while(CUR_CHAR != SQUIRREL_EOB) {
+ switch(CUR_CHAR){
+ case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;
+ case _SC('\n'):
+ _currentline++;
+ _prevtoken=_curtoken;
+ _curtoken=_SC('\n');
+ NEXT();
+ _currentcolumn=1;
+ continue;
+ case _SC('#'): LexLineComment(); continue;
+ case _SC('/'):
+ NEXT();
+ switch(CUR_CHAR){
+ case _SC('*'):
+ NEXT();
+ LexBlockComment();
+ continue;
+ case _SC('/'):
+ LexLineComment();
+ continue;
+ case _SC('='):
+ NEXT();
+ RETURN_TOKEN(TK_DIVEQ);
+ continue;
+ case _SC('>'):
+ NEXT();
+ RETURN_TOKEN(TK_ATTR_CLOSE);
+ continue;
+ default:
+ RETURN_TOKEN('/');
+ }
+ case _SC('='):
+ NEXT();
+ if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }
+ else { NEXT(); RETURN_TOKEN(TK_EQ); }
+ case _SC('<'):
+ NEXT();
+ switch(CUR_CHAR) {
+ case _SC('='):
+ NEXT();
+ if(CUR_CHAR == _SC('>')) {
+ NEXT();
+ RETURN_TOKEN(TK_3WAYSCMP);
+ }
+ RETURN_TOKEN(TK_LE)
+ break;
+ case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break;
+ case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break;
+ case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break;
+ }
+ RETURN_TOKEN('<');
+ case _SC('>'):
+ NEXT();
+ if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}
+ else if(CUR_CHAR == _SC('>')){
+ NEXT();
+ if(CUR_CHAR == _SC('>')){
+ NEXT();
+ RETURN_TOKEN(TK_USHIFTR);
+ }
+ RETURN_TOKEN(TK_SHIFTR);
+ }
+ else { RETURN_TOKEN('>') }
+ case _SC('!'):
+ NEXT();
+ if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
+ else { NEXT(); RETURN_TOKEN(TK_NE); }
+ case _SC('@'): {
+ SQInteger stype;
+ NEXT();
+ if(CUR_CHAR != _SC('"')) {
+ RETURN_TOKEN('@');
+ }
+ if((stype=ReadString('"',true))!=-1) {
+ RETURN_TOKEN(stype);
+ }
+ Error(_SC("error parsing the string"));
+ }
+ case _SC('"'):
+ case _SC('\''): {
+ SQInteger stype;
+ if((stype=ReadString(CUR_CHAR,false))!=-1){
+ RETURN_TOKEN(stype);
+ }
+ Error(_SC("error parsing the string"));
+ }
+ case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
+ case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):
+ {SQInteger ret = CUR_CHAR;
+ NEXT(); RETURN_TOKEN(ret); }
+ case _SC('.'):
+ NEXT();
+ if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
+ NEXT();
+ if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
+ NEXT();
+ RETURN_TOKEN(TK_VARPARAMS);
+ case _SC('&'):
+ NEXT();
+ if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
+ else { NEXT(); RETURN_TOKEN(TK_AND); }
+ case _SC('|'):
+ NEXT();
+ if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }
+ else { NEXT(); RETURN_TOKEN(TK_OR); }
+ case _SC(':'):
+ NEXT();
+ if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }
+ else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }
+ case _SC('*'):
+ NEXT();
+ if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}
+ else RETURN_TOKEN('*');
+ case _SC('%'):
+ NEXT();
+ if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}
+ else RETURN_TOKEN('%');
+ case _SC('-'):
+ NEXT();
+ if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}
+ else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}
+ else RETURN_TOKEN('-');
+ case _SC('+'):
+ NEXT();
+ if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}
+ else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}
+ else RETURN_TOKEN('+');
+ case SQUIRREL_EOB:
+ return 0;
+ default:{
+ if (scisdigit(CUR_CHAR)) {
+ SQInteger ret = ReadNumber();
+ RETURN_TOKEN(ret);
+ }
+ else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
+ SQInteger t = ReadID();
+ RETURN_TOKEN(t);
+ }
+ else {
+ SQInteger c = CUR_CHAR;
+ if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
+ NEXT();
+ RETURN_TOKEN(c);
+ }
+ RETURN_TOKEN(0);
+ }
+ }
+ }
+ return 0;
+}
+
+SQInteger SQLexer::GetIDType(SQChar *s)
+{
+ SQObjectPtr t;
+ if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {
+ return SQInteger(_integer(t));
+ }
+ return TK_IDENTIFIER;
+}
+
+
+SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
+{
+ INIT_TEMP_STRING();
+ NEXT();
+ if(IS_EOB()) return -1;
+ for(;;) {
+ while(CUR_CHAR != ndelim) {
+ switch(CUR_CHAR) {
+ case SQUIRREL_EOB:
+ Error(_SC("unfinished string"));
+ return -1;
+ case _SC('\n'):
+ if(!verbatim) Error(_SC("newline in a constant"));
+ APPEND_CHAR(CUR_CHAR); NEXT();
+ _currentline++;
+ break;
+ case _SC('\\'):
+ if(verbatim) {
+ APPEND_CHAR('\\'); NEXT();
+ }
+ else {
+ NEXT();
+ switch(CUR_CHAR) {
+ case _SC('x'): NEXT(); {
+ if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
+ const SQInteger maxdigits = 4;
+ SQChar temp[maxdigits+1];
+ SQInteger n = 0;
+ while(isxdigit(CUR_CHAR) && n < maxdigits) {
+ temp[n] = CUR_CHAR;
+ n++;
+ NEXT();
+ }
+ temp[n] = 0;
+ SQChar *sTemp;
+ APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));
+ }
+ break;
+ case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;
+ case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;
+ case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;
+ case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;
+ case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;
+ case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;
+ case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;
+ case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;
+ case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;
+ case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
+ case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
+ default:
+ Error(_SC("unrecognised escaper char"));
+ break;
+ }
+ }
+ break;
+ default:
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ }
+ }
+ NEXT();
+ if(verbatim && CUR_CHAR == '"') { //double quotation
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ }
+ else {
+ break;
+ }
+ }
+ TERMINATE_BUFFER();
+ SQInteger len = _longstr.size()-1;
+ if(ndelim == _SC('\'')) {
+ if(len == 0) Error(_SC("empty constant"));
+ if(len > 1) Error(_SC("constant too long"));
+ _nvalue = _longstr[0];
+ return TK_INTEGER;
+ }
+ _svalue = &_longstr[0];
+ return TK_STRING_LITERAL;
+}
+
+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); }
+ }
+}
+
+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
+#define TOCTAL 5
+ SQInteger type = TINT, firstchar = CUR_CHAR;
+ SQChar *sTemp;
+ INIT_TEMP_STRING();
+ NEXT();
+ 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"));
+ }
+ }
+ else {
+ APPEND_CHAR((int)firstchar);
+ while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
+ if(CUR_CHAR == _SC('.')) type = TFLOAT;
+ if(isexponent(CUR_CHAR)) {
+ if(type != TFLOAT) Error(_SC("invalid numeric format"));
+ type = TSCIENTIFIC;
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ if(CUR_CHAR == '+' || CUR_CHAR == '-'){
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ }
+ if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
+ }
+
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ }
+ }
+ TERMINATE_BUFFER();
+ switch(type) {
+ case TSCIENTIFIC:
+ case TFLOAT:
+ _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
+ return TK_FLOAT;
+ case TINT:
+ LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
+ return TK_INTEGER;
+ case THEX:
+ LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
+ return TK_INTEGER;
+ case TOCTAL:
+ LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
+ return TK_INTEGER;
+ }
+ return 0;
+}
+
+SQInteger SQLexer::ReadID()
+{
+ SQInteger res;
+ INIT_TEMP_STRING();
+ do {
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
+ TERMINATE_BUFFER();
+ res = GetIDType(&_longstr[0]);
+ if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
+ _svalue = &_longstr[0];
+ }
+ return res;
+}