1 /*$Id: m_base.h,v 26.138 2013/04/24 02:32:27 al Exp $ -*- C++ -*-
2  * Copyright (C) 2003 Albert Davis
3  * Author: Albert Davis <aldavis@gnu.org>
4  *
5  * This file is part of "Gnucap", the Gnu Circuit Analysis Package
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301, USA.
21  *------------------------------------------------------------------
22  */
23 //testing=script,sparse 2009.08.13
24 #ifndef BASE_H_INCLUDED
25 #define BASE_H_INCLUDED
26 #include "l_lib.h"
27 #include "ap.h"
28 #include "constant.h"
29 /*--------------------------------------------------------------------------*/
30 class Float;
31 class String;
32 /*--------------------------------------------------------------------------*/
33 class Base
34 {
35 private:
Base(const Base &)36   explicit Base(const Base&) {unreachable();}
37   // This private base copy constructor inhibits generation of
38   // copy constructors for its derived classes.
39 protected:
Base()40   explicit Base() {}
41 public:
42   virtual void parse(CS&) = 0;
43   virtual void dump(std::ostream& o)const = 0;
~Base()44   virtual ~Base() {}
val_string()45   virtual std::string val_string()const		{untested(); return "error";}
to_bool()46   virtual bool to_bool()const			{unreachable(); return false;}
47 
minus()48   virtual Base* minus()const			{untested(); return NULL;}
plus()49   virtual Base* plus()const			{untested(); return NULL;}
50 
less(const Base *)51   virtual Base* less(const Base*)const		{untested(); return NULL;}
less(const Float *)52   virtual Base* less(const Float*)const		{untested(); return NULL;}
less(const String *)53   virtual Base* less(const String*)const	{untested(); return NULL;}
greater(const Base *)54   virtual Base* greater(const Base*)const	{untested(); return NULL;}
greater(const Float *)55   virtual Base* greater(const Float*)const	{untested(); return NULL;}
greater(const String *)56   virtual Base* greater(const String*)const	{untested(); return NULL;}
leq(const Base *)57   virtual Base* leq(const Base*)const		{untested(); return NULL;}
leq(const Float *)58   virtual Base* leq(const Float*)const		{untested(); return NULL;}
leq(const String *)59   virtual Base* leq(const String*)const 	{untested(); return NULL;}
geq(const Base *)60   virtual Base* geq(const Base*)const		{untested(); return NULL;}
geq(const Float *)61   virtual Base* geq(const Float*)const		{untested(); return NULL;}
geq(const String *)62   virtual Base* geq(const String*)const 	{untested(); return NULL;}
not_equal(const Base *)63   virtual Base* not_equal(const Base*)const	{untested(); return NULL;}
not_equal(const Float *)64   virtual Base* not_equal(const Float*)const	{untested(); return NULL;}
not_equal(const String *)65   virtual Base* not_equal(const String*)const	{untested(); return NULL;}
equal(const Base *)66   virtual Base* equal(const Base*)const		{untested(); return NULL;}
equal(const Float *)67   virtual Base* equal(const Float*)const	{untested(); return NULL;}
equal(const String *)68   virtual Base* equal(const String*)const	{untested(); return NULL;}
add(const Base *)69   virtual Base* add(const Base*)const		{untested(); return NULL;}
add(const Float *)70   virtual Base* add(const Float*)const		{untested(); return NULL;}
add(const String *)71   virtual Base* add(const String*)const		{untested(); return NULL;}
multiply(const Base *)72   virtual Base* multiply(const Base*)const	{untested(); return NULL;}
multiply(const Float *)73   virtual Base* multiply(const Float*)const	{untested(); return NULL;}
multiply(const String *)74   virtual Base* multiply(const String*)const	{untested(); return NULL;}
subtract(const Base *)75   virtual Base* subtract(const Base*)const	{untested(); return NULL;}
subtract(const Float *)76   virtual Base* subtract(const Float*)const	{untested(); return NULL;}
subtract(const String *)77   virtual Base* subtract(const String*)const	{untested(); return NULL;}
r_subtract(const Base *)78   virtual Base* r_subtract(const Base*)const	{untested(); return NULL;}
r_subtract(const Float *)79   virtual Base* r_subtract(const Float*)const	{untested(); return NULL;}
r_subtract(const String *)80   virtual Base* r_subtract(const String*)const	{untested(); return NULL;}
divide(const Base *)81   virtual Base* divide(const Base*)const	{untested(); return NULL;}
divide(const Float *)82   virtual Base* divide(const Float*)const	{untested(); return NULL;}
divide(const String *)83   virtual Base* divide(const String*)const	{untested(); return NULL;}
r_divide(const Base *)84   virtual Base* r_divide(const Base*)const	{untested(); return NULL;}
r_divide(const Float *)85   virtual Base* r_divide(const Float*)const	{untested(); return NULL;}
r_divide(const String *)86   virtual Base* r_divide(const String*)const	{untested(); return NULL;}
87 
88   Base* logic_not()const;
89   Base* logic_or(const Base* X)const;
90   Base* logic_and(const Base* X)const;
91 };
92 inline CS&	     operator>>(CS& f, Base& b)	{untested();b.parse(f); return f;}
93 inline std::ostream& operator<<(std::ostream& out, const Base& d)
94 					{d.dump(out); return out;}
95 /*--------------------------------------------------------------------------*/
96 template <class T>
97 class List_Base
98   :public Base
99 {
100 private:
101   std::list<T*> _list;
102 public:
103   virtual void parse(CS& f) = 0;
104 protected:
105   virtual void dump(std::ostream& o)const;
106   virtual ~List_Base();
List_Base()107   explicit List_Base() {}
List_Base(const List_Base & p)108   explicit List_Base(const List_Base& p) : Base(), _list(p._list) {untested();}
109 public:
110   typedef typename std::list<T*>::const_iterator const_iterator;
is_empty()111   bool		 is_empty()const {return _list.empty();}
size()112   size_t	 size()const	 {return _list.size();}
begin()113   const_iterator begin()const	 {return _list.begin();}
end()114   const_iterator end()const	 {return _list.end();}
front()115   const T*	 front()const	 {untested();assert(!is_empty()); return _list.front();}
back()116   const T*	 back()const	 {assert(!is_empty()); return _list.back();}
back()117   T*		 back()		 {assert(!is_empty()); return _list.back();}
push_back(T * x)118   void		 push_back(T* x) {assert(x);	       _list.push_back(x);}
pop_back()119   void  	 pop_back()	 {assert(!is_empty()); _list.pop_back();}
120 };
121 /*--------------------------------------------------------------------------*/
122 template <class T>
123 class List
124   :public List_Base<T>
125 {
126 protected:
List()127   explicit List() {untested();}
128 public:
129   void parse(CS& f);
130 };
131 /*--------------------------------------------------------------------------*/
132 #if 0
133 template <class T>
134 class Collection
135   :public List_Base<T>
136 {
137 protected:
138   explicit Collection() {untested();}
139 public:
140   void parse(CS& f);
141 };
142 #endif
143 /*--------------------------------------------------------------------------*/
144 class Float
145   :public Base
146 {
147 private:
148   double _data;
dump(std::ostream & o)149   void dump(std::ostream& o)const {itested();
150     if (_data==NOT_INPUT) {untested();
151       o<<"NA";
152     }else{itested();
153       o<<_data;
154     }
155   }
156 public:
Float(const Float & p)157   /*implicit*/ Float(const Float& p) :Base(), _data(p._data) {untested();}
Float(CS & file)158   explicit Float(CS& file)		{untested();parse(file);}
Float(const std::string & s)159   explicit Float(const std::string& s)	{CS cs(CS::_STRING, s); parse(cs);}
_data(x)160   Float(double x=NOT_INPUT) :_data(x) {}
161   void parse(CS&);
value()162   double value()const			{return _data;}
163   operator double()const		{untested();return _data;}
val_string()164   std::string val_string()const		{return ftos(_data, 0, 15, ftos_EXP);}
to_bool()165   bool to_bool()const			{return (_data != 0);}
166 
minus()167   Base* minus()const			{return new Float(-_data);}
plus()168   Base* plus()const			{return new Float(_data);}
169 
less(const Float * X)170   Base* less(const Float* X)const	{assert(X); return new Float((_data < X->_data)?1.:0.);}
greater(const Float * X)171   Base* greater(const Float* X)const	{assert(X); return new Float((_data > X->_data)?1.:0.);}
leq(const Float * X)172   Base* leq(const Float* X)const	{assert(X); return new Float((_data <= X->_data)?1.:0.);}
geq(const Float * X)173   Base* geq(const Float* X)const	{assert(X); return new Float((_data >= X->_data)?1.:0.);}
not_equal(const Float * X)174   Base* not_equal(const Float* X)const	{assert(X); return new Float((_data != X->_data)?1.:0.);}
equal(const Float * X)175   Base* equal(const Float* X)const	{assert(X); return new Float((_data == X->_data)?1.:0.);}
add(const Float * X)176   Base* add(const Float* X)const	{assert(X); return new Float(_data + X->_data);}
multiply(const Float * X)177   Base* multiply(const Float* X)const	{assert(X); return new Float(_data * X->_data);}
subtract(const Float * X)178   Base* subtract(const Float* X)const	{untested();assert(X); return new Float(_data - X->_data);}
r_subtract(const Float * X)179   Base* r_subtract(const Float* X)const	{assert(X); return new Float(X->_data - _data);}
divide(const Float * X)180   Base* divide(const Float* X)const	{untested();assert(X); return new Float(_data / X->_data);}
r_divide(const Float * X)181   Base* r_divide(const Float* X)const	{assert(X); return new Float(X->_data / _data);}
182 
less(const Base * X)183   Base* less(const Base* X)const	{return ((X) ? (X->greater(this))   : (NULL));}
greater(const Base * X)184   Base* greater(const Base* X)const	{return ((X) ? (X->less(this))      : (NULL));}
leq(const Base * X)185   Base* leq(const Base* X)const		{return ((X) ? (X->geq(this))       : (NULL));}
geq(const Base * X)186   Base* geq(const Base* X)const		{return ((X) ? (X->leq(this))       : (NULL));}
not_equal(const Base * X)187   Base* not_equal(const Base* X)const	{return ((X) ? (X->not_equal(this)) : (NULL));}
equal(const Base * X)188   Base* equal(const Base* X)const	{return ((X) ? (X->equal(this))	    : (NULL));}
add(const Base * X)189   Base* add(const Base* X)const 	{return ((X) ? (X->add(this))       : (NULL));}
multiply(const Base * X)190   Base* multiply(const Base* X)const	{return ((X) ? (X->multiply(this))  : (NULL));}
subtract(const Base * X)191   Base* subtract(const Base* X)const	{return ((X) ? (X->r_subtract(this)): (NULL));}
r_subtract(const Base * X)192   Base* r_subtract(const Base* X)const	{untested();return ((X) ? (X->subtract(this))  : (NULL));}
divide(const Base * X)193   Base* divide(const Base* X)const	{return ((X) ? (X->r_divide(this))  : (NULL));}
r_divide(const Base * X)194   Base* r_divide(const Base* X)const	{untested();return ((X) ? (X->divide(this))    : (NULL));}
195 
less(const String *)196   Base* less(const String*)const	{untested();return NULL;}
greater(const String *)197   Base* greater(const String*)const	{untested();return NULL;}
leq(const String *)198   Base* leq(const String*)const 	{untested();return NULL;}
geq(const String *)199   Base* geq(const String*)const 	{untested();return NULL;}
not_equal(const String *)200   Base* not_equal(const String*)const	{untested();return NULL;}
equal(const String *)201   Base* equal(const String*)const	{untested();return NULL;}
add(const String *)202   Base* add(const String*)const 	{           return NULL;}
multiply(const String *)203   Base* multiply(const String*)const	{untested();return NULL;}
subtract(const String *)204   Base* subtract(const String*)const	{untested();return NULL;}
r_subtract(const String *)205   Base* r_subtract(const String*)const	{untested();return NULL;}
divide(const String *)206   Base* divide(const String*)const	{untested();return NULL;}
r_divide(const String *)207   Base* r_divide(const String*)const	{	    return NULL;}
208 
is_NA()209   bool  is_NA()const			{untested();return _data == NOT_INPUT;}
210 };
211 /*--------------------------------------------------------------------------*/
212 class String
213   :public Base
214 {
215 protected:
216   std::string _data;
217 public:
parse(CS &)218   void parse(CS&) {unreachable(); incomplete();}
219 private:
dump(std::ostream & o)220   void dump(std::ostream& o)const {untested();o << _data;}
221 public:
String(CS & file)222   explicit String(CS& file) {untested();parse(file);}
String()223   explicit String()	    {}
String(const std::string & s)224   explicit String(const std::string& s) :_data(s) {}
225   operator const std::string&()const	{return _data;}
val_string()226   std::string val_string()const		{untested();return _data;}
to_bool()227   bool to_bool()const			{untested();return (_data != "");}
228 
minus()229   Base* minus()const			{untested(); return NULL;}
plus()230   Base* plus()const			{untested(); return NULL;}
231 
less(const String * X)232   Base* less(const String* X)const	{untested();assert(X); return new Float((_data < X->_data)?1.:0.);}
greater(const String * X)233   Base* greater(const String* X)const	{untested();assert(X); return new Float((_data > X->_data)?1.:0.);}
leq(const String * X)234   Base* leq(const String* X)const	{untested();assert(X); return new Float((_data <= X->_data)?1.:0.);}
geq(const String * X)235   Base* geq(const String* X)const	{untested();assert(X); return new Float((_data >= X->_data)?1.:0.);}
not_equal(const String * X)236   Base* not_equal(const String* X)const	{untested();assert(X); return new Float((_data != X->_data)?1.:0.);}
equal(const String * X)237   Base* equal(const String* X)const	{untested();assert(X); return new Float((_data == X->_data)?1.:0.);}
add(const String *)238   Base* add(const String*)const		{	     return NULL;}
multiply(const String *)239   Base* multiply(const String*)const	{untested(); return NULL;}
subtract(const String *)240   Base* subtract(const String*)const	{untested(); return NULL;}
r_subtract(const String *)241   Base* r_subtract(const String*)const	{untested(); return NULL;}
divide(const String *)242   Base* divide(const String*)const	{untested(); return NULL;}
r_divide(const String *)243   Base* r_divide(const String*)const	{untested(); return NULL;}
244 
less(const Base * X)245   Base* less(const Base* X)const	{untested();return ((X) ? (X->greater(this))   : (NULL));}
greater(const Base * X)246   Base* greater(const Base* X)const	{untested();return ((X) ? (X->less(this))      : (NULL));}
leq(const Base * X)247   Base* leq(const Base* X)const		{untested();return ((X) ? (X->geq(this))       : (NULL));}
geq(const Base * X)248   Base* geq(const Base* X)const		{untested();return ((X) ? (X->leq(this))       : (NULL));}
not_equal(const Base * X)249   Base* not_equal(const Base* X)const	{untested();return ((X) ? (X->not_equal(this)) : (NULL));}
equal(const Base * X)250   Base* equal(const Base* X)const	{untested();return ((X) ? (X->equal(this))     : (NULL));}
add(const Base * X)251   Base* add(const Base* X)const 	{	    return ((X) ? (X->add(this))       : (NULL));}
multiply(const Base * X)252   Base* multiply(const Base* X)const	{untested();return ((X) ? (X->multiply(this))  : (NULL));}
subtract(const Base * X)253   Base* subtract(const Base* X)const	{untested();return ((X) ? (X->r_subtract(this)): (NULL));}
r_subtract(const Base * X)254   Base* r_subtract(const Base* X)const	{untested();return ((X) ? (X->subtract(this))  : (NULL));}
divide(const Base * X)255   Base* divide(const Base* X)const	{	    return ((X) ? (X->r_divide(this))  : (NULL));}
r_divide(const Base * X)256   Base* r_divide(const Base* X)const	{untested();return ((X) ? (X->divide(this))    : (NULL));}
257 
less(const Float *)258   Base* less(const Float*)const 	{untested();return NULL;}
greater(const Float *)259   Base* greater(const Float*)const	{untested();return NULL;}
leq(const Float *)260   Base* leq(const Float*)const  	{untested();return NULL;}
geq(const Float *)261   Base* geq(const Float*)const  	{untested();return NULL;}
not_equal(const Float *)262   Base* not_equal(const Float*)const	{untested();return NULL;}
equal(const Float *)263   Base* equal(const Float*)const	{untested();return NULL;}
add(const Float *)264   Base* add(const Float*)const  	{           return NULL;}
multiply(const Float *)265   Base* multiply(const Float*)const	{untested();return NULL;}
subtract(const Float *)266   Base* subtract(const Float*)const	{untested();return NULL;}
r_subtract(const Float *)267   Base* r_subtract(const Float*)const	{untested();return NULL;}
divide(const Float *)268   Base* divide(const Float*)const	{untested();return NULL;}
r_divide(const Float *)269   Base* r_divide(const Float*)const	{untested();return NULL;}
270 };
271 /*--------------------------------------------------------------------------*/
272 class Name_String	// a string that contains only alnum and _[]
273   :public String
274 {
275 public:
276   void parse(CS&);
277 public:
Name_String(CS & file)278   explicit Name_String(CS& file)	{parse(file);}
Name_String()279   explicit Name_String()		{untested();}
280 };
281 /*--------------------------------------------------------------------------*/
282 class Quoted_String	// the first non-blank character is a quote
283   :public String	// a repeat of the same character terminates it
284 {
285 public:
286   void parse(CS&);
287 public:
Quoted_String(CS & file)288   explicit Quoted_String(CS& file)	{untested();parse(file);}
Quoted_String()289   explicit Quoted_String()		{untested();}
290 };
291 /*--------------------------------------------------------------------------*/
292 class Tail_String	// a string that is parsed to the end of a line
293   :public String
294 {
295 public:
296   void parse(CS&);
Tail_String(CS & file)297   explicit Tail_String(CS& file)	{untested();parse(file);}
Tail_String()298   explicit Tail_String()		{untested();}
299 };
300 
301 /*--------------------------------------------------------------------------*/
302 /*--------------------------------------------------------------------------*/
303 template <class T>
~List_Base()304 List_Base<T>::~List_Base()
305 {
306   for (typename std::list<T*>::iterator
307 	  i = _list.begin(); i != _list.end(); ++i) {
308     assert(*i);
309     delete *i;
310   }
311 }
312 /*--------------------------------------------------------------------------*/
313 template <class T>
dump(std::ostream & Out)314 void List_Base<T>::dump(std::ostream& Out)const
315 {untested();
316   for (const_iterator i = begin(); i != end(); ++i) {untested();
317     assert(*i);
318     Out << **i;
319   }
320 }
321 /*--------------------------------------------------------------------------*/
322 template <class T>
parse(CS & File)323 void List<T>::parse(CS& File)
324 {untested();
325   //skip_comment(File);
326   unsigned here = File.cursor();
327   for (;;) {untested();
328     if (File.match1('[')) {untested();
329       break;
330     }else{untested();
331       T* x = new T(File);
332       if (!File.stuck(&here)) {untested();
333 	push(x);
334       }else{untested();
335 	delete x;
336 	File.warn(0, "what's this? (List)");
337 	break;
338       }
339       //skip_comment(File);
340     }
341   }
342 }
343 /*--------------------------------------------------------------------------*/
344 #if 0
345 template <class T>
346 void Collection<T>::parse(CS& File)
347 {untested();
348   unsigned here = File.cursor();
349   T* m = new T(File);
350   if (!File.stuck(&here)) {untested();
351     push(m);
352   }else{untested();
353     delete m;
354     File.warn(0, "what's this? (Collection)");
355   }
356 }
357 #endif
358 /*--------------------------------------------------------------------------*/
359 /*--------------------------------------------------------------------------*/
360 /*--------------------------------------------------------------------------*/
361 #endif
362