玩的时候用了 .cr
作为后缀,结果被 GitHub 识别成其他语言了,
跑过去一看,真有这么个编程语言抢我后缀.. Crystal 语言,Ruby 的语法,代码是编译执行的:
# Compute prime numbers up to 100 with the Sieve of Eratosthenes
max = 100
sieve = Array.new(max, true)
sieve[0] = false
sieve[1] = false
(2...max).each do |i|
if sieve[i]
(2 * i).step(max - 1, i) do |j|
sieve[j] = false
end
end
end
sieve.each_with_index do |prime, number|
puts number if prime
end
搜索论坛被提到过一次 http://ruby-china.org/topics/10389
Crystal 的博客上提到下面几点:
具体代码还是 pre-alpha 的... 等正式发布玩一下... 不过不知道发布要几几年啊..
疑惑起来了.. 在知乎发了个帖问 http://www.zhihu.com/question/22399630 自己在学做很简单的脚本语言,, 类型推断究竟能多大程度让动态语言有静态语言的效率呢? 是所有的语言,能够类型推断的话,就都能够被编译成二进制代码吗?
不能啊,类型推断算法本身有复杂度限制啊 ...
Inferring Recursive Data Types 里面总结了几种不同的类型系统,对应的类型推断算法的复杂度,有几种是 P/NP HARD 的 ...
是所有的语言,能够类型推断的话,就都能够被编译成二进制代码吗?
不需要类型推断,也能编译成二进制代码的。只是运行起来可能还没解释执行快
我理解的类型推断相当于在编译期运行个类似 Prolog 的东西
比如
fun f(a, b) { return a+b; }
改写成
f(A, B, Ret) :-
+(A, B, Ret)
就好了
#4 楼 @jiyinyiyong 编译到二进制很简单的,把 vm 指令都改成函数调用就可以了,其实和解释执行区别不大... 如果把 vm 指令的实现内联进来,就能省掉 call 的开销,但编译出来的结果就会很大 (这里很矛盾的,如果用提取公共子表达式之类的优化手段,就退化回前面那种代码了). 所以一般都选择性的内联,和选择性的优化 (编译时间比执行时间还长的话,即时编译也没有意义了)
编译期类型作用就是去掉运行时的类型检查和方法查找开销,如果调用目标代码固定了就能内联进来 -- 但动态语言就是不固定的,很多脚本的大部分代码就是只运行一遍,延迟到运行时检查速度更快。还有个作用是利用数据类型的知识,减少从 tagged pointer 拆箱/装箱的开销,减少从对象取成员/写成员的开销 -- 但是这种优化之前往往要做逃逸分析,对象逃不出去才能这么做,而只要语言支持 continuation 或者比较强的运行时反射,基本都逃逸了... 另外,声明成 immutable 的变量就可以不用做逃逸分析直接拆箱。
#14 楼 @luikore 术语超多 >_< 还只会很基础的解释器... 直观感觉是一路 type assertion...
if block.Tag == "block" {
if item, ok := block.Value.(context); ok {
runtime := Env{}
for i, para := range item.args {
// println("i is:", i)
// debugPrint(xs)
if token, ok := para.(cirru.Token); ok {
runtime[token.Text] = cirruGet(env, xs[i+1:i+2])
}
}
for _, line := range item.code {
if exp, ok := line.(cirru.List); ok {
ret = Evaluate(&runtime, exp)
}
}
return
}
}
https://github.com/Cirru/cirru-gopher/blob/master/block.go#L25
距离编译好远..
#16 楼 @jiyinyiyong 编译器和解释器代码构造相似,真正干事情的地方改成打印或者拼字符串就可以了。你可以先弄个输出 js/C 代码的编译器,会玩了就可以尝试输出 llvm 字节码了 (如果用 llvm 的话,建议实现语言选 C++, 可以少走很多弯路). 想直接输出 x86 也不难,可以看看 libjit 和 xbyak, 不过要先学习 calling convention 和熟悉 stack layout.
.NET DLR 上做语言更简单,把树给它就好了。
关键词都给你了,自己看 wiki 咯。