几年前我就有3个梦想:
1.攒钱读mba,将来抓一把人爱怎么训怎么训。
2.做一个基于信任机制的物流平台,东西爱怎么买怎么买。
3.搞一个自己的cpu,代码爱怎么写怎么写。
前面2个跟本话题无关,说说cpu。虽然vhdl也会了,fpga也买的起了,但是连自己的代码风格都没有,爱怎么写就怎么写越来越成了一句空话。于是元旦守岁期间终于决定写一个简单编译器先,塌塌实实地一步一步来。
大致的想法是:
1,先做一个编译器的东西(叫什么再说),把oo源代码编译成中间代码。调用 .net framework和jdk解释执行.把oo语言语法定义好先。
2,等出了一个比较完善的oo语言时,抛开 .net framework和jdk 自己写中间代码解释器。
3,如果到这里我还没死心的话,就自己写vhdl,利用fpga,完成我的cpu梦(什么?那是假的?可龙芯差不多就是这么干的).
在家里鼓捣半天,利用CodeDom的思想和正则表达式进行简单的代码识别(好象叫什么词法分析),能把一个简单的代码编译成中间代码。终于在屏幕上打印出了一个"hello world".用网友的话说:万里长征迈出了历史性的一步,一时高兴就在csdn发帖了。结果招来一顿质疑,一顿猛解释还是没能把我宣传blog之嫌给洗清。为了那点可怜的自尊心,思考再3,我决定发布ooStudio 0.000111版。
下载/Files/sukyboor/oo.rar
运行现在需要.net framework 2.0的支持,如果您电脑没有的话可以找www.google.com借.
编译器就是那个ooStudio.exe了。但是好象没认真做,不过你可以改改源文件test.os(ps,就能编译这个文件,傻吧)编译后会生成个中间代码test.xml。废话不说了,上代码:
1namespace Test
2{
3 import System;
4
5 public class Form1
6 {
7 private numeric a;
8 private numeric b = 0;
9 public bool c = false;
10
11 public void Form1()
12 {
13 InitializeComponent();
14 }
15
16 private void button1_Click(numeric i,bool index)
17 {
18 dom.Parse("test.os");
19 dom.Compile("test.xml");
20 }
21 }
22}
23
24namespace Test.Run
25{
26 import System;
27
28 /// <summary>
29 /// 演示
30 /// </summary>
31 public struct Demo
32 {
33 public void say()
34 {
35 System.Console.OutPut("Hello World!");
36 }
37 }
38}
编译后的中间代码(合不合理将来再说,关键是先要让它跑起来.而且做代码输入时智感知方便些).2{
3 import System;
4
5 public class Form1
6 {
7 private numeric a;
8 private numeric b = 0;
9 public bool c = false;
10
11 public void Form1()
12 {
13 InitializeComponent();
14 }
15
16 private void button1_Click(numeric i,bool index)
17 {
18 dom.Parse("test.os");
19 dom.Compile("test.xml");
20 }
21 }
22}
23
24namespace Test.Run
25{
26 import System;
27
28 /// <summary>
29 /// 演示
30 /// </summary>
31 public struct Demo
32 {
33 public void say()
34 {
35 System.Console.OutPut("Hello World!");
36 }
37 }
38}
1<?xml version="1.0" encoding="utf-8"?>
2<doc>
3 <NameSpace name="Test.Run">
4 <Import name="System" />
5 <Class name="Demo" Label="struct">
6 <Method name="say" MethodAttributes="public">
7 <MethodInvoke InvokeExpression="System.Console.OutPut">
8 <Variable Value=""Hello World!"" />
9 </MethodInvoke>
10 </Method>
11 </Class>
12 </NameSpace>
13 <NameSpace name="Test">
14 <Import name="System" />
15 <Class name="Form1" Label="class">
16 <Method name="button1_Click" MethodAttributes="private">
17 <Parameter name="i" TypeName="numeric" />
18 <Parameter name="index" TypeName="bool" />
19 <MethodInvoke InvokeExpression="dom.Parse">
20 <Variable Value=""test.os"" />
21 </MethodInvoke>
22 <MethodInvoke InvokeExpression="dom.Compile">
23 <Variable Value=""test.xml"" />
24 </MethodInvoke>
25 </Method>
26 <Method name="Form1" MethodAttributes="public">
27 <MethodInvoke InvokeExpression="InitializeComponent">
28 <Variable Value="" />
29 </MethodInvoke>
30 </Method>
31 <Variable name="a" TypeName="numeric" Value="" VariableAttributes="private" />
32 <Variable name="b" TypeName="numeric" Value="0" VariableAttributes="private" />
33 <Variable name="c" TypeName="bool" Value="false" VariableAttributes="public" />
34 </Class>
35 </NameSpace>
36</doc>
可能细心的你会发现怎么还有个System.xml。没错,我把对系统访问的功能封在这里了。这样从外面看起来就更像那么回事.现在用最笨的方法,将所有<MethodInvoke InvokeExpression="SysCall">的都交给.net framework/jdk去解释。2<doc>
3 <NameSpace name="Test.Run">
4 <Import name="System" />
5 <Class name="Demo" Label="struct">
6 <Method name="say" MethodAttributes="public">
7 <MethodInvoke InvokeExpression="System.Console.OutPut">
8 <Variable Value=""Hello World!"" />
9 </MethodInvoke>
10 </Method>
11 </Class>
12 </NameSpace>
13 <NameSpace name="Test">
14 <Import name="System" />
15 <Class name="Form1" Label="class">
16 <Method name="button1_Click" MethodAttributes="private">
17 <Parameter name="i" TypeName="numeric" />
18 <Parameter name="index" TypeName="bool" />
19 <MethodInvoke InvokeExpression="dom.Parse">
20 <Variable Value=""test.os"" />
21 </MethodInvoke>
22 <MethodInvoke InvokeExpression="dom.Compile">
23 <Variable Value=""test.xml"" />
24 </MethodInvoke>
25 </Method>
26 <Method name="Form1" MethodAttributes="public">
27 <MethodInvoke InvokeExpression="InitializeComponent">
28 <Variable Value="" />
29 </MethodInvoke>
30 </Method>
31 <Variable name="a" TypeName="numeric" Value="" VariableAttributes="private" />
32 <Variable name="b" TypeName="numeric" Value="0" VariableAttributes="private" />
33 <Variable name="c" TypeName="bool" Value="false" VariableAttributes="public" />
34 </Class>
35 </NameSpace>
36</doc>
oo.dll就是我照着codedom重写的解释器.挺有意思的,我是按照msdn codedom介绍首页依次把code*改成*Element,就看个名字,最近脑袋有点绣逗不看名字我还写不出来:).不直接用codedom.是因为,codedom不会按照你的要求去解释执行我们编译出来的中间代码的.
好了,现在就让它表现一下吧。运行run.exe。等等,它怎么知道我们要执行哪个程序?介个嘛,看看Run.exe.config就明白了,主要是个人一直很喜欢smart client的智能更新,比较反感 run.exe test.xml test.demo.say 这种方式.智者见智,仁者见仁 这个有的商量。
屏幕上应该会输出 hello world吧。
如果你有兴趣输出:
hello word
hello powerpoint
hello excel
hello frontpage
hello outlook
hello access
那你就修改一下test.os,后用ooStudio.exe重新编译吧。
1public void say()
2 {
3 System.Console.OutPut("hello word!");
4 System.Console.OutPut("hello powerpoint!");
5 System.Console.OutPut("hello excel!");
6 System.Console.OutPut("hello frontpage!");
7 System.Console.OutPut("hello outlook!");
8 System.Console.OutPut("hello access!");
9 }
2 {
3 System.Console.OutPut("hello word!");
4 System.Console.OutPut("hello powerpoint!");
5 System.Console.OutPut("hello excel!");
6 System.Console.OutPut("hello frontpage!");
7 System.Console.OutPut("hello outlook!");
8 System.Console.OutPut("hello access!");
9 }