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::StringtoChar() 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