Как мне реализовать «else if» в веб-сборке? - PullRequest
2 голосов
/ 15 апреля 2020

Я строю проект, который использует ANTLR для анализа созданной мной грамматики пользовательского языка, и моя задача состоит в том, чтобы скомпилировать / перенести этот код в Web Assembly.

Это пример кода код, который я могу попытаться преобразовать с помощью программы:

if (<condition>) {
    <some code>
}
else if (<condition>) {
    <some code>
}
else {
    <some code>
}

Я не имею ни малейшего опыта работы с веб-сборкой, однако это требование для проекта. Кажется, операторы «если» и «еще» довольно прямолинейны, моя единственная проблема - это утверждение «еще, если».

Единственный способ, которым я могу подумать о его реализации, - это вставить все «еще, если» операторы в предложении «else» выбора над ним, так как, похоже, нет никакого синтаксиса веб-сборки для поддержки прямого оператора «else if».

Любой совет, который можно предложить, будет fantasti c, ура.

Ответы [ 2 ]

2 голосов
/ 15 апреля 2020

Единственный способ, которым я могу думать о его реализации, - это вложить все операторы «else if» в предложение «else» выбора над ним

Да, это вполне допустимый подход. Однако, кроме инструкций if и else, есть также опция для использования select, которая возвращает либо первое, либо второе операнд, основанный на условии.

Чтобы увидеть, как другие языки решают эту проблему, я бы порекомендовал иметь go с WebAssembly Studio .

Например, следующее Код ActionScript:

export function if_else_test(input: i32): i32 {
  if (input > 10) {
    return 101;
  } else if (input > 20) {
    return 102;
  } else {
    return 103;
  }
}

компилируется в следующее:

  (func $if_else_test (export "if_else_test") (type $t1) (param $p0 i32) (result i32)
    i32.const 101
    i32.const 102
    i32.const 103
    get_local $p0
    i32.const 20
    i32.gt_s
    select
    get_local $p0
    i32.const 10
    i32.gt_s
    select)

Приведенный выше код загружает в стек три различных возвращаемых значения, а затем использует пару операторов select для возврата правильное значение на основе двух условий if.

Несмотря на то, что logi c может быть проще следовать, если его переписать с использованием синтаксиса 'function call':

  (func $if_else_test (export "if_else_test") (type $t1) (param $p0 i32) (result i32)
    (select
      (i32.const 101)
      (select 
        (i32.const 102)
        (i32.const 103)
        (i32.gt_s
          (i32.const 20)
          (get_local $p0)
        )
      )
      (i32.gt_s
        (i32.const 10)
        (get_local $p0)
      )
    )
1 голос
/ 15 апреля 2020

Единственный способ реализовать это - вставить все операторы "else if" в предложение "else" выбора над ним

Да, именно так Вы делаете это.

PS: Вам может быть интересно узнать, что многие языки на самом деле не имеют выделенного синтаксиса else-if. Например, в C и многих его потомках синтаксис операторов if выглядит следующим образом:

statement: 'if' '(' expression ')' statement ('else' statement)?

Таким образом, else if - это просто else, за которым следует оператор if. Так что даже на синтаксическом уровне во многих языках else if - это просто оператор if внутри ветви else.

Поскольку ваш синтаксис выглядит аналогично, вы, вероятно, могли бы также написать свою грамматику таким образом, так что вы бы не стали не нужно ничего делать для поддержки else if s.

...