Перейти к содержимому
Krutoy

LostUser - простейший робот

Рекомендуемые сообщения

Я только что понял, что я могу изменять метатаблицы строк!

Это значит, что я могу добавить методы к строкам, тем самым полностью превратив имя робота в луа-программу, без подстанов и замен.

 

Например, я могу добавить __bnot к строке, что будет ее загружать и превращать в функцию.

getmetatable('').__bnot=function(s)return load('return '..s) end

print((~'5*5')()) -- 25

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
3 минуты назад, Krutoy сказал:

Я только что понял, что я могу изменять метатаблицы строк!

Вроде machine.lua в OpenComputers запрещал так делать.

Что ли, ещё один баг в OC нашёлся?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
14 минуты назад, Krutoy сказал:

А machine.lua есть на EEPROM ?

Обязательно. Без machine.lua даже EEPROM не запустится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ок, тогда я могу делать трубу в строку

 

Вот, чистый луа код без замены символов

 

Tg()|'a1.tr()'

 

Превращается в (еще оборачивается в pcall что бы ошибок не было при итерации)

for k,v in pairs(trade.getTrades()) do
  v.tr()
end

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Продолжаю программировать.

Понял что моя "труба" на самом деле называется "map". И теперь переписал код, что бы оператор map был через "*".

Еще, "/" это `filter(v)`, а "%" это оператор "reduce(a,b)"

 

T = q({{index=1},{name='n2'},{index=3}})
print(T*'v.i'/'v'%'a+b') -- 4

Осталось понять, что должно происходить, если мы делаем фильтр в таблицу или фильтр в число.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

В общем, похоже вырисовывается в какой-то мере стабильно работающий код.

 

Пока вся документация на английском:

https://github.com/Krutoy242/lostuser

 

В общем, я сохранил правила укорачивания и добавил больше функций между таблицами и функциями.

 

Приведу пример дрона, который носит предметы между точками.

 

36HdGzO.gif

 

Компоненты: Инвентарь, Контроллер инвентаря

Имя дрона:

P=i/Nf300Dm^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х слотов и поочереди их выбрасывает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если кто то читает эту тему, подскажите - как сделать присваивание внутри выражения?

 

Например, есть вот такой код:

_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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
 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

Все эти варианты не особо красивы.

Или тебе не красота нужна? Какова конечная цель этого трюка?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
В 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/Nf300Dm^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 😃

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

  

В 04.04.2022 в 00:37, Krutoy сказал:

Моя версия проще. Лешего, не нужно учить луа. Скрафтил и вперёд.

Идея крутая, но чую что тут не хватает аля SPA простого который тупо рисовал блок-схемы или человеко читаемый код. А при желании еще и разжевывал что каждая команда делает с примерами и видосами. Но там кол-во работы настолько большое что повеситься можно >_<

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
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

У меня если честно мозг устает такой "читаемый код" делать. 😅

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
В 04.03.2023 в 18:08, Krutoy сказал:

Цель этого трюка - сократить количество символов в коде.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 минуту назад, eu_tomat сказал:

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

Ну да, в этом и суть. Я придумываю правила сам.

Вот только я не пишу свой парсер. Я придерживаюсь синтаксиса Луа, а поэтому, не могу сделать из присваивания выражение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Только что, Krutoy сказал:

Я придерживаюсь синтаксиса Луа, а поэтому, не могу сделать из присваивания выражение.

А что мешает? Ты же сам захотел присваивание внутри выражения, что не свойственно для Lua. Например, выражения вида

a,b = c,d = e,f

можно было бы заменять на нормальный код

c,d = e,f
a,b = c,d

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
31 минуту назад, eu_tomat сказал:

А что мешает?

Например то, что будет очень сложно засунуть в EEPROM настоящий парсер со своим мощным синтаксисом :lol:

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
В 10.03.2023 в 13:46, Krutoy сказал:

Например то, что будет очень сложно засунуть в EEPROM настоящий парсер со своим мощным синтаксисом :lol:

Это препятствие снова возвращает мои мысли к озвученной ранее идее:

В 09.09.2022 в 15:00, eu_tomat сказал:

С точки зрения пользователя я бы предпочёл использовать стандартный синтаксис Lua, и чтобы все необходимые сокращения кода за меня выполняла программа. Получилось бы подобие упаковщика кода в последовательность ASCII-символов, которые можно было бы ввести через наковальню.

Это решение позволит уйти от создания уникального мощного, но компактного парсера, и сосредоточиться на универсальном и простом компрессоре, которому вообще не требуется ничего знать о синтаксисе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
В 09.09.2022 в 15:12, Krutoy сказал:

Вопрос такой - как узнать все доступные в наковальне символы? Не все символы можно вставлять в название, например

§

Очень интересно получается:

  • Через наковальню знак параграфа нельзя добавить, зато можно через компьютер.
  • Через наковальню можно задать имя робота длиной максимум 30 символов, а через компьютер — больше мегабайта. И это, скорее всего, не предел, просто для вызова функции rep не хватило оперативной памяти. Ограничение EEPROM в 4096 байт с этого момента потеряло свою актуальность.

 

Upd:

 

Обсудили этот трюк в дискорде:

  • Я заметил, что видимое имя робота обрезается по модулю 64 KiB. Например, при длине имени 64*1024+1 видимое имя будет состоять из одного символа, по крайней мере, при использовании стандартных ASCII-символов.
  • @ProgramCrafter сделал прогноз, что имя длиннее 32KiB не переживёт перезагрузки сервера. Так и вышло: сохранился лишь огрызок из 32769 символов. Формат NBT не позволяет сохранить больше.
Изменено пользователем eu_tomat
upd

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

Записал небольшой гайд о простом функционале

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
23 часа назад, Krutoy сказал:

Записал небольшой гайд о простом функционале

А что там в ролике за бутылочка, ускоряющая сборку робота?

И как ты сделал рецепт крафта своей EEPROM?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в тему...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...