flat assembler
Message board for the users of flat assembler.

 Index > Macroinstructions > Match directive and lazy evaluation
Author
baldr

Joined: 19 Mar 2008
Posts: 1651
baldr
Ability of match to replace the symbolic constants with their values has interesting side effect:
Code:
```; Simple macros to display symbolic constants
macro s_display symbol* { display `symbol }
macro v_display symbol* { match vv,symbol \{ irps v,vv \\{ s_display v \\} \} }
macro sv_display [symbol] {
s_display symbol
display "="
v_display symbol
display 13, 10
}
; Here goes the magic (equ's are placed backward intentionally)
thousand equ ten*hundred
hundred equ ten*ten
ten equ 10
sv_display thousand, hundred, ten
match vv,thousand { match v,vv \{ dd v \} }
match v,hundred { dd v }    ```
Display: wrote:
thousand=ten*hundred
hundred=ten*ten
ten=10
Plain dd thousand or hundred both fail, as you may have guessed.
It appears that match does replacement only once, so we have to peel that thousand onion twice.

May equ be of some help?
Code:
```; Append to the previous code
real_thousand equ thousand
sv_display real_thousand
really_real_thousand equ real_thousand
sv_display really_real_thousand    ```
Display: wrote:
real_thousand=ten*hundred
really_real_thousand=ten*hundred
Bad luck. Let's tweak it more:
Code:
```; Append to the previous code
; Simple evaluating equ (1.69.00+)
struc equ! expr* { rept 1 v:expr \{ . equ v \} }
match vv,thousand { match v,vv \{ real_thousand equ! v \} }
sv_display ten, real_thousand
; For something different
ten equ ten*ten
match vv,thousand { match v,vv \{ real_thousand equ! v \} }
sv_display ten, real_thousand    ```
Display: wrote:
ten=10
real_thousand=1000
ten=10*10
real_thousand=1000000
Quite amusing. Deferred symbolic constant replacement may be useful. The next result astounds me.
Code:
```; Append to the previous code
ten equ 10+10
match vv,thousand {;step by step
display "Step 1: vv="
v_display vv
display 13, 10
match v,vv \{
display "Step 2: v="
v_display v
dd v; output file contains 220
display 13, 10
WTF?! equ! v
\}
}
sv_display ten, WTF?!    ```
Display: wrote:
Step 1: vv=10+10*ten*ten
Step 2: v=10+10*10+10*10+10
ten=10+10
WTF?!=4010
How it could be possible? Probably equ! is responsible for that…
Code:
```; Append to the previous code
; Test the evaluator
result equ! 10+10*10+10*10+10
sv_display result    ```
Display: wrote:
result=220
Hmm, I'm lost. Looks like equ! calculates 10+10*(10+10)*(10+10) when invoked within match. Remains of token boundaries?
Code:
```; Append to the previous code
; Test the hypothesis
match v,hundred { WTF?! equ! v }
sv_display ten, WTF?!    ```
Display: wrote:
ten=10+10
WTF?!=400
Aha! Now it becomes clearer. Let's add another match to get it right.
Code:
```; Append to the previous code
; Test the hypothesis II
match vv,hundred { match v,vv \{ good_one equ! v \} }
sv_display ten, good_one    ```
Display: wrote:
ten=10+10
good_one=120
Perfect match!

Disclaimer:
Those macros are limited in functionality, don't expect too much from them.
FASM macro programming is highly addictive and can be dangerous to your mental health.

_________________
"Don't belong. Never join. Think for yourself. Peace." – Victor Stone.
23 Jan 2010, 00:01
Tomasz Grysztar

Joined: 16 Jun 2003
Posts: 7796
Location: Kraków, Poland
Tomasz Grysztar
Note the two samples located at the very bottom of this post: http://board.flatassembler.net/topic.php?p=96490#96490
The REPT's "precalc" ability was implemented in such a way, that it evaluates the value of each symbolic constant it encounters (with recursion) and then uses this value for calculation. As opposed to the classis EQU value replacement, where it's just a plain string replacement without any recursion.

Thus it is recommended to use the DEFINE directive with "precalc" - they make a good pair.
23 Jan 2010, 00:22
baldr

Joined: 19 Mar 2008
Posts: 1651
baldr
Tomasz Grysztar,

It was my backward equs order that caused the confusion. That v_display macro use match itself and displays value after one replacement, and rept in equ! got it before.
23 Jan 2010, 02:37
Tomasz Grysztar

Joined: 16 Jun 2003
Posts: 7796
Location: Kraków, Poland
Tomasz Grysztar
Then try with backward DEFINEs and "equ!" macro.
23 Jan 2010, 09:34
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First

 Jump to: Select a forum Official----------------AssemblyPeripheria General----------------MainTutorials and ExamplesDOSWindowsLinuxUnixMenuetOS Specific----------------MacroinstructionsOS ConstructionIDE DevelopmentProjects and IdeasNon-x86 architecturesHigh Level LanguagesProgramming Language DesignCompiler Internals Other----------------FeedbackHeapTest Area

Forum Rules:
 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum