added a command line option +lb_gvt_pose to set the gvt intervals between load balancing.
[charm.git] / src / libs / ck-libs / pose / etrans.pl
1 #!/usr/bin/perl
2 #!/bin/sh 
3 #exec perl -w -x $0 ${1+"$@"} # -*- mode: perl; perl-indent-level: 2; -*-
4 #!perl -w 
5
6 #$Id$
7
8 use FileHandle;
9 use English;
10 use strict;
11 use Getopt::Std;
12 my %opts;
13 our($opt_s);
14 my $result=getopts('sD:',\%opts);
15 $opt_s=$opts{'s'};
16 my $infile = shift @ARGV;
17 my @otherfiles = @ARGV;
18 my $inci = "$infile.ci";
19 my $inh = "$infile.h";
20 my $inC = "$infile.C";
21 my $outci = "$infile\_sim.ci";
22 my $outh = "$infile\_sim.h";
23 #my $outC = "$infile\_sim.C";
24 my (@strategies,@representations,@posera,@groups,@newline);
25 my (%posers,%strat, %methods,%rep,%base,%events,%nonevents,%messages,%needsopeq,%puppy,%cppuppy,%emessages,%extradecl, %inits);
26 my ($class,$method,$message);
27 my ($template,$tdef, $classpattern); #for template support
28 my $wantindent=0;
29 print "Processing .ci files...\n";
30 #hashes for parse state
31 my %openblock;
32 my %closeblock;
33 my %closecomment;
34 my %opencomment;
35 my %incomment;
36 my %blocklevel;
37 my %lastline;
38 # BEGIN READ HEADERS & MESSAGES
39 #read inci
40 my $incihandle= new FileHandle();
41 if(defined($opts{'D'}))
42 {
43
44     $incihandle->open(" cpp -D$opts{'D'} $inci| grep -v '^#'|") or die "cannot open $inci";
45 }
46 else
47 {
48     $incihandle->open(" cpp $inci| grep -v '^#'|") or die "cannot open $inci";
49
50 }
51 inithandle($incihandle);
52 my $outcihandle=new FileHandle();
53 $outcihandle->open(">$outci") or die "cannot open $outci";
54 my @line;
55 my $thisline;
56 my @otherstuff;
57 while (@line=split(' ',($thisline=getcodeline($incihandle)))) {
58   if ($line[0] eq "message") {
59     chop $line[1];
60     $messages{$line[1]}=$lastline{$incihandle};
61   }
62   elsif ($line[0] eq "poser") {
63     $posers{$line[1]}=poserdeal($incihandle,\@line,$thisline);
64     push(@posera,$posers{$line[1]});
65   }
66   elsif ($line[0] =~ /((group)|(chare))/) {
67     push(@groups,groupnchardeal($incihandle,\@line,$thisline));
68   }
69   else
70   {
71       push(@otherstuff,$thisline);
72   }
73 }
74
75 foreach my $j (keys %events) {
76   foreach my $i (@{$events{$j}}) {
77     print "class $j has method $i->[0] $i->[1] \n";
78   }
79 }
80
81
82 $incihandle->close();
83 %emessages=%messages;
84 # on to classes
85 # END READ HEADERS & MESSAGES
86
87 # BEGIN HEADERS
88 # write outci
89 print "Processing headers...\n";
90 $outcihandle->print("module $infile {\n");
91 $outcihandle->print("  extern module sim;\n");
92 $outcihandle->print("  extern module pose;\n");
93 $outcihandle->print(@otherstuff);
94 $outcihandle->print("\n");
95 foreach my $i (keys %messages) {
96   $outcihandle->print("  message $i;\n");
97 }
98 $outcihandle->print("\n");
99
100 # write outh
101 my $outhhandle=new FileHandle();
102 my $indent=`indent --version`;
103 if ( $wantindent && ( $indent =~ /GNU/) && ( $indent !~ /2.2.5/) ) {
104   $outhhandle->open("|indent -npcs -npsl -bap -bad -br -nce > $outh") or die "cannot open indented $outh";
105 } else {
106   $outhhandle->open("> $outh") or die "cannot open $outh";
107 }
108 $outhhandle->print("#ifndef $infile\_H\n");
109 $outhhandle->print( "#define $infile\_H\n");
110 $outhhandle->print( "#include \"pose.h\"\n");
111 $outhhandle->print( "#include \"$infile.decl.h\"\n");
112 $outhhandle->print( "\n");
113 #foreach my $i (@strategies) {
114 #    $outhhandle->print( "#include \"$i.h\"\n");
115 #}
116 #foreach my $i (@representations) {
117 #    if ($i ne "rep") {
118 #       $outhhandle->print( "#include \"$i.h\"\n");
119 #    }
120 #}
121
122 # END HEADERS
123
124 # BEGIN READ CLASSES
125 print "Processing classes...\n";
126 my $group;
127 foreach $group (@groups) {
128   foreach (@{$group->{literal}}) {
129     $outcihandle->print($_."\n");
130   }
131 }
132 my $poser;
133 foreach $poser (@posera) {
134   foreach (@{$poser->{literal}}) {
135     $outcihandle->print($_."\n");
136   }
137 }
138 #footer
139 $outcihandle->print("};\n"); 
140 $outcihandle->close;
141
142 # PRESCAN $infile.h for cpPups.  Record them by class so we don't make new ones.
143 my $inhhandle=new FileHandle();
144 $inhhandle->open("$inh") or die "cannot open $inh";
145 inithandle($inhhandle);
146 while (@line=split(' ',($thisline=getcodeline($inhhandle))))
147   {
148     #seek the puppy
149     if ($thisline =~ /^\s*class\s+([^:\s\(\{]+)/)
150       {
151         $class=$1;
152       }
153     if ($thisline =~ /void\s+cpPup\s*\(PUP\s*/)
154       {
155         $cppuppy{$class}=1;
156         print "found user defined cppup for class $class \n";
157       }
158   }
159 # BEGIN READ MESSAGES FROM $infile.H
160 print "Processing messages...\n";
161 $inhhandle->open("$inh") or die "cannot open $inh";
162 inithandle($inhhandle);
163 my ($currep,$curstrat,$annoying,$declaration);
164 my ($opeq,$destructor);
165 my ($numClasses);
166 my (@pair);
167 # foreach message append :public eventMsg to decl
168 # reject message if no operator= defined within
169 # foreach class save body in array and make two copies
170 # first one is written verbatim
171 # second one append :public sim to header decl
172 my $inbody=0;
173 my $inpup=0;
174 my ($ismessage,$issim,$isconstructor);
175 my @body;
176 while (@line=split(' ',($thisline=getcodeline($inhhandle)))) {
177   if ($inbody) {
178     if (posefunctest($thisline)>0) {
179       push(@body,posefuncmap($thisline,$issim,$isconstructor,$class));
180     } else {
181       push(@body,$lastline{$inhhandle});
182     }
183     if ($thisline =~ /$class&*\s*operator\s*=.*$class&/i) {
184       $opeq=1;
185     }
186     if ($thisline =~ /~$class/i) {
187       $destructor=1;
188     }
189     #seek the puppy
190     if ($thisline =~ /void\s+pup\s*\(PUP\s*::\s*er/) {
191       $puppy{$class}=[];
192       #   print "Found puppy for $class\n";
193       #got our puppy
194       if ($openblock{$inhhandle}) {
195         # got the body here
196         $inpup=$blocklevel{$inhhandle};
197       } elsif ($currep eq "chpt") {
198         push(@body,"  void cpPup(PUP::er &p);") if(!exists ($cppuppy{$class}) );
199       } else {                  #do nothing
200       }
201     } elsif (($inpup)&&($thisline !~/((chpt<state)|(chpt::pup))/)) {
202       #     print "Inserting pup ".$lastline{$inhhandle}." for $class \n";
203       push(@{$puppy{$class}},$lastline{$inhhandle});
204     }
205   }
206   if ($inpup && ($blocklevel{$inhhandle}<$inpup) && ($closeblock{$inhhandle}==1)) { #got the whole pup
207     #add the cpPup
208     if (!exists($cppuppy{$class}) && ($currep eq "chpt")) {
209       $inpup=0;
210       push(@body,"  void cpPup(PUP::er &p) {");
211       push(@body,@{$puppy{$class}});
212     }
213   }
214   if (($blocklevel{$inhhandle}==0) && ($closeblock{$inhhandle}==1)) { #got the whole thing
215     print "class $class issim $issim ismessage $ismessage $inbody defined \n";
216     $inbody=0;
217     if ($ismessage) {
218       $outhhandle->print("class $class : public eventMsg {\n");
219       foreach (@body) {
220         $outhhandle->print("$_\n");
221       }
222       $outhhandle->print("\n");
223     } elsif ($issim) {
224       #take care of first class copy
225       $outhhandle->print("class $class : public ".$base{$class}.$extradecl{$class}." {\n");
226       $outhhandle->print(" private:\n   void ResolveFn(int fnIdx, void *msg);\n") if ($#{$events{$class}}>=0);
227       $outhhandle->print("   void ResolveCommitFn(int fnIdx, void *msg);\n") if($#{$events{$class}}>=0);
228       $outhhandle->print(" public:\n");
229       $outhhandle->print("   $class(CkMigrateMessage *) {};\n");
230       $outhhandle->print("   void pup(PUP::er &p);\n") if exists $puppy{$class};
231       #   $outhhandle->print("   void cpPup(PUP::er &p);\n");
232       # Get verbatim from .ci file for SOUT
233       # we stored that in the $posers hash
234       my $thischar=$posers{$class};
235       #for classes with strategies go get them
236       foreach (@{$thischar->{literal}}) {
237         my ($lmethod,$lmessage);
238         my @newline = split;
239         next if (/array \[1D\]/); #skip classdef
240         next if (/\}\;/);       #skip close
241         next if (/initproc/);   #skip init
242         next if (/initnode/);   #skip init
243         if ($newline[0] ne "entry") {
244           $outhhandle->print("$_\n");
245         }
246         else {
247           s/entry\s//;
248           s/\[.+\]\s//;
249           $outhhandle->print("  $_\n");
250           for my $i (@newline) {
251             if ($i =~ /([\w_]+)\((\w+)/) {
252               $lmethod = $1;
253               $lmessage = $2;
254               last;
255             }
256           }
257           if(defined $lmethod and defined $lmessage)
258             {
259               my $pair = [$lmethod, $lmessage];
260               push(@{$methods{$class}}, $pair);
261               print "\n  method  ".$class."::".$lmethod."(".$lmessage.")\n";
262             }
263         }
264       }
265       foreach my $thisinit (@{$inits{$class}}) {
266           # output the wrapper version this init method
267           # if we had to handle this generically there would be less hardcode
268           $outhhandle->print("   static void ".$thisinit."(void);\n");
269
270         }
271       $outhhandle->print("};\n\n");
272       if (($curstrat =~ /((opt)|(adapt))/) || ($currep eq "chpt")) {
273         print "warning ! no ::operator= in class $class" if (exists($needsopeq{$class}) &&( $opeq!=1));
274         print "warning ! no ~ destructor in $class" if $destructor!=1;
275       }
276       if (!exists($puppy{$class})) {
277         print "warning ! $class has no puppy, you loser \n";
278       }
279       #2nd copy
280       if ($currep eq "chpt") {
281         $outhhandle->print("class state_$class : public $currep<state_$class>".$extradecl{$class}." {\n");
282       } else {
283         $outhhandle->print("class state_$class : public $currep ".$extradecl{$class}." {\n");
284       }
285       $outhhandle->print("  friend class $class;\n");
286       my $declout=0;
287       foreach (@body) {
288         #substitute state_$class for occurence of $class
289         s/(\b$class\b)/state_$1/g;
290         #ifdef wrap chpt<>
291         if(/chpt/)
292           {
293             $outhhandle->print("#ifndef SEQUENTIAL_POSE\n");
294             $outhhandle->print("$_"."\n");
295             $outhhandle->print("#endif\n");
296           }
297         else
298           {
299             $outhhandle->print("$_");
300             $outhhandle->print("\n");
301           }
302         #look for the public declaration
303
304         if ((/public:/)&&(!$declout)) {
305           $outhhandle->print("  state_$class(sim *p, strat *s) { parent = p; myStrat = s; }\n");
306           $declout=1;
307         }
308       }
309       $outhhandle->print("\n");
310       #make state_$class constructor
311
312     } else {                    #dunno what this is, just pass it
313       foreach (@body) {
314         if(/chpt/)
315           {
316             $outhhandle->print("#ifndef SEQUENTIAL_POSE\n");
317             $outhhandle->print("$_"."\n");
318             $outhhandle->print("#endif\n");
319           }
320         else
321           {
322             $outhhandle->print("$_");
323             $outhhandle->print("\n");
324           }
325       }
326     }
327     $inpup=0;
328     @body=();
329     $opeq=0;
330     $destructor=0;
331   } elsif (($blocklevel{$inhhandle}==1) && ($openblock{$inhhandle}==1) &&(!$inbody)) { # decl line
332     # is  it a message or a sim class?
333     # is a chpt?
334 #    print "declaration line $thisline \n";
335     $inbody=1;
336     if ($thisline =~ /^\s*class\s+([^:\s\(\{]+)/) {
337       $class=$1;
338       $tdef='';
339       $classpattern=$class;
340       if ($thisline =~ /:/) {
341         if (exists($base{$class})) {
342           $isconstructor=1;
343           $issim=1;
344           $ismessage=0;
345           $curstrat=$strat{$class};
346           $currep = $rep{$class};
347           my $extradecl=$POSTMATCH;
348           if($extradecl =~ /:\s*([^\{]+)/) {
349             $extradecl{$class}=", ".$1;
350           }
351           print "$curstrat... $currep...$class...$extradecl\n";
352         }
353         else
354           {
355             $outhhandle->print($thisline."\n");
356             $issim=0;
357             $isconstructor=0;
358             $ismessage=0;
359             delete($emessages{$class}) if exists($emessages{$class});
360           }
361       } elsif (defined($messages{$class})) {
362         $ismessage=1;
363         $issim=0;
364       } elsif (exists($base{$class})) {
365         $isconstructor=1;
366         $issim=1;
367         $ismessage=0;
368         $curstrat=$strat{$class};
369         $currep = $rep{$class};
370         print "$curstrat... $currep...$class \n";
371       } else {                  #some sort of local use class
372         $isconstructor=1;
373         $issim=$ismessage=0;
374         push(@body,$thisline);
375       }
376     } elsif ($thisline =~ /^\s*template\s*<\s*class\s+(.*)\s*>\s*class\s+([^:\s\(\{]+)/) {
377       $class=$2;
378       $tdef=$1;
379       $classpattern=$class.'\s*<.*>';
380       if ($thisline =~ /:/) {
381         $outhhandle->print($thisline."\n");
382         $issim=0;
383         $isconstructor=0;
384         $ismessage=0;
385         delete($emessages{$class}) if exists($emessages{$class});
386       } elsif (defined($messages{$class})) {
387         $ismessage=1;
388         $issim=0;
389       } elsif (exists($base{$class})) {
390         $isconstructor=1;
391         $issim=1;
392         $ismessage=0;
393         $curstrat=$strat{$class};
394         $currep = $rep{$class};
395         print "$curstrat... $currep...$class \n";
396       } else {                  #some sort of local use class
397         # which is all we really expect to work with templates right now anyway
398         $isconstructor=1;
399         $issim=$ismessage=0;
400         push(@body,$thisline);
401       }
402     } else {                    #classes otherwise unknown
403       $issim=$ismessage=0;
404       push(@body,$thisline);
405     }
406     #   print "sim $issim message $ismessage constructor $isconstructor \n";
407   } elsif(!$inbody){
408     #stuff otherwise unknown
409     $outhhandle->print("$thisline\n");
410 #    $outhhandle->print($lastline{$inhhandle}."\n");
411   }
412   else
413     {
414 #    print("inbody is $inbody, and we have $thisline\n");
415     }
416 }
417
418 $outhhandle->print("#endif\n");
419 $outhhandle->close;
420 $inhhandle->close;
421 # END WRITE .H FILES
422
423 # BEGIN WRITE .C FILE
424 my ($inbase,$inext)=split('\.',$inC);
425 my $simhead=$inbase.'_sim.h';
426 my $defhead=$inbase.'.def.h';
427 my $outC=$inbase.'_sim'.'.'.$inext;
428 my $outChandle=new FileHandle();
429 if ( $wantindent && ( $indent =~ /GNU/) && ( $indent !~ /2.2.5/) ) {
430   $outChandle->open("|indent -npcs -npsl -bap -bad -br -nce>$outC") or die "cannot open $outC";
431 } else {
432   $outChandle->open(">$outC") or die "cannot open $outC";
433 }
434 $outChandle->print( "#include \"$simhead\"\n");
435 $outChandle->print( "#include \"$defhead\"\n\n");
436
437 foreach my $incfile ($inC,@otherfiles)
438 {
439
440   print "Generating source for $incfile...\n";
441
442   my ($inbase,$inext)=split('\.',$incfile);
443   my $inChandle=new FileHandle();
444   $inChandle->open("$incfile") or die "cannot open $incfile";
445   inithandle($inChandle);
446   my ($thefnidx);
447   my($iseventmethod,$isweird,$isnoneventmethod, $isinitmethod);
448   my ($returntype,,$messagename,$found);
449   while (@line=split(' ',($thisline=getcodeline($inChandle)))) {
450     if (($line[0] eq "#define") || ($line[0] eq "#include")) {
451       $outChandle->print("$thisline\n");
452     } elsif ($inbody) {
453       if (posefunctest($thisline)>0) {
454         push(@body,posefuncmap($thisline,$issim,$isconstructor,$class));
455       } else {
456         push(@body,$lastline{$inChandle});
457       }
458     }
459
460     if (($blocklevel{$inChandle}<=1) && ($openblock{$inChandle}==1) &&(!$inbody)) { # decl line
461       # handle wrapper class (constructor and resolve) construction for
462       # sim classes and event methods
463       # get class name and method name
464       #         print "open on $thisline :level".$blocklevel{$inChandle}." open:".$openblock{$inChandle}." close:".$closeblock{$inChandle}."\n";
465       $iseventmethod=$isnoneventmethod=$isconstructor=$isweird=$issim=$isinitmethod=0;
466       $class=$message=$messagename=$returntype=$method='';
467       $declaration=$lastline{$inChandle};
468       $inbody=1;
469       # regexp if block to extract the fields
470       # expecting  class::method(parameters)
471       if ($thisline =~ /^\s*([^:\s\(]+)\s*\:\:\s*([^\s\(]+)\s*\(\s*([^\s\*]+)\s*[\*]*\s*([^\s\,\{\)]+)/) {
472         $returntype='';
473         $class=$1;
474         $method=$2;
475         $message=$3;
476         $messagename=$4;
477       }
478       # expecting retval *class::method(parameters)
479       elsif ($thisline =~ /^\s*([^:\s\(]+ \*)([^\s:\(]+)\s*\:\:\s*([^\s\(]+)\s*\(\s*([^\s\*]+)\s*\**\s*([^\s,\)\{]+)/) {
480
481         $returntype=$1;
482         $class=$2;
483         $method=$3;
484         $message=$4;
485         $messagename=$5;
486       }
487       # expecting retval class::method(parameters)
488       elsif ($thisline =~ /^\s*([^:\s\(]+)\s?([^\s:\(]+)\s*\:\:\s*([^\s\(]+)\s*\(\s*([^\s\*]+)\s*\**\s*([^\s,\)\{]+)/) {
489         $returntype=$1;
490         $class=$2;
491         $method=$3;
492         $message=$4;
493         $messagename=$5;
494       }
495
496       # expecting  class::method()
497       elsif ($thisline =~ /^\s*\**\s*([^\s:\(]+)\s*::\s*([^\s\(]+)\s*\(\s*\)/) {
498         $returntype='';
499         $class=$1;
500         $method=$2;
501         $message=$messagename='';
502       }
503       # expecting  retval *class::method()
504       elsif ($thisline =~  /^\s*([^\s\(:]+\s*\*)([^\s:]+)\s*::\s*([^\s\(]+)\s*\(\s*\)/) {
505         $returntype=$1;
506         $class=$2;
507         $method=$3;
508         $message=$messagename='';
509       }
510       # expecting  retval class::method()
511       elsif ($thisline =~  /^\s*([^\s\(:]+)\s?([^\s:]+)\s*::\s*([^\s\(]+)\s*\(\s*\)/) {
512         $returntype=$1;
513         $class=$2;
514         $method=$3;
515         $message=$messagename='';
516       } else {
517         #funkulation: non class subroutine perhaps just pass
518         #these for now since we have no handling instructions.
519         print STDERR "$thisline at $incfile ".$inChandle->input_line_number." is being passed untranslated\n";
520         $isweird=1;
521         $inbody=1;
522         $outChandle->print($lastline{$inChandle}."\n");
523         $declaration='';
524         next;
525       }
526       $issim=1 if exists($base{$class});
527       $isconstructor =1 if($class eq $method);
528       my $j;
529       foreach $j (@{$events{$class}}) {
530         if ($method eq $j->[0]) {
531           $iseventmethod = 1;
532         }
533       }
534       foreach $j (@{$nonevents{$class}}) {
535         if ($method eq $j) {
536           $isnoneventmethod = 1;
537         }
538       }
539       foreach $j (@{$inits{$class}}) {
540         if ($method eq $j) {
541           $isinitmethod = 1;
542         }
543       }
544       if ($isinitmethod)
545         {
546           my $retval =$returntype;
547           $retval =undef if $retval =~ /void/;
548           $outChandle->print("$declaration\n");
549           $outChandle->print("  state_".$class."::".$method."();\n");
550           $outChandle->print("}\n");
551
552         }
553       #      print "class is $class, method is $method close=".$closeblock{$inChandle}." issim = $issim iseventmethod = $iseventmethod isnoneventmethod $isnoneventmethod \n";
554
555       if ($iseventmethod &&  ($messagename ne '')) {
556
557         $outChandle->print("$declaration\n");
558
559         $outChandle->print("#ifndef CMK_OPTIMIZE\n");
560         $outChandle->print("$messagename->sanitize();\n");
561         $outChandle->print("  int tstat;\n");
562         $outChandle->print("  if(pose_config.stats){\n");
563         $outChandle->print("    tstat = localStats->TimerRunning();\n");
564         $outChandle->print("    if (tstat)\n");
565         $outChandle->print("      localStats->SwitchTimer(SIM_TIMER);\n");
566         $outChandle->print("    else\n");
567         $outChandle->print("      localStats->TimerStart(SIM_TIMER);\n");
568         $outChandle->print("  }\n");
569         $outChandle->print("#endif\n");
570         $outChandle->print("#ifndef SEQUENTIAL_POSE\n");
571         $outChandle->print("  PVT *pvt = (PVT *)CkLocalBranch(ThePVT);\n");
572         $outChandle->print("  pvt->objUpdate($messagename->timestamp, RECV);\n");
573         #$outChandle->print("  srVector[$messagename->evID.getPE()]++;\n");
574         $outChandle->print("#endif\n");
575         $outChandle->print("  Event *e = new Event();\n");
576         $outChandle->print("  if ((POSE_endtime < 0) || ($messagename->timestamp <= POSE_endtime)) {\n");
577         $outChandle->print("    e->evID = $messagename->evID;\n");
578         $outChandle->print("    e->timestamp = $messagename->timestamp;\n");
579         $outChandle->print("    e->done = e->commitBfrLen = 0;\n");
580         $outChandle->print("    e->commitBfr = NULL;\n");
581         $outChandle->print("    e->msg = $messagename;\n");
582         $thefnidx = 0;
583         #setup index for non constructor methods
584         foreach my $i (@{$methods{$class}}) {
585           if ($i->[0] ne $class) {
586             foreach my $j (@{$events{$class}}) {
587
588               if (($i->[0] eq $j->[0])&& ($i->[1] eq $j->[1])) {
589                 $thefnidx++;
590               } else {
591
592               }
593             }
594           }
595           if (($i->[0] eq $method) && ($i->[1] eq $message)) {
596             print "$class $method $message has index $thefnidx\n";
597             last;
598           }
599         }
600         $outChandle->print("    e->fnIdx = $thefnidx;\n");
601         $outChandle->print("    e->next = e->prev = NULL;\n");
602         $outChandle->print("    e->spawnedList = NULL;\n");
603         #$outChandle->print("char str[30];\n");
604         #$outChandle->print("CkPrintf(\"[%d] RECV(event) @ %d: Event=%s\\n\", thisIndex, $messagename->timestamp, $messagename->evID.sdump(str));\n");
605         $outChandle->print("#ifndef SEQUENTIAL_POSE\n");        
606         $outChandle->print("    CkAssert(e->timestamp >= pvt->getGVT());\n");
607         $outChandle->print("#endif\n");
608         $outChandle->print("    eq->InsertEvent(e);\n");
609         $outChandle->print("    Step();\n");
610         $outChandle->print("  }\n");
611         $outChandle->print("#ifndef CMK_OPTIMIZE\n");
612         $outChandle->print("  if(pose_config.stats){\n");
613         $outChandle->print("    if (tstat)\n");
614         $outChandle->print("      localStats->SwitchTimer(tstat);\n");
615         $outChandle->print("    else\n");
616         $outChandle->print("      localStats->TimerStop();}\n");
617         $outChandle->print("#endif\n");
618         $outChandle->print("}\n");
619       } elsif ($isnoneventmethod) {
620         my $retval =$returntype;
621         $retval =undef if $retval =~ /void/;
622         $outChandle->print("$declaration\n");
623         $outChandle->print("  ".$retval." result;\n ") if($retval);
624         $outChandle->print("  result= ") if($retval);
625         $outChandle->print("  ((state_".$class." *)objID)->".$method."(".$messagename.");\n");
626         $outChandle->print("  return result\n;") if($retval);
627         $outChandle->print("}\n");
628       } elsif ($issim && $isconstructor &&($messagename ne '')) { 
629         #create the wrapper parent class constructor
630         $outChandle->print($returntype." ") if($returntype);
631         $outChandle->print(join('',$class,"::",$method,'(',$message,' *',$messagename,"){\n"));
632         $outChandle->print("  usesAtSync=true;\n");
633         $outChandle->print("#ifndef CMK_OPTIMIZE\n");
634         $outChandle->print("  if(pose_config.stats)\n");
635         $outChandle->print("    {localStats->TimerStart(SIM_TIMER);}\n");
636         $outChandle->print("#endif\n");
637         $outChandle->print("  LBgroup *localLBG;\n\n");
638         $outChandle->print("  if(pose_config.lb_on)\n");
639         $outChandle->print("     localLBG = TheLBG.ckLocalBranch();\n\n");
640         $outChandle->print("  myStrat = new ".$strat{$class}."();\n");
641         $outChandle->print("  $messagename->parent = this;\n");
642         $outChandle->print("  $messagename->str = myStrat;\n");
643         $outChandle->print("  POSE_TimeType _ts = $messagename->timestamp;\n");
644         $outChandle->print("#ifndef CMK_OPTIMIZE\n  if(pose_config.stats){\n    localStats->SwitchTimer(DO_TIMER);}\n#endif\n");
645
646         $outChandle->print("  objID = new state_$method($messagename);\n");
647         $outChandle->print("#ifndef CMK_OPTIMIZE\n  if(pose_config.stats){\n    localStats->SwitchTimer(SIM_TIMER);}\n#endif\n");
648         $outChandle->print("  myStrat->init(eq, objID, this, thisIndex);\n");
649         $outChandle->print("#ifndef CMK_OPTIMIZE\n  if(pose_config.stats){\n    localStats->TimerStop();}\n#endif\n");
650         $outChandle->print("#ifndef SEQUENTIAL_POSE\n");
651         $outChandle->print("  PVT *pvt = (PVT *)CkLocalBranch(ThePVT);\n");
652         $outChandle->print("  myPVTidx = pvt->objRegister(thisIndex, _ts, sync, this);\n");
653         $outChandle->print("#endif\n");
654         $outChandle->print("  if(pose_config.lb_on)\n");
655         $outChandle->print("    myLBidx = localLBG->objRegister(thisIndex, sync, this);\n");
656         $outChandle->print("}\n");
657         #create the pup constructor
658         if (exists($puppy{$class})) {
659           $outChandle->print(join('','void ',$class,"::pup(PUP::er &p)\n"));
660           $outChandle->print("  {\n");
661           $outChandle->print("    sim::pup(p);\n");
662           $outChandle->print("    if (p.isUnpacking()) {\n");
663           $outChandle->print("      myStrat = new ".$strat{$class}.";\n");
664           $outChandle->print("      objID = new state_$class(this, myStrat);\n");
665           $outChandle->print("      myStrat->init(eq, objID, this, thisIndex);\n");
666           $outChandle->print("    }\n");
667           $outChandle->print("    ((state_$class *)objID)->pup(p);\n");
668           if ($rep{$class} eq "chpt") {
669             $outChandle->print("    Event *ev = eq->front()->next;\n");
670             $outChandle->print("    int checkpointed;\n\n");
671             $outChandle->print("    while (ev != eq->back()) {\n");
672             $outChandle->print("      if (p.isUnpacking()) {\n");
673             $outChandle->print("        p(checkpointed);\n");
674             $outChandle->print("        if (checkpointed) {\n");
675             $outChandle->print("          ev->cpData = new state_$class(this, myStrat);\n");
676             $outChandle->print("          ((state_$class *)ev->cpData)->cpPup(p);\n");
677             $outChandle->print("        }\n");
678             $outChandle->print("        else ev->cpData = NULL;\n");
679             $outChandle->print("      }\n");
680             $outChandle->print("      else {\n");
681             $outChandle->print("        if (ev->cpData) {\n");
682             $outChandle->print("          checkpointed = 1;\n");
683             $outChandle->print("          p(checkpointed);\n");
684             $outChandle->print("          ((state_$class *)ev->cpData)->cpPup(p);\n");
685             $outChandle->print("        }\n");
686             $outChandle->print("        else {\n");
687             $outChandle->print("          checkpointed = 0;\n");
688             $outChandle->print("          p(checkpointed);\n");
689             $outChandle->print("        }\n");
690             $outChandle->print("      } \n");
691             $outChandle->print("     ev=ev->next; \n");
692             $outChandle->print("    }\n");
693
694           }
695           $outChandle->print("  }\n");
696         }
697       } else {                  #non constructor
698       }
699       if ($closeblock{$inChandle}==1) { #its a one liner
700         print "oneliner for  $class $method sim $issim\n";
701         $declaration =~ s/(\b$class\b)/state_$1/gm      if($issim);
702         if (($method eq 'pup') &&(exists($puppy{$class})) && !exists($cppuppy{$class}) && ($rep{$class} eq "chpt")) {
703           my $cpdec=$declaration;
704           $cpdec =~ s/:pup/:cpPup/gm;
705           $outChandle->print($cpdec."\n");
706         }
707         $outChandle->print($declaration."\n");
708         $inbody=0;
709       }
710       # print "done open on $thisline :level".$blocklevel{$inChandle}." open:".$openblock{$inChandle}." close:".$closeblock{$inChandle}."\n";
711     } elsif (($blocklevel{$inChandle}==0) && ($closeblock{$inChandle}==1)) { #got the whole thing
712       #handle verbatim and translation copying of block
713       #if rep is chpt and the $puppy{$class} hash has no elements make the cpPup copy
714       #      print "on close class is $class, method is $method issim = $issim iseventmethod = $iseventmethod \n";
715       # print "close  for $class $method \n";
716       $declaration =~ s/(\b$class\b)/state_$1/gm      if($issim);
717
718       if (($method eq 'pup') &&(exists($puppy{$class}))  && !exists($cppuppy{$class}) && ($rep{$class} eq "chpt")) {
719         my $cpdec=$declaration;
720         $cpdec =~ s/:pup/:cpPup/gm;
721         $outChandle->print($cpdec."\n");
722         foreach (@body) {
723           if ($_ =~ /(chpt<state[^>]+>)/) { #translate to rep
724             $outChandle->print($`."rep".$'."\n");
725           } else {
726             $outChandle->print($_."\n");
727           }
728         }
729       }
730       $outChandle->print($declaration."\n");
731       $outChandle->print("init($messagename);\n") if(length($messagename) && ($issim && $isconstructor));
732       while ($_ =shift @body) {
733         s/\bthishandle\b/thisIndex/gm;
734         if(/chpt/)
735           {
736             $outChandle->print("#ifndef SEQUENTIAL_POSE\n");
737             $outChandle->print("$_"."\n");
738             $outChandle->print("#endif\n");
739           }
740         else
741           {
742             $outChandle->print($_."\n");
743           }
744       }
745       $inbody=0;
746     } elsif (!$inbody) {        #regular line
747       #    print "regular line $thisline at $incfile is passed untranslated \n";
748       $outChandle->print($lastline{$inChandle}."\n");
749     } else {
750     }
751   }
752   #test incomplete block
753   if($blocklevel{$inChandle}>0 || $openblock{$inChandle}>0)
754     {
755       print STDERR "ERROR $incfile file terminated with open block\n";
756     }
757   $outChandle->print("\n");
758   $inChandle->close;
759   if ($incfile eq $inC) {
760     #generate ResolveFns 
761     my ($key,$count,$first,@array);
762     foreach $key (keys %methods) {
763       print "key is $key\n";
764       if ($strat{$key} ne "none") {
765         my $count = 1;
766         my $first = 1;
767         my $ifopen=0;
768         @array = @{$methods{$key}};
769         foreach my $i (@array) {
770           $found = 0;
771           foreach my $j (@{$events{$key}}) {
772             if (($j->[0] eq $i->[0])&& ($i->[1]==$j->[1])) {
773               $found = 1;
774             }
775           }
776           if ($found && ($i->[0] ne $key)) {
777             if ($ifopen ==0) {
778               $outChandle->print("void $key\:\:ResolveFn(int fnIdx, void *msg)\n{\n");
779               $outChandle->print("  if (fnIdx >0){\n");
780               $outChandle->print("    if (sync == OPTIMISTIC)\n");
781               $outChandle->print("      ((state_$key *) objID)->checkpoint((state_$key *) objID);\n");
782               $outChandle->print("    ((state_$key *) objID)->update(((eventMsg *)msg)->timestamp, ((eventMsg *)msg)->rst);\n");
783               $outChandle->print("  }\n");
784
785
786               $outChandle->print("  if (fnIdx == ");
787               $ifopen=1;
788             } elsif ($first == 0) {
789               $outChandle->print("  else if (fnIdx == ");
790             }
791             $outChandle->print("$count) {\n");
792             $first = 0;
793             $outChandle->print("#ifndef CMK_OPTIMIZE\n");
794             $outChandle->print("  if(pose_config.stats)\n");
795             $outChandle->print("    if (!CpvAccess(stateRecovery)) {localStats->Do();\n");
796             $outChandle->print("    if(pose_config.dop)\n");
797             $outChandle->print("      st = CmiWallTimer();\n");
798             $outChandle->print("    localStats->SwitchTimer(DO_TIMER);}\n");
799             $outChandle->print("#endif\n");
800
801             $outChandle->print("    ((state_$key *) objID)->$i->[0](($i->[1] *)msg);\n");
802             $outChandle->print("#ifndef CMK_OPTIMIZE\n");
803             $outChandle->print("  if(pose_config.stats)\n");
804             $outChandle->print("    if (!CpvAccess(stateRecovery)) {\n");
805             $outChandle->print("    if(pose_config.dop){\n");
806             $outChandle->print("      et = CmiWallTimer();\n");
807             $outChandle->print("      eq->currentPtr->ert = eq->currentPtr->srt + (et-st);\n");
808             $outChandle->print("      ((state_$key *) objID)->ort = eq->currentPtr->ert+0.000001;\n");
809             $outChandle->print("      eq->currentPtr->evt = ((state_$key *) objID)->OVT();\n");
810             $outChandle->print("    }\n");
811             $outChandle->print("    localStats->SwitchTimer(SIM_TIMER);}\n");
812             $outChandle->print("#endif\n");
813
814             $outChandle->print("  }\n");
815             $outChandle->print("  else if (fnIdx == -$count) {\n");
816             $outChandle->print("    ((state_$key *) objID)->$i->[0]_anti(($i->[1] *)msg);\n");
817             $outChandle->print("  }\n");
818             $count++;
819           }
820         }
821         if ($ifopen) {
822           $outChandle->print("}\n\n");
823         }
824       }
825     }
826
827     foreach $key (keys %methods) {
828       if ($strat{$key} ne "none") {
829         my $count = 1;
830         my $first = 1;
831         my $ifopen =0;
832         @array = @{$methods{$key}};
833         foreach my $i (@array) {
834           $found = 0;
835           foreach my $j (@{$events{$key}}) {
836             if (($j->[0] eq $i->[0]) &&($i->[1]==$j->[1])) {
837               $found = 1;
838             }
839           }
840           if ($found && ($i->[0] ne $key)) {
841             if ($ifopen == 0) {
842               $outChandle->print("void $key\:\:ResolveCommitFn(int fnIdx, void *msg)\n{\n");
843
844               $outChandle->print("  if (fnIdx == ");
845               $ifopen=1;
846             } elsif ($first == 0) {
847               $outChandle->print("  else if (fnIdx == ");
848             }
849             $outChandle->print("$count) {\n");
850             $first = 0;
851             $outChandle->print("    ((state_$key *) objID)->$i->[0]_commit(($i->[1] *)msg);\n");
852             $outChandle->print("  }\n");
853             $count++;
854           }
855         }
856         if ($ifopen) {
857           $outChandle->print("}\n\n");
858         }
859       }
860
861     }
862   }
863
864   #create the inline mapsize function
865   #$outChandle->print("int MapSizeToIdx(int size)\n{\n");
866   #my $sizeline=0;
867   #$outChandle->print("    static int eventMsgSz = sizeof(eventMsg);\n"); 
868   #foreach my $i (keys %emessages) {
869   #  $outChandle->print("    static int ".$i."Sz = sizeof(".$i.");\n"); 
870   #}
871   #$outChandle->print("\n");
872   #$outChandle->print("    if (size == eventMsgSz) return ".$sizeline++.";\n");
873   #foreach my $i (keys %emessages) {
874   #  $outChandle->print("    else if (size == ".$i."Sz) return ".$sizeline++.";\n");
875   #}
876   #$outChandle->print("    return $sizeline;\n");
877   #$outChandle->print("}\n");
878   #$outChandle->close;
879
880   # END WRITE .C FILES
881 }
882
883 #codelines have  ; or { or */
884 #we keep reading till our line meets those criteria.
885 #it could conceivably exceed them and have more than one logical code line
886 #we're willing to live with that for now. 
887 #we'll record block open, close, and comment for test convenience.
888 sub inithandle
889   {
890     my($inhandle)=@_;
891     $lastline{$inhandle}='';
892     $openblock{$inhandle}=0;
893     $closeblock{$inhandle}=0;
894     $blocklevel{$inhandle}=0;
895     $opencomment{$inhandle}=0;
896     $incomment{$inhandle}=0;
897     $closecomment{$inhandle}=0;
898   }
899 #given a file handle read it till we have a proper code line.
900 #something with either a { } or ; on it.
901 #Note: we do not handle stuff inside quotes yet.
902 #throw away all blank lines and comments
903 #then return the codeline
904 #keep the original line with comments in lastline 
905 #so the parser can use the pure uncommented version
906 #and we can printout the commented version
907 sub getcodeline
908   {
909     my ($inhandle)=@_;
910     my $retline='';
911     my $thisline;
912     $lastline{$inhandle}='';
913     while ($thisline=$inhandle->getline()) {
914       chomp $thisline;
915       if ($thisline =~ /^\s*$/m) { #ignore blank lines
916         $thisline='';
917         next;
918       }
919       if ($thisline =~ m://.*$:) { # strip single line comment
920         $lastline{$inhandle}.=$thisline."\n";
921         $thisline=$PREMATCH.$POSTMATCH;
922       } else {
923         $lastline{$inhandle}.=$thisline;
924       }
925       $retline.=$thisline;
926 #      last if ($retline =~ /^\s*\#/);
927       if ($retline =~ m:^\s*/\*.*\*/\s*$:m ) {
928         #pure comment line
929         # throw it out
930         $retline='';
931         $closecomment{$inhandle}=0;
932         $opencomment{$inhandle}=0;
933         $incomment{$inhandle}=0;
934         $lastline{$inhandle}.="\n";
935         next;
936     }
937 #      elsif ($retline =~ m:^\s*\#:m ) {
938         # precompile line
939         # pass it without consideration
940 #       $closecomment{$inhandle}=0;
941 #       $opencomment{$inhandle}=0;
942 #       $incomment{$inhandle}=0;
943 #       $lastline{$inhandle}.="\n";
944 #       last;
945 #      }
946  elsif ($retline =~ m:/\*.*\*/:m) { # line containing comment plus other stuff
947         #strip comments out
948         while ($retline =~ m:/\*.*\*/:m) {
949           $retline=$PREMATCH.$POSTMATCH;
950           $closecomment{$inhandle}=0;
951           $incomment{$inhandle}=0;
952           $opencomment{$inhandle}=0;
953         }
954         $lastline{$inhandle}.="\n";
955         next if($retline =~ /^\s*$/); #nothing to test
956       } elsif ($retline =~ m:/\*:m) {
957         $lastline{$inhandle}.="\n";
958         # we don't really use opencomment or closecomment for
959         # anything, but might as well keep track of the state.
960         $closecomment{$inhandle}=1;
961         next; #should now be handled by the comment stripper condition
962       } elsif ($retline =~ m:\*/:m) {
963         $opencomment{$inhandle}=1;
964         $incomment{$inhandle}=1;
965         next;        #keep scanning till we got the end of the comment
966       } elsif ($incomment{$inhandle}==1) { #keep scanning for end
967         next;
968       }
969       if ($retline =~ /\{/m) {
970         $openblock{$inhandle}=1;
971         $blocklevel{$inhandle}+=($retline =~tr/\{//);
972       } else {
973         $openblock{$inhandle}=0;
974       }
975       if ($retline =~ /\}/m) {
976         $closeblock{$inhandle}=1;
977         $blocklevel{$inhandle}-=($retline =~tr/\}//);
978       } else {
979         $closeblock{$inhandle}=0;
980       }
981       last if ($retline =~ /^\s*\#/);
982       last if ($retline =~ /;/m);
983       last if ($retline =~ /^\s*\w+\s*:\s*$/); # let publi|cprivate on its own line pass through 
984       last if($openblock{$inhandle}==1);
985       last if($closeblock{$inhandle}==1);
986     }
987     return $retline;
988   }
989
990 #given first line of a char object
991 #record useful structure
992 sub poserdeal
993   {
994     my($inhandle,$lineref,$thisline)=@_;
995     my $poser;
996     my @line=@$lineref;
997     my $class;
998     my $sim;
999     my $strat;
1000     my $rep;
1001     if (($openblock{$inhandle}==1) && ($blocklevel{$inhandle}==1)) {
1002       if ($thisline =~ /^\s*(poser)\s+(\S+)\s+\:\s+(\S+)\s+(\S+)\s+(\S+)\s*\{\s*$/) {
1003
1004         $line[0]="chare";
1005         $class=$2;
1006         $sim=$3;
1007         $strat=$4;
1008         $rep=$5;
1009         if($opt_s)
1010         {
1011             $strat='seq';
1012             $rep='rep'
1013         }
1014         print " poserdeal class $class \n";
1015         push(@strategies, $strat);
1016         push(@representations , $rep);
1017         $base{$class}=$sim;
1018         $strat{$class}=$strat;
1019         $rep{$class}=$rep;
1020         $events{$class}=[];
1021         push(@{$poser->{outarr}}, "  @line\n");
1022         push(@{$poser->{literal}}, "array [1D] ".$class." : ".$sim." \{");
1023         print  "chare ".$class." : ".$sim."\{\n";
1024         $needsopeq{$class}=1 if($strat{$class} eq "opt");
1025         $needsopeq{$class}=1 if($rep{$class} eq "chpt");
1026       }
1027       else {
1028         print $thisline;
1029         die "bad poser declaration";
1030       }
1031     } else {
1032       print $thisline;
1033       die "bad poser declaration";
1034     }
1035     #if sim, add to the base strat and rep hashes
1036     #scan for event declarations, track them in events hash and strip event keyword
1037     #store non even entries
1038     while (@line=split(' ',($thisline=getcodeline($inhandle)))) {
1039       if ($closeblock{$inhandle}==1) {
1040         push(@{$poser->{literal}}, $lastline{$inhandle});
1041         push(@{$poser->{outarr}}, "  ".$thisline);
1042         last;
1043       } 
1044       elsif ($line[0] eq "entry") {
1045         if ($thisline =~ /(\,event\,|\,event|event\,|\s\[event\]).*\s(.*)\(\s*(\S[^\*\s\)]*)/) {
1046           $method = $2;
1047           $message = $3;
1048           push(@{$events{$class}}, [$method,$message]);
1049           #       print " poserdeal events  class $class  method $method message $message \n";
1050         } elsif ($thisline =~ /\s+[\*]*\s*(\S+)\(/) {
1051           $method = $1;
1052           push(@{$nonevents{$class}}, ($method)) if $class ne $method;
1053         }
1054         $thisline =~ s/(\,event\,|\,event|event\,|\s\[event\])//;
1055         push(@{$poser->{literal}}, $thisline);
1056         push(@{$poser->{entry}},$thisline);
1057         push(@{$poser->{outarr}}, "  ".$thisline);
1058       }
1059       elsif($thisline =~ /(initnode|initproc).*\s(.*)\(\s*(\S[^\*\s\)]*)/) {
1060         $method= $2;
1061         $message= $3;
1062         push(@{$inits{$class}}, ($method)) if $class ne $method;
1063         printf("inits for $class $method\n");
1064         # there is no transformation for the literal method in ci
1065         # .h and .C just need to support static keyword and simple
1066         # callthru wrapper
1067         push(@{$poser->{literal}}, $thisline);
1068         push(@{$poser->{outarr}}, "  ".$thisline);
1069       }
1070
1071     }
1072     return $poser;
1073   }
1074
1075
1076 sub groupnchardeal
1077   {
1078     my($inhandle,$lineref,$thisline)=@_;
1079     my $group;
1080     my @line=@$lineref;
1081     my $class;
1082     push(@{$group->{literal}}, $lastline{$inhandle});
1083     if (($line[2] eq "{") || ($line[4] eq "{")) {
1084       $strat{$line[1]} = "none";
1085       push(@{$group->{outarr}}, "  $thisline\n");
1086
1087     } else {
1088       die "what the hell is this? $thisline ";
1089     }
1090     #if sim, add to the base strat and rep hashes
1091     #scan for event declarations, track them in events hash and strip event keyword
1092     while ($thisline=getcodeline($inhandle)) {
1093       @line=split(' ',$thisline);
1094       push(@{$group->{literal}}, $lastline{$inhandle});
1095       if ($closeblock{$inhandle}) {
1096         push(@{$group->{outarr}}, "  ".$thisline);
1097         last;
1098       } elsif ($line[0] eq "entry") {
1099         if ($thisline =~ /(\,event\,|\,event|event\,|\s\[event\]).*\s(.*)\(\s*(\S[^\*\s\)]*)/) {
1100 #         $method = $2;
1101           $message = $3;
1102           $method = $line[2];
1103           $method =~ s/\*?(.+)\(.+/$1/;
1104           push(@{$events{$class}}, [$method,$message]);
1105         } elsif ($thisline =~ /\s+[\*]*\s*(\S+)\(/) {   
1106           $method = $1;
1107           push(@{$nonevents{$class}}, ($method)) if $class ne $method;
1108         }
1109         $thisline =~ s/(\,event\,|\,event|event\,|\s\[event\])//;
1110         push(@{$group->{entry}},$thisline);
1111         push(@{$group->{outarr}}, "  ".$thisline);
1112       } else {
1113         if (($line[2] eq "{") || ($line[4] eq "{")) {
1114           $strat{$line[1]} = "none";
1115           push(@{$group->{outarr}}, "  ".$thisline);
1116         } else {
1117           die "what the hell is this $thisline";
1118         }
1119       }
1120     }
1121     return $group;
1122   }
1123
1124 sub posefunctest
1125   {
1126     my ($line)=shift;
1127     if ($line =~ /POSE_create/) {
1128       return 1;
1129     } elsif ($line =~ /POSE_creations_complete/) {
1130       return 2;
1131     } elsif ($line =~ /POSE_invoke_at/) {
1132       return 4;
1133     } elsif ($line =~ /POSE_invoke/) {
1134       return 3;
1135     } elsif ($line =~ /POSE_local_invoke/) {
1136       return 5;
1137     } else {
1138       return 0;
1139     }
1140   }
1141
1142 #given a POSE_* call break it down into its segments and return them as a list
1143 sub posefuncparse
1144   {
1145     my($line)=@_;
1146     my($restline);
1147     my @segments;
1148     if ($line =~ /\)\s*;\s*$/) { #strip );
1149       my $foo=$MATCH;
1150       $foo =~ tr/ \t//d;
1151       $line=$PREMATCH.$foo;
1152       chop $line;
1153       chop $line;
1154     }
1155     if ($line =~ /(POSE_[\w_]+)\s*\(/) { #strip funcname(
1156       $segments[0]=$1;
1157     } else {
1158       return undef;
1159     }
1160     my $preline=$PREMATCH;
1161     $restline=$POSTMATCH;
1162     if (($restline =~/\(+[^\)]*,[^\)]*\)/) || ($restline =~/\[+[^\]]*,[^\]]*\]/)) {
1163       #ok now we hunt down the groups and take them out of the expression
1164       #replace with &*# number
1165       my @inner_ugliness;
1166       my $hackline=$restline;
1167       while (($hackline =~/(\([^\(\)]*,[^\(\)]*\))/)||($hackline =~/(\[[^\[\]]*,[^\]\[]*\])/)) { # there exists an inner parenthesized expression with commas in
1168         push(@inner_ugliness,$1);
1169         $hackline=$PREMATCH.' &*#'.$#inner_ugliness.' '.$POSTMATCH;
1170       }
1171       my @uglysegs=split(/,/,$hackline);
1172       my $i;
1173       for ($i=0,$i<=$#uglysegs,$i++) {
1174         while ($uglysegs[$i] =~ /( &\*\#)([\d]+ )/) {
1175           $uglysegs[$i]=$PREMATCH.$inner_ugliness[$2].$POSTMATCH;
1176         }
1177       }
1178       push(@segments,@uglysegs);
1179     } else {                    #no ickiness just split it
1180       push(@segments,split(/,/,$restline));
1181     }
1182     my $i;
1183     for ($i=0;$i<$#segments;$i++) {
1184       $segments[$i]=~ s/^\s*(.*)\s*$/$1/e;
1185     }
1186     return($preline,@segments);
1187   }
1188
1189 #given an input line and the context
1190 #determine if it is a posefunc and if so map it.
1191 sub posefuncmap
1192   {
1193     my($line,$issim,$isconstructor,$simobjtype)=@_;
1194     my($type,$output);
1195     if (($type=posefunctest($line))>0) {
1196       #do stuff
1197       my($preline,@segments)=posefuncparse($line);
1198       
1199       if ($type==1)             #create
1200         {
1201           my($sim,$msg);
1202           if ($segments[1]=~/\s*([^(]*)\s*\(\s*([^)]*)\s*\)/) {
1203             $sim=$1;
1204             $msg=$2;
1205             $output=$preline."\n{\n";
1206             $output.="int _POSE_handle = ".$segments[3].";\n";
1207             $output.="POSE_TimeType _POSE_atTime = ".$segments[4].";\n" if ($#segments>=4);
1208             $output.=$msg."->Timestamp(_POSE_handle);\n";
1209             $output.="#ifdef DEBUG_POSE_INVOKE\n";
1210             $output.='CkError("invoking (*(CProxy_'.$sim.' *)&parent->thisProxy)['.$segments[2].'].insert('.$msg.')at line %d\n",__LINE__);'."\n";
1211             $output.="#endif\n";
1212             $output.="(*(CProxy_".$sim." *)&parent->thisProxy)[".$segments[2]."].insert(".$msg;
1213             if ($#segments>=4) {
1214               $output.=",_POSE_atTime";
1215             }
1216             $output.=");}\n";
1217           } else {
1218             die "could not parse ".$segments[1]."in $line";
1219           }
1220         } elsif ($type==2)      #create_complete
1221           {
1222             $output=$preline."parent->thisProxy.doneInserting();\n";
1223           } elsif ($type==3)    #invoke
1224             {
1225               if (!$issim) {
1226                 die "cannot use POSE_invoke from non sim object";
1227               }
1228               my($event,$msg);
1229               if ($segments[1]=~/\s*([^(]*)\s*\(\s*([^)]*)\s*\)/) {
1230                 $event=$1;
1231                 $msg=$2;
1232                 if ($isconstructor) {
1233                   $output=$preline."\n{\n";
1234                   $output.="int _POSE_handle = ".$segments[3].";\n";
1235                   if ($#segments>=4)
1236                   {
1237                       $output.="POSE_TimeType _POSE_timeOffset = ".$segments[4].";\n";
1238                   }
1239                   else
1240                   {
1241                       $output.="POSE_TimeType _POSE_timeOffset = 0;\n";
1242                   }
1243                   $output.="CkAssert(_POSE_timeOffset >=0);";
1244                   $output.=$msg."->Timestamp(ovt+(_POSE_timeOffset));\n";
1245                   $output.="#ifndef SEQUENTIAL_POSE\n";
1246                   $output.="PVT *pvt = (PVT *)CkLocalBranch(ThePVT);\n";
1247                   $output.="pvt->objUpdate(ovt+(_POSE_timeOffset), SEND);\n";
1248                   $output.="#endif\n";
1249                   #$output.="char str[30];\n";
1250                   #$output.="CkPrintf(\"[%d] SEND(event) to [%d] @ %d: Event=%s\\n\", parent->thisIndex, _POSE_handle, $msg->timestamp, $msg->evID.sdump(str));\n";
1251                   $output.="#ifndef CMK_OPTIMIZE\n";
1252                   $output.="$msg->sanitize();\n";
1253                   $output.="#endif\n";
1254                   $output.="#ifndef CMK_OPTIMIZE\n";
1255                   $output.="  if(pose_config.stats)\n";
1256                   $output.="    parent->localStats->SwitchTimer(COMM_TIMER);\n";
1257                   $output.="#endif\n";
1258                   $output.="#ifdef DEBUG_POSE_INVOKE\n";
1259                   $output.='CkError("invoking (*(CProxy_'.$segments[2].' *)&parent->thisProxy)[%d].'.$segments[1].'at line %d\n",_POSE_handle,__LINE__);'."\n";
1260                   $output.="#endif\n";
1261
1262                   $output.="(* (CProxy_".$segments[2]." *)&parent->thisProxy)[_POSE_handle].".$segments[1].";\n";
1263                   $output.="#ifndef CMK_OPTIMIZE\n";
1264                   $output.="  if(pose_config.stats)\n";
1265                   $output.="    parent->localStats->SwitchTimer(DO_TIMER);\n";
1266                   $output.="#endif\n";
1267                   #$output.="int _destPE = parent->thisProxy.ckLocalBranch()->lastKnown(CkArrayIndex1D(_POSE_handle));\n";
1268
1269                   #$output.="parent->srVector[_destPE]++;\n";
1270                   $output.="}\n";
1271                 } else {
1272                   $output=$preline."\n{\n";
1273                   $output.="if (!CpvAccess(stateRecovery)) {\n";
1274                   $output.="int _POSE_handle = ".$segments[3].";\n";
1275                   $output.="POSE_TimeType _POSE_timeOffset = ".$segments[4].";\n";
1276                   $output.="registerTimestamp(_POSE_handle, ".$msg.",_POSE_timeOffset);\n";
1277                   $output.="if(pose_config.dop){\n";
1278                   $output.="  parent->ct = CmiWallTimer();\n";
1279                   $output.="  $msg->rst = parent->ct - parent->st + parent->eq->currentPtr->srt;\n";
1280                   $output.="}\n";
1281                   #$output.="char str[30];\n";
1282                   #$output.="CkPrintf(\"[%d] SEND(event) to [%d] @ %d: Event=%s\\n\", parent->thisIndex, _POSE_handle, $msg->timestamp, $msg->evID.sdump(str));\n";               
1283                   $output.="#ifndef CMK_OPTIMIZE\n";
1284                   $output.="$msg->sanitize();\n";
1285                   $output.="#endif\n";
1286                   $output.="#ifndef CMK_OPTIMIZE\n";
1287                   $output.="  if(pose_config.stats)\n";
1288                   $output.="    parent->localStats->SwitchTimer(COMM_TIMER);\n";
1289                   $output.="#endif\n";
1290                   $output.="#ifdef DEBUG_POSE_INVOKE\n";
1291                   $output.='CkError("invoking (*(CProxy_'.$segments[2].' *)&parent->thisProxy)[%d].'.$segments[1].'at line %d\n",_POSE_handle,__LINE__);'."\n";
1292                   $output.="#endif\n";
1293
1294                   $output.="(* (CProxy_".$segments[2]." *)&parent->thisProxy)[_POSE_handle].".$segments[1].";\n";
1295                   $output.="#ifndef CMK_OPTIMIZE\n";
1296                   $output.="  if(pose_config.stats)\n";
1297                   $output.="    parent->localStats->SwitchTimer(DO_TIMER);\n";
1298                   $output.="#endif\n";
1299                   #$output.="int _destPE = parent->thisProxy.ckLocalBranch()->lastKnown(CkArrayIndex1D(_POSE_handle));\n";
1300                   #$output.="parent->srVector[_destPE]++;\n";
1301                   $output.="}\n";
1302                   $output.="else delete ".$msg.";}\n";
1303                 }
1304               } else {
1305                 die "could not parse .".$segments[1]."in $line";
1306               }
1307             } elsif ($type==4)  #invoke_at
1308               {
1309                 my($event,$msg);
1310                 if ($segments[1]=~/\s*([^(]*)\s*\(\s*([^)]*)\s*\)/) {
1311                   $event=$1;
1312                   $msg=$2;
1313                   if (!$issim || ($issim && $isconstructor)) {
1314                     print "warning: should use POSE_invoke instead of POSE_invoke_at inside sim object constructors\n" if ($issim && $isconstructor);
1315                     $output=$preline."\n{\n";
1316                     $output.="int _POSE_handle = ".$segments[3].";\n";
1317                     $output.="POSE_TimeType _POSE_atTime =".$segments[4].";\n";
1318                     $output.="CkAssert(_POSE_atTime >=0);\n";
1319                     $output.=$msg."->Timestamp(_POSE_atTime);\n";
1320                     $output.="#ifndef SEQUENTIAL_POSE\n";
1321                     $output.="PVT *pvt = (PVT *)CkLocalBranch(ThePVT);\n";
1322                     $output.="pvt->objUpdate(_POSE_atTime, SEND);\n";
1323                     $output.="#endif\n";
1324                     #$output.="char str[30];\n";
1325                     #$output.="CkPrintf(\"[%d] SEND(event) to [%d] @ %d: Event=%s\\n\", parent->thisIndex, _POSE_handle, $msg->timestamp, $msg->evID.sdump(str));\n";             
1326                     $output.="#ifndef CMK_OPTIMIZE\n";
1327                     $output.="$msg->sanitize();\n";
1328                     $output.="#endif\n";
1329                   $output.="#ifndef CMK_OPTIMIZE\n";
1330                   $output.="  if(pose_config.stats)\n";
1331                   $output.="   parent->localStats->SwitchTimer(COMM_TIMER);\n";
1332                   $output.="#endif\n";
1333                   $output.="#ifdef DEBUG_POSE_INVOKE\n";
1334                   $output.='CkError("invoking (*(CProxy_'.$segments[2].' *)&parent->thisProxy)[%d].insert('.$segments[1].'at line %d\n",_POSE_handle,__LINE__);'."\n";
1335                   $output.="#endif\n";
1336
1337                     $output.="(*(CProxy_".$segments[2]." *)&parent->thisProxy)[_POSE_handle].".$segments[1].";\n";
1338                   $output.="#ifndef CMK_OPTIMIZE\n";
1339                   $output.="  if(pose_config.stats)\n";
1340                   $output.="    parent->localStats->SwitchTimer(DO_TIMER);\n";
1341                   $output.="#endif\n";
1342                     #$output.="int _destPE = parent->thisProxy.ckLocalBranch()->lastKnown(CkArrayIndex1D(_POSE_handle));\n";
1343                     #$output.="parent->srVector[_destPE]++;\n";
1344                     $output.="}\n";
1345               
1346                     $output.="}\n";
1347                   } else {
1348                     print "warning: should use POSE_invoke instead of POSE_invoke_at in side sim object nonconstructors\n" if ($issim && $isconstructor);
1349                     $output=$preline."\n{\n";
1350                     $output.="int _POSE_handle = ".$segments[3].";\n";
1351                     $output.="int _POSE_atTime = ".$segments[4].";\n";
1352                     $output.="if (!CpvAccess(stateRecovery)) {\n";
1353                     $output.="registerTimestamp(_POSE_handle, ".$msg.", _POSE_atTime);\n";
1354                     $output.="if(pose_config.dop){\n";
1355                     $output.="  parent->ct = CmiWallTimer();\n";
1356                     $output.="  $msg->rst = parent->ct - parent->st + parent->eq->currentPtr->srt;\n";
1357                     $output.="}\n";
1358                     #$output.="char str[30];\n";
1359                     #$output.="CkPrintf(\"[%d] SEND(event) to [%d] @ %d: Event=%s\\n\", parent->thisIndex, _POSE_handle, $msg->timestamp, $msg->evID.sdump(str));\n";             
1360                     $output.="#ifndef CMK_OPTIMIZE\n";
1361                     $output.="$msg->sanitize();\n";
1362                     $output.="#endif\n";
1363                   $output.="#ifndef CMK_OPTIMIZE\n";
1364                   $output.="  if(pose_config.stats)\n";
1365                   $output.="    parent->localStats->SwitchTimer(COMM_TIMER);\n";
1366                   $output.="#endif\n";
1367                   $output.="#ifdef DEBUG_POSE_INVOKE\n";
1368                   $output.='CkError("invoking (*(CProxy_'.$segments[2].' *)&parent->thisProxy)[%d].insert('.$segments[1].'at line %d\n",_POSE_handle,__LINE__);'."\n";
1369                   $output.="#endif\n";
1370                     $output.="(* (CProxy_".$segments[2]." *)&parent->thisProxy)[_POSE_handle].".$segments[1].";\n";
1371                   $output.="#ifndef CMK_OPTIMIZE\n";
1372                   $output.="  if(pose_config.stats)\n";
1373                   $output.="    parent->localStats->SwitchTimer(DO_TIMER);\n";
1374                   $output.="#endif\n";
1375                     #$output.="int _destPE = parent->thisProxy.ckLocalBranch()->lastKnown(CkArrayIndex1D(_POSE_handle));\n";
1376                     #$output.="parent->srVector[_destPE]++;\n";
1377                     $output.="}\n";
1378                     $output.="else delete ".$msg.";}\n";
1379                   }
1380                 } else {
1381                   die "could not parse ".$segments[1]."in $line";
1382                 }
1383               } elsif ($type==5) #local_invoke
1384                 {
1385                   my($event,$msg);
1386                   if ($segments[1]=~/\s*([^(]*)\s*\(\s*([^)]*)\s*\)/) {
1387                     $event=$1;
1388                     $msg=$2;
1389                     if ($issim && $isconstructor) {
1390                       $output=$preline."\n{\n";
1391                       $output.="POSE_TimeType _POSE_timeOffset = ".$segments[2].";\n";
1392                       $output.=$msg."->Timestamp(ovt+(_POSE_timeOffset));\n";
1393                       $output.="#ifndef SEQUENTIAL_POSE\n";
1394                       $output.="PVT *pvt = (PVT *)CkLocalBranch(ThePVT);\n";
1395                       $output.="pvt->objUpdate(ovt+(_POSE_timeOffset), SEND);\n";
1396                       $output.="#endif\n";
1397                       #$output.="char str[30];\n";
1398                       #$output.="CkPrintf(\"[%d] SEND(event) to [%d] @ %d: Event=%s\\n\", parent->thisIndex, parent->thisIndex, $msg->timestamp, $msg->evID.sdump(str));\n";              
1399                       $output.="#ifndef CMK_OPTIMIZE\n";
1400                       $output.="$msg->sanitize();\n";
1401                       $output.="#endif\n";
1402                   $output.="#ifndef CMK_OPTIMIZE\n";
1403                   $output.="  if(pose_config.stats)\n";
1404                   $output.="    parent->localStats->SwitchTimer(COMM_TIMER);\n";
1405                   $output.="#endif\n";
1406                       $output.="(* (CProxy_".$simobjtype." *)&parent->thisProxy)[parent->thisIndex].".$segments[1].";\n";
1407                   $output.="#ifndef CMK_OPTIMIZE\n";
1408                   $output.="  if(pose_config.stats)\n";
1409                   $output.="    parent->localStats->SwitchTimer(DO_TIMER);\n";
1410                   $output.="#endif\n";
1411
1412                       #$output.="parent->srVector[CkMyPe()]++;\n";
1413                       $output.="}\n";
1414                     } elsif ($issim) {
1415                       $output=$preline."\n{\n";
1416                       $output.="POSE_TimeType _POSE_timeOffset = ".$segments[2].";\n";
1417                       $output.="if (!CpvAccess(stateRecovery)) {\n";
1418                       $output.="registerTimestamp(parent->thisIndex, ".$msg.", _POSE_timeOffset);\n";
1419                       $output.="if(pose_config.dop){\n";
1420                       $output.="  parent->ct = CmiWallTimer();\n";
1421                       $output.="  $msg->rst = parent->ct - parent->st + parent->eq->currentPtr->srt;\n";
1422                       $output.="}\n";
1423                       #$output.="char str[30];\n";
1424                       #$output.="CkPrintf(\"[%d] SEND(event) to [%d] @ %d: Event=%s\\n\", parent->thisIndex, parent->thisIndex, $msg->timestamp, $msg->evID.sdump(str));\n";              
1425                       $output.="#ifndef CMK_OPTIMIZE\n";
1426                       $output.="$msg->sanitize();\n";
1427                       $output.="#endif\n";
1428                       $output.="#ifndef CMK_OPTIMIZE\n";
1429                       $output.="  if(pose_config.stats)\n";
1430                       $output.="    parent->localStats->SwitchTimer(COMM_TIMER);\n";
1431                       $output.="#endif\n";
1432                       $output.="#ifdef DEBUG_POSE_INVOKE\n";
1433                       $output.='CkError("invoking (*(CProxy_'.$simobjtype.' *)&parent->thisProxy)[%d].'.$segments[1].'at line %d\n",parent->thisIndex,__LINE__);'."\n";
1434                       $output.="#endif\n";
1435
1436                       $output.="(* (CProxy_".$simobjtype." *)&parent->thisProxy)[parent->thisIndex].".$segments[1].";\n";
1437                   $output.="#ifndef CMK_OPTIMIZE\n";
1438                   $output.="  if(pose_config.stats)\n";
1439                   $output.="    parent->localStats->SwitchTimer(DO_TIMER);\n";
1440                   $output.="#endif\n";
1441                       #$output.="parent->srVector[CkMyPe()]++;\n";
1442                       $output.="}\n";
1443                       $output.="else delete(".$msg.");\n}";
1444                     } else {
1445                       die "untranslatably deranged to call POSE_local_invoke from non sim object";
1446                     }
1447                   } else {
1448                     die "could not parse .".$segments[1];
1449                   }
1450                 }
1451     }
1452   }
1453