From 3032e754a7173ae8d09ec92b5362e6a22a3a0262 Mon Sep 17 00:00:00 2001 From: Thomas Applencourt Date: Mon, 23 Jan 2017 08:51:58 -0600 Subject: [PATCH] add support for WHERE statement --- src/build_file.py | 68 ++++++++++++++++++++++------------------ src/irpf90_t.py | 4 +-- src/module.py | 17 +++++++--- src/preprocessed_text.py | 25 ++++++++++----- 4 files changed, 70 insertions(+), 44 deletions(-) diff --git a/src/build_file.py b/src/build_file.py index b856367..1782a3c 100644 --- a/src/build_file.py +++ b/src/build_file.py @@ -180,9 +180,15 @@ def create_build_compile(t, l_module, l_ext_modfile=[], ninja=True): # MOD name are not part of the standart. needed_modules = [dress(x, in_root=True) for x in l_ext_modfile] - needed_modules += [ - "%s.irp.o" % (x.filename) for x in l_module if x.name in t.needed_modules_usr - ] + + # Expensive and stupid. We can create a dict to do the loockup only once + for m in t.needed_modules_usr: + for x in l_module: + if m in x.gen_mod and x.filename != t.filename: + needed_modules.append("%s.irp.o" % x.filename) + + from util import uniquify + needed_modules = uniquify(needed_modules) needed_modules_irp = [ "%s.irp.module.o" % (x.filename) for x in l_module if x.name in t.needed_modules_irp @@ -200,12 +206,13 @@ def create_build_compile(t, l_module, l_ext_modfile=[], ninja=True): list_of_modules = ' '.join(map(dress, needed_modules)) list_of_modules_irp = ' '.join(map(dress, needed_modules_irp)) - inline_module = True - if not inline_module: + inline_include = True + if not inline_include: #Wrong name, this not work! #list_of_includes = ' '.join(map(lambda x: dress(x, in_root=True), t.includes)) raise NotImplemented else: + #The include have already by included list_of_includes = ' ' l_build = [ @@ -283,24 +290,23 @@ def create_makefile(d_flags,d_var,irpf90_flags,ninja=True): '\n'.join("{0} = {1}".format(k, ' '.join(v)) for k, v in sorted(d_var.iteritems())), ''] - result += [ -r'# Dark magic below modify with caution!', -r'# "You are Not Expected to Understand This"', -r"# .", -r"# /^\ .", -r'# /\ "V",', -r"# /__\ I O o", -r"# //..\\ I .", -r"# \].`[/ I", -r"# /l\/j\ (] . O", -r"# /. ~~ ,\/I .", -r"# \\L__j^\/I o", -r"# \/--v} I o .", -r"# | | I _________", -r"# | | I c(` ')o", -r"# | l I \. ,/", -r"# _/j L l\_! _//^---^\\_", -r""] + result += [ r'# Dark magic below modify with caution!', + r'# "You are Not Expected to Understand This"', + r"# .", + r"# /^\ .", + r'# /\ "V",', + r"# /__\ I O o", + r"# //..\\ I .", + r"# \].`[/ I", + r"# /l\/j\ (] . O", + r"# /. ~~ ,\/I .", + r"# \\L__j^\/I o", + r"# \/--v} I o .", + r"# | | I _________", + r"# | | I c(` ')o", + r"# | l I \. ,/", + r"# _/j L l\_! _//^---^\\_", + r""] result += ["", "ifeq ($(BUILD_SYSTEM),ninja)", @@ -309,16 +315,16 @@ r""] "else ifeq ($(BUILD_SYSTEM),make)", "\tBUILD_FILE=IRPF90_temp/build.make", "\tBUILD_SYSTEM += -j", -"else", -"DUMMY:", - "\t$(error 'Wrong BUILD_SYSTEM: $(BUILD_SYSTEM)')", -"endif"] + "else", + "DUMMY:", + "\t$(error 'Wrong BUILD_SYSTEM: $(BUILD_SYSTEM)')", + "endif"] result += ["", -"define run_and_touch", -" $(BUILD_SYSTEM) -C $(dir $(1) ) -f $(notdir $(1) ) $(addprefix $(CURDIR)/, $(2)) && touch $(2)", -"endef", - "", + "define run_and_touch", + " $(BUILD_SYSTEM) -C $(dir $(1) ) -f $(notdir $(1) ) $(addprefix $(CURDIR)/, $(2)) && touch $(2)", + "endef", + "", "EXE := $(shell egrep -ri '^\s*program' *.irp.f | cut -d'.' -f1)", "", ".PHONY: all", diff --git a/src/irpf90_t.py b/src/irpf90_t.py index b58a78c..6011c25 100644 --- a/src/irpf90_t.py +++ b/src/irpf90_t.py @@ -75,8 +75,8 @@ l_type = [ "Assert", "Touch", "SoftTouch", "Irp_read", "Irp_write", "Irp_If", "Irp_Else", "Irp_Endif", "Openmp", "Directive", "Use", "Do", "Enddo", "If", "Elseif", "Else", "Endif", "Select", "Case", "End_select", "Provide", "NoDep", "Return", "Include", - "Implicit", "Free", "End", "Provide_all","Contains",'Type','End_module','Interface','End_interface' -] + "Implicit", "Free", "End", "Provide_all","Contains",'Type','End_module','Interface','End_interface', + 'Where','Elsewhere','Endwhere'] for t in l_type: globals()[t] = type(t, (Line, ), {}) diff --git a/src/module.py b/src/module.py index 2885b62..e94be9d 100644 --- a/src/module.py +++ b/src/module.py @@ -155,11 +155,15 @@ class Fmodule(object): result = [] dec = [] use = [] + module = [] for vars, line in text: if isinstance(line, (Subroutine, Function, Program,Interface,Module)): inside += 1 + if type(line) == Module: + module.append((vars,line)) + if inside: result.append((vars, line)) else: @@ -167,6 +171,7 @@ class Fmodule(object): use.append((vars, line)) elif type(line) == Declaration: dec.append((vars, line)) + if isinstance(line,(End,End_interface,End_module)): inside += -1 @@ -175,13 +180,13 @@ class Fmodule(object): print 'Something wrong append' sys.exit(1) - return use, dec, result + return use, module, dec, result result = remove_providers(self.text) result = modify_functions(result) from collections import namedtuple - Residual_text_use_dec = namedtuple('Residual_text_use_dec', ['use', 'dec', 'result']) + Residual_text_use_dec = namedtuple('Residual_text_use_dec', ['use', 'module', 'dec', 'result']) return Residual_text_use_dec(*extract_use_dec_text(result)) @@ -189,6 +194,11 @@ class Fmodule(object): def use(self): return set(" %s" % line.text for _, line in self.residual_text_use_dec.use) + @irpy.lazy_property + def gen_mod(self): + '''List of module generated by the user in this module...''' + return set("%s" % line.subname for _, line in self.residual_text_use_dec.module) + @irpy.lazy_property def dec(self): '''The declaration of this module @@ -230,8 +240,7 @@ class Fmodule(object): @irpy.lazy_property def needed_modules(self): - l = set(x.split()[1] for x in self.generated_text + self.head + self.residual_text - if x.lstrip().startswith("use ")) + l = set(x.split(',only').pop(0).split()[1] for x in self.generated_text + self.head + self.residual_text if x.lstrip().startswith("use ")) if self.name in l: l.remove(self.name) diff --git a/src/preprocessed_text.py b/src/preprocessed_text.py index 6fbece7..e24fea3 100644 --- a/src/preprocessed_text.py +++ b/src/preprocessed_text.py @@ -34,6 +34,8 @@ import sys re_endif = re.compile("end +if") re_elseif = re.compile("else +if") re_enddo = re.compile("end +do") +re_endwhere = re.compile("end +where") + re_endtype = re.compile("end +type.*") re_endmodule = re.compile("end +module",re.I) re_endselect = re.compile("end +select") @@ -91,7 +93,10 @@ simple_dict = { "module": Module, "endmodule": End_module, "interface": Interface, - "endinterface": End_interface + "endinterface": End_interface, + "where": Where, + "elsewhere": Elsewhere, + "endwhere": Endwhere, } def get_canonized_text(text_lower): @@ -104,6 +109,7 @@ def get_canonized_text(text_lower): text_canonized = re_endif.sub("endif", text_canonized) text_canonized = re_endselect.sub("endselect", text_canonized) text_canonized = re_endinterface.sub("endinterface", text_canonized) + text_canonized = re_endwhere.sub('endwhere',text_canonized) for c in """()'"[]""": text_canonized = text_canonized.replace(c, " %s " % c) @@ -422,7 +428,7 @@ def remove_comments(text, form): inside = False elif c == '!' and not inside: - return str_[:i] + return str_[:i].strip() return str_ @@ -842,13 +848,18 @@ def check_begin_end(raw_text): for t_end, l_begin in d_block.iteritems(): n_end = len(d_type[t_end]) n_begin = sum(len(d_type[t_begin]) for t_begin in l_begin) - - if n_end > n_begin: + + if n_end != n_begin: + + if n_end > n_begin: logger.error("You have more close statement than open statement (%s) (%s)",line.filename,t_end) - sys.exit(1) - elif n_end < n_begin: + else: logger.error('You have more end statement than open statenemt for (%s) (%s)' % (line.filename, t_end)) - sys.exit(1) + + for i in zip([l for i in l_begin for l in d_type[i]], d_type[t_end]): + logger.debug(i) + + sys.exit(1) ###################################################################### def remove_ifdefs(text):