Fix brainf*ck interpreter memory issue
[bob_language.git] / code.asm
blob46c22426aaadb75e5c6804d5c3f53df6902b0658
1 jump BoBInit
2 jump BBGetLength
3 jump BBSetLength
4 jump BBCopy
5 jump BBGetElement
6 jump BBSetElement
7 jump BBNot
8 jump BBAnd
9 jump BBOr
10 jump BBXor
11 jump BBShiftLeft
12 jump BBShiftRight
13 jump BBNegate
14 jump BBEquals
15 jump BBGreater
16 jump BBAdd
17 jump BBSubtract
18 jump BBMultiply
19 jump BBDivide
20 jump BBModulo
21 jump BBgetchr
22 jump BBgetint
23 jump BBoutstr
24 jump BFinalizeResult
25 jump BBIsZero
26 jump BBTrue
27 jump BBFalse
29 CMemCopy0Loop: @^0 = @^1 + 0
30 ^0 = ^0 + 1
31 ^1 = ^1 + 1
32 ^2 = ^2 - 1
33 CMemCopy: if ^2 CMemCopy0Loop
34 pop
35 pop
36 pop
37 return
39 CMemSet0Loop: @^0 = ^2 + 0
40 ^0 = ^0 + 1
41 ^1 = ^1 - 1
42 CMemSet: if ^1 CMemSet0Loop
43 pop
44 pop
45 pop
46 return
48 ECommonException: push 42
49 ECommonException0Loop: @^0 = 16 + 0
50 ^0 = ^0 + 1
51 jump ECommonException0Loop
52 pop
53 return
55 ERangeCheckError: writechar 10
56 writechar 82
57 writechar 97
58 writechar 110
59 writechar 103
60 writechar 101
61 writechar 32
62 writechar 67
63 writechar 104
64 writechar 101
65 writechar 99
66 writechar 107
67 writechar 32
68 writechar 69
69 writechar 114
70 writechar 114
71 writechar 111
72 writechar 114
73 writechar 10
74 writechar 10
75 call ECommonException
76 return
78 EoutstrError: writechar 10
79 writechar 111
80 writechar 117
81 writechar 116
82 writechar 95
83 writechar 115
84 writechar 116
85 writechar 114
86 writechar 32
87 writechar 69
88 writechar 114
89 writechar 114
90 writechar 111
91 writechar 114
92 writechar 10
93 writechar 10
94 call ECommonException
95 return
97 EDivisionByZeroError: writechar 10
98 writechar 68
99 writechar 105
100 writechar 118
101 writechar 105
102 writechar 115
103 writechar 105
104 writechar 111
105 writechar 110
106 writechar 32
107 writechar 66
108 writechar 121
109 writechar 32
110 writechar 90
111 writechar 101
112 writechar 114
113 writechar 111
114 writechar 32
115 writechar 69
116 writechar 114
117 writechar 114
118 writechar 111
119 writechar 114
120 writechar 10
121 writechar 10
122 call ECommonException
123 return
125 BCreateR: edx = eax + 2
126 new ecx edx
127 edx = ecx + 1
128 @edx = eax + 0
129 eax = ecx + 2
130 return
132 BBCreate: edx = ^0 + 2
133 new ecx edx
134 edx = ecx + 1
135 @edx = ^0 + 0
136 ^0 = ecx + 2
137 top eax
138 return
140 BCreateEmptyR: push eax
141 call BCreateR
142 edx = eax + 0
143 top ecx
145 BCreateEmpty0Loop: @edx = 0 + 0
146 edx = edx + 1
147 ecx = ecx - 1
148 if ecx BCreateEmpty0Loop
149 return
151 BDestroy: top eax
153 BDestroyR: eax = eax - 2
154 delete eax
155 return
157 BDestroyC: eax = ^0 - 2
158 delete eax
159 return
161 BLengthC: eax = ^0 - 1
162 eax = @eax + 0
163 return
165 BBGetLength: push ^0
166 call BLengthC
167 ^1 = eax + 0
168 call BDestroy
169 call BBToBlob
170 return
172 BBSetLength: push ^1
173 call BToIndex
174 ifeq eax ERangeCheckError
175 push eax
176 push ^1
177 call BResize
178 ecx = eax + 0
179 eax = ^1 + 0
180 ^1 = ecx + 0
181 call BDestroyR
182 call BDestroy
183 return
185 BResize: call BLengthC
186 top ecx
188 top edx
189 edx = edx - eax
190 if edx BResize0Bigger
191 top eax
192 BResize0Bigger: top edx
194 push eax
195 push ecx
196 eax = edx + 0
197 call BCreateEmptyR
198 push eax
199 call CMemCopy
200 return
202 BEnlarge: call BLengthC
203 top ecx
205 top edx
207 push eax
208 push ecx
209 ecx = eax - edx
210 if ecx BEnlarge0Bigger
211 eax = edx + 0
212 BEnlarge0Bigger: call BCreateEmptyR
213 push eax
214 call CMemCopy
215 return
217 BCopy: call BLengthC
218 top edx
220 push eax
221 push edx
222 call BCreateR
223 push eax
224 call CMemCopy
225 return
227 BBCopy: call BCopy
228 push eax
229 return
231 BToIndex: call BOptimize
232 push ebx
233 push eax
234 eax = eax - 1
235 eax = @eax + 0
236 ecx = eax - 4
237 if ecx ERangeCheckError
238 edx = ^0 + eax
239 edx = edx - 1
240 ecx = @edx & 128
241 if ecx ERangeCheckError
242 ebx = 0 + 0
243 BToIndex0Loop: ebx = ebx << 8
244 ebx = ebx + @edx
245 edx = edx - 1
246 eax = eax - 1
247 if eax BToIndex0Loop
248 call BDestroy
249 eax = ebx + 0
250 top ebx
252 return
254 BBToBlob: eax = 4 + 0
255 call BCreateR
256 edx = eax + 1
257 @eax = ^0 & 255
258 ^0 = ^0 >> 8
259 @edx = ^0 & 255
260 ^0 = ^0 >> 8
261 edx = edx + 1
262 @edx = ^0 & 255
263 ^0 = ^0 >> 8
264 edx = edx + 1
265 @edx = ^0 & 255
266 push eax
267 push eax
268 call BOptimize
269 ^1 = eax + 0
270 call BDestroy
271 return
273 BToPtr: top edx
275 top eax
277 push ebx
278 ebx = edx + 0
279 push eax
280 call BToIndex
281 push eax
282 eax = ebx - 1
283 eax = @eax + 0
284 top ecx
285 eax = ecx - eax
286 ifgeq eax ERangeCheckError
287 eax = ebx + ecx
289 top ebx
291 return
293 BGetElement: call BToPtr
294 push @eax
295 eax = 1 + 0
296 call BCreateR
297 top @eax
299 return
301 BBGetElement: push 0
302 push ^2
303 push ^2
304 call BGetElement
305 ^0 = eax + 0
306 eax = ^1 + 0
307 call BDestroyR
308 eax = ^2 + 0
309 call BDestroyR
310 ^2 = ^0 + 0
313 return
315 BBSetElement: push ^1
316 call BToIndex
317 ecx = eax + 0
318 eax = ^1 + 0
319 ^1 = ecx + 0
320 call BDestroyR
321 eax = ^2 - 1
322 eax = @eax + 0
323 push eax
324 push ^3
325 eax = eax + ^3
326 push eax
327 push ^3
328 call BEnlarge
329 edx = eax + ^3
330 push edx
331 call CMemCopy
332 ^1 = ^2 + 0
333 ^2 = eax + 0
334 call BDestroy
335 call BDestroy
336 return
338 BOptimize: call BLengthC
339 top ecx
341 eax = eax - 1
342 edx = ecx + eax
343 ifeq @edx BOptimize0RemoveZerosLoop
344 edx = @edx - 255
345 ifeq edx BOptimize0RemoveOnesLoop
346 push ecx
347 call BCopy
348 return
349 BOptimize0RemoveZerosLoop: ifeq eax BOptimize0End
350 edx = edx - 1
351 edx = @edx & 128
352 if edx BOptimize0End
353 eax = eax - 1
354 edx = ecx + eax
355 ifeq @edx BOptimize0RemoveZerosLoop
356 jump BOptimize0End
357 BOptimize0RemoveOnesLoop: ifeq eax BOptimize0End
358 edx = ecx + eax
359 edx = edx - 1
360 edx = @edx & 128
361 ifeq edx BOptimize0End
362 eax = eax - 1
363 edx = ecx + eax
364 edx = @edx - 255
365 ifeq edx BOptimize0RemoveOnesLoop
366 BOptimize0End: eax = eax + 1
367 push eax
368 push ecx
369 call BResize
370 return
372 BNot: push ebx
373 eax = ^1 - 1
374 eax = @eax + 0
375 ebx = eax + 0
376 call BCreateR
377 edx = ^1 + 0
378 ecx = eax + 0
379 BNot0Loop: @ecx = @edx ^ 255
380 ecx = ecx + 1
381 edx = edx + 1
382 ebx = ebx - 1
383 if ebx BNot0Loop
384 top ebx
387 return
389 BBNot: push ^0
390 call BNot
391 ecx = eax + 0
392 eax = ^0 + 0
393 ^0 = ecx + 0
394 call BDestroyR
395 return
397 BAnd: push ebx
398 push esi
399 eax = ^2 - 1
400 eax = @eax + 0
401 ebx = eax + 0
402 eax = ^3 - 1
403 eax = @eax + 0
404 edx = eax - ebx
405 if edx BAnd0Max
406 edx = 0 - edx
407 ecx = eax + 0
408 eax = ebx + 0
409 ebx = ecx + 0
410 ecx = ^3 + 0
411 ^3 = ^2 + 0
412 ^2 = ecx + 0
413 BAnd0Max: push 0
414 push edx
415 call BCreateR
416 ecx = eax + 0
417 esi = ^4 + 0
418 edx = ^5 + 0
419 BAnd0Loop: @ecx = @esi & @edx
420 ecx = ecx + 1
421 esi = esi + 1
422 edx = edx + 1
423 ebx = ebx - 1
424 if ebx BAnd0Loop
425 push ecx
426 call CMemSet
427 top esi
429 top edi
433 return
435 BBAnd: push 0
436 push ^2
437 push ^2
438 call BAnd
439 ^0 = eax + 0
440 eax = ^1 + 0
441 call BDestroyR
442 eax = ^2 + 0
443 call BDestroyR
444 ^2 = ^0 + 0
447 return
449 BOr: push ebx
450 push esi
451 eax = ^2 - 1
452 eax = @eax + 0
453 ebx = eax + 0
454 eax = ^3 - 1
455 eax = @eax + 0
456 edx = eax - ebx
457 if edx BOr0Max
458 edx = 0 - edx
459 ecx = eax + 0
460 eax = ebx + 0
461 ebx = ecx + 0
462 ecx = ^3 + 0
463 ^3 = ^2 + 0
464 ^2 = ecx + 0
465 BOr0Max: push edx
466 call BCreateR
467 ecx = eax + 0
468 esi = ^3 + 0
469 edx = ^4 + 0
470 BOr0Loop: @ecx = @esi | @edx
471 ecx = ecx + 1
472 esi = esi + 1
473 edx = edx + 1
474 ebx = ebx - 1
475 if ebx BOr0Loop
476 push edx
477 push ecx
478 call CMemCopy
479 top esi
481 top edi
485 return
487 BBOr: push 0
488 push ^2
489 push ^2
490 call BOr
491 ^0 = eax + 0
492 eax = ^1 + 0
493 call BDestroyR
494 eax = ^2 + 0
495 call BDestroyR
496 ^2 = ^0 + 0
499 return
501 BXor: push ebx
502 push esi
503 eax = ^2 - 1
504 eax = @eax + 0
505 ebx = eax + 0
506 eax = ^3 - 1
507 eax = @eax + 0
508 edx = eax - ebx
509 if edx BXor0Max
510 edx = 0 - edx
511 ecx = eax + 0
512 eax = ebx + 0
513 ebx = ecx + 0
514 ecx = ^3 + 0
515 ^3 = ^2 + 0
516 ^2 = ecx + 0
517 BXor0Max: push edx
518 call BCreateR
519 ecx = eax + 0
520 esi = ^3 + 0
521 edx = ^4 + 0
522 BXor0Loop: @ecx = @esi ^ @edx
523 ecx = ecx + 1
524 esi = esi + 1
525 edx = edx + 1
526 ebx = ebx - 1
527 if ebx BXor0Loop
528 push edx
529 push ecx
530 call CMemCopy
531 top esi
533 top edi
537 return
539 BBXor: push 0
540 push ^2
541 push ^2
542 call BXor
543 ^0 = eax + 0
544 eax = ^1 + 0
545 call BDestroyR
546 eax = ^2 + 0
547 call BDestroyR
548 ^2 = ^0 + 0
551 return
553 BToShiftLow: call BLengthC
554 top ecx
556 edx = 0 + 0
557 ifleq eax BToShiftLow0End
558 edx = @ecx & 7
559 BToShiftLow0End: eax = edx + 0
560 return
562 BToShiftHigh: call BLengthC
563 edx = eax - 5
564 ifl edx BToShiftHigh0Small
565 eax = 5 + 0
566 ecx = ^0 + 4
567 ecx = @ecx >> 2
568 if ecx BToShiftHigh0Overflow
569 ecx = ^0 + 5
570 jump BToShiftHigh0Check
571 BToShiftHigh0Loop: if @ecx BToShiftHigh0Overflow
572 ecx = ecx + 1
573 edx = edx - 1
574 BToShiftHigh0Check: if edx BToShiftHigh0Loop
575 BToShiftHigh0Small: top ecx
576 ^0 = @ecx >> 3
577 push 5
578 jump BToShiftHigh1Check
579 BToShiftHigh1Loop: ecx = ecx + 1
580 edx = @ecx << ^0
581 ^1 = ^1 | edx
582 ^0 = ^0 + 8
583 BToShiftHigh1Check: eax = eax - 1
584 if eax BToShiftHigh1Loop
586 top eax
588 return
589 BToShiftHigh0Overflow: eax = 2147483647 + 0
591 return
593 BShiftLeft: push ebx
594 push esi
595 push edi
596 push ^4
597 call BSign
598 ifeq eax BShiftLeft0Positive
599 push ^4
600 call BNegate
601 ebx = eax + 0
602 push eax
603 push ^4
604 call BShiftRight
605 esi = eax + 0
606 eax = ebx + 0
607 call BDestroyR
608 eax = esi + 0
609 jump BShiftLeft0End
610 BShiftLeft0Positive: eax = ^3 - 1
611 eax = @eax + 0
612 push eax
613 push ^5
614 call BToShiftLow
615 ebx = eax + 0
616 push ^5
617 call BToShiftHigh
618 esi = ^0 + eax
619 edi = ^4 + ^0
620 edi = edi - 1
621 edi = @edi << ebx
622 edi = edi >> 8
623 ifeq edi BShiftLeft0NoExtraNeeded
624 eax = esi + 1
625 call BCreateEmptyR
626 esi = esi + eax
627 @esi = edi + 0
628 jump BShiftLeft0ExtraDone
629 BShiftLeft0NoExtraNeeded: eax = esi + 0
630 call BCreateEmptyR
631 esi = esi + eax
632 BShiftLeft0ExtraDone: esi = esi - ^0
633 edx = 0 + 0
634 edi = ^4 + 0
635 BShiftLeft0Loop: ecx = @edi << ebx
636 edx = edx | ecx
637 @esi = edx & 255
638 edx = edx >> 8
639 edi = edi + 1
640 esi = esi + 1
641 ^0 = ^0 - 1
642 if ^0 BShiftLeft0Loop
643 BShiftLeft0End: pop
644 top edi
646 top esi
648 top ebx
652 return
654 BBShiftLeft: push 0
655 push ^2
656 push ^2
657 call BShiftLeft
658 ^0 = eax + 0
659 eax = ^1 + 0
660 call BDestroyR
661 eax = ^2 + 0
662 call BDestroyR
663 ^2 = ^0 + 0
666 return
668 BShiftRight: push ^1
669 call BSign
670 ifeq eax BShiftRight0Positive
671 push ^1
672 call BNegate
673 ^1 = eax + 0
674 push eax
675 push ^1
676 call BShiftLeft
677 ^0 = eax + 0
678 eax = ^1 + 0
679 call BDestroyR
680 top eax
683 return
684 BShiftRight0Positive: call BLengthC
685 push eax
686 push ^2
687 call BToShiftHigh
688 eax = ^0 - eax
689 push eax
690 push ^3
691 call BToShiftLow
692 ^3 = eax + 0
693 push ebx
694 ebx = ^2 + ^3
695 ebx = ebx - 1
696 eax = @ebx >> ^4
697 ^3 = 0 + 0
698 if eax BShiftRight0NoExtraNeeded
699 ^1 = ^1 - 1
700 ^3 = @ebx + 0
701 ebx = ebx - 1
702 BShiftRight0NoExtraNeeded: if ^1 BShiftRight0NonZero
703 eax = 1 + 0
704 call BCreateEmptyR
705 jump BShiftRight0End
706 BShiftRight0NonZero: eax = ^1 + 0
707 call BCreateR
708 edx = eax + ^1
709 BShiftRight0Loop: edx = edx - 1
710 ^3 = ^3 << 8
711 ^3 = ^3 | @ebx
712 ebx = ebx - 1
713 ecx = ^3 >> ^4
714 @edx = ecx & 255
715 ^1 = ^1 - 1
716 if ^1 BShiftRight0Loop
717 BShiftRight0End: top ebx
723 return
725 BBShiftRight: push 0
726 push ^2
727 push ^2
728 call BShiftRight
729 ^0 = eax + 0
730 eax = ^1 + 0
731 call BDestroyR
732 eax = ^2 + 0
733 call BDestroyR
734 ^2 = ^0 + 0
737 return
739 BNegate: top eax
741 push ebx
742 push esi
743 push edi
744 ebx = eax + 0
745 eax = eax - 1
746 eax = @eax + 0
747 esi = eax + 0
748 call BCreateR
749 edi = eax + 0
750 ecx = 0 + 1
751 jump BNegate0MiddleOfLoop
752 BNegate0Loop: eax = eax + 1
753 ebx = ebx + 1
754 BNegate0MiddleOfLoop: edx = @ebx ^ 255
755 edx = edx + ecx
756 @eax = edx & 255
757 ecx = edx >> 8
758 esi = esi - 1
759 if esi BNegate0Loop
760 if ecx BNegate0OptimizeEnd
761 edx = @eax ^ @ebx
762 edx = edx >> 7
763 if edx BNegate0OptimizeEnd
764 eax = edi - 1
765 eax = @eax + 0
766 eax = eax + 1
767 push eax
768 push edi
769 call BEnlarge
770 jump BNegate0OptimizeCommon
771 BNegate0OptimizeEnd: push edi
772 call BOptimize
773 BNegate0OptimizeCommon: esi = eax + 0
774 eax = edi + 0
775 call BDestroyR
776 eax = esi + 0
777 top edi
779 top esi
781 top ebx
783 return
785 BBNegate: push ^0
786 call BNegate
787 ecx = eax + 0
788 eax = ^0 + 0
789 ^0 = ecx + 0
790 call BDestroyR
791 return
793 BSign: call BLengthC
794 eax = eax + ^0
795 eax = eax - 1
796 eax = @eax >> 7
798 return
800 BSignExtend: call BLengthC
801 push eax
802 push eax
803 push ^2
804 eax = ^4 + 0
805 call BCreateR
806 push eax
807 ^4 = ^5 - ^3
808 push ^1
809 call BSign
810 ^5 = eax * 255
811 ^3 = ^3 + ^0
812 top eax
813 call CMemCopy
814 call CMemSet
815 return
817 BEquals: call BLengthC
818 push eax
819 eax = ^2 - 1
820 eax = @eax + 0
821 eax = eax ^ ^0
822 if eax BEquals0Return
823 eax = ^1 + 0
824 ecx = ^2 + 0
825 BEquals0Loop: edx = @eax ^ @ecx
826 if edx BEquals0Return
827 eax = eax + 1
828 ecx = ecx + 1
829 ^0 = ^0 - 1
830 if ^0 BEquals0Loop
831 BEquals0Return: eax = 1 + 0
832 call BCreateR
833 ifeq ^0 BEquals0ReturnTrue
834 @eax = 0 + 0
835 jump BEquals0End
836 BEquals0ReturnTrue: @eax = 255 + 0
837 BEquals0End: pop
840 return
842 BBEquals: push 0
843 push ^2
844 push ^2
845 call BEquals
846 ^0 = eax + 0
847 eax = ^1 + 0
848 call BDestroyR
849 eax = ^2 + 0
850 call BDestroyR
851 ^2 = ^0 + 0
854 return
856 BBGreater: call BBSubtract
857 push ^0
858 call BSign
859 if eax BBGreater0ReturnFalse
860 call BLengthC
861 eax = eax ^ 1
862 ifneq eax BBGreater0ReturnTrue
863 top eax
864 ifeq @eax BBGreater0ReturnFalse
865 BBGreater0ReturnTrue: call BDestroyC
866 ^0 = 255 + 0
867 jump BBGreater0End
868 BBGreater0ReturnFalse: call BDestroyC
869 ^0 = 0 + 0
870 BBGreater0End: eax = 1 + 0
871 call BCreateR
872 top @eax
873 ^0 = eax + 0
874 return
876 BBAdd: call BLengthC
877 push eax
878 eax = ^2 - 1
879 eax = @eax + 0
880 ecx = ^0 - eax
881 if ecx BBAdd0Min
882 ^0 = eax + 0
883 BBAdd0Min: ^0 = ^0 + 1
884 push ^0
885 push ^0
886 push ^3
887 call BSignExtend
888 push eax
889 push ^1
890 push ^5
891 call BSignExtend
892 ^1 = eax + 0
893 eax = ^2 + 0
894 call BCreateR
895 push eax
896 push 0
897 ecx = ^2 + 0
898 edx = ^3 + 0
899 BBAdd0Loop: ^0 = ^0 + @edx
900 ^0 = @ecx + ^0
901 @eax = ^0 & 255
902 ^0 = ^0 >> 8
903 eax = eax + 1
904 ecx = ecx + 1
905 edx = edx + 1
906 ^4 = ^4 - 1
907 if ^4 BBAdd0Loop
908 ^0 = ^1 + 0
909 call BOptimize
910 ^3 = eax + 0
911 call BDestroy
912 call BDestroy
913 call BDestroy
914 top eax
915 ^0 = ^2 + 0
916 ^2 = eax + 0
917 call BDestroy
918 call BDestroy
919 return
921 BBSubtract: call BLengthC
922 push eax
923 eax = ^2 - 1
924 eax = @eax + 0
925 ecx = ^0 - eax
926 if ecx BBSubtract0Min
927 ^0 = eax + 0
928 BBSubtract0Min: ^0 = ^0 + 1
929 push ^0
930 push ^0
931 push ^3
932 call BSignExtend
933 push eax
934 push ^1
935 push ^5
936 call BSignExtend
937 ^1 = eax + 0
938 eax = ^2 + 0
939 call BCreateR
940 push eax
941 push 0
942 ecx = ^2 + 0
943 edx = ^3 + 0
944 BBSubtract0Loop: ^0 = ^0 + @edx
945 ^0 = @ecx - ^0
946 @eax = ^0 & 255
947 ^0 = ^0 >> 8
948 ^0 = ^0 & 1
949 eax = eax + 1
950 ecx = ecx + 1
951 edx = edx + 1
952 ^4 = ^4 - 1
953 if ^4 BBSubtract0Loop
954 ^0 = ^1 + 0
955 call BOptimize
956 ^3 = eax + 0
957 call BDestroy
958 call BDestroy
959 call BDestroy
960 top eax
961 ^0 = ^2 + 0
962 ^2 = eax + 0
963 call BDestroy
964 call BDestroy
965 return
967 BDecimalAdd16R: push ebx
968 push esi
969 push edi
970 esi = eax + 0
971 ebx = edx + 0
972 eax = eax - 1
973 eax = @eax + 0
974 edi = eax + 0
975 ecx = esi + 0
976 BDecimalAdd16R0Loop: edx = @ecx + ebx
977 ebx = edx / 10
978 @ecx = edx % 10
979 ecx = ecx + 1
980 eax = eax - 1
981 if eax BDecimalAdd16R0Loop
982 ifeq ebx BDecimalAdd16R0End
983 eax = edi + 1
984 push eax
985 push esi
986 call BEnlarge
987 push esi
988 esi = eax + 0
989 call BDestroy
990 ecx = esi + edi
991 @ecx = ebx + 0
992 BDecimalAdd16R0End: eax = esi + 0
993 top edi
995 top esi
997 top ebx
999 return
1001 BDecimalMul16R: push ebx
1002 push esi
1003 push edi
1004 esi = eax + 0
1005 eax = eax - 1
1006 eax = @eax + 0
1007 edi = eax + 0
1008 ecx = esi + 0
1009 ebx = 0 + 0
1010 BDecimalMul16R0Loop: edx = @ecx * 16
1011 edx = edx + ebx
1012 ebx = edx / 10
1013 @ecx = edx % 10
1014 ecx = ecx + 1
1015 eax = eax - 1
1016 if eax BDecimalMul16R0Loop
1017 ifeq ebx BDecimalMul16R0End
1018 eax = edi + 1
1019 edx = ebx / 10
1020 ifeq edx BDecimalMul16R0NoMore
1021 eax = eax + 1
1022 BDecimalMul16R0NoMore: push eax
1023 push esi
1024 call BEnlarge
1025 push esi
1026 esi = eax + 0
1027 call BDestroy
1028 ecx = esi + edi
1029 BDecimalMul16R0OneMore: @ecx = ebx % 10
1030 ebx = ebx / 10
1031 ecx = ecx + 1
1032 if ebx BDecimalMul16R0OneMore
1033 BDecimalMul16R0End: eax = esi + 0
1034 top edi
1036 top esi
1038 top ebx
1040 return
1042 BBMultiply: call BLengthC
1043 push eax
1044 eax = ^1 - 1
1045 eax = @eax + 0
1046 ^0 = ^0 + eax
1047 push ^0
1048 push ^2
1049 call BSignExtend
1050 ecx = eax + 0
1051 eax = ^1 + 0
1052 ^1 = ecx + 0
1053 call BDestroyR
1054 push ^0
1055 push ^3
1056 call BSignExtend
1057 ecx = eax + 0
1058 eax = ^2 + 0
1059 ^2 = ecx + 0
1060 call BDestroyR
1061 eax = ^0 + 0
1062 call BCreateEmptyR
1063 push eax
1064 push 0
1065 push 0
1066 ^1 = 0 + 0
1067 BBMultiply0OuterLoop: ecx = 0 + 0
1068 ^0 = 0 + 0
1069 BBMultiply0InnerLoop: eax = ^4 + ^1
1070 edx = ^5 + ^0
1071 eax = @eax * @edx
1072 ecx = ecx + eax
1073 eax = ^0 + ^1
1074 edx = ^2 + eax
1075 ecx = ecx + @edx
1076 @edx = ecx & 255
1077 ecx = ecx >> 8
1078 ^0 = ^0 + 1
1079 eax = ^0 + ^1
1080 eax = ^3 - eax
1081 if eax BBMultiply0InnerLoop
1082 ^1 = ^1 + 1
1083 eax = ^3 - ^1
1084 if eax BBMultiply0OuterLoop
1085 eax = ^4 + 0
1086 call BDestroyR
1087 eax = ^5 + 0
1088 call BDestroyR
1089 ^0 = ^2 + 0
1090 call BOptimize
1091 ^4 = eax + 0
1093 call BDestroy
1096 return
1098 # BBDivMod(CBlob1, cBlob2: Blob): (Blob, Blob, Int); blobcall;
1099 BBDivMod: push ^0
1100 call BSign
1101 ecx = 0 + 0
1102 ifeq eax BBDivMod0NoSign0
1103 call BBNegate
1104 ecx = 3 + 0
1105 BBDivMod0NoSign0: push ecx
1106 push ^2
1107 call BSign
1108 ifeq eax BBDivMod0NoSign1
1109 ^0 = ^0 ^ 1
1110 push ^2
1111 call BBNegate
1112 ^3 = ^0 + 0
1114 BBDivMod0NoSign1: eax = ^2 - 1
1115 eax = @eax + 0
1116 ecx = ^2 + eax
1117 BBDivMod0Loop: eax = eax - 1
1118 ecx = ecx - 1
1119 ifneq @ecx BBDivMod0LoopDone
1120 if eax BBDivMod0Loop
1121 call EDivisionByZeroError
1122 BBDivMod0LoopDone: push eax
1123 push @ecx
1124 ifeq eax BBDivMod0NoMoreDivisor
1125 ecx = ecx - 1
1126 ^0 = ^0 << 8
1127 ^0 = ^0 + @ecx
1128 eax = eax - 1
1129 ifeq eax BBDivMod0NoMoreDivisor
1130 ^0 = ^0 + 1
1131 BBDivMod0NoMoreDivisor: eax = ^3 - 1
1132 eax = @eax + 0
1133 eax = eax - 1
1134 ecx = ^3 + eax
1135 BBDivMod1Check: ifneq @ecx BBDivMod1LoopDone
1136 eax = eax - 1
1137 ecx = ecx - 1
1138 if eax BBDivMod1Check
1139 BBDivMod1LoopDone: push eax
1140 push ecx
1141 eax = eax - ^3
1142 push eax
1143 ifeq eax BBDivMod9SameLength
1144 ^0 = ^0 - 1
1145 BBDivMod9SameLength: eax = eax + 1
1146 if eax BBDivMod7Large
1147 ^0 = ^7 + 0
1148 call BDestroy
1149 eax = 1 + 0
1150 call BCreateR
1151 @eax = 0 + 0
1152 ^6 = eax + 0
1153 jump BBDivMod8Early
1154 BBDivMod7Large: call BCreateEmptyR
1155 ^0 = ^0 + eax
1156 push eax
1157 push 0
1158 push 0
1159 push 0
1160 jump BBDivMod2Check
1161 BBDivMod2Loop: ^0 = 0 + 0
1162 eax = ^5 + 0
1163 ecx = ^6 + 0
1164 edx = 3 + 0
1165 BBDivMod3Loop: ifl ecx BBDivMod3LoopDone
1166 ^0 = ^0 << 8
1167 ^0 = ^0 + @eax
1168 ecx = ecx - 1
1169 eax = eax - 1
1170 edx = edx - 1
1171 if edx BBDivMod3Loop
1172 BBDivMod3LoopDone: ^0 = ^0 / ^7
1173 ecx = ^0 >> 8
1174 ifeq ecx BBDivMod6SingleByte
1175 ^0 = ecx + 0
1176 BBDivMod6SingleByte: eax = ^4 + 0
1177 ^5 = ^5 - 1
1178 ^6 = ^6 - 1
1179 call BBDivMod0AddMul
1180 BBDivMod2Check: eax = ^6 - ^8
1181 if eax BBDivMod2Loop
1182 ifl eax BBDivMod4Done
1183 eax = @^5 + 0
1184 ifleq ^6 BBDivMod5NoAdd
1185 ecx = ^5 - 1
1186 eax = eax << 8
1187 eax = eax + @ecx
1188 BBDivMod5NoAdd: ^0 = eax / ^7
1189 ifeq ^0 BBDivMod4Done
1190 eax = ^3 + 0
1191 call BBDivMod0AddMul
1192 BBDivMod4Done: ^0 = ^11 + 0
1193 call BDestroy
1194 ^10 = ^2 + 0
1199 BBDivMod8Early: pop
1203 return
1204 BBDivMod0AddMul: edx = ^0 + 0
1205 BBDivMod0AddMul0Loop: edx = edx + @eax
1206 @eax = edx & 255
1207 eax = eax + 1
1208 edx = edx >> 8
1209 ifneq edx BBDivMod0AddMul0Loop
1210 ^2 = ^11 + 0
1211 ^1 = ^8 + 1
1212 eax = 0 + 0
1213 edx = ^5 - ^8
1214 BBDivMod0AddMul1Loop: ecx = @^2 * ^0
1215 eax = eax + ecx
1216 ecx = eax & 255
1217 ecx = @edx - ecx
1218 @edx = ecx & 255
1219 ecx = ecx >> 31
1220 eax = eax >> 8
1221 eax = eax - ecx
1222 ^2 = ^2 + 1
1223 ^1 = ^1 - 1
1224 edx = edx + 1
1225 if ^1 BBDivMod0AddMul1Loop
1226 ifeq eax BBDivMod0AddMul2Check
1227 @edx = @edx - eax
1228 jump BBDivMod0AddMul2Check
1229 BBDivMod0AddMul2Loop: ^6 = ^6 - 1
1230 ^5 = ^5 - 1
1231 ^4 = ^4 - 1
1232 BBDivMod0AddMul2Check: ifneq @^5 BBDivMod0AddMul2SkipLoop
1233 if ^6 BBDivMod0AddMul2Loop
1234 BBDivMod0AddMul2SkipLoop: return
1236 BBDivide: call BBDivMod
1237 eax = ^1 + 0
1238 call BDestroyR
1239 ^1 = ^2 + 0
1240 ^0 = ^0 & 1
1241 ifeq ^0 BBDivide0Optimize
1242 ^0 = ^2 + 0
1243 call BNegate
1244 jump BBDivide0End
1245 BBDivide0Optimize: ^0 = ^2 + 0
1246 call BOptimize
1247 BBDivide0End: ^1 = eax + 0
1248 call BDestroy
1249 return
1251 BBModulo: call BBDivMod
1252 eax = ^2 + 0
1253 call BDestroyR
1254 ^0 = ^0 & 2
1255 ifeq ^0 BBModulo0Optimize
1256 ^0 = ^1 + 0
1257 call BNegate
1258 jump BBModulo0End
1259 BBModulo0Optimize: ^0 = ^1 + 0
1260 call BOptimize
1261 BBModulo0End: ^1 = eax + 0
1262 call BDestroy
1263 return
1265 BIntToStr: push ebx
1266 push esi
1267 push edi
1268 edi = eax + 0
1269 eax = eax - 1
1270 eax = @eax + 0
1271 edx = edi + eax
1272 edx = edx - 1
1273 ebx = @edx >> 7
1274 if ebx BIntToStr0Negate
1275 esi = edi + 0
1276 jump BIntToStr0SignDone
1277 BIntToStr0Negate: push edi
1278 call BNegate
1279 esi = eax + 0
1280 BIntToStr0SignDone: eax = esi - 1
1281 eax = @eax + 0
1282 edi = eax + 0
1283 esi = esi + eax
1284 eax = 1 + 0
1285 call BCreateR
1286 @eax = 0 + 0
1287 BIntToStr0Loop: esi = esi - 1
1288 call BDecimalMul16R
1289 edx = @esi >> 4
1290 call BDecimalAdd16R
1291 call BDecimalMul16R
1292 edx = @esi & 15
1293 call BDecimalAdd16R
1294 edi = edi - 1
1295 if edi BIntToStr0Loop
1296 edi = eax + 0
1297 eax = eax - 1
1298 eax = @eax + 0
1299 eax = eax + ebx
1300 call BCreateR
1301 push eax
1302 ifeq ebx BIntToStr0NoSign
1303 eax = esi + 0
1304 call BDestroyR
1305 top eax
1306 @eax = 45 + 0
1307 BIntToStr0NoSign: eax = edi - 1
1308 eax = @eax + 0
1309 esi = eax + 0
1310 edi = edi + eax
1311 top ecx
1312 ebx = ecx + ebx
1313 BIntToStr1Loop: edi = edi - 1
1314 @ebx = @edi + 48
1315 ebx = ebx + 1
1316 esi = esi - 1
1317 if esi BIntToStr1Loop
1318 eax = edi + 0
1319 call BDestroyR
1320 top eax
1322 top edi
1324 top esi
1326 top ebx
1328 return
1330 BBPrintStr: call BLengthC
1331 top ecx
1332 BBPrintStr0Loop: writechar @ecx
1333 ecx = ecx + 1
1334 eax = eax - 1
1335 if eax BBPrintStr0Loop
1336 call BDestroy
1337 return
1339 BBPrintInt: top eax
1340 call BIntToStr
1341 push eax
1342 call BBPrintStr
1343 call BDestroy
1344 return
1346 BBgetchr: eax = 1 + 0
1347 call BCreateR
1348 readchar @eax
1349 push eax
1350 return
1352 BBgetint: readint eax
1353 push eax
1354 call BBToBlob
1355 return
1357 BBoutstr: call BLengthC
1358 top ecx
1359 BBoutstr0Loop: eax = eax - 1
1360 edx = @ecx - 37
1361 ifneq edx BBoutstr0WriteChar
1362 ifeq eax EoutstrError
1363 eax = eax - 1
1364 ecx = ecx + 1
1365 edx = @ecx - 37
1366 ifeq edx BBoutstr0WriteChar
1367 edx = @ecx - 115
1368 ifeq edx BBoutstr0Percents
1369 edx = @ecx - 100
1370 ifeq edx BBoutstr0Percentd
1371 jump EoutstrError
1372 BBoutstr0Percents: call BBoutstr0GetPar
1373 call BBPrintStr
1374 jump BBoutstr0ClearStack
1375 BBoutstr0Percentd: call BBoutstr0GetPar
1376 call BBPrintInt
1377 BBoutstr0ClearStack: top ecx
1379 top eax
1381 ^1 = ^0 + 0
1383 jump BBoutstr0Continue
1384 BBoutstr0WriteChar: writechar @ecx
1385 BBoutstr0Continue: ecx = ecx + 1
1386 if eax BBoutstr0Loop
1387 call BDestroy
1388 return
1389 BBoutstr0GetPar: push eax
1390 push ecx
1391 push ^3
1392 return
1395 BFinalizeResult: eax = ebx + 0
1396 ecx = eax + 1
1397 ifneq ecx BFinalizeResult0End
1398 eax = 1 + 0
1399 call BCreateR
1400 @eax = 0 + 0
1401 BFinalizeResult0End: push eax
1402 return
1404 BBIsZero: call BLengthC
1405 ecx = eax - 1
1406 ifneq ecx BBIsZero0Return1
1407 ifneq @^0 BBIsZero0Return1
1408 eax = 0 + 0
1409 jump BBIsZero0End
1410 BBIsZero0Return1: eax = 1 + 0
1411 BBIsZero0End: push ^0
1412 ^1 = eax + 0
1413 call BDestroy
1414 top eax
1416 return
1418 BBTrue: push 1
1419 call BBCreate
1420 @eax = 255 + 0
1421 return
1423 BBFalse: push 1
1424 call BBCreate
1425 @eax = 0 + 0
1426 return