export function labelerPushStatement()

in packages/sqrl/src/compile/compileLabelerStatements.ts [34:127]


export function labelerPushStatement(
  parserState: SqrlParserState,
  ast: Ast
): void {
  const instance = parserState.instance;

  sqrlInvariant(
    ast,
    ast.type !== "execute",
    "Execute statement is only valid in sqrl tests"
  );

  if (ast.type === "constant" && ast.value === null) {
    return;
  } else if (ast.type === "include") {
    const includeFiles = parserState.importer.getIncludeFiles(ast);

    parserState.usedFiles.add(ast.filename);

    parserState.wrapWhere(ast.where, () => {
      for (const includeFile of includeFiles) {
        parserState.wrapWhere(includeFile.where, () => {
          pushFile(parserState, includeFile.ast);
        });
      }
    });
  } else if (ast.type === "assert") {
    sqrlInvariant(
      ast,
      parserState.allowAssertions,
      "Assertions are only valid in sqrl tests"
    );
    parserState.pushStatement({
      type: "call",
      func: "assert",
      args: [ast.expr],
      location: ast.location,
    });
  } else if (ast.type === "if") {
    let resultAst: Ast = ast;
    let conditionAst: Ast = SqrlAst.constant(true);

    while (resultAst.type === "if") {
      sqrlInvariant(
        resultAst,
        SqrlAst.isConstantNull(resultAst.falseBranch),
        "`if` statements cannot contain a false branch"
      );
      conditionAst = SqrlAst.and(conditionAst, resultAst.condition);
      resultAst = resultAst.trueBranch;
    }

    if (resultAst.type !== "call") {
      throw buildSqrlError(ast, "`if` statement true branch must be a `call`");
    }

    const func = resultAst.func;
    sqrlInvariant(
      ast,
      instance.isStatement(func),
      `Function '${func}' was not registered as a statement`
    );

    const statementFeature = instance.statementFeature(func);
    const registeredCall = SqrlAst.registerCall(resultAst);
    parserState.addStatement(
      ast,
      statementFeature,
      SqrlAst.branch(conditionAst, registeredCall)
    );
  } else if (ast.type === "call") {
    parserState.addCallStatement(ast, ast);
  } else if (ast.type === "listComprehension") {
    instance.assertStatementAst(ast.output);
    const funcAst = ast.output;
    const newAst = Object.assign({}, ast, {
      output: SqrlAst.registerCall(ast.output),
    });

    if (funcAst.type !== "call") {
      throw buildSqrlError(
        funcAst,
        "List comprehension statement must be a function"
      );
    }

    const statementFeature = instance.statementFeature(funcAst.func);
    parserState.addStatement(ast, statementFeature, newAst);
  } else if (ast.type === "when") {
    compileWhenBlock(parserState, ast);
  } else {
    sqrlInvariant(ast, false, `Unhandled ast type:: ${ast.type}`);
  }
}