Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Question about scoping, .local and IMCC (shorter)

17 views
Skip to first unread message

Clinton Pierce

unread,
Jun 27, 2003, 3:06:43 PM6/27/03
to perl6-i...@perl.org

Sorry, the example was unnecessarily long.

> After a quick reading of this, I'd have expected the value of "f" at the indicated point to be 1, but instead it's 2.

.local int f
.sub _main
.local int x
.sub _foo1
f=1
x=2
call _foo2
end
.end
.sub _foo2
print "f is 1: "
print f
print "\n"
ret
.end
.end

Luke Palmer

unread,
Jun 27, 2003, 6:43:29 PM6/27/03
to cli...@geeksalad.org, perl6-i...@perl.org

Yeah, I don't think you can use .local across subs like that. I think
.local means "local to this sub" and *inner subs aren't closures*. In
fact, I don't think inner subs are useful for much of anything at all.

If you're a compiler, what you probably want to do is set up a some
scratchpads and put f and x in them. So the perl code:

my $f;
{
my $x;
foo1();

sub foo1 { ($f, $x) = (1, 2); foo2() }
sub foo2 { print "f is 1: $f\n"; print "x is 2: $x\n" }
}

Is roughly equivalent to:

# Main, unlabeled program
.sub _main
.local PerlInt f
f = new PerlInt
new_pad 0
store_lex -1, "f", f
call _anon1
end
.end

# Outermost { }
.sub _anon1
.local PerlInt x
x = new PerlInt
new_pad 1
store_lex -1, "x", x
call _foo1
ret
.end

.sub _foo1
.local PerlInt f
.local PerlInt x
f = new PerlInt
x = new PerlInt
f = 1
x = 2
store_lex "f", f
store_lex "x", x
call _foo2
ret
.end

.sub _foo2
.local PerlInt f
.local PerlInt x
find_lex f, "f"


print "f is 1: "
print f
print "\n"

find_lex x, "x"
print "x is 2: "
print x
print "\n"
ret
.end

, Unfortunately.

Clinton Pierce

unread,
Jun 27, 2003, 7:05:56 PM6/27/03
to Luke Palmer, perl6-i...@perl.org
> Yeah, I don't think you can use .local across subs like that. I think
> .local means "local to this sub" and *inner subs aren't closures*. In
> fact, I don't think inner subs are useful for much of anything at all.

The more I read, the more likely I think this is a bug. For example, the note following the example in P6E (emphasis mine):

.local string hello
hello="Polly want a cracker?\n"
print hello
.sub _main
hello="Hello, Polly\n"
print hello
end
.end
The first line of this example, the .local directive defines
a *file global variable* named hello. The main routine uses
the same variable, and would give a parse error if it hadn't
been defined. "Polly want a cracker" is never assigned to the
variable and printed.

This just screams bug.

Aside from that, I think .local should be my mechanism to create lexically scoped names at this level anyway (they serve a different purpose than scratchpads, globals, etc...).



> If you're a compiler, what you probably want to do is set up a some
> scratchpads and put f and x in them. So the perl code:

The scratchpads are a good idea, but clumsy for what I wanted to do here.

Leopold Toetsch

unread,
Jun 27, 2003, 6:08:58 PM6/27/03
to Clinton Pierce, perl6-i...@perl.org
Clinton Pierce wrote:

> Sorry, the example was unnecessarily long.
>
>
>>After a quick reading of this, I'd have expected the value of "f" at the indicated point to be 1, but instead it's 2.

The dark chapters of imcc documentations and functionality are getting
revealed again ;-)

The story is like this:
- the "pseudo gloabal" declaration of C<f> declares a variable usable in
both subs. This was invented[1] to cover vars outside of all subs in a
main execution stream, which is intersparsed with sub declarations, like
a perl programm could be.
- both subs "_foo1" and "_foo2" are compiled totally independent. This
implies: no usage of C<f> and C<x> in "_foo1" do interfere, so they get
the same register - bumm.

If you want true variables around compilations units, please use globals
or lexicals if they are in the same lexical pad.

[1] This "feature" is IMHO at the boarders of imcc as the namespace
instructions is. Should the HL handle these or imcc? But if its as
confusing as your test case, I would say I'll rather not support this
inside imcc.

leo

Leopold Toetsch

unread,
Jun 28, 2003, 3:10:12 AM6/28/03
to Clinton Pierce, perl6-i...@perl.org
Clinton Pierce <cli...@geeksalad.org> wrote:
>> Yeah, I don't think you can use .local across subs like that. I think
>> .local means "local to this sub" and *inner subs aren't closures*. In
>> fact, I don't think inner subs are useful for much of anything at all.

> Aside from that, I think .local should be my mechanism to create lexically scoped names at this level anyway (they serve a different purpose than scratchpads, globals, etc...).
>

From imcc/docs/calling_conventions.pod:

Namespaces and lexicals
- Should imcc keep track of pad opcodes?
- Should imcc even emit such opcodes from e.g. .local directives?

Currently symbolic variables behave exactly like temporary variables.
They only serve for better readability ("sum" vs. $P123).

leo

Clinton Pierce

unread,
Jun 28, 2003, 10:46:34 AM6/28/03
to Leopold Toetsch, perl6-i...@perl.org
> The story is like this:
> - the "pseudo gloabal" declaration of C<f> declares a variable usable in
> both subs. This was invented[1] to cover vars outside of all subs in a
> main execution stream, which is intersparsed with sub declarations, like
> a perl programm could be.
> - both subs "_foo1" and "_foo2" are compiled totally independent. This
> implies: no usage of C<f> and C<x> in "_foo1" do interfere, so they get
> the same register - bumm.

Yuck. I was afraid of this.

> If you want true variables around compilations units, please use globals
> or lexicals if they are in the same lexical pad.
>
> [1] This "feature" is IMHO at the boarders of imcc as the namespace
> instructions is. Should the HL handle these or imcc? But if its as
> confusing as your test case, I would say I'll rather not support this
> inside imcc.

My vote? Rip it out completely. It's *terribly* confusing. (And sends me back to the drawing board, at a cost of speed.)

To have a name be valid in two scopes because of a single declaration, yet have them not related in any significant way just boggles the mind. Sort of reminiscent of a joke "intern" declaration in C I saw once (IIRC):

/* This means that *every* function in here gets an
automagical "auto int foo". Not the same one -- their
own. That way they don't each have to declare it. */
intern int i;

void sub1 () {
i=56; // Variable used only once
return;
}
void sub2 () {
printf("%d", i); // Danger! Use of uninitialized value!
return;
}
void sub3 () {
for(i=0; i<10; i++);
}
int main(int argc, char **argv) {
sub1();
sub2();
sub3();
}


Melvin Smith

unread,
Jun 28, 2003, 1:32:04 PM6/28/03
to Clinton Pierce, Leopold Toetsch, perl6-i...@perl.org
At 10:46 AM 6/28/2003 -0400, Clinton Pierce wrote:
> > If you want true variables around compilations units, please use globals
> > or lexicals if they are in the same lexical pad.
> >
> > [1] This "feature" is IMHO at the boarders of imcc as the namespace
> > instructions is. Should the HL handle these or imcc? But if its as
> > confusing as your test case, I would say I'll rather not support this
> > inside imcc.
>
>My vote? Rip it out completely. It's *terribly* confusing. (And sends
>me back to the drawing board, at a cost of speed.)

Clint, I'm not sure which feature you mean is confusing here. I think you are
referring to supporting .local outside of subs, and I agree with that. However,
I think symbol tracking and scope checking is the high level language's
responsibility so the example you provided really should not be so big
of a deal, we should just put back the correct semantic checks for symbols.

Then if a language like Perl wants a funky scope type such as "local" (not
to be confused with IMCC .local) then it can implement them at a higher
level.

I've not been paying attention lately, but your example was the first I'd
seen using
.local outside a sub, and I don't recall writing the grammar to support
that, so I assume this was a feature Leo patched in lately.

Either option works for me:

1) We can define semantics for .local at the module (file) level, and at
the sub level, and correct the compiler so your example works

2) We generate a parse error and disallow it, but at least don't accept it
as valid code.

I trust Leo will make whichever choice for good reason, but my vote is
in for (2) because it keeps IMCC simpler.

-Melvin

PS: I also don't care for nested sub definitions at an intermediate language
level. They aren't real closures, so I don't see the point. Let the HL
compiler implement them.


Clinton Pierce

unread,
Jun 28, 2003, 2:01:43 PM6/28/03
to Melvin Smith, perl6-i...@perl.org
> Clint, I'm not sure which feature you mean is confusing here. I think you are
> referring to supporting .local outside of subs, and I agree with that. However,
> I think symbol tracking and scope checking is the high level language's
> responsibility so the example you provided really should not be so big
> of a deal, we should just put back the correct semantic checks for symbols.

Yes. We're agreed then. What I *thought* I had found was a way to delegate a portion of that task downward and outward but I was wrong.

> Then if a language like Perl wants a funky scope type such as "local" (not
> to be confused with IMCC .local) then it can implement them at a higher
> level.

And that's what I'm planning to do now. Fortunately I've only got two scopes at the language level to deal with:

* a strictly lexical scope. BASIC's subs and functions; anything
not in a sub is in an implied main()
* a global scope. Anything declared with COMMON.

I got nailed trying to implement the second by being clever: push declarations (.local) of things declared COMMON from the scope in which it's seen to an outer encasing scope. Thus in BASIC/Perl:

# BASIC
COMMON a
sub foo ()
a=1
c=3
end sub
a=15
usedonce=0
call foo()

# Perlish equivalent
{
my $a;
sub foo {
my $c;
$a=1;
}
sub main {
my $usedonce;

$a=15;
$usedonce=0;
foo();
}
}

So when I see occurances of "a", I'd look them up in the COMMON list and if they were there, I'd simply not do the PIR declaration in the inner scope, and let the outer declaration take care of it for me. They'd share a register and everthing would work.

Except that they don't share a register, and this doesn't work. I'll probably hack in pads this weekend instead.



> I've not been paying attention lately, but your example was the first I'd
> seen using
> .local outside a sub, and I don't recall writing the grammar to support
> that, so I assume this was a feature Leo patched in lately.

It was there long enough to make it into P6E. *shrug* I'd only began looking at it last month or so.

Afterthought: there aren't a lot of examples with nested .subs either. I've found two in t/syn and they're not terribly demonstrative of their usefulness. What's implemented there could be done without the outer .sub. *shrug*

> Either option works for me:
> 1) We can define semantics for .local at the module (file) level, and at
> the sub level, and correct the compiler so your example works
> 2) We generate a parse error and disallow it, but at least don't accept it
> as valid code.
>
> I trust Leo will make whichever choice for good reason, but my vote is
> in for (2) because it keeps IMCC simpler.

> PS: I also don't care for nested sub definitions at an intermediate language


> level. They aren't real closures, so I don't see the point. Let the HL
> compiler implement them.

I'm used to the concept in Macro Assemblers where I can designate registers, memory addresses, etc... by name and those names have a particular scope. Usually this is to a file, or to some kind of compilation unit. Thus I can mix and match (cut and paste) bits together and either have them use the globally defined names (for special hardware registers, etc...) or the locally defined ones.

In my mind, when I saw: 1. .local, 2. automagical register spillage in IMCC, and 3. nested compilation units I thought I'd found Assembler Manna.

Either way: once things are decided and cast into stone, the documentation needs to be unambiguous!

Leopold Toetsch

unread,
Jun 29, 2003, 6:33:35 AM6/29/03
to Clinton Pierce, perl6-i...@perl.org
Clinton Pierce <cli...@geeksalad.org> wrote:
> {
> my $a;
> sub foo {
> my $c;
> $a=1;
> }
> sub main {
> my $usedonce;

> $a=15;
> $usedonce=0;
> foo();
> }
> }

This really looks like imcc should emit global/pad opcodes for named
global/local variables.

leo

Leopold Toetsch

unread,
Jun 29, 2003, 10:55:45 AM6/29/03
to Melvin Smith, Clinton Pierce, perl6-i...@perl.org
Melvin Smith wrote:

> Then if a language like Perl wants a funky scope type such as "local" (not
> to be confused with IMCC .local) then it can implement them at a higher
> level.

I'm not too sure, but it seems, that all named variable handling of an
interpreted HL finally ends up in either find_global/store_global or
lexical pad opcodes. The latter may be optimized to just a parrot
register access, if no introspective features or eval are present.

> I've not been paying attention lately, but your example was the first
> I'd seen using
> .local outside a sub, and I don't recall writing the grammar to support
> that, so I assume this was a feature Leo patched in lately.

Yes, I did put it in on popular demand, and - yes - its already the
second time that this leads to confusion. The current behavior is
clearly a bug.


> 1) We can define semantics for .local at the module (file) level, and at
> the sub level, and correct the compiler so your example works
>
> 2) We generate a parse error and disallow it, but at least don't accept it
> as valid code.
>
> I trust Leo will make whichever choice for good reason, but my vote is
> in for (2) because it keeps IMCC simpler.

If language writers can agree on a more highlevel like variable handling
WRT globals/named locals, I'd emit just corresponding parrot opcodes
including scope frames (which we don't have yet). If $HL differ already
too much at this level, I'm for 2) too.


> -Melvin
>
> PS: I also don't care for nested sub definitions at an intermediate
> language
> level. They aren't real closures, so I don't see the point. Let the HL
> compiler implement them.

Yes, they are useful only, if the whole variable stuff is done too.


leo

0 new messages