Author: coke
Date: Fri Mar  2 17:58:27 2007
New Revision: 17299

Added:
   trunk/languages/tcl/src/class/tclproc.pir
Removed:
   trunk/languages/tcl/src/pmc/tclproc.pmc
Modified:
   trunk/   (props changed)
   trunk/MANIFEST
   trunk/languages/tcl/config/makefiles/root.in
   trunk/languages/tcl/runtime/builtin/info.pir
   trunk/languages/tcl/runtime/builtin/proc.pir
   trunk/languages/tcl/runtime/builtin/rename.pir
   trunk/languages/tcl/runtime/tcllib.pir

Log:
[tcl]
* Convert the TclProc PMC into a ParrotObject, so attributes work with it.
* update [proc] to generate an anonymous TclProc, and then store it
  in the appropriate namespace. (rather than having this happen at
  in the PIR compiler).
* Set attributes on each user defined procedure in [proc] and retrieve them
  via [info], avoiding the need for several hidden globals that were
  carrying this information.



Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST      (original)
+++ trunk/MANIFEST      Fri Mar  2 17:58:27 2007
@@ -2049,6 +2049,7 @@
 languages/tcl/src/builtin/update.pir                        [tcl]
 languages/tcl/src/builtin/while.tmt                         [tcl]
 languages/tcl/src/class/tclconst.pir                        [tcl]
+languages/tcl/src/class/tclproc.pir                         [tcl]
 languages/tcl/src/grammar/expr/expression.pg                [tcl]
 languages/tcl/src/grammar/expr/functions.pir                [tcl]
 languages/tcl/src/grammar/expr/operators.pir                [tcl]
@@ -2064,7 +2065,6 @@
 languages/tcl/src/pmc/tclint.pmc                            [tcl]
 languages/tcl/src/pmc/tcllist.pmc                           [tcl]
 languages/tcl/src/pmc/tclobject.pmc                         [tcl]
-languages/tcl/src/pmc/tclproc.pmc                           [tcl]
 languages/tcl/src/pmc/tclstring.pmc                         [tcl]
 languages/tcl/src/returncodes.pir                           [tcl]
 languages/tcl/src/tclsh.pir                                 [tcl]

Modified: trunk/languages/tcl/config/makefiles/root.in
==============================================================================
--- trunk/languages/tcl/config/makefiles/root.in        (original)
+++ trunk/languages/tcl/config/makefiles/root.in        Fri Mar  2 17:58:27 2007
@@ -31,8 +31,7 @@
  tclfloat \
  tcllist \
  tclarray \
- tcldict \
- tclproc
+ tcldict
 
 GENERATED_INLINES = \
  $(C_BUILTIN)/break.pir \
@@ -106,7 +105,8 @@
        $(PARROT) tcl.pbc $< --pir > $@
 
 CLASSES = \
-  $(CLASSDIR)/tclconst.pir
+  $(CLASSDIR)/tclconst.pir \
+  $(CLASSDIR)/tclproc.pir
 
 pmcs:
        @cd $(PMCDIR) && $(PMCBUILD) generate $(PMCS)

Modified: trunk/languages/tcl/runtime/builtin/info.pir
==============================================================================
--- trunk/languages/tcl/runtime/builtin/info.pir        (original)
+++ trunk/languages/tcl/runtime/builtin/info.pir        Fri Mar  2 17:58:27 2007
@@ -76,9 +76,24 @@
 
   .local string procname
   procname = shift argv
-  $P1 = get_root_global ['_tcl'], 'proc_args'
-  $P2 = $P1[procname]
-  if_null $P2, no_args
+
+  .local pmc __namespace
+  __namespace = get_root_global ['_tcl'], '__namespace'
+
+  .local pmc    ns
+  .local string name
+  ns   = __namespace(procname)
+  name = pop ns
+  name = '&' . name
+
+  unshift ns, 'tcl'
+  $P1 = get_root_global ns, name
+  if null $P1 goto no_args
+
+  $P2 = getattribute $P1, 'args'
+  if null $P2 goto no_args
+  .return($P2)
+
   .return($P2)
 
 no_args:
@@ -108,11 +123,12 @@
   .local string name
   ns   = __namespace(procname)
   name = pop ns
+  name = '&' . name
 
   unshift ns, 'tcl'
-  $P1 = get_root_global ns, 'proc_body'
+  $P1 = get_root_global ns, name
   if null $P1 goto no_body
-  $P2 = $P1[name]
+  $P2 = getattribute $P1, 'HLL_source'
   if null $P2 goto no_body
   .return($P2)
 
@@ -169,9 +185,23 @@
 
   .local pmc __set
   __set = get_root_global ['_tcl'], '__set'
-  $P1 = get_root_global ['_tcl'], 'proc_defaults'
-  $P2 = $P1[procname]
-  if_null $P2, not_proc
+
+  .local pmc __namespace
+  __namespace = get_root_global ['_tcl'], '__namespace'
+
+  .local pmc    ns
+  .local string name
+  ns   = __namespace(procname)
+  name = pop ns
+  name = '&' . name
+
+  unshift ns, 'tcl'
+  $P1 = get_root_global ns, name
+  if null $P1 goto not_proc
+
+  $P2 = getattribute $P1, 'defaults'
+  $P9 = getattribute $P1, 'args'
+  if null $P2 goto check_arg
 
   $P3 = $P2[argname]
   if_null $P3, check_arg
@@ -184,9 +214,7 @@
 
 check_arg:
   # there's no default. is there even an arg?
-  $P1 = get_root_global ['_tcl'], 'proc_args'
-  $P2 = $P1[procname]
-  $P3 = __list($P2)
+  $P3 = __list($P9)
   $P4 = new .Iterator, $P3
 loop:
   unless $P4 goto not_argument 

Modified: trunk/languages/tcl/runtime/builtin/proc.pir
==============================================================================
--- trunk/languages/tcl/runtime/builtin/proc.pir        (original)
+++ trunk/languages/tcl/runtime/builtin/proc.pir        Fri Mar  2 17:58:27 2007
@@ -32,7 +32,7 @@
   code      = new 'PGE::CodeString'
   args_code = new 'PGE::CodeString'
   defaults  = new 'PGE::CodeString'
-  namespace = ""
+  namespace = ''
 
   .local pmc ns
   .local string name
@@ -73,9 +73,7 @@
 
 create:
   code.emit(<<'END_PIR', namespace, name)
-.HLL 'tcl', 'tcl_group'
-.namespace %0
-.sub '&%1'
+.sub 'xxx' :anon
   .param pmc args :slurpy
   .include 'languages/tcl/src/returncodes.pir'
   .local pmc epoch, colons, split, unk, interactive :unique_reg
@@ -97,11 +95,14 @@
   unshift info_level, $P0
 END_PIR
 
+   .local pmc defaults_info
+   defaults_info = new .TclDict 
+
   .local string args_usage, args_info
   .local int i, elems, min, max, is_slurpy
   .local pmc arg
-  args_usage = ""
-  args_info  = ""
+  args_usage = ''
+  args_info  = ''
   args  = __list(args)
   i     = 0
   elems = elements args
@@ -142,17 +143,11 @@
   lexpad['$%1'] = $P1
 END_PIR
 
-   $P1 = get_root_global ['_tcl'], 'proc_defaults'
-   $P2 = $P1[full_name]
-   if_null $P2, vivify_key
-   goto got_default_key
-vivify_key:
-   $P2 = new .TclDict
-   $P1[full_name] = $P2
-got_default_key:
    $S0 = arg[0]
    $S1 = arg[1]
-   $P2[$S0] = $S1
+   defaults_info[$S0] = $S1
+
+got_default_key:
 
     defaults.emit(<<'END_PIR', i, $S0, $S1)
 default_%0:
@@ -177,9 +172,6 @@
   args_info  .= " args"
 
 store_info:
-  # Save the args for the proc for [info args]
-  $P1 = get_root_global ['_tcl'], 'proc_args'
-  $P1[full_name] = args_info
 
     code .= <<'END_PIR'
   .local int argc
@@ -219,14 +211,6 @@
   .local string parsed_body, body_reg
   (parsed_body, body_reg) = __script(body, 'pir_only'=>1)
 
-  # Save the code for the proc for [info body]
-  $P1 = get_hll_global ns, 'proc_body'
-  unless null $P1 goto save_body
-  $P1 = new .Hash
-  set_hll_global ns, 'proc_body', $P1
-save_body:
-  $P1[name] = body
-
   code .= parsed_body
   
   code.emit(<<"END_PIR", body_reg)
@@ -263,28 +247,46 @@
   $I0 = find_charset 'ascii'
   $S0 = trans_charset $I0
   $P0 = pir_compiler($S0)
- 
+
   # the PIR compiler returns an Eval PMC, which contains each sub that
-  # was compiled in it. we want the first one, and we want to put it
-  # into a TclProc...
+  # was compiled in it. we want the first (and only) one, and we want to
+  # put it into a TclProc...
   $P0 = $P0[0]
  
-  $P1 = new .TclProc 
+  $P1 = new 'TclProc'
   assign $P1, $P0
 
-  # Attach some metadata to the sub...
-  # RT#41614
-  #$P8 = getclass "TclProc"
-  #addattribute $P8, 'source'
-  #$P9 = new .String
-  #$P9 = $S0
-  #setattribute $P1, 'source',     $P9
-  ##setattribute $P1, 'HLL_source', body
+  $P9 = new .String
+  $P9 = $S0
+  setattribute $P1, 'PIR_source', $P9
+
+  $P9 = new .String
+  $P9 = 'Tcl'
+  setattribute $P1, 'HLL',        $P9
+
+  setattribute $P1, 'HLL_source', body
+
+  $P9 = new .String
+  $P9 = args_info
+  setattribute $P1, 'args',       $P9
+
+  setattribute $P1, 'defaults',   defaults_info
  
   # And now store it into the appropriate slot in the namespace
+  .local pmc ns_target
+  ns_target = get_hll_namespace 
+
+  .local pmc iter, sub_ns
+  iter = new .Iterator, ns
+walk_ns:
+  unless iter goto done_walk
+  sub_ns = shift iter
+  ns_target = ns_target[sub_ns]
+  goto walk_ns
+done_walk:
 
-  #say name
-  #ns[name] = $P1
+  name = '&' . name
+  ns_target[name] = $P1
 
   .return ('')
 

Modified: trunk/languages/tcl/runtime/builtin/rename.pir
==============================================================================
--- trunk/languages/tcl/runtime/builtin/rename.pir      (original)
+++ trunk/languages/tcl/runtime/builtin/rename.pir      Fri Mar  2 17:58:27 2007
@@ -56,31 +56,16 @@
 
 delete_builtin:
   builtin = get_root_global ['_tcl'; 'builtins'], oldName
-  if null builtin goto delete_args
+  if null builtin goto return
   
   $P0 = get_root_namespace ['_tcl'; 'builtins']
   delete $P0[oldName]
 
-  if delete_only goto delete_args
+  if delete_only goto return
 
 add_builtin:
   set_root_global ['_tcl'; 'builtins'], newName, builtin
 
-
-delete_args:
-  $P0 = get_root_global ['_tcl'], 'proc_args'
-  $I0 = exists $P0[oldName]
-  unless $I0 goto return
-
-  args = $P0[oldName]
-  delete $P0[oldName]
-
-  if delete_only goto return
-
-add_args:
-  $P0[newName] = args
-
-
 return:
   .return('')
 

Modified: trunk/languages/tcl/runtime/tcllib.pir
==============================================================================
--- trunk/languages/tcl/runtime/tcllib.pir      (original)
+++ trunk/languages/tcl/runtime/tcllib.pir      Fri Mar  2 17:58:27 2007
@@ -34,6 +34,7 @@
 
 # class files (HLL: _Tcl)
 .include 'languages/tcl/src/class/tclconst.pir'
+.include 'languages/tcl/src/class/tclproc.pir'
 
 # create the 'tcl' namespace -- see RT #39852
 # http://rt.perl.org/rt3/Ticket/Display.html?id=39852
@@ -188,12 +189,6 @@
   $P1 = new .ResizablePMCArray
   store_global 'events', $P1
 
-  $P1 = new .TclArray
-  store_global 'proc_args', $P1
-
-  $P1 = new .TclDict
-  store_global 'proc_defaults', $P1
-
   # Global variable initialization
 
    #version info

Added: trunk/languages/tcl/src/class/tclproc.pir
==============================================================================
--- (empty file)
+++ trunk/languages/tcl/src/class/tclproc.pir   Fri Mar  2 17:58:27 2007
@@ -0,0 +1,32 @@
+=head1 TclProc
+
+A .Sub with attributes
+
+=cut
+
+.include "languages/tcl/src/returncodes.pir"
+.include "languages/tcl/src/macros.pir"
+
+.HLL 'parrot', ''
+.namespace [ 'TclProc' ]
+
+.cloneable()
+
+=head2 __class_init
+
+Define the attributes required for the class.
+
+=cut
+
+.sub __class_init :load
+
+  $P0 = getclass 'Sub'
+  $P1 = subclass $P0, 'TclProc'
+
+  addattribute $P1, 'PIR_source'
+  addattribute $P1, 'namespace'
+  addattribute $P1, 'HLL'         # In our case, Tcl...
+  addattribute $P1, 'HLL_source'
+  addattribute $P1, 'args'
+  addattribute $P1, 'defaults'    # Should combine this with 'args' for a more 
Perl-sixy way of specifying args.
+.end

Reply via email to