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}`);
}
}