export function registerControlFunctions()

in packages/sqrl/src/function/ControlFunctions.ts [18:131]


export function registerControlFunctions(instance: StdlibRegistry) {
  instance.save(null, {
    name: "if",
    allowNull: true,
    transformAst(state: SqrlParserState, ast: CallAst): Ast {
      sqrlInvariant(
        ast,
        ast.args.length === 2 || ast.args.length === 3,
        "if() requires a condition, value and optional else value"
      );

      const elseValue = ast.args[2] || SqrlAst.constant(null);
      return SqrlAst.branch(ast.args[0], ast.args[1], elseValue);
    },
    argstring: "condition, true_result, false_result",
    docstring:
      "Returns either the true_result or false_result based on the condition",
  });

  instance.save(
    function ifNull(test, valueIfNull) {
      if (test === null) {
        return valueIfNull;
      } else {
        return test;
      }
    },
    {
      allowSqrlObjects: true,
      allowNull: true,
      args: [AT.any, AT.any],
      pure: true,
      argstring: "value, valueIfNull",
      docstring: "Returns the value, or valueIfNull if it is null",
    }
  );

  instance.save(null, {
    name: INPUT_FUNCTION,
    transformAst(state, ast: CallAst) {
      throw new Error(
        "This is a language feature, should not be called in runtime"
      );
    },
    argstring: "",
    docstring: "Sets the given feature as an input value",
  });

  instance.save(function _slotWait() {
    throw new Error("This function is a language builtin");
  });

  instance.save(null, {
    name: "wait",
    transformAst(state, ast: CallAst): CallAst {
      return SqrlAst.call(
        "_slotWait",
        ast.args.map((arg) => {
          if (arg.type !== "feature") {
            throw buildSqrlError(arg, "wait only allows features as arguments");
          }
          return SqrlAst.slotName(arg.value);
        })
      );
    },
    argstring: "feature[, ...]",
    docstring:
      "Function that returns once all of the input features have been calculated",
  });

  instance.save(
    async function _listComprehension(
      state,
      iterator,
      outputFn,
      whereFn,
      values
    ) {
      if (values === null) {
        return null;
      }
      invariant(
        Array.isArray(values),
        "Invalid values for list comprehension."
      );

      let promise;
      if (whereFn === true) {
        promise = Promise.all(
          values.map((value) => outputFn.call(state, value))
        );
      } else {
        promise = Promise.all(
          values.map((value) => {
            return whereFn.call(state, value).then((filterResult) => {
              return SqrlObject.isTruthy(filterResult)
                ? outputFn.call(state, value)
                : null;
            });
          })
        );
      }

      const rv = await promise;
      return rv.filter((v) => v !== null);
    },
    {
      allowNull: true,
      allowSqrlObjects: true,
      args: [AT.state, AT.any, AT.any, AT.any],
      async: true,
    }
  );
}