Author: coke
Date: Wed Aug  3 11:03:50 2005
New Revision: 8785

Modified:
   trunk/languages/tcl/lib/tclconst.pir
   trunk/languages/tcl/t/tcl_backslash.t
Log:
add support for hex escapes back in.



Modified: trunk/languages/tcl/lib/tclconst.pir
==============================================================================
--- trunk/languages/tcl/lib/tclconst.pir        (original)
+++ trunk/languages/tcl/lib/tclconst.pir        Wed Aug  3 11:03:50 2005
@@ -29,6 +29,33 @@ Define the attributes required for the c
   $P0[118] = "\v"
   
   store_global "_Tcl", "backslashes", $P0
+
+  $P0 = new Hash
+  $P0[ 48] =  0 # "0"
+  $P0[ 49] =  1
+  $P0[ 50] =  2
+  $P0[ 51] =  3
+  $P0[ 52] =  4
+  $P0[ 53] =  5
+  $P0[ 54] =  6
+  $P0[ 55] =  7
+  $P0[ 56] =  8
+  $P0[ 57] =  9
+  $P0[ 65] = 10 # "A"
+  $P0[ 66] = 11
+  $P0[ 67] = 12
+  $P0[ 68] = 13
+  $P0[ 69] = 14
+  $P0[ 70] = 15
+  $P0[ 97] = 10 # "a"
+  $P0[ 98] = 11
+  $P0[ 99] = 12
+  $P0[100] = 13
+  $P0[101] = 14
+  $P0[102] = 15
+  
+  store_global "_Tcl", "hexadecimal", $P0
+
 .end
 
 .sub __clone method
@@ -45,8 +72,9 @@ Define the attributes required for the c
   .local int value_length
   value_length = length value
 
-  .local pmc backslashes
+  .local pmc backslashes, hexadecimal
   find_global backslashes, "_Tcl", "backslashes"
+  find_global hexadecimal, "_Tcl", "hexadecimal"
   
   .local int pos
   pos = 0
@@ -56,11 +84,11 @@ loop:
  
   $I0 = pos + 1
   $I0 = ord value, $I0
-  if $I0 == 120 goto hexidecimal # x
-  if $I0 == 117 goto unicode     # u
-  if $I0 <   48 goto simple      # < 0
-  if $I0 <=  55 goto octal       # 0..7  
-                                 # > 7
+  if $I0 == 120 goto hex      # x
+  if $I0 == 117 goto unicode  # u
+  if $I0 <   48 goto simple   # < 0
+  if $I0 <=  55 goto octal    # 0..7  
+                              # > 7
 simple:
   $I1 = exists backslashes[$I0]
   if $I1 goto special
@@ -139,13 +167,44 @@ octal3:
 
 =for comment
 
-Hexidecimal escapes consist of an C<x>, followed by any number of hexidecimal
+Hexadecimal escapes consist of an C<x>, followed by any number of hexadecimal
 digits. However, only the last two are used.
 
 =cut
 
-hexidecimal:
-  inc pos
+ .local int hex_pos, hex_digit, hex_value
+hex:
+  # at this point, pos is set to the backslash
+  hex_value = 0
+  hex_pos = pos + 2 # skip the backslash and the x
+  
+hex_loop:
+  if hex_pos >= value_length goto hex_done
+  $I0 = ord value, hex_pos
+  $I1 = exists hexadecimal[$I0]
+  unless $I1 goto hex_done 
+  hex_digit = hexadecimal[$I0]
+  band hex_value, 15     # high byte discarded
+  hex_value *= 16        # low byte promoted
+  hex_value += hex_digit # new low byte added.
+
+  inc hex_pos
+
+  goto hex_loop
+
+hex_done:
+  $I0 = hex_pos - pos
+  if $I0 == 2 goto hex_not_really
+  $S0 = chr hex_value
+  substr value, pos, $I0, $S0 
+
+  pos = hex_pos
+  goto loop
+
+hex_not_really:
+  # This was a \x escape that had no hex value..
+  substr value, pos, 2, "x"
+  pos = hex_pos
   goto loop
 
 =for comment

Modified: trunk/languages/tcl/t/tcl_backslash.t
==============================================================================
--- trunk/languages/tcl/t/tcl_backslash.t       (original)
+++ trunk/languages/tcl/t/tcl_backslash.t       Wed Aug  3 11:03:50 2005
@@ -111,11 +111,6 @@ TCL
 S4
 OUT
 
-TODO: {
-local $TODO = "hex & unicode escapes recently un-implemented. Fix soon.";
-
-# XXX Should suppress warnings about wide characters in Test::*... how?
-
 language_output_is("tcl",<<'TCL',<<OUT,"hex single char, invalid");
   set a \xq
   puts $a
@@ -179,6 +174,11 @@ TCL
 jq
 OUT
 
+TODO: {
+local $TODO = "unicode escapes recently un-implemented. Fix soon.";
+
+# XXX Should suppress warnings about wide characters in Test::*... how?
+
 language_output_is("tcl",<<'TCL',<<OUT,"unicode single char, invalid");
   set a \uq
   puts $a

Reply via email to