##增加新的类型和运算 这里先增加char型和bool型。char型代表一个unicode字符,因为c的wchar_t是32位的,所以这里用i32来实现char型。char可以看成是32位整型,可以和long型或double型互相转换,可以进行数值的运算。bool型代表真假值,这里用i1来实现,只有两个值true和false。
例子:char c = 'A'; //普通字符c = '\t'; //转义字符c = '\u4e2d'; //unicode码bool b = true;b = false;
数值型(char,long,double)的运算原来只有+、-、*、/,这里增加%(求余)、>、<、==、!=、>=、<=等运算。bool型支持逻辑运算&&、||、!和比较运算==、!=。
##if-else分支 定义if-else的语法如下:
if (expression) { .....} else { .....}if (expression) { .....}
ir的br指令是实现流程控制的最重要指令,使用它来进行基本块间的跳转。br可以直接跳转,如br label %bb1
,执行过程跳转到基本块bb1上;br也可以是有条件跳转,如br i1 %cond, label %then, label %else
,如果cond等于1就跳转到基本块then上,如果等于0就跳到else上。这样代码和ir的对应关系如下:
![在此输入图片描述](http://static.oschina.net/uploads/space/2013/0314/160543_4wGB_207326.png)
使用irBuilder.CreateCondBr(condVal, thenBB, elseBB)
和irBuilder.CreateBr(outBB)
可以生成对应的指令。
##for循环 定义for循环的语法如下:
for(statement; expression; statement){ .....}
for循环也是用br来实现。它的对应比if-else的要稍微复杂些:
##局部变量 for和if-else的代码块都应该产生新的作用域,里面定义的变量外面是不可见的。在代码块里定义的变量需要分配新的内存,但显然不能在for的里面出现alloca指令,因为这样会不断的申请栈上的内存。这里的策略是把所有的栈内存分配都放在函数的开头(clang也是这样做的),所以函数的开头要有一个alloc基本块,用来插入alloca指令,这样就可以在代码块内重复的使用对应的内存。例如:
##完整代码
##例子 ####test.sp
long main(){ printL(fibonacci(10));println(); //55 printL(fibonacci(20));println(); //6765 printC('\u4e60'); printC('\u8fd1'); printC('\u5e73'); println(); return 0;}long fibonacci(long n){ if(n < 0) return 0; if(n == 0) return 0; else if(n == 1) return 1; else return fibonacci(n-1)+fibonacci(n-2);}