
**********************************************
记录时间:	2012年3月12日 下午 3:54

  这半年基本没碰这个编译器，现在要开始把编译器改写成中文编程的，而不是类C语言，所以从中文分词、
  中文语法解析一直到底层的类型系统要重新设计，其实应该扔掉以前的编译器代码，重新写一个编译器。
  先在目前的基础上改写试试，实在不行了就重写编译器。

**********************************************
修改时间:	2012年3月30日 下午 3点50分

  1 把编译器的界面改成不带有菜单的，文档浏览器用自定义的Tab实现，带有关闭图标和新建文档图标等；
    去掉原先的工程形式,不需要建立一个工程加入文件再编译,而是直接一个C文件就可以编译,当前打开
  2 哪个文件就编译哪个;
  3 BUG:Tab的标签大小是默认的，改字体大小也不行，没办法只好设置一个合适的字体去适应这个尺寸；

**********************************************
修改时间:	2012年3月30日 晚上 10点06分

  今晚上开始正式调试类型系统，好像成功了，可以定义指向静态变量的引用；但是指针和引用都不能指向局部变量，
  不知道为什么。居然会有这个BUG。  回去睡觉...

**********************************************
修改时间:	2012年3月31日 晚上 9点24分

  发现指针不能指向局部变量的原因了,在"读取地址"指令中只是把变量地址读了出来,而对于局部变量的地址只是
相对地址,还需要加上堆栈指针的值.现在改过来正确了.

**********************************************
修改时间:	2012年4月2日 下午 6点02分

  把数组的下标运算[] 改成点运算: Array[0] 需要写成 Array.0
  这样数组和结构体都用"."访问成员;下一步计划:去掉指针类型,
  把数组和指针的默认转换去掉,用数组引用代替;

  说明: 近期的任务是把原来的类型系统(C语言系列)逐渐改成现在
的类型系统:去掉指针,使用引用代替;去掉数组,使用结构体代替,到最后
的类型系统中只有唯一一种类型;

**********************************************
修改时间:	2012年4月2日 晚上 10点04分

  把数组的访问改成.运算,然后多维数组也可以使用了,把那个PC的俄罗斯方块编译成功;还有
其他的AVR软件仿真的一些程序等都可以通过了。目前的BUG：不允许结构体数组和
数组类型成员的结构体，这个需要把类型分析提前到语法树展开中才行，明天再试试。。。睡觉去。。

**********************************************
修改时间:	2012年4月3日 晚上 9点42分

  把数组和结构体改成引用,在内部不再以指针偏移量的形式计算,测试通过.下一步计划:
彻底去掉指针,在类型定义中去掉,内部的取地址.指针加减等都去掉;
目前的一个BUG:对于基本变量的引用传递还是要靠指针(在MIDI电子琴程序中用到取地址等没有改);

  今天忙一天，累得不行~  感觉今天已经完成编译器的最核心的设计了，剩下的都是外层了。。。

**********************************************
修改时间:	2012年4月6日 上午 11:10

在引用前缀中应该是成员引用,而不是标识符:

   @引用前缀 --> #顺序 ?@标识符 &<<<<

**********************************************
修改时间:	2012年4月6日 晚上 ?:?

把编译器的内置虚拟类型提取出来,这样可以随意修改,
把u.base和u.code改成u.vbasetype.base和u.vcodetype.code,测试通过;下一步把根目录u字符提取出来,换成i;

（今天在网上无意中看到演员白静和她丈夫之间的恩怨，很揪心。。。）

**********************************************
修改时间:	2012年4月7日 晚上 7:12

    把结构体的运算和类型分析提前到语法树展开中,下一步是把其他的运算的返回类型分析都提前到语法树展开;

**********************************************
修改时间:	2012年4月8日 晚上 8:50

    今天完成关键的一步：把中间代码层去掉，全部提升到语法树展开中，这样编译器的编译结构就少了一层，
非常好。以前在语法树展开中对表达式的返回类型分析不全，需要添加一层规范化代码；现在把这层规范化代码全部
在语法树展开中实现，这样可以在语法树展开的时候实现更多的特性，例如全部成员访问包括结构体、数组等
都采用“.”表示，在以后还可以去掉这个点运算，直接用名词的顺序排列表示成员引用，相当于在C语言中
省略数组下标的中括号[]和结构体引用的点运算符号省略；

    目前产生两个新BUG：函数的形参和实参类型是否相同没进行检查；不支持无地址的虚拟类型；

**********************************************
修改时间:	2012年4月9日 上午 10:51

    还有一个BUG：goto语句只能向下跳转，因为在语法树展开时顺序分析标号的定义；

    正在整理剩余的中间代码层0；昨天用了一个非常强的办法：直接在语法树展开中调用规范化类的类型分析，
然后生成代码层1，直接跳过代码层0；目前应该没什么问题；

**********************************************
修改时间:	2012年4月9日 下午 3:51

    去掉中间指令：赋值运算（bit和bool），改成和普通变量一样的方式；发现在汇编宏表达式计算中不能
对宏变量赋值：$2 = 0 不对，只好用 $2 = 0 + 0 代替；以后有时间再把这里整理一下;

**********************************************
修改时间:	2012年4月9日 下午 17:09

把分量运算的格式改为如下，其中位置信息作为常量放到最后：

    public const string 写入分量 = "写入分量"; // 写入分量 变量索引 变量索引 变量索引 #位置

这样所有的变量都在虚拟指令的第1、2、3个位置，其中1用于保存0, 2、3用于加载0，加载1；

**********************************************
修改时间:	2012年4月9日 下午 17:35

    把加载和保存处理成显式的加载_0,加载_1和保存_0, 发现一个问题:
虚拟指令: 读取地址 V1 V2 这是原先的,改成 读取地址 V1 #V2,因为V2这个位置其实只是一个常量而已;
但是在变量分配时只对用到的变量分配,而V2可能尚未分配地址. 于是额外加了一个地址判断,当V2没有分配
地址时先分配地址再读取地址到V1中;

**********************************************
修改时间:	2012年4月9日 晚上 10:00

今晚上调试类型系统,想把所有的类型处理放到一个核心的类中,终于快弄好了,到最后发现一个难解决的问题:

//if( !VarType.isRefer( SubType ) ) {
	NodeType = VarType.AddRefer( VarType.VBase, SubType );
//}

在目前的类型系统中不允许定义指向引用的引用,但是把上面的去掉注释就不行,显然是个BUG;
在GetInterface这个函数中也有问题! 但是这两个问题纠结到一块竟然又没问题了!!!难道以前一直这么
将就着过来的么??? 例如在PC程序中这个运算:

wc.lpszClassName = lpClassName;//设置窗口属性

这里应该改成引用的指向运算:
wc.lpszClassName => lpClassName;//设置窗口属性

    明天继续，争取把这个最后的BUG搞定，基本就没问题了。。。

**********************************************
修改时间:	2012年4月10日 下午 14:09

    引用类型这里太纠结了...主要还是以前没什么经验,应该把接口都统一到一个类中,尤其要注意绝对不要
出现字符串的硬编码...以前的引用类型系统有问题,应该类似基本变量一样,分为系统变量和用户变量;
所有的系统变量都具有显式地址,包括基本类型和基本引用类型,用 & 表示,不用 Vbase & 表示了; 类似通过空格
区分基本变量一样;最后到汇编库转换时全部是系统变量,即要么是无空格的,要么是以 & 开始的;


//2012.4.11 深夜 一点钟
//如果是标准类型(结构体, 扩展变量等),一定具有显式地址!!!  关键就在这!!!

一段注释... 无语了... 也许是这样：把初始变量的类型规范化为3种：基本类型、对数组和结构体的系统引用，
还有对“带有标准存储区的引用”的系统引用；

**********************************************
修改时间:	2012年4月11日 下午 5:32

昨晚上通宵，却什么也没干成！！！今上午睡了半天，中午清醒了一点，然后下午终于把类型系统弄懂了，
目前完成通用引用指向数据的读取了，下面是测试代码，因为通用引用的写接口还没有处理好，所以定义了
一个16位的整型和那个引用类型的地址重叠，临时代替引用的指定；在读接口这里，读了一次之后再读一次，
如果是引用类型会继续调用读接口，如果不是的话程序里面自动判断返回；

	//编译器C#程序
	int RefIndex = 读接口( VarIndex, ref Type );
	return 读取方法( RefIndex );


	//单片机测试函数
	public void start()
	{
		DATA1_DDR = 0xff;
		DATA2_DDR = 0xff;
		
		iic_pack.init();
		
		addr = 0x0003;
		d1 = 0x0f;
		d2 = 0xaa;
		
		DATA1 = ref;
		
		forever {}
	}
	iic uint16 addr = [u.addr]0;
	iic uint8 d1 = [u.addr]2;
	iic uint8 d2 = [u.addr]3;
	
	iic& iic uint8 ref = [u.addr]0;
	
	[2]iic uint8 arrayiic = [u.addr]2;
	tank ttt = [u.addr]4;
	struct tank {
		iic uint8 x;
		iic uint8 y;
		[2]iic uint8 array;
	}
	[2]tank tankarray = [u.addr]0;

结构体和数组以及它们的混合类型都测试通过，下一步就差写接口了；    先去吃饭了。。。

    晚上没做什么，松波过来画图用我电脑，我就在旁边练习《夜五》，把结尾那段弹得差不多了。
现在也挺好啊，以前为什么想那么多呢？？？看她用的尺子比较旧，就送她一个新塑料尺子，
还有两个大香蕉~~~

**********************************************
修改时间:	2012年4月12日 上午 9:32

    读写接口应该没问题了，现在对于多维数组的下标运算出错，好好改下。。。

**********************************************
修改时间:	2012年4月12日 上午 11:07

    在变量定义时判断赋值类型,这样可以在定义一个引用时就把它指向某个类型:

&uint8 p => data;

    应该把引用的指向运算改为 -> 或其他形式,不用 =>, 防止和赋值运算 = 混淆;

    刚才解决函数形参的类型定义，遇到普通引用时改为系统引用，另外在GetInterface中也有
类型的直接操作，需要改回来封装一下；然后再考虑函数定义解析那里用到变量列表，看下那个
是否需要也改为系统引用；

**********************************************
修改时间:	2012年4月12日 下午 5:01

把基本类型的形参传递方式弄好了，增加了一个关键字 change，形参带有这个标志时传递的是引用，
以下是测试程序中的一个函数定义：

public dll sint32 midiOutOpen(
			uint32 lphMidiOut (change),
			uint32 uDeviceID,
			uint32 dwCallback,
			uint32 dwInstance,
			uint32 dwFlags ) {}

上面是封装的DLL函数，第一个参数带有change标志，编译器把这个变量的类型自动加上一个引用符号。

然后去掉了形参定义中的引用,全部为值类型,编译器自动判断是否加上引用前缀;

**********************************************
修改时间:	2012年4月13日 上午 9:10

    去掉函数的形参类型列表，用形参索引列表代替，因为形参索引在语法树展开之前就设置了，所以下一步
是去掉传递形参中的“function”约定，直接用索引；

-------------------------------------
    嗯,改好了.下一步是设计自写运算,即:如果以一个表达式作为一条语句时,编译器自动插入一个赋值语句,
把表达式的结果写回到表达式的第一个操作数中,这样,在语句中允许写 A + B;  A >> B; ...

以下语句具有同样的作用:
A = A + 1;
A + 1;
A += 1;
++A;

这样编译器可以去掉后两种运算,不支持 ++, -- 和 += -= 之类的运算;

-------------------------------------
    现在把上面的自写运算实现了,例如在for语句中,用 i + 1 代替 i++ , 这样写:

for( uint8 i = 0; i < 8; i + 1 ) {...}

-------------------------------------
    在运算符号表上去掉了 ++ -- += -= *= /= ....这类运算全部去掉了,所以用户无法使用这些运算了.
实际上只是在运算符号表中去掉这些,在编译器内核还是支持这些运算的,这样万一以后感觉不好,还可以再改回来;

--------------------------------------
    整理了类型系统,把引用的符号 "&" 提取出来,用字符串常量 "+" 代替,只要语法树和这个符号一致即可,
定义一个引用:

& uint8 data;  //原先的形式
+ uint8 data;  //现在的形式

--------------------------------------
    整理数组的定义,不用 [8] uint8 的形式,而用乘号:(这是内部形式,语法树中还是原先的形式,需要改一下)

[8] uint8 array;  //原先的形式
8 * uint8 array;  //现在的形式

**********************************************
修改时间:	2012年4月15日 下午 20:19

    去掉了形参定义中的 change 标志,当需要传递引用时直接用 base uint8 这种形式,在函数实参传递那里
修改一些代码,使得引用的传递正常,以前对于双层引用只是传递第一层引用的值;

**********************************************
修改时间:	2012年4月18日 下午 6:19

    以前的常量需要根据后缀判断其类型,如123s表示有符号数;  今天把常量类型设计成上下文相关的,
在有符号数运算中和无符号数运算中具有相应的类型, 首先编译器遇到常量时设置其类型为 N?,Z? 
然后在双目运算,单目运算,函数实参,函数返回,条件语句这些地方检测需要的常量类型并替换成相应的类型;
用windows程序测试通过,俄罗斯方块等;
----------------------------------------------
    用MCS51的一个弹球游戏测试刚才的常量类型自动识别,发现了一个BUG:当引用作为左值时复合运算失效,
例如:
X + 1;    //X为基本类型可以
Ref + 1;  //Ref为引用时,这个式子的计算结果不对,前几天测试那个1602液晶屏也发现这个问题... 今晚解决它
----------------------------------------------
发现原因了,ref这个变量一般是临时生成的,然后编译器把 Ref + 1; 这个语句翻译为 Ref = Ref + 1; 这时候
再把结果写回到 Ref 时由于 Ref 是临时变量导致编译器释放了 Ref 分配的空间,而 Ref + 1这个临时结果的
存放空间是 Ref 所在的地址,导致出错. 在程序中把 Ref 的 isComp 属性设为 true 就好了.

不过上面的液晶屏那段程序还是不行,看来是别的原因.
----------------------------------------------
    折腾了半天终于发现原因了,原来编译器没问题,而是在LCD1602的驱动上,在读取字节函数中,从port_in
读取数据时需要等待一段时间,要不然LCD1602反应不过来,读到的是无意义数据.  这个是在proteus里仿真
必须这样,不知道实际的硬件是否需要等待,有时间的话试验一下;

	N8 read_data()
	{
		port_dir = 0x00;
		wait();
		RS = high;
		RW = high;
		E = high;
		
		//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
		//这个延时非常重要, 需要等待LCD反应(软件仿真时)
		//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

		loop( 10 ) {}
		
		N8 data = port_in;
		E = low;
		port_dir = 0xff;
		return data;
	}

**********************************************
记录时间:	2012年4月19日 下午 3:26

    想了一些关于组合式编程语法方面的事,基本没有什么头绪...  刚才想到可以先设计一个临时的语法:
编译器根据用户配置(图形化界面)生成各个CPU通信的接口程序,用于多机编程;再生成各个元件的import代码
并包含到engine控制器元件中,然后在语法上把 "." 的形式改为空格分隔,最后就是流程词汉化和中文分词;
最关键的地方在于,是否在语法上可以把点运算设计为空格分隔,相当于在C语言中去掉结构体分量运算的那个"."

**********************************************
修改时间:	2012年4月20日 上午 10:51

    上午期末考试,考了一科<<软件设计实践>> 不会写... 交白卷了.   把编译器的语法分析改了下,去掉了
成员引用的点运算".",例如访问一个二维数组: Array 1 2 = 0; 相当于C语言: Array[1][2] = 0; 包括结构体
也可以这样使用,下一步是把函数调用的成员引用形式也改为这样,然后就可以在程序中这样写:

小车1 向前跑();
小灯1 点亮();
小灯2 熄灭();

如果进一步,去掉函数调用的小括号,并采用某种智能中文分词,程序可以写成这样:

小灯1点亮;小灯2熄灭;
如果按键A按下, ....

**********************************************
修改时间:	2012年4月21日 晚上 9:41

    彻底去掉了点运算,有些引起歧义的语法加了前缀区分,如定义一个字符串需要加上<string>标志:

6*code N8  Array = "hello";           //以前的定义方式
6*code N8  Array = <string> "hello";  //现在的定义方式

    但是这些临时修改的语法很别扭,以后还要再改回来. 发现一个问题, 以前关于语法分析总是莫名其妙
地失败,原因可能是"成员访问"和其他的"重复"语法项可以包含0项;现在改成前面有一个标志符,后面可以接
若干个词(也可以没有)------对了,其实上面的那个字符串数组不必加<string>的,语法上应该能识别,改回来试试...
----------------------------------------------
改过来了,定义字符串又不需要加上 <string>关键字了,只是改了语法树就行了.


**********************************************
修改时间:	2012年4月22日 上午 10:46

    把流程控制语句改成了类似于VB的格式

if( a>b ) { 语句 }    //以前的格式
if a>b, 语句 ...      //现在的格式, 每个语句的结尾需要有三个点 ... 作为结束符号,类似于VB中的 end;

**********************************************
修改时间:	2012年4月22日 下午 6:19

    把所有的分号语法全部改为逗号语法,例如表达式以逗号结束等等; 下午把全部程序测试通过;

**********************************************
修改时间:	2012年4月23日 晚上 8:19

    刚才把if语句的结束用简化形式表示, 如  if a > b, return. 其中返回指令用句号结束,表示if语句结束,
但是下午调试了半天一直到晚上都不行,刚才发现这里不对(已经改正了):

int ExpIndex = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
string Head = ParseNet.NodeSet[ ExpIndex ][ 0 ];
switch( Head ) {
	case ParseNet.Node.goto控制:			goto语句( ExpIndex ); return;
	case ParseNet.Node.continue控制:		continue语句( ExpIndex, ControlIndex ); return;
	case ParseNet.Node.break控制:			break语句( ExpIndex, ControlIndex ); return;
	case ParseNet.Node.return控制:			return语句( ExpIndex ); return;
	default : 					表达式语句( Index ); return;
}
其中表达式语句的索引为Index ,而其他的是ExpIndex , ...额...

（中午和松波去外边找木板做机器人模型，下午王磊打电话让去考试 ASP，算了，不去了。。。
下午想程序想得头疼，赵婷和霍义霞过来玩了会儿，晚上一个人了开始写程序，
刚刚把 if 和 for 语句的简化结束方式测试好，下一步是把其他控制语句改为可以简化结束的形式，
用句号作为语法分析。）

**********************************************
修改时间:	2012年4月24日 上午 9:52

    今天早上就开始下大雨, 天阴阴的... 本来打算把上下文表达式设置为公共环境信息，然后在表达式解析器
中根据环境信息对表达式进行不同的处理，例如 用户写 N+1，编译器自动把结果写回到变量 N 中，然后想
不好，每次调用表达式解析器都要设置环境信息，所以还是用目前这个吧。然后把 for 语句的定义改了一下，

现在的：
@for语句 --> #顺序 for @语句 @表达式 , @语句 @带结束语句列表<<<<

原来的：
@for语句 --> #顺序 for @语句 @表达式 , 无值表达式 , @带结束语句列表<<<<

去掉了"无值表达式"这个概念,这样全部的上下文处理都在"表达式语句"中处理,...不错

**********************************************
修改时间:	2012年4月24日 晚上 9:59

    把类型系统中的数组前缀去掉了,换成数组,这样向统一的类型系统进了一步,明天把变量定义语句去掉,换成
"随用随定义"的方式;

**********************************************
修改时间:	2012年4月25日 晚上 10:03

    今天把变量类型的定义格式改成后缀的, Data (N8) ... 改正了一些常量类型在形参传递,分量写入等错误;

**********************************************
修改时间:	2012年4月27日 下午 2:14

    把类型定义的引用改成 ->,以前是 + :
+N8 data,
->N8 data,
把结构体的 type 关键字放在后边,这样可以实现预计的中文语法:

    音符 类型 = [音阶(N8)，度数(N8)，节拍(N8)]，
    音符序列 ( [音符 类型 * ?] ) = [ 1,2,3, 4,5,6, 7,8,9 ],

    当前音符(->音符 类型) -> 音符序列第n个，
    音高(N8) = 当前音符的度数 * 7 + 当前音符的音阶，
    节拍(N8) = 当前音符的节拍，
    n + 1,
    如果 n==音符序列的长度，n = 0。

**********************************************
修改时间:	2012年4月28日 下午 3:00

    修改了流程语句,去掉 for while do-while 等格式,改成 反复执行 加上若干条件,

反复执行 初始..  每次..  直到../..次

一个实例:

	//等待数据包起点
	d(N8),
	反复执行 直到 d == 0xff, 初始 跳至开始, 

		//等待接收数据

		反复执行 直到 chip RI == 1, ...
		chip RI = 0,
		d = chip SBUF.

    把所有测试程序修改成了适合这个流程控制的格式; 下一步是把 if 和 switch 改成统一的格式;

**********************************************
修改时间:	2012年4月28日 晚上 10:02

    今晚上修改编译器的控制流程,打算把if语句用硬编码实现,改了一堆发现涉及到
continue等语句时不好弄,....明天再说吧.

**********************************************
修改时间:	2012年4月29日 上午 10:32

    把流程语句的解析改为程序硬解码,不再用那个流程控制列表解析;

**********************************************
修改时间:	2012年4月30日 上午 10:10

    今天是学校5月1放假第一天,...

    昨晚在操场一个人慢慢地走,一边思考多核编译的思路,毫无头绪... 呜呜

    从今天开始，准备解决编译器的另一个大问题——多核编译，就是说可以在一个记事本中写多个程序，
编译器产生多个HEX文件下载到对应的芯片中，在一个芯片中的程序可以读写另一个芯片中的变量等；

**********************************************
修改时间:	2012年5月2日 晚上 10:04

    这几天放假,思考多核编程的方案...  刚刚实现一个初步的方案:可以在一个记事本中写多个
函数,用CPU选择指令分割,然后编译生成多个hex文件,但是不支持跨核变量和函数的调用,就是说不允许
在芯片A中访问芯片B的变量和函数;目前可以AVR和mcs51混合编程,即在一个记事本中既有AVR程序又有
MCS51程序,编译器编译之后生成两个HEX文件,可以分别下载到两个芯片中,刚才测试好像不存在变量地址
分配冲突...  明天继续.

**********************************************
修改时间:	2012年5月3日 中午 12:00

    刚刚把初步的多核编译弄好,现在可以在一个记事本中写两个程序,编译器自动生成两个exe文件,都能运行;
用音乐播放器和图像处理程序测试的,把这两个程序复制粘贴到一个记事本中编译;目前临时在CodeData中
加上了一个芯片索引,当前编译哪个芯片就提供哪个芯片的数据,应该改成内置的,只需在切换芯片时
设置当前芯片序号即可,下午有时间改成这样...

**********************************************
修改时间:	2012年5月3日 晚上 10:01

今晚上程序写得头疼~~ 改了一些之后，屏幕放大镜和音乐程序放在一起又不行了！哎，然后中午的那个备份也不行，
真纠结。。。。。先回去睡觉了.

**********************************************
修改时间:	2012年5月4日 上午 10:54

    在同一个txt文件中粘贴4个程序,编译,产生4个exe文件,其中只有第一个exe文件无法正常运行;但是这个程序
在单独编译时就没问题,应该就是编译器某个小小的BUG,但是现在还没找到...好头疼,上午找了半天了...呜

**********************************************
修改时间:	2012年5月4日 下午 1:33

    终于找到原因了，呜呜呜。。。是结构体变量的地址分配出了问题，假如在同一个记事本文件中包含了
两个独立的程序（A和B），在结构体类型补全中没考虑多芯片的情况，导致在程序A中定义的结构体却在
程序B的内存空间中分配。下面是一段测试程序，把其他地方都注释了只临时定义一个结构体，才发现了问题。

//	public link unit kernel32 {}
//	public link unit user32 {}
//	public link unit gdi32 {}
//	public link unit windows {}
	type t=[d1(N8),d2(N8),]
//	link vdata code {} = ici Cloud code,
	www(->t type),
//	//起始函数
	public void start()
	{
		wc(t type),
		www -> wc,
		
//		hInstance(N32) = kernel32 GetModuleHandle[ 0 ],
//		cmd(N32) = kernel32 GetCommandLine[],
//		WinMain[ hInstance, 0, cmd, windows SW_SHOWDEFAULT ],
//		kernel32 ExitProcess[ 0 ],
	}

补充：这两天发现了一种非常好用的软件：文本比较器，可以比较出两个txt的不同之处。

**********************************************
修改时间:	2012年5月6日 下午 2:35

    修改一些小的地方。下一步是把函数的调用改为不带有中括号的，用逗号分隔，这样就把基本识别单位
减小到表达式（以逗号结尾的语句），再以后可以减小到单词，即每次读取一个词判断是什么再决定下次
怎么做；最终要减小到单个的字，涉及到中文智能分词。

**********************************************
修改时间:	2012年5月9日 下午 5:44

    放弃函数调用格式的修正了，以后再说吧。这几天在想多核编程和虚拟机，以及图形界面等，没什么头绪；
刚才把PC80X86的编译改了一下，编译器自动生成汇编中需要的inc声明，这样就不需要导入原来的include文件夹
了，去掉。编译器也少了4M左右，不错。遇到一个问题，原来的inc文件中带有后缀为A、W和不带这两个字符，
应该是表示ASCII代码和UNICODE代码格式的函数，现在把这个提高到库的DLL函数定义中，而不是依靠原来的inc文件
(原来的没法修改)，这样就可以显示汉字了，不错啊。

**********************************************
修改时间:	2012年5月11日 下午 4:10

    开始设计虚拟机，类似Java的，别再玩了。。。。
需要在编译器内核中添加一个新的CPU类型，相当于给编译器增加一个芯片移植；

    上午把类似Java的字节码弄好了，发现了一个以前的BUG：在“读取地址”这个指令中只区分了
code，static和local，实际上还有vdata，只是碰巧vdata的读取和static一样不需要加偏移量；已经改好了。

**********************************************
修改时间:	2012年5月12日

    晚上给虚拟机的字节码进行规范化，把标号和函数调用改为行号的形式，这样下一步就可以做虚拟机解释器了；
明天和李雅她们去北京十渡玩……

**********************************************
修改时间:	2012年5月14日 晚上 11:00

    今晚通宵,非要把虚拟机设计出来...  这几天什么都没干,净玩了... 今晚松波和义霞在这儿玩

**********************************************
修改时间:	2012年5月15日 上午 9:58

    昨晚通宵，其实也没怎么写程序，只是把虚拟机的框架弄了下，半夜躺地板上睡了俩小时，早上起来接着弄。刚才
顺带把中间指令弄了下，去掉“为零跳转”和“递减跳转”，已经不用了。好了接着做虚拟机。。。。还剩下
条件跳转指令和运算指令没处理。

**********************************************
修改时间:	2012年5月18日 上午 11:08

    这两天真忙, 帮10电子的同学做东西参加学校的教具设计大赛; 后天还要毕设答辩;
    上午把虚拟机做好了,可以进行循环指令测试了,下午争取把系统调用加上,就可以测试
电子琴了.

**********************************************
修改时间:	2012年5月19日 上午 9:02

    昨天下午把虚拟机解释器做好了，写了一个控制MIDI的程序，发现编译器的DLL函数有问题，由于DLL函数没有分配
形参，导致在虚拟机中给DLL函数传递的实参出错，现在改好了，可以控制MIDI发出声音了，但是整个的电子琴程序
还是不能工作，应该就是虚拟机的细节有漏洞了。

    昨晚松波李雅她们在这做东西，。。。心酸酸的，哎，算了，以后再也不会了。
----------------------------------------------
    今天早早起来到小屋子，开始！！！ 争取把虚拟机调试好。

**********************************************
修改时间:	2012年5月21日 上午 9:26

    昨天毕业答辩，OK，以后没事了。早上把小屋子好好收拾干净。开始安心做编译器。

**********************************************
修改时间:	2012年5月22日 上午 11:32

    上午把虚拟机的运算类型整理下，每个类型的运算都用显式表示，全部放到switch中，下一步是把剩下的
整理好，然后把虚拟机的CPU模型从32位改成8位，这样可以和DLL进行引用、数组等的交互；

**********************************************
修改时间:	2012年5月23日 上午 8:33

    昨晚把虚拟机改为8位模式运行,但是那个电子琴不能工作了,今天争取解决这个BUG. 

昨晚李雅过来玩，她爱看张德芬的书，就把那本<<修炼当下的力量>>给她了

--------------------------------------
下午 5:48

    下午把虚拟机的CPU模型改成long类型作为寄存器，到最后发现一点：对于虚拟机需要做有符号数的符号扩展，
而以前的接口函数全部处理为无符号数，没考虑这一点。然后纠结好长时间，发现其实没问题，
因为写系统量之后函数返回立刻执行读系统量，再执行装载操作，其中有符号扩展，所以没问题，

    晚上回来继续做... 先吃饭去了.

--------------------------------------
晚上 7:55

终于完成关键的一步了,可以在虚拟机中调用DLL,虚拟机采用8位字节模式传递参数,处理好了4字节形参的大小端约定，
传递引用时采用下面的方式（电子琴程序的一段测试代码）：

case "midiOutOpen":
uint offset = VM.BASE[ VM.DP + 0 * 4 + 0 ];
winmm.midiOutOpen( out VM.BASE[ offset ], GetValue( 1 ), GetValue( 1 ), GetValue( 2 ), GetValue( 3 ) );
break;

发现Windows的DLL函数是采用小端模式的，变量的低字节存放在低地址，高字节存放在高地址；

--------------------------------------
晚上 10:03

把函数定义格式改了下, 返回值在函数名后边,而形参在函数名前边,和C语言正好相反;
下一步是重新加入"改变"修饰符;

**********************************************
修改时间:	2012年5月25日 上午 8:08

    昨晚上可以用虚拟机写 MessageBox() 程序了

--------------------------------------
下午 2:57
    把虚拟机的CODE区和BASE区合并,但是语法上还是区分二者; 这样可以不用处理常量字符串和
变量字符串的地址区别,简化MessageBox等DLL的调用;

    刚才顺带把强制类型转换改写了下,去掉一个小BUG,在底层代码中表示为(N)_uint8_sint8;

--------------------------------------
下午 5:22

    现在可以在虚拟机中调用DLL CH375,控制小地鼠机器人前进后退,一开始只能通信一次,然后在每次
向USB发送数据后接收应答数据就可以连续通信了; 但是在C#版本的程序中并没有接收应答也能连续通信,
为什么呢?

--------------------------------------
晚上 10:02

    晚上试验了下在虚拟机中调用GDI32画图函数，应该没问题。明天在虚拟机中加上中断模块，模仿
事件处理，在虚拟机中用C#程序拦截WindProc，然后触发用户代码中的WindProc

**********************************************
修改时间:	2012年5月26日 晚上 8:08

    今天把虚拟机的中断系统做好了,下一步是设计回调函数的形参传递,用一个临时数组,主要传递
窗体回调函数的hwnd,Msg,wParam和lParam这四个参数;

    下午在6教前边的小树林傻坐了半天，看那个给花喷水的小装置一圈一圈地转……

--------------------------------------
晚上 9:36

    呜呜,彻底放弃,刚才试验了在虚拟机中运行Windows窗体很卡,打开一个窗体需要半天,WndProc函数执行
很慢,不实用. 那就在虚拟机中去掉事件响应和回调函数,由用户调用API获取键盘和鼠标信息;

**********************************************
修改时间:	2012年5月27日 上午 9:34

    上午调试虚拟机的中断系统，用中断机制代替回调函数,先用键盘和鼠标事件作为中断源，
但是各个事件混到一块了，仔细检查发现在中断列表的排序中有问题，汗。。。
用冒泡法排序，内层迭代应该从上一层的起点加1开始，这里从零开始，导致排序不对：

string[] Cut = IntSet[ ChipIndex ].TrimEnd( '\n' ).Split( '\n' );

//按照从小到大的顺序排序
for( int i = 0; i < Cut.Length - 1; ++i ) {
	int i_Number = int.Parse( Cut[ i ].Split( ' ' )[ 0 ] );

	//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	//下边这个循环原来的时候一直写成:
	//for( int j = 0; j < Cut.Length; ++j ) {
	//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

	for( int j = i + 1; j < Cut.Length; ++j ) {
		int j_Number = int.Parse( Cut[ j ].Split( ' ' )[ 0 ] );
		if( j_Number < i_Number ) {
			string Copy = Cut[ j ];
			Cut[ j ] = Cut[ i ];
			Cut[ i ] = Copy;
			i_Number = j_Number;
		}
	}
}
return Cut;


**********************************************
修改时间:	2012年5月27日 晚上 8:02

    对于未定义的中断，编译器自动插入空指令代替；

----------------------------------------------
晚上 8:17

    把中断事件改写成缓冲区形式，这样在一个事件发生时可以被另一个事件中断，
例如在鼠标进入和鼠标移动事件，只要发生鼠标进入事件就紧接着发生鼠标移动事件，导致鼠标进入事件丢失；
现在改成缓冲区就避免了这种情况，刚才测试通过，两个事件可以同时响应；KeyPress和KeyDown也互不影响；

    下一步是实现带有参数的中断函数，例如发生按键事件，会传递给中断函数一个按键码值，发生
鼠标移动则传递鼠标当前坐标。。。带有形参的中断函数；

----------------------------------------------
晚上 10:12

    设计好了带有形参的中断系统，可以在鼠标移动按键事件等直接使用传递过来的参数；

    今晚上计划通宵。。。嗯，。。。

----------------------------------------------
早上 5:12

    额。。。 晚上好冷，冻死我了。。。

把虚拟机的指令调试界面和运行界面分离成两个，以后就可以隐藏调试界面，用户用不到；
发现一个BUG，当事件产生太频繁的时候，可能冲掉上一次事件的形参，应该把形参也放在缓冲区；试试。。。

----------------------------------------------
    刚才把中断的形参也放到缓冲区中，写了一个FIFO，居然没有错误直接通过，然后开虚拟机调试器测试，鼠标
移动事件全部保存下来了没有丢失，而且鼠标移动时显示的图形非常流畅，以前的总是断断续续，可能是因为
丢失了一些鼠标移动信息，现在没问题了；

**********************************************
修改时间:	2012年5月28日 上午 9:37

    修改调试器界面，可以在调试器中对虚拟机进行单步，全速执行，暂停等控制；

----------------------------------------------
晚上 9:20

    增加了芯片名称的语法，编译生成的hex文件以芯片名称为准，不再用程序文件名；

----------------------------------------------
晚上 9:58

    今晚继续通宵。。。刚回去拿了衣服。

    关于虚拟机应该没问题了，虚拟机告一段落，开始下一个任务：集成ISP下载。。。

    计划今晚上实现编译器集成ISP下载功能，这样 编译->下载 一键执行
编译完成后自动把编译生成的hex文件下载到单片机中，争取把S51，S52，MEGA8,16,32的下载驱动弄好；

----------------------------------------------
深夜 0:07

    调试ISP下载器。发现不读芯片ID而直接下载HEX文件也行，在下载器中添加了S51，S52，MEGA8,16,32
这5种芯片，刚才试验了MEGA32和S52，可以下载HEX文件运行正常；目前对于每种芯片都是采用同一套USB
读写流程；所以芯片ID的作用应该不大吧、、、

    下一步是把ISP下载器集成到编译器中。

**********************************************
修改时间:	2012年5月29日 上午 9:49

    上午把ISP下载集成到编译器中，目前是一个独立的窗体，编译完成需要手工打开生成的hex文件去下载，
下一步是把ISP下载和编译结合起来，编译完成后自动控制ISP下载器导入生成的hex文件；

----------------------------------------------
下午 4:23

    今天把编译器的各个组件界面调整一下，初步把虚拟机和编译器整合起来，可以编译后就进行单步运行等；
把组件库列表单独放在一个窗体中，以后要把其他窗体都从主窗体中分离出来，最后主窗体只包含程序编辑界面，
成为一个普通的组件；

    刚才调试器只能执行一次，第二次执行就不能工作了，后来发现不是编译器的问题，而是那个音乐程序
在退出时没有关闭MIDI，导致第二次虚拟机运行时打开MIDI打开失败；加了一个关闭函数就好了；

**********************************************
修改时间:	2012年5月30日 晚上 10:19

    今晚继续。。。这几天干脆就住在实验室了，前天把被子和垫子都搬到实验室了。就吃饭出去。
刚才楼管大师傅过来查楼，和他打招呼，他已经默许我住这楼里了

    白天把界面部分弄了下，把各个组件分离出单独的文件夹；

    ISP下载器基本完成了，今晚上开始下一个任务：设计图形编程系统，用户可以在组件库中选择组件，
拖到工作面板上，再用导线把各个组件连接起来，例如：拖出一个LCD1602液晶屏，拖出一个AVR单片机，
然后用鼠标把液晶屏的各个引脚和单片机连接起来，点击一个“自动生成”按钮，编译器就会根据
用户的连线情况自动生成程序的配置代码，类似于C语言的“#define RS P1.3”这样的配置代码；

    开始……

----------------------------------------------
晚上 11:41

    困得不行,睡觉去...

**********************************************
修改时间:	2012年6月1日 上午 10:53

    把全部组件分离出来,相对独立.

**********************************************
修改时间:	2012年6月2日 夜里 0:38

    把图形界面的基本操作弄好了，用相机照了几个电路板照片放到界面中显示，可以用鼠标拖动这些照片；

**********************************************
修改时间:	2012年6月5日 晚上 8:25

    在图形界面中的刷新改为定时器，以前是在鼠标移动事件中，导致鼠标移动过快时画面卡住；
换成定时器就好了,图形界面很流畅;

**********************************************
修改时间:	2012年6月6日 半夜 2:41

    今晚上终于开始有点进度了，把图形界面的参数加载和保存都实现了，目前还只是坐标的；
刚才从1点开始看日记，从去年11月到今年4月，看到2点半，然后改了一个编译器小BUG，睡觉了。。。

**********************************************
修改时间:	2012年6月6日 晚上 11:08

    基本上按照组件式加载配置，每个组件有个独立的文件说明其背景图片和配置端口等；
目前未完成配置端口的读取和保存，明天继续。。。

**********************************************
修改时间:	2012年6月8日 晚上 11:58

    刚才把端口配置信息单独提取出来，放到组件列表后边，以前是在每个组件中列出端口配置信息，
这样在端口反序列化时，因为需要根据组件名称和端口名称获取端口对象，但是有些组件还没有建立，
导致出错；现在改好了，在所有组件建立之后（文本到对象列表反序列化）再进行端口对象指定；

**********************************************
修改时间:	2012年6月9日 晚上 10:08

1 把图形界面的叠加分为三层,最底层是各个组件的背景图,中间层是连接导线,最上层是端口小方块;
2 把组件的创建单独弄出来,可以传递一个配置文件路径作为参数创建,为下一步组件的动态添加做准备;

**********************************************
修改时间:	2012年6月10日 晚上 0:27

    把组件的物理拖动弄好了,当用户拖动一个组件时,遇到前方有另一个组件阻挡,则另一个组件也会被
推动,这样保证不会有某两个组件重叠到一起;

------------------------------
2012年6月10日 上午 11:56
    在图形界面中增加了右键菜单,可以重命名组件;增加删除组件按钮,下午把删除功能加上,删除时
先遍历组件列表,如果存在对选中组件的链接则给出提示,不存在则直接删除;

------------------------------
2012年6月11日 晚上 0:45
    把界面部分改了一下，在Tab标题栏显示一个红白相间的背景图片，就像工程车颜色那样，改了些
其他界面颜色部分，效果不错；  发现 红和白相容，黄和黑相容；以后要好好研究下视觉造型等等；

------------------------------
2012年6月11日 晚上 1:47
    Tab去掉未选中标签的关闭图标，只显示当前选中的标签的关闭图标；

**********************************************
修改时间:	2012年6月12日 半夜 2:01

    初步做好了组件浏览器，左边显示一个树状列表，右边显示组件图片，单击扩展名为“M”的
文件节点时右边的图形界面中就显示这个节点组件的图形，鼠标单击图形后自动关闭组件浏览器，
并在鼠标单击的当前位置创建新的组件，设置其 isNew 属性为真，这样在鼠标移动事件中做些处理，
如设置组件的坐标为鼠标坐标等；

（还有几天就毕业了，这几天一直住实验室，白天睡觉晚上写程序，生活好落魄~~~）

    今天上午两个大二音乐系的学生过来用我的电脑上校内网报选修，甄立老师也进来看见电钢
非要让弹一首，我弹了一个《夜五》，那个音乐系的同学居然说比他弹得好，呵呵
听他弹了一首《梦中的婚礼》挺不错

    好想找个学音乐的同学好好交流下，可惜就要毕业了，以后基本没有机会了。。。

**********************************************
修改时间:	2012年6月13日 半夜 0:50

    开始做组件设计器，用一些图片文件加上一些端口，用鼠标拖动调整端口位置，最后导出为
一个标准组件添加到组件库中，就可以像标准组件一样拖到面板上连线写程序了。目前刚把基本
的双缓冲显示和图片的导入、鼠标滚轮调整图片大小弄好，明天重写程序，争取明天把组件设计器
做好。

    晚上王雪带她小弟过来玩，给小孩几个贝壳逗他说话，小孩儿挺好玩

    先睡觉去了

**********************************************
修改时间:	2012年6月14日 半夜 1:31

    把组件设计器基本做好了，可以设计自定义的组件添加到组件库中，也可以双击组件类型文件名
启动组件设计器进行修改；  以*.M 扩展名表示组件类型文件，其实是文本文件，下一步是改成二进制
的文件，其中存放组件的所有信息，如背景图片等。（目前是在组件文件中内嵌背景图片文件的路径）

---------------------------------------
修改时间:	2012年6月14日 半夜 2:55

    刚才把全部的“n_Design”命名空间去掉了，换成 n_类名，最好是每个类都设置一个命名空间；

    	睡觉去...... 就喜欢敲这仨字

**********************************************
修改时间:	2012年6月14日 上午 11:05

    上午把编译器结构调整下，另外当用户打开一个文件或双击文件图标打开编译器时，编译器
自动根据文件类型启动相应的组件打开，目前支持如下几种文件：

TEST.V:		虚拟机字节码文件，调用调试器和虚拟机打开此文件并自动运行；
TEST.M:		图形组件类型文件，调用组件设计器打开此文件；
TEST.HEX:	单片机的机器码文件，调用ISP下载器打开此文件；
TEST.A/txt/...	程序文件，以及其他的记事本文件等等全部采用编译器的文本编辑器打开；

（而以前的时候不管什么文件类型全部采用文本编辑器打开的）

**********************************************
修改时间:	2012年6月15日 上午 12:01

* 上午设计了一个单片机最小系统的图形模块添加到组件库，可以使用了；
* 在图形界面的左上角添加了一个小地图，就像网络游戏中的小地图一样显示当前窗口和背景的比例；
* 增加了自动命名，用户拖出的组件自动按照 基本名+数字 的形式递增；

**********************************************
修改时间:	2012年6月17日 晚上 10:53

    下午试验了一个图形界面程序示例，在图形面板中拖出一个单片机最小系统和一个
4位数码管显示模块，用鼠标把它们连起来，编译器自动产生相应的端口配置，然后在
程序中可以直接控制数码管显示数字了。目前还不支持字节型端口，只支持位端口；

    这几天中午好热，小屋里没法待，每天下午除了睡觉就是去小树林里看书

    今晚上计划把遥控小地鼠的博客写写，再写一个介绍这个编程语言的说明文档，明天
去网吧传到博客上；



