YES !
J'ai enfin couché la forme de mon algo à partir de laquelle je vais coder !
Je suis resté sur mon idée première, mais je crois qu'à part les piles d'opérateurs/opérandes, je dois faire à peu près pareil que PpHd. J'aurai une récursion nécessairement limitée (je crois plus faible que la sienne (?), parce que je n'ai que 4 catégories de priorités dans mes opérateurs), hors évaluation d'expression entre parenthèses.
Finalement, j'ai simplifié mes deux fonctions de base, et c'est une troisième fonction, Decompose( EXPR ), qui est chargée de toute la merde, parenthèses et compagnie. Les deux premières deviennent toutes simples !
Et les symboles et labels seront gérés (différences de x labels, labels inconnus ou autres types de relogements. Je m'en faisais une montagne parce que je réfléchissais mal).
Seul petit hic, les demi/quarts de relogements. J'ai déjà mon idée (simple), mais je l'ai pas mise dans l'algo. C'est plus emmerdant qu'une addition ou une soustraction, parqu'il ne faut pas se contenter d'additionner le relogement à sa place, faut retenir qu'il faut le diviser, et par quel nombre, et ça seul le linker peut le faire.
Je mets le code, dès fois que, maintenant qu'il est devenu plus simple. Pour ceux qui regarderont, ne vous attardez pas sur Decompose() si vous voulez pas vous faire chier, sachez juste ce qu'il renvoie.
algo
Syntax:
IMM immediate 32 bits value
OP mathematical operator which is between the first IMM and the end of EXPR
EXPR* ptr to an expression
---------------------------------------------------
IMM MainEval( EXPR* ) // EXPR* will be updated
Decompose( EXPR ) // Create IMM, OP, EXPR2
If OP == 0 // No operator ?
Then IMM // Ok, it's just a symbol or a number to evaluate
Else Eval( IMM, OP, EXPR2 ) // Else evaluate the expression
---------------------------------------------------
IMM Eval( IMM, OP, EXPR )
Decompose( EXPR ) // Create IMM2, OP2, EXPR2
If OP2 == 0 // No operator ?
Then OP( IMM, IMM2 ) // So its just an operation do to
Else If OP >= OP2 // Else if priority( OP1 ) > Priority( OP2 )
Then IMM3 = OP( IMM, IMM2 ) // First perform the OP stuff
Eval( IMM3, OP2, EXPR2* ) // Then evaluate the end of the expression
Else IMM3 = Eval( IMM2, OP2, EXPR2*)
OP (IMM, IMM3)
// then perform the OP stuff
---------------------------------------------------
IMM OP EXPR Decompose( EXPR )
/*
In entry, we have an expression.
The goal is to return :
- its first numeric element
- the next operator
- a ptr to the end of the expression
We can find :
- a negate sign
- an opening bracket
- a number (binary, decimal or hexadecimal form)
- a defined symbol (integer or relocated symbol)
- an undefined symbol (label)
- an operator
*/
Begin:
If NegateSign()
Then SetFlagNegate() // Local flag
If OpenBracket()
Then SkipBracket()
BracketCount++
MainEval( EXPR ) // Get IMM
While CloseBracket()
BracketCount-- // Error if BRACKET_COUNT < 0
Goto ReadOperator
If Number()
Then EvalNumber() // Get IMM
Goto ReadOperator
If DefinedSymbol()
Then GetSymbolValue() // Get IMM
Goto ReadOperator
If UndefinedSymbol()
Then AddReloc
SetFlagRelocType()
Goto Begin
ReadOperator:
ApplyNegate( IMM )
ReadOperator() // Get OP
Return( IMM, OP, EXPR* ) // Return
Evidemment, tous vos conseils/critiques/remarques sont les bienvenus
Sasume -> au final, avec ça, je ne lirai qu'une fois chaque caractère de mon expression, sans aller chercher "en avant".