flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > struggling with fasmg again... defining custom calm

Author
Thread Post new topic Reply to topic
fabbel



Joined: 30 Oct 2012
Posts: 83
fabbel 13 Dec 2023, 14:40
Hi
Question for you Tomasz, again about CALM :
i've been trying to use CALM to define "custom" CALM instuction - i.e. something more or less similar to c1, c2, c3 calminstructions in x86-2 package
... but with
* args
* local variables (defined with 'local ....')
* AND inx definition subjected to control directives (i.e. if, ....)
.... to allow for conditional definition of inx body

Despite everything I tried, I cant' figure out how to manage this... , in particular, I can't make FASMG properly reckon the argument(s) and locals ...
... I understand there is some kind of namespacing issue, but can't seem to find adequate workaround....
Could you pls help / direct me how to to it ??

see e.g. below snippet :
Code:
include 'utility/xcalm.inc'

macro ?! line&
        local __xcalm
        define __xcalm                          __xcalm
        define __xcalm.__local__                local

        calminstruction __xcalm.local locals&                   ; to prevent unconditional interception of 'local'
        end calminstruction

        match __local?, __xcalm.__local__
                calminstruction __xcalm.collect_xcalm def&
                        local _def, _buf

                                match =end? =xcalm?, def
                                jyes @end_xcalm

                                take _def, def
                                exit

                        @end_xcalm:
                                asm mvmacro __xcalm.collect_xcalm, ?
                                asm mvmacro __local, __xcalm.local

                        @rev:
                                take _buf, _def
                                jyes @rev

                        @loop_def:
                                assemble _buf
                                take , _buf
                                take _buf, _buf
                                jyes @loop_def

                                asm end calminstruction
                end calminstruction


                calminstruction xcalm? def*&
                                arrange def, =calminstruction def
                                call __xcalm.collect_xcalm, def
                                asm mvmacro __local, __xcalm.local
                                asm mvmacro ?, __xcalm.collect_xcalm
                end calminstruction

        end match


        purge ?
        line
end macro

FLAG = 1
CPT = 10

        xcalm test
                display 'test'
                display 13
                display 10
if FLAG
                compute CPT, CPT + 1
end if
        end xcalm


test

repeat 1 _cpt:CPT
        display 'CPT=', `_cpt, 13, 10
end repeat

    


... above works with such simple 'xcalm' test inx
... but fails as soon as i try to add argument(s) or local(s) inside 'xcalm'

e.g.

Code:
        xcalm test2 arg
                local _tmp

                        display 'arg='
                        arrange _tmp, arg
                        stringify _tmp
                        display _tmp
                        display 13
                        display 10

        end xcalm

test2 dummy
    
Post 13 Dec 2023, 14:40
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8340
Location: Kraków, Poland
Tomasz Grysztar 13 Dec 2023, 22:46
Yes, I suspect you have problems caused by the namespace context, because when lines that you collect become arguments of a macro, fasmg attaches the context to their text, and this context is not your intended one (of the inside of defined CALM instruction) because this definition has not been actually started yet - as you are just collecting lines to generate the full definition later.

My current solutions are way too convoluted - you could exploit the fact that the text intercepted while a definition of a macro is started is considered contextless, but this would require passing all the lines through twice (first, with a dummy macro definition, to gather the contextless text of all the lines, and then the second pass, no longer inside a macro definition, to filter which lines are to be passed to the collection).

I think the correct solution would be to add a syntactic option for any instruction definition, to specify that some macros should not add context information to the text of their arguments. The same exception that now applies to arguments of an unconditional macro executed during a definition of another macro, would then apply to any macro defined with this additional attribute. I should look into this.

Oh, and one more thing: you can remove all the context information from any text with RAWMATCH, or by passing it through STRINGIFY and EVAL, but this is not the same thing as not adding the context in the first place. Because the line may already contain snippets of text that have context inherited from elsewhere, and when adding the context information, it is only applied to the areas of text that did not have their own context information in the first place. Clearing all the context from the text would remove both, that's why it is not really a correct solution to the problem.

I'm aware that this is a very convoluted issue. If what I wrote appears incomprehensible, I could perhaps show it step by step on some examples...
Post 13 Dec 2023, 22:46
View user's profile Send private message Visit poster's website Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 83
fabbel 14 Dec 2023, 09:23
Hi Tomasz, thanks for feedback. Indeed, would be keen on seeing some step by step examples to clarify / demonstrate this topic.
Post 14 Dec 2023, 09:23
View user's profile Send private message Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 83
fabbel 14 Dec 2023, 09:43
On my side, I tried different variations of the snippet presented above ...

.. one of which was to capture arguments and locals during 'xcalm' lines collection,
to later 'preprocess' thoses lines before assembling them,
by prefixing all arguments & locals with '#', trying to enforce uniform 'local-ized' context in this way
(i.e. uniform context, local to resulting calm instruction definition) :
typ. any local variable defined as ' _var' in xcalm block, would be assembled as '#_var'
inside resulting calm instruction body (same for arguments).
... it kinda worked ...
... until I tried defining some xcalm using typ. 'arrange' cmd :
bec. as I see, typ. in the pattern (2nd arg. to arrange cmd), '#_var' is not interpreted as a single identifier,
but split as litteral '#', followed by identifier '_var', which destroyed the purpose

leading me to the question :
wud being able to somehow enforce 'coalescence' of '#' & '_var' into 'local-ized' identifier '_var'
help in solving this, or am I just plain misguided and the idea should be simply dropped dead.
Happy to see your view there as well

thx
Post 14 Dec 2023, 09:43
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8340
Location: Kraków, Poland
Tomasz Grysztar 14 Dec 2023, 10:33
I'm just going to add the feature I mentioned above. I should have done that ages ago.
Post 14 Dec 2023, 10:33
View user's profile Send private message Visit poster's website Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 83
fabbel 14 Dec 2023, 10:36
ok, many thx then !
Post 14 Dec 2023, 10:36
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8340
Location: Kraków, Poland
Tomasz Grysztar 14 Dec 2023, 12:37
The new feature is up, with k9u0 release (I'm going to make a dedicated thread with more information about it). The name of a macro argument can now use a "&" prefix to make it carry the text without adding context information, so that the text may become reinterpreted when put into new context.

In your example, it should be enough to change
Code:
macro ?! line&    
into
Code:
macro ?! &line&    
and also
Code:
calminstruction __xcalm.collect_xcalm def&    
into
Code:
calminstruction __xcalm.collect_xcalm &def&    
and this should solve your issues.
Post 14 Dec 2023, 12:37
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8340
Location: Kraków, Poland
Tomasz Grysztar 14 Dec 2023, 12:51
Also, here's my attempt to implement the same thing simpler:
Code:
macro xcalm declaration&
        local head
        define head calminstruction declaration
        calminstruction ? &line&
                local buffer, collection
                match =purge ?, line
                jyes commit
                take collection, line
                exit
            commit:
                take buffer, collection
                jyes commit
                assemble line
                assemble head
            out:
                take line, buffer
                jno done
                assemble line
                jump out
            done:
        end calminstruction
end macro

macro end?.xcalm!
        end calminstruction
        purge ?
end macro    
It passes a simple test:
Code:
FLAG = 1

        xcalm test arg
                display 'test'
                display 13
                display 10
if FLAG
                display arg
end if
        end xcalm

test 'arg'    
It also depends on the new feature, though.
Post 14 Dec 2023, 12:51
View user's profile Send private message Visit poster's website Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 83
fabbel 14 Dec 2023, 12:58
That was quick !
Will update to new release and look into this !
Tx !
Post 14 Dec 2023, 12:58
View user's profile Send private message Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 83
fabbel 14 Dec 2023, 15:45
getting Error with arrange cmd ...
... I mean changing prev. simple test to :
Code:
FLAG = 1
define REMEMBER_ARG

                xcalm test arg
                        display 'test'
                        display 13
                        display 10
if FLAG
                        stringify arg
                        display arg
end if

                        arrange REMEMBER_ARG, arg
                end xcalm

test 'arg'
    


yields
Quote:

Error: the value of symbol 'test:arg' is not valid for this use.
Post 14 Dec 2023, 15:45
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8340
Location: Kraków, Poland
Tomasz Grysztar 14 Dec 2023, 16:29
That's because STRINGIFY made a byte string value, which ARRANGE does not support.
Post 14 Dec 2023, 16:29
View user's profile Send private message Visit poster's website Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 83
fabbel 14 Dec 2023, 16:33
of course ! ... dumb me sry... missing the obvious ...
Post 14 Dec 2023, 16:33
View user's profile Send private message Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 83
fabbel 18 Dec 2023, 15:07
Hi

Can u pls have a look at the below - using irpv directive
(using 'xcalm' exactly as per your above implementation)

Code:
calminstruction local locls&    ; to prevent unconditional interception of 'local' inx 
end calminstruction

define __STACK__                first
define __STACK__                second


                xcalm test arg
                        local _tmp

                                display 'test :'
                                display 13
                                display 10

irpv __val, __STACK__
                                arrange _tmp, =__val arg
                                stringify _tmp
                                display _tmp
                                display 13
                                display 10
end irpv

                end xcalm

purge local

test try
    


I get :
Quote:

test :
first arg
second arg

Quote:

test try
test [5] (CALM)
Error: symbol 'arg' is undefined or out of scope.


... looks like (global) context is added to the arg symbol inside irpv block
... maybe some interference due to the '=__val' part in the arrange line (arrange _tmp, =__val arg) ?
Post 18 Dec 2023, 15:07
View user's profile Send private message Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 83
fabbel 18 Dec 2023, 15:15
... typ. it works fine if I replace
Code:
                                arrange _tmp, =__val arg
    


with

Code:
                                arrange _tmp, =__val =try
    


=> output :
Quote:

test :
first try
second try
Post 18 Dec 2023, 15:15
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8340
Location: Kraków, Poland
Tomasz Grysztar 18 Dec 2023, 16:04
It seems I overlooked one place that also needed adjustment to the new feature. Should be fixed now (version "k9zk").
Post 18 Dec 2023, 16:04
View user's profile Send private message Visit poster's website Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 83
fabbel 18 Dec 2023, 16:06
Will (re)try, thx !
Post 18 Dec 2023, 16:06
View user's profile Send private message Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 83
fabbel 18 Dec 2023, 16:15
Works fine now. Tx !
Post 18 Dec 2023, 16:15
View user's profile Send private message 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.