diff --git a/example/input.irp.f b/example/input.irp.f index e41611b..2f5049a 100644 --- a/example/input.irp.f +++ b/example/input.irp.f @@ -4,13 +4,19 @@ &BEGIN_PROVIDER [ integer, d4 ] &BEGIN_PROVIDER [ integer, d5 ] - BEGIN_SHELL [ /usr/bin/python ] -for i in range(1,6): - print " print *, 'd%d'"%(i,) - print " read(*,*) d%d"%(i,) - if i > 1: - print " ASSERT ( d%d > d%d )"%(i,i-1) - END_SHELL + print *, 'd1' + read(*,*) d1 + BEGIN_TEMPLATE + print *, '$X' + read(*,*) $X + ASSERT ( $X > $Y ) + + SUBST [ X, Y ] + d2; d1;; + d3; d2;; + d4; d3;; + d5; d4;; + END_TEMPLATE END_PROVIDER diff --git a/src/irpf90_t.py b/src/irpf90_t.py index 7a1dee4..b1658dc 100644 --- a/src/irpf90_t.py +++ b/src/irpf90_t.py @@ -107,6 +107,24 @@ class End_shell(Line): def __repr__(self): return "%20s:%5d : %s"%("End_shell",self.i,self.text) +class Begin_template(Line): + def __init__(self,i,text,filename): + Line.__init__(self,i,text,filename) + def __repr__(self): + return "%20s:%5d : %s"%("Begin_template",self.i,self.text) + +class End_template(Line): + def __init__(self,i,text,filename): + Line.__init__(self,i,text,filename) + def __repr__(self): + return "%20s:%5d : %s"%("End_template",self.i,self.text) + +class Subst(Line): + def __init__(self,i,text,filename): + Line.__init__(self,i,text,filename) + def __repr__(self): + return "%20s:%5d : %s"%("Subst",self.i,self.text) + class Assert(Line): def __init__(self,i,text,filename): Line.__init__(self,i,text,filename) diff --git a/src/preprocessed_text.py b/src/preprocessed_text.py index 9d7a3b9..75cf876 100644 --- a/src/preprocessed_text.py +++ b/src/preprocessed_text.py @@ -49,6 +49,9 @@ simple_dict = { "subroutine": Subroutine , "begin_shell": Begin_shell , "end_shell": End_shell , + "begin_template": Begin_template , + "end_template": End_template , + "subst": Subst , "end_doc": End_doc , "begin_provider": Begin_provider , "&begin_provider": Cont_provider , @@ -226,6 +229,87 @@ def execute_shell(text): result.append(line) return result +###################################################################### +def execute_templates(text): + '''Execute the templates''' + def fail(l,a,b): error.fail(l,"In %s, %s"%(a,b)) + + def get_variables(line): + buffer = line.text.split('[',1) + if len(buffer)<2: + fail(line,"Subst","Syntax error") + buffer = buffer[1].replace(']','') + buffer = buffer.split(',') + return map(lambda x: '$%s'%(x.strip()), buffer) + + TEMPLATE = 1 + SUBST = 2 + inside = 0 + result = [] + for line in text: + if inside == 0: + if isinstance(line,Begin_template): + script = [] + inside = TEMPLATE + script = "template = \"\"\"\n" + else: + result.append(line) + elif inside == TEMPLATE: + if isinstance(line,Begin_template): + fail(line,"template", "Nested Begin_Template") + elif isinstance(line,End_template): + fail(line,"template","Missing Subst") + elif isinstance(line,Subst): + inside = SUBST + script += "\"\"\"\n" + variables = get_variables(line) + script += "v = []\n" + subst = "" + else: + script += line.text+"\n" + else: # inside == SUBST + if isinstance(line,Begin_template): + fail(line,"subst","Nested Begin_template") + elif isinstance(line,Subst): + fail(line,"subst","Subst already defined") + elif isinstance(line,End_template): + inside = 0 + subst = subst.rstrip() + if subst[-2:] == ';;': + subst = subst[:-2] + for s in subst.split(';;'): + buffer = map(lambda x: x.strip(), s.split(';')) + if len(buffer) != len(variables): + fail(line,"subst","%d variables defined, and %d substitutions"%(len(variables),len(buffer))) + script += "v.append( { \\\n" + for t,v in zip(variables,buffer): + script += ' "%s": """%s""" ,\n'%(t,v) + script += "} )\n" + script += "for d in v:\n t0 = str(template)\n" + for v in variables: + script += " t0 = t0.replace('%s',d['%s'])\n"%(v,v) + script += " print t0\n" + # Write script file + scriptname = "%s%s_template_%d"%(irpdir,line.filename,line.i) + file = open(scriptname,'w') + file.writelines(script) + file.close() + scriptname = "%s_template_%d"%(line.filename,line.i) + file = open(scriptname,'w') + file.writelines(script) + file.close() + # Execute shell + import os + pipe = os.popen("python < %s"%(scriptname),'r') + lines = pipe.readlines() + pipe.close() + result += get_text(lines,scriptname) + os.remove(scriptname) + else: + subst += line.text+'\n' + + return result + ###################################################################### def form(text): '''Find if the text is in fixed form or in free form''' @@ -730,6 +814,7 @@ def create_preprocessed_text(filename): lines = file.readlines() file.close() result = get_text(lines,filename) + result = execute_templates(result) result = execute_shell(result) fortran_form = form(result) result = remove_ifdefs(result)