@invert str; //ставит строку в обратном порядке
local int,'i',[len v0]; //v0 - входящая строка, в i записываем ее длину
local str,'s',''; //инициализируем пустую строку
mov v0, //записываем в v0 результат работы функции (копируем из буферной строки s)
[loop_down i,i,1, //нисходящий цикл
mov s,s+#[char v0,i] //получить символ исходной строки и записать его в буферную
];
@str_add str,str; //длинное сложение
local int,'i',[len v1]-[len v0]; //разница длин
//можно сделать swap v1,v0; но это не оптимально
ifmore i,
mov v0,[str i,$30]+v0; //str создает строку указанной длины и заполняет ее указанным байтом, по-умолчанию пробел
ifless i,
mov v1,[str -i,$30]+v1;
local int,'j',0; //переменная для хранения переполнения
loop_down i,[len v1],1, {
mov j,j+[char v0,i]+[char v1,i]-$60;
set_char v0,i,$30+[div j,10];
};
if j,
mov v0,#$30+j''v0; //дополнительная единица вначале
@str_sub str,str; //длинное вычитание с дополнением
local int,'i',[len v1]-[len v0];
ifmore i,
mov v0,[str i,$30]+v0;
ifless i,
mov v1,[str -i,$30]+v1;
local int,'j',0;
loop_down i,[len v1],1, {
mov j,[char v0,i]-j-[char v1,i]+10;
set_char v0,i,$30+[div j,10];
dec j;
}; //у вычитания не производится увеличения длины
@str_mul_ str,int; //умножение строки на малое число
local int,'i',0;
ifnot v1, {
mov v0,'0'; //если v1=0
break; //выход из функции
};
local int,'j',0;
loop_down i,[len v0],1, {
mov j,[char v0,i]-$30*v1+j;
set_char v0,i,$30+[div j,10];
};
ifmore j,
mov v0,j+v0; //допишем избыток
@str_mul str,str; //умножение двух строк
local int,'i';
local str,'s','0';
local int,'j',[len v0];
mov v0,[
loop_down i,j,1,
mov s,[str_add s,[str_mul_ v1,[char v0,i]-$30]+[str j-i,$30]]
];
@long_fac int; //длинный факториал
local str,'s','1';
msg v0+'! = '+[loop v0,1,v0, mov s,[str_mul_ s,v0]];