动机
话说我已经忘了什么时候看的这篇博文了,但是从那以后确实就入坑了(说不清是什么坑),感谢王垠
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>()
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>):RetValue()
}
fun ext_env(name: Expr.Symbol, value: RetValue, env: LinkedList>)
: LinkedList> {
var ret = env.clone() as LinkedList>
ret.push(Pair(name, value))
return ret
}
fun lookup(symbol:Expr.Symbol, env: LinkedList>):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>) : 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) {
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)))
}