Author: fperrad
Date: Thu Feb 8 01:11:34 2007
New Revision: 16922
Modified:
trunk/languages/lua/lib/luaaux.pir
trunk/languages/lua/lib/luastring.pir
trunk/languages/lua/t/string.t
trunk/languages/lua/t/table.t
Log:
[Lua]
- full string.format
- and add tests
Modified: trunk/languages/lua/lib/luaaux.pir
==============================================================================
--- trunk/languages/lua/lib/luaaux.pir (original)
+++ trunk/languages/lua/lib/luaaux.pir Thu Feb 8 01:11:34 2007
@@ -73,7 +73,9 @@
.param pmc arg
$S0 = "no value"
if_null arg, L0
- $S0 = typeof arg
+ $S1 = typeof arg
+ if $S1 == 'Undef' goto L0
+ $S0 = $S1
$I0 = isa arg, 'LuaNumber'
unless $I0 goto L1
.return (arg)
@@ -125,7 +127,9 @@
.local pmc val
$S0 = "no value"
if_null arg, L0
- $S0 = typeof arg
+ $S1 = typeof arg
+ if $S1 == 'Undef' goto L0
+ $S0 = $S1
$I0 = isa arg, 'LuaString'
unless $I0 goto L1
val = arg
Modified: trunk/languages/lua/lib/luastring.pir
==============================================================================
--- trunk/languages/lua/lib/luastring.pir (original)
+++ trunk/languages/lua/lib/luastring.pir Thu Feb 8 01:11:34 2007
@@ -344,31 +344,186 @@
will produce the string:
"a string with \"quotes\" and \
- new line"
+ new line"
The options C<c>, C<d>, C<E>, C<e>, C<f>, C<g>, C<G>, C<i>, C<o>, C<u>, C<X>,
and C<x> all expect a number as argument, whereas C<q> and C<s> expect a
string.
This function does not accept string values containing embedded zeros.
-STILL INCOMPLETE.
-
=cut
.sub '_string_format' :anon
.param pmc formatstring :optional
.param pmc argv :slurpy
+ .local string strfrmt
+ .local string b
+ .local int arg
+ .local int idx
+ strfrmt = checkstring(formatstring)
+ $I1 = length strfrmt
+ b = ''
+ arg = 0
+ new $P1, .Array
+ set $P1, 1
+ idx = 0
+L1:
+ unless idx < $I1 goto L2
+ $S0 = substr strfrmt, idx, 1
+ unless $S0 != '%' goto L3
+ b .= $S0
+ inc idx
+ goto L1
+L3:
+ inc idx
+ $S0 = substr strfrmt, idx, 1
+ unless $S0 == '%' goto L4
+ b .= $S0
+ inc idx
+L4:
+ .local string form
+ .local string buff
+ $P0 = argv[arg]
+ inc arg
+ (idx, form) = scanformat(strfrmt, idx)
+ $S0 = substr strfrmt, idx, 1
+ unless $S0 == 'c' goto L5
+ $I0 = checknumber($P0)
+ $P1[0] = $I0
+ buff = sprintf form, $P1
+ goto L6
+L5:
+ $I0 = index 'diouxX', $S0
+ unless $I0 >= 0 goto L7
+ $I0 = checknumber($P0)
+ $P1[0] = $I0
+ buff = sprintf form, $P1
+ goto L6
+L7:
+ $I0 = index 'eEfgG', $S0
+ unless $I0 >= 0 goto L8
+ $N0 = checknumber($P0)
+ $P1[0] = $N0
+ buff = sprintf form, $P1
+ goto L6
+L8:
+ unless $S0 == 'q' goto L9
+ $S0 = checkstring($P0)
+ buff = quoted($S0)
+ goto L6
+L9:
+ unless $S0 == 's' goto L10
+ buff = checkstring($P0)
+ $I0 = index form, '.'
+ if $I0 >= 0 goto L11
+ $I0 = length $S0
+ unless $I0 >= 100 goto L11
+ goto L6
+L11:
+ $P1[0] = $P0
+ buff = sprintf form, $P1
+ goto L6
+L10:
+ $S1 = "invalid option '%" . $S0
+ $S1 .= "' to 'format'"
+ error($S1)
+L6:
+ b .= buff
+ inc idx
+ goto L1
+L2:
.local pmc ret
- $S0 = checkstring(formatstring)
- push_eh _handler
- $S1 = sprintf $S0, argv
new ret, .LuaString
- set ret, $S1
+ set ret, b
.return (ret)
-_handler:
- error("bad argument #? to 'format'")
.end
+.sub 'scanformat' :anon
+ .param string strfrmt
+ .param int start
+ .const string flags = '-+ #0'
+ .const string digits = '0123456789'
+ .local int idx
+ $I1 = length strfrmt
+ idx = start
+L1:
+ unless idx < $I1 goto L2
+ $S0 = substr strfrmt, idx, 1
+ $I0 = index flags, $S0
+ unless $I0 >= 0 goto L2
+ inc idx
+ goto L1
+L2:
+ $I0 = idx - start
+ unless $I0 > 5 goto L3
+ error("invalid format (repeated flags)")
+L3:
+ $S0 = substr strfrmt, idx, 1
+ $I0 = index digits, $S0
+ unless $I0 >= 0 goto L4
+ inc idx
+L4:
+ $S0 = substr strfrmt, idx, 1
+ $I0 = index digits, $S0
+ unless $I0 >= 0 goto L5
+ inc idx
+L5:
+ unless $S0 == '.' goto L6
+ inc idx
+ $S0 = substr strfrmt, idx, 1
+ $I0 = index digits, $S0
+ unless $I0 >= 0 goto L7
+ inc idx
+L7:
+ $S0 = substr strfrmt, idx, 1
+ $I0 = index digits, $S0
+ unless $I0 >= 0 goto L6
+ inc idx
+L6:
+ $S0 = substr strfrmt, idx, 1
+ $I0 = index digits, $S0
+ unless $I0 >= 0 goto L8
+ error("invalid format (width or precision too long)")
+L8:
+ .local string form
+ $I0 = idx - start
+ inc $I0
+ $S0 = substr strfrmt, start, $I0
+ form = '%' . $S0
+ .return (idx, form)
+.end
+
+.sub 'quoted' :anon
+ .param string s
+ .local string b
+ .local int idx
+ $I1 = length s
+ b = '"'
+ idx = 0
+L1:
+ unless idx < $I1 goto L2
+ $S0 = substr s, idx, 1
+ inc idx
+ $I0 = index "\"\\\n", $S0
+ unless $I0 >= 0 goto L3
+ b .= "\\"
+ b .= $S0
+ goto L1
+L3:
+ unless $S0 == "\r" goto L4
+ b .= "\\r"
+ goto L1
+L4:
+ unless $S0 == "\0" goto L5
+ b .= "\\000"
+ goto L1
+L5:
+ b .= $S0
+ goto L1
+L2:
+ b .= '"'
+ .return (b)
+.end
=item C<string.gmatch (s, pattern)>
Modified: trunk/languages/lua/t/string.t
==============================================================================
--- trunk/languages/lua/t/string.t (original)
+++ trunk/languages/lua/t/string.t Thu Feb 8 01:11:34 2007
@@ -27,7 +27,7 @@
use FindBin;
use lib "$FindBin::Bin";
-use Parrot::Test tests => 14;
+use Parrot::Test tests => 20;
use Test::More;
language_output_is( 'lua', << 'CODE', << 'OUTPUT', 'function string.byte' );
@@ -106,16 +106,53 @@
<h1>a title</h1>
OUTPUT
+language_output_is( 'lua', << 'CODE', << 'OUTPUT', 'function string.format %q'
);
+print(string.format('%q', 'a string with "quotes" and \n new line'))
+CODE
+"a string with \"quotes\" and \
+ new line"
+OUTPUT
+
language_output_is( 'lua', << 'CODE', << 'OUTPUT', 'function string.format
(too many arg)' );
print(string.format("%s %s", 1, 2, 3))
CODE
1 2
OUTPUT
+language_output_like( 'lua', << 'CODE', << 'OUTPUT', 'function string.format
(too few arg)' );
+print(string.format("%s %s", 1))
+CODE
+/string expected, got no value/
+OUTPUT
+
language_output_like( 'lua', << 'CODE', << 'OUTPUT', 'function string.format
(bad arg)' );
print(string.format("%d", 'toto'))
CODE
-/bad argument #(\d+|\?) to 'format'/
+/number expected, got string/
+OUTPUT
+
+language_output_like( 'lua', << 'CODE', << 'OUTPUT', 'function string.format
(invalid option)' );
+print(string.format("%k", 'toto'))
+CODE
+/invalid option '%k' to 'format'/
+OUTPUT
+
+language_output_like( 'lua', << 'CODE', << 'OUTPUT', 'function string.format
(invalid format)' );
+print(string.format("%------s", 'toto'))
+CODE
+/invalid format \(repeated flags\)/
+OUTPUT
+
+language_output_like( 'lua', << 'CODE', << 'OUTPUT', 'function string.format
(invalid format)' );
+print(string.format("pi = %.123f", math.pi))
+CODE
+/invalid format \(width or precision too long\)/
+OUTPUT
+
+language_output_like( 'lua', << 'CODE', << 'OUTPUT', 'function string.format
(invalid format)' );
+print(string.format("% 123s", 'toto'))
+CODE
+/invalid format \(width or precision too long\)/
OUTPUT
language_output_is( 'lua', << 'CODE', << 'OUTPUT', 'function string.len' );
Modified: trunk/languages/lua/t/table.t
==============================================================================
--- trunk/languages/lua/t/table.t (original)
+++ trunk/languages/lua/t/table.t Thu Feb 8 01:11:34 2007
@@ -27,7 +27,7 @@
use FindBin;
use lib "$FindBin::Bin";
-use Parrot::Test tests => 16;
+use Parrot::Test tests => 17;
use Test::More;
language_output_is( 'lua', << 'CODE', << 'OUTPUT', 'function concat' );
@@ -229,6 +229,33 @@
luaH_set 10
OUTPUT
+language_output_is( 'lua', << 'CODE', << 'OUTPUT', 'function sort' );
+lines = {
+ luaH_set = 10,
+ luaH_get = 24,
+ luaH_present = 48,
+}
+
+function pairsByKeys (t, f)
+ local a = {}
+ for n in pairs(t) do a[#a + 1] = n end
+ table.sort(a, f)
+ local i = 0 -- iterator variable
+ return function () -- iterator function
+ i = i + 1
+ return a[i], t[a[i]]
+ end
+end
+
+for name, line in pairsByKeys(lines, function (a, b) return a < b end) do
+ print(name, line)
+end
+CODE
+luaH_get 24
+luaH_present 48
+luaH_set 10
+OUTPUT
+
language_output_is( 'lua', << 'CODE', << 'OUTPUT', 'function sort (all
permutations)' );
function permgen (a, n)
n = n or #a