Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
victorlei committed Jul 27, 2016
1 parent 7ed8bf4 commit d570edf
Show file tree
Hide file tree
Showing 14 changed files with 1,364 additions and 1,099 deletions.
413 changes: 204 additions & 209 deletions smop/backend.py

Large diffs are not rendered by default.

54 changes: 18 additions & 36 deletions smop/callgraph.py
Original file line number Diff line number Diff line change
@@ -1,49 +1,31 @@
import parse,sys
import parse,sys,os
import networkx as nx
import node,resolve
import node,resolve,options

def callgraph(func_list):
def callgraph(G, stmt_list):
"""
Build callgraph of func_list, ignoring
built-in functions
"""
G = nx.DiGraph()
for func in func_list:
G.add_node(func.head.ident.name)
func_list = []
for stmt in stmt_list:
try:
G.add_node(stmt.head.ident.name)
func_list.append(stmt)
except:
pass
for func in func_list:
assert isinstance(func,node.function)
func_name = func.head.ident.name
resolve.resolve(func)
#resolve.resolve(func)
for s in node.postorder(func):
if (s.__class__ is node.funcall and
s.func_expr.__class__ is node.ident and
s.func_expr.name in G.nodes()):
G.add_edge(func_name,s.func_expr.name)
return G

G = nx.DiGraph()

def postorder_edge(u):
if isinstance(u,node.node):
for v in u:
for t in postorder_edge(v):
yield (v,t)
yield (u,u) # returns only traversible objects

def foo(tree):
G = nx.DiGraph()
for u,v in postorder_edge(tree):
G.add_edge(id(u),id(v))
return G

def main():
func_list = parse.parse(open(sys.argv[1]).read())
G = foo(func_list)
#G = callgraph(func_list)
nx.write_dot(G,"G.dot")
#H = nx.dfs_tree(G,'solver')
#nx.write_dot(H,"H.dot")
#print nx.topological_sort(H)

s.func_expr.__class__ is node.ident):
#if s.func_expr.name in G.nodes():
G.add_edge(func_name,s.func_expr.name)
#nx.write_dot(G,"G.dot")
#for u in G.nodes():
# if G.out_degree(u) == 0:
# print u
if __name__ == '__main__':
main()
51 changes: 35 additions & 16 deletions smop/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import __builtin__

import numpy
from sparsearray import sparsearray as sparse
from numpy import sqrt,eye
from numpy import sqrt
from numpy.fft import fft2
from numpy.linalg import inv
from numpy.linalg import qr as _qr
Expand Down Expand Up @@ -54,6 +53,10 @@ class matlabarray(np.ndarray):
"""
>>> matlabarray()
matlabarray([], shape=(0, 0), dtype=float64)
>>> matlabarray([arange(1,5), arange(1,5)])
matlabarray([1, 2, 3, 4, 5, 1, 2, 3, 4, 5])
>>> matlabarray(["hello","world"])
matlabarray("helloworld")
"""

def __new__(cls,a=[],dtype=None):
Expand Down Expand Up @@ -303,14 +306,16 @@ class char is a rectangular string matrix, which
>>> print s
hello
world
>>> s.shape
(2, 5)
>>> s=char([104, 101, 108, 108, 111, 119, 111, 114, 108, 100])
>>> s.shape = 2,5
>>> print s
hello
world
"""

def __new__(cls, a=""):
if not isinstance(a,str):
raise NotImplementedError
a = "".join([chr(c) for c in a])
obj = np.array(list(a),
dtype='|S1',
copy=False,
Expand All @@ -332,7 +337,7 @@ def __str__(self):
return "\n".join("".join(s) for s in self)
raise NotImplementedError

class struct_(object):
class struct(object):
def __init__(self,*args):
for i in range(0,len(args),2):
setattr(self,str(args[i]),args[i+1])
Expand All @@ -356,7 +361,7 @@ def arange(start,stop,step=1,**kwargs):
step,
**kwargs).reshape(1,-1),**kwargs)
def cat(*args):
return np.concatenate([matlabarray(a) for a in args],axis=1)
return matlabarray(np.concatenate([matlabarray(a) for a in args],axis=1)).reshape(-1)

def ceil(a):
return numpy.ceil(a)
Expand Down Expand Up @@ -557,16 +562,27 @@ def rand(*args,**kwargs):
except:
pass

def rand(*args,**kwargs):
if not args:
return np.random.rand()
if len(args) == 1:
args += args
try:
return np.random.rand(np.prod(args)).reshape(args,order="F")
except:
def assert_(a,b=None):
if b is None:
assert a
else:
assert isequal(a,b)

def shared(a):
pass

def rand(*args,**kwargs):
"""from core aka libsmop.py"""
return np.random.rand()
# if not args:
# return np.random.rand()
# if len(args) == 1:
# args += args
# try:
# return np.random.rand(np.prod(args)).reshape(args,order="F")
# except:
# pass

def randn(*args,**kwargs):
if not args:
return np.random.randn()
Expand Down Expand Up @@ -665,6 +681,9 @@ def zeros(*args,**kwargs):
args += args
return matlabarray(np.zeros(args,**kwargs))

def isa(a,b):
return True

if __name__ == "__main__":
import doctest
doctest.testmod()
Expand Down
120 changes: 73 additions & 47 deletions smop/lexer.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
# SMOP compiler -- Simple Matlab/Octave to Python compiler
# Copyright 2011-2014 Victor Leikehman
# SMOP -- Simple Matlab/Octave to Python compiler
# Copyright 2011-2016 Victor Leikehman

import sys
import re
from zlib import adler32
import lex
from lex import TOKEN
import ply.lex as lex
from ply.lex import TOKEN
import readline
import options

class IllegalCharacterError(Exception):
pass

tokens = [
"AND", "ANDAND", "ANDEQ", "BACKSLASH", "COLON", "COMMA", "DIV","DIVEQ",
"DOT", "DOTDIV", "DOTDIVEQ", "DOTEXP", "DOTMUL","DOTMULEQ", "END_EXPR",
"END_STMT", "EQ", "EQEQ", "EXP", "EXPEQ", "FIELD", "GE", "GT", "HANDLE",
"IDENT", "LBRACE", "LBRACKET", "LE", "LPAREN", "LT",
"MINUS","MINUSMINUS","MINUSEQ","MUL","MULEQ","NE", "NEG",
"NUMBER", "OR","OREQ", "OROR", "PLUS", "PLUSEQ","PLUSPLUS",
"RBRACE", "RBRACKET", "RPAREN", "SEMI", "STRING", "TRANSPOSE",
]
tokens = [ "AND", "ANDAND", "ANDEQ", "BACKSLASH", "COLON", "COMMA",
"DIV","DIVEQ", "DOT", "DOTDIV", "DOTDIVEQ", "DOTEXP",
"DOTMUL","DOTMULEQ", "END_EXPR", "END_STMT", "EQ", "EQEQ",
"EXP", "EXPEQ", "FIELD", "GE", "GT", "HANDLE", "IDENT",
"LBRACE", "LBRACKET", "LE", "LPAREN", "LT",
"MINUS","MINUSMINUS","MINUSEQ","MUL","MULEQ","NE", "NEG",
"NUMBER", "OR","OREQ", "OROR", "PLUS", "PLUSEQ","PLUSPLUS",
"RBRACE", "RBRACKET", "RPAREN", "SEMI", "STRING",
"TRANSPOSE", "ERROR_STMT", "COMMENT" ]

reserved = {
"break" : "BREAK",
Expand Down Expand Up @@ -85,7 +86,8 @@ def new():
states = (("matrix","inclusive"),
("afterkeyword","exclusive"))

ws = r"(\s|(\#|%).*\n|\.\.\..*\n|\\\n)"
ws = r"(\s|\.\.\..*\n|\\\n)"
#ws = r"(\s|(\#|(%[^!])).*\n|\.\.\..*\n|\\\n)"
ws1 = ws+"+"
ws0 = ws+"*"
ms = r"'([^']|(''))*'"
Expand All @@ -94,11 +96,13 @@ def new():
id = r"[a-zA-Z_][a-zA-Z_0-9]*"

def unescape(s):
"""
ffd52d5fc5
"""
if s[0] == "'":
return s[1:-1].replace("''","'")
return s[1:-1].replace("''","'").decode("string_escape")
else:
return s[1:-1].replace('""','"')
#return s[1:-1].decode('string_escape').replace('""','"')
return s[1:-1].replace('""','"').decode("string_escape")

@TOKEN(mos)
def t_afterkeyword_STRING(t):
Expand Down Expand Up @@ -133,26 +137,30 @@ def t_STRING(t):
def t_IDENT(t):
t.lexer.lineno += t.value.count("\n")
if t.value[0] == ".":
# Reserved words are not reserved when used as fields.
# So return=1 is illegal, but foo.return=1 is fine.
# Reserved words are not reserved
# when used as fields. So return=1
# is illegal, but foo.return=1 is fine.
t.type = "FIELD"
return t
if t.value in ("endwhile","endfunction","endif","endfor",
"endswitch","end_try_catch"): # octave
if t.value in ("endwhile","endfunction",
"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:
if (t.lexer.parens > 0 or
t.lexer.brackets > 0 or
t.lexer.braces > 0):
t.type = "END_EXPR"
else:
t.type = "END_STMT"
else:
t.type = reserved.get(t.value,"IDENT")
if t.type != "IDENT" and t.lexer.lexdata[t.lexer.lexpos]=="'":
if (t.type != "IDENT" and
t.lexer.lexdata[t.lexer.lexpos]=="'"):
t.lexer.begin("afterkeyword")
return t


def t_LPAREN(t):
r"\("
t.lexer.parens += 1
Expand Down Expand Up @@ -215,6 +223,8 @@ def t_SEMI(t):

def t_NUMBER(t):
r"(0x[0-9A-Fa-f]+)|((\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?[ij]?)"
# <-------------> <------------------><------------->
# int,oct,hex float exp
if t.value[-1] == 'i':
t.value = t.value[:-1]+'j'
t.value = eval(t.value)
Expand All @@ -228,18 +238,25 @@ def t_NEWLINE(t):
t.type = "SEMI"
return t

def t_comment(t):
r"(%|\#).*"
pass
def t_ERROR_STMT(t):
r"%!(error|warning|test|demo).*"
return t

# keep multiline comments
def t_COMMENT(t):
r"(^[ \t]*[%#].*\n)+"
t.lexer.lineno += t.value.count("\n")
if not options.keep_comments:
return
t.type = "COMMENT"
return t

# drop end-of-line comments
def t_comment(t):
r"(%|\#)!?"
if not options.testing_mode or t.value[-1] != "!":
t.lexer.lexpos = t.lexer.lexdata.find("\n",t.lexer.lexpos)

# @TOKEN(ws+r"(?=[-+]\S)")
# def t_matrix_WHITESPACE(t):
# #r"\s+(?=[-+]\S)"
# # Whitespace, followed by + or - followed by anything but whitespace
# t.lexer.lineno += t.value.count("\n")
# t.type = "COMMA"
# return t

@TOKEN(r"(?<=\w)" + ws1 + r"(?=\()")
def t_matrix_BAR(t):
Expand Down Expand Up @@ -298,24 +315,33 @@ def t_error(t):
column=t.lexer.lexpos - t.lexer.lexdata.rfind("\n",0,t.lexer.lexpos)
raise IllegalCharacterError(t.lineno,column,t.value[0])

lexer = lex.lex(reflags=re.I)

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 = []
return lexer

if __name__ == "__main__":
def main():
lexer = new()
try:
while 1:
line = raw_input("=>> ")
if not line:
continue
while line[-1] == "\\":
line = line[:-1] + raw_input("... ")
line = ""
while 1:
try:
line += raw_input("=>> ").decode("string_escape")
print len(line), [c for c in line]
except EOFError:
reload(sys.modules["lexer.py"])
lexer.input(line)
for tok in lexer:
print len(str(tok.value)), tok
except EOFError:
pass
print list(tok for tok in lexer)
line = ""

if __name__ == "__main__":
options.testing_mode = 0
options.debug_lexer = 0
lexer = new()
buf = open(sys.argv[1]).read()
lexer.input(buf)
for tok in lexer:
print tok

Loading

0 comments on commit d570edf

Please sign in to comment.