Example #1
0
def _backend(self,level=0):
    if (self.args[0].__class__ is node.number and
        self.args[1].__class__ is node.number):
        return node.number(self.args[0].value +
                           self.args[1].value)._backend()
    else:
        return "(%s+%s)" % (self.args[0]._backend(),
                            self.args[1]._backend())
Example #2
0
def _backend(self,level=0):
    if (self.args[0].__class__ is node.number and
        self.args[1].__class__ is node.number):
        return node.number(self.args[0].value +
                           self.args[1].value)._backend()
    else:
        return "(%s +%s)" % (self.args[0]._backend(),
                            self.args[1]._backend())
Example #3
0
"""
 SMOP compiler -- Simple Matlab/Octave to Python compiler
 Copyright 2011-2013 Victor Leikehman
"""

import inspect
import sys
import node
from node import extend

import options, parse

ZERO = node.number(0)


def rewrite(t):
    global modified
    modified = []
    while do_rewrite(t) or modified:
        modified = []


def do_rewrite(t):
    for u in node.postorder(t):
        try:
            u._rewrite()
        except:
            assert 0


def lineno():
Example #4
0
def p_expr_number(p):
    "number : NUMBER"
    p[0] = node.number(p[1],lineno=p.lineno(1),lexpos=p.lexpos(1))
Example #5
0
def p_expr_end(p):
    "end : END_EXPR"
    p[0] = node.expr(op="end",args=node.expr_list([node.number(0),
                                                   node.number(0)]))
Example #6
0
def do_resolve(t,symtab):
    """
    Array references
    ----------------

    a(x)         --> a[x-1]         if rank(a) == 1
                 --> a.flat[x-1]    otherwise

    a(:)         --> a              if rank(a) == 1
                 --> a.flat[-1,1]   otherwise

    a(x,y,z)     --> a[x-1,y-1,z-1]

    a(x:y)       --> a[x-1:y]
    a(x:y:z)     --> a[x-1,z,y]

    a(...end...) --> a[... a.shape[i]...]
    a(x==y)      --> ???

    Function calls
    --------------

    start:stop          --> np.arange(start,stop+1)
    start:step:stop     --> np.arange(start,stop+1,step)

    """
    t._resolve(symtab)
    #pprint.pprint(symtab)
    for u in node.postorder(t):
        if (u.__class__ is node.funcall and 
            u.func_expr.__class__ is node.ident):
            if u.func_expr.defs:
                # Both node.arrayref and node.builtins are subclasses
                # of node.funcall, so we are allowed to assign to its
                # __class__ field.  Convert funcall nodes to array
                # references.
                u.__class__ = node.arrayref
            elif u.func_expr.defs == set():
                # Function used, but there is no definition. It's
                # either a builtin function, or a call to user-def
                # function, which is defined later.
                cls = getattr(node,u.func_expr.name,None)
                # """
                # if not cls:
                #     # This is the first time we met u.func_expr.name
                #     cls = type(u.func_expr.name,
                #                (node.funcall,),
                #                { 'code' : None })
                #     setattr(node,u.func_expr.name,cls)
                # assert cls
                # if issubclass(cls,node.builtins) and u.__class__ != cls:
                #     u.func_expr = None # same in builtins ctor

                if cls:
                    u.__class__ = cls
            else:
                # Only if we have A(B) where A.defs is None
                assert 0



        if u.__class__ in (node.arrayref,node.cellarrayref):
            # if (len(u.args) == 1
            #     and isinstance(u.args[0],node.expr)
            #     and u.args[0].op == ":"):
            #     # FOO(:) becomes ravel(FOO)
            #     u.become(node.ravel(u.func_expr))
            # else:
            for i in range(len(u.args)):
                cls = u.args[i].__class__
                if cls is node.number:
                    u.args[i].value -= 1
                elif cls is node.expr and u.args[i].op in ("==","!=","~=","<","=<",">",">="):
                    pass
                elif cls is node.expr and u.args[i].op == ":":
                    # Colon expression as a subscript becomes a
                    # slice.  Everywhere else it becomes a call to
                    # the "range" function (done in a separate pass,
                    # see below).
                    u.args[i].op = "::" # slice marked with op=::
                    if u.args[i].args:
                        if type(u.args[i].args[0]) is node.number:
                            u.args[i].args[0].value -= 1
                        else:
                            u.args[i].args[0] = node.sub(u.args[i].args[0],
                                                         node.number(1))
                    for s in node.postorder(u.args[i]):
                        if s.__class__==node.expr and s.op=="end" and not s.args:
                            s.args = node.expr_list([u.func_expr,node.number(i)])
                elif cls is node.expr and u.args[i].op == "end":
                    u.args[i] = node.number(-1)
                else:
                    u.args[i] = node.sub(u.args[i],node.number(1))

    for u in node.postorder(t):
        if u.__class__ == node.ident and u.defs == set():
            cls = getattr(node,u.name,None)
            if cls and issubclass(cls,node.builtins):
                u.become(cls())

        elif u.__class__ == node.expr and u.op == ":" and u.args:
            if len(u.args) == 2:
                u.become(node.range(u.args[0],
                                    node.add(u.args[1],node.number(1))))
            else:
                u.become(node.range(u.args[0],
                                    node.add(u.args[1],node.number(1)),
                                    u.args[2]))
Example #7
0
def p_expr_number(p):
    "number : NUMBER"
    p[0] = node.number(p[1], lineno=p.lineno(1), lexpos=p.lexpos(1))
Example #8
0
def p_expr_end(p):
    "end : END_EXPR"
    p[0] = node.expr(op="end",
                     args=node.expr_list([node.number(0),
                                          node.number(0)]))
Example #9
0
def resolve(t, symtab=None, fp=None, func_name=None):
    if symtab is None:
        symtab = {}
    do_resolve(t, symtab)
    G = as_networkx(t)
    #import pdb;pdb.set_trace()
    for n in G.nodes():
        u = G.node[n]["ident"]
        if u.props:
            pass
        elif G.out_edges(n) and G.in_edges(n):
            u.props = "U"  # upd
            #print u.name, u.lineno, u.column
        elif G.in_edges(n):
            u.props = "D"  # def
        elif G.out_edges(n):
            u.props = "R"  # ref
        else:
            u.props = "F"  # ???
        G.node[n]["label"] = "%s\\n%s" % (n, u.props)

    for u in node.postorder(t):
        if u.__class__ is node.func_decl:
            u.ident.name += "_"
        elif u.__class__ is node.funcall:
            try:
                if u.func_expr.props in "UR":  # upd,ref
                    u.__class__ = node.arrayref
                else:
                    u.func_expr.name += "_"
            except:
                pass

    for u in node.postorder(t):
        if u.__class__ in (node.arrayref, node.cellarrayref):
            for i, v in enumerate(u.args):
                if v.__class__ is node.expr and v.op == ":":
                    v.op = "::"
                for w in node.postorder(v):
                    if w.__class__ is node.expr and w.op == "end":
                        w.args[0] = u.func_expr
                        w.args[1] = node.number(i)

    for u in node.postorder(t):
        if u.__class__ is node.let:
            if (u.ret.__class__ is node.ident
                    and u.args.__class__ is node.matrix):
                u.args = node.funcall(func_expr=node.ident("matlabarray"),
                                      args=node.expr_list([u.args]))

    H = nx.connected_components(G.to_undirected())
    for i, component in enumerate(H):
        for nodename in component:
            if G.node[nodename]["ident"].props == "R":
                has_update = 1
                break
        else:
            has_update = 0
        if has_update:
            for nodename in component:
                G.node[nodename]["ident"].props += "S"  # sparse
        #S = G.subgraph(nbunch)
        #print S.edges()
    return G
Example #10
0
def do_resolve(t, symtab):
    """
    Array references
    ----------------

    a(x)         --> a[x-1]         if rank(a) == 1
                 --> a.flat[x-1]    otherwise

    a(:)         --> a              if rank(a) == 1
                 --> a.flat[-1,1]   otherwise

    a(x,y,z)     --> a[x-1,y-1,z-1]

    a(x:y)       --> a[x-1:y]
    a(x:y:z)     --> a[x-1,z,y]

    a(...end...) --> a[... a.shape[i]...]
    a(x==y)      --> ???

    Function calls
    --------------

    start:stop          --> np.arange(start,stop+1)
    start:step:stop     --> np.arange(start,stop+1,step)

    """
    t._resolve(symtab)
    #pprint.pprint(symtab)
    for u in node.postorder(t):
        if (u.__class__ is node.funcall and u.func_expr.__class__ is node.expr
                and u.func_expr.op == "."):
            u.__class__ = node.arrayref
        elif (u.__class__ is node.funcall
              and u.func_expr.__class__ is node.ident):
            if u.func_expr.defs:
                # Both node.arrayref and node.builtins are subclasses
                # of node.funcall, so we are allowed to assign to its
                # __class__ field.  Convert funcall nodes to array
                # references.
                u.__class__ = node.arrayref
            elif u.func_expr.defs == set():
                # Function used, but there is no definition. It's
                # either a builtin function, or a call to user-def
                # function, which is defined later.
                cls = getattr(node, u.func_expr.name, None)
                # """
                # if not cls:
                #     # This is the first time we met u.func_expr.name
                #     cls = type(u.func_expr.name,
                #                (node.funcall,),
                #                { 'code' : None })
                #     setattr(node,u.func_expr.name,cls)
                # assert cls
                # if issubclass(cls,node.builtins) and u.__class__ != cls:
                #     u.func_expr = None # same in builtins ctor

                if cls:
                    u.__class__ = cls
            else:
                # Only if we have A(B) where A.defs is None
                assert 0

        if u.__class__ in (node.arrayref, node.cellarrayref):
            # if (len(u.args) == 1
            #     and isinstance(u.args[0],node.expr)
            #     and u.args[0].op == ":"):
            #     # FOO(:) becomes ravel(FOO)
            #     u.become(node.ravel(u.func_expr))
            # else:
            for i in range(len(u.args)):
                cls = u.args[i].__class__
                if cls is node.number:
                    u.args[i].value -= 1
                elif cls is node.expr and u.args[i].op in ("==", "!=", "~=",
                                                           "<", "=<", ">",
                                                           ">="):
                    pass
                elif cls is node.expr and u.args[i].op == ":":
                    # Colon expression as a subscript becomes a
                    # slice.  Everywhere else it becomes a call to
                    # the "range" function (done in a separate pass,
                    # see below).
                    u.args[i].op = "::"  # slice marked with op=::
                    if u.args[i].args:
                        if type(u.args[i].args[0]) is node.number:
                            u.args[i].args[0].value -= 1
                        else:
                            u.args[i].args[0] = node.sub(
                                u.args[i].args[0], node.number(1))
                    for s in node.postorder(u.args[i]):
                        if s.__class__ == node.expr and s.op == "end" and not s.args:
                            s.args = node.expr_list(
                                [u.func_expr, node.number(i)])
                elif cls is node.expr and u.args[i].op == "end":
                    u.args[i] = node.number(-1)
                else:
                    u.args[i] = node.sub(u.args[i], node.number(1))

    for u in node.postorder(t):
        if u.__class__ == node.ident and u.defs == set():
            cls = getattr(node, u.name, None)
            if cls and issubclass(cls, node.builtins):
                u.become(cls())

        elif u.__class__ == node.expr and u.op == ":" and u.args:
            if len(u.args) == 2:
                u.become(
                    node.range(u.args[0], node.add(u.args[1], node.number(1))))
            else:
                u.become(
                    node.range(u.args[0], node.add(u.args[1], node.number(1)),
                               u.args[2]))
Example #11
0
def end_expressions(u):
    if u.__class__ in (node.arrayref, node.cellarrayref):
        if w.__class__ is node.expr and w.op == "end":
            w.args[0] = u.func_expr
            w.args[1] = node.number(i)  # FIXME
Example #12
0
"""
 SMOP compiler -- Simple Matlab/Octave to Python compiler
 Copyright 2011-2013 Victor Leikehman
"""

import inspect
import sys
import node
from node import extend

import options,parse

ZERO = node.number(0)

def rewrite(t):
    global modified; modified = []
    while do_rewrite(t) or modified:
        modified = []

def do_rewrite(t):
    for u in node.postorder(t):
        try:
            u._rewrite()
        except:
            assert 0

def lineno():
    """Returns the current line number in our program."""
    return inspect.currentframe().f_back.f_lineno

@extend(node.node)
Example #13
0
def resolve(t, symtab=None, fp=None, func_name=None):
    if symtab is None:
        symtab = {}
    do_resolve(t,symtab)
    G = as_networkx(t)
    #import pdb;pdb.set_trace()
    for n in G.nodes():
        u = G.node[n]["ident"]
        if u.props:
            pass
        elif G.out_edges(n) and G.in_edges(n):
            u.props = "U" # upd
            #print u.name, u.lineno, u.column
        elif G.in_edges(n):
            u.props = "D" # def
        elif G.out_edges(n):
            u.props = "R" # ref
        else:
            u.props = "F" # ???
        G.node[n]["label"] = "%s\\n%s" % (n, u.props)

    for u in node.postorder(t):
        if u.__class__ is node.func_decl:
            u.ident.name += "_"
        elif u.__class__ is node.funcall:
            try:
                if u.func_expr.props in "UR": # upd,ref
                    u.__class__ = node.arrayref
                else:
                    u.func_expr.name += "_"
            except:
                pass

    for u in node.postorder(t):
        if u.__class__ in (node.arrayref,node.cellarrayref):
            for i,v in enumerate(u.args):
                if v.__class__ is node.expr and v.op == ":":
                    v.op = "::"
                for w in node.postorder(v):
                    if w.__class__ is node.expr and w.op == "end":
                        w.args[0] = u.func_expr
                        w.args[1] = node.number(i)

    for u in node.postorder(t):
        if u.__class__ is node.let:
            if (u.ret.__class__ is node.ident and
                u.args.__class__ is node.matrix):
                u.args = node.funcall(func_expr=node.ident("matlabarray"),
                                      args=node.expr_list([u.args]))

    H = nx.connected_components(G.to_undirected())
    for i,component in enumerate(H):
        for nodename in component:
            if G.node[nodename]["ident"].props == "R":
                has_update = 1
                break
        else:
            has_update = 0
        if has_update:
            for nodename in component:
                G.node[nodename]["ident"].props += "S"  # sparse
        #S = G.subgraph(nbunch)
        #print S.edges()
    return G