經(jīng)過昨天的艱苦奮斗我終于在
Vczh Library++ 3.0里完成這么一個(gè)功能了。假設(shè)我現(xiàn)在用代碼組裝了一個(gè)語法樹:
1 BasicProgramNode program;
2 program.DefineStructure(L"Complex")
3 .Member(L"r", t_int())
4 .Member(L"i", t_int());
5 program.DefineFunction(L"main").ReturnType(t_int()).Statement(
6 s_var(t_type(L"Complex"), L"a")
7 <<s_var(t_type(L"Complex"), L"b")
8 <<s_var(t_type(L"Complex"), L"c")
9 <<s_expr(e_name(L"a").Member(L"r").Assign(e_prim(1)))
10 <<s_expr(e_name(L"a").Member(L"i").Assign(e_prim(2)))
11 <<s_expr(e_name(L"b").Member(L"r").Assign(e_prim(3)))
12 <<s_expr(e_name(L"b").Member(L"i").Assign(e_prim(4)))
13 <<s_var(t_type(L"Complex"), L"x", e_name(L"a"))
14 <<s_var(t_type(L"Complex"), L"y")
15 <<s_expr(e_name(L"y").Assign(e_name(L"b")))
16 <<s_expr(e_name(L"c").Member(L"r").Assign(
17 e_name(L"x").Member(L"r") + e_name(L"y").Member(L"r")
18 ))
19 <<s_expr(e_name(L"c").Member(L"i").Assign(
20 e_name(L"x").Member(L"i") + e_name(L"y").Member(L"i")
21 ))
22 <<s_expr(e_result().Assign(
23 e_name(L"c").Member(L"r")*e_prim(100) + e_name(L"c").Member(L"i")
24 ))
25 );
于是最近寫的N個(gè)函數(shù)終于可以發(fā)揮作用了。首先我會(huì)拿這個(gè)program編譯成指令集先跑一次,如果答案跟測試用例給出的一致那就繼續(xù)往下走。接下來就將這個(gè)program還原成一個(gè)NativeX語言的字符串,然后調(diào)用NativeX的語法分析器再編譯一次,這樣每一個(gè)語法樹的節(jié)點(diǎn)都有一個(gè)指向記號的屬性了。這樣語法樹生成指令集的時(shí)候,每一個(gè)指令原本屬于哪顆語法樹也就都記錄下來了。這個(gè)時(shí)候,將指令集輸出成文本文件的時(shí)候,就可以根據(jù)位置信息使用NativeX的源代碼打上注釋,然后再跑一次。這樣還可以通過豐富的測試用例來測試NativeX的語法分析器,而且還不會(huì)被語法分析器影響。因?yàn)閜rogram編譯了一次,program->NativeX->newProgram又編譯了一次,哇哈哈。結(jié)果如下:
(窺孔優(yōu)化在這個(gè)時(shí)候就可以大展身手了,不過我還沒做……)
1 /*NativeX Code*/
2 unit nativex_program_generated;
3 structure Complex
4 {
5 int32 r;
6 int32 i;
7 }
8
9 function int32 main()
10 {
11 variable Complex a;
12 variable Complex b;
13 variable Complex c;
14 (a.r=1);
15 (a.i=2);
16 (b.r=3);
17 (b.i=4);
18 variable Complex x = a;
19 variable Complex y;
20 (y=b);
21 (c.r=(x.r+y.r));
22 (c.i=(x.i+y.i));
23 (result=((c.r*100)+c.i));
24 }
25
26
27 /*Assembly*/
28 .data
29 .label
30 0: instruction 3
31 .code
32 // unit nativex_program_generated;
33 0: stack_reserve 0
34 1: stack_reserve 0
35 2: ret 0
36 // function int32 main()
37 3: stack_reserve 40
38 // (a.r=1);
39 4: push s8 1
40 5: convert s32 s8
41 6: stack_offset -8
42 7: push s32 0
43 8: add s32
44 9: write s32
45 // (a.i=2);
46 10: push s8 2
47 11: convert s32 s8
48 12: stack_offset -8
49 13: push s32 4
50 14: add s32
51 15: write s32
52 // (b.r=3);
53 16: push s8 3
54 17: convert s32 s8
55 18: stack_offset -16
56 19: push s32 0
57 20: add s32
58 21: write s32
59 // (b.i=4);
60 22: push s8 4
61 23: convert s32 s8
62 24: stack_offset -16
63 25: push s32 4
64 26: add s32
65 27: write s32
66 // variable Complex x = a;
67 28: stack_offset -8
68 29: stack_offset -32
69 30: copymem 8
70 // (y=b);
71 31: stack_offset -16
72 32: stack_offset -40
73 33: copymem 8
74 // (c.r=(x.r+y.r));
75 34: stack_offset -40
76 35: push s32 0
77 36: add s32
78 37: read s32
79 38: stack_offset -32
80 39: push s32 0
81 40: add s32
82 41: read s32
83 42: add s32
84 43: stack_offset -24
85 44: push s32 0
86 45: add s32
87 46: write s32
88 // (c.i=(x.i+y.i));
89 47: stack_offset -40
90 48: push s32 4
91 49: add s32
92 50: read s32
93 51: stack_offset -32
94 52: push s32 4
95 53: add s32
96 54: read s32
97 55: add s32
98 56: stack_offset -24
99 57: push s32 4
100 58: add s32
101 59: write s32
102 // (result=((c.r*100)+c.i));
103 60: stack_offset -24
104 61: push s32 4
105 62: add s32
106 63: read s32
107 64: push s8 100
108 65: convert s32 s8
109 66: stack_offset -24
110 67: push s32 0
111 68: add s32
112 69: read s32
113 70: mul s32
114 71: add s32
115 72: resptr
116 73: write s32
117 // function int32 main()
118 74: stack_reserve -40
119 75: ret 0
120
最新的代碼可以在
這里獲得。
posted on 2010-06-04 19:49
陳梓瀚(vczh) 閱讀(2767)
評論(1) 編輯 收藏 引用 所屬分類:
VL++3.0開發(fā)紀(jì)事