Lua解析赋值类型代码的过程(2)

1 static void exprstat (LexState *ls) { 2 /* stat -> func | assignment */ 3 FuncState *fs = ls->fs; 4 struct LHS_assign v; 5 primaryexp(ls, &v.v); 6 if (v.v.k == VCALL) /* stat -> func */ 7 SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ 8 else { /* stat -> assignment */ 9 v.prev = NULL; 10 assignment(ls, &v, 1); 11 } 12 }

第四行的LHS_assign结构体是为了处理多变量赋值的情况的,例如a,b,c = ...。在LHS_assign中成员v类型为expdesc描述了等号左边的变量,详情可见上篇文章里对expdesc的介绍。接下来进入primaryexp,来获取并填充“foo”变量的expdesc信息,这会接着进入prefixexp函数中

1 static void prefixexp (LexState *ls, expdesc *v) { 2 /* prefixexp -> NAME | '(' expr ')' */ 3 switch (ls->t.token) { 4 case '(': { 5 int line = ls->linenumber; 6 luaX_next(ls); 7 expr(ls, v); 8 check_match(ls, ')', '(', line); 9 luaK_dischargevars(ls->fs, v); 10 return; 11 } 12 case TK_NAME: { 13 singlevar(ls, v); 14 return; 15 } 16 default: { 17 luaX_syntaxerror(ls, "unexpected symbol"); 18 return; 19 } 20 } 21 }

由于当前token是“foo”,因此进入TK_NAME分支,调用singlevar。

1 static void singlevar (LexState *ls, expdesc *var) { 2 TString *varname = str_checkname(ls); 3 FuncState *fs = ls->fs; 4 if (singlevaraux(fs, varname, var, 1) == VGLOBAL) 5 var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ 6 } 7 static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { 8 if (fs == NULL) { /* no more levels? */ 9 init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ 10 return VGLOBAL; 11 } 12 else { 13 int v = searchvar(fs, n); /* look up at current level */ 14 if (v >= 0) { 15 init_exp(var, VLOCAL, v); 16 if (!base) 17 markupval(fs, v); /* local will be used as an upval */ 18 return VLOCAL; 19 } 20 else { /* not found at current level; try upper one */ 21 if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) 22 return VGLOBAL; 23 var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ 24 var->k = VUPVAL; /* upvalue in this level */ 25 return VUPVAL; 26 } 27 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/bf7705818895345d97148c7a2e76ddb0.html