2010-01-29 4 views
3

J'ai une chaîne générée qui contient le code pour un module erlang.Comment compiler le code erlang chargé dans une chaîne?

Existe-t-il un moyen de compiler le module généré directement à partir de la chaîne?

Ou existe-t-il un moyen de convertir la chaîne dans le format requis pour compile:forms/1? Ou devrais-je l'enregistrer dans un fichier temporaire d'abord, puis le compiler avec compile:file/1?

Alternativement, je peux ajouter un support au module de compilation, mais il doit y avoir une raison pour laquelle les bonnes personnes qui écrivent erlang ne l'ont pas ajouté.

Répondre

13

Vous devez analyser votre chaîne en jetons, puis analyser les jetons en formulaires. Malheureusement, il est seulement possible d'analyser un formulaire à la fois, donc vous devrez soit couper votre chaîne, soit vos jetons aux limites du formulaire. Voici un court exemple:

% create tokens from strings containing forms 
> {ok, MTs, _} = erl_scan:string("-module(z)."). 
> {ok, ETs, _} = erl_scan:string("-export([f/0])."). 
> {ok, FTs, _} = erl_scan:string("f() -> hello_world."). 
% tokens to erl_parse trees 
> {ok,MF} = erl_parse:parse_form(MTs). 
> {ok,EF} = erl_parse:parse_form(ETs). 
> {ok,FF} = erl_parse:parse_form(FTs). 

% compile forms to binary 
> {ok, z, Bin} = compile:forms([MF,EF,FF]). 
{ok,z,<<70,79,82,49,0,0,1,164,66,69,65,77,65,116,111,109,0,0,0,...>>} 

% load module from binary 
> code:load_binary(z, "nofile", Bin). 
{module,z} 

% test 
> z:f(). 
hello_world 

Sinon, vous pouvez analyser votre chaîne, puis couper la liste de jetons résultant à {dot, _} jetons à part.

+0

On dirait bien, merci, je ne savais pas que je devais tout renverser: D –

+1

Correction de la faute de frappe. Je suppose que vous pourriez mettre votre code source entier dans une seule chaîne, le scanner, puis couper la liste de jetons à chaque '{point, _}'. – Zed

+0

Aussi, notez que comprend ne fonctionne pas avec cette approche (voir: http://stackoverflow.com/questions/2013119/compile-forms-with-included-header-files) – Zed

0

Stockez le contenu de la chaîne dans un fichier avec un nom de module (s'il n'y figure pas dans le code) et compilez-le en utilisant compile module.
Le code devient disponible dans la machine virtuelle. J'utilise cette technique pour convertir un fichier de configuration en un module. De cette façon, il n'y a pas beaucoup de copie binaire pendant l'exécution.