33 FD_DCG(
"Iec61131stCodeGenerator(" <<
this <<
")::Iec61131stCodeGenerator()");
39 FD_DCG(
"Iec61131stCodeGenerator(" <<
this <<
")::~Iec61131stCodeGenerator()");
45 FD_DCG(
"Iec61131stCodeGenerator::Clear()");
61 FD_DCG(
"Iec61131stCodeGenerator::DoReadTargetConfiguration()");
66 if(rTr.ExistsBegin(
"IecDeclarePhysical")) {
67 rTr.ReadBegin(
"IecDeclarePhysical",token);
69 rTr.ReadEnd(
"IecDeclarePhysical");
72 if(rTr.ExistsBegin(
"IecDeclareSymbolic")) {
73 rTr.ReadBegin(
"IecDeclareSymbolic",token);
75 rTr.ReadEnd(
"IecDeclareSymbolic");
78 if(rTr.ExistsBegin(
"IncludeCyclic"))
80 if(rTr.ExistsBegin(
"IecTimeOperators")) {
81 rTr.ReadBegin(
"IecTimeOperators",token);
83 rTr.ReadEnd(
"IecTimeOperators");
89 FD_DCG(
"Iec61131stCodeGenerator::DoWriteTargetConfiguration()");
94 token.SetEmpty(
"IecDeclarePhysical");
98 token.SetEmpty(
"IecDeclareSymbolic");
104 token.SetEmpty(
"IecTimeOperators");
129 FCG_VERB1(
"Iec61131stCodeGenerator::Compile(): prefer compiled bitmasks over bit-address maths");
134 FCG_VERB1(
"Iec61131stCodeGenerator::Compile(): using array for state as return value datatype");
145 Comment(
"************************************************");
146 Comment(
"CodeGenerator: Target IEC 61131 Structured Text ");
147 Comment(
"************************************************");
160 Comment(
"************************************************");
161 Comment(
"CodeGenerator: Generated Code Ends Here ");
162 Comment(
"************************************************");
169 Comment(
"************************************************");
170 Comment(
"* function block to host cyclic code *");
171 Comment(
"************************************************");
220 Comment(
"************************************************");
221 Comment(
"* end of cyclic function block *");
223 Output() <<
"END_FUNCTION_BLOCK";
232 Comment(
"************************************************");
233 Comment(
"* function to host the event name loopup table *");
234 Comment(
"************************************************");
236 Output() <<
"FUNCTION " <<
mPrefix <<
"event_lookup_f" <<
" : STRING";
244 Output() <<
"VAR CONSTANT";
251 Output() <<
"END_FUNCTION";
256 Comment(
"************************************************");
257 Comment(
"* function to host state name loopup tables *");
258 Comment(
"************************************************");
260 Output() <<
"FUNCTION " <<
mPrefix <<
"state_lookup_f" <<
" : STRING";
270 Output() <<
"VAR CONSTANT";
277 Output() <<
"CASE GID OF";
279 for(
size_t gid=0; gid<
Size(); ++gid) {
281 Output() << ToStringInteger(gid) <<
": "
282 <<
mPrefix <<
"state_lookup_f" <<
" := " <<
mPrefix <<
"state_lookup_" << ToStringInteger(gid) <<
"[IDX]" <<
";";
287 Output() <<
"IF LEN(" <<
mPrefix <<
"state_lookup_f) = 0 THEN";
293 Output() <<
"END_FUNCTION";
302 FD_DCG(
"Iec61131stCodeGenerator(" <<
this <<
")::StateReset()");
317 Comment(
"elapsed time since last invokation");
332 std::string lineaddr= lit->second.mAddress;
333 if(lineaddr.size()<1)
continue;
334 if(lineaddr.at(0)==
'%') iocnt++;
338 if(!ait->second.mSetClr)
continue;
339 std::string actaddr= ait->second.mAddress;
340 if(actaddr.size()<1)
continue;
341 if(actaddr.at(0)==
'%') ++iocnt;
348 Comment(
"import physical i/o addresses");
351 std::string lineaddr= lit->second.mAddress;
352 if(lineaddr.size()<1)
continue;
353 if(lineaddr.at(0)==
'%') {
354 Output() <<
"AT " << lineaddr <<
" : BOOL;";
360 if(!ait->second.mSetClr)
continue;
361 std::string actaddr= ait->second.mAddress;
362 if(actaddr.size()<1)
continue;
363 if(actaddr.at(0)==
'%') {
364 Output() <<
"AT " << actaddr <<
" : BOOL;";
379 std::string lineaddr= lit->second.mAddress;
380 if(lineaddr.size()<1)
continue;
381 if(lineaddr.at(0)!=
'%') iocnt++;
385 if(!ait->second.mSetClr)
continue;
386 std::string actaddr= ait->second.mAddress;
387 if(actaddr.size()<1)
continue;
388 if(actaddr.at(0)!=
'%') ++iocnt;
394 Comment(
"import i/o variables");
397 std::string lineaddr= lit->second.mAddress;
398 if(lineaddr.size()<1)
continue;
399 if(lineaddr.at(0)!=
'%') {
406 if(!ait->second.mSetClr)
continue;
407 std::string actaddr= ait->second.mAddress;
408 if(actaddr.size()<1)
continue;
409 if(actaddr.at(0)!=
'%') {
421 Comment(
"************************************************");
422 Comment(
"* extra cyclic code from configuration *");
426 Comment(
"* end of extra code from configuration *");
427 Comment(
"************************************************");
453 Comment(
"************************************************");
454 Comment(
"* update timer states *");
461 AA cnt(
"timer_" + tit->second.mAddress +
"_cnt");
462 AA run(
"timer_" + tit->second.mAddress +
"_run");
498 Comment(
"iec timer to simulate system time");
508 Comment(
"do reset/track systime");
509 Output() <<
"IF " <<
mPrefix <<
"exec_event = -1 " <<
" THEN" << std::endl;
510 Output() <<
" " <<
mPrefix <<
"systime_ton(IN:=false);" << std::endl;
511 Output() <<
" " <<
mPrefix <<
"systime_recent := TIME#0ms;" << std::endl;
512 Output() <<
"END_IF;" << std::endl;
513 Output() <<
mPrefix <<
"systime_ton(IN:=true, PT:=TIME#2h, ET=>" <<
mPrefix <<
"systime_now);" << std::endl;
519 Output() <<
"IF " <<
mPrefix <<
"systime_now < TIME#1h THEN" << std::endl;
521 Output() <<
"ELSE" << std::endl;
522 Output() <<
" " <<
mPrefix <<
"systime_ton(IN:=false, PT:=TIME#2h);" << std::endl;
523 Output() <<
" " <<
mPrefix <<
"systime_ton(IN:=true, PT:=TIME#2h);" << std::endl;
524 Output() <<
" " <<
mPrefix <<
"systime_recent := TIME#0ms;" << std::endl;
525 Output() <<
"END_IF;" << std::endl;
548 Output() <<
"(* " << text <<
" *)";
557 if((ltype !=
mIntegerType) && (ltype !=
mWordType) && (ltype !=
"BOOL") && (ltype !=
"STRING") && (ltype !=
"TIME") && (ltype !=
"TON"))
558 FCG_ERR(
"Iec61131stCodeGenerator::VariableDeclare(): unsupported type [" << ltype <<
"]");
559 Output() << laddr <<
" : " << ltype <<
";";
564 if((ltype !=
mIntegerType) && (ltype !=
mWordType) && (ltype !=
"BOOL") && (ltype !=
"STRING") && (ltype !=
"TIME"))
565 FCG_ERR(
"Iec61131stCodeGenerator::VariableDeclare(): unsupported type [" << ltype <<
"]");
566 Output() << laddr <<
" : " << ltype <<
" := " << lval <<
";";
574 if(address==
"reset") res=
"RESET";
575 if(address==
"status") res=
"STATUS";
577 if(address==
"recent_event") res=
"RECENT_EVENT";
578 if(address.find(
"pending_events")==0)
579 if(address!=
"pending_events_t")
580 res=
"PENDING_EVENTS"+address.substr(14);
581 if(address.find(
"enabled_events")==0)
582 if(address!=
"enabled_events_t")
583 res=
"ENABLED_EVENTS"+address.substr(14);
586 if(address.find(
"parallel_state")==0)
587 if(address!=
"parallel_state_t")
588 res=
"PARALLEL_STATE"+address.substr(14);
591 if(res==
"") res=
mPrefix+address;
644 return AX(
"SHL( IN:=" +
WordConstant(1) +
" , N:=" + expression +
" )" );
654 std::string res(ToStringInteger(val));
658 FCG_ERR(
"Iec61131stCodeGenerator: unsupported integer data type");
801 std::stringstream sstr;
802 sstr <<
mWordType <<
"#16#" << std::setbase(16) << std::setfill(
'0');
803 if(
mWordType ==
"BYTE") sstr << std::setw(2) << (val & 0xff);
804 else if(
mWordType ==
"WORD") sstr << std::setw(4) << (val & 0xffff);
805 else if(
mWordType ==
"DWORD") sstr << std::setw(8) << (val & 0xffffffff);
806 else if(
mWordType ==
"LWORD") sstr << std::setw(16) << (val & 0xffffffffffffffff);
807 else FCG_ERR(
"Iec61131stCodeGenerator: unsupported word data type");
821 if(val) valstr=
"true";
else valstr=
"false";
828 if(val) valstr=
"true";
else valstr=
"false";
852 std::stringstream strstr;
854 if(val.size()<25) newline=25;
858 if(vit==val.size())
break;
861 if(vit==val.size())
break;
865 strstr << std::endl <<
" ";
870 return AX(strstr.str());
876 FCG_ERR(
"Iec61131stCodeGenerator::Cintarray(): ignoring empty const vector");
880 FCG_ERR(
"Iec61131stCodeGenerator::Cwordarray(): const vector exceeds address range");
895 return AA(address +
"[" + ToStringInteger(index) +
"]");
911 std::stringstream strstr;
913 if(val.size()<11) newline=15;
917 if(vit==val.size())
break;
920 if(vit==val.size())
break;
924 strstr << std::endl <<
" ";
929 return AX(strstr.str());
935 FCG_ERR(
"Iec61131stCodeGenerator::Cwordarray(): ignoring empty const vector");
939 FCG_ERR(
"Iec61131stCodeGenerator::Cwordarray(): const vector exceeds addres range");
954 return AA(address +
"[" + ToStringInteger(index) +
"]");
971 for(std::size_t i=0; i<val.length(); ++i) {
976 if(c==
'\'') { res.append(
"$'");
continue; }
978 if(c==
'$') { res.append(
"$$");
continue; }
980 if((c>=0x20) && (c<0x7f)) { res.append(1,c);
continue; };
982 FCG_ERR(
"EmbeddedcCodeGenerator: non-printable ascii or other encoding unsupported [" << val <<
"]");
990 std::stringstream strstr;
997 strstr <<
"[ " << std::endl;
1001 if(vit==val.size())
break;
1004 if(vit==val.size())
break;
1008 strstr << std::endl;
1013 return AX(strstr.str());
1020 FCG_ERR(
"Iec61131stCodeGenerator::Cstrarray(): ignoring empty const vector");
1024 FCG_ERR(
"Iec61131stCodeGenerator::Cstrarray(): const vector exceeds addres range");
1029 for(
size_t i=0; i<val.size(); ++i)
1030 if(val[i].size()>len) len=val[i].size();
1032 Output() <<
TargetAddress(address) <<
" : ARRAY[" << offset <<
".." << val.size()+offset-1 <<
"] OF STRING[" << ToStringInteger(len) <<
"] := ";
1043 return AA(address +
"[" + ToStringInteger(index) +
"]");
1059 FCG_ERR(
"Iec61131stCodeGenerator::Intarray(): ignoring empty const vector");
1063 FCG_ERR(
"Iec61131stCodeGenerator::Intarray(): const vector exceeds addres range");
1079 FCG_ERR(
"Iec61131stCodeGenerator::Intarray(): ignoring empty const vector");
1083 FCG_ERR(
"Iec61131stCodeGenerator::Intarray(): const vector exceeds addres range");
1092 return AA(address +
"[" + ToStringInteger(index) +
"]");
1109 FCG_ERR(
"Iec61131stCodeGenerator::Wordarray(): ignoring empty const vector");
1113 FCG_ERR(
"Iec61131stCodeGenerator::Wordarray(): const vector exceeds addres range");
1129 FCG_ERR(
"Iec61131stCodeGenerator::Wordarray(): ignoring empty const vector");
1133 FCG_ERR(
"Iec61131stCodeGenerator::Wordarray(): const vector exceeds addres range");
1142 return AA(address +
"[" + ToStringInteger(index) +
"]");
1167 Output() <<
"IF " << expression <<
" THEN";
1174 Output() <<
"IF NOT " << expression <<
" THEN";
1197 Output() <<
"ELSIF " << expression <<
" THEN";
1227 FCG_VERB0(
"CodeGenerator: WARNING: inconsistent empty range of switch-cases");
1246 FCG_VERB0(
"CodeGenerator: WARNING: inconsistent empty range of switch-cases");
1251 int from=*vals.begin();
1252 int to= *(--vals.end());
1253 if(to+1-from== (
int) vals.size()) {
1258 std::set< int >::const_iterator vit=vals.begin();
1259 for(; vit!=vals.end(); ++ vit) {
1260 if(vit!=vals.begin())
Output() <<
", ";
1286 Output() <<
"WHILE true DO";
1293 Output() <<
"IF " << expression <<
" THEN EXIT; END_IF;";
1300 Output() <<
"END_WHILE;";
1336 std::string res(
"TIME#" + ToStringInteger(val) +
"ms");
1343 Output() << address <<
" := true;" ;
1347 Output() << address <<
" := false;" ;
1351 Output() << expression <<
";";
1355Iec61131stCodeGenerator::IECVariableType Iec61131stCodeGenerator::CurrentVariableType(
void) {
1356 return mCurrentVariableType;
1359void Iec61131stCodeGenerator::CurrentVariableType(
const IECVariableType & type) {
1360 mCurrentVariableType = type;
#define FAUDES_REGISTERCODEGENERATOR(ftype, ctype)
Class registration macro.
Code-generator for target IEC 61131-3 ST.
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)
LineIterator LinesEnd()
Access to line records by iterator.
std::map< std::string, ActionAddress >::iterator ActionAddressIterator
Access to action record by iterator.
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
LineIterator LinesBegin()
Access to line records by iterator.
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.
std::map< std::string, LineAddress >::iterator LineIterator
Access to line records by iterator.
static std::string VersionString(void)
Version (refers to macro COMPILEDES_VERSION, defined in cgp_codegenerator.h)
Idx Size(void) const
Number of generators.
virtual void IndentDec()
Indentation (convenience support for derived classes)
ActionAddressIterator ActionAddressesEnd()
Access to action addresses by iterator.
ActionAddressIterator ActionAddressesBegin()
Access to action addresses by iterator.
unsigned long word_t
Code-generator internal data type of target words.
Abstract address; see also Absstract_Addresses.
Abstract expression; see also Absstract_Addresses.
Execution semantics in terms of code primitives.
virtual void DeclareTimers(void)
Use target implementation to declare timers, typically "timer_run_*" and "timer_cnt_*".
bool mBitAddressArithmetic
code option: compute bit and word address on target
std::string mStateUpdateHook
code option: state change hook
virtual void DeclareSmallCarray(void)
Declare bit-mask loop-ups.
virtual void DoGenerateResetCode(void)
cut-and-paste template for code snippet assembly
bool mArrayForState
code option: use int arrays to represent that overall state
virtual void DeclareReset(void)
Declare "reset".
virtual void LiteralAppend(void)
Cosmetic: append literally from configuration.
virtual void DeclareStatus(void)
Declare "status".
virtual void DeclareRecentEvent(void)
Declare "recent_event".
virtual void Comment(const std::string &text)
Target comments (see EmbeddedcCodeGenerator for consistent reimplementation pattern)
virtual void DeclareAux(void)
Declare variables local to the provided snippets, e.g. helpers for bit-mask computation.
bool mEventNameLookup
code option: event name lookup
virtual void DeclareEventNameLookup(void)
Declare symbolic name lookup tables.
std::map< std::string, bitarray_rec > mBitarrays
Record of all declared bit-arrays.
bool mStateNameLookup
code option: state name lookup
virtual void DoReadTargetConfiguration(TokenReader &rTr)
re-implement token i/o for extra configuration
virtual void DeclareParallelState(void)
Declare "parallel_state".
std::string mIntegerType
target data type for integer
virtual void DeclareLoopState(void)
Declare loop state, i.e. line levels, loop flag.
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
virtual void DeclareLargeCarray(void)
Declare compiled transition relations.
virtual void ResetState(void)
Reset state.
bool mArrayForBitmasks
code option: use const array to represent bit-masks
virtual void DeclareStateNameLookup(void)
Declare symbolic name lookup tables.
virtual void DoCompile(void)
virtual hook to extend compiled data
virtual void LiteralPrepend(void)
Cosmetic: prepend literally from configuration data.
std::vector< bool > mHasStateNames
record per generator whether there is a lookup table
virtual void DeclarePendingEvents(void)
Declare "pending_events" and "enabled_events".
std::string mPrefix
universal prefix (pseudo name space)
std::string mEventExecutionHook
code option: event exec hook
Implementation of primitives by IEC 61131 ST.
virtual void WordNand(const AA &address, const AX &expression)
generate code: conditionals
virtual AX IntegerIsEq(const AA &address, int val)
generate code: conditionals
virtual void DoReadTargetConfiguration(TokenReader &rTr)
File i/o.
virtual void RunActionSet(const std::string &address)
generate code: conditionals
virtual void IfElseIfTrue(const AX &expression)
generate code: conditionals
virtual void DoWriteTargetConfiguration(TokenWriter &rTw) const
File i/o.
virtual AX IntegerIsLess(const AA &address, int val)
generate code: conditionals
virtual void DeclareImportPhysicalIo(void)
generate code: conditionals
virtual void UpdateSystime(void)
generate code: conditionals
virtual AX BooleanIsNotEq(const AA &op1, const AA &op2)
generate code: conditionals
virtual void CintarrayDeclare(const AA &address, int offset, const std::vector< int > &val)
generate code: conditionals
virtual void IfFalse(const AX &expression)
generate code: conditionals
virtual bool HasCintarray(void)
generate code: conditionals
virtual void WordDeclare(const AA &address)
generate code: conditionals
virtual bool HasWordarray(void)
generate code: conditionals
virtual void IfTrue(const AX &expression)
generate code: conditionals
virtual void BooleanDeclare(const AA &address)
generate code: conditionals
virtual ~Iec61131stCodeGenerator(void)
Explicit destructor.
virtual AX BooleanIsEq(const AA &op1, const AA &op2)
generate code: conditionals
virtual void BooleanAssign(const AA &address, int val)
generate code: conditionals
virtual void IfWord(const AX &expression)
generate code: conditionals
virtual AX WordIsEq(const AA &address, word_t val)
generate code: conditionals
virtual void InsertExecHooks(void)
generate code: conditionals
virtual void TimerDeclare(const AA &address, const std::string &val)
generate code: conditionals
void DoGenerate(void)
code generation hook (overall)
virtual void Clear(void)
Clear all data.
virtual void SwitchEnd(void)
generate code: conditionals
virtual void LoopEnd(void)
generate code: conditionals
virtual AX WordarrayConstant(const std::vector< word_t > &val)
generate code: conditionals
virtual AX StrarrayConstant(const std::vector< std::string > &val)
generate code: conditionals
virtual void TimerStart(const AA &address)
generate code: conditionals
virtual void WordAssign(const AA &address, word_t val)
generate code: conditionals
virtual AA CstrarrayAccess(const AA &address, int index)
generate code: conditionals
virtual void DeclareSystime(void)
generate code: conditionals
virtual AX WordIsNotEq(const AA &address, word_t val)
generate code: conditionals
virtual void WordarrayDeclare(const AA &address, int offset, int len)
generate code: conditionals
virtual AX StringConstant(const std::string &val)
generate code: conditionals
virtual void Comment(const std::string &text)
generate code: conditionals
virtual void TimerReset(const AA &address, const std::string &val)
generate code: conditionals
virtual AX IntegerConstant(int val)
generate code: conditionals
virtual void DecrementTimers(void)
code snippet
virtual AX IntegerRemainder(const AX &expression, int val)
generate code: conditionals
std::string mLiteralCyclic
option: extra cyclic code
virtual void IfEnd(void)
generate code: conditionals
virtual bool HasIntarray(void)
generate code: conditionals
virtual AA CintarrayAccess(const AA &address, int index)
generate code: conditionals
void DoCompile(void)
add my preferences to DoCompile
virtual void DeclareImportSymbolicIo(void)
generate code: conditionals
virtual AX IntarrayConstant(const std::vector< int > &val)
generate code: conditionals
virtual AX WordIsMaskSet(const AA &address, word_t mask)
generate code: conditionals
virtual std::string TargetAddress(const AA &address)
abstract address conversion
virtual bool HasCwordarray(void)
generate code: conditionals
virtual int CountImportPhysicalIo(void)
generate code: conditionals
virtual AX IntegerIsGreater(const AA &address, int val)
generate code: conditionals
virtual void RunActionClr(const std::string &address)
generate code: conditionals
virtual AX TimeConstant(int val)
generate code: conditionals
virtual AX WordIsBitSet(const AA &address, int idx)
generate code: conditionals
virtual bool HasIntmaths(void)
generate code: conditionals
virtual AA WordarrayAccess(const AA &address, int index)
generate code: conditionals
virtual void DoGenerateLookups(void)
code generation hook (lookup functions)
virtual AX TimerIsElapsed(const AA &address)
generate code: conditionals
virtual void LoopBegin(void)
generate code: conditionals
virtual void WordOr(const AA &address, word_t val)
generate code: conditionals
virtual void ResetState(void)
generate code: conditionals
virtual void SwitchBegin(const AA &address)
generate code: conditionals
virtual void RunActionExe(const AX &expression)
generate code: conditionals
virtual void CstrarrayDeclare(const AA &address, int offset, const std::vector< std::string > &val)
generate code: conditionals
virtual AX WordIsBitClr(const AA &address, int idx)
generate code: conditionals
virtual void LoopBreak(const AX &expression)
generate code: conditionals
virtual void SwitchBreak(void)
generate code: conditionals
virtual AA IntarrayAccess(const AA &address, int index)
generate code: conditionals
virtual AX IntegerIsNotEq(const AA &address, int val)
generate code: conditionals
virtual void IntegerAssign(const AA &address, int val)
generate code: conditionals
virtual void IfElse(void)
generate code: conditionals
virtual void WordAnd(const AA &address, word_t val)
generate code: conditionals
virtual void IntegerDeclare(const AA &address)
generate code: conditionals
virtual void SwitchCases(const AA &address, int from, int to)
generate code: conditionals
virtual void DeclareTimers(void)
generate code: conditionals
bool mHasIecTimeOperators
option: overloaded operators for time maths
virtual void VariableDeclare(const std::string &laddr, const std::string <ype)
generate code: conditionals
virtual AX IntegerBitmask(const AX &expression)
generate code: conditionals
virtual void IntegerIncrement(const AA &address, int val)
generate code: conditionals
Iec61131stCodeGenerator(void)
Constructor.
virtual bool HasMultiCase(void)
generate code: conditionals
std::string mIecDeclareSymbolic
option: formal declaration of io variables
virtual void CwordarrayDeclare(const AA &address, int offset, const std::vector< word_t > &val)
generate code: conditionals
virtual AX WordConstant(word_t val)
generate code: conditionals
virtual bool HasCstrarray(void)
generate code: conditionals
virtual AA CwordarrayAccess(const AA &address, int index)
generate code: conditionals
virtual void IntarrayDeclare(const AA &address, int offset, int len)
generate code: conditionals
virtual void SwitchCase(const AA &address, int val)
generate code: conditionals
virtual void DoGenerateFunction(void)
code generation hook (function block)
virtual void TimerStop(const AA &address)
generate code: conditionals
virtual int CountImportSymbolicIo(void)
generate code: conditionals
virtual void FunctionReturn(void)
generate code: conditionals
virtual AX TargetExpression(const AA &address)
abstract address conversion
std::string mIecDeclarePhysical
option: formal declaration of io lines
virtual AX IntegerQuotient(const AX &expression, int val)
generate code: conditionals
virtual void LiteralCyclic(void)
generate code: conditionals