while
语句的语义是这样定义的:
while(
表达式
)
语句
1
当表达式为非
0
值时执行
while
语句中的内嵌语句
1
。其特点就是先判断表达式的值,然后再执行语句。
LCC
是通过下面的代码来处理这个语句的:
#015 case WHILE:
#016 whilestmt(genlabel(3), swp, lev + 1);
#017 break;
上面第
16
行语句里,第一个参数
genlabel(3)
是指
while
语句使用三个标号。第二参数
swp
是指明是否在
switch
语句里。第三个参数是指明递归调用次数。
然后调用函数
whilestmt
处理。
#001 static void whilestmt(int lab, Swtch swp, int lev)
#002 {
#003 Coordinate pt;
#004 Tree e;
#005
#006 refinc *= 10.0;
#007 t = gettok();
#008 expect('(');
第
7
行获取下一个记号。
第
8
行测试下一个是否左括号开始。
#009 walk(NULL, 0, 0);
#010 pt = src;
#011 e = texpr(conditional, ')', FUNC);
第
9
行是复位分配的内存。
第
10
行是保存当前源程序位置。
第
11
行是调用函数
conditional
来处理条件表达式。
#012 branch(lab + 1);
#013 definelab(lab);
#014 statement(lab, swp, lev);
#015 definelab(lab + 1);
#016 definept(&pt);
#017 walk(e, lab, 0);
#018 if (findlabel(lab + 2)->ref)
#019 definelab(lab + 2);
#020 }
第
12
行是处理标号
2
分支。
第
13
行是定义标号
1
。
第
14
行是处理语句
1
。
第
15
行是定义标号
2.
第
16
行是定义执行点。
第
17
行是对条件表达式生成
DAG
代码。
第
18
行是判断是否需要生成标号
3
。
while
语句最终生成的汇编代码有下面的形式:
跳转到
标号
2
标号
1
:语句
1
标号
2
:如果
条件表达式不等于
0
就跳转到标号
1
运行
标号
3
:
上面的标号
3
是为了方便里面有跳转语句跳出循环体的,比如使用
goto
、
break
、
return
等等,就需跳到标号
3
运行。