flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > [fasmg] making quoted strings in macros/calminstructions?

Author
Thread Post new topic Reply to topic
dosmancer



Joined: 20 Feb 2025
Posts: 19
Location: Kingdom of Sweden
dosmancer 08 May 2025, 00:25
This works:
Code:
calminstruction test1
        local tmp
        arrange tmp, =display 'Hello'
        assemble tmp
end calminstruction
test1    

But suppose you want to create the quoted string dynamically. This is my attempt but it didn't work sadly:
Code:
calminstruction test2 val
        local tmp
        arrange quote, '
        arrange tmp, =display quote val quote
        assemble tmp
end calminstruction
test2 Hello

; flat assembler  version g.kp60
; fasm_macro_tests/attempt_to_create_quoted_string.asm [16]:
;         test2 Hello
; test2 [4]
; Processed: display ' Hello '
; Error: missing end quote.    
Post 08 May 2025, 00:25
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4227
Location: vpcmpistri
bitRAKE 08 May 2025, 03:10
Code:
calminstruction str line&
        stringify line
        display line
end calminstruction
str test -3 -0.1    


Code:
calminstruction(var) str line&
        stringify line
        publish var,line
end calminstruction
tmp str test -3 -0.1
display 10,tmp    

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 08 May 2025, 03:10
View user's profile Send private message Visit poster's website Reply with quote
dosmancer



Joined: 20 Feb 2025
Posts: 19
Location: Kingdom of Sweden
dosmancer 08 May 2025, 13:24
Thanks. That works for the exact case I mentioned but I just intended that to be
a simple demonstration. I will try to explain better what I'm trying to do.
Code:
calminstruction str line&
        stringify line
        assemble line ; won't work because assemble can't take string "value"
end calminstruction
str display ' Hello '    

Code:
calminstruction test val
        local tmp
        arrange tmp, =display val
        assemble tmp
end calminstruction
test ' Hello ' ; This works. It's this kind of 'Hello' I want to make dynamically.    

Code:
calminstruction test2 val
        local tmp
        arrange quote, '
        ; This will put the following into tmp: display ' Hello '
        ; and that sort of looks alright but it isn't. assemble command refuses
        ; to accecpt it.
        arrange tmp, =display quote val quote
        assemble tmp
end calminstruction
test2 Hello    

Now, let's have some fun.
First, we create a util to count number of tokens:
Code:
calminstruction calminstruction?.count_tokens? line&
        local count, head, tail
        transform line
        compute count, 0
        arrange tail, line
    next:
        match head tail, tail
        jno last
        compute count, count + 1
        jump next
    last:
        match head, tail
        jno done
        compute count, count + 1
    done:
        local line_str, count_str
        arrange line_str, line
        stringify line_str
        arrange count_str, count
        stringify count_str
        display line_str bappend " consists of " bappend count_str bappend \
                " tokens" bappend 13 bappend 10
end calminstruction    

Now let's examine what's going on:
Code:
calminstruction test3 val
        arrange quote, '
        arrange quotedHello, ' Hello '
        arrange rawHello, =Hello

        arrange incorrect, =display quote rawHello quote
        arrange correct, =display quotedHello
        
        count_tokens correct
        count_tokens incorrect
end calminstruction
test3    

This produces the output:
Code:
flat assembler  version g.kp60
display ' Hello ' consists of 2 tokens
display ' Hello ' consists of 4 tokens

2 passes, 0 bytes.    

The correct case consists of 2 tokens namely display and ' Hello '.
The incorrect case consists of 4 tokens namely display and ' and Hello and '.

Like it's almost as if I'd need some kind of quote command that is like the stringify command but unlike stringify which produces a string "value" the quote command would make tokens into a "quoted string",
unless there is another way to create these "one-token quoted strings"
Post 08 May 2025, 13:24
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8394
Location: Kraków, Poland
Tomasz Grysztar 08 May 2025, 14:22
The quote character is not a token by itself, unlike special characters like a colon or comma. It is consumed when forming a string token. When you write:
Code:
arrange quote, '    
the last token of this line is a string token, with empty string inside, and in this case additionally marked as "missing end quote" (which causes an error if you try to evaluate it in an expression, but is allowed otherwise).

Tokens are only created during the tokenization process - when the lines are read from the raw source text. After that, all fasm's operations only move tokens around, but each and every token is indivisible and unmodifiable entity. When you perform an ARRANGE, it just combines tokens from various sources into a new sequence, but you cannot form new tokens this way.

Why do you need it to be a single string token, though? Usually when fasmg expects a string value, like in an INCLUDE statement, it can be provided as computable expression.

But if it's really necessary, there is a way to perform a new tokenization of raw text: the EVAL directive.
Post 08 May 2025, 14:22
View user's profile Send private message Visit poster's website Reply with quote
dosmancer



Joined: 20 Feb 2025
Posts: 19
Location: Kingdom of Sweden
dosmancer 08 May 2025, 21:04
Tomasz Grysztar wrote:
the last token of this line is a string token, with empty string inside, and in this case additionally marked as "missing end quote" (which causes an error if you try to evaluate it in an expression, but is allowed otherwise).

Thanks. That explains the error message and the reason behind it.
Tomasz Grysztar wrote:
Why do you need it to be a single string token, though?

I have a Motorola 68000 project and, for now, I want it to be possible for different assemblers to assemble the source code. In order to do this I have tried to make all macros with fasmg and those macros I either run directly with fasmg or I use preprocess.asm to produce output which another assembler can assemble.

So I have the preprocess.asm that, with some overrides to produce text instead, preprocesses main.asm. Non-fasmg assemblers assemble file that is output (i.e. all macros are expanded):
Code:
define preprocess_asm

macro calminstruction?._assemble? &line&
    stringify line
    emit lengthof line, line
    emit 1, 13
    emit 1, 10
end macro

define MACROS
namespace MACROS
    include "macros.inc"
end namespace

; and the rest of preprocess.asm    


When I assemble with fasmg I include the macros and main.asm directly (no preprocessing) as well as switch to normal assemble command:

Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Wrapper for fasmg                                                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

include "macros.inc"

macro calminstruction?._assemble? line&
    assemble line
end macro

include "main.asm" ; the actual source code (does not contain any macro definitions!)    


The problem arose in the macros.inc file here:

Code:
;;;;;;;;;;;;;;;;
;; MACROS.INC ;;
;;;;;;;;;;;;;;;;

calminstruction meta_version
        local tmp, quote, s_since_2025, m_since_2025

        arrange quote, '

        compute tmp, __time__
        compute s_since_2025, tmp - 1735686000
        compute m_since_2025, s_since_2025 / 60
        arrange tmp, =dc.=b quote=GM m_since_2025 quote
        _assemble tmp ; <-- here
end calminstruction
    

The code works for the preprocess case because it stringifies and then emits the line as text.

Running it directly via the fasmg wrapper (i.e. without any preprocessing) did cause the problem with "missing end quote".

Note: I have since then refactored the code and it now works without having to create a "single-token quoted string"
Post 08 May 2025, 21:04
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8394
Location: Kraków, Poland
Tomasz Grysztar 09 May 2025, 06:29
I see. As I understand, you would prefer to keep the value as a single quoted string to make the line clean/readable in the source generated for other assemblers. Here's how you could make it into a quoted string using EVAL:
Code:
include 'xcalm.inc'

struc tokenize string
        eval 'define . ',string
end struc

calminstruction meta_version
        local tmp, quote, s_since_2025, m_since_2025

        compute tmp, __time__
        compute s_since_2025, tmp - 1735686000
        compute m_since_2025, s_since_2025 / 60
        arrange m_since_2025, m_since_2025
        stringify m_since_2025

        compute tmp, "'GM" bappend m_since_2025 bappend "'"
        asm tmp tokenize tmp

        arrange tmp, =dc.=b tmp
        _assemble tmp
end calminstruction    
Post 09 May 2025, 06:29
View user's profile Send private message Visit poster's website Reply with quote
dosmancer



Joined: 20 Feb 2025
Posts: 19
Location: Kingdom of Sweden
dosmancer 10 May 2025, 11:09
Tomasz Grysztar wrote:
Code:
struc tokenize string
        eval 'define . ',string
end struc

calminstruction meta_version
        local tmp, quote, s_since_2025, m_since_2025

        compute tmp, __time__
        compute s_since_2025, tmp - 1735686000
        compute m_since_2025, s_since_2025 / 60
        arrange m_since_2025, m_since_2025
        stringify m_since_2025

        compute tmp, "'GM" bappend m_since_2025 bappend "'"
        asm tmp tokenize tmp

        arrange tmp, =dc.=b tmp
        _assemble tmp
end calminstruction    

Thanks. Works perfectly 👌
Post 10 May 2025, 11:09
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.