flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Match directive and lazy evaluation

Author
Thread Post new topic Reply to topic
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 23 Jan 2010, 00:01
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
; That was predictable, how about this?
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! Wink

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.
Post 23 Jan 2010, 00:01
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 23 Jan 2010, 00:22
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.
Post 23 Jan 2010, 00:22
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 23 Jan 2010, 02:37
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.
Post 23 Jan 2010, 02:37
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 23 Jan 2010, 09:34
Then try with backward DEFINEs and "equ!" macro.
Post 23 Jan 2010, 09:34
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.