# New Ticket Created by Jonathan Sillito # Please include the string: [perl #15846] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=15846 >
This patch supersedes my previous lexical scope patch <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=15800 > In this implementation, find_lex and store_lex only operate on the current pad, and open_lex/close_lex have been renamed to new_pad/pop_pad. The implementation is still quite simple (no pad descriptors, no accessing by index), but is at least a start on what is needed. The files affected by the patch are: - core.ops: added implementation the 4 ops. - dod.c: added interpreter->ctx.pad_stack to the initial first dod pass (I am not sure how to test if this is correct ...) - interpreter.c and interpreter.h: added pad_stack to Parrot_Context. In addition to the patch an updated test and example pasm file are attached: - lexicals.t: simple tests for the 4 ops that should to in t/op/ - lexicals.pasm: simple example that should go in examples/assembly/ Again, comments welcome. -- Jonathan Sillito -- attachment 1 ------------------------------------------------------ url: http://rt.perl.org/rt2/attach/32009/26690/0ce4d7/lex.patch -- attachment 2 ------------------------------------------------------ url: http://rt.perl.org/rt2/attach/32009/26691/38d4e4/lexicals.t -- attachment 3 ------------------------------------------------------ url: http://rt.perl.org/rt2/attach/32009/26692/dc2ab1/lexicals.pasm
Index: core.ops =================================================================== RCS file: /cvs/public/parrot/core.ops,v retrieving revision 1.187 diff -u -r1.187 core.ops --- core.ops 26 Jul 2002 19:15:56 -0000 1.187 +++ core.ops 30 Jul 2002 18:42:45 -0000 @@ -3604,6 +3604,23 @@ ######################################## +=item B<new_pad>() + +Create a new lexical scope pad and push it onto the +current lexical scope stack. + +=item B<pop_pad>() + +Pop the current lexical scope pad off the stack + +=item B<store_lex>(in PMC, in STR) + +Store object $1 as lexical symbol $2 + +=item B<find_lex>(in PMC, in STR) + +Find the lexical variable named $2 and store it in $1 + =item B<store_global>(in PMC, in STR) Store global $1 as global symbol $2 @@ -3613,6 +3630,41 @@ Find the global named $2 and store it in $1 =cut + +op new_pad() { + PMC* hash = pmc_new(interpreter, enum_class_PerlHash); + stack_push(interpreter, &interpreter->ctx.pad_stack, hash, STACK_ENTRY_DESTINATION, STACK_CLEANUP_NULL); + + goto NEXT(); +} + +op pop_pad() { + stack_pop(interpreter, &interpreter->ctx.pad_stack, NULL, STACK_ENTRY_DESTINATION); + goto NEXT(); +} + +op store_lex(in PMC, in STR) { + PMC * hash = NULL; + KEY key; + Stack_entry_type type = 0; + MAKE_KEY(key, $2, enum_key_string, struct_val); + hash = (PMC *)stack_peek(interpreter, interpreter->ctx.pad_stack, &type); + hash->vtable->set_pmc_keyed(interpreter, hash, NULL, $1, &key); + goto NEXT(); +} + +op find_lex(out PMC, in STR) { + PMC * hash = NULL; + KEY key; + Stack_entry_type type = 0; + MAKE_KEY(key, $2, enum_key_string, struct_val); + hash = (PMC *)stack_peek(interpreter, interpreter->ctx.pad_stack, &type); + $1 = hash->vtable->get_pmc_keyed(interpreter, hash, &key); + + /* FIXME: should the not found case be an internal_exception ? */ + + goto NEXT(); +} op store_global(in PMC, in STR) { KEY key; Index: dod.c =================================================================== RCS file: /cvs/public/parrot/dod.c,v retrieving revision 1.8 diff -u -r1.8 dod.c --- dod.c 23 Jul 2002 07:25:02 -0000 1.8 +++ dod.c 30 Jul 2002 18:42:45 -0000 @@ -92,6 +92,23 @@ } } + /* Walk lexical pad stack */ + cur_stack = interpreter->ctx.pad_stack; + while (cur_stack) { + if (cur_stack->buffer) { + buffer_lives(cur_stack->buffer); + entry = (Stack_Entry_t *)(cur_stack->buffer->bufstart); + for (i = 0; i < cur_stack->used; i++) { + if (STACK_ENTRY_PMC == entry[i].entry_type && + entry[i].entry.pmc_val) { + last = mark_used(entry[i].entry.pmc_val, last); + } + } + } + + cur_stack = cur_stack->prev; + } + /* Finally the general stack */ cur_stack = interpreter->ctx.user_stack; Index: interpreter.c =================================================================== RCS file: /cvs/public/parrot/interpreter.c,v retrieving revision 1.93 diff -u -r1.93 interpreter.c --- interpreter.c 18 Jul 2002 04:29:39 -0000 1.93 +++ interpreter.c 30 Jul 2002 18:42:45 -0000 @@ -570,6 +570,9 @@ interpreter->DOD_block_level--; interpreter->GC_block_level--; + /* Stack for lexical pads */ + interpreter->ctx.pad_stack = new_stack(interpreter); + /* Need a user stack */ interpreter->ctx.user_stack = new_stack(interpreter); Index: include/parrot/interpreter.h =================================================================== RCS file: /cvs/public/parrot/include/parrot/interpreter.h,v retrieving revision 1.50 diff -u -r1.50 interpreter.h --- include/parrot/interpreter.h 18 Jul 2002 04:30:42 -0000 1.50 +++ include/parrot/interpreter.h 30 Jul 2002 18:42:46 -0000 @@ -89,6 +89,7 @@ struct SRegChunk *string_reg_base; /* Base of the string stack */ struct PRegChunk *pmc_reg_base; /* Base of the PMC stack */ + struct Stack_Chunk *pad_stack; /* Base of the lex pad stack */ struct Stack_Chunk *user_stack; /* Base of the scratch stack */ struct Stack_Chunk *control_stack; /* Base of the flow control stack */ IntStack intstack; /* Base of the regex stack */ @@ -105,7 +106,6 @@ struct Stash *perl_stash; /* Pointer to the global variable * area */ - struct Scratchpad *cur_pad; /* The current scratchpad */ struct Arenas *arena_base; /* Pointer to this interpreter's * arena */ void *piodata; /* interpreter's IO system */
#! perl -w use Parrot::Test tests => 2; output_is(<<CODE, <<OUTPUT, "simple store and fetch"); new_pad new P0, .PerlInt new P1, .PerlInt set P0, 12 set P1, 7 store_lex P0, "Integer" find_lex P1, "Integer" print P1 print "\\n" end CODE 12 OUTPUT output_is(<<CODE, <<OUTPUT, "nested scopes"); new P0, .PerlInt new P1, .PerlInt new P2, .PerlInt new P3, .PerlInt set P0, 0 set P1, 1 set P2, 2 # outer most lexical scope new_pad store_lex P0, "a" find_lex P3, "a" print P3 print "\\n" new_pad store_lex P1, "a" new_pad store_lex P2, "c" find_lex P3, "c" print P3 print "\\n" pop_pad pop_pad find_lex P3, "a" print P3 print "\\n" end CODE 0 2 0 OUTPUT 1;
# # lexicals.pasm # # A program to demonstrate lexical scopes. # # $Id: $ # new P0, .PerlInt new P1, .PerlInt new P2, .PerlInt new P3, .PerlInt set P0, 0 set P1, 1 # outer most lexical scope new_pad store_lex P0, "a" find_lex P3, "a" print P3 # prints 0 print "\n" new_pad store_lex P1, "b" store_lex P1, "a" find_lex P3, "a" print P3 # prints 1 print "\n" find_lex P3, "b" print P3 # prints 1 print "\n" pop_pad find_lex P3, "a" print P3 # prints 0 print "\n" end