flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > [fasmg] Strange behaviour with STRING word

Author
Thread Post new topic Reply to topic
VMo



Joined: 06 Sep 2024
Posts: 4
Location: Brest FRANCE
VMo 21 Jun 2025, 15:41
Hello to all !
Using Fasmg as backend for an ada 83 compiler, I stumbled upon a problem with using STRING as name for a namespace.

Reducing the problem to its simplest form here it is :

Code:
namespace WHATEVER

macro VAR
end macro

namespace STRING
VAR
end namespace

end namespace
    


gives "illegal instruction at line 7 (VAR)

If "STRING" is replaced with "STRING_" or anything else reasonable, it passes ok.
If the outside namespace is removed, even with STRING it passes.

Why is it so ? I did not see STRING as a keyword in the documentation, and why would it be context dependent ?
I perhaps missed something simple...
Post 21 Jun 2025, 15:41
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8434
Location: Kraków, Poland
Tomasz Grysztar 21 Jun 2025, 17:05
Yes, STRING is a keyword, it is one of the expression operators (documented in section 4 of the manual). All such operators are defined as global case-insensitive symbols, so when you enter "namespace STRING", you enter a namespace of a symbol that is defined in outside of your WHATEVER namespace and the macro VAR is no longer in scope.

You can override this with your own local symbol:
Code:
namespace WHATEVER

macro VAR
end macro

string? = 1

namespace STRING
VAR
end namespace

end namespace    
And for this very reason it is recommended to always define the anchor symbol for the namespace you plan to use, otherwise you may not have a complete control over what namespace you are actually selecting.
Post 21 Jun 2025, 17:05
View user's profile Send private message Visit poster's website Reply with quote
VMo



Joined: 06 Sep 2024
Posts: 4
Location: Brest FRANCE
VMo 21 Jun 2025, 18:09
Ok I got it, thank you very much indeed Thomas !
Post 21 Jun 2025, 18:09
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8434
Location: Kraków, Poland
Tomasz Grysztar 21 Jun 2025, 19:52
With the latest CALM capabilities it's possible to overload the NAMESPACE directive to make it require a defined symbol as an anchor:
Code:
calminstruction namespace? &identifier
        match   identifier:equ, identifier, :
        jyes    found
        check   defined identifier
        jyes    found
        err     'no defined symbol found for the namespace anchor'
    found:
        arrange identifier, =namespace identifier
        assemble identifier
end calminstruction    
The DEFINED check does not work with expression operators like STRING, because it expects a well-formed expression, but in your case this side-effect could be actually helpful.
Post 21 Jun 2025, 19:52
View user's profile Send private message Visit poster's website Reply with quote
Jessé



Joined: 03 May 2025
Posts: 59
Location: Brazil
Jessé 21 Jun 2025, 20:00
Indeed, I already had a similar problem when I unfortunately choose the word 'else' as a term in a code:

Code:
; ... something previously happening
match something else, dest
    ; pattern subroutine
; some more stuff
end match
    


The above code gaves me absolute chaos on that thing. So it is always a good idea to check if a term is a keyword or fasmg directive that may conflict.
Post 21 Jun 2025, 20:00
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8434
Location: Kraków, Poland
Tomasz Grysztar 22 Jun 2025, 08:18
Jessé wrote:
Indeed, I already had a similar problem when I unfortunately choose the word 'else' as a term in a code:

Code:
; ... something previously happening
match something else, dest
    ; pattern subroutine
; some more stuff
end match
    


The above code gaves me absolute chaos on that thing. So it is always a good idea to check if a term is a keyword or fasmg directive that may conflict.
It think it could be interesting to explain in detail what is happening here. Before any line is assembled, it goes through preprocessing, where any active parameters are replaced with their value. A successful MATCH in your example defines an "else" parameter, so if all the following lines (before the MATCH block is closed and the parameter deactivated) this word is replaced with whatever it was matched with:
Code:
macro poke dest
        match something else, dest
        else match anything else, dest
        end match
end macro

poke +A    
In this example line:
Code:
        else match anything else, dest    
becomes:
Code:
        A match anything A, +A    
because "else" is a parameter with value "A", and "dest" is a parameter (of longer lifespan) with value "+A". You can see the content of this preprocessed line in the error message (it's a good exercise to check whether they agree with your mental model).

The parameters are normally case-sensitive, so you could still avoid the conflict by using different case:
Code:
macro poke dest
        match something else, dest
        ELSE match anything Else, dest
        end match
end macro

poke +A    
This would break again if you made the parameter case-insensitive:
Code:
        match something else?, dest    
But you could also add another parameter, which would have value "else", allowing you to somehow inject this word into the preprocessed line:
Code:
macro poke dest
        match something else? || _ELSE_, dest || else
        _ELSE_ match anything _ELSE_, dest
        end match
end macro    
and the parameters do not need to be defined all at once, they may have different lifespans:
Code:
macro poke dest
        match _ELSE_, else
                match something else?, dest
                _ELSE_ match anything _ELSE_, dest
                end match
        end match
end macro    
I do not recommend using these tricks normally, but I believe that playing with them should give a better understanding of what happens, and more confidence to use fasmg's engine exactly as you see fit.
Post 22 Jun 2025, 08:18
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8434
Location: Kraków, Poland
Tomasz Grysztar 22 Jun 2025, 08:27
As for the NAMESPACE overloading I proposed earlier, here's a version with more granular error messages:
Code:
calminstruction namespace? &identifier
        match   identifier:equ, identifier, :
        jyes    finish
        match   identifier:name, identifier, :
        jno     invalid
        match   identifier:expression, identifier, :
        jno     operator
        check   defined identifier
        jyes    finish
        err     'no defined symbol found for the namespace anchor'
        jump    finish
    operator:
        err     'operator symbol used as a namespace anchor'
        jump    finish
    invalid:
        err     'not a valid identifier'
    finish:
        arrange identifier, =namespace identifier
        assemble identifier
end calminstruction    
They could also be made to only warn:
Code:
calminstruction warn? prefix:'', value:, suffix:''
        display __FILE__
        display '['
        local   tmp
        compute tmp, __LINE__
        arrange tmp, tmp
        stringify tmp
        display tmp
        display '] warning: '
        display prefix
        stringify value
        display value
        display suffix
        display 10
end calminstruction

calminstruction namespace? &identifier
        match   identifier:equ, identifier, :
        jyes    finish
        match   identifier:name, identifier, :
        jno     invalid
        match   identifier:expression, identifier, :
        jno     operator
        check   defined identifier
        jyes    finish
        xcall   warn, ('symbol "'), identifier ,('" is undefined')
        jump    finish
    operator:
        xcall   warn, ('"'), identifier, ('" is an operator')
        jump    finish
    invalid:
        xcall   warn, ('"'), identifier, ('" is not a valid identifier of a symbol')
    finish:
        arrange identifier, =namespace identifier
        assemble identifier
end calminstruction    
Post 22 Jun 2025, 08:27
View user's profile Send private message Visit poster's website Reply with quote
VMo



Joined: 06 Sep 2024
Posts: 4
Location: Brest FRANCE
VMo 22 Jun 2025, 15:06
Thank you for those interesting examples, fasm is definitely a fascinating assembly engine. For now I can adhere to the simple solution of adding an identifier definition in front of each namespace use.
Post 22 Jun 2025, 15:06
View user's profile Send private message Reply with quote
Jessé



Joined: 03 May 2025
Posts: 59
Location: Brazil
Jessé 22 Jun 2025, 17:33
Very interesting, Tomasz, I'll try to recreate the scenario with the exact problem and post it back here. Unfortunately, I don't have the exact scenario anymore, so, I should do some tests, but I can tell that it is related to a previous than BETA1 version of my fastcall macro toolkit developing.
And also important is, at that time, fasmg version was 'g.kp60'. And the prompt solution were replacing 'else' term with another word. I'll let you know.
Thanks again for the detailed explanation.

P.S.: the issue occured in a long "switch case" block (i.e., it has plenty of 'else match's and 'else if's following the line with the issue).
Post 22 Jun 2025, 17:33
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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.