Skip to content

Instantly share code, notes, and snippets.

@binki
Last active December 30, 2016 19:00
Show Gist options
  • Save binki/3f9ec47fed01deacba9184a417ec8790 to your computer and use it in GitHub Desktop.
Save binki/3f9ec47fed01deacba9184a417ec8790 to your computer and use it in GitHub Desktop.
More interpolated string macro fun
// Haxe’s macro support makes for a golden opportunity for building
// program metadata during compiletime. I think it would be very cool
// to be able to preprocess interpolated strings so that text can be
// extracted and analyzed separately (NLS?) or, e.g., to do JavaScript-style
// tagged string stuff/C#-style FormattableString stuff like automatically
// escaping expressions when building HTML, etc.
//
// However, it looks to me like right now macros are given CStrings
// which don’t even let you know if the string will be interpolated or
// not. And MacroStringTools.formatString() seems insufficient…
import haxe.macro.Expr;
import haxe.macro.MacroStringTools;
import haxe.macro.Printer;
class InterpolatedMacroPlay2 {
static function main() {
trace(intr('asdf'));
// How do I distinguish these two? I want to be able to
// separate out stuff from the top-level string from whole
// expressions in sub-level strings. But these produce
// identical ASTs when passed through
// MacroStringTools.formatString().
trace(intr('asdf${''}${'bsdf'}'));
trace(intr('asdf${''}bsdf'));
}
public macro static function intr(e:ExprOf<String>) {
trace('');
var formatted = null;
switch (e.expr) {
case ExprDef.EConst(c):
switch (c) {
case CString(s): formatted = MacroStringTools.formatString(s, e.pos);
default:
}
default:
}
trace(new Printer().printExpr(formatted));
trace(formatted);
return e;
}
}
$ haxe --run InterpolatedMacroPlay2
InterpolatedMacroPlay2.hx:30:
InterpolatedMacroPlay2.hx:40: "asdf"
InterpolatedMacroPlay2.hx:41: { expr => EConst(CString(asdf)), pos => #pos(InterpolatedMacroPlay2.hx:18: characters 20-24) }
InterpolatedMacroPlay2.hx:30:
InterpolatedMacroPlay2.hx:40: "asdf" + '' + 'bsdf'
InterpolatedMacroPlay2.hx:41: { expr => EBinop(OpAdd,{ expr => EBinop(OpAdd,{ expr => EConst(CString(asdf)), pos => #pos(InterpolatedMacroPlay2.hx:25: characters 20-24) },{ expr => EConst(CString()), pos => #pos(InterpolatedMacroPlay2.hx:25: characters 26-28) }), pos => #pos(InterpolatedMacroPlay2.hx:25: characters 20-28) },{ expr => EConst(CString(bsdf)), pos => #pos(InterpolatedMacroPlay2.hx:25: characters 31-37) }), pos => #pos(InterpolatedMacroPlay2.hx:25: characters 20-37) }
InterpolatedMacroPlay2.hx:30:
InterpolatedMacroPlay2.hx:40: "asdf" + '' + "bsdf"
InterpolatedMacroPlay2.hx:41: { expr => EBinop(OpAdd,{ expr => EBinop(OpAdd,{ expr => EConst(CString(asdf)), pos => #pos(InterpolatedMacroPlay2.hx:26: characters 20-24) },{ expr => EConst(CString()), pos => #pos(InterpolatedMacroPlay2.hx:26: characters 26-28) }), pos => #pos(InterpolatedMacroPlay2.hx:26: characters 20-28) },{ expr => EConst(CString(bsdf)), pos => #pos(InterpolatedMacroPlay2.hx:26: characters 29-33) }), pos => #pos(InterpolatedMacroPlay2.hx:26: characters 20-33) }
InterpolatedMacroPlay2.hx:18: asdf
InterpolatedMacroPlay2.hx:25: asdfbsdf
InterpolatedMacroPlay2.hx:26: asdfbsdf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment