[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