動機
話說我已經忘了什么時候看的這篇博文了,但是從那以后確實就入坑了(說不清是什么坑),感謝王垠
http://www.yinwang.org/blog-cn/2012/08/01/interpreter/
關于Kotlin
簡單的說就是Java的改良版。更多特性,填了很多坑,代碼還更精簡。十分看好。關鍵是函數是第一公民啊 :D
這貨也經常被形容為Android世界的Swift,可以看看后面的代碼,是有點像。
丟個官網大家自己去看吧,還能在線試用 :D
這貨是jetbrains開發出來的。和intellij兼容無限好。簡直不要更爽,十分看好它的潛力。
(開腦洞的話,2年以內Kotlin爆炸式增長,Google收購JetBrains,Kotlin一統網頁+安卓開發 (想多了))
http://www.kotlinlang.org/
關于這個解釋器
邏輯完全是仿的博文里的那個。寫的很矬很羅嗦。就當看個樂吧(然而并沒有人會看......)
順便再次推薦Programming Languages: Application and Interpretation(2nd)這本書。沒看過這個的話我是想不出來怎么用靜態語言去實現那一堆東西的。總之,這本書粗看一遍都收獲巨大,仔細看的話,那還不飛上天啊。。。
書的主頁
http://cs.brown.edu/~sk/Publications/Books/ProgLangs/2007-04-26/
import java.util.*
val env0 = LinkedList<Pair<Expr.Symbol, RetValue>>()
sealed class Expr{
class Symbol(val name:String):Expr()
class Num(val num:Int):Expr()
class Lambda(val arg:Symbol, val body:Expr):Expr()
class App(val func:Expr,val arg:Expr):Expr()
class ArithOp(val op:Char,val e1:Expr, val e2:Expr):Expr()
}
sealed class RetValue{
class NumValue(val num: Int):RetValue()
class Closure(val fundef:Expr.Lambda,
val env:LinkedList<Pair<Expr.Symbol, RetValue>>):RetValue()
}
fun ext_env(name: Expr.Symbol, value: RetValue, env: LinkedList<Pair<Expr.Symbol,RetValue>>)
: LinkedList<Pair<Expr.Symbol, RetValue>> {
var ret = env.clone() as LinkedList<Pair<Expr.Symbol, RetValue>>
ret.push(Pair(name, value))
return ret
}
fun lookup(symbol:Expr.Symbol, env: LinkedList<Pair<Expr.Symbol, RetValue>>):RetValue {
for(p in env){
if(symbol.name==p.first.name){
return p.second
}
}
val str = symbol.name
throw UnknownError("Look up Failed,not fould $str in env $env")
}
fun interp1(exp:Expr,
env: LinkedList<Pair<Expr.Symbol, RetValue>>) : RetValue {
when (exp){
is Expr.Symbol -> return lookup(exp, env)
is Expr.Num -> return RetValue.NumValue(exp.num)
is Expr.Lambda -> return RetValue.Closure(exp,env)
is Expr.App -> {
val appclosure = interp1(exp.func,env) as RetValue.Closure
val argvalue = interp1(exp.arg,env)
return interp1(appclosure.fundef.body,
ext_env(appclosure.fundef.arg,argvalue,appclosure.env))
}
is Expr.ArithOp -> {
val v1 = interp1(exp.e1,env) as RetValue.NumValue
val v2 = interp1(exp.e2,env) as RetValue.NumValue
return when(exp.op){
'+' -> RetValue.NumValue(v1.num+v2.num)
'-' -> RetValue.NumValue(v1.num-v2.num)
'*' -> RetValue.NumValue(v1.num*v2.num)
'/' -> RetValue.NumValue(v1.num/v2.num)
else -> throw UnknownError("Unexpected op"+exp.op)
}
}
}
}
fun interp(exp: Expr):Int {
val ret = interp1(exp,env0)
when (ret){
is RetValue.NumValue -> return ret.num
is RetValue.Closure -> throw UnknownError("Unexpected Closure in interp with $exp")
}
}
fun main(args: Array<String>) {
fun drive(exp:Expr) {
println(interp(exp))
}
drive(Expr.App(
Expr.App(Expr.Lambda(Expr.Symbol("x"),
Expr.Lambda(Expr.Symbol("y"),
Expr.ArithOp('*',Expr.Symbol("x"),Expr.Symbol("y"))))
,Expr.Num(2))
,Expr.Num(3)))
/*
((lambda (y)
(((lambda (y)
(lambda (x) (* y 2))) 3) 0)) 4)
*/
drive(Expr.App(
Expr.Lambda(Expr.Symbol("y"),
Expr.App(
Expr.App(
Expr.Lambda(Expr.Symbol("y"),
Expr.Lambda(Expr.Symbol("x"),
Expr.ArithOp('*',Expr.Symbol("y"),Expr.Num(2))))
,Expr.Num(3))
,Expr.Num(0)))
,Expr.Num(4)))
}