From 6b9cfe247055160ac50aa9fca65a8d32667b1780 Mon Sep 17 00:00:00 2001 From: Victor Lei Date: Fri, 11 Nov 2016 06:41:33 +0200 Subject: [PATCH] WIP --- INSTALL | 17 +++++++++++ smop/backend.py | 20 +++++------- smop/core.py | 7 ++--- smop/lexer.py | 17 +++-------- smop/libscripts/Makefile | 7 +++-- smop/main.py | 30 ++++++++++-------- smop/parse.py | 5 ++- smop/resolve.py | 66 ++++++++++++++++++++++------------------ 8 files changed, 90 insertions(+), 79 deletions(-) diff --git a/INSTALL b/INSTALL index 0b06b26f..d531e875 100644 --- a/INSTALL +++ b/INSTALL @@ -1,5 +1,22 @@ smop -- matlab to python compiler +Installation with pip +===================== + +Install pip + + sudo apt-get install python-pip + +Install smop + + pip install smop --user + +or + + sudo pip install smop + +Done. + Installation with easy_install ============================== diff --git a/smop/backend.py b/smop/backend.py index 88f04183..513684c7 100644 --- a/smop/backend.py +++ b/smop/backend.py @@ -52,7 +52,7 @@ def del elif else except exec finally for from global if import in is lambda not or pass print raise - return try while + return try while with Data Float Int Numeric Oxphys array close float int input @@ -217,15 +217,15 @@ def _backend(self,level=0): def _backend(self,level=0): self.args.append(node.ident("*args")) self.args.append(node.ident("**kwargs")) - s = """ @function def %s(%s): - nargin = sys._getframe(1).f_locals["nargin"] - varargin = sys._getframe(1).f_locals["varargin"] - nargout = sys._getframe(1).f_locals["nargout"] + varargin = %s.varargin + nargin = %s.nargin """ % (self.ident._backend(), - self.args._backend()) + self.args._backend(), + self.ident._backend(), + self.ident._backend()) return s @extend(node.funcall) @@ -364,13 +364,7 @@ def _backend(self,level=0): @extend(node.string) def _backend(self,level=0): - if "\n" in self.value: - return '"""%s"""' % self.value - if options.strings == "C": - return 'r"%s"' % self.value.replace('"',r'\"') - if options.strings == "F": - return "r'%s'" % self.value.replace("'",r"''") - assert 0 + return "'%s'" % str(self.value).encode("string_escape") @extend(node.sub) def _backend(self,level=0): diff --git a/smop/core.py b/smop/core.py index 4d694d5c..7da2c9b6 100644 --- a/smop/core.py +++ b/smop/core.py @@ -711,10 +711,9 @@ def print_usage(): def function(f): def helper(*args,**kwargs): - nargout = kwargs and kwargs["nargout"] - varargin = cellarray(args) - nargin=len(args) - return f(*args) + helper.nargin = len(args) + helper.varargin = cellarray(args) + return f(*args,**kwargs) return helper def error(s): diff --git a/smop/lexer.py b/smop/lexer.py index 890ec3b1..1f49701b 100644 --- a/smop/lexer.py +++ b/smop/lexer.py @@ -101,19 +101,10 @@ def new(): id = r"[a-zA-Z_][a-zA-Z_0-9]*" def unescape(s): - """ - ffd52d5fc5 - """ - try: - if s == r"'\'" or s == r'"\"': - return s[1:-1] - if s[0] == "'": - return s[1:-1].replace("''","'").decode("string_escape") - else: - return s[1:-1].replace('""','"').decode("string_escape") - except ValueError: - print s - raise + if s[0] == "'": + return s[1:-1].replace("''","'") + else: + return s[1:-1].decode("string_escape") @TOKEN(mos) def t_afterkeyword_STRING(t): diff --git a/smop/libscripts/Makefile b/smop/libscripts/Makefile index be19d467..06b3d56b 100644 --- a/smop/libscripts/Makefile +++ b/smop/libscripts/Makefile @@ -7,20 +7,21 @@ MFILES = $(shell find $(SCRIPTS) -name \*.m -type f) CYTHON = cython PYTHON = python CAT = cat -XFILES = -x white.m,summer.m,spring.m,rainbow.m,prism.m,pink.m,ocean.m,lines.m,jet.m +XFILES = -x white.m,summer.m,spring.m,rainbow.m,prism.m,pink.m,ocean.m,lines.m,jet.m,__gnuplot_open_stream__.m FLAGS = SMOP = $(PYTHON) ../main.py V = 2.7 all: $(PYFILES) - grep Autogen libscripts.py | wc -l + $(CAT) *.py > libscripts.py clean: rm -f libscripts.py *.pyc *.py %.py: %.m $(SMOP) $^ $(FLAGS) $(XFILES) - ($(PYTHON) $@ && $(CAT) $@ >> libscripts.py) + $(PYTHON) $@ +.DELETE_ON_ERROR: diff --git a/smop/main.py b/smop/main.py index 6f328d5e..449caf8a 100644 --- a/smop/main.py +++ b/smop/main.py @@ -2,7 +2,7 @@ # Copyright 2011-2016 Victor Leikehman from os.path import splitext,basename import version -import sys,cPickle,glob,os,tarfile +import sys,cPickle,os #,tarfile import getopt,re import lexer import parse @@ -13,7 +13,11 @@ import callgraph import networkx as nx import pickle -import readline +try: + import readline +except: + import readline as pyreadline + import graphviz def main(): @@ -21,10 +25,10 @@ def main(): if not options.filelist: options.parser.print_help() return - if (len(options.filelist) == 1 and - options.filelist[0].endswith(".tar")): - tar = tarfile.open(options.filelist[0]) - options.filelist = tar.getnames() + #if (len(options.filelist) == 1 and + # options.filelist[0].endswith(".tar")): + # tar = tarfile.open(options.filelist[0]) + # options.filelist = tar.getnames() if options.output == "-": fp = sys.stdout elif options.output: @@ -41,7 +45,7 @@ def main(): if options.link: print >> fp, "from %s import *" % options.link print >> fp, "#", options.filename - + for i, options.filename in enumerate(options.filelist): try: if not options.filename.endswith((".m")): @@ -52,15 +56,15 @@ def main(): print "\tExcluded: '%s'" % options.filename continue if options.verbose: - print options.filename - if tar: - buf = tar.extractfile(options.filename).read() - else: - buf = open(options.filename).read() + print i, options.filename + #if tar: + # buf = tar.extractfile(options.filename).read() + #else: + buf = open(options.filename).read() buf = buf.replace("\r\n","\n") buf = buf.decode("ascii",errors="ignore") stmt_list=parse.parse(buf if buf[-1]=='\n' else buf+'\n') - #assert None not in stmt_list + #assert None not in stmt_list if not stmt_list: return if not options.no_resolve: diff --git a/smop/parse.py b/smop/parse.py index fe04fc02..9c3cac60 100644 --- a/smop/parse.py +++ b/smop/parse.py @@ -40,7 +40,7 @@ class syntax_error(error): pass precedence = ( - ("left", "COMMA"), + ("right", "COMMA"), ("right","DOTDIVEQ","DOTMULEQ","EQ","EXPEQ", "MULEQ","MINUSEQ","DIVEQ","PLUSEQ","OREQ","ANDEQ"), ("nonassoc","HANDLE"), @@ -435,8 +435,7 @@ def p_ident_init_opt(p): else: p[0] = p[1] if len(p) == 2: -# p[0].init = node.ident(name="None") if p[0].name != "varargin" else "" - pass + p[0].init = node.ident(name="None") else: p[0].init = p[3] diff --git a/smop/resolve.py b/smop/resolve.py index dc025c0f..fcf77c8e 100644 --- a/smop/resolve.py +++ b/smop/resolve.py @@ -1,15 +1,15 @@ # smop -- Matlab to Python compiler # Copyright 2011-2013 Victor Leikehman """ -if i.defs: - i is defined, possibly more than once. +if i.defs: + i is defined, possibly more than once. Typical for vairable references. if i.defs is None: i is a definition (lhs) - + if i.defs == set(): - i is used but not defined. + i is used but not defined. Typical for function calls. symtab is a temporary variable, which maps @@ -18,46 +18,49 @@ It is used in if_stmt, for_stmt, and while_stmt. """ -import copy,sys,pprint +import copy import node from node import extend -import backend,options import networkx as nx -def graphviz(t,fp,func_name): + +def graphviz(t, fp, func_name): fp.write("digraph %s {\n" % func_name) fp.write('graph [rankdir="LR"];\n') for u in node.postorder(t): - if u.__class__ in (node.ident,node.param): - fp.write("%s [label=%s_%s_%s];\n" % (u.lexpos,u.name,u.lineno,u.column)) + if u.__class__ in (node.ident, node.param): + fp.write("%s [label=%s_%s_%s];\n" % + (u.lexpos, u.name, u.lineno, u.column)) if u.defs: for v in u.defs: - fp.write("%s -> %s" % (u.lexpos,v.lexpos)) + fp.write("%s -> %s" % (u.lexpos, v.lexpos)) if u.lexpos < v.lexpos: fp.write('[color=red]') - #else: + # else: # fp.write('[label=%s.%s]' % (v.lineno,v.column)) fp.write(';\n') fp.write("}\n") + def as_networkx(t): G = nx.DiGraph() for u in node.postorder(t): - if u.__class__ in (node.ident,node.param): - uu = "%s_%s_%s" % (u.name,u.lineno,u.column) - #label = "%s\\n%s" % (uu, u.props if u.props else "") - G.add_node(uu, ident=u) # label=label) + if u.__class__ in (node.ident, node.param): + uu = "%s_%s_%s" % (u.name, u.lineno, u.column) + # label = "%s\\n%s" % (uu, u.props if u.props else "") + G.add_node(uu, ident=u) if u.defs: for v in u.defs: - vv = "%s_%s_%s" % (v.name,v.lineno,v.column) + vv = "%s_%s_%s" % (v.name, v.lineno, v.column) G.add_node(vv, ident=v) if u.lexpos < v.lexpos: - G.add_edge(uu,vv,color="red") + G.add_edge(uu, vv, color="red") else: - G.add_edge(uu,vv,color="black") + G.add_edge(uu, vv, color="black") return G + def resolve(t, symtab=None, fp=None, func_name=None): if symtab is None: symtab = {} @@ -123,6 +126,7 @@ def resolve(t, symtab=None, fp=None, func_name=None): #print S.edges() return G + def do_resolve(t,symtab): t._resolve(symtab) @@ -135,7 +139,7 @@ def copy_symtab(symtab): @extend(node.arrayref) @extend(node.cellarrayref) -@extend(node.funcall) +@extend(node.funcall) def _lhs_resolve(self,symtab): # Definitely lhs array indexing. It's both a ref and a def. # Must properly handle cases such as foo(foo(17))=42 @@ -143,6 +147,8 @@ def _lhs_resolve(self,symtab): self.func_expr._resolve(symtab) # A self.args._resolve(symtab) # B self.func_expr._lhs_resolve(symtab) + + @extend(node.expr) def _lhs_resolve(self,symtab): @@ -219,7 +225,7 @@ def _resolve(self,symtab): @extend(node.null_stmt) @extend(node.continue_stmt) -@extend(node.break_stmt) +@extend(node.break_stmt) def _resolve(self,symtab): pass @@ -227,13 +233,13 @@ def _resolve(self,symtab): def _resolve(self,symtab): self.func_expr._resolve(symtab) self.args._resolve(symtab) - self.args[0]._lhs_resolve(symtab) + self.args[0]._lhs_resolve(symtab) @extend(node.try_catch) def _resolve(self,symtab): self.try_stmt._resolve(symtab) self.catch_stmt._resolve(symtab) # ??? - + @extend(node.ident) def _resolve(self,symtab): if self.defs is None: @@ -243,7 +249,7 @@ def _resolve(self,symtab): except KeyError: # defs == set() means name used, but not defined pass - + @extend(node.arrayref) @extend(node.cellarrayref) @extend(node.funcall) @@ -255,12 +261,12 @@ def _resolve(self,symtab): self.args._resolve(symtab) #if self.ret: # self.ret._lhs_resolve(symtab) - + @extend(node.expr) def _resolve(self,symtab): for expr in self.args: expr._resolve(symtab) - + @extend(node.number) @extend(node.string) @extend(node.comment_stmt) @@ -271,21 +277,21 @@ def _resolve(self,symtab): # def _resolve(self,symtab): # # TODO: does the order of A and B matter? Only if the # # evaluation of function args may change the value of the -# # func_expr. +# # func_expr. # self.func_expr._resolve(symtab) # A # self.args._resolve(symtab) # B # self.ret._lhs_resolve(symtab) - + @extend(node.return_stmt) def _resolve(self,symtab): self.ret._resolve(symtab) #symtab.clear() - + @extend(node.stmt_list) def _resolve(self,symtab): for stmt in self: stmt._resolve(symtab) - + @extend(node.where_stmt) # FIXME where_stmt ??? @extend(node.while_stmt) def _resolve(self,symtab): @@ -302,4 +308,4 @@ def _resolve(self,symtab): self.head._resolve(symtab) self.body._resolve(symtab) self.head.ret._resolve(symtab) - +