flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
l_inc 31 Jul 2015, 00:11
DimonSoft
There's a simple way to create a single-shot macro: Code: macro single_shot {} macro single_shot { single_shot purge single_shot } Though it's not quite nesting friendly, which is what you're gonna need. Anyway I'd recommend you to restrain from that. Following is an architecture you'd be good with: Code: match , { local begin_ctx, end_ctx,\ begin_stub, end_stub,\ begin_proc, end_proc macro begin_stub \{ display 'Error: begin context not defined',13,10 err \} macro end_stub \{ display 'Error: end context not defined',13,10 err \} define begin_ctx begin_stub define end_ctx end_stub macro begin \{ match b,begin_ctx \\{ b \\} \} macro end args& \{ match ,args \\{ match e,end_ctx \\\{ e \\\} restore begin_ctx,end_ctx rept 0 \\\{ \\} match,\\{ end args \\} \} ;here you can start defining contexts such as procedure macro procedure \{ define begin_ctx begin_proc \} macro begin_proc \{ define end_ctx end_proc display 'Prologue',13,10 \} macro end_proc \{ display 'Epilogue',13,10 \} } Here you have shared identifiers begin_ctx and end_ctx to hold the context of the begin-end pair. If there's no context, the stub macros are invoked. An important part here is that you can define data shared between paired macros inside the local identifiers and still the data is not available from outside. Additionally you avoid large macro definition-purging-redefinition overhead otherwise induced for each begin-end pair. Moreover nesting-friendliness is by design. P.S. And note that you need to preserve the original functionality of the end directive (end if, end while, etc.) as shown in the code above. _________________ Faith is a superposition of knowledge and fallacy |
|||
![]() |
|
DimonSoft 01 Aug 2015, 17:20
l_inc
Thanks, this match trick reminds me of the Javascript anonymous functions and looks amazing. Thanks for the idea. But I’m afraid, even with prepsrc tool, I don’t get how it solves the problem of using standard end if- and end while-like structures. And I can’t see where does the rept 0 statement end. Could you explain this in more detail, please? I tried this code: Code: if eax eq procedure begin end end if and got this output from prepsrc: Code: if eax eq ;procedure ;define begin_ctx?TE begin_proc?TI ;begin ;match b,begin_proc?TI{b} ;begin_proc?TI ;define end_ctx?TF end_proc?TJ display 'Prologue',13,10 ;end ;match, ;{ ; match e,end_ctx?TF \{ e \} ; restore begin_ctx?TE,end_ctx?TF ; rept 0 \{ ;} ;match e,end_proc?TJ{e} ;end_proc?TJ display 'Epilogue',13,10 ;restore begin_ctx?TE,end_ctx?TF ;rept 0{ ; match,{end} ;end if ;match,if ;{ ; match e,end_ctx?TF \{ e \} ; restore begin_ctx?TE,end_ctx?TF ; rept 0 \{ ;} ;match,{end if} end if |
|||
![]() |
|
DimonSoft 01 Aug 2015, 17:38
UPD. Oops, found the description of the preprocessor bug/feature which makes such rept 0 work as “ignore everything until the next closing curly bracket”, in this case—ignore the next match.
So, am I right if I say that the pattern you’ve suggested makes work the end macro this way (as currently implemented)? 1) makes it a part of begin-end pair, if no arguments are given; 2) leaves any end anything statements the way they are taking advantage of the “less-nested” end anything implementation. |
|||
![]() |
|
l_inc 02 Aug 2015, 00:58
DimonSoft
Quote: Oops, found the description of the preprocessor bug/feature Well, it's definitely not a bug, cause the behavior is documented and expected. I'd say it's a side effect of the preprocessor design, though this kind of use cases could very well be one of the author's intentions. Quote: So, am I right if I say that the pattern you’ve suggested makes work the end macro this way (as currently implemented)? Yes, you are perfectly right. _________________ Faith is a superposition of knowledge and fallacy |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.