Author: coke
Date: Thu Oct  6 11:55:49 2005
New Revision: 9381

Modified:
   trunk/languages/tcl/TODO
   trunk/languages/tcl/lib/builtins/while.pir
   trunk/languages/tcl/lib/commands/while.pir
Log:
[while] is now inlined.



Modified: trunk/languages/tcl/TODO
==============================================================================
--- trunk/languages/tcl/TODO    (original)
+++ trunk/languages/tcl/TODO    Thu Oct  6 11:55:49 2005
@@ -26,7 +26,7 @@ Generate compiler-variants for several b
 commands like C<while>. 
 Modify the compiler for tclcommand to generate the inline version if
 it's available. (C<proc> and C<expr> should also be straightforward, as they
-already compile anyway.)  [Completed: incr, break, continue, for]
+already compile anyway.)  [Completed: incr, break, continue, for, while]
 
 Note: compiled builtins always take two args: the register_num to begin
 using for the inlined code, and a single container pmc that contains the

Modified: trunk/languages/tcl/lib/builtins/while.pir
==============================================================================
--- trunk/languages/tcl/lib/builtins/while.pir  (original)
+++ trunk/languages/tcl/lib/builtins/while.pir  Thu Oct  6 11:55:49 2005
@@ -0,0 +1,70 @@
+.namespace [ "_Tcl::builtins" ]
+
+.sub "while"
+  .param int register_num
+  .param pmc argv
+
+  .local int argc
+  argc = argv
+  if argc != 2 goto badargs
+
+  .local string pir_code,loop_label,done_label,temp_code
+  .local int cond_num
+  $S0 = register_num
+  loop_label = "loop" . $S0
+  done_label = "done" . $S0
+
+  .local pmc cond,body,compiler,expr_compiler
+
+  compiler= find_global "_Tcl", "compile"
+  expr_compiler= find_global "_Tcl", "__expression_compile"
+
+  cond  = argv[0]
+  body  = argv[1]
+
+  pir_code .= loop_label
+  pir_code .= ":\n"
+
+  (cond_num,    temp_code) = expr_compiler(register_num, cond)
+  register_num = cond_num + 1
+  pir_code .= temp_code
+
+  $P1 = new .Array
+  $P1 = 2
+  $P1[0] = cond_num
+  $P1[1] = done_label
+
+  sprintf temp_code, "unless $P%i goto %s\n", $P1
+
+  pir_code .= temp_code
+
+  (register_num,temp_code) = compiler(register_num, body)
+  pir_code .= temp_code
+  inc register_num
+  
+  $S0=<<"END_PIR"
+goto %s
+%s:
+$P%i=new .TclString
+$P%i=\"\"
+END_PIR
+
+   $P1 = new Array
+   $P1 = 4
+   $P1[0] = loop_label
+   $P1[1] = done_label
+   $P1[2] = register_num
+   $P1[3] = register_num
+
+   temp_code = sprintf $S0, $P1
+   pir_code .= temp_code
+
+  .return(register_num,pir_code)
+
+badargs:
+  pir_code =<<"END_PIR"
+.throw('wrong # args: should be \"while test command\"')
+END_PIR
+
+  .return(register_num,pir_code)
+.end

Modified: trunk/languages/tcl/lib/commands/while.pir
==============================================================================
--- trunk/languages/tcl/lib/commands/while.pir  (original)
+++ trunk/languages/tcl/lib/commands/while.pir  Thu Oct  6 11:55:49 2005
@@ -1,3 +1,5 @@
+# XXX convert to a call to the inline'd version
+
 ###
 # [while]
 

Reply via email to