{
var elements = new Array();
for (var i = 0; i < code.length; i++)
{
code[i] = run(code[i]); //递归向下读取
if(code[i] instanceof Function) //解析表达式
{
if(code[i].length <= 0) //无参函数可省略[]直接以函数名称调用
{
code[i] = code[i].call(null);
}
else if(i == 0) //调用带参数的函数[funcall,args...]
{
return code[i].apply(null, code.slice(1));
}
}
}
return code;
}
return Element(code);
};
})();
function Assert(msg, cond)
{
if(cond)
return true;
else
{
alert(msg);
throw new Error(msg);
}
};
function Element(arg)
{
if(arg == null)
return [];
else if(arg instanceof Function && arg.length <= 0)
return arg.call(null);
else
return arg;
};
__funList = new Array();
以上这段简简单单不过数十行的javascript代码由三个辅助函数、一个主体对象、一个常量NIL(后面我们会知道它表示一个空表或者逻辑false),以及一个存放函数名称的堆栈组成。
LispScript静态对象构成了LispScript解析器的主体,它只有一个Run方法,该方法用向下递归的方式解析传递进来的LispScript代码,代码的类型——相信细心的读者已经发现了——直接用的是javascript的数组,也就是一系列“[”、“]”和分隔符“,”构成的序列。
用javascript天然的数组特性,使得我们的解析器可以设计得十分简洁——不用去拆分和解析每一个token,于是一段简短到不到50行的代码惊人地实现了整个LispScript解析器的核心!
三个辅助函数的作用分别是为函数迭代提供解析(toEvalString),检测序列异常(Assert,后面的具体实现中其实并没有用到),以及解析指令单词(Element)
接下来我们先定义表达式.表达式或是一个原子[atom],它是一个字母序列(如 foo),或是一个由零个或多个表达式组成的表(list), 表达式之间用逗号分开, 放入一对中括号中. 以下是一些表达式:
(注:原Lisp语法的表达式用空格隔开,放入一对括号中。因是javascript的实现,所以用中括号和逗号较为简洁)










