Il programmino non è completo, ma intanto fatti un'idea.
Manca un analizzatore di sintassi ma andrebbe anche migliorata la gestione degli errori, e queste sono due pecche che vanno aggiustate.
Un'altra cosa: avevo pensato di utilizzare le funzioni di libreria che fornisce la Borland (sotto forma di sorgenti c-asm) col compilatore per basare il tutto sui long double, così anche se non sono portabili si hanno a disposizione i sorgenti.
Tra l'altro così facendo si può implementare una gestione degli errori tutta personalizzata per il programma: non mi piace che se faccio log(-10) mi vedo scritto a video "DOMAIN error", me lo devo gestire IO!!
Ed ecco il main:
codice:
/******************************************\
|* Analizzatore di Formule matematiche *|
|* e funzioni analitiche trascendenti *|
|* *|
|* by SnakePlissken *|
|* aka AntonioMacrì *|
\******************************************/
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <dos.h>
#include "ExprEval.c"
void visualizzaOperazioni(void);
void calcolaFormule(void);
int main() {
char scelta;
while(1) {
clrscr();
printf("\n%80s\n", "Analizzatore di formule matematiche - SnakePlissken ");
printf("\n Menu principale\n\n");
printf(" 1. Visualizza operazioni disponibili\n");
printf(" 2. Calcola formule\n");
printf(" 3. Esci\n");
do
scelta = getch();
while(scelta!='1' && scelta!='2' && scelta!='3');
switch(scelta) {
case '1':
visualizzaOperazioni();
break;
case '2':
calcolaFormule();
break;
case '3':
return(0);
}
}
}
void visualizzaOperazioni(void) {
clrscr();
printf( "\n\n1. Operatori binari:\n\n"
" + Esegue la somma\n"
" - Esegue la sottrazione\n"
" / Esegue la divisione\n"
" * Esegue la moltiplicazione\n"
" ^ Eleva alla potenza\n"
" % Calcola il modulo (il resto della divisione)\n");
printf("\nPremi un tasto per visualizzare le funzioni aggiuntive...\n");
getch();
printf("\n\n2. Funzioni aggiuntive:\n\n"
" Funzioni logaritmiche:\n"
" ln(N) Calcola il logaritmo naturale (in base e) di N\n"
" log(N) Calcola il logaritmo decimale di N\n"
" log(b,N) Calcola il logaritmo in base b di N\n\n");
printf(" Funzioni Trigonometriche:\n"
" sin(a) Calcola il seno dell'angolo a misurato in radianti\n"
" cos() Coseno\n"
" tan() Tangente\n"
" sec() Secante\n"
" cot() Cotangente\n"
" cosec() Cosecante\n"
" Varianti:\n"
" a- Calcola l'arco- {-seno, -coseno, -tangente, ...}\n"
" -h Calcola il {seno-, coseno-, tangente-, ...} iperbolico\n"
" Esempio:\n"
" acosh(.5) Calcola l'arcocoseno iperbolico di un angolo di 0.5 radianti\n");
printf("\nPremi un tasto per visualizzare le altre funzioni...\n");
getch();
printf("\n\n Altre funzioni:\n"
" exp(N) Funzione esponenziale (calcola e^N)\n"
" d2r() Converte i gradi in radianti\n"
" sqrt() Calcola la radice quadrata\n"
" cbrt() Calcola la radice cubica\n"
" root(n,x) Calcola la radice n-esima di x\n"
" fact() Calcola il fattoriale\n"
" fibo() Calcola il numero di Fibonacci\n");
printf("\nPremi un tasto per visualizzare le costanti disponibili...\n");
getch();
printf("\n\n3. Costanti:\n\n"
" PI Valore del Pi greco ã\n"
" E Valore di e\n");
printf("\n\n\nNB: I parametri da passare alle funzioni vanno sempre messi tra parentesi.");
printf("\n Nell'uso di costanti, il loro nome deve essere preceduto da un '#'.");
getch();
}
#define START 1
#define ELAPSEDTIME 2
double timeCounter(int todo) {
static struct time t1;
if (todo == START) {
gettime(&t1);
}
else {
struct time t2;
double dt1, dt2;
gettime(&t2);
dt1 = t1.ti_hour*360000 + t1.ti_min*6000 + t1.ti_sec*100 + t1.ti_hund;
dt2 = t2.ti_hour*360000 + t2.ti_min*6000 + t2.ti_sec*100 + t2.ti_hund;
return((dt2-dt1)/100);
}
return(0);
}
void calcolaFormule(void) {
char expr[150];
double result, time;
errorType *err;
clrscr();
printf("\n\nInserisci una formula:\n");
while(gets(expr)[0]) {
printf(" Sto calcolando... ");
timeCounter(START);
err = EvaluateExpression(expr, &result);
time = timeCounter(ELAPSEDTIME);
gotoxy(1, wherey());
clreol();
switch (err->flag) {
case 0:
printf(" Risultato: %lG\n", result);
if(time > 3.0L)
printf(" Tempo impiegato: %lG sec\n", time);
break;
case INVALP:
printf(" Errore:\n %s: Parametro non valido!\n", err->funct);
break;
case DOMAIN:
printf(" Errore:\n %s: Valore fuori dal dominio della funzione!\n", err->funct);
break;
case SYNTAXERROR:
printf(" Errore di Sintassi!\n");
}
printf("\n\nInserisci un'altra formula:\n");
}
}