Scala.js Компиляция времени выполнения в Javascript

Всем привет. Я хочу выяснить, как использовать инструменты Scala.js для компиляции выражений Scala в Javascript во время выполнения. Вот упрощенная настройка, в качестве примера.

Скажем, у нас есть простой DSL, который состоит из Ctx => Boolean функции и логические операции над ними, а-ля следующие:

implicit class Simple[Ctx](f: Ctx => Boolean) {
  def &&(g: Ctx => Boolean): Ctx => Boolean = ctx => f(ctx) && g(ctx)
  def ||(g: Ctx => Boolean): Ctx => Boolean = ctx => f(ctx) || g(ctx)
  def unary_!: Ctx => Boolean = ctx => !f(ctx)
}

И давайте предположим, что у нас есть некоторые "строительные блоки", жестко запрограммированные, скомпилированные в Javascript и экспортированные следующим образом:

@ExportJSTopLevel("foo") def foo[Ctx](ctx: Ctx): Boolean = ???
@ExportJSTopLevel("bar") def bar[Ctx](ctx: Ctx): Boolean = ???
// and so on

Теперь из этих строительных блоков можно собрать простые логические выражения, такие как: foo && bar или же foo || !bar, так далее.

Допустим, некоторые постоянные сущности создаются во время выполнения с такими выражениями, как их тела. Я хочу иметь возможность скомпилировать их в Javascript, как функции с той же сигнатурой, что и у строительных блоков выше, которые вызывают эти строительные блоки.

Я нашел несколько ссылок в Интернете на таинственный класс под названием ScalaJSOptimizer где-то в инструментах Scala.js. Однако ссылки на этот класс всегда не работают или показывают, что он принадлежит пакету, которого даже в последней версии артефакта "scalajs-tools" нет.

Каков наилучший способ выполнить то, что я хочу сделать?

3 ответа

Решение

То, что вы пытаетесь сделать, возможно, и было тщательно исследовано на многих языках (глубокое встраивание DSL). Чтобы достичь того, чего вы хотите, вы должны:

  1. Найдите или создайте глубокую структуру встраивания в Scala, которая может выводить JavaScript.
  2. Убедитесь, что фреймворк компилируется с Scala.js.
  3. Создайте свой DSL, используя эту платформу.

Я знаю, что вы могли бы использовать следующие фреймворки:

  1. DB Lab: я не думаю, что у него есть бэкэнд JS, но его можно добавить для ваших нужд.
  2. LMS: имеет бэкэнд JS, однако вы должны использовать Rep введите ваши DSL.

Вам следует проверить у авторов, компилируются ли эти фреймворки с Scala.js и каково состояние их бэкэндов JS.

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

Я также не знаю, какова ваша конечная цель, но если вы действительно-действительно хотите скомпилировать Scala.js во время выполнения, вам лучше всего посмотреть на исходный код scalafiddle.io, который делает именно это, и начать с копирования что бы он ни делал, и меняя его оттуда.

Вот код, который касается компиляции из Javascript в IR Scala.js, а затем из IR в Javascript String:

Интересные методы здесь compile, link (fastOptJS а также fullOptJS), а также export, Я знаю, что Stackru препятствует внешним ссылкам, но код действительно слишком большой и грубый, чтобы его можно было воспроизводить здесь. Лучше всего клонировать этот репо, открыть его в вашей IDE и посмотреть, как код преобразует Scala.js. code: String приходит в конструкторе этого Compiler класс, через все промежуточные шаги, до окончательного Javascript String возвращается из export метод

Честно говоря, я думаю, что создание его как "компиляция выражений Scala в Javascript во время выполнения" создает рецепт для отказа. Scala.js не может скомпилировать Scala и, вероятно, не сможет сделать это в ближайшем будущем - слишком большая часть инфраструктуры компилятора ориентирована на JVM.

Поэтому вместо этого я бы рекомендовал переосмыслить проблему. Формально определите язык, с которым вы хотите работать во время выполнения. (Что вполне может быть подмножеством Scala.) Используйте синтаксический анализатор Scala.js, такой как FastParse, чтобы написать для него синтаксический анализатор, который генерирует абстрактное синтаксическое слово, и интерпретатор, который превращает эти синтаксические деревья в JavaScript.

Да, это немного усилий. Но это достижимо, что попытка скомпилировать произвольный Scala для JavaScript во время выполнения, в Scala.js, не...

Другие вопросы по тегам