diff --git a/src/module.py b/src/module.py index 4238c44..c77ad1d 100644 --- a/src/module.py +++ b/src/module.py @@ -3,6 +3,7 @@ from irpf90_t import * from variable import * from variables import variables +import preprocessed_text class Fmodule(object): @@ -10,13 +11,30 @@ class Fmodule(object): self.text = text self.name = "%s_mod"%(filename[:-6].lower()) + def put_info(text): + if len(text) > 0: + lenmax = 80 - len(filename) + format = "%"+str(lenmax)+"s ! %s:%4s" + for vars,line in text: + line.text = format%(line.text.ljust(lenmax),line.filename,str(line.i)) + return text + def is_main(self): if '_is_main' not in self.__dict__: - buffer = filter(lambda x: isinstance(x[1],Program),self.text) - self._is_main = (buffer != []) + self._is_main = self.prog_name is not None return self._is_main is_main = property(is_main) + def prog_name(self): + if '_prog_name' not in self.__dict__: + buffer = filter(lambda x: isinstance(x[1],Program),self.text) + if buffer == []: + self._prog_name = None + else: + self._prog_name = buffer[0][1].filename + return self._prog_name + prog_name = property(prog_name) + def variables(self): if '_variables' not in self.__dict__: from variables import variables @@ -27,7 +45,11 @@ class Fmodule(object): def head(self): if '_head' not in self.__dict__: - self._head = None + result = [ "module %s"%(self.name) ] + result += self.use + result += self.dec + result.append( "end module %s"%(self.name) ) + self._head = result return self._head head = property(head) @@ -41,16 +63,99 @@ class Fmodule(object): def generated_text(self): if '_generated_text' not in self.__dict__: - self._generated_text = None + result = [] + for var in self.variables: + var = variables[var] + result += var.provider + result += var.builder + if var.is_freed: + result += var.free + if var.is_touched: + result += var.toucher + if var.is_read: + result += var.reader + if var.is_written: + result += var.writer + self._generated_text = result return self._generated_text generated_text = property(generated_text) def residual_text(self): if '_residual_text' not in self.__dict__: - self._residual_text = None + from variables import build_use + def remove_providers(text): + result = [] + inside = False + for vars,line in text: + if isinstance(line,Begin_provider): + inside = True + if not inside: + result.append( (vars,line) ) + if isinstance(line,End_provider): + inside = False + return result + + def modify_functions(text): + result = [] + for vars,line in text: + if type(line) in [ Subroutine, Function ]: + variable_list = list(vars) + elif isinstance(line,End): + result += map(lambda x: ([],Use(line.i,x,line.filename)), build_use(variable_list)) + else: + variable_list += vars + result.append( (vars,line) ) + return result + + def extract_use_dec_text(text): + inside = False + result = [] + dec = [] + use = [] + for vars,line in text: + if type(line) in [ Subroutine, Function]: + inside = True + if inside: + result.append( (vars,line) ) + else: + if isinstance(line,Use): + use.append( (vars,line) ) + elif isinstance(line,Declaration): + dec.append( (vars,line) ) + if isinstance(line,End): + inside = False + return use, dec, result + + result = remove_providers(self.text) + result = modify_functions(result) + result = preprocessed_text.move_to_top(result,Declaration) + result = preprocessed_text.move_to_top(result,Use) + use,dec,result = extract_use_dec_text(result) + self._use = make_single(map(lambda x: " "+x[1].text, use)) + self._dec = make_single(map(lambda x: " "+x[1].text, dec)) + result = map(lambda x: " "+x[1].text, result) + if self.is_main: + result = [ \ + "program irp_program", + " call %s"%(self.prog_name), + "end irp_program", + ] + result + self._residual_text = result return self._residual_text residual_text = property(residual_text) + def use(self): + if '_use' not in self.__dict__: + self.residual_text + return self._use + use = property(use) + + def dec(self): + if '_dec' not in self.__dict__: + self.residual_text + return self._dec + dec = property(dec) + def needed_modules(self): if '_needed_modules' not in self.__dict__: buffer = filter(lambda x: isinstance(x,Use), self.generated_text) @@ -62,9 +167,9 @@ class Fmodule(object): if __name__ == '__main__': from parsed_text import parsed_text for filename, text in parsed_text: - if filename == 'electrons.irp.f': + if filename == 'random.irp.f': x = Fmodule(text,filename) break - print x.needed_vars - print x.is_main + for line in x.residual_text: + print line diff --git a/src/modules.py b/src/modules.py index 16aa3d1..19827fe 100644 --- a/src/modules.py +++ b/src/modules.py @@ -1,21 +1,5 @@ #!/usr/bin/python -def modify_functions(): - result = [] - for filename,text in parsed_text: - begin = -1 - for i, (vars,line) in enumerate(text): - if type(line) in [ Subroutine, Function ]: - text[i] = [ text[i] ] - variable_list = list(vars) - begin = i - elif type(line) in [ End_provider, End ]: - text[begin].insert(1,map(lambda x: ([],x), build_use(variable_list))) - else: - variable_list += vars - text = flatten(text) - result.append ( (filename, text) ) - def residual_text(): pass diff --git a/src/parsed_text.py b/src/parsed_text.py index 7fe4e9c..a42bb74 100644 --- a/src/parsed_text.py +++ b/src/parsed_text.py @@ -87,16 +87,26 @@ def get_parsed_text(): vars = line.text.split() if len(vars) < 2: error.fail(line,"Syntax error") - vars = vars[1:] + vars = map(lower,vars[1:]) + for v in vars: + variables[v].is_freed = True result.append( ([],Simple_line(line.i,"!%s"%(line.text),line.filename)) ) for var in vars: result.append( ([],Simple_line(line.i," call free_%s"%var, line.filename)) ) + elif isinstance(line,Irp_read): + variables[line.filename].is_read = True + result.append( ([],Simple_line(line.i,"!%s"%(line.text),line.filename)) ) + elif isinstance(line,Irp_write): + variables[line.filename].is_written = True + result.append( ([],Simple_line(line.i,"!%s"%(line.text),line.filename)) ) elif isinstance(line,Touch): vars = line.text.split() if len(vars) < 2: error.fail(line,"Syntax error") vars = map(lower,vars[1:]) + for v in vars: + variables[v].is_touched = True def fun(x): if x not in variables: error.fail(line,"Variable %s unknown"%(x,)) @@ -272,15 +282,6 @@ def build_needs(): build_needs() -###################################################################### -def put_info(): - for filename, text in parsed_text: - if len(text) > 0: - lenmax = 80 - len(text[0][1].filename) - format = "%"+str(lenmax)+"s ! %s:%4s" - for vars,line in text: - line.text = format%(line.text.ljust(lenmax),line.filename,str(line.i)) - ###################################################################### if __name__ == '__main__': for i in range(len(parsed_text)): diff --git a/src/preprocessed_text.py b/src/preprocessed_text.py index c998898..9004294 100644 --- a/src/preprocessed_text.py +++ b/src/preprocessed_text.py @@ -319,7 +319,7 @@ def irp_simple_statements(text): txt = line.text.lstrip() result = [ Simple_line(i,"!",f), - Simple_line(i,"! >>> %s"%(txt,),f ), + t(i,"! >>> %s"%(txt,),variable ), Provide_all(i," call %ser_%s('%s')"%(rw,variable,num),f), Simple_line(i,"! >>> END %s "%(txt,),f ), Simple_line(line.i,"!",f), @@ -665,15 +665,19 @@ def move_to_top(text,t): assert isinstance(text,list) assert t in [ Declaration, Implicit, Use, Cont_provider ] - begin = -1 + inside = False for i in range(len(text)): line = text[i] if type(line) in [ Begin_provider, Subroutine, Function ]: begin = i + inside = True + elif type(line) in [ End_provider, End ]: + inside = False elif isinstance(line,t): - text.pop(i) - begin += 1 - text.insert(begin,line) + if inside: + text.pop(i) + begin += 1 + text.insert(begin,line) return text diff --git a/src/variable.py b/src/variable.py index abecfc1..9ca95b2 100644 --- a/src/variable.py +++ b/src/variable.py @@ -15,6 +15,10 @@ class Variable(object): self.text = text if name is not None: self._name = name.lower() + self.is_freed = False + self.is_read = False + self.is_written = False + self.is_touched = False ############################################################ def name(self): @@ -380,11 +384,33 @@ class Variable(object): return self._provider provider = property(provider) + ########################################################## + def builder(self): + if '_builder' not in self.__dict__: + if '_needs' not in self.__dict__: + import parsed_text + from variables import build_use + name = self.name + for line in filter(lambda x: type(x) not in [ Begin_doc, End_doc, Doc], self.text): + if type(line) == Begin_provider: + result = [ "subroutine bld_%s"%(name) ] + result += build_use([name]+self.needs) + elif type(line) == Cont_provider: + pass + elif type(line) == End_provider: + result.append( "end subroutine bld_%s"%(name) ) + break + else: + result.append(line.text) + self._builder = result + return self._builder + builder = property(builder) + ###################################################################### if __name__ == '__main__': from preprocessed_text import preprocessed_text from variables import variables #for v in variables.keys(): # print v - for line in variables['grid_eplf_aa'].provider: + for line in variables['grid_eplf_aa'].builder: print line diff --git a/src/version.py b/src/version.py index 366c449..47a355a 100644 --- a/src/version.py +++ b/src/version.py @@ -1 +1 @@ -version = "1.1.6" +version = "1.1.7"