54 lines
1.7 KiB
JavaScript
Raw Normal View History

// 表达式函数解析为突破小程序不支持js实现的折中方案
function evaluate(env, expr) {
const tokens = expr.split(/(?![^(]*\)),/); // 分割外层参数,忽略内层逗号
return tokens.map((token) => {
if (token.trim().startsWith('\'') && token.trim().endsWith('\'')) {
// 处理字符串字面量
return token.trim().slice(1, -1);
} else if (/^[0-9]+(\.[0-9]+)?$/.test(token.trim())) {
// 处理数字字面量
return parseFloat(token);
} else if (/^[A-Za-z_]\w*\(/.test(token.trim())) {
// 处理函数调用
const fnName = token.trim().substring(0, token.indexOf('('));
const args = token.trim().slice(token.indexOf('(') + 1, -1); // 提取参数部分
if (!(fnName in env)) {
throw new Error(`Function '${fnName}' is not defined`);
}
return env[fnName](...evaluate(env, args));
} else {
// 处理变量
if (!(token.trim() in env)) {
throw new Error(`Variable '${token.trim()}' is not defined`);
}
return env[token.trim()];
}
});
}
export function interpret(env, expression) {
if (!/^[A-Za-z_]\w*\(/.test(expression)) {
throw new Error('Expression must start with a function call');
}
const fnName = expression.substring(0, expression.indexOf('('));
const argsString = expression.substring(expression.indexOf('(') + 1, expression.lastIndexOf(')'));
if (!(fnName in env)) {
throw new Error(`函数 '${fnName}' 未定义`);
}
const args = evaluate(env, argsString);
try {
return env[fnName](...args);
} catch (e) {
throw new Error(`执行错误 '${fnName}': ${e.message}`);
}
}
export default {
interpret
}