10
0
mirror of https://gitlab.com/scemama/irpf90.git synced 2024-12-23 04:43:34 +01:00

Fixe edge case for interface support

This commit is contained in:
Thomas Applencourt 2017-01-24 17:21:38 +00:00
parent 3032e754a7
commit 34854ce1f5
5 changed files with 112 additions and 56 deletions

View File

@ -183,6 +183,7 @@ def create_build_compile(t, l_module, l_ext_modfile=[], ninja=True):
# Expensive and stupid. We can create a dict to do the loockup only once # Expensive and stupid. We can create a dict to do the loockup only once
for m in t.needed_modules_usr: for m in t.needed_modules_usr:
# m is name
for x in l_module: for x in l_module:
if m in x.gen_mod and x.filename != t.filename: if m in x.gen_mod and x.filename != t.filename:
needed_modules.append("%s.irp.o" % x.filename) needed_modules.append("%s.irp.o" % x.filename)

View File

@ -669,12 +669,9 @@ class Entity(object):
import parsed_text import parsed_text
# Move the variable to top, and add the text # Move the variable to top, and add the text
l_builder_text_raw = [ parsed_text.move_to_top_list(text, [Declaration, Implicit, Use])
x[1] for x in parsed_text.move_to_top_list(text, [Declaration, Implicit, Use])
] result.extend( line.text for _,line in text if not isinstance(line, (Begin_doc, End_doc, Doc, Cont_provider)))
result.extend(
line.text for line in l_builder_text_raw
if not isinstance(line, (Begin_doc, End_doc, Doc, Cont_provider)))
if command_line.do_profile: if command_line.do_profile:
result += [ result += [

View File

@ -223,13 +223,9 @@ class Irpy_comm_world(object):
@irpy.lazy_property @irpy.lazy_property
def t_filename_parsed_text(self): def t_filename_parsed_text(self):
'''(filename,parsed_text)''' '''(filename,parsed_text)'''
import parsed_text
d_entity = self.d_entity d_entity = self.d_entity
d_routine = self.d_routine d_routine = self.d_routine
# ~ # ~ # ~
# F i r s t R o u n d
# ~ # ~ # ~
import parsed_text import parsed_text
vtuple = [(v, s.same_as, s.regexp) for v, s in d_entity.iteritems()] vtuple = [(v, s.same_as, s.regexp) for v, s in d_entity.iteritems()]
def worker_parsed(filename_text): def worker_parsed(filename_text):
@ -238,14 +234,21 @@ class Irpy_comm_world(object):
parsed_text_0 = parmap(worker_parsed, self.t_filename_preprocessed_text) parsed_text_0 = parmap(worker_parsed, self.t_filename_preprocessed_text)
from irpf90_t import NoDep,Declaration,Implicit,Use,Cont_provider
def moved_to_top_l(ptext):
l = [NoDep, Declaration, Implicit, Use, Cont_provider]
for _, text in ptext:
parsed_text.move_to_top_list(text, l)
#Touch routine #Touch routine
parsed_text.build_sub_needs(parsed_text_0, d_routine) parsed_text.build_sub_needs(parsed_text_0, d_routine)
parsed_text.parsed_moved_to_top(parsed_text_0) moved_to_top_l(parsed_text_0)
parsed_text_1 = parsed_text.add_subroutine_needs(parsed_text_0, d_routine) parsed_text_1 = parsed_text.add_subroutine_needs(parsed_text_0, d_routine)
parsed_text_1 = parsed_text.move_variables(parsed_text_1) parsed_text_1 = parsed_text.move_variables(parsed_text_1)
parsed_text.parsed_moved_to_top(parsed_text_1) moved_to_top_l(parsed_text_1)
parsed_text.check_opt(parsed_text_1) parsed_text.check_opt(parsed_text_1)
parsed_text_1 = parsed_text.perform_loop_substitutions(parsed_text_1) parsed_text_1 = parsed_text.perform_loop_substitutions(parsed_text_1)

View File

@ -134,8 +134,16 @@ class Fmodule(object):
result = [] result = []
variable_list = [] variable_list = []
skip_interface = False
for vars, line in text: for vars, line in text:
if type(line) in [Interface, End_interface]:
skip_interface = not skip_interface
if skip_interface:
result.append((vars, line))
continue
if type(line) in [Subroutine, Function, Program]: if type(line) in [Subroutine, Function, Program]:
#Deep copy... #Deep copy...
variable_list = list(vars) variable_list = list(vars)
@ -152,12 +160,10 @@ class Fmodule(object):
'''Extract the global declaration statement and module use form the declaration of function. ''' '''Extract the global declaration statement and module use form the declaration of function. '''
inside = 0 inside = 0
result = [] result,dec,use,module = [],[],[],[]
dec = []
use = []
module = []
for vars, line in text: for vars, line in text:
if isinstance(line, (Subroutine, Function, Program,Interface,Module)): if isinstance(line, (Subroutine, Function, Program,Interface,Module)):
inside += 1 inside += 1
@ -223,7 +229,7 @@ class Fmodule(object):
if len(l) != len(uniquify(l)): if len(l) != len(uniquify(l)):
raise NotImplementedError raise NotImplementedError
return [" %s" % line.text for _, line in self.residual_text_use_dec.dec] return l
@irpy.lazy_property @irpy.lazy_property
def residual_text(self): def residual_text(self):
@ -235,8 +241,12 @@ class Fmodule(object):
result += map(lambda x: ([], Simple_line(line.i, x, line.filename)), result += map(lambda x: ([], Simple_line(line.i, x, line.filename)),
build_call_provide(vars, self.d_all_variable)) build_call_provide(vars, self.d_all_variable))
from parsed_text import move_to_top_list
return [line.text for _, line in move_to_top_list(result, [Declaration, Implicit, Use])] from parsed_text import move_to_top_list, move_interface
move_to_top_list(result, [Declaration, Implicit, Use])
move_interface(result)
return [line.text for _, line in result]
@irpy.lazy_property @irpy.lazy_property
def needed_modules(self): def needed_modules(self):

View File

@ -200,70 +200,101 @@ def get_parsed_text(filename, text, variables, subroutines, vtuple):
###################################################################### ######################################################################
def move_to_top_list(text, it): def move_to_top_list(text, it):
'This function is Unpure' # ( List[ List[Entity], Line], Iterator)
'test will be modify' '''Move the all the element of List[ List[Entity], Line] of Line's Type containt in IT are the top of text.
Note:
- The permutation neeed to be done following `it` order
- We can have `nested` subroutine / Function. (Because of interface)
- This function is called way to much. Is need to be efficient
- This function is Unpure
- One pass over `text`
NB:
- I am not really proud of the Sentinel value for the deleted,
but I waste already so much time on more cleaver but not working solution...
'''
assert type(text) == list
assert set(it).issubset([NoDep, Declaration, Implicit, Use, Cont_provider]) assert set(it).issubset([NoDep, Declaration, Implicit, Use, Cont_provider])
from collections import defaultdict
d_permutation = defaultdict(list)
# ~ # ~ # ~ # ~ # ~ # ~
# G e t P e r m u t a t i o n # G e t P e r m u t a t i o n
# ~ # ~ # ~ # ~ # ~ # ~
inside = False from collections import defaultdict
d_permutation = defaultdict(list)
# Type:List(begin, Line)
# We will insert the Line at begin position later on
l_begin = []
for i, (l_var, line) in enumerate(text): for i, (l_var, line) in enumerate(text):
t = type(line) t = type(line)
if t in [Begin_provider, Program, Subroutine, Function]:
begin = i if t in [Begin_provider, Module,Program, Subroutine, Function]:
inside = True l_begin.append(i)
elif t in [End_provider, End]: elif t in [End_provider, End]:
inside = False l_begin.pop()
elif inside and t in it:
d_permutation[t].append([begin, (l_var, line), i]) elif l_begin and t in it:
d_permutation[t].append( (l_begin[-1], [l_var, line]) )
# Put the sentinel, will be deleted after the insertion
text[i] = None
# ~ # ~ # ~ # ~ # ~ # ~
# O r d e r t h e m # O r d e r t h e m
# ~ # ~ # ~ # ~ # ~ # ~
# We need to do the permutation in the correct order
d_insert = defaultdict(list) d_insert = defaultdict(list)
d_remove = defaultdict(list)
for t in reversed(it): for t in reversed(it):
for begin, tline, idx_remove in d_permutation[t]: for begin, tline in d_permutation[t]:
d_insert[begin].append(tline) d_insert[begin].append(tline)
d_remove[begin].append(idx_remove)
# ~ # ~ # ~ # ~ # ~ # ~
# D o t h e m # D o t h e m
# ~ # ~ # ~ # ~ # ~ # ~
# Because idx are sorted, it's easy to do the insert part of the move
for idx in sorted(d_remove.keys()): # Just pad each insert by the number of precedent insert
padding = 0 padding = 0
for idx in sorted(d_insert.keys()):
for tline in d_insert[idx]: for tline in d_insert[idx]:
text.insert(idx + padding + 1, tline) text.insert(idx + padding + 1, tline)
padding += 1 padding += 1
for idx_remove in sorted(d_remove[idx]): # Now do the Delete part of the move. Fortunatly we put a sentinel to know the line to delete
text.pop(idx_remove + padding) for i in reversed(xrange(len(text))):
padding += -1 if text[i] is None:
return text del text[i]
def parsed_moved_to_top(parsed_text): def move_interface(parsed_text,s_type=(Use,Implicit,Declaration,Subroutine,Function,Module)):
'This subroutine is unpur:' # ( List[ List[Entity], Line], Iterator)
' inout(parsed_text)' '''Move everything containt into 'interface' below the first instance of s_type who preced it
l = [NoDep, Declaration, Implicit, Use, Cont_provider] Note:
for _, text in parsed_text: = This function is unpur
move_to_top_list(text, l) '''
# Get the born of the interface
i_begin = [ i for i, (_, line) in enumerate(parsed_text) if isinstance(line,Interface) ]
i_end = [ i+1 for i, (_, line) in enumerate(parsed_text) if isinstance(line,End_interface) ]
# Get the begin of the insert
i_insert = []
for begin in i_begin:
i_insert.append(next(i+1 for i in range(begin,-1,-1) if isinstance(parsed_text[i][1], s_type)))
# Do the insert and the delete in one passe
for insert, begin, end in zip(i_insert,i_begin,i_end):
parsed_text[insert:insert] = parsed_text[begin:end]
padding = end-begin
parsed_text[begin+padding:end+padding] = []
###################################################################### ######################################################################
def build_sub_needs(parsed_text, d_subroutine): def build_sub_needs(parsed_text, d_subroutine):
#(List[ Tuple[List[Entity], Tuple[int,List[Line]] ]]) -> None #(List[ Tuple[List[Entity], Tuple[int,List[Line]] ]], Dict[str:Sub]) -> None
'''Set the needs, and provides arguements of Routine present in parsed_text '''Set the needs, and provides arguements of Routine present in parsed_text
Note: Note:
@ -299,8 +330,10 @@ def add_subroutine_needs(parsed_text, subroutines):
###################################################################### ######################################################################
def move_variables(parsed_text): def move_variables(parsed_text):
#(List[ Tuple[List[Entity], Tuple[int,List[Line]] ]]
'''Move variables into the top of the declaraiton''' '''Move variables into the top of the declaraiton'''
def func(filename, text): def func(filename, text):
result = [] result = []
append = result.append append = result.append
@ -313,8 +346,17 @@ def move_variables(parsed_text):
old_elsevars = [] old_elsevars = []
revtext = list(text) revtext = list(text)
revtext.reverse() revtext.reverse()
skip_interface = False
try: try:
for vars, line in revtext: for vars, line in revtext:
if type(line) in [Interface, End_interface]:
skip_interface = not skip_interface
if skip_interface:
append(([], line))
continue
if type(line) in [End_provider, End]: if type(line) in [End_provider, End]:
varlist = [] varlist = []
append(([], line)) append(([], line))
@ -357,7 +399,10 @@ def move_variables(parsed_text):
varlist += vars varlist += vars
append(([], line)) append(([], line))
except: except:
error.fail(line, "Unable to parse file") from util import logger
logger.error("Unable to parse file %s", line)
import sys
sys.exit(1)
result.reverse() result.reverse()
@ -369,7 +414,7 @@ def move_variables(parsed_text):
varlist = [] varlist = []
try: try:
for vars, line in text: for vars, line in text:
if vars != []: if vars:
vars = uniquify(vars) vars = uniquify(vars)
if type(line) in [Begin_provider, Program, Subroutine, Function]: if type(line) in [Begin_provider, Program, Subroutine, Function]:
varlist = list(vars) varlist = list(vars)