UNPKG

mlld

Version:

mlld: llm scripting language

185 lines (183 loc) 6.52 kB
import { isTruthy, toNumber, isEqual } from './chunk-6FAJL6ND.mjs'; import { evaluate } from './chunk-6SG7EQJL.mjs'; import { MlldDirectiveError } from './chunk-YVSXROKS.mjs'; import { __name } from './chunk-NJQWMXLH.mjs'; // interpreter/eval/expressions.ts async function evaluateUnifiedExpression(node, env) { try { switch (node.type) { case "BinaryExpression": return await evaluateBinaryExpression(node, env); case "UnaryExpression": return await evaluateUnaryExpression(node, env); case "TernaryExpression": return await evaluateTernaryExpression(node, env); case "ArrayFilterExpression": return await evaluateArrayFilterExpression(node, env); case "ArraySliceExpression": return await evaluateArraySliceExpression(node, env); case "Literal": if (node.valueType === "none") { throw new Error('The "none" keyword can only be used as a condition in /when directives'); } return node.value; case "VariableReference": try { const varResult = await evaluate(node, env); return varResult.value; } catch (error) { if (error.message && error.message.includes("Variable not found")) { return void 0; } throw error; } case "ExecReference": const execResult = await evaluate(node, env); return execResult.value; case "Text": return node.content; default: const result = await evaluate(node, env); return result.value; } } catch (error) { throw new MlldDirectiveError( `Expression evaluation failed: ${error instanceof Error ? error.message : String(error)}`, "expression", { location: node?.location, cause: error, context: { nodeType: node?.type, operator: node?.operator }, env } ); } } __name(evaluateUnifiedExpression, "evaluateUnifiedExpression"); async function evaluateBinaryExpression(node, env) { let { operator } = node; if (Array.isArray(operator)) { operator = operator[0]; } const leftResult = await evaluateUnifiedExpression(node.left, env); if (operator === "&&") { const leftTruthy = isTruthy(leftResult); if (!leftTruthy) { return leftResult; } const rightResult2 = await evaluateUnifiedExpression(node.right, env); return rightResult2; } if (operator === "||") { const leftTruthy = isTruthy(leftResult); if (leftTruthy) { return leftResult; } const rightResult2 = await evaluateUnifiedExpression(node.right, env); return rightResult2; } const rightResult = await evaluateUnifiedExpression(node.right, env); switch (operator) { case "==": const equal = isEqual(leftResult, rightResult); return equal; case "!=": return !isEqual(leftResult, rightResult); case "~=": const regex = new RegExp(String(rightResult)); return regex.test(String(leftResult)); case "<": const leftNum = toNumber(leftResult); const rightNum = toNumber(rightResult); const ltResult = leftNum < rightNum; return ltResult; case ">": return toNumber(leftResult) > toNumber(rightResult); case "<=": return toNumber(leftResult) <= toNumber(rightResult); case ">=": return toNumber(leftResult) >= toNumber(rightResult); case "+": return toNumber(leftResult) + toNumber(rightResult); case "-": return toNumber(leftResult) - toNumber(rightResult); case "*": return toNumber(leftResult) * toNumber(rightResult); case "/": return toNumber(leftResult) / toNumber(rightResult); case "%": return toNumber(leftResult) % toNumber(rightResult); default: throw new Error(`Unknown binary operator: ${operator}`); } } __name(evaluateBinaryExpression, "evaluateBinaryExpression"); async function evaluateUnaryExpression(node, env) { const operandResult = await evaluateUnifiedExpression(node.operand, env); switch (node.operator) { case "!": return !isTruthy(operandResult); case "-": return -toNumber(operandResult); case "+": return +toNumber(operandResult); default: throw new Error(`Unknown unary operator: ${node.operator}`); } } __name(evaluateUnaryExpression, "evaluateUnaryExpression"); async function evaluateTernaryExpression(node, env) { const conditionResult = await evaluateUnifiedExpression(node.condition, env); return isTruthy(conditionResult) ? await evaluateUnifiedExpression(node.trueBranch, env) : await evaluateUnifiedExpression(node.falseBranch, env); } __name(evaluateTernaryExpression, "evaluateTernaryExpression"); async function evaluateArrayFilterExpression(node, env) { const array = await evaluateUnifiedExpression(node.array, env); if (!Array.isArray(array)) { throw new Error(`Cannot filter non-array value: ${typeof array}`); } const results = []; for (const item of array) { const itemEnv = env.withVariable("$", item); const passes = await evaluateUnifiedExpression(node.filter, itemEnv); if (passes) { results.push(item); } } return results; } __name(evaluateArrayFilterExpression, "evaluateArrayFilterExpression"); async function evaluateArraySliceExpression(node, env) { const array = await evaluateUnifiedExpression(node.array, env); if (!Array.isArray(array)) { throw new Error(`Cannot slice non-array value: ${typeof array}`); } const start = node.start || 0; const end = node.end !== void 0 ? node.end : array.length; return array.slice(start, end); } __name(evaluateArraySliceExpression, "evaluateArraySliceExpression"); function isUnifiedExpressionNode(node) { return node && [ "BinaryExpression", "UnaryExpression", "TernaryExpression", "ArrayFilterExpression", "ArraySliceExpression", "Literal" ].includes(node.type); } __name(isUnifiedExpressionNode, "isUnifiedExpressionNode"); async function evaluateArrayFilter(array, filter, env) { const results = []; for (const item of array) { const itemEnv = env.withVariable("$", item); const passes = await evaluateUnifiedExpression(filter, itemEnv); if (passes) results.push(item); } return results; } __name(evaluateArrayFilter, "evaluateArrayFilter"); export { evaluateArrayFilter, evaluateUnifiedExpression, isUnifiedExpressionNode }; //# sourceMappingURL=expressions-FPH3NB7C.mjs.map //# sourceMappingURL=expressions-FPH3NB7C.mjs.map