After posting the blog post, I spent some time trying to solve this problem... After a few attempts, I found another pattern where the brackets are no longer necessary:
eval(function () {
var s = '', ww = [v] > ; (s = v);
var ws = [n] > ww('
(' n ') ');
pnView3(14 , [n] > ww(' [' n '] '),
1, 37,
ws, [] > ww(' ... '),
2, 1
);
document.write(s);
} .lamda0());
However, due to the relationship between operator precedence, comparison, gate, assignment and other operators Still can't be written directly in a (pseudo) Lambda expression.
That is to say
function(a, b) { a == b }
still needs to be written as
[a, b] > (a == b)
In addition, the selected pattern itself has practical effects - when combining an array with another thing When comparing, the script engine will first try to convert both sides into numerical values. If unsuccessful, it will convert them into strings and then compare.
But I think under normal circumstances very few people would compare arrays with other things like this - so you don’t even need to actively avoid it, as long as you don’t deliberately use it like this when you don’t need (pseudo) Lambda expressions. No problem anymore.
The new implementation code is as follows:
/*!
L-amda "a-Lambda", a module provides Alternate "Lambda" style programming ability for JavaScript.
Created By NanaLich. 2010-09-10
This module is published under WTFPL v2, so you just DO WHAT THE Fxxx YOU WANT TO with it.
*/
!function () {
function attachEntry(o, a, m) {
var i, j, n;
o = [].concat(o);
while (i = o.shift()) {
for (j in a) {
if (!i[n = a[j]]) i[n] = m;
}
}
}
var xx = /"(?:\[sS]|[^x22])*"|'(?:\[sS]|[^x27])*'|([^sw]s*)[(s*|s*[A-Z$_][w$]*s*(?:,s*[A-Z$_][w$]*s*)*)]s*(>)s*((?)/gi;
var xy = /[nr),;]}]|$/.source;
function rxClone(rx) {
return new RegExp(rx.source, (rx.global ? 'g' : '') (rx.ignoreCase ? 'i' : '') (rx.multiline ? 'm' : ''));
}
attachEntry(RegExp, ['clone'], rxClone);
attachEntry(RegExp.prototype, ['clone'], function () { return rxClone(this); });
function translateLambda(s) {
var m, l = 0, r = '', x = xx.clone(); // 由于firefox、safari等浏览器对全局匹配正则表达式有过度的优化,所以这里采用一种迂回的办法创建不重复的正则表达式实例
while (m = x.exec(s)) {
var h = m[0];
switch (h.charAt(0)) { // 判断期待的语法成分
case '$': // 函数传参
case ')':
case ']':
case '"': // 匹配到了字符串
case "'":
continue; // 以上皆跳过
}
var p, q, t, k = m[4].length, y = new RegExp(k ? '\)' : xy, 'g');
r = s.substring(l, p = m.index); // 在结果字符串上附加之前余留的内容
y.lastIndex = l = p h.length; // 从伪运算符之后开始寻找右括号或者其它符号
while (q = y.exec(s)) {
q = q.index;
try {
t = 'return(' s.substring(l, q) ');';
new Function(t); // 语法测试
r = m[1] 'function(' m[2] '){ ' translateLambda(t) ' }'; // 翻译里面的内容
x.lastIndex = l = q k; // 下一次查找从当前边界之后开始
break;
} catch (ex) { }
}
if (!q) l = p; // 说明找不到右括号或者有效的代码,直接附加所有匹配的内容
}
try {
r = s.substr(l);
new Function(r); // 语法测试
return r;
} catch (ex) { // 失败,返回原文
return s;
}
};
var lamdaAliases = ["translateLambda", "lambda", "lamda"];
attachEntry(String, lamdaAliases, translateLambda);
attachEntry(String.prototype, lamdaAliases, function () { return translateLambda(this); });
var funPrototype = Function.prototype;
attachEntry(Function, lamdaAliases, function (func) { return translateLambda('0,' func); });
attachEntry(funPrototype, lamdaAliases, function () { return translateLambda('0,' this); });
var lamda0aliases = ['lambdaInit', 'lambda0', 'lamda0'];
attachEntry(Function, lamda0aliases, function (func) { return translateLambda('!' func '()'); });
attachEntry(funPrototype, lamda0aliases, function () { return translateLambda('!' this '()'); });
} ();
这次为函数增加了专门的方法,去掉了之前蹩足的判断、也增加了新方法稍微简化调用过程;
修正了有额外空格时无法判断期望语法成分的BUG。
另外由于Codeplex再次抽疯,这次还是没有下载。