極致之美——百行代碼實(shí)現(xiàn)全新智能語言第5/6頁
更新時(shí)間:2007年03月14日 00:00:00 作者:
復(fù)制代碼 代碼如下:
為了學(xué)習(xí),測(cè)試上面的ListScript,我寫了一個(gè)命令環(huán)境
<script>
NIL = [];
Array.prototype.toEvalString = function()
{
if(this.length <= 0) return "NIL";
var str = "";
for (var i = 0; i < this.length; i++)
{
if(this instanceof Array)
str += "," + this.toEvalString();
else str += "," + this;
}
return "[" + str.slice(1) + "]";
};
(function(){
LispScript = {
Run : run
};
function run(code)
{
if(code instanceof Array)
{
var elements = new Array();
for (var i = 0; i < code.length; i++)
{
code = run(code); //遞歸向下讀取
if(code instanceof Function) //解析表達(dá)式
{
if(code.length <= 0) //無參函數(shù)可省略[]直接以函數(shù)名稱調(diào)用
{
code = code.call(null);
}
else if(i == 0) //調(diào)用帶參數(shù)的函數(shù)[funcall,args...]
{
return code.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();
/////////////////
quote = _ = function(args)
{
if(arguments.length < 1)
return [];
else if(arguments.length >= 1)
{
return arguments[0];
}
};
//[atom,x]返回原子true如果x的值是一個(gè)原子或是空表,否則返回[]. 在Lisp中我們按慣例用原子true表示真, 而用空表表示假.
atom = function(arg)
{
var tmp = LispScript.Run(arg); //先對(duì)參數(shù)求值
if(!(tmp instanceof Array) || tmp.length <= 0)
return true;
else
return [];
};
//[eq,x,y]返回t如果x和y的值是同一個(gè)原子或都是空表, 否則返回[].
equal = eq = function(arg1, arg2)
{
var tmp1 = LispScript.Run(arg1);
var tmp2 = LispScript.Run(arg2); //先對(duì)參數(shù)求值
if(!(tmp1 instanceof Array) && !(tmp2 instanceof Array) &&
tmp1.toString() == tmp2.toString() ||
(tmp1 instanceof Function) && (tmp2 instanceof Function) && tmp1.toString() == tmp2.toString() ||
(tmp1 instanceof Array) && (tmp2 instanceof Array) && (tmp1.length == 0) && (tmp2.length == 0))
return true;
else
return [];
};
//[car,x]期望x的值是一個(gè)表并且返回x的第一個(gè)元素.
car = function(arg)
{
var tmp = LispScript.Run(arg); //先對(duì)參數(shù)求值
if(tmp instanceof Array && tmp.length > 0)
return tmp[0];
else
return [];
};
//[cdr,x]期望x的值是一個(gè)表并且返回x的第一個(gè)元素之后的所有元素.
cdr = function(arg)
{
var tmp = LispScript.Run(arg); //先對(duì)參數(shù)求值
if(tmp instanceof Array && tmp.length > 0)
return tmp.slice(1);
else
return [];
};
//[cons,x,y]期望y的值是一個(gè)表并且返回一個(gè)新表,它的第一個(gè)元素是x的值, 后面跟著y的值的各個(gè)元素.
cons = function(arg1, arg2)
{
var tmp1 = LispScript.Run(arg1);
var tmp2 = LispScript.Run(arg2); //先對(duì)參數(shù)求值
if(tmp2 instanceof Array)
{
var list = new Array();
list.push(tmp1);
return list.concat(tmp2);
}
else
return [];
};
/*
[cond [...] ...[...]] 的求值規(guī)則如下. p表達(dá)式依次求值直到有一個(gè)返回t. 如果能找到這樣的p表達(dá)式,相應(yīng)的e表達(dá)式的值作為整個(gè)cond表達(dá)式的返回值.
*/
cond = function(args)
{
for (var i = 0; i < arguments.length; i++)
{
if(arguments instanceof Array)
{
var cond = LispScript.Run(arguments[0]); //先對(duì)參數(shù)求值
//alert(cond);
if(cond == true && arguments[1] != null)
return LispScript.Run(arguments[1]);
}
}
return [];
};
//則稱為函數(shù)調(diào)用.它的值計(jì)算如下.每一個(gè)表達(dá)式先求值,然后e再求值.在e的求值過程中,每個(gè)出現(xiàn)在e中的的值是相應(yīng)的在最近一次的函數(shù)調(diào)用中的值.
lambda = function(args, code)
{
if(code instanceof Array)
{
var fun = new Function(args,
"for(var i = 0; i < arguments.length; i++) arguments = LispScript.Run(arguments);return LispScript.Run("+code.toEvalString()+");");
var globalFuncName = __funList.pop();
fun._funName = globalFuncName;
if(globalFuncName != null)
self[globalFuncName] = fun;
return fun;
}
return [];
};
</script>
<script>
var prompt = '>';
function initPrompt()
{
if(cmd.value == '')
cmd.value = prompt;
}
function runLastCmd()
{
if(window.event.keyCode == 13)
{
window.event.returnValue = false;
var idx = cmd.value.lastIndexOf('\n') + 1;
idx += prompt.length;
var strCmd = cmd.value.substr(idx);
var output = '';
try
{
var lisp = eval(strCmd);
if(lisp instanceof Array)
{
output = LispScript.Run(lisp);
}
else
{
output = '未知命令';
}
}
catch(e)
{
output = '語法錯(cuò)誤';
}
if(output instanceof Array)
{
output = '[' + output + ']';
}
cmd.value += '\n' + output + '\n' + prompt;
}
}
</script>
<textarea id=cmd style="width:600px;height:600px" onkeydown="runLastCmd()" onclick="initPrompt()">
</textarea>
相關(guān)文章
微信小程序的數(shù)據(jù)存儲(chǔ)與Django等服務(wù)發(fā)送請(qǐng)求?講解
這篇文章主要為大家介紹了微信小程序的數(shù)據(jù)存儲(chǔ)與Django等服務(wù)發(fā)送請(qǐng)求講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
js中根據(jù)字?jǐn)?shù)截取字符串,不能截?cái)鄒rl
給一個(gè)文字,對(duì)輸出的文字進(jìn)行截取,保留400個(gè)字符,其中對(duì)url的保留比較麻煩,尤其是有兩個(gè)相同url時(shí)不能采用indexOf獲取其字符位置2012-01-01
AJAX XMLHttpRequest對(duì)象創(chuàng)建使用詳解
這篇文章主要介紹了AJAX XMLHttpRequest對(duì)象創(chuàng)建使用詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
利用JS如何計(jì)算字符串所占字節(jié)數(shù)示例代碼
因?yàn)樽罱?xiàng)目有個(gè)需求要用js計(jì)算一串字符串寫入到localStorage里所占的內(nèi)存,所以便有了這篇文章,下面這篇文章主要給大家介紹了關(guān)于利用JS如何計(jì)算字符串所占字節(jié)數(shù)的相關(guān)資料,需要的朋友可以參考下。2017-09-09
js實(shí)現(xiàn)拖拽效果(構(gòu)造函數(shù))
這篇文章主要介紹了js利用構(gòu)造函數(shù)實(shí)現(xiàn)拖拽效果2015-12-12
javascript之querySelector和querySelectorAll使用說明
其實(shí)關(guān)于querySelector和querySelectorAll的介紹說明很多,在此主要是做個(gè)記錄2011-10-10

