示例#1
0
    def build_next(f, parent=None):
        if type(f) != Frame:
            return

        subnode = f.subnode
        if f.label >= 0:  # and f.label < 3:
            n2 = js_parse("this.$s1 = 0;", [f_name(f)], start_node=AssignNode)
            n2.replace(n2[1], f.funcnode)
            f.funcnode.name = "(anonymous)"
            f.funcnode.is_anonymous = True

            node2.add(n2)  #f.funcnode)

        if f.totframes > 0:
            if f.node != None and type(f.node) == WhileNode:
                f2 = f_next(f)
                f2 = f2.label if f2 != -1 else -1
                n = js_parse(
                    """
                     if (!"placeholder") {
                        return [$i1, undefined];
                     }
                     """, [f2])

                if n == None:
                    typespace.error("internal error", subnode)

                n2 = find_node(n, StrLitNode)
                n2.parent.replace(n2, f.node[0])

                subnode.add(n)
                f2 = f_first(f)
                n.add(
                    js_parse("return [$i, undefined];", [f2.label],
                             start_node=ReturnNode))
            elif f.node != None and type(f.node) == TryNode:
                n = StatementList()

                if n == None:
                    typespace.error("internal error", subnode)

                f3 = f_raw_next(f)
                while f3 != -1 and type(f3.node) != CatchNode:
                    f3 = f_raw_next(f3)

                if f3 == -1:
                    typespace.error("Orphaned try block", f.node)

                f3name = "_nfothing"
                if len(f3.node) > 0:
                    f3name = f3.node[0].gen_js(0).replace("scope.", "")

                n.add(
                    js_parse(
                        """
           this.trystack.push([$i, "$s"]);
                        """, [f3.label, f3name]))

                f2 = f_first(f)
                n.add(
                    js_parse("return [$i, undefined];", [f2.label],
                             start_node=ReturnNode))
                subnode.add(n)
                f2.pop_trystack = True
            elif f.node != None and type(f.node) == IfNode:
                f2 = f_first(f)
                f1 = f_raw_next(f)
                while type(
                        f1.node) != ElseNode and f1.label != len(flatframes):
                    f1 = f_raw_next(f1)

                if f1.label == len(flatframes):
                    f1 = f_next(f)

                n = js_parse(
                    """
          if (!("placeholder")) {
            return [$i1, undefined];
          } else {
            return [$i2, undefined];
          }
        """, [f1.label, f2.label])

                n2 = find_node(n, StrLitNode)
                n2.parent.replace(n2, f.node[0].copy())

                if n == None:
                    typespace.error("internal error", subnode)

                f2 = f_first(f)
                n.add(
                    js_parse("return [$i, undefined];", [f2.label],
                             start_node=ReturnNode))
                subnode.add(n)
                f2.pop_trystack = True
            elif f.node != None and type(f.node) == ElseNode:
                f2 = f_first(f)
                f1 = f_raw_next(f)
                while type(
                        f1.node) != ElseNode and f1.label != len(flatframes):
                    f1 = f_raw_next(f1)

                if f1.label == len(flatframes):
                    f1 = f_next(f)

                n = js_parse(
                    """
          return [$i1, undefined];
        """, [f2.label])

                if n == None:
                    typespace.error("internal error", subnode)

                f2 = f_first(f)
                subnode.add(n)
            elif f.node != None and type(f.node) == CatchNode:
                f2 = f_first(f)

                n = js_parse(
                    """
          return [$i1, undefined];
        """, [f2.label])

                if n == None:
                    typespace.error("internal error", subnode)
                subnode.add(n)
            elif f.node != None and type(f.node) == ForLoopNode:
                f2 = f_first(f)
                f3 = f_next(f)

                f3 = f3.label if f2 != -1 else -1
                f2 = f2.label if f2 != -1 else -1

                n = js_parse(
                    """
                     if ($n) {
                      return [$i, undefined];
                     } else {
                      return [$i, undefined];
                     }                       
                     """, [f.node[0][1], f2, f3])

                if n == None:
                    typespace.error("internal error", subnode)

                subnode.add(n)
示例#2
0
 def build_next(f, parent=None):
   if type(f) != Frame: 
     return
   
   subnode = f.subnode
   if f.label >= 0: # and f.label < 3:
     n2 = js_parse("this.$s1 = 0;", [f_name(f)], start_node=AssignNode)
     n2.replace(n2[1], f.funcnode)
     f.funcnode.name = "(anonymous)"
     f.funcnode.is_anonymous = True
     
     node2.add(n2) #f.funcnode)
       
   if f.totframes > 0:
     if f.node != None and type(f.node) == WhileNode:
       f2 = f_next(f)
       f2 = f2.label if f2 != -1 else -1
       n = js_parse("""
                    if (!"placeholder") {
                       return [$i1, undefined];
                    }
                    """, [f2])
       
       if n == None:
         typespace.error("internal error", subnode);
         
       n2 = find_node(n, StrLitNode);
       n2.parent.replace(n2, f.node[0])
       
       subnode.add(n)
       f2 = f_first(f);
       n.add(js_parse("return [$i, undefined];", [f2.label], start_node=ReturnNode))
     elif f.node != None and type(f.node) == TryNode:
       n = StatementList()
       
       if n == None:
         typespace.error("internal error", subnode);
       
       f3 = f_raw_next(f)
       while f3 != -1 and type(f3.node) != CatchNode:
         f3 = f_raw_next(f3);
       
       if f3 == -1:
         typespace.error("Orphaned try block", f.node)
       
       f3name = "_nfothing"
       if len(f3.node) > 0:
         f3name = f3.node[0].gen_js(0).replace("scope.", "")
         
       n.add(js_parse("""
          this.trystack.push([$i, "$s"]);
                       """, [f3.label, f3name]))
                       
       f2 = f_first(f);
       n.add(js_parse("return [$i, undefined];", [f2.label], start_node=ReturnNode))
       subnode.add(n)
       f2.pop_trystack = True
     elif f.node != None and type(f.node) == IfNode:
       f2 = f_first(f)
       f1 = f_raw_next(f)
       while type(f1.node) != ElseNode and f1.label != len(flatframes):
         f1 = f_raw_next(f1)
       
       if f1.label == len(flatframes):
         f1 = f_next(f)
       
       n = js_parse("""
         if (!("placeholder")) {
           return [$i1, undefined];
         } else {
           return [$i2, undefined];
         }
       """, [f1.label, f2.label]);
       
       n2 = find_node(n, StrLitNode)
       n2.parent.replace(n2, f.node[0].copy())
       
       if n == None:
         typespace.error("internal error", subnode);
       
       f2 = f_first(f);
       n.add(js_parse("return [$i, undefined];", [f2.label], start_node=ReturnNode))
       subnode.add(n)
       f2.pop_trystack = True
     elif f.node != None and type(f.node) == ElseNode:
       f2 = f_first(f)
       f1 = f_raw_next(f)
       while type(f1.node) != ElseNode and f1.label != len(flatframes):
         f1 = f_raw_next(f1)
       
       if f1.label == len(flatframes):
         f1 = f_next(f)
       
       n = js_parse("""
         return [$i1, undefined];
       """, [f2.label]);
       
       if n == None:
         typespace.error("internal error", subnode);
       
       f2 = f_first(f);
       subnode.add(n)
     elif f.node != None and type(f.node) == CatchNode:
       f2 = f_first(f)
       
       n = js_parse("""
         return [$i1, undefined];
       """, [f2.label]);
       
       if n == None:
         typespace.error("internal error", subnode);
       subnode.add(n)
     elif f.node != None and type(f.node) == ForLoopNode:
       f2 = f_first(f);
       f3 = f_next(f)
       
       f3 = f3.label if f2 != -1 else -1
       f2 = f2.label if f2 != -1 else -1
       
       n = js_parse("""
                    if ($n) {
                     return [$i, undefined];
                    } else {
                     return [$i, undefined];
                    }                       
                    """, [f.node[0][1], f2, f3])
       
       if n == None:
         typespace.error("internal error", subnode);
       
       subnode.add(n)
示例#3
0
def bleh():
    for frames in flatframes:
        fname = f_name(frames)
        n = js_parse("""
           function $s1(scope) {
            if (_do_frame_debug) console.log("in $s1");

           }""", (fname),
                     start_node=FunctionNode)

        if type(n[1]) != StatementList:
            n.replace(n[1], StatementList())
        n = n[1]

        func = n
        while type(func) != FunctionNode:
            func = func.parent

        excl = (type(frames.node) == StatementList
                and type(frames.parent.node) == FunctionNode)
        if frames.node != None and not excl and type(
                frames.node) != FunctionNode:
            f = frames

            sl = StatementList()
            f.node[f.node._startcur] = sl

        frames.funcnode = func
        frames.subnode = frames.funcnode

        local_frames = "["
        totframes = 0

        for i, f in enumerate(frames):
            if type(f) != Frame:
                frames.subnode.add(f)
                frames.leaf = True

            else:
                frames.leaf = False
                if len(local_frames) > 1: local_frames += ", "
                local_frames += f_ref(f)  #.replace("this.", "")
                totframes += 1
                if f.node != None and type(f.node) != FunctionNode:
                    if len(f.node.children) > f.node._startcur + 1:
                        do_conv(f.node, f)

        if frames.leaf:
            f2 = f_next(frames)
            f2 = f2.label if f2 != -1 else -1
            frames.subnode.add(
                js_parse("return [$i, undefined];", [f2],
                         start_node=ReturnNode))

        local_frames = "%s_frames = " % f_ref(frames) + local_frames + "];"

        frames.frames = js_parse(local_frames)
        frames.totframes = totframes

    def build_next(f, parent=None):
        if type(f) != Frame:
            return

        subnode = f.subnode
        if f.label >= 0:  # and f.label < 3:
            n2 = js_parse("this.$s1 = 0;", [f_name(f)], start_node=AssignNode)
            n2.replace(n2[1], f.funcnode)
            f.funcnode.name = "(anonymous)"
            f.funcnode.is_anonymous = True

            node2.add(n2)  #f.funcnode)

        if f.totframes > 0:
            if f.node != None and type(f.node) == WhileNode:
                f2 = f_next(f)
                f2 = f2.label if f2 != -1 else -1
                n = js_parse(
                    """
                     if (!"placeholder") {
                        return [$i1, undefined];
                     }
                     """, [f2])

                if n == None:
                    typespace.error("internal error", subnode)

                n2 = find_node(n, StrLitNode)
                n2.parent.replace(n2, f.node[0])

                subnode.add(n)
                f2 = f_first(f)
                n.add(
                    js_parse("return [$i, undefined];", [f2.label],
                             start_node=ReturnNode))
            elif f.node != None and type(f.node) == TryNode:
                n = StatementList()

                if n == None:
                    typespace.error("internal error", subnode)

                f3 = f_raw_next(f)
                while f3 != -1 and type(f3.node) != CatchNode:
                    f3 = f_raw_next(f3)

                if f3 == -1:
                    typespace.error("Orphaned try block", f.node)

                f3name = "_nfothing"
                if len(f3.node) > 0:
                    f3name = f3.node[0].gen_js(0).replace("scope.", "")

                n.add(
                    js_parse(
                        """
           this.trystack.push([$i, "$s"]);
                        """, [f3.label, f3name]))

                f2 = f_first(f)
                n.add(
                    js_parse("return [$i, undefined];", [f2.label],
                             start_node=ReturnNode))
                subnode.add(n)
                f2.pop_trystack = True
            elif f.node != None and type(f.node) == IfNode:
                f2 = f_first(f)
                f1 = f_raw_next(f)
                while type(
                        f1.node) != ElseNode and f1.label != len(flatframes):
                    f1 = f_raw_next(f1)

                if f1.label == len(flatframes):
                    f1 = f_next(f)

                n = js_parse(
                    """
          if (!("placeholder")) {
            return [$i1, undefined];
          } else {
            return [$i2, undefined];
          }
        """, [f1.label, f2.label])

                n2 = find_node(n, StrLitNode)
                n2.parent.replace(n2, f.node[0].copy())

                if n == None:
                    typespace.error("internal error", subnode)

                f2 = f_first(f)
                n.add(
                    js_parse("return [$i, undefined];", [f2.label],
                             start_node=ReturnNode))
                subnode.add(n)
                f2.pop_trystack = True
            elif f.node != None and type(f.node) == ElseNode:
                f2 = f_first(f)
                f1 = f_raw_next(f)
                while type(
                        f1.node) != ElseNode and f1.label != len(flatframes):
                    f1 = f_raw_next(f1)

                if f1.label == len(flatframes):
                    f1 = f_next(f)

                n = js_parse(
                    """
          return [$i1, undefined];
        """, [f2.label])

                if n == None:
                    typespace.error("internal error", subnode)

                f2 = f_first(f)
                subnode.add(n)
            elif f.node != None and type(f.node) == CatchNode:
                f2 = f_first(f)

                n = js_parse(
                    """
          return [$i1, undefined];
        """, [f2.label])

                if n == None:
                    typespace.error("internal error", subnode)
                subnode.add(n)
            elif f.node != None and type(f.node) == ForLoopNode:
                f2 = f_first(f)
                f3 = f_next(f)

                f3 = f3.label if f2 != -1 else -1
                f2 = f2.label if f2 != -1 else -1

                n = js_parse(
                    """
                     if ($n) {
                      return [$i, undefined];
                     } else {
                      return [$i, undefined];
                     }                       
                     """, [f.node[0][1], f2, f3])

                if n == None:
                    typespace.error("internal error", subnode)

                subnode.add(n)

    node2.insert(
        1,
        js_parse("""
    this[Symbol.iterator] = function() {
      return this;
    }
  """)[0])
    for f in flatframes:
        build_next(f, f.parent)

    #process returns from within try nodes
    for f in flatframes:
        if f.parent != None and type(f.parent.node) == TryNode:

            def visit_rets1(n2):
                target = n2[0][0][0].val
                isyield = n2[0][0][1].val
                ni = n2.parent.index(n2)

                if target >= f_next(f.parent).label:
                    n3 = js_parse("this.trystack.pop();")[0]
                    n2.parent.insert(ni, n3)

            traverse(f.subnode, ReturnNode, visit_rets1, copy_children=True)

    #process yields
    for f in flatframes:
        f2 = f.parent
        set_yield = None

        def visit_rets2(n2):
            if set_yield != None:
                #print(n2)
                n2[0][0].replace(n2[0][0][1], set_yield)

        set_yield = find_node(f.subnode, YieldNode)
        if set_yield != None:
            set_yield.parent.remove(set_yield)
            set_yield = ArrayLitNode(ExprListNode([set_yield[0]]))

        traverse(f.subnode, ReturnNode, visit_rets2, copy_children=True)

    def find_parent_frame(f, ntypes, include_first=True):
        p = f
        if not include_first:
            p = p.parent

        while p != None:
            if type(p.node) in ntypes:
                return p
            p = p.parent
        return None

    #process breaks
    for f in flatframes:
        f2 = f.parent

        def visit_rets3(n2):
            p = n2.parent
            while not null_node(p) and p != f.subnode:
                if type(p) in [WhileNode, DoWhileNode, ForLoopNode]: break
                p = p.parent

            if p != f.subnode and not null_node(p):
                return  #break corresponds to a loop internal to this frame
            p = find_parent_frame(f, [WhileNode, DoWhileNode, ForLoopNode],
                                  True)

            if p == None:
                typespace.error(
                    "Invalid break statement (switches within generators aren't supported yet)",
                    n2)

            f2 = f_next(p)

            n3 = js_parse("return [$i, undefined];", [f2.label],
                          start_node=ReturnNode)
            n2.parent.replace(n2, n3)

        traverse(f.subnode, BreakNode, visit_rets3, copy_children=True)

    #process continues
    for f in flatframes:
        f2 = f.parent

        def visit_rets3(n2):
            p = n2.parent
            while not null_node(p) and p != f.subnode:
                p = p.parent

            if p != f.subnode and not null_node(p):
                return  #continue corresponds to a loop internal to this frame
            p = f.parent
            while p != None:
                if type(p.node) in [WhileNode, DoWhileNode, ForLoopNode]:
                    break
                p = p.parent

            if p == None:
                typespace.error("Invalid continue statement")

            n3 = js_parse("return [$i, undefined];", [p.label],
                          start_node=ReturnNode)
            n2.parent.replace(n2, n3)

        traverse(f.subnode, ContinueNode, visit_rets3, copy_children=True)

    firstnode = js_parse("if (this.first) {\n}", start_node=IfNode)
    firstnode2 = js_parse("if (this.first) {\n}", start_node=IfNode)
    firstnode.replace(firstnode[1], StatementList())
    firstnode2.replace(firstnode2[1], StatementList())
    flatframes[0].subnode.add(firstnode)
    node2.insert(1, firstnode2[1])

    firstnode = firstnode[1]
    firstnode2 = firstnode2[1]

    args = list(node.children[0])
    for i3 in range(len(args)):
        argn = args[i3]
        while type(argn) not in [IdentNode, VarDeclNode]:
            argn = argn[0]

        args[i3] = argn.val

    scope = {}
    for f in flatframes:
        scope.update(f.scope)

    s = "{"
    j2 = 0
    for j, v in enumerate(scope.keys()):
        if j2 > 0: s += ", "
        j2 += 1

        if v in args:
            s += "%s:%s" % ("%s_%s" % (v, scope[v]), v)
        else:
            s += "%s:undefined" % ("%s_%s" % (v, scope[v]))
    s += "}"

    s = "this.scope = %s;\n" % s
    firstnode2.add(js_parse(s)[0])

    #ensure all frames have returns
    for f in flatframes:
        if not find_node(f.subnode, ReturnNode):
            f.subnode.add(
                js_parse("return [$i, undefined];", [f_next(f).label],
                         start_node=ReturnNode))

    framelist = "["
    for i, f in enumerate(flatframes):
        if i > 0: framelist += ", "
        framelist += "this.frame_%i" % f.label
    framelist = "this.frames = %s];" % framelist
    node2.add(js_parse(framelist))

    node2.add(
        js_parse(
            """
    this.cur = 1;
    this.trystack = new Array();
    
    this.next = function() {
      var ret;
      while (this.cur < this.frames.length) {
        try {
          ret = this.frames[this.cur].call(this, this.scope);
        } catch (_generator_error) {
          if (this.trystack.length > 0) {
            var ts1 = this.trystack.pop();
            
            this.scope[ts1[1]] = _generator_error;
            
            ret = [ts1[0], undefined];
          } else {
            throw _generator_error;
          }
        }
        
        if (ret[0] == this.frames.length) {
          return {done : true, value : undefined};
          break;
        }
        
        if (ret[0] == this.cur) {
          console.trace();
          console.log("YEEK!")
          return {done : true, value : undefined};
        }
        
        this.cur = ret[0];
        
        if (ret[1] != undefined) {
          return {value : ret[1][0], done : false};
        } else {
          return {value : undefined, done : false};
        }
      }
    }
  """, []))

    node.parent.replace(node, node2)
示例#4
0
def bleh():
  for frames in flatframes:
    fname = f_name(frames)
    n = js_parse("""
           function $s1(scope) {
            if (_do_frame_debug) console.log("in $s1");

           }""", (fname), start_node=FunctionNode)
    
    if type(n[1]) != StatementList:
      n.replace(n[1], StatementList())
    n = n[1]
    
    func = n
    while type(func) != FunctionNode:
      func = func.parent
    
    excl = (type(frames.node) == StatementList and type(frames.parent.node) == FunctionNode) 
    if frames.node != None and not excl and type(frames.node) != FunctionNode:
      f = frames
      
      sl = StatementList()
      f.node[f.node._startcur] = sl
        
    frames.funcnode = func
    frames.subnode = frames.funcnode
    
    local_frames = "["
    totframes = 0

    for i, f in enumerate(frames):
      if type(f) != Frame:
        frames.subnode.add(f)
        frames.leaf = True
        
      else:
        frames.leaf = False
        if len(local_frames) > 1: local_frames += ", "
        local_frames += f_ref(f) #.replace("this.", "")
        totframes += 1
        if f.node != None and type(f.node) != FunctionNode:
          if len(f.node.children) > f.node._startcur + 1:
            do_conv(f.node, f)
    
    if frames.leaf:
      f2 = f_next(frames)
      f2 = f2.label if f2 != -1 else -1
      frames.subnode.add(js_parse("return [$i, undefined];", [f2], start_node=ReturnNode));

    local_frames = "%s_frames = "%f_ref(frames) + local_frames + "];"
      
    frames.frames = js_parse(local_frames)
    frames.totframes = totframes

  def build_next(f, parent=None):
    if type(f) != Frame: 
      return
    
    subnode = f.subnode
    if f.label >= 0: # and f.label < 3:
      n2 = js_parse("this.$s1 = 0;", [f_name(f)], start_node=AssignNode)
      n2.replace(n2[1], f.funcnode)
      f.funcnode.name = "(anonymous)"
      f.funcnode.is_anonymous = True
      
      node2.add(n2) #f.funcnode)
        
    if f.totframes > 0:
      if f.node != None and type(f.node) == WhileNode:
        f2 = f_next(f)
        f2 = f2.label if f2 != -1 else -1
        n = js_parse("""
                     if (!"placeholder") {
                        return [$i1, undefined];
                     }
                     """, [f2])
        
        if n == None:
          typespace.error("internal error", subnode);
          
        n2 = find_node(n, StrLitNode);
        n2.parent.replace(n2, f.node[0])
        
        subnode.add(n)
        f2 = f_first(f);
        n.add(js_parse("return [$i, undefined];", [f2.label], start_node=ReturnNode))
      elif f.node != None and type(f.node) == TryNode:
        n = StatementList()
        
        if n == None:
          typespace.error("internal error", subnode);
        
        f3 = f_raw_next(f)
        while f3 != -1 and type(f3.node) != CatchNode:
          f3 = f_raw_next(f3);
        
        if f3 == -1:
          typespace.error("Orphaned try block", f.node)
        
        f3name = "_nfothing"
        if len(f3.node) > 0:
          f3name = f3.node[0].gen_js(0).replace("scope.", "")
          
        n.add(js_parse("""
           this.trystack.push([$i, "$s"]);
                        """, [f3.label, f3name]))
                        
        f2 = f_first(f);
        n.add(js_parse("return [$i, undefined];", [f2.label], start_node=ReturnNode))
        subnode.add(n)
        f2.pop_trystack = True
      elif f.node != None and type(f.node) == IfNode:
        f2 = f_first(f)
        f1 = f_raw_next(f)
        while type(f1.node) != ElseNode and f1.label != len(flatframes):
          f1 = f_raw_next(f1)
        
        if f1.label == len(flatframes):
          f1 = f_next(f)
        
        n = js_parse("""
          if (!("placeholder")) {
            return [$i1, undefined];
          } else {
            return [$i2, undefined];
          }
        """, [f1.label, f2.label]);
        
        n2 = find_node(n, StrLitNode)
        n2.parent.replace(n2, f.node[0].copy())
        
        if n == None:
          typespace.error("internal error", subnode);
        
        f2 = f_first(f);
        n.add(js_parse("return [$i, undefined];", [f2.label], start_node=ReturnNode))
        subnode.add(n)
        f2.pop_trystack = True
      elif f.node != None and type(f.node) == ElseNode:
        f2 = f_first(f)
        f1 = f_raw_next(f)
        while type(f1.node) != ElseNode and f1.label != len(flatframes):
          f1 = f_raw_next(f1)
        
        if f1.label == len(flatframes):
          f1 = f_next(f)
        
        n = js_parse("""
          return [$i1, undefined];
        """, [f2.label]);
        
        if n == None:
          typespace.error("internal error", subnode);
        
        f2 = f_first(f);
        subnode.add(n)
      elif f.node != None and type(f.node) == CatchNode:
        f2 = f_first(f)
        
        n = js_parse("""
          return [$i1, undefined];
        """, [f2.label]);
        
        if n == None:
          typespace.error("internal error", subnode);
        subnode.add(n)
      elif f.node != None and type(f.node) == ForLoopNode:
        f2 = f_first(f);
        f3 = f_next(f)
        
        f3 = f3.label if f2 != -1 else -1
        f2 = f2.label if f2 != -1 else -1
        
        n = js_parse("""
                     if ($n) {
                      return [$i, undefined];
                     } else {
                      return [$i, undefined];
                     }                       
                     """, [f.node[0][1], f2, f3])
        
        if n == None:
          typespace.error("internal error", subnode);
        
        subnode.add(n)
      
      
  node2.insert(1, js_parse("""
    this[Symbol.iterator] = function() {
      return this;
    }
  """)[0])
  for f in flatframes:
    build_next(f, f.parent)
  
  #process returns from within try nodes
  for f in flatframes:
    if f.parent != None and type(f.parent.node) == TryNode:
      def visit_rets1(n2):
        target = n2[0][0][0].val
        isyield = n2[0][0][1].val
        ni = n2.parent.index(n2)
        
        if target >= f_next(f.parent).label:
          n3 = js_parse("this.trystack.pop();")[0]
          n2.parent.insert(ni, n3)
        
      traverse(f.subnode, ReturnNode, visit_rets1, copy_children=True);

  #process yields
  for f in flatframes:
    f2 = f.parent
    set_yield = None
    
    def visit_rets2(n2):
      if set_yield != None:
        #print(n2)
        n2[0][0].replace(n2[0][0][1], set_yield);
        
    set_yield = find_node(f.subnode, YieldNode);
    if set_yield != None:
      set_yield.parent.remove(set_yield);
      set_yield = ArrayLitNode(ExprListNode([set_yield[0]]))
      
    traverse(f.subnode, ReturnNode, visit_rets2, copy_children=True);
  
  def find_parent_frame(f, ntypes, include_first=True):
    p = f
    if not include_first:
      p = p.parent
      
    while p != None:
      if type(p.node) in ntypes:
        return p
      p = p.parent
    return None
    
  #process breaks
  for f in flatframes:
    f2 = f.parent
    
    def visit_rets3(n2):
      p = n2.parent
      while not null_node(p) and p != f.subnode:
        if type(p) in [WhileNode, DoWhileNode, ForLoopNode]: break
        p = p.parent
        
      if p != f.subnode and not null_node(p): return #break corresponds to a loop internal to this frame
      p = find_parent_frame(f, [WhileNode, DoWhileNode, ForLoopNode], True)
        
      if p == None:
        typespace.error("Invalid break statement (switches within generators aren't supported yet)", n2)
      
      
      f2 = f_next(p)
        
      n3 = js_parse("return [$i, undefined];", [f2.label], start_node=ReturnNode);
      n2.parent.replace(n2, n3)
      
    traverse(f.subnode, BreakNode, visit_rets3, copy_children=True);

  #process continues
  for f in flatframes:
    f2 = f.parent
    
    def visit_rets3(n2):
      p = n2.parent
      while not null_node(p) and p != f.subnode:
        p = p.parent
        
      if p != f.subnode and not null_node(p): return #continue corresponds to a loop internal to this frame
      p = f.parent
      while p != None:
        if type(p.node) in [WhileNode, DoWhileNode, ForLoopNode]:
          break;
        p = p.parent
        
      if p == None:
        typespace.error("Invalid continue statement")
      
      n3 = js_parse("return [$i, undefined];", [p.label], start_node=ReturnNode);
      n2.parent.replace(n2, n3)
      
    traverse(f.subnode, ContinueNode, visit_rets3, copy_children=True);

  firstnode = js_parse("if (this.first) {\n}", start_node=IfNode)
  firstnode2 = js_parse("if (this.first) {\n}", start_node=IfNode)
  firstnode.replace(firstnode[1], StatementList())
  firstnode2.replace(firstnode2[1], StatementList())
  flatframes[0].subnode.add(firstnode);
  node2.insert(1, firstnode2[1]);

  firstnode = firstnode[1]
  firstnode2 = firstnode2[1]
  
  args = list(node.children[0])
  for i3 in range(len(args)):
    argn = args[i3]
    while type(argn) not in [IdentNode, VarDeclNode]:
      argn = argn[0]
   
    args[i3] = argn.val
  
  scope = {}
  for f in flatframes:
    scope.update(f.scope)
  
  s = "{"
  j2 = 0
  for j, v in enumerate(scope.keys()):
    if j2 > 0: s += ", "
    j2 += 1
    
    if v in args:
      s += "%s:%s" % ("%s_%s"%(v, scope[v]), v)
    else:
      s += "%s:undefined" % ("%s_%s"%(v, scope[v]))
  s += "}"
    
  s = "this.scope = %s;\n" % s
  firstnode2.add(js_parse(s)[0])
  
  #ensure all frames have returns
  for f in flatframes:
    if not find_node(f.subnode, ReturnNode):
      f.subnode.add(js_parse("return [$i, undefined];", [f_next(f).label], start_node=ReturnNode));
    
  framelist = "["
  for i, f in enumerate(flatframes):
    if i > 0: framelist += ", "
    framelist += "this.frame_%i" % f.label
  framelist = "this.frames = %s];"%framelist
  node2.add(js_parse(framelist));
  
  node2.add(js_parse("""
    this.cur = 1;
    this.trystack = new Array();
    
    this.next = function() {
      var ret;
      while (this.cur < this.frames.length) {
        try {
          ret = this.frames[this.cur].call(this, this.scope);
        } catch (_generator_error) {
          if (this.trystack.length > 0) {
            var ts1 = this.trystack.pop();
            
            this.scope[ts1[1]] = _generator_error;
            
            ret = [ts1[0], undefined];
          } else {
            throw _generator_error;
          }
        }
        
        if (ret[0] == this.frames.length) {
          return {done : true, value : undefined};
          break;
        }
        
        if (ret[0] == this.cur) {
          console.trace();
          console.log("YEEK!")
          return {done : true, value : undefined};
        }
        
        this.cur = ret[0];
        
        if (ret[1] != undefined) {
          return {value : ret[1][0], done : false};
        } else {
          return {value : undefined, done : false};
        }
      }
    }
  """, []))
  
  node.parent.replace(node, node2)