Skip to content

Commit

Permalink
work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
victorlei committed Jul 31, 2013
1 parent 2c9471d commit de9dfc9
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 100 deletions.
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'},
Expand Down
54 changes: 30 additions & 24 deletions smop/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions smop/fastsolver.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
23 changes: 10 additions & 13 deletions smop/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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"
Expand All @@ -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:
Expand All @@ -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:
Expand Down
5 changes: 2 additions & 3 deletions smop/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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."""
Expand Down Expand Up @@ -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
Expand Down
5 changes: 1 addition & 4 deletions smop/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -29,6 +29,3 @@

line_numbering=True #True # uses either # or ! or %

""" Map func name (str) to node.function instance
"""
functab = {}
39 changes: 10 additions & 29 deletions smop/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
"""
Expand Down
4 changes: 2 additions & 2 deletions smop/resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
42 changes: 21 additions & 21 deletions smop/typeof.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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):
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down

0 comments on commit de9dfc9

Please sign in to comment.