如何寫 Lisp 解釋器?
關於代碼的話我搜到了兩個例子
http://blog.csdn.net/sedgewick/article/details/5928653http://www.googies.info/articles/lispy.html但具體說, 寫一個解釋器應該怎樣考慮呢?
function interpret(form, env, ctx){
if(form instanceof Array){
switch(form[0]){
case "lambda": {
var params = form[1];
var body = form[2];
return ctx(function(ctx){ return function() {
var e = Object.create(env);
for(var j = 0; j &< params.length; j++) e[params[j]] = arguments[j];
return interpret(body, e, ctx)
}})
};
case "if": {
var test = form[1], consequent = form[2], alternate = form[3];
return interpret(form[1], env, function(c){
if(c) return interpret(consequent, env, ctx)
else return interpret(alternate, env, ctx)
})
};
case "callcc": {
return interpret(form[1], env, function(f){
var fctx = function(){ return function(x){ return ctx(x) }};
return f(fctx)(fctx)
})
};
case "quote": {
return ctx(form[1])
};
default: {
return interpretCall(form, env, ctx);
};
}
} else if(typeof form === "string") {
return ctx(env[form])
} else {
return ctx(form)
}
}
function interpretCall(form, env, ctx){
return interpret(form[0], env, function(callee){
return interpret$(form.slice(1), env, function(args){
return callee(ctx).apply(null, args)
})
})
}
function interpret$(form, env, ctx){
if(!form.length) return ctx(null);
else return interpret(form[0], env, function(x0){
return interpret$(form.slice(1), env, function(x$){
if(x$) return ctx([x0])
else return ctx([x0].concat(x$))
})
})
}
function id(x){ return x }
var env0 = { trace: function(ctx){ return function(x) { return ctx(console.log(x)) }}};
interpret(["trace", ["callcc", ["lambda", ["return"], ["return", ["quote", 3]]]]], env0, id);
因為之前有人說我偷懶沒做 call/cc,今天我就做它一回。全文按照 Danvy 他們的抽象解釋模式寫成,顯式傳遞 Continuation。
下面是個混淆版function $(C,E,K){if(!(C instanceof Array))return K("string"==typeof C?
E[C]:C);switch(C[0]){case"lambda":return K(function(K){return function(
){for(var e=Object.create(E),u=0;u&
如果想完整理解建議閱讀SICP第4章,以及MIT配套的視頻和講義。整體來說,你需要考慮以下幾個方面(你可以對照著看一下你給的第二個鏈接中的文章,我覺得Peter Norvig已經描述的很清楚了):1,詞法分析器(lexical analyzer),即將程序分解為一個個詞法單位,例如「(+ 5 a)」字元串,分解為["+", 5, "a"]。2,語法分析器(Parser),就是把上面的結果構造成一顆語法樹,即 "+"
/
5 "a"3,求值器(Ealuator),通常求值器還需要一個環境參數,然後計算上述語法樹在該環境下的值。例如,假設此時求值環境為{"+": &Contents ? Build Your Own Lisp
王垠這篇還是寫的不錯的 ---- 怎樣寫一個解釋器還有就是sicp的第四章了
只是寫一個簡單解釋器的話:
1. 王垠大神的一篇簡潔易懂的博客
2. 還有下面兩篇用python實現的一個例子:(非常容易上手)
(How to Write a (Lisp) Interpreter (in Python))(An ((Even Better) Lisp) Interpreter (in Python))上面的文章都介紹了每個特性的考慮方式,應該比較符合題主需求。以前很傻很天真地寫過一個,放在了Google Code上面。當時的思路是這樣子的,一開始只是想寫一個程序來從標準輸入讀取廣義表,然後生成內部的鏈表形式的廣義表,再調用一個函數將其以相對美觀的形式輸出來。當我完成了第一步之後,就發現既然可以生成廣義表了,那麼其實剩下的工作,就是解析廣義表並將其作為一個表達式進行求值而已了。沒有任何經驗,光聽別人講的話,肯定是不能理解別人的話的,既然如此,lz倒不如從自己認為是``正確""的地方著手,然後一步步地做出來一個呢。
sicp解釋器注釋版http://zhuanlan.zhihu.com/p/20740190
Write Yourself a Scheme in 48 Hours
推薦一篇文章:The Root of LISP
推薦閱讀:
※一個編程語言能否成功的關鍵之處?
※Lisp可以完成哪些其它語言難以實現的功能?最好能夠舉一些例子
※函數式語言中如何實現while true?
※學習 LISP 有哪些網站或書籍推薦?
※如何評價 Racket 這門編程語言?