Exemple #1
0
def visit_yields(node):
  p = node
  
  while not null_node(p) and type(p) != FunctionNode:
    p = p.parent
  
  if null_node(p):
    typespace.error("yield keyword only valid within functions")
  
  p.is_generator = True
Exemple #2
0
def visit_yields(node):
    p = node

    while not null_node(p) and type(p) != FunctionNode:
        p = p.parent

    if null_node(p):
        typespace.error("yield keyword only valid within functions")

    p.is_generator = True
Exemple #3
0
    def visit(n):
        if type(n.parent) == TryNode: return

        sl = n.parent

        i = sl.children.index(n)
        i -= 1

        #we remove n here, since we may have to ascend through
        #several layers of StatementList nodes
        sl.children.remove(n)
        while 1:
            while i >= 0:
                if type(sl[i]) == TryNode:
                    break
                i -= 1

            if i >= 0 or null_node(sl.parent): break

            i = sl.parent.children.index(sl)
            sl = sl.parent

        if i < 0:
            sys.stderr.write("%s:(%d): error: orphaned catch block\n" %
                             (n.file, n.line))
            sys.exit(-1)

        tn = sl[i]
        tn.add(n)
Exemple #4
0
    def visit(n):
        if type(n.parent) == TryNode:
            return

        sl = n.parent

        i = sl.children.index(n)
        i -= 1

        # we remove n here, since we may have to ascend through
        # several layers of StatementList nodes
        sl.children.remove(n)
        while 1:
            while i >= 0:
                if type(sl[i]) == TryNode:
                    break
                i -= 1

            if i >= 0 or null_node(sl.parent):
                break

            i = sl.parent.children.index(sl)
            sl = sl.parent

        if i < 0:
            sys.stderr.write("%s:(%d): error: orphaned catch block\n" % (n.file, n.line))
            sys.exit(-1)

        tn = sl[i]
        tn.add(n)
Exemple #5
0
 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)
Exemple #6
0
 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)
Exemple #7
0
 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)
Exemple #8
0
 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)
Exemple #9
0
    def apply_frame_scope(n, scope, frames):
        if type(n) == IdentNode:
            if n.val in scope:
                n.val = "scope.%s_%d" % (n.val, scope[n.val])
            else:
                p = n.parent
                n2 = n
                #check for implicit declarations within catch and loop nodes
                while not null_node(p):
                    if type(p) in [CatchNode, WhileNode, ForLoopNode]: break
                    n2 = p
                    p = p.parent

                if not null_node(p) and n2 == p[0]:
                    scope[n.val] = frames.label
                    n.val = "scope.%s_%d" % (n.val, scope[n.val])

        elif type(n) == VarDeclNode:
            n.local = False
            if "local" in n.modifiers: n.modifiers.remove("local")

            if hasattr(n.parent, "_c_loop_node"):
                frames = n.parent._c_loop_node.frame
                #print("yay", n.parent._c_loop_node.frame.label)

            if n.val not in scope:
                scope[n.val] = frames.label
            if n.val in scope:
                n.val = "scope.%s_%d" % (n.val, scope[n.val])
        for c in n.children:
            #ignore expr functions, but not nested functions?
            if type(c) == FunctionNode and type(c.parent) == AssignNode:
                continue
            if type(n) == BinOpNode and n.op == "." and c == n[1] and type(
                    c) == IdentNode:
                continue
            if type(n) == FuncCallNode and type(c) == IdentNode and c == n[0]:
                continue

            apply_frame_scope(c, scope, frames)
Exemple #10
0
 def apply_frame_scope(n, scope, frames):
   if type(n) == IdentNode:
     if n.val in scope:
       n.val = "scope.%s_%d" % (n.val, scope[n.val])
     else:
       p = n.parent
       n2 = n
       #check for implicit declarations within catch and loop nodes
       while not null_node(p):
         if type(p) in [CatchNode, WhileNode, ForLoopNode]: break
         n2 = p
         p = p.parent
         
       if not null_node(p) and n2 == p[0]:
         scope[n.val] = frames.label
         n.val = "scope.%s_%d" % (n.val, scope[n.val])
         
   elif type(n) == VarDeclNode:
     n.local = False;
     if "local" in n.modifiers: n.modifiers.remove("local")
     
     if hasattr(n.parent, "_c_loop_node"):
       frames = n.parent._c_loop_node.frame
       #print("yay", n.parent._c_loop_node.frame.label)
     
     if n.val not in scope:
       scope[n.val] = frames.label
     if n.val in scope:
       n.val = "scope.%s_%d" % (n.val, scope[n.val])
   for c in n.children:
     #ignore expr functions, but not nested functions?
     if type(c) == FunctionNode and type(c.parent) == AssignNode: continue
     if type(n) == BinOpNode and n.op == "." and c == n[1] and type(c) == IdentNode:
       continue
     if type(n) == FuncCallNode and type(c) == IdentNode and c == n[0]:
       continue
       
     apply_frame_scope(c, scope, frames)
Exemple #11
0
 def is_stype(n):
   ret = type(n) in stypes # and (n._has_yield or n.parent._has_yield)
   
   return ret
   
   if type(n) == CatchNode:
     ret |= prior_try(n)._has_yield
   if type(n) == ElseNode:
     ret |= prior_if(n)._has_yield
   
   if type(n) in [IfNode, ElseNode]:
     p5 = n.parent
     while not null_node(p5):
       if hasattr(p5, "_has_yield") and p5._has_yield:
         ret = True;
         break
       p5 = p5.parent
       
   return ret
Exemple #12
0
    def is_stype(n):
        ret = type(n) in stypes  # and (n._has_yield or n.parent._has_yield)

        return ret

        if type(n) == CatchNode:
            ret |= prior_try(n)._has_yield
        if type(n) == ElseNode:
            ret |= prior_if(n)._has_yield

        if type(n) in [IfNode, ElseNode]:
            p5 = n.parent
            while not null_node(p5):
                if hasattr(p5, "_has_yield") and p5._has_yield:
                    ret = True
                    break
                p5 = p5.parent

        return ret
Exemple #13
0
    def visit(n):
        if type(n.parent) == IfNode:
            return

        if n in vset:
            return
        vset.add(n)

        sl = n.parent

        i = sl.children.index(n)
        # i -= 1

        # we remove n here, since we may have to ascend through
        # several layers of StatementList nodes
        sl.children.remove(n)

        # clamp i
        i = max(min(i, len(sl) - 1), 0)
        # print(len(sl), i)
        while 1:
            while i >= 0 and i < len(sl):
                if type(sl[i]) == IfNode:
                    break

                i -= 1

            if i >= 0 or null_node(sl.parent):
                break

            i = sl.parent.children.index(sl)
            sl = sl.parent

        if i < 0:
            sys.stderr.write("%s:(%d): error: orphaned else block\n" % (n.file, n.line))
            sys.exit(-1)

        tn = sl[i]
        while len(tn) > 2:
            tn = tn[2][0]
        tn.add(n)
        found[0] = True
Exemple #14
0
    def visit(n):
        if type(n.parent) == IfNode: return

        if n in vset: return
        vset.add(n)

        sl = n.parent

        i = sl.children.index(n)
        #i -= 1

        #we remove n here, since we may have to ascend through
        #several layers of StatementList nodes
        sl.children.remove(n)

        #clamp i
        i = max(min(i,
                    len(sl) - 1), 0)
        #print(len(sl), i)
        while 1:
            while i >= 0 and i < len(sl):
                if type(sl[i]) == IfNode:
                    break

                i -= 1

            if i >= 0 or null_node(sl.parent): break

            i = sl.parent.children.index(sl)
            sl = sl.parent

        if i < 0:
            sys.stderr.write("%s:(%d): error: orphaned else block\n" %
                             (n.file, n.line))
            sys.exit(-1)

        tn = sl[i]
        while len(tn) > 2:
            tn = tn[2][0]
        tn.add(n)
        found[0] = True
Exemple #15
0
 def prior_try(n):
   if n.parent == None: return None
   
   sl = n.parent
   i = sl.children.index(n)-1
   while 1:
     while i >= 0:
       if type(sl[i]) == TryNode:
         break
       i -= 1
       
     if i >= 0 or null_node(n.parent): break
     
     i = sl.parent.children.index(sl);
     sl = sl.parent;
     
   if i < 0:
     typespace.error("Orphaned catch node", n)
     sys.exit(-1)
   
   return sl[i]
Exemple #16
0
    def prior_try(n):
        if n.parent == None: return None

        sl = n.parent
        i = sl.children.index(n) - 1
        while 1:
            while i >= 0:
                if type(sl[i]) == TryNode:
                    break
                i -= 1

            if i >= 0 or null_node(n.parent): break

            i = sl.parent.children.index(sl)
            sl = sl.parent

        if i < 0:
            typespace.error("Orphaned catch node", n)
            sys.exit(-1)

        return sl[i]
Exemple #17
0
    def expand_mozilla_forloops_new(node, scope):
        if node.of_keyword == "in":
            typespace.warning("Temporary warning: detected for-in usage", node)
            return

        func = node.parent
        while not null_node(func) and type(func) != FunctionNode:
            func = func.parent

        if not null_node(func):
            if func.name in forloop_expansion_exclude:
                return

        def prop_ident_change(node, oldid, newid):
            if type(node) in [IdentNode, VarDeclNode] and node.val == oldid:
                if type(node.parent) == BinOpNode and node.parent.op == ".":
                    if node != node.parent[1]:
                        node.val = newid
                else:
                    node.val = newid

            for c in node.children:
                if type(c) == FunctionNode:
                    continue
                prop_ident_change(c, oldid, newid)

        # for-in-loops don't seem to behave like for-C-loops,
        # the iteration variable is in it's own scope, and
        # doesn't seem to affect the parent scope.
        val = node[0].val
        di = 0
        while node[0].val in scope:
            node[0].val = "%s_%d" % (val, di)
            di += 1

            # print(node[0].val)

        if node[0].val != val:
            scope[node[0].val] = node[0]
            prop_ident_change(node.parent, val, node[0].val)

        slist = node.parent.children[1]
        if type(slist) != StatementList:
            s = StatementList()
            s.add(slist)
            slist = s

        itername = node[0].val
        objname = node[1].gen_js(0)
        if glob.g_log_forloops:
            n2 = js_parse(
                """
        var __iter_$s1 = __get_iter($s2, $s3, $s4, $s5);
        var $s1;
        while (1) {
          var __ival_$s1 = __iter_$s1.next();
          if (__ival_$s1.done) {
            break;
          }
          
          $s1 = __ival_$s1.value;
        }
      """,
                (itername, objname, "'" + node[0].file + "'", node[0].line, "'" + node.of_keyword + "'"),
            )
        else:
            n2 = js_parse(
                """
        var __iter_$s1 = __get_iter($s2);
        var $s1;
        while (1) {
          var __ival_$s1 = __iter_$s1.next();
          if (__ival_$s1.done) {
            break;
          }
          
          $s1 = __ival_$s1.value;
        }
      """,
                (itername, objname),
            )

        def set_line(n, slist, line, lexpos):
            n.line = line
            n.lexpos = lexpos

            for c in n.children:
                set_line(c, slist, line, lexpos)

        # preserving line info is a bit tricky.
        # slist goes through a js->gen_js->js cycle,
        # so make sure we still have it (and its
        # line/lexpos information).

        set_line(n2, slist, node.line, node.lexpos)
        for c in slist:
            n2[2][1].add(c)

        node.parent.parent.replace(node.parent, n2)
Exemple #18
0
    def expand_mozilla_forloops_new(node, scope):
        use_in_iter = False

        if (node.of_keyword == "in"):
            use_in_iter = True
            typespace.warning("Temporary warning: detected for-in usage", node)

            if not inside_generator(node):
                return

        func = node.parent
        while not null_node(func) and type(func) != FunctionNode:
            func = func.parent

        if not null_node(func):
            if func.name in forloop_expansion_exclude: return

        def prop_ident_change(node, oldid, newid):
            if type(node) in [IdentNode, VarDeclNode] and node.val == oldid:
                if type(node.parent) == BinOpNode and node.parent.op == ".":
                    if node != node.parent[1]:
                        node.val = newid
                else:
                    node.val = newid

            for c in node.children:
                if type(c) == FunctionNode:
                    continue
                prop_ident_change(c, oldid, newid)

        #for-in-loops don't seem to behave like for-C-loops,
        #the iteration variable is in it's own scope, and
        #doesn't seem to affect the parent scope.
        val = node[0].val
        di = 0
        while node[0].val in scope:
            node[0].val = "%s_%d" % (val, di)
            di += 1

            #print(node[0].val)

        if node[0].val != val:
            scope[node[0].val] = node[0]
            prop_ident_change(node.parent, val, node[0].val)

        slist = node.parent.children[1]
        if type(slist) != StatementList:
            s = StatementList()
            s.add(slist)
            slist = s

        getiter = "__get_in_iter" if use_in_iter else "__get_iter"

        itername = node[0].val
        objname = node[1].gen_js(0)
        if glob.g_log_forloops:
            n2 = js_parse(
                """
        var __iter_$s1 = __get_iter($s2, $s3, $s4, $s5);
        var $s1;
        while (1) {
          var __ival_$s1 = __iter_$s1.next();
          if (__ival_$s1.done) {
            break;
          }
          
          $s1 = __ival_$s1.value;
        }
      """.replace("__get_iter", getiter),
                (itername, GETITER, objname, "'" + node[0].file + "'",
                 node[0].line, "'" + node.of_keyword + "'"))
        else:
            n2 = js_parse(
                """
        var __iter_$s1 = __get_iter($s2);
        var $s1;
        while (1) {
          var __ival_$s1 = __iter_$s1.next();
          if (__ival_$s1.done) {
            break;
          }
          
          $s1 = __ival_$s1.value;
        }
      """.replace("__get_iter", getiter), (itername, objname))

        def set_line(n, slist, line, lexpos):
            n.line = line
            n.lexpos = lexpos

            for c in n.children:
                set_line(c, slist, line, lexpos)

        #preserving line info is a bit tricky.
        #slist goes through a js->gen_js->js cycle,
        #so make sure we still have it (and its
        #line/lexpos information).

        set_line(n2, slist, node.line, node.lexpos)
        for c in slist:
            n2[2][1].add(c)

        node.parent.parent.replace(node.parent, n2)