Commit a4f649ba authored by erodrigu's avatar erodrigu
Browse files

This is a combination of 6 commits.

Move remove_indexing at the top of the function

Updated the REGEX structure, now it captures N members depth

Changed functions fix_subprogram_calls to properly check functions inside IF

Avoid misplaced blocks on update_blocks

Update text and blocks after finishing the loop

Capture write statements with a REGEX and case insensitive
parent 1f25391e
......@@ -208,7 +208,7 @@ class Module(ReadSourceFile):
# If the line corresponds to the end of a procedure, returns None
# If is neither one of these cases, returns the same procedure
block = self.main
parent_block = None
parent_block = block
# Rebuild the text
text = "".join([l + "\n" for l in self.lines[:] if l.strip()])
self.lines = text.split("\n")
......@@ -224,7 +224,7 @@ class Module(ReadSourceFile):
elif _line.lower().count("function"):
_pattern = RegexPattern.function_declaration
_group_idx = 0
elif _line.lower().find("type") == 0:
elif _line.lower().count("type"):
_group_idx = -1
_pattern = RegexPattern.general_type_declaration
# We are changing block
......
......@@ -16,6 +16,11 @@ def get_variable(contents, procedure=None, vault=None):
contents = BasicFunctions.remove_literals(contents)
# Remove the indexing from array and DT:
# ght_abl <-- ght_abl(2:jpka)
# todelay%z1d <-- todelay(ji)%z1d(:)
contents = remove_indexing(contents)
if NatureDeterminer.has_intrinsics(contents):
raise Error.VariableNotFound("The string %s is not a variable" % contents)
if NatureDeterminer.is_an_hardcoded_array(contents):
......@@ -27,10 +32,6 @@ def get_variable(contents, procedure=None, vault=None):
if NatureDeterminer.has_operations(contents):
raise Error.VariableNotFound("The string %s is not a variable" % contents)
# Remove the indexing from array and DT:
# ght_abl <-- ght_abl(2:jpka)
# todelay%z1d <-- todelay(ji)%z1d(:)
contents = remove_indexing(contents)
if re.search(RegexPattern.variable, contents):
try:
return vault.get_variable_by_name(var_name=contents, procedure=procedure)
......
......@@ -242,8 +242,8 @@ class ImplementRPE:
pattern = "^[^\!]*\s*write\([^()]*\) (.*)."
for l_index, line in enumerate(module.lines):
if re.search("WRITE *\(", line):
wc = BasicFunctions.close_brackets(line[line.find("WRITE"):])
if re.search("(?<!\w)(WRITE) *\(", line, re.IGNORECASE):
wc = BasicFunctions.close_brackets(line[line.lower().find("write"):])
line = line.replace(wc, "WRITE()")
matches = re.search(pattern, line.strip(), re.IGNORECASE)
......@@ -387,6 +387,7 @@ class ImplementRPE:
return temporal_call.strip()
def _fix_arguments(self, line, subprogram_call):
original_line = line
for s_call in subprogram_call:
if not s_call.subprogram.is_external:
for arg, dummy_a in zip(s_call.arguments, s_call.dummy_arguments):
......@@ -416,29 +417,27 @@ class ImplementRPE:
Error.ExceptionNotManaged("Here we should use temporal variables")
else:
line = self._fix_external_call(s_call, line)
return line
def _check_and_fix_call(self, line, search_line, block):
subprogram_call = \
CallManager.get_procedure_inline(search_line, self.vault, block)
# If something was found check if can be fixed
if subprogram_call:
temp = self._fix_arguments(search_line, subprogram_call)
return line.replace(search_line, temp)
# Nothing needed to be fixed
if original_line == line:
return None
return line
def fix_subprogram_calls(self, module):
# Returns arguments of subprograms call and corresponding type and dummy
for _index, line in enumerate(module.lines):
if line.replace(" ", "").lower().strip().find("if(") == 0:
line = self._check_and_fix_call(line, line, module.blocks[_index])
temporal_call = BasicFunctions.remove_if_condition(line)
line = self._check_and_fix_call(line, temporal_call, module.blocks[_index])
if_condition, conditional_piece = BasicFunctions.split_if_condition(line)
for piece in if_condition, conditional_piece:
subprogram_call = \
CallManager.get_procedure_inline(piece, self.vault, module.blocks[_index])
# If something was found check if it has to be fixed
if subprogram_call:
fix = self._fix_arguments(piece, subprogram_call)
# Something needed fix: substitute in line
if fix:
line = line.replace(piece, fix)
module.lines[_index] = line
def _find_kind_of_parameter_declaration(self, argument, procedure):
"""Return the nature of the parameter declaration. Depending on the type, the fix will be different"""
# These are real, but need some manipulation before adding the RPE constructor
......
......@@ -86,7 +86,7 @@ def add_sbits_to_rpe_variables(vault):
# Allocatable
for variable in allocatable:
insert_variable_precision_specification_to_allocatable(variable, var_counter)
insert_variable_precision_specification_to_allocatable(variable, var_counter, vault)
# Non allocatable that appear in a namelist
na_in_namelist, na_not_in_namelist = Splitter.split_by_appearance_in_namelist(non_allocatable)
......@@ -97,7 +97,7 @@ def add_sbits_to_rpe_variables(vault):
# Variables inside routines
for variable in not_in_main:
if not isinstance(variable.procedure, BasicStructures.DerivedType) and variable.intent != "in":
insert_variable_precision_to_routine_variable(variable, var_counter)
insert_variable_precision_to_routine_variable(variable, var_counter, vault)
# Adding sbits assignation and apply_truncation after routine calls
insert_variable_precision_after_subroutine_call(vault, var_counter)
......@@ -151,21 +151,16 @@ def insert_variable_precision_specification(variable, module, insertion_line, co
var_name = member_name if member_name else variable.name
# Add apply_truncation
new_line = condition + " CALL apply_truncation(%s)" % var_name
module.lines.insert(insertion_line, new_line)
module.lines[insertion_line] += "\n" + condition + " CALL apply_truncation(%s)" % var_name
# Add sbits
new_line = condition + " %s%%sbits = emulator_variable_precisions(%i)" % (var_name, variable.id)
module.lines.insert(insertion_line, new_line)
module.lines[insertion_line] += "\n" + condition + " %s%%sbits = emulator_variable_precisions(%i)" % (var_name, variable.id)
# Add variable usage specification
new_line = condition + " variable_is_used(%i) = .true." % variable.id
module.lines.insert(insertion_line, new_line)
module.rebuild_text()
module.lines[insertion_line] += "\n" + condition + " variable_is_used(%i) = .true." % variable.id
def insert_variable_precision_specification_to_allocatable(variable, counter_object):
def insert_variable_precision_specification_to_allocatable(variable, counter_object, vault):
for module in [variable.module] + variable.procedure.module.used_by:
for line_index, line in enumerate(module.lines):
if re.search(RegexPattern.allocation_variable_name % variable.name, line, re.I):
......@@ -176,8 +171,12 @@ def insert_variable_precision_specification_to_allocatable(variable, counter_obj
for arg in arguments:
cleaned_arg = Getter.remove_indexing(arg)
if cleaned_arg.count(variable.name):
# Remove array arguments (if any) and get only the member and var: foo%var(2:3) --> foo%var
# Get variable name without indexing (foo(n)%var --> foo%var)
member_name = arg.split(variable.name)[0] + variable.name
member_type = Getter.get_type_of_contents(member_name, module.blocks[line_index], vault)
# Fix only if it's an rpe_var
if member_type != 'rpe_var':
member_name = None
break
if not member_name:
continue
......@@ -185,10 +184,15 @@ def insert_variable_precision_specification_to_allocatable(variable, counter_obj
# Check that we did not match a member with the same name: a_i will also match %a_i
if re.search(RegexPattern.allocation_member_name % variable.name, line.replace(" ",""), re.I):
continue
variable.id = counter_object.count
variable.mutable = True
counter_object.up()
insert_variable_precision_specification(variable, module, line_index + 1, member_name=member_name)
insert_variable_precision_specification(variable, module, line_index, member_name=member_name)
module.rebuild_text()
module.update_blocks(vault)
return
......@@ -203,10 +207,12 @@ def insert_variable_precision_specification_to_namelist_parameter(variable, coun
variable.id = counter_object.count
variable.mutable = True
counter_object.up()
insert_variable_precision_specification(variable, module, index + 1)
insert_variable_precision_specification(variable, module, index)
module.rebuild_text()
module.update_blocks(vault)
def insert_variable_precision_to_routine_variable(variable, counter_object):
def insert_variable_precision_to_routine_variable(variable, counter_object, vault):
module, first_use_line = find_first_use(variable)
if module:
variable.id = counter_object.count
......@@ -222,6 +228,8 @@ def insert_variable_precision_to_routine_variable(variable, counter_object):
if variable.is_member_of:
member_name = BasicFunctions.remove_if_condition(_line).split(variable.name)[0] + variable.name
insert_variable_precision_specification(variable, module, first_use_line, condition, member_name)
module.rebuild_text()
module.update_blocks(vault)
else:
warnings.warn("Variable %s not found %s in routine %s" % (
variable.name, variable.procedure.module.name, variable.procedure.name))
......@@ -246,6 +254,7 @@ def insert_variable_precision_after_subroutine_call(vault, counter):
module.lines[_index] = line.replace(temporal_call[1],
_add_argument_truncation(temporal_call, subroutine_calls, counter))
module.rebuild_text()
module.update_blocks(vault)
# End fo rpe insertion
......
......@@ -18,8 +18,8 @@ array_with_member = array + r"%\w+"
array_with_array_member = array + "%" + array
###### STRUCTURE
# Simple strucure a%b%c
structure = r"\w+%*\w*%\w+"
# Simple multulayer strucure a%b%c%...
structure = r"\w+(?:%\w+)+"
# Simple structure with array member a%b(:)
structure_with_member_array = r"\w+%" + array
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment