随笔-341  评论-2670  文章-0  trackbacks-0
    经过昨天的艰苦奋斗我终于在Vczh Library++ 3.0里完成这么一个功能了。假设我现在用代码组装了一个语法树:
 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个函数终于可以发挥作用了。首先我会拿这个program编译成指令集先跑一次,如果答案跟测试用例给出的一致那就继续往下走。接下来就将这个program还原成一个NativeX语言的字符串,然后调用NativeX的语法分析器再编译一次,这样每一个语法树的节点都有一个指向记号的属性了。这样语法树生成指令集的时候,每一个指令原本属于哪颗语法树也就都记录下来了。这个时候,将指令集输出成文本文件的时候,就可以根据位置信息使用NativeX的源代码打上注释,然后再跑一次。这样还可以通过丰富的测试用例来测试NativeX的语法分析器,而且还不会被语法分析器影响。因为program编译了一次,program->NativeX->newProgram又编译了一次,哇哈哈。结果如下:

    (窥孔优化在这个时候就可以大展身手了,不过我还没做……)
  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) 阅读(2758) 评论(1)  编辑 收藏 引用 所属分类: VL++3.0开发纪事

评论:
# re: Vczh Library++3.0之成功将源代码注释进指令列表 2010-06-05 03:06 | radar
↖(^ω^)↗  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理