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)
Ответ на: комментарий от Xenius

Не будет. Там вместо функций заглушки стоят. Вот runtime https://github.com/resetius/qumir/tree/master/qumir/runtime Надо для настоящей графики ставить реальные вызовы. Кстати сейчас это будет сделать довольно просто так как весь графический рантайм асинхронный и он легко встроится в eventloop gtk или qt

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

Это должно делаться само. В llvm есть такая оптимизация, но там должен выполняться набор условий которым должна соответствовать функция, то есть надо codegen править по любому.

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

Кстати на сайте pykumir некоторые программы исполняются на моем движке, по поведению версия от января этого года. Там похоже роутинг по движкам сделан в зависимости от того какие исполнители используются. Автор сайта со мной не связывался для того чтобы нормально интеграцию сделать.

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

Странно. Но вообще ты не думаешь доработать ЯП до возможности применения в качестве полноценного заменителя паскаля и C для простеньких программок? Надо сделать возможность доставать параметры из командной строки, раздельно вывод на stdout и stderr ну и всё такое прочее. Не так уж и много, как я понимаю. А поскольку виджеты тебе не нужны вроде, наверное SDL будет самое кроссплатформенное. Qt и Gtk жирные и тяжелые. Может Tk прикрутить, если SDL не хочешь?

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

Я сейчас ядром занимаюсь. Поддержкой контейнеров. Хэш мапы независимые от типов и прочее. Оно в закрытой репе пока. Еще в планах compile-time трансформации. Очень нужно для генерации hash комбайнеров. Но это вряд ли доедет до кумир-представления.

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