irpf90/src/module.py

242 lines
7.7 KiB
Python
Raw Normal View History

2009-09-08 16:00:46 +02:00
#!/usr/bin/python
2009-09-23 12:51:27 +02:00
# IRPF90 is a Fortran90 preprocessor written in Python for programming using
# the Implicit Reference to Parameters (IRP) method.
# Copyright (C) 2009 Anthony SCEMAMA
#
# This program 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 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Anthony Scemama
# LCPQ - IRSAMC - CNRS
# Universite Paul Sabatier
# 118, route de Narbonne
# 31062 Toulouse Cedex 4
# scemama@irsamc.ups-tlse.fr
2009-09-23 12:51:27 +02:00
2009-09-08 16:00:46 +02:00
from irpf90_t import *
from variable import *
from variables import variables
2009-12-09 09:42:36 +01:00
from command_line import command_line
2009-09-08 18:20:20 +02:00
import preprocessed_text
2009-09-09 00:46:42 +02:00
from util import *
2009-09-08 16:00:46 +02:00
class Fmodule(object):
header = \
[ "! -*- F90 -*-",
"!",
"!-----------------------------------------------!",
"! This file was generated with the irpf90 tool. !",
"! !",
"! DO NOT MODIFY IT BY HAND !",
"!-----------------------------------------------!",
"" ]
2009-09-08 16:00:46 +02:00
def __init__(self,text,filename):
2009-09-09 00:46:42 +02:00
self.text = put_info(text,filename)
2009-09-09 16:59:43 +02:00
self.name = "%s_mod"%(filename[:-6])
2009-09-08 16:00:46 +02:00
def is_main(self):
if '_is_main' not in self.__dict__:
2009-09-08 18:20:20 +02:00
self._is_main = self.prog_name is not None
2009-09-08 16:00:46 +02:00
return self._is_main
is_main = property(is_main)
2009-09-08 18:20:20 +02:00
def prog_name(self):
if '_prog_name' not in self.__dict__:
2010-10-02 23:42:55 +02:00
buffer = filter(lambda x: type(x[1]) == Program,self.text)
2009-09-08 18:20:20 +02:00
if buffer == []:
self._prog_name = None
else:
self._prog_name = buffer[0][1].filename
return self._prog_name
prog_name = property(prog_name)
2009-09-08 16:00:46 +02:00
def variables(self):
if '_variables' not in self.__dict__:
from variables import variables
name = self.name
self._variables = filter(lambda x: variables[x].fmodule == name, variables)
return self._variables
variables = property(variables)
2009-09-08 16:00:46 +02:00
def head(self):
if '_head' not in self.__dict__:
result = [ "module %s"%(self.name) ]
2009-09-08 18:20:20 +02:00
result += self.use
result += self.dec
2009-09-09 00:46:42 +02:00
result += flatten( map(lambda x: variables[x].header,self.variables) )
2009-09-08 18:20:20 +02:00
result.append( "end module %s"%(self.name) )
self._head = result
2009-09-08 16:00:46 +02:00
return self._head
head = property(head)
def needed_vars(self):
if '_needed_vars' not in self.__dict__:
result = map(lambda x: variables[x].needs,self.variables)
result = make_single ( flatten(result) )
self._needed_vars = result
return self._needed_vars
needed_vars = property(needed_vars)
def includes(self):
if '_includes' not in self.__dict__:
buffer = []
for v in self.needed_vars:
buffer += variables[v].includes
self._includes = make_single(buffer)
return self._includes
includes = property(includes)
2009-09-08 16:00:46 +02:00
def generated_text(self):
if '_generated_text' not in self.__dict__:
2009-09-08 18:20:20 +02:00
result = []
for var in self.variables:
var = variables[var]
result += var.provider
result += var.builder
if var.is_read:
result += var.reader
if var.is_written:
result += var.writer
self._generated_text = result
2009-09-08 16:00:46 +02:00
return self._generated_text
generated_text = property(generated_text)
def residual_text(self):
if '_residual_text' not in self.__dict__:
2009-09-09 17:55:17 +02:00
from variables import build_use, call_provides
2009-09-09 16:59:43 +02:00
from parsed_text import move_to_top
2009-09-08 18:20:20 +02:00
def remove_providers(text):
result = []
inside = False
for vars,line in text:
2010-10-02 23:42:55 +02:00
if type(line) == Begin_provider:
2009-09-08 18:20:20 +02:00
inside = True
if not inside:
result.append( (vars,line) )
2010-10-02 23:42:55 +02:00
if type(line) == End_provider:
2009-09-08 18:20:20 +02:00
inside = False
return result
def modify_functions(text):
result = []
2009-09-09 00:46:42 +02:00
variable_list = []
2009-09-08 18:20:20 +02:00
for vars,line in text:
if type(line) in [ Subroutine, Function ]:
variable_list = list(vars)
2010-10-02 23:42:55 +02:00
elif type(line) == End:
2009-09-08 18:20:20 +02:00
result += map(lambda x: ([],Use(line.i,x,line.filename)), build_use(variable_list))
else:
variable_list += vars
result.append( (vars,line) )
return result
def extract_use_dec_text(text):
inside = False
result = []
dec = []
use = []
for vars,line in text:
if type(line) in [ Subroutine, Function]:
inside = True
if inside:
result.append( (vars,line) )
else:
2010-10-02 23:42:55 +02:00
if type(line) == Use:
2009-09-08 18:20:20 +02:00
use.append( (vars,line) )
2010-10-02 23:42:55 +02:00
elif type(line) == Declaration:
2009-09-08 18:20:20 +02:00
dec.append( (vars,line) )
2010-10-02 23:42:55 +02:00
if type(line) == End:
2009-09-08 18:20:20 +02:00
inside = False
return use, dec, result
2009-09-09 16:59:43 +02:00
def provide_variables(text):
result = []
for vars,line in text:
result.append( ([],line) )
2009-09-09 17:55:17 +02:00
result += map(lambda x: ([],Simple_line(line.i,x,line.filename)), call_provides(vars))
2009-09-09 16:59:43 +02:00
return result
2009-09-08 18:20:20 +02:00
result = remove_providers(self.text)
result = modify_functions(result)
use,dec,result = extract_use_dec_text(result)
self._use = make_single(map(lambda x: " "+x[1].text, use))
self._dec = make_single(map(lambda x: " "+x[1].text, dec))
2009-09-09 16:59:43 +02:00
result = provide_variables(result)
result = move_to_top(result,Declaration)
result = move_to_top(result,Implicit)
result = move_to_top(result,Use)
2009-09-09 00:46:42 +02:00
result = map(lambda x: x[1], result)
result = map(lambda x: x.text, result)
2009-09-08 18:20:20 +02:00
if self.is_main:
2009-12-09 09:42:36 +01:00
temp = [ "program irp_program" ]
2011-09-30 19:10:18 +02:00
if command_line.do_profile:
temp += [ "call irp_init_timer()" ]
2009-12-09 09:42:36 +01:00
if command_line.do_openmp:
temp += [ "!$OMP PARALLEL" ]
temp += [ "!$OMP MASTER" ]
temp += [ " call %s"%(self.prog_name) ]
if command_line.do_openmp:
temp += [ "!$OMP END MASTER" ]
temp += [ "!$OMP END PARALLEL" ]
2011-09-30 19:10:18 +02:00
if command_line.do_profile:
temp += [ "call irp_print_timer()" ]
temp += [ " call irp_finalize_%s()"%(irp_id) ]
2009-12-09 09:42:36 +01:00
temp += [ "end program" ]
result = temp + result
2009-09-08 18:20:20 +02:00
self._residual_text = result
2009-09-08 16:00:46 +02:00
return self._residual_text
residual_text = property(residual_text)
2009-09-08 18:20:20 +02:00
def use(self):
if '_use' not in self.__dict__:
self.residual_text
return self._use
use = property(use)
def dec(self):
if '_dec' not in self.__dict__:
self.residual_text
return self._dec
dec = property(dec)
2009-09-08 16:00:46 +02:00
def needed_modules(self):
if '_needed_modules' not in self.__dict__:
2009-09-09 00:55:13 +02:00
buffer = filter(lambda x: x.lstrip().startswith("use "), \
self.generated_text+self.head+self.residual_text)
buffer = map(lambda x: x.split()[1], buffer)
2010-03-12 13:14:52 +01:00
buffer = filter(lambda x: x.endswith("_mod"),buffer )
2009-09-08 16:00:46 +02:00
self._needed_modules = make_single(buffer)
2009-09-09 00:55:13 +02:00
if self.name in self._needed_modules:
self._needed_modules.remove(self.name)
2009-09-08 16:00:46 +02:00
return self._needed_modules
needed_modules = property(needed_modules)
2009-09-09 00:46:42 +02:00
######################################################################
2009-09-08 16:00:46 +02:00
if __name__ == '__main__':
from parsed_text import parsed_text
for filename, text in parsed_text:
if filename == 'vmc_step.irp.f':
2009-09-08 16:00:46 +02:00
x = Fmodule(text,filename)
break
2009-09-09 00:46:42 +02:00
for line in x.head:
2009-09-08 18:20:20 +02:00
print line
print x.includes
2009-09-08 16:00:46 +02:00