flat assembler
Message board for the users of flat assembler.
Index
> Compiler Internals > [fasmg] possible bug with redifined macro and "." struc sym |
Author |
|
Tomasz Grysztar 05 Dec 2019, 10:18
This is a complex interaction and a risky usage pattern. Unconditional macros can be really tricky to use, I would recommend avoiding them unless you really need them for some specific reason (but then you should make sure that you know how they interact with everything).
By using PURGE, or defining macro multiple times, you make it so it cannot be forward-referenced. Therefore the ABC macro does not have the DEF macro expanded in its text, because at the time ABC macro is defined, DEF is not yet defined. And then when ABC macro is called, it in turn calls DEF macro, which refers to "." symbol that is interpreted in its own context (not in the context of ABC macro). On the other hand, when you define DEF macro just once and do not PURGE it, it can be forward-referenced and it is recognized and expanded at the time when ABC macro is defined. The DISPLAY line then becomes a part of the text of the ABC macro and therefore "." is interpreted in that context (as you probably expected). In general, if you'd like unconditional macro to be reliably expanded in the text of another macro, define it outside. |
|||
05 Dec 2019, 10:18 |
|
MaoKo 05 Dec 2019, 20:38
Yes thx Tomasz. I forget here to use the ?! macro to debug.
Code: struc ABC? macro DEF?! display .+"0", $0A end macro redefine . $06 DEF end struc Apparently the above code is fine but if the struc ABC is called several time the DEF is not constant and cannot be forward-referenced. A possible "solution" is to declare it recursive. Such decl prevent the second call to ABC. With nested macro in my first example, I like the idea of restricting the scope (like private). Fortunately there is the "local" keyword. An idea, is maybe an instruction "static" that behave like local but each invocation can access the same symbol (expr,instr). |
|||
05 Dec 2019, 20:38 |
|
Tomasz Grysztar 06 Dec 2019, 15:55
Keep in mind that this relies on DEF being forward-referenced (because it is defined when the macro is called for the first time, but it is being used (expanded) when the macro is being defined. Therefore this needs a second pass to even start working properly (though if you need it just for debugging, then that's perhaps not an issue).
This is also why LOCAL would not help you here. Because you need the macro to be expanded when the outer STRUC is being defined, not when it is called. Also, BTW, you cannot make an unconditional macro recursive, an unconditional recursion would be infinite, for this reason this combination is not really allowed. Therefore, if you really need to keep the definition inside your STRUC, you'd need to do something like: Code: struc ABC? if ~ definite ABCDEF ABCDEF := 1 macro DEF?! display .+"0", $0A end macro end if redefine . $06 DEF end struc MaoKo wrote: An idea, is maybe an instruction "static" that behave like local but each invocation can access the same symbol (expr,instr). |
|||
06 Dec 2019, 15:55 |
|
MaoKo 14 Dec 2019, 07:41
Thank you, Tomasz. I have just another question in mind.
Why in this code, the context associated with the "." symbol seem to be dropped? Code: struc insert_database? __database equ . redefine . $02 end struc distinct? := $00 macro store_wrapper?! object?* namespace distinct? object insert_database end namespace end macro struc main_loop? redefine . $01 store_wrapper . display .+"0", $A ; display 1 end struc ^ main_loop display distinct..+"0", $0A ; error display .+"0", $0A ; display 2 I have difficulties to understand why after the macroinstruction "store_wrapper .", the "." still has the value $01. And why, it's create the global "." symbol? If I remplace the "." with a different local symbol, everything works fine. Thank you in advance . |
|||
14 Dec 2019, 07:41 |
|
Tomasz Grysztar 14 Dec 2019, 09:15
This is yet another demonstration of why unconditional macros are tricky and should not be used without a good reason. Because your "store_wrapper" macro is unconditional, is it expanded during the definition of STRUC main_loop. And at the time the context is still global, so the value of "object" parameter has the global context associated with it and such text with context becomes part of the "main_loop" macro.
|
|||
14 Dec 2019, 09:15 |
|
MaoKo 14 Dec 2019, 09:33
Ok I think that I understand. And if you do:
Code: struc main_loop? local local_object? redefine local_object $01 store_wrapper local_object display local_object+"0", $A end struc The store_wrapper expand and after that the local keyword "take the control". Ps: I think that you should, maybe, introduce the subtle behavior with "." in the man. |
|||
14 Dec 2019, 09:33 |
|
Tomasz Grysztar 14 Dec 2019, 10:15
This behavior is not unique to ".", any identifier would keep its original context when used like this. The reason that it behaves differently with LOCAL is because LOCAL defines parameters for preprocessing, which take precedence over everything else. Consider this example:
Code: macro wrapper! object* namespace distinct object = 1 a = 2 repeat 1, a: 3 display 'parameter: ','0'+object,10 end repeat end namespace end macro macro main wrapper a end macro main display 'local: ','0'+distinct.a,10 display 'global: ','0'+a,10 Code: macro main namespace distinct a = 1 ; "a" here marked with global context a = 2 repeat 1, a: 3 display 'parameter: ','0'+a,10 ; "a" here also marked with global context, but preprocessing takes precedence end repeat end namespace end macro And LOCAL directive also defines parameters, so they take precedence over anything else. |
|||
14 Dec 2019, 10:15 |
|
MaoKo 14 Dec 2019, 11:19
thx .
|
|||
14 Dec 2019, 11:19 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.