1687 lines
54 KiB
JavaScript
1687 lines
54 KiB
JavaScript
|
/*
|
||
|
* @project: TERA
|
||
|
* @version: Development (beta)
|
||
|
* @license: MIT (not for evil)
|
||
|
* @copyright: Yuriy Ivanov 2017-2019 [progr76@gmail.com]
|
||
|
* Web: https://terafoundation.org
|
||
|
* Twitter: https://twitter.com/terafoundation
|
||
|
* Telegram: https://web.telegram.org/#/im?p=@terafoundation
|
||
|
*/
|
||
|
|
||
|
const LOC_ADD_NAME = "$";
|
||
|
module.exports = function ()
|
||
|
{
|
||
|
'use strict';
|
||
|
this.ErrorIgnore = false;
|
||
|
this.ErrorOne = true;
|
||
|
this.CommentIgnore = true;
|
||
|
this.PrintMargin = 120;
|
||
|
this.FileNumber = 0;
|
||
|
this.InjectCheck = true;
|
||
|
this.SideMode = "client";
|
||
|
this.Clear = function ()
|
||
|
{
|
||
|
this.ExternMap = {};
|
||
|
this.FunctionMap = {};
|
||
|
this.WasPlus = 0;
|
||
|
this.buf = "";
|
||
|
this.stream = "";
|
||
|
this.bWasBackSlash = false;
|
||
|
this.pos = 0;
|
||
|
this.start = 0;
|
||
|
this.beforeRegExp = 0;
|
||
|
this.value = "";
|
||
|
this.type = "";
|
||
|
this.BlockLevel = 0;
|
||
|
this.LastStreamValue = "";
|
||
|
this.CountCol = 0;
|
||
|
this.ErrCount = 0;
|
||
|
this.WasEnter = false;
|
||
|
this.lastComment = 0;
|
||
|
this.lastAddCode = - 1;
|
||
|
this.LineNumber = 0;
|
||
|
this.posLineNumber = 0;
|
||
|
this.IgnoreCodeLevel = false;
|
||
|
this.AddToStream = this.AddToStreamAddTab;
|
||
|
};
|
||
|
this.AllowedWords = {true:1, false:1, undefined:1, Infinity:1, NaN:1, null:1, context:5, this:5, arguments:5, };
|
||
|
this.KeyWords = {break:1, return:1, case:1, do:1, if:1, switch:1, var:1, throw:1, while:1, default:1, for:1, try:1, continue:1,
|
||
|
with:1, function:3, void:3, new:3, delete:3, typeof:3, finally:5, catch:5, else:5, instanceof:4, in:4, };
|
||
|
this.ProcessWords = {break:"break", return:"return", case:"case", do:"do", if:"if", switch:"switch", var:"var", throw:"throw",
|
||
|
with:"with", while:"while", default:"default", for:"for", try:"try", continue:"continue", function:"function", void:"void",
|
||
|
new:"new", delete:"delete", typeof:"typeof", finally:"finally", catch:"catch", else:"else", };
|
||
|
this.enIndenifier = "1";
|
||
|
this.enString = "2";
|
||
|
this.enNumber = "3";
|
||
|
this.enSpaces = "4";
|
||
|
this.enNewLine = "5";
|
||
|
this.enComments = "6";
|
||
|
this.enRegular = "7";
|
||
|
this.enOperator = "O";
|
||
|
this.enEndFile = "EoF";
|
||
|
this.lexTypeAll = new Array(0x10000);
|
||
|
this.lexTypeIdentifier = new Array(0x10000);
|
||
|
this.lexTypeNumbers = new Array(0x10000);
|
||
|
this.lexTypeNumbers16 = new Array(0x10000);
|
||
|
this.lexTypeSpaces = new Array(0x10000);
|
||
|
this.lexTypeNewLines = new Array(0x10000);
|
||
|
this.lexTypeRegStart = new Array(0x10000);
|
||
|
this.SpacesArray = new Array(100);
|
||
|
this.Init = function ()
|
||
|
{
|
||
|
var BufNumbers = "0123456789";
|
||
|
var BufNumbers16 = "0123456789ABCDEFabcdef";
|
||
|
var BufChars = "~!%^&*-+/<>`@#()=\\|{}[];':\"?,.";
|
||
|
var BufSpaces = " \t\b\f\v\u00A0\u2028\u2029\u000C";
|
||
|
var BufNewLine = "\n\r";
|
||
|
var BufRegStart = "`~!#%^&*(+|-=\\[{};:,?<>";
|
||
|
SetType("N", BufNumbers, this.lexTypeAll);
|
||
|
SetType("C", BufChars, this.lexTypeAll);
|
||
|
SetType("S", BufSpaces, this.lexTypeAll);
|
||
|
SetType("M", BufNewLine, this.lexTypeAll);
|
||
|
SetLetterType("L", this.lexTypeAll, this.lexTypeAll);
|
||
|
SetType("N", BufNumbers, this.lexTypeNumbers);
|
||
|
SetType("N", BufNumbers16, this.lexTypeNumbers16);
|
||
|
SetType("S", BufSpaces, this.lexTypeSpaces);
|
||
|
SetType("M", BufNewLine, this.lexTypeNewLines);
|
||
|
SetType("R", BufRegStart, this.lexTypeRegStart);
|
||
|
SetLetterType("L", this.lexTypeAll, this.lexTypeIdentifier);
|
||
|
SetType("N", BufNumbers, this.lexTypeIdentifier);
|
||
|
Normalize(this.lexTypeAll);
|
||
|
Normalize(this.lexTypeNumbers);
|
||
|
Normalize(this.lexTypeNumbers16);
|
||
|
Normalize(this.lexTypeSpaces);
|
||
|
Normalize(this.lexTypeNewLines);
|
||
|
Normalize(this.lexTypeRegStart);
|
||
|
Normalize(this.lexTypeIdentifier);
|
||
|
this.SpacesArray[0] = "";
|
||
|
this.SpacesArray[1] = "";
|
||
|
for(var i = 2; i < 100; i++)
|
||
|
this.SpacesArray[i] = this.SpacesArray[i - 1] + " ";
|
||
|
|
||
|
function SetType(type,buf,TypeArray)
|
||
|
{
|
||
|
for(var pos = 0; pos < buf.length; pos++)
|
||
|
{
|
||
|
var c = buf.charCodeAt(pos);
|
||
|
TypeArray[c] = type;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
function SetLetterType(type,lexTypeAll,TypeArray)
|
||
|
{
|
||
|
for(var i = 32; i < 0x10000; i++)
|
||
|
{
|
||
|
if(!lexTypeAll[i] || lexTypeAll[i] == "L")
|
||
|
TypeArray[i] = "L";
|
||
|
}
|
||
|
TypeArray[92] = "L";
|
||
|
};
|
||
|
|
||
|
function Normalize(TypeArray)
|
||
|
{
|
||
|
for(var i = 0; i < 0x10000; i++)
|
||
|
{
|
||
|
TypeArray[i] = TypeArray[i] || false;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
function SetVeryQuickly(TypeArray)
|
||
|
{
|
||
|
var Ret = 0;
|
||
|
for(var i = 0; i < 0x10000; i++)
|
||
|
{
|
||
|
if(TypeArray[i])
|
||
|
Ret = 1;
|
||
|
else
|
||
|
Ret = 0;
|
||
|
}
|
||
|
return Ret;
|
||
|
};
|
||
|
};
|
||
|
this.Init();
|
||
|
|
||
|
function LANG(Str)
|
||
|
{
|
||
|
for(var i = 1; i < arguments.length; i++)
|
||
|
Str = Str.replace("%" + i, arguments[i]);
|
||
|
return Str;
|
||
|
};
|
||
|
this.Error = function ()
|
||
|
{
|
||
|
var Str1 = LANG.apply(this, arguments);
|
||
|
var begin = 0;
|
||
|
for(var i = this.start; i >= 0; i--)
|
||
|
if(this.buf[i] == "\n" || this.buf[i] == "\r")
|
||
|
{
|
||
|
begin = i + 1;
|
||
|
break;
|
||
|
}
|
||
|
var end = this.buf.length - 1;
|
||
|
for(var i = this.pos; i < this.buf.length; i++)
|
||
|
if(this.buf[i] == "\n" || this.buf[i] == "\r")
|
||
|
{
|
||
|
end = i;
|
||
|
break;
|
||
|
}
|
||
|
var line = 1;
|
||
|
for(var i = 0; i < this.start; i++)
|
||
|
if(this.buf[i] == "\n")
|
||
|
{
|
||
|
line++;
|
||
|
}
|
||
|
var col = this.start + 1 - begin;
|
||
|
var Dots1 = "";
|
||
|
var Dots2 = "";
|
||
|
if(this.start - begin > 100)
|
||
|
{
|
||
|
begin = this.start - 100;
|
||
|
Dots1 = "...";
|
||
|
}
|
||
|
if(end - this.start > 100)
|
||
|
{
|
||
|
end = this.start + 100;
|
||
|
Dots2 = "...";
|
||
|
}
|
||
|
this.ErrCount++;
|
||
|
var ErrLabel;
|
||
|
if(!this.ErrorOne && this.ErrorIgnore)
|
||
|
ErrLabel = " <<err:" + this.ErrCount + ">> ";
|
||
|
else
|
||
|
ErrLabel = " <<?>> ";
|
||
|
var StrLine = this.buf.substring(begin, this.start) + ErrLabel + this.buf.substring(this.start, end);
|
||
|
var Str2 = LANG("At line: %1 col: %2", line - 1, col - 1);
|
||
|
var Str = "SyntaxError: " + Str1 + ". " + Str2 + "\n" + Dots1 + StrLine + Dots2;
|
||
|
if(this.ErrorIgnore)
|
||
|
{
|
||
|
console.log(Str);
|
||
|
this.stream += ErrLabel;
|
||
|
this.stream += this.value + " ";
|
||
|
if(this.ErrorOne)
|
||
|
{
|
||
|
this.stream += "\n\n" + Str;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.NotBackPos();
|
||
|
return ;
|
||
|
}
|
||
|
}
|
||
|
throw Str;
|
||
|
};
|
||
|
this.code_base = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\u0402\u0403\u201a\u0453\u201e\u2026\u2020\u2021\u20ac\u2030\u0409\u2039\u040a\u040c\u040b\u040f\u0452\u2018\u2019\u201c\u201d\u2022\u2013\u2014\ufffd\u2122\u0459\u203a\u045a\u045c\u045b\u045f\xa0\u040e\u045e\u0408\xa4\u0490\xa6\xa7\u0401\xa9\u0404\xab\xac\xad\xae\u0407\xb0\xb1\u0406\u0456\u0491\xb5\xb6\xb7\u0451\u2116\u0454\xbb\u0458\u0405\u0455\u0457\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f';
|
||
|
this.FromBackSlashString = function (str)
|
||
|
{
|
||
|
var Ret = "";
|
||
|
for(var i = 0; i < str.length; i++)
|
||
|
{
|
||
|
var s = str[i];
|
||
|
if(s == "\\")
|
||
|
{
|
||
|
var s2 = str[i + 1];
|
||
|
switch(s2)
|
||
|
{
|
||
|
case "r":
|
||
|
i = i + 1;
|
||
|
Ret = Ret + "\r";
|
||
|
break;
|
||
|
case "n":
|
||
|
i = i + 1;
|
||
|
Ret = Ret + "\n";
|
||
|
break;
|
||
|
case "t":
|
||
|
i = i + 1;
|
||
|
Ret = Ret + "\t";
|
||
|
break;
|
||
|
case "b":
|
||
|
i = i + 1;
|
||
|
Ret = Ret + "\b";
|
||
|
break;
|
||
|
case "f":
|
||
|
i = i + 1;
|
||
|
Ret = Ret + "\f";
|
||
|
break;
|
||
|
case "u":
|
||
|
var s = str.substring(i + 2, i + 6);
|
||
|
var code = parseInt(s);
|
||
|
if(isNaN(code))
|
||
|
this.Error("Unrecognize unicode symbol: '%1'", "\\u" + s);
|
||
|
else
|
||
|
Ret = Ret + String.fromCharCode(code);
|
||
|
i = i + 5;
|
||
|
break;
|
||
|
case "x":
|
||
|
var s = str.substring(i + 2, i + 4);
|
||
|
var code = parseInt(s, 16);
|
||
|
if(isNaN(code))
|
||
|
this.Error("Unrecognize Latin symbol: '%1'", "\\x" + s);
|
||
|
else
|
||
|
Ret = Ret + this.code_base.charAt(code);
|
||
|
i = i + 3;
|
||
|
break;
|
||
|
default:
|
||
|
var c = str.charCodeAt(i + 1);
|
||
|
if(this.lexTypeNumbers[c] == "N")
|
||
|
{
|
||
|
var s = str.substring(i + 1, i + 4);
|
||
|
var code = parseInt(s, 8);
|
||
|
if(isNaN(code))
|
||
|
this.Error("Unrecognize Latin symbol: '%1'", "\\" + s);
|
||
|
else
|
||
|
Ret = Ret + this.code_base.charAt(code);
|
||
|
i = i + 3;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Ret = Ret + s;
|
||
|
}
|
||
|
}
|
||
|
return Ret;
|
||
|
};
|
||
|
this.PosString = function ()
|
||
|
{
|
||
|
var separator = this.buf[this.pos];
|
||
|
this.pos++;
|
||
|
while(this.pos < this.buf.length)
|
||
|
{
|
||
|
var s = this.buf[this.pos];
|
||
|
if(s == separator)
|
||
|
{
|
||
|
this.pos++;
|
||
|
return ;
|
||
|
}
|
||
|
else
|
||
|
if(s == "\\")
|
||
|
{
|
||
|
this.pos++;
|
||
|
this.bWasBackSlash = true;
|
||
|
}
|
||
|
else
|
||
|
if(s == "\n")
|
||
|
{
|
||
|
this.Error("Found end of line during calculate string");
|
||
|
return ;
|
||
|
}
|
||
|
this.pos++;
|
||
|
}
|
||
|
this.Error("Found end of file during calculate string");
|
||
|
};
|
||
|
this.PosRegExp = function ()
|
||
|
{
|
||
|
this.Error("RegExp not support");
|
||
|
return ;
|
||
|
var separator = "/";
|
||
|
this.pos++;
|
||
|
while(this.pos < this.buf.length)
|
||
|
{
|
||
|
var s = this.buf[this.pos];
|
||
|
if(s == separator)
|
||
|
{
|
||
|
this.pos++;
|
||
|
return ;
|
||
|
}
|
||
|
else
|
||
|
if(s == "[")
|
||
|
{
|
||
|
separator = "";
|
||
|
}
|
||
|
else
|
||
|
if(s == "]" && separator == "")
|
||
|
{
|
||
|
separator = "/";
|
||
|
}
|
||
|
else
|
||
|
if(s == "\\")
|
||
|
{
|
||
|
this.pos++;
|
||
|
this.bWasBackSlash = true;
|
||
|
}
|
||
|
else
|
||
|
if(s == "\n")
|
||
|
{
|
||
|
this.Error("Found end of line during calculate regexp");
|
||
|
return ;
|
||
|
}
|
||
|
this.pos++;
|
||
|
}
|
||
|
this.Error("Found end of file during calculate regexp");
|
||
|
};
|
||
|
this.PosCurrentType = function (TypeArray)
|
||
|
{
|
||
|
while(this.pos < this.buf.length)
|
||
|
{
|
||
|
var c = this.buf.charCodeAt(this.pos);
|
||
|
if(!TypeArray[c])
|
||
|
break;
|
||
|
if(c == 92)
|
||
|
this.bWasBackSlash = true;
|
||
|
this.pos++;
|
||
|
}
|
||
|
};
|
||
|
this.PosIdentifier = function ()
|
||
|
{
|
||
|
this.PosCurrentType(this.lexTypeIdentifier);
|
||
|
};
|
||
|
this.PosSpaces = function ()
|
||
|
{
|
||
|
this.PosCurrentType(this.lexTypeSpaces);
|
||
|
};
|
||
|
this.PosNewLines = function ()
|
||
|
{
|
||
|
this.PosCurrentType(this.lexTypeNewLines);
|
||
|
};
|
||
|
this.PosNumber = function ()
|
||
|
{
|
||
|
if(this.buf[this.pos] == "0")
|
||
|
{
|
||
|
this.pos++;
|
||
|
var s = this.buf[this.pos];
|
||
|
if(s == "x" || s == "X")
|
||
|
{
|
||
|
this.pos++;
|
||
|
this.PosCurrentType(this.lexTypeNumbers16);
|
||
|
}
|
||
|
else
|
||
|
if(s == ".")
|
||
|
{
|
||
|
this.pos++;
|
||
|
this.PosCurrentType(this.lexTypeNumbers);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.PosCurrentType(this.lexTypeNumbers);
|
||
|
}
|
||
|
return ;
|
||
|
}
|
||
|
this.PosCurrentType(this.lexTypeNumbers);
|
||
|
if(this.buf[this.pos] == ".")
|
||
|
{
|
||
|
this.pos++;
|
||
|
this.PosCurrentType(this.lexTypeNumbers);
|
||
|
}
|
||
|
if(this.buf[this.pos] == "e" || this.buf[this.pos] == "E")
|
||
|
{
|
||
|
this.pos++;
|
||
|
var s2 = this.buf[this.pos];
|
||
|
if(s2 == "+" || s2 == "-")
|
||
|
this.pos++;
|
||
|
var posstart = this.pos;
|
||
|
this.PosCurrentType(this.lexTypeNumbers);
|
||
|
if(posstart == this.pos)
|
||
|
this.Error("Unrecognize exponent number");
|
||
|
}
|
||
|
var c = this.buf.charCodeAt(this.pos);
|
||
|
var type = this.lexTypeAll[c];
|
||
|
if(type == "L")
|
||
|
this.Error("Unrecognize number");
|
||
|
};
|
||
|
this.PosCommentsOneLine = function ()
|
||
|
{
|
||
|
while(this.pos < this.buf.length)
|
||
|
{
|
||
|
var s = this.buf[this.pos];
|
||
|
if(s == '\n')
|
||
|
break;
|
||
|
else
|
||
|
if(s == '\r')
|
||
|
break;
|
||
|
this.pos++;
|
||
|
}
|
||
|
};
|
||
|
this.PosCommentsMultiLine = function ()
|
||
|
{
|
||
|
while(this.pos < this.buf.length)
|
||
|
{
|
||
|
var s = this.buf[this.pos] + this.buf[this.pos + 1];
|
||
|
if(s == '*/')
|
||
|
{
|
||
|
this.pos += 2;
|
||
|
break;
|
||
|
}
|
||
|
this.pos++;
|
||
|
}
|
||
|
};
|
||
|
this.BackPos = function ()
|
||
|
{
|
||
|
if(this.type != this.enEndFile)
|
||
|
this.pos = this.start;
|
||
|
};
|
||
|
this.NotBackPos = function ()
|
||
|
{
|
||
|
if(this.pos == this.start)
|
||
|
this.PosNextItem();
|
||
|
};
|
||
|
this.PosNextToken = function ()
|
||
|
{
|
||
|
this.WasEnter = false;
|
||
|
while(true)
|
||
|
{
|
||
|
this.PosNextItem();
|
||
|
switch(this.type)
|
||
|
{
|
||
|
case this.enNewLine:
|
||
|
this.WasEnter = true;
|
||
|
break;
|
||
|
case this.enSpaces:
|
||
|
case this.enComments:
|
||
|
break;
|
||
|
default:
|
||
|
return this.type;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
this.PosNextItem = function ()
|
||
|
{
|
||
|
this.start = this.pos;
|
||
|
if(this.pos >= this.buf.length)
|
||
|
{
|
||
|
this.type = this.enEndFile;
|
||
|
return this.enEndFile;
|
||
|
}
|
||
|
var c = this.buf.charCodeAt(this.pos);
|
||
|
var lex = this.lexTypeAll[c];
|
||
|
switch(lex)
|
||
|
{
|
||
|
case "L":
|
||
|
this.bWasBackSlash = false;
|
||
|
this.PosIdentifier();
|
||
|
this.value = this.buf.substring(this.start, this.pos);
|
||
|
if(this.bWasBackSlash)
|
||
|
this.value = this.FromBackSlashString(this.value);
|
||
|
this.beforeRegExp = 65;
|
||
|
this.type = this.enIndenifier;
|
||
|
if(this.value == "in" || this.value == "of" || this.value == "instanceof")
|
||
|
{
|
||
|
return this.value;
|
||
|
}
|
||
|
return this.enIndenifier;
|
||
|
case "N":
|
||
|
this.PosNumber();
|
||
|
this.value = this.buf.substring(this.start, this.pos);
|
||
|
this.beforeRegExp = 48;
|
||
|
this.type = this.enNumber;
|
||
|
return this.enNumber;
|
||
|
case "S":
|
||
|
this.PosSpaces();
|
||
|
this.type = this.enSpaces;
|
||
|
return this.enSpaces;
|
||
|
case "M":
|
||
|
this.PosNewLines();
|
||
|
this.type = this.enNewLine;
|
||
|
return this.enNewLine;
|
||
|
case "C":
|
||
|
var s = this.buf[this.pos];
|
||
|
switch(s)
|
||
|
{
|
||
|
case '"':
|
||
|
case "'":
|
||
|
this.bWasBackSlash = false;
|
||
|
this.PosString();
|
||
|
this.value = this.buf.substring(this.start, this.pos);
|
||
|
this.beforeRegExp = 65;
|
||
|
this.type = this.enString;
|
||
|
return this.enString;
|
||
|
case "/":
|
||
|
var s2 = this.buf[this.pos + 1];
|
||
|
if(s2 == '/')
|
||
|
{
|
||
|
this.PosCommentsOneLine();
|
||
|
if(!this.CommentIgnore && this.lastComment <= this.start)
|
||
|
{
|
||
|
this.lastComment = this.start + 1;
|
||
|
this.value = this.buf.substring(this.start, this.pos);
|
||
|
this.AddToStream(this.value);
|
||
|
this.AddToStream("\n");
|
||
|
}
|
||
|
this.type = this.enComments;
|
||
|
return this.enComments;
|
||
|
}
|
||
|
else
|
||
|
if(s2 == '*')
|
||
|
{
|
||
|
this.PosCommentsMultiLine();
|
||
|
if(!this.CommentIgnore && this.lastComment <= this.start)
|
||
|
{
|
||
|
this.lastComment = this.start + 1;
|
||
|
this.value = this.buf.substring(this.start, this.pos);
|
||
|
this.AddToStream(this.value);
|
||
|
if(this.buf[this.pos] == "\n")
|
||
|
{
|
||
|
this.AddToStream("\n");
|
||
|
this.pos++;
|
||
|
}
|
||
|
}
|
||
|
this.type = this.enComments;
|
||
|
return this.enComments;
|
||
|
}
|
||
|
else
|
||
|
if(this.lexTypeRegStart[this.beforeRegExp] == "R")
|
||
|
{
|
||
|
this.PosRegExp();
|
||
|
this.beforeRegExp = 65;
|
||
|
while("gmi".indexOf(this.buf[this.pos]) >= 0)
|
||
|
{
|
||
|
this.pos++;
|
||
|
}
|
||
|
this.value = this.buf.substring(this.start, this.pos);
|
||
|
this.type = this.enRegular;
|
||
|
return this.enRegular;
|
||
|
}
|
||
|
s += this.AddNextOperator("=");
|
||
|
break;
|
||
|
case "/":
|
||
|
this.beforeRegExp = 0;
|
||
|
s += this.AddNextOperator("=");
|
||
|
break;
|
||
|
case "=":
|
||
|
s += this.AddNextOperator("=");
|
||
|
s += this.AddNextOperator("=");
|
||
|
break;
|
||
|
case ">":
|
||
|
s += this.AddNextOperator(">");
|
||
|
s += this.AddNextOperator("=");
|
||
|
if(s == ">>=")
|
||
|
break;
|
||
|
s += this.AddNextOperator(">");
|
||
|
s += this.AddNextOperator("=");
|
||
|
break;
|
||
|
case "<":
|
||
|
s += this.AddNextOperator("<");
|
||
|
s += this.AddNextOperator("=");
|
||
|
break;
|
||
|
case "!":
|
||
|
s += this.AddNextOperator("=");
|
||
|
s += this.AddNextOperator("=");
|
||
|
break;
|
||
|
case "~":
|
||
|
break;
|
||
|
case "+":
|
||
|
s += this.AddNextOperator("+");
|
||
|
if(s == "++")
|
||
|
break;
|
||
|
s += this.AddNextOperator("=");
|
||
|
break;
|
||
|
case "-":
|
||
|
s += this.AddNextOperator("-");
|
||
|
if(s == "--")
|
||
|
break;
|
||
|
s += this.AddNextOperator("=");
|
||
|
break;
|
||
|
case "*":
|
||
|
s += this.AddNextOperator("=");
|
||
|
break;
|
||
|
case "&":
|
||
|
s += this.AddNextOperator("&");
|
||
|
if(s == "&&")
|
||
|
break;
|
||
|
s += this.AddNextOperator("=");
|
||
|
break;
|
||
|
case "|":
|
||
|
s += this.AddNextOperator("|");
|
||
|
if(s == "||")
|
||
|
break;
|
||
|
s += this.AddNextOperator("=");
|
||
|
break;
|
||
|
case "^":
|
||
|
s += this.AddNextOperator("=");
|
||
|
break;
|
||
|
case "%":
|
||
|
s += this.AddNextOperator("=");
|
||
|
break;
|
||
|
case ".":
|
||
|
var c2 = this.buf.charCodeAt(this.pos + 1);
|
||
|
if(this.lexTypeNumbers[c2])
|
||
|
{
|
||
|
this.pos++;
|
||
|
this.PosNumber();
|
||
|
this.value = this.buf.substring(this.start, this.pos);
|
||
|
this.beforeRegExp = 48;
|
||
|
this.type = this.enNumber;
|
||
|
return this.enNumber;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
this.beforeRegExp = c;
|
||
|
this.value = s;
|
||
|
this.pos++;
|
||
|
this.type = s;
|
||
|
return s;
|
||
|
default:
|
||
|
this.Error("Unrecognize symbol: '%1'", c);
|
||
|
}
|
||
|
this.type = this.enNewLine;
|
||
|
return this.enNewLine;
|
||
|
};
|
||
|
this.AddNextOperator = function (find)
|
||
|
{
|
||
|
var s2 = this.buf[this.pos + 1];
|
||
|
if(s2 == find)
|
||
|
{
|
||
|
this.pos++;
|
||
|
return s2;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return "";
|
||
|
}
|
||
|
};
|
||
|
this.ParseLexem = function (Code,bWrite)
|
||
|
{
|
||
|
this.Clear();
|
||
|
this.buf = Code;
|
||
|
this.beforeRegExp = 61;
|
||
|
var AllStr = "";
|
||
|
while(true)
|
||
|
{
|
||
|
var type = this.PosNextItem();
|
||
|
if(type == this.enEndFile)
|
||
|
break;
|
||
|
if(bWrite)
|
||
|
{
|
||
|
AllStr = AllStr + this.value + "\n";
|
||
|
}
|
||
|
}
|
||
|
if(AllStr)
|
||
|
{
|
||
|
console.log(AllStr);
|
||
|
}
|
||
|
return AllStr;
|
||
|
};
|
||
|
this.ParseLexem2 = function (Code)
|
||
|
{
|
||
|
this.Clear();
|
||
|
this.buf = Code;
|
||
|
this.beforeRegExp = 61;
|
||
|
var n = 0;
|
||
|
var Value1 = new Uint32Array(Code.length);
|
||
|
var Value2 = new Uint32Array(Code.length);
|
||
|
while(true)
|
||
|
{
|
||
|
var type = this.PosNextItem();
|
||
|
if(type == this.enEndFile)
|
||
|
break;
|
||
|
Value1[n] = this.start;
|
||
|
Value2[n] = this.pos;
|
||
|
n++;
|
||
|
}
|
||
|
return {Value1:Value1, Value2:Value2};
|
||
|
};
|
||
|
this.ParseCode = function (Code)
|
||
|
{
|
||
|
this.Clear();
|
||
|
this.buf = Code;
|
||
|
this.ParseSmart();
|
||
|
};
|
||
|
this.ParseSmart = function ()
|
||
|
{
|
||
|
var bPublic = 0;
|
||
|
while(true)
|
||
|
{
|
||
|
var type = this.PosNextToken();
|
||
|
if(type === this.enEndFile)
|
||
|
break;
|
||
|
if(type === this.enString && this.value === '"public"')
|
||
|
{
|
||
|
bPublic = 1;
|
||
|
continue;
|
||
|
}
|
||
|
if(this.value === "function")
|
||
|
{
|
||
|
var FuncName = this.Parse_function(0, 1);
|
||
|
if(bPublic)
|
||
|
this.ExternMap[FuncName] = bPublic;
|
||
|
bPublic = 0;
|
||
|
this.AddNewLineToStream(";\n");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.Error("Require 'function' indenifier");
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
this.ParseBlock = function (sConditions,bOneIteration,bSimpleMode,bNotCheck)
|
||
|
{
|
||
|
if(!bOneIteration)
|
||
|
this.BlockLevel++;
|
||
|
var WasIgnoreCodeLevel = this.IgnoreCodeLevel;
|
||
|
var bWasLabel = false;
|
||
|
this.beforeRegExp = 61;
|
||
|
Main:
|
||
|
while(true)
|
||
|
{
|
||
|
var posSave = this.pos;
|
||
|
var type = this.PosNextToken();
|
||
|
if(!bNotCheck && !bSimpleMode && !bWasLabel)
|
||
|
{
|
||
|
switch(type)
|
||
|
{
|
||
|
case ";":
|
||
|
case ":":
|
||
|
case "{":
|
||
|
case "}":
|
||
|
case this.enEndFile:
|
||
|
break;
|
||
|
case this.enIndenifier:
|
||
|
default:
|
||
|
this.AddCheckLineToStream();
|
||
|
}
|
||
|
}
|
||
|
switch(type)
|
||
|
{
|
||
|
case ";":
|
||
|
bWasLabel = false;
|
||
|
break;
|
||
|
case ":":
|
||
|
this.Error("Unexpected token: '%1'", this.GetTokenName(type));
|
||
|
bWasLabel = false;
|
||
|
break;
|
||
|
case "{":
|
||
|
this.AddNewLineToStream("{\n", true);
|
||
|
this.ParseBlock("}");
|
||
|
this.AddNewLineToStream("}\n", true);
|
||
|
bWasLabel = false;
|
||
|
break;
|
||
|
case "}":
|
||
|
break Main;
|
||
|
case this.enEndFile:
|
||
|
break Main;
|
||
|
case this.enIndenifier:
|
||
|
bNotCheck = false;
|
||
|
var Name = this.value;
|
||
|
var key = this.KeyWords[Name];
|
||
|
if(key == 1 || Name == "function")
|
||
|
{
|
||
|
this["Parse_" + this.ProcessWords[Name]]();
|
||
|
if(!bSimpleMode)
|
||
|
{
|
||
|
this.AddNewLineToStream(";\n");
|
||
|
}
|
||
|
type = this.type;
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
this.pos = posSave;
|
||
|
type = this.ParseExpressionWithComma(false, false, true);
|
||
|
if(type === ":")
|
||
|
{
|
||
|
bWasLabel = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bWasLabel = false;
|
||
|
if(!bSimpleMode)
|
||
|
{
|
||
|
this.AddNewLineToStream(";\n");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if(bOneIteration && type != ":")
|
||
|
break;
|
||
|
}
|
||
|
if(sConditions)
|
||
|
{
|
||
|
if(sConditions.indexOf(type) == - 1)
|
||
|
{
|
||
|
this.Error("Error block closing. Unexpected token: '%1'", this.GetTokenName(type));
|
||
|
}
|
||
|
}
|
||
|
this.IgnoreCodeLevel = WasIgnoreCodeLevel;
|
||
|
if(!bOneIteration)
|
||
|
this.BlockLevel--;
|
||
|
return type;
|
||
|
};
|
||
|
this.ParseOneBlock = function ()
|
||
|
{
|
||
|
var type = this.PosNextToken();
|
||
|
if(type == "{")
|
||
|
{
|
||
|
this.AddNewLineToStream("\n");
|
||
|
this.AddNewLineToStream("{\n", true);
|
||
|
var type = this.ParseBlock("}");
|
||
|
this.AddNewLineToStream("}\n", true);
|
||
|
}
|
||
|
else
|
||
|
if(type == ";")
|
||
|
{
|
||
|
if(this.InjectCheck)
|
||
|
{
|
||
|
this.AddCheckLineToStream();
|
||
|
this.AddNewLineToStream("\n");
|
||
|
}
|
||
|
else
|
||
|
this.AddNewLineToStream(";\n");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(this.InjectCheck)
|
||
|
{
|
||
|
this.AddNewLineToStream("\n");
|
||
|
this.AddNewLineToStream("{\n", true);
|
||
|
this.BackPos();
|
||
|
var type = this.ParseBlock(false, true);
|
||
|
this.AddNewLineToStream("}\n", true);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.AddNewLineToStream("\n");
|
||
|
this.BackPos();
|
||
|
this.BlockLevel++;
|
||
|
type = this.ParseBlock(false, true);
|
||
|
this.BlockLevel--;
|
||
|
}
|
||
|
}
|
||
|
if(type == ";")
|
||
|
{
|
||
|
this.NotBackPos();
|
||
|
}
|
||
|
return type;
|
||
|
};
|
||
|
this.ParseExpressionWithComma = function (sConditions,bCanEmpty,bCanLabel)
|
||
|
{
|
||
|
var sConditions2;
|
||
|
if(sConditions)
|
||
|
sConditions2 = "," + sConditions;
|
||
|
while(true)
|
||
|
{
|
||
|
var prev = this.pos;
|
||
|
var type = this.ParseExpression(sConditions2, bCanEmpty, bCanLabel);
|
||
|
if(type != ",")
|
||
|
break;
|
||
|
if(prev == this.pos || !sConditions2)
|
||
|
this.PosNextItem();
|
||
|
bCanLabel = false;
|
||
|
if(this.CountCol <= this.PrintMargin)
|
||
|
this.AddToStream(", ");
|
||
|
else
|
||
|
this.AddNewLineToStream(",\n", true);
|
||
|
}
|
||
|
return type;
|
||
|
};
|
||
|
this.ParseExpression = function (sConditions,bCanEmpty,bCanLabel)
|
||
|
{
|
||
|
var WasPlus2 = this.WasPlus;
|
||
|
var stream2 = this.stream;
|
||
|
this.WasPlus = 0;
|
||
|
this.stream = "";
|
||
|
var type = this.ParseExpression0(sConditions, bCanEmpty, bCanLabel);
|
||
|
if(this.WasPlus)
|
||
|
this.stream = stream2 + "CHKL(" + this.stream + ")";
|
||
|
else
|
||
|
this.stream = stream2 + this.stream;
|
||
|
this.WasPlus = WasPlus2;
|
||
|
return type;
|
||
|
};
|
||
|
this.ParseExpression0 = function (sConditions,bCanEmpty,bCanLabel)
|
||
|
{
|
||
|
var bWasExpr = false;
|
||
|
var bCanDot = false;
|
||
|
var bCanLeftSide = false;
|
||
|
this.beforeRegExp = 61;
|
||
|
Main:
|
||
|
while(true)
|
||
|
{
|
||
|
var type = this.PosNextItem();
|
||
|
switch(type)
|
||
|
{
|
||
|
case this.enSpaces:
|
||
|
case this.enComments:
|
||
|
continue;
|
||
|
case this.enNewLine:
|
||
|
bCanLeftSide = false;
|
||
|
this.WasEnter = true;
|
||
|
continue;
|
||
|
case this.enNumber:
|
||
|
case this.enIndenifier:
|
||
|
case this.enString:
|
||
|
case this.enRegular:
|
||
|
case "{":
|
||
|
if(bWasExpr)
|
||
|
break Main;
|
||
|
}
|
||
|
switch(type)
|
||
|
{
|
||
|
case this.enIndenifier:
|
||
|
var Name = this.value;
|
||
|
var key = this.KeyWords[Name];
|
||
|
if(key == 3)
|
||
|
{
|
||
|
this["Parse_" + this.ProcessWords[Name]]();
|
||
|
}
|
||
|
else
|
||
|
if(key == 1 || key == 5)
|
||
|
{
|
||
|
type = this.enOperator;
|
||
|
this.BackPos();
|
||
|
break Main;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(!this.AllowedWords[Name])
|
||
|
Name = LOC_ADD_NAME + Name;
|
||
|
this.AddToStream(Name);
|
||
|
if(bCanLabel)
|
||
|
{
|
||
|
var posSave2 = this.pos;
|
||
|
var type2 = this.PosNextToken();
|
||
|
if(type2 == ":")
|
||
|
{
|
||
|
type = type2;
|
||
|
bWasExpr = true;
|
||
|
this.AddNewLineToStream(":\n", true);
|
||
|
return ":";
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.pos = posSave2;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
bCanLeftSide = true;
|
||
|
bCanDot = true;
|
||
|
bWasExpr = true;
|
||
|
break;
|
||
|
case this.enNumber:
|
||
|
this.AddToStream(this.value);
|
||
|
bCanLeftSide = false;
|
||
|
bCanDot = true;
|
||
|
bWasExpr = true;
|
||
|
break;
|
||
|
case this.enString:
|
||
|
this.AddToStream(this.value);
|
||
|
bCanLeftSide = false;
|
||
|
bCanDot = true;
|
||
|
bWasExpr = true;
|
||
|
break;
|
||
|
case this.enRegular:
|
||
|
this.AddToStream(this.value);
|
||
|
bCanLeftSide = false;
|
||
|
bCanDot = true;
|
||
|
bWasExpr = true;
|
||
|
break;
|
||
|
case "{":
|
||
|
this.ParseDefObject();
|
||
|
bCanLeftSide = false;
|
||
|
bCanDot = true;
|
||
|
bWasExpr = true;
|
||
|
break;
|
||
|
case "[":
|
||
|
this.ParseDefArray();
|
||
|
bCanLeftSide = true;
|
||
|
bCanDot = true;
|
||
|
bWasExpr = true;
|
||
|
break;
|
||
|
case "(":
|
||
|
this.ParseFunctionCall(bCanDot);
|
||
|
bCanLeftSide = true;
|
||
|
bCanDot = true;
|
||
|
bWasExpr = true;
|
||
|
break;
|
||
|
case ".":
|
||
|
if(!bCanDot)
|
||
|
this.Error("Unexpected token: '%1'", type);
|
||
|
this.AddToStream(".");
|
||
|
this.RequireIndenifier();
|
||
|
bCanLeftSide = true;
|
||
|
bCanDot = true;
|
||
|
bWasExpr = true;
|
||
|
break;
|
||
|
case "?":
|
||
|
if(!bWasExpr)
|
||
|
this.Error("Require expression before token: '%1'", type);
|
||
|
this.ParseIfCondition();
|
||
|
bCanLeftSide = false;
|
||
|
bCanDot = false;
|
||
|
bWasExpr = true;
|
||
|
break;
|
||
|
case "=":
|
||
|
case "+=":
|
||
|
if(type === "+=")
|
||
|
this.WasPlus = 1;
|
||
|
if(!bCanLeftSide)
|
||
|
this.Error("Unexpected token: '%1'", type);
|
||
|
this.AddToStream(" " + type + " ");
|
||
|
var type2 = this.ParseExpression(undefined, false, false);
|
||
|
bCanLeftSide = false;
|
||
|
bCanDot = false;
|
||
|
bWasExpr = true;
|
||
|
break;
|
||
|
case "-=":
|
||
|
case "*=":
|
||
|
case "/=":
|
||
|
case ">>=":
|
||
|
case "<<=":
|
||
|
case ">>>=":
|
||
|
case "&=":
|
||
|
case "|=":
|
||
|
case "^=":
|
||
|
case "%=":
|
||
|
if(!bCanLeftSide)
|
||
|
this.Error("Unexpected token: '%1'", type);
|
||
|
this.AddToStream(" " + type + " ");
|
||
|
bCanLeftSide = false;
|
||
|
bCanDot = false;
|
||
|
bWasExpr = false;
|
||
|
break;
|
||
|
case "!":
|
||
|
this.AddToStream(type);
|
||
|
bCanLeftSide = false;
|
||
|
bCanDot = false;
|
||
|
break;
|
||
|
case "~":
|
||
|
this.AddToStream(type);
|
||
|
bCanLeftSide = false;
|
||
|
bCanDot = false;
|
||
|
break;
|
||
|
case "==":
|
||
|
case "===":
|
||
|
case "!=":
|
||
|
case "!==":
|
||
|
case ">=":
|
||
|
case "<=":
|
||
|
case ">":
|
||
|
case "<":
|
||
|
case "~":
|
||
|
case "^":
|
||
|
case "&":
|
||
|
case "|":
|
||
|
case "<<":
|
||
|
case ">>":
|
||
|
case ">>>":
|
||
|
case "%":
|
||
|
case "*":
|
||
|
case "/":
|
||
|
case "&&":
|
||
|
case "||":
|
||
|
if(!bWasExpr)
|
||
|
this.Error("Require expression before token: '%1'", type);
|
||
|
bWasExpr = false;
|
||
|
this.AddToStream(" " + type + " ");
|
||
|
bCanLeftSide = false;
|
||
|
bCanDot = false;
|
||
|
break;
|
||
|
case "-":
|
||
|
case "+":
|
||
|
if(type === "+")
|
||
|
this.WasPlus = 1;
|
||
|
bWasExpr = false;
|
||
|
this.AddToStream(" " + type + " ");
|
||
|
bCanLeftSide = false;
|
||
|
bCanDot = false;
|
||
|
break;
|
||
|
case "++":
|
||
|
case "--":
|
||
|
if(this.WasEnter)
|
||
|
if(bWasExpr)
|
||
|
{
|
||
|
type = ";";
|
||
|
break Main;
|
||
|
}
|
||
|
if(bWasExpr)
|
||
|
if(!bCanDot)
|
||
|
this.Error("Invalid left-side argument before token: '%1'", type);
|
||
|
this.AddToStream(type);
|
||
|
bCanLeftSide = false;
|
||
|
bCanDot = false;
|
||
|
break;
|
||
|
case "in":
|
||
|
case "of":
|
||
|
case "instanceof":
|
||
|
if(!bWasExpr)
|
||
|
this.Error("Invalid argument before: '%1'", type);
|
||
|
this.AddToStream(" " + type + " ");
|
||
|
this.ParseExpressionWithComma(false, false);
|
||
|
bWasExpr = true;
|
||
|
bCanLeftSide = false;
|
||
|
bCanDot = false;
|
||
|
break;
|
||
|
case ",":
|
||
|
case ";":
|
||
|
case ")":
|
||
|
case "]":
|
||
|
case "}":
|
||
|
case ":":
|
||
|
case this.enEndFile:
|
||
|
break Main;
|
||
|
default:
|
||
|
this.Error("Unexpected token: '%1'", type);
|
||
|
}
|
||
|
this.WasEnter = false;
|
||
|
}
|
||
|
if(sConditions)
|
||
|
{
|
||
|
if(sConditions.indexOf(type) == - 1)
|
||
|
{
|
||
|
if(type == this.enOperator)
|
||
|
this.Error("Unexpected keywords: '%1'", Name);
|
||
|
else
|
||
|
{
|
||
|
var str = this.GetTokenName(type);
|
||
|
if(str == type)
|
||
|
this.Error("Error expression closing. Unexpected token: '%1'", str);
|
||
|
else
|
||
|
this.Error("Error expression closing. Unexpected %1", str);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.BackPos();
|
||
|
}
|
||
|
if(!bCanEmpty && !bWasExpr)
|
||
|
{
|
||
|
var str;
|
||
|
if(type == this.enOperator)
|
||
|
str = Name;
|
||
|
else
|
||
|
{
|
||
|
str = this.GetTokenName(type);
|
||
|
}
|
||
|
if(str == type)
|
||
|
this.Error("Require expression before token: '%1'", str);
|
||
|
else
|
||
|
this.Error("Require expression before: %1", str);
|
||
|
}
|
||
|
return type;
|
||
|
};
|
||
|
this.GetTokenName = function (type)
|
||
|
{
|
||
|
switch(type)
|
||
|
{
|
||
|
case this.enNumber:
|
||
|
return "number";
|
||
|
case this.enIndenifier:
|
||
|
return "indenifier";
|
||
|
case this.enString:
|
||
|
return "string";
|
||
|
case this.enRegular:
|
||
|
return "regular";
|
||
|
case this.enEndFile:
|
||
|
return "End of file";
|
||
|
default:
|
||
|
return type;
|
||
|
}
|
||
|
};
|
||
|
this.RequireChar = function (sFind)
|
||
|
{
|
||
|
var type = this.PosNextToken();
|
||
|
if(type != sFind)
|
||
|
this.Error("Require token: '%1'", sFind);
|
||
|
};
|
||
|
this.RequireIndenifier = function (Name,DopStr)
|
||
|
{
|
||
|
var type = this.PosNextToken();
|
||
|
if(type != this.enIndenifier || (Name && this.value != Name))
|
||
|
{
|
||
|
if(Name)
|
||
|
this.Error("Require indenifier: '%1'", Name);
|
||
|
else
|
||
|
this.Error("Require indenifier");
|
||
|
}
|
||
|
if(DopStr)
|
||
|
this.AddToStream(DopStr + this.value);
|
||
|
else
|
||
|
this.AddToStream(this.value);
|
||
|
return this.value;
|
||
|
};
|
||
|
this.RequireIndenifierOptional = function ()
|
||
|
{
|
||
|
var type = this.PosNextToken();
|
||
|
if(type != this.enIndenifier)
|
||
|
{
|
||
|
this.BackPos();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.AddToStream(" " + this.value);
|
||
|
}
|
||
|
};
|
||
|
this.HasEnter = function ()
|
||
|
{
|
||
|
this.PosNextToken();
|
||
|
this.BackPos();
|
||
|
return this.WasEnter;
|
||
|
};
|
||
|
this.Parse_var = function ()
|
||
|
{
|
||
|
this.AddToStream("var ");
|
||
|
while(true)
|
||
|
{
|
||
|
this.RequireIndenifier(undefined, LOC_ADD_NAME);
|
||
|
var type = this.PosNextToken();
|
||
|
this.AddToStream(type);
|
||
|
if(type === "=")
|
||
|
this.ParseExpressionWithComma(false, false);
|
||
|
if(type !== ",")
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
this.Parse_function = function (bGetSet,bFindExternal)
|
||
|
{
|
||
|
if(!bGetSet)
|
||
|
{
|
||
|
this.AddToStream("function ");
|
||
|
}
|
||
|
var FuncName;
|
||
|
var type = this.PosNextToken();
|
||
|
if(type == this.enIndenifier)
|
||
|
{
|
||
|
FuncName = this.value;
|
||
|
if(bGetSet)
|
||
|
this.AddToStream(FuncName);
|
||
|
else
|
||
|
this.AddToStream(LOC_ADD_NAME + FuncName);
|
||
|
type = this.PosNextToken();
|
||
|
}
|
||
|
else
|
||
|
if(bGetSet)
|
||
|
{
|
||
|
this.Error("Require name before: '%1'", type);
|
||
|
}
|
||
|
if(type != "(")
|
||
|
this.Error("Require token: '%1'", "(");
|
||
|
this.AddToStream("(");
|
||
|
var bMustIdentifier = false;
|
||
|
while(true)
|
||
|
{
|
||
|
type = this.PosNextToken();
|
||
|
if(type == this.enIndenifier)
|
||
|
{
|
||
|
var Name = this.value;
|
||
|
this.AddToStream(LOC_ADD_NAME + Name);
|
||
|
type = this.PosNextToken();
|
||
|
if(type == ",")
|
||
|
{
|
||
|
this.AddToStream(",");
|
||
|
bMustIdentifier = true;
|
||
|
continue;
|
||
|
}
|
||
|
bMustIdentifier = false;
|
||
|
}
|
||
|
else
|
||
|
if(bMustIdentifier)
|
||
|
{
|
||
|
this.Error("Require indenifier");
|
||
|
break;
|
||
|
}
|
||
|
if(type == ")")
|
||
|
break;
|
||
|
this.Error("Require indenifier");
|
||
|
}
|
||
|
if(FuncName && bFindExternal)
|
||
|
{
|
||
|
this.FunctionMap[FuncName] = 1;
|
||
|
type = this.PosNextToken();
|
||
|
if(this.value === 'public')
|
||
|
{
|
||
|
this.ExternMap[FuncName] = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.BackPos();
|
||
|
}
|
||
|
}
|
||
|
this.RequireChar("{");
|
||
|
this.AddNewLineToStream(")\n", true);
|
||
|
this.AddNewLineToStream("{\n", true);
|
||
|
if(this.InjectCheck)
|
||
|
{
|
||
|
this.AddCheckLineToStream(30);
|
||
|
}
|
||
|
this.ParseBlock("}", false, false, false);
|
||
|
this.AddNewLineToStream("\n");
|
||
|
this.AddToStream("}", "} ");
|
||
|
return FuncName;
|
||
|
};
|
||
|
this.ParseFunctionCall = function (bCanEmpty)
|
||
|
{
|
||
|
this.AddToStream("(");
|
||
|
this.ParseExpressionWithComma(")", true);
|
||
|
this.AddToStream(")");
|
||
|
};
|
||
|
this.Parse_void = function ()
|
||
|
{
|
||
|
this.AddToStream("void ");
|
||
|
var type = this.ParseExpression();
|
||
|
};
|
||
|
this.Parse_new = function ()
|
||
|
{
|
||
|
this.AddToStream("new ");
|
||
|
var type = this.ParseExpression();
|
||
|
};
|
||
|
this.Parse_delete = function ()
|
||
|
{
|
||
|
this.AddToStream("delete ");
|
||
|
this.ParseExpression();
|
||
|
};
|
||
|
this.ParseIfCondition = function ()
|
||
|
{
|
||
|
this.AddToStream(" ? ");
|
||
|
this.ParseExpression(":");
|
||
|
this.AddToStream(" : ");
|
||
|
this.ParseExpression();
|
||
|
};
|
||
|
this.ParseDefArray = function ()
|
||
|
{
|
||
|
this.AddToStream("[");
|
||
|
this.ParseExpressionWithComma("]", true);
|
||
|
this.AddToStream("]");
|
||
|
};
|
||
|
this.ParseDefObject = function ()
|
||
|
{
|
||
|
this.BlockLevel++;
|
||
|
this.AddToStream("{");
|
||
|
while(true)
|
||
|
{
|
||
|
var type = this.PosNextToken();
|
||
|
if(type == this.enIndenifier || type == this.enString || type == this.enNumber)
|
||
|
{
|
||
|
var Name = this.value;
|
||
|
if(Name === "get" || Name === "set")
|
||
|
{
|
||
|
type = this.PosNextToken();
|
||
|
if(type == ":")
|
||
|
{
|
||
|
this.AddToStream(Name + ":");
|
||
|
type = this.ParseExpression(",}");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.AddToStream(Name + " ");
|
||
|
this.BackPos();
|
||
|
this.Parse_function(true);
|
||
|
type = this.PosNextToken();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.RequireChar(":");
|
||
|
this.AddToStream(Name + ":");
|
||
|
type = this.ParseExpression(",}");
|
||
|
}
|
||
|
}
|
||
|
if(type == "}")
|
||
|
break;
|
||
|
else
|
||
|
if(type == ",")
|
||
|
{
|
||
|
if(this.CountCol <= this.PrintMargin)
|
||
|
this.AddToStream(", ");
|
||
|
else
|
||
|
this.AddNewLineToStream(",\n", true);
|
||
|
continue;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.Error("Unexpected token: '%1'", this.GetTokenName(type));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
this.BlockLevel--;
|
||
|
this.AddToStream("}", "} ");
|
||
|
};
|
||
|
this.Parse_break = function ()
|
||
|
{
|
||
|
this.AddToStream("break");
|
||
|
if(this.HasEnter())
|
||
|
return ;
|
||
|
this.RequireIndenifierOptional();
|
||
|
};
|
||
|
this.Parse_continue = function ()
|
||
|
{
|
||
|
this.AddToStream("continue");
|
||
|
if(this.HasEnter())
|
||
|
return ;
|
||
|
this.RequireIndenifierOptional();
|
||
|
};
|
||
|
this.Parse_return = function ()
|
||
|
{
|
||
|
this.AddToStream("return ");
|
||
|
if(this.HasEnter())
|
||
|
return ;
|
||
|
this.ParseExpressionWithComma(false, true);
|
||
|
};
|
||
|
this.Parse_typeof = function ()
|
||
|
{
|
||
|
this.AddToStream("typeof ");
|
||
|
this.ParseExpression();
|
||
|
};
|
||
|
this.Parse_for = function ()
|
||
|
{
|
||
|
this.AddToStream("for(");
|
||
|
this.RequireChar("(");
|
||
|
var bForInMode = false;
|
||
|
var bWasVar = false;
|
||
|
var bWasName;
|
||
|
var posSave = this.pos;
|
||
|
var type = this.PosNextToken();
|
||
|
if(type == this.enIndenifier)
|
||
|
{
|
||
|
if(this.value == "var")
|
||
|
{
|
||
|
type = this.PosNextToken();
|
||
|
bWasVar = true;
|
||
|
}
|
||
|
if(type == this.enIndenifier)
|
||
|
{
|
||
|
bWasName = this.value;
|
||
|
type = this.PosNextToken();
|
||
|
if(type == this.enIndenifier && (this.value == "in" || this.value == "of"))
|
||
|
bForInMode = true;
|
||
|
}
|
||
|
}
|
||
|
if(bForInMode)
|
||
|
{
|
||
|
if(bWasVar)
|
||
|
this.AddToStream("var ");
|
||
|
this.AddToStream(LOC_ADD_NAME + bWasName + " " + this.value + " ");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.pos = posSave;
|
||
|
var type = this.ParseBlock(";", true, true);
|
||
|
if(type == ";")
|
||
|
this.NotBackPos();
|
||
|
this.AddToStream("; ");
|
||
|
this.ParseExpressionWithComma(";", true);
|
||
|
this.AddToStream("; ");
|
||
|
}
|
||
|
this.ParseExpressionWithComma(")", true);
|
||
|
this.AddToStream(")");
|
||
|
this.ParseOneBlock();
|
||
|
};
|
||
|
this.Parse_while = function ()
|
||
|
{
|
||
|
this.RequireChar("(");
|
||
|
this.AddToStream("while(");
|
||
|
this.ParseExpressionWithComma(")");
|
||
|
this.AddToStream(")");
|
||
|
this.ParseOneBlock();
|
||
|
};
|
||
|
this.Parse_do = function ()
|
||
|
{
|
||
|
this.AddToStream("do");
|
||
|
this.ParseOneBlock();
|
||
|
this.RequireIndenifier("while");
|
||
|
this.RequireChar("(");
|
||
|
this.AddToStream("(");
|
||
|
this.ParseExpressionWithComma(")");
|
||
|
this.AddToStream(")");
|
||
|
};
|
||
|
this.Parse_if = function ()
|
||
|
{
|
||
|
this.AddToStream("if(");
|
||
|
this.RequireChar("(");
|
||
|
this.ParseExpressionWithComma(")");
|
||
|
this.AddToStream(")");
|
||
|
this.ParseOneBlock();
|
||
|
var type = this.PosNextToken();
|
||
|
if(type == this.enIndenifier && this.ProcessWords[this.value] == "else")
|
||
|
{
|
||
|
this.AddToStream("else");
|
||
|
this.ParseOneBlock();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.BackPos();
|
||
|
}
|
||
|
};
|
||
|
this.Parse_switch = function ()
|
||
|
{
|
||
|
this.RequireChar("(");
|
||
|
this.AddToStream("switch(");
|
||
|
this.ParseExpressionWithComma(")");
|
||
|
this.RequireChar("{");
|
||
|
this.AddNewLineToStream(")\n", true);
|
||
|
this.AddNewLineToStream("{\n", true);
|
||
|
this.BlockLevel++;
|
||
|
this.ParseBlock("}", false, false, true);
|
||
|
this.BlockLevel--;
|
||
|
this.AddNewLineToStream("}\n", true);
|
||
|
};
|
||
|
this.Parse_case = function ()
|
||
|
{
|
||
|
this.BlockLevel--;
|
||
|
this.AddToStream("case ");
|
||
|
this.ParseExpressionWithComma(":");
|
||
|
this.AddNewLineToStream(":\n", true);
|
||
|
this.BlockLevel++;
|
||
|
};
|
||
|
this.Parse_default = function ()
|
||
|
{
|
||
|
this.RequireChar(":");
|
||
|
this.BlockLevel--;
|
||
|
this.AddNewLineToStream("default:\n", true);
|
||
|
this.BlockLevel++;
|
||
|
};
|
||
|
this.Parse_with = function ()
|
||
|
{
|
||
|
this.RequireChar("(");
|
||
|
this.AddToStream("with(");
|
||
|
this.ParseExpressionWithComma(")");
|
||
|
this.AddToStream(")");
|
||
|
this.ParseOneBlock();
|
||
|
};
|
||
|
this.Parse_try = function ()
|
||
|
{
|
||
|
this.Error("try-catch not support");
|
||
|
return ;
|
||
|
this.RequireChar("{");
|
||
|
this.AddToStream("try\n");
|
||
|
this.AddNewLineToStream("{\n", true);
|
||
|
this.ParseBlock("}");
|
||
|
this.AddNewLineToStream("}\n", true);
|
||
|
var type = this.PosNextToken();
|
||
|
if(type == this.enIndenifier && this.ProcessWords[this.value] == "catch")
|
||
|
{
|
||
|
this.AddToStream("catch(");
|
||
|
this.RequireChar("(");
|
||
|
this.RequireIndenifier();
|
||
|
this.RequireChar(")");
|
||
|
this.AddNewLineToStream(")\n", true);
|
||
|
this.AddNewLineToStream("{\n", true);
|
||
|
this.RequireChar("{");
|
||
|
this.ParseBlock("}");
|
||
|
this.AddToStream("}");
|
||
|
type = this.PosNextToken();
|
||
|
}
|
||
|
if(type == this.enIndenifier && this.ProcessWords[this.value] == "finally")
|
||
|
{
|
||
|
this.RequireChar("{");
|
||
|
this.AddNewLineToStream("\n");
|
||
|
this.AddNewLineToStream("finally\n", true);
|
||
|
this.AddNewLineToStream("{\n", true);
|
||
|
this.ParseBlock("}");
|
||
|
this.AddToStream("}");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.BackPos();
|
||
|
}
|
||
|
};
|
||
|
this.Parse_throw = function ()
|
||
|
{
|
||
|
this.AddToStream("throw ");
|
||
|
if(this.HasEnter())
|
||
|
return ;
|
||
|
var type = this.ParseExpressionWithComma();
|
||
|
};
|
||
|
this.AddCheckLineToStream = function (Count)
|
||
|
{
|
||
|
if(this.InjectCheck)
|
||
|
{
|
||
|
if(!Count)
|
||
|
Count = 1;
|
||
|
this.CalculateLineNumber();
|
||
|
this.AddToStream("DO(" + Count + ");");
|
||
|
}
|
||
|
};
|
||
|
this.CalculateLineNumber = function ()
|
||
|
{
|
||
|
for(var i = this.posLineNumber; i < this.pos; i++)
|
||
|
if(this.buf[i] == "\n")
|
||
|
this.LineNumber++;
|
||
|
this.posLineNumber = this.pos;
|
||
|
};
|
||
|
this.CalculateLineNumber0 = function (str)
|
||
|
{
|
||
|
for(var i = 0; i < str.length; i++)
|
||
|
if(str[i] == "\n")
|
||
|
this.LineNumber++;
|
||
|
};
|
||
|
this.AddCheckToStream = function (str)
|
||
|
{
|
||
|
if(this.InjectCheck)
|
||
|
{
|
||
|
this.AddToStream(str);
|
||
|
}
|
||
|
};
|
||
|
this.AddToStreamSimple = function (str,strMustLast)
|
||
|
{
|
||
|
if(strMustLast)
|
||
|
this.LastStreamValue = strMustLast;
|
||
|
else
|
||
|
this.LastStreamValue = str;
|
||
|
if(!this.IgnoreCodeLevel)
|
||
|
this.stream += str;
|
||
|
};
|
||
|
this.AddToStreamAddTab = function (str,strMustLast)
|
||
|
{
|
||
|
if(this.LastStreamValue[this.LastStreamValue.length - 1] == "\n")
|
||
|
{
|
||
|
this.CountCol = 0;
|
||
|
if(!this.IgnoreCodeLevel)
|
||
|
this.stream += this.SpacesArray[this.BlockLevel >= 100 ? 99 : this.BlockLevel];
|
||
|
}
|
||
|
if(str[str.length - 1] == "\n")
|
||
|
{
|
||
|
this.CountCol = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.CountCol += str.length;
|
||
|
}
|
||
|
this.AddToStreamSimple(str, strMustLast);
|
||
|
};
|
||
|
this.AddNewLineToStream = function (str,bAlways)
|
||
|
{
|
||
|
var sLast = this.LastStreamValue[this.LastStreamValue.length - 1];
|
||
|
if(bAlways || sLast != "\n")
|
||
|
{
|
||
|
if(str == ";\n" && (sLast == "}" || sLast == ";"))
|
||
|
{
|
||
|
this.AddToStream("\n");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this.AddToStream(str);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
global.LexerJS = new module.exports();
|