macroshaxe

Return anonymous structure from expression macro


Given a map Map<String, Int> how can I create anonymous structure from expression macro?

This is what I am trying to achieve:

var res = myMacroFunc(["var1"=>12, "var2"=>66]);

res == {var1: 12, var2: 66}

Solution

  • There might be a cleaner way to do this... but you can iterate through each expression in the array declaration, use switch statement to match $a => $b and generate ObjectField. Store all ObjectFields in an array to create a EObjectDecl.

    Here's a working version in Haxe Playground.

    public static macro function myMacroFunc(e:haxe.macro.Expr):haxe.macro.Expr {
      final objects = [];
      switch (e.expr) {
        // input is array decl
        case EArrayDecl(values):
          {
            for (v in values) {
              switch (v) {
                // match expression of format $a => $b
                case macro $a => $b: {
                    switch (a.expr) {
                      // "a" must be a string constant, so we extract that
                      case EConst(CString(s, _)): {
                          objects.push({field: s, expr: b});
                        }
                      case _: {}
                    }
                  }
                case _: {}
              }
            }
          }
        case _:
          {}
      }
    
      return {
        pos: e.pos, // re-use input position
        expr: EObjectDecl(objects) // pass to EObjectDecl
      };
    }