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:
parent
3032e754a7
commit
34854ce1f5
@ -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)
|
||||||
|
@ -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 += [
|
||||||
|
@ -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)
|
||||||
|
@ -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):
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user