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): ...@@ -208,7 +208,7 @@ class Module(ReadSourceFile):
# If the line corresponds to the end of a procedure, returns None # If the line corresponds to the end of a procedure, returns None
# If is neither one of these cases, returns the same procedure # If is neither one of these cases, returns the same procedure
block = self.main block = self.main
parent_block = None parent_block = block
# Rebuild the text # Rebuild the text
text = "".join([l + "\n" for l in self.lines[:] if l.strip()]) text = "".join([l + "\n" for l in self.lines[:] if l.strip()])
self.lines = text.split("\n") self.lines = text.split("\n")
...@@ -224,7 +224,7 @@ class Module(ReadSourceFile): ...@@ -224,7 +224,7 @@ class Module(ReadSourceFile):
elif _line.lower().count("function"): elif _line.lower().count("function"):
_pattern = RegexPattern.function_declaration _pattern = RegexPattern.function_declaration
_group_idx = 0 _group_idx = 0
elif _line.lower().find("type") == 0: elif _line.lower().count("type"):
_group_idx = -1 _group_idx = -1
_pattern = RegexPattern.general_type_declaration _pattern = RegexPattern.general_type_declaration
# We are changing block # We are changing block
......
...@@ -16,6 +16,11 @@ def get_variable(contents, procedure=None, vault=None): ...@@ -16,6 +16,11 @@ def get_variable(contents, procedure=None, vault=None):
contents = BasicFunctions.remove_literals(contents) 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): if NatureDeterminer.has_intrinsics(contents):
raise Error.VariableNotFound("The string %s is not a variable" % contents) raise Error.VariableNotFound("The string %s is not a variable" % contents)
if NatureDeterminer.is_an_hardcoded_array(contents): if NatureDeterminer.is_an_hardcoded_array(contents):
...@@ -27,10 +32,6 @@ def get_variable(contents, procedure=None, vault=None): ...@@ -27,10 +32,6 @@ def get_variable(contents, procedure=None, vault=None):
if NatureDeterminer.has_operations(contents): if NatureDeterminer.has_operations(contents):
raise Error.VariableNotFound("The string %s is not a variable" % 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): if re.search(RegexPattern.variable, contents):
try: try:
return vault.get_variable_by_name(var_name=contents, procedure=procedure) return vault.get_variable_by_name(var_name=contents, procedure=procedure)
......
...@@ -242,8 +242,8 @@ class ImplementRPE: ...@@ -242,8 +242,8 @@ class ImplementRPE:
pattern = "^[^\!]*\s*write\([^()]*\) (.*)." pattern = "^[^\!]*\s*write\([^()]*\) (.*)."
for l_index, line in enumerate(module.lines): for l_index, line in enumerate(module.lines):
if re.search("WRITE *\(", line): if re.search("(?<!\w)(WRITE) *\(", line, re.IGNORECASE):
wc = BasicFunctions.close_brackets(line[line.find("WRITE"):]) wc = BasicFunctions.close_brackets(line[line.lower().find("write"):])
line = line.replace(wc, "WRITE()") line = line.replace(wc, "WRITE()")
matches = re.search(pattern, line.strip(), re.IGNORECASE) matches = re.search(pattern, line.strip(), re.IGNORECASE)
...@@ -387,6 +387,7 @@ class ImplementRPE: ...@@ -387,6 +387,7 @@ class ImplementRPE:
return temporal_call.strip() return temporal_call.strip()
def _fix_arguments(self, line, subprogram_call): def _fix_arguments(self, line, subprogram_call):
original_line = line
for s_call in subprogram_call: for s_call in subprogram_call:
if not s_call.subprogram.is_external: if not s_call.subprogram.is_external:
for arg, dummy_a in zip(s_call.arguments, s_call.dummy_arguments): for arg, dummy_a in zip(s_call.arguments, s_call.dummy_arguments):
...@@ -416,29 +417,27 @@ class ImplementRPE: ...@@ -416,29 +417,27 @@ class ImplementRPE:
Error.ExceptionNotManaged("Here we should use temporal variables") Error.ExceptionNotManaged("Here we should use temporal variables")
else: else:
line = self._fix_external_call(s_call, line) line = self._fix_external_call(s_call, line)
return line
def _check_and_fix_call(self, line, search_line, block): # Nothing needed to be fixed
subprogram_call = \ if original_line == line:
CallManager.get_procedure_inline(search_line, self.vault, block) return None
# 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)
return line return line
def fix_subprogram_calls(self, module): def fix_subprogram_calls(self, module):
# Returns arguments of subprograms call and corresponding type and dummy
for _index, line in enumerate(module.lines): for _index, line in enumerate(module.lines):
if line.replace(" ", "").lower().strip().find("if(") == 0: if_condition, conditional_piece = BasicFunctions.split_if_condition(line)
line = self._check_and_fix_call(line, line, module.blocks[_index]) for piece in if_condition, conditional_piece:
subprogram_call = \
temporal_call = BasicFunctions.remove_if_condition(line) CallManager.get_procedure_inline(piece, self.vault, module.blocks[_index])
line = self._check_and_fix_call(line, temporal_call, 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 module.lines[_index] = line
def _find_kind_of_parameter_declaration(self, argument, procedure): 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""" """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 # These are real, but need some manipulation before adding the RPE constructor
......
...@@ -86,7 +86,7 @@ def add_sbits_to_rpe_variables(vault): ...@@ -86,7 +86,7 @@ def add_sbits_to_rpe_variables(vault):
# Allocatable # Allocatable
for variable in 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 # Non allocatable that appear in a namelist
na_in_namelist, na_not_in_namelist = Splitter.split_by_appearance_in_namelist(non_allocatable) 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): ...@@ -97,7 +97,7 @@ def add_sbits_to_rpe_variables(vault):
# Variables inside routines # Variables inside routines
for variable in not_in_main: for variable in not_in_main:
if not isinstance(variable.procedure, BasicStructures.DerivedType) and variable.intent != "in": 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 # Adding sbits assignation and apply_truncation after routine calls
insert_variable_precision_after_subroutine_call(vault, var_counter) insert_variable_precision_after_subroutine_call(vault, var_counter)
...@@ -151,21 +151,16 @@ def insert_variable_precision_specification(variable, module, insertion_line, co ...@@ -151,21 +151,16 @@ def insert_variable_precision_specification(variable, module, insertion_line, co
var_name = member_name if member_name else variable.name var_name = member_name if member_name else variable.name
# Add apply_truncation # Add apply_truncation
new_line = condition + " CALL apply_truncation(%s)" % var_name module.lines[insertion_line] += "\n" + condition + " CALL apply_truncation(%s)" % var_name
module.lines.insert(insertion_line, new_line)
# Add sbits # Add sbits
new_line = condition + " %s%%sbits = emulator_variable_precisions(%i)" % (var_name, variable.id) module.lines[insertion_line] += "\n" + condition + " %s%%sbits = emulator_variable_precisions(%i)" % (var_name, variable.id)
module.lines.insert(insertion_line, new_line)
# Add variable usage specification # Add variable usage specification
new_line = condition + " variable_is_used(%i) = .true." % variable.id module.lines[insertion_line] += "\n" + condition + " variable_is_used(%i) = .true." % variable.id
module.lines.insert(insertion_line, new_line)
module.rebuild_text()
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 module in [variable.module] + variable.procedure.module.used_by:
for line_index, line in enumerate(module.lines): for line_index, line in enumerate(module.lines):
if re.search(RegexPattern.allocation_variable_name % variable.name, line, re.I): 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 ...@@ -176,8 +171,12 @@ def insert_variable_precision_specification_to_allocatable(variable, counter_obj
for arg in arguments: for arg in arguments:
cleaned_arg = Getter.remove_indexing(arg) cleaned_arg = Getter.remove_indexing(arg)
if cleaned_arg.count(variable.name): 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_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 break
if not member_name: if not member_name:
continue continue
...@@ -185,10 +184,15 @@ def insert_variable_precision_specification_to_allocatable(variable, counter_obj ...@@ -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 # 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): if re.search(RegexPattern.allocation_member_name % variable.name, line.replace(" ",""), re.I):
continue continue
variable.id = counter_object.count variable.id = counter_object.count
variable.mutable = True variable.mutable = True
counter_object.up() 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 return
...@@ -203,10 +207,12 @@ def insert_variable_precision_specification_to_namelist_parameter(variable, coun ...@@ -203,10 +207,12 @@ def insert_variable_precision_specification_to_namelist_parameter(variable, coun
variable.id = counter_object.count variable.id = counter_object.count
variable.mutable = True variable.mutable = True
counter_object.up() 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) module, first_use_line = find_first_use(variable)
if module: if module:
variable.id = counter_object.count variable.id = counter_object.count
...@@ -222,6 +228,8 @@ def insert_variable_precision_to_routine_variable(variable, counter_object): ...@@ -222,6 +228,8 @@ def insert_variable_precision_to_routine_variable(variable, counter_object):
if variable.is_member_of: if variable.is_member_of:
member_name = BasicFunctions.remove_if_condition(_line).split(variable.name)[0] + variable.name 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) insert_variable_precision_specification(variable, module, first_use_line, condition, member_name)
module.rebuild_text()
module.update_blocks(vault)
else: else:
warnings.warn("Variable %s not found %s in routine %s" % ( warnings.warn("Variable %s not found %s in routine %s" % (
variable.name, variable.procedure.module.name, variable.procedure.name)) variable.name, variable.procedure.module.name, variable.procedure.name))
...@@ -246,6 +254,7 @@ def insert_variable_precision_after_subroutine_call(vault, counter): ...@@ -246,6 +254,7 @@ def insert_variable_precision_after_subroutine_call(vault, counter):
module.lines[_index] = line.replace(temporal_call[1], module.lines[_index] = line.replace(temporal_call[1],
_add_argument_truncation(temporal_call, subroutine_calls, counter)) _add_argument_truncation(temporal_call, subroutine_calls, counter))
module.rebuild_text() module.rebuild_text()
module.update_blocks(vault)
# End fo rpe insertion # End fo rpe insertion
......
...@@ -18,8 +18,8 @@ array_with_member = array + r"%\w+" ...@@ -18,8 +18,8 @@ array_with_member = array + r"%\w+"
array_with_array_member = array + "%" + array array_with_array_member = array + "%" + array
###### STRUCTURE ###### STRUCTURE
# Simple strucure a%b%c # Simple multulayer strucure a%b%c%...
structure = r"\w+%*\w*%\w+" structure = r"\w+(?:%\w+)+"
# Simple structure with array member a%b(:) # Simple structure with array member a%b(:)
structure_with_member_array = r"\w+%" + array 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