54 lines
1.7 KiB
JavaScript
54 lines
1.7 KiB
JavaScript
// 表达式函数解析,为突破小程序不支持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
|
||
} |