CompileDES 3.14
Executable-Code Generation from Synchronised libFAUDES Automata
cgp_embeddedc.cpp
Go to the documentation of this file.
1
3/*
4 FAU Discrete Event Systems Library (libFAUDES)
5
6 Copyright (C) 2010, 2016 Thomas Moor
7
8*/
9
10// my includes
11#include "cgp_embeddedc.h"
12
13
14/*
15******************************************************************
16******************************************************************
17******************************************************************
18
19EmbeddedcCodeGenerator implementation
20
21******************************************************************
22******************************************************************
23******************************************************************
24*/
25
26// Register derived class
28
29
30// EmbeddedcCodeGenerator(void)
32 FD_DCG("EmbeddedcCodeGenerator(" << this << ")::EmbeddedcCodeGenerator()");
33}
34
35
36// EmbeddedcCodeGenerator(void)
38 FD_DCG("EmbeddedcCodeGenerator(" << this << ")::~EmbeddedcCodeGenerator()");
39}
40
41// clear
43 FD_DCG("EmbeddedcCodeGenerator::Clear()");
44 // call base
46 // my flavor of defaults
47 mPrefix="fcg_";
48 mWordType="unsigned char";
49 mWordSize=8;
50 mIntegerType="int";
51 mIntegerSize=16;
52}
53
54//DoReadTargetConfiguration(rTr)
56 FD_DCG("EmbeddedcCodeGenerator::DoReadTargetConfiguration()");
57 // base
59}
60
61//DoWriteTargetConfiguration(rTw)
63 FD_DCG("EmbeddedcCodeGenerator::DoWriteTargetConfiguration()");
64 // base
66}
67
68// DoCompile()
70 // call base
72 // my preferences
74 FCG_VERB1("EmbeddedcCodeGenerator::Compile(): prefer compiled bitmasks over bit-address maths");
76 }
77}
78
79
80// DoGenerate()
82 FD_DCG("EmbeddedcCodeGenerator(" << this << ")::DoGenerate()");
83 // cut and paste from base
84 mBitarrays.clear();
85 // say hello
86 Comment("************************************************");
87 Comment("CodeGenerator: Target Embedded C ");
88 Comment("************************************************");
89 LineFeed(1);
90 Comment(std::string("CompileDES ") + VersionString());
91 Comment(std::string("Configuration: ") + Name());
92 LineFeed(2+1);
93 // base class snippets
96 // cyclic function
97 LineFeed(2);
98 Output() << "void " << mPrefix << "cyclic(void) { ";
99 LineFeed();
102 Output() << "}; /* end function " << mPrefix << "cyclic() */";
103 LineFeed();
104 LineFeed(2+1);
105 // extra: provide timer decrement interface to host application
107 // snippets
109 Comment("************************************************");
110 Comment("CodeGenerator: Generated Code Ends Here ");
111 Comment("************************************************");
112}
113
114
115
116// code blocks: organise time decrement as function to be periodically
117// invoked by the host application
119 // timer update function
120 if(TimersBegin()!=TimersEnd()) {
121 Comment("************************************************");
122 Comment("* update timer states *");
123 Comment("************************************************");
124 LineFeed(2);
125 Output() << "void " << mPrefix <<"timerdec(int dec) { ";
126 LineFeed();
127 IndentInc();
129 for(;tit!=TimersEnd();++tit) {
130 Output() << "if( " << TargetAddress(AA("timer_" + tit->second.mAddress + "_run")) << " ) "
131 << TargetAddress(AA("timer_" + tit->second.mAddress + "_cnt")) << " -= dec;";
132 LineFeed();
133 }
134 IndentDec();
135 Output() << "};";
136 LineFeed();
137 LineFeed(1+2);
138 }
139}
140
141// generate code
143 if((mEventExecutionHook!="") || (mStateUpdateHook!="")) {
144 Comment("call hooks");
145 if(mEventExecutionHook!="") {
146 std::string hook = mEventExecutionHook + "(" + TargetExpression(AA("exec_event")) + ");";
147 Output() << hook;
148 LineFeed(1);
149 }
150 if(mStateUpdateHook!="") {
151 std::string hook = mStateUpdateHook + "(" + TargetAddress(AA("parallel_state")) + ");";
152 Output() << hook;
153 LineFeed(1);
154 }
155 LineFeed(1);
156 }
157}
158
159// generate code
160void EmbeddedcCodeGenerator::Comment(const std::string& text) {
161 // write comment
162 if(!mMuteComments) {
163 Output() << "/* " << text << " */";
164 LineFeed();
165 }
166 // call base to record muted comments
168}
169
170// address transformation
171std::string EmbeddedcCodeGenerator::TargetAddress(const AA& address) {
172 // should so some mangeling to replace non-ascii / funny characters
173 std::string res=mPrefix+address;
174 return res;
175}
176
177// address transformation
181
182// generate code: integer
183void EmbeddedcCodeGenerator::IntegerDeclare(const AA& address){
184 Output() << "static " << mIntegerType << " " << TargetAddress(address) << ";";
185 LineFeed();
186}
187
188// generate code: integer
189void EmbeddedcCodeGenerator::IntegerDeclare(const AA& address, int val){
190 Output() << "static " << mIntegerType << " " << TargetAddress(address) << "=" << val << ";";
191 LineFeed();
192}
193
194// generate code: integer
195void EmbeddedcCodeGenerator::IntegerAssign(const AA& address, int val){
196 Output() << TargetAddress(address) << " = " << IntegerConstant(val) << ";";
197 LineFeed();
198}
199
200// generate code: integer
201void EmbeddedcCodeGenerator::IntegerAssign(const AA& address, const AX& expression){
202 Output() << TargetAddress(address) << " = " << expression << ";";
203 LineFeed();
204}
205
206// generate code: integer
207void EmbeddedcCodeGenerator::IntegerIncrement(const AA& address, int val) {
208 if(val==1)
209 Output() << TargetAddress(address) << "++;";
210 else if(val==-1)
211 Output() << TargetAddress(address) << "--;";
212 else if(val!=0)
213 Output() << TargetAddress(address) << " += " << IntegerConstant(val) << ";";
214 if(val!=0)
215 LineFeed();
216}
217
218// integer maths
219EmbeddedcCodeGenerator::AX EmbeddedcCodeGenerator::IntegerQuotient(const AX& expression, int val) {
220 return AX(expression + " / " + IntegerConstant(val));
221}
222
223// integer maths
224EmbeddedcCodeGenerator::AX EmbeddedcCodeGenerator::IntegerRemainder(const AX& expression, int val) {
225 return AX(expression + " % " + IntegerConstant(val));
226}
227
228// integer maths
229CodePrimitives::AX EmbeddedcCodeGenerator::IntegerBitmask(const AX& expression) {
230 return AX("(" + WordConstant(1) + " << " + expression + ")" );
231}
232
233// integer compare
234CodePrimitives::AX EmbeddedcCodeGenerator::IntegerIsEq(const AA& address, int val) {
235 return AX(TargetAddress(address) + " == " + IntegerConstant(val));
236}
237
238// integer compare
239CodePrimitives::AX EmbeddedcCodeGenerator::IntegerIsEq(const AA& address, const AX& expression) {
240 return AX(TargetAddress(address) + " == " + expression);
241}
242
243// integer compare
244CodePrimitives::AX EmbeddedcCodeGenerator::IntegerIsNotEq(const AA& address, const AX& expression) {
245 return AX(TargetAddress(address) + " != " + expression);
246}
247
248// integer compare
249CodePrimitives::AX EmbeddedcCodeGenerator::IntegerIsNotEq(const AA& address, int val) {
250 return AX(TargetAddress(address) + " != " + IntegerConstant(val));
251}
252
253// integer compare
254CodePrimitives::AX EmbeddedcCodeGenerator::IntegerIsGreater(const AA& address, int val) {
255 return AX(TargetAddress(address) + " > " + IntegerConstant(val));
256}
257
258// integer compare
259CodePrimitives::AX EmbeddedcCodeGenerator::IntegerIsLess(const AA& address, int val) {
260 return AX(TargetAddress(address) + " < " + IntegerConstant(val));
261}
262
263// integer maths
264bool EmbeddedcCodeGenerator::HasIntmaths(void) {
265 return true;
266}
267
268// generate code: integer
269CodePrimitives::AX EmbeddedcCodeGenerator::IntegerConstant(int val) {
270 AX res(ToStringInteger(val));
271 if(mIntegerType == "char") return res;
272 if(mIntegerType == "int8_t") return res;
273 if(mIntegerType == "int") return res;
274 if(mIntegerType == "int16_t") return res;
275 if(mIntegerType == "long") return AX(res + "L");
276 if(mIntegerType == "int32_t") return AX(res + "L");
277 if(mIntegerType == "long long") return AX(res + "LL");
278 FCG_ERR("EmbeddedcCodeGenerator: unsupported integer data type [" << mIntegerType << "]");
279 return res;
280}
281
282// generate code: word
283void EmbeddedcCodeGenerator::WordDeclare(const AA& address){
284 Output() << "static " << mWordType << " " << TargetAddress(address) << ";";
285 LineFeed();
286}
287
288// generate code: word
289void EmbeddedcCodeGenerator::WordDeclare(const AA& address, word_t val){
290 Output() << "static " << mWordType << " " << TargetAddress(address) << "=" << val << ";";
291 LineFeed();
292}
293
294// generate code: word
295void EmbeddedcCodeGenerator::WordAssign(const AA& address, word_t val){
296 Output() << TargetAddress(address) << " = " << WordConstant(val) << ";";
297 LineFeed();
298}
299
300// generate code: word
301void EmbeddedcCodeGenerator::WordAssign(const AA& address, const AX& expression){
302 Output() << TargetAddress(address) << " = " << expression << ";";
303 LineFeed();
304}
305
306// generate code: word
307void EmbeddedcCodeGenerator::WordOr(const AA& address, word_t val) {
308 Output() << TargetAddress(address) << " |= " << WordConstant(val) << ";";
309 LineFeed();
310}
311
312// generate code: word
313void EmbeddedcCodeGenerator::WordOr(const AA& address, const AX& expression) {
314 Output() << TargetAddress(address) << " |= " << expression << ";";
315 LineFeed();
316}
317
318// generate code: word
319void EmbeddedcCodeGenerator::WordOr(const AA& address, const AA& op1, const AA& op2) {
320 Output() << TargetAddress(address) << " = " << TargetExpression(op1) << " | " << TargetExpression(op2) << ";";
321 LineFeed();
322}
323
324// generate code: word
325void EmbeddedcCodeGenerator::WordOr(const AA& address, const AA& op1, word_t op2) {
326 Output() << TargetAddress(address) << " = " << TargetExpression(op1) << " | " << WordConstant(op2) << ";";
327 LineFeed();
328}
329
330// generate code: word
331void EmbeddedcCodeGenerator::WordAnd(const AA& address, word_t val) {
332 Output() << TargetAddress(address) << " &= " << WordConstant(val) << ";";
333 LineFeed();
334}
335
336// generate code: word
337void EmbeddedcCodeGenerator::WordAnd(const AA& address, const AX& expression) {
338 Output() << TargetAddress(address) << " &= " << expression << ";";
339 LineFeed();
340}
341
342// generate code: word
343void EmbeddedcCodeGenerator::WordAnd(const AA& address, const AA& op1, const AA& op2) {
344 Output() << TargetAddress(address) << " = " << TargetExpression(op1) << " & " << TargetExpression(op2) << ";";
345 LineFeed();
346}
347
348// generate code: word
349void EmbeddedcCodeGenerator::WordAnd(const AA& address, const AA& op1, word_t op2) {
350 Output() << TargetAddress(address) << " = " << TargetExpression(op1) << " & " << WordConstant(op2) << ";";
351 LineFeed();
352}
353
354// generate code: word
355void EmbeddedcCodeGenerator::WordNand(const AA& address, const AX& expression) {
356 Output() << TargetAddress(address) << " &= ~(" << expression << ");";
357 LineFeed();
358}
359
360// generate code: word
361CodePrimitives::AX EmbeddedcCodeGenerator::WordIsBitSet(const AA& address, int idx) {
362 return AX("( " + TargetAddress(address) + " & " + WordConstant(0x01<<idx) + " ) != 0");
363}
364
365// generate code: word
366CodePrimitives::AX EmbeddedcCodeGenerator::WordIsBitClr(const AA& address, int idx) {
367 return AX("( " + TargetAddress(address) + " & " + WordConstant(0x01<<idx) + " ) == 0");
368}
369
370// generate code: word
371CodePrimitives::AX EmbeddedcCodeGenerator::WordIsMaskSet(const AA& address, word_t mask) {
372 return AX("( " + TargetAddress(address) + " & " + WordConstant(mask) + " ) != 0");
373}
374
375// generate code: conditionals
376CodePrimitives::AX EmbeddedcCodeGenerator::WordIsEq(const AA& address, word_t val) {
377 return AX(TargetAddress(address) + " == " + WordConstant(val));
378}
379
380// generate code: conditionals
381CodePrimitives::AX EmbeddedcCodeGenerator::WordIsNotEq(const AA& address, word_t val) {
382 return AX(TargetAddress(address) + " != " + WordConstant(val));
383}
384
385// generate code: word
386EmbeddedcCodeGenerator::AX EmbeddedcCodeGenerator::WordConstant(word_t val) {
387 AX res;
388 std::stringstream sstr;
389 sstr << "0x" << std::setbase(16) << std::setfill('0');
390 // special case: zero
391 if(val==0) sstr << std::setw(2);
392 // special case: char
393 if(mWordType == "unsigned char") { sstr << std::setw(2); val &=0xff; }
394 // do stream
395 if(mWordType == "unsigned char") sstr << val;
396 else if(mWordType == "uint8_t") sstr << ((uint8_t) val) << "U";
397 else if(mWordType == "unsigned short") sstr << ((unsigned short) val) << "U";
398 else if(mWordType == "unsigned int") sstr << ((unsigned int) val) << "U";
399 else if(mWordType == "uint16_t") sstr << ((uint16_t) val) << "U";
400 else if(mWordType == "unsigned long") sstr << ((unsigned long) val) << "UL";
401 else if(mWordType == "uint32_t") sstr << ((uint32_t) val) << "UL";
402 else if(mWordType == "unsigned long long") sstr << ((unsigned long long) val) << "ULL";
403 else FCG_ERR("EmbeddedcCodeGenerator: unsupported word data type [" << mWordType <<"]");
404 sstr >> res;
405 return res;
406}
407
408// generate code: string constant
409EmbeddedcCodeGenerator::AX EmbeddedcCodeGenerator::StringConstant(const std::string& val) {
410 AX res;
411 res.append(1,'\"');
412 for(std::size_t i=0; i<val.length(); ++i) {
413 char c=val.at(i);
414 // terminate
415 if(c==0) break;
416 // quote double quote
417 if(c=='"') { res.append("\\\""); continue; }
418 // quote back slash
419 if(c=='\\') { res.append("\\\\"); continue; }
420 // printable ascii
421 if((c>=0x20) && (c<0x7f)) { res.append(1,c); continue; };
422 // error on other (alternative: use octal encoding to support utf8)
423 FCG_ERR("EmbeddedcCodeGenerator: non-printable ascii or other encoding unsupported [" << val <<"]");
424 }
425 res.append(1,'\"');
426 return res;
427}
428
429// const-int array (Embedded C only helper)
430EmbeddedcCodeGenerator::AX EmbeddedcCodeGenerator::IntarrayConstant(int offset, const std::vector<int>& val) {
431 std::stringstream strstr;
432 int newline=20;
433 if(val.size()+offset<25) newline=25;
434 strstr << "{ " ;
435 size_t vit=0;
436 while(true) {
437 if(vit==val.size()+offset) break;
438 if(vit< (size_t) offset)
439 strstr << IntegerConstant(0);
440 else
441 strstr << IntegerConstant(val[vit-offset]);
442 ++vit;
443 if(vit==val.size()+offset) break;
444 strstr << ", ";
445 newline--;
446 if(newline==0) {
447 strstr << std::endl << " ";
448 newline=20;
449 }
450 }
451 strstr << " }";
452 return AX(strstr.str());
453}
454
455// const-int-array
456void EmbeddedcCodeGenerator::CintarrayDeclare(const AA& address, int offset, const std::vector<int>& val) {
457 if(val.size()==0) {
458 FCG_ERR("EmbeddedcCodeGenerator::Cintarray(): ignoring empty const vector");
459 return;
460 }
461 if(val.size()>= (1ULL << (mIntegerSize-1))) {
462 FCG_ERR("EmbeddedcCodeGenerator::Cintarray(): const vector exceeds addres range");
463 return;
464 }
465 //const std::vector<int> *pval=&val;
466 if(offset>0) {
467 std::vector<int> oval(val.size()+offset,0);
468 for(size_t i=0; i<val.size(); ++i)
469 oval[offset+i]=val[i];
470 //pval=&oval;
471 }
472 Output() << "const " << mIntegerType << " " << TargetAddress(address) << "[] = ";
473 LineFeed();
474 IndentInc();
475 Output() << IntarrayConstant(offset,val) << ";";
476 LineFeed();
477 IndentDec();
478}
479
480// int array access by const
481EmbeddedcCodeGenerator::AA EmbeddedcCodeGenerator::CintarrayAccess(const AA& address, int index) {
482 return AA(address + "[" + ToStringInteger(index) + "]");
483};
484
485// int array access by expression
486EmbeddedcCodeGenerator::AA EmbeddedcCodeGenerator::CintarrayAccess(const AA& address, const AA& indexaddr){
487 return AA(address + "[" + TargetAddress(indexaddr) + "]");
488};
489
490// tell parent class about this feature
491bool EmbeddedcCodeGenerator::HasCintarray(void) {
492 return true;
493};
494
495
496// const-word array (Embedded C only helper)
497EmbeddedcCodeGenerator::AX EmbeddedcCodeGenerator::WordarrayConstant(int offset, const std::vector<word_t>& val) {
498 std::stringstream strstr;
499 int newline=20;
500 if(val.size()+offset<25) newline=25;
501 strstr << "{ " ;
502 size_t vit=0;
503 while(true) {
504 if(vit==val.size()+offset) break;
505 if(vit < (size_t) offset)
506 strstr << WordConstant(0);
507 else
508 strstr << WordConstant(val[vit-offset]);
509 ++vit;
510 if(vit==val.size()+offset) break;
511 strstr << ", ";
512 newline--;
513 if(newline==0) {
514 strstr << std::endl << " ";
515 newline=20;
516 }
517 }
518 strstr << " }";
519 return AX(strstr.str());
520}
521
522// const-word-array
523void EmbeddedcCodeGenerator::CwordarrayDeclare(const AA& address, int offset, const std::vector<word_t>& val) {
524 if(val.size()==0) {
525 FCG_ERR("EmbeddedcCodeGenerator::Cwordarray(): ignoring empty const vector");
526 return;
527 }
528 if(val.size()>= (1ULL << (mIntegerSize-1))) {
529 FCG_ERR("EmbeddedcCodeGenerator::Cwordarray(): const vector exceeds addres range");
530 return;
531 }
532 Output() << "const " << mWordType << " " << TargetAddress(address) << "[] = ";
533 IndentInc();
534 Output() << WordarrayConstant(offset,val) << ";";
535 LineFeed();
536 IndentDec();
537}
538
539// word-array access by const
540EmbeddedcCodeGenerator::AA EmbeddedcCodeGenerator::CwordarrayAccess(const AA& address, int index) {
541 return AA(address + "[" + ToStringInteger(index) + "]");
542};
543
544// word array access by expression
545EmbeddedcCodeGenerator::AA EmbeddedcCodeGenerator::CwordarrayAccess(const AA& address, const AA& indexaddr){
546 return AA(address + "[" + TargetAddress(indexaddr) + "]");
547};
548
549// tell parent class about this feature
550bool EmbeddedcCodeGenerator::HasCwordarray(void) {
551 return true;
552};
553
554// int-array
555void EmbeddedcCodeGenerator::IntarrayDeclare(const AA& address, int offset, const std::vector<int>& val) {
556 if(val.size()==0) {
557 FCG_ERR("EmbeddedcCodeGenerator::Intarray(): ignoring empty const vector");
558 return;
559 }
560 if(val.size()>= (1ULL << (mIntegerSize-1))) {
561 FCG_ERR("EmbeddedcCodeGenerator::Intarray(): vector exceeds address range");
562 return;
563 }
564 Output() << mIntegerType << " " << TargetAddress(address) << "[] = ";
565 IndentInc();
566 Output() << IntarrayConstant(offset,val) << ";";
567 LineFeed();
568 IndentDec();
569}
570
571// int-array
572void EmbeddedcCodeGenerator::IntarrayDeclare(const AA& address, int offset, int len) {
573 if(len==0) {
574 FCG_ERR("EmbeddedcCodeGenerator::Intarray(): ignoring empty const vector");
575 return;
576 }
577 if(len+offset>= (1LL << (mIntegerSize-1))) {
578 FCG_ERR("EmbeddedcCodeGenerator::Intarray(): const vector exceeds address range");
579 return;
580 }
581 Output() << mIntegerType << " " << TargetAddress(address) << "[" << IntegerConstant(len+offset) << "];";
582 LineFeed();
583}
584
585// int-array access by const
587 return AA(address + "[" + ToStringInteger(index) + "]");
588};
589
590// int array access by expression
592 return AA(address + "[" + TargetAddress(indexaddr) + "]");
593};
594
595// tell parent class about this feature
597 return true;
598};
599
600// word-array
601void EmbeddedcCodeGenerator::WordarrayDeclare(const AA& address, int offset, const std::vector<word_t>& val) {
602 if(val.size()==0) {
603 FCG_ERR("EmbeddedcCodeGenerator::Wordarray(): ignoring empty const vector");
604 return;
605 }
606 if(val.size()+offset >= (1ULL << (mIntegerSize-1))) {
607 FCG_ERR("EmbeddedcCodeGenerator::Wordarray(): const vector exceeds addres range");
608 return;
609 }
610 Output() << mWordType << " " << TargetAddress(address) << "[] = ";
611 IndentInc();
612 Output() << WordarrayConstant(offset,val) << ";";
613 LineFeed();
614 IndentDec();
615}
616
617// word-array
618void EmbeddedcCodeGenerator::WordarrayDeclare(const AA& address, int offset, int len) {
619 if(len==0) {
620 FCG_ERR("EmbeddedcCodeGenerator::Wordarray(): ignoring empty const vector");
621 return;
622 }
623 if(len+offset>= (1LL << (mIntegerSize-1))) {
624 FCG_ERR("EmbeddedcCodeGenerator::Wordarray(): const vector exceeds addres range");
625 return;
626 }
627 Output() << mWordType << " " << TargetAddress(address) << "[" << IntegerConstant(len+offset) << "];";
628 LineFeed();
629}
630
631// word-array access by const
632EmbeddedcCodeGenerator::AA EmbeddedcCodeGenerator::WordarrayAccess(const AA& address, int index) {
633 return AA(address + "[" + ToStringInteger(index) + "]");
634};
635
636// word array access by expression
637EmbeddedcCodeGenerator::AA EmbeddedcCodeGenerator::WordarrayAccess(const AA& address, const AA& indexaddr){
638 return AA(address + "[" + TargetAddress(indexaddr) + "]");
639};
640
641// tell parent class about this feature
642bool EmbeddedcCodeGenerator::HasWordarray(void) {
643 return true;
644};
645
646// literal const-string array (Embedded C only helper)
647EmbeddedcCodeGenerator::AX EmbeddedcCodeGenerator::StrarrayConstant(int offset, const std::vector<std::string>& val) {
648 std::stringstream strstr;
649 int newline;
650 if(val.size()+offset <4) {
651 newline=4;
652 strstr << "{ ";
653 } else {
654 newline=1;
655 strstr << "{" << std::endl;
656 }
657 size_t vit=0;
658 while(true) {
659 if(vit==val.size()+offset) break;
660 if(vit < (size_t)offset)
661 strstr << StringConstant("");
662 else
663 strstr << StringConstant(val[vit-offset]);
664 ++vit;
665 if(vit==val.size()+offset) break;
666 strstr << ", ";
667 newline--;
668 if(newline==0) {
669 strstr << std::endl;
670 newline=1;
671 }
672 }
673 strstr << " }";
674 return AX(strstr.str());
675}
676
677// const string array
678void EmbeddedcCodeGenerator::CstrarrayDeclare(const AA& address, int offset, const std::vector<std::string>& val) {
679 if(val.size()==0) {
680 FCG_ERR("EmbeddedcCodeGenerator::Cstrarrayy(): ignoring empty string array");
681 return;
682 }
683 if(val.size()+offset >= (1ULL << (mIntegerSize-1))) {
684 FCG_ERR("EmbeddedcCodeGenerator::Cstrarray(): string array exceeds address range");
685 return;
686 }
687 Output() << "const char* const" << " " << TargetAddress(address) << "[] = ";
688 IndentInc();
689 Output() << StrarrayConstant(offset,val) << ";";
690 LineFeed();
691 IndentDec();
692};
693
694// const string array
695EmbeddedcCodeGenerator::AA EmbeddedcCodeGenerator::CstrarrayAccess(const AA& address, int index) {
696 return AA(address + "[" + ToStringInteger(index) + "]");
697};
698
699// const string array
700EmbeddedcCodeGenerator::AA EmbeddedcCodeGenerator::CstrarrayAccess(const AA& address, const AA& indexaddr){
701 return AA(address + "[" + TargetAddress(indexaddr) + "]");
702};
703
704// tell parent about this feature
705bool EmbeddedcCodeGenerator::HasCstrarray(void) {
706 return true;
707};
708
709
710// generate code: conditionals
711void EmbeddedcCodeGenerator::IfTrue(const AX& expression) {
712 Output() << "if( " << expression << " ) {";
713 LineFeed();
714 IndentInc();
715}
716
717// generate code: conditionals
718void EmbeddedcCodeGenerator::IfFalse(const AX& expression) {
719 Output() << "if( ! ( " << expression << " ) ) {";
720 LineFeed();
721 IndentInc();
722}
723
724// generate code: conditionals
725void EmbeddedcCodeGenerator::IfWord(const AX& expression) {
726 Output() << "if( " << expression << " ) {";
727 LineFeed();
728 IndentInc();
729}
730
731// generate code: conditionals
732void EmbeddedcCodeGenerator::IfElse(void) {
733 IndentDec();
734 Output() << "} else {";
735 LineFeed();
736 IndentInc();
737}
738
739// generate code: conditionals
740void EmbeddedcCodeGenerator::IfElseIfTrue(const AX& expression) {
741 IndentDec();
742 Output() << "} else if( " << expression << " ) {";
743 LineFeed();
744 IndentInc();
745}
746
747// generate code: conditionals
748void EmbeddedcCodeGenerator::IfEnd(void) {
749 IndentDec();
750 Output() << "};";
751 LineFeed();
752}
753
754// switch control
755void EmbeddedcCodeGenerator::SwitchBegin(const AA& address){
756 Output() << "switch(" << TargetAddress(address) << ") {";
757 LineFeed();
758}
759
760// switch control
761void EmbeddedcCodeGenerator::SwitchCase(const AA& address, int val){
762 (void) address;
763 Output() << "case " << IntegerConstant(val) << ":";
764 LineFeed();
765 IndentInc();
766}
767
768// switch control
769void EmbeddedcCodeGenerator::SwitchCases(const AA& address, int from, int to){
770 // simplify to singleton
771 if(from==to) {
772 SwitchCase(address, from);
773 return;
774 }
775 // do range (quiet for empty)
776 for(int val=from; val<=to; ++val) {
777 Output() << "case " << IntegerConstant(val) << ":";
778 LineFeed();
779 }
780 IndentInc();
781}
782
783// switch control
784void EmbeddedcCodeGenerator::SwitchCases(const AA& address, const std::set< int >& vals){
785 (void) address;
786 // do set (quiet for empty)
787 std::set< int >::const_iterator vit=vals.begin();
788 for(; vit!=vals.end(); ++ vit) {
789 Output() << "case " << IntegerConstant(*vit) << ":";
790 LineFeed();
791 }
792 IndentInc();
793}
794
795// switch control
796void EmbeddedcCodeGenerator::SwitchBreak(void){
797 Output() << "break;";
798 LineFeed();
799 IndentDec();
800}
801
802// switch control
803void EmbeddedcCodeGenerator::SwitchEnd(void){
804 Output() << "default:";
805 LineFeed();
806 IndentInc();
807 Output() << "break;";
808 LineFeed();
809 IndentDec();
810 Output() << "};";
811 LineFeed();
812}
813
814// switch control
815bool EmbeddedcCodeGenerator::HasMultiCase(void) {
816 return true;
817}
818
819// loops
820void EmbeddedcCodeGenerator::LoopBegin(void) {
821 Output() << "while(1) {";
822 LineFeed();
823 IndentInc();
824}
825
826// loops
827void EmbeddedcCodeGenerator::LoopBreak(const AX& expression) {
828 Output() << "if( " << expression << " ) break;";
829 LineFeed();
830}
831
832
833// loops
834void EmbeddedcCodeGenerator::LoopEnd(void) {
835 IndentDec();
836 Output() << "};";
837 LineFeed();
838}
839
840void EmbeddedcCodeGenerator::FunctionReturn(void) {
841 Output() << "return;";
842 LineFeed();
843}
844
845
846// timer
847void EmbeddedcCodeGenerator::TimerDeclare(const AA& address, const std::string& litval) {
848 // read/check ftu time format
849 char* next;
850 const char* first = litval.c_str();
851 strtol(first,&next,10);
852 bool err=false;
853 if(*next!='f') err=true;
854 if(!err) if(*(++next)!='t') err=true;
855 if(!err) if(*(++next)!='u') err=true;
856 if(!err) if(*(++next)!=0) err=true;
857 if(err) {
858 FCG_ERR("EmbeddedcCodeGenerator: missmatched time literal "+ litval);
859 }
860 Output() << "static int " << TargetAddress(AA("timer_"+address+"_cnt")) << ";";
861 LineFeed();
862 Output() << "static char " << TargetAddress(AA("timer_"+address+"_run")) << ";";
863 LineFeed();
864}
865void EmbeddedcCodeGenerator::TimerStart(const AA& address) {
866 Output() << TargetAddress(AA("timer_"+address+"_run")) << " = 1;";
867 LineFeed();
868}
869void EmbeddedcCodeGenerator::TimerStop(const AA& address) {
870 Output() << TargetAddress(AA("timer_"+address+"_run")) << " = 0;";
871 LineFeed();
872}
873void EmbeddedcCodeGenerator::TimerReset(const AA& address, const std::string& litval) {
874 int val=(int) strtol(litval.c_str(),NULL,10);
875 Output() << TargetAddress(AA("timer_"+address+"_cnt")) << " = " << IntegerConstant(val) << ";";
876 LineFeed();
877}
878CodePrimitives::AX EmbeddedcCodeGenerator::TimerIsElapsed(const AA& address) {
879 return AX(TargetAddress(AA("timer_"+address+"_run")) + " && (" + TargetAddress(AA("timer_"+address+"_cnt")) + " <= 0)");
880}
881
882
883// output actions
884void EmbeddedcCodeGenerator::RunActionSet(const std::string& address) {
885 Output() << address << " = 1;" ;
886 LineFeed();
887}
888void EmbeddedcCodeGenerator::RunActionClr(const std::string& address) {
889 Output() << address << " = 0;" ;
890 LineFeed();
891}
892void EmbeddedcCodeGenerator::RunActionExe(const AX& expression) {
893 Output() << expression << ";";
894 LineFeed();
895}
896
897
898
#define FAUDES_REGISTERCODEGENERATOR(ftype, ctype)
Class registration macro.
Code-generator for target C.
virtual void LineFeed(int lines=1)
LineFeed (convenience support for derived classes)
virtual const std::string & Name(void) const
Get objects's name (reimplementing base faudes::Type)
TimerIterator TimersBegin()
Access to timer records by iterator.
virtual void IndentInc()
Indentation (convenience support for derived classes)
TimerIterator TimersEnd()
Access to timer records by iterator.
int mWordSize
compressed boolean capacity of target type word
bool mMuteComments
mute comments
int mIntegerSize
compressed boolean capacity of target type integer
std::map< std::string, TimerConfiguration >::iterator TimerIterator
Access to timer records by iterator.
virtual std::ostream & Output(void)
Output stream.
static std::string VersionString(void)
Version (refers to macro COMPILEDES_VERSION, defined in cgp_codegenerator.h)
virtual void IndentDec()
Indentation (convenience support for derived classes)
Abstract address; see also Absstract_Addresses.
Abstract expression; see also Absstract_Addresses.
Execution semantics in terms of code primitives.
bool mBitAddressArithmetic
code option: compute bit and word address on target
std::string mStateUpdateHook
code option: state change hook
virtual void DoGenerateDeclarations(void)
cut-and-paste template for code snippet assembly
virtual void DoGenerateResetCode(void)
cut-and-paste template for code snippet assembly
virtual void LiteralAppend(void)
Cosmetic: append literally from configuration.
virtual void Comment(const std::string &text)
Target comments (see EmbeddedcCodeGenerator for consistent reimplementation pattern)
std::map< std::string, bitarray_rec > mBitarrays
Record of all declared bit-arrays.
virtual void DoReadTargetConfiguration(TokenReader &rTr)
re-implement token i/o for extra configuration
std::string mIntegerType
target data type for integer
virtual void DoGenerateCyclicCode(void)
cut-and-paste template for code snippet assembly
virtual void Clear(void)
Clear all data.
std::string mWordType
target data type for word
virtual void DoWriteTargetConfiguration(TokenWriter &rTw) const
re-implement token i/o for extra configuration
bool mArrayForBitmasks
code option: use const array to represent bit-masks
virtual void DoCompile(void)
virtual hook to extend compiled data
virtual void LiteralPrepend(void)
Cosmetic: prepend literally from configuration data.
std::string mPrefix
universal prefix (pseudo name space)
std::string mEventExecutionHook
code option: event exec hook
Implementation of code primitives by generic C-code.
void DoCompile(void)
add my preferences to DoCompile
void DoGenerate(void)
virtual hook for generate
virtual bool HasIntarray(void)
default int-array: not supported
virtual void DoWriteTargetConfiguration(TokenWriter &rTw) const
File i/o.
virtual void Comment(const std::string &text)
Target comments (see EmbeddedcCodeGenerator for consistent reimplementation pattern)
EmbeddedcCodeGenerator(void)
Constructor.
virtual void DoReadTargetConfiguration(TokenReader &rTr)
File i/o.
virtual AA IntarrayAccess(const AA &address, int index)
default int-array: not supported
virtual void Clear(void)
Clear all data.
virtual void DecrementTimers(void)
re-implemented/additional code blocks
virtual std::string TargetAddress(const AA &address)
abstract address conversion
virtual ~EmbeddedcCodeGenerator(void)
Explicit destructor.
virtual AX TargetExpression(const AA &address)
abstract address conversion
void InsertExecHooks(void)
Helper to insert target code for execution hooks.
virtual void IntarrayDeclare(const AA &address, int offset, int len)
default int-array: not supported