Вопрос по стеку Lua, стеку Lua и нюансы его чтения
Пользователь
Сообщений: Регистрация: 18.10.2016
12.03.2024 05:06:56
1. Вопрос к знатокам: при работе со стеком, перед началом чтения через lua_next(L, -2), нам необходимо делать lua_pushnil(L). Зачем? Ведь это по сути означает "положить сверху NULL". Для чего мы это делаем? 2. Далее, почему в некоторых случаях мы читаем данные, как lua_tostring(L, -1). А в некоторых lua_tostring(L, 1). Если я правильно понимаю - это не одно и то же. В стеке из двух элементов индекс 1 - это низ стека, а -1 - верх стека! 3. Потом, для чего мы делаем lua_pop(L, 1); при использовании lua_next(L, -2), когда читаем стек? Ведь это удалит только один верхний элемент и все. Т.е., когда я читаю из стека некую таблицу - я должен посмотреть ключ (поле) по lua_next(L, -2) и, если он есть, то прочесть данные через lua_tostring(L, -1). Но потом я удаляю всего 1 элемент сверху. Не понимаю, что за дичь. 4. Есть у кого-то понимание / объяснение / картинка как выглядит стек qLua, когда в нем лежат смешанные данные? Т.е. как туда кладется таблица, строки и т.д.? Потому что по логике чтения я могу предположить, что туда кладется сначала ключ, а сверху значение. Это следует из логики чтения: -2 ключ, -1 значение (что тоже какая-то хрень, но это еще как-то понять можно набухавшись). Но что если у меня таблица в таблице или плоские данные, типа строка / число? Документация не то чтобы объясняет это все.
Можно конечно забить и принять это как факт, а для себя сделать класс-обертку и забыть навсегда эти ужасы. Но стало уж очень принципиально понять, как это работает и что вообще происходит.
Пользователь
Сообщений: Регистрация: 30.01.2015
12.03.2024 06:24:58
Цитата
Виталий написал: 1. Вопрос к знатокам: при работе со стеком, перед началом чтения через lua_next(L, -2), нам необходимо делать lua_pushnil(L). Зачем? Ведь это по сути означает "положить сверху NULL". Для чего мы это делаем? 2. Далее, почему в некоторых случаях мы читаем данные, как lua_tostring(L, -1). А в некоторых lua_tostring(L, 1). Если я правильно понимаю - это не одно и то же. В стеке из двух элементов индекс 1 - это низ стека, а -1 - верх стека! 3. Потом, для чего мы делаем lua_pop(L, 1); при использовании lua_next(L, -2), когда читаем стек? Ведь это удалит только один верхний элемент и все. Т.е., когда я читаю из стека некую таблицу - я должен посмотреть ключ (поле) по lua_next(L, -2) и, если он есть, то прочесть данные через lua_tostring(L, -1). Но потом я удаляю всего 1 элемент сверху. Не понимаю, что за дичь. 4. Есть у кого-то понимание / объяснение / картинка как выглядит стек qLua, когда в нем лежат смешанные данные? Т.е. как туда кладется таблица, строки и т.д.? Потому что по логике чтения я могу предположить, что туда кладется сначала ключ, а сверху значение. Это следует из логики чтения: -2 ключ, -1 значение (что тоже какая-то хрень, но это еще как-то понять можно набухавшись). Но что если у меня таблица в таблице или плоские данные, типа строка / число? Документация не то чтобы объясняет это все.
Можно конечно забить и принять это как факт, а для себя сделать класс-обертку и забыть навсегда эти ужасы. Но стало уж очень принципиально понять, как это работает и что вообще происходит.
1. Не NULL а nil. Чтобы выбрать первый элемент таблицы. ------------------------ 2. -1,1 - выбор с разных концов стека. --------------------------- 3. см документацию: int lua_next (lua_State *L, int index); Снимает ключ со стека, ложит пару ключ-значение из таблицы Т е ключ функция сама убирает из стека, а значение убираем сами. ------------------------------ 4. qLua - это библиотека функций. У нее нет стека. Стек есть у виртуальной машины луа. qLua никаким боком не имеет отношение к этому. ------------------- Не надо ничего предполагать или гадать, лучше прочитать:
написал: 1. Вопрос к знатокам: при работе со стеком, перед началом чтения через lua_next(L, -2), нам необходимо делать lua_pushnil(L). Зачем? Ведь это по сути означает "положить сверху NULL". Для чего мы это делаем? 2. Далее, почему в некоторых случаях мы читаем данные, как lua_tostring(L, -1). А в некоторых lua_tostring(L, 1). Если я правильно понимаю - это не одно и то же. В стеке из двух элементов индекс 1 - это низ стека, а -1 - верх стека! 3. Потом, для чего мы делаем lua_pop(L, 1); при использовании lua_next(L, -2), когда читаем стек? Ведь это удалит только один верхний элемент и все. Т.е., когда я читаю из стека некую таблицу - я должен посмотреть ключ (поле) по lua_next(L, -2) и, если он есть, то прочесть данные через lua_tostring(L, -1). Но потом я удаляю всего 1 элемент сверху. Не понимаю, что за дичь. 4. Есть у кого-то понимание / объяснение / картинка как выглядит стек qLua, когда в нем лежат смешанные данные? Т.е. как туда кладется таблица, строки и т.д.? Потому что по логике чтения я могу предположить, что туда кладется сначала ключ, а сверху значение. Это следует из логики чтения: -2 ключ, -1 значение (что тоже какая-то хрень, но это еще как-то понять можно набухавшись). Но что если у меня таблица в таблице или плоские данные, типа строка / число? Документация не то чтобы объясняет это все.
Можно конечно забить и принять это как факт, а для себя сделать класс-обертку и забыть навсегда эти ужасы. Но стало уж очень принципиально понять, как это работает и что вообще происходит.
1. Не NULL а nil. Чтобы выбрать первый элемент таблицы. ------------------------ 2. -1,1 - выбор с разных концов стека. --------------------------- 3. см документацию: int lua_next (lua_State *L, int index); Снимает ключ со стека, ложит пару ключ-значение из таблицы Т е ключ функция сама убирает из стека, а значение убираем сами. ------------------------------ 4. qLua - это библиотека функций. У нее нет стека. Стек есть у виртуальной машины луа. qLua никаким боком не имеет отношение к этому. ------------------- Не надо ничего предполагать или гадать, лучше прочитать:
Спасибо.
1. Не принципиально, суть поняли. Я на разных языках пишу, где-то NULL (что даже привычней мне), но это одно и то же. 2. Вот зачем и почему? Т.е. я не понимаю почему в одном случае мы читаем через 1, а в других через -1. От чего зависит? Ну т.е. есть какое-то правило по которым таблицы сверху всегда или что, почему таблицы обчитываются через отрицательные индексы сверху стека? 3. Это типа lua_next снимает ключ, а мы через pop убираем остальное после чтения? Жесть какая-то, ну ладно. 4. Хорошо, допустим, но вот интересно как раз как это работает в Lua. Потому что у меня сложилось ощущение какого-то изврата. Хочу понять подробнее как оно работает
Пользователь
Сообщений: Регистрация: 20.03.2023
12.03.2024 23:44:17
Виталий, "2. Вот зачем и почему? Т.е. я не понимаю почему в одном случае мы читаем через 1, а в других через -1. От чего зависит? Ну т.е. есть какое-то правило по которым таблицы сверху всегда или что, почему таблицы обчитываются через отрицательные индексы сверху стека?" Вы такой вопрос задаёте и тогда, когда в питоне видите отрицательные индексы в списках? Это известная идиома в интепретируемых языках и стек-машинах (виртуальных машинах), чисто для удобства программиста, чтобы ему не высчитывать номер индекса с начала контейнера (списка, строки, стека), если он знает номер с конца. В луа от этого проигрыш в скорости небольшой, но есть.
Пользователь
Сообщений: Регистрация: 18.10.2016
13.03.2024 04:20:05
Цитата
funduk написал: , "2. Вот зачем и почему? Т.е. я не понимаю почему в одном случае мы читаем через 1, а в других через -1. От чего зависит? Ну т.е. есть какое-то правило по которым таблицы сверху всегда или что, почему таблицы обчитываются через отрицательные индексы сверху стека?" Вы такой вопрос задаёте и тогда, когда в питоне видите отрицательные индексы в списках? Это известная идиома в интепретируемых языках и стек-машинах (виртуальных машинах), чисто для удобства программиста, чтобы ему не высчитывать номер индекса с начала контейнера (списка, строки, стека), если он знает номер с конца. В луа от этого проигрыш в скорости небольшой, но есть.
На пайтоне я не пишу, никак до него не дойду и то в рамках нейросеток интересен, не более. Но суть вопроса не в том, почему индекс отрицательный, а почему во всех примерах с таблицами я вижу использование отрицательных индексов, а в примерах с передачей строки/числа - положительный. Это чисто совпадение или таблицы всегда кладут сверху стека? Т.е. можно ли это считать постоянным событием или нужно всегда проверять не таблица ли передо мной (видел вроде метод такой)?
написал: 1. Вопрос к знатокам: при работе со стеком, перед началом чтения через lua_next(L, -2), нам необходимо делать lua_pushnil(L). Зачем? Ведь это по сути означает "положить сверху NULL". Для чего мы это делаем? 2. Далее, почему в некоторых случаях мы читаем данные, как lua_tostring(L, -1). А в некоторых lua_tostring(L, 1). Если я правильно понимаю - это не одно и то же. В стеке из двух элементов индекс 1 - это низ стека, а -1 - верх стека! 3. Потом, для чего мы делаем lua_pop(L, 1); при использовании lua_next(L, -2), когда читаем стек? Ведь это удалит только один верхний элемент и все. Т.е., когда я читаю из стека некую таблицу - я должен посмотреть ключ (поле) по lua_next(L, -2) и, если он есть, то прочесть данные через lua_tostring(L, -1). Но потом я удаляю всего 1 элемент сверху. Не понимаю, что за дичь. 4. Есть у кого-то понимание / объяснение / картинка как выглядит стек qLua, когда в нем лежат смешанные данные? Т.е. как туда кладется таблица, строки и т.д.? Потому что по логике чтения я могу предположить, что туда кладется сначала ключ, а сверху значение. Это следует из логики чтения: -2 ключ, -1 значение (что тоже какая-то хрень, но это еще как-то понять можно набухавшись). Но что если у меня таблица в таблице или плоские данные, типа строка / число? Документация не то чтобы объясняет это все.
Можно конечно забить и принять это как факт, а для себя сделать класс-обертку и забыть навсегда эти ужасы. Но стало уж очень принципиально понять, как это работает и что вообще происходит.
1. Не NULL а nil. Чтобы выбрать первый элемент таблицы. ------------------------ 2. -1,1 - выбор с разных концов стека. --------------------------- 3. см документацию: int lua_next (lua_State *L, int index); Снимает ключ со стека, ложит пару ключ-значение из таблицы Т е ключ функция сама убирает из стека, а значение убираем сами. ------------------------------ 4. qLua - это библиотека функций. У нее нет стека. Стек есть у виртуальной машины луа. qLua никаким боком не имеет отношение к этому. ------------------- Не надо ничего предполагать или гадать, лучше прочитать:
Спасибо.
1. Не принципиально, суть поняли. Я на разных языках пишу, где-то NULL (что даже привычней мне), но это одно и то же. 2. Вот зачем и почему? Т.е. я не понимаю почему в одном случае мы читаем через 1, а в других через -1. От чего зависит? Ну т.е. есть какое-то правило по которым таблицы сверху всегда или что, почему таблицы обчитываются через отрицательные индексы сверху стека? 3. Это типа lua_next снимает ключ, а мы через pop убираем остальное после чтения? Жесть какая-то, ну ладно. 4. Хорошо, допустим, но вот интересно как раз как это работает в Lua. Потому что у меня сложилось ощущение какого-то изврата. Хочу понять подробнее как оно работает
Небольшой ликбез. ------------------------- 1. Вы ошибаетесь. NULL и nil это не одно и то же. Это одно и тоже в objective-c, но не в луа. В Lua нет NULL. --------------------- Но если сравнить различные языки, то , если в данных присутствуют значения NULL, логические операторы и операторы сравнения могут возвращать, кроме TRUE или FALSE, также и третий результат — UNKNOWN. --------------- nil в Lua - это всегда false. ----------------- 2. Этот способ адресации делает VMLua не только стековой машиной, но и регистровой машиной. Отрицательный индекс удобен, когда работаем с вершиной, положительные, когда работаем с фактическими параметрами функций. -------------------------------- 4. Зря Вы не читаете учебники и документацию, а придумываете объяснение сами. Проблема Вашего непонимания в том, что Вы не знаете архитектуры процессоров. Пытаетесь разобраться в "железе" на основе знания какого-либо языка программирования. -------------------- Очевидно, что Ваши ощущения - это и есть результат незнания. ------------------ Подробнее написано в ссылках, выше и в других статьях в интернете.
Добавлю отсебятину: в Lua для логического типа и типа nil не используется память под данные: просто байт для хранения типа переменной указывает, что тип этой переменной nil. Для логического типа байт типа указывает, что это лог. тип, а дополнительный бит в этом байте равен 0/1 в случае false/true.
Пользователь
Сообщений: Регистрация: 18.10.2016
13.03.2024 19:33:54
Цитата
nikolz написал: 1. Вы ошибаетесь. NULL и nil это не одно и то же. Это одно и тоже в objective-c, но не в луа. В Lua нет NULL.
Допустим, но глобально в текущей ситуации это разве что-то меняет? Это пусто, 0, ничего, false.
Цитата
Serge123 написал: Но если сравнить различные языки, то , если в данных присутствуют значения NULL, логические операторы и операторы сравнения могут возвращать, кроме TRUE или FALSE, также и третий результат — UNKNOWN.
Только JS встречал, с которым сейчас в основном и работаю. Больше нигде.
Цитата
nikolz написал: 2. Этот способ адресации делает VMLua не только стековой машиной, но и регистровой машиной.Отрицательный индекс удобен, когда работаем с вершиной, положительные, когда работаем с фактическими параметрами функций.
Ну вот примерно про это я и спрашивал. Получается, что это просто работа со стеком таким образом, чтобы не превращать его в массив. Стек - это первый зашел и последний вышел. А если читать стек по положительным индексам - это массив получится. Получается, что это просто выбор разраба, как читать - ок. Меня это и интересовала: это правило или просто так сложилось.
Цитата
nikolz написал: 4. Зря Вы не читаете учебники и документацию, а придумываете объяснение сами. Проблема Вашего непонимания в том, что Вы не знаете архитектуры процессоров.Пытаетесь разобраться в "железе" на основе знания какого-либо языка программирования. -------------------- Очевидно, что Ваши ощущения - это и есть результат незнания.
Ну так я сюда и пришел за знаниями. Разве форумы не для того чтобы быстро получить ответ на вопрос и продвинуться дальше? Читать документацию и прочее можно до бесконечности. У меня знакомый 4 года назад начал изучение ReactJS с чтения документации, тогда как я советовал ему освоить базу и начать работать. До сих пор учит. Зачем же в такие крайности?
Цитата
nikolz написал: Подробнее написано в ссылках, выше и в других статьях в интернете.
написал: 1. Вы ошибаетесь. NULL и nil это не одно и то же. Это одно и тоже в objective-c, но не в луа. В Lua нет NULL.
Допустим, но глобально в текущей ситуации это разве что-то меняет? Это пусто, 0, ничего, false.
Цитата
написал: Но если сравнить различные языки, то , если в данных присутствуют значения NULL, логические операторы и операторы сравнения могут возвращать, кроме TRUE или FALSE, также и третий результат — UNKNOWN.
Только JS встречал, с которым сейчас в основном и работаю. Больше нигде.
Цитата
написал: 2. Этот способ адресации делает VMLua не только стековой машиной, но и регистровой машиной.Отрицательный индекс удобен, когда работаем с вершиной, положительные, когда работаем с фактическими параметрами функций.
Ну вот примерно про это я и спрашивал. Получается, что это просто работа со стеком таким образом, чтобы не превращать его в массив. Стек - это первый зашел и последний вышел. А если читать стек по положительным индексам - это массив получится. Получается, что это просто выбор разраба, как читать - ок. Меня это и интересовала: это правило или просто так сложилось.
Цитата
написал: 4. Зря Вы не читаете учебники и документацию, а придумываете объяснение сами. Проблема Вашего непонимания в том, что Вы не знаете архитектуры процессоров.Пытаетесь разобраться в "железе" на основе знания какого-либо языка программирования. -------------------- Очевидно, что Ваши ощущения - это и есть результат незнания.
Ну так я сюда и пришел за знаниями. Разве форумы не для того чтобы быстро получить ответ на вопрос и продвинуться дальше? Читать документацию и прочее можно до бесконечности. У меня знакомый 4 года назад начал изучение ReactJS с чтения документации, тогда как я советовал ему освоить базу и начать работать. До сих пор учит. Зачем же в такие крайности?
Цитата
написал: Подробнее написано в ссылках, выше и в других статьях в интернете.
Спасибо.
Массив регистров. - это и есть регистровый способ адресации. Т е VMLua это не только стековая, но и регистровая машина. Два в одном.
Пользователь
Сообщений: Регистрация: 30.01.2015
13.03.2024 20:33:53
вообще-то, это форум по QUIK, а не про луа. ------------- Тут постоянно путают qLua с VMLua.
Пользователь
Сообщений: Регистрация: 30.01.2015
13.03.2024 20:37:08
QLUA - это библиотека функций, написанная на СИ --------------------------- VMLua - это виртуальная вычислительная машина , тоже написанная на CИ , интерпретирующая байт-код скрипта Lua.
Пользователь
Сообщений: Регистрация: 18.10.2016
13.03.2024 22:16:38
Цитата
nikolz написал: QLUA - это библиотека функций, написанная на СИ --------------------------- VMLua - это виртуальная вычислительная машина , тоже написанная на CИ , интерпретирующая байт-код скрипта Lua.
Но ведь ветка называется "Программирование на языке Lua".
написал: QLUA - это библиотека функций, написанная на СИ --------------------------- VMLua - это виртуальная вычислительная машина , тоже написанная на CИ , интерпретирующая байт-код скрипта Lua.
Но ведь ветка называется "Программирование на языке Lua".
Но вопросы не о программировании на луа, а о внутреннем строении функций на СИ.
Пользователь
Сообщений: Регистрация: 30.01.2015
14.03.2024 06:18:56
Полагаю, что программирование на луа и строение VMLua - это две большие разницы, подобно как руление на авто и строение двигателя авто.