Krutoy Автор темы 1 169 Опубликовано: 12 сентября, 2022 Я только что понял, что я могу изменять метатаблицы строк! Это значит, что я могу добавить методы к строкам, тем самым полностью превратив имя робота в луа-программу, без подстанов и замен. Например, я могу добавить __bnot к строке, что будет ее загружать и превращать в функцию. getmetatable('').__bnot=function(s)return load('return '..s) end print((~'5*5')()) -- 25 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ProgramCrafter 550 Опубликовано: 12 сентября, 2022 3 минуты назад, Krutoy сказал: Я только что понял, что я могу изменять метатаблицы строк! Вроде machine.lua в OpenComputers запрещал так делать. Что ли, ещё один баг в OC нашёлся? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Krutoy Автор темы 1 169 Опубликовано: 12 сентября, 2022 26 минут назад, ProgramCrafter сказал: Вроде machine.lua в OpenComputers запрещал так делать. Что ли, ещё один баг в OC нашёлся? А machine.lua есть на EEPROM ? Если да, то это досада =(( UPD: Нашел... Печалька https://github.com/MightyPirates/OpenComputers/blob/master-MC1.12/src/main/resources/assets/opencomputers/lua/machine.lua#L730 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 157 Опубликовано: 12 сентября, 2022 14 минуты назад, Krutoy сказал: А machine.lua есть на EEPROM ? Обязательно. Без machine.lua даже EEPROM не запустится. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Krutoy Автор темы 1 169 Опубликовано: 12 сентября, 2022 Ок, тогда я могу делать трубу в строку Вот, чистый луа код без замены символов Tg()|'a1.tr()' Превращается в (еще оборачивается в pcall что бы ошибок не было при итерации) for k,v in pairs(trade.getTrades()) do v.tr() end 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Krutoy Автор темы 1 169 Опубликовано: 7 января, 2023 Продолжаю программировать. Понял что моя "труба" на самом деле называется "map". И теперь переписал код, что бы оператор map был через "*". Еще, "/" это `filter(v)`, а "%" это оператор "reduce(a,b)" T = q({{index=1},{name='n2'},{index=3}}) print(T*'v.i'/'v'%'a+b') -- 4 Осталось понять, что должно происходить, если мы делаем фильтр в таблицу или фильтр в число. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Krutoy Автор темы 1 169 Опубликовано: 2 марта, 2023 В общем, похоже вырисовывается в какой-то мере стабильно работающий код. Пока вся документация на английском: https://github.com/Krutoy242/lostuser В общем, я сохранил правила укорачивания и добавил больше функций между таблицами и функциями. Приведу пример дрона, который носит предметы между точками. Компоненты: Инвентарь, Контроллер инвентаря Имя дрона: P=i/Nf300ⓡDm^Pp,s/1~'Dg!>1',_(Pl) Описание каждой части имени: Nf300: Выполняет navigation.findWaypoints(300). Это никакое заранее указанное сокращение. Большая буква - это сокращение, которое получают все компоненты. navigation -> N, inventory_controller -> I и так далее. i/Nf300: Здесь используется единственная предустановленная переменная i. i = порядковый индекс текущего цикла программы, начиная с нуля. i / table - специальная функция "Получить индекс по модулю" или t[i % #t + 1]. Все эти функции, которые есть математические операторы над таблицами, есть в документации. По смыслу мы просто пробегаем каждый цикл по следующему вейпоинту. P=i/Nf300: Просто записываем в глобальную переменную P наш вейпоинт. Локальные переменные не могут сокращаться, поэтому мы используем глобальную. А еще, если буква будет большая, мы сможем сократить точку далее. ⓡ: просто один символ который будет заменен на return . Приму советы как избежать таких замен, что бы сохранить чистый Lua код 🙂 Dm^Pp: вызывает drone.move(table.unpack(P.position)). Тут должно быть просто. Dm => D.m => drone.m => drone.move. В документации по ссылке выше перечислены все операторы, и там написано что если функцию (drone.move) возвести в степень таблицы (p.position) то мы получим вызов функции с раскрытием таблицы в параметры. s/1~'Dg!>1' => while drone.getOffset() > 1 do sleep(1) end. Здесь символ ! заменяется на () _(Pl): Загрузить P.label как Lua код. Эта функция будет загружена и выполнена. Точки называются _'Dsk0'~4 и _'Dsel(k)Dd(0)'~4 соответственно. Первая сосет 4 раза, вторая выбирает каждый из 4х слотов и поочереди их выбрасывает. 4 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Krutoy Автор темы 1 169 Опубликовано: 3 марта, 2023 Если кто то читает эту тему, подскажите - как сделать присваивание внутри выражения? Например, есть вот такой код: _1_ function f() return _2_ end Я могу менять только _1_ и _2_. Я хочу что бы в _2_ было присваивание и тут же использование этой переменной. Например a=robot.move -- присваивание not a(3) and robot.turn(true) -- выражение Пока надумалось только такое решение - сделать функцию, которая будет присваивать значение глобальной переменной. Но этот вариант выглядит криво function _a(v) a = v end function f() return _a(robot.move), a(3) end Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 157 Опубликовано: 3 марта, 2023 1 час назад, Krutoy сказал: этот вариант выглядит криво А что именно ты хочешь выпрямить? Компактный вариант вроде используемого в языке Си вряд ли получится. Можно, например, избавиться от возврата мусорного значения в return без потери читаемости кода: function _a(v) a = v return a end function f() return _a(robot.move)(3) end Можно не захламлять пространство имён названием функции, но читаемость кода заметно снизится: function f() return (function(v)a=v return v end)(math.sin)(3.14) end Все эти варианты не особо красивы. Или тебе не красота нужна? Какова конечная цель этого трюка? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Krutoy Автор темы 1 169 Опубликовано: 4 марта, 2023 В 03.03.2023 в 11:31, eu_tomat сказал: Какова конечная цель этого трюка? Цель этого трюка - сократить количество символов в коде. Пример из реального кода: У нас есть точка из Навигатора дрона P=navigation.findWaypoints(300) Дальше по коду, мы полетим к этому вейпоинту, подождем, а затем выполним его название drone.move(table.unpack(P.position)) while drone.getOffset() > 1 do sleep(1) end run(P.label) В моем сокращении это всё выглядит так: P=i/Nf300ⓡDm^Pp,s/1~'Dg!>1',_(Pl) Допустим, я сделаю ту функцию function _P(v) P = v; return P end Тогда сокращение будет выглядить так: _P(i/Nf300),Dm^Pp,s/1~'Dg!>1',_(Pl) И это только увеличило количество символов на +1 😃 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Taruu 30 Опубликовано: 8 марта, 2023 В 04.04.2022 в 00:37, Krutoy сказал: Моя версия проще. Лешего, не нужно учить луа. Скрафтил и вперёд. Идея крутая, но чую что тут не хватает аля SPA простого который тупо рисовал блок-схемы или человеко читаемый код. А при желании еще и разжевывал что каждая команда делает с примерами и видосами. Но там кол-во работы настолько большое что повеситься можно >_< Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Krutoy Автор темы 1 169 Опубликовано: 9 марта, 2023 13 часа назад, Taruu сказал: Идея крутая, но чую что тут не хватает аля SPA простого который тупо рисовал блок-схемы или человеко читаемый код. А при желании еще и разжевывал что каждая команда делает с примерами и видосами. Но там кол-во работы настолько большое что повеситься можно >_< Мне кажется, делать "читаемый код" тут бессмысленно. Это как когда ты был в школе - тебе объяснили что такое знак +. Там не было никаких SPA схем или "человеко читаемый код". Может, показали пару-тройку яблок что бы объяснить что такое сложение. Думаю так же и здесь. Пару десятков раз заходишь в справочник что какой знак делает, потом привыкаешь. Да и я если честно, сам не совсем понимаю, как делать "человеко-читаемый код" в функциональном программировании. Например, есть оператор "apply" или по-русски "применение". В моем коде он выглядит как f/n, где f - функция, n - число или boolean. Результат будет выглядеть вот так: -- f/n function(...) return f(n, ...) end А теперь еще раз используем "применение": -- f/a/b function(...) return (function(...) return f(a, ...) end)(b, ...) end У меня если честно мозг устает такой "читаемый код" делать. 😅 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 157 Опубликовано: 10 марта, 2023 В 04.03.2023 в 18:08, Krutoy сказал: Цель этого трюка - сократить количество символов в коде. Но в конечном-то итоге ты хочешь сократить количество символов не в коде Lua, а в коде на твоём специфическом языке. И если правила этого языка ты определяешь сам, то можно создавать в принципе любые правила. Например, можно любое выражение присваивания интерпретировать по правилам языка Си. В каких-то случаях присваивание продолжится, в каких-то случаях оно окажется однократным, а иногда будет и вовсе отсутствовать, как это бывает с результатами вызова функций. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Krutoy Автор темы 1 169 Опубликовано: 10 марта, 2023 1 минуту назад, eu_tomat сказал: Но в конечном-то итоге ты хочешь сократить количество символов не в коде Lua, а в коде на твоём специфическом языке. И если правила этого языка ты определяешь сам, то можно создавать в принципе любые правила. Например, можно любое выражение присваивания интерпретировать по правилам языка Си. В каких-то случаях присваивание продолжится, в каких-то случаях оно окажется однократным, а иногда будет и вовсе отсутствовать, как это бывает с результатами вызова функций. Ну да, в этом и суть. Я придумываю правила сам. Вот только я не пишу свой парсер. Я придерживаюсь синтаксиса Луа, а поэтому, не могу сделать из присваивания выражение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 157 Опубликовано: 10 марта, 2023 Только что, Krutoy сказал: Я придерживаюсь синтаксиса Луа, а поэтому, не могу сделать из присваивания выражение. А что мешает? Ты же сам захотел присваивание внутри выражения, что не свойственно для Lua. Например, выражения вида a,b = c,d = e,f можно было бы заменять на нормальный код c,d = e,f a,b = c,d Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Krutoy Автор темы 1 169 Опубликовано: 10 марта, 2023 31 минуту назад, eu_tomat сказал: А что мешает? Например то, что будет очень сложно засунуть в EEPROM настоящий парсер со своим мощным синтаксисом Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 157 Опубликовано: 11 марта, 2023 В 10.03.2023 в 13:46, Krutoy сказал: Например то, что будет очень сложно засунуть в EEPROM настоящий парсер со своим мощным синтаксисом Это препятствие снова возвращает мои мысли к озвученной ранее идее: В 09.09.2022 в 15:00, eu_tomat сказал: С точки зрения пользователя я бы предпочёл использовать стандартный синтаксис Lua, и чтобы все необходимые сокращения кода за меня выполняла программа. Получилось бы подобие упаковщика кода в последовательность ASCII-символов, которые можно было бы ввести через наковальню. Это решение позволит уйти от создания уникального мощного, но компактного парсера, и сосредоточиться на универсальном и простом компрессоре, которому вообще не требуется ничего знать о синтаксисе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 157 Опубликовано: 12 марта, 2023 (изменено) В 09.09.2022 в 15:12, Krutoy сказал: Вопрос такой - как узнать все доступные в наковальне символы? Не все символы можно вставлять в название, например § Очень интересно получается: Через наковальню знак параграфа нельзя добавить, зато можно через компьютер. Через наковальню можно задать имя робота длиной максимум 30 символов, а через компьютер — больше мегабайта. И это, скорее всего, не предел, просто для вызова функции rep не хватило оперативной памяти. Ограничение EEPROM в 4096 байт с этого момента потеряло свою актуальность. Upd: Обсудили этот трюк в дискорде: Я заметил, что видимое имя робота обрезается по модулю 64 KiB. Например, при длине имени 64*1024+1 видимое имя будет состоять из одного символа, по крайней мере, при использовании стандартных ASCII-символов. @ProgramCrafter сделал прогноз, что имя длиннее 32KiB не переживёт перезагрузки сервера. Так и вышло: сохранился лишь огрызок из 32769 символов. Формат NBT не позволяет сохранить больше. Изменено 12 марта, 2023 пользователем eu_tomat upd 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Krutoy Автор темы 1 169 Опубликовано: 24 марта, 2023 Записал небольшой гайд о простом функционале 3 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 157 Опубликовано: 25 марта, 2023 23 часа назад, Krutoy сказал: Записал небольшой гайд о простом функционале А что там в ролике за бутылочка, ускоряющая сборку робота? И как ты сделал рецепт крафта своей EEPROM? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах