Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [Все]   Вниз
  Печать  
Автор Тема: интерпретируемый язык с поддержкой переменных  (Прочитано 35772 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 09-07-2013 11:26 » 

пока ещё не знаю, как точно вопрос задать

Одновременно в двух проектах на C++ потребовалась поддержка какого-нибудь языка (без наворотов, чтобы пользователь мог написать в виде текста небольшой отрывок кода, а программа могла бы понимать этот язык "на лету")

Пример, как это может понадобиться -
"на вход" приходит значение, это значение обрабатывается функцией пользователя и выдаётся "на выход"

 Входные параметры я могу передать функции в программе и сам - в текстовом виде. Затем интерпретатор это всё пережёвывает, после чего я забираю выходные данные

Подскажите, что имеется уже в природе или нет такое ?
Записан

darkelf
Молодой специалист

ua
Offline Offline

« Ответ #1 : 09-07-2013 11:46 » 

Алексей++, посмотрите в сторону lua (www.lua.org), очень неплохой, шустрый и компактный язык, довольно легко встраивается в программы на C/C++.
« Последнее редактирование: 09-07-2013 11:51 от darkelf » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 09-07-2013 14:34 » 

https://forum.shelek.ru/index.php/topic,29156.msg285399.html#msg285399
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 09-07-2013 18:55 » 

tcl http://www.tcl.tk/
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 09-07-2013 19:34 » 

Многие скриптовые языки имеют возможность запуска себя из чужого кода. Сперва надо определить требования, поверх наложить маску пожеланий и результат в студию.
« Последнее редактирование: 09-07-2013 19:36 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 10-07-2013 03:35 » 

Dimka, у меня же не шарп. Не совсем понял, как мне тот пост поможет

darkelf, Sla, RXL, сейчас почитаю
Записан

zubr
Гость
« Ответ #6 : 10-07-2013 03:57 » 

Насколько я понимаю, для любого скриптового языка нужна виртуальная машина, которая будет интерпретировать скриптовый язык в байт-код и выполнять его. То есть это должна быть какая то внешняя программа, которую надо будет тягать вместе с программой или использовать какую то виртуальную машину, встроенную в систему.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 10-07-2013 04:23 » 

Tcl - сложный синтаксис, низкое быстродействие
http://ru.wikipedia.org/wiki/Tcl
http://www.tcl.tk/

Lua - на первый взгляд самое то (синтаксис терпимый, быстродействие по описанию неплохое, распространённость. Имеются исходники на C - вот самое интересное)
http://ru.wikipedia.org/wiki/Lua
http://www.lua.org/about.html
мануал http://www.lua.org/manual/5.1/

zubr, да, это у меня ещё пока в тумане, ещё не вник, как вызвать "текстовую" функцию из своего кода и получить результат её работы. Виртуальная машина, я думаю, не обязательно должна быть запущена постоянно. Например, я вызываю функцию библиотеки движка, передаю ей текст программы, параметры, получаю ответ. Это тоже должно быть, мне кажется


http://www.ibm.com/developerworks/ru/library/l-lua/
-> http://lua-users.org/wiki/LuaBinaries
--> http://luabinaries.sourceforge.net/
---> http://sourceforge.net/projects/luabinaries/files/5.2.1/
static, dynamic версии
« Последнее редактирование: 10-07-2013 05:16 от Алексей++ » Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 10-07-2013 06:08 » 

Интерпретатор может быть запущен постоянно в отдельном процессе, а можно запускать по необходимости. Все зависит от того, как в него можно подавать команды: через файл, через стандартный ввод процесса, через вызовы API. Производительнее, соотв., постоянно запущенный. Интерпретация может быть текста программы или байт-кода. Соотв., байт-код будет быстрее на этап синтаксического разбора и компиляции. Если скрипт использует библиотеки, постоянно запущенный интерпретатор может их подгрузить заранее. И не забудь о контроле ошибок интерпретатора.
« Последнее редактирование: 10-07-2013 06:11 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 10-07-2013 06:08 » 

Цитата
Tcl - сложный синтаксис, низкое быстродействие
Ты че? с дуба свалился?
32к serial port почти в реалтайме.
Какое тебе еще нужно быстродействие?

Ты хочешь предоставить пользователю управлять чем-то, или автоматизировать какой-то процесс.
Потерпит. 0.75сек (lua) ничем не отличается от 0,76сек(tcl)

Синтаксис? Не сложнее бейсика
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 10-07-2013 06:29 » 

Sla, не всё сразу, я уже за Lua принялся ))
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 10-07-2013 06:36 » 

Алексей++, ну если ты внимательно прочитаешь, там написано, что вместо C# может быть любой язык. В том числе тобою любимый C++.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
zubr
Гость
« Ответ #12 : 10-07-2013 08:16 » 

Как вариант заюзать ява-скрипт или VB-скрипт, а в качестве виртуальной машины старый добрый осел IE, который запускать как COM-объект в невидимом режиме.
Записан
Kivals
Команда клуба

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 10-07-2013 08:26 » 

Ну ежели дело дошло до VBScript/JScript то и я свои 5 копеек вставлю Улыбаюсь
в 1С у себя использую объект MSScriptControl.ScriptControl (правда я использую для других целей, но в этой задаче тоже подойдет) - ИЕ не нужен...
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 10-07-2013 09:04 » 

не не, IE точно не нужно ))

я разобрался, как статически слинковать lua библиотеку, тестовый пример прошёл. Щас с типом userdata разберусь - и дело практически в шляпе.
Оказывается, при закачке нужно обращать внимание на версию студии, а то будет трах с линкером - я поначалу для vs11 качнул, а у меня 9

Dimka, тогда я не понимаю, как этим постом по ссылке воспользоваться Улыбаюсь Расскажи
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 10-07-2013 12:10 » 

Алексей++, всё, что на C# написано, написать на C++ - элементарно. Единственное, что там важно, это JScript - вот он такой, какой есть.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #16 : 11-07-2013 06:09 » 

я уж начал с LUA разбираться, я пока что с ним продолжу )

застопорился здесь: на стек не помещается результат работы функции. В чём загвоздка ?

(click to show)
Код:
	int error=0;
lua_State* L =luaL_newstate();

if(L)
{
std::string errortext;
std::string chunk;
int luaErr=0;

chunk="function f(a,b) return a+b end";
luaErr=luaL_loadbuffer(L, &chunk[0], chunk.size(), 0);

if(0==luaErr)
{

lua_getglobal(L, "f");//функция для вызова
lua_pushnumber(L, 3);
lua_pushnumber(L, 6);

luaErr=lua_pcall(L,1+2,1,0);

if(0==luaErr)
{
int result=0;

//смотрю результат в стеке
result=lua_tonumber(L, -1);

//>>>>>>>>>>>>>>>>>>>>>>>>>>>> //result==0

lua_pop(L, 1);

}
else
{
errortext=lua_tostring(L, -1);
lua_pop(L, 1);  //извлечь сообщение об ошибке из стека

}
}

lua_close(L);
}


тестовый проект прицепляю, чтобы было можно попробовать "не напрягаясь" - в архиве есть всё нужное вместе с библиотекой

Приведённый код находится в файле tDlg.cpp


Добавлено через 31 минуту и 35 секунд:
ну и параллельно смотрю JScript, так как наличие классов тоже, возможно, потребуется

* test.rar (216.6 Кб - загружено 870 раз.)
« Последнее редактирование: 11-07-2013 06:40 от Алексей1153 » Записан

darkelf
Молодой специалист

ua
Offline Offline

« Ответ #17 : 11-07-2013 07:04 » 

застопорился здесь: на стек не помещается результат работы функции. В чём загвоздка ?

тестовый проект прицепляю, чтобы было можно попробовать "не напрягаясь" - в архиве есть всё нужное вместе с библиотекой

Приведённый код находится в файле tDlg.cpp
я уж начал с LUA разбираться, я пока что с ним продолжу )

К сожалению собрать не получается - при линковке выдаёт:
Цитата
1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj)
1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in LIBCMTD.lib(dbgdel.obj)
1>LIBCMT.lib(invarg.obj) : error LNK2005: __initp_misc_invarg already defined in LIBCMTD.lib(invarg.obj)
1>LIBCMT.lib(invarg.obj) : error LNK2005: __call_reportfault already defined in LIBCMTD.lib(invarg.obj)
1>LIBCMT.lib(invarg.obj) : error LNK2005: __set_invalid_parameter_handler already defined in LIBCMTD.lib(invarg.obj)
1>LIBCMT.lib(invarg.obj) : error LNK2005: __get_invalid_parameter_handler already defined in LIBCMTD.lib(invarg.obj)
1>LIBCMT.lib(invarg.obj) : error LNK2005: __invoke_watson already defined in LIBCMTD.lib(invarg.obj)
1>LIBCMT.lib(invarg.obj) : error LNK2005: "void __cdecl _invoke_watson(unsigned short const *,unsigned short const *,unsigned short const *,unsigned int,unsigned int)" (?_invoke_watson@@YAXPBG00II@Z) already defined in LIBCMTD.lib(invarg.obj)
1>LIBCMT.lib(invarg.obj) : error LNK2005: __invalid_parameter already defined in LIBCMTD.lib(invarg.obj)
1>LIBCMT.lib(invarg.obj) : error LNK2005: "void __cdecl _invalid_parameter(unsigned short const *,unsigned short const *,unsigned short const *,unsigned int,unsigned int)" (?_invalid_parameter@@YAXPBG00II@Z) already defined in LIBCMTD.lib(invarg.obj)
1>LIBCMT.lib(invarg.obj) : error LNK2005: ___pInvalidArgHandler already defined in LIBCMTD.lib(invarg.obj)
1>LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
Visual Studio 2010
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #18 : 11-07-2013 07:10 » 

darkelf, это да, у меня студия 9 , а тебе, значит, нужны файлы для 10 . Вот тут http://sourceforge.net/projects/luabinaries/files/5.2.1/Windows%20Libraries/Static/
либо lua-5.2.1_Win32_vc10_lib.zip
либо lua-5.2.1_Win64_vc10_lib.zip
(2010 - это ведь 10 ? Улыбаюсь  А то там ещё для 11 есть версии)

и файл *.hpp переименуй на *.cpp

-------------------------------------------

а есть ли в природе готовые C++ классы, реализующие JScript ? В тырнете не нашёл. Пока что непонятно, как выполнить скрипт на JScript из C++ - функции . Кроме как, конечно, динамически подключить jscript.dll , интерфейс которой я пока ещё не знаю ))
« Последнее редактирование: 11-07-2013 07:14 от Алексей++ » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #19 : 11-07-2013 07:44 » 

Sla, смотрю ещё Incr tcl Отлично  

----------

#include "itcl32\include\itcl.h"
#include "itcl32\include\itclDecls.h"
#include "itcl32\include\itclInt.h"
#include "itcl32\include\itclIntDecls.h"
#include "itcl32\include\itk.h"
#include "itcl32\include\itkDecls.h"

хм, ругается на отсутствие tcl.h , а такого там нет вообще

Слава, куда бечь ?
« Последнее редактирование: 11-07-2013 07:59 от Алексей++ » Записан

darkelf
Молодой специалист

ua
Offline Offline

« Ответ #20 : 11-07-2013 08:23 » 

Даже с теми библиотеками всё-равно получились те-же ошибки. На базе Вашего примера написал свой - в итоге получилось следующим способом (для Visual Studio 6.0 и lua 5.1, думаю аналогично должно работать и для других студий/версий lua):
Код: (C)
#include <stdio.h>
#include "lua.h"

#pragma comment(lib, "lua51.lib")

int main(int argc, char* argv[])
{ char* chunk  ="function f(a,b) return a + b end";
  lua_State *L;
  int luaErr;

  L = lua_open();

  luaL_openlibs(L);

  if (luaL_loadstring(L, chunk) || lua_pcall(L,0,0,0))
  { printf("error: %s", lua_tostring(L, -1));
    lua_close(L);
    return 1;
  }

  lua_getglobal(L, "f");//функция для вызова
  lua_pushnumber(L, 3);
  lua_pushnumber(L, 6);

  luaErr=lua_pcall(L,2,1,0);

  if(0==luaErr)
  { int result=2;

    //смотрю результат в стеке
    result=lua_tonumber(L, -1);

    printf("%s -> %d\n", chunk, result);

    lua_pop(L, 1);
  }
  else
  { char* errortext;

    errortext=lua_tostring(L, -1);

    printf("%s -> error %s\n", chunk, errortext);

    lua_pop(L, 1);  //извлечь сообщение об ошибке из стека
  }
 
  lua_close(L);

  return 0;
}
как я понял - ключевым было выполнить само объявление функции (это там, где после luaL_loadstring(L, chunk) вызывается lua_pcall(L,0,0,0))
« Последнее редактирование: 11-07-2013 08:27 от darkelf » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 11-07-2013 08:49 » 

darkelf, спасибо, вононочо, оказывается. А где вычитал ?  Я не видел упоминаний

ну и 2 таки параметра, а не 3 (в доках сказано, что первый обязательно будет - имя функции)

ну а так - получилось получить результат Улыбаюсь

----------------

...по остальным вопросам тоже ещё актуально -  поскольку в LUA классов нет, всё же хотелось бы разобраться и с JScript и/или tcl . Юзеры желают писать свои структуры данных в стиле, близком к C/C++
Записан

darkelf
Молодой специалист

ua
Offline Offline

« Ответ #22 : 11-07-2013 08:52 » 

Алексей++, эксперименты ставил, а потом ещё поискал в интернетах - и нашел вроде рабочий пример: http://cc.byexamples.com/2008/07/15/calling-lua-function-from-c/ и по нём сравнивал - что и где отличается

Цитата
...по остальным вопросам тоже ещё актуально -  поскольку в LUA классов нет, всё же хотелось бы разобраться и с JScript и/или tcl . Юзеры желают писать свои структуры данных в стиле, близком к C/C++
В Lua вместо классов есть таблицы, и поверх них даже как-то делают ООП, но в этой области я не разбирался, и поэтому подсказать не могу, сорри. На вскидку нашлось: http://lua-users.org/wiki/ObjectOrientedProgramming
« Последнее редактирование: 11-07-2013 08:59 от darkelf » Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #23 : 11-07-2013 09:23 » 

Sla, смотрю ещё Incr tcl Отлично 

----------

#include "itcl32\include\itcl.h"
#include "itcl32\include\itclDecls.h"
#include "itcl32\include\itclInt.h"
#include "itcl32\include\itclIntDecls.h"
#include "itcl32\include\itk.h"
#include "itcl32\include\itkDecls.h"

хм, ругается на отсутствие tcl.h , а такого там нет вообще

Слава, куда бечь ?
гы  is an OO system for Tcl.
Бечь за тиклем....
http://www.tcl.tk/software/tcltk/
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #24 : 11-07-2013 09:25 » 

darkelf, про таблицы я понял, ассоциировать можно всё и вся, но тут вопрос в другом - сделать возможность описания юзерских структур в "привычном виде" , на их языке это означает - "в стиле C или похоже" Улыбаюсь  
Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #25 : 11-07-2013 09:28 » 

сделать возможность описания юзерских структур в "привычном виде"

Именно это.... тупо описываешь или переменные, или просто в строке, типа самопальный конфиг, потом отдаешь интерпретатору, а он сам разберется Улыбаюсь
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #26 : 11-07-2013 09:31 » 

Sla, оно мне предлагает инсталлер качать , а в виде lib / dll / h нету ?


тупо описываешь или переменные, или просто в строке, типа самопальный конфиг, потом отдаешь интерпретатору, а он сам разберется Улыбаюсь
это же городить надо . Ну посмотрим
Записан

darkelf
Молодой специалист

ua
Offline Offline

« Ответ #27 : 11-07-2013 09:40 » 

darkelf, про таблицы я понял, ассоциировать можно всё и вся, но тут вопрос в другом - сделать возможность описания юзерских структур в "привычном виде" , на их языке это означает - "в стиле C или похоже" Улыбаюсь  
Если рассматривать применение таблиц в виде именно структур, то они получаются вполне похожие, особенно если сравнивать с C99:

Код: (Lua)
a = { field1 = 5, field2 = 10}

print(a.field1, a.field2) -- 5       10
в C99:
Код: (C)
#include <stdio.h>
struct A { int field1; int field2; };

struct A a = { .field1 = 5, .field2 = 10 };

int main(int argc, char* argv[])
{ printf("%d %d\n", a.field1, a.field2);
  return 0;
}
« Последнее редактирование: 11-07-2013 09:47 от darkelf » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #28 : 11-07-2013 09:45 » 

darkelf, ну, я тоже уже понял. Только из-за отсутствия типов у народа крышу снесёт, наверное )
Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #29 : 11-07-2013 09:47 » 

Sla, оно мне предлагает инсталлер качать , а в виде lib / dll / h нету ?

Проинсталь, чего боишься?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #30 : 11-07-2013 09:49 » 

Алексей++, типы тоже есть, но вроде и в js тоже с типами плохо, точнее полностью аналогично - базовые типы есть числа, строки и булевские.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #31 : 11-07-2013 09:50 » 

Sla, ок
Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #32 : 11-07-2013 10:02 » 

на в тикле тоже нет явных типов
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #33 : 11-07-2013 10:34 » 

darkelf, даже можно наборы функций добавлять )

Код:
		chunk="function f1(a,b) return a+b end";
luaL_loadbuffer(L, &chunk[0], chunk.size(), 0);
lua_pcall(L,0,0,0);

chunk="function f2(a,b) return a+b+10 end";
luaL_loadbuffer(L, &chunk[0], chunk.size(), 0);
lua_pcall(L,0,0,0);
      

и работает

Записан

darkelf
Молодой специалист

ua
Offline Offline

« Ответ #34 : 11-07-2013 11:33 » 

darkelf, даже можно наборы функций добавлять )

Код:
		chunk="function f1(a,b) return a+b end";
luaL_loadbuffer(L, &chunk[0], chunk.size(), 0);
lua_pcall(L,0,0,0);

chunk="function f2(a,b) return a+b+10 end";
luaL_loadbuffer(L, &chunk[0], chunk.size(), 0);
lua_pcall(L,0,0,0);
      

и работает
можно и зараз множество функций:
Код: (C)
chunk="function f1(a,b) return a+b end ; function f2(a,b) return a+b+10 end";
luaL_loadbuffer(L, &chunk[0], chunk.size(), 0);
lua_pcall(L,0,0,0);
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #35 : 11-07-2013 14:38 » 

ООП можно соорудить на чём угодно. В JavaScript и Lua оно одинаковое - безклассовое на замыканиях и ассоциативных массивах.

Насчёт типизированности не понял. Зачем в интерпретируемом языке типизация? Она имеет смыл лишь при компиляции - когда весь текст заранее проверяешь на косяки. Алексей++, ты хочешь иметь раздельные стадии компиляции и исполнения?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #36 : 17-07-2013 09:48 » 

darkelf, ага, уже понял ) Можно вообще любой синтаксически верный кусок текста добавить

Dimka, пока что потребовалось в таком виде: загружаю в "машину" все функции, по мере необходимости вызываю нужную, передаю ей числовые параметры, получаю ответ, делаю действие.  Уже увидел, что, в принципе, можно все параметры сделать текстовыми.

 Когда компилируется -  думаю, лучше это пусть делается после определения нужных функций (и этим, видимо, как раз и занимается вызов lua_pcall(L,0,0,0)  после загрузки ещё одного куска кода )

замыкания - ага, уже почитал, интересная штука. Но пока ещё в голове нет стройности в том, как организовать класс в привычном виде - с методами . Ещё просто не дошёл до этого места, там разберусь )

А в остальном пока всё устраивает в LUA
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #37 : 17-07-2013 19:52 » 

Цитата: Алексей++
Но пока ещё в голове нет стройности в том, как организовать класс в привычном виде - с методами .
Элементарно. Метод - это функция, в контексте которой содержатся переменные объекта (видны ей). В данном случае это переменные внутри замыкания и/или значения (которые не ключи) ассоциативного массива. Функция - это тоже объект, назначенный переменной. Т.е. функцию можно добавить в объект как и любое другое значение - и будут тебе методы Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #38 : 19-07-2013 06:37 » 

Dimka,  правильно ли я понимаю ? Попытался описать фабрику класса A

(судя по выводу в консоль, это работает)


Код: (Lua)
-- фабрика экземпляров класса A
function create_class_A()
       
        local this={} --таблица будет содержать переменные и методы экземпляра
       
        this.var=0 -- объявил и инит. переменную var
       
        this.get_var= -- метод, возвращающий var
                function()
                        return this.var
                end
       
        return this
end



function test()

        local a1=create_class_A()
        local a2=create_class_A()

        a1.var=1
        a2.var=2
       
        print(a1:get_var())
        print(a2:get_var())
       
end

> test()
1
2
>
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #39 : 19-07-2013 08:42 » 

Алексей++, с уточнением, что внутри объекта есть разница между замыканием и ассоциативным массивом как точкой доступа.
Код: (Lua)
-- конструктор объекта
function createC()

  -- локальные переменные функции createC сохранятся внутри замыкания и не будут видны снаружи
  -- так делаются private члены
  -- чтобы их отличать от public, локальных переменных и аргументов методов, будем им ставить префикс "_"

  -- private поля и сразу их инициализация как в конструкторе, код инициализации может быть произвольной сложности
  local _x = 1

  -- protected static поля - общие для всех объектов
  _Const = 3

  -- private методы
  function _printState()
    print(_x)
  end

  -- ассоциативный массив для создаваемого объекта, являющийся точкой доступа к объекту
  -- содержимое ассоциативного массива хранит public члены объекта
  local self = {}

  -- public поля и сразу их инциализация, например, для объявления доступных снаружи констант, которые будем писать с большой буквы
  self.Const = _Const

  -- public методы
  function self.set(x)
    -- можем работать с private членами, поскольку функция находится в общем замыкании с переменными
    _x = x
    _printState()
  end

  function self.get()
    return _x
  end

  -- конструктор обязательно возвращает ассоциативный массив с открытыми членами объекта
  return self

end

-- использование
o = createC()
-- теперь в переменной o находится ассоциативный массив с открытыми членами объекта,
-- со всеми функциями внутри этого массива связано замыкание конструктора, в котором хранятся закрытые члены объекта
o.set(o.Const)
print(o.get())
3
3
Таким образом, функция createC здесь не вполне фабрика. Она не ограничивается только созданием ассоциативного массива со связанными между собой элементами, она ещё генерирует собственное замыкание с закрытыми внутри него private переменными и вспомогательными функциями и увязывает всю эту конструкцию в единый объект.

Стоит заметить, что конструктор может порождать целую серию ассоциативных массивов, являющихся разными интерфейсами одного и того же объекта. Например
Код: (Lua)
function createProcessor

  local readerInterface = {}
  function readerInterface.read()
    print("read")
  end

  local writerInterface = {}
  function writerInterface.write()
    print("write")
  end

  return readerInterface, writerInterface

end

reader, writer = createProcessor()
reader.read()
writer.write()
read
write

Наследование с полиморфизмом поведения реализуется элементарно. Достаточно получить ассоциативный массив предка и дополнить/переписать его под потомка. При этом private-члены будут свои для каждого конструктора. С одним ассоциативным массивом связывается несколько замыканий: по одному замыканию от каждого конструктора с local-переменными (private) и общее замыкание для всех конструкторов и всех объектов с не local переменными (static protected).

Код: (Lua)
function createParent
  local _x = 1
  _y = 3
  local self = {}
  function self.test()
    print("test")
  end
  function self.foo()
    print("parent")
    print(_x)
    print(_y)
  end
  return self
end

function createChild
  local _x = 2
  local self = createParent()
  function self.foo()
    print("child")
    print(_x)
    print(_y)
  end
  return self
end

p = createParent()
p.test()
p.foo()
c = createChild()
c.test() -- унаследовано от parent
c.foo() -- переопределено, но переменная _y видна из parent и является общей для всех объектов
test
parent
1
3
test
child
2
3

В общем, вот и весь краткий курс безклассового ООП.
« Последнее редактирование: 19-07-2013 09:12 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #40 : 19-07-2013 09:03 » 

по первому блоку кода: я всё так и понял, вроде бы. Только в моём случае все переменные размещались в таблице this, которая будет жить в объекте благодаря замыканию и которая есть эквивалент _x, по сути. С той лишь разницей, что я вернул ссылку на эту приватную таблицу, тем самым разрешив доступ ко всем полям извне. Тут вроде всё понятно

С наследованием тоже понятно, спасибо.  По сути, всё то, что в C++ скрывается синтаксисом, тут как на ладони расписывается ))

Добавлено через 22 минуты и 24 секунды:
а как организовать аналог сишной локальной static переменной в функции ? Глобальная таблица ?

« Последнее редактирование: 19-07-2013 09:25 от Алексей1153 » Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #41 : 19-07-2013 11:02 » 

Алексей++, нет, в C++ нету замыканий функций. Наоборот, из объектов можно делать аналог функций с замыканиями - функторы: объекты с оператором (). В Lua всё с точностью наоборот: из функций с замыканиями делаются объекты.

Аналога static переменных внутри функций нет. Но через замыкание можно - см. выше переменные внутри конструктора без local. Т.е. в чистом виде это будет просто замыкание без ассоциативных массивов.
Код: (Lua)
f = (function()
  staticVar = 0
  return function()
    staticVar = staticVar + 1
    print(staticVar)
  end
end)()

f()
f()
1
2
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #42 : 19-07-2013 11:14 » 

Нет, выше я всюду неправ насчёт не local переменных и функция - это просто глобальные переменные и функции, видимые отовсюду. Они не закрыты. Т.е. за пределами объектов такие переменные могут изменить значение, а функции конфликтовать за счёт совпадения имён. Значит нет static protected, бывают только private - это local переменные и функции внутри функций.
« Последнее редактирование: 19-07-2013 21:32 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: 1 2 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines