my
, it will contain two functions:isdigit
will check if the string passed in the parameter consists of numbers onlyhash
will convert the parameter to a hash string according to our algorithmmy_isdigit
: static int my_isdigit(OS * os, int params, int, int, void*) { OS::String str = os->toString(-params); int len = str.getLen(); for(int i = 0; i < len; i++){ if(!isdigit(str[i])){ os->pushBool(false); return 1; } } os->pushBool(len > 0); return 1; }
OS::String str = os->toString(-params);
params
is the number of parameters that were passed to the function from the OS. -params
is a relative pointer on the stack to the first parameter. If we needed to turn to the second parameter, then it would look like this: os->toString(-params+1)
, to the third one - os->toString(-params+2)
, etc.toFloat, toDouble, toInt, toString, toUserdata, popFloat
, etc.getAbsoluteOffs(int offs)
and then work like this: int params_offs = os->getAbsoluteOffs(-params); OS::String str = os->toString(params_offs); // OS::String str = os->toString(params_offs+1); //
my_hash
: static int my_hash(OS * os, int params, int, int, void*) { OS::String str = os->toString(-params); int i, len = str.getLen(), hash = 5381; for(i = 0; i < len; i++){ hash = ((hash << 5) + hash) + str[i]; } hash &= 0x7fffffff; char buf[16]; for(i = 0; hash > 0; hash >>= 4){ buf[i++] = "0123456789abcdef"[hash & 0xf]; } buf[i] = 0; os->pushString(buf); return 1; }
return 1;
void initMyModule(OS * os) { OS::FuncDef funcs[] = { {"isdigit", my_isdigit}, {"hash", my_hash}, {} }; os->getModule("my"); os->setFuncs(funcs); os->pop(); }
for(var i, s in ["123", "12w", 1234, " df", " "]){ print("my.isdigit("..s..") = "my.isdigit(s)" my.hash("..s..") = "my.hash(s)) }
my.isdigit(123) = true my.hash(123) = bf9878b my.isdigit(12w) = false my.hash(12w) = f3a878b my.isdigit(1234) = true my.hash(1234) = f89c87c7 my.isdigit( df) = false my.hash( df) = f48478b my.isdigit( ) = false my.hash( ) = 5082f6c7
#include "objectscript.h" #include <ctype.h> using namespace ObjectScript; static int my_isdigit(OS * os, int params, int, int, void*) { OS::String str = os->toString(-params); int len = str.getLen(); for(int i = 0; i < len; i++){ if(!isdigit(str[i])){ os->pushBool(false); return 1; } } os->pushBool(len > 0); return 1; } static int my_hash(OS * os, int params, int, int, void*) { OS::String str = os->toString(-params); int i, len = str.getLen(), hash = 5381; for(i = 0; i < len; i++){ hash = ((hash << 5) + hash) + str[i]; } char buf[16]; hash &= 0x7fffffff; for(i = 0; hash > 0; hash >>= 4){ buf[i++] = "0123456789abcdef"[hash & 0xf]; } buf[i] = 0; os->pushString(buf); return 1; } void initMyModule(OS * os) { OS::FuncDef funcs[] = { {"isdigit", my_isdigit}, {"hash", my_hash}, {} }; os->getModule("my"); os->setFuncs(funcs); os->pop(); } void main() { OS * os = OS::create(); initMyModule(os); os->require("main.os"); os->release(); }
OS::String
toChar()
function. ObjectScript stores in memory all the different strings in a single copy , so OS::String
is a constant string, it cannot be changed under any circumstances. But you can get a new line. OS::String
implements a number of constructors and a concatenation operator, so OS::String
can be created from custom code and work with it (if necessary).os->release()
earlier than OS::String
strings stored in custom code are destroyed?os->release()
does not destroy an instance of OS, but it will be destroyed when the last string OS::String
ceases to exist.Source: https://habr.com/ru/post/153021/
All Articles