9509574714c792ceb724aa7aa2f64e712d0bd696
[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("#ifndef CMK_OPTIMIZE\n");
633         $outChandle->print("  if(pose_config.stats)\n");
634         $outChandle->print("    {localStats->TimerStart(SIM_TIMER);}\n");
635         $outChandle->print("#endif\n");
636         $outChandle->print("  LBgroup *localLBG;\n\n");
637         $outChandle->print("  if(pose_config.lb_on)\n");
638         $outChandle->print("     localLBG = TheLBG.ckLocalBranch();\n\n");
639         $outChandle->print("  myStrat = new ".$strat{$class}."();\n");
640         $outChandle->print("  $messagename->parent = this;\n");
641         $outChandle->print("  $messagename->str = myStrat;\n");
642         $outChandle->print("  POSE_TimeType _ts = $messagename->timestamp;\n");
643         $outChandle->print("#ifndef CMK_OPTIMIZE\n  if(pose_config.stats){\n    localStats->SwitchTimer(DO_TIMER);}\n#endif\n");
644
645         $outChandle->print("  objID = new state_$method($messagename);\n");
646         $outChandle->print("#ifndef CMK_OPTIMIZE\n  if(pose_config.stats){\n    localStats->SwitchTimer(SIM_TIMER);}\n#endif\n");
647         $outChandle->print("  myStrat->init(eq, objID, this, thisIndex);\n");
648         $outChandle->print("#ifndef CMK_OPTIMIZE\n  if(pose_config.stats){\n    localStats->TimerStop();}\n#endif\n");
649         $outChandle->print("#ifndef SEQUENTIAL_POSE\n");
650         $outChandle->print("  PVT *pvt = (PVT *)CkLocalBranch(ThePVT);\n");
651         $outChandle->print("  myPVTidx = pvt->objRegister(thisIndex, _ts, sync, this);\n");
652         $outChandle->print("#endif\n");
653         $outChandle->print("  if(pose_config.lb_on)\n");
654         $outChandle->print("    myLBidx = localLBG->objRegister(thisIndex, sync, this);\n");
655         $outChandle->print("}\n");
656         #create the pup constructor
657         if (exists($puppy{$class})) {
658           $outChandle->print(join('','void ',$class,"::pup(PUP::er &p)\n"));
659           $outChandle->print("  {\n");
660           $outChandle->print("    sim::pup(p);\n");
661           $outChandle->print("    if (p.isUnpacking()) {\n");
662           $outChandle->print("      myStrat = new ".$strat{$class}.";\n");
663           $outChandle->print("      objID = new state_$class(this, myStrat);\n");
664           $outChandle->print("      myStrat->init(eq, objID, this, thisIndex);\n");
665           $outChandle->print("    }\n");
666           $outChandle->print("    ((state_$class *)objID)->pup(p);\n");
667           if ($rep{$class} eq "chpt") {
668             $outChandle->print("    Event *ev = eq->front()->next;\n");
669             $outChandle->print("    int checkpointed;\n\n");
670             $outChandle->print("    while (ev != eq->back()) {\n");
671             $outChandle->print("      if (p.isUnpacking()) {\n");
672             $outChandle->print("        p(checkpointed);\n");
673             $outChandle->print("        if (checkpointed) {\n");
674             $outChandle->print("          ev->cpData = new state_$class(this, myStrat);\n");
675             $outChandle->print("          ((state_$class *)ev->cpData)->cpPup(p);\n");
676             $outChandle->print("        }\n");
677             $outChandle->print("        else ev->cpData = NULL;\n");
678             $outChandle->print("      }\n");
679             $outChandle->print("      else {\n");
680             $outChandle->print("        if (ev->cpData) {\n");
681             $outChandle->print("          checkpointed = 1;\n");
682             $outChandle->print("          p(checkpointed);\n");
683             $outChandle->print("          ((state_$class *)ev->cpData)->cpPup(p);\n");
684             $outChandle->print("        }\n");
685             $outChandle->print("        else {\n");
686             $outChandle->print("          checkpointed = 0;\n");
687             $outChandle->print("          p(checkpointed);\n");
688             $outChandle->print("        }\n");
689             $outChandle->print("      } \n");
690             $outChandle->print("     ev=ev->next; \n");
691             $outChandle->print("    }\n");
692
693           }
694           $outChandle->print("  }\n");
695         }
696       } else {                  #non constructor
697       }
698       if ($closeblock{$inChandle}==1) { #its a one liner
699         print "oneliner for  $class $method sim $issim\n";
700         $declaration =~ s/(\b$class\b)/state_$1/gm      if($issim);
701         if (($method eq 'pup') &&(exists($puppy{$class})) && !exists($cppuppy{$class}) && ($rep{$class} eq "chpt")) {
702           my $cpdec=$declaration;
703           $cpdec =~ s/:pup/:cpPup/gm;
704           $outChandle->print($cpdec."\n");
705         }
706         $outChandle->print($declaration."\n");
707         $inbody=0;
708       }
709       # print "done open on $thisline :level".$blocklevel{$inChandle}." open:".$openblock{$inChandle}." close:".$closeblock{$inChandle}."\n";
710     } elsif (($blocklevel{$inChandle}==0) && ($closeblock{$inChandle}==1)) { #got the whole thing
711       #handle verbatim and translation copying of block
712       #if rep is chpt and the $puppy{$class} hash has no elements make the cpPup copy
713       #      print "on close class is $class, method is $method issim = $issim iseventmethod = $iseventmethod \n";
714       # print "close  for $class $method \n";
715       $declaration =~ s/(\b$class\b)/state_$1/gm      if($issim);
716
717       if (($method eq 'pup') &&(exists($puppy{$class}))  && !exists($cppuppy{$class}) && ($rep{$class} eq "chpt")) {
718         my $cpdec=$declaration;
719         $cpdec =~ s/:pup/:cpPup/gm;
720         $outChandle->print($cpdec."\n");
721         foreach (@body) {
722           if ($_ =~ /(chpt<state[^>]+>)/) { #translate to rep
723             $outChandle->print($`."rep".$'."\n");
724           } else {
725             $outChandle->print($_."\n");
726           }
727         }
728       }
729       $outChandle->print($declaration."\n");
730       $outChandle->print("init($messagename);\n") if(length($messagename) && ($issim && $isconstructor));
731       while ($_ =shift @body) {
732         s/\bthishandle\b/thisIndex/gm;
733         if(/chpt/)
734           {
735             $outChandle->print("#ifndef SEQUENTIAL_POSE\n");
736             $outChandle->print("$_"."\n");
737             $outChandle->print("#endif\n");
738           }
739         else
740           {
741             $outChandle->print($_."\n");
742           }
743       }
744       $inbody=0;
745     } elsif (!$inbody) {        #regular line
746       #    print "regular line $thisline at $incfile is passed untranslated \n";
747       $outChandle->print($lastline{$inChandle}."\n");
748     } else {
749     }
750   }
751   #test incomplete block
752   if($blocklevel{$inChandle}>0 || $openblock{$inChandle}>0)
753     {
754       print STDERR "ERROR $incfile file terminated with open block\n";
755     }
756   $outChandle->print("\n");
757   $inChandle->close;
758   if ($incfile eq $inC) {
759     #generate ResolveFns 
760     my ($key,$count,$first,@array);
761     foreach $key (keys %methods) {
762       print "key is $key\n";
763       if ($strat{$key} ne "none") {
764         my $count = 1;
765         my $first = 1;
766         my $ifopen=0;
767         @array = @{$methods{$key}};
768         foreach my $i (@array) {
769           $found = 0;
770           foreach my $j (@{$events{$key}}) {
771             if (($j->[0] eq $i->[0])&& ($i->[1]==$j->[1])) {
772               $found = 1;
773             }
774           }
775           if ($found && ($i->[0] ne $key)) {
776             if ($ifopen ==0) {
777               $outChandle->print("void $key\:\:ResolveFn(int fnIdx, void *msg)\n{\n");
778               $outChandle->print("  if (fnIdx >0){\n");
779               $outChandle->print("    if (sync == OPTIMISTIC)\n");
780               $outChandle->print("      ((state_$key *) objID)->checkpoint((state_$key *) objID);\n");
781               $outChandle->print("    ((state_$key *) objID)->update(((eventMsg *)msg)->timestamp, ((eventMsg *)msg)->rst);\n");
782               $outChandle->print("  }\n");
783
784
785               $outChandle->print("  if (fnIdx == ");
786               $ifopen=1;
787             } elsif ($first == 0) {
788               $outChandle->print("  else if (fnIdx == ");
789             }
790             $outChandle->print("$count) {\n");
791             $first = 0;
792             $outChandle->print("#ifndef CMK_OPTIMIZE\n");
793             $outChandle->print("  if(pose_config.stats)\n");
794             $outChandle->print("    if (!CpvAccess(stateRecovery)) {localStats->Do();\n");
795             $outChandle->print("    if(pose_config.dop)\n");
796             $outChandle->print("      st = CmiWallTimer();\n");
797             $outChandle->print("    localStats->SwitchTimer(DO_TIMER);}\n");
798             $outChandle->print("#endif\n");
799
800             $outChandle->print("    ((state_$key *) objID)->$i->[0](($i->[1] *)msg);\n");
801             $outChandle->print("#ifndef CMK_OPTIMIZE\n");
802             $outChandle->print("  if(pose_config.stats)\n");
803             $outChandle->print("    if (!CpvAccess(stateRecovery)) {\n");
804             $outChandle->print("    if(pose_config.dop){\n");
805             $outChandle->print("      et = CmiWallTimer();\n");
806             $outChandle->print("      eq->currentPtr->ert = eq->currentPtr->srt + (et-st);\n");
807             $outChandle->print("      ((state_$key *) objID)->ort = eq->currentPtr->ert+0.000001;\n");
808             $outChandle->print("      eq->currentPtr->evt = ((state_$key *) objID)->OVT();\n");
809             $outChandle->print("    }\n");
810             $outChandle->print("    localStats->SwitchTimer(SIM_TIMER);}\n");
811             $outChandle->print("#endif\n");
812
813             $outChandle->print("  }\n");
814             $outChandle->print("  else if (fnIdx == -$count) {\n");
815             $outChandle->print("    ((state_$key *) objID)->$i->[0]_anti(($i->[1] *)msg);\n");
816             $outChandle->print("  }\n");
817             $count++;
818           }
819         }
820         if ($ifopen) {
821           $outChandle->print("}\n\n");
822         }
823       }
824     }
825
826     foreach $key (keys %methods) {
827       if ($strat{$key} ne "none") {
828         my $count = 1;
829         my $first = 1;
830         my $ifopen =0;
831         @array = @{$methods{$key}};
832         foreach my $i (@array) {
833           $found = 0;
834           foreach my $j (@{$events{$key}}) {
835             if (($j->[0] eq $i->[0]) &&($i->[1]==$j->[1])) {
836               $found = 1;
837             }
838           }
839           if ($found && ($i->[0] ne $key)) {
840             if ($ifopen == 0) {
841               $outChandle->print("void $key\:\:ResolveCommitFn(int fnIdx, void *msg)\n{\n");
842
843               $outChandle->print("  if (fnIdx == ");
844               $ifopen=1;
845             } elsif ($first == 0) {
846               $outChandle->print("  else if (fnIdx == ");
847             }
848             $outChandle->print("$count) {\n");
849             $first = 0;
850             $outChandle->print("    ((state_$key *) objID)->$i->[0]_commit(($i->[1] *)msg);\n");
851             $outChandle->print("  }\n");
852             $count++;
853           }
854         }
855         if ($ifopen) {
856           $outChandle->print("}\n\n");
857         }
858       }
859
860     }
861   }
862
863   #create the inline mapsize function
864   #$outChandle->print("int MapSizeToIdx(int size)\n{\n");
865   #my $sizeline=0;
866   #$outChandle->print("    static int eventMsgSz = sizeof(eventMsg);\n"); 
867   #foreach my $i (keys %emessages) {
868   #  $outChandle->print("    static int ".$i."Sz = sizeof(".$i.");\n"); 
869   #}
870   #$outChandle->print("\n");
871   #$outChandle->print("    if (size == eventMsgSz) return ".$sizeline++.";\n");
872   #foreach my $i (keys %emessages) {
873   #  $outChandle->print("    else if (size == ".$i."Sz) return ".$sizeline++.";\n");
874   #}
875   #$outChandle->print("    return $sizeline;\n");
876   #$outChandle->print("}\n");
877   #$outChandle->close;
878
879   # END WRITE .C FILES
880 }
881
882 #codelines have  ; or { or */
883 #we keep reading till our line meets those criteria.
884 #it could conceivably exceed them and have more than one logical code line
885 #we're willing to live with that for now. 
886 #we'll record block open, close, and comment for test convenience.
887 sub inithandle
888   {
889     my($inhandle)=@_;
890     $lastline{$inhandle}='';
891     $openblock{$inhandle}=0;
892     $closeblock{$inhandle}=0;
893     $blocklevel{$inhandle}=0;
894     $opencomment{$inhandle}=0;
895     $incomment{$inhandle}=0;
896     $closecomment{$inhandle}=0;
897   }
898 #given a file handle read it till we have a proper code line.
899 #something with either a { } or ; on it.
900 #Note: we do not handle stuff inside quotes yet.
901 #throw away all blank lines and comments
902 #then return the codeline
903 #keep the original line with comments in lastline 
904 #so the parser can use the pure uncommented version
905 #and we can printout the commented version
906 sub getcodeline
907   {
908     my ($inhandle)=@_;
909     my $retline='';
910     my $thisline;
911     $lastline{$inhandle}='';
912     while ($thisline=$inhandle->getline()) {
913       chomp $thisline;
914       if ($thisline =~ /^\s*$/m) { #ignore blank lines
915         $thisline='';
916         next;
917       }
918       if ($thisline =~ m://.*$:) { # strip single line comment
919         $lastline{$inhandle}.=$thisline."\n";
920         $thisline=$PREMATCH.$POSTMATCH;
921       } else {
922         $lastline{$inhandle}.=$thisline;
923       }
924       $retline.=$thisline;
925 #      last if ($retline =~ /^\s*\#/);
926       if ($retline =~ m:^\s*/\*.*\*/\s*$:m ) {
927         #pure comment line
928         # throw it out
929         $retline='';
930         $closecomment{$inhandle}=0;
931         $opencomment{$inhandle}=0;
932         $incomment{$inhandle}=0;
933         $lastline{$inhandle}.="\n";
934         next;
935     }
936 #      elsif ($retline =~ m:^\s*\#:m ) {
937         # precompile line
938         # pass it without consideration
939 #       $closecomment{$inhandle}=0;
940 #       $opencomment{$inhandle}=0;
941 #       $incomment{$inhandle}=0;
942 #       $lastline{$inhandle}.="\n";
943 #       last;
944 #      }
945  elsif ($retline =~ m:/\*.*\*/:m) { # line containing comment plus other stuff
946         #strip comments out
947         while ($retline =~ m:/\*.*\*/:m) {
948           $retline=$PREMATCH.$POSTMATCH;
949           $closecomment{$inhandle}=0;
950           $incomment{$inhandle}=0;
951           $opencomment{$inhandle}=0;
952         }
953         $lastline{$inhandle}.="\n";
954         next if($retline =~ /^\s*$/); #nothing to test
955       } elsif ($retline =~ m:/\*:m) {
956         $lastline{$inhandle}.="\n";
957         # we don't really use opencomment or closecomment for
958         # anything, but might as well keep track of the state.
959         $closecomment{$inhandle}=1;
960         next; #should now be handled by the comment stripper condition
961       } elsif ($retline =~ m:\*/:m) {
962         $opencomment{$inhandle}=1;
963         $incomment{$inhandle}=1;
964         next;        #keep scanning till we got the end of the comment
965       } elsif ($incomment{$inhandle}==1) { #keep scanning for end
966         next;
967       }
968       if ($retline =~ /\{/m) {
969         $openblock{$inhandle}=1;
970         $blocklevel{$inhandle}+=($retline =~tr/\{//);
971       } else {
972         $openblock{$inhandle}=0;
973       }
974       if ($retline =~ /\}/m) {
975         $closeblock{$inhandle}=1;
976         $blocklevel{$inhandle}-=($retline =~tr/\}//);
977       } else {
978         $closeblock{$inhandle}=0;
979       }
980       last if ($retline =~ /^\s*\#/);
981       last if ($retline =~ /;/m);
982       last if ($retline =~ /^\s*\w+\s*:\s*$/); # let publi|cprivate on its own line pass through 
983       last if($openblock{$inhandle}==1);
984       last if($closeblock{$inhandle}==1);
985     }
986     return $retline;
987   }
988
989 #given first line of a char object
990 #record useful structure
991 sub poserdeal
992   {
993     my($inhandle,$lineref,$thisline)=@_;
994     my $poser;
995     my @line=@$lineref;
996     my $class;
997     my $sim;
998     my $strat;
999     my $rep;
1000     if (($openblock{$inhandle}==1) && ($blocklevel{$inhandle}==1)) {
1001       if ($thisline =~ /^\s*(poser)\s+(\S+)\s+\:\s+(\S+)\s+(\S+)\s+(\S+)\s*\{\s*$/) {
1002
1003         $line[0]="chare";
1004         $class=$2;
1005         $sim=$3;
1006         $strat=$4;
1007         $rep=$5;
1008         if($opt_s)
1009         {
1010             $strat='seq';
1011             $rep='rep'
1012         }
1013         print " poserdeal class $class \n";
1014         push(@strategies, $strat);
1015         push(@representations , $rep);
1016         $base{$class}=$sim;
1017         $strat{$class}=$strat;
1018         $rep{$class}=$rep;
1019         $events{$class}=[];
1020         push(@{$poser->{outarr}}, "  @line\n");
1021         push(@{$poser->{literal}}, "array [1D] ".$class." : ".$sim." \{");
1022         print  "chare ".$class." : ".$sim."\{\n";
1023         $needsopeq{$class}=1 if($strat{$class} eq "opt");
1024         $needsopeq{$class}=1 if($rep{$class} eq "chpt");
1025       }
1026       else {
1027         print $thisline;
1028         die "bad poser declaration";
1029       }
1030     } else {
1031       print $thisline;
1032       die "bad poser declaration";
1033     }
1034     #if sim, add to the base strat and rep hashes
1035     #scan for event declarations, track them in events hash and strip event keyword
1036     #store non even entries
1037     while (@line=split(' ',($thisline=getcodeline($inhandle)))) {
1038       if ($closeblock{$inhandle}==1) {
1039         push(@{$poser->{literal}}, $lastline{$inhandle});
1040         push(@{$poser->{outarr}}, "  ".$thisline);
1041         last;
1042       } 
1043       elsif ($line[0] eq "entry") {
1044         if ($thisline =~ /(\,event\,|\,event|event\,|\s\[event\]).*\s(.*)\(\s*(\S[^\*\s\)]*)/) {
1045           $method = $2;
1046           $message = $3;
1047           push(@{$events{$class}}, [$method,$message]);
1048           #       print " poserdeal events  class $class  method $method message $message \n";
1049         } elsif ($thisline =~ /\s+[\*]*\s*(\S+)\(/) {
1050           $method = $1;
1051           push(@{$nonevents{$class}}, ($method)) if $class ne $method;
1052         }
1053         $thisline =~ s/(\,event\,|\,event|event\,|\s\[event\])//;
1054         push(@{$poser->{literal}}, $thisline);
1055         push(@{$poser->{entry}},$thisline);
1056         push(@{$poser->{outarr}}, "  ".$thisline);
1057       }
1058       elsif($thisline =~ /(initnode|initproc).*\s(.*)\(\s*(\S[^\*\s\)]*)/) {
1059         $method= $2;
1060         $message= $3;
1061         push(@{$inits{$class}}, ($method)) if $class ne $method;
1062         printf("inits for $class $method\n");
1063         # there is no transformation for the literal method in ci
1064         # .h and .C just need to support static keyword and simple
1065         # callthru wrapper
1066         push(@{$poser->{literal}}, $thisline);
1067         push(@{$poser->{outarr}}, "  ".$thisline);
1068       }
1069
1070     }
1071     return $poser;
1072   }
1073
1074
1075 sub groupnchardeal
1076   {
1077     my($inhandle,$lineref,$thisline)=@_;
1078     my $group;
1079     my @line=@$lineref;
1080     my $class;
1081     push(@{$group->{literal}}, $lastline{$inhandle});
1082     if (($line[2] eq "{") || ($line[4] eq "{")) {
1083       $strat{$line[1]} = "none";
1084       push(@{$group->{outarr}}, "  $thisline\n");
1085
1086     } else {
1087       die "what the hell is this? $thisline ";
1088     }
1089     #if sim, add to the base strat and rep hashes
1090     #scan for event declarations, track them in events hash and strip event keyword
1091     while ($thisline=getcodeline($inhandle)) {
1092       @line=split(' ',$thisline);
1093       push(@{$group->{literal}}, $lastline{$inhandle});
1094       if ($closeblock{$inhandle}) {
1095         push(@{$group->{outarr}}, "  ".$thisline);
1096         last;
1097       } elsif ($line[0] eq "entry") {
1098         if ($thisline =~ /(\,event\,|\,event|event\,|\s\[event\]).*\s(.*)\(\s*(\S[^\*\s\)]*)/) {
1099 #         $method = $2;
1100           $message = $3;
1101           $method = $line[2];
1102           $method =~ s/\*?(.+)\(.+/$1/;
1103           push(@{$events{$class}}, [$method,$message]);
1104         } elsif ($thisline =~ /\s+[\*]*\s*(\S+)\(/) {   
1105           $method = $1;
1106           push(@{$nonevents{$class}}, ($method)) if $class ne $method;
1107         }
1108         $thisline =~ s/(\,event\,|\,event|event\,|\s\[event\])//;
1109         push(@{$group->{entry}},$thisline);
1110         push(@{$group->{outarr}}, "  ".$thisline);
1111       } else {
1112         if (($line[2] eq "{") || ($line[4] eq "{")) {
1113           $strat{$line[1]} = "none";
1114           push(@{$group->{outarr}}, "  ".$thisline);
1115         } else {
1116           die "what the hell is this $thisline";
1117         }
1118       }
1119     }
1120     return $group;
1121   }
1122
1123 sub posefunctest
1124   {
1125     my ($line)=shift;
1126     if ($line =~ /POSE_create/) {
1127       return 1;
1128     } elsif ($line =~ /POSE_creations_complete/) {
1129       return 2;
1130     } elsif ($line =~ /POSE_invoke_at/) {
1131       return 4;
1132     } elsif ($line =~ /POSE_invoke/) {
1133       return 3;
1134     } elsif ($line =~ /POSE_local_invoke/) {
1135       return 5;
1136     } else {
1137       return 0;
1138     }
1139   }
1140
1141 #given a POSE_* call break it down into its segments and return them as a list
1142 sub posefuncparse
1143   {
1144     my($line)=@_;
1145     my($restline);
1146     my @segments;
1147     if ($line =~ /\)\s*;\s*$/) { #strip );
1148       my $foo=$MATCH;
1149       $foo =~ tr/ \t//d;
1150       $line=$PREMATCH.$foo;
1151       chop $line;
1152       chop $line;
1153     }
1154     if ($line =~ /(POSE_[\w_]+)\s*\(/) { #strip funcname(
1155       $segments[0]=$1;
1156     } else {
1157       return undef;
1158     }
1159     my $preline=$PREMATCH;
1160     $restline=$POSTMATCH;
1161     if (($restline =~/\(+[^\)]*,[^\)]*\)/) || ($restline =~/\[+[^\]]*,[^\]]*\]/)) {
1162       #ok now we hunt down the groups and take them out of the expression
1163       #replace with &*# number
1164       my @inner_ugliness;
1165       my $hackline=$restline;
1166       while (($hackline =~/(\([^\(\)]*,[^\(\)]*\))/)||($hackline =~/(\[[^\[\]]*,[^\]\[]*\])/)) { # there exists an inner parenthesized expression with commas in
1167         push(@inner_ugliness,$1);
1168         $hackline=$PREMATCH.' &*#'.$#inner_ugliness.' '.$POSTMATCH;
1169       }
1170       my @uglysegs=split(/,/,$hackline);
1171       my $i;
1172       for ($i=0,$i<=$#uglysegs,$i++) {
1173         while ($uglysegs[$i] =~ /( &\*\#)([\d]+ )/) {
1174           $uglysegs[$i]=$PREMATCH.$inner_ugliness[$2].$POSTMATCH;
1175         }
1176       }
1177       push(@segments,@uglysegs);
1178     } else {                    #no ickiness just split it
1179       push(@segments,split(/,/,$restline));
1180     }
1181     my $i;
1182     for ($i=0;$i<$#segments;$i++) {
1183       $segments[$i]=~ s/^\s*(.*)\s*$/$1/e;
1184     }
1185     return($preline,@segments);
1186   }
1187
1188 #given an input line and the context
1189 #determine if it is a posefunc and if so map it.
1190 sub posefuncmap
1191   {
1192     my($line,$issim,$isconstructor,$simobjtype)=@_;
1193     my($type,$output);
1194     if (($type=posefunctest($line))>0) {
1195       #do stuff
1196       my($preline,@segments)=posefuncparse($line);
1197       
1198       if ($type==1)             #create
1199         {
1200           my($sim,$msg);
1201           if ($segments[1]=~/\s*([^(]*)\s*\(\s*([^)]*)\s*\)/) {
1202             $sim=$1;
1203             $msg=$2;
1204             $output=$preline."\n{\n";
1205             $output.="int _POSE_handle = ".$segments[3].";\n";
1206             $output.="POSE_TimeType _POSE_atTime = ".$segments[4].";\n" if ($#segments>=4);
1207             $output.=$msg."->Timestamp(_POSE_handle);\n";
1208             $output.="#ifdef DEBUG_POSE_INVOKE\n";
1209             $output.='CkError("invoking (*(CProxy_'.$sim.' *)&parent->thisProxy)['.$segments[2].'].insert('.$msg.')at line %d\n",__LINE__);'."\n";
1210             $output.="#endif\n";
1211             $output.="(*(CProxy_".$sim." *)&parent->thisProxy)[".$segments[2]."].insert(".$msg;
1212             if ($#segments>=4) {
1213               $output.=",_POSE_atTime";
1214             }
1215             $output.=");}\n";
1216           } else {
1217             die "could not parse ".$segments[1]."in $line";
1218           }
1219         } elsif ($type==2)      #create_complete
1220           {
1221             $output=$preline."parent->thisProxy.doneInserting();\n";
1222           } elsif ($type==3)    #invoke
1223             {
1224               if (!$issim) {
1225                 die "cannot use POSE_invoke from non sim object";
1226               }
1227               my($event,$msg);
1228               if ($segments[1]=~/\s*([^(]*)\s*\(\s*([^)]*)\s*\)/) {
1229                 $event=$1;
1230                 $msg=$2;
1231                 if ($isconstructor) {
1232                   $output=$preline."\n{\n";
1233                   $output.="int _POSE_handle = ".$segments[3].";\n";
1234                   if ($#segments>=4)
1235                   {
1236                       $output.="POSE_TimeType _POSE_timeOffset = ".$segments[4].";\n";
1237                   }
1238                   else
1239                   {
1240                       $output.="POSE_TimeType _POSE_timeOffset = 0;\n";
1241                   }
1242                   $output.="CkAssert(_POSE_timeOffset >=0);";
1243                   $output.=$msg."->Timestamp(ovt+(_POSE_timeOffset));\n";
1244                   $output.="#ifndef SEQUENTIAL_POSE\n";
1245                   $output.="PVT *pvt = (PVT *)CkLocalBranch(ThePVT);\n";
1246                   $output.="pvt->objUpdate(ovt+(_POSE_timeOffset), SEND);\n";
1247                   $output.="#endif\n";
1248                   #$output.="char str[30];\n";
1249                   #$output.="CkPrintf(\"[%d] SEND(event) to [%d] @ %d: Event=%s\\n\", parent->thisIndex, _POSE_handle, $msg->timestamp, $msg->evID.sdump(str));\n";
1250                   $output.="#ifndef CMK_OPTIMIZE\n";
1251                   $output.="$msg->sanitize();\n";
1252                   $output.="#endif\n";
1253                   $output.="#ifndef CMK_OPTIMIZE\n";
1254                   $output.="  if(pose_config.stats)\n";
1255                   $output.="    parent->localStats->SwitchTimer(COMM_TIMER);\n";
1256                   $output.="#endif\n";
1257                   $output.="#ifdef DEBUG_POSE_INVOKE\n";
1258                   $output.='CkError("invoking (*(CProxy_'.$segments[2].' *)&parent->thisProxy)[%d].'.$segments[1].'at line %d\n",_POSE_handle,__LINE__);'."\n";
1259                   $output.="#endif\n";
1260
1261                   $output.="(* (CProxy_".$segments[2]." *)&parent->thisProxy)[_POSE_handle].".$segments[1].";\n";
1262                   $output.="#ifndef CMK_OPTIMIZE\n";
1263                   $output.="  if(pose_config.stats)\n";
1264                   $output.="    parent->localStats->SwitchTimer(DO_TIMER);\n";
1265                   $output.="#endif\n";
1266                   #$output.="int _destPE = parent->thisProxy.ckLocalBranch()->lastKnown(CkArrayIndex1D(_POSE_handle));\n";
1267
1268                   #$output.="parent->srVector[_destPE]++;\n";
1269                   $output.="}\n";
1270                 } else {
1271                   $output=$preline."\n{\n";
1272                   $output.="if (!CpvAccess(stateRecovery)) {\n";
1273                   $output.="int _POSE_handle = ".$segments[3].";\n";
1274                   $output.="POSE_TimeType _POSE_timeOffset = ".$segments[4].";\n";
1275                   $output.="registerTimestamp(_POSE_handle, ".$msg.",_POSE_timeOffset);\n";
1276                   $output.="if(pose_config.dop){\n";
1277                   $output.="  parent->ct = CmiWallTimer();\n";
1278                   $output.="  $msg->rst = parent->ct - parent->st + parent->eq->currentPtr->srt;\n";
1279                   $output.="}\n";
1280                   #$output.="char str[30];\n";
1281                   #$output.="CkPrintf(\"[%d] SEND(event) to [%d] @ %d: Event=%s\\n\", parent->thisIndex, _POSE_handle, $msg->timestamp, $msg->evID.sdump(str));\n";               
1282                   $output.="#ifndef CMK_OPTIMIZE\n";
1283                   $output.="$msg->sanitize();\n";
1284                   $output.="#endif\n";
1285                   $output.="#ifndef CMK_OPTIMIZE\n";
1286                   $output.="  if(pose_config.stats)\n";
1287                   $output.="    parent->localStats->SwitchTimer(COMM_TIMER);\n";
1288                   $output.="#endif\n";
1289                   $output.="#ifdef DEBUG_POSE_INVOKE\n";
1290                   $output.='CkError("invoking (*(CProxy_'.$segments[2].' *)&parent->thisProxy)[%d].'.$segments[1].'at line %d\n",_POSE_handle,__LINE__);'."\n";
1291                   $output.="#endif\n";
1292
1293                   $output.="(* (CProxy_".$segments[2]." *)&parent->thisProxy)[_POSE_handle].".$segments[1].";\n";
1294                   $output.="#ifndef CMK_OPTIMIZE\n";
1295                   $output.="  if(pose_config.stats)\n";
1296                   $output.="    parent->localStats->SwitchTimer(DO_TIMER);\n";
1297                   $output.="#endif\n";
1298                   #$output.="int _destPE = parent->thisProxy.ckLocalBranch()->lastKnown(CkArrayIndex1D(_POSE_handle));\n";
1299                   #$output.="parent->srVector[_destPE]++;\n";
1300                   $output.="}\n";
1301                   $output.="else delete ".$msg.";}\n";
1302                 }
1303               } else {
1304                 die "could not parse .".$segments[1]."in $line";
1305               }
1306             } elsif ($type==4)  #invoke_at
1307               {
1308                 my($event,$msg);
1309                 if ($segments[1]=~/\s*([^(]*)\s*\(\s*([^)]*)\s*\)/) {
1310                   $event=$1;
1311                   $msg=$2;
1312                   if (!$issim || ($issim && $isconstructor)) {
1313                     print "warning: should use POSE_invoke instead of POSE_invoke_at inside sim object constructors\n" if ($issim && $isconstructor);
1314                     $output=$preline."\n{\n";
1315                     $output.="int _POSE_handle = ".$segments[3].";\n";
1316                     $output.="POSE_TimeType _POSE_atTime =".$segments[4].";\n";
1317                     $output.="CkAssert(_POSE_atTime >=0);\n";
1318                     $output.=$msg."->Timestamp(_POSE_atTime);\n";
1319                     $output.="#ifndef SEQUENTIAL_POSE\n";
1320                     $output.="PVT *pvt = (PVT *)CkLocalBranch(ThePVT);\n";
1321                     $output.="pvt->objUpdate(_POSE_atTime, SEND);\n";
1322                     $output.="#endif\n";
1323                     #$output.="char str[30];\n";
1324                     #$output.="CkPrintf(\"[%d] SEND(event) to [%d] @ %d: Event=%s\\n\", parent->thisIndex, _POSE_handle, $msg->timestamp, $msg->evID.sdump(str));\n";             
1325                     $output.="#ifndef CMK_OPTIMIZE\n";
1326                     $output.="$msg->sanitize();\n";
1327                     $output.="#endif\n";
1328                   $output.="#ifndef CMK_OPTIMIZE\n";
1329                   $output.="  if(pose_config.stats)\n";
1330                   $output.="   parent->localStats->SwitchTimer(COMM_TIMER);\n";
1331                   $output.="#endif\n";
1332                   $output.="#ifdef DEBUG_POSE_INVOKE\n";
1333                   $output.='CkError("invoking (*(CProxy_'.$segments[2].' *)&parent->thisProxy)[%d].insert('.$segments[1].'at line %d\n",_POSE_handle,__LINE__);'."\n";
1334                   $output.="#endif\n";
1335
1336                     $output.="(*(CProxy_".$segments[2]." *)&parent->thisProxy)[_POSE_handle].".$segments[1].";\n";
1337                   $output.="#ifndef CMK_OPTIMIZE\n";
1338                   $output.="  if(pose_config.stats)\n";
1339                   $output.="    parent->localStats->SwitchTimer(DO_TIMER);\n";
1340                   $output.="#endif\n";
1341                     #$output.="int _destPE = parent->thisProxy.ckLocalBranch()->lastKnown(CkArrayIndex1D(_POSE_handle));\n";
1342                     #$output.="parent->srVector[_destPE]++;\n";
1343                     $output.="}\n";
1344               
1345                     $output.="}\n";
1346                   } else {
1347                     print "warning: should use POSE_invoke instead of POSE_invoke_at in side sim object nonconstructors\n" if ($issim && $isconstructor);
1348                     $output=$preline."\n{\n";
1349                     $output.="int _POSE_handle = ".$segments[3].";\n";
1350                     $output.="int _POSE_atTime = ".$segments[4].";\n";
1351                     $output.="if (!CpvAccess(stateRecovery)) {\n";
1352                     $output.="registerTimestamp(_POSE_handle, ".$msg.", _POSE_atTime);\n";
1353                     $output.="if(pose_config.dop){\n";
1354                     $output.="  parent->ct = CmiWallTimer();\n";
1355                     $output.="  $msg->rst = parent->ct - parent->st + parent->eq->currentPtr->srt;\n";
1356                     $output.="}\n";
1357                     #$output.="char str[30];\n";
1358                     #$output.="CkPrintf(\"[%d] SEND(event) to [%d] @ %d: Event=%s\\n\", parent->thisIndex, _POSE_handle, $msg->timestamp, $msg->evID.sdump(str));\n";             
1359                     $output.="#ifndef CMK_OPTIMIZE\n";
1360                     $output.="$msg->sanitize();\n";
1361                     $output.="#endif\n";
1362                   $output.="#ifndef CMK_OPTIMIZE\n";
1363                   $output.="  if(pose_config.stats)\n";
1364                   $output.="    parent->localStats->SwitchTimer(COMM_TIMER);\n";
1365                   $output.="#endif\n";
1366                   $output.="#ifdef DEBUG_POSE_INVOKE\n";
1367                   $output.='CkError("invoking (*(CProxy_'.$segments[2].' *)&parent->thisProxy)[%d].insert('.$segments[1].'at line %d\n",_POSE_handle,__LINE__);'."\n";
1368                   $output.="#endif\n";
1369                     $output.="(* (CProxy_".$segments[2]." *)&parent->thisProxy)[_POSE_handle].".$segments[1].";\n";
1370                   $output.="#ifndef CMK_OPTIMIZE\n";
1371                   $output.="  if(pose_config.stats)\n";
1372                   $output.="    parent->localStats->SwitchTimer(DO_TIMER);\n";
1373                   $output.="#endif\n";
1374                     #$output.="int _destPE = parent->thisProxy.ckLocalBranch()->lastKnown(CkArrayIndex1D(_POSE_handle));\n";
1375                     #$output.="parent->srVector[_destPE]++;\n";
1376                     $output.="}\n";
1377                     $output.="else delete ".$msg.";}\n";
1378                   }
1379                 } else {
1380                   die "could not parse ".$segments[1]."in $line";
1381                 }
1382               } elsif ($type==5) #local_invoke
1383                 {
1384                   my($event,$msg);
1385                   if ($segments[1]=~/\s*([^(]*)\s*\(\s*([^)]*)\s*\)/) {
1386                     $event=$1;
1387                     $msg=$2;
1388                     if ($issim && $isconstructor) {
1389                       $output=$preline."\n{\n";
1390                       $output.="POSE_TimeType _POSE_timeOffset = ".$segments[2].";\n";
1391                       $output.=$msg."->Timestamp(ovt+(_POSE_timeOffset));\n";
1392                       $output.="#ifndef SEQUENTIAL_POSE\n";
1393                       $output.="PVT *pvt = (PVT *)CkLocalBranch(ThePVT);\n";
1394                       $output.="pvt->objUpdate(ovt+(_POSE_timeOffset), SEND);\n";
1395                       $output.="#endif\n";
1396                       #$output.="char str[30];\n";
1397                       #$output.="CkPrintf(\"[%d] SEND(event) to [%d] @ %d: Event=%s\\n\", parent->thisIndex, parent->thisIndex, $msg->timestamp, $msg->evID.sdump(str));\n";              
1398                       $output.="#ifndef CMK_OPTIMIZE\n";
1399                       $output.="$msg->sanitize();\n";
1400                       $output.="#endif\n";
1401                   $output.="#ifndef CMK_OPTIMIZE\n";
1402                   $output.="  if(pose_config.stats)\n";
1403                   $output.="    parent->localStats->SwitchTimer(COMM_TIMER);\n";
1404                   $output.="#endif\n";
1405                       $output.="(* (CProxy_".$simobjtype." *)&parent->thisProxy)[parent->thisIndex].".$segments[1].";\n";
1406                   $output.="#ifndef CMK_OPTIMIZE\n";
1407                   $output.="  if(pose_config.stats)\n";
1408                   $output.="    parent->localStats->SwitchTimer(DO_TIMER);\n";
1409                   $output.="#endif\n";
1410
1411                       #$output.="parent->srVector[CkMyPe()]++;\n";
1412                       $output.="}\n";
1413                     } elsif ($issim) {
1414                       $output=$preline."\n{\n";
1415                       $output.="POSE_TimeType _POSE_timeOffset = ".$segments[2].";\n";
1416                       $output.="if (!CpvAccess(stateRecovery)) {\n";
1417                       $output.="registerTimestamp(parent->thisIndex, ".$msg.", _POSE_timeOffset);\n";
1418                       $output.="if(pose_config.dop){\n";
1419                       $output.="  parent->ct = CmiWallTimer();\n";
1420                       $output.="  $msg->rst = parent->ct - parent->st + parent->eq->currentPtr->srt;\n";
1421                       $output.="}\n";
1422                       #$output.="char str[30];\n";
1423                       #$output.="CkPrintf(\"[%d] SEND(event) to [%d] @ %d: Event=%s\\n\", parent->thisIndex, parent->thisIndex, $msg->timestamp, $msg->evID.sdump(str));\n";              
1424                       $output.="#ifndef CMK_OPTIMIZE\n";
1425                       $output.="$msg->sanitize();\n";
1426                       $output.="#endif\n";
1427                       $output.="#ifndef CMK_OPTIMIZE\n";
1428                       $output.="  if(pose_config.stats)\n";
1429                       $output.="    parent->localStats->SwitchTimer(COMM_TIMER);\n";
1430                       $output.="#endif\n";
1431                       $output.="#ifdef DEBUG_POSE_INVOKE\n";
1432                       $output.='CkError("invoking (*(CProxy_'.$simobjtype.' *)&parent->thisProxy)[%d].'.$segments[1].'at line %d\n",parent->thisIndex,__LINE__);'."\n";
1433                       $output.="#endif\n";
1434
1435                       $output.="(* (CProxy_".$simobjtype." *)&parent->thisProxy)[parent->thisIndex].".$segments[1].";\n";
1436                   $output.="#ifndef CMK_OPTIMIZE\n";
1437                   $output.="  if(pose_config.stats)\n";
1438                   $output.="    parent->localStats->SwitchTimer(DO_TIMER);\n";
1439                   $output.="#endif\n";
1440                       #$output.="parent->srVector[CkMyPe()]++;\n";
1441                       $output.="}\n";
1442                       $output.="else delete(".$msg.");\n}";
1443                     } else {
1444                       die "untranslatably deranged to call POSE_local_invoke from non sim object";
1445                     }
1446                   } else {
1447                     die "could not parse .".$segments[1];
1448                   }
1449                 }
1450     }
1451   }
1452