On Thu, 18 Nov 2004 09:26:33 +0100, Pierre Maurette :
static int * dToRArray[4];
Ben... non. Eviter les "magic values" comme la peste (sauf peut-être 42).
static int const NB_dToRArray= 4; static int * dToRArray [NB_dToRArray]; Merci. Soyez rassuré, c'est une règle que j'applique le plus souvent.
-- Pierre
PtitMat
Christophe Lephay wrote:
PtitMat wrote:
Je commence par dejà apprendre a utiliser les exeptions avec les réponses précédentes. Chaque chose en son temps. La factory sera pour plus tard (je vai eviter de faire une usine a gaz parfaite pour me perdre dans les vapeurs)... ;-)
class ajoute : public instruction { char valeur; reg registre;
void extrait_operandes( std::istream& is ) { // extraire depuis le flux les opérandes requis ... }
public: // la fonction fabrique static ajoute * make( std::istream& is ) { ajoute * instr = new ajoute; instr->extrait_operandes( is ); return instr; }
};
classe soustrait : public instruction { char valeur; reg registre;
void extrait_operandes( std::istream& is ) { // extraire depuis le flux les opérandes requis ... }
public: // la fonction fabrique static soustrait * make( std::istream& is ) { soustrait * instr = new soustrait; instr->extrait_operandes( is ); return instr; }
};
Tu peux faire un fabrique sommaire basée sur un map :
typedef instruction * (* pf ) ( std::istream& ); // typedef pour pointeur sur fonction std::map< char, pf > fabrique;
// initialisation de la fabrique : fabrique[ '1' ] = ajoute::&make; fabrique[ '2' ] = soustrait::&make; ...
// disons que la rom est mappée dans le fichier "rom" : std::ifstream ifs( "rom" );
// lecture du premier digit, code de l'instruction char c; ifs.get( c );
// recherche du digit std::map< char, pf >::iterator it; it = fabrique.find( c );
// erreur si l'instruction n'est pas reconnue par la fabrique if( it == fabrique.end() ) throw( "instruction invalide" );
// dans le cas contraire, on appelle la fonction make associée via déréférencement de l'itérateur instruction * instr = (*it)( ifs ); // appel de la fonction make ...
En gros, ça te donne l'idée. Bonne digestion ;)
Chris
Bonjour a tous
Merci pour votre aide. J'ai écrit ma fonction de la sorte et elle ne changera plus sauf si a l'avenir je decouvre un bug ;-)
int * Ccpu::dToR( int dx ) { try { switch( dx ) { case 0: return pR0; break; case 1: return pR1; break; case 2: return pR2; break; case 3: return pR3; break;
default: throw( dx ); } } catch (int Rx) { int lPc; lPc = getPc();//Prend la valeur de Program Counter cout << "Instruction number " << lPc << " Try to acces to register R" << Rx << " which doesn't exist" << endl; exit (0); } }
Christophe Lephay wrote:
PtitMat wrote:
Je commence par dejà apprendre a utiliser les exeptions avec les
réponses précédentes.
Chaque chose en son temps.
La factory sera pour plus tard (je vai eviter de faire une usine a gaz
parfaite pour me perdre dans les vapeurs)... ;-)
class ajoute : public instruction
{
char valeur;
reg registre;
void extrait_operandes( std::istream& is )
{
// extraire depuis le flux les opérandes requis
...
}
public:
// la fonction fabrique
static ajoute * make( std::istream& is )
{
ajoute * instr = new ajoute;
instr->extrait_operandes( is );
return instr;
}
};
classe soustrait : public instruction
{
char valeur;
reg registre;
void extrait_operandes( std::istream& is )
{
// extraire depuis le flux les opérandes requis
...
}
public:
// la fonction fabrique
static soustrait * make( std::istream& is )
{
soustrait * instr = new soustrait;
instr->extrait_operandes( is );
return instr;
}
};
Tu peux faire un fabrique sommaire basée sur un map :
typedef instruction * (* pf ) ( std::istream& ); // typedef pour pointeur
sur fonction
std::map< char, pf > fabrique;
// initialisation de la fabrique :
fabrique[ '1' ] = ajoute::&make;
fabrique[ '2' ] = soustrait::&make;
...
// disons que la rom est mappée dans le fichier "rom" :
std::ifstream ifs( "rom" );
// lecture du premier digit, code de l'instruction
char c;
ifs.get( c );
// recherche du digit
std::map< char, pf >::iterator it;
it = fabrique.find( c );
// erreur si l'instruction n'est pas reconnue par la fabrique
if( it == fabrique.end() )
throw( "instruction invalide" );
// dans le cas contraire, on appelle la fonction make associée via
déréférencement de l'itérateur
instruction * instr = (*it)( ifs ); // appel de la fonction make
...
En gros, ça te donne l'idée. Bonne digestion ;)
Chris
Bonjour a tous
Merci pour votre aide.
J'ai écrit ma fonction de la sorte et elle ne changera plus sauf si a
l'avenir je decouvre un bug ;-)
int * Ccpu::dToR( int dx )
{
try
{
switch( dx )
{
case 0: return pR0; break;
case 1: return pR1; break;
case 2: return pR2; break;
case 3: return pR3; break;
default: throw( dx );
}
}
catch (int Rx)
{
int lPc;
lPc = getPc();//Prend la valeur de Program Counter
cout << "Instruction number " << lPc << " Try to acces to register R"
<< Rx << " which doesn't exist" << endl;
exit (0);
}
}
Je commence par dejà apprendre a utiliser les exeptions avec les réponses précédentes. Chaque chose en son temps. La factory sera pour plus tard (je vai eviter de faire une usine a gaz parfaite pour me perdre dans les vapeurs)... ;-)
class ajoute : public instruction { char valeur; reg registre;
void extrait_operandes( std::istream& is ) { // extraire depuis le flux les opérandes requis ... }
public: // la fonction fabrique static ajoute * make( std::istream& is ) { ajoute * instr = new ajoute; instr->extrait_operandes( is ); return instr; }
};
classe soustrait : public instruction { char valeur; reg registre;
void extrait_operandes( std::istream& is ) { // extraire depuis le flux les opérandes requis ... }
public: // la fonction fabrique static soustrait * make( std::istream& is ) { soustrait * instr = new soustrait; instr->extrait_operandes( is ); return instr; }
};
Tu peux faire un fabrique sommaire basée sur un map :
typedef instruction * (* pf ) ( std::istream& ); // typedef pour pointeur sur fonction std::map< char, pf > fabrique;
// initialisation de la fabrique : fabrique[ '1' ] = ajoute::&make; fabrique[ '2' ] = soustrait::&make; ...
// disons que la rom est mappée dans le fichier "rom" : std::ifstream ifs( "rom" );
// lecture du premier digit, code de l'instruction char c; ifs.get( c );
// recherche du digit std::map< char, pf >::iterator it; it = fabrique.find( c );
// erreur si l'instruction n'est pas reconnue par la fabrique if( it == fabrique.end() ) throw( "instruction invalide" );
// dans le cas contraire, on appelle la fonction make associée via déréférencement de l'itérateur instruction * instr = (*it)( ifs ); // appel de la fonction make ...
En gros, ça te donne l'idée. Bonne digestion ;)
Chris
Bonjour a tous
Merci pour votre aide. J'ai écrit ma fonction de la sorte et elle ne changera plus sauf si a l'avenir je decouvre un bug ;-)
int * Ccpu::dToR( int dx ) { try { switch( dx ) { case 0: return pR0; break; case 1: return pR1; break; case 2: return pR2; break; case 3: return pR3; break;
default: throw( dx ); } } catch (int Rx) { int lPc; lPc = getPc();//Prend la valeur de Program Counter cout << "Instruction number " << lPc << " Try to acces to register R" << Rx << " which doesn't exist" << endl; exit (0); } }
drkm
Fabien LE LEZ writes:
On Thu, 18 Nov 2004 19:20:54 +0100, drkm :
Pourquoi ? Puisque toutes les fonctions membres utilisent `dToR()' ... ;-)
Dans ce cas, ces données devraient être dans une classe à part, ne contenant pas grand-chose d'autre que les pRx et dToR().
Je ne te suis pas ...
--drkm
Fabien LE LEZ <gramster@gramster.com> writes:
On Thu, 18 Nov 2004 19:20:54 +0100, drkm <usenet.fclcxx@fgeorges.org>:
Pourquoi ? Puisque toutes les fonctions membres utilisent
`dToR()' ... ;-)
Dans ce cas, ces données devraient être dans une classe à part, ne
contenant pas grand-chose d'autre que les pRx et dToR().
Bonjour a tous Merci pour votre aide. J'ai écrit ma fonction de la sorte et elle ne changera plus sauf si a l'avenir je decouvre un bug ;-)
int * Ccpu::dToR( int dx ) { try { switch( dx ) { case 0: return pR0; break; case 1: return pR1; break; case 2: return pR2; break; case 3: return pR3; break;
default: throw( dx ); } } catch (int Rx) { int lPc; lPc = getPc();//Prend la valeur de Program Counter cout << "Instruction number " << lPc << " Try to acces to register R" (*) << Rx << " which doesn't exist" << endl; exit (0); } }
Ben ça me semble correct, si ce n'est qu'il serait potentiellement plus judicieux de remplacer le cout de la ligne marquée par (*) par un cerr...
Chris
drkm
PtitMat writes:
Ne cite pas l'entièreté de l'article auquel tu réponds, si cela n'est pas nécessaire, stp.
int * Ccpu::dToR( int dx ) { try { switch( dx ) { case 0: return pR0; break; case 1: return pR1; break; case 2: return pR2; break; case 3: return pR3; break;
default: throw( dx ); } } catch (int Rx) { int lPc; lPc = getPc();//Prend la valeur de Program Counter cout << "Instruction number " << lPc << " Try to acces to register R" << Rx << " which doesn't exist" << endl; exit (0); } }
Ici, je n'ai pas compris l'utilisation d'une exception. As-tu essayé une des autres réponses qu'il t'a été données ? J'aurais tendence à utiliser celle de James. Elle ne te convient pas ?
--drkm
PtitMat <toto@toto.fr> writes:
Ne cite pas l'entièreté de l'article auquel tu réponds, si cela
n'est pas nécessaire, stp.
int * Ccpu::dToR( int dx )
{
try
{
switch( dx )
{
case 0: return pR0; break;
case 1: return pR1; break;
case 2: return pR2; break;
case 3: return pR3; break;
default: throw( dx );
}
}
catch (int Rx)
{
int lPc;
lPc = getPc();//Prend la valeur de Program Counter
cout << "Instruction number " << lPc << " Try to acces to register R"
<< Rx << " which doesn't exist" << endl;
exit (0);
}
}
Ici, je n'ai pas compris l'utilisation d'une exception. As-tu
essayé une des autres réponses qu'il t'a été données ? J'aurais
tendence à utiliser celle de James. Elle ne te convient pas ?
Ne cite pas l'entièreté de l'article auquel tu réponds, si cela n'est pas nécessaire, stp.
int * Ccpu::dToR( int dx ) { try { switch( dx ) { case 0: return pR0; break; case 1: return pR1; break; case 2: return pR2; break; case 3: return pR3; break;
default: throw( dx ); } } catch (int Rx) { int lPc; lPc = getPc();//Prend la valeur de Program Counter cout << "Instruction number " << lPc << " Try to acces to register R" << Rx << " which doesn't exist" << endl; exit (0); } }
Ici, je n'ai pas compris l'utilisation d'une exception. As-tu essayé une des autres réponses qu'il t'a été données ? J'aurais tendence à utiliser celle de James. Elle ne te convient pas ?
--drkm
Jean-Marc Bourguet
PtitMat writes:
J'ai écrit ma fonction de la sorte et elle ne changera plus sauf si a l'avenir je decouvre un bug ;-)
int * Ccpu::dToR( int dx ) { try { switch( dx ) { case 0: return pR0; break; case 1: return pR1; break; case 2: return pR2; break; case 3: return pR3; break;
default: throw( dx ); } } catch (int Rx) { int lPc; lPc = getPc();//Prend la valeur de Program Counter cout << "Instruction number " << lPc << " Try to acces to register R" << Rx << " which doesn't exist" << endl; exit (0); } }
* Les exceptions, c'est fait pour sortir de la fonction qui les lance -- et bien souvent pour dépiler plusieurs fonctions par la même occasion car sinon il y a des chances qu'un autre moyen de rapporter l'erreur soit meilleur.
* Pourquoi les pRx ne forment-ils pas un tableau (je pourrais comprendre s'ils portaient d'autres noms -- et encore, on peut faire un tableau avec des copies des pointeurs puisque c'en est --, mais ici c'est vraiment criant) ?
* exit() dans du C++ est presque toujours une erreur. Ou bien on veut faire du clean-up et alors c'est une exception qu'il faut jeter et qui doit arriver jusqu'à main(), ou bien on n'en veut pas et c'est abort() (ou _exit() pour Unix, _Exit() avec un lib c99) éventuellement précédé d'un fflush(0) si on veut vider les tampons.
* je modéliserais les registres d'un processeur par des unsigned et pas des int.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
PtitMat <toto@toto.fr> writes:
J'ai écrit ma fonction de la sorte et elle ne changera
plus sauf si a l'avenir je decouvre un bug ;-)
int * Ccpu::dToR( int dx )
{
try
{
switch( dx )
{
case 0: return pR0; break;
case 1: return pR1; break;
case 2: return pR2; break;
case 3: return pR3; break;
default: throw( dx );
}
}
catch (int Rx)
{
int lPc;
lPc = getPc();//Prend la valeur de Program Counter
cout << "Instruction number " << lPc << " Try to acces to
register R" << Rx << " which doesn't exist" << endl;
exit (0);
}
}
* Les exceptions, c'est fait pour sortir de la fonction qui
les lance -- et bien souvent pour dépiler plusieurs
fonctions par la même occasion car sinon il y a des chances
qu'un autre moyen de rapporter l'erreur soit meilleur.
* Pourquoi les pRx ne forment-ils pas un tableau (je
pourrais comprendre s'ils portaient d'autres noms -- et
encore, on peut faire un tableau avec des copies des
pointeurs puisque c'en est --, mais ici c'est vraiment
criant) ?
* exit() dans du C++ est presque toujours une erreur. Ou
bien on veut faire du clean-up et alors c'est une exception
qu'il faut jeter et qui doit arriver jusqu'à main(), ou bien
on n'en veut pas et c'est abort() (ou _exit() pour Unix,
_Exit() avec un lib c99) éventuellement précédé d'un
fflush(0) si on veut vider les tampons.
* je modéliserais les registres d'un processeur par des
unsigned et pas des int.
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
J'ai écrit ma fonction de la sorte et elle ne changera plus sauf si a l'avenir je decouvre un bug ;-)
int * Ccpu::dToR( int dx ) { try { switch( dx ) { case 0: return pR0; break; case 1: return pR1; break; case 2: return pR2; break; case 3: return pR3; break;
default: throw( dx ); } } catch (int Rx) { int lPc; lPc = getPc();//Prend la valeur de Program Counter cout << "Instruction number " << lPc << " Try to acces to register R" << Rx << " which doesn't exist" << endl; exit (0); } }
* Les exceptions, c'est fait pour sortir de la fonction qui les lance -- et bien souvent pour dépiler plusieurs fonctions par la même occasion car sinon il y a des chances qu'un autre moyen de rapporter l'erreur soit meilleur.
* Pourquoi les pRx ne forment-ils pas un tableau (je pourrais comprendre s'ils portaient d'autres noms -- et encore, on peut faire un tableau avec des copies des pointeurs puisque c'en est --, mais ici c'est vraiment criant) ?
* exit() dans du C++ est presque toujours une erreur. Ou bien on veut faire du clean-up et alors c'est une exception qu'il faut jeter et qui doit arriver jusqu'à main(), ou bien on n'en veut pas et c'est abort() (ou _exit() pour Unix, _Exit() avec un lib c99) éventuellement précédé d'un fflush(0) si on veut vider les tampons.
* je modéliserais les registres d'un processeur par des unsigned et pas des int.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
PtitMat
Christophe Lephay wrote:
PtitMat wrote:
cout << "Instruction number " << lPc << " Try to acces to register R" (*) << Rx << " which doesn't exist" << endl; exit (0); } }
Ben ça me semble correct, si ce n'est qu'il serait potentiellement plus judicieux de remplacer le cout de la ligne marquée par (*) par un cerr...
Chris
C'est fait.
Je suis débutant, comme indiqué dans l'énoncé du problème. Je ne conaissait pas cerr, mais c'est vrai que 'est plus logique d'utiliser la sortie d'érreur que la sortie standard.
Mat
Christophe Lephay wrote:
PtitMat wrote:
cout << "Instruction number " << lPc << " Try to acces to register R" (*)
<< Rx << " which doesn't exist" << endl;
exit (0);
}
}
Ben ça me semble correct, si ce n'est qu'il serait potentiellement plus
judicieux de remplacer le cout de la ligne marquée par (*) par un cerr...
Chris
C'est fait.
Je suis débutant, comme indiqué dans l'énoncé du problème.
Je ne conaissait pas cerr, mais c'est vrai que 'est plus logique
d'utiliser la sortie d'érreur que la sortie standard.
cout << "Instruction number " << lPc << " Try to acces to register R" (*) << Rx << " which doesn't exist" << endl; exit (0); } }
Ben ça me semble correct, si ce n'est qu'il serait potentiellement plus judicieux de remplacer le cout de la ligne marquée par (*) par un cerr...
Chris
C'est fait.
Je suis débutant, comme indiqué dans l'énoncé du problème. Je ne conaissait pas cerr, mais c'est vrai que 'est plus logique d'utiliser la sortie d'érreur que la sortie standard.
Mat
Pierre Maurette
Jean-Marc Bourguet a écrit:
PtitMat writes:
J'ai écrit ma fonction de la sorte et elle ne changera plus sauf si a l'avenir je decouvre un bug ;-)
int * Ccpu::dToR( int dx ) { try { switch( dx ) { case 0: return pR0; break; case 1: return pR1; break; case 2: return pR2; break; case 3: return pR3; break;
default: throw( dx ); } } catch (int Rx) { int lPc; lPc = getPc();//Prend la valeur de Program Counter cout << "Instruction number " << lPc << " Try to acces to register R" << Rx << " which doesn't exist" << endl; exit (0); } }
* Les exceptions, c'est fait pour sortir de la fonction qui les lance -- et bien souvent pour dépiler plusieurs fonctions par la même occasion car sinon il y a des chances qu'un autre moyen de rapporter l'erreur soit meilleur.
* Pourquoi les pRx ne forment-ils pas un tableau (je pourrais comprendre s'ils portaient d'autres noms -- et encore, on peut faire un tableau avec des copies des pointeurs puisque c'en est --, mais ici c'est vraiment criant) ? Oui, et peut-être une enum pour dx. Ça ne garantit pas que dx reste
entre les bornes, mais ça aide. En fait, ça dépend du genre des registres. MMX0, ..., MMX7 se prêtent à un dx int (et une arithmétique en modulo), EAX, EBX, etc. à une enum.
* je modéliserais les registres d'un processeur par des unsigned et pas des int. Une union serait pas mal, non ?
-- Pierre
Jean-Marc Bourguet <jm@bourguet.org> a écrit:
PtitMat <toto@toto.fr> writes:
J'ai écrit ma fonction de la sorte et elle ne changera
plus sauf si a l'avenir je decouvre un bug ;-)
int * Ccpu::dToR( int dx )
{
try
{
switch( dx )
{
case 0: return pR0; break;
case 1: return pR1; break;
case 2: return pR2; break;
case 3: return pR3; break;
default: throw( dx );
}
}
catch (int Rx)
{
int lPc;
lPc = getPc();//Prend la valeur de Program Counter
cout << "Instruction number " << lPc << " Try to acces to
register R" << Rx << " which doesn't exist" << endl;
exit (0);
}
}
* Les exceptions, c'est fait pour sortir de la fonction qui
les lance -- et bien souvent pour dépiler plusieurs
fonctions par la même occasion car sinon il y a des chances
qu'un autre moyen de rapporter l'erreur soit meilleur.
* Pourquoi les pRx ne forment-ils pas un tableau (je
pourrais comprendre s'ils portaient d'autres noms -- et
encore, on peut faire un tableau avec des copies des
pointeurs puisque c'en est --, mais ici c'est vraiment
criant) ?
Oui, et peut-être une enum pour dx. Ça ne garantit pas que dx reste
entre les bornes, mais ça aide. En fait, ça dépend du genre des
registres. MMX0, ..., MMX7 se prêtent à un dx int (et une arithmétique
en modulo), EAX, EBX, etc. à une enum.
* je modéliserais les registres d'un processeur par des
unsigned et pas des int.
Une union serait pas mal, non ?
J'ai écrit ma fonction de la sorte et elle ne changera plus sauf si a l'avenir je decouvre un bug ;-)
int * Ccpu::dToR( int dx ) { try { switch( dx ) { case 0: return pR0; break; case 1: return pR1; break; case 2: return pR2; break; case 3: return pR3; break;
default: throw( dx ); } } catch (int Rx) { int lPc; lPc = getPc();//Prend la valeur de Program Counter cout << "Instruction number " << lPc << " Try to acces to register R" << Rx << " which doesn't exist" << endl; exit (0); } }
* Les exceptions, c'est fait pour sortir de la fonction qui les lance -- et bien souvent pour dépiler plusieurs fonctions par la même occasion car sinon il y a des chances qu'un autre moyen de rapporter l'erreur soit meilleur.
* Pourquoi les pRx ne forment-ils pas un tableau (je pourrais comprendre s'ils portaient d'autres noms -- et encore, on peut faire un tableau avec des copies des pointeurs puisque c'en est --, mais ici c'est vraiment criant) ? Oui, et peut-être une enum pour dx. Ça ne garantit pas que dx reste
entre les bornes, mais ça aide. En fait, ça dépend du genre des registres. MMX0, ..., MMX7 se prêtent à un dx int (et une arithmétique en modulo), EAX, EBX, etc. à une enum.
* je modéliserais les registres d'un processeur par des unsigned et pas des int. Une union serait pas mal, non ?