|
@@ -1,55 +1,56 @@
|
|
|
-/*
|
|
|
|
|
- see copyright notice in squirrel.h
|
|
|
|
|
-*/
|
|
|
|
|
-#include "sqpcheader.h"
|
|
|
|
|
-#include <ctype.h>
|
|
|
|
|
-#include <stdlib.h>
|
|
|
|
|
-#include <limits.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() {SQInteger rc = Next(); if(rc < 0) return rc; _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) tbl->NewSlot( SQString::Create(_sharedstate, _SC(#key)) ,SQInteger(id))
|
|
|
|
|
-
|
|
|
|
|
-SQLexer::SQLexer(){_keywords=0;}
|
|
|
|
|
-SQLexer::~SQLexer()
|
|
|
|
|
-{
|
|
|
|
|
- _keywords->Release();
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
|
|
+/*
|
|
|
|
|
+ see copyright notice in squirrel.h
|
|
|
|
|
+*/
|
|
|
|
|
+#include "sqpcheader.h"
|
|
|
|
|
+#include <ctype.h>
|
|
|
|
|
+#include <stdlib.h>
|
|
|
|
|
+#include <limits.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() {SQInteger rc = Next(); if(rc < 0) return rc; _currentcolumn++;}
|
|
|
|
|
+#define NEXT() {if(Next()) return -1;}
|
|
|
|
|
+#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) tbl->NewSlot( SQString::Create(_sharedstate, _SC(#key)) ,SQInteger(id))
|
|
|
|
|
+
|
|
|
|
|
+SQLexer::SQLexer(){_keywords=0;}
|
|
|
|
|
+SQLexer::~SQLexer()
|
|
|
|
|
+{
|
|
|
|
|
+ _keywords->Release();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
SQInteger SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg,
|
|
SQInteger SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg,
|
|
|
- SQUserPointer up,CompilerErrorFunc efunc,void *ed, SQBool want_comments)
|
|
|
|
|
|
|
+ SQUserPointer up,CompilerErrorFunc efunc,void *ed, SQBool want_comments)
|
|
|
{
|
|
{
|
|
|
_want_comments = want_comments;
|
|
_want_comments = want_comments;
|
|
|
- _lasterror[0] = '\0';
|
|
|
|
|
- _svalue = NULL;
|
|
|
|
|
- _errfunc = efunc;
|
|
|
|
|
- _errtarget = ed;
|
|
|
|
|
|
|
+ _lasterror[0] = '\0';
|
|
|
|
|
+ _svalue = NULL;
|
|
|
|
|
+ _errfunc = efunc;
|
|
|
|
|
+ _errtarget = ed;
|
|
|
_sharedstate = ss;
|
|
_sharedstate = ss;
|
|
|
- if(_keywords) _keywords->Release();
|
|
|
|
|
- _keywords = GetKeywords();
|
|
|
|
|
- return ResetReader(rg, up, 1);
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ if(_keywords) _keywords->Release();
|
|
|
|
|
+ _keywords = GetKeywords();
|
|
|
|
|
+ return ResetReader(rg, up, 1);
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
-SQInteger SQLexer::ResetReader(SQLEXREADFUNC rg, SQUserPointer up, SQInteger line)
|
|
|
|
|
-{
|
|
|
|
|
- _readf = rg;
|
|
|
|
|
- _up = up;
|
|
|
|
|
|
|
+SQInteger SQLexer::ResetReader(SQLEXREADFUNC rg, SQUserPointer up, SQInteger line)
|
|
|
|
|
+{
|
|
|
|
|
+ _readf = rg;
|
|
|
|
|
+ _up = up;
|
|
|
_lasttokenline = _currentline = line;
|
|
_lasttokenline = _currentline = line;
|
|
|
- _lasttokencolumn = 0;
|
|
|
|
|
- _currentcolumn = 0;
|
|
|
|
|
- _prevtoken = -1;
|
|
|
|
|
- _reached_eof = SQFalse;
|
|
|
|
|
- return Next();
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ _lasttokencolumn = 0;
|
|
|
|
|
+ _currentcolumn = 0;
|
|
|
|
|
+ _prevtoken = -1;
|
|
|
|
|
+ _reached_eof = SQFalse;
|
|
|
|
|
+ return Next();
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
SQTable * SQLexer::GetKeywords()
|
|
SQTable * SQLexer::GetKeywords()
|
|
|
{
|
|
{
|
|
@@ -142,40 +143,41 @@ SQTable * SQLexer::GetKeywords()
|
|
|
|
|
|
|
|
return tbl;
|
|
return tbl;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-SQInteger SQLexer::Error(const SQChar *fmt, ...)
|
|
|
|
|
-{
|
|
|
|
|
- va_list vl;
|
|
|
|
|
- va_start(vl, fmt);
|
|
|
|
|
- scvsprintf(_lasterror, sizeof(_lasterror), fmt, vl);
|
|
|
|
|
- va_end(vl);
|
|
|
|
|
|
|
+
|
|
|
|
|
+SQInteger SQLexer::Error(const SQChar *fmt, ...)
|
|
|
|
|
+{
|
|
|
|
|
+ va_list vl;
|
|
|
|
|
+ va_start(vl, fmt);
|
|
|
|
|
+ scvsprintf(_lasterror, sizeof(_lasterror), fmt, vl);
|
|
|
|
|
+ va_end(vl);
|
|
|
if(_errfunc) _errfunc(_errtarget,_lasterror);
|
|
if(_errfunc) _errfunc(_errtarget,_lasterror);
|
|
|
- return -1;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-SQInteger SQLexer::Next()
|
|
|
|
|
-{
|
|
|
|
|
- SQInteger t = _readf(_up);
|
|
|
|
|
- if(t > MAX_CHAR) return Error(_SC("Invalid character"));
|
|
|
|
|
- if(t != 0) {
|
|
|
|
|
- _currdata = (LexChar)t;
|
|
|
|
|
- return 0;
|
|
|
|
|
- }
|
|
|
|
|
- _currdata = SQUIRREL_EOB;
|
|
|
|
|
|
|
+ return -1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+SQInteger SQLexer::Next()
|
|
|
|
|
+{
|
|
|
|
|
+ SQInteger t = _readf(_up);
|
|
|
|
|
+ if(t > MAX_CHAR) return Error(_SC("Invalid character"));
|
|
|
|
|
+ if(t != 0) {
|
|
|
|
|
+ _currdata = (LexChar)t;
|
|
|
|
|
+ ++_currentcolumn;
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ _currdata = SQUIRREL_EOB;
|
|
|
_reached_eof = SQTrue;
|
|
_reached_eof = SQTrue;
|
|
|
- return 0;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-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;
|
|
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const SQChar *SQLexer::GetTokenName(int tk_code) {
|
|
const SQChar *SQLexer::GetTokenName(int tk_code) {
|
|
@@ -190,9 +192,9 @@ const SQChar *SQLexer::GetTokenName(int tk_code) {
|
|
|
}
|
|
}
|
|
|
return str_tk;
|
|
return str_tk;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-SQInteger SQLexer::LexBlockComment()
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+SQInteger SQLexer::LexBlockComment()
|
|
|
{
|
|
{
|
|
|
/*
|
|
/*
|
|
|
if(CUR_CHAR == _SC('*'))
|
|
if(CUR_CHAR == _SC('*'))
|
|
@@ -202,18 +204,18 @@ SQInteger SQLexer::LexBlockComment()
|
|
|
printf("Doument comment found at line %d\n", _currentline);
|
|
printf("Doument comment found at line %d\n", _currentline);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-*/
|
|
|
|
|
|
|
+*/
|
|
|
bool done = false;
|
|
bool done = false;
|
|
|
if(_want_comments) INIT_TEMP_STRING();
|
|
if(_want_comments) INIT_TEMP_STRING();
|
|
|
- NEXT(); //remove the comment token '*'
|
|
|
|
|
- while(!done) {
|
|
|
|
|
- switch(CUR_CHAR) {
|
|
|
|
|
- case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); continue;}}; break;
|
|
|
|
|
- case _SC('\n'): _currentline++; break;
|
|
|
|
|
- case SQUIRREL_EOB: return Error(_SC("missing \"*/\" in comment"));
|
|
|
|
|
|
|
+ NEXT(); //remove the comment token '*'
|
|
|
|
|
+ while(!done) {
|
|
|
|
|
+ switch(CUR_CHAR) {
|
|
|
|
|
+ case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); continue;}}; break;
|
|
|
|
|
+ case _SC('\n'): _currentline++; break;
|
|
|
|
|
+ case SQUIRREL_EOB: return Error(_SC("missing \"*/\" in comment"));
|
|
|
}
|
|
}
|
|
|
if(_want_comments) APPEND_CHAR(CUR_CHAR);
|
|
if(_want_comments) APPEND_CHAR(CUR_CHAR);
|
|
|
- NEXT();
|
|
|
|
|
|
|
+ NEXT();
|
|
|
}
|
|
}
|
|
|
if(_want_comments)
|
|
if(_want_comments)
|
|
|
{
|
|
{
|
|
@@ -221,35 +223,35 @@ SQInteger SQLexer::LexBlockComment()
|
|
|
if(_longstr.size() > 0) _longstr.pop_back(); //remove the last '*'
|
|
if(_longstr.size() > 0) _longstr.pop_back(); //remove the last '*'
|
|
|
_svalue = &_longstr[0];
|
|
_svalue = &_longstr[0];
|
|
|
}
|
|
}
|
|
|
- return 0;
|
|
|
|
|
-}
|
|
|
|
|
-SQInteger SQLexer::LexLineComment()
|
|
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+SQInteger SQLexer::LexLineComment()
|
|
|
{
|
|
{
|
|
|
if(_want_comments) INIT_TEMP_STRING();
|
|
if(_want_comments) INIT_TEMP_STRING();
|
|
|
- NEXT(); //remove the comment token
|
|
|
|
|
|
|
+ NEXT(); //remove the comment token
|
|
|
while (CUR_CHAR != _SC('\n') && (!IS_EOB())) {if(_want_comments) APPEND_CHAR(CUR_CHAR); NEXT();}
|
|
while (CUR_CHAR != _SC('\n') && (!IS_EOB())) {if(_want_comments) APPEND_CHAR(CUR_CHAR); NEXT();}
|
|
|
if(_want_comments)
|
|
if(_want_comments)
|
|
|
{
|
|
{
|
|
|
TERMINATE_BUFFER();
|
|
TERMINATE_BUFFER();
|
|
|
_svalue = &_longstr[0];
|
|
_svalue = &_longstr[0];
|
|
|
}
|
|
}
|
|
|
- return 0;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-SQInteger SQLexer::Lex()
|
|
|
|
|
-{
|
|
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+SQInteger SQLexer::Lex()
|
|
|
|
|
+{
|
|
|
_lasttokenline = _currentline;
|
|
_lasttokenline = _currentline;
|
|
|
- _lasttokencolumn = _currentcolumn;
|
|
|
|
|
- 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;
|
|
|
|
|
|
|
+ _lasttokencolumn = _currentcolumn;
|
|
|
|
|
+ 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('#'):
|
|
case _SC('#'):
|
|
|
NEXT();
|
|
NEXT();
|
|
|
if(CUR_CHAR == '!') //shell shebang
|
|
if(CUR_CHAR == '!') //shell shebang
|
|
@@ -260,184 +262,184 @@ SQInteger SQLexer::Lex()
|
|
|
}
|
|
}
|
|
|
RETURN_TOKEN(TK_PRAGMA);
|
|
RETURN_TOKEN(TK_PRAGMA);
|
|
|
continue;
|
|
continue;
|
|
|
- case _SC('/'):
|
|
|
|
|
- NEXT();
|
|
|
|
|
- switch(CUR_CHAR){
|
|
|
|
|
- case _SC('*'):
|
|
|
|
|
- if(LexBlockComment()) return -1;
|
|
|
|
|
|
|
+ case _SC('/'):
|
|
|
|
|
+ NEXT();
|
|
|
|
|
+ switch(CUR_CHAR){
|
|
|
|
|
+ case _SC('*'):
|
|
|
|
|
+ if(LexBlockComment()) return -1;
|
|
|
if(_want_comments) RETURN_TOKEN(TK_COMMENT_BLOCK)
|
|
if(_want_comments) RETURN_TOKEN(TK_COMMENT_BLOCK)
|
|
|
- continue;
|
|
|
|
|
- case _SC('/'):
|
|
|
|
|
- if(LexLineComment()) return -1;
|
|
|
|
|
|
|
+ continue;
|
|
|
|
|
+ case _SC('/'):
|
|
|
|
|
+ if(LexLineComment()) return -1;
|
|
|
if(_want_comments) RETURN_TOKEN(TK_COMMENT_LINE)
|
|
if(_want_comments) RETURN_TOKEN(TK_COMMENT_LINE)
|
|
|
- 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('=') }
|
|
|
|
|
|
|
+ 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 {
|
|
else {
|
|
|
NEXT();
|
|
NEXT();
|
|
|
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_EQ_IDENTITY) }
|
|
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_EQ_IDENTITY) }
|
|
|
else { RETURN_TOKEN(TK_EQ); }
|
|
else { 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('!')}
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ 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 {
|
|
else {
|
|
|
NEXT();
|
|
NEXT();
|
|
|
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_NE_IDENTITY)}
|
|
if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_NE_IDENTITY)}
|
|
|
else { RETURN_TOKEN(TK_NE); }
|
|
else { RETURN_TOKEN(TK_NE); }
|
|
|
- }
|
|
|
|
|
- case _SC('@'): {
|
|
|
|
|
- SQInteger stype;
|
|
|
|
|
- NEXT();
|
|
|
|
|
- if(CUR_CHAR != _SC('"')) {
|
|
|
|
|
- RETURN_TOKEN('@');
|
|
|
|
|
- }
|
|
|
|
|
- if((stype=ReadString('"',true))!=-1) {
|
|
|
|
|
- RETURN_TOKEN(stype);
|
|
|
|
|
- }
|
|
|
|
|
- return Error(_SC("error parsing the string"));
|
|
|
|
|
- }
|
|
|
|
|
- case _SC('"'):
|
|
|
|
|
- case _SC('\''): {
|
|
|
|
|
- SQInteger stype;
|
|
|
|
|
- if((stype=ReadString(CUR_CHAR,false))!=-1){
|
|
|
|
|
- RETURN_TOKEN(stype);
|
|
|
|
|
- }
|
|
|
|
|
- return 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 stype;
|
|
|
|
|
+ NEXT();
|
|
|
|
|
+ if(CUR_CHAR != _SC('"')) {
|
|
|
|
|
+ RETURN_TOKEN('@');
|
|
|
|
|
+ }
|
|
|
|
|
+ if((stype=ReadString('"',true))!=-1) {
|
|
|
|
|
+ RETURN_TOKEN(stype);
|
|
|
|
|
+ }
|
|
|
|
|
+ return Error(_SC("error parsing the string"));
|
|
|
|
|
+ }
|
|
|
|
|
+ case _SC('"'):
|
|
|
|
|
+ case _SC('\''): {
|
|
|
|
|
+ SQInteger stype;
|
|
|
|
|
+ if((stype=ReadString(CUR_CHAR,false))!=-1){
|
|
|
|
|
+ RETURN_TOKEN(stype);
|
|
|
|
|
+ }
|
|
|
|
|
+ return 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('~'):
|
|
|
{
|
|
{
|
|
|
- SQInteger ret = CUR_CHAR;
|
|
|
|
|
|
|
+ SQInteger ret = CUR_CHAR;
|
|
|
NEXT();
|
|
NEXT();
|
|
|
if((ret == _SC('[') || ret == _SC('{') || ret == _SC('(')) && CUR_CHAR == _SC('=')){
|
|
if((ret == _SC('[') || ret == _SC('{') || ret == _SC('(')) && CUR_CHAR == _SC('=')){
|
|
|
//lets try lua literal delimiters
|
|
//lets try lua literal delimiters
|
|
|
- SQInteger stype;
|
|
|
|
|
- if((stype=ReadString(ret,true))!=-1){
|
|
|
|
|
- RETURN_TOKEN(stype);
|
|
|
|
|
- }
|
|
|
|
|
- return Error(_SC("error parsing the string"));
|
|
|
|
|
|
|
+ SQInteger stype;
|
|
|
|
|
+ if((stype=ReadString(ret,true))!=-1){
|
|
|
|
|
+ RETURN_TOKEN(stype);
|
|
|
|
|
+ }
|
|
|
|
|
+ return Error(_SC("error parsing the string"));
|
|
|
}
|
|
}
|
|
|
else RETURN_TOKEN(ret);
|
|
else RETURN_TOKEN(ret);
|
|
|
- }
|
|
|
|
|
- case _SC('.'):
|
|
|
|
|
- NEXT();
|
|
|
|
|
- if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
|
|
|
|
|
- NEXT();
|
|
|
|
|
- if (CUR_CHAR != _SC('.')){ return Error(_SC("invalid token '..'")); }
|
|
|
|
|
- NEXT();
|
|
|
|
|
- RETURN_TOKEN(TK_VARPARAMS);
|
|
|
|
|
- case _SC('^'):
|
|
|
|
|
- NEXT();
|
|
|
|
|
- //if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_BIT_XOR_EQ);}
|
|
|
|
|
- RETURN_TOKEN('^');
|
|
|
|
|
- case _SC('&'):
|
|
|
|
|
- NEXT();
|
|
|
|
|
- //if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_BIT_AND_EQ);}
|
|
|
|
|
- if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
|
|
|
|
|
- else { NEXT(); RETURN_TOKEN(TK_AND); }
|
|
|
|
|
- case _SC('|'):
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ case _SC('.'):
|
|
|
|
|
+ NEXT();
|
|
|
|
|
+ if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
|
|
|
NEXT();
|
|
NEXT();
|
|
|
- //if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_BIT_OR_EQ);}
|
|
|
|
|
- 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 if (CUR_CHAR == _SC('>')){ NEXT(); RETURN_TOKEN('.');} //accept C/C++ like pointers
|
|
|
|
|
- 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)) {
|
|
|
|
|
|
|
+ if (CUR_CHAR != _SC('.')){ return Error(_SC("invalid token '..'")); }
|
|
|
|
|
+ NEXT();
|
|
|
|
|
+ RETURN_TOKEN(TK_VARPARAMS);
|
|
|
|
|
+ case _SC('^'):
|
|
|
|
|
+ NEXT();
|
|
|
|
|
+ //if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_BIT_XOR_EQ);}
|
|
|
|
|
+ RETURN_TOKEN('^');
|
|
|
|
|
+ case _SC('&'):
|
|
|
|
|
+ NEXT();
|
|
|
|
|
+ //if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_BIT_AND_EQ);}
|
|
|
|
|
+ if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
|
|
|
|
|
+ else { NEXT(); RETURN_TOKEN(TK_AND); }
|
|
|
|
|
+ case _SC('|'):
|
|
|
|
|
+ NEXT();
|
|
|
|
|
+ //if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_BIT_OR_EQ);}
|
|
|
|
|
+ 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 if (CUR_CHAR == _SC('>')){ NEXT(); RETURN_TOKEN('.');} //accept C/C++ like pointers
|
|
|
|
|
+ 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();
|
|
SQInteger ret = ReadNumber();
|
|
|
- if(ret < 0) return -1;
|
|
|
|
|
- RETURN_TOKEN(ret);
|
|
|
|
|
- }
|
|
|
|
|
- else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
|
|
|
|
|
|
|
+ if(ret < 0) return -1;
|
|
|
|
|
+ RETURN_TOKEN(ret);
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
|
|
|
SQInteger t = ReadID();
|
|
SQInteger t = ReadID();
|
|
|
- if(t < 0) return -1;
|
|
|
|
|
- RETURN_TOKEN(t);
|
|
|
|
|
- }
|
|
|
|
|
- else {
|
|
|
|
|
- SQInteger c = CUR_CHAR;
|
|
|
|
|
- if (sciscntrl((int)c)) return Error(_SC("unexpected character(control)"));
|
|
|
|
|
- NEXT();
|
|
|
|
|
- RETURN_TOKEN(c);
|
|
|
|
|
- }
|
|
|
|
|
- RETURN_TOKEN(0);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return 0;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
|
|
+ if(t < 0) return -1;
|
|
|
|
|
+ RETURN_TOKEN(t);
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ SQInteger c = CUR_CHAR;
|
|
|
|
|
+ if (sciscntrl((int)c)) return Error(_SC("unexpected character(control)"));
|
|
|
|
|
+ NEXT();
|
|
|
|
|
+ RETURN_TOKEN(c);
|
|
|
|
|
+ }
|
|
|
|
|
+ RETURN_TOKEN(0);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
SQInteger SQLexer::GetIDType(const SQChar *s,SQInteger len)
|
|
SQInteger SQLexer::GetIDType(const SQChar *s,SQInteger len)
|
|
|
{
|
|
{
|
|
|
SQObjectPtr t;
|
|
SQObjectPtr t;
|
|
|
if(_keywords->GetStr(s,len, t)) {
|
|
if(_keywords->GetStr(s,len, t)) {
|
|
|
- return SQInteger(_integer(t));
|
|
|
|
|
- }
|
|
|
|
|
- return TK_IDENTIFIER;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ return SQInteger(_integer(t));
|
|
|
|
|
+ }
|
|
|
|
|
+ return TK_IDENTIFIER;
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
#ifdef SQUNICODE
|
|
#ifdef SQUNICODE
|
|
|
#if WCHAR_SIZE == 2
|
|
#if WCHAR_SIZE == 2
|
|
@@ -498,10 +500,10 @@ SQInteger SQLexer::ProcessStringHexEscape(SQChar *dest, SQInteger maxdigits)
|
|
|
dest[n] = 0;
|
|
dest[n] = 0;
|
|
|
return n;
|
|
return n;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
|
|
|
|
|
-{
|
|
|
|
|
- INIT_TEMP_STRING();
|
|
|
|
|
|
|
+
|
|
|
|
|
+SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
|
|
|
|
|
+{
|
|
|
|
|
+ INIT_TEMP_STRING();
|
|
|
SQInteger start_equals = 0;
|
|
SQInteger start_equals = 0;
|
|
|
SQChar cdelim1, cdelim2;
|
|
SQChar cdelim1, cdelim2;
|
|
|
if(ndelim == _SC('{')){
|
|
if(ndelim == _SC('{')){
|
|
@@ -527,9 +529,9 @@ SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
|
|
|
return Error(_SC("expect '%c' on literal delimiter"), cdelim1);
|
|
return Error(_SC("expect '%c' on literal delimiter"), cdelim1);
|
|
|
}
|
|
}
|
|
|
ndelim = cdelim2;
|
|
ndelim = cdelim2;
|
|
|
- }
|
|
|
|
|
- NEXT();
|
|
|
|
|
- if(IS_EOB()) return -1;
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ NEXT();
|
|
|
|
|
+ if(IS_EOB()) return -1;
|
|
|
if(start_equals) {
|
|
if(start_equals) {
|
|
|
int cr_nl = CUR_CHAR == _SC('\r');
|
|
int cr_nl = CUR_CHAR == _SC('\r');
|
|
|
if(cr_nl) NEXT();
|
|
if(cr_nl) NEXT();
|
|
@@ -541,26 +543,26 @@ SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
|
|
|
{
|
|
{
|
|
|
return Error(_SC("unfinished string"));
|
|
return Error(_SC("unfinished string"));
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- for(;;) {
|
|
|
|
|
|
|
+ for(;;) {
|
|
|
while(CUR_CHAR != ndelim) {
|
|
while(CUR_CHAR != ndelim) {
|
|
|
- SQInteger x = CUR_CHAR;
|
|
|
|
|
- switch(x) {
|
|
|
|
|
- case SQUIRREL_EOB:
|
|
|
|
|
- return Error(_SC("unfinished string"));
|
|
|
|
|
- case _SC('\n'):
|
|
|
|
|
- if(!verbatim) return 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) {
|
|
|
|
|
|
|
+ SQInteger x = CUR_CHAR;
|
|
|
|
|
+ switch(x) {
|
|
|
|
|
+ case SQUIRREL_EOB:
|
|
|
|
|
+ return Error(_SC("unfinished string"));
|
|
|
|
|
+ case _SC('\n'):
|
|
|
|
|
+ if(!verbatim) return 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'): {
|
|
case _SC('x'): {
|
|
|
const SQInteger maxdigits = sizeof(SQChar) * 2;
|
|
const SQInteger maxdigits = sizeof(SQChar) * 2;
|
|
|
SQChar temp[maxdigits + 1];
|
|
SQChar temp[maxdigits + 1];
|
|
@@ -584,31 +586,31 @@ SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
|
|
|
#else
|
|
#else
|
|
|
AddUTF8(scstrtoul(temp, &stemp, 16));
|
|
AddUTF8(scstrtoul(temp, &stemp, 16));
|
|
|
#endif
|
|
#endif
|
|
|
- }
|
|
|
|
|
- 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:
|
|
|
|
|
- return Error(_SC("unrecognised escaper char"));
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- break;
|
|
|
|
|
- default:
|
|
|
|
|
- APPEND_CHAR(CUR_CHAR);
|
|
|
|
|
- NEXT();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- NEXT();
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ 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:
|
|
|
|
|
+ return Error(_SC("unrecognised escaper char"));
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ APPEND_CHAR(CUR_CHAR);
|
|
|
|
|
+ NEXT();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ NEXT();
|
|
|
if(start_equals){
|
|
if(start_equals){
|
|
|
bool lastBraceAdded = false;
|
|
bool lastBraceAdded = false;
|
|
|
if(CUR_CHAR == _SC('=')){
|
|
if(CUR_CHAR == _SC('=')){
|
|
@@ -632,154 +634,154 @@ SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
|
|
|
if(!lastBraceAdded) APPEND_CHAR(cdelim2); //the first NEXT() after break the while loop
|
|
if(!lastBraceAdded) APPEND_CHAR(cdelim2); //the first NEXT() after break the while loop
|
|
|
APPEND_CHAR(CUR_CHAR);
|
|
APPEND_CHAR(CUR_CHAR);
|
|
|
NEXT();
|
|
NEXT();
|
|
|
- }
|
|
|
|
|
- else 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) return Error(_SC("empty constant"));
|
|
|
|
|
- if(len > 1) return 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');
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ else 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) return Error(_SC("empty constant"));
|
|
|
|
|
+ if(len > 1) return 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 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 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;
|
|
SQInteger type = TINT, firstchar = CUR_CHAR;
|
|
|
- SQUnsignedInteger itmp=0;
|
|
|
|
|
- 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)) return Error(_SC("invalid octal number"));
|
|
|
|
|
- }
|
|
|
|
|
- else {
|
|
|
|
|
- NEXT();
|
|
|
|
|
- type = THEX;
|
|
|
|
|
- while(isxdigit(CUR_CHAR)) {
|
|
|
|
|
- APPEND_CHAR(CUR_CHAR);
|
|
|
|
|
- NEXT();
|
|
|
|
|
- }
|
|
|
|
|
- if(_longstr.size() > MAX_HEX_DIGITS) return 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('.') || isexponent(CUR_CHAR)) type = TFLOAT;
|
|
|
|
|
- if(isexponent(CUR_CHAR)) {
|
|
|
|
|
- if(type != TFLOAT) return 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)) return 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:
|
|
|
|
|
|
|
+ SQUnsignedInteger itmp=0;
|
|
|
|
|
+ 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)) return Error(_SC("invalid octal number"));
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ NEXT();
|
|
|
|
|
+ type = THEX;
|
|
|
|
|
+ while(isxdigit(CUR_CHAR)) {
|
|
|
|
|
+ APPEND_CHAR(CUR_CHAR);
|
|
|
|
|
+ NEXT();
|
|
|
|
|
+ }
|
|
|
|
|
+ if(_longstr.size() > MAX_HEX_DIGITS) return 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('.') || isexponent(CUR_CHAR)) type = TFLOAT;
|
|
|
|
|
+ if(isexponent(CUR_CHAR)) {
|
|
|
|
|
+ if(type != TFLOAT) return 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)) return 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],&itmp);
|
|
LexInteger(&_longstr[0],&itmp);
|
|
|
- break;
|
|
|
|
|
- case THEX:
|
|
|
|
|
- LexHexadecimal(&_longstr[0],&itmp);
|
|
|
|
|
- break;
|
|
|
|
|
- case TOCTAL:
|
|
|
|
|
- LexOctal(&_longstr[0],&itmp);
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- switch(type) {
|
|
|
|
|
- case TINT:
|
|
|
|
|
- case THEX:
|
|
|
|
|
|
|
+ break;
|
|
|
|
|
+ case THEX:
|
|
|
|
|
+ LexHexadecimal(&_longstr[0],&itmp);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case TOCTAL:
|
|
|
|
|
+ LexOctal(&_longstr[0],&itmp);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ switch(type) {
|
|
|
|
|
+ case TINT:
|
|
|
|
|
+ case THEX:
|
|
|
case TOCTAL:
|
|
case TOCTAL:
|
|
|
//to allow 64 bits integers comment bellow
|
|
//to allow 64 bits integers comment bellow
|
|
|
//if(itmp > INT_MAX) return Error(_SC("integer overflow %ulld %d"));
|
|
//if(itmp > INT_MAX) return Error(_SC("integer overflow %ulld %d"));
|
|
|
- _nvalue = (SQInteger) itmp;
|
|
|
|
|
- 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();
|
|
|
|
|
|
|
+ _nvalue = (SQInteger) itmp;
|
|
|
|
|
+ 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],_longstr.size() - 1);
|
|
res = GetIDType(&_longstr[0],_longstr.size() - 1);
|
|
|
- if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR || res == TK_DESTRUCTOR) {
|
|
|
|
|
- _svalue = &_longstr[0];
|
|
|
|
|
- }
|
|
|
|
|
- return res;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR || res == TK_DESTRUCTOR) {
|
|
|
|
|
+ _svalue = &_longstr[0];
|
|
|
|
|
+ }
|
|
|
|
|
+ return res;
|
|
|
|
|
+}
|