Skip to content

Commit

Permalink
version 0.25
Browse files Browse the repository at this point in the history
  • Loading branch information
victorlei committed Jul 1, 2014
1 parent 44086d2 commit 497846e
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 63 deletions.
30 changes: 14 additions & 16 deletions smop/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ def _backend(self,level=0):
# size([])
# 0 0
if not self.args:
return "np.array([])"
return "matlabarray()"
elif any(a.__class__ is node.string for a in self.args):
return " + ".join(a._backend() for a in self.args)
else:
return "np.array([%s])" % self.args._backend()
return "matlabarray([%s])" % self.args._backend()

@extend(node.cellarrayref)
@exceptions
Expand Down Expand Up @@ -163,11 +163,7 @@ def _backend(self,level=0):
self.args[2]._backend(),
self.args[1]._backend())
if self.op == ":":
#return "arange(%s)" % self.args._backend()
if not self.args:
return ":"
else:
return "%s:%s" % (self.args[0],self.args[1])
return "range_(%s)" % self.args._backend()

if self.op == "end":
if self.args:
Expand All @@ -193,6 +189,7 @@ def _backend(self,level=0):
return "%s %s %s" % (self.args[0]._backend(),
optable.get(self.op,self.op),
self.args[1]._backend())
import pdb;pdb.set_trace()
ret = "%s=" % self.ret._backend() if self.ret else ""
return ret+"%s(%s)" % (self.op,
",".join([t._backend() for t in self.args]))
Expand Down Expand Up @@ -227,17 +224,19 @@ def _backend(self,level=0):
@extend(node.let)
@exceptions
def _backend(self,level=0):
if options.line_numbering:
s = "# %d\n" % self.lineno + level*indent
else:
s = ''
# if options.line_numbering:
# s = "# %d\n" % self.lineno + level*indent
# else:
# s = ''
if self.args.__class__ is node.funcall:
self.args.nargout = self.nargout
s += "%s=%s" % (self.ret._backend(),
self.args._backend())
if (self.ret.__class__ is node.ident and
self.args.__class__ is node.ident):
s += ".copy()"
s = "%s=%s.copy()" % (self.ret._backend(),
self.args._backend())
else:
s = "%s=%s" % (self.ret._backend(),
self.args._backend())
return s

@extend(node.expr_list)
Expand Down Expand Up @@ -304,8 +303,7 @@ def _backend(self,level=0):
@extend(node.ident)
@exceptions
def _backend(self,level=0):
#return self.name if self.name not in reserved else self.name+"_"
return self.name
return self.name if self.name not in reserved else "_"+self.name

@extend(node.stmt_list)
@exceptions
Expand Down
16 changes: 11 additions & 5 deletions smop/lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ def new():
t_LT = r"\<"
t_MINUS = r"\-"
t_MUL = r"\*"
t_NE = r"~="
t_NEG = r"\~"
t_NE = r"(~=)|(!=)"
t_NEG = r"\~|!"
t_OR = r"\|"
t_OROR = r"\|\|"
t_PLUS = r"\+"
Expand Down Expand Up @@ -93,8 +93,11 @@ def t_TRANSPOSE(t):
return t

def t_STRING(t):
r"'([^']|(''))*'"
t.value = t.value[1:-1].replace("''","'")
"""('([^']|(''))*')|("([^"]|(""))*")"""
if t.value[0] == "'":
t.value = t.value[1:-1].replace("''","'")
else:
t.value = t.value[1:-1].replace('""','"')
return t

def t_IDENT(t):
Expand All @@ -105,6 +108,9 @@ def t_IDENT(t):
# So return=1 is illegal, but foo.return=1 is fine.
t.type = "FIELD"
return t
if t.value in ("endfunction","endif","endfor"): # octave
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"
Expand Down Expand Up @@ -198,7 +204,7 @@ def t_NEWLINE(t):
return t

def t_comment(t):
r"%.*"
r"(%|\#).*"
pass


Expand Down
4 changes: 2 additions & 2 deletions smop/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,10 +340,10 @@ def __str__(self):
#"sort",
#"strcmp",
#"strcmpi",
"sub", # synthetic opcode
"sub", # synthetic opcode for subtract
#"sum",
"transpose",
"true",
#"true",
#"zeros",
]

Expand Down
10 changes: 9 additions & 1 deletion smop/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,14 @@ def p_let(p):
"""
assert (isinstance(p[1],(node.ident,node.funcall,node.cellarrayref)) or
(isinstance(p[1],node.expr) and p[1].op in (("{}","DOT","."))))
try:
# a(:) = ...
# ravel(a) = ...
# a[:] =
if p[1].func_expr.name == "ravel":
p[1] = node.arrayref(p[1].args[0],node.expr(":",node.expr_list()))
except:
pass
if isinstance(p[1],node.getfield):
p[0] = node.setfield(p[1].args[0],
p[1].args[1],
Expand Down Expand Up @@ -569,7 +577,7 @@ def p_funcall_expr(p):
len(p[3])==1 and
p[3][0].__class__ is node.expr and
p[3][0].op == ":" and not p[3][0].args):
# foo(:)
# foo(:) => ravel(foo)
p[0] = node.funcall(func_expr=node.ident("ravel"),
args=node.expr_list([p[1]]))
else:
Expand Down
75 changes: 36 additions & 39 deletions smop/resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ def do_resolve(t,symtab):
# 2. Iterate over ident nodes. Referenced, but undefined nodes
# become funcall nodes.
# 3. Function declaration require special handling

# 1. pass I
for u in node.postorder(t):
if (u.__class__ is node.funcall and
u.func_expr.__class__ is node.expr and u.func_expr.op == "."):
Expand All @@ -88,55 +90,50 @@ def do_resolve(t,symtab):
else:
u.func_expr.name += "_"

# 2. pass II
for u in node.postorder(t.body):
if (u.__class__ is node.ident and u.name[0] != "." and u.defs == set() and u.name[-1] != "_"):
u.become(node.funcall(func_expr=node.ident(u.name+"_"),
args=node.expr_list()))

# 3. special handling for func decl
try:
t.head.ident.name += "_"
except:
pass

for u in node.postorder(t):
if u.__class__ in (node.arrayref,node.cellarrayref):
for i in range(len(u.args)):
cls = u.args[i].__class__
if cls is node.number:
u.args[i].value -= 1
elif cls is node.expr and u.args[i].op in ("==","!=","~=","<","=<",">",">="):
pass
elif cls is node.expr and u.args[i].op == ":":
# Colon expression as a subscript becomes a
# slice. Everywhere else it becomes a call to
# the "range" function (done in a separate pass,
# see below).
u.args[i].op = "::" # slice marked with op=::
if u.args[i].args:
u.args[i].args[0] = node.sub(u.args[i].args[0],
node.number(1))
# for s in node.postorder(u.args[i]):
# if s.__class__==node.expr and s.op=="end" and not s.args:
# s.args = node.expr_list([u.func_expr,node.number(i)])
# Done. Referenced, but undefined name references
# converted to funcall objects. For example,
# rand+1 converted to rand()+1

if 1:
for u in node.postorder(t):
if u.__class__ in (node.arrayref,node.cellarrayref):
for i in range(len(u.args)):
cls = u.args[i].__class__
if cls is node.expr and u.args[i].op == ":":
# Colon expression as a subscript becomes a
# slice. Everywhere else it becomes a call to
# the "range" function (done in a separate pass,
# see below).
u.args[i].op = "::" # slice marked with op=::
for s in node.postorder(u.args[i]):
if s.__class__==node.expr and s.op=="end" and not s.args:
s.args = node.expr_list([u.func_expr,node.number(i)])

if 1:
# These range nodes are appended after appending _ to funcall
# objects. HACK use range_
for u in node.postorder(t):
if u.__class__ == node.expr and u.op == ":" and u.args:
if len(u.args) == 2:
w = node.funcall(node.ident("range_"),
node.expr_list([u.args[0],
u.args[1]]))
else:
u.args[i] = node.sub(u.args[i],node.number(1))

for u in node.postorder(t):
### if u.__class__ == node.ident and u.defs == set():
### cls = getattr(node,u.name,None)
### if cls and issubclass(cls,node.builtins):
### u.become(cls())
if u.__class__ == node.expr and u.op == ":" and u.args:
if len(u.args) == 2:
w = node.funcall(node.ident("range"),
node.expr_list([u.args[0],
node.add(u.args[1],node.number(1))]))
u.become(w)
### else:
### u.become(node.range_(u.args[0],
### node.add(u.args[1],node.number(1)),
### u.args[2]))

w = node.funcall(node.ident("range_"),
node.expr_list([u.args[0],
u.args[1],
u.args[2]]))
#def _fix(tree):
# for s in node.postorder(tree):
# try:
Expand Down

0 comments on commit 497846e

Please sign in to comment.