lua if条件语句的实现
2012-12-05 20:16
706 查看
先来看看lua if语句最简单的用法:
要分析lua如何通过词法(llex.c),语法(lparse.c),代码生成器(lcode.c)来解析上面这段代码,生成供虚拟机执行的字节码, 就得先知道这段lua代码最终究竟生成了什么模样的字节码。
先来一步步断点调试虚拟机的执行入口luaV_execute(lvm.c),发现上述代码执行流程为:
1:OP_LOADK ----> 2:OP_LE ---> 3:OP_LOADK ---> 4:OP_RETURN
就这4步。 第1步,第4步分别把3和4加载到n(加载到栈). 第4步就是退出函数了。第2步是条件语句的关键. 来看看OP_LE干了些啥工作:
(2)处拿出当前指令i的B,C操作数进行比较,与A操作数判等,如果相等就跳到PC指向的指令,从(1)看出*pc就是i的下条指令。 所以OP_JMP紧接到是OP_JMP指令,非LOADK.
如果不相等就pc指针再次加1跳过OP_JMP直接到下一条语句。所以上述简单的条件语句的虚拟字节码如下
1:OP_LOADK ----> 2:OP_LE ----> 3: OP_JMP ---> 4:OP_LOADK ---> 4:OP_RETURN
2号指令会判断条件,如果成立就再次把指令指针pc加一跳过3进入4,否则直接跳入4.
知道了if虚拟字节码接下来看看lua是怎么分析的。
if语法分析的入口:
不分析else和elseif部分,test_then_block的代码如下:
在cond中通过expr函数对表达式进行分析,也即 表达式 n > 3的分析,
下面的还真是不知道怎么组织,还是未完待续吧......
local n = 3 if n > 3 then n = 4 else n = 5 end
字节码
要分析lua如何通过词法(llex.c),语法(lparse.c),代码生成器(lcode.c)来解析上面这段代码,生成供虚拟机执行的字节码, 就得先知道这段lua代码最终究竟生成了什么模样的字节码。先来一步步断点调试虚拟机的执行入口luaV_execute(lvm.c),发现上述代码执行流程为:
1:OP_LOADK ----> 2:OP_LE ---> 3:OP_LOADK ---> 4:OP_RETURN
就这4步。 第1步,第4步分别把3和4加载到n(加载到栈). 第4步就是退出函数了。第2步是条件语句的关键. 来看看OP_LE干了些啥工作:
void luaV_execute (lua_State *L, int nexeccalls) { ... ... const Instruction i = *pc++; // (1) ... switch (GET_OPCODE(i)) { case OP_LE: { Protect( if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) // (2)B,C操作数比较多结果是否等于A操作数 dojump(L, pc, GETARG_sBx(*pc)); // 跳到指定指令 ) pc++; // 跳过OP_JMP指令 continue; ... } ... }
(2)处拿出当前指令i的B,C操作数进行比较,与A操作数判等,如果相等就跳到PC指向的指令,从(1)看出*pc就是i的下条指令。 所以OP_JMP紧接到是OP_JMP指令,非LOADK.
如果不相等就pc指针再次加1跳过OP_JMP直接到下一条语句。所以上述简单的条件语句的虚拟字节码如下
1:OP_LOADK ----> 2:OP_LE ----> 3: OP_JMP ---> 4:OP_LOADK ---> 4:OP_RETURN
2号指令会判断条件,如果成立就再次把指令指针pc加一跳过3进入4,否则直接跳入4.
知道了if虚拟字节码接下来看看lua是怎么分析的。
词法分析,代码生成
if语法分析的入口:static void ifstat (LexState *ls, int line) { /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ FuncState *fs = ls->fs; int flist; int escapelist = NO_JUMP; flist = test_then_block(ls); /* IF cond THEN block */ while (ls->t.token == TK_ELSEIF) { luaK_concat(fs, &escapelist, luaK_jump(fs)); luaK_patchtohere(fs, flist); flist = test_then_block(ls); /* ELSEIF cond THEN block */ } if (ls->t.token == TK_ELSE) { luaK_concat(fs, &escapelist, luaK_jump(fs)); luaK_patchtohere(fs, flist); luaX_next(ls); /* skip ELSE (after patch, for correct line info) */ block(ls); /* `else' part */ } else luaK_concat(fs, &escapelist, flist); luaK_patchtohere(fs, escapelist); check_match(ls, TK_END, TK_IF, line); }
不分析else和elseif部分,test_then_block的代码如下:
static int test_then_block (LexState *ls) { /* test_then_block -> [IF | ELSEIF] cond THEN block */ int condexit; luaX_next(ls); /* skip IF or ELSEIF */ condexit = cond(ls); checknext(ls, TK_THEN); block(ls); /* `then' part */ return condexit; }
static int cond (LexState *ls) { /* cond -> exp */ expdesc v; expr(ls, &v); /* read condition */ if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */ luaK_goiftrue(ls->fs, &v); return v.f; }
在cond中通过expr函数对表达式进行分析,也即 表达式 n > 3的分析,
下面的还真是不知道怎么组织,还是未完待续吧......
相关文章推荐
- If条件分支语句的实现机制
- 编写一个计算某个月份的天数程序,请用if-else条件语句实现。要求根据用户输入的月份,判断出月份所包含的天数。
- 不使用乘除法,for,while,if,else,switch,case,条件判断语句(A?B:C) 实现:1+2+....+n
- 实现1+2+3+...+n。要求不能使用乘除法,for,while,if,else,switch,case,等关键字及条件判断语句。
- MySQL 如何利用一条语句实现类似于if-else条件语句的判断
- 求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。Java实现
- 不用if、条件语句实现取较大值 未完待续...
- MySQL中根据if标签实现多条件模糊查询(动态SQL语句)
- 实现1+2+3...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)
- TensoFlow实现条件语句
- If条件判断语句21
- Java基础---Java条件语句之if(十七)
- 求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)
- [uEnv.txt]在uEnv.txt文件中使用if语句实现Image/dtb文件切换
- Java基础---Java条件语句之嵌套if(二十)
- 【Python技巧系列】条件语句一行实现
- 不用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)求1+2+…+n
- java题目:求 1+2+...+n,要求不能用除法、 for、 while、 if、 else、 switch、 case 等关键字及条件判断语句( A?B:C)。
- 第7章、if条件语句
- 2013C++-第8周项目——用if语句实现分支结构程序设计