[Mumps2Py:] [8] moved to package.

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


Revision: 8
Author:   pgallot
Date:     2008-01-17 17:56:48 +0000 (Thu, 17 Jan 2008)

Log Message:
-----------
moved to package.

Added Paths:
-----------
    trunk/mumps2py/tok2python.py


Copied: trunk/mumps2py/tok2python.py (from rev 7, trunk/tok2python.py)
===================================================================
--- trunk/mumps2py/tok2python.py	                        (rev 0)
+++ trunk/mumps2py/tok2python.py	2008-01-17 17:56:48 UTC (rev 8)
@@ -0,0 +1,416 @@
+# Copyright 2008 Patrick Gallot
+
+##    This file is part of Mumps2Py.
+##
+##    Mumps2Py is free software: you can redistribute it and/or modify
+##    it under the terms of the GNU General Public License as published by
+##    the Free Software Foundation, either version 3 of the License, or
+##    (at your option) any later version.
+##
+##    Mumps2Py is distributed in the hope that it will be useful,
+##    but WITHOUT ANY WARRANTY; without even the implied warranty of
+##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##    GNU General Public License for more details.
+##
+##    You should have received a copy of the GNU General Public License
+##    along with Mumps2Py.  If not, see <http://www.gnu.org/licenses/>.
+""" translate the tokens extracted from the Mumps code into Python code."""
+import re
+import mumps_module, tokprepass
+from tokens import *
+
+class TranslationError(Exception):
+    """Exception class for errors related to translating Mumps code to Python"""
+    def __init__(self, translation, token, dscr=""):
+        Exception.__init__(self)
+        self.translation = translation
+        self.token = token
+        self.dscr = dscr
+        print self.error_msg()
+        
+    def error_msg(self):
+        """ returns a formated string containing information about the error"""
+        errormsg = "\nError: %s %s\n\t%s" % \
+                   (self.translation.mumps_module.mod_name, self.dscr, \
+                    str(self.token))
+        return errormsg
+
+
+class Translation:
+    def __init__(self, a_mumps_module):
+        self.mumps_module = a_mumps_module
+        self.code = []
+
+    def add_code(self, block):
+        """adds another block of code to the translation"""
+        self.code.append(block)
+
+def tab(indentlevel):
+    if indentlevel:
+        return "%*c" % (indentlevel, '\t')
+    else:
+        return ""
+    
+def translate_comment(translation, token):
+    """translate a Mumps comment to Python"""
+    return "%s# %s\n" % (tab(token.indentlevel), token.val)
+
+def translate_label(translation, token):
+    """translate a Mumps label to Python"""
+# TODO: anything that should be done for ExternallyVisible?
+    if token.parameters:
+        if len(token.parameters) == 1:
+            return "def %s(%s):\n" % (token.val, token.parameters[0])
+        else:
+            label_str = "def %s(" % (token.val)
+            for param in token.parameters[:-1]:
+                label_str = "%s%s ," % (label_str, param)
+            label_str = label_str + " ):\n"
+            return label_str
+    else:
+        return "def %s():\n" % (token.Name)
+
+def translate_expr(translation, token):
+    """translate a Mumps expression Command to Python"""
+
+    def translate_num(translation, token):
+        """ translates a number """
+        return token.val
+
+    def translate_str(translation, token):
+        """ translates a Mumps string to Python """
+        new_str = re.sub(r'["]{2}', '\"', token.val[1:-1])
+        return '\"'+ new_str + '\"'
+
+    def translate_fcc_newline(translation, token):
+        """ translates a Mumps-style newline to Python"""
+        return r'"\n"'
+
+    def translate_intr_extract(translation, token):
+        """ translates the Mumps Intrinsic function EXTRACT to python"""
+        if len(token.params) == 3:
+            extract_str = "%s[%s:%s]" % (
+                translate_expr(translation, token.params[0]),
+                translate_expr_sub_one(translation, token.params[1]),
+                translate_expr(translation, token.params[2]))
+        elif len(token.params) == 2:
+            extract_str = "%s[%s]" % (
+                translate_expr(translation, token.params[0]),
+                translate_expr_sub_one(translation, token.params[1]))
+        else:
+            raise TranslationError(translation,token,
+                                   "incorrect number of parameters")
+        return extract_str
+                 
+    def translate_local_var(translation, token):
+        """ translates a local variable into a Python variable"""
+        if not token.__dict__.has_key('indices'):
+            return token.varname
+        else:
+            raise TranslationError(translation, token, "idiom not implemented")
+
+    def translate_expr_list(translation, token):
+        """ translates a sequence of literals, variables, operators, etc."""
+
+        def trans_unary_expr(left_token, right_token):
+            if left_token.toktype == OPSUB:
+                return "-"+translate_expr(translation, right_token)
+            elif left_token.is_not():
+                return "not "+translate_expr(translation, right_token)
+            else:
+                raise TranslationError(translation, left_token,
+                                       "unknown expression pattern")
+        def trans_binary_op(token):
+            op_trans_dict = {OPADD:'+', OPSUB:'-', OPMULT:'*', OPEXP:'**',
+                             OPMODULO:'%', OPGT:'>', OPLT:'<', OPNGT:'<=',
+                             OPNLT:'>=', OPEQ:'==', OPNEQ:'!=', OPAND:'and',
+                             OPOR:'or'}
+
+            if op_trans_dict.has_key(token.toktype):
+                return op_trans_dict[token.toktype]
+            else:
+                raise TranslationError(translation, token,
+                                       "unknown expression pattern")
+            
+        expr_list = token.expr_list[:]
+        first_token = expr_list.pop(0)
+        if first_token.is_unaryop():
+            left_str = "(%s)" % (trans_unary_expr(first_token, expr_list.pop(0)))
+        else:
+            left_str = translate_expr(translation, first_token)
+        while expr_list:
+            not_str=""
+            binop_token = expr_list.pop(0)
+            if binop_token.is_not():
+                not_str = "not "
+                binop_token = expr_list.pop(0)
+                
+            right_token = expr_list.pop(0)
+            if right_token.is_unaryop():
+                right_str = trans_unary_expr(right_token, expr_list.pop(0))
+            else:
+                right_str = translate_expr(translation, right_token)
+            left_str = "%s(%s %s %s)" % (not_str,left_str, trans_binary_op(binop_token),
+                                       right_str)
+        return left_str
+
+    expr_transl_dict = {
+        NUMLITERAL:translate_num,
+        STRINGLITERAL:translate_str,
+        LOCALVAR:translate_local_var,
+        FCC_NEWLINE:translate_fcc_newline,
+        F_EXTRACT: translate_intr_extract,
+        EXPR: translate_expr_list}
+
+    if expr_transl_dict.has_key(token.toktype):
+        trans_func = expr_transl_dict[token.toktype]
+        expr = trans_func(translation, token)
+        return expr
+    else:
+        raise TranslationError(translation, token,
+                               "token type translation not implemented")
+
+def translate_expr_plus_one(translation, token):
+    if token.is_int():
+        return str(int(token.val,10) + 1)
+    else:
+        return translate_expr(translation,token) + "+1"
+    
+def translate_expr_sub_one(translation, token):
+    if token.is_int():
+        return str(int(token.val,10) - 1)
+    else:
+        return translate_expr(translation,token) + "-1"
+
+def translate_write(translation, token):
+    """translate the Mumps Write Command to Python"""
+    write_str = ""
+    indentlevel = token.indentlevel
+    if token.post_condition_expr:
+        write_str = "%sif %s:\n" % (tab(indentlevel),
+                                  translate_expr(translation,
+                                                 token.post_condition_expr))
+        indentlevel = indentlevel + 1
+
+    write_args = ""
+    for item in token.write_list[:-1]:
+        write_args = write_args + translate_expr(translation, item) + " + "
+
+    write_args = write_args + translate_expr(translation,
+                                             token.write_list[-1]) + ", "
+    write_str = "%s%sprint %s\n" % (write_str, tab(token.indentlevel),
+                                    write_args)
+    return write_str
+
+def translate_for(translation, token):
+    """translate the Mumps For Command to Python"""
+    #TODO: completely redo to use a MumpsCL iterator...
+    if len(token.for_loops) == 1 and token.for_loops[0].has_key('TermVal'):
+        init_tok = token.for_loops[0]['initVal']
+        incr_tok = token.for_loops[0]['IncrVal']
+        trm_tok = token.for_loops[0]['TermVal']
+        init_val = translate_expr(translation, init_tok)
+        incr_val = translate_expr(translation, incr_tok)
+        
+        if incr_tok.is_int():
+            if int(incr_tok.val) > 0:
+                trm_val = translate_expr_plus_one(translation, trm_tok)
+            else:
+                trm_val = translate_expr_sub_one(translation, trm_tok)
+        else:
+            trm_val = translate_expr(translation, trm_tok)
+
+        if init_val == '0': # the default starting value in a range, omit
+            init_val = ""
+        else:
+            init_val = init_val + ", "
+        if incr_val == '1': # the default increment value in a range, omit
+            incr_val = "" 
+        else:
+            incr_val = ", " + incr_val
+            
+        for_str = "%sfor %s in range(%s%s%s):\n" % \
+                  (tab(token.indentlevel), \
+                   translate_expr(translation, token.loop_incr_var),
+                   init_val,
+                   trm_val,
+                   incr_val)
+        return for_str
+    else:
+        raise TranslationError(translation, token, "idiom not implemented")
+
+def translate_set(translation, token):
+    """ translate the Mumps Set command to Python"""
+    set_str = ""
+    indentlevel = token.indentlevel
+    if token.post_condition_expr:
+        set_str = "%sif %s:\n" % (tab(indentlevel),
+                                  translate_expr(translation,
+                                                 token.post_condition_expr))
+        indentlevel = indentlevel + 1
+    for item in token.var_set:
+        if item.has_key("indirection"):
+            raise TranslationError(translation, token, "idiom not implemented")
+        elif item.has_key("multiset"):
+            for varname in item["var_names"]:
+                set_str = "%s%s%s = %s\n" % \
+                          ( set_str, tab(indentlevel),
+                            translate_expr(translation, varname),
+                            translate_expr(translation, item["val"]))
+        else:
+            set_str = "%s%s%s = %s\n" % \
+                      ( set_str, tab(indentlevel),
+                        translate_expr(translation, item["varname"]),
+                        translate_expr(translation, item["val"]))
+    return set_str
+
+def translate_do(translation, token):
+    """translate the Mumps Do command to Python"""
+    if not token.post_condition_expr and len(token.entry_ref) == 0:
+        return ""
+    else:
+        raise TranslationError(translation, token,
+                               "token type translation not implemented")
+
+def translate_if(translation, token):
+    """translate the Mumps If commands to Python"""
+    condition_list = token.condition_list[:]
+    condition_str = ""
+    while len(condition_list) > 1:
+        condition_str = translate_expr(translation, condition_list.pop(0)) \
+                        +" or "
+    if_str = "%sif %s%s:\n" % (tab(token.indentlevel),
+                               condition_str,
+                               translate_expr(translation,
+                                              condition_list.pop(0)))
+    return if_str
+
+def translate_break(translation, token):
+    """translate the Mumps Break command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_close(translation, token):
+    """translate the Mumps Close command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_else(translation, token):
+    """translate the Mumps Else command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_goto(translation, token):
+    """translate the Mumps Goto command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_hang(translation, token):
+    """translate the Mumps Hang/Halt commands to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_job(translation, token):
+    """translate the Mumps Job command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_kill(translation, token):
+    """translate the Mumps Kill command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_lock(translation, token):
+    """translate the Mumps Lock command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_merge(translation, token):
+    """translate the Mumps Merge command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_new(translation, token):
+    """ translate the MUmps New command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_open(translation, token):
+    """translate the Mumps Open command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_quit(translation, token):
+    """ translate the Mumps Quit command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_read(translation, token):
+    """ translate the Mumps Read command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_use(translation, token):
+    """ translate the Mumps Use command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_view(translation, token):
+    """ translate the Mumps View command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+def translate_xecute(translation, token):
+    """ translate the Mumps Xecute command to Python"""
+    raise TranslationError(translation, token,
+                           "token type translation not implemented")
+
+
+TRANS_FUNC_DICT = {
+    COMMENT: translate_comment,
+    LABEL: translate_label,
+    BREAKCMD: translate_break,
+    CLOSECMD: translate_close,
+    DOCMD: translate_do,
+    ELSECMD: translate_else,
+    FORCMD: translate_for,
+    GOTOCMD: translate_goto,
+    HANGCMD: translate_hang,
+    IFCMD: translate_if,
+    JOBCMD: translate_job,
+    KILLCMD: translate_kill,
+    LOCKCMD: translate_lock,
+    MERGECMD: translate_merge,
+    NEWCMD: translate_new,
+    OPENCMD: translate_open,
+    QUITCMD: translate_quit,
+    READCMD: translate_read,
+    SETCMD: translate_set,
+    USECMD: translate_use,
+    VIEWCMD: translate_view,
+    WRITECMD: translate_write,
+    XECUTECMD: translate_xecute,
+    }
+
+
+def translate(a_mumps_module):
+    """translate all of a mumps module to Python"""
+    translation = Translation(a_mumps_module)
+
+    tokprepass.prepass(a_mumps_module)
+    try:
+        for token in a_mumps_module.TokenList:
+            if TRANS_FUNC_DICT.has_key(token.toktype):
+                trans_func = TRANS_FUNC_DICT[token.toktype]
+                
+                code_block = trans_func(translation, token)
+                print code_block
+                translation.add_code(code_block)
+            else:
+                raise TranslationError(translation, token, 
+                                       "token type translation not implemented")
+    except TranslationError, e:
+        translation.code.append("incomplete!!!\n")
+        return translation.code
+    
+    return translation.code


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