flat assembler
Message board for the users of flat assembler.
Index
> Macroinstructions > Simple error I can't see or smth I don't understand |
Author |
|
l_inc 01 Dec 2013, 23:08
^_^
I can point to the very location of the error. But the global cause of such problems is the fragile and awry architecture of the macros (I mean the architecture of your macros, not the one of the fasm's macrolanguage). It's full of hidden problems which are going to progressively show up. Thus the architecture should be completely and very carefully reconsidered. In particular it's very error prone to open a brace at a code location separate from the code location where the corresponding closing brace is expected. Macroblocks should rather be declared in monolithic code pieces. The actual difference between the working and non-working macroexpansion is that the working one engages the last match macroblock in the mov redefinition macro ("match =4 =0 ..."). The non-working examples make the _lm macro include the following match macroblock with it's closing brace used as the _lm definition ending. This way the _lm macro definition is closed before the first instruction of the lamda-function. Thus when it comes to endlamda the closing brace after endp is not consumed and therefore used as an argument of the endp macro. As long as endp does not take any arguments, this results in the error you see. _________________ Faith is a superposition of knowledge and fallacy |
|||
01 Dec 2013, 23:08 |
|
baldr 02 Dec 2013, 01:44
^_^,
l_inc pinned the problem exactly. It can be circumvented with some refactoring (to merge all cases into one): Code: format PE console include "Win32AX.Inc" macro __lambdas {}; empty lambdas list struc reequ [val] { common restore . . equ val } macro mov dest*, [src*] { common local __lambda lambda? equ -; not yet match =lambda args, src \{ __proc equ proc __lambda args lambda? reequ + \} match =lambda, src \{ __proc equ proc __lambda lambda? reequ + \} match -, lambda? \{; still not mov dest, src __proc equ \} match +, lambda? \{ mov dest, __lambda \} restore lambda? match , __proc \{ restore __proc rept 0 \\{; skip following 'match' \} match ___proc, __proc \{; expand '__proc' restore __proc macro __lambdas \\{ __lambdas; process previous lambdas ___proc; start current lambda definition \} } endlambda fix endp } .code here: mov edi, lambda uses ebx, mask and eax, [mask] ret endlambda stdcall edi, 1 mov edi, lambda mov eax, STD_OUTPUT_HANDLE ret endlambda stdcall edi ret __lambdas .end here |
|||
02 Dec 2013, 01:44 |
|
l_inc 02 Dec 2013, 09:28
baldr wrote: rept 0 uses aforementioned preprocessor behavior to implement something like else clause for enclosing match This is a really nice one. Never thought of this way of implementing an "elsematch". _________________ Faith is a superposition of knowledge and fallacy |
|||
02 Dec 2013, 09:28 |
|
revolution 02 Dec 2013, 09:32
l_inc wrote:
|
|||
02 Dec 2013, 09:32 |
|
l_inc 02 Dec 2013, 20:09
revolution
Killjoy. _________________ Faith is a superposition of knowledge and fallacy |
|||
02 Dec 2013, 20:09 |
|
revolution 02 Dec 2013, 20:55
l_inc wrote: Killjoy. |
|||
02 Dec 2013, 20:55 |
|
baldr 02 Dec 2013, 21:45
revolution,
Actually I used that hack only for proper cleanup: __proc symbolic constant is either empty or proc macro invocation. I can't restore it neither after macro directive, nor before it, except if inside match block to expand symbol; but match won't succeed with empty symbolic constant. So I choose to use rept 0 as a kind of goto. Probably I'd overlooked some option available. |
|||
02 Dec 2013, 21:45 |
|
l_inc 03 Dec 2013, 12:48
baldr
You could do it pretty conventionally by just declaring __proc as local. Another way would be to make a nested match and use ___proc as an expansion argument of the internal match. This way you don't need an additional restore for the constant you expand (in this case ___proc), cause its lifetime is limited by the external match macroblock. But come on, guys! How do you define a "hack", if such a lovely implementation of an "elsematch" falls into this category? I mean, this approach is quite general-purpose and appropriate for any case, where one needs an "elsematch", which is a crucial criterion for something to be not a hack. Is it just because you wouldn't think of it at the first place? Well, not every originally nontrivial solution is a hack. _________________ Faith is a superposition of knowledge and fallacy |
|||
03 Dec 2013, 12:48 |
|
^_^ 03 Dec 2013, 23:10
I merged those matches to one and expanded everything i could, so it works now (well, sort of), but after that example by baldr I can say that I really do not understand how this works.
l_inc wrote: Macroblocks should rather be declared in monolithic code pieces. But macro is just inserting pieces of text, will it really make a difference if I do it manually? l_inc wrote: This way the _lm macro definition is closed before the first instruction of the lamda-function But how is this even possible? I thought match block would not be expanded, and this closing-match bracket will still be closing-match bracket, I have no idea how it becomes end of macro. |
|||
03 Dec 2013, 23:10 |
|
baldr 04 Dec 2013, 00:16
^_^ wrote: …I can say that I really do not understand how this works. ^_^ wrote: But how is this even possible? I thought match block would not be expanded, and this closing-match bracket will still be closing-match bracket, I have no idea how it becomes end of macro. Code: ;macro __lambda_macro_1{ ; proc __lambda_proc_1 uses __lambda_preserve ;;; ;;; Here next-to-last 'match' expansion ends; following is the expansion of 'mov' macro top nesting level. ;;; ; match=4=0,__lambda_parsed __matched ;{ ; match _lp _lm,__lambda_proc_current __lambda_macro_current ; \{ ; mov edi,_lp ; macro _lm{ ; proc _lp uses __lambda_preserve,__lambda_args ; \} ;} If you have questions about my refactoring, just ask. |
|||
04 Dec 2013, 00:16 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.