From de9dfc9649d9d18eb545234d9651bd3c6ada38ad Mon Sep 17 00:00:00 2001 From: Victor Leikehman Date: Wed, 31 Jul 2013 22:33:56 +0300 Subject: [PATCH] work in progress --- setup.py | 4 ++-- smop/backend.py | 54 ++++++++++++++++++++++++++--------------------- smop/fastsolver.m | 4 ++-- smop/main.py | 23 +++++++++----------- smop/node.py | 5 ++--- smop/options.py | 5 +---- smop/parse.py | 39 +++++++++------------------------- smop/resolve.py | 4 ++-- smop/typeof.py | 42 ++++++++++++++++++------------------ 9 files changed, 80 insertions(+), 100 deletions(-) diff --git a/setup.py b/setup.py index ffc86fd4..2404e900 100644 --- a/setup.py +++ b/setup.py @@ -8,10 +8,10 @@ description = 'Matlab to Python compiler', license = 'MIT', keywords = 'matlab octave python compiler', - url = 'http://chiselapp.com/user/victorlei/repository/smop-dev/index', + #url = 'http://chiselapp.com/user/victorlei/repository/smop-dev/index', #download_url = 'http://code.google.com/p/smop-dev/downloads/list', name = 'smop', - version = '0.22', + version = '0.23', entry_points = { 'console_scripts': [ 'smop = smop.main:main', ], }, packages = ['smop'], #package_dir = {'':'src'}, diff --git a/smop/backend.py b/smop/backend.py index 607fc5c2..14bb7a9f 100644 --- a/smop/backend.py +++ b/smop/backend.py @@ -211,13 +211,13 @@ def _backend(self,level=0): # func_name = self.func_expr.name # else: # func_name = self.__class__.__name__ - if self.ret is None: + #if self.ret is None: return "%s(%s)" % (self.func_expr._backend(), self.args._backend()) - else: - return ("%s = %s(%s)" % (self.ret._backend(), - self.func_expr._backend(), - self.args._backend())) + #else: + # return ("%s = %s(%s)" % (self.ret._backend(), + # self.func_expr._backend(), + # self.args._backend())) @extend(node.let) @exceptions @@ -226,9 +226,14 @@ def _backend(self,level=0): s = "# %d\n" % self.lineno + level*indent else: s = '' - return "%s%s=%s" % (s, - self.ret._backend(), - self.args._backend()) + if self.nargout > 1: + return "%s=%s # nargout=%d" % (self.ret._backend(), + self.args._backend(), + self.nargout) + else: + return "%s=%s" % (self.ret._backend(), + self.args._backend()) + @extend(node.expr_list) @exceptions @@ -371,13 +376,13 @@ def _backend(self,level=0): @extend(node.builtins) @exceptions def _backend(self,level=0): - if not self.ret: + #if not self.ret: return "%s(%s)" % (self.__class__.__name__, self.args._backend()) - else: - return ("%s=%s(%s)" % (self.ret._backend(), - self.__class__.__name__, - self.args._backend())) + # else: + # return ("%s=%s(%s)" % (self.ret._backend(), + # self.__class__.__name__, + # self.args._backend())) @extend(node.strcmp) @exceptions @@ -409,11 +414,11 @@ def _backend(self,level=0): @exceptions def _backend(self,level=0): if len(self.args) == 1: - if self.ret: - return "%s = %s.shape" % (self.ret, - self.args[0]._backend()) - else: - return "%s.shape" % self.args[0]._backend() + # if self.ret: + # return "%s = %s.shape" % (self.ret, + # self.args[0]._backend()) + # else: + return "%s.shape" % self.args[0]._backend() if self.args[1].__class__ is node.number: return "%s.shape[%s]" % (self.args[0]._backend(), @@ -473,12 +478,13 @@ def _backend(self,level=0): @extend(node.find) @exceptions def _backend(self,level=0): - if self.ret and len(self.ret) == 2: - return "%s,%s = np.nonzero(%s)" % (self.ret[0]._backend(), - self.ret[1]._backend(), - self.args[0]._backend()) - else: - return "np.flatnonzero(%s)" % self.args[0]._backend() + return "np.flatnonzero(%s)" % self.args[0]._backend() + # if self.ret and len(self.ret) == 2: + # return "%s,%s = np.nonzero(%s)" % (self.ret[0]._backend(), + # self.ret[1]._backend(), + # self.args[0]._backend()) + # else: + # return "np.flatnonzero(%s)" % self.args[0]._backend() @extend(node.load) @exceptions diff --git a/smop/fastsolver.m b/smop/fastsolver.m index 9f17fcfc..2116bc88 100644 --- a/smop/fastsolver.m +++ b/smop/fastsolver.m @@ -873,8 +873,8 @@ end; end; newitem=curpos(newpos(1),newpos(2)); - pfin2 = 123 - %[pfin2(1) pfin2(2)]=find(finpos==newitem); + pfin2 = [] + [pfin2(1) pfin2(2)]=find(finpos==newitem); dirx2=sign(pfin2(1)-newpos(1)); diry2=sign(pfin2(2)-newpos(2)); wt(newitem)=wt(newitem)+20000; diff --git a/smop/main.py b/smop/main.py index 744f5e51..9ce60305 100644 --- a/smop/main.py +++ b/smop/main.py @@ -6,7 +6,7 @@ import lexer,parse,resolve,backend,options,rewrite,node,typeof def usage(): - print "SMOP compiler version 0.22" + print "SMOP compiler version 0.23" print """Usage: smop [options] file-list Options: -V --version @@ -49,7 +49,7 @@ def main(): elif o in ("-v", "--verbose"): verbose += 1 elif o in ("-V", "--version"): - print "SMOP compiler version 0.22" + print "SMOP compiler version 0.23" sys.exit() elif o in ("-h", "--help"): usage() @@ -62,7 +62,7 @@ def main(): if not output: output = "a.py" fp = open(output,"w") if output != "-" else sys.stdout - print >> fp, "# Autogenerated with SMOP version 0.22" + print >> fp, "# Autogenerated with SMOP version 0.23" print >> fp, "# " + " ".join(sys.argv) print >> fp, "from __future__ import division" print >> fp, "import numpy as np" @@ -89,7 +89,7 @@ def main(): for func_obj in func_list: try: func_name = func_obj.head.ident.name - options.functab[func_name] = func_obj + symtab[func_name] = func_obj print "\t",func_name except AttributeError: if verbose: @@ -101,17 +101,14 @@ def main(): resolve.resolve(func_obj) if options.do_typeof: - t = func_obj.apply(**symtab) + for func_obj in func_list: + t = func_obj.apply([],symtab) - if options.do_listing: - for key in sorted(options.functab.keys()): - print key, options.functab[key].head.ident - - print "*" * 50 - - # end for - if options.do_rewrite: + if options.do_rewrite: + for func_obj in func_list: rewrite.rewrite(func_obj) + + for func_obj in func_list: s = backend.backend(func_obj) print >> fp, s except Exception as ex: diff --git a/smop/node.py b/smop/node.py index f0c080a3..346714ca 100644 --- a/smop/node.py +++ b/smop/node.py @@ -44,7 +44,6 @@ def wrapper(self,*args,**kwargs): return f(self,*args,**kwargs) except: print "%s.%s()" % (self.__class__.__name__, f.__name__) - import pdb; pdb.set_trace() raise wrapper.__name__ = f.__name__ return wrapper @@ -142,7 +141,7 @@ class stmt(node): pass # str(self.args)) class let(stmt,recordtype("let", - "ret args lineno lexpos", + "ret args lineno lexpos nargout", default=None)): """Assignment statement, except [x,y]=foo(x,y,z), which is handled by call_stmt.""" @@ -209,7 +208,7 @@ class allocate_stmt(stmt,recordtype("allocate_stmt", # # FUNCALL -class funcall(node,recordtype("funcall","func_expr args ret",default=None)): +class funcall(node,recordtype("funcall","func_expr args",default=None)): """Funcall instances represent (a) Array references, both lhs and rhs (b) Function call expressions diff --git a/smop/options.py b/smop/options.py index f359422c..9524266a 100644 --- a/smop/options.py +++ b/smop/options.py @@ -18,7 +18,7 @@ do_allocate = 0 do_resolve = 1 -do_rewrite = 1 +do_rewrite = 0 do_rename = 0 # SSA do_typeof = 0 do_listing = 0 @@ -29,6 +29,3 @@ line_numbering=True #True # uses either # or ! or % -""" Map func name (str) to node.function instance -""" -functab = {} diff --git a/smop/parse.py b/smop/parse.py index 1cafbd1b..8c7b57ee 100644 --- a/smop/parse.py +++ b/smop/parse.py @@ -396,36 +396,17 @@ def p_let(p): p[0] = node.setfield(p[1].args[0], p[1].args[1], p[3]) - elif isinstance(p[1],node.matrix): - assert len(p[1].args) > 0 - ret = p[1].args - # p[3] may be a single ident, hiding a funcall w/o the arguments - if isinstance(p[3],node.ident): - # [a b] = foo - p[0] = node.funcall(func_expr=p[3], - args=node.expr_list(), - ret=ret) - elif isinstance(p[3],node.funcall): - # [a b] = foo(x,y) - p[0] = node.funcall(func_expr=p[3].func_expr, - args=p[3].args, - ret=ret) - else: - # In MATLAB, there is yet another way to assign simultaneously - # several values, by using struct arrays as follows: - # >>> foo(1).x=100 - # >>> foo(2).x=200 - # >>> [a b] = foo.x - # There is no attempt to support struct arrays which are not - # scalars, that is whose size is other than 1,1 - assert 0 else: - #if p[3].is_const(): - # p[1].value = p[3] - p[0] = node.let(ret=p[1], - args=p[3], - lineno=p.lineno(2), - lexpos=p.lexpos(2)) + #assert len(p[1].args) > 0 + ret = p[1].args if isinstance(p[1],node.matrix) else p[1] + p[0] = node.let(ret=ret, + args=p[3], + lineno=p.lineno(2), + lexpos=p.lexpos(2)) + if isinstance(p[1],node.matrix): + p[0].nargout = len(p[1].args) + else: + p[0].nargout = 0 def p_for_stmt(p): """ diff --git a/smop/resolve.py b/smop/resolve.py index 9edbce6b..f08cb1d9 100644 --- a/smop/resolve.py +++ b/smop/resolve.py @@ -340,8 +340,8 @@ def _resolve(self,symtab): if self.func_expr: self.func_expr._resolve(symtab) self.args._resolve(symtab) - if self.ret: - self.ret._lhs_resolve(symtab) + #if self.ret: + # self.ret._lhs_resolve(symtab) @extend(node.setfield) # a subclass of funcall @exceptions diff --git a/smop/typeof.py b/smop/typeof.py index 61c1b47e..3d1819a8 100644 --- a/smop/typeof.py +++ b/smop/typeof.py @@ -11,18 +11,26 @@ @extend(node.function) @exceptions -def apply(self,*args,**symtab): +def apply(self,args,symtab): name = self.head.ident.name if name in callstack: return - #print "%%%", self.head.ident.name + print "%%%", self.head.ident.name callstack.add(name) params = [(u.name,u.lineno) for u in self.head.args] - symtab.update(map(None,params,args)) + if len(args) < len(self.head.args): # head.args are formal params + args += [''] * (len(self.head.args)-len(args)) + symtab.update(zip(params,args)) self.body._typeof(symtab) #return [symtab[u.name,u.lineno] for u in self.ret] - return "".join([u._typeof(symtab) for u in self.head.ret]) +# for u in node.postorder(self): +# if u.__class__ is node.ident: +# try: +# print u.name,u.lineno,symtab[u.name,u.lineno] +# except: +# print u.name,u.lineno,'?' + return '' #[u._typeof(symtab) for u in self.head.ret] @extend(node.node) @exceptions @@ -36,12 +44,6 @@ def _typeof(self,symtab): symtab[self.ident.name,self.ident.lineno] = 'i' self.stmt_list._typeof(symtab) -# @extend(node.function) -# @exceptions -# def _typeof(self,symtab): -# self.head._typeof(symtab) -# self.body._typeof(symtab) - @extend(node.func_decl) @exceptions def _typeof(self,symtab): @@ -70,7 +72,7 @@ def _typeof(self,symtab): try: return symtab[self.name,self.lineno] except: - #print '+++ Missing type for',self.name + print '+++ Missing type for',self.name return '' ts = set([u._typeof(symtab) for u in self.defs if u.defs is None]) if '' in ts: @@ -203,12 +205,9 @@ def _typeof(self,symtab): @extend(node.sort) @exceptions def _typeof(self,symtab): - if not self.ret: - return self.args[0]._typeof(symtab) - if len(self.ret) == 1: - return self.args[0]._typeof(symtab) - if len(self.ret) == 2: - return self.args[0]._typeof(symtab) + 'i' + return self.args[0]._typeof(symtab) + #if len(self.ret) == 2: + # return self.args[0]._typeof(symtab) + 'i' @extend(node.numel) @extend(node.floor) @@ -230,12 +229,13 @@ def _typeof(self,symtab): def _typeof(self,symtab): return 'l' -@extend(node.funcall) # func_expr,args,ret +@extend(node.funcall) # func_expr,args @exceptions def _typeof(self,symtab): - #func = symtab[self.func_expr.name,self.func_expr.lineno] - func = options.functab[self.func_expr.name] - return func.apply(self.args) + func_obj = symtab[self.func_expr.name] + #if not self.ret: + return func_obj.apply(self.args,symtab) + #return ['' for i in self.ret] @extend(node.ravel) @exceptions