diff --git a/smop/backend.py b/smop/backend.py index c2517d07..88f04183 100644 --- a/smop/backend.py +++ b/smop/backend.py @@ -56,7 +56,7 @@ def del elif else except Data Float Int Numeric Oxphys array close float int input - open range type write zeros + open range type write len """.split()) @@ -215,19 +215,17 @@ def _backend(self,level=0): @extend(node.func_stmt) def _backend(self,level=0): - if (self.args and - isinstance(self.args[-1],node.ident) and - self.args[-1].name == "varargin"): - self.args[-1].name = "*varargin" + 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"] """ % (self.ident._backend(), self.args._backend()) - return s @extend(node.funcall) @@ -367,10 +365,12 @@ def _backend(self,level=0): @extend(node.string) def _backend(self,level=0): if "\n" in self.value: - fmt = '"""%s"""' - else: - fmt = '"%s"' - return fmt % 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 @extend(node.sub) def _backend(self,level=0): diff --git a/smop/core.py b/smop/core.py index 0d252d76..a229880b 100644 --- a/smop/core.py +++ b/smop/core.py @@ -693,7 +693,7 @@ def true(*args): return matlabarray(np.ones(args,dtype=bool,order="F")) def version(): - return char('0.26') + return char('0.29') def zeros(*args,**kwargs): if not args: @@ -709,7 +709,9 @@ def print_usage(): raise Exception def function(f): - def helper(*args): + def helper(*args,**kwargs): + nargout = kwargs and kwargs["nargout"] + varargin = cellarray(args) nargin=len(args) return f(*args) return helper diff --git a/smop/fastsolver.m b/smop/fastsolver.m index 2116bc88..196b825e 100644 --- a/smop/fastsolver.m +++ b/smop/fastsolver.m @@ -1,4 +1,4 @@ -function moves=solver(A,B,w0) +function moves=fastsolver(A,B,w0) [moves,optmove,optscore]=cbest(A,B,w0); curscore=sum(w0(moves(:,1))); lots=1; diff --git a/smop/lexer.py b/smop/lexer.py index ba543840..890ec3b1 100644 --- a/smop/lexer.py +++ b/smop/lexer.py @@ -9,6 +9,9 @@ import readline import options +class unbalanced_end(Exception): + pass + class IllegalCharacterError(Exception): pass @@ -20,7 +23,8 @@ class IllegalCharacterError(Exception): "MINUS","MINUSMINUS","MINUSEQ","MUL","MULEQ","NE", "NEG", "NUMBER", "OR","OREQ", "OROR", "PLUS", "PLUSEQ","PLUSPLUS", "RBRACE", "RBRACKET", "RPAREN", "SEMI", "STRING", - "TRANSPOSE", "ERROR_STMT", "COMMENT", "END_FUNCTION","POW", ] + "TRANSPOSE", "ERROR_STMT", "COMMENT", "END_FUNCTION", + "END_UNEXPECTED","POW", ] reserved = { "break" : "BREAK", @@ -149,22 +153,28 @@ def t_IDENT(t): # is illegal, but foo.return=1 is fine. t.type = "FIELD" return t - if t.value == "endfunction": - t.type = "END_FUNCTION" + if (t.value == "end" and (t.lexer.parens > 0 or + t.lexer.brackets > 0 or + t.lexer.braces > 0)): + t.type = "END_EXPR" return t - if t.value in ("endwhile", "endif","endfor", - "endswitch","end_try_catch"): - t.type = "END_STMT" - return t - if t.value == "end": - if (t.lexer.parens > 0 or - t.lexer.brackets > 0 or - t.lexer.braces > 0): - t.type = "END_EXPR" + if t.value in ("end","endif","endfunction","endwhile", + "endfor","endswitch","end_try_catch"): + keyword = t.lexer.stack.pop() # if,while,etc. + #assert keyword == t.value or keyword == "try" + if keyword == "function": + t.type = "END_FUNCTION" else: t.type = "END_STMT" + return t else: t.type = reserved.get(t.value,"IDENT") + if t.value in ("if","function","while", + "for","switch","try"): + # lexer stack may contain only these + # six words, ever, because there is + # one place to push -- here + t.lexer.stack.append(t.value) if (t.type != "IDENT" and t.lexer.lexdata[t.lexer.lexpos]=="'"): t.lexer.begin("afterkeyword") @@ -326,9 +336,9 @@ def t_error(t): lexer = lex.lex(reflags=re.MULTILINE) lexer.brackets = 0 # count open square brackets - lexer.parens = 0 # count open parentheses - lexer.braces = 0 # count open curly braces - lexer.stack = [] + lexer.parens = 0 # count open parentheses + lexer.braces = 0 # count open curly braces + lexer.stack = [] return lexer def main(): diff --git a/smop/libscripts/Makefile b/smop/libscripts/Makefile index bb1ffa64..be19d467 100644 --- a/smop/libscripts/Makefile +++ b/smop/libscripts/Makefile @@ -6,20 +6,21 @@ PYFILES= $(sort $(subst .m,.py,$(notdir $(MFILES) ))) MFILES = $(shell find $(SCRIPTS) -name \*.m -type f) CYTHON = cython PYTHON = python -XFILES = +CAT = cat +XFILES = -x white.m,summer.m,spring.m,rainbow.m,prism.m,pink.m,ocean.m,lines.m,jet.m FLAGS = SMOP = $(PYTHON) ../main.py V = 2.7 all: $(PYFILES) - grep __main__ libscripts.py | wc -l + grep Autogen libscripts.py | wc -l clean: rm -f libscripts.py *.pyc *.py %.py: %.m - $(SMOP) $^ $(FLAGS) - ($(PYTHON) $@ && cat $@ >> libscripts.py) + $(SMOP) $^ $(FLAGS) $(XFILES) + ($(PYTHON) $@ && $(CAT) $@ >> libscripts.py) diff --git a/smop/options.py b/smop/options.py index 926f36d9..9da41e86 100644 --- a/smop/options.py +++ b/smop/options.py @@ -87,6 +87,9 @@ parser.add_argument("-R","--no-resolve", action="store_true", help="omit name resolution") +parser.add_argument("-S","--strings", default="C", +help="""C for Octave style, F for Matlab style""") + parser.add_argument("-T","--testing-mode",action="store_true", help= """support special "testing" percent-bang comments used to write Octave test suite. When disabled, behaves like diff --git a/smop/parse.py b/smop/parse.py index 78e19380..fe04fc02 100644 --- a/smop/parse.py +++ b/smop/parse.py @@ -435,7 +435,8 @@ 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 "" +# p[0].init = node.ident(name="None") if p[0].name != "varargin" else "" + pass else: p[0].init = p[3] @@ -831,6 +832,9 @@ def p_error(p): #print "Discarded comment", p.value parser.errok() return + if p.type == "END_UNEXPECTED": + raise syntax_error(p) + raise syntax_error(p) parser = yacc.yacc(start="top")