On Nov 24, 5:08 pm, Tony Arcieri <
tony.arci...@medioh.com> wrote:
> On Wed, Nov 24, 2010 at 5:53 AM, candlerb <
b.cand...@pobox.com> wrote:
> > I've not looked at Reia for a while, but I like the new website, and
> > I've just built the latest git master. A bunch of tests fail, but it
> > runs. It's looking very impressive.
>
> Awesome, great work. Is it available on github?
Is what available on github? All I did was build your code from
git://
github.com/tarcieri/reia.git
Here are the tests which fail:
$ rake
(in /v/brian/git/reia)
Checking Erlang version... 5.7.4 (ok)
bin/reia test/
runner.re
EE..............................E..........EEEEEE.....E.........................
builtins/
binary.re ERROR: undef
builtins/
boolean.re ERROR: undef
builtins/
tuple.re ERROR: undef
builtins/
range.re ERROR: undef
builtins/
regexp.re ERROR: undef
builtins/
numeric.re ERROR: undef
builtins/
dict.re ERROR: undef
builtins/
fun.re ERROR: undef
core/
blocks.re ERROR: undef
core/
funrefs.re ERROR: undef
Finished in 0.085041 seconds
78 assertions, 0 failures, 10 errors
rake aborted!
Command failed with status (1): [bin/reia test/runner.re...]
/v/brian/git/reia/Rakefile:92
(See full trace by running task with --trace)
> I've been
> meaning to add an option to reiac ala reiac --erl that would output pretty
> printed Erlang source code.
That would be great. I was just trying to get at the abstract parse
tree so I could erl_pp it.
As far as I can tell, this has to be read from the .beam file, not the
loaded chunk in RAM: see
http://erlang.2086793.n4.nabble.com/Help-with-erl-parse-epp-td2108447.html
Looking for a function which can split a .reb into chunks, I found
reia_internal:load. Unfortunately this loads and executes, so I'd need
to reimplement the logic just to load the abstract code chunk.
This gives something interesting to try in reia itself -
unfortunately, as it uses record types, I think I'll have to deal with
them as tuples (I don't suppose reia supports records?)
$ bin/ire
...
>> (:ok, data) = erl.file.read_file("lib/uuid.reb".to_list()); (data.class(), data.size())
=> (Binary,6120)
### Using my knowledge of the record format
>> (:reia_module, version, filename, base_module) = erl.binary_to_term(data)
...
>> filename
=>
[47,118,47,98,114,105,97,110,47,103,105,116,47,114,101,105,97,47,108,105,98,47,117,117,105,100,46,114,101]
### Not sure how to turn this into a reia string now:
>> String(filename).puts()
NoMethodError: undefined method 'initialize' for String
>> (:reia_string, filename).puts()
/v/brian/git/reia/lib/
uuid.re
>> (:ok, (mod, chunks)) = erl.beam_lib.chunks(base_module, [:abstract_code]); mod
=> :'/v/brian/git/reia/lib/uuid'
>> erl.length(chunks)
=> 1
>> (:abstract_code, (vers,forms)) = chunks[0]; nil
=> nil
>> forms.size()
=> 6
>> erl.erl_pp.form(forms[0])
=> [[[[[45,[109,111,100,117,108,101]]],[[40,
[[[39,47,118,47,98,114,105,97,110,47,103,105,116,47,114,101,105,97,47,108,105,98,47,117,117,105,100,39]],
41]]]],[46,10]]]
### Again, would be nice to have a simple way to wrap this iolist in a
String
>> (:reia_string, erl.erl_pp.form(forms[0]))
=> "-module('/v/brian/git/reia/lib/uuid').
"
>> forms.each() { |form| erl.io.fwrite(<["~s"]>, erl.erl_pp.form(form)) }; nil
-module('/v/brian/git/reia/lib/uuid').
-file("/v/brian/git/reia/lib/
uuid.re", 1).
-code([{class,
9,
'UUID',
'Object',
[{function,
11,
initialize,
[],
{var,1,'_'},
[{match,11,{ivar,11,ref},{native_call,11,erlang,make_ref,
[]}}]},
...
-parent('/v/brian/git/reia/lib/uuid').
-submodules([{static,
'UUID',
<<70,
79,
82,
49,
0,
0,
10,
52,
66,
69,
65,
77,
65,
116,
111,
109,
0,
0,
0,
...
159,
0,
0,
0>>}]).
toplevel() ->
reia_internal:load_submodule('UUID', module_info(attributes)).
Hmm, I didn't learn as much about the reia compiled code from that as
I thought I would. What are the -code and -submodule sections?
But I did have a useful play with ire talking to erlang. It can be a
bit awkward, but still easier than the erl shell :-)
One thing I learnt to be careful of when mapping erlang to reia is to
remember the : for atoms. It's easy to write:
(reia_module, version, filename, base_module) =
erl.binary_to_term(data)
instead of
(:reia_module, version, filename, base_module) =
erl.binary_to_term(data)
Both work, but the first case would also match things that don't start
with the :reia_module atom.
> Going down the road of having Strings be binaries internally is
> another option. iolists seemed like the POLS for Erlang, though.
If Strings were binaries internally it would be easier to deal with
native erlang code which accepts or returns binaries - such as the
format argument to erl.io.fwrite, or the data returned by
erl.file.file_read
Some methods return iolists anyway, like erl_pp:form, but you still
have to wrap them in (reia_string, ...) to use them as Strings in
reia.
If strings were binaries, and you wanted lazy flattening, you could
always write
mylist = [s1, s2]
explicitly (if a bare binary is also an iolist, this would be
acceptable to functions which take iolists). Or perhaps String could
be a native binary, but you also have an (:iolist, ...) class which
works like String today.
> > I notice that converting a binary to a string doesn't wrap it in a
> > list, is this intentional?
>
> > >> erl.io.write("foo")
> > {reia_string,[<<102,111,111>>]}=> :ok
> > >> erl.io.write(<["foo"]>.to_s())
> > {reia_string,<<102,111,111>>}=> :ok
>
> Yes, my understanding is that a naked binary is still a valid iolist.
Then perhaps for efficiency the string literal "foo" should be
(reia_string,<["foo"]>) instead of (reia_string,[<["foo>]"]) ?
Cheers,
Brian.