Is there a way to read arbitrary haxe code into a file using macros?

So of course I know I can accomplish this by running a pre-build script or something like that. But I want to see if there’s a way I can read in some text from somewhere (let’s say, after processing a file) and effectively paste the code at a given position using the macro system.

While you can’t exactly paste code you have haxe.macro.Context.parse to go from a string to code.

You can do this in an initialization macro, in which case you can generate a class with your code using haxe.macro.Context.defineType.
Or adding it to an existing class using a build macro and @:build.

EDIT: see @bendmorris’ answer bellow for how to actually include code at a specific position (forgot about those macros)

1 Like

Sure you can. A macro function returns an expression of Haxe code (which can also be a block); calls to that function are replaced with the resulting expression at compile time:

import haxe.macro.Context;

class Test {
    macro static function insertCode() {
        return Context.parse("{var a = 1, b = 2; trace(a + b);}", Context.currentPos());
    }

    static function main() {
        trace("start");
        insertCode();
        trace("end");
    }
}

Result:

Test.hx:9: start
Test.hx:10: 3
Test.hx:11: end
2 Likes

While that works with something simple like that, I haven’t been able to let the code actually define classes and use the class outside:

This doesn’t work:

class Main
{
    private static macro function generateClass()
    {
        var text = "class TextAdventureTest
        {
            public function run():Bool
            {
                trace('Hello big, adventurous world!');
                return true;
            }
        }";
        return Context.parse(text, Context.currentPos());
    }

    static function main()
    {
        generateClass();
        var adventure = new TextAdventureTest();
        adventure.run();
    }
}

I get Type not found : TextAdventureTest

This won’t work because a class declaration isn’t valid at the place you’re calling the macro (inside a function.) For this you can use an initialization macro, as @ibilon described.

Okay. So the thing I want to do isn’t possible. Macros probably aren’t the right approach anyway. Thanks all for your help!