this.scopes = [];
this.indexedScopes = {};
this.timer = new Date() * 1;
-
+ this.debug = false;
}
// list of keywords that should not be used in object literals.
this.ts.rewind();
this.braceNesting = 0;
this.scopes= [];
- this.mode = 'CHECKING_SYMBOL_TREE';
+ this.mode = 'PASS2_SYMBOL_TREE';
//println("MUNGING?");
var isObjectLitAr = [ false ];
this.scopes.push(scope);
- token = this.ts.lookTok();
+ token = this.ts.lookTok(1);
while (token) {
// this.timerPrint("parseScope AFTER lookT: " + token.toString());
- //println("START<i>"+token.data+"</i>");
+ !this.debug|| print(token.type + '.' + token.name+ ":" + token.data);
switch(token.type + '.' + token.name) {
case "KEYW.VAR":
case "KEYW.CONST": // not really relivant as it's only mozzy that does this.
//this.log("parseScope GOT VAR/CONST : " + token.toString());
while (true) {
token = this.ts.nextTok();
-
- if (token.name == "var") { // kludge..
- continue;
- }
+ !this.debug|| print( token.toString());
+
if (!token) { // can return false at EOF!
break;
}
+ if (token.name == "VAR") { // kludge..
+ continue;
+ }
//this.logR("parseScope GOT VAR : <B>" + token.toString() + "</B>");
- if (!token.type =="NAME") {
- println(token.toString());
- throw "var without ident";
+ if (token.type !="NAME") {
+ print(token.toString());
+ print( "var without ident");
+ Seed.quit()
}
scope.declareIdentifier(token.data, token);
} else {
token.identifier = identifier;
- this.warn("The variable " + symbol + " has already been declared in the same scope...");
+ this.warn("The variable " + token.data + ' (line:' + token.line + ") has already been declared in the same scope...");
}
}
token = this.ts.nextTok();
+ !this.debug|| print(token.toString());
/*
assert token.getType() == Token.SEMI ||
token.getType() == Token.ASSIGN ||
this.parseExpression();
//this.logR("parseScope DONE : <B>ParseExpression</B> - tok is:" + this.ts.lookT(0).toString());
-
- if (this.ts.lookTok(0).data == ';') {
+ token = this.ts.lookTok(1);
+ !this.debug|| print("AFTER EXP: " + token.toString());
+ if (token.data == ';') {
break;
}
}
break;
+ case "NAME.NAME":
- default:
- if ((token.type != "NAME") && (token.type != "KEYW"){
- break;
- }
+ //print("DEAL WITH NAME:");
// got identifier..
// look for { ** : <- indicates obj literal.. ** this could occur with numbers ..
//println("<i>"+token.data+"</i>");
break;
}
+ // print("DEAL WITH obj lit:");
var isInObjectLitAr = isObjectLitAr[isObjectLitAr.length-1];
if (isInObjectLitAr && (this.ts.lookTok(1).data == ":") && (this.ts.lookTok(-1).data == ",")) {
// skip anyting with "." before it..!!
-
- if (this.ts.lookTok(-1).data(".")) {
+
+ if (this.ts.lookTok(-1).data == ".") {
// skip, it's an object prop.
//println("<i>"+token.data+"</i>");
break;
}
+ symbol = token.data;
+ if (this.mode == 'PASS2_SYMBOL_TREE') {
+
+ //println("GOT IDENT: -2 : " + this.ts.lookT(-2).toString() + " <BR> ..... -1 : " + this.ts.lookT(-1).toString() + " <BR> ");
+
+ //print ("MUNGE?" + symbol);
+
+ //println("GOT IDENT: <B>" + symbol + "</B><BR/>");
+
+ //println("GOT IDENT (2): <B>" + symbol + "</B><BR/>");
+ identifier = this.getIdentifier(symbol, scope);
+
+ if (identifier == false) {
+// BUG!find out where builtin is defined...
+ if (symbol.length <= 3 && Scope.builtin.indexOf(symbol) < 0) {
+ // Here, we found an undeclared and un-namespaced symbol that is
+ // 3 characters or less in length. Declare it in the global scope.
+ // We don't need to declare longer symbols since they won't cause
+ // any conflict with other munged symbols.
+ this.globalScope.declareIdentifier(symbol, token);
+ this.warn("Found an undeclared symbol: " + symbol + ' (line:' + token.line + ')', true);
+ }
+
+ //println("GOT IDENT IGNORE(3): <B>" + symbol + "</B><BR/>");
+ } else {
+ token.identifier = identifier;
+ identifier.refcount++;
+ }
+ }
+ break;
//println("<B>SID</B>");
-
-
+ default:
+ if (token.type != 'KEYW') {
+ break;
+ }
+ // print("Check eval:");
symbol = token.data;
}
- } else if (this.mode == 'CHECKING_SYMBOL_TREE') {
-
- //println("GOT IDENT: -2 : " + this.ts.lookT(-2).toString() + " <BR> ..... -1 : " + this.ts.lookT(-1).toString() + " <BR> ");
-
-
-
- //println("GOT IDENT: <B>" + symbol + "</B><BR/>");
-
- //println("GOT IDENT (2): <B>" + symbol + "</B><BR/>");
- identifier = this.getIdentifier(symbol, scope);
-
- if (identifier == false) {
-// BUG!find out where builtin is defined...
- if (symbol.length <= 3 && Scope.builtin.indexOf(symbol) < 0) {
- // Here, we found an undeclared and un-namespaced symbol that is
- // 3 characters or less in length. Declare it in the global scope.
- // We don't need to declare longer symbols since they won't cause
- // any conflict with other munged symbols.
- this.globalScope.declareIdentifier(symbol, token);
- this.warn("Found an undeclared symbol: " + symbol, true);
- }
-
- //println("GOT IDENT IGNORE(3): <B>" + symbol + "</B><BR/>");
- } else {
- token.identifier = identifier;
- identifier.refcount++;
- }
-
}
break;
// in the same brace nesting, bracket nesting and paren nesting.
// Parse functions if any...
//println("<i>EXP</i><BR/>");
+ !this.debug || print("PARSE EXPR");
var symbol;
var token;
var currentScope;
currentScope = this.scopes[this.scopes.length-1];
//println("<i>"+token.data+"</i>");
-
- switch (token.data.toUpperCase()) {
-
- case ';':
- case ',':
- if (this.braceNesting == expressionBraceNesting &&
- bracketNesting == 0 &&
- parensNesting == 0) {
- return;
- }
- break;
+ !this.debug|| print ("EXP" + token.toString());
+ switch (token.type) {
+ case 'PUNC':
+ switch(token.data) {
+
+ case ';':
+ case ',':
+ if (this.braceNesting == expressionBraceNesting &&
+ bracketNesting == 0 &&
+ parensNesting == 0) {
+
+ return;
+ }
+ break;
- case 'FUNCTION':
- this.parseFunctionDeclaration();
- break;
+
- case '{': //Token.LC:
- isObjectLitAr.push(false);
-
- this.braceNesting++;
- break;
+ case '{': //Token.LC:
+ isObjectLitAr.push(false);
+
+ this.braceNesting++;
+ break;
- case '}': //Token.RC:
- this.braceNesting--;
- isObjectLitAr.pop();
-
- // assert braceNesting >= expressionBraceNesting;
- break;
+ case '}': //Token.RC:
+ this.braceNesting--;
+ isObjectLitAr.pop();
+
+ // assert braceNesting >= expressionBraceNesting;
+ break;
- case '[': //Token.LB:
- bracketNesting++;
- break;
+ case '[': //Token.LB:
+ bracketNesting++;
+ break;
- case ']': //Token.RB:
- bracketNesting--;
- break;
+ case ']': //Token.RB:
+ bracketNesting--;
+ break;
- case '(': //Token.LP:
- parensNesting++;
- break;
+ case '(': //Token.LP:
+ parensNesting++;
+ break;
- case ')': //Token.RP:
- parensNesting--;
+ case ')': //Token.RP:
+ parensNesting--;
+ break;
+ }
break;
- }
- switch(token.type) {
-
+
case 'STRN': // used for object lit detection..
if (this.ts.lookTok(-1).data == "{" && this.ts.lookTok(1).data == ":" ) {
// then we are in an object lit.. -> we need to flag the brace as such...
var isInObjectLitAr = isObjectLitAr[isObjectLitAr.length-1];
- if (isInObjectLitAr && this.ts.lookTok(1).data = ":" &&
+ if (isInObjectLitAr && this.ts.lookTok(1).data == ":" &&
( this.ts.lookTok(-1).data == "{" || this.ts.lookTok(-1).data == "," )) {
// see if we can replace..
// remove the quotes..
break;
-
-
- /*
- case Token.SPECIALCOMMENT:
- if (mode == BUILDING_SYMBOL_TREE) {
- protectScopeFromObfuscation(currentScope);
- this.warn("Using JScript conditional comments is not recommended." + (munge ? " Moreover, using JScript conditional comments reduces the level of compression!" : ""), true);
- }
- break;
- */
+
+
case 'NAME':
- case 'KEYW':
+
symbol = token.data;
if (this.ts.lookTok(-1).data == "{" && this.ts.lookTok(1).data == ":") {
// then we are in an object lit.. -> we need to flag the brace as such...
break;
}
+ if (this.mode == 'PASS2_SYMBOL_TREE') {
+
+ identifier = this.getIdentifier(symbol, currentScope);
+ //println("<B>??</B>");
+ if (identifier == false) {
+
+ if (symbol.length <= 3 && Scope.builtin.indexOf(symbol) < 0) {
+ // Here, we found an undeclared and un-namespaced symbol that is
+ // 3 characters or less in length. Declare it in the global scope.
+ // We don't need to declare longer symbols since they won't cause
+ // any conflict with other munged symbols.
+ this.globalScope.declareIdentifier(symbol, token);
+ this.warn("Found an undeclared symbol: " + symbol + ' (line:' + token.line + ')', true);
+ } else {
+ //println("undeclared")
+ }
+
+
+ } else {
+ //println("<B>++</B>");
+ token.identifier = identifier;
+ identifier.refcount++;
+ }
+
+ }
+ break;
+
- //println("<B>EID</B>");
+ //println("<B>EID</B>");
+ case 'KEYW':
+
+ if (token.name == "FUNCTION") {
+
+ this.parseFunctionDeclaration();
+ break;
+ }
+
+
+ symbol = token.data;
if (this.mode == 'BUILDING_SYMBOL_TREE') {
if (symbol == "eval") {
}
break;
}
- if (this.mode == 'CHECKING_SYMBOL_TREE') {
-
- identifier = this.getIdentifier(symbol, currentScope);
- //println("<B>??</B>");
- if (identifier == false) {
-
- if (symbol.length <= 3 && Scope.builtin.indexOf(symbol) < 0) {
- // Here, we found an undeclared and un-namespaced symbol that is
- // 3 characters or less in length. Declare it in the global scope.
- // We don't need to declare longer symbols since they won't cause
- // any conflict with other munged symbols.
- this.globalScope.declareIdentifier(symbol, token);
- this.warn("Found an undeclared symbol: " + symbol, true);
- } else {
- //println("undeclared")
- }
-
-
- } else {
- //println("<B>++</B>");
- token.identifier = identifier;
- identifier.refcount++;
- }
-
- }
- break;
+
}
if (!this.ts.nextTok()) break;
}
parseFunctionDeclaration : function()
{
-
+ // print("PARSE FUNCTION");
var symbol;
var token;
var currentScope = false;
// Parse function arguments.
var argpos = 0;
- while (!this.ts.lookTok().data == ')') { //(token = consumeToken()).getType() != Token.RP) {
+ while (this.ts.lookTok().data != ')') { //(token = consumeToken()).getType() != Token.RP) {
token = this.ts.nextTok();
-
+ // print ("FUNC ARGS: " + token.toString())
//assert token.getType() == Token.NAME ||
// token.getType() == Token.COMMA;
if (token.type == 'NAME' && this.mode == 'BUILDING_SYMBOL_TREE') {
}
return false;
}
-});
\ No newline at end of file
+};
\ No newline at end of file