LINUX.ORG.RU
ФорумTalks

Добавил поддержку корутин в свою реализацию Кумира

 ,


0

2

Предыдущая серия про Кумир тут: Компилятор русского языка программирования Кумир

Если кратко то я добавил поддержку корутин. На синтаксисе это никак не отразилось, а вот во внутреннем языке оно есть. Это позволило в частности сделать нормальную анимацию в браузере.

Например, есть код анимации задачи n-тел:

использовать Рисователь

  алг
  нач
      вещ таб x[0:N-1], y[0:N-1], vx[0:N-1], vy[0:N-1]
      вещ таб tx[0:N-1, 0:TAIL-1], ty[0:N-1, 0:TAIL-1]
      цел frame

      инициализировать(x, y, vx, vy, tx, ty)
      новый лист(W, H, чёрный)

      frame := 0
      нц пока да
          шаг_физики(x, y, vx, vy, tx, ty)
          нарисовать(frame, x, y, tx, ty)
          frame := frame + 1
      кц
  кон

  алг шаг_физики(...)
  нач
      | обычный CPU-код, без команд Рисователя
  кон

  алг нарисовать(...)
  нач
      | рисуем кадр
      окружность(int(CX), int(CY), 12)
      ...
      окружность(int(x[i]), int(y[i]), 2)

      | граница кадра / suspend point
      новый лист(W, H, чёрный)
  кон

Трансляция во внутренний язык (ast, core-lang):

(fun <main> void () ()
    (block
      ...
      (call инициализировать x y vx vy tx ty)
      (call |новый лист| W H чёрный)
      (= frame 0)
      (while
        #t
        (block
          (call шаг_физики x y vx vy tx ty)
          (call нарисовать frame x y tx ty)
          (= frame (+ frame 1))))))

  (fun шаг_физики void (...) ()
    (block
      ...))

  (fun нарисовать void (...) ()
    (block
      ...
      (call окружность (call int CX) (call int CY) 12)
      ...
      (call окружность (call int (index i x)) (call int (index i y)) 2)
      (call |новый лист| W H чёрный)))

Тут «новый лист» это на самом деле переход к новому фрейму. Это корутина. Данный ast трансформируется в

(fun <main> <future void> () ()
    (block
      ...
      (call инициализировать x y vx vy tx ty)

      ;; прямой suspend point: painter_new_sheet / "новый лист"
      (await (call |новый лист| W H (: 4278190080 <named цвет i64>)))

      (= frame 0)
      (while
        (cast 1 bool)
        (block
          ;; обычная функция: не стала корутиной
          (call шаг_физики x y vx vy tx ty)

          ;; транзитивный await:
          ;; main ждёт нарисовать, потому что нарисовать внутри вызывает новый лист
          (await (call нарисовать frame x y tx ty))

          (= frame (+ frame 1))))))

  (fun шаг_физики void (...) ()
    (block
      ...))

  (fun нарисовать <future void> (...) ()
    (block
      ...
      (call окружность (call int CX) (call int CY) 12)
      ...
      (call окружность (call int (index i x)) (call int (index i y)) 2)

      ;; локальный suspend point, из-за него вся функция стала Future<void>
      (await (call |новый лист| W H (: 4278190080 <named цвет i64>)))))

То есть автоматом ставится await и все вызывающие функции транзитивно становятся корутинами. Это позволяет прыгнуть в js, сделать отрисовку, а потом прыгнуть назад в кумир.

Демка: http://qumir.dev/s/ZTZjYjM2NzRk

Звезды ставить сюда: https://github.com/resetius/qumir

★★★★★

Последнее исправление: Reset (всего исправлений: 1)

Например, есть код анимации задачи n-тел:

Я вставил верхнюю часть твоей писанины к тебе на страницу в окно редактора. Перенажимал все кнопки. Ничего не произошло. Как запустить твоё поделие?

Enthusiast ★★★★
()
Ответ на: комментарий от Enthusiast

Я снипет в пост вставил, а не полную программу, для запуска специально сделал быструю ссылку :) Вот еще раз ссылка: http://qumir.dev/s/ZTZjYjM2NzRk

Reset ★★★★★
() автор топика
Ответ на: комментарий от Reset

Надо было так: координата_по_оси_X, координата_по_оси_Y, скорость_по_оси_X, скорость_по_оси_Y

хѣръ, ижица, ижица-хѣръ, ижица-ѹкъ

frunobulax ★★★★
()
Ответ на: комментарий от Reset

икс, игрэк, скорость_икс, скорость_игрек или х, у, вх, ву? Ну чтобы набирать, не переключаясь. Кстати в официальной IDE есть временное переключение раскладки по AltGr, только у меня не работало. Нужно чтобы набирать []{} в основном.

Xenius ★★★★★
()

В полноценном императивном языке программирования должны быть как минимум структуры (связанные в одну переменную разнородные данные) и указатели, у тебя их похоже нет.

Что-то роскомопозор не даёт грузить CSS с сайта, поэтому загружаются какие-то разнородные иконки и не работает.

Кстати можно их gzip сжать как workaround. Он даёт по 15 килобайт грузить, а у тебя где-то вдвое больше.

Xenius ★★★★★
()
Ответ на: комментарий от Xenius

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

zurg ★★
()
Ответ на: комментарий от Reset

У меня на капсе стоит - не особо напрягает

У меня тоже. Но такое частое переключение напрягло бы.

Camel ★★★★★
()
Ответ на: комментарий от Xenius

В core-lang в который делается трансляция есть все. А в кумире их изначально не было, я придерживаюсь оригинального синтаксиса. Можно конечно прагмы добавить со своими расширениями.

Через структуры сделаны комплексные числа. Через указатели передача значений по ссылке (арг рез в сигнатурах), а также массивы

Reset ★★★★★
() автор топика
Ответ на: комментарий от Xenius

Что-то роскомопозор не даёт грузить CSS с сайта, поэтому загружаются какие-то разнородные иконки и не работает.

Печаль. Попробую посмотреть под русским vpn вечером

Reset ★★★★★
() автор топика
Ответ на: комментарий от Reset

А нужны ли прагмы? Просто сделать расширение не противоречащее оригиналу?

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

Xenius ★★★★★
()
Последнее исправление: Xenius (всего исправлений: 1)
Ответ на: комментарий от Xenius

Интерпретатор кумира на кумире кстати есть и написан на массивах, на Хабре статья есть :)

Reset ★★★★★
() автор топика
Ответ на: комментарий от Reset

В этой реализации ключевые слова регистрозависимые?

// Ещё мне кажется, что в русском ЯП слово «инициализировать» выглядит крайне всрато, и можно было бы подобрать аналог покороче и понативнее.

hobbit ★★★★★
()
Ответ на: комментарий от frunobulax

юс малый, юс большой и два йотированных же.

hobbit ★★★★★
()
Ответ на: комментарий от Reset

А смысл в интерпретаторе? Он ничего не даёт, только замедляет. Хотя конечно интересно сколько так можно сделать уровней вложенности. Надо компилятор.

Xenius ★★★★★
()
Ответ на: комментарий от Xenius

Я далек пока от компилятора кумира на кумире. У меня кодогенерация зависит от llvm. Ну можно конечно сказать что генерируем не as, а llvm-as и звать потом llvm тулзу вместо as, но я не уверен что это хороший путь

Reset ★★★★★
() автор топика
Ответ на: комментарий от Xenius

Генерить любой asm тяжелее чем llvm ir так как надо делать аллокатор регистров и выбор инструкций

Reset ★★★★★
() автор топика

использовать Рисователь

алг

нач

  вещ

Кажется, хватит на сегодня интернета. Пойду спать.

Zhbert ★★★★★
()
Ответ на: комментарий от ya-betmen

какая-то не смишная шутка, что нормального в динамически типизированной эзотерической нечитаемой скриптухе и давно заслуженно мёртвой

zurg ★★
()
Ответ на: комментарий от zurg

Так ты сам написал критерии. Я просто подумал, что под них может подойти.

ya-betmen ★★★★★
()
Ответ на: комментарий от zurg

Обыватель не понял мощь перла, ему подавай что попроще

Reset ★★★★★
() автор топика
Ответ на: комментарий от dataman

Само получилось. Я считаю что это эпохальное изменение. Тем более я этим проектом с декабря не занимался :)

Reset ★★★★★
() автор топика
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)