/* $Id$ */ /* * Copyright (C) 2006 Richard Braun * * This program is free software; you can redistribute it and/or modify * it 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "mtx.h" #include "mtxvalue.h" #include "mtxsymbol.h" #include "mtxexception.h" #include #include #include using namespace std; struct mtx_special_name MtxSymbol::special_names[] = { {"about", about}, {"list", list}, {"quit", quit}, {"exit", quit}, {NULL, NULL} }; string about(const MtxSymbol *symbol) { return MTX_NOTICE; } string list(const MtxSymbol *symbol) { vector::const_iterator iterator; vector symbols; string list; symbols = symbol->getLanguage()->getSymbols(); if (symbols.empty()) return "No registered variable"; list = "List of registered variables :\n"; for (iterator = symbols.begin(); iterator != symbols.end(); iterator++) list += (*iterator).getName() + " = " + (*iterator).toString() + "\n"; list.erase(list.length() - 1); return list; } string quit(const MtxSymbol *symbol) { std::exit(0); } MtxSymbol::MtxSymbol() { value = NULL; language = NULL; setSpecial(); } MtxSymbol::MtxSymbol(MtxLanguage *language, const string &name) { this->name = name; value = NULL; this->language = language; setSpecial(); } MtxSymbol::MtxSymbol(MtxLanguage *language, const MtxValue &value) { this->value = value.clone(); this->language = language; setSpecial(); } MtxSymbol::MtxSymbol(MtxLanguage *language, const string &name, const MtxValue &value) { this->name = name; this->value = value.clone(); this->language = language; setSpecial(); } MtxSymbol::MtxSymbol(const MtxSymbol &symbol) { name = symbol.name; if (symbol.value == NULL) value = NULL; else value = symbol.value->clone(); language = symbol.language; special = symbol.special; } MtxSymbol::~MtxSymbol() { if (value != NULL) delete value; } MtxSymbol & MtxSymbol::operator=(const MtxSymbol &symbol) { if (this != &symbol) { name = symbol.name; if (value != NULL) delete value; if (symbol.value == NULL) value = NULL; else value = symbol.value->clone(); language = symbol.language; special = symbol.special; } return *this; } void MtxSymbol::setSpecial() { if (name.length() == 0) special = false; else { size_t i; i = 0; do { if (special_names[i].name == NULL) { special = false; break; } else if (name == special_names[i].name) { special = true; break; } i++; } while (true); } } size_t MtxSymbol::getSpecial() const { size_t i; if (special == false) throw MtxException("MtxSymbol::getSpecial() called whereas this->special " "is false"); i = 0; do { if (name == special_names[i].name) return i; i++; } while(true); } MtxSymbol MtxSymbol::getSymbol(bool create, bool fail_if_special) const { if (special) { if (fail_if_special) throw MtxException("invalid use of special name in expression"); else return *this; } if (name.length() == 0 && create) throw MtxException("invalid lvalue"); if (!create) { if (name.length() == 0) return *this; else return language->getSymbol(name); } else { language->setSymbol(*this); return *this; } } string MtxSymbol::getName() const { return name; } void MtxSymbol::setName(const string &name) { this->name = name; } MtxValue * MtxSymbol::getValue() const { return value; } string MtxSymbol::toString() const { if (name.length() == 0) { if (value == NULL) throw MtxException("null value"); return value->toString(); } else { if (special) return special_names[getSpecial()].function(this); else return language->getSymbol(name).value->toString(); } } bool MtxSymbol::isSilent() const { throw MtxException("MtxSymbol->isSilent() should never be called"); } bool MtxSymbol::isSpecial() const { return special; } MtxLanguage * MtxSymbol::getLanguage() const { return language; }