Skip to content

[Feature request] Detect the type of a given piece of code (basic reflection or pattern matching) #1705

Open
@Rangi42

Description

@Rangi42

(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 (or EQUS expanding out to c). LOW(bc) is not usable as a condition code in call/jp/jr.
  • "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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementTypically new features; lesser priority than bugsrgbasmThis affects RGBASM

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions