破晓 发表于 2016-8-11 10:21:57

Javascript的变量名混淆细节

来源:http://div.io/topic/397<p></p><div><br></div><div><div class="topic-firstfloor-detail type" style="font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; counter-reset: chapter 0 section 0 subsection 0; font-size: 16px; color: rgb(51, 51, 51); padding-top: 20px; padding-bottom: 20px; margin-top: 10px; line-height: 1.7; width: auto; margin-left: auto !important; margin-right: auto !important;"><h2 style="font-size: 26px; margin-top: 20px; margin-bottom: 20px; counter-reset: section 0; font-weight: normal;"><strong>前言</strong></h2><p style="margin-top: 18px; margin-bottom: 18px;">UglifyJS会对JS文件的变量名进行混淆处理,要理解Javascript变量混淆的细节,我们需要回答以下几个问题:<br>1.遇到一个变量myName,我们怎么知道这个myName变量要不要混淆<br>2.混淆名字怎么生成才合适,新的名字替换旧的名字时有什么要注意的地方?<br>3.哪些关键字会产生一个作用域?<br>4.作用域链跟符号表在UglifyJS里边是怎么体现?<br>5.UglifyJS混淆的过程是什么样?</p><p style="margin-top: 18px; margin-bottom: 18px;">我们先梳理一下这5个问题,最后贴出我阅读UglifyJS在这部分的实现时做的代码注释。</p><h2 style="font-size: 26px; margin-top: 20px; margin-bottom: 20px; counter-reset: section 0; font-weight: normal;"><strong>1.遇到一个变量myName,我们怎么知道这个myName变量要不要混淆</strong></h2><p style="margin-top: 18px; margin-bottom: 18px;"><strong>规则1.1:只有在作用域链上边的声明过的名字才可以混淆;当前文件声明的全局变量的名字不能混淆</strong><br>Javascript里边涉及到名字分为三种:变量名、函数名、标签名,下文统称为名字。<br>为了混淆某个名字,我们必须知道这个名字在当前作用域以及作用域链上的声明情况以及使用情况。我们先从变量的名字混淆开始讨论。</p><p style="margin-top: 18px; margin-bottom: 18px;">举个简单的例子,JS文件内容是:var myName = {}; myName.prop = val;<br>这里myName这个名字可以被混淆成别的名字,但是val这个变量就不能被混淆,因为它是全局变量,有可能在别的文件里边声明定义了。<br>同时我们知道如果在当前文件定义了一个全局变量,有可能会被另一个文件所引用,因此这个全局变量的名字也不能被混淆。<br>当然这里适用于函数名跟标签名。&nbsp;<br><strong>规则1.2:函数声明时的参数名可以混淆。</strong><br>对于一个函数声明:function func(argA, argB, argC){}<br>Javascript这里进入func之后其实就进入了func的作用域,我们知道argA/argB/argC其实就是在这个func作用域上声明的变量,&nbsp;<br><strong>规则1.3:catch后边参数列表的名字可以混淆。</strong><br>还可以发现一个特殊的地方,就是:try{ } catch(e) { }&nbsp;<br><strong>规则1.4:在使用了with的作用域链上的所有变量名都不能混淆。</strong><br>举个例子:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> A</span><span class="pun" style="color: rgb(102, 102, 0);">(){</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> myName </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"A"</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> B</span><span class="pun" style="color: rgb(102, 102, 0);">(){</span><span class="pln" style="color: rgb(0, 0, 0);">
          myName </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"B"</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="kwd" style="color: rgb(0, 0, 136);">with</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">obj</span><span class="pun" style="color: rgb(102, 102, 0);">){</span><span class="pln" style="color: rgb(0, 0, 0);">
               myName </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"with"</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px;">由于with会改变当前的作用域链,我们知道在with里边,如果obj具有myName这个属性的话,那myName = "with"其实就等价于obj.myName = "with";<br>如果是这种情况混淆了myName这个名字,运行时可能就不再对obj的myName属性进行赋值了。同理如果myName混淆成名字e的话,刚刚好obj有个属性名字叫做e,也可能会引起运行时错误。&nbsp;<br><strong>规则1.5:在使用了eval的作用域链上的所有变量名都不能混淆。</strong></p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> A</span><span class="pun" style="color: rgb(102, 102, 0);">(){</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> myName </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"A"</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> B</span><span class="pun" style="color: rgb(102, 102, 0);">(){</span><span class="pln" style="color: rgb(0, 0, 0);">
          myName </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"B"</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="kwd" style="color: rgb(0, 0, 136);">eval</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="str" style="color: rgb(0, 136, 0);">"myName = 1;"</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px;">因为eval是在运行时才知道执行的字符串的内容,因此在静态分析的时候并不能知道eval后边的字符串引用了什么变量,如果在当前作用域链上混淆了某些变量,可能引起eval的时候会有运行时找不到变量的错误。当然再复杂的情况就是eval里边又使用eval跟with嵌套&nbsp;<br></p><h2 style="font-size: 26px; margin-top: 20px; margin-bottom: 20px; counter-reset: section 0; font-weight: normal;"><strong>2.混淆名字怎么生成才合适,新的名字替换旧的名字时有什么要注意的地方?</strong></h2><p style="margin-top: 18px; margin-bottom: 18px;">如果我明确了一个变量myName需要被混淆,那最后它应该变成什么样的名字呢?首先肯定是越短越好,这样可以更有效的减少JS文件体积,下载JS速度也相应会提高。<br>因此简单的方案就是我从 $_ 这54个字母中取一个作为作为变量名即可,如果当前作用域声明的变量超过了54个,那就需要从$<span style="margin-right: 0.25em; border-bottom-width: 1px; border-bottom-style: dotted;">这64个字母中再去取第二个字母,如果还不够就接着取第三个字母。看完UglifyJS源码,觉得最牛逼的一点是,竟然为了考虑到gzip后的JS文件更小,其使用的混淆名字的顺序是:"etnrisouaflchpdvmgybwESxTNCkLAOM</span>DPHBjFIqRUzWXV$JKQGYZ0516372984"<br>UglifyJS的实现是,当前作用域得到的第1个混淆名为e,第2个混淆名是t……第54个是Z,第55个是et,第56个是tt……<br>讨论完怎么生成名字的规则后需要讨论混淆的规则了,混淆必须根据当前作用域的一些信息才能得以进行,首先这个规则最简单:</p><p style="margin-top: 18px; margin-bottom: 18px;"><strong>规则2.1:当前作用域不同变量混淆后的变量名不能重复,同时混淆后的名字不能是关键字。</strong>&nbsp;<br><br>其次要考虑以下几种在作用域链上的特殊情况:</p><p style="margin-top: 18px; margin-bottom: 18px;"><strong>规则2.2:作用域B的祖宗作用域是作用域A,作用域B如果引用作用域A的变量name,而name变量被混淆后的名字为e,则作用域B里边不得再使用e来作为其下所有变量的混淆名字。</strong><br>场景1. 作用域B里边引用了作用域A作用域声明的变量name,因此作用域B里边就不能再使用name混淆后的变量名字e,否则会出现下图右侧那样的问题:&nbsp;<a href="http://divio.qiniudn.com/FgsD9fXROkbe3aRGPuijscT9BBgF" target="_blank" style="text-decoration: none; color: rgb(49, 135, 219);"><img src="http://divio.qiniudn.com/FgsD9fXROkbe3aRGPuijscT9BBgF" alt="" width="632" height="209" style="vertical-align: baseline; max-width: 50em; margin-top: 1em; margin-bottom: 1em;"></a><br>这个情况只要作用域B是在作用域A的嵌套底下才会出现。<br></p><p style="margin-top: 18px; margin-bottom: 18px;"><strong>规则2.3:作用域B的祖宗作用域是作用域A,作用域B如果引用作用域A不参与混淆的变量e,则作用域B里边不得再使用e来作为其下所有变量的混淆名字。</strong><br>场景2.作用域A可能用到了一个全局变量e,因此我们不能将它混淆为其他名字,接着作用域B里边有e的引用,这个时候作用域B里边就不能再使用name混淆后的变量名字e,否则会出现下图右侧那样,e.b实际是引用了作用域B的e变量&nbsp;<a href="http://divio.qiniudn.com/FsB2VoliJy7pV" target="_blank" style="text-decoration: none; color: rgb(49, 135, 219);"><img src="http://divio.qiniudn.com/FsB2VoliJy7pV" alt="" style="vertical-align: baseline; max-width: 50em; margin-top: 1em; margin-bottom: 1em;"></a></p><p style="margin-top: 18px; margin-bottom: 18px;">这个情况只要作用域B是在作用域A的嵌套底下才会出现。<br></p><p style="margin-top: 18px; margin-bottom: 18px;"><strong>规则2.4:不能混淆全局变量。</strong><br>场景3.作用域A可能一个全局变量name,但是我们在作用域A的祖宗作用域中都找不到name的声明,这时候就不能把name给混淆掉,否则会出现右图那样,实际上没有e这个全局变量&nbsp;<a href="http://divio.qiniudn.com/FgaINlQsK8eD5Qmg-Pyn4Gvlmslu" target="_blank" style="text-decoration: none; color: rgb(49, 135, 219);"><img src="http://divio.qiniudn.com/FgaINlQsK8eD5Qmg-Pyn4Gvlmslu" alt="" style="vertical-align: baseline; max-width: 50em; margin-top: 1em; margin-bottom: 1em;"></a><br></p><h2 style="font-size: 26px; margin-top: 20px; margin-bottom: 20px; counter-reset: section 0; font-weight: normal;"><strong>3.哪些关键字会产生一个作用域?</strong></h2><p style="margin-top: 18px; margin-bottom: 18px;">在UglifyJS里边采用with<span style="margin-right: 0.25em; border-bottom-width: 1px; border-bottom-style: dotted;">new</span>scope这个函数来为AST树枝生成作用域信息。<br>可以从其源码中看到两个地方会产生作用域信息。&nbsp;<strong>规则3.1:整个JS文件处于一个全局作用域,UglifyJS称为toplevel。</strong><strong>规则3.2:function关键字声明的函数内部处于一个作用域。</strong>&nbsp;<strong>规则3.3:作用域A可以嵌套作用域B,这里可称之为作用域链,为了叙述方便,我把作用域B为作用域A的后代,变量的声明是沿着作用域链从低向上找到对应的定义。</strong></p><p style="margin-top: 18px; margin-bottom: 18px;">也许会比较奇怪两个问题:<br>1.with块里边不算作用域?<br>其实从Javascript的角度上来说,with是会改变当前作用域的。<br>在with(obj){ /**/ }的块里边,其实是位于一个新的作用域上,作用域的符号表就是obj这个对象。<br>但是为什么UglifyJS不把with认为是一个作用域?原因是with是在运行时改变了当前作用域链,UglifyJS在静态分析源代码的时候根本没法得知运行时的信息,因此没法把它当做作用域来看待,因为静态分析没法知道在with块里边怎么混淆变量名字,因此才有了规则1.4。</p><p style="margin-top: 18px; margin-bottom: 18px;">2.catch块不算作用域?<br>先看一个简单的Demo&nbsp;<a href="http://divio.qiniudn.com/FsLciavuVu-Id8uNR6UQ7CEiNmLk" target="_blank" style="text-decoration: none; color: rgb(49, 135, 219);"><img src="http://divio.qiniudn.com/FsLciavuVu-Id8uNR6UQ7CEiNmLk" alt="" style="vertical-align: baseline; max-width: 50em; margin-top: 1em; margin-bottom: 1em;"></a><br>其实这个例子不能说明问题,你应该始终把catch块认为是一个with块!<br>在进入catch块的时候,Javascript确实会生成一个作用域,这个作用域跟with的参数一样,是一个对象,也许你会奇怪这个对象有什么属性?答案就是:catch后边带的参数名是什么,这个对象就有那个属性。<br>上边的Demo中,进入catch的时候,实际上就是把一个对象Obj = {e:{}}放到了当前作用域链上。<br>然后在解析myName的时候,发现Obj没有,就回到了父亲作用域上找myName的声明,如果找不到,就在父亲作用域上边声明myName这个变量。<br>解析e变量的时候,发现e在当前的Obj属性有,所以在catch里边能够找到e的声明。<br>但是同with关键字一样,UglifyJS没法静态分析得到这个信息,因此它不会为catch这个AST树枝生成作用域信息。但是!catch跟with不同的地方就是,catch在静态分析的时候是可以知道在catch块作用域里边声明的变量了,没错,就是catch后边带的参数名字e,因此UglifyJS是会对这个变量进行混淆处理的。</p><h2 style="font-size: 26px; margin-top: 20px; margin-bottom: 20px; counter-reset: section 0; font-weight: normal;"><strong>4.作用域链跟符号表在UglifyJS里边是怎么体现?</strong></h2><p style="margin-top: 18px; margin-bottom: 18px;">UglifyJS的实现里边是使用Scope作为作用域类,这边罗列一下其属性,详细的实现见文章末尾的代码注释:</p><ol style="padding-left: 30px; margin-bottom: 14px;"><li>names = {} 表示在当前作用域下声明的变量函数的名字,也即是我们常常说的符号表!</li><li>mangled = {} 混淆前变量以及混淆后变量的映射表,变量myName混淆后得到变量e,那么mangled["myName"] == "e"。</li><li>rev_mangled = {} 跟mangled反过来,为了可以反查出混淆前变量的名字是什么。</li><li>cname = 当前已经混淆的变量个数,方便生成下一个混淆变量名字。</li><li>refs = {} 记录着当前作用域内引用的信息,ref["a"] = 表示当前作用域使用了作用域链上B作用域所声明的a变量。</li><li>uses_with = true/false 表示当前作用域有没有使用了with块,如果有的话,这条作用域链上的变量都不能混淆。</li><li>uses_eval = true/false 表示当前作用域有没有使用eval函数,如果有的话,这条作用域链上的变量都不能混淆。</li><li>parent = 父亲作用域是谁。</li><li>children = [] 孩子作用域列表。</li><li>level = 作用域嵌套深度,全局作用域为0。</li></ol><h2 style="font-size: 26px; margin-top: 20px; margin-bottom: 20px; counter-reset: section 0; font-weight: normal;"><strong>5.UglifyJS混淆的过程是什么样?</strong></h2><p style="margin-top: 18px; margin-bottom: 18px;">在语法分析之后得到AST树,UglifyJS就会开始遍历AST树,然后为某些节点生成作用域信息。<br>接着重新遍历AST树,再混淆里边的变量名,如下图:&nbsp;<a href="http://divio.qiniudn.com/FnhiND4zv4iiKM322MheCQQDwmJM" target="_blank" style="text-decoration: none; color: rgb(49, 135, 219);"><img src="http://divio.qiniudn.com/FnhiND4zv4iiKM322MheCQQDwmJM" alt="" style="vertical-align: baseline; max-width: 50em; margin-top: 1em; margin-bottom: 1em;"></a><br>UglifyJS的实现中是采用一个叫做ast<span style="margin-right: 0.25em; border-bottom-width: 1px; border-bottom-style: dotted;">walker来遍历AST树,调用者可以传递不同的树枝遍历器给它,以实现不同的遍历效果,这个实现非常巧妙,可以从上图中看到,四个对AST树的操作其实底层都是需要遍历AST树的,而且每次对树的处理不一样,例如ast</span>add<span style="margin-right: 0.25em; border-bottom-width: 1px; border-bottom-style: dotted; margin-left: 0.25em;">scope要为树枝绑定作用域信息,ast</span>mangle要把叶子节点名字混淆掉,ast<span style="margin-right: 0.25em; border-bottom-width: 1px; border-bottom-style: dotted; margin-left: 0.25em;">squeeze要优化树枝大小,最后的gen</span>code要把树枝输出成字符串。<br>ast<span style="margin-right: 0.25em; border-bottom-width: 1px; border-bottom-style: dotted;">walker对象是通过with</span>walkers这个API来重写遍历器:&nbsp;<a href="http://divio.qiniudn.com/FnPW06aSiGymKSp6yre72wOgkwaZ" target="_blank" style="text-decoration: none; color: rgb(49, 135, 219);"><img src="http://divio.qiniudn.com/FnPW06aSiGymKSp6yre72wOgkwaZ" alt="" style="vertical-align: baseline; max-width: 50em; margin-top: 1em; margin-bottom: 1em;"></a><br>遍历AST树的时候,可以重定义遍历器,对树枝进行处理:&nbsp;<a href="http://divio.qiniudn.com/FhjfwBz4exCu5AHoJrytOJ7yRqyU" target="_blank" style="text-decoration: none; color: rgb(49, 135, 219);"><img src="http://divio.qiniudn.com/FhjfwBz4exCu5AHoJrytOJ7yRqyU" alt="" style="vertical-align: baseline; max-width: 50em; margin-top: 1em; margin-bottom: 1em;"></a></p><h2 style="font-size: 26px; margin-top: 20px; margin-bottom: 20px; counter-reset: section 0; font-weight: normal;"><strong>代码注释</strong></h2><h4 style="font-size: 18px;"><strong>AST树遍历</strong></h4><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="com" style="color: rgb(136, 0, 0);">//遍历AST树</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="com" style="color: rgb(136, 0, 0);">//AST = ["toplevel", ["name", ]]</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="com" style="color: rgb(136, 0, 0);">//一般数组的第一个是当前语法规则</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="com" style="color: rgb(136, 0, 0);">//后边几个为语法规则对应的值</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="com" style="color: rgb(136, 0, 0);">//例如函数的AST树枝就是这样表示:["function", "func_name", arguments, body],其中arguments为数组,body是另一个AST子树</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> ast_walker</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> _vardefs</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">defs</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">defs</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">def</span><span class="pun" style="color: rgb(102, 102, 0);">){</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> a </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> def</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">def</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">length </span><span class="pun" style="color: rgb(102, 102, 0);">&gt;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
                a</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">def</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">]);</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> a</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">})</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> _block</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">statements</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="com" style="color: rgb(136, 0, 0);">//语句块</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> out </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">statements </span><span class="pun" style="color: rgb(102, 102, 0);">!=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
            out</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">push</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">statements</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">));</span><span class="com" style="color: rgb(136, 0, 0);">//遍历所有语句</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> out</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//默认的树枝遍历器</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//从这里就可以看出了整个AST树枝的组成结构了</span><span class="pln" style="color: rgb(0, 0, 0);">

   </span><span class="com" style="color: rgb(136, 0, 0);">//叶子节点(例如数值就是所谓的叶子节点)遍历器都是默认不处理 返回原有的树枝结构</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//如果节点不是叶子,,那么这个树枝的子树还需要递归遍历,例如:toplevel, function</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//下边再针对某些特殊的地方做注释</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> walkers </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"string"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">str</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> str </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"num"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">num</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> num </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"name"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> name </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"toplevel"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">statements</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">statements</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"block"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _block</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"splice"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _block</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="com" style="color: rgb(136, 0, 0);">//貌似没有这个状态?</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"var"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _vardefs</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"const"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _vardefs</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"try"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">t</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> c</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> f</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);">
                MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">t</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);">
                c </span><span class="pun" style="color: rgb(102, 102, 0);">!=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">?</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> c</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">c</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
                f </span><span class="pun" style="color: rgb(102, 102, 0);">!=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">?</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">f</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"throw"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"new"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ctor</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> args</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ctor</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">args</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"switch"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> body</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">body</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">branch</span><span class="pun" style="color: rgb(102, 102, 0);">){</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> branch</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">?</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">branch</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">])</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
                         MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">branch</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">})</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"break"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">label</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> label </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"continue"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">label</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> label </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"conditional"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">cond</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> t</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> e</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">cond</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">t</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">e</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"assign"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">op</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> lvalue</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> rvalue</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> op</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">lvalue</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">rvalue</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"dot"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//expr.b 的AST是这样=&gt; ["dot", expr, "b"];</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">].</span><span class="pln" style="color: rgb(0, 0, 0);">concat</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">slice</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">arguments</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">));</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"call"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> args</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">args</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"function"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> args</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> body</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> args</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">slice</span><span class="pun" style="color: rgb(102, 102, 0);">(),</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">body</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"debugger"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"defun"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> args</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> body</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> args</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">slice</span><span class="pun" style="color: rgb(102, 102, 0);">(),</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">body</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"if"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">conditional</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> t</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> e</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">conditional</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">t</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">e</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"for"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">init</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> cond</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> step</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> block</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">init</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">cond</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">step</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">block</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"for-in"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">vvar</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> key</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> hash</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> block</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//for (var init in obj)</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//AST为:["for-in", init, lhs, obj, statement]</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">vvar</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">key</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">hash</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">block</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"while"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">cond</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> block</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">cond</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">block</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"do"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">cond</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> block</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">cond</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">block</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"return"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"binary"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">op</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> left</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> right</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> op</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">left</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">right</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"unary-prefix"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">op</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> expr</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> op</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"unary-postfix"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">op</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> expr</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> op</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"sub"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> subscript</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//expr 的AST是这样=&gt; ["dot", expr, subscript];</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">subscript</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"object"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">props</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">props</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">p</span><span class="pun" style="color: rgb(102, 102, 0);">){</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> p</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">length </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pln" style="color: rgb(0, 0, 0);">
                  </span><span class="pun" style="color: rgb(102, 102, 0);">?</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> p</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">p</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">])</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);">
                  </span><span class="com" style="color: rgb(136, 0, 0);">//p == get | set</span><span class="pln" style="color: rgb(0, 0, 0);">
                  </span><span class="com" style="color: rgb(136, 0, 0);">//p 是get|set的函数体</span><span class="pln" style="color: rgb(0, 0, 0);">
                  </span><span class="com" style="color: rgb(136, 0, 0);">//p 为get|set函数名</span><span class="pln" style="color: rgb(0, 0, 0);">
                  </span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> p</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">p</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">]),</span><span class="pln" style="color: rgb(0, 0, 0);"> p</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// get/set-ter</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">})</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"regexp"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">rx</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> mods</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> rx</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> mods </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"array"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">elements</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">elements</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"stat"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">stat</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">stat</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"seq"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//逗号表达式</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">].</span><span class="pln" style="color: rgb(0, 0, 0);">concat</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">slice</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">arguments</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">));</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"label"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> block</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="com" style="color: rgb(136, 0, 0);">//这里的block应该statement才对!</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">block</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"with"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> block</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">block</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"atom"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> name </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"directive"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">dir</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> dir </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> user </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{};</span><span class="com" style="color: rgb(136, 0, 0);">//自定义树枝遍历器</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> stack </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[];</span><span class="com" style="color: rgb(136, 0, 0);">//AST遍历时的堆栈信息</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//遍历AST</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">try</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//当前AST树压栈</span><span class="pln" style="color: rgb(0, 0, 0);">
            stack</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">push</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

            </span><span class="com" style="color: rgb(136, 0, 0);">//["function", "func_name", arguments, body]</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">//AST树的第一个元素是这个树的类型</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> type </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> ast</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">

            </span><span class="com" style="color: rgb(136, 0, 0);">//取出遍历钩子,这个钩子可以是外界传递进来 也可以是内部默认</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">//具体由with_walkers第一个参数来生成</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> gen </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> user</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">type</span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">gen</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="com" style="color: rgb(136, 0, 0);">//如果有自定义的树枝遍历器,则用这个遍历器来遍历该树枝,得到结果</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> ret </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> gen</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">apply</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> ast</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">slice</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">));</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ret </span><span class="pun" style="color: rgb(102, 102, 0);">!=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
                  </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> ret</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">//否则调用默认的树枝遍历器</span><span class="pln" style="color: rgb(0, 0, 0);">
            gen </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> walkers</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">type</span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> gen</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">apply</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> ast</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">slice</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">));</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);"> finally </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//最后恢复堆栈信息</span><span class="pln" style="color: rgb(0, 0, 0);">
            stack</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">pop</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//跟walk一样是遍历AST的功能,但是是采用默认的树枝遍历器来遍历</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> dive</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">try</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            stack</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">push</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> walkers</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">ast</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">]].</span><span class="pln" style="color: rgb(0, 0, 0);">apply</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> ast</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">slice</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">));</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);"> finally </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            stack</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">pop</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//外边可以传入自定义的遍历器</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//@param walkers 外界定义的遍历器</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//@param cont @unknowed</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> with_walkers</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">walkers</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> cont</span><span class="pun" style="color: rgb(102, 102, 0);">){</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//walkers = {"function":function(){}}</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> save </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{},</span><span class="pln" style="color: rgb(0, 0, 0);"> i</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//i是语法规则名</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">i in walkers</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">HOP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">walkers</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> i</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            save</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> user</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="com" style="color: rgb(136, 0, 0);">//保存原来的遍历器</span><span class="pln" style="color: rgb(0, 0, 0);">
            user</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> walkers</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="com" style="color: rgb(136, 0, 0);">//用新的遍历器覆盖之</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> ret </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> cont</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="com" style="color: rgb(136, 0, 0);">//执行钩子 一般这里外边会调用:walk(ast)来遍历AST树</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">//恢复原来的状态</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">i in save</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">HOP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">save</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> i</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(!</span><span class="pln" style="color: rgb(0, 0, 0);">save</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">])</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">delete</span><span class="pln" style="color: rgb(0, 0, 0);"> user</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">else</span><span class="pln" style="color: rgb(0, 0, 0);"> user</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> save</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">//得到遍历后生成的新的AST树</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> ret</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      walk</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      dive</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> dive</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      with_walkers</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> with_walkers</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      parent</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//如果是当前这样的AST树</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//["toplevel", ["stat", ["function", "A", [], []]]]</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//遍历到树枝function的时候</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//stack是这样的</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">/*
               ["toplevel", ["stat", ["function", "A", [], []]]]
               ["stat", ["function", "A", [], []]]
               ["function", "A", [], []]
          */</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//function的父亲其实就是堆栈stack的倒数第二个节点</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> stack</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">stack</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">length </span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// last one is current node</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      stack</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> stack</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">&lt;/</span><span class="pln" style="color: rgb(0, 0, 0);">pre</span><span class="pun" style="color: rgb(102, 102, 0);">&gt;</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="pun" style="color: rgb(102, 102, 0);">&lt;</span><span class="pln" style="color: rgb(0, 0, 0);">h4</span><span class="pun" style="color: rgb(102, 102, 0);">&gt;&lt;</span><span class="pln" style="color: rgb(0, 0, 0);">strong</span><span class="pun" style="color: rgb(102, 102, 0);">&gt;作用域信息&lt;</span><span class="str" style="color: rgb(0, 136, 0);">/strong&gt;&lt;/</span><span class="pln" style="color: rgb(0, 0, 0);">h4</span><span class="pun" style="color: rgb(102, 102, 0);">&gt;</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">&lt;</span><span class="pln" style="color: rgb(0, 0, 0);">pre lang</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="str" style="color: rgb(0, 136, 0);">"javascript"</span><span class="pun" style="color: rgb(102, 102, 0);">&gt;</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="com" style="color: rgb(136, 0, 0);">/*
   这份代码设计了作用域链的属性以及方法
   同时还有一个遍历AST树给节点加作用域信息的with_new_scope方法
*/</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="com" style="color: rgb(136, 0, 0);">//作用域信息类</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">Scope</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">parent</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">

   </span><span class="com" style="color: rgb(136, 0, 0);">//当前作用域的符号表,包括变量跟函数变量</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">names </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{};</span><span class="pln" style="color: rgb(0, 0, 0);">      </span><span class="com" style="color: rgb(136, 0, 0);">// names defined in this scope</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//混淆变量表</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//例如源代码是:var myOldName; 压缩后变成:var e;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//那么mangled跟rev_mangled分别记录着这个映射关系</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//mangled["myOldName"] = "e"   |    rev_mangled["e"] = "myOldName" </span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">mangled </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{};</span><span class="pln" style="color: rgb(0, 0, 0);">      </span><span class="com" style="color: rgb(136, 0, 0);">// mangled names (orig.name =&gt; mangled)</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">rev_mangled </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{};</span><span class="pln" style="color: rgb(0, 0, 0);"></span><span class="com" style="color: rgb(136, 0, 0);">// reverse lookup (mangled =&gt; orig.name)</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//当前作用域已经混淆的变量个数</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">cname </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">      </span><span class="com" style="color: rgb(136, 0, 0);">// current mangled name</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//当前作用域使用到的引用变量名字</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//例如 function(){var i, j; j = 1;}</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//此时refs = {"j" : &lt;Scope&gt;}; i只是一个声明 不是一个引用</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">refs </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{};</span><span class="pln" style="color: rgb(0, 0, 0);">         </span><span class="com" style="color: rgb(136, 0, 0);">// names referenced from this scope</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//如果在with里边?@unkowned</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">uses_with </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">false</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// will become TRUE if with() is detected in this or any subscopes</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//如果在eval里边?@unkowned</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">uses_eval </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">false</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// will become TRUE if eval() is detected in this or any subscopes</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//作用域的指示性字符串列表,例如:"use strict";</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">directives </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[];</span><span class="pln" style="color: rgb(0, 0, 0);">   </span><span class="com" style="color: rgb(136, 0, 0);">// directives activated from this scope</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//当前作用域的父亲作用域,由此可以搞成一个作用域链!</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">parent </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> parent</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">   </span><span class="com" style="color: rgb(136, 0, 0);">// parent scope</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//当前作用于的子作用域列表</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">children </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[];</span><span class="pln" style="color: rgb(0, 0, 0);">   </span><span class="com" style="color: rgb(136, 0, 0);">// sub-scopes</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//如果设置了父亲,那么在父亲的children加上当前对象。</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//level只嵌套深度</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">parent</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">level </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> parent</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">level </span><span class="pun" style="color: rgb(102, 102, 0);">+</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      parent</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">children</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">push</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">else</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">level </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> base54_digits</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//你可以自定义混淆的表哦~通过自己定义DIGITS_OVERRIDE_FOR_TESTING这个变量</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">typeof</span><span class="pln" style="color: rgb(0, 0, 0);"> DIGITS_OVERRIDE_FOR_TESTING </span><span class="pun" style="color: rgb(102, 102, 0);">!=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"undefined"</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> DIGITS_OVERRIDE_FOR_TESTING</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">else</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//为什么是下边这个字符串?用这个顺序混淆之后 再gzip之后会得到更少的字节</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//这里要了解gzip算法 @unkowned</span><span class="pln" style="color: rgb(0, 0, 0);">

   </span><span class="com" style="color: rgb(136, 0, 0);">//见:https://github.com/mishoo/UglifyJS/commit/4072f80ada49f8bd541045690f5f922ff5a43b59</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//Optimize list of digits for generating identifiers for gzip compression.</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//The list is based on reserved words and identifiers used in dot-expressions. It saves a quite a few bytes.</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"etnrisouaflchpdvmgybwESxTNCkLAOM_DPHBjFIqRUzWXV$JKQGYZ0516372984"</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> base54 </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(){</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> DIGITS </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> base54_digits</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//最后得到的混淆顺序是这样:</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//e t n r …… Z</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//et tt nt rt …… Zt //为什么这里不是 ee te ……</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//……</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">num</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">/*
   //为了第二位数也是从e开始: ee te ……
   //其实可以优化成这个样子:
      var ret = "", base = 54;//54是前边54个英文+$ 因为不能用数字开头
      var b = 0, maxb = 1 + num &gt; 54 ? Math.ceil((num-54+1)/64) : 0;
      do {
            ret += DIGITS.charAt(num % base);
            b++;
            num = Math.floor(num / base) - 1;
            base = 64;
      } while (num &gt;= 0 &amp;&amp; b &lt;= maxb);
      return ret;
          */</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> ret </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">""</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> base </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">54</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="com" style="color: rgb(136, 0, 0);">//54是前边54个英文+$ 因为不能用数字开头</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">do</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            ret </span><span class="pun" style="color: rgb(102, 102, 0);">+=</span><span class="pln" style="color: rgb(0, 0, 0);"> DIGITS</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">charAt</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">num </span><span class="pun" style="color: rgb(102, 102, 0);">%</span><span class="pln" style="color: rgb(0, 0, 0);"> base</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
            num </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">Math</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">floor</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">num </span><span class="pun" style="color: rgb(102, 102, 0);">/</span><span class="pln" style="color: rgb(0, 0, 0);"> base</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
            base </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">64</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">while</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">num </span><span class="pun" style="color: rgb(102, 102, 0);">&gt;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> ret</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">})();</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="com" style="color: rgb(136, 0, 0);">//作用域对象成员方法</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="typ" style="color: rgb(102, 0, 102);">Scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">prototype </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//判断在当前作用域上能不能找到变量name</span><span class="pln" style="color: rgb(0, 0, 0);">
    has</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//沿着作用链一层一层搜索符号表 有木有!</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> s </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> s </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">parent</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">HOP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">names</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//看看当前混淆的名字处于那个作用链上边</span><span class="pln" style="color: rgb(0, 0, 0);">
    has_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">mname</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> s </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> s </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">parent</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">HOP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">rev_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> mname</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//这个没太大意义</span><span class="pln" style="color: rgb(0, 0, 0);">
    toJSON</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            names</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">names</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
            uses_eval</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">uses_eval</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
            uses_with</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">uses_with
      </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//这个函数就是变量名字混淆的关键了!</span><span class="pln" style="color: rgb(0, 0, 0);">
    next_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">// we must be careful that the new mangled name:</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">// 1. doesn't shadow a mangled name from a parent</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//    scope, unless we don't reference the original</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//    name from this scope OR from any sub-scopes!</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//    This will get slow.</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">// 2. doesn't shadow an original name from a parent</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//    scope, in the event that the name is not mangled</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//    in the parent scope and we reference that name</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//    here OR IN ANY SUBSCOPES!</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">// 3. doesn't shadow a name that is referenced but not</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//    defined (possibly global defined elsewhere).</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(;;)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//留意了,通过base54这个函数生成混淆后的名字</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> m </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> base54</span><span class="pun" style="color: rgb(102, 102, 0);">(++</span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">cname</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> prior</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

            </span><span class="com" style="color: rgb(136, 0, 0);">//有个优先级</span><span class="pln" style="color: rgb(0, 0, 0);">

            </span><span class="com" style="color: rgb(136, 0, 0);">// case 1.</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">/*
               对应这样的情况
                  var name = {};//混淆后得到变量名字a
                  function(){
                         //在这里边要混淆name2这个变量成名字a 发现a已经在父亲作用域时混淆的时候用到了
                         //prior = this.has_mangled("a"); =&gt; 父亲作用域
                         //那就得看看在当前作用域内,name有没有被引用了
                         //如果有name.b = 1 那么name2就不能用名字a
                         //否则可以使用名字a
                         var name2 = {};
                         name.b = 1;
                  }
             */</span><span class="pln" style="color: rgb(0, 0, 0);">
            prior </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">has_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">m</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">prior </span><span class="pun" style="color: rgb(102, 102, 0);">&amp;&amp;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">refs</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">prior</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">rev_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">m</span><span class="pun" style="color: rgb(102, 102, 0);">]]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">===</span><span class="pln" style="color: rgb(0, 0, 0);"> prior</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">continue</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

            </span><span class="com" style="color: rgb(136, 0, 0);">// case 2.</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">/*
               对应这样的情况
               e = {};//这个在父亲作用域有e这个变量
               function(){
                         //this这里想要把变量name1也混淆成e这个名字
                         var name1;
                         e.a = 1;
                  }
             */</span><span class="pln" style="color: rgb(0, 0, 0);">
            prior </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">has</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">m</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">//!prior.has_mangled(m)说明了e这个变量名字不是混淆 而是原始名字 这里可以认为是全局作用域的引用!</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">prior </span><span class="pun" style="color: rgb(102, 102, 0);">&amp;&amp;</span><span class="pln" style="color: rgb(0, 0, 0);"> prior </span><span class="pun" style="color: rgb(102, 102, 0);">!==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">&amp;&amp;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">refs</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">m</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">===</span><span class="pln" style="color: rgb(0, 0, 0);"> prior </span><span class="pun" style="color: rgb(102, 102, 0);">&amp;&amp;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">!</span><span class="pln" style="color: rgb(0, 0, 0);">prior</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">has_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">m</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">continue</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

            </span><span class="com" style="color: rgb(136, 0, 0);">// case 3.</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">/*
               对应这样的情况
                  name = 1;
                  //这种name是全局对象,通过refs找不到对应的作用域,这种变量名字也不能混淆!
             */</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">HOP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">refs</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> m</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">&amp;&amp;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">refs</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">m</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">continue</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

            </span><span class="com" style="color: rgb(136, 0, 0);">// I got "do" once. :-/</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(!</span><span class="pln" style="color: rgb(0, 0, 0);">is_identifier</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">m</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">continue</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> m</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//设置混淆变量名的符号表而已</span><span class="pln" style="color: rgb(0, 0, 0);">
    set_mangle</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> m</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">rev_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">m</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">mangled</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> m</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//获取name变量映射的混淆名</span><span class="pln" style="color: rgb(0, 0, 0);">
    get_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> newMangle</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//在with跟eval里边不混淆变量名!</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">uses_eval </span><span class="pun" style="color: rgb(102, 102, 0);">||</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">uses_with</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// no mangle if eval or with is in use</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> s </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">has</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">//不在作用域链上的 可能是别的文件定义的全局变量 所以不能混淆!</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(!</span><span class="pln" style="color: rgb(0, 0, 0);">s</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// not in visible scope, no mangle</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">//已经混淆过的,那直接返回即可</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">HOP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">mangled</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">mangled</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// already mangled in this scope</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">//外部调用指定newMangle = false告诉你不混淆 还混淆个毛线~</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(!</span><span class="pln" style="color: rgb(0, 0, 0);">newMangle</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">                      </span><span class="com" style="color: rgb(136, 0, 0);">// not found and no mangling requested</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">//最后如果发现需要混淆了,那么调用next_mangled得到一个混淆名 同时设置好符号表映射关系</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">set_mangle</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">next_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">());</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//看看name是不是一个引用,以下几个情况都属于引用:</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//在全局域里边的name </span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//在with eval里边的变量都属于引用,名字不能混淆</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//或者当前作用域有refs</span><span class="pln" style="color: rgb(0, 0, 0);">
    references</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> name </span><span class="pun" style="color: rgb(102, 102, 0);">&amp;&amp;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">!</span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">parent </span><span class="pun" style="color: rgb(102, 102, 0);">||</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">uses_with </span><span class="pun" style="color: rgb(102, 102, 0);">||</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">uses_eval </span><span class="pun" style="color: rgb(102, 102, 0);">||</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">refs</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//记录当前作用域的变量声明</span><span class="pln" style="color: rgb(0, 0, 0);">
    define</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> type</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name </span><span class="pun" style="color: rgb(102, 102, 0);">!=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">type </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"var"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">||</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">!</span><span class="pln" style="color: rgb(0, 0, 0);">HOP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">names</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">names</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> type </span><span class="pun" style="color: rgb(102, 102, 0);">||</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"var"</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//@unkowned</span><span class="pln" style="color: rgb(0, 0, 0);">
    active_directive</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">dir</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> member</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">dir</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">directives</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">||</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">parent </span><span class="pun" style="color: rgb(102, 102, 0);">&amp;&amp;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">parent</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">active_directive</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">dir</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="com" style="color: rgb(136, 0, 0);">//为当前AST树加入作用域信息</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> ast_add_scope</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> current_scope </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> w </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> ast_walker</span><span class="pun" style="color: rgb(102, 102, 0);">(),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> w</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">walk</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> having_eval </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[];</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> with_new_scope</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">cont</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//为当前生成一个子作用域,加入到作用域链中</span><span class="pln" style="color: rgb(0, 0, 0);">
      current_scope </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">new</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">Scope</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">current_scope</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
      current_scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">labels </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">new</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">Scope</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">//拿到作用域块的AST树枝</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> ret </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> current_scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">body </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> cont</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">//把作用域信息记录在树枝上</span><span class="pln" style="color: rgb(0, 0, 0);">
      ret</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">scope </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> current_scope</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">//回到上一层作用域!</span><span class="pln" style="color: rgb(0, 0, 0);">
      current_scope </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> current_scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">parent</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> ret</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> define</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> type</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> current_scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">define</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> type</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> reference</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      current_scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">refs</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">true</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> _lambda</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> args</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> body</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> is_defun </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"defun"</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> is_defun </span><span class="pun" style="color: rgb(102, 102, 0);">?</span><span class="pln" style="color: rgb(0, 0, 0);"> define</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"defun"</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> args</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> with_new_scope</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(){</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//进入函数体 要生成一个作用域信息</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(!</span><span class="pln" style="color: rgb(0, 0, 0);">is_defun</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> define</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"lambda"</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">//当前函数声明的参数为此作用域的符号信息</span><span class="pln" style="color: rgb(0, 0, 0);">
            MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">args</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">){</span><span class="pln" style="color: rgb(0, 0, 0);"> define</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"arg"</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">});</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">body</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">})];</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> _vardefs</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">type</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">defs</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//var a = b;</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//b要算进引用列表~</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//a要算进声明列表</span><span class="pln" style="color: rgb(0, 0, 0);">
            MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">defs</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">d</span><span class="pun" style="color: rgb(102, 102, 0);">){</span><span class="pln" style="color: rgb(0, 0, 0);">
                define</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">d</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> type</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">d</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">])</span><span class="pln" style="color: rgb(0, 0, 0);"> reference</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">d</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">]);</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">});</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> _breacont</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">label</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">label</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
            current_scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">labels</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">refs</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">label</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">true</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> with_new_scope</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(){</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">// process AST</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> ret </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> w</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">with_walkers</span><span class="pun" style="color: rgb(102, 102, 0);">({</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="str" style="color: rgb(0, 136, 0);">"function"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _lambda</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="str" style="color: rgb(0, 136, 0);">"defun"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _lambda</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="str" style="color: rgb(0, 136, 0);">"label"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> stat</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> current_scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">labels</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">define</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="str" style="color: rgb(0, 136, 0);">"break"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _breacont</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="str" style="color: rgb(0, 136, 0);">"continue"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _breacont</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="str" style="color: rgb(0, 136, 0);">"with"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">expr</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> block</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> s </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> current_scope</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> s </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">parent</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
                  s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">uses_with </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">true</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="str" style="color: rgb(0, 136, 0);">"var"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _vardefs</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="str" style="color: rgb(0, 136, 0);">"var"</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="str" style="color: rgb(0, 136, 0);">"const"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _vardefs</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="str" style="color: rgb(0, 136, 0);">"const"</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="str" style="color: rgb(0, 136, 0);">"try"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">t</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> c</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> f</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">c </span><span class="pun" style="color: rgb(102, 102, 0);">!=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">
                  </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);">
                  MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">t</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);">
                  </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> define</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">c</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"catch"</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">c</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);">
                  f </span><span class="pun" style="color: rgb(102, 102, 0);">!=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">?</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">f</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="str" style="color: rgb(0, 136, 0);">"name"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"eval"</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
                  having_eval</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">push</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">current_scope</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="com" style="color: rgb(136, 0, 0);">//留意一下</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="com" style="color: rgb(136, 0, 0);">//var a = 1; 这里的a不是引用 只是一个声明</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="com" style="color: rgb(136, 0, 0);">//只有在真正使用a的时候才算是引用,例如:</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="com" style="color: rgb(136, 0, 0);">//a.b; a=1</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="com" style="color: rgb(136, 0, 0);">//留意:for (var a in arr) 这里的a也算是一个引用,因为相当于var a;for(a in arr)</span><span class="pln" style="color: rgb(0, 0, 0);">
                reference</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="com" style="color: rgb(136, 0, 0);">//记录一下当前作用域使用到的引用</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(){</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">});</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">// the reason why we need an additional pass here is</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">// that names can be used prior to their definition.</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">// scopes where eval was detected and their parents</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">// are marked with uses_eval, unless they define the</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">// "eval" name.</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//如果某个作用域有使用eval,会导致这条作用域链上边的变量都不能混淆</span><span class="pln" style="color: rgb(0, 0, 0);">
      MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">having_eval</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">){</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(!</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">has</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="str" style="color: rgb(0, 136, 0);">"eval"</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">while</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
                scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">uses_eval </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">true</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
                scope </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">parent</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">});</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">// for referenced names it might be useful to know</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">// their origin scope.current_scope here is the</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">// toplevel one.</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//本来 refs = {a:true} 现在要fix成 refs = {a:&lt;Scope&gt;}</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//需要知道变量a在哪个作用域上被引用,因为这会影响变量名混淆的操作</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> fixrefs</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> i</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">// do children first; order shouldn't matter</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">i </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">children</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">length</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">--</span><span class="pln" style="color: rgb(0, 0, 0);">i </span><span class="pun" style="color: rgb(102, 102, 0);">&gt;=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">;)</span><span class="pln" style="color: rgb(0, 0, 0);">
                fixrefs</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">children</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">]);</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">i in scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">refs</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">HOP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">refs</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> i</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="com" style="color: rgb(136, 0, 0);">// find origin scope and propagate the reference to origin</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="com" style="color: rgb(136, 0, 0);">//找到当前引用变量名字i在哪个作用域声明的!</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="com" style="color: rgb(136, 0, 0);">//</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="com" style="color: rgb(136, 0, 0);">/*
                  var a = 1;//当前作用域 =&gt; origin | s.parent.parent
                  (functin (){ //当前作用域 =&gt;s.parent
                              (function(){ //当前作用域 =&gt;s
                                 a = 1;
                              })
                  })
                  由于在s.parent.parent 以及 s.parent是不知道a被s引用了
                  所以这里要从底层递归上来 记录每一个作用域都引用了a 防止a变量在中间某层被认作是一个没用的变量干掉了。
                */</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> origin </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">has</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);"> s </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> scope</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> s </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">parent</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
                  s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">refs</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> origin</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
                  </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">s </span><span class="pun" style="color: rgb(102, 102, 0);">===</span><span class="pln" style="color: rgb(0, 0, 0);"> origin</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">break</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//修复当前作用域的引用</span><span class="pln" style="color: rgb(0, 0, 0);">
      fixrefs</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">current_scope</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> ret</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">});</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">&lt;/</span><span class="pln" style="color: rgb(0, 0, 0);">pre</span><span class="pun" style="color: rgb(102, 102, 0);">&gt;</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="pun" style="color: rgb(102, 102, 0);">&lt;</span><span class="pln" style="color: rgb(0, 0, 0);">h4</span><span class="pun" style="color: rgb(102, 102, 0);">&gt;&lt;</span><span class="pln" style="color: rgb(0, 0, 0);">strong</span><span class="pun" style="color: rgb(102, 102, 0);">&gt;变量混淆&lt;</span><span class="str" style="color: rgb(0, 136, 0);">/strong&gt;&lt;/</span><span class="pln" style="color: rgb(0, 0, 0);">h4</span><span class="pun" style="color: rgb(102, 102, 0);">&gt;</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">&lt;</span><span class="pln" style="color: rgb(0, 0, 0);">pre lang</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="str" style="color: rgb(0, 136, 0);">"javascript"</span><span class="pun" style="color: rgb(102, 102, 0);">&gt;</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="com" style="color: rgb(136, 0, 0);">//混淆变量名需要在静态分析时候知道当前作用域链</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="com" style="color: rgb(136, 0, 0);">//ast_mangle执行前需要先执行ast_add_scope,把作用域信息记录在树枝上</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> ast_mangle</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> options</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//拿到一个遍历器</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> w </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> ast_walker</span><span class="pun" style="color: rgb(102, 102, 0);">(),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> w</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">walk</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> scope</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    options </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> defaults</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">options</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      mangle       </span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">true</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      toplevel   </span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">false</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      defines      </span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      except       </span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      no_functions </span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">false</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">});</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//关键函数</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//输入变量名字name 输出混淆后的变量名</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> get_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> newMangle</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//如果参数指定不混淆变量名 那还做啥!</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(!</span><span class="pln" style="color: rgb(0, 0, 0);">options</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">mangle</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

   </span><span class="com" style="color: rgb(136, 0, 0);">//如果参数指定不混淆全局变量 并且当前作用域是在全局上 那还做啥!</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(!</span><span class="pln" style="color: rgb(0, 0, 0);">options</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">toplevel </span><span class="pun" style="color: rgb(102, 102, 0);">&amp;&amp;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">!</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">parent</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// don't mangle toplevel</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">//你可以为uglify指定一些不要他混淆的变量名</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">options</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">except </span><span class="pun" style="color: rgb(102, 102, 0);">&amp;&amp;</span><span class="pln" style="color: rgb(0, 0, 0);"> member</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> options</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">except</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">//参数指定不混淆函数变量名:uglify --no-mangle-functions</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//defun 指的是定义的函数,语句块以这样开始:function A(){}</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//留意 var c = function A(){}这种不算defun</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">options</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">no_functions </span><span class="pun" style="color: rgb(102, 102, 0);">&amp;&amp;</span><span class="pln" style="color: rgb(0, 0, 0);"> HOP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">names</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">&amp;&amp;</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">names</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">'defun'</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">||</span><span class="pln" style="color: rgb(0, 0, 0);"> scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">names</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">'lambda'</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">//除了上边不用混淆的情况,其他情况都要混淆</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//具体混淆算法见scope.get_mangled</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">get_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> newMangle</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//可以自己为某些变量做变量名替换的操作,例如:</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//uglifyjs -o a.js a.js -c --define DEBUG=true</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="com" style="color: rgb(136, 0, 0);">//那么代码中的DEBUG变量最后会被替换成true</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> get_define</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">options</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">defines</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">// we always lookup a defined symbol for the current scope FIRST, so declared</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">// vars trump a DEFINE symbol, but if no such var is found, then match a DEFINE value</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(!</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">has</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="com" style="color: rgb(136, 0, 0);">//留意这个判断!如果当前作用域没有这个变量 才会考虑用参数里边的列表映射替换这个变量!</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">HOP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">options</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">defines</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
                  </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> options</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">defines</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> _lambda</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> args</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> body</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(!</span><span class="pln" style="color: rgb(0, 0, 0);">options</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">no_functions </span><span class="pun" style="color: rgb(102, 102, 0);">&amp;&amp;</span><span class="pln" style="color: rgb(0, 0, 0);"> options</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">mangle</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="com" style="color: rgb(136, 0, 0);">//如果函数名需要混淆!</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> is_defun </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"defun"</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> extra</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
               </span><span class="com" style="color: rgb(136, 0, 0);">//如果是函数定义 那么名字要混淆</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">is_defun</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> name </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> get_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

                </span><span class="com" style="color: rgb(136, 0, 0);">//如果是这样的情况:</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="com" style="color: rgb(136, 0, 0);">//(function A(){})(); A函数里边没有引用自己 所以等同于 (function(){})();</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="com" style="color: rgb(136, 0, 0);">//(function A(){A();}) A函数递归自己,那么A这个名字就要参与混淆了</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">else</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">body</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">references</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
                  extra </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{};</span><span class="com" style="color: rgb(136, 0, 0);">//混淆后的名字要记录起来 函数体里边的作用域就不能再用这个名字了</span><span class="pln" style="color: rgb(0, 0, 0);">

                  </span><span class="com" style="color: rgb(136, 0, 0);">//当前作用域没有使用with以及eval的情况才能混淆名字</span><span class="pln" style="color: rgb(0, 0, 0);">
                  </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(!(</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">uses_eval </span><span class="pun" style="color: rgb(102, 102, 0);">||</span><span class="pln" style="color: rgb(0, 0, 0);"> scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">uses_with</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);">
                        name </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> extra</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">next_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">
                  </span><span class="kwd" style="color: rgb(0, 0, 136);">else</span><span class="pln" style="color: rgb(0, 0, 0);">
                        extra</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">else</span><span class="pln" style="color: rgb(0, 0, 0);"> name </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//函数体要在其作用域去混淆变量名</span><span class="pln" style="color: rgb(0, 0, 0);">
      body </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> with_scope</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">body</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(){</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//函数参数名需要混淆</span><span class="pln" style="color: rgb(0, 0, 0);">
            args </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">args</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">){</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> get_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">});</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">body</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);"> extra</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> name</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> args</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> body </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> with_scope</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">s</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> cont</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> extra</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> _scope </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> scope</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      scope </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="com" style="color: rgb(136, 0, 0);">//extra表示当前作用域已经使用过的混淆名字</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">extra</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> i in extra</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">HOP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">extra</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> i</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">set_mangle</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> extra</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">]);</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> i in s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">names</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">HOP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">s</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">names</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> i</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            get_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">true</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="com" style="color: rgb(136, 0, 0);">//为当前作用域使用到的名字做混淆</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> ret </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> cont</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">
      ret</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">scope </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> s</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="com" style="color: rgb(136, 0, 0);">//绑定作用域信息</span><span class="pln" style="color: rgb(0, 0, 0);">
      scope </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> _scope</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> ret</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> _vardefs</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">defs</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="com" style="color: rgb(136, 0, 0);">//变量名字混淆</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">defs</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">d</span><span class="pun" style="color: rgb(102, 102, 0);">){</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> get_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">d</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">]),</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">d</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">])</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">})</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> _breacont</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">label</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="com" style="color: rgb(136, 0, 0);">//label标签的混淆!</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">label</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">labels</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">get_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">label</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">

    </span><span class="com" style="color: rgb(136, 0, 0);">//自定义其中一些涉及到需要混淆变量名的树枝遍历器</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> w</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">with_walkers</span><span class="pun" style="color: rgb(102, 102, 0);">({</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"function"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _lambda</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"defun"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">// move function declarations to the top when</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">// they are not in some block.</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">//先混淆函数名以及函数体的变量名字</span><span class="pln" style="color: rgb(0, 0, 0);">
               </span><span class="com" style="color: rgb(136, 0, 0);">//得到一个新的树枝</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> ast </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> _lambda</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">apply</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> arguments</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

            </span><span class="com" style="color: rgb(136, 0, 0);">//看看要不要把当前定义提到最前边</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">/*
               var a = 1,b = 2;
               function C(){}
                  function D(){}

                  其实可以优化成:

               function C(){}
                  function D(){}
               var a = 1,b = 2;
             */</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">switch</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">w</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">parent</span><span class="pun" style="color: rgb(102, 102, 0);">()[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">])</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">case</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"toplevel"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">case</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"function"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">case</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">"defun"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);">
               </span><span class="com" style="color: rgb(136, 0, 0);">//把函数定义提前</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">at_top</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> ast</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"label"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">label</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> stat</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">labels</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">refs</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">label</span><span class="pun" style="color: rgb(102, 102, 0);">])</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);">
               </span><span class="com" style="color: rgb(136, 0, 0);">//获取label对应的混淆名字</span><span class="pln" style="color: rgb(0, 0, 0);">
                scope</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">labels</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">get_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">label</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">true</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);">
                walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">stat</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">//如果没有一个地方引用当前label 那可以去掉这个label了</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">stat</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"break"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _breacont</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"continue"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _breacont</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"var"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _vardefs</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"const"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> _vardefs</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"name"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//看看当前名字有没有在作用域链声明 有的话才混淆</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> get_define</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">||</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> get_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">name</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"try"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">t</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> c</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> f</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);">
                     MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">t</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">),</span><span class="pln" style="color: rgb(0, 0, 0);">
                     c </span><span class="pun" style="color: rgb(102, 102, 0);">!=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">?</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> get_mangled</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">c</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">]),</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">c</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">
                     f </span><span class="pun" style="color: rgb(102, 102, 0);">!=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">?</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">f</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">null</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"toplevel"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">body</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> self </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="com" style="color: rgb(136, 0, 0);">//为什么这里会有self.scope,因为在ast_add_scope已经为树生成了作用域信息</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> with_scope</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">self</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">scope</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(){</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);"> self</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">body</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">];</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">});</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="str" style="color: rgb(0, 136, 0);">"directive"</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//指示性字符串也提到当前作用域前边</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//function(){var a = 1; "use strict";}</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//优化成 function(){"use strict"; var a = 1;}</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">at_top</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">},</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//混淆变量名字需要绑定节点的作用域信息!</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> walk</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast_add_scope</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ast</span><span class="pun" style="color: rgb(102, 102, 0);">));</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">});</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="com" style="color: rgb(136, 0, 0);">//辅助方法</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(){</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//遍历一个语句块a的时候</span><span class="pln" style="color: rgb(0, 0, 0);">
    MAP </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">a</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> f</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> o</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//可能有函数定义 以及 指示性字符串放到这个块最前边</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">//所以top就记录了这些树枝</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> ret </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[],</span><span class="pln" style="color: rgb(0, 0, 0);"> top </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[],</span><span class="pln" style="color: rgb(0, 0, 0);"> i</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> doit</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
          </span><span class="com" style="color: rgb(136, 0, 0);">//遍历的过程 把AtTop的类型提到top数组</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> val </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> f</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">call</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">o</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> a</span><span class="pun" style="color: rgb(102, 102, 0);">[</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">],</span><span class="pln" style="color: rgb(0, 0, 0);"> i</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">val instanceof </span><span class="typ" style="color: rgb(102, 0, 102);">AtTop</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
                val </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> val</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">v</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">val instanceof </span><span class="typ" style="color: rgb(102, 0, 102);">Splice</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
                  top</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">push</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">apply</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">top</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> val</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">v</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">else</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
                  top</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">push</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">val</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="com" style="color: rgb(136, 0, 0);">//其余的 看看语句是否可以忽略 不能忽略的语句放到ret数组</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="kwd" style="color: rgb(0, 0, 136);">else</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">val </span><span class="pun" style="color: rgb(102, 102, 0);">!=</span><span class="pln" style="color: rgb(0, 0, 0);"> skip</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">val instanceof </span><span class="typ" style="color: rgb(102, 0, 102);">Splice</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
                  ret</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">push</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">apply</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ret</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> val</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">v</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">else</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
                  ret</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">push</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">val</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
                </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
            </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">a instanceof </span><span class="typ" style="color: rgb(102, 0, 102);">Array</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">i </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">0</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> i </span><span class="pun" style="color: rgb(102, 102, 0);">&lt;</span><span class="pln" style="color: rgb(0, 0, 0);"> a</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">length</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">++</span><span class="pln" style="color: rgb(0, 0, 0);">i</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> doit</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">else</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">for</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">i in a</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">HOP</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">a</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> i</span><span class="pun" style="color: rgb(102, 102, 0);">))</span><span class="pln" style="color: rgb(0, 0, 0);"> doit</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">//top数组一定排在ret数组之前</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> top</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">concat</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">ret</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
    MAP</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">at_top </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">val</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">new</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">AtTop</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">val</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
    MAP</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">splice </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">val</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">new</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">Splice</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">val</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> skip </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> MAP</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">skip </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{};</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">AtTop</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">val</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">v </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> val </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">Splice</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">val</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">v </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> val </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">})();</span></code></pre></div><div class="topic-firstfloor-additional" style="margin-top: 10px; margin-bottom: 10px; color: rgb(51, 51, 51); font-family: &quot;Microsoft Yahei&quot;, 微软雅黑, &quot;Helvetica Neue&quot;, adobe雅黑, &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 12px; line-height: 18px;"></div><div class="user-actions" style="color: rgb(153, 153, 153); padding: 12px 5px; margin-top: 10px; border-top-width: 1px; border-top-style: solid; border-top-color: rgb(226, 226, 226); font-family: &quot;Microsoft Yahei&quot;, 微软雅黑, &quot;Helvetica Neue&quot;, adobe雅黑, &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 12px; line-height: 18px;"><div class="faved-user" style="position: absolute; top: -26px; right: 0px;"><a href="http://div.io/user/fouber" class="avatar" style="text-decoration: none; color: rgb(38, 159, 63);"><img src="http://div.io/uploads/avatar/4_s.png" alt="前端农民工" style="width: 24px; height: 24px; border-radius: 24px;"></a>&nbsp;<a href="http://div.io/user/320" class="avatar" style="text-decoration: none; color: rgb(38, 159, 63);"><img src="http://div.io/uploads/avatar/320_s.jpg" alt="polandeme" style="width: 24px; height: 24px; border-radius: 24px;"></a>&nbsp;<span class="muted">2 人关注了该主题</span></div><div><span class="muted"><br></span></div><span class="fa fa-weibo" style="display: inline-block; font-stretch: normal; line-height: 1; font-family: FontAwesome; font-size: 14px; text-rendering: auto; -webkit-font-smoothing: antialiased; transform: translate(0px, 0px); color: rgb(165, 165, 165);"></span></div></div>
页: [1]
查看完整版本: Javascript的变量名混淆细节