UNPKG

mlld

Version:

mlld: a modular prompt scripting language

311 lines (309 loc) 9.37 kB
import { evaluate } from './chunk-FYMHT7UG.mjs'; import { isTextLike, isArray, isObject, isCommandResult, isPipelineInput } from './chunk-V5L6FBQT.mjs'; import { __name } from './chunk-OMKLS24H.mjs'; // interpreter/eval/expression.ts function isTruthy(value) { if (value && typeof value === "object" && "type" in value && "name" in value) { const variable = value; if (isTextLike(variable)) { const str = variable.value; if (str === "" || str.toLowerCase() === "false" || str === "0") { return false; } return true; } else if (isArray(variable)) { return variable.value.length > 0; } else if (isObject(variable)) { return Object.keys(variable.value).length > 0; } else if (isCommandResult(variable)) { return variable.value.trim().length > 0; } else if (isPipelineInput(variable)) { return variable.value.text.length > 0; } return isTruthy(variable.value); } if (value === null || value === void 0) { return false; } if (typeof value === "boolean") { return value; } if (typeof value === "number") { return value !== 0 && !isNaN(value); } if (typeof value === "string") { if (value === "*") { return true; } if (value === "") { return false; } if (value.toLowerCase() === "false") { return false; } if (value === "0") { return false; } return true; } if (Array.isArray(value)) { return value.length > 0; } if (typeof value === "object") { return Object.keys(value).length > 0; } return !!value; } __name(isTruthy, "isTruthy"); async function evaluateExpression(node, env, context) { if (process.env.MLLD_DEBUG === "true") { console.log("[DEBUG] evaluateExpression called with node type:", node.type); if (node.type === "BinaryExpression") { console.log("[DEBUG] Binary operator:", node.operator); } } if (node.type === "BinaryExpression") { return evaluateBinaryExpression(node, env, context); } else if (node.type === "TernaryExpression") { return evaluateTernaryExpression(node, env, context); } else if (node.type === "UnaryExpression") { return evaluateUnaryExpression(node, env, context); } throw new Error(`Unknown expression type: ${node.type}`); } __name(evaluateExpression, "evaluateExpression"); async function evaluateBinaryExpression(node, env, context) { let { operator, left, right } = node; if (Array.isArray(operator)) { operator = operator[0]; } if (process.env.MLLD_DEBUG === "true") { console.log("[DEBUG] evaluateBinaryExpression called with operator:", operator); console.log("[DEBUG] evaluateBinaryExpression:", { operator, leftType: left.type, rightType: right.type, left: left.type === "VariableReference" ? left.identifier : left, right: right.type === "VariableReference" ? right.identifier : right }); } const expressionContext = { isExpression: true, ...context }; if (operator === "&&") { const leftResult2 = await evaluate(left, env, expressionContext); const leftTruthy = isTruthy(leftResult2.value); if (!leftTruthy) { return { value: leftResult2.value, env }; } const rightResult2 = await evaluate(right, env, expressionContext); return { value: rightResult2.value, env }; } if (operator === "||") { const leftResult2 = await evaluate(left, env, expressionContext); const leftTruthy = isTruthy(leftResult2.value); if (process.env.MLLD_DEBUG === "true") { console.log("[DEBUG] || operator left side:", { left: leftResult2.value, leftTruthy, leftType: typeof leftResult2.value, isVariable: leftResult2.value && typeof leftResult2.value === "object" && "type" in leftResult2.value }); } if (leftTruthy) { return { value: leftResult2.value, env }; } const rightResult2 = await evaluate(right, env, expressionContext); if (process.env.MLLD_DEBUG === "true") { console.log("[DEBUG] || operator right side:", { right: rightResult2.value, rightTruthy: isTruthy(rightResult2.value) }); } return { value: rightResult2.value, env }; } const leftResult = await evaluate(left, env, expressionContext); const rightResult = await evaluate(right, env, expressionContext); if (process.env.MLLD_DEBUG === "true") { console.log("[DEBUG] Evaluated operands:", { leftResult: leftResult.value, rightResult: rightResult.value, leftIsVariable: leftResult.value && typeof leftResult.value === "object" && "type" in leftResult.value, rightIsVariable: rightResult.value && typeof rightResult.value === "object" && "type" in rightResult.value }); } if (operator === "==") { const equal = isEqual(leftResult.value, rightResult.value); if (process.env.MLLD_DEBUG === "true") { console.log("[DEBUG] == comparison:", { left: leftResult.value, leftType: typeof leftResult.value, right: rightResult.value, rightType: typeof rightResult.value, equal }); } return { value: equal, env }; } if (operator === "!=") { const equal = isEqual(leftResult.value, rightResult.value); return { value: !equal, env }; } if (operator === "<") { const leftNum = toNumber(leftResult.value); const rightNum = toNumber(rightResult.value); console.log("[DEBUG] < comparison:", leftResult.value, "<", rightResult.value, "=", leftNum < rightNum); return { value: leftNum < rightNum, env }; } if (operator === ">") { const leftNum = toNumber(leftResult.value); const rightNum = toNumber(rightResult.value); return { value: leftNum > rightNum, env }; } if (operator === "<=") { const leftNum = toNumber(leftResult.value); const rightNum = toNumber(rightResult.value); return { value: leftNum <= rightNum, env }; } if (operator === ">=") { const leftNum = toNumber(leftResult.value); const rightNum = toNumber(rightResult.value); return { value: leftNum >= rightNum, env }; } throw new Error(`Unknown binary operator: ${operator}`); } __name(evaluateBinaryExpression, "evaluateBinaryExpression"); async function evaluateTernaryExpression(node, env, context) { const { condition, trueBranch, falseBranch } = node; const condResult = await evaluate(condition, env, { isExpression: true, ...context }); const condTruthy = isTruthy(condResult.value); if (condTruthy) { return evaluate(trueBranch, env, { isExpression: true, ...context }); } else { return evaluate(falseBranch, env, { isExpression: true, ...context }); } } __name(evaluateTernaryExpression, "evaluateTernaryExpression"); async function evaluateUnaryExpression(node, env, context) { const { operator, operand } = node; if (operator === "!") { const operandResult = await evaluate(operand, env, { isExpression: true, ...context }); const operandTruthy = isTruthy(operandResult.value); return { value: !operandTruthy, env }; } throw new Error(`Unknown unary operator: ${operator}`); } __name(evaluateUnaryExpression, "evaluateUnaryExpression"); function isEqual(a, b) { const aValue = extractValue(a); const bValue = extractValue(b); if (aValue === null || aValue === void 0) { return bValue === null || bValue === void 0; } if (bValue === null || bValue === void 0) { return false; } if (typeof aValue === "string" && typeof bValue === "boolean") { return aValue === "true" && bValue === true || aValue === "false" && bValue === false; } if (typeof bValue === "string" && typeof aValue === "boolean") { return bValue === "true" && aValue === true || bValue === "false" && aValue === false; } if (typeof aValue === "string" && typeof bValue === "number") { const numA = Number(aValue); return !isNaN(numA) && numA === bValue; } if (typeof bValue === "string" && typeof aValue === "number") { const numB = Number(bValue); return !isNaN(numB) && numB === aValue; } return aValue === bValue; } __name(isEqual, "isEqual"); function extractValue(value) { if (value && typeof value === "object" && "type" in value && "value" in value) { const variable = value; return variable.value; } return value; } __name(extractValue, "extractValue"); function toNumber(value) { if (value && typeof value === "object" && "type" in value && "value" in value) { const variable = value; return toNumber(variable.value); } if (value === null) { return 0; } if (value === void 0) { return NaN; } if (typeof value === "boolean") { return value ? 1 : 0; } if (typeof value === "number") { return value; } if (typeof value === "string") { if (value === "true") { return 1; } if (value === "false") { return 0; } const num = Number(value); return num; } return NaN; } __name(toNumber, "toNumber"); export { evaluateExpression, isEqual, isTruthy, toNumber }; //# sourceMappingURL=expression-CKCH5HUL.mjs.map //# sourceMappingURL=expression-CKCH5HUL.mjs.map