wiz-lang / wiz

A high-level assembly language for writing homebrew software and games on retro console platforms.
http://wiz-lang.org/
Other
409 stars 40 forks source link

Declare external functions #128

Open sehugg opened 3 years ago

sehugg commented 3 years ago

I tried to define some functions in ROM like this:

namespace bios {
  extern const ioinit @ 0xfda3 : func();
}

And then:

bios.ioinit();

But then I get a "expression is not callable" error. Am I missing a better way to do this? I tried var/const, func vs func(), etc.

Bananattack commented 3 years ago

Hi, thanks for reporting this! An extern keyword for functions would be really handy.

Doing like you did in the example wouldn't work though -- func when used in type of a const or var already is used to declare a function pointer, so the declaration there would mean a place in memory that holds a function pointer.

However, there's workarounds for you can use to get an external function in the meantime. Right now, the way to declare a function that's defined externally is to use a let statement or a inline func that calls the address directly, like so:

namespace bios {
    // Using an let declaration to bind a name to an address casted as func.
    // ioinit can be called like a function expression, and gets substituted anywhere it is referenced.
    let ioinit = 0xFDA3 as func;

    // alternatively, you can wrap a raw call in an inline func, like so:
    // however -- the downside to this version is that inline functions have no address, so you can't take a pointer to it.
    // (let, however will allow this)
    inline func ioinit2() {
        (0xFDA3 as func)();
    }
}

You can check the common/msx folder in the repo for an example of wrapping the MSX BIOS routines.

However, it would be nice to support something like extern func name() @ 0xFDA3; though, for consistency with some other declarations that allow the @ syntax. It would also improve error diagnostics compared to calling a let expression, and it would allow taking the address unlike an inline function...

I'll leave this open because I think this would be a good addition to the language.

There's also potentially some stuff with function values vs pointers that could be better clarified. This would definitely benefit from better docs (pending a merge of the docs site that lhsazevedo had worked on, to start with).

I've been less active on Wiz maintenance lately due to dayjob work, but trying to get back into the swing of things here. I've been working on a small refactor that will hopefully aid in making new feature development and fixes easier. It's been taking longer than expected due to only managing a few hours each week on sideprojects, but I'm trying to get this balanced a bit more. And I would like to get to these improvements at some point -- both better docs and extern funcs.

Anyway hope that this reply helps! And I hope that I can get to this task eventually.