| Author |
Message |
|
| uwiger |
Posted: Thu Jul 06, 2006 2:32 pm |
|
|
|
User
Joined: 03 Jul 2006
Posts: 604
Location: Sweden
|
So, I was able to hack my way in, in lieu of a documented solution:
1) Copy file_io_server.erl (from kernel) to ram_file_io_server.erl
and modify slightly:
diff ram_file_io_server.erl file_io_server.erl
18c18
< -module(ram_file_io_server).
---
> -module(file_io_server).
27c27
< -define(PRIM_FILE, ram_file).
---
> -define(PRIM_FILE, prim_file).
2) Write the following code:
compile_string(_W, Mod, Str) ->
Fname = Mod ++ ".erl",
{ok, Fd} = open_ram_file(Fname),
file:write(Fd, Str),
file:position(Fd, 0),
case epp_dodger:parse(Fd) of
{ok, Tree} ->
Forms = revert_tree(Tree),
close_ram_file(Fd),
Forms;
Error ->
close_ram_file(Fd),
Error
end.
open_ram_file(Fname) ->
ram_file_io_server:start(self(), Fname, [read,write]).
close_ram_file(Fd) ->
file:close(Fd).
revert_tree(Tree) ->
[erl_syntax:revert(T) || T <- Tree].
The 'ram' option to file:open/2 is not documented; the whole ram_file
framework seems to be secret. The problem with file:open(F, [ram, read,
write]) is that the opened file seems to get the same type of semantics
as with 'raw'. Epp_dodger uses the io module to parse the contents
behind Fd, and this doesn't work with raw devices.
(One could of course imagine a slight rewrite of file_io_server so that
it accepts some other low-level file driver other than prim_file... but
file_io_server is by all means undocumented too.)
After this, one just needs to call
{ok,M,Bin} = compile:forms(Forms, [binary]),
compile:load_binary(M, F, Bin).
BR,
Ulf W
> -----Original Message-----
> From: Ulf Wiger (AL/EAB)
> Sent: den 6 juli 2006 14:22
> To: erlang-questions@erlang.org
> Subject: compiling a module from a string
>
>
> I want to effectively call
>
> Str = "-module(m).\n-export([foo/0]).\nfoo() -> foo.\n".
> compile:string(Str, [binary]).
>
>
> Of course, this doesn't work, since compile.erl assumes that
> the source has to come from a file. So does epp.erl, BTW, and
> epp_dodger.
>
> A naive, but futile approach is of course:
>
> {ok, Tokens, _} = erl_scan:string(Str),
> erl_parse:tokens(Tokens).
>
> I'm sure there's a elegant sequence of commands that does
> this, but which is it?
>
> BR,
> Ulf W
Post recived frommailinglist |
|
|
| Back to top |
|
| axel |
Posted: Thu Jul 06, 2006 2:59 pm |
|
|
|
User
Joined: 03 Mar 2005
Posts: 271
|
On 2006-07-06 16:19, Ulf Wiger (AL/EAB) wrote:
>> Of course, this doesn't work, since compile.erl assumes that
>> the source has to come from a file. So does epp.erl, BTW, and
>> epp_dodger.
when faced with a similar problem for a pretty printer (epp_dodger
wanting a file) i found that epp_dodger:parse/1 could handle an io
object, instead of a file. so i wrote a string_io module that has
open()/close() and received the io_requests. would this have worked for
you? ie, can compile take an io object?
bengt
--
EPO guidelines 1978: "If the contribution to the known art resides
solely in a computer program then the subject matter is not
patentable in whatever manner it may be presented in the claims."
Post recived frommailinglist |
|
|
| Back to top |
|
| uwiger |
Posted: Thu Jul 06, 2006 8:40 pm |
|
|
|
User
Joined: 03 Jul 2006
Posts: 604
Location: Sweden
|
I want to effectively call
Str = "-module(m).\n-export([foo/0]).\nfoo() -> foo.\n".
compile:string(Str, [binary]).
Of course, this doesn't work, since compile.erl assumes that the source
has to come from a file. So does epp.erl, BTW, and epp_dodger.
A naive, but futile approach is of course:
{ok, Tokens, _} = erl_scan:string(Str),
erl_parse:tokens(Tokens).
I'm sure there's a elegant sequence of commands that does this, but
which is it?
BR,
Ulf W
Post recived frommailinglist |
|
|
| Back to top |
|
| mats |
Posted: Mon Jul 10, 2006 11:03 am |
|
|
|
User
Joined: 28 Feb 2005
Posts: 168
Location: budapest,hungary
|
Ulf Wiger (AL/EAB) wrote:
> I want to effectively call
>
> Str = "-module(m).\n-export([foo/0]).\nfoo() -> foo.\n".
> compile:string(Str, [binary]).
this should work iff there are no #@#$&* macros. if there is, it's pretty
easy to write a subset of epp and call it between scanning and parsing.
mats
cl(Text) ->
Forms = scan_and_parse(Text,1,[]),
{ok,Mod,Bin} = compile:forms(Forms),
code:load_binary(Mod,"generated",Bin).
scan_and_parse([],_Line,Forms) -> lists:reverse(Forms);
scan_and_parse(Text,Line,Forms) ->
{done,{ok,Toks,NLine},Cont} = erl_scan:tokens([],Text,Line),
{ok,Form} = erl_parse:parse_form(Toks),
scan_and_parse(Cont,NLine,[Form|Forms]).
Post recived frommailinglist |
|
|
| Back to top |
|
| uwiger |
Posted: Mon Jul 10, 2006 11:32 am |
|
|
|
User
Joined: 03 Jul 2006
Posts: 604
Location: Sweden
|
MaCro = Mats Cronqvist wrote:
> >
> > Str = "-module(m).\n-export([foo/0]).\nfoo() -> foo.\n".
> > compile:string(Str, [binary]).
>
> this should work iff there are no #@#$&* macros. if there
> is, it's pretty easy to write a subset of epp and call it
> between scanning and parsing.
Well, my ram_file_io_server works like a charm and lets me
use all the wonderful macros too. (:
/U
Post recived frommailinglist |
|
|
| Back to top |
|
| mats |
Posted: Mon Jul 10, 2006 11:44 am |
|
|
|
User
Joined: 28 Feb 2005
Posts: 168
Location: budapest,hungary
|
Ulf Wiger (AL/EAB) wrote:
>
> MaCro = Mats Cronqvist wrote:
>>> Str = "-module(m).\n-export([foo/0]).\nfoo() -> foo.\n".
>>> compile:string(Str, [binary]).
>> this should work iff there are no #@#$&* macros. if there
>> is, it's pretty easy to write a subset of epp and call it
>> between scanning and parsing.
>
> Well, my ram_file_io_server works like a charm and lets me
> use all the wonderful macros too. (:
>
my post was mainly to inform the lurkers that it is not necessary to hack
around in the kernel sources.
of course, if i can save even one poor, unsuspecting soul from using macros i
will surely get my reward in the hereafter.
mats
Post recived frommailinglist |
|
|
| Back to top |
|
|
|
All times are GMT
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|
|