Squirrel: Общие вопросы и не очень…

Тема в разделе "LANGS.C", создана пользователем Paguo_86PK, 4 мар 2017.

  1. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Когдa в моих псевдо-проектах понадобилось использовать скриптовые вставки, по-началу я нашёл пример с биндингом готового MS-JavaScript от IE. Но, примеры были до того скудны, что все эти Dispatch и Variant меня очень быстро доконали и я стал искать нечто удобнее, пусть стороннее и подгружаемое. :download:
    Первоначально отыскал некий AngelScript и получилось довольно легко (после чудовищных танцев с бубном под дудку MS-IE-JS) всё заставить работать с пол пинка :good:
    Однако, наткнулся на Белочку и некоторые из её синтаксических особенностей мне приглянулись больше. И я взял её за основу :good2:

    P.S.: Думаю, что на этом форуме есть программисты, для которых "белочка" - не белая горячка :russian:
    Надеюсь, тема будет полезна и остальным. Потому, этот пост не будет содержать никаких вопросов… :whistle:
     
  2. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Вопрoс первый
    Код (C++):
    1. // Squirrel.cpp : Defines the entry point for the console application.
    2. //
    3.  
    4. #include "stdafx.h"
    5.  
    6. #include <stdio.h>
    7. #include<stdlib.h>
    8. #include<string.h>
    9. #include<stdarg.h>
    10.  
    11. // TODO: reference additional headers your program requires here
    12. #include "../../SQUIRREL3/include/squirrel.h"
    13. #include "../../SQUIRREL3/include/sqstdio.h"
    14. #include "../../SQUIRREL3/include/sqstdaux.h"
    15. #ifdef _MSC_VER
    16. #pragma comment (lib ,"../../SQUIRREL3/lib/squirrel.lib")
    17. #pragma comment (lib ,"../../SQUIRREL3/lib/sqstdlib.lib")
    18. #endif
    19.  
    20. HSQUIRRELVM svm;
    21.  
    22. SQInteger   SQF_Test(HSQUIRRELVM v) {
    23.     SQInteger       iArg = sq_gettop(v); //number of arguments
    24.     SQInteger       iValue, jValue,     i, j;
    25.     SQChar const    *pszValue;
    26.     char            sz[64] = {0};
    27.     wchar_t         wsz[64];
    28.     SQMemberHandle  sqh;
    29.     union {
    30.         SQChar const    *pszKey;
    31.     };
    32.     while(iArg > 1) {
    33.         switch(sq_gettype(v, iArg)) {
    34.         case OT_TABLE:
    35.             sq_pushnull(v);  //null iterator
    36.             while(SQ_SUCCEEDED(sq_next(v, -2))) {
    37.                 switch(sq_gettype(v, -2)) {
    38.                 case OT_STRING:
    39.                     sq_getstring(v, -2, &pszKey);
    40.                         if(!strcmp(pszKey, "x")) {
    41.                             // Тут начинается довольно проблемный код,
    42.                             // который никак не могу верно сформулировать
    43.                             // Цель: Тупо члену x присвоить числовое значение
    44.                             sq_pushstring(svm, "x", -3);
    45.                             sq_pushinteger(svm, 123);
    46.                             sq_rawset(svm, -5);
    47. // Здесь я очень сильно намусорил, перебирая разные варианты,
    48. // которые только мог выгуглить и отыскать в официальном мануале...
    49. // Не работает НИКАК! Хоть тресни в пятом измерении...
    50. //                          sq_set(v, -1);
    51. /*
    52. HSQOBJECT hsq_obj;
    53. //sq_getstackobj(v, -1, &retObj);
    54. //sq_objtointeger(&retObj);
    55. //                          SQ_SUCCEEDED(sq_getmemberhandle(v, -2, &sqh));
    56.                             //sq_pushstring(v, "x", -1),
    57. //                              sq_pushinteger(v, 123);
    58. //                              sq_setattributes(v, -1);
    59. //sq_resetobject(&hsq_obj); //initialize the handle
    60. sq_getstackobj(v,-1,&hsq_obj); //retrieve an object handle from the pos –2
    61. hsq_obj._unVal.nInteger ++;
    62. sq_pushobject(v, hsq_obj);
    63. sq_rawset(v, -1);
    64. sq_rawset(v, -2);
    65. sq_rawset(v, -3);
    66. //sq_addref(v,&hsq_obj); //adds a reference to the object
    67. //sq_pushinteger(v, 123);
    68. //sq_rawset(v,-1);
    69. */
    70.                         } else
    71.                         break;
    72.                 }
    73.                 sq_pop(v,2); //pops key and val before the nex iteration
    74.             }
    75.             sq_pop(v, 2);
    76.             break;
    77.         }
    78.         //sq_pop(v, 1);
    79.         -- iArg;
    80.     }
    81.     return 1;
    82. }
    83.  
    84. struct {
    85.     char        *alias;
    86.     SQInteger   (*function)(HSQUIRRELVM);
    87. } alf[] = {
    88.     "Test"      ,SQF_Test,
    89.     NULL,   NULL
    90. };
    91.  
    92. SQInteger SQ_register_global_func(HSQUIRRELVM v, SQFUNCTION f, char const *fname) {
    93.     sq_pushroottable(v);
    94.     sq_pushstring(v,fname,-1);
    95.     sq_newclosure(v,f,0); //create a new function
    96.     sq_newslot(v,-3,SQFalse);
    97.     sq_pop(v,1); //pops the root table    
    98.     return 0;
    99. }
    100.  
    101. void printfunc(HSQUIRRELVM v, const SQChar *s, ...) {
    102.     char    sz[4096];
    103.     va_list vl;
    104.     va_start(vl, s);
    105.     vprintf(s, vl);
    106. //  scvprintf(stdout, s, vl);
    107.     va_end(vl);
    108. //  Beep(500, 5);
    109. }
    110.  
    111. void errorfunc(HSQUIRRELVM v, const SQChar *s, ...) {
    112.     char    sz[4096];
    113.     va_list vl;
    114.     va_start(vl, s);
    115. //  scvprintf(stderr, s, vl);
    116.     vprintf(s, vl);
    117.     va_end(vl);
    118. }
    119.  
    120. SQChar  szCmd[] =
    121. "//\
    122. \r\n    function TeSt(_) {\
    123. \r\n        _.x = 456;\
    124. \r\n    }\
    125. \r\n    ::print(\"BEGIN\\r\\n\");\
    126. \r\n    local   q = {\
    127. \r\n                x = null\
    128. \r\n            };\
    129. \r\n    ::print(\"Initial status: q.x = \" + q.x + \"\\r\\n\");\
    130. \r\n// Выведет на консоль \"q = (null : 0x00000000) ...\" - пока верно\
    131. \r\n    Test(q); // Тут в q член x должен стать integer 123\
    132. \r\n    ::print(\">After Test(q): q.x = \" + q.x + \"\\r\\n\");\
    133. \r\n// Выведет на консоль то же \"q = (null : 0x00000000)\" - уже не верно (где 123???)\
    134. \r\n    TeSt(q); // Тут в q член x должен стать integer 456 и в консоли это выйдет\
    135. \r\n    ::print(\">After TeSt(q): q.x = \" + q.x + \"\\r\\n\");\
    136. \r\n    ::print(\"FINISH\\r\\n\");\
    137. \r\n";
    138.  
    139. int main(int argc, char* argv[])
    140. {
    141.     int     i;
    142.     svm = sq_open(1024); // creates a VM with initial stack size 1024
    143.     sq_setforeignptr(svm, 0);
    144.     sqstd_seterrorhandlers(svm); //registers the default error handlers
    145.     sq_setprintfunc(svm, printfunc, errorfunc); //sets the print function
    146.     i = sizeof alf / sizeof *alf;
    147.     while(i --)
    148.         SQ_register_global_func(svm, alf[i].function, alf[i].alias);
    149.     sq_pushroottable(svm); //push the root table(were the globals of the script will be stored)}
    150.     //
    151.     SQInteger oldtop = sq_gettop(svm);
    152.             sq_compilebuffer(svm, szCmd, (int)strlen(szCmd) * sizeof SQChar, "compile", 1);
    153.             sq_pushroottable(svm);
    154.             sq_call(svm, 1, SQFalse, SQTrue);
    155.         sq_settop(svm, oldtop);
    156.     //
    157.     printf("Hello World!\n");
    158.     return 0;
    159. }
    Выдаёт следующее:
    Код (DOS):
    1. BEGIN
    2. Initial status: q.x = (null : 0x00000000)
    3. >After Test(q): q.x = (null : 0x00000000)
    4. >After TeSt(q): q.x = 456
    5. FINISH
    6. Hello World!
    7. Press any key to continue
    P.S.: Кто-нибудь может мне помочь? :scratch_one-s_head:
    Что-то в сети не могу выгуглить ни примера, ни намёка, каким образом в готовой данной скриптом таблице изменять отдельные её члены… :read:
    (В своей утилите я перед вызовом callback-функции пользователя сейчас тупо заполняю таблицу из нескольких сотен членов данными из файла (FileMapping), а после возврата - обратно её сканирую и все значения скидываю обратно в файл. А это, сами понимаете, слишком много лишнего труда и нагрузки.
    Суть функции, которую пытаюсь расписать, в том, чтобы сканировать всю таблицу и числовые значения встречаемых членов скидывать в соответствующее место файла. Что достаточно легко.
    А вот члены, значения которых - null, функция должна, наоборот, прочитать из файла и вернуть им значение в таблицу. С чем я не могу справиться никак с сентября прошлого года :blush2: , когда решил таки оптимизировать это дело…
    А официальный форум даже не принимает моей темы :censored: )
    Спасибо!
     
  3. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    Paguo_86PK, а что за сервер БД, тоже белочка?:)
     
  4. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    попробуй редактировать бд чрез консольную утилиту ==>> если пашет, то в своей проге пиши/читай бд чрез сию тулзу.
     
  5. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Вчерa таки добился своего (кошмар, пол года топтаться из-за пустячка):
    Код (C++):
    1. #include <stdio.h>
    2. #include<stdlib.h>
    3. #include<string.h>
    4. #include<stdarg.h>
    5.  
    6. #include "../../SQUIRREL3/include/squirrel.h"
    7. #include "../../SQUIRREL3/include/sqstdio.h"
    8. #include "../../SQUIRREL3/include/sqstdaux.h"
    9. #ifdef _MSC_VER
    10. #pragma comment (lib ,"../../SQUIRREL3/lib/squirrel.lib")
    11. #pragma comment (lib ,"../../SQUIRREL3/lib/sqstdlib.lib")
    12. #endif
    13.  
    14. HSQUIRRELVM svm;
    15.  
    16. SQInteger   SQF_Test(HSQUIRRELVM v) {
    17.     SQInteger       iArg = sq_gettop(v); //number of arguments
    18.     SQInteger       iValue, jValue,     i, j;
    19.     SQChar const    *pszValue;
    20.     char            sz[64] = {0};
    21.     wchar_t         wsz[64];
    22.     SQMemberHandle  sqh;
    23.     union {
    24.         SQChar const    *pszKey;
    25.     };
    26.     while(iArg > 1) {
    27.         switch(sq_gettype(v, iArg)) {
    28.         case OT_TABLE:
    29.             sq_pushnull(v);  //null iterator
    30.             while(SQ_SUCCEEDED(sq_next(v, -2))) {
    31.                 switch(sq_gettype(v, -2)) {
    32.                 case OT_STRING:
    33.                     sq_getstring(v, -2, &pszKey);
    34.                         if(!strcmp(pszKey, "x")) {
    35.                             sq_pushstring(v, "x", -1);
    36.                             sq_pushinteger(v, 123);
    37.                             sq_set(v, -9);
    38.                         }
    39.                     break;
    40.                 }
    41.                 sq_pop(v,2); //pops key and val before the nex iteration
    42.             }
    43.             sq_pop(v, 2);
    44.             break;
    45.         }
    46.         //sq_pop(v, 1);
    47.         -- iArg;
    48.     }
    49.     return 1;
    50. }
    51.  
    52. struct {
    53.     char        *alias;
    54.     SQInteger   (*function)(HSQUIRRELVM);
    55. } alf[] = {
    56.     "Test"      ,SQF_Test,
    57.     NULL,   NULL
    58. };
    59.  
    60. SQInteger SQ_register_global_func(HSQUIRRELVM v, SQFUNCTION f, char const *fname) {
    61.     sq_pushroottable(v);
    62.     sq_pushstring(v,fname,-1);
    63.     sq_newclosure(v,f,0); //create a new function
    64.     sq_newslot(v,-3,SQFalse);
    65.     sq_pop(v,1); //pops the root table   
    66.     return 0;
    67. }
    68.  
    69. void printfunc(HSQUIRRELVM v, const SQChar *s, ...) {
    70.     char    sz[4096];
    71.     va_list vl;
    72.     va_start(vl, s);
    73.     vprintf(s, vl);
    74.     va_end(vl);
    75. }
    76.  
    77. void errorfunc(HSQUIRRELVM v, const SQChar *s, ...) {
    78.     char    sz[4096];
    79.     va_list vl;
    80.     va_start(vl, s);
    81.     vprintf(s, vl);
    82.     va_end(vl);
    83. }
    84.  
    85. SQChar  szCmd[] =
    86. "//\
    87. \r\n    function TeSt(_) {\
    88. \r\n        _.x = 456;\
    89. \r\n    }\
    90. \r\n    ::print(\"BEGIN\\r\\n\");\
    91. \r\n    local   q = {\
    92. \r\n                x = null\
    93. \r\n            };\
    94. \r\n    ::print(\"Initial status: q.x = \" + q.x + \"\\r\\n\");\
    95. \r\n// Write to console \"q = (null : 0x00000000) ...\" - right!\
    96. \r\n    Test(q); // Here are q.x is setted to a integer 123\
    97. \r\n    ::print(\">After Test(q): q.x = \" + q.x + \"\\r\\n\");\
    98. \r\n// Write to console now \"q = 123\" - very nice)\
    99. \r\n    TeSt(q); // Here are q.x is setted to a integer 456 - right, but through TeSt...\
    100. \r\n    ::print(\">After TeSt(q): q.x = \" + q.x + \"\\r\\n\");\
    101. \r\n    ::print(\"FINISH\\r\\n\");\
    102. \r\n";
    103.  
    104. int main(int argc, char* argv[])
    105. {
    106.     int     i;
    107.     svm = sq_open(1024); // creates a VM with initial stack size 1024
    108.     sq_setforeignptr(svm, 0);
    109.     sqstd_seterrorhandlers(svm); //registers the default error handlers
    110.     sq_setprintfunc(svm, printfunc, errorfunc); //sets the print function
    111.     i = sizeof alf / sizeof *alf;
    112.     while(i --)
    113.         SQ_register_global_func(svm, alf[i].function, alf[i].alias);
    114.     sq_pushroottable(svm); //push the root table(were the globals of the script will be stored)}
    115.     //
    116.     SQInteger oldtop = sq_gettop(svm);
    117.             sq_compilebuffer(svm, szCmd, (int)strlen(szCmd) * sizeof SQChar, "compile", 1);
    118.             sq_pushroottable(svm);
    119.             sq_call(svm, 1, SQFalse, SQTrue);
    120.         sq_settop(svm, oldtop);
    121.     //
    122.     return 0;
    123. }
    Выдаёт следующее:
    Код (DOS):
    1. BEGIN
    2. Initial status: q.x = (null : 0x00000000)
    3. >After Test(q): q.x = 123
    4. >After TeSt(q): q.x = 456
    5. FINISH
    6. Press any key to continue
    P.S.: Банальная невнимательность и довольно плохое понимание работы Lua-стека…