Просмотр полной версии : [Вопрос] ulong (оператор #emit)
Доброго времени суток. Хотелось бы узнать, как можно в ulong (https://github.com/tdworg/samp-include-ulong)от VVWVV конвертировать строку в ulong? Там нет для этого функционала, но как можно написать аналог strval для ulong?
давно я не писал на pawn, попробую написать.
Что-то такое должно получиться:
stock ulong:ulong_strval(str[], bool:ispacked=false, off=0, size=sizeof str)
{
new ulong:result;
new c;
new pos=off;
while ('0'<=(c=str[pos])<='9') {
#emit load.s.pri result
#emit const.alt 10
#emit umul
#emit push.pri
#emit load.s.pri c
#emit const.alt '0'
#emit sub
#emit pop.alt
#emit add
#emit stor.s.pri result
pos++;
}
return result;
}
Это unsafe функция.
DC. заметил, что ispacked подсвечивается в списке формальных аргументов?
Daniel_Cortez
09.04.2020, 16:28
Во-первых, искренне не понимаю, откуда вообще взялось название "ulong". Если рассматривать это с позиции разработчика, знакомого как минимум с C/C++, слово "long" подразумевает тип данных большего размера, т.е. не 4 байта (размер ячейки), а 8. Здесь же тип "ulong" ограничен всё теми же 4 байтами и является просто чем-то вроде беззнакового типа данных ("чем-то вроде", потому что в Pawn нет типов данных как таковых - есть теги) и было бы логичнее назвать его "ucell" (т.е. "беззнаковая ячейка"; кстати, именно так этот тип данных и называется в исходниках Pawn). Впрочем, это так, небольшая придирка, на работе инклуда это не сказывается =)
Да и вообще, это ничто на фоне других популярных инклудов/плагинов - взять, к примеру, небезызвестные плагины с нелепыми хайповыми названиями, начинающимися на "Pawn.*", как будто они являются частью проекта Pawn (т.е. наравне с компилятором, интерпретатором и стандартными библиотеками; не говоря уже о том, что это тянет на недобросовестное использование торговой марки "Pawn").
Во-вторых,
ulong:ulong_strval(str[], bool:ispacked=false, off=0, size=sizeof str)
если передаваемый в функцию массив используется только для чтения, его следует помечать как "const" (т.е. в данном случае - "const str[]").
В-третьих,
new ulong:result;
https://pro-pawn.ru/showthread.php?16839-warning-210-%28-%29
В-четвёртых, зачем нужен параметр "off", если функцию можно использовать так:
new ulong:result = ulong_strval(inputtext[4]);
?
В-пятых, не используется параметр "size" (ты это имел в виду под "unsafe-функция"?), но он и не нужен - строка всё равно заканчивается нуль-символом, на котором выполнение цикла while прервётся, так что ситуация с OOB исключена. По этой же причине и у стандартной функции strval() нет параметра "size".
В-шестых, параметр "ispacked" тоже не особо нужен, упакованность строки можно проверить и внутри самой функции.
И, наконец, в-седьмых, с помощью оператора __emit вычитание кода символа "0" можно записать так:
add.c (-'0')
, т.е. без загрузки значения в ALT, благодаря чему не нужно лишний раз сохранять другое значение из PRI в стек.
В итоге у меня получилась такая функция:
stock ulong:ulong_strval(const str[])
{
new const bool:packed = (str[0] & ~0xFF != 0);
new ulong:result = ulong:0;
new pos = 0;
new c;
while ('0' <= (c = (packed ? str{pos} : str[pos])) <= '9') {
__emit load.s.pri result;
__emit const.alt 10;
__emit umul;
__emit move.alt;
__emit load.s.pri c;
__emit add.c (-'0');
__emit add;
__emit stor.s.pri result;
pos++;
}
return result;
}
DC. заметил, что ispacked подсвечивается в списке формальных аргументов?
А что ты ожидал? =)
Подсветка работает на простой замене текста, ибо полноценный анализ синтаксиса => неоправданная нагрузка на сервер (либо на клиент, если делать клиент-сайдом на js).
спасибо. проверю, как будет время.
Во-первых, искренне не понимаю, откуда вообще взялось название "ulong". Если рассматривать это с позиции разработчика, знакомого как минимум с C/C++, слово "long" подразумевает тип данных большего размера, т.е. не 4 байта (размер ячейки), а 8. Здесь же тип "ulong" ограничен всё теми же 4 байтами и является просто чем-то вроде беззнакового типа данных ("чем-то вроде", потому что в Pawn нет типов данных как таковых - есть теги) и было бы логичнее назвать его "ucell" (т.е. "беззнаковая ячейка"; кстати, именно так этот тип данных и называется в исходниках Pawn). Впрочем, это так, небольшая придирка, на работе инклуда это не сказывается =)
Да и вообще, это ничто на фоне других популярных инклудов/плагинов - взять, к примеру, небезызвестные плагины с нелепыми хайповыми названиями, начинающимися на "Pawn.*", как будто они являются частью проекта Pawn (т.е. наравне с компилятором, интерпретатором и стандартными библиотеками; не говоря уже о том, что это тянет на недобросовестное использование торговой марки "Pawn").
Во-вторых,
если передаваемый в функцию массив используется только для чтения, его следует помечать как "const" (т.е. в данном случае - "const str[]").
В-третьих,
https://pro-pawn.ru/showthread.php?16839-warning-210-%28-%29
В-четвёртых, зачем нужен параметр "off", если функцию можно использовать так:
?
В-пятых, не используется параметр "size" (ты это имел в виду под "unsafe-функция"?), но он и не нужен - строка всё равно заканчивается нуль-символом, на котором выполнение цикла while прервётся, так что ситуация с OOB исключена. По этой же причине и у стандартной функции strval() нет параметра "size".
В-шестых, параметр "ispacked" тоже не особо нужен, упакованность строки можно проверить и внутри самой функции.
И, наконец, в-седьмых, с помощью оператора __emit вычитание кода символа "0" можно записать так:
add.c (-'0')
, т.е. без загрузки значения в ALT, благодаря чему не нужно лишний раз сохранять другое значение из PRI в стек.
В итоге у меня получилась такая функция:
stock ulong:ulong_strval(const str[])
{
new const bool:packed = (str[0] & ~0xFF != 0);
new ulong:result = ulong:0;
new pos = 0;
new c;
while ('0' <= (c = (packed ? str{pos} : str[pos])) <= '9') {
__emit load.s.pri result;
__emit const.alt 10;
__emit umul;
__emit move.alt;
__emit load.s.pri c;
__emit add.c (-'0');
__emit add;
__emit stor.s.pri result;
pos++;
}
return result;
}
А что ты ожидал? =)
Подсветка работает на простой замене текста, ибо полноценный анализ синтаксиса => неоправданная нагрузка на сервер (либо на клиент, если делать клиент-сайдом на js).
"давно я не писал на pawn, попробую написать." =) я знал, что ты это исправишь, спасибо.
Powered by vBulletin® Version 4.2.0 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot