-
Notifications
You must be signed in to change notification settings - Fork 0
/
rbtree.asm
813 lines (635 loc) · 7.32 KB
/
rbtree.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
; color (0=black, 1=red, -1=free)
; value
; p_left (-1 == nil)
; p_right (-1 == nil)
; p_parent
; memory map:
; 0: number_of_mallocated_entries
; 1: root
; 1000 + 5*n particular allocated thing
call 1 ; _init
call 1000 ; main
exit
label 190 ; (addr) safe_getval (addr) (val)
dup
label 191 ; (addr) unsafe_getval (val)
push 1
add
load
ret
label 192 ; (addr) getright (addr/-1)
push 1
add
label 193 ; (addr) getleft (addr/-1)
push 2
add
load
ret
label 200 ; (addr_number) (addr_root) append_number (-)
call 190 ; safe_getval
copy 2
call 191 ; unsafe_getval
sub
;stack: (addr_number) (addr_root) val_root-val_number
jn 202 ; number_bigger_than_root
; number_lower_than_root
dup
call 193 ; getleft
dup
jn 210 ; append_left
; recurse to the left
slide 1
jump 200
label 210 ; append_left
pop
; set_left
copy 1
copy 1
push 2
add
swap
store
swap
push 4
add
swap
store
ret
label 202
; number_bigger_than_root
dup
call 192 ; getright
dup
jn 212
slide 1
jump 200
label 212
pop
; set right
copy 1
copy 1
push 3
add
swap
store
swap
push 4
add
swap
store
ret
label 215 ; (addr_node) getuncle (addr_uncle)
push 4
add
load ; (parent)
dup
push 4
add
load
; (parent) (grandparent)
swap
copy 1
; (grandparent) (parent) (grandparent)
push 3
add
load
; (gp) (parent) (gp->right)
sub
; (gp) (parent ==? gp->right)
jz 216 ; uncle is left
; uncle is right
push 1
add
label 216 ; uncle is left
push 2
add
load
ret
label 217 ; (addr_node) getchildcase (0-3)
push 0
swap
dup
push 4
add
load
swap
copy 1
; 0 (parent) (node) (parent)
push 2
add
load
; 0 (parent) (node) (parent->left)
sub
jz 218
slide 1
push 1
swap
label 218
dup
push 4
add
load
; 0/1 parent gp
push 2
add
load
; 0/1 parent gp->left
sub
jz 219
push 2
add
label 219
ret
label 220 ; (addr_number) repaint (-)
; push 42
; ochr
; dup
; call 10 ; puti
; push 42
; ochr
dup
push 4
add
load
; (n) (p)
; if I am root, then black and done
jn 221 ; it IS root
jump 222
label 221
push 0
store
ret ; nothing more to do for root
label 222
; if my parent is root, then red and done
dup
push 4
add
load
push 4
add
load
; (n) (g)
jn 223 ; has_parent_root
jump 224
label 223
pop
ret
label 224 ; "could have uncle"
; (n)
;; if uncle is red...
dup ; backup the node address in case uncle is black
call 215 ; getuncle
dup
load
dup
; (n) (uncle) (color) (color)
jn 230
; (n) (uncle) (color)
dup
jz 230 ; uncle_is_black
; (n) (uncle) (color)
pop
; uncle_is_red ; stack: (node) (uncle)
push 0 ; change color of uncle to black
store
push 4 ; change color of parent to black
add
load
dup
push 0
store
push 4 ; grand parent to red
add
load
dup
push 1
store
; stack: (grandparent)
jump 220 ; repeat steps 2, 3 for grandparent
label 230
; (n) (uncle) (color)
pop
; TODO uncle_is_black ; stack: (node) (uncle)
pop
dup
call 217 ; getchildcase
push 38
ochr
dup
call 10 ; puti
push 38
ochr
dup
jz 240
push 1
sub
dup
jz 250
push 1
sub
jz 260
; rr
; stack: (node)
pop
ret
label 240 ; ll
; stack: (node) (result)
pop
push 4
add
load
dup
push 4
add
load
; stack: (p) (g)
; p->parent = g->parent
copy 1
push 4
add ; (p) (g) (p[parent])
copy 1
push 4
add
load ; (p) (g) (p[parent]) (g->parent)
store ; (p) (g)
dup
push 4
add
load ; (p) (g) (gg)
dup
jn 241
; (p) (g) (gg)
; g->parent->left_or_right = p
break
dup
push 2
add
load ; (p) (g) (gg) (gg->left)
copy 2
sub ; (p) (g) (gg) (result)
jz 243
push 1
add
label 243
push 2
add
; (p) (g) (gg[correct])
copy 2
store ; (p) (g)
jump 242
label 241
; (p) (g) -1
pop
; root = p
copy 1
push 1
swap
store
label 242
; g->parent = p
dup
push 4
add ; (p) (g) (g[parent])
copy 2
store
; g->left = p->right
; (p) (g)
dup
push 2
add
copy 2
push 3
add
load
store
; p->right = g
; (p) (g)
copy 1
push 3
add
copy 1
store
; coloring
push 1
store
push 0
store
ret
label 250 ; lr
; stack: (node) (result)
pop
dup
push 4
add
load
; (x) (p)
; x->parent = p->parent
copy 1
push 4
add
copy 1
push 4
add
load
store
; g->left = p
dup
push 4
add
load
push 2
add
copy 1
store
; p->right = x->left
dup
push 3
add
copy 2
push 2
add
load
store
; x->left = p
; (x) (p)
dup
copy 2
push 2
add
swap
store
; (x) (p)
swap
copy 1
; p->parent = x
push 4
add
swap
store
push 1
jump 240
label 260 ; rl
; stack: (node)
pop
ret
label 300 ; delete_number
ret
label 400 ; display_tree
ret
label 450 ; (-) dump_mem (-)
push -1
push 32 ;
push 58 ; :
push 107 ; k
push 111 ; o
push 108 ; l
push 65 ; A
call 2 ; puts
push 0
load
dup
call 10 ; puti
push -1
push 32 ;
push 58 ; :
push 116 ; t
push 111 ; o
push 111 ; o
push 82 ; R
push 32
call 2 ; puts
push 1
load
call 10 ; puti
push 10 ; \n
ochr
push 1000
label 451
; how_many_entries current_address
swap
dup
jz 452
push 1
sub
swap
; body
dup
push 40 ; (
ochr
push 64 ; @
ochr
dup
call 10 ; puti
push 32 ;
ochr
load ; color
dup
jn 453 ; color==hole
jz 454 ; color==black
; color==red
push -1
push 32 ;
push 109
push 48
push 91
push 27
push 100 ; d
push 101 ; e
push 114 ; r
push 109
push 49
push 51
push 91
push 27
call 2 ; puts
jump 455
label 453 ; color==hole
pop
push -1
push 101 ; e
push 108 ; l
push 111 ; o
push 104 ; h
call 2 ; puts
jump 456
label 454 ; color==black
push -1
push 32 ;
push 109
push 48
push 91
push 27
push 107 ; k
push 99 ; c
push 97 ; a
push 108 ; l
push 98 ; b
push 109
push 49
push 91
push 27
call 2 ; puts
label 455
push 1
add
dup
load
call 10 ; puti
push 32 ;
ochr
push 76 ; L
ochr
push 1
add
dup
load
call 10 ; puti
push 32 ;
ochr
push 82 ; R
ochr
push 1
add
dup
load
call 10 ; puti
push 32 ;
ochr
push 80 ; P
ochr
push 1
add
dup
load
call 10 ; puti
push 4
sub
label 456 ; end of body
push 41 ; )
ochr
push 5
add
jump 451
label 452
push 10
ochr
pop
pop
ret
label 500 ; (val) (color) malloc (addr)
; break
push 0
load
dup
push 1
add
push 0
swap
store
push 5
mul
push 1000
add
; val color addr
swap
copy 1
swap
store
; val addr
swap
copy 1
push 1
add
swap
store
; addr
dup
push 2
add
dup
push 1
add
dup
push 1
add
push -1
store
push -1
store
push -1
store
ret
label 600 ; (addr) free (-)
; push 5
; mul
; push 1000
; add
push -1
store
ret
label 1 ; _init
push 0
push 0
store
ret
label 2 ; (-1) (tnirp to gnirts) puts (-) ; prints inverted string
dup
jn 3
ochr
jump 2
label 3
pop
ret
label 10 ; (N) puti (-) ; prints number
push -1
swap
label 12
dup
push 10
mod
push 48
add
swap
dup
jz 11
push 10
div
jump 12
label 11
pop ; remove terminating zero
copy 1 ; -1 if this is a first zero
jn 2 ; puts
pop
jump 2 ; puts
label 1000 ; main
;;;;; ROOT
push 230
push 0
call 500 ; malloc
push 1
swap
store ; remember the root address
call 450 ; dump_mem
;;;;; NUMBERS
push -1
push 11
push 56
push 4
push 17
push 290
push 220
;;;;; ADDING LOOP
label 1010
dup
jn 1012
push 1 ; red
call 500 ; malloc
dup
push 1
load ; root
call 200 ; append_number
call 220 ; repaint
call 450 ; dump_mem
jump 1010
label 1012
ret