Hey all,
Its 2am im a little sleepy so I may be missing something elementary here;
I have calculator from the relisoft site that ive been modifying.
Code:
main
{input
scanner
parser}
Been modifying it to implement complex numbers, using the <complex> standard with c++.
So far so good; it can evaluate expressions like : (5 + j)/(5 + 16j) etc correctly.
The program im modifying has a symbaltable where it has a list of functions, ive gone through every single declared double and checked to make sure its complex<double> now, but still when it tries to use any of the functions in the table:
Code:
symtab.cpp:57: error: invalid conversion from `double (*)(double) throw ()' to
`std::complex<double> (*)(std::complex<double>)'
Looked in stroustrups book, and the normal, cos, sin, exp functions are built in, cant understand why I cant change all the double types to complex and use the existing program structure? It works with operators... but functions... nope.
Perhaps vague description, however whenever I post code, the nice people here go ahead and code the whole thing, which is more than what I need, and more of your time than I want to take.
A suggestion as to what I may be overlooking would be fine.
Edit: In case its too vague,
symtab.cpp:
Code:
//------------------------------------
// symtab.cpp
// (c) Bartosz Milewski, 1994
//------------------------------------
#include "symtab.h"
#include <cassert>
#include <cstring>
#include <iostream>
#include <complex>
using std::complex;
using std::cout;
using std::endl;
complex<double> CoTan (complex<double> x)
{
complex<double> y = tan (x);
if (y.real() == 0)
{
cout << "cotan of " << x << " undefined\n";
return HUGE_VAL;
}
return 1.0 / y;
} //do this for other funs
complex<double> cos (complex<double> x)
{
complex<double> y = cos (x);
if (y.real() == 0)
{
cout << "cotan of " << x << " undefined\n";
return HUGE_VAL;
}
return 1.0 / y;
} //do this for other funs
FunctionEntry funArr [maxIdFun] =
{
// log, "log",
// log10,"log10",
// exp, "exp",
// sqrt, "sqrt",
// sin, "sin",
// cos, "cos",
// tan, "tan",
CoTan,"cotan",
// sinh, "sinh",
// cosh, "cosh",
// tanh, "tanh",
// asin, "asin",
// acos, "acos",
// atan, "atan",
0, ""
};
FunctionTable::FunctionTable (SymbolTable & symTab, FunctionEntry funArr [])
: _size(0)
{
for (int i = 0; i < maxIdFun; ++i)
{
int len = strlen (funArr [i].strFun);
if (len == 0)
break;
_pFun [i] = funArr [i].pFun;
cout << funArr[i].strFun << endl;
int j = symTab.ForceAdd (funArr[i].strFun, len);
assert (i == j);
++_size;
}
}
List::List ()
: _pHead(0)
{}
List::~List ()
{
// free linked list
while (_pHead != 0)
{
Link * pLink = _pHead;
_pHead = _pHead->Next();
delete pLink;
}
}
void List::Add (int id)
{
// add in front of the list
Link * pLink = new Link (_pHead, id);
_pHead = pLink;
}
// Find the list in hash table that may contain
// the id of the string we are looking for
List const & HTable::Find (char const * str, int len) const
{
int i = hash (str, len);
assert (i >= 0 && i < _size);
return _aList [i];
}
void HTable::Add (char const * str, int len, int id)
{
int i = hash (str, len);
assert (i >= 0 && i < _size);
_aList [i].Add (id);
}
// Private hashing function
int HTable::hash (char const * str, int len) const
{
// no empty strings, please
assert (len != 0);
// must be unsigned, hash should return positive number
unsigned h = str [0];
for (int i = 1; i < len; ++i)
h = (h << 4) + str [i];
return h % _size; // small positive integer
}
SymbolTable::SymbolTable (int size)
: _size (size), _curId (0), _curStrOff (0), _htab (size + 1)
{
_offStr = new int [size];
_bufSize = size * 10;
_strBuf = new char [_bufSize];
}
SymbolTable::~SymbolTable()
{
delete []_offStr;
delete []_strBuf;
}
// Add string without looking for duplicates
int SymbolTable::ForceAdd (char const * str, int len)
{
// is there enough space?
if (_curId == _size
|| _curStrOff + len + 1 >= _bufSize)
{
return idNotFound;
}
// point to place where the string will be stored
_offStr [_curId] = _curStrOff;
// copy the string there
strncpy (&_strBuf [_curStrOff], str, len);
// calculate new offset
_curStrOff += len;
_strBuf [_curStrOff] = 0; // null terminate
++_curStrOff;
// add to hash table
_htab.Add (str, len, _curId);
++_curId;
return _curId - 1;
}
int SymbolTable::Find (char const * str, int len) const
{
// Get a short list from hash table
List const & list = _htab.Find (str, len);
// Iterate over this list
for (Link const * pLink = list.GetHead ();
pLink != 0;
pLink = pLink->Next () )
{
int id = pLink->Id ();
int offStr = _offStr [id];
// char const * strStored = &_strBuf [ offStr ];
char const * strStored = _strBuf + offStr;
if (strcmp (str, strStored) == 0) // they're equal
{
return id; // success!
}
}
return idNotFound;
}
// map integer into string. Must be valid id
char const * SymbolTable::GetString (int id) const
{
assert (id >= 0);
assert (id < _curId);
int offStr = _offStr [id];
return &_strBuf [offStr];
// return _strBuf + offStr;
}
symtab.h:
Code:
#if !defined SYMTAB_H
#define SYMTAB_H
//------------------------------------
// symtab.h
// (c) Bartosz Milewski, 1994
//------------------------------------
#include <cstring>
#include <complex>
using std::complex;
const int maxIdFun = 16;
typedef complex<double> (*PFun) (complex<double> x);
class FunctionEntry
{
public:
PFun pFun;
char* strFun;
};
extern FunctionEntry funArr [];
class SymbolTable;
class FunctionTable
{
public:
FunctionTable (SymbolTable& symTab, FunctionEntry funArr []);
int Size () const { return _size; }
PFun GetFun (int id) { return _pFun [id]; }
private:
PFun _pFun [maxIdFun];
int _size;
};
// stores integer id in a link
class Link
{
public:
Link (Link * pNext, int id)
: _pNext (pNext), _id (id) {}
Link * Next () const { return _pNext; }
int Id () const { return _id; }
private:
Link * _pNext;
int _id;
};
// Linked list of id's stored in links
class List
{
public:
List ();
~List ();
void Add (int id);
Link const * GetHead () const { return _pHead; }
private:
Link * _pHead;
};
// Hash table of strings
class HTable
{
public:
explicit HTable (int size): _size(size)
{
_aList = new List[size];
}
~HTable ()
{
delete [] _aList;
}
List const & Find (char const * str, int len) const;
List const & Find (char const * str) const
{
return Find (str, strlen (str));
}
void Add (char const * str, int len, int id);
void Add (char const * str, int id)
{
Add (str, strlen (str), id);
}
private:
int hash (char const * str, int len) const;
List * _aList;
int _size;
};
const int idNotFound = -1;
// String table maps strings to ints
// and ints to strings
class SymbolTable
{
public:
explicit SymbolTable (int size);
~SymbolTable ();
int ForceAdd (char const * str, int len);
int Find (char const * str, int len) const;
char const * GetString (int id) const;
private:
HTable _htab;
int * _offStr; // offsets of strings in buffer
int _size;
int _curId;
char * _strBuf;
int _bufSize;
int _curStrOff;
};
#endif