etisserant@0: /* etisserant@0: * (c) 2003 Mario de Sousa etisserant@0: * etisserant@0: * Offered to the public under the terms of the GNU General Public License etisserant@0: * as published by the Free Software Foundation; either version 2 of the etisserant@0: * License, or (at your option) any later version. etisserant@0: * etisserant@0: * This program is distributed in the hope that it will be useful, but etisserant@0: * WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General etisserant@0: * Public License for more details. etisserant@0: * etisserant@0: * This code is made available on the understanding that it will not be etisserant@0: * used in safety-critical situations without a full and competent review. etisserant@0: */ etisserant@0: etisserant@0: /* etisserant@0: * An IEC 61131-3 IL and ST compiler. etisserant@0: * etisserant@0: * Based on the etisserant@0: * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) etisserant@0: * etisserant@0: */ etisserant@0: etisserant@0: /* etisserant@0: * Definition of the Abstract Syntax data structure components etisserant@0: */ etisserant@0: etisserant@0: #include etisserant@0: #include /* required for exit() */ etisserant@0: #include etisserant@0: etisserant@0: #include "absyntax.hh" etisserant@0: //#include "../stage1_2/iec.hh" /* required for BOGUS_TOKEN_ID, etc... */ etisserant@0: #include "visitor.hh" etisserant@0: etisserant@0: #define ABORT(str) {printf("ERROR: %s\n", str); exit(0);} etisserant@0: etisserant@0: etisserant@0: etisserant@0: symbol_c *tree_root = NULL; etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: /* The base class of all symbols */ etisserant@0: symbol_c::symbol_c(void) { etisserant@0: lineno = 0; etisserant@0: } etisserant@0: etisserant@0: symbol_c::symbol_c(long lineno) { etisserant@0: this->lineno = lineno; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: etisserant@0: token_c::token_c(const char *value) { etisserant@0: this->value = value; etisserant@0: // printf("New token: %s\n", value); etisserant@0: } etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: list_c::list_c(void) { etisserant@0: n = 0; etisserant@0: elements = NULL; etisserant@0: } etisserant@0: etisserant@0: list_c::list_c(symbol_c *elem) { etisserant@0: n = 0; etisserant@0: elements = NULL; etisserant@0: add_element(elem); etisserant@0: } etisserant@0: etisserant@0: /* insert a new element */ etisserant@0: void list_c::add_element(symbol_c *elem) { etisserant@0: //printf("list_c::add_element()\n"); etisserant@0: n++; etisserant@0: elements = (symbol_c **)realloc(elements, n * sizeof(symbol_c *)); etisserant@0: if (elements == NULL) etisserant@0: ABORT("Out of memory"); etisserant@0: elements[n - 1] = elem; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: #define SYM_LIST(class_name_c) \ etisserant@0: void *class_name_c::accept(visitor_c &visitor) {return visitor.visit(this);} etisserant@0: etisserant@0: #define SYM_TOKEN(class_name_c) \ etisserant@0: class_name_c::class_name_c(const char *value): token_c(value) {} \ etisserant@0: void *class_name_c::accept(visitor_c &visitor) {return visitor.visit(this);} etisserant@0: etisserant@0: #define SYM_REF0(class_name_c) \ etisserant@0: void *class_name_c::accept(visitor_c &visitor) {return visitor.visit(this);} etisserant@0: etisserant@0: etisserant@0: #define SYM_REF2(class_name_c, ref1, ref2) \ etisserant@0: class_name_c::class_name_c(symbol_c *ref1, \ etisserant@0: symbol_c *ref2) { \ etisserant@0: this->ref1 = ref1; \ etisserant@0: this->ref2 = ref2; \ etisserant@0: } \ etisserant@0: void *class_name_c::accept(visitor_c &visitor) {return visitor.visit(this);} etisserant@0: etisserant@0: etisserant@0: #define SYM_REF4(class_name_c, ref1, ref2, ref3, ref4) \ etisserant@0: class_name_c::class_name_c(symbol_c *ref1, \ etisserant@0: symbol_c *ref2, \ etisserant@0: symbol_c *ref3, \ etisserant@0: symbol_c *ref4) { \ etisserant@0: this->ref1 = ref1; \ etisserant@0: this->ref2 = ref2; \ etisserant@0: this->ref3 = ref3; \ etisserant@0: this->ref4 = ref4; \ etisserant@0: } \ etisserant@0: void *class_name_c::accept(visitor_c &visitor) {return visitor.visit(this);} etisserant@0: etisserant@0: etisserant@0: #define SYM_REF6(class_name_c, ref1, ref2, ref3, ref4, ref5, ref6) \ etisserant@0: class_name_c::class_name_c(symbol_c *ref1, \ etisserant@0: symbol_c *ref2, \ etisserant@0: symbol_c *ref3, \ etisserant@0: symbol_c *ref4, \ etisserant@0: symbol_c *ref5, \ etisserant@0: symbol_c *ref6) { \ etisserant@0: this->ref1 = ref1; \ etisserant@0: this->ref2 = ref2; \ etisserant@0: this->ref3 = ref3; \ etisserant@0: this->ref4 = ref4; \ etisserant@0: this->ref5 = ref5; \ etisserant@0: this->ref6 = ref6; \ etisserant@0: } \ etisserant@0: void *class_name_c::accept(visitor_c &visitor) {return visitor.visit(this);} etisserant@0: etisserant@0: etisserant@0: etisserant@0: #include "absyntax.def" etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: #undef SYM_LIST etisserant@0: #undef SYM_TOKEN etisserant@0: #undef SYM_TOKEN etisserant@0: #undef SYM_REF0 etisserant@0: #undef SYM_REF2 etisserant@0: #undef SYM_REF4 etisserant@0: #undef SYM_REF6 etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: