diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ef7cd62 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +packages/.rpmmacros +packages/*.tar.gz +packages/*.rpm +packages/sourceforge.sh +packages/version +src/*.pyc +irpf90.make +irpf90_entities +IRPF90_temp +IRPF90_man diff --git a/bin/irpf90 b/bin/irpf90 index a2d974d..a79c7e9 100755 --- a/bin/irpf90 +++ b/bin/irpf90 @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python -u # IRPF90 is a Fortran90 preprocessor written in Python for programming using # the Implicit Reference to Parameters (IRP) method. # Copyright (C) 2009 Anthony SCEMAMA diff --git a/example/Makefile b/example/Makefile index 0612439..4602bb7 100644 --- a/example/Makefile +++ b/example/Makefile @@ -1,6 +1,6 @@ IRPF90 = irpf90 #-a -d FC = gfortran -FCFLAGS= -ffree-line-length-none -O2 +FCFLAGS= -O2 SRC= OBJ= diff --git a/src/command_line.py b/src/command_line.py index dbabc7d..f3c50b2 100644 --- a/src/command_line.py +++ b/src/command_line.py @@ -36,9 +36,10 @@ options['a'] = [ 'assert' , 'Activate assertions', 0 ] options['h'] = [ 'help' , 'Print this help', 0 ] options['i'] = [ 'init' , 'Initialize current directory', 0 ] options['D'] = [ 'define' , 'Define variable', 1 ] +options['o'] = [ 'checkopt' , 'Show where optimization may be required', 0 ] options['p'] = [ 'preprocess' , 'Preprocess file', 1 ] -options['o'] = [ 'openmp' , 'Auto-parallelization', 0 ] -options['m'] = [ 'memory' , 'Debug memory', 0 ] +options['t'] = [ 'openmp' , 'Task Auto-parallelization', 0 ] +options['m'] = [ 'memory' , 'Debug memory info', 0 ] class CommandLine(object): diff --git a/src/irp_stack.py b/src/irp_stack.py index b12ca6c..74550ee 100644 --- a/src/irp_stack.py +++ b/src/irp_stack.py @@ -57,6 +57,15 @@ $OMP_DECL ithread = $OMP_GET_THREAD_NUM nthread = $OMP_GET_NUM_THREADS $1 +""" + if command_line.do_memory: + txt+=""" + if (.not.alloc) then + print *, 'Allocating irp_stack(',STACKMAX,',',nthread,')' + print *, 'Allocating irp_cpu(',STACKMAX,',',nthread,')' + print *, 'Allocating stack_index(',nthread,')' + endif""" + txt +=""" $2 end subroutine diff --git a/src/makefile.py b/src/makefile.py index bb702fe..c6736bc 100644 --- a/src/makefile.py +++ b/src/makefile.py @@ -43,7 +43,7 @@ def create(): file = open(FILENAME,"w") t = """IRPF90 = irpf90 #-a -d FC = gfortran -FCFLAGS= -ffree-line-length-none -O2 +FCFLAGS= -O2 SRC= OBJ= diff --git a/src/parsed_text.py b/src/parsed_text.py index 7100c17..94ee199 100644 --- a/src/parsed_text.py +++ b/src/parsed_text.py @@ -33,14 +33,16 @@ from subroutines import subroutines import regexps import error -vtuple = map(lambda v: (v, variables[v], variables[v].same_as, variables[v].regexp), variables.keys()) +vtuple = map(lambda v: (v, variables[v].same_as, variables[v].regexp), variables.keys()) +stuple = map(lambda s: (s, subroutines[s].regexp), subroutines.keys()) +stuple = filter(lambda s: subroutines[s[0]].is_function, stuple) def find_variables_in_line(line): assert isinstance(line,Line) result = [] sub_done = False buffer = line.text.lower() - for v,var,same_as,regexp in vtuple: + for v,same_as,regexp in vtuple: if v in buffer: if not sub_done: buffer = regexps.re_string.sub('',buffer) @@ -49,6 +51,18 @@ def find_variables_in_line(line): result.append(same_as) return result +def find_funcs_in_line(line): + assert isinstance(line,Line) + result = [] + sub_done = False + buffer = line.text.lower() + for s,regexp in stuple: + if s in buffer: + if regexp.search(buffer) is not None: + result.append(s) + return result + + def find_subroutine_in_line(line): assert isinstance(line,Call) buffer = line.text.split('(')[0] @@ -108,17 +122,16 @@ def get_parsed_text(): error.fail(line,"Variable %s is unknown"%(v)) result.append( (l,Simple_line(line.i,"!%s"%(line.text),line.filename)) ) elif isinstance(line,Call): + l = find_variables_in_line(line) + l = filter(lambda x: x not in varlist, l) sub = find_subroutine_in_line(line) if sub not in subroutines: t = Simple_line + result.append( (l,Simple_line(line.i,line.text,line.filename)) ) else: - if subroutines[sub].touches == []: - t = Simple_line - else: - t = Provide_all - l = find_variables_in_line(line) - l = filter(lambda x: x not in varlist, l) - result.append( (l,t(line.i,line.text,line.filename)) ) + result.append( (l,line) ) + if subroutines[sub].touches != []: + result.append( ([],Provide_all(line.i,"",line.filename)) ) elif isinstance(line,Free): vars = line.text.split() if len(vars) < 2: @@ -186,7 +199,10 @@ def get_parsed_text(): return main_result parsed_text = get_parsed_text() + + ###################################################################### + def move_to_top(text,t): assert isinstance(text,list) assert t in [ Declaration, Implicit, Use, Cont_provider ] @@ -236,35 +252,30 @@ def move_variables(): varlist = [] result.append( ([],line) ) elif type(line) in [ Endif, End_select ]: - old_ifvars.append(ifvars) - old_elsevars.append(elsevars) - old_varlist.append(varlist) + old_ifvars.append( list(ifvars) ) + old_elsevars.append( list(elsevars) ) + old_varlist.append( list(varlist) ) varlist = [] result.append( ([],line) ) elif type(line) == Else: + elsevars += list(varlist) result.append( (varlist,line) ) - elsevars = list(varlist) - if vars != []: - varlist = old_varlist.pop() - varlist += vars - old_varlist.append(varlist) varlist = [] elif type(line) in [ Elseif, Case ]: - ifvars += varlist + ifvars += list(varlist) result.append( (varlist,line) ) if vars != []: varlist = old_varlist.pop() varlist += vars - old_varlist.append(varlist) + old_varlist.append( list(varlist) ) varlist = [] elif type(line) in [ If, Select ]: - ifvars += varlist + ifvars += list(varlist) result.append( (varlist,line) ) vars += filter(lambda x: x in elsevars, ifvars) ifvars = old_ifvars.pop() elsevars = old_elsevars.pop() - varlist = old_varlist.pop() - varlist += vars + varlist = old_varlist.pop() + vars elif type(line) in [ Begin_provider, Subroutine, Function ]: varlist += vars result.append( (varlist,line) ) @@ -279,6 +290,7 @@ def move_variables(): varlist += vars result.append( ([],line) ) result.reverse() + # 2nd pass text = result result = [] @@ -313,6 +325,39 @@ def move_variables(): return main_result parsed_text = move_variables() +###################################################################### +def build_sub_needs(): + # Needs + for filename, text in parsed_text: + sub = None + for vars,line in text: + if type(line) in [ Subroutine, Function ]: + subname = find_subname(line) + sub = subroutines[subname] + sub.needs = [] + sub.to_provide = vars + elif isinstance(line,End): + sub.needs = make_single(sub.needs) + sub = None + if sub is not None: + sub.needs += vars + +build_sub_needs() +##################################################################### + +def add_subroutine_needs(): + main_result = [] + for filename, text in parsed_text: + result = [] + for vars,line in text: + if isinstance(line,Call): + subname = find_subname(line) + vars = subroutines[subname].to_provide + result.append( (vars,line) ) + main_result.append( (filename, result) ) + return main_result + +parsed_text = add_subroutine_needs() ###################################################################### def build_needs(): @@ -331,6 +376,17 @@ def build_needs(): var = None if var is not None: var.needs += vars + if isinstance(line,Call): + subname = find_subname(line) + var.needs += subroutines[subname].needs + elif type(line) in [ \ + Simple_line, Assert, + Do , If, + Elseif , Select, + ]: + funcs = find_funcs_in_line(line) + for f in funcs: + var.needs += subroutines[f].needs for v in variables.keys(): main = variables[v].same_as if main != v: @@ -365,10 +421,30 @@ for filename,text in parsed_text: result.append ( (filename,text) ) parsed_text = result +###################################################################### +from command_line import command_line + +def check_opt(): + if not command_line.do_checkopt: + return + + for filename, text in parsed_text: + do_level = 0 + for vars,line in text: + if do_level > 0 and vars != []: + print "Optimization: %s line %d"%(line.filename,line.i) + for v in vars: + print " PROVIDE ",v + if isinstance(line,Do): + do_level += 1 + elif isinstance(line,Enddo): + do_level -= 1 +check_opt() + ###################################################################### if __name__ == '__main__': for i in range(len(parsed_text)): - if parsed_text[i][0] == 'libqcio_groups.irp.f': + if parsed_text[i][0] == 'properties.irp.f': print '!-------- %s -----------'%(parsed_text[i][0]) for line in parsed_text[i][1]: print line[1] diff --git a/src/preprocessed_text.py b/src/preprocessed_text.py index cdd30c0..9bb3c5f 100644 --- a/src/preprocessed_text.py +++ b/src/preprocessed_text.py @@ -304,14 +304,14 @@ def remove_continuation(text,form): if form == Free_form: for line in text: if line.text[-1] == '&': - buffer = "%s%s "%(buffer,line.text[:-1].lstrip()) + buffer = "%s%s\n"%(buffer,line.text) if number == 0: t = type(line) number = line.i else: if number != 0: newline = t(number, \ - "%s%s"%(buffer,line.text.lstrip()), \ + "%s%s"%(buffer,line.text), \ line.filename) line = newline number = 0 @@ -327,7 +327,7 @@ def remove_continuation(text,form): if line.text[5] != ' ': is_continuation = True if is_continuation: - buffer = "%s %s"%(line.text[6:].lstrip(),buffer) + buffer = "&\n%s %s %s"%(line.text[:5],line.text[6:],buffer) else: line.text = line.text+buffer result.insert(0,line) diff --git a/src/regexps.py b/src/regexps.py index c5f30a6..0b19934 100644 --- a/src/regexps.py +++ b/src/regexps.py @@ -51,5 +51,5 @@ re_decl = re.compile( "".join( [ r"^\ *", re_test = re.compile(r"\( *(.*)(\.[a-zA-Z]*\.|[<>]=?|[=/]=)([^=]*)\)") -re_string = re.compile(r"'.*'") +re_string = re.compile(r"'.*?'") diff --git a/src/subroutine.py b/src/subroutine.py index 610fa9f..e17b085 100644 --- a/src/subroutine.py +++ b/src/subroutine.py @@ -46,6 +46,13 @@ class Sub(object): return self._name name = property(name) + ############################################################ + def is_function(self): + if '_is_function' not in self.__dict__: + self._is_function = "function" in self.line.text.lower() + return self._is_function + is_function = property(is_function) + ############################################################ def doc(self): if '_doc' not in self.__dict__: diff --git a/src/subroutines.py b/src/subroutines.py index 0f5055e..5491e95 100644 --- a/src/subroutines.py +++ b/src/subroutines.py @@ -35,7 +35,7 @@ def create_subroutines(): buffer = [] inside = False for line in text: - if isinstance(line,Subroutine): + if type(line) in [ Subroutine, Function ]: inside = True if inside: buffer.append(line) diff --git a/src/util.py b/src/util.py index 1aa8ab4..edd51a8 100644 --- a/src/util.py +++ b/src/util.py @@ -39,12 +39,14 @@ def same_file(filename,txt): file = open(filename,"r") except IOError: return False - lines = file.readlines() + stream = file.read() file.close() - if len(lines) != len(txt): + + buffer = ''.join(txt) + + if len(stream) != len(buffer): return False - for a,b in zip(lines,txt): - if a != b: + if stream != buffer: return False return True @@ -69,11 +71,7 @@ def find_subname(line): if not buffer.endswith(')'): buffer += "()" buffer = buffer.split('(') - if len(buffer) > 1: - buffer = " ".join(buffer[:-1]) - else: - buffer = buffer[0] - buffer = buffer.lower().split() + buffer = buffer[0].lower().split() if len(buffer) < 2: error.fail(line,"Syntax Error") return buffer[-1] diff --git a/src/variable.py b/src/variable.py index d799e35..5fb6086 100644 --- a/src/variable.py +++ b/src/variable.py @@ -191,7 +191,6 @@ class Variable(object): if '_regexp' not in self.__dict__: import re self._regexp = re.compile( \ - #r"^.*[^a-z0-9'\"_]+%s([^a-z0-9_]|$)"%(self.name),re.I) r"([^a-z0-9'\"_]|^)%s([^a-z0-9_]|$)"%(self.name),re.I) return self._regexp regexp = property(regexp) @@ -406,15 +405,23 @@ class Variable(object): result = " allocate(%s(%s),stat=irp_err)" result = result%(name,','.join(self.dim)) if command_line.do_memory: - tmp = "\n print *, 'Allocating %s(%s)'" - result += tmp%(name,','.join(self.dim)) + tmp = "\n print *, 'Allocating %s(%s), (',%s,')'" + d = ','.join(self.dim) + if ":" in d: + result += tmp%(name,d,"''") + else: + result += tmp%(name,d,d) return result result = [ " if (allocated (%s) ) then"%(name) ] result += dimensions_OK() result += [\ " if (.not.irp_dimensions_OK) then", - " deallocate(%s)"%(name) ] + " deallocate(%s,stat=irp_err)"%(name), + " if (irp_err /= 0) then", + " print *, irp_here//': Deallocation failed: %s'"%(name), + do_size(), + " endif"] if command_line.do_memory: result += [\ " print *, 'Deallocating %s'"%(name) ] diff --git a/src/version.py b/src/version.py index 504db19..9630c29 100644 --- a/src/version.py +++ b/src/version.py @@ -1 +1 @@ -version = "1.1.31" +version = "1.1.43"