diff -r e08c65e27557 -r 873a5b60a7ea stage4/generate_cc/plciec.h --- a/stage4/generate_cc/plciec.h Wed Jul 11 09:53:27 2007 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,776 +0,0 @@ -/* - * (c) 2003 Mario de Sousa - * - * Offered to the public under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * This code is made available on the understanding that it will not be - * used in safety-critical situations without a full and competent review. - */ - -/* - * An IEC 61131-3 IL and ST compiler. - * - * Based on the - * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) - * - */ - - -/* - * Code to be included into the code generated by the 4th stage. - * - * This is part of the 4th stage that generates - * a c++ source program equivalent to the IL and ST - * code. - */ - - -#ifndef __PLCIEC_H -#define __PLCIEC_H - -//#include -#include "plc.h" -#include -#include - - - -/* function that generates an IEC runtime error */ -void IEC_error(void) { - /* TODO... */ - fprintf(stderr, "IEC 61131-3 runtime error.\n"); - exit(1); -} - - - -typedef bool BOOL; -#define TRUE true -#define FALSE false - -typedef i8 SINT; -typedef i16 INT; -typedef i32 DINT; -typedef i64 LINT; - -typedef u8 USINT; -typedef u16 UINT; -typedef u32 UDINT; -typedef u64 ULINT; - -typedef u8 BYTE; -typedef u16 WORD; -typedef u32 DWORD; -typedef u64 LWORD; - -typedef f32 REAL; -typedef f64 LREAL; - - - - - - -/*********************************************/ -/* TIME AND DATE data trypes */ -/*********************************************/ - -/* NOTE: All the time and date data types use a struct timespec - * internally to store the time and date. This is so as to ease all the - * operations (add, subtract, multiply and division) the standard defines - * on these same data types. - * However, in order to ease the implementation of the comparison operators - * (==, =>, <=, <, >, <>), the two elements in the timespec structure - * must be handled in such a way as to guarantee the following: - * - The stored time is always the result of the operation tv_sec + tv_nsec*1e-9 - * - tv_sec and tv_nsec will always have the same sign - * (i.e. either both positive or both negative) - * - tv_nsec always holds a value in the range ]-1, +1[ seconds. - * (note that -1 and +1 are excluded form the range) - */ - - -/* NOTE: According to the C++ standard, the result of the % and / operations is implementation dependent - * when the at least one of the operands is negative! However, whatever the result of the operations, we are - * guaranteed that (a/b)*b + (a%b) is always equal to a. - * This means that, even knowing that both tv_sec and tv_sec always have the same sign (we make it so this is true), - * we must still re-normailze the result for both the addition and subtraction operations! - */ - -static inline void __normalizesign_timespec (struct timespec *ts) { - if ((ts->tv_sec > 0) && (ts->tv_nsec < 0)) { - ts->tv_sec--; - ts->tv_nsec += 1000000000; - } - if ((ts->tv_sec < 0) && (ts->tv_nsec > 0)) { - ts->tv_sec++; - ts->tv_nsec -= 1000000000; - } -} - - -static inline struct timespec __add_timespec (const struct timespec &t1, const struct timespec &t2) { - /* NOTE the following sum works correctly because a long can hold a litle more than 2 seconds expressed in nano seconds! */ - long nsec; - nsec = t1.tv_nsec + t2.tv_nsec; - struct timespec ts; - ts.tv_sec = t1.tv_sec + t2.tv_sec + (nsec / 1000000000); - ts.tv_nsec = nsec % 1000000000; - - __normalizesign_timespec(&ts); - -return ts; -} - - -static inline struct timespec __sub_timespec (const struct timespec &t1, const struct timespec &t2) { - /* NOTE the following subtraction works correctly because a long can hold a litle more than 2 seconds expressed in nano seconds! */ - long nsec = t1.tv_nsec - t2.tv_nsec; - struct timespec ts; - ts.tv_sec = t1.tv_sec - t2.tv_sec + nsec / 1000000000; - ts.tv_nsec = nsec % 1000000000; - - __normalizesign_timespec(&ts); - - return ts; -} - - -static inline struct timespec __mul_timespec (const struct timespec &t1, const long double value) { -#if 0 - /* A simple implementation that risks reducing the precision of the TIME value */ - long double sec_d1 = t1.tv_nsec / (long double)1e9 * value; - long double sec_d2 = t1.tv_sec * value; - long int sec = (long int)truncl(sec_d1 + sec_d2); - struct timespec ts; - ts.tv_sec = sec; - ts.tv_nsec = (long int)((sec_d1 + sec_d2 - sec)*1e9); - return ts; -#else - /* A more robust implementation that reduces the loss of precision of the TIME value */ - /* NOTE: The following assumes that the value stored in tv_nsec is never larger than 1 sec - * and is also based on the fact that tv_nsec can safely store slighlty more thanb 2 sec. - */ - long double sec_d1 = t1.tv_nsec / (long double)1e9 * value; - long double sec_d2 = t1.tv_sec * value; - long int sec1 = (long int)sec_d1; - long int sec2 = (long int)sec_d2; - struct timespec ts; - ts.tv_sec = sec1 + sec2; - ts.tv_nsec = (long int)(((sec_d1 - sec1) + (sec_d2 - sec2))*1e9); - /* re-normalize the value of tv_nsec */ - /* i.e. guarantee that it falls in the range ]-1, +1[ seconds. */ - if (ts.tv_nsec >= 1000000000) {ts.tv_nsec -= 1000000000; ts.tv_sec += 1;} - if (ts.tv_nsec <= -1000000000) {ts.tv_nsec += 1000000000; ts.tv_sec -= 1;} - /* We don't need to re-normalize the sign, since we are guaranteed that tv_sec and tv_nsec - * will still both have the same sign after being multiplied by the same value. - */ - return ts; -#endif -} - -/* Helper Macro for the comparison operators... */ -#define __compare_timespec(CMP, t1, t2) ((t1.tv_sec == t2.tv_sec)? t1.tv_nsec CMP t2.tv_nsec : t1.tv_sec CMP t2.tv_sec) - - - -/* Some necessary forward declarations... */ -/* -class TIME; -class TOD; -class DT; -class DATE; - -typedef struct timespec __timebase_t; -*/ - -typedef struct TIME timespec; -typedef struct TOD timespec; -typedef struct DT timespec; -typedef struct DATE timespec; - -static inline struct timespec __time_to_timespec(int sign, double mseconds, double seconds, double minutes, double hours, double days) { - struct timespec ts; - - /* sign is 1 for positive values, -1 for negative time... */ - long double total_sec = ((days*24 + hours)*60 + minutes)*60 + seconds + mseconds/1e3; - if (sign >= 0) sign = 1; else sign = -1; - ts.tv_sec = sign * (long int)total_sec; - ts.tv_nsec = sign * (long int)((total_sec - ts.tv_sec)*1e9); - - return ts; -} - - -static inline struct timespec __tod_to_timespec(double seconds, double minutes, double hours) { - struct timespec ts; - - long double total_sec = (hours*60 + minutes)*60 + seconds; - ts.tv_sec = (long int)total_sec; - ts.tv_nsec = (long int)((total_sec - ts.tv_sec)*1e9); - - return ts; -} - -static inline struct timespec __date_to_timespec(int day, int month, int year) { - struct timespec ts; - struct tm broken_down_time; - - broken_down_time.tm_sec = 0; - broken_down_time.tm_min = 0; - broken_down_time.tm_hour = 0; - broken_down_time.tm_mday = day; /* day of month, from 1 to 31 */ - broken_down_time.tm_mon = month - 1; /* month since January, in the range 0 to 11 */ - broken_down_time.tm_year = year - 1900; /* number of years since 1900 */ - - time_t epoch_seconds = mktime(&broken_down_time); /* determine number of seconds since the epoch, i.e. Jan 1st 1970 */ - - if ((time_t)(-1) == epoch_seconds) - IEC_error(); - - ts.tv_sec = epoch_seconds; - ts.tv_nsec = 0; - - return ts; -} - -static inline struct timespec __dt_to_timespec(double seconds, double minutes, double hours, int day, int month, int year) { - struct timespec ts; - - long double total_sec = (hours*60 + minutes)*60 + seconds; - ts.tv_sec = (long int)total_sec; - ts.tv_nsec = (long int)((total_sec - ts.tv_sec)*1e9); - - struct tm broken_down_time; - broken_down_time.tm_sec = 0; - broken_down_time.tm_min = 0; - broken_down_time.tm_hour = 0; - broken_down_time.tm_mday = day; /* day of month, from 1 to 31 */ - broken_down_time.tm_mon = month - 1; /* month since January, in the range 0 to 11 */ - broken_down_time.tm_year = year - 1900; /* number of years since 1900 */ - - time_t epoch_seconds = mktime(&broken_down_time); /* determine number of seconds since the epoch, i.e. Jan 1st 1970 */ - if ((time_t)(-1) == epoch_seconds) - IEC_error(); - - ts.tv_sec += epoch_seconds; - if (ts.tv_sec < epoch_seconds) - /* since the TOD is always positive, if the above happens then we had an overflow */ - IEC_error(); - - return ts; -} - - - - - - - - -#ifdef 0 -class TIME{ - private: - /* private variable that contains the value of time. */ - /* NOTE: The stored value is _always_ (time.tv_sec + time.tv_nsec), - no matter whether tv_sec is positive or negative, or tv_nsec is positive or negative. - */ - __timebase_t time; - - public: - /* conversion to __timebase_t */ - operator __timebase_t(void) {return time;} - - /* constructors... */ - TIME (void) {time.tv_sec = 0; time.tv_nsec = 0;} - TIME (__timebase_t time) {this->time = time;} - TIME (const TIME &time) {this->time = time.time;} /* copy constructor */ - TIME(int sign, double mseconds, double seconds=0, double minutes=0, double hours=0, double days=0) { - /* sign is 1 for positive values, -1 for negative time... */ - long double total_sec = ((days*24 + hours)*60 + minutes)*60 + seconds + mseconds/1e3; - if (sign >= 0) sign = 1; else sign = -1; - time.tv_sec = sign * (long int)total_sec; - time.tv_nsec = sign * (long int)((total_sec - time.tv_sec)*1e9); - } - - /* used in plciec.cc to set the value of the __CURRENT_TIME variable without having to call a - * TIME((__timebase_t time) constructor followed by the copy constructor. - */ - void operator= (__timebase_t time) {this->time = time;} - - /* Arithmetic operators (section 2.5.1.5.6. of version 2 of the IEC 61131-3 standard) */ - TIME operator+ (const TIME &time) {return TIME(__add_timespec(this->time, time.time));} - TIME operator- (const TIME &time) {return TIME(__sub_timespec(this->time, time.time));} - - friend TOD operator+ (const TIME &time, const TOD &tod); - friend TOD operator+ (const TOD &tod, const TIME &time); - friend TOD operator- (const TOD &tod, const TIME &time); - - friend DT operator+ (const TIME &time, const DT &dt); - friend DT operator+ (const DT &dt, const TIME &time); - friend DT operator- (const DT &dt, const TIME &time); - - friend TIME operator* (const TIME &time, const long double value); - friend TIME operator* (const long double value, const TIME &time); - friend TIME operator/ (const TIME &time, const long double value); - - /* Comparison operators (section 2.5.1.5.4. of version 2 of the IEC 61131-3 standard) */ - BOOL operator> (const TIME &time) {return __compare_timespec(>, this->time, time.time);} - BOOL operator>= (const TIME &time) {return __compare_timespec(>=, this->time, time.time);} - BOOL operator< (const TIME &time) {return __compare_timespec(<, this->time, time.time);} - BOOL operator<= (const TIME &time) {return __compare_timespec(<=, this->time, time.time);} - BOOL operator== (const TIME &time) {return __compare_timespec(==, this->time, time.time);} - BOOL operator!= (const TIME &time) {return !__compare_timespec(==, this->time, time.time);} -}; - - - -/* Time of Day */ -class TOD { - private: - __timebase_t time; - - public: - /* conversion to __timebase_t */ - operator __timebase_t(void) {return time;} - - /* constructors... */ - TOD (void) {time.tv_sec = 0; time.tv_nsec = 0;} - TOD (__timebase_t time) {this->time = time;} - TOD (const TOD &tod) {this->time = tod.time;} /* copy constructor */ - TOD (double seconds, double minutes=0, double hours=0) { - long double total_sec = (hours*60 + minutes)*60 + seconds; - time.tv_sec = (long int)total_sec; - time.tv_nsec = (long int)((total_sec - time.tv_sec)*1e9); - } - - /* Arithmetic operators (section 2.5.1.5.6. of version 2 of the IEC 61131-3 standard) */ - TIME operator- (const TOD &tod) {return TIME(__sub_timespec(this->time, tod.time));} - - friend TOD operator+ (const TIME &time, const TOD &tod); - friend TOD operator+ (const TOD &tod, const TIME &time); - friend TOD operator- (const TOD &tod, const TIME &time); - - /* The following operation is not in the standard, - * but will ease the implementation of the default function CONCAT_DATE_TOD - */ - friend DT operator+ (const DATE &date, const TOD &tod); - friend DT operator+ (const TOD &tod, const DATE &date); - - /* Comparison operators (section 2.5.1.5.4. of version 2 of the IEC 61131-3 standard) */ - BOOL operator> (const TOD &tod) {return __compare_timespec(>, this->time, tod.time);} - BOOL operator>= (const TOD &tod) {return __compare_timespec(>=, this->time, tod.time);} - BOOL operator< (const TOD &tod) {return __compare_timespec(<, this->time, tod.time);} - BOOL operator<= (const TOD &tod) {return __compare_timespec(<=, this->time, tod.time);} - BOOL operator== (const TOD &tod) {return __compare_timespec(==, this->time, tod.time);} - BOOL operator!= (const TOD &tod) {return !__compare_timespec(==, this->time, tod.time);} -}; - - - -//typedef DATE; -class DATE { - private: - __timebase_t time; - - public: - /* conversion to __timebase_t */ - operator __timebase_t(void) {return time;} - - /* constructors... */ - DATE (void) {time.tv_sec = 0; time.tv_nsec = 0;} - DATE (__timebase_t time) {this->time = time;} - DATE (const DATE &date) {this->time = date.time;} /* copy constructor */ - DATE (int day, int month, int year) { - struct tm broken_down_time; - - broken_down_time.tm_sec = 0; - broken_down_time.tm_min = 0; - broken_down_time.tm_hour = 0; - broken_down_time.tm_mday = day; /* day of month, from 1 to 31 */ - broken_down_time.tm_mon = month - 1; /* month since January, in the range 0 to 11 */ - broken_down_time.tm_year = year - 1900; /* number of years since 1900 */ - - time_t epoch_seconds = mktime(&broken_down_time); /* determine number of seconds since the epoch, i.e. Jan 1st 1970 */ - - if ((time_t)(-1) == epoch_seconds) - IEC_error(); - - time.tv_sec = epoch_seconds; - time.tv_nsec = 0; - } - - /* Arithmetic operators (section 2.5.1.5.6. of version 2 of the IEC 61131-3 standard) */ - TIME operator- (const DATE &date) {return TIME(__sub_timespec(this->time, date.time));} - /* The following operation is not in the standard, - * but will ease the implementation of the default function CONCAT_DATE_TOD - */ - friend DT operator+ (const DATE &date, const TOD &tod); - friend DT operator+ (const TOD &tod, const DATE &date); - - /* Comparison operators (section 2.5.1.5.4. of version 2 of the IEC 61131-3 standard) */ - BOOL operator> (const DATE &date) {return __compare_timespec(>, this->time, date.time);} - BOOL operator>= (const DATE &date) {return __compare_timespec(>=, this->time, date.time);} - BOOL operator< (const DATE &date) {return __compare_timespec(<, this->time, date.time);} - BOOL operator<= (const DATE &date) {return __compare_timespec(<=, this->time, date.time);} - BOOL operator== (const DATE &date) {return __compare_timespec(==, this->time, date.time);} - BOOL operator!= (const DATE &date) {return !__compare_timespec(==, this->time, date.time);} -}; - - - - - -class DT { - private: - __timebase_t time; - - public: - /* conversion to __timebase_t */ - operator __timebase_t(void) {return time;} - - /* constructors... */ - DT (void) {time.tv_sec = 0; time.tv_nsec = 0;} - DT (__timebase_t time) {this->time = time;} - DT (const DT &dt) {this->time = dt.time;} /* copy constructor */ - DT (double seconds, double minutes, double hours, int day, int month, int year) { - long double total_sec = (hours*60 + minutes)*60 + seconds; - time.tv_sec = (long int)total_sec; - time.tv_nsec = (long int)((total_sec - time.tv_sec)*1e9); - - struct tm broken_down_time; - broken_down_time.tm_sec = 0; - broken_down_time.tm_min = 0; - broken_down_time.tm_hour = 0; - broken_down_time.tm_mday = day; /* day of month, from 1 to 31 */ - broken_down_time.tm_mon = month - 1; /* month since January, in the range 0 to 11 */ - broken_down_time.tm_year = year - 1900; /* number of years since 1900 */ - - time_t epoch_seconds = mktime(&broken_down_time); /* determine number of seconds since the epoch, i.e. Jan 1st 1970 */ - if ((time_t)(-1) == epoch_seconds) - IEC_error(); - - time.tv_sec += epoch_seconds; - if (time.tv_sec < epoch_seconds) - /* since the TOD is always positive, if the above happens then we had an overflow */ - IEC_error(); - } - - /* Helpers to conversion operators (section 2.5.1.5.6. of version 2 of the IEC 61131-3 standard) */ - DATE __to_DATE(void) { -#if 0 - /* slow version */ - struct tm broken_down_time; - time_t seconds = time.tv_sec; - if (NULL == gmtime_r(seconds, &broken_down_time)) /* get the UTC (GMT) broken down time */ - IEC_error(); - return DATE(broken_down_time.tm_mday, broken_down_time.tm_mon, broken_down_time.tm_year); -#else - /* Faster version, based on the fact that the date will always be a multiple of 60*60*24 seconds, - * and that the value of tv_nsec falls in the range ]-1, +1[ - */ - /* The above is true since the Unix function mktime() seems to ignore all leap seconds! */ - struct timespec date_time = {time.tv_sec - (time.tv_sec % (24*60*60)), 0}; - return DATE(date_time); -#endif - } - - TOD __to_TOD(void) { -#if 0 - /* slow version */ - struct tm broken_down_time; - time_t seconds = time.tv_sec; - if (NULL == gmtime_r(seconds, &broken_down_time)) /* get the UTC (GMT) broken down time */ - IEC_error(); - return TOD(broken_down_time.tm_sec, broken_down_time.tm_min, broken_down_time.tm_hour); -#else - /* Faster version, based on the fact that the date will always be a multiple of 60*60*24 seconds - * and that the value of tv_nsec falls in the range ]-1, +1[ - */ - /* The above is true since the Unix function mktime() seems to ignore all leap seconds! */ - struct timespec time_time = {time.tv_sec % (24*60*60), time.tv_nsec}; - return TOD(time_time); -#endif - } - - /* Arithmetic operators (section 2.5.1.5.6. of version 2 of the IEC 61131-3 standard) */ - TIME operator- (const DT &dt) {return TIME(__sub_timespec(this->time, dt.time));} - - friend DT operator+ (const TIME &time, const DT &dt); - friend DT operator+ (const DT &dt, const TIME &time); - friend DT operator- (const DT &dt, const TIME &time); - - /* Comparison operators (section 2.5.1.5.4. of version 2 of the IEC 61131-3 standard) */ - BOOL operator> (const DT &dt) {return __compare_timespec(>, this->time, dt.time);} - BOOL operator>= (const DT &dt) {return __compare_timespec(>=, this->time, dt.time);} - BOOL operator< (const DT &dt) {return __compare_timespec(<, this->time, dt.time);} - BOOL operator<= (const DT &dt) {return __compare_timespec(<=, this->time, dt.time);} - BOOL operator== (const DT &dt) {return __compare_timespec(==, this->time, dt.time);} - BOOL operator!= (const DT &dt) {return !__compare_timespec(==, this->time, dt.time);} -}; - - -/* The operations on time and data types... */ -TOD operator+ (const TIME &time, const TOD &tod) {return TOD(__add_timespec(tod.time, time.time));}; -TOD operator+ (const TOD &tod, const TIME &time) {return TOD(__add_timespec(tod.time, time.time));}; -TOD operator- (const TOD &tod, const TIME &time) {return TOD(__sub_timespec(tod.time, time.time));}; - -DT operator+ (const TIME &time, const DT &dt) {return DT(__add_timespec(dt.time, time.time));}; -DT operator+ (const DT &dt, const TIME &time) {return DT(__add_timespec(dt.time, time.time));}; -DT operator- (const DT &dt, const TIME &time) {return DT(__sub_timespec(dt.time, time.time));}; - -TIME operator* (const TIME &time, const long double value) {return TIME(__mul_timespec(time.time, value));} -TIME operator* (const long double value, const TIME &time) {return TIME(__mul_timespec(time.time, value));} -TIME operator/ (const TIME &time, const long double value) {return TIME(__mul_timespec(time.time, 1.0/value));} - -/* The following operation is not in the standard, - * but will ease the implementation of the default function CONCAT_DATE_TOD - */ -DT operator+ (const DATE &date, const TOD &tod) {return DT(__add_timespec(date.time, tod.time));}; -DT operator+ (const TOD &tod, const DATE &date) {return DT(__add_timespec(date.time, tod.time));}; - -#endif - -/* global variable that will be used to implement the timers TON, TOFF and TP */ -extern TIME __CURRENT_TIME; - - - -//typedef STRING; -//typedef WSTRING; - - - -typedef union __IL_DEFVAR_T { - BOOL BOOLvar; - - SINT SINTvar; - INT INTvar; - DINT DINTvar; - LINT LINTvar; - - USINT USINTvar; - UINT UINTvar; - UDINT UDINTvar; - ULINT ULINTvar; - - BYTE BYTEvar; - WORD WORDvar; - DWORD DWORDvar; - LWORD LWORDvar; - - REAL REALvar; - LREAL LREALvar; - - /* NOTE: since the TIME, DATE, ... classes all have constructors, - * C++ does not allow them to be used as members of a union. - * The workaround is to use a base data type (in this case __timebase_t) that - * contains all the internal data these classes require, and then add an operator - * member function to each class that allows it to be converted to that same base data type, - * acompanied by a constructor using that data type. - */ - - TIME TIMEvar; - TOD TODvar; - DT DTvar; - DATE DATEvar; - - /* - __timebase_t TIMEvar; - __timebase_t TODvar; - __timebase_t DTvar; - __timebase_t DATEvar; - */ -} __IL_DEFVAR_T; - /*TODO TODO TODO TODO TODO TODO TODO TODO TODO - * How do we add support for the possibility of storing - * data values of derived data types into the default register, - * to be later used for calling functions, stroing in another - * variable, etc...? - * - * For example: - * TYPE - * point_t : STRUCT - * x : INT; - * y : INT; - * END_STRUCT; - * END_TYPE - * - * VAR p1, p2, p3 : point_t; - * - * LD p1 - * ST p2 - * - * - * We could do it with a pointer to void, that would contain not - * the value itself, but rather the address in which the value - * is currently stored. - * For example, we could add a - * void *generic_ptr - * to this union, and then have the above LD and ST instructions - * converted to: - * __IL_DEFVAR.generic_ptr = (void *)(&p1); - * p2 = *((point_t *)__IL_DEFVAR.generic_ptr); - * - * Unfortunately the above will only work as long as the p1 variable - * does not get a chance to change its value before the default register - * gets loaded with something esle (and therefore the value is no - * longer needed). - * Additionally, a scenario where the value of p1 may change before the - * default register gets a new value is if p1 is used in a function block - * call for an output parameter! - * For example: - * - * LD p1 - * CAL funcblock( - * param1 => p1 - * ) - * ST p2 - * - * In the above scenario, p1 gets a new value when the function block - * funcblock is called. When we get to copy the default register to - * p2, we will no longer be copying the value that got stored in the default - * register when we did 'LD p1', but rather the value returned by the - * function block call!!! - * - * How the do we implement this??? - * We will probably need to declare a default variable of the correct data - * type whenever we get these values stored to the default register. - * For example - * LD p1 - * ST p2 - * - * would be converted to: - * union { - * point_tvar point_t; - * } __IL_DEFVAR_special ; - * - * __IL_DEFVAR_special.point_tvar = p1; - * p2 = __IL_DEFVAR_special.point_tvar; - * - * The above requires that we iterate through the whole Instruction list - * before we start the conversion, in order to first determine if we need - * to declare that new variable for the default register. - * - * Since we have to do this, it would probaly be a better idea to simply - * do away with the __IL_DEFVAR_T data type we declare here, and - * declare the __IL_DEFVAR at the begining of each IL code segment - * with all the data types that get used in that segment! - */ - - -/* Names start with double underscore so as not to clash with - * names in ST or IL source code! Names including a double underscore are - * ilegal under IL and ST! - */ - -/* This is an abstract base class, that cannot be instantiated... */ -template class __ext_ref_c { - public: - virtual void operator= (value_type value) = 0; - virtual operator value_type(void) = 0; -}; - - - - - - -/* Names start with double underscore so as not to clash with - * names in ST or IL source code! Names including a double underscore are - * ilegal under IL and ST! - */ -template class __ext_element_c - : public __ext_ref_c { -//{ - - private: - value_type value; - - public: - virtual void operator= (value_type value) { - this->value = value; - } - - virtual operator value_type(void) { - return value; - } - - __ext_element_c(void) {} - - __ext_element_c(value_type value) { - this->value = value; - } -}; - - -/* Names start with double underscore so as not to clash with - * names in ST or IL source code! Names including a double underscore are - * ilegal under IL and ST! - */ -template class __plc_pt_c - : public __ext_ref_c { - - private: - plc_pt_t plc_pt; - bool valid_plc_pt; - - private: - void init_name(const char *pt_name) { - /* assume error! */ - valid_plc_pt = false; - plc_pt = plc_pt_by_name(pt_name); - if (plc_pt.valid == 0) { - plc_pt = plc_pt_null(); - return; - } - /* We can't have this check here, otherwise the boolean variables won't work correctly, - * since MatPLC uses 1 bit for boolean variables, whereas g++ uses 8 bits. - */ - /* - if (plc_pt_len(plc_pt) != size) { - plc_pt = plc_pt_null(); - return; - } - */ - valid_plc_pt = true; - } - - public: - virtual void operator= (value_type value) { - plc_set(plc_pt, *((u32 *)&value)); - } - - virtual operator value_type(void) { - u32 tmp_val = plc_get(plc_pt); - return *((value_type *)&tmp_val); - } - - __plc_pt_c(const char *pt_name) { - init_name(pt_name); - } - - __plc_pt_c(const char *pt_name, value_type init_value) { - init_name(pt_name); - *this = init_value; - } - - bool valid(void) {return valid_plc_pt;} -}; - - - -#define DEFAULT_MODULE_NAME "iec" - - - -#endif /* __PLCIEC_H */ - -