--- a/stage4/generate_cc/generate_cc.cc Wed Feb 14 19:57:01 2007 +0100
+++ b/stage4/generate_cc/generate_cc.cc Tue Feb 20 18:17:21 2007 +0100
@@ -38,6 +38,7 @@
// #include <stdio.h> /* required for NULL */
#include <string>
#include <iostream>
+#include <typeinfo>
#include "../../util/symtable.hh"
#include "../../util/dsymtable.hh"
@@ -176,6 +177,7 @@
#include "decompose_var_instance_name.cc"
#include "search_varfb_instance_type.cc"
#include "search_constant_type.cc"
+#include "search_expression_type.cc"
#include "generate_cc_base.cc"
#include "generate_cc_typedecl.cc"
@@ -523,7 +525,7 @@
symbol->fblock_name->accept(*this);
s4o.print(FB_FUNCTION_SUFFIX);
s4o.print("(");
- /* first and only parameter is a pointer to the data */
+ /* first and only parameter is a pointer to the data */
symbol->fblock_name->accept(*this);
s4o.print(" *");
s4o.print(FB_FUNCTION_PARAM);
@@ -549,23 +551,46 @@
s4o.print(FB_FUNCTION_SUFFIX);
s4o.print(s4o.indent_spaces + "() \n\n");
-
-
-
-
-
-
-#if 0
-
-+++++++++++++++++++++++++++++++++++++
- s4o.print(s4o.indent_spaces + "class ");
- symbol->fblock_name->accept(*this);
- s4o.print(" {\n");
- s4o.indent_right();
-
- /* (A.2) Public variables: i.e. the function parameters... */
- s4o.print(s4o.indent_spaces + "public:\n");
- s4o.indent_right();
+ s4o.indent_left();
+ s4o.print("\n\n\n\n");
+
+ return NULL;
+}
+
+
+/* The remaining temp_var_decls_c, temp_var_decls_list_c
+ * and non_retentive_var_decls_c are handled in the generate_cc_vardecl_c class
+ */
+
+
+/**********************/
+/* B 1.5.3 - Programs */
+/**********************/
+
+
+
+public:
+/* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */
+//SYM_REF4(program_declaration_c, program_type_name, var_declarations, function_block_body, unused)
+void *visit(program_declaration_c *symbol) {
+ generate_cc_vardecl_c *vardecl;
+ TRACE("program_declaration_c");
+
+ /* start off by adding this declaration to the global
+ * program declaration symbol table...
+ */
+ program_type_symtable.insert(symbol->program_type_name, symbol);
+
+ /* (A) Program data structure declaration... */
+ /* (A.1) Data structure declaration */
+ s4o.print("// PROGRAM ");
+ symbol->program_type_name->accept(*this);
+ s4o.print("\n// Data part\n");
+ s4o.print("typedef struct {\n");
+ s4o.indent_right();
+
+ /* (A.2) Public variables: i.e. the program parameters... */
+ s4o.print(s4o.indent_spaces + "// PROGRAM Interface - IN, OUT, IN_OUT variables\n");
vardecl = new generate_cc_vardecl_c(&s4o,
generate_cc_vardecl_c::local_vf,
generate_cc_vardecl_c::input_vt |
@@ -573,226 +598,60 @@
generate_cc_vardecl_c::inoutput_vt);
vardecl->print(symbol->var_declarations);
delete vardecl;
- s4o.indent_left();
s4o.print("\n");
-
/* (A.3) Private internal variables */
- s4o.print(s4o.indent_spaces + "private:\n");
- s4o.indent_right();
+ s4o.print(s4o.indent_spaces + "// PROGRAM private variables - TEMP, private and located variables\n");
vardecl = new generate_cc_vardecl_c(&s4o,
generate_cc_vardecl_c::local_vf,
- generate_cc_vardecl_c::private_vt |
- generate_cc_vardecl_c::located_vt);
- vardecl->print(symbol->var_declarations);
- delete vardecl;
- s4o.indent_left();
- s4o.print("\n");
-
----------------------------------
- /* (B) Constructor */
- s4o.print(s4o.indent_spaces + "public:\n");
- s4o.indent_right();
- s4o.print(s4o.indent_spaces);
- symbol->fblock_name->accept(*this);
- s4o.print("(void)\n");
- s4o.indent_right();
- s4o.print(s4o.indent_spaces);
- vardecl = new generate_cc_vardecl_c(&s4o,
- generate_cc_vardecl_c::constructorinit_vf,
- generate_cc_vardecl_c::input_vt |
- generate_cc_vardecl_c::output_vt |
- generate_cc_vardecl_c::inoutput_vt |
- generate_cc_vardecl_c::private_vt);
- vardecl->print(symbol->var_declarations);
- delete vardecl;
- s4o.print("\n" + s4o.indent_spaces + "{}\n\n");
- s4o.indent_left();
- s4o.indent_left();
----------------------------------
-
-
- /* (C) Public Function*/
- /* (C.1) Public Function declaration */
- s4o.print(s4o.indent_spaces + "public:\n");
- s4o.indent_right();
- s4o.print(s4o.indent_spaces + "void f(void) {\n");
-
- /* (C.2) Temporary variables */
- s4o.indent_right();
- vardecl = new generate_cc_vardecl_c(&s4o, generate_cc_vardecl_c::localinit_vf, generate_cc_vardecl_c::temp_vt);
- vardecl->print(symbol->var_declarations);
- delete vardecl;
- s4o.indent_left();
- s4o.print("\n");
-
- /* (C.3) Public Function body */
- s4o.indent_right();
- this->current_scope = symbol;
- symbol->fblock_body->accept(*this);
- this->current_scope = NULL;
- s4o.indent_left();
- s4o.print(s4o.indent_spaces + "} /* f() */\n\n");
- s4o.indent_left();
-
- /* (D) Close the class declaration... */
- s4o.indent_left();
- s4o.print(s4o.indent_spaces + "}; /* class ");
- symbol->fblock_name->accept(*this);
- s4o.print(" */\n");
-
----------------------------------
- /* (E) Initialise the static member variables... */
- vardecl = new generate_cc_vardecl_c(&s4o,
- generate_cc_vardecl_c::globalinit_vf,
- generate_cc_vardecl_c::located_vt);
- vardecl->print(symbol->var_declarations, symbol->fblock_name);
- delete vardecl;
-
-#endif
-
- s4o.indent_left();
- s4o.print("\n\n\n\n");
-
- return NULL;
-}
-
-
-/* The remaining temp_var_decls_c, temp_var_decls_list_c
- * and non_retentive_var_decls_c are handled in the generate_cc_vardecl_c class
- */
-
-
-/**********************/
-/* B 1.5.3 - Programs */
-/**********************/
-
-
-
-public:
-/* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */
-//SYM_REF4(program_declaration_c, program_type_name, var_declarations, function_block_body, unused)
-void *visit(program_declaration_c *symbol) {
- generate_cc_vardecl_c *vardecl;
- TRACE("program_declaration_c");
-
- /* start off by adding this declaration to the global
- * program declaration symbol table...
- */
- program_type_symtable.insert(symbol->program_type_name, symbol);
-
- /* (A) Class (Function Block) declaration... */
- /* (A.1) Class (Function Block) name */
- s4o.print("// PROGRAM\n");
- s4o.print(s4o.indent_spaces);
- symbol->program_type_name->accept(*this);
- s4o.print("\n //Data part\n");
- s4o.print("typedef struct {\n");
- s4o.indent_right();
-
- /* (A.2) Public variables: i.e. the program parameters... */
- s4o.print(s4o.indent_spaces + "//PROGRAM interface IN OUT IN_OUT variables\n");
- s4o.indent_right();
- vardecl = new generate_cc_vardecl_c(&s4o,
- generate_cc_vardecl_c::local_vf,
- generate_cc_vardecl_c::input_vt |
- generate_cc_vardecl_c::output_vt |
- generate_cc_vardecl_c::inoutput_vt);
- vardecl->print(symbol->var_declarations);
- delete vardecl;
- s4o.indent_left();
- s4o.print("\n");
-
- /* (A.3) Private internal variables */
- s4o.print(s4o.indent_spaces + "// PROGRAM private variables - TEMP, private and located variables\n");
- s4o.indent_right();
- vardecl = new generate_cc_vardecl_c(&s4o,
- generate_cc_vardecl_c::local_vf,
+ generate_cc_vardecl_c::temp_vt |
generate_cc_vardecl_c::private_vt |
generate_cc_vardecl_c::located_vt |
- generate_cc_vardecl_c::external_vt);
+ generate_cc_vardecl_c::external_vt);
vardecl->print(symbol->var_declarations);
delete vardecl;
- s4o.print("\n ");
+ s4o.print("\n");
+
+ /* (A.4) Program data structure type name. */
s4o.indent_left();
s4o.print("} ");
symbol->program_type_name->accept(*this);
- s4o.print(";\n\n ");
- /* (B) Constructor */
- /* (B.1) Constructor name... */
- s4o.print("// Code part");
- /*PROGRAM Interface*/
- s4o.indent_right();
- s4o.print(s4o.indent_spaces);
+ s4o.print(";\n\n");
+
+ /* (B) Function with PROGRAM body */
+ /* (B.1) Function declaration */
+ s4o.print("// Code part\n");
+ /* function interface */
s4o.print("void ");
symbol->program_type_name->accept(*this);
s4o.print(FB_FUNCTION_SUFFIX);
- /* (B.2) Constructor parameters (i.e. the external variables)... */
s4o.print("(");
+ /* first and only parameter is a pointer to the data */
symbol->program_type_name->accept(*this);
- s4o.indent_right();
- s4o.print(" ");
+ s4o.print(" *");
+ s4o.print(FB_FUNCTION_PARAM);
+ s4o.print(") {\n");
+ s4o.indent_right();
+
+ /* (B.2) Initialize TEMP variables */
+ /* function body */
+ s4o.print(s4o.indent_spaces + "// Initialise TEMP variables\n");
vardecl = new generate_cc_vardecl_c(&s4o,
- generate_cc_vardecl_c::finterface_vf,
- generate_cc_vardecl_c::external_vt);
- vardecl->print(symbol->var_declarations);
- delete vardecl;
- s4o.print(")");
- s4o.print("{\n");
- s4o.indent_left();
-
- /* (B.2) Member initializations... */
- s4o.indent_right();
- s4o.print(s4o.indent_spaces + "//Initialise PROGRAM variables\n");
- vardecl = new generate_cc_vardecl_c(&s4o,
- generate_cc_vardecl_c::constructorinit_vf,
- generate_cc_vardecl_c::input_vt |
- generate_cc_vardecl_c::output_vt |
- generate_cc_vardecl_c::inoutput_vt |
- generate_cc_vardecl_c::private_vt |
- generate_cc_vardecl_c::external_vt);
- vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->");
- delete vardecl;
- s4o.print("\n" + s4o.indent_spaces);
- s4o.indent_left();
- s4o.indent_left();
-
- /* (C) Public Function*/
- /* (C.1) Public Function declaration */
- s4o.print(s4o.indent_spaces);
- //s4o.indent_right();
- //s4o.print(s4o.indent_spaces + "void f(void) {\n");
-
- /* (C.2) Temporary variables */
- //s4o.indent_right();
- //vardecl = new generate_cc_vardecl_c(&s4o, generate_cc_vardecl_c::localinit_vf, generate_cc_vardecl_c::temp_vt);
- //vardecl->print(symbol->var_declarations);
- //delete vardecl;
- //s4o.indent_left();
+ generate_cc_vardecl_c::init_vf,
+ generate_cc_vardecl_c::temp_vt);
+ vardecl->print(symbol->var_declarations, NULL, FB_FUNCTION_PARAM"->");
+ delete vardecl;
s4o.print("\n");
- /* (C.3) Public Function body */
- s4o.indent_right();
+ /* (B.3) Function code */
generate_cc_IL_and_ST_c generate_cc_code(&s4o, symbol, FB_FUNCTION_PARAM"->");
symbol->function_block_body->accept(generate_cc_code);
s4o.indent_left();
- s4o.print(s4o.indent_spaces + "} //");
+ s4o.print(s4o.indent_spaces + "} // ");
symbol->program_type_name->accept(*this);
s4o.print(FB_FUNCTION_SUFFIX);
- s4o.print("()\n");
- s4o.indent_left();
-
- /* (D) Close the class declaration... */
- s4o.indent_left();
- s4o.print(s4o.indent_spaces + "}; /* void ");
- symbol->program_type_name->accept(*this);
- s4o.print(" */\n\n\n");
-
- /* (E) Initialise the static member variables... */
- vardecl = new generate_cc_vardecl_c(&s4o,
- generate_cc_vardecl_c::globalinit_vf,
- generate_cc_vardecl_c::located_vt);
- vardecl->print(symbol->var_declarations, symbol->program_type_name);
- delete vardecl;
+ s4o.print(s4o.indent_spaces + "() \n\n");
+
+ s4o.indent_left();
s4o.print("\n\n\n\n");
return NULL;
--- a/stage4/generate_cc/generate_cc_base.cc Wed Feb 14 19:57:01 2007 +0100
+++ b/stage4/generate_cc/generate_cc_base.cc Tue Feb 20 18:17:21 2007 +0100
@@ -172,7 +172,6 @@
return NULL;
}
-
void *print_unary_expression(symbol_c *exp,
const char *operation) {
s4o.print(operation);
@@ -182,6 +181,32 @@
return NULL;
}
+ void *print_binary_function(const char *function,
+ symbol_c *l_exp,
+ symbol_c *r_exp) {
+ s4o.print(function);
+ s4o.print("(");
+ l_exp->accept(*this);
+ s4o.print(", ");
+ r_exp->accept(*this);
+ s4o.print(")");
+ return NULL;
+ }
+
+ void *print_compare_function(const char *function,
+ const char *compare_sign,
+ symbol_c *l_exp,
+ symbol_c *r_exp) {
+ s4o.print(function);
+ s4o.print("(");
+ s4o.print(compare_sign);
+ s4o.print(", ");
+ l_exp->accept(*this);
+ s4o.print(", ");
+ r_exp->accept(*this);
+ s4o.print(")");
+ return NULL;
+ }
/***************************/
/* 2.1.6 - Pragmas */
@@ -309,7 +334,7 @@
/* SYM_REF2(duration_c, neg, interval) */
void *visit(duration_c *symbol) {
TRACE("duration_c");
- s4o.print("TIME(");
+ s4o.print("__time_to_timespec(");
if (NULL == symbol->neg)
s4o.print("1"); /* positive time value */
else
@@ -318,6 +343,10 @@
s4o.print(", ");
symbol->interval->accept(*this);
+ if (typeid(*symbol->interval) == typeid(hours_c)) {s4o.print(", 0");}
+ if (typeid(*symbol->interval) == typeid(minutes_c)) {s4o.print(", 0, 0");}
+ if (typeid(*symbol->interval) == typeid(seconds_c)) {s4o.print(", 0, 0, 0");}
+ if (typeid(*symbol->interval) == typeid(milliseconds_c)) {s4o.print(", 0, 0, 0, 0");}
s4o.print(")");
return NULL;
}
@@ -401,7 +430,7 @@
/* SYM_REF2(time_of_day_c, daytime, unused) */
void *visit(time_of_day_c *symbol) {
TRACE("time_of_day_c");
- s4o.print("TOD(");
+ s4o.print("__tod_to_timespec(");
symbol->daytime->accept(*this);
s4o.print(")");
return NULL;
@@ -423,7 +452,7 @@
/* SYM_REF2(date_c, date_literal, unused) */
void *visit(date_c *symbol) {
TRACE("date_c");
- s4o.print("DATE(");
+ s4o.print("__date_to_timespec(");
symbol->date_literal->accept(*this);
s4o.print(")");
return NULL;
@@ -445,7 +474,7 @@
/* SYM_REF2(date_and_time_c, date_literal, daytime) */
void *visit(date_and_time_c *symbol) {
TRACE("date_and_time_c");
- s4o.print("DT(");
+ s4o.print("__dt_to_timespec(");
symbol->daytime->accept(*this);
s4o.print(", ");
symbol->date_literal->accept(*this);
--- a/stage4/generate_cc/generate_cc_il.cc Wed Feb 14 19:57:01 2007 +0100
+++ b/stage4/generate_cc/generate_cc_il.cc Tue Feb 20 18:17:21 2007 +0100
@@ -53,6 +53,7 @@
* (function, function block or program within which
* the possible il_operand variable instance was declared).
*/
+
class search_il_operand_type_c {
private:
@@ -175,7 +176,8 @@
* This object instance will then later be called while the
* remaining il code is being handled.
*/
- search_il_operand_type_c *search_il_operand_type;
+ //search_il_operand_type_c *search_il_operand_type;
+ search_expression_type_c *search_expression_type;
/* The initial value that should be given to the IL default variable
* imediately after a parenthesis is opened.
@@ -296,7 +298,8 @@
default_variable_name(IL_DEFVAR, NULL),
default_variable_back_name(IL_DEFVAR_BACK, NULL)
{
- search_il_operand_type = new search_il_operand_type_c(scope);
+ //search_il_operand_type = new search_il_operand_type_c(scope);
+ search_expression_type = new search_expression_type_c(scope);
search_fb_instance_decl = new search_fb_instance_decl_c(scope);
current_operand = NULL;
current_operand_type = NULL;
@@ -306,7 +309,8 @@
virtual ~generate_cc_il_c(void) {
delete search_fb_instance_decl;
- delete search_il_operand_type;
+ //delete search_il_operand_type;
+ delete search_expression_type;
}
void generate(instruction_list_c *il) {
@@ -317,9 +321,11 @@
private:
/* A helper function... */
+ /*
bool is_bool_type(symbol_c *type_symbol) {
return (NULL != dynamic_cast<bool_type_name_c *>(type_symbol));
}
+ */
/* A helper function... */
void *XXX_operator(symbol_c *lo, const char *op, symbol_c *ro) {
@@ -333,6 +339,22 @@
}
/* A helper function... */
+ void *XXX_function(const char *func, symbol_c *lo, symbol_c *ro) {
+ if ((NULL == lo) || (NULL == ro)) ERROR;
+ if (NULL == func) ERROR;
+
+ lo->accept(*this);
+ s4o.print(" = ");
+ s4o.print(func);
+ s4o.print("(");
+ lo->accept(*this);
+ s4o.print(", ");
+ ro->accept(*this);
+ s4o.print(")");
+ return NULL;
+ }
+
+ /* A helper function... */
void *XXX_CAL_operator(const char *param_name, symbol_c *fb_name) {
if (NULL == fb_name) ERROR;
symbolic_variable_c *sv = dynamic_cast<symbolic_variable_c *>(fb_name);
@@ -365,12 +387,23 @@
this->default_variable_name.accept(*this);
this->default_variable_name.current_type = backup;
- s4o.print(" = (");
- this->default_variable_name.accept(*this);
- s4o.print(operation);
- o->accept(*this);
- s4o.print(")");
-
+ if (search_expression_type->is_time_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_time_compatible(this->current_operand_type)) {
+ s4o.print(" = __compare_timespec(");
+ s4o.print(operation);
+ s4o.print(", ");
+ this->default_variable_name.accept(*this);
+ s4o.print(", ");
+ o->accept(*this);
+ s4o.print(")");
+ }
+ else {
+ s4o.print(" = (");
+ this->default_variable_name.accept(*this);
+ s4o.print(operation);
+ o->accept(*this);
+ s4o.print(")");
+ }
/* the data type resulting from this operation... */
this->default_variable_name.current_type = &(this->bool_type);
return NULL;
@@ -379,20 +412,22 @@
/* A helper function... */
void C_modifier(void) {
- if (NULL == this->default_variable_name.current_type) ERROR;
-
- s4o.print("if (");
- this->default_variable_name.accept(*this);
- s4o.print(") ");
+ if (search_expression_type->is_numeric_compatible(default_variable_name.current_type)) {
+ s4o.print("if (");
+ this->default_variable_name.accept(*this);
+ s4o.print(") ");
+ }
+ else {ERROR;}
}
/* A helper function... */
void CN_modifier(void) {
- if (NULL == this->default_variable_name.current_type) ERROR;
-
- s4o.print("if (!");
- this->default_variable_name.accept(*this);
- s4o.print(") ");
+ if (search_expression_type->is_numeric_compatible(default_variable_name.current_type)) {
+ s4o.print("if (!");
+ this->default_variable_name.accept(*this);
+ s4o.print(") ");
+ }
+ else {ERROR;}
}
@@ -486,7 +521,7 @@
if (NULL == this->current_operand) {
this->current_operand_type = NULL;
} else {
- this->current_operand_type = search_il_operand_type->get_type(this->current_operand);
+ this->current_operand_type = search_expression_type->get_type(this->current_operand);
if (NULL == this->current_operand_type) ERROR;
}
@@ -975,7 +1010,7 @@
/* the data type resulting from this operation... */
this->default_variable_name.current_type = this->current_operand_type;
XXX_operator(&(this->default_variable_name),
- is_bool_type(this->current_operand_type)?" = !":" = ~",
+ search_expression_type->is_bool_type(this->current_operand_type)?" = !":" = ~",
this->current_operand);
return NULL;
}
@@ -988,7 +1023,7 @@
void *visit(STN_operator_c *symbol) {
XXX_operator(this->current_operand,
- is_bool_type(this->current_operand_type)?" = !":" = ~",
+ search_expression_type->is_bool_type(this->current_operand_type)?" = !":" = ~",
&(this->default_variable_name));
/* the data type resulting from this operation is unchamged. */
return NULL;
@@ -997,7 +1032,7 @@
void *visit(NOT_operator_c *symbol) {
if ((NULL != this->current_operand) || (NULL != this->current_operand_type)) ERROR;
XXX_operator(&(this->default_variable_name),
- is_bool_type(this->default_variable_name.current_type)?" = !":" = ~",
+ search_expression_type->is_bool_type(this->default_variable_name.current_type)?" = !":" = ~",
&(this->default_variable_name));
/* the data type resulting from this operation is unchanged. */
return NULL;
@@ -1008,7 +1043,7 @@
C_modifier();
this->current_operand->accept(*this);
- s4o.print(is_bool_type(this->current_operand_type)?" = true":" = 1");
+ s4o.print(search_expression_type->is_bool_type(this->current_operand_type)?" = true":" = 1");
/* the data type resulting from this operation is unchanged! */
return NULL;
}
@@ -1018,7 +1053,7 @@
C_modifier();
this->current_operand->accept(*this);
- s4o.print(is_bool_type(this->current_operand_type)?" = false":" = 0");
+ s4o.print(search_expression_type->is_bool_type(this->current_operand_type)?" = false":" = 0");
/* the data type resulting from this operation is unchanged! */
return NULL;
}
@@ -1033,87 +1068,155 @@
void *visit(PT_operator_c *symbol) {return XXX_CAL_operator("PT", this->current_operand);}
void *visit(AND_operator_c *symbol) {
- XXX_operator(&(this->default_variable_name), " &= ", this->current_operand);
- /* the data type resulting from this operation... */
- this->default_variable_name.current_type = this->current_operand_type;
+ if (search_expression_type->is_numeric_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_numeric_compatible(this->current_operand_type)) {
+ XXX_operator(&(this->default_variable_name), " &= ", this->current_operand);
+ /* the data type resulting from this operation... */
+ this->default_variable_name.current_type = this->current_operand_type;
+ }
+ else {ERROR;}
return NULL;
}
void *visit(OR_operator_c *symbol) {
- XXX_operator(&(this->default_variable_name), " |= ", this->current_operand);
- /* the data type resulting from this operation... */
- this->default_variable_name.current_type = this->current_operand_type;
+ if (search_expression_type->is_numeric_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_numeric_compatible(this->current_operand_type)) {
+ XXX_operator(&(this->default_variable_name), " |= ", this->current_operand);
+ /* the data type resulting from this operation... */
+ this->default_variable_name.current_type = this->current_operand_type;
+ }
+ else {ERROR;}
return NULL;
}
void *visit(XOR_operator_c *symbol) {
- // '^' is a bit by bit exclusive OR !! Also seems to work with boolean types!
- XXX_operator(&(this->default_variable_name), " ^= ", this->current_operand);
- /* the data type resulting from this operation... */
- this->default_variable_name.current_type = this->current_operand_type;
+ if (search_expression_type->is_numeric_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_numeric_compatible(this->current_operand_type)) {
+ // '^' is a bit by bit exclusive OR !! Also seems to work with boolean types!
+ XXX_operator(&(this->default_variable_name), " ^= ", this->current_operand);
+ /* the data type resulting from this operation... */
+ this->default_variable_name.current_type = this->current_operand_type;
+ }
+ else {ERROR;}
return NULL;
}
void *visit(ANDN_operator_c *symbol) {
- XXX_operator(&(this->default_variable_name),
- is_bool_type(this->current_operand_type)?" &= !":" &= ~",
- this->current_operand);
- /* the data type resulting from this operation... */
- this->default_variable_name.current_type = this->current_operand_type;
+ if (search_expression_type->is_numeric_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_numeric_compatible(this->current_operand_type)) {
+ XXX_operator(&(this->default_variable_name),
+ search_expression_type->is_bool_type(this->current_operand_type)?" &= !":" &= ~",
+ this->current_operand);
+ /* the data type resulting from this operation... */
+ this->default_variable_name.current_type = this->current_operand_type;
+ }
+ else {ERROR;}
return NULL;
}
void *visit(ORN_operator_c *symbol) {
- XXX_operator(&(this->default_variable_name),
- is_bool_type(this->current_operand_type)?" |= !":" |= ~",
- this->current_operand);
- /* the data type resulting from this operation... */
- this->default_variable_name.current_type = this->current_operand_type;
+ if (search_expression_type->is_numeric_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_numeric_compatible(this->current_operand_type)) {
+ XXX_operator(&(this->default_variable_name),
+ search_expression_type->is_bool_type(this->current_operand_type)?" |= !":" |= ~",
+ this->current_operand);
+ /* the data type resulting from this operation... */
+ this->default_variable_name.current_type = this->current_operand_type;
+ }
+ else {ERROR;}
return NULL;
}
void *visit(XORN_operator_c *symbol) {
- XXX_operator(&(this->default_variable_name),
- // bit by bit exclusive OR !! Also seems to work with boolean types!
- is_bool_type(this->current_operand_type)?" ^= !":" ^= ~",
- this->current_operand);
- /* the data type resulting from this operation... */
- this->default_variable_name.current_type = this->current_operand_type;
+ if (search_expression_type->is_numeric_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_numeric_compatible(this->current_operand_type)) {
+ XXX_operator(&(this->default_variable_name),
+ // bit by bit exclusive OR !! Also seems to work with boolean types!
+ search_expression_type->is_bool_type(this->current_operand_type)?" ^= !":" ^= ~",
+ this->current_operand);
+ /* the data type resulting from this operation... */
+ this->default_variable_name.current_type = this->current_operand_type;
+ }
+ else {ERROR;}
return NULL;
}
void *visit(ADD_operator_c *symbol) {
- XXX_operator(&(this->default_variable_name), " += ", this->current_operand);
- /* the data type resulting from this operation... */
- this->default_variable_name.current_type = this->current_operand_type;
+ if (search_expression_type->is_time_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_time_compatible(this->current_operand_type)) {
+ XXX_function("__add_timespec", &(this->default_variable_name), this->current_operand);
+ /* the data type resulting from this operation... */
+ this->default_variable_name.current_type = this->current_operand_type;
+ return NULL;
+ }
+ if (search_expression_type->is_numeric_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_numeric_compatible(this->current_operand_type)) {
+ XXX_operator(&(this->default_variable_name), " += ", this->current_operand);
+ /* the data type resulting from this operation... */
+ this->default_variable_name.current_type = this->current_operand_type;
+ return NULL;
+ }
+ ERROR;
return NULL;
}
void *visit(SUB_operator_c *symbol) {
- XXX_operator(&(this->default_variable_name), " -= ", this->current_operand);
- /* the data type resulting from this operation... */
- this->default_variable_name.current_type = this->current_operand_type;
+ if (search_expression_type->is_time_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_time_compatible(this->current_operand_type)) {
+ XXX_function("__sub_timespec", &(this->default_variable_name), this->current_operand);
+ /* the data type resulting from this operation... */
+ this->default_variable_name.current_type = this->current_operand_type;
+ return NULL;
+ }
+ if (search_expression_type->is_numeric_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_numeric_compatible(this->current_operand_type)) {
+ XXX_operator(&(this->default_variable_name), " -= ", this->current_operand);
+ /* the data type resulting from this operation... */
+ this->default_variable_name.current_type = this->current_operand_type;
+ return NULL;
+ }
+ ERROR;
return NULL;
}
void *visit(MUL_operator_c *symbol) {
- XXX_operator(&(this->default_variable_name), " *= ", this->current_operand);
- /* the data type resulting from this operation... */
- this->default_variable_name.current_type = this->current_operand_type;
+ if (search_expression_type->is_time_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_time_compatible(this->current_operand_type)) {
+ XXX_function("__mul_timespec", &(this->default_variable_name), this->current_operand);
+ /* the data type resulting from this operation... */
+ this->default_variable_name.current_type = this->current_operand_type;
+ return NULL;
+ }
+ if (search_expression_type->is_numeric_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_numeric_compatible(this->current_operand_type)) {
+ XXX_operator(&(this->default_variable_name), " *= ", this->current_operand);
+ /* the data type resulting from this operation... */
+ this->default_variable_name.current_type = this->current_operand_type;
+ return NULL;
+ }
+ ERROR;
return NULL;
}
void *visit(DIV_operator_c *symbol) {
- XXX_operator(&(this->default_variable_name), " /= ", this->current_operand);
- /* the data type resulting from this operation... */
- this->default_variable_name.current_type = this->current_operand_type;
+ if (search_expression_type->is_numeric_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_numeric_compatible(this->current_operand_type)) {
+ XXX_operator(&(this->default_variable_name), " /= ", this->current_operand);
+ /* the data type resulting from this operation... */
+ this->default_variable_name.current_type = this->current_operand_type;
+ }
+ else {ERROR;}
return NULL;
}
void *visit(MOD_operator_c *symbol) {
- XXX_operator(&(this->default_variable_name), " %= ", this->current_operand);
- /* the data type resulting from this operation... */
- this->default_variable_name.current_type = this->current_operand_type;
+ if (search_expression_type->is_numeric_compatible(this->default_variable_name.current_type) &&
+ search_expression_type->is_numeric_compatible(this->current_operand_type)) {
+ XXX_operator(&(this->default_variable_name), " %= ", this->current_operand);
+ /* the data type resulting from this operation... */
+ this->default_variable_name.current_type = this->current_operand_type;
+ }
+ else {ERROR;}
return NULL;
}
--- a/stage4/generate_cc/generate_cc_st.cc Wed Feb 14 19:57:01 2007 +0100
+++ b/stage4/generate_cc/generate_cc_st.cc Tue Feb 20 18:17:21 2007 +0100
@@ -32,7 +32,10 @@
*/
-
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
class generate_cc_st_c: public generate_cc_typedecl_c {
@@ -53,16 +56,27 @@
*/
search_fb_instance_decl_c *search_fb_instance_decl;
+ /* When compiling st code, it becomes necessary to determine the
+ * data type of st expressions. To do this, we must first find the
+ * st operand's declaration, within the scope of the function block
+ * or function currently being processed.
+ * The following object does just that...
+ * This object instance will then later be called while the
+ * remaining st code is being handled.
+ */
+ search_expression_type_c *search_expression_type;
public:
generate_cc_st_c(stage4out_c *s4o_ptr, symbol_c *scope, const char *variable_prefix = NULL)
: generate_cc_typedecl_c(s4o_ptr) {
search_fb_instance_decl = new search_fb_instance_decl_c(scope);
+ search_expression_type = new search_expression_type_c(scope);
this->set_variable_prefix(variable_prefix);
}
virtual ~generate_cc_st_c(void) {
delete search_fb_instance_decl;
+ delete search_expression_type;
}
@@ -107,25 +121,141 @@
}
private:
+
/***************************************/
/* B.3 - Language ST (Structured Text) */
/***************************************/
/***********************/
/* B 3.1 - Expressions */
/***********************/
-void *visit(or_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " || ");}
-/* TODO ... XOR expression... */
-void *visit(xor_expression_c *symbol) {ERROR; return print_binary_expression(symbol->l_exp, symbol->r_exp, " XOR ");}
-void *visit(and_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " && ");}
-void *visit(equ_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " == ");}
-void *visit(notequ_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " != ");}
-void *visit(lt_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " < ");}
-void *visit(gt_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " > ");}
-void *visit(le_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " <= ");}
-void *visit(ge_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " >= ");}
-void *visit(add_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " + ");}
-void *visit(sub_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " - ");}
-void *visit(mul_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " * ");}
+void *visit(or_expression_c *symbol) {
+ symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+ symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+ if (typeid(*left_type) == typeid(bool_type_name_c) && typeid(*right_type) == typeid(bool_type_name_c)) {
+ return print_binary_expression(symbol->l_exp, symbol->r_exp, " || ");
+ }
+ if (search_expression_type->is_numeric_compatible(left_type) && search_expression_type->is_numeric_compatible(right_type)) {
+ return print_binary_expression(symbol->l_exp, symbol->r_exp, " | ");
+ }
+ ERROR;
+ return NULL;
+}
+
+void *visit(xor_expression_c *symbol) {
+ symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+ symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+ if (typeid(*left_type) == typeid(bool_type_name_c) && typeid(*right_type) == typeid(bool_type_name_c)) {
+ s4o.print("(");
+ symbol->l_exp->accept(*this);
+ s4o.print(" && !");
+ symbol->r_exp->accept(*this);
+ s4o.print(") || (!");
+ symbol->l_exp->accept(*this);
+ s4o.print(" && ");
+ symbol->r_exp->accept(*this);
+ s4o.print(")");
+ }
+ if (search_expression_type->is_numeric_compatible(left_type) && search_expression_type->is_numeric_compatible(right_type)) {
+ return print_binary_expression(symbol->l_exp, symbol->r_exp, " ^ ");
+ }
+ ERROR;
+ return NULL;
+}
+
+void *visit(and_expression_c *symbol) {
+ symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+ symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+ if (typeid(*left_type) == typeid(bool_type_name_c) && typeid(*right_type) == typeid(bool_type_name_c)) {
+ return print_binary_expression(symbol->l_exp, symbol->r_exp, " && ");
+ }
+ if (search_expression_type->is_numeric_compatible(left_type) && search_expression_type->is_numeric_compatible(right_type)) {
+ return print_binary_expression(symbol->l_exp, symbol->r_exp, " & ");
+ }
+ ERROR;
+ return NULL;
+}
+
+void *visit(equ_expression_c *symbol) {
+ symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+ symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+ if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+ return print_compare_function("__compare_timespec", "==", symbol->l_exp, symbol->r_exp);
+ }
+ return print_binary_expression(symbol->l_exp, symbol->r_exp, " == ");
+}
+
+void *visit(notequ_expression_c *symbol) {
+ symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+ symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+ if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+ return print_compare_function("__compare_timespec", "!=", symbol->l_exp, symbol->r_exp);
+ }
+ return print_binary_expression(symbol->l_exp, symbol->r_exp, " != ");
+}
+
+void *visit(lt_expression_c *symbol) {
+ symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+ symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+ if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+ return print_compare_function("__compare_timespec", "<", symbol->l_exp, symbol->r_exp);
+ }
+ return print_binary_expression(symbol->l_exp, symbol->r_exp, " < ");
+}
+
+void *visit(gt_expression_c *symbol) {
+ symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+ symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+ if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+ return print_compare_function("__compare_timespec", ">", symbol->l_exp, symbol->r_exp);
+ }
+ return print_binary_expression(symbol->l_exp, symbol->r_exp, " > ");
+}
+
+void *visit(le_expression_c *symbol) {
+ symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+ symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+ if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+ return print_compare_function("__compare_timespec", "<=", symbol->l_exp, symbol->r_exp);
+ }
+ return print_binary_expression(symbol->l_exp, symbol->r_exp, " <= ");
+}
+
+void *visit(ge_expression_c *symbol) {
+ symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+ symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+ if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+ return print_compare_function("__compare_timespec", ">=", symbol->l_exp, symbol->r_exp);
+ }
+ return print_binary_expression(symbol->l_exp, symbol->r_exp, " >= ");
+}
+
+void *visit(add_expression_c *symbol) {
+ symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+ symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+ if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+ return print_binary_function("__add_timespec", symbol->l_exp, symbol->r_exp);
+ }
+ return print_binary_expression(symbol->l_exp, symbol->r_exp, " + ");
+}
+
+void *visit(sub_expression_c *symbol) {
+ symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+ symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+ if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+ return print_binary_function("__sub_timespec", symbol->l_exp, symbol->r_exp);
+ }
+ return print_binary_expression(symbol->l_exp, symbol->r_exp, " - ");
+}
+
+void *visit(mul_expression_c *symbol) {
+ symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
+ symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+ if (search_expression_type->is_time_compatible(left_type) && search_expression_type->is_time_compatible(right_type)) {
+ return print_binary_function("__mul_timespec", symbol->l_exp, symbol->r_exp);
+ }
+ return print_binary_expression(symbol->l_exp, symbol->r_exp, " * ");
+}
+
void *visit(div_expression_c *symbol) {return print_binary_expression(symbol->l_exp, symbol->r_exp, " / ");}
void *visit(mod_expression_c *symbol) {
s4o.print("((");
--- a/stage4/generate_cc/plciec.h Wed Feb 14 19:57:01 2007 +0100
+++ b/stage4/generate_cc/plciec.h Tue Feb 20 18:17:21 2007 +0100
@@ -182,15 +182,100 @@
/* 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. */
@@ -451,6 +536,7 @@
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;
@@ -490,16 +576,18 @@
* 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/stage4/generate_cc/search_expression_type.cc Tue Feb 20 18:17:21 2007 +0100
@@ -0,0 +1,244 @@
+/*
+ * (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)
+ *
+ */
+
+
+/* Determine the data type of an ST expression.
+ * A reference to the relevant type definition is returned.
+ *
+ * For example:
+ * 2 + 3 -> returns reference to a int_type_name_c object.
+ * 22.2 - 5 -> returns reference to a real_type_name_c object.
+ * etc...
+ */
+class search_expression_type_c: public search_constant_type_c {
+ private:
+ search_varfb_instance_type_c *search_varfb_instance_type;
+ search_base_type_c search_base_type;
+
+ public:
+ search_expression_type_c(symbol_c *search_scope) {
+ search_varfb_instance_type = new search_varfb_instance_type_c(search_scope);
+ }
+
+ virtual ~search_expression_type_c(void) {
+ delete search_varfb_instance_type;
+ }
+
+ /* A helper function... */
+ bool is_bool_type(symbol_c *type_symbol) {
+ return (typeid(*type_symbol) == typeid(bool_type_name_c));
+ }
+
+ /* A helper function... */
+ bool is_time_compatible(symbol_c *type_symbol) {
+ if (typeid(*type_symbol) == typeid(time_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(date_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(tod_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(dt_type_name_c)) {return true;}
+ return false;
+ }
+
+ /* A helper function... */
+ bool is_numeric_compatible(symbol_c *type_symbol) {
+ if (typeid(*type_symbol) == typeid(sint_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(int_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(dint_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(lint_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(usint_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(uint_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(udint_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(ulint_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(real_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(lreal_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(byte_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(word_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(dword_type_name_c)) {return true;}
+ if (typeid(*type_symbol) == typeid(lword_type_name_c)) {return true;}
+ return false;
+ }
+
+ private:
+
+ static bool_type_name_c bool_type_name;
+
+ /* A helper function... */
+ void *compute_boolean_expression(symbol_c *left_type, symbol_c *right_type) {
+ if (typeid(*left_type) == typeid(bool_type_name_c) and typeid(*right_type) == typeid(bool_type_name_c)) {return (void *)left_type;}
+ if (is_numeric_compatible(left_type) && is_numeric_compatible(right_type)) {return (void *)left_type;}
+ ERROR;
+ return NULL;
+ }
+
+ /* A helper function... */
+ void *compute_numeric_expression(symbol_c *left_type, symbol_c *right_type) {
+ if (is_numeric_compatible(left_type) && is_numeric_compatible(right_type)) {return (void *)left_type;}
+ ERROR;
+ return NULL;
+ }
+
+ /* a helper function... */
+ symbol_c *base_type(symbol_c *symbol) {
+ return (symbol_c *)symbol->accept(search_base_type);
+ }
+
+/*********************/
+/* B 1.4 - Variables */
+/*********************/
+
+ void *visit(symbolic_variable_c *symbol) {
+ symbol_c *res;
+
+ /* Nope, now we assume it is a variable, and determine its type... */
+ res = search_varfb_instance_type->get_type(symbol);
+ if (NULL != res) return res;
+
+ return NULL;
+ }
+
+
+/***************************************/
+/* B.3 - Language ST (Structured Text) */
+/***************************************/
+/***********************/
+/* B 3.1 - Expressions */
+/***********************/
+ void *visit(or_expression_c *symbol) {
+ symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
+ symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
+ return compute_boolean_expression(left_type, right_type);
+ }
+
+ void *visit(xor_expression_c *symbol) {
+ symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
+ symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
+ return compute_boolean_expression(left_type, right_type);
+ }
+
+ void *visit(and_expression_c *symbol) {
+ symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
+ symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
+ return compute_boolean_expression(left_type, right_type);
+ }
+
+ void *visit(equ_expression_c *symbol) {return (void *)&bool_type_name;}
+ void *visit(notequ_expression_c *symbol) {return (void *)&bool_type_name;}
+ void *visit(lt_expression_c *symbol) {return (void *)&bool_type_name;}
+ void *visit(gt_expression_c *symbol) {return (void *)&bool_type_name;}
+ void *visit(le_expression_c *symbol) {return (void *)&bool_type_name;}
+ void *visit(ge_expression_c *symbol) {return (void *)&bool_type_name;}
+
+ void *visit(add_expression_c *symbol) {
+ symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
+ symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
+ if (is_time_compatible(left_type) && is_time_compatible(right_type)) {return left_type;}
+ return compute_numeric_expression(left_type, right_type);
+ }
+
+ void *visit(sub_expression_c *symbol) {
+ symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
+ symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
+ if (is_time_compatible(left_type) && is_time_compatible(right_type)) {return left_type;}
+ return compute_numeric_expression(left_type, right_type);
+ }
+
+ void *visit(mul_expression_c *symbol) {
+ symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
+ symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
+ if (is_time_compatible(left_type) && is_time_compatible(right_type)) {return left_type;}
+ return compute_numeric_expression(left_type, right_type);
+ }
+
+ void *visit(div_expression_c *symbol) {
+ symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
+ symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
+ return compute_numeric_expression(left_type, right_type);
+ }
+
+ void *visit(mod_expression_c *symbol) {
+ symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
+ symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
+ return compute_numeric_expression(left_type, right_type);
+ }
+
+ void *visit(power_expression_c *symbol) {
+ symbol_c *left_type = base_type((symbol_c *)symbol->l_exp->accept(*this));
+ symbol_c *right_type = base_type((symbol_c *)symbol->r_exp->accept(*this));
+ if (typeid(*left_type) == typeid(real_type_name_c) and typeid(*right_type) == typeid(sint_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(real_type_name_c) and typeid(*right_type) == typeid(int_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(real_type_name_c) and typeid(*right_type) == typeid(dint_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(real_type_name_c) and typeid(*right_type) == typeid(lint_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(real_type_name_c) and typeid(*right_type) == typeid(usint_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(real_type_name_c) and typeid(*right_type) == typeid(uint_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(real_type_name_c) and typeid(*right_type) == typeid(udint_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(real_type_name_c) and typeid(*right_type) == typeid(ulint_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(lreal_type_name_c) and typeid(*right_type) == typeid(sint_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(lreal_type_name_c) and typeid(*right_type) == typeid(int_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(lreal_type_name_c) and typeid(*right_type) == typeid(dint_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(lreal_type_name_c) and typeid(*right_type) == typeid(lint_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(lreal_type_name_c) and typeid(*right_type) == typeid(usint_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(lreal_type_name_c) and typeid(*right_type) == typeid(uint_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(lreal_type_name_c) and typeid(*right_type) == typeid(udint_type_name_c)) {return (void *)left_type;}
+ if (typeid(*left_type) == typeid(lreal_type_name_c) and typeid(*right_type) == typeid(ulint_type_name_c)) {return (void *)left_type;}
+ ERROR;
+ return NULL;
+ }
+
+ void *visit(neg_expression_c *symbol) {
+ symbol_c *exp_type = base_type((symbol_c *)symbol->exp->accept(*this));
+ if (typeid(*exp_type) == typeid(sint_type_name_c)) {return (void *)exp_type;}
+ if (typeid(*exp_type) == typeid(int_type_name_c)) {return (void *)exp_type;}
+ if (typeid(*exp_type) == typeid(dint_type_name_c)) {return (void *)exp_type;}
+ if (typeid(*exp_type) == typeid(lint_type_name_c)) {return (void *)exp_type;}
+ if (typeid(*exp_type) == typeid(usint_type_name_c)) {return (void *)exp_type;}
+ if (typeid(*exp_type) == typeid(uint_type_name_c)) {return (void *)exp_type;}
+ if (typeid(*exp_type) == typeid(udint_type_name_c)) {return (void *)exp_type;}
+ if (typeid(*exp_type) == typeid(ulint_type_name_c)) {return (void *)exp_type;}
+ if (typeid(*exp_type) == typeid(real_type_name_c)) {return (void *)exp_type;}
+ if (typeid(*exp_type) == typeid(lreal_type_name_c)) {return (void *)exp_type;}
+ if (typeid(*exp_type) == typeid(time_type_name_c)) {return (void *)exp_type;}
+ ERROR;
+ return NULL;
+ }
+
+ void *visit(not_expression_c *symbol) {
+ symbol_c *exp_type = base_type((symbol_c *)symbol->exp->accept(*this));
+ if (typeid(*exp_type) == typeid(bool_type_name_c)) {return (void *)exp_type;}
+ ERROR;
+ return NULL;
+ }
+
+ void *visit(function_invocation_c *symbol) {
+ function_declaration_c *f_decl = function_symtable.find_value(symbol->function_name);
+
+ if (f_decl == function_symtable.end_value())
+ /* should never occur. The function being called MUST be in the symtable... */
+ ERROR;
+
+ return base_type(f_decl->type_name);
+ }
+
+};
+
+bool_type_name_c search_expression_type_c::bool_type_name;
+
--- a/stage4/generate_iec/generate_iec.cc Wed Feb 14 19:57:01 2007 +0100
+++ b/stage4/generate_iec/generate_iec.cc Tue Feb 20 18:17:21 2007 +0100
@@ -1163,7 +1163,7 @@
/* '(' step_name ',' step_name {',' step_name} ')' */
void *visit(step_name_list_c *symbol) {
- print_list(symbol, "(", ", ", ") ");
+ print_list(symbol, "(", ", ", ")");
return NULL;
}