2017-09-11 4 views
4

Donner le codevariables d'interpolation et macro Chaîne

class Test { 
    static function main() { 
    var i = 1; 
    trace(m('some before $i some after')); // some before 1 some after 
    } 

    static macro function m(e: haxe.macro.Expr) 
    { 
    trace(e); // { expr => EConst(CString(some before $i some after)), pos => #pos(Test.hx:4: characters 12-39) } 

    // trace the name of referenced var 
    /* 
    trace(); 
    */ 

    return macro $e; 
    } 
} 

Que dois-je placer dans le code commenté pour trace() le nom de la variable utilisée dans une expression String interpolée sans analyse syntaxique manuelle de la chaîne constante?

Répondre

4

Qu'est-ce que vous voulez est formatString:

class Test { 
    #if !macro 
    static function main() { 
    var i = 1; 
    trace(m('some before $i some after')); // some before 1 some after 
    } 
    #end 
    static macro function m(e: haxe.macro.Expr) 
    { 
    switch e.expr { 
     case EConst(CString(s)): 
     trace(haxe.macro.MacroStringTools.formatString(s, e.pos)); 
     default: 
    } 
    return e; 
    } 
} 
+0

Je suppose que c'est aussi ce que les différentes cibles utilisent pour sortir leurs chaînes interpolées ... Cela répond à ma question initiale. Et je pense que je devrais commencer vraiment à lire les documents de l'API. Et probablement le code source de vos bibliothèques sur github. ;) – szczepanpp

+2

Neat, merci Juraj, apprendre quelque chose de nouveau tous les jours. Je vais laisser ma réponse au cas où les gens vont chercher des mots-clés dans la solution naïve. : D Au moins j'ai le 'cas EConst (CString (str)):' Merci au didacticiel de correspondance de modèle récent de Mark. –

2

L'expression en entrée est une chaîne littérale constante. Donc, vous devez analyser le $i vous-même. Voici un exemple utilisant un regular expression, et pour les points bonus, obtenez son type dans le contexte appelant.

http://try-haxe.mrcdk.com/#B0B9E (Cliquez Build+run, et voir à la fois la sortie et la sortie du compilateur onglets)

import haxe.macro.Expr; 
import haxe.macro.Context; 

class Test { 
    static function main() { 
    var i = 1; 
    trace(m('some before $i some after')); // some before 1 some after 
    } 

    static macro function m(e: Expr) 
    { 
    trace(e); // { expr => EConst(CString(some before $i some after)), pos => #pos(Test.hx:4: characters 12-39) } 

    var interpolated:String = null; 
    switch e.expr { 
     case EConst(CString(str)): 
     trace(str); // 'some before $i some after' 
     var r = ~/\$\w+/; 
     if (r.match(str)) { // matched(0) -> $i 
      interpolated = r.matched(0).substr(1); 
      trace(interpolated); // 'i' 
     } 
     default: throw 'Macro m expects a string literal...'; 
    } 

    if (interpolated!=null) { 
     var t = Context.typeof({expr: EConst(CIdent(interpolated)), pos:Context.currentPos()}); 
     trace('Got interpolated var $interpolated of type $t'); // Got interpolated var i of type TAbstract(Int,[]) 
    } 

    return macro $e; 
    } 
} 
+0

Jeff, merci pour une réponse complète (btw n'a pas pensé à utiliser 'Context.typeof (...)'). Mais en fait, ma question était juste de vérifier mon hypothèse que c'est la seule façon de le faire. Qu'en est-il de 'trace (m ('certains avant $ {Std.string (i)} certains après'));' (http://try-haxe.mrcdk.com/#fEF62)? :) – szczepanpp

+0

Oui, l'entrée de la macro est simplement une chaîne. Analysez-le comme vous voulez, regex est un échantillon rapide paresseux. Il peut y avoir des bibliothèques pour analyser $ interpolation, je n'ai jamais regardé. Mais vous pourriez pousser autour: https://github.com/Simn/hxparse https://github.com/Simn/hxparse/wiki/Writing-a-Parser, dont https://github.com/Simn/haxeparser est basé sur. Plus précisément, cela semble lié à l'analyse par interpolation: https://github.com/Simn/haxeparser/blob/master/src/haxeparser/HaxeLexer.hx#L198-L203 –

+0

Autant que je comprends, haxeparser ne fonctionnera pas lorsqu'il est utilisé dans un contexte macro. Mais en fait il pourrait y avoir un peu de manipulation de code, donc je vais juste devoir vérifier si haxparse fonctionne dans les macros (ça devrait). – szczepanpp