[Mumps2Py:] [120] code clean-up; in preparation for handling indirection.

[ Thread Index | Date Index | More lists.mumps2py.org/discuss Archives ]


Revision: 120
Author:   pgallot
Date:     2008-02-21 22:02:15 +0000 (Thu, 21 Feb 2008)

Log Message:
-----------
code clean-up; in preparation for handling indirection.

Modified Paths:
--------------
    trunk/mumps2py/mumps2tok.py
    trunk/mumps2py/mumps_module.py
    trunk/mumps2py/tok2python.py
    trunk/mumps2py/tokprepass.py


Modified: trunk/mumps2py/mumps2tok.py
===================================================================
--- trunk/mumps2py/mumps2tok.py	2008-02-18 20:55:55 UTC (rev 119)
+++ trunk/mumps2py/mumps2tok.py	2008-02-21 22:02:15 UTC (rev 120)
@@ -21,9 +21,8 @@
 
 class ParseError(Exception):
     """ Exception class for errors relating to parsing Mumps code."""
-    def __init__(self, the_module, line, dscr = "", pos = 0, lineno = -1):
+    def __init__(self, line, dscr = "", pos = 0, lineno = -1):
         Exception.__init__(self)
-        self.module = the_module
         self.line = line
         self.lineno = lineno
         self.pos = pos
@@ -33,13 +32,12 @@
     def error_msg(self):
         """ returns a formated string containing information about the error"""
         if self.pos:
-            errormsg = "\nError: %s %d:%d : %s\n\t%s\n[%s]" \
-                      % (self.module.mod_name, self.lineno, self.pos,
-                         self.dscr, self.line, self.line[self.pos:])
+            errormsg = "\nError: %d:%d : %s\n\t%s\n[%s]" % \
+                       (self.lineno, self.pos, self.dscr, self.line,
+                        self.line[self.pos:])
         else:
-            errormsg = "\nError: %s %d: %s\n\t%s" \
-                      % (self.module.mod_name, self.lineno, self.dscr,
-                         self.line)
+            errormsg = "\nError: %d: %s\n\t%s" % \
+                       (self.lineno, self.dscr, self.line)
         return errormsg
 
 MUMPS_RE_DICT = {
@@ -63,7 +61,7 @@
     "cmdEnd":re.compile(r"[ ]|\s*$")
     }
 
-def consume_actuallist(routine, line, pos):
+def consume_actuallist(line, pos):
     """ parses a list of parameters """
     actuallist = []
     while line[pos] != ")":
@@ -71,7 +69,7 @@
         if line[pos] == '.' and not MUMPS_RE_DICT['num'].match(line, pos):
             pass_by_ref = True
             pos = pos + 1            
-        exprtok = parse_expr(routine, line, pos, r"([:,)])")
+        exprtok = parse_expr(line, pos, r"([:,)])")
         if pass_by_ref:
             exprtok.pass_by_ref = True            
         actuallist.append(exprtok)
@@ -79,30 +77,30 @@
         if line[pos] == ":":
             pos = pos + 1
             condtok = exprtok
-            exprtok = parse_expr(routine, line, pos, r"[,)]")
+            exprtok = parse_expr(line, pos, r"[,)]")
             exprtok.post_condition(condtok)
         elif line[pos] == ",":
             pos = pos + 1
     return (pos + 1, actuallist)
 
-def consume_entry_ref(routine, line, pos):
+def parse_entry_ref(line, pos):
     """ parses a Mumps Entry Ref"""
     token = Token(ENTRYREF, pos)
     if line[pos] == '@':
         if MUMPS_RE_DICT["nakedRef"].match(line, pos + 1):
-            indirect = parse_expr(routine, line, pos+1, r"([,+: ]|\s$)")
+            indirect = parse_expr(line, pos+1, r"([,+: ]|\s$)")
             token.indirect = indirect
             pos = indirect.end
         else:
-            indirect = parse_expr(routine, line, pos, r"(\^|[ +),:]|\s*$)")
+            indirect = parse_expr(line, pos, r"(\^|[ +),:]|\s*$)")
             token.indirect = indirect
             pos = indirect.end
         if not MUMPS_RE_DICT["cmdEnd"].match(line, pos) and line[pos] == '+':
-            offset = parse_expr(routine, line, pos + 1, r"(\^|[ ),:]|\s*$)")
+            offset = parse_expr(line, pos + 1, r"(\^|[ ),:]|\s*$)")
             token.offset = offset
             pos = offset.end
         if not MUMPS_RE_DICT["cmdEnd"].match(line, pos) and line[pos] == '^':
-            routine = parse_expr(routine, line, pos + 1, r"([ ,)(:]|\s*$)")
+            routine = parse_expr(line, pos + 1, r"([ ,)(:]|\s*$)")
             token.routine = routine
             pos = routine.end
     else:
@@ -112,47 +110,45 @@
             token.label = m_name.group()
             pos = m_name.end()
         if not MUMPS_RE_DICT["cmdEnd"].match(line, pos) and line[pos] == '+':
-            offset = parse_expr(routine, line, pos + 1, r"(\^|[ ):,]|\s*$)")
+            offset = parse_expr(line, pos + 1, r"(\^|[ ):,]|\s*$)")
             token.offset = offset
             pos = offset.end
         if not MUMPS_RE_DICT["cmdEnd"].match(line, pos) and line[pos] == '^':
             pos = pos + 1
             m_name = re_name.match(line, pos)
             if not m_name:
-                routine = parse_expr(routine, line, pos, r"([ ),(:]|\s*$)")
+                routine = parse_expr(line, pos, r"([ ),(:]|\s*$)")
                 token.routine = routine
                 pos = routine.end
             else:
                 token.routine = m_name.group()
                 pos = m_name.end()
         if not MUMPS_RE_DICT["cmdEnd"].match(line, pos) and line[pos] == '(':
-            pos, token.params = consume_actuallist(routine, line, pos + 1)
+            pos, token.params = consume_actuallist(line, pos + 1)
     
     token.end = pos
     return (token, pos)
 
-def parse_emptyline(routine, line, startpos=0):
+def parse_emptyline(line, startpos = 0):
     """ parses a line of Mumps code which contains practically nothing"""
     token = Token(EMPTYLINE, startpos)
     token.end = len(line)
-    routine.add_token(token)
     return token
 
-def parse_label(routine, line):
+def parse_label(line, startpos = 0):
     """ parses a Mumps label"""
-    token = Token(LABEL, 0)
+    token = Token(LABEL, startpos)
     re_match = re.match(r"[%a-zA-Z0-9]+", line)
     token.val = re_match.group()
     pos = re_match.end()
     
     if not MUMPS_RE_DICT["cmdEnd"].match(line, pos) and line[pos] == '(':
-        pos, token.params = consume_actuallist(routine, line, pos + 1)
+        pos, token.params = consume_actuallist(line, pos + 1)
 
     token.end = pos
-    routine.add_token(token)
     return token
 
-def parse_comment(routine, line, startpos = 0):
+def parse_comment(line, startpos = 0):
     """ parses a Mumps comment"""
     re_match = MUMPS_RE_DICT["comment"].match(line, startpos)
     val = re_match.group("comment")
@@ -165,14 +161,13 @@
         token = Token(COMMENT, startpos)
         token.val = val[1:]
     token.end = len(line)
-    routine.add_token(token)
     return token
 
-def parse_expr(routine, line, startpos, terminator = r"([ ]|\s*$)"):
+def parse_expr(line, startpos, terminator = r"([ ]|\s*$)"):
     """ parses a Mumps expression by recursive descent"""
     #if __debug__: print "parse_expr %d [%s]" % (startpos, line[startpos:])
     
-    def consume_pattern(lineno, line, pos):
+    def consume_pattern(line, pos):
         """ parses a mumps-style pattern-matching pattern"""
         atom_list = []
         m_pat = MUMPS_RE_DICT["patAtom"]
@@ -187,14 +182,14 @@
                 if atom.group("mxrp"):
                     sub_token.maxrep = atom.group("mxrp")
             if atom.group("str"):
-                sub_token.match_str = parse_expr(\
-                    routine, line, atom.start("str"), r'\w|[ .,:)(]|\s*$')
+                sub_token.match_str = parse_expr( line, atom.start("str"),
+                                                  r'\w|[ .,:)(]|\s*$')
                 pos = sub_token.match_str.end
             elif atom.group("altlist"):
                 sub_token.params = []
                 pos = atom.end()
                 while line[pos] != ")":
-                    (sub_pat, pos) = consume_pattern(lineno, line, pos)
+                    (sub_pat, pos) = consume_pattern(line, pos)
                     sub_token.params.append(sub_pat)
                     if line[pos] == ",":
                         pos = pos + 1
@@ -209,7 +204,7 @@
     def consume_sub_expr(mobj):
         """ parses a parens-enclosed sub-expression"""
         token = Token(EXPR, mobj.start())
-        token.expr_list = [ parse_expr(routine, line, mobj.end(), r"([)])"), ]
+        token.expr_list = [ parse_expr(line, mobj.end(), r"([)])"), ]
         pos = token.expr_list[-1].end + 1
         return (token, pos) 
 
@@ -246,18 +241,17 @@
         """ parses a Mumps naked reference"""
         token = Token(OPNAKEDREF, mobj.start())
         pos = mobj.end()
-        pos, token.indices = consume_actuallist(routine, line, pos)
+        pos, token.indices = consume_actuallist(line, pos)
         return (token, pos)
 
     def consume_indirection(mobj):
         """ parses a Mumps indirection argument"""
         token = Token(INDIRECTION, mobj.start())
-        expr = parse_expr(routine, line, mobj.end(), \
-                          r"(\^|\\|[-@:,+=><#&!*/ ')]|\s*$)")
+        expr = parse_expr(line, mobj.end(), r"(\^|\\|[-@:,+=><#&!*/ ')]|\s*$)")
         token.expr = expr
         pos = expr.end
         if line[pos] == '@' and line[pos + 1] == '(':
-            pos, indices = consume_actuallist(routine, line, pos + 2)
+            pos, indices = consume_actuallist(line, pos + 2)
             token.indices = indices               
         return (token, pos)
 
@@ -270,7 +264,7 @@
         token.varname = mobj.group("var")
         pos = mobj.end("var")
         if mobj.group("indexed"):
-            pos, indices = consume_actuallist(routine, line, pos + 1)
+            pos, indices = consume_actuallist(line, pos + 1)
             token.indices = indices
         return (token, pos)
 
@@ -278,7 +272,7 @@
         """ parses a Mumps extrinsic function or variable"""
         pos = mobj.end()
         token = Token(USERFUNC, pos)
-        (entry_ref, end_pos) = consume_entry_ref(routine, line, pos)
+        (entry_ref, end_pos) = parse_entry_ref(line, pos)
         token.entry_ref = entry_ref
         return (token, end_pos)
 
@@ -290,13 +284,13 @@
             toktype = INTRINSIC_FUNCS.get(name, F_UNKNOWN)
             token = Token(toktype, mobj.start())
             if toktype == F_TEXT:
-                (params, end_pos) = consume_entry_ref(routine, line, pos)
+                (params, end_pos) = parse_entry_ref(line, pos)
                 token.params = params
                 pos = end_pos + 1
             else:
                 if toktype == F_UNKNOWN:
                     token.name = name
-                pos, token.params = consume_actuallist(routine, line, pos)
+                pos, token.params = consume_actuallist(line, pos)
         else: # vars...
             toktype = INTRINSIC_VARS.get(name, V_UNKNOWN)
             token = Token(toktype, mobj.start())
@@ -313,7 +307,7 @@
         if toktype == SSV_UNKNOWN:
             token.name = name
         if mobj.group("indexed"):
-            pos, indices = consume_actuallist(routine, line, pos + 1)
+            pos, indices = consume_actuallist(line, pos + 1)
             token.indices = indices
         return (token, pos)
         
@@ -321,8 +315,7 @@
         """ parses mumps-style pattern-matchine patterns"""
         pos = mobj.end()
         token = OpToken(OPPATMATCH, mobj.start())
-        (token.params, pos) = consume_pattern(routine, line, pos)
-        token.end = pos
+        token.params, pos = consume_pattern(line, pos)
         return (token, pos)
 
     pattern_list = [
@@ -349,60 +342,48 @@
             re_match = pattern.match(line, pos)
             if re_match:
                 pattern_match = True
-                (sub_token, end_pos) = consume(re_match)
+                sub_token, end_pos = consume(re_match)
                 pos = sub_token.end = end_pos
                 token.expr_list.append(sub_token)
                 break
 
         if not pattern_match:
-            raise ParseError(routine, line, "No Pattern match", pos )
+            raise ParseError(line, "No Pattern match", pos )
 
     token.end = pos
-    if len(token.expr_list)==2:
-        (left_tok, right_tok) = token.expr_list
+    if len(token.expr_list) == 2:
+        right_tok = token.expr_list.pop()
+        left_tok = token.expr_list.pop()
         if right_tok.is_num() and left_tok.toktype in (OPADD, OPSUB):
             if left_tok.toktype == OPSUB:
                 right_tok.val = "-" + right_tok.val
             token = right_tok
-    elif len(token.expr_list)==1:
+    elif len(token.expr_list) == 1:
         token = token.expr_list[0]
     return token
 
-def parse_command(routine, line, startpos=0):
+def parse_command(line, startpos=0):
     """parses all known Mumps commands"""
 
-    def consume_arg_indirection(routine, line, pos):
-        """ parses an argument indirection expression"""
-        mterminated = MUMPS_RE_DICT["cmdEnd"]
-        if not mterminated.match(line, pos) and line[pos:pos+2] == '@(':
-            indirection = parse_expr(routine, line, pos, r"([ ,:]|\s*$)")
-
-            new_pos = indirection.end
-            if mterminated.match(line, new_pos):
-                routine.last_token().indirection = indirection
-                routine.end_token(new_pos)
-                return True
-        return False
-         
-    def parse_xecute(routine, line, pos):
+    def parse_xecute(parent_tok, line, pos):
         """ parses the Mumps Xecute command"""
         expr_list = []
         mterminated = MUMPS_RE_DICT["cmdEnd"]
         while not mterminated.match(line, pos):
-            exprtok = parse_expr(routine, line, pos, r"([ :,]|\s*$)")
+            exprtok = parse_expr(line, pos, r"([ :,]|\s*$)")
             pos = exprtok.end
             if line[pos] == ":":
-                condtok = parse_expr(routine, line, pos + 1, r"([ ,]|\s*$)")
+                condtok = parse_expr(line, pos + 1, r"([ ,]|\s*$)")
                 exprtok.post_condition(condtok)
                 pos = condtok.end
             if line[pos] == ",":
                 pos = pos + 1
             expr_list.append(exprtok)
             
-        routine.last_token().Xecute = expr_list
-        routine.end_token(pos + 1)
+        parent_tok.Xecute = expr_list
+        parent_tok.end = pos + 1
 
-    def parse_write(routine, line, pos):
+    def parse_write(parent_tok, line, pos):
         """ parses the Mumps Write command"""
         write_list = []
         mterminated = MUMPS_RE_DICT["cmdEnd"]
@@ -415,24 +396,82 @@
                 pos = pos + 1
             elif line[pos] == '?':
                 sub_token = Token(FCC_MOV, pos)
-                sub_token.offset = parse_expr(routine, line, pos+1, \
-                                              r"([, ]|\s*$)")
-                pos = sub_token.offset.end
+                offset = parse_expr(line, pos + 1, r"([, ]|\s*$)")
+                sub_token.offset = offset
+                pos = offset.end
             elif line[pos] == '*':
                 sub_token = Token(FCC_CHARVAL, pos)
-                sub_token.val = parse_expr(routine, line, pos+1, r"([, ]|\s*$)")
-                pos = sub_token.val.end
+                val = sub_token.val = parse_expr(line, pos + 1, r"([, ]|\s*$)")
+                pos = val.end
             else:
-                sub_token = parse_expr(routine, line, pos, r"([, ]|\s*$)")
+                sub_token = parse_expr(line, pos, r"([, ]|\s*$)")
                 pos = sub_token.end
             if line[pos] == ',':
                 pos = pos + 1
             write_list.append(sub_token)
 
-        routine.last_token().write_list = write_list
-        routine.end_token(pos)
+        parent_tok.write_list = write_list
+        parent_tok.end = pos
 
-    def parse_read(routine, line, pos):
+    def parse_view(parent_tok, line, pos):
+        """parses the Mumps View command"""
+        keyword_items = []
+        mterminated = MUMPS_RE_DICT["cmdEnd"]
+        while not mterminated.match(line, pos):
+            item = {}
+            keyword = parse_expr(line, pos, r"([:, ]|\s*$)")
+            item["keyword"] = keyword
+            pos = keyword.end
+            expressions = []
+            while not mterminated.match(line, pos) and line[pos] == ':':
+                pos = pos + 1
+                expr = parse_expr(line, pos, r"([:, ]|\s*$)")
+                pos = expr.end
+                expressions.append(expr)
+            item["expressions"] = expressions
+            if not mterminated.match(line, pos) and line[pos] == ',':
+                pos = pos + 1
+            keyword_items.append(item)
+
+        parent_tok.keyword_items = keyword_items
+        parent_tok.end = pos
+
+    def parse_set(parent_tok, line, pos):
+        """ parses the Mumps Set command"""
+        var_set = []
+        mterminated = MUMPS_RE_DICT["cmdEnd"]
+        while not mterminated.match(line, pos):
+            var = {}
+            if line[pos] == '(':
+                pos = pos + 1
+                var_list = []
+                while line[pos] != ")":
+                    varname = parse_expr(line, pos, r"([,)])")
+                    var_list.append(varname)
+                    pos = varname.end
+                    if line[pos] == ',':
+                        pos = pos + 1
+                var["var_names"] = var_list
+                pos = pos + 1
+            else:
+                varname = parse_expr(line, pos, r"([,= ]|\s*$)")
+                var["varname"] = varname
+                pos = varname.end
+            if not mterminated.match(line, pos) and line[pos] == '=':
+                pos = pos + 1
+                val = parse_expr(line, pos, r"([ ,]|\s*$)")
+                var["val"] = val
+                pos = val.end
+            else: # note: this is somewhat of an assumption, but...
+                var["indirection"] = varname
+                del var["varname"]
+            var_set.append(var)
+            if not mterminated.match(line, pos) and line[pos] == ',':
+                pos = pos + 1
+        parent_tok.var_set = var_set
+        parent_tok.end = pos
+
+    def parse_read(parent_tok, line, pos):
         """ parses the Mumps Read command"""
         read_list = []
         mterminated = MUMPS_RE_DICT["cmdEnd"]
@@ -445,161 +484,91 @@
                 pos = pos + 1
             elif line[pos] == '?':
                 sub_token = Token(FCC_MOV, pos)
-                sub_token.offset = parse_expr(routine, line, pos + 1, \
-                                              r"([, ]|\s*$)")
-                pos = sub_token.offset.end
+                offset = parse_expr(line, pos + 1, r"([, ]|\s*$)")
+                sub_token.offset = offset
+                pos = offset.end
             elif line[pos] == '"': # it's a string.
-                sub_token = parse_expr(routine, line, pos, r"([, ]|\s*$)")
+                sub_token = parse_expr(line, pos, r"([, ]|\s*$)")
                 pos = sub_token.end
             elif line[pos] == '*':
                 sub_token = Token(FCC_CHARVAL, pos)
-                char_val_name = parse_expr(routine, line, pos + 1, \
-                                           r"([:, ]|\s*$)")
+                char_val_name = parse_expr(line, pos + 1, r"([:, ]|\s*$)")
                 sub_token.char_val_name = char_val_name
                 pos = char_val_name.end
             else:
-                sub_token = parse_expr(routine, line, pos + 1, r"([#:, ]|\s*$)")
+                sub_token = parse_expr(line, pos + 1, r"([#:, ]|\s*$)")
                 pos = sub_token.end
                 if not mterminated.match(line, pos) and line[pos] == '#':
-                    max_chars = parse_expr(routine, line, pos + 1, \
-                                           r"([:, ]|\s*$)")
+                    max_chars = parse_expr(line, pos + 1, r"([:, ]|\s*$)")
                     sub_token.max_chars = max_chars 
                     pos = max_chars.end
             if not mterminated.match(line, pos) and line[pos] == ':':
-                timeout = parse_expr(routine, line, pos + 1, r"[ ,]|\s*$")
+                timeout = parse_expr(line, pos + 1, r"[ ,]|\s*$")
                 sub_token.timeout = timeout
                 pos = timeout.end
             if not mterminated.match(line, pos) and line[pos] == ',':
                 pos = pos + 1
             read_list.append(sub_token)
 
-        routine.last_token().read_list = read_list
-        routine.end_token(pos)
+        parent_tok.read_list = read_list
+        parent_tok.end = pos
                 
-    def parse_view(routine, line, pos):
-        """parses the Mumps View command"""
-        keyword_items = []
+    def parse_quit(parent_tok, line, pos):
+        """parses the Mumps Quit command"""
+        mterminated = re.compile(r"[; ]|\s*$")
+        if not mterminated.match(line, pos):
+            return_val = parse_expr(line, pos)
+            pos = return_val.end
+            parent_tok.expr = return_val
+        parent_tok.end = pos
+
+    def parse_new(parent_tok, line, pos):
+        """parses the Mumps New command"""
+        new_list = []
+        excl_list = []
         mterminated = MUMPS_RE_DICT["cmdEnd"]
         while not mterminated.match(line, pos):
-            item = {}
-            keyword = parse_expr(routine, line, pos, r"([:, ]|\s*$)")
-            item["keyword"] = keyword
-            pos = keyword.end
-            expressions = []
-            while not mterminated.match(line, pos) and line[pos] == ':':
+            if line[pos] == '(':
                 pos = pos + 1
-                expr = parse_expr(routine, line, pos, r"([:, ]|\s*$)")
-                pos = expr.end
-                expressions.append(expr)
-            item["expressions"] = expressions
+                while line[pos] != ')':
+                    vartok = parse_expr(line, pos, r"([,)])")
+                    pos = vartok.end
+                    excl_list.append(vartok)
+                    if line[pos] == ',':
+                        pos = pos + 1
+                pos = pos + 1 # eat the closing parens.
+            else:
+                vartok = parse_expr(line, pos, r"([ ,]|\s*$)")
+                pos = vartok.end
+                new_list.append(vartok)
             if not mterminated.match(line, pos) and line[pos] == ',':
                 pos = pos + 1
-            keyword_items.append(item)
+                
+        parent_tok.new_list = new_list
+        parent_tok.excl_list = excl_list
+        parent_tok.end = pos
 
-        routine.last_token().keyword_items = keyword_items
-        routine.end_token(pos)
-
-    def parse_merge(routine, line, pos):
+    def parse_merge(parent_tok, line, pos):
         """parses the Mumps Merge Command"""
         items = []
         mterminated = MUMPS_RE_DICT["cmdEnd"]
         while not mterminated.match(line, pos):
             merge_item = {}
-            recipient = parse_expr(routine, line, pos, r"([=, ]|\s*$)")
+            recipient = parse_expr(line, pos, r"([=, ]|\s*$)")
             merge_item["l_item"] = recipient
             pos = recipient.end
             if not mterminated.match(line, pos) and line[pos] == '=':
                 pos = pos + 1
-                copy_item = parse_expr(routine, line, pos, r"([, ]|\s*$)")
+                copy_item = parse_expr(line, pos, r"([, ]|\s*$)")
                 merge_item["r_item"] = copy_item
                 pos = copy_item.end
             items.append(merge_item)
             if not mterminated.match(line, pos) and line[pos] == ',':
                 pos = pos + 1
-        routine.last_token().items = items
-        routine.end_token(pos)
+        parent_tok.items = items
+        parent_tok.end = pos
 
-    def parse_devicecmd(routine, line, pos):
-        """parses the Mumps Open, Close, and Use commands"""
-        device_list = []
-        mterminated = MUMPS_RE_DICT["cmdEnd"]
-        while not mterminated.match(line, pos):
-            device = {}
-            expr = parse_expr(routine, line, pos + 1, r"([ :,]|\s*$)")
-            device["Expr"] = expr
-            pos = expr.end
-            if not mterminated.match(line, pos) and line[pos] == ':':
-                pos = pos + 1
-                if line[pos] == '(':
-                    pos = pos + 1
-                    keyword_list = []
-                    while line[pos] != ')':
-                        keyword = parse_expr(routine, line, pos, r"[,:=)]")
-                        keyword_list.append(keyword)
-                        pos = keyword.end
-                        if line[pos] == "=":
-                            kval = parse_expr(routine, line, pos, r"[,:)]")
-                            keyword.keyval = kval
-                            pos = kval.end
-                        if line[pos] in (':', ','):
-                            pos = pos + 1
-                    device["keyword_list"] = keyword_list
-                    pos = pos + 1
-                else:
-                    keyword = parse_expr(routine, line, pos, r"[ =:,]|\s*$")
-                    device["keyword_list"] = [keyword, ]
-                    pos = keyword.end
-                    if not mterminated.match(line, pos) and line[pos] == "=":
-                        keyword.keyval = parse_expr(routine, line, pos + 1,
-                                                    r"[ ,:)]|\s*$")
-                        pos = keyword.keyval.end
-            if not mterminated.match(line, pos) and line[pos] == ':':
-                pos = pos + 1
-                timeout = parse_expr(routine, line, pos, r"[ ,]|\s*$")
-                device["Expr"].timeout = timeout
-                pos = timeout.end
-            if not mterminated.match(line, pos) and line[pos] == ',':
-                pos = pos + 1
-            device_list.append(device)
-        routine.last_token().device_list = device_list
-        routine.end_token(pos)
-
-    def parse_set(routine, line, pos):
-        """ parses the Mumps Set command"""
-        var_set = []
-        mterminated = MUMPS_RE_DICT["cmdEnd"]
-        while not mterminated.match(line, pos):
-            var = {}
-            if line[pos] == '(':
-                pos = pos + 1
-                var_list = []
-                while line[pos] != ")":
-                    varname = parse_expr(routine, line, pos, r"([,)])")
-                    var_list.append(varname)
-                    pos = varname.end
-                    if line[pos] == ',':
-                        pos = pos + 1
-                var["var_names"] = var_list
-                pos = pos + 1
-            else:
-                varname = parse_expr(routine, line, pos, r"([,= ]|\s*$)")
-                var["varname"] = varname
-                pos = varname.end
-            if not mterminated.match(line, pos) and line[pos] == '=':
-                pos = pos + 1
-                val = parse_expr(routine, line, pos, r"([ ,]|\s*$)")
-                var["val"] = val
-                pos = val.end
-            else: # note: this is somewhat of an assumption, but...
-                var["indirection"] = varname
-                del var["varname"]
-            var_set.append(var)
-            if not mterminated.match(line, pos) and line[pos] == ',':
-                pos = pos + 1
-        routine.last_token().var_set = var_set
-        routine.end_token(pos)
-
-    def parse_lock(routine, line, pos):
+    def parse_lock(parent_tok, line, pos):
         """parses the Mumps Lock command"""
         lock_list = []
         mterminated = MUMPS_RE_DICT["cmdEnd"]
@@ -612,7 +581,7 @@
                 nref_list = []
                 pos = pos + 1
                 while line[pos] != ')':
-                    nref = parse_expr(routine, line, pos, r"([,)])")
+                    nref = parse_expr(line, pos, r"([,)])")
                     pos = nref.end
                     nref_list.append(nref)
                     if line[pos] == ',':
@@ -620,32 +589,58 @@
                 lock_item["nrefs"] = nref_list
                 pos = pos + 1 # eat the closing parenthesis
             else:
-                nref = parse_expr(routine, line, pos, r"([ ,:]|\s*$)")
+                nref = parse_expr(line, pos, r"([ ,:]|\s*$)")
                 pos = nref.end
                 lock_item["nrefs"] = (nref, )
             if not mterminated.match(line, pos) and line[pos] == ':':
                 pos = pos + 1
-                timeout = parse_expr(routine, line, pos, r"[ ,]|\s*$")
+                timeout = parse_expr(line, pos, r"[ ,]|\s*$")
                 for nref in lock_item["nrefs"]:
                     nref.timeout = timeout
                 pos = timeout.end
             lock_list.append(lock_item)
             if line[pos] == ',':
                 pos = pos + 1
-        routine.last_token().lock_list = lock_list
-        routine.end_token(pos)
+        parent_tok.lock_list = lock_list
+        parent_tok.end = pos
 
-    def parse_job(routine, line, pos):
+    def parse_kill(parent_tok, line, pos):
+        """parses the Mumps Kill command"""
+        kill_list = []
+        excl_list = []
+        mterminated = MUMPS_RE_DICT["cmdEnd"]
+        while not mterminated.match(line, pos):
+            if line[pos] == '(':
+                pos = pos + 1
+                while line[pos] != ')':
+                    vartok = parse_expr(line, pos, r"([,)])")
+                    pos = vartok.end
+                    excl_list.append(vartok)
+                    if line[pos] == ',':
+                        pos = pos + 1
+                pos = pos + 1 # eat the closing parens.
+            else:
+                vartok = parse_expr(line, pos, r"([ ,]|\s*$)")
+                pos = vartok.end
+                kill_list.append(vartok)
+            if not mterminated.match(line, pos) and line[pos] == ',':
+                pos = pos + 1
+                
+        parent_tok.kill_list = kill_list
+        parent_tok.excl_list = excl_list
+        parent_tok.end = pos
+                           
+    def parse_job(parent_tok, line, pos):
         """parses the Mumps Job command"""
         entry_ref_list = []
         mterminated = MUMPS_RE_DICT["cmdEnd"]
         while not mterminated.match(line, pos):
-            (entry_ref, pos) = consume_entry_ref(routine, line, pos)
+            (entry_ref, pos) = parse_entry_ref(line, pos)
             if not mterminated.match(line, pos) and line[pos] == '(':
                 pos = pos + 1
                 params = []
                 while line[pos] != ")":
-                    paramtok = parse_expr(routine, line, pos, r"([,)])")
+                    paramtok = parse_expr(line, pos, r"([,)])")
                     params.append(paramtok)
                     pos = paramtok.end
                     if line[pos] == ',':
@@ -658,7 +653,7 @@
                     pos = pos + 1
                     keyword_list = []
                     while line[pos] != ')':
-                        keyword = parse_expr(routine, line, pos, r"([:)])")
+                        keyword = parse_expr(line, pos, r"([:)])")
                         keyword_list.append(keyword)
                         pos = keyword.end
                         if line[pos] == ':':
@@ -667,156 +662,93 @@
                     entry_ref.keyword_list = keyword_list
             if not mterminated.match(line, pos) and line[pos] == ':':
                 pos = pos + 1
-                timeout = parse_expr(routine, line, pos, r"[ ,]|\s*$")
+                timeout = parse_expr(line, pos, r"[ ,]|\s*$")
                 entry_ref.timeout = timeout
                 pos = timeout.end
             if not mterminated.match(line, pos) and line[pos] == ',':
                 pos = pos + 1
             entry_ref_list.append(entry_ref)
-        routine.last_token().entry_ref = entry_ref_list
-        routine.end_token(pos)
+        parent_tok.entry_ref = entry_ref_list
+        parent_tok.end = pos
 
-    def parse_quit(routine, line, pos):
-        """parses the Mumps Quit command"""
-        mterminated = re.compile(r"[; ]|\s*$")
-        if not mterminated.match(line, pos):
-            return_val = parse_expr(routine, line, pos)
-            pos = return_val.end
-            routine.last_token().expr = return_val
-        routine.end_token(pos)
-
-    def parse_new(routine, line, pos):
-        """parses the Mumps New command"""
-        new_list = []
-        excl_list = []
-        mterminated = MUMPS_RE_DICT["cmdEnd"]
-        while not mterminated.match(line, pos):
-            if line[pos] == '(':
-                pos = pos + 1
-                while line[pos] != ')':
-                    vartok = parse_expr(routine, line, pos, r"([,)])")
-                    pos = vartok.end
-                    excl_list.append(vartok)
-                    if line[pos] == ',':
-                        pos = pos + 1
-                pos = pos + 1 # eat the closing parens.
-            else:
-                vartok = parse_expr(routine, line, pos, r"([ ,]|\s*$)")
-                pos = vartok.end
-                new_list.append(vartok)
-            if not mterminated.match(line, pos) and line[pos] == ',':
-                pos = pos + 1
-                
-        routine.last_token().new_list = new_list
-        routine.last_token().excl_list = excl_list
-        routine.end_token(pos)
-
-    def parse_kill(routine, line, pos):
-        """parses the Mumps Kill command"""
-        kill_list = []
-        excl_list = []
-        mterminated = MUMPS_RE_DICT["cmdEnd"]
-        while not mterminated.match(line, pos):
-            if line[pos] == '(':
-                pos = pos + 1
-                while line[pos] != ')':
-                    vartok = parse_expr(routine, line, pos, r"([,)])")
-                    pos = vartok.end
-                    excl_list.append(vartok)
-                    if line[pos] == ',':
-                        pos = pos + 1
-                pos = pos + 1 # eat the closing parens.
-            else:
-                vartok = parse_expr(routine, line, pos, r"([ ,]|\s*$)")
-                pos = vartok.end
-                kill_list.append(vartok)
-            if not mterminated.match(line, pos) and line[pos] == ',':
-                pos = pos + 1
-                
-        routine.last_token().kill_list = kill_list
-        routine.last_token().excl_list = excl_list
-        routine.end_token(pos)
-                           
-    def parse_if(routine, line, pos):
+    def parse_if(parent_tok, line, pos):
         """parses the Mumps If command"""
         expr_list = []
         mterminated = MUMPS_RE_DICT["cmdEnd"]
         while not mterminated.match(line, pos):
-            exprtok = parse_expr(routine, line, pos, r"([ ,]|\s*$)")
+            exprtok = parse_expr(line, pos, r"([ ,]|\s*$)")
             expr_list.append(exprtok)
             pos = exprtok.end
             if line[pos] == ",":
                 pos = pos + 1
-        routine.last_token().condition_list = expr_list
-        routine.end_token(pos + 1)
+        parent_tok.condition_list = expr_list
+        parent_tok.end = pos + 1
 
-    def parse_hang(routine, line, pos):
+    def parse_hang(parent_tok, line, pos):
         """parses the Mumps Hang/Halt commands"""
-        timetok = parse_expr(routine, line, pos)
-        routine.last_token().HangTime = timetok
-        routine.end_token(timetok.end)
+        timetok = parse_expr(line, pos)
+        parent_tok.HangTime = timetok
+        parent_tok.end = timetok.end
 
-    def parse_goto(routine, line, pos):
+    def parse_goto(parent_tok, line, pos):
         """parse the Mumps Goto command"""
         entry_ref_list = []
         mterminated = MUMPS_RE_DICT["cmdEnd"]
         while not mterminated.match(line, pos):
-            (entry_ref, pos) = consume_entry_ref(routine, line, pos)
+            (entry_ref, pos) = parse_entry_ref(line, pos)
             if not mterminated.match(line, pos) and line[pos] == ':':
                 pos = pos + 1
-                condtok = parse_expr(routine, line, pos, r"([ ,]|\s$)")
+                condtok = parse_expr(line, pos, r"([ ,]|\s$)")
                 entry_ref.post_condition(condtok)
                 pos = condtok.end
             if not mterminated.match(line, pos) and line[pos] == ',':
                 pos = pos + 1
             entry_ref_list.append(entry_ref)
 
-        routine.last_token().entry_ref = entry_ref_list
-        routine.end_token(pos)
+        parent_tok.entry_ref = entry_ref_list
+        parent_tok.end = pos
 
-    def parse_for(routine, line, pos):
+    def parse_for(parent_tok, line, pos):
         """ parses the Mumps For command"""
         loops = []
         loop_incr_var = None
         mterminated = MUMPS_RE_DICT["cmdEnd"]
         if not mterminated.match(line, pos):
-            loop_incr_var = parse_expr(routine, line, pos, r"([=])")
+            loop_incr_var = parse_expr(line, pos, r"([=])")
             pos = loop_incr_var.end + 1 # eat the equal sign.
             while not mterminated.match(line, pos):
                 loop_vals = {}
-                loop_vals["initVal"] = parse_expr(routine, line, pos, \
-                                                  r"([,: ]|\s$)")
+                loop_vals["initVal"] = parse_expr(line, pos, r"([,: ]|\s$)")
                 pos = loop_vals["initVal"].end
                 if not mterminated.match(line, pos) and line[pos] == ':':
                     pos = pos + 1
-                    incr_val = parse_expr(routine, line, pos, r"([ :,]|\s$)")
+                    incr_val = parse_expr(line, pos, r"([ :,]|\s$)")
                     loop_vals["IncrVal"] = incr_val
                     pos = incr_val.end
                 if not mterminated.match(line, pos) and line[pos] == ':':
                     pos = pos + 1
-                    terminal_val = parse_expr(routine, line, pos, \
-                                              r"([ :,]|\s$)")
+                    terminal_val = parse_expr(line, pos, r"([ :,]|\s$)")
                     loop_vals["TermVal"] = terminal_val
                     pos = terminal_val.end
                 loops.append(loop_vals)
                 if not mterminated.match(line, pos) and line[pos] == ',':
                     pos = pos + 1
                 
-        routine.last_token().loop_incr_var = loop_incr_var
-        routine.last_token().for_loops = loops
-        routine.end_token(pos)
+        parent_tok.loop_incr_var = loop_incr_var
+        parent_tok.for_loops = loops
+        parent_tok.end = pos
 
-    def parse_do(routine, line, pos):
+    def parse_do(parent_tok, line, pos):
         """parses the Mumps Do command"""
         entry_ref_list = []
         mterminated = MUMPS_RE_DICT["cmdEnd"]
         while not mterminated.match(line, pos):
-            (entry_ref, pos) = consume_entry_ref(routine, line, pos)
+            (entry_ref, pos) = parse_entry_ref(line, pos)
             if not mterminated.match(line, pos) and line[pos] == '(':
                 pos = pos + 1
                 params = []
                 while line[pos] != ")":
-                    paramtok = parse_expr(routine, line, pos, r"([,)])")
+                    paramtok = parse_expr(line, pos, r"([,)])")
                     params.append(paramtok)
                     pos = paramtok.end
                     if line[pos] == ',':
@@ -825,50 +757,108 @@
                 pos = pos + 1
             if not mterminated.match(line, pos) and line[pos] == ':':
                 pos = pos + 1
-                condtok = parse_expr(routine, line, pos, r"([ ,]|\s$)")
+                condtok = parse_expr(line, pos, r"([ ,]|\s$)")
                 entry_ref.post_condition(condtok)
                 pos = condtok.end
             if not mterminated.match(line, pos) and line[pos] == ',':
                 pos = pos + 1
             entry_ref_list.append(entry_ref)
 
-        routine.last_token().entry_ref = entry_ref_list
-        routine.end_token(pos)
+        parent_tok.entry_ref = entry_ref_list
+        parent_tok.end = pos
         
-    def parse_break(routine, line, pos):
+    def parse_devicecmd(parent_tok, line, pos):
+        """parses the Mumps Open, Close, and Use commands"""
+        device_list = []
+        mterminated = MUMPS_RE_DICT["cmdEnd"]
+        while not mterminated.match(line, pos):
+            device = {}
+            expr = parse_expr(line, pos + 1, r"([ :,]|\s*$)")
+            device["Expr"] = expr
+            pos = expr.end
+            if not mterminated.match(line, pos) and line[pos] == ':':
+                pos = pos + 1
+                if line[pos] == '(':
+                    pos = pos + 1
+                    keyword_list = []
+                    while line[pos] != ')':
+                        keyword = parse_expr(line, pos, r"[,:=)]")
+                        keyword_list.append(keyword)
+                        pos = keyword.end
+                        if line[pos] == "=":
+                            kval = parse_expr(line, pos, r"[,:)]")
+                            keyword.keyval = kval
+                            pos = kval.end
+                        if line[pos] in (':', ','):
+                            pos = pos + 1
+                    device["keyword_list"] = keyword_list
+                    pos = pos + 1
+                else:
+                    keyword = parse_expr(line, pos, r"[ =:,]|\s*$")
+                    device["keyword_list"] = [keyword, ]
+                    pos = keyword.end
+                    if not mterminated.match(line, pos) and line[pos] == "=":
+                        keyword.keyval = parse_expr(line, pos + 1,
+                                                    r"[ ,:)]|\s*$")
+                        pos = keyword.keyval.end
+            if not mterminated.match(line, pos) and line[pos] == ':':
+                pos = pos + 1
+                timeout = parse_expr(line, pos, r"[ ,]|\s*$")
+                device["Expr"].timeout = timeout
+                pos = timeout.end
+            if not mterminated.match(line, pos) and line[pos] == ',':
+                pos = pos + 1
+            device_list.append(device)
+        parent_tok.device_list = device_list
+        parent_tok.end = pos
+
+    def parse_break(parent_tok, line, pos):
         """parse the Mumps Break command"""
         expr_list = []
         mterminated = MUMPS_RE_DICT["cmdEnd"]
         while not mterminated.match(line, pos):
-            exprtok = parse_expr(routine, line, pos, r"([ :,]|\s*$)")
+            exprtok = parse_expr(line, pos, r"([ :,]|\s*$)")
             pos = exprtok.end
             if line[pos] == ":":
-                condtok = parse_expr(routine, line, pos+1, r"([ ,]|\s*$)")
+                condtok = parse_expr(line, pos + 1, r"([ ,]|\s*$)")
                 exprtok.post_condition(condtok)
                 pos = condtok.end
             if line[pos] == ",":
                 pos = pos + 1
             expr_list.append(exprtok)
             
-        routine.last_token().Xecute = expr_list
-        routine.end_token(pos + 1)
+        parent_tok.Xecute = expr_list
+        parent_tok.end = pos + 1
 
-    def consume_unknowncommand(routine, line, pos):
+    def consume_unknowncommand(parent_tok, line, pos):
         """eat the argument of an unknown command"""
         val = ""
         mterminated = MUMPS_RE_DICT["cmdEnd"]
         while not mterminated.match(line, pos):
             if line[pos] == '"':
-                str_val = parse_expr(routine, line, pos, r'[ _,:)]|\s*$')
+                str_val = parse_expr(line, pos, r'[ _,:)]|\s*$')
                 new_pos = str_val.end
             else:
                 new_pos = pos + 1
             val = val + line[pos:new_pos]
             pos = new_pos
             
-        routine.last_token().val = val
-        routine.end_token(pos)
+        parent_tok.val = val
+        parent_tok.end = pos
         
+    def consume_arg_indirection(parent_tok, line, pos):
+        """ parses an argument indirection expression"""
+        mterminated = MUMPS_RE_DICT["cmdEnd"]
+        if not mterminated.match(line, pos) and line[pos:pos+2] == '@(':
+            indirection = parse_expr(line, pos, r"([ ,:]|\s*$)")
+
+            new_pos = indirection.end
+            if mterminated.match(line, new_pos):
+                parent_tok.indirection = indirection
+                parent_tok.end = new_pos
+                return True
+        return False
+         
     command_list = {BREAKCMD:parse_break,
                    CLOSECMD:parse_devicecmd,
                    DOCMD:parse_do,
@@ -899,25 +889,25 @@
     pos = re_match.end("cmd") + 1
 
     toktype = CMD_TOKEN_DICT.get(cmd, UNKNOWNCMD)
-    routine.add_token(Token(toktype, startpos))
+    cmd_token = Token(toktype, startpos)
     if toktype == UNKNOWNCMD:
-        routine.last_token().name = cmd
+        cmd_token.name = cmd
     if re_match.group("indents"): # count the periods for the nesting level...
-        routine.indent_token( \
-            len(re.findall("[.]", line[startpos:re_match.start("cmd")]))) 
+        prefix = line[startpos:re_match.start("cmd")]
+        cmd_token.indentlevel = len(re.findall("[.]", prefix)) 
     if line[re_match.end("cmd")] == ':':
-        condtok = parse_expr(routine, line, pos)
-        routine.post_condition(condtok)
+        condtok = parse_expr(line, pos)
+        cmd_token.post_condition(condtok)
         pos = condtok.end + 1
     
-    if not consume_arg_indirection(routine, line, pos):
+    if not consume_arg_indirection(cmd_token, line, pos):
         if toktype in command_list:
             parse_func = command_list[toktype]
-            parse_func(routine, line, pos)
+            parse_func(cmd_token, line, pos)
         else:
-            routine.end_token(pos)
+            cmd_token.end = pos
 
-    return routine.last_token()
+    return cmd_token
 
 def parseMumps(routine, open_fileinput= None):
     """ Parse all the code of given Mumps module."""
@@ -948,8 +938,9 @@
             for (pattern, parser, dscr) in pattern_list:
                 if pattern.match(line):
                     pattern_match = True
-                    token = parser(routine, line)
+                    token = parser(line)
                     token.line_no(fileinput.lineno())
+                    routine.add_token(token)
                     pos = token.end
                    
                     while not re.match(r"\s*$", line[pos:]):
@@ -958,18 +949,18 @@
                             # no need to scan for labels...
                             if pattern.match(line, pos):
                                 inside_pattern_match = True
-                                token = parser(routine, line, pos)
+                                token = parser(line, pos)
+                                routine.add_token(token)
                                 pos = token.end
                                 break
                             
                         if not inside_pattern_match:
-                            raise ParseError(routine, line, \
-                                             "no Matching pattern", pos, \
+                            raise ParseError(line, "no Matching pattern", pos, \
                                              fileinput.lineno())
                     break
 
             if not pattern_match:
-                raise ParseError(routine, line, "no Pattern match", pos, \
+                raise ParseError(line, "no Pattern match", pos, \
                                  fileinput.lineno())
     finally:
         if not open_fileinput:

Modified: trunk/mumps2py/mumps_module.py
===================================================================
--- trunk/mumps2py/mumps_module.py	2008-02-18 20:55:55 UTC (rev 119)
+++ trunk/mumps2py/mumps_module.py	2008-02-21 22:02:15 UTC (rev 120)
@@ -19,7 +19,7 @@
 import mumps2py_config
 
 class ModuleInfo:
-    """ A ModuleInfo object represents one complete unit of Mumps source code."""
+    """ A ModuleInfo object represents one Mumps routine."""
     def __init__(self, inputfile, outputdir, name, startline = 1, endline = -1):
         self.input_file = inputfile
         if os.path.isabs(name):
@@ -30,41 +30,28 @@
         self.mod_name = outname
         self.start = startline
         self.end = endline
-        self.TokenList = []
+        self.token_list = []
 
     def __str__(self):
         return "Module %s" % self.mod_name
 
     def tokenlist_isempty(self):
         """ returns true if the Token List is empty."""
-        return not len(self.TokenList)
+        return not len(self.token_list)
 
     def empty_tokenlist(self):
         """ clear out the Token List."""
-        while len(self.TokenList):
-            self.TokenList.pop()
+        while len(self.token_list):
+            self.token_list.pop()
         
     def add_token(self, newtoken):
         """ add a new token to the token list."""
-        self.TokenList.append(newtoken)
+        self.token_list.append(newtoken)
 
-    def end_token(self, endpos):
-        """used to indicate where the last token added ended."""
-        self.TokenList[-1].end = endpos
+    def tokenized(self):
+        """return the token list"""
+        return self.token_list
 
-    def indent_token(self, nestlevel):
-        """sets the indent level for the last token added to this module."""
-        self.TokenList[-1].indentlevel = nestlevel
-
-    def post_condition(self, tvexprtoklist):
-        """adds the given post-condition to the last token added to this module"""
-        tok = self.TokenList[-1]
-        tok.post_condition(tvexprtoklist)
-
-    def last_token(self):
-        """returns the last Token added to this module's TokenList"""
-        return self.TokenList[-1]
-
 class RoutineFilter:
     """creates an object that will filter which routines to process,
 based on the criteria provided"""

Modified: trunk/mumps2py/tok2python.py
===================================================================
--- trunk/mumps2py/tok2python.py	2008-02-18 20:55:55 UTC (rev 119)
+++ trunk/mumps2py/tok2python.py	2008-02-21 22:02:15 UTC (rev 120)
@@ -841,7 +841,7 @@
 
     tokprepass.prepass(a_mumps_module)
     try:
-        for token in a_mumps_module.TokenList:
+        for token in a_mumps_module.tokenized():
             if TRANS_FUNC_DICT.has_key(token.toktype):
                 trans_func = TRANS_FUNC_DICT[token.toktype]
                 

Modified: trunk/mumps2py/tokprepass.py
===================================================================
--- trunk/mumps2py/tokprepass.py	2008-02-18 20:55:55 UTC (rev 119)
+++ trunk/mumps2py/tokprepass.py	2008-02-21 22:02:15 UTC (rev 120)
@@ -71,7 +71,7 @@
     indentlevel_state = {'new':0, 'next':0}
     localvars_state = {'collection':{} }
     mergevars_state = {'collection':{} }
-    for token in a_mumps_module.TokenList:
+    for token in a_mumps_module.tokenized():
         fix_indent_levels(token, indentlevel_state)
         findall_localvars(token, localvars_state)
         if token.toktype == MERGECMD:


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/