发布DynamicStruct-0.2 and BytecodeStruct-0.1

DynamicStruct,是我最近自己在鼓捣的一个ruby项目,这是一个更大的计划的一部分。

当他完成之后,应该是这样的一个结构:

Aurum
|
V
RubyBCL
|
V
DynamicStruct

Aurum是目前徐昊正在做的一个项目,简单的介绍可以看这里:《[url=http://www.blogjava.net/raimundox/archive/2007/09/05/143028.html]A very brief introduction to Aurum[/url]》

通过aurum,可以更加方便的定义新的语言。

但是,仅仅依靠aurum,只能让新设计出来的语言,运行于aurum的解释环境中,ruby就已经是够慢的解释语言了,这样的解释执行方式,可以说完全无法得到具有实用价值的语言。但是,如果可以通过aurum,将一种语言编译成Java Bytecode,那么,美好的未来就会是:“能够快速的定义,具有实用价值的,新语言!而且,各种新语言,都能够基于JVM,互联互通。”

RubyBCL,现在还没有出现。仅有的灵感,来自Charles Nutter的一篇blog:《[url=http://headius.blogspot.com/2007/11/bytecode-tools-in-ruby-low-level-dsl.html]Bytecode Tools in Ruby: A Low-level DSL[/url]》。这篇blog可能无法在国内访问。转贴一点过来吧:

  cb = Compiler::ClassBuilder.build("MyClass", "MyClass.java") do
field :list, ArrayList

constructor(String, ArrayList) do
aload 0
invokespecial Object, "<init>", Void::TYPE
aload 0
aload 1
aload 2
invokevirtual this, :bar, [ArrayList, String, ArrayList]
aload 0
swap
putfield this, :list, ArrayList
returnvoid
end

static_method(:foo, this, String) do
new this
dup
aload 0
new ArrayList
dup
invokespecial ArrayList, "<init>", Void::TYPE
invokespecial this, "<init>", [Void::TYPE, String, ArrayList]
areturn
end

method(:bar, ArrayList, String, ArrayList) do
aload 1
invokevirtual(String, :toLowerCase, String)
aload 2
swap
invokevirtual(ArrayList, :add, [Boolean::TYPE, Object])
aload 2
areturn
end

method(:getList, ArrayList) do
aload 0
getfield this, :list, ArrayList
areturn
end

static_method(:main, Void::TYPE, String[]) do
aload 0
ldc_int 0
aaload
invokestatic this, :foo, [this, String]
invokevirtual this, :getList, ArrayList
aprintln
returnvoid
end
end
cb.write("MyClass.class")


这样一段代码,就能够得到一个MyClass.class。这个class,也可以用下面的java代码编译得到。

import java.util.ArrayList;
public class MyClass {
public ArrayList list;
public MyClass(String a, ArrayList b) {
list = bar(a, b);
}
public static MyClass foo(String a) {
return new MyClass(a, new ArrayList());
}
public ArrayList bar(String a, ArrayList b) {
b.add(a.toLowerCase());
return b;
}
public ArrayList getList() {
return list;
}
public static void main(String[] args) {
System.out.println(foo(args[0]).getList());
}
}


非常漂亮的DSL,但是,在看过Charles Nutter放在svn里的代码之后,我才发现,这家伙太讨巧了,事实上他上面的那些DSL,最后还是利用JRuby,调用了ASM这个java类库。所以,我打算,仅仅借鉴他的DSL设计,但是却用纯粹的ruby,来实现一个生成Java Bytecode的lib。

至于DynamicStruct,要从BitStruct说起,由于ruby没有一个很方便的处理二进制文件的类库,所以我找到了[url=http://redshift.sourceforge.net/bit-struct/doc/index.html]bit-struct[/url],还有一篇不错的中文介绍:《[url=http://liubin.nanshapo.com/2007/06/16/%E7%94%A8bit-struct%E5%A4%84%E7%90%86%E7%BB%93%E6%9E%84%E5%8C%96%EF%BC%88%E4%BA%8C%E8%BF%9B%E5%88%B6%EF%BC%89%E6%95%B0%E6%8D%AE/]用bit-struct处理结构化(二进制)数据[/url]》

但是,后来我发现,这个bit-struct,存在绝大的问题,甚至不能仅仅在他的基础上进行修改。因为他只能支持定长的数据结构,而不是可变长度的array list,变长的string,或者switch结构。因此,只能推倒重写。

我现在的工作,就是一个初步的二进制文件读写类库的实现。

简单的看看其中的测试代码吧:

require "dynamic-struct"

class ClassFile<DynamicStruct
u4 :magic
u2 :file
field_type :clsf
end

class Temp<DynamicStruct
u2 :t_file
clsf :cf
field_type :temp
end

class Temp2<DynamicStruct
u2 :t_file
clsf :cf
temp :ttt
u1 :uu1
u2 :uu2
end

a=Temp2.new
a.t_file=1
a.cf.magic=2
a.cf.file=3
a.ttt.t_file=4
a.ttt.cf.magic=5
a.ttt.cf.file=6
a.uu1=444
a.uu2=888

f=open("C:\\test1.class","wb")
a.write(f)
f.close

f = File.new("C:\\test1.class")
b=Temp2.new
b.read(f)
f.close

puts b.to_s


这个test1,基本完成了与bit-struct类似的工作。

require "dynamic-struct"

class Temp<DynamicStruct
string :str,1
end

a=Temp.new
a.str='String Test!'

f=open("C:\\test2.class","wb")
a.write(f)
f.close
f = File.new("C:\\test2.class")
b=Temp.new
b.read(f)
f.close
puts b.to_s


这是动态字符串的效果。

require "dynamic-struct"

class TempArray<ArrayField
size_byte 1
item_type :u2
field_type :u2array
end

class TempStruct<DynamicStruct
u2array :ua
end

ts=TempStruct.new
ts.ua.add(1)
ts.ua.add(2)
ts.ua.add(3)
ts.ua[2]=4
puts ts.to_s
f=open("C:\\test3.class","wb")
ts.write(f)
f.close
f = File.new("C:\\test3.class")
b=TempStruct.new
b.read(f)
f.close

puts b.to_s


这是array list的效果。

require "dynamic-struct"

class TempSwitch<SwitchField
size_byte 1
item_type_list({1=>:u1,2=>:u2,3=>:u4,4=>:u8})
field_type :temps
end

class TempStruct<DynamicStruct
temps :tus
end

ts=TempStruct.new
u=UnsignedField.new
u.field_type_name="u4"
u.value=33
ts.tus.value=u

puts ts.to_s
f=open("C:\\test4.class","wb")
ts.write(f)
f.close
f = File.new("C:\\test4.class")
b=TempStruct.new
b.read(f)
f.close

puts b.to_s


这是switch的效果。

附上源代码,欢迎多多批评!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值