masz przykład, przed chwilą napisałem na szybko:
#include <iostream>
#include <stack>
#include <string>
#include <map>
#define ASSIGN(a) trans[#a] = a;
typedef std::stack<int> stack;
using std::cin;
using std::cout;
using std::string;
using std::endl;
typedef int (*func)(stack);
typedef std::map<string,func> transmap;
transmap trans;
bool error = false;
bool terminate = false;
int suma(stack s)
{
int sum = 0;
while (!s.empty())
{
sum+=s.top();
s.pop();
}
return sum;
}
int roznica(stack s)
{
if (s.size()!=2)
{
cout << "Zla ilosc parametrow!\n";
error = true;
return 0;
}
// trzeba pamietac ze parametry na stosie sa w odwrotnej kolejnosci
int sum = -s.top();
s.pop();
sum+= s.top();
return sum;
}
int wypisz(stack s)
{
cout << "Ta funkcja nic nie robi poza wypisaniem tego tekstu.\n";
return 0;
}
int koniec(stack s)
{
terminate = true;
}
// http://www.codeproject.com/KB/stl/stdstringtrim.aspx
void trim(string& str)
{
string::size_type pos = str.find_last_not_of(' ');
if(pos != string::npos) {
str.erase(pos + 1);
pos = str.find_first_not_of(' ');
if(pos != string::npos) str.erase(0, pos);
}
else str.erase(str.begin(), str.end());
}
// nie sprawdza czy liczba nie jest za dluga
bool try_convert(string& s, int& num)
{
//cout << "debug: try_convert: s=XX" << s << "XX" << endl; // <-- zeby bylo biale znaki widac
trim(s);
//cout << "debug: try_convert: s=XX" << s << "XX" << endl;
if (s.size()==0)
return false;
const char* p = s.c_str();
bool neg = false;
if (*p == '-')
{
neg=true;
++p;
}
num = 0;
while (*p)
{
if (*p<'0' || *p>'9')
return false;
num *= 10;
num += *p - '0';
++p;
}
if (neg)
num = -num;
return true;
}
bool call_func(const string& s)
{
string func_name;
string func_params;
size_t p = s.find_first_of('(');
size_t r = s.find_last_of(')');
if (p==string::npos || r==string::npos || p>r)
return false;
func_name = s.substr(0,p);
func_params = s.substr(p+1, r-p-1);
trim(func_name);
//cout << "debug: func_name=" << func_name << endl;
//cout << "debug: func_params=" << func_params << endl;
transmap::iterator it = trans.find(func_name);
if (it==trans.end())
return false;
//cout << "debug: doszedlem tu" << endl;
stack st;
string param;
int par;
while (1) // func_params.size()!=0
{
p = func_params.find_first_of(',');
if (p==string::npos)
{
//cout << "debug: func_params=" << func_params << endl;
trim(func_params);
if (func_params.size()==0)
break;
if (!try_convert(func_params, par))
return false;
st.push(par);
break;
}
param = func_params.substr(0, p);
//cout << "debug: param=" << param << endl;
if (!try_convert(param, par))
return false;
st.push(par);
func_params = func_params.erase(0, p+1);
}
int ret = it->second(st);
cout << "Funkcja zwrocila: " << ret << endl;
if (error)
return false;
return true;
}
int main()
{
ASSIGN(suma);
ASSIGN(roznica);
ASSIGN(wypisz);
ASSIGN(koniec);
string s;
while(!terminate)
{
cout << "> ";
std::getline(cin, s, '\n');
if (!call_func(s))
break;
cout << endl;
}
if (!terminate)
cout << "\n\nProgram zakonczyl sie, bo:\npodales nieprawidlowa nazwe funkcji,\nzle ja wywolales\nlub wystapil blad w funkcji!" << endl;
return 0;
}
po włączeniu wpisujesz jedną z nazw funkcji:
suma(1,2,3,4)
roznica(7,5)
wypisz()
koniec()
suma moze miec dowolna liczbe parametrow: liczby calkowite (int)
roznica musi miec dokladnie 2 parametry
wypisz moze miec dowolna liczbe parametrow bo je ignoruje
koniec dow. liczba parm. - wylacza program
zla nazwa funkcji lub nieprawidlowe argumenty spowoduja wylaczenie programu (celowe). funkcje ladnie widac jak dodawac samemu.