1
+ (module
2
+ (memory (export " mem" ) 1 )
3
+
4
+ (global $outputOffset i32 (i32.const 0 ))
5
+ (global $linebreak i32 (i32.const 10 ))
6
+ (global $space i32 (i32.const 32 ))
7
+ (global $A i32 (i32.const 65 ))
8
+
9
+ ;;
10
+ ;; Output a diamond made of letters with line breaks after each line.
11
+ ;;
12
+ ;; @param {i32} $letter - the character code of the letter in the middle of the diamond
13
+ ;;
14
+ ;; @returns {(i32,i32)} - the offset and length of the output string in linear memory
15
+ ;;
16
+ (func (export " rows" ) (param $letter i32 ) (result i32 i32 )
17
+ (local $size i32 )
18
+ (local $outputLength i32 )
19
+ (local $pos i32 )
20
+ (local $top i32 )
21
+ (local $bottom i32 )
22
+ (local $left i32 )
23
+ (local $right i32 )
24
+ ;; size of the diamond A = 1, B = 3, C = 5...
25
+ (local.set $size (i32.add (i32.const -1 ) (i32.shl
26
+ (i32.sub (local.get $letter ) (i32.const 64 )) (i32.const 1 ))))
27
+ ;; fill grid with spaces
28
+ (local.set $outputLength (i32.mul (local.get $size ) (i32.add (local.get $size ) (i32.const 1 ))))
29
+ (memory.fill (global.get $outputOffset ) (global.get $space ) (local.get $outputLength ))
30
+ ;; add line breaks
31
+ (local.set $pos (local.get $size ))
32
+ (loop $linebreaks
33
+ (i32.store8 (i32.add (global.get $outputOffset ) (local.get $pos )) (global.get $linebreak ))
34
+ (local.set $pos (i32.add (local.get $pos ) (i32.add (local.get $size ) (i32.const 1 ))))
35
+ (br_if $linebreaks (i32.lt_u (local.get $pos ) (local.get $outputLength ))))
36
+ ;; rows: letter - a, size - (letter - A)
37
+ ;; cols: (size >> 1) +/- (letter - A)
38
+ ;; start of a row (beginning with 0): row * (size + 1)
39
+ (loop $lines
40
+ (local.set $pos (i32.sub (local.get $letter ) (global.get $A )))
41
+ (local.set $top (i32.mul (local.get $pos ) (i32.add (local.get $size ) (i32.const 1 ))))
42
+ (local.set $bottom (i32.mul (i32.sub (i32.sub (local.get $size ) (local.get $pos )) (i32.const 1 ))
43
+ (i32.add (local.get $size ) (i32.const 1 ))))
44
+ (local.set $left (i32.sub (i32.shr_u (local.get $size ) (i32.const 1 )) (local.get $pos )))
45
+ (local.set $right (i32.add (i32.shr_u (local.get $size ) (i32.const 1 )) (local.get $pos )))
46
+ (i32.store8 (i32.add (i32.add (global.get $outputOffset )
47
+ (local.get $top )) (local.get $left )) (local.get $letter ))
48
+ (i32.store8 (i32.add (i32.add (global.get $outputOffset )
49
+ (local.get $top )) (local.get $right )) (local.get $letter ))
50
+ (i32.store8 (i32.add (i32.add (global.get $outputOffset )
51
+ (local.get $bottom )) (local.get $left )) (local.get $letter ))
52
+ (i32.store8 (i32.add (i32.add (global.get $outputOffset )
53
+ (local.get $bottom )) (local.get $right )) (local.get $letter ))
54
+ (local.set $letter (i32.sub (local.get $letter ) (i32.const 1 )))
55
+ (br_if $lines (i32.ge_u (local.get $letter ) (global.get $A ))))
56
+ (global.get $outputOffset ) (local.get $outputLength )
57
+ )
58
+ )
0 commit comments