etisserant@0: /*
Edouard@279: * matiec - a compiler for the programming languages defined in IEC 61131-3
etisserant@0: *
Edouard@279: * Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt)
Edouard@279: * Copyright (C) 2007-2011 Laurent Bessard and Edouard Tisserant
etisserant@0: *
Edouard@279: * This program is free software: you can redistribute it and/or modify
Edouard@279: * it under the terms of the GNU General Public License as published by
Edouard@279: * the Free Software Foundation, either version 3 of the License, or
Edouard@279: * (at your option) any later version.
Edouard@279: *
Edouard@279: * This program is distributed in the hope that it will be useful,
Edouard@279: * but WITHOUT ANY WARRANTY; without even the implied warranty of
Edouard@279: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Edouard@279: * GNU General Public License for more details.
Edouard@279: *
Edouard@279: * You should have received a copy of the GNU General Public License
Edouard@279: * along with this program. If not, see .
Edouard@279: *
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: * A generic symbol table that allows duplicate values.
etisserant@0: *
etisserant@0: * This is used to create a symbol table of previously defined
etisserant@0: * functions. Duplicate are allowed since the standard permits function\
etisserant@0: * overloading in the standard library.
etisserant@0: */
etisserant@0:
etisserant@0:
etisserant@0: #include
etisserant@0: #include "symtable.hh"
msousa@596: #include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0: /* clear all entries... */
etisserant@0: template
etisserant@0: void dsymtable_c::reset(void) {
etisserant@0: _base.clear();
etisserant@0: }
etisserant@0:
etisserant@0:
etisserant@0: template
etisserant@0: void dsymtable_c::insert(const char *identifier_str, value_t new_value) {
etisserant@0: // std::cout << "store_identifier(" << identifier_str << "): \n";
etisserant@0: std::pair new_element(identifier_str, new_value);
etisserant@0: /* iterator res = */ _base.insert(new_element);
etisserant@0: }
etisserant@0:
etisserant@0:
etisserant@0: template
etisserant@0: void dsymtable_c::insert(const symbol_c *symbol, value_t new_value) {
etisserant@0: const token_c *name = dynamic_cast(symbol);
etisserant@0: if (name == NULL)
etisserant@0: ERROR;
etisserant@0: insert(name->value, new_value);
etisserant@0: }
etisserant@0:
etisserant@0:
etisserant@0: #if 0
etisserant@0: template
etisserant@0: void dsymtable_c::insert_noduplicate(const char *identifier_str, value_t new_value) {
etisserant@0: if (find_value(identifier_str) != null_value)
etisserant@0: /* already present in the set! */
etisserant@0: ERROR;
etisserant@0:
etisserant@0: // std::cout << "store_identifier(" << identifier_str << "): \n";
etisserant@0: std::pair new_element(identifier_str, new_value);
etisserant@0: /* iterator res = */ _base.insert(new_element);
etisserant@0: }
etisserant@0:
etisserant@0:
etisserant@0: template
etisserant@0: void dsymtable_c::insert_noduplicate(const symbol_c *symbol, value_t new_value) {
etisserant@0: const token_c *name = dynamic_cast(symbol);
etisserant@0: if (name == NULL)
etisserant@0: ERROR;
etisserant@0: insert_noduplicate(name->value, new_value);
etisserant@0: }
etisserant@0: #endif
etisserant@0:
etisserant@0:
msousa@350:
msousa@350: /* Determine how many entries are associated to key identifier_str */
msousa@350: /* returns:
msousa@350: * 0: if no entry is found
msousa@350: * 1: if 1 entry is found
msousa@350: * 2: if more than 1 entry is found
msousa@350: */
msousa@350: template
msousa@350: int dsymtable_c::multiplicity(const char *identifier_str) {
msousa@350: iterator lower = _base.lower_bound(identifier_str);
msousa@350: if (lower == _base.end()) return 0;
msousa@350:
msousa@350: iterator upper = _base.upper_bound(identifier_str);
msousa@350: iterator second = lower;
msousa@350: second++;
msousa@350:
msousa@350: if (second == upper) return 1;
msousa@350:
msousa@350: return 2;
msousa@350: }
msousa@350:
msousa@350:
etisserant@0: /* returns null_value if not found! */
etisserant@0: template
etisserant@0: value_type dsymtable_c::find_value(const char *identifier_str) {
etisserant@0: iterator i = _base.find(identifier_str);
etisserant@0:
etisserant@0: if (i == _base.end())
etisserant@0: return null_value;
etisserant@0: else
etisserant@0: return i->second;
etisserant@0: }
etisserant@0:
etisserant@0:
etisserant@0: template
msousa@350: const char * dsymtable_c::symbol_to_string(const symbol_c *symbol) {
etisserant@0: const token_c *name = dynamic_cast(symbol);
etisserant@0: if (name == NULL)
etisserant@0: ERROR;
msousa@350: return name->value;
etisserant@0: }
etisserant@0:
etisserant@0:
etisserant@0: /* debuging function... */
etisserant@0: template
etisserant@0: void dsymtable_c::print(void) {
etisserant@0: for(iterator i = _base.begin();
etisserant@0: i != _base.end();
etisserant@0: i++)
etisserant@0: std::cout << i->second << ":" << i->first << "\n";
etisserant@0: std::cout << "=====================\n";
etisserant@0: }
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0:
etisserant@0: