mruby / mruby

Lightweight Ruby
MIT License
5.31k stars 791 forks source link

Approach to parse multiple not defined list of files #2311

Open luislavena opened 10 years ago

luislavena commented 10 years ago

Hello,

After looking into the source, specially mrbc.c, noticed there is not a easy mechanism to feed multiple files into a context and be able to obtain a single irep from it.

The current mechanism of mrb_load_file_cxt requires usage of mrbc_partial_hook and an already defined list of files to be fed into the parser to set the filename and continue loading other files in order to produce a single irep with multiple pools.

But there is no mechanism to feed mutliple files, setting their filenames and obtain a single irep.

The idea is to use the same mrb_state and mrb_context to collect multiple files in multiple passes, pseudo code follows:

mrbc_filename(mrb, cxt, "a.rb");
mrb_load_string_cxt(mrb, "puts 'a'", cxt);

mrbc_filename(mrb, cxt, "b.rb");
mrb_load_string_cxt(mrb, "puts 'b'", cxt);

irep = mrb....(mrb, cxt);
mrb_dump_irep_binary(mrb, irep, ...);

It is required for me to go low level (mrb_parser_parse, mrb_parser_set_filename, etc)?

Thank you.

luislavena commented 10 years ago

An update on this, even when using directly mrb_parser_parse and mrb_parser_set_filename the tree is reset on every invocation of parse:

NODE_SCOPE:
  NODE_BEGIN:
    NODE_CALL:
      NODE_SELF
      method='puts' (281)
      args:
        NODE_STR "a" len 1
NODE_SCOPE:
  NODE_BEGIN:
    NODE_CALL:
      NODE_SELF
      method='puts' (281)
      args:
        NODE_STR "b" len 1

Is there another approach without using parser_hook ?

Thank you.

luislavena commented 9 years ago

Closing due lack of response (almost a year).

Cheers.

zzak commented 9 years ago

It doesn't seem the intent of mrb parser to accept multiple files at once /cc @matz

matz commented 9 years ago

Sorry, I missed this issue. I don't understand why do you want to creating one irep from multiple source file. Since irep itself has filename info, it cannot be generated from multiple files.

luislavena commented 9 years ago

@matz perhaps I'm mistaken, but from what I looked at the code (see my initial description), mrbc produces a single irep from a defined list of files that is fed into the parser.

$ mrbc -v -g -ofoo.mrb a.rb b.rb c.rb
mruby 1.1.0 (2014-11-19)
00001 NODE_SCOPE:
00001   NODE_BEGIN:
00001     NODE_CALL:
00001       NODE_SELF
00000       method='puts' (218)
00001       args:
00001         NODE_STR "hello from a" len 12
00001     NODE_CALL:
00001       NODE_SELF
00000       method='puts' (218)
00001       args:
00001         NODE_STR "hello from b" len 12
00001     NODE_CALL:
00001       NODE_SELF
00001       method='puts' (221)
00001       args:
00001         NODE_STR "hello from c" len 12
irep 0x7f95a0500020 nregs=4 nlocals=1 pools=3 syms=2 reps=0
file: a.rb
    1 000 OP_LOADSELF   R1
    1 001 OP_STRING R2  L(0)    ; "hello from a"
    1 002 OP_SEND   R1  :puts   1
file: b.rb
    1 003 OP_LOADSELF   R1
    1 004 OP_STRING R2  L(1)    ; "hello from b"
    1 005 OP_SEND   R1  :puts   1
file: c.rb
    1 006 OP_LOADSELF   R1
    1 007 OP_STRING R2  L(2)    ; "hello from c"
    1 008 OP_SEND   R1  :puts   1
    1 009 OP_STOP

This is not possible to obtain without knowing the list of files in advance, but was looking for options for this.

Either way, if that is no possible, not a problem.

Thank you.

matz commented 9 years ago

Ah, right. Sorry, I forgot about debugging section info. It's possible. Then why do you want to do this?

luislavena commented 9 years ago

@matz even without the debug information, I wanted to produce a single irep to be loaded by a single instruction. The idea was to store the bytecode on a resource element and be loaded quickly.

It was also the idea expose a mruby VM interface in order to write the packager that generates that single irep.

Anyway, that was a year ago and I give up on the experiment. The functionality to parse, produce and load irep wasn't easy to use for this purpose.

Thank you.