Mercurial > hg > CbC > CbC_xv6
comparison src/gearsTools/generate_stub.pl @ 44:94ca6db2ee9c
add perl script
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 02 Mar 2019 21:05:26 +0900 |
parents | |
children | 9647d79fe97e |
comparison
equal
deleted
inserted
replaced
43:b94d72292dfa | 44:94ca6db2ee9c |
---|---|
1 #!/usr/bin/perl | |
2 | |
3 use strict; | |
4 use Getopt::Std; | |
5 use File::Path qw(make_path); | |
6 | |
7 # interface.h | |
8 # typedef struct Worker { | |
9 # int id; | |
10 # struct Context* contexts; | |
11 # enum Code execute; | |
12 # enum Code taskSend; | |
13 # enum Code taskRecive; | |
14 # enum Code shutdown; | |
15 # struct Queue* tasks; | |
16 # } Worker; | |
17 | |
18 our($opt_o,$opt_d,$opt_h); | |
19 getopts('o:d:h'); | |
20 | |
21 my $dir = "."; | |
22 if ($opt_d) { | |
23 $dir = $opt_d; | |
24 if (! -d $dir) { | |
25 make_path $dir; | |
26 } | |
27 } | |
28 | |
29 for my $fn (@ARGV) { | |
30 next if ($fn !~ /\.cbc$/); | |
31 &getDataGear($fn); | |
32 &generateDataGear($fn); | |
33 } | |
34 | |
35 my %var; | |
36 my %code; | |
37 my %dataGearVar; | |
38 my %outputVar; # output var initializer | |
39 my %outputArgs; # continuation's output variables | |
40 my %dataGear; | |
41 my %dataGearName; | |
42 my %generic; | |
43 my %dataGearVarType; | |
44 my %codeGear; | |
45 my $implementation; | |
46 my $interface; | |
47 | |
48 # interface definision | |
49 # | |
50 # typedef struct Stack<Type, Impl>{ | |
51 # Type* stack; | |
52 # Type* data; | |
53 # Type* data1; | |
54 # __code whenEmpty(...); | |
55 # __code clear(Impl* stack,__code next(...)); | |
56 # __code push(Impl* stack,Type* data, __code next(...)); | |
57 # __code pop(Impl* stack, __code next(Type*, ...)); | |
58 # __code pop2(Impl* stack, Type** data, Type** data1, __code next(Type**, Type**, ...)); | |
59 # __code isEmpty(Impl* stack, __code next(...), __code whenEmpty(...)); | |
60 # __code get(Impl* stack, Type** data, __code next(...)); | |
61 # __code get2(Impl* stack,..., __code next(...)); | |
62 # __code next(...); | |
63 # } Stack; | |
64 # | |
65 # calling example | |
66 # | |
67 # goto nodeStack->push((union Data*)node, stackTest3); | |
68 # | |
69 # generated meta level code | |
70 # | |
71 # Gearef(context, Stack)->stack = (union Data*)nodeStack; | |
72 # Gearef(context, Stack)->data = (union Data*)node; | |
73 # Gearef(context, Stack)->next = C_stackTest3; | |
74 # goto meta(context, nodeStack->push); | |
75 | |
76 sub getDataGear { | |
77 my ($filename) = @_; | |
78 my ($codeGearName, $name, $inTypedef); | |
79 open my $fd,"<",$filename or die("can't open $filename $!"); | |
80 while (<$fd>) { | |
81 if (! $inTypedef) { | |
82 if (/^typedef struct (\w+)\s*<(.*)>/) { | |
83 $inTypedef = 1; | |
84 $name = $1; | |
85 $dataGear{$name} = $_; | |
86 $var{$name} = {}; | |
87 $code{$name} = {}; | |
88 $generic{$name} = \split(/,/,$2); | |
89 } elsif (/^typedef struct (\w+)/) { | |
90 $inTypedef = 1; | |
91 $name = $1; | |
92 $dataGear{$name} = $_; | |
93 $var{$name} = {}; | |
94 $code{$name} = {}; | |
95 $generic{$name} = []; | |
96 } elsif (/^(\w+)(\*)+ create(\w+)\(/) { | |
97 if (defined $interface) { | |
98 die "duplicate interface $interface\n"; | |
99 } | |
100 $interface = $1; | |
101 $implementation = $3; | |
102 if ( -f "$interface.cbc") { | |
103 &getDataGear("$interface.cbc"); | |
104 } | |
105 } elsif(/^(.*)par goto (\w+)\((.*)\)/) { | |
106 my $codeGearName = $2; | |
107 if ($filename =~ /^(.*)\/(.*)/) { | |
108 $codeGearName = "$1/$codeGearName"; | |
109 } | |
110 if ( -f "$codeGearName.cbc") { | |
111 &getCodeGear("$codeGearName.cbc"); | |
112 } | |
113 } elsif(/^#interface "(.*)"/) { | |
114 # use interface | |
115 my $interfaceHeader = $1; | |
116 next if ($interfaceHeader =~ /context.h/); | |
117 if (-f $interfaceHeader) { | |
118 &getDataGear("$interfaceHeader"); | |
119 &getCodeGear("$interfaceHeader"); | |
120 } | |
121 } elsif (/^\_\_code (\w+)\((.*)\)(.*)/) { | |
122 my $codeGearName = $1; | |
123 if ($filename =~ /^(.*)\/(.*)/) { | |
124 $codeGearName = "$1/$codeGearName"; | |
125 } | |
126 if ( -f "$codeGearName.cbc") { | |
127 &getCodeGear("$codeGearName.cbc"); | |
128 } | |
129 } | |
130 next; | |
131 } | |
132 # gather type name and type | |
133 $dataGear{$name} .= $_; | |
134 if (/^\s*(.*)\s+(\w+);$/ ) { | |
135 my $ttype = $1; | |
136 my $tname = $2; | |
137 if ($ttype =~ /^(union|struct)?\s*(\w+)/) { | |
138 $ttype = $2; | |
139 } | |
140 $var{$name}->{$tname} = $ttype; | |
141 } | |
142 if (/^}/) { | |
143 $inTypedef = 0; | |
144 } | |
145 } | |
146 | |
147 } | |
148 | |
149 sub getCodeGear { | |
150 my ($filename) = @_; | |
151 open my $fd,"<",$filename or die("can't open $filename $!"); | |
152 my ($name,$impln); | |
153 while (<$fd>) { | |
154 if (/^(\w+)(\*)+ create(\w+)\(/) { | |
155 $name = $1; | |
156 $impln = $3; | |
157 } elsif(/^typedef struct (.*)<.*>\s*{/) { | |
158 $name = $1; | |
159 } | |
160 if (defined $name) { | |
161 if (/^\s*\_\_code (\w+)\((.*)\);/) { | |
162 my $args = $2; | |
163 my $method = $1; | |
164 $code{$name}->{$method} = []; | |
165 while($args) { | |
166 # replace comma | |
167 $args =~ s/(^\s*,\s*)//; | |
168 # continuation case | |
169 if ($args =~ s/^(\s)*\_\_code\s+(\w+)\(([^)]*)\)//) { | |
170 my $next = $2; | |
171 my @args = split(/,/,$3); | |
172 push(@{$code{$name}->{$method}},"\_\_code $next"); | |
173 } elsif ($args =~ s/^(struct|union)?\s*(\w+)(\**)\s+(\w+)//) { | |
174 my $structType = $1; | |
175 my $typeName = $2; | |
176 my $ptrType = $3; | |
177 my $varName = $4; | |
178 my $typeField = lcfirst($typeName); | |
179 push(@{$code{$name}->{$method}},"$typeName$ptrType $varName"); | |
180 } elsif ($args =~ s/(.*,)//) { | |
181 } else { | |
182 last; | |
183 } | |
184 } | |
185 } | |
186 } elsif (/^\_\_code (\w+)\((.*)\)(.*)/) { | |
187 my $codeGearName = $1; | |
188 my $args = $2; | |
189 my $inputCount = 0; | |
190 my $outputCount = 0; | |
191 my $inputIncFlag = 1; | |
192 while($args) { | |
193 if ($args =~ s/(^\s*,\s*)//) { | |
194 } | |
195 if ($args =~ s/^(\s)*\_\_code\s+(\w+)\((.*?)\)//) { | |
196 $codeGear{$codeGearName}->{"code"}->{$2} = "\_\_code"; | |
197 $inputIncFlag = 0; | |
198 my @outputs = split(/,/,$3); | |
199 for my $output (@outputs) { | |
200 if ($output =~ /\s*(struct|union)?\s*(\w+)(\*)?+\s(\w+)/) { | |
201 my $type = $2; | |
202 my $varName = $4; | |
203 $codeGear{$codeGearName}->{"var"}->{$varName} = "$type $outputCount"; | |
204 $outputCount++; | |
205 } | |
206 } | |
207 } elsif ($args =~ s/^(struct|union)?\s*(\w+)(\*)?+\s(\w+)// && $inputIncFlag) { | |
208 my $type = $2; | |
209 my $varName = $4; | |
210 $codeGear{$codeGearName}->{"var"}->{$varName} = "$type $inputCount"; | |
211 $inputCount++; | |
212 } elsif ($args =~ s/(.*,)//) { | |
213 } else { | |
214 last; | |
215 } | |
216 } | |
217 $codeGear{$codeGearName}->{"input"} = $inputCount; | |
218 $codeGear{$codeGearName}->{"output"} = $outputCount; | |
219 } | |
220 } | |
221 } | |
222 | |
223 sub generateStub { | |
224 my($fd,$prevCodeGearName,$dataGearName) = @_; | |
225 print $fd "__code ", $prevCodeGearName ,"_stub(struct Context* context) {\n"; | |
226 print $fd $dataGearName; | |
227 print $fd "\n} \n\n"; | |
228 return 1; | |
229 } | |
230 | |
231 sub generateStubArgs { | |
232 my($codeGearName, $varName, $typeName, $ptrType, $typeField, $interface,$output) = @_; | |
233 my $varname1 = $output?"O_$varName":$varName; | |
234 for my $n ( @{$dataGearVar{$codeGearName}} ) { | |
235 # we already have it | |
236 return 0 if ( $n eq $varname1); | |
237 } | |
238 push @{$dataGearVar{$codeGearName}}, $varname1; | |
239 push @{$dataGearVarType{$codeGearName}}, $typeName; | |
240 if ($typeName eq $implementation) { | |
241 # get implementation | |
242 $dataGearName{$codeGearName} .= "\t$typeName* $varName = ($typeName*)GearImpl(context, $interface, $varName);\n"; | |
243 } else { | |
244 # interface var | |
245 for my $ivar (keys %{$var{$interface}}) { | |
246 # input data gear field | |
247 if ($varName eq $ivar) { | |
248 if ($typeName eq $var{$interface}->{$ivar}) { | |
249 if ($output) { | |
250 $dataGearName{$codeGearName} .= "\t$typeName$ptrType* O_$varName = &Gearef(context, $interface)->$varName;\n"; | |
251 $outputVar{$codeGearName} .= "\t$typeName$ptrType $varName = *O_$varName;\n"; | |
252 return 1; | |
253 } | |
254 $dataGearName{$codeGearName} .= "\t$typeName$ptrType $varName = Gearef(context, $interface)->$varName;\n"; | |
255 return 1; | |
256 } | |
257 } | |
258 } | |
259 | |
260 # interface continuation | |
261 for my $cName (keys %{$code{$interface}}) { | |
262 if ($varName eq $cName) { | |
263 # continuation field | |
264 $dataGearName{$codeGearName} .= "\tenum Code $varName = Gearef(context, $interface)->$varName;\n"; | |
265 return 1; | |
266 } | |
267 } | |
268 | |
269 # par goto var | |
270 for my $var (keys %{$codeGear{$codeGearName}->{"var"}}) { | |
271 # input data gear field | |
272 if ($varName eq $var) { | |
273 my ($type, $count) = split(/\s/, $codeGear{$codeGearName}->{"var"}->{$var}); | |
274 if ($typeName eq $type) { | |
275 if ($output) { | |
276 $dataGearName{$codeGearName} .= "\t$typeName$ptrType* O_$varName = ($typeName $ptrType*)&context->data[context->odg + $count];\n"; | |
277 $outputVar{$codeGearName} .= "\t$typeName$ptrType $varName = *O_$varName;\n"; | |
278 return 1; | |
279 } | |
280 $dataGearName{$codeGearName} .= "\t$typeName$ptrType $varName = &context->data[context->idg + $count]->$typeName;\n"; | |
281 return 1; | |
282 } | |
283 } | |
284 } | |
285 | |
286 # par goto continuation | |
287 for my $cName (keys %{$codeGear{$codeGearName}->{"code"}}) { | |
288 if ($varName eq $cName) { | |
289 # continuation field | |
290 $dataGearName{$codeGearName} .= "\tenum Code $varName = context->next;\n"; | |
291 return 1; | |
292 } | |
293 } | |
294 | |
295 # par goto continuation | |
296 # global or local variable case | |
297 if ($typeName eq "Code") { | |
298 $dataGearName{$codeGearName} .= "\tenum $typeName$ptrType $varName = Gearef(context, $interface)->$varName;\n"; | |
299 return 1; | |
300 } | |
301 $dataGearName{$codeGearName} .= "\t$typeName$ptrType $varName = Gearef(context, $typeName);\n"; | |
302 return 1; | |
303 } | |
304 } | |
305 | |
306 sub generateDataGear { | |
307 my ($filename) = @_; | |
308 open my $in,"<",$filename or die("can't open $filename $!"); | |
309 | |
310 my $fn; | |
311 if ($opt_o) { | |
312 $fn = $opt_o; | |
313 } else { | |
314 my $fn1 = $filename; | |
315 $fn1 =~ s/\.cbc/.c/; | |
316 my $i = 1; | |
317 $fn = "$dir/$fn1"; | |
318 while ( -f $fn) { | |
319 $fn = "$dir/$fn1.$i"; | |
320 $i++; | |
321 } | |
322 } | |
323 if ( $fn =~ m=(.*)/[^/]+$= ) { | |
324 if (! -d $1) { | |
325 make_path $1; | |
326 } | |
327 } | |
328 open my $fd,">",$fn or die("can't write $fn $!"); | |
329 | |
330 my $prevCodeGearName; | |
331 my $inTypedef = 0; | |
332 my $inStub = 0; | |
333 my $inParGoto = 0; | |
334 my $inMain = 0 ; | |
335 my %stub; | |
336 my $codeGearName; | |
337 my %localVarType; | |
338 | |
339 while (<$in>) { | |
340 if (! $inTypedef && ! $inStub && ! $inMain) { | |
341 if (/^typedef struct (\w+) \{/) { | |
342 $inTypedef = 1; | |
343 } elsif (/^int main\((.*)\) \{/) { | |
344 $inMain = 1; | |
345 } elsif(/^#interface "(.*)"/) { | |
346 my $interfaceHeader = $1; | |
347 # #interface not write | |
348 next unless ($interfaceHeader =~ /context.h/); | |
349 } elsif (/^\_\_code (\w+)\((.*)\)(.*)/) { | |
350 %localVarType = {}; | |
351 $codeGearName = $1; | |
352 my $args = $2; | |
353 my $tail = $3; | |
354 if ($codeGearName =~ /_stub$/) { | |
355 # don't touch already existing stub | |
356 $inStub = 1; | |
357 $stub{$codeGearName} = 1; | |
358 print $fd $_; | |
359 next; | |
360 } | |
361 if (defined $prevCodeGearName) { | |
362 # stub is generated just before next CodeGear | |
363 if (defined $stub{$prevCodeGearName."_stub"}) { | |
364 undef $prevCodeGearName; | |
365 } else { | |
366 &generateStub($fd,$prevCodeGearName,$dataGearName{$prevCodeGearName}); | |
367 $stub{$prevCodeGearName."_stub"} = 1; | |
368 } | |
369 } | |
370 # analyzing CodeGear argument | |
371 # these arguments are extract from current context's arugment DataGear Interface | |
372 # and passed to the CodeGear | |
373 # struct Implementaion needs special handling | |
374 # __code next(...) ---> enum Code next | |
375 $prevCodeGearName = $codeGearName; | |
376 $dataGearVar{$codeGearName} = []; | |
377 $outputVar{$codeGearName} = ""; | |
378 $outputArgs{$codeGearName} = {}; | |
379 my $newArgs = "struct Context *context,"; | |
380 if ($args=~/^struct Context\s*\*\s*context/) { | |
381 $newArgs = ""; | |
382 } | |
383 if (!$args){ | |
384 $newArgs = "struct Context *context"; | |
385 } | |
386 while($args) { | |
387 if ($args =~ s/(^\s*,\s*)//) { | |
388 $newArgs .= $1; | |
389 } | |
390 # continuation case | |
391 if ($args =~ s/^(\s)*\_\_code\s+(\w+)\(([^)]*)\)//) { | |
392 my $next = $2; | |
393 my @args = split(/,/,$3); | |
394 if (&generateStubArgs($codeGearName, $next, "Code", "", $next, $interface,0) ) { | |
395 $newArgs .= "enum Code $next"; | |
396 } | |
397 # analyze continuation arguments | |
398 # output arguments are defined in the Interface take the pointer of these | |
399 # output arguments are put into the Interface DataGear just before the goto | |
400 for my $arg (@args) { | |
401 $arg =~ s/^\s*//; | |
402 last if ($arg =~ /\.\.\./); | |
403 $arg =~ s/^(struct|union)?\s*(\w+)(\**)\s(\w+)//; | |
404 my $structType = $1; | |
405 my $typeName = $2; | |
406 my $ptrType = $3; | |
407 my $varName = $4; | |
408 my $typeField = lcfirst($typeName); | |
409 push(@{$outputArgs{$codeGearName}->{$next}}, $varName); | |
410 if (&generateStubArgs($codeGearName, $varName, $typeName, $ptrType, $typeField, $interface,1)) { | |
411 $newArgs .= ",$structType $typeName **O_$varName"; | |
412 } | |
413 } | |
414 } elsif ($args =~ s/^(struct|union)?\s*(\w+)(\**)\s(\w+)//) { | |
415 my $structType = $1; | |
416 my $typeName = $2; | |
417 my $ptrType = $3; | |
418 my $varName = $4; | |
419 my $typeField = lcfirst($typeName); | |
420 $newArgs .= $&; # assuming no duplicate | |
421 &generateStubArgs($codeGearName, $varName, $typeName, $ptrType, $typeField, $interface,0); | |
422 } elsif ($args =~ s/(.*,)//) { | |
423 $newArgs .= $1; | |
424 } else { | |
425 $newArgs .= $args; | |
426 last; | |
427 } | |
428 } | |
429 # generate goto statement from stub to the CodeGear in the buffer | |
430 $dataGearName{$codeGearName} .= "\tgoto $codeGearName(context"; | |
431 for my $arg ( @{$dataGearVar{$codeGearName}}) { | |
432 $dataGearName{$codeGearName} .= ", $arg"; | |
433 } | |
434 $dataGearName{$codeGearName} .= ");"; | |
435 # generate CodeGear header with new arguments | |
436 print $fd "__code $codeGearName($newArgs)$tail\n"; | |
437 if ($outputVar{$codeGearName} ne "") { | |
438 # output data var can be use before write | |
439 # it should be initialze by gearef | |
440 print $fd $outputVar{$codeGearName}; | |
441 } | |
442 next; | |
443 } elsif (/^(.*)goto (\w+)\-\>(\w+)\((.*)\);/) { | |
444 # handling goto statement | |
445 # convert it to the meta call form with two arugments, that is context and enum Code | |
446 my $prev = $1; | |
447 my $next = $2; | |
448 my $method = $3; | |
449 my $tmpArgs = $4; | |
450 $tmpArgs =~ s/\(.*\)/\(\)/; | |
451 my @args = split(/,/,$tmpArgs); | |
452 my @types = @{$dataGearVarType{$codeGearName}}; | |
453 my $ntype; | |
454 my $ftype; | |
455 for my $v (@{$dataGearVar{$codeGearName}}) { | |
456 my $t = shift @types; | |
457 if ($v eq $next || $v eq "O_$next") { | |
458 $ntype = $t; | |
459 $ftype = lcfirst($ntype); | |
460 } | |
461 } | |
462 if (!defined $ntype) { | |
463 $ntype = $localVarType{$next}; | |
464 $ftype = lcfirst($ntype); | |
465 } | |
466 print $fd "\tGearef(context, $ntype)->$ftype = (union Data*) $next;\n"; | |
467 # Put interface argument | |
468 my $prot = $code{$ntype}->{$method}; | |
469 my $i = 1; | |
470 for my $arg (@args) { | |
471 my $pType; | |
472 my $pName; | |
473 my $p = @$prot[$i]; | |
474 next if ($p eq $arg); | |
475 $p =~ s/^(.*)\s(\w+)//; | |
476 $pType = $1; | |
477 $pName = $2; | |
478 $arg =~ s/^(\s)*(\w+)/$2/; | |
479 if ($pType =~ s/\_\_code$//) { | |
480 if ($arg =~ /(\w+)\(.*\)/) { | |
481 print $fd "\tGearef(context, $ntype)->$pName = $1;\n"; | |
482 } else { | |
483 print $fd "\tGearef(context, $ntype)->$pName = C_$arg;\n"; | |
484 } | |
485 } elsif ($pType =~ /Data\**$/){ | |
486 print $fd "\tGearef(context, $ntype)->$pName = (union $pType) $arg;\n"; | |
487 } else { | |
488 print $fd "\tGearef(context, $ntype)->$pName = $arg;\n"; | |
489 } | |
490 $i++; | |
491 } | |
492 print $fd "${prev}goto meta(context, $next->$method);\n"; | |
493 next; | |
494 } elsif(/^(.*)par goto (\w+)\((.*)\);/) { | |
495 # handling par goto statement | |
496 # convert it to the parallel | |
497 my $prev = $1; | |
498 my $codeGearName = $2; | |
499 my $args = $3; | |
500 my $inputCount = $codeGear{$codeGearName}->{'input'}; | |
501 my $outputCount = $codeGear{$codeGearName}->{'output'}; | |
502 my @iterateCounts; | |
503 # parse examples 'par goto(.., iterate(10), exit);' | |
504 if ($args =~ /iterate\((.*)?\),/) { | |
505 @iterateCounts = split(/,/,$1);; | |
506 $inputCount--; | |
507 } | |
508 # replace iterate keyword | |
509 $args =~ s/iterate\((.*)?\),//; | |
510 my @dataGears = split(/,\s*/, $args); | |
511 my $nextCodeGear = pop(@dataGears); | |
512 if (! $inParGoto) { | |
513 $inParGoto = 1; | |
514 print $fd "${prev}struct Element* element;\n"; | |
515 } | |
516 my $initTask = << "EOFEOF"; | |
517 ${prev}context->task = NEW(struct Context); | |
518 ${prev}initContext(context->task); | |
519 ${prev}context->task->next = C_$codeGearName; | |
520 ${prev}context->task->idgCount = $inputCount; | |
521 ${prev}context->task->idg = context->task->dataNum; | |
522 ${prev}context->task->maxIdg = context->task->idg + $inputCount; | |
523 ${prev}context->task->odg = context->task->maxIdg; | |
524 ${prev}context->task->maxOdg = context->task->odg + $outputCount; | |
525 EOFEOF | |
526 print $fd $initTask; | |
527 if (@iterateCounts) { | |
528 print $fd "${prev}context->task->iterate = 0;\n"; | |
529 my $len = @iterateCounts; | |
530 if ($len == 1) { | |
531 print $fd "${prev}context->task->iterator = createMultiDimIterator(context, $iterateCounts[0], 1, 1);\n"; | |
532 } elsif ($len == 2) { | |
533 print $fd "${prev}context->task->iterator = createMultiDimIterator(context, $iterateCounts[0], $iterateCounts[1], 1);\n"; | |
534 } elsif ($len == 3) { | |
535 print $fd "${prev}context->task->iterator = createMultiDimIterator(context, $iterateCounts[0], $iterateCounts[1], $iterateCounts[2]);\n"; | |
536 } | |
537 } | |
538 for my $dataGear (@dataGears) { | |
539 print $fd "${prev}GET_META($dataGear)->wait = createSynchronizedQueue(context);\n"; | |
540 } | |
541 for my $i (0..$inputCount-1) { | |
542 print $fd "${prev}context->task->data[context->task->idg+$i] = (union Data*)@dataGears[$i];\n"; | |
543 } | |
544 for my $i (0..$outputCount-1) { | |
545 print $fd "${prev}context->task->data[context->task->odg+$i] = (union Data*)@dataGears[$inputCount+$i];\n"; | |
546 } | |
547 my $putTask = << "EOFEOF"; | |
548 ${prev}element = &ALLOCATE(context, Element)->Element; | |
549 ${prev}element->data = (union Data*)context->task; | |
550 ${prev}element->next = context->taskList; | |
551 ${prev}context->taskList = element; | |
552 EOFEOF | |
553 print $fd $putTask; | |
554 next; | |
555 } elsif (/^(.*)goto (\w+)\((.*)\);/) { | |
556 # handling goto statement | |
557 # convert it to the meta call form with two arugments, that is context and enum Code | |
558 my $prev = $1; | |
559 my $next = $2; | |
560 my @args = split(/,/, $3); | |
561 my $v = 0; | |
562 for my $n ( @{$dataGearVar{$codeGearName}} ) { | |
563 # continuation arguments | |
564 $v = 1 if ( $n eq $next); | |
565 } | |
566 if ($v || defined $code{$interface}->{$next}) { | |
567 # write continuation's arguments into the interface arguments | |
568 # we may need a commit for a shared DataGear | |
569 for my $arg ( @{$outputArgs{$codeGearName}->{$next}} ) { | |
570 my $v = shift(@args); | |
571 print $fd "\t*O_$arg = $v;\n"; | |
572 } | |
573 if ($inParGoto) { | |
574 print $fd "${prev}Gearef(context, TaskManager)->taskList = context->taskList;\n"; | |
575 print $fd "${prev}Gearef(context, TaskManager)->next1 = C_$next;\n"; | |
576 print $fd "${prev}goto meta(context, C_$next);\n"; | |
577 } else { | |
578 print $fd "${prev}goto meta(context, $next);\n"; | |
579 } | |
580 next; | |
581 } | |
582 if ($inParGoto) { | |
583 print $fd "${prev}Gearef(context, TaskManager)->taskList = context->taskList;\n"; | |
584 print $fd "${prev}Gearef(context, TaskManager)->next1 = C_$next;\n"; | |
585 print $fd "${prev}goto meta(context, C_$next);\n"; | |
586 next; | |
587 } elsif ($next eq "meta") { | |
588 print $fd $_; | |
589 next; | |
590 } else { | |
591 print $fd "${prev}goto meta(context, C_$next);\n"; | |
592 next; | |
593 } | |
594 } elsif(/^.*(struct|union)?\s(\w+)\*\s(\w+)\s?[=;]/) { | |
595 my $type = $2; | |
596 my $varName = $3; | |
597 $localVarType{$varName} = $type; | |
598 s/new\s+(\w+)\(\)/\&ALLOCATE(context, \1)->\1/g; # replacing new | |
599 } elsif(/^}/) { | |
600 $inParGoto = 0; | |
601 } else { | |
602 s/new\s+(\w+)\(\)/\&ALLOCATE(context, \1)->\1/g; # replacing new | |
603 } | |
604 # gather type name and type | |
605 } elsif ($inMain) { | |
606 if (/^(.*)goto start_code\(main_context\);/) { | |
607 print $fd $_; | |
608 next; | |
609 } elsif (/^(.*)goto (\w+)\((.*)\);/) { | |
610 my $prev = $1; | |
611 my $next = $2; | |
612 print $fd "${prev}struct Context* main_context = NEW(struct Context);\n"; | |
613 print $fd "${prev}initContext(main_context);\n"; | |
614 print $fd "${prev}main_context->next = C_$next;\n"; | |
615 print $fd "${prev}goto start_code(main_context);\n"; | |
616 next; | |
617 } | |
618 } | |
619 if (/^}/) { | |
620 $inStub = 0; | |
621 $inTypedef = 0; | |
622 $inMain = 0; | |
623 } | |
624 print $fd $_; | |
625 } | |
626 if (defined $prevCodeGearName) { | |
627 if (!defined $stub{$prevCodeGearName."_stub"}) { | |
628 $stub{$prevCodeGearName."_stub"} = &generateStub($fd,$prevCodeGearName,$dataGearName{$codeGearName}); | |
629 } | |
630 } | |
631 } | |
632 | |
633 # end |