Description
(I'm still exploring what this feature would involve; maybe it's not practical. But the problems from lacking something like this are real, even if there's a better solution than this.)
A problem that repeatedly comes up when writing macros is: how to tell what type an argument is?
Maybe you want to take a number or a string, and act differently based on which one it is. Maybe you want to take an 8- or 16-bit register. Maybe you want to take a label or a numeric literal.
Workarounds common in current asm macros are basically "string inspection". Want to know if it's a number or string? Check STRFIND("\1", "\"") == 0
... but that only works if \1
was a literal quoted string, not e.g. STRCAT("hel", "lo")
. Want to know if it's an 8-bit register? Check if STRLWR("\1")
is "a"
, "b"
, "c"
, etc... but that fails for LOW(bc)
. Want to know if it's a condition code? Check against "c"
, "nc"
, "z"
, "nz"
... but that fails for !!!z
, or for cy
if you did DEF cy EQUS "c"
.
Basically I'd like a DATATYPE()
function that takes pretty much any argument and returns something indicating its type. EQUS
expansion would occur inside the argument, which solves problems like DEF cy EQUS "c"
, or string-detection issues. (I'm writing up this request because I ran into a case where #name
was not an appropriate substitute for "{name}"
-- when a macro is inspecting it for a leading "
.)
I think DATATYPE
returning a string would be clear to the user and easy for us to extend in future, like JS typeof
. As for what types it should recognize:
"directive"
:SECTION
,assert
,MACRO
, etc"instruction"
:jp
,call
,Halt
, etc"rl"
:rl
... it can be a directive or an instruction"reg8"
:A
,LOW(de)
, etc"reg16"
:bc
,DE
,hl
,sp
,Af
"condition"
:z
,!nc
,!!!z
, etc"c"
:c
... it can be a register or a condition- Note that this would only apply to literal
c
(orEQUS
expanding out toc
).LOW(bc)
is not usable as a condition code incall/jp/jr
.
- Note that this would only apply to literal
"number"
:42
,$beef
,%1001
,BANK(x)
, etc"string"
:"hello"
,"""world"""
,STRCAT("a", "b")
, etc"identifier"
:Foo
,bar
,.
, etc"local"
:.foo
,Global.local
,..
, etc"other"
: Anything not matching a well-defined pattern (*
,SECTION UNION
,z + 2
, etc)- I'm not sure whether too-wild things should be supported and detected as
"other"
, or just be syntax errors. The actual real-world use cases don't need such flexibility, so we'd be fine making them syntax errors and maybe in future allowing broader input.
- I'm not sure whether too-wild things should be supported and detected as