compiler une fonction avec giac

Librairie C++ de calcul formel/ C++ symbolic computation library

Modérateur : xcasadmin

cdeval
Messages : 192
Inscription : mer. juin 03, 2009 4:28 pm

compiler une fonction avec giac

Message par cdeval » dim. mars 21, 2010 11:10 pm

Bonjour Bernard,

je suis en train d'ajouter la possibilité de créer ses propres fonctions faisant appel à giac dans OOo à partir d'une boite de dialogue.
Ces fonctions seront alors utilisables dans le tableur en passant des cellules comme paramètres (j'exploite une fonctionnalité de OOo qui permet d'ajouter une fonction définie par un programme écrit en OOoBasic).
Cela me demande peu d'effort de programmation puisque j'ai juste à passer à giac ma chaine de caractère définissant ma fonction.
Mais le retour que j'obtiens après évaluation de ma commande est incomplet.
Par exemple je teste :

Code : Tout sélectionner

test(a):={return(a+1)}
une fenetre de commande giac me renvoie bien :

Code : Tout sélectionner

// Parsing test
// Success compiling test
 (a)->{ 
  return(a+1);  
}
mais si je l'appelle avec ma commande (dans mon code C++ : e=giac::eval(e,contextptr);), alors je n'ai pas le premier commentaire "success compiling". Je récupère juste :

Code : Tout sélectionner

 (a)->{ 
  return(a+1);  
}
c'est plus gênant quand il y a une erreur de compilation avec par exemple :

Code : Tout sélectionner

test(a):=return(a+1)}
giac me dit :

Code : Tout sélectionner

// Parsing test
// Success compiling test
undef
:1: syntax error, unexpected T_BLOC_END line 1 at }
:1: syntax error, unexpected T_BLOC_END line 1 at }
et ma commande me renvoie juste :

Code : Tout sélectionner

undef
J'aimerais bien récupérer la même chose qu'avec giac pour permettre le débogage par l'utilisateur dans OOo.
C'est possible ?

voilà un premier jet de cette boite de dialogue avec le résultat de la compilation :
screenshot_098.png
screenshot_098.png (30.47 Kio) Consulté 6242 fois

parisse
Messages : 5739
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: compiler une fonction avec giac

Message par parisse » lun. mars 22, 2010 1:37 pm

Pour ca, il faut que tu indique un flux de sortie C++ pour les messages (tout ce qui apparait en bleu avant la valeur de retour dans xcas). Je ne sais pas dans quelle mesure tu peux interagir avec ce type de flux. Typiquement, un programme C++ desirant par exemple renvoyer les sorties vers un fichier appele disons "log" fera la chose suivante:
ofstream of("log");
logptr(&of,contextptr);
// code ou les sorties sont detournees vers le fichier
logptr(&std::cerr,contextptr);
Tu peux mettre l'adresse d'un flux qui n'est pas un fichier sur le disque, comme ici std::cerr, il faut juste qu'il soit un type derive de la classe ostream.

cdeval
Messages : 192
Inscription : mer. juin 03, 2009 4:28 pm

Re: compiler une fonction avec giac

Message par cdeval » lun. mars 22, 2010 2:53 pm

J'ai compris,
dans mon programme, je ne récupère que la partie "string" de ma variable gen et non les erreurs envoyées vers std::cerr
J'ai suivi tes conseils mais en utilisant plutôt la classe ostringstream pour récupérer l'erreur dans une variable.
Ça marche au poil :

Code : Tout sélectionner

int main(){
	giac::context * contextptr=0;
	giac::child_id=1;
	ostringstream oss (ostringstream::out);
	logptr(&oss,contextptr);
	for(;;){
	gen a;
	cout << "Tapez une expression : ";
	cin >> a;
	cout << "resultat : " << eval(a,contextptr) << endl;
	cout << "erreur renvoyée : " << oss.str() << endl;
	}
}
et le résultat :

Code : Tout sélectionner

Tapez une expression : test(x):={return(x+1)}
resultat :  (x)->{ 
  return(x+1);  
}
erreur renvoyée : // Parsing test
// Success compiling test
Y a plus qu'à intégrer ça dans OOo.
Merci encore une fois !

cdeval
Messages : 192
Inscription : mer. juin 03, 2009 4:28 pm

Re: compiler une fonction avec giac

Message par cdeval » mer. mars 24, 2010 9:02 am

ça y est ça fonctionne dans OOo,
j'ai eu des petits soucis car une compilation giac provoque une sortie de flux qui, si elle n'est pas gérée dans OOo, provoque un signal "terminate" et plante OOo.
j'ai donc écrit une fonction spéciale qui gère le flux et que j'appelle pour toute instruction giac qui amène une compilation.
Il m'est maintenant possible de définir des nouvelles fonctions directement dans OOo et de les utiliser dans le tableur en passant des cellules comme argument.
je suis content !

voilà ce que ça donne brut de décoffrage :
screenshot_100.png
screenshot_100.png (55.9 Kio) Consulté 6231 fois

cdeval
Messages : 192
Inscription : mer. juin 03, 2009 4:28 pm

Re: compiler une fonction avec giac

Message par cdeval » mer. mars 24, 2010 5:47 pm

Me revoilà : je n'avais pas testé une compilation de fonction comportant une erreur de syntaxe.
Quand je compile :

Code : Tout sélectionner

test(x):={return(3x }
je n'arrive pas à récupérer le flux qui dit :

Code : Tout sélectionner

Compatibilite de la syntaxexcas
Erreur grammaticale ligne 1 a }
J'ai le problème avec le programme :

Code : Tout sélectionner

int main(){
	giac::context * contextptr=0;
	giac::child_id=1;
	ostringstream oss (ostringstream::out);
	logptr(&oss,contextptr);
	for(;;){
	oss.str("");
	gen a;
	cout << "Tapez une expression : ";
	cin >> a;
	cout << "resultat : " << eval(a,contextptr) << endl;
	cout << "erreur renvoyée : " << oss.str().c_str() << endl;
/*	const char * chaine = oss.str().c_str();
	int strlenght = strlen(oss.str().c_str()) + 1;
	cout << "longueur : " << strlenght << endl;
	for(int j=0; j<strlenght;j++)
		cout << (int) chaine[j] << " ";
	cout << endl;*/
	}
}
et le comportement est assez étrange : une entrée se fait toute seule juste après le résultat de l'affichage :

Code : Tout sélectionner

Tapez une expression : test(x):={return(3x }
resultat : "test(x):={return(3x"
Tapez une expression : resultat : undef
as-tu une idée pour que je récupère ce message d'erreur de syntaxe ?

parisse
Messages : 5739
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: compiler une fonction avec giac

Message par parisse » mer. mars 24, 2010 6:32 pm

Oui, l'erreur ne sort pas sur le flux logptr. Il faut tester si
giac::first_error_line(contextptr)
est non nul, et si c'est le cas, c'est le numéro de ligne de la 1ère erreur, et
giac::error_token_name(contextptr))
désigne le mot où l'erreur a été repérée.

cdeval
Messages : 192
Inscription : mer. juin 03, 2009 4:28 pm

Re: compiler une fonction avec giac

Message par cdeval » jeu. mars 25, 2010 1:59 pm

Ça fonctionne parfaitement.
Il m'a suffit de gérer différemment la sortie suivant qu'il y a une erreur ou non à la compilation.
Je pense qu'il ne me manque rien maintenant.
Voilà une petite copie d'écran.
merci encore, A+
screenshot_104.png
screenshot_104.png (61.44 Kio) Consulté 6223 fois

Répondre