Leopold Toetsch <[EMAIL PROTECTED]> wrote:

>  t/pmc/namespace.t

> Please have a look at the supported syntax constructs. Are these
> sufficient for HLL writers?

Some more thoughts WRT namespaces.

We can define a namespace, where a function or method is stored:

  .namespace ["Foo"]
  .sub bar
  ...

This does effectively (during bytecode loading)

  store_global "Foo", "bar", pmc_of_sub_bar

where the C<pmc_of_sub_bar> is living in the constant table.
The general way (and the only one, if the function is in another
bytecode segment), to call the function, is:

  $P0 = find_global "Foo", "bar"
  $P0()

Ok so far.

But what happens, if the PIR file contains just a plain

  bar()

The implementation looks into the current namespace and then in other
namespaces present in the compiled source file, which seems to be quite
wrong to me. Below is a test program [1] that shows how it's working
now.

The opcode to get at the sub "bar" is:

  set_p_pc $P0, "bar"

where the symbol "bar" (the PMC constant of the sub) is located in the
source file.

The C<bar()> shorthand call syntax could now look into the current
namespace only. But that seems to restricted to me - or it would make
the shortcut almost useless.

I think that the C<bar()> shortcut should emit a new opcode:

  $P0 = find_name "bar"

or maybe:

  $P0 = HLL."find_name"("bar")  # HLL := a Perl6, Python, ... PMC

The C<find_name> opcode could now look into the current lexicals, the
current namespace aka package, the globals, and finally into the
builtins in that order.

Further: to be able to search the current package namespace, the
interpreter has to know, in which namespace it's currently executing.
This is also needed for MMD function search. To achieve that, all
subroutines would need to remember their namespace and when calling the
sub, that namespace could be placed into the interpreter context.

Comments very welcome,
leo

[1]

$ cat s.imc
.namespace ["Main"]     # try it with and w/o this line

.sub main @MAIN
    print "calling foo\n"
    foo()
    print "calling Foo::foo\n"
    $P0 = find_global "Foo", "foo"
    $P0()
    print "calling baz\n"
    baz()
.end

.sub foo
    print "  foo\n"
    bar()
.end

.sub bar
    print "  bar\n"
.end

.sub fie
    print "  fie\n"
.end

.namespace ["Foo"]

.sub foo
    print "  Foo::foo\n"
    bar()
    fie()
.end

.sub bar
    print "  Foo::bar\n"
.end

.sub baz
    print "  Foo::baz\n"
.end

$ parrot s.imc
calling foo
  foo
  bar
calling Foo::foo
  Foo::foo
  bar                   # or Foo::bar
  fie
calling baz
  Foo::baz

Reply via email to