flat assembler
Message board for the users of flat assembler.

 Index > Windows > Complex dynamic formulas
Author
kasake36

Joined: 28 Mar 2006
Posts: 68
kasake36 06 Feb 2007, 14:44
Hello!

I am at the start of writing a program that reads in "complex" formulas from a textfile, e.g.:

"KO - ((150-A) * 2) - (40 - B) - ((180 -X) / 3)"

After the formula is read, the alphabetic variables get replaced with their character-values, so the result would be a string that needs to get calculated. Programming this calculation manually would be much work i believe, so i wanted to ask if anyone of you has some ideas for doing the calculation.
I thought about calling a extern library function if one does exist. Also: would a FASM macro be possible? (i've never written one)

P.S.: I've not programmed anything yet, just starting to plan...
06 Feb 2007, 14:44
Reverend

Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend 06 Feb 2007, 20:35
Get some converting routines (ie. text -> number). Save all the converted alphabetic variables somewhere and do the calculations step by step (you have the formula nicely put inside braces, so no problem).

Code:
```1 = 150-A
2 = [1] * 2
3 = 40 - B
4 = [2] - [3]
...
```

Code:
```; 1 = 150-A
mov eax, 150
sub eax, [A]

; 2 = [1] * 2
shl eax, 1 ; this equals eax = eax*2

; 3 = 40 - B
mov ecx, 40
sub ecx, [B]

; 4 = [2] - [3]
sub eax, ecx
...
```
06 Feb 2007, 20:35
kasake36

Joined: 28 Mar 2006
Posts: 68
kasake36 07 Feb 2007, 07:14
That's what i didn't want to do first, because i still believe it ends up in a mess (at least for me) but anyways, i'll do it this way. Thanks.
07 Feb 2007, 07:14
Reverend

Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend 07 Feb 2007, 11:55
If you don't want mess than just put this code in a procedure like this:
Code:
```proc formula A, B, K, O, X
...
endp    ```
Save this "messy" code in some diffferent file. And in your main application, include it. Then your main code will look like:
Code:
```...
stdcall formula, [A], [B], [K], [O], [X]
...    ```

But generally my opinion is that sooner or later you will have to get used to the "messy" code if you choose assembly.
07 Feb 2007, 11:55
kasake36

Joined: 28 Mar 2006
Posts: 68
kasake36 07 Feb 2007, 13:27
With messy i meant the part of the program that divides the formula into simple calculations. I wanted to do something similar using C several years ago and i failed, but i do not know the reason for the failure at the moment. The only thing i have in mind is that the program was a mess. On the other side i'm a bit more experienced nowadays.
07 Feb 2007, 13:27
PopeInnocent

Joined: 01 Jan 2004
Posts: 18
Location: USA
PopeInnocent 08 Feb 2007, 23:09
If I understand you correctly, it sounds like you want to read in a formula and calculate it. An LR(1) recursive-descent parser would probably work perfectly for you, and it would distinctly non-messy.
08 Feb 2007, 23:09
kasake36

Joined: 28 Mar 2006
Posts: 68
kasake36 09 Feb 2007, 08:52
Oh my gosh....
Thanks for the keywords! I'll have to spent some thought on that!
09 Feb 2007, 08:52
kandamun

Joined: 20 Jul 2005
Posts: 25
kandamun 10 Feb 2007, 08:25
It is another way of doing this.
10 Feb 2007, 08:25
kasake36

Joined: 28 Mar 2006
Posts: 68
kasake36 12 Feb 2007, 07:41
RPN seems a bit more comfortable than the LR(1) stuff (for the calculation with assembler) and i believe the customer would appreciate to write down the formulas in that syntax - it looks more pro and he can brag around in front of his nice secretaries
12 Feb 2007, 07:41
donkey7

Joined: 31 Jan 2005
Posts: 127
Location: Poland, Malopolska
donkey7 12 Feb 2007, 11:24
you don't need the customer to write in rpn syntax. instead you can use algorithm to convert from classic notation to rpn.
Code:
```repeat
get_next_element;
if element_is_a_value then
write_it_to_output
else
if element_is_a_operator then
while priority_of_first_operator_on_stack >= priority_of_element do
move_first_operator_from_stack_to_output
push_element_on_stack
if element_equal_( then
push_it_on_stack
if element_equal_) then
while first_element_on_stack_is_a_operator do ; ( remove_elements_util_( )
move_it_from_stack_to_output
delete_(_from_beginnig_of_stack
end if
until end_of_data
while stack_non_empty do
move_operator_from_stack_to_output
```

then you apply algorithm to evaluate it:
Code:
```repeat
get_next_element
if element_is_a_value then
push_it_onto_stack
else
pop_needed_values_from_stack
do_operation
push_the_result_onto_stack
end if
until end_of_data
```

because the evaluation algorithm is stack based you can easily implement it for 80387 fpu (which is also stack based).

you can also look at:
http://en.wikipedia.org/wiki/Reverse_Polish_notation
http://en.wikipedia.org/wiki/Shunting_yard_algorithm

_________________
Keep coding!
12 Feb 2007, 11:24
kasake36

Joined: 28 Mar 2006
Posts: 68
kasake36 12 Feb 2007, 11:35