Add String#repeat method (#67)

This commit is contained in:
Max Graey
2018-04-07 19:59:26 +03:00
committed by Daniel Wirtz
parent f1b00c90be
commit b7ef21950b
8 changed files with 897 additions and 62 deletions

View File

@ -125,7 +125,7 @@
(call $abort
(i32.const 0)
(i32.const 8)
(i32.const 232)
(i32.const 234)
(i32.const 4)
)
(unreachable)

View File

@ -195,7 +195,7 @@
(call $abort
(i32.const 0)
(i32.const 8)
(i32.const 232)
(i32.const 234)
(i32.const 4)
)
(unreachable)

View File

@ -15,7 +15,7 @@
(global $std/string/nullStr (mut i32) (i32.const 0))
(global $argumentCount (mut i32) (i32.const 0))
(global $std/string/c (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 436))
(global $HEAP_BASE i32 (i32.const 520))
(memory $0 1)
(data (i32.const 4) "\10\00\00\00h\00i\00,\00 \00I\00\'\00m\00 \00a\00 \00s\00t\00r\00i\00n\00g")
(data (i32.const 40) "\0d\00\00\00s\00t\00d\00/\00s\00t\00r\00i\00n\00g\00.\00t\00s")
@ -45,6 +45,11 @@
(data (i32.const 404) "\02\00\00\00a\00a")
(data (i32.const 412) "\03\00\00\00a\00b\00c")
(data (i32.const 424) "\03\00\00\001\002\003")
(data (i32.const 436) "\03\00\00\00a\00a\00a")
(data (i32.const 448) "\08\00\00\00a\00b\00a\00b\00a\00b\00a\00b")
(data (i32.const 468) "\05\00\00\00a\00a\00a\00a\00a")
(data (i32.const 484) "\06\00\00\00a\00a\00a\00a\00a\00a")
(data (i32.const 500) "\07\00\00\00a\00a\00a\00a\00a\00a\00a")
(export "getString" (func $std/string/getString))
(export "memory" (memory $0))
(start $start)
@ -156,7 +161,7 @@
(call $abort
(i32.const 0)
(i32.const 72)
(i32.const 232)
(i32.const 234)
(i32.const 4)
)
(unreachable)
@ -376,7 +381,7 @@
(call $abort
(i32.const 0)
(i32.const 72)
(i32.const 211)
(i32.const 213)
(i32.const 4)
)
(unreachable)
@ -1087,7 +1092,7 @@
(call $abort
(i32.const 0)
(i32.const 72)
(i32.const 431)
(i32.const 469)
(i32.const 10)
)
(unreachable)
@ -3352,8 +3357,20 @@
(i32.and
(if (result i32)
(tee_local $2
(i32.eqz
(get_local $0)
(i32.and
(if (result i32)
(tee_local $2
(i32.eq
(get_local $0)
(get_local $1)
)
)
(get_local $2)
(i32.eqz
(get_local $0)
)
)
(i32.const 1)
)
)
(get_local $2)
@ -3421,14 +3438,17 @@
(local $2 i32)
(local $3 i32)
(if
(get_local $0)
(if
(i32.eqz
(get_local $1)
)
(return
(i32.const 0)
)
(i32.eq
(get_local $0)
(get_local $1)
)
(return
(i32.const 1)
)
)
(if
(i32.eqz
(get_local $0)
)
(return
(i32.eqz
@ -3436,6 +3456,14 @@
)
)
)
(if
(i32.eqz
(get_local $1)
)
(return
(i32.const 0)
)
)
(set_local $2
(i32.load
(get_local $1)
@ -3495,8 +3523,20 @@
(i32.and
(if (result i32)
(tee_local $2
(i32.eqz
(get_local $0)
(i32.and
(if (result i32)
(tee_local $2
(i32.eq
(get_local $0)
(get_local $1)
)
)
(get_local $2)
(i32.eqz
(get_local $0)
)
)
(i32.const 1)
)
)
(get_local $2)
@ -3564,14 +3604,17 @@
(local $2 i32)
(local $3 i32)
(if
(get_local $0)
(if
(i32.eqz
(get_local $1)
)
(return
(i32.const 0)
)
(i32.eq
(get_local $0)
(get_local $1)
)
(return
(i32.const 1)
)
)
(if
(i32.eqz
(get_local $0)
)
(return
(i32.eqz
@ -3579,6 +3622,14 @@
)
)
)
(if
(i32.eqz
(get_local $1)
)
(return
(i32.const 0)
)
)
(set_local $2
(i32.load
(get_local $0)
@ -3631,7 +3682,154 @@
(i32.const 0)
)
)
(func $start (; 28 ;) (type $v)
(func $~lib/string/String#repeat (; 28 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local $3 i32)
(local $4 i32)
(if
(i32.eqz
(get_local $0)
)
(block
(call $abort
(i32.const 0)
(i32.const 72)
(i32.const 386)
(i32.const 4)
)
(unreachable)
)
)
(set_local $3
(i32.load
(get_local $0)
)
)
(if
(i32.and
(if (result i32)
(tee_local $2
(i32.lt_s
(get_local $1)
(i32.const 0)
)
)
(get_local $2)
(i32.gt_s
(i32.mul
(get_local $3)
(get_local $1)
)
(i32.const 268435456)
)
)
(i32.const 1)
)
(unreachable)
)
(if
(i32.and
(if (result i32)
(tee_local $2
(i32.eqz
(get_local $1)
)
)
(get_local $2)
(i32.eqz
(get_local $3)
)
)
(i32.const 1)
)
(return
(i32.const 332)
)
)
(if
(i32.eq
(get_local $1)
(i32.const 1)
)
(return
(get_local $0)
)
)
(set_local $4
(call $~lib/internal/string/allocate
(i32.mul
(get_local $3)
(get_local $1)
)
)
)
(set_local $2
(i32.const 0)
)
(set_local $1
(i32.mul
(tee_local $3
(i32.shl
(get_local $3)
(i32.const 1)
)
)
(get_local $1)
)
)
(loop $continue|0
(if
(i32.lt_s
(get_local $2)
(get_local $1)
)
(block
(call $~lib/memory/move_memory
(i32.add
(i32.add
(get_local $4)
(i32.const 4)
)
(get_local $2)
)
(i32.add
(get_local $0)
(i32.const 4)
)
(get_local $3)
)
(set_local $2
(i32.add
(get_local $2)
(get_local $3)
)
)
(br $continue|0)
)
)
)
(get_local $4)
)
(func $~lib/string/String#repeat|trampoline (; 29 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(block $1of1
(block $0of1
(block $oob
(br_table $0of1 $1of1 $oob
(get_global $argumentCount)
)
)
(unreachable)
)
(set_local $1
(i32.const 0)
)
)
(call $~lib/string/String#repeat
(get_local $0)
(get_local $1)
)
)
(func $start (; 30 ;) (type $v)
(set_global $~lib/allocator/arena/startOffset
(i32.and
(i32.add
@ -4446,5 +4644,190 @@
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 332)
(i32.const 100)
)
(i32.const 332)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 66)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(block (result i32)
(set_global $argumentCount
(i32.const 0)
)
(call $~lib/string/String#repeat|trampoline
(i32.const 316)
(i32.const 0)
)
)
(i32.const 332)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 67)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 316)
(i32.const 1)
)
(i32.const 316)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 68)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 316)
(i32.const 2)
)
(i32.const 404)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 69)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 316)
(i32.const 3)
)
(i32.const 436)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 70)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 388)
(i32.const 4)
)
(i32.const 448)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 71)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 316)
(i32.const 5)
)
(i32.const 468)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 72)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 316)
(i32.const 6)
)
(i32.const 484)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 73)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 316)
(i32.const 7)
)
(i32.const 500)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 74)
(i32.const 0)
)
(unreachable)
)
)
)
)

View File

@ -3,7 +3,7 @@ import "allocator/arena";
// preliminary
var str: string = "hi, I'm a string";
var nullStr: String;
var nullStr: string;
// exactly once in static memory
assert(changetype<usize>(str) == changetype<usize>("hi, I'm a string"));
@ -62,3 +62,13 @@ assert("" >= "");
assert("" <= "");
assert("123".length == 3);
assert("".repeat(100) == "");
assert("a".repeat() == "");
assert("a".repeat(1) == "a");
assert("a".repeat(2) == "aa");
assert("a".repeat(3) == "aaa");
assert("ab".repeat(4) == "abababab");
assert("a".repeat(5) == "aaaaa");
assert("a".repeat(6) == "aaaaaa");
assert("a".repeat(7) == "aaaaaaa");

View File

@ -47,7 +47,7 @@
(global $~lib/internal/string/CharCode.z i32 (i32.const 122))
(global $~lib/internal/string/EMPTY i32 (i32.const 332))
(global $std/string/c (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 436))
(global $HEAP_BASE i32 (i32.const 520))
(memory $0 1)
(data (i32.const 4) "\10\00\00\00h\00i\00,\00 \00I\00\'\00m\00 \00a\00 \00s\00t\00r\00i\00n\00g\00")
(data (i32.const 40) "\0d\00\00\00s\00t\00d\00/\00s\00t\00r\00i\00n\00g\00.\00t\00s\00")
@ -78,6 +78,11 @@
(data (i32.const 404) "\02\00\00\00a\00a\00")
(data (i32.const 412) "\03\00\00\00a\00b\00c\00")
(data (i32.const 424) "\03\00\00\001\002\003\00")
(data (i32.const 436) "\03\00\00\00a\00a\00a\00")
(data (i32.const 448) "\08\00\00\00a\00b\00a\00b\00a\00b\00a\00b\00")
(data (i32.const 468) "\05\00\00\00a\00a\00a\00a\00a\00")
(data (i32.const 484) "\06\00\00\00a\00a\00a\00a\00a\00a\00")
(data (i32.const 500) "\07\00\00\00a\00a\00a\00a\00a\00a\00a\00")
(export "getString" (func $std/string/getString))
(export "memory" (memory $0))
(start $start)
@ -206,7 +211,7 @@
(call $abort
(i32.const 0)
(i32.const 72)
(i32.const 232)
(i32.const 234)
(i32.const 4)
)
(unreachable)
@ -464,7 +469,7 @@
(call $abort
(i32.const 0)
(i32.const 72)
(i32.const 211)
(i32.const 213)
(i32.const 4)
)
(unreachable)
@ -1266,7 +1271,7 @@
(call $abort
(i32.const 0)
(i32.const 72)
(i32.const 431)
(i32.const 469)
(i32.const 10)
)
(unreachable)
@ -3851,9 +3856,21 @@
(i32.and
(if (result i32)
(tee_local $2
(i32.eq
(get_local $0)
(i32.const 0)
(i32.and
(if (result i32)
(tee_local $2
(i32.eq
(get_local $0)
(get_local $1)
)
)
(get_local $2)
(i32.eq
(get_local $0)
(i32.const 0)
)
)
(i32.const 1)
)
)
(get_local $2)
@ -3934,6 +3951,15 @@
(local $4 i32)
(local $5 i32)
(local $6 i32)
(if
(i32.eq
(get_local $0)
(get_local $1)
)
(return
(i32.const 1)
)
)
(if
(i32.eq
(get_local $0)
@ -3945,14 +3971,14 @@
(i32.const 0)
)
)
(if
(i32.eq
(get_local $1)
(i32.const 0)
)
(return
(i32.const 0)
)
)
(if
(i32.eq
(get_local $1)
(i32.const 0)
)
(return
(i32.const 0)
)
)
(set_local $2
@ -4027,9 +4053,21 @@
(i32.and
(if (result i32)
(tee_local $2
(i32.eq
(get_local $0)
(i32.const 0)
(i32.and
(if (result i32)
(tee_local $2
(i32.eq
(get_local $0)
(get_local $1)
)
)
(get_local $2)
(i32.eq
(get_local $0)
(i32.const 0)
)
)
(i32.const 1)
)
)
(get_local $2)
@ -4110,6 +4148,15 @@
(local $4 i32)
(local $5 i32)
(local $6 i32)
(if
(i32.eq
(get_local $0)
(get_local $1)
)
(return
(i32.const 1)
)
)
(if
(i32.eq
(get_local $0)
@ -4121,14 +4168,14 @@
(i32.const 0)
)
)
(if
(i32.eq
(get_local $1)
(i32.const 0)
)
(return
(i32.const 0)
)
)
(if
(i32.eq
(get_local $1)
(i32.const 0)
)
(return
(i32.const 0)
)
)
(set_local $2
@ -4193,7 +4240,172 @@
)
)
)
(func $start (; 28 ;) (type $v)
(func $~lib/string/String#repeat (; 28 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32)
(local $3 i32)
(local $4 i32)
(local $5 i32)
(local $6 i32)
(if
(i32.eqz
(i32.ne
(get_local $0)
(i32.const 0)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 72)
(i32.const 386)
(i32.const 4)
)
(unreachable)
)
)
(set_local $2
(i32.load
(get_local $0)
)
)
(if
(i32.and
(if (result i32)
(tee_local $3
(i32.lt_s
(get_local $1)
(i32.const 0)
)
)
(get_local $3)
(i32.gt_s
(i32.mul
(get_local $2)
(get_local $1)
)
(i32.shl
(i32.const 1)
(i32.const 28)
)
)
)
(i32.const 1)
)
(unreachable)
)
(if
(i32.and
(if (result i32)
(tee_local $3
(i32.eq
(get_local $1)
(i32.const 0)
)
)
(get_local $3)
(i32.eqz
(get_local $2)
)
)
(i32.const 1)
)
(return
(i32.const 332)
)
)
(if
(i32.eq
(get_local $1)
(i32.const 1)
)
(return
(get_local $0)
)
)
(set_local $4
(call $~lib/internal/string/allocate
(i32.mul
(get_local $2)
(get_local $1)
)
)
)
(set_local $5
(i32.shl
(get_local $2)
(i32.const 1)
)
)
(block $break|0
(block
(set_local $3
(i32.const 0)
)
(set_local $6
(i32.mul
(get_local $5)
(get_local $1)
)
)
)
(loop $continue|0
(if
(i32.lt_s
(get_local $3)
(get_local $6)
)
(block
(block
(call $~lib/memory/move_memory
(i32.add
(i32.add
(get_local $4)
(i32.const 4)
)
(get_local $3)
)
(i32.add
(get_local $0)
(i32.const 4)
)
(get_local $5)
)
)
(set_local $3
(i32.add
(get_local $3)
(get_local $5)
)
)
(br $continue|0)
)
)
)
)
(return
(get_local $4)
)
)
(func $~lib/string/String#repeat|trampoline (; 29 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(block $1of1
(block $0of1
(block $oob
(br_table $0of1 $1of1 $oob
(get_global $argumentCount)
)
)
(unreachable)
)
(set_local $1
(i32.const 0)
)
)
(call $~lib/string/String#repeat
(get_local $0)
(get_local $1)
)
)
(func $start (; 30 ;) (type $v)
(set_global $~lib/allocator/arena/startOffset
(i32.and
(i32.add
@ -5077,5 +5289,190 @@
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 332)
(i32.const 100)
)
(i32.const 332)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 66)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(block (result i32)
(set_global $argumentCount
(i32.const 0)
)
(call $~lib/string/String#repeat|trampoline
(i32.const 316)
(i32.const 0)
)
)
(i32.const 332)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 67)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 316)
(i32.const 1)
)
(i32.const 316)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 68)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 316)
(i32.const 2)
)
(i32.const 404)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 69)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 316)
(i32.const 3)
)
(i32.const 436)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 70)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 388)
(i32.const 4)
)
(i32.const 448)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 71)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 316)
(i32.const 5)
)
(i32.const 468)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 72)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 316)
(i32.const 6)
)
(i32.const 484)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 73)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $~lib/string/String.__eq
(call $~lib/string/String#repeat
(i32.const 316)
(i32.const 7)
)
(i32.const 500)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 40)
(i32.const 74)
(i32.const 0)
)
(unreachable)
)
)
)
)