etisserant@0: /* msousa@261: * matiec - a compiler for the programming languages defined in IEC 61131-3 msousa@261: * Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt) msousa@261: * msousa@261: * This program is free software: you can redistribute it and/or modify msousa@261: * it under the terms of the GNU General Public License as published by msousa@261: * the Free Software Foundation, either version 3 of the License, or msousa@261: * (at your option) any later version. msousa@261: * msousa@261: * This program is distributed in the hope that it will be useful, msousa@261: * but WITHOUT ANY WARRANTY; without even the implied warranty of msousa@261: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the msousa@261: * GNU General Public License for more details. msousa@261: * msousa@261: * You should have received a copy of the GNU General Public License msousa@261: * along with this program. If not, see . msousa@261: * 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: /* msousa@261: * An IEC 61131-3 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: etisserant@0: etisserant@0: etisserant@0: /* The base class of all symbols */ etisserant@0: symbol_c::symbol_c(void) { mario@69: this->first_line = 0; mario@69: this->first_column = 0; mario@69: this->last_line = 0; mario@69: this->last_column = 0; mario@69: } mario@69: mario@69: symbol_c::symbol_c(int first_line, int first_column, int last_line, int last_column) { mario@69: this->first_line = first_line; mario@69: this->first_column = first_column; mario@69: this->last_line = last_line; mario@69: this->last_column = last_column; mario@69: } mario@69: mario@69: mario@69: mario@69: token_c::token_c(const char *value, int fl, int fc, int ll, int lc) mario@69: :symbol_c(fl, fc, ll, lc) { 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: mario@69: list_c::list_c(int fl, int fc, int ll, int lc) mario@69: :symbol_c(fl, fc, ll, lc) { etisserant@0: n = 0; etisserant@0: elements = NULL; etisserant@0: } etisserant@0: mario@69: list_c::list_c(symbol_c *elem, int fl, int fc, int ll, int lc) mario@69: :symbol_c(fl, fc, ll, lc) { 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; mario@69: mario@69: if (elem == NULL) mario@69: return; mario@69: mario@69: /* adjust the location parameters, taking into account the new element. */ mario@69: if ((first_line == elem->first_line) && mario@69: (first_column > elem->first_column)) { mario@69: first_column = elem->first_column; mario@69: } mario@69: if (first_line > elem->first_line) { mario@69: first_line = elem->first_line; mario@69: first_column = elem->first_column; mario@69: } mario@69: if ((last_line == elem->last_line) && mario@69: (last_column < elem->last_column)) { mario@69: last_column = elem->last_column; mario@69: } mario@69: if (last_line < elem->last_line) { mario@69: last_line = elem->last_line; mario@69: last_column = elem->last_column; mario@69: } mario@69: } etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: #define SYM_LIST(class_name_c) \ mario@69: class_name_c::class_name_c(int fl, int fc, int ll, int lc) \ mario@69: :list_c(fl, fc, ll, lc) {} \ mario@69: class_name_c::class_name_c(symbol_c *elem, int fl, int fc, int ll, int lc) \ mario@69: :list_c(elem, fl, fc, ll, lc) {} \ etisserant@0: void *class_name_c::accept(visitor_c &visitor) {return visitor.visit(this);} etisserant@0: etisserant@0: #define SYM_TOKEN(class_name_c) \ mario@69: class_name_c::class_name_c(const char *value, int fl, int fc, int ll, int lc) \ mario@69: :token_c(value, fl, fc, ll, lc) {} \ mario@69: void *class_name_c::accept(visitor_c &visitor) {return visitor.visit(this);} mario@69: mario@69: #define SYM_REF0(class_name_c) \ mario@69: class_name_c::class_name_c(int fl, int fc, \ mario@69: int ll, int lc \ mario@69: ): symbol_c(fl, fc, ll, lc) {} \ mario@69: void *class_name_c::accept(visitor_c &visitor) {return visitor.visit(this);} mario@69: mario@69: mario@69: #define SYM_REF1(class_name_c, ref1) \ mario@69: class_name_c::class_name_c(symbol_c *ref1, \ mario@69: int fl, int fc, \ mario@69: int ll, int lc \ mario@69: ): symbol_c(fl, fc, ll, lc) { \ mario@69: this->ref1 = ref1; \ mario@69: } \ mario@69: void *class_name_c::accept(visitor_c &visitor) {return visitor.visit(this);} mario@69: mario@69: mario@69: #define SYM_REF2(class_name_c, ref1, ref2) \ mario@69: class_name_c::class_name_c(symbol_c *ref1, \ mario@69: symbol_c *ref2, \ mario@69: int fl, int fc, \ mario@69: int ll, int lc \ mario@69: ): symbol_c(fl, fc, ll, lc) { \ mario@69: this->ref1 = ref1; \ mario@69: this->ref2 = ref2; \ mario@69: } \ mario@69: void *class_name_c::accept(visitor_c &visitor) {return visitor.visit(this);} mario@69: mario@69: mario@69: #define SYM_REF3(class_name_c, ref1, ref2, ref3) \ etisserant@0: class_name_c::class_name_c(symbol_c *ref1, \ etisserant@0: symbol_c *ref2, \ etisserant@0: symbol_c *ref3, \ mario@69: int fl, int fc, \ mario@69: int ll, int lc \ mario@69: ): symbol_c(fl, fc, ll, lc) { \ mario@69: this->ref1 = ref1; \ mario@69: this->ref2 = ref2; \ mario@69: this->ref3 = ref3; \ mario@69: } \ mario@69: void *class_name_c::accept(visitor_c &visitor) {return visitor.visit(this);} mario@69: mario@69: mario@69: #define SYM_REF4(class_name_c, ref1, ref2, ref3, ref4) \ mario@69: class_name_c::class_name_c(symbol_c *ref1, \ mario@69: symbol_c *ref2, \ mario@69: symbol_c *ref3, \ mario@69: symbol_c *ref4, \ mario@69: int fl, int fc, \ mario@69: int ll, int lc \ mario@69: ): symbol_c(fl, fc, ll, lc) { \ 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: mario@69: #define SYM_REF5(class_name_c, ref1, ref2, ref3, ref4, ref5) \ mario@69: class_name_c::class_name_c(symbol_c *ref1, \ mario@69: symbol_c *ref2, \ mario@69: symbol_c *ref3, \ mario@69: symbol_c *ref4, \ mario@69: symbol_c *ref5, \ mario@69: int fl, int fc, \ mario@69: int ll, int lc \ mario@69: ): symbol_c(fl, fc, ll, lc) { \ mario@69: this->ref1 = ref1; \ mario@69: this->ref2 = ref2; \ mario@69: this->ref3 = ref3; \ mario@69: this->ref4 = ref4; \ mario@69: this->ref5 = ref5; \ mario@69: } \ mario@69: void *class_name_c::accept(visitor_c &visitor) {return visitor.visit(this);} mario@69: mario@69: mario@69: 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, \ mario@69: symbol_c *ref6, \ mario@69: int fl, int fc, \ mario@69: int ll, int lc \ mario@69: ): symbol_c(fl, fc, ll, lc) { \ mario@69: this->ref1 = ref1; \ mario@69: this->ref2 = ref2; \ mario@69: this->ref3 = ref3; \ mario@69: this->ref4 = ref4; \ mario@69: this->ref5 = ref5; \ mario@69: this->ref6 = ref6; \ mario@69: } \ 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 mario@69: #undef SYM_REF1 etisserant@0: #undef SYM_REF2 mario@69: #undef SYM_REF3 etisserant@0: #undef SYM_REF4 mario@69: #undef SYM_REF5 etisserant@0: #undef SYM_REF6 etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: