p5
Version:
[](https://www.npmjs.com/package/p5)
57 lines (47 loc) • 2.53 kB
JavaScript
import { extractNodeTypeInfo, propagateTypeToAssignOnUse, createNodeData, getOrCreateNode } from './ir_dag.js';
import { recordInBasicBlock } from './ir_cfg.js';
import { BaseType, OpCode, NodeType } from './ir_types.js';
import { c as createStrandsNode } from '../ir_builders-CMXkjMoV.js';
import { userError } from './strands_FES.js';
import './strands_builtins.js';
function buildTernary(strandsContext, condition, ifTrue, ifFalse) {
const { dag, cfg, p5 } = strandsContext;
// Ensure all inputs are StrandsNodes
const condNode = condition?.isStrandsNode ? condition : p5.strandsNode(condition);
const trueNode = ifTrue?.isStrandsNode ? ifTrue : p5.strandsNode(ifTrue);
const falseNode = ifFalse?.isStrandsNode ? ifFalse : p5.strandsNode(ifFalse);
// Get type info for both nodes
let trueType = extractNodeTypeInfo(dag, trueNode.id);
let falseType = extractNodeTypeInfo(dag, falseNode.id);
// Propagate type from the known branch to any ASSIGN_ON_USE branch
if (trueType.baseType === BaseType.ASSIGN_ON_USE && falseType.baseType !== BaseType.ASSIGN_ON_USE) {
propagateTypeToAssignOnUse(dag, trueNode.id, falseType.baseType, falseType.dimension);
trueType = extractNodeTypeInfo(dag, trueNode.id);
} else if (falseType.baseType === BaseType.ASSIGN_ON_USE && trueType.baseType !== BaseType.ASSIGN_ON_USE) {
propagateTypeToAssignOnUse(dag, falseNode.id, trueType.baseType, trueType.dimension);
falseType = extractNodeTypeInfo(dag, falseNode.id);
}
// After ASSIGN_ON_USE propagation, if both types are known, they must match
if (
trueType.baseType !== BaseType.ASSIGN_ON_USE &&
falseType.baseType !== BaseType.ASSIGN_ON_USE &&
(trueType.baseType !== falseType.baseType || trueType.dimension !== falseType.dimension)
) {
userError('type error',
'The true and false branches of a ternary expression must have the same type. ' +
`Right now, the true branch is a ${trueType.baseType}${trueType.dimension}, and the false branch is a ${falseType.baseType}${falseType.dimension}.`
);
}
const resultType = trueType;
const nodeData = createNodeData({
nodeType: NodeType.OPERATION,
opCode: OpCode.Nary.TERNARY,
dependsOn: [condNode.id, trueNode.id, falseNode.id],
baseType: resultType.baseType,
dimension: resultType.dimension,
});
const id = getOrCreateNode(dag, nodeData);
recordInBasicBlock(cfg, cfg.currentBlock, id);
return createStrandsNode(id, resultType.dimension, strandsContext);
}
export { buildTernary };