lua源码注释 lparse.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
/* 参考的BNF地址 shankusu.me/lua/TheCompleteSyntaxOfLua51/ */
/*
** $Id: lparser.c,v 2.42.1.4 2011/10/21 19:31:42 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/


#include <string.h>
#include <stdio.h>

#define lparser_c
#define LUA_CORE

#include "lua.h"

#include "lcode.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "llex.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"


/* 也只有函数调用或变参操作符这两种TOKEN能返回 ... */
#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)

/* i:当前活跃的locvar的索引 */
#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])

/* 检查value是否超过了limit限制,超过则报错msg */
#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)


/*
** nodes for block list (list of active blocks)
** previous:往前跳(eg:查找变量时从now-block往前一级一级的block找)
*/
typedef struct BlockCnt {
struct BlockCnt *previous; /* chain */
int breaklist; /* list of jumps out of this loop */

/*
** !!!!在进入本block的瞬间,外面已经激活的var的数量, !!!!
** 意味着本块内激活的locvar的reg.idx不会低于整个值,
** 用于按照便变量的生存期检索变量
** 退出本block后,将fs->reg重置到本次即可清掉本block内激活的actvar
*/
lu_byte nactvar; /* # active locals outside the breakable structure */

lu_byte upval; /* true if some variable in the block is an upvalue(本块中存在某些变量是其它块的upvalues:本块关闭时要做善后处理?) */
lu_byte isbreakable; /* true if `block' is a loop, 语法规则:break仅能用于loop的block中 */
} BlockCnt;



/*
** prototypes for recursive non-terminal functions
*/
static void chunk (LexState *ls);
static void expr (LexState *ls, expdesc *v);

/* anchor:锚 */
static void anchor_token (LexState *ls) {
if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
TString *ts = ls->t.seminfo.ts;
luaX_newstring(ls, getstr(ts), ts->tsv.len);
}
}


static void error_expected (LexState *ls, int token) {
luaX_syntaxerror(ls,
luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token)));
}


static void errorlimit (FuncState *fs, int limit, const char *what) {
const char *msg = (fs->f->linedefined == 0) ?
luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
fs->f->linedefined, limit, what);
luaX_lexerror(fs->ls, msg, 0);
}


static int testnext (LexState *ls, int c) {
if (ls->t.token == c) {
luaX_next(ls);
return 1;
}
else return 0;
}

/* 检查当前c是否为特定的token'Type */
static void check (LexState *ls, int c) {
if (ls->t.token != c)
error_expected(ls, c);
}

static void checknext (LexState *ls, int c) {
check(ls, c);
luaX_next(ls);
}


#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }


/* 在where(line)这里,who(TK.1)需要一个what(TK.2)匹配
** eg: function 需要一个end来结束函数定义
*/
static void check_match (LexState *ls, int what, int who, int where) {
if (!testnext(ls, what)) {
if (where == ls->linenumber) /* 当前行,那就不需要打印line信息了? */
error_expected(ls, what);
else {
/* 输出连带line信息的错误信息 */
luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
LUA_QS " expected (to close " LUA_QS " at line %d)",
luaX_token2str(ls, what), luaX_token2str(ls, who), where));
}
}
}

/*
** 强制检查并当前token的type为TK_NAME,返回当前token,
** 读取下一个token
*/
static TString *str_checkname (LexState *ls) {
TString *ts;
check(ls, TK_NAME); /* 当前token'type必须是TK_NAME的类型 */
ts = ls->t.seminfo.ts; /* 提取token的值 */
luaX_next(ls); /* 继续读下一个token */
return ts;
}

/* KEYCODE: 关键函数 */
static void init_exp (expdesc *e, expkind k, int i) {
e->f = e->t = NO_JUMP;

/*
************************************exp对应的reg已定或是一个参数无需reg*********************************
** VVOID, VKNUM, VNIL, VTRUE, VFALSE, i:0 值直接被包含在表达式expdesc中,无需寄存器
** VK i:常量表中的索引
** VLOCAL i:locvar占用的reg索引
** VGLOBAL i:NO_REG->全局变量名的NAME在常量表中的索引
**
**
***********************************需回填指令的RA?**********************************
** VRELOCABLE i:?对应指令OP在指令数组中的下标(方便回填指令中的RA?)?
** VCALL, VVARARG i:对应指令OP在指令数组中的下标(方便回填指令中的RA?)
**
** VNONRELOC i:对应指令OP在指令数组的下标(方便回填指令中的RA?)
*/
e->k = k;
e->u.s.info = i;
}

/* 用字符串(TK_NAME)s初始化expdesc的e表达式 */
static void codestring (LexState *ls, expdesc *e, TString *s) {
init_exp(e, VK, luaK_stringK(ls->fs, s));
}

/* 先检查当前t的类型为NAME,后将其携带的string赋值给expdesc, 内部读取一次luaX_next() */
static void checkname(LexState *ls, expdesc *e) {
codestring(ls, e, str_checkname(ls));
}

/*
** 填充一个全新的 Locvar信息到 Proto.locvars (供调试用)
*/
static int registerlocalvar (LexState *ls, TString *varname) {
FuncState *fs = ls->fs;
Proto *f = fs->f;
int oldsize = f->sizelocvars;

/* 原来的总数组f->sizelocvars空间不足则扩大 */
luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
LocVar, SHRT_MAX, "too many local variables");

while (oldsize < f->sizelocvars) /* locvars数组扩大则将新增的slot填NULL */
f->locvars[oldsize++].varname = NULL;

/* 更新locvar信息, startPC,endPC暂时还不确定 */
f->locvars[fs->nlocvars].varname = varname;
/* printf("registerlocalvar: idx(%d), name(%p)\n", fs->nlocvars, varname); */
luaC_objbarrier(ls->L, f, varname);
return fs->nlocvars++;
}

/* 如果v是不变的string则此宏定义可以利用宏处理阶段提高程序速度 */
#define new_localvarliteral(ls,v,n) \
new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n)

/* KEYCODE
** 注册一个本地变量信息到 Proto.locvars ,
** 填充变量名, startpc,endpc稍后再处理
**
*/
static void new_localvar (LexState *ls, TString *name, int n) {
FuncState *fs = ls->fs;
luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables");
/* 设置actvar 到 Proto.nlocvars 的映射 */
/* 这里仅设置了变量的name, 尚未设置startpc,endpc */
fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name));
//printf("......... %d->%d", fs->nactvar+n, fs->actvar[fs->nactvar+n]);
}

/*
** 更新!!! FunState.nactvar 数量,更新 Proto.locvars.startpc
** 一次性生成多个locvar时,nvars可以告诉本函数方便一次性调整到位
*/
static void adjustlocalvars (LexState *ls, int nvars) {
FuncState *fs = ls->fs;

/* 更新fs中当前激活的locvar数量 */
/* 更新fs中当前激活的locvar数量 */
/* 更新fs中当前激活的locvar数量 */
fs->nactvar = cast_byte(fs->nactvar + nvars);

/* 更新localvar的startpc */
for (; nvars; nvars--) {
getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
/* 对应的chunk结束时,再更新endpc信息,也只有那个时候才能确切的知道endpc */
}
}

/* 确定一批actvar的endpc
** 仔细看这个函数,很有意思哈(结合 new_localvar adjustlocalvars 一起看 )
*/
static void removevars (LexState *ls, int tolevel) {
FuncState *fs = ls->fs;
while (fs->nactvar > tolevel) /* 这里tolevel是指block结束时对应的pc.idx */
getlocvar(fs, --fs->nactvar).endpc = fs->pc; /* 离开block时,关闭block内actvar */
}

/* 查找一个upvalue,返回其在upval数组中的索引,没有则构建 */
static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
int i;
Proto *f = fs->f;
int oldsize = f->sizeupvalues;
/* 当前存在的upvalue中已存在吗? */
for (i=0; i<f->nups; i++) {
if (fs->upvalues[i].k == v->k && /* 类型为VUPVAL */
fs->upvalues[i].info == v->u.s.info) { /* 在proto中的索引一致 */
lua_assert(f->upvalues[i] == name); /* 名字就必须一致了 */
return i;
}
}

/* new one */

/* 数组容量不够则扩大 */
luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues");
luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
TString *, MAX_INT, "");
while (oldsize < f->sizeupvalues)
f->upvalues[oldsize++] = NULL;

f->upvalues[f->nups] = name;
luaC_objbarrier(fs->L, f, name);
lua_assert(v->k == VLOCAL || v->k == VUPVAL); /* 这里的v->k==VLOCAL ? */
/* 更新到fs */
fs->upvalues[f->nups].k = cast_byte(v->k);
fs->upvalues[f->nups].info = cast_byte(v->u.s.info);
return f->nups++;
}

/* 尝试在当前fs中匹配激活状态的locvar */
static int searchvar (FuncState *fs, TString *n) {
int i;
for (i=fs->nactvar-1; i >= 0; i--) {
if (n == getlocvar(fs, i).varname)
return i;
}
return -1; /* not found */
}

/* fs中的locvar在其它函数中被当作upval引用
** 标记fs中对应的block,你有变量是其它fs的upval
** level:actvar在reg数组中的索引
*/
static void markupval (FuncState *fs, int level) {
BlockCnt *bl = fs->bl;
/* 这个标记过程的逻辑蛮有意思的 */
while (bl && bl->nactvar > level)
bl = bl->previous;
if (bl)
bl->upval = 1;
}

/* 查找变量名对应的表达式类型的值类型(VLOCAL还是?)
**
** 仔细看这个函数的逻辑,搞明白关于变量的查找过程
** step1:先在本地fs6激活中的locvar查找,找到则返回VLOCAL
** step2:往前一个fs5中的激活中的locvar查找,找不到,继续下一步step3
** step3:继续往前一个fs1中的激活的locvar查找,一直到fs1->pre为空,则
** 可以确定var是一个VGLOBAL
** step4:在某一个fs3中的激活中的locvar被找到,则标记此fs3中的bl表示你的某个var被其它fsX当作upval了
** 往前退,在fs4中的upval中新增一条信息(此upval在父fs3中是VLOCAL,且在fs3的actvar中的索引是多少)
** 再往前退,在fs5中的upval中新增一条信息(此upval在父fs4中是UPVAL,且在fs4的upvalues的索引是多少)
** 再往前退,直到初始的fs6,在fs6中的upval中新增一条信息(此upval在父fs5中是UPVAL,且在fs5的upvalues的索引是多少)
**
** 理论上可以优化下:在本地locvar找不到时,先不要在父fs中找,而是在本fs的upvales中找下
*/
static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
if (fs == NULL) { /* no more levels? */
/* default is global variable, NO_REG:表示此全局变量尚未决定其寄存器的位置
** 全局变量对应的NAME在p中常量表的索引由singlevar()函数来处理
*/
init_exp(var, VGLOBAL, NO_REG);
return VGLOBAL; /* 往外一层一层都找不到时,则认为它是全局变量 */
}
else {
/* 在激活的locvar中找到了,则是本地变量 */
int v = searchvar(fs, n); /* look up at current level */
if (v >= 0) {
init_exp(var, VLOCAL, v);
if (!base)
markupval(fs, v); /* local will be used as an upval */
return VLOCAL;
}
else { /* not found at current level; try upper one */
if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) /* 都没找到,则是全局变量 */
return VGLOBAL;
/* 父func中找到,在自己的fun中算upval */
var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */
var->k = VUPVAL; /* upvalue in this level */
return VUPVAL;
}
}
}

/*
** step1: 检查ls->t.token的类型为TK_NAME,读取下一个TOKEN
** step2: 根据上一个token的NAME,确定其变量(VLOCAL,VGLOBAL还是VUPVAL?)类型,
** 后填充expdesc.u.s.info信息
*/
static void singlevar (LexState *ls, expdesc *var) {
TString *varname = str_checkname(ls);
FuncState *fs = ls->fs;

/*
** OP_GETGLOBAL A Bx R(A) := Gbl[Kst(Bx)]
** OP_SETGLOBAL A Bx Gbl[Kst(Bx)] := R(A)
** 全局变量的指令需要知道表示全局变量的NAME在常量表中的idx,
** 理解这一点就明白了下面var->u.s.info的赋值的意义
*/
if (singlevaraux(fs, varname, var, 1) == VGLOBAL) { /* VLOCVAR,VUPVAL在singlevaraux中已被init_exp初始化 */
var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */
}
}

/* 针对 nvars = nexps 赋值进行调整
** 如果右边少了则给左边赋NIL
** 如果右边有call,...则确定期待的返回值个数
**
** !!! 如果右边多了,本函数未处理!!!
*/
static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
FuncState *fs = ls->fs;
/* extra: 右边除掉fun和...外,表达式的数量少于左边的val的数量的情况下,缺失的数量? */
int extra = nvars - nexps;
if (hasmultret(e->k)) { /* exp的类型为VARARG或CALL */
extra++; /* includes call itself:除开VARARG和CALL本身 */
/* 如果右边exp多了,那就不用补偿左边了
** OP_VARARG A B R(A), R(A+1), ..., R(A+B-1) = vararg
** 看上面的指令的含义,猜测这里是在确定B的值
*/
if (extra < 0) extra = 0;

luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
if (extra > 1) luaK_reserveregs(fs, extra-1);
}
else {
if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
if (extra > 0) { /* nexps:包含右边最后一个exp */
int reg = fs->freereg;
/* 为左边多出来的var申请reg,然后填NIL */
luaK_reserveregs(fs, extra);
luaK_nil(fs, reg, extra);
}
}
}

/* 进入一个新的block */
static void enterlevel (LexState *ls) {
if (++ls->L->nCcalls > LUAI_MAXCCALLS)
luaX_lexerror(ls, "chunk has too many syntax levels", 0);
}


#define leavelevel(ls) ((ls)->L->nCcalls--)

/* 进入块时,初始化block信息 */
static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
bl->breaklist = NO_JUMP;
bl->isbreakable = isbreakable;
bl->nactvar = fs->nactvar;
bl->upval = 0;

/* 这里有个印象 */
bl->previous = fs->bl;
fs->bl = bl;

lua_assert(fs->freereg == fs->nactvar);
}


static void leaveblock (FuncState *fs) {
BlockCnt *bl = fs->bl;
fs->bl = bl->previous;

/* 确定本block内激活的var的生存周期的endpc */
removevars(fs->ls, bl->nactvar);

/* OP_CLOSE A close all variables in the stack up to (>=) R(A) */
if (bl->upval) {
luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
}

/* a block either controls scope or breaks (never both) */
lua_assert(!bl->isbreakable || !bl->upval); /* TODOLOOK 还不是太理解 */

lua_assert(bl->nactvar == fs->nactvar); /* 这个必须保证 */
fs->freereg = fs->nactvar; /* free registers */

luaK_patchtohere(fs, bl->breaklist);
}


static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
FuncState *fs = ls->fs;
Proto *f = fs->f;
int oldsize = f->sizep;
int i;
luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
MAXARG_Bx, "constant table overflow");
while (oldsize < f->sizep) f->p[oldsize++] = NULL;
f->p[fs->np++] = func->f;
luaC_objbarrier(ls->L, f, func->f);
init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
for (i=0; i<func->f->nups; i++) {
OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; /* TODOLOOK 这里不是明白 */
luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
}
}

/* 开始编译函数 */
static void open_func (LexState *ls, FuncState *fs) {
lua_State *L = ls->L;

fs->L = L;
Proto *f = luaF_newproto(L);
fs->ls = ls;
fs->f = f; /* funState 在编译哪个Proto */

/* ls指向最新的一个FuncState,这里可以猜测,只有先编译完了子函数才有可能编译父函数 */
fs->prev = ls->fs; /* linked list of funcstates */
ls->fs = fs;

fs->pc = 0;
fs->lasttarget = -1;
fs->jpc = NO_JUMP;
fs->freereg = 0;
fs->nk = 0;
fs->np = 0;
fs->nlocvars = 0;
fs->nactvar = 0;
fs->bl = NULL; /* 这里是NULL */
f->source = ls->source;
f->maxstacksize = 2; /* registers 0/1 are always valid */
fs->h = luaH_new(L, 0, 0);

/* anchor table of constants and prototype (to avoid being collected)
** 常量和原型的锚表(避免被收集)
*/
sethvalue2s(L, L->top, fs->h);
incr_top(L); /* 放到堆栈上可避免被gc,如果编译失败stack回缩,则可自动被gc(没有被其它obj引用的话 ) */
setptvalue2s(L, L->top, f);
incr_top(L);

}


static void close_func (LexState *ls) {
lua_State *L = ls->L;
FuncState *fs = ls->fs;
Proto *f = fs->f;

/* 关闭还处于激活状态的actvar(设置endpc) */
removevars(ls, 0);

/* 自动补一个 OP_RETURN 指令 */
luaK_ret(fs, 0, 0); /* final return */

/* 释放多余的mem */
luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
f->sizecode = fs->pc;

luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
f->sizelineinfo = fs->pc;

luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
f->sizek = fs->nk;

luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
f->sizep = fs->np;

luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
f->sizelocvars = fs->nlocvars;

luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
f->sizeupvalues = f->nups;

lua_assert(luaG_checkcode(f)); /* 检查生成的字节码是否有明显的问题 */
lua_assert(fs->bl == NULL);

/* 本子函数编译完毕,切换到母函数中去 */
ls->fs = fs->prev;

/* last token read was anchored(锚定) in defunct function; must reanchor(锚) it */
if (fs) anchor_token(ls);
L->top -= 2; /* remove table and prototype from the stack */
}


Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
struct LexState lexstate;
struct FuncState funcstate; /* mainFunc */

lexstate.buff = buff;
/* 设置input信息,但,buff在上面就设置了,有点意思吧,z和buff对于lexState是有点不同的 */
luaX_setinput(L, &lexstate, z, luaS_new(L, name));

/* 一个lua文件,编译模块将其当做一个函数来看待
** 函数原型 function (...)
** end
**
** BNF funcbody ::= `(´ [parlist] `)´ block end
*/
open_func(&lexstate, &funcstate);
funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg,哈哈知道lua文件一般开头的local modName=...的语法支撑了吧 */
luaX_next(&lexstate); /* read first token */
chunk(&lexstate);
check(&lexstate, TK_EOS); /* 直到编译到文件EOF才结束编译流程 */
close_func(&lexstate);

lua_assert(lexstate.fs == NULL); /* lexstate下不应该还有未编译完的funState了 */
lua_assert(funcstate.prev == NULL); /* 已编译完的主函数上面还有其它函数,不可能的嘛 */
lua_assert(funcstate.f->nups == 0); /* 编译结束,主函数不应该有nups了 */
return funcstate.f;
}



/*============================================================*/
/* GRAMMAR RULES */
/*============================================================*/

/* A.B, A:B
** 对前缀生成必要的估值指令,放入free'reg(若有必要)
** 用上述值作为A,再和B一起生成新的VINDEXED表达式
*/
static void field (LexState *ls, expdesc *v) {
/* field -> ['.' | ':'] NAME */
FuncState *fs = ls->fs;
expdesc key;

/*
**将前缀(a.b.c中的a.b)加载到reg中
**若前缀已在寄存器中则无需处理(A=VLOCAL(a))
*/
luaK_exp2anyreg(fs, v);

luaX_next(ls); /* skip the dot or colon */

checkname(ls, &key); /* 读取NAME这个域的常量exp并返回给key */

/* 生成新的VINDEXED表达式(求值指令,指令的目标寄存器尚未处理) */
luaK_indexed(fs, v, &key);
}


static void yindex (LexState *ls, expdesc *v) {
/* index -> '[' expr ']' */
luaX_next(ls); /* skip the '[' */
expr(ls, v);
luaK_exp2val(ls->fs, v);
checknext(ls, ']');
}


/*
** {======================================================================
** Rules for Constructors
** =======================================================================
*/

/* 构造表 tbl {a, b, c=val, d.e} */
struct ConsControl {
expdesc *t; /* table descriptor 指代本表的expdesc */
expdesc v; /* last list item read: 指代正在分析到的哪一个元素eg(b),对于c=val用不上v */
int nh; /* total number of `record' elements */
int na; /* total number of array elements */
int tostore; /* number of array elements pending to be stored */
};

/* 形如 local tbl = { x = y, [a] = b,}
** 中的x=1,这种指定tbl[k]=v的表达式
*/
static void recfield (LexState *ls, struct ConsControl *cc) {
/* recfield -> (NAME | `['exp1`]') = exp1 */
FuncState *fs = ls->fs;
int reg = ls->fs->freereg;
expdesc key, val;
int rkkey;

/* 对key生成加载指令 */
if (ls->t.token == TK_NAME) {
luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
checkname(ls, &key);
}
else /* ls->t.token == '[' */
yindex(ls, &key);

cc->nh++;
checknext(ls, '=');
/* 回填上述k的加载指令,将表达式的值SET到next'free'reg上 */
rkkey = luaK_exp2RK(fs, &key);

/* 初始化表达式val */
expr(ls, &val);
/* 先生成对val的LOAD_XXX加载指令,后生成OP_SETTABLE */
luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val));

fs->freereg = reg; /* free registers 释放表达式占用的临时寄存器 */
}

/* local tbl = {a,b,c,d}
** 解析完毕b,关闭对b的解析
*/
static void closelistfield (FuncState *fs, struct ConsControl *cc) {
if (cc->v.k == VVOID) return; /* there is no list item */
luaK_exp2nextreg(fs, &cc->v);
cc->v.k = VVOID; /* 释放表达式 */
if (cc->tostore == LFIELDS_PER_FLUSH) {
luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */
cc->tostore = 0; /* no more items pending */
}
}

/* local tbl = {a, b, c, d}
** 结束d的解析后,调到这里
** 逻辑独立出来是因为函数调用作为表的最后一个元素和非最后一个元素,其期望对其返回值的个数是不一样的
*/
static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
if (cc->tostore == 0) return;
if (hasmultret(cc->v.k)) {
luaK_setmultret(fs, &cc->v);
luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET);
cc->na--; /* do not count last expression (unknown number of elements) */
}
else {
if (cc->v.k != VVOID)
luaK_exp2nextreg(fs, &cc->v);
luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore);
}
}

/* tbl = {a,b, c = 100} 数组中单个field eg:a
*/
static void listfield (LexState *ls, struct ConsControl *cc) {
expr(ls, &cc->v);
luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
cc->na++;
cc->tostore++;
}

static void constructor (LexState *ls, expdesc *t) {
/* constructor -> ?? */
FuncState *fs = ls->fs;
int line = ls->linenumber;

int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
struct ConsControl cc;
cc.na = cc.nh = cc.tostore = 0;
cc.t = t;

/* 初始化table的exp */
init_exp(t, VRELOCABLE, pc);

init_exp(&cc.v, VVOID, 0); /* no value (yet) */

luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
checknext(ls, '{');
do {
lua_assert(cc.v.k == VVOID || cc.tostore > 0);
if (ls->t.token == '}') break; /* 表被遍历完毕 */
closelistfield(fs, &cc);
switch(ls->t.token) {
case TK_NAME: { /* may be listfields or recfields */
luaX_lookahead(ls);
if (ls->lookahead.token != '=') /* expression? */
listfield(ls, &cc);
else
recfield(ls, &cc);
break;
}
case '[': { /* constructor_item -> recfield */
recfield(ls, &cc);
break;
}
default: { /* constructor_part -> listfield */
listfield(ls, &cc);
break;
}
}
} while (testnext(ls, ',') || testnext(ls, ';'));
check_match(ls, '}', '{', line);
lastlistfield(fs, &cc);
SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
}

/* }====================================================================== */


/*
** 解析函数的显式形参列表(对于modName:sub(x,y) 这种隐含的第一个self参数,在外面已被解析完毕
*/
static void parlist (LexState *ls) {
/* parlist -> [ param { `,' param } ] */
FuncState *fs = ls->fs;
Proto *f = fs->f;
int nparams = 0;
f->is_vararg = 0;
if (ls->t.token != ')') { /* is `parlist' not empty? */
do {
switch (ls->t.token) {
case TK_NAME: { /* param -> NAME */
new_localvar(ls, str_checkname(ls), nparams++);
/* adjustlocalvars 在下面调用:一次性调整到位 */
break;
}
case TK_DOTS: { /* param -> `...' */
luaX_next(ls);
#if defined(LUA_COMPAT_VARARG)
/* use `arg' as default name */
new_localvarliteral(ls, "arg", nparams++);
f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
#endif
f->is_vararg |= VARARG_ISVARARG;
break;
}
default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
}
} while (!f->is_vararg && testnext(ls, ',')); /* 这里看得出来 ... 只能是最后一个形参 */
}else {
// function name() body end 显式形参为空
}

adjustlocalvars(ls, nparams);
f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG));
luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
}

/* 解析函数形参和函数体 */
static void body (LexState *ls, expdesc *e, int needself, int line) {
/* body -> `(' parlist `)' chunk END */
FuncState new_fs;

/* 更新ls中的fs变量,完成编译对象的切换 */
open_func(ls, &new_fs);

/* 新函数从哪一方开始定义 */
new_fs.f->linedefined = line;

/* local name = function () 或者 local function name() 这两种函数定义格式对应的函数都是从‘(’开始,*/
checknext(ls, '(');

/* 这里看得出来self将是本fs的第一个locvar,占用一个正常的locvar
** Proto.numparams 中也包含self
*/
if (needself) { /* 处理 function modName:sub() body end 这种情况,参考funcname()代码可知 */
new_localvarliteral(ls, "self", 0);
adjustlocalvars(ls, 1);
}
/* 解析显式形参 */
parlist(ls);

checknext(ls, ')');

chunk(ls);

/* 函数定义结束于哪一行 */
new_fs.f->lastlinedefined = ls->linenumber;

check_match(ls, TK_END, TK_FUNCTION, line);

close_func(ls);

pushclosure(ls, &new_fs, e);
}

/* 解析表达式,返回表达式中的项的数量 */
static int explist1 (LexState *ls, expdesc *v) {
/* explist1 -> expr { `,' expr } */
int n = 1; /* at least one expression */
expr(ls, v);
while (testnext(ls, ',')) {
luaK_exp2nextreg(ls->fs, v);
expr(ls, v);
n++;
}
return n;
}

/* funcargs -> `(' [ explist1 ] `)' | constructor | STRING */
static void funcargs (LexState *ls, expdesc *f) {
FuncState *fs = ls->fs;
expdesc args;
int base, nparams;
int line = ls->linenumber;
switch (ls->t.token) {
case '(': { /* funcargs -> `(' [ explist1 ] `)' */
if (line != ls->lastline)
luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
luaX_next(ls);
if (ls->t.token == ')') /* arg list is empty? */
args.k = VVOID;
else {
explist1(ls, &args);
luaK_setmultret(fs, &args);
}
check_match(ls, ')', '(', line);
break;
}
case '{': { /* funcargs -> constructor */
constructor(ls, &args);
break;
}
case TK_STRING: { /* funcargs -> STRING */
codestring(ls, &args, ls->t.seminfo.ts);
luaX_next(ls); /* must use `seminfo' before `next' */
break;
}
default: {
luaX_syntaxerror(ls, "function arguments expected");
return;
}
}
lua_assert(f->k == VNONRELOC);
base = f->u.s.info; /* base register for call */
if (hasmultret(args.k))
nparams = LUA_MULTRET; /* open call */
else {
if (args.k != VVOID)
luaK_exp2nextreg(fs, &args); /* close last argument */
nparams = fs->freereg - (base+1);
}
init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
luaK_fixline(fs, line);
fs->freereg = base+1; /* call remove function and arguments and leaves
(unless changed) one result */
}




/*
** {======================================================================
** Expression parsing
** =======================================================================
*/


static void prefixexp (LexState *ls, expdesc *v) {
/* prefixexp -> NAME | '(' expr ')' */
switch (ls->t.token) {
case '(': {
int line = ls->linenumber;
luaX_next(ls);
expr(ls, v);
check_match(ls, ')', '(', line);
luaK_dischargevars(ls->fs, v);
return;
}
case TK_NAME: {
/* 确定当前ls->t.token的变量类型(VLOCAL,VGLOBAL还是VUPVAL?)
** 填充expdesc.u.s.info信息
** 读取下一个Token
*/
singlevar(ls, v);
return;
}
default: {
luaX_syntaxerror(ls, "unexpected symbol");
return;
}
}
}

/* primary:基本的 */
static void primaryexp (LexState *ls, expdesc *v) {
/* primaryexp -> prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
FuncState *fs = ls->fs;

prefixexp(ls, v);

for (;;) {
switch (ls->t.token) {
case '.': { /* field */
field(ls, v);
break;
}
case '[': { /* `[' exp1 `]' */
expdesc key;
luaK_exp2anyreg(fs, v);
yindex(ls, &key);
luaK_indexed(fs, v, &key);
break;
}
case ':': { /* `:' NAME funcargs */
expdesc key;
luaX_next(ls);
checkname(ls, &key);
luaK_self(fs, v, &key);
funcargs(ls, v);
break;
}
case '(': case TK_STRING: case '{': { /* funcargs 函数调用 */
luaK_exp2nextreg(fs, v);
funcargs(ls, v);
break;
}
default: return;
}
}
}

/* 对表达式进行初始化,间接表达式则生成求src.val的指令, 等待回填dst.reg */
static void simpleexp (LexState *ls, expdesc *v) {
/* simpleexp -> NUMBER | STRING | NIL | true | false | ... |
constructor | FUNCTION body | primaryexp */
switch (ls->t.token) {
case TK_NUMBER: {
init_exp(v, VKNUM, 0);
v->u.nval = ls->t.seminfo.r; /* 直接赋值NUMBER */
break;
}
case TK_STRING: {
codestring(ls, v, ls->t.seminfo.ts);
break;
}
case TK_NIL: {
init_exp(v, VNIL, 0);
break;
}
case TK_TRUE: {
init_exp(v, VTRUE, 0);
break;
}
case TK_FALSE: {
init_exp(v, VFALSE, 0);
break;
}
case TK_DOTS: { /* vararg */
FuncState *fs = ls->fs;
check_condition(ls, fs->f->is_vararg,
"cannot use " LUA_QL("...") " outside a vararg function");
fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
break;
}
case '{': { /* constructor */
constructor(ls, v);
return;
}
case TK_FUNCTION: {
luaX_next(ls);
body(ls, v, 0, ls->linenumber);
return;
}
default: {
primaryexp(ls, v);
return;
}
}
luaX_next(ls);
}

/* 返回TK可能的一元操作符TK */
static UnOpr getunopr (int op) {
switch (op) {
case TK_NOT: return OPR_NOT;
case '-': return OPR_MINUS;
case '#': return OPR_LEN;
default: return OPR_NOUNOPR;
}
}


static BinOpr getbinopr (int op) {
switch (op) {
case '+': return OPR_ADD;
case '-': return OPR_SUB;
case '*': return OPR_MUL;
case '/': return OPR_DIV;
case '%': return OPR_MOD;
case '^': return OPR_POW;
case TK_CONCAT: return OPR_CONCAT;
case TK_NE: return OPR_NE;
case TK_EQ: return OPR_EQ;
case '<': return OPR_LT;
case TK_LE: return OPR_LE;
case '>': return OPR_GT;
case TK_GE: return OPR_GE;
case TK_AND: return OPR_AND;
case TK_OR: return OPR_OR;
default: return OPR_NOBINOPR;
}
}

/* 操作符的优先级分左右:用于处理结合性? */
static const struct {
lu_byte left; /* left priority for each binary operator */
lu_byte right; /* right priority */
} priority[] = { /* ORDER OPR */
{6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
{10, 9}, {5, 4}, /* power and concat (right associative) */
{3, 3}, {3, 3}, /* equality and inequality */
{3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
{2, 2}, {1, 1} /* logical (and/or) */
};

#define UNARY_PRIORITY 8 /* priority for unary operators,一元操作符的优先级? */


/*
** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
** where `binop' is any binary operator with a priority higher than `limit'
** 操作符表达式
*/
static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
BinOpr op;
UnOpr uop;
enterlevel(ls);
uop = getunopr(ls->t.token);
if (uop != OPR_NOUNOPR) {
luaX_next(ls);
subexpr(ls, v, UNARY_PRIORITY);
luaK_prefix(ls->fs, uop, v);
}
else simpleexp(ls, v);

/* expand while operators have priorities higher than `limit' */
op = getbinopr(ls->t.token);
while (op != OPR_NOBINOPR && priority[op].left > limit) {
expdesc v2;
BinOpr nextop;
luaX_next(ls);
luaK_infix(ls->fs, op, v);
/* read sub-expression with higher priority */
nextop = subexpr(ls, &v2, priority[op].right);
luaK_posfix(ls->fs, op, v, &v2);
op = nextop;
}
leavelevel(ls);
return op; /* return first untreated operator */
}


static void expr (LexState *ls, expdesc *v) {
subexpr(ls, v, 0);
}

/* }==================================================================== */



/*
** {======================================================================
** Rules for Statements
** =======================================================================
*/

/* repeat
** statements
** until( condition )
*/

static int block_follow (int token) {
switch (token) { /* END和EOS还没理解 */
case TK_ELSE: case TK_ELSEIF: case TK_END:
case TK_UNTIL: case TK_EOS:
return 1;
default: return 0;
}
}


static void block (LexState *ls) {
/* block -> chunk */
FuncState *fs = ls->fs;
BlockCnt bl;
enterblock(fs, &bl, 0);
chunk(ls);
lua_assert(bl.breaklist == NO_JUMP);
leaveblock(fs);
}


/*
** structure to chain all variables in the left-hand side of an
** assignment
*/
struct LHS_assign {
struct LHS_assign *prev;
expdesc v; /* variable (global, local, upvalue, or indexed) */
};


/*
** check whether, in an assignment to a local variable, the local variable
** is needed in a previous assignment (to a table). If so, save original
** local value in a safe place and use this safe copy in the previous
** assignment.
*/
static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
FuncState *fs = ls->fs;
int extra = fs->freereg; /* eventual position to save local variable */
int conflict = 0;
for (; lh; lh = lh->prev) {
if (lh->v.k == VINDEXED) {
if (lh->v.u.s.info == v->u.s.info) { /* conflict? */
conflict = 1;
lh->v.u.s.info = extra; /* previous assignment will use safe copy */
}
if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */
conflict = 1;
lh->v.u.s.aux = extra; /* previous assignment will use safe copy */
}
}
}
if (conflict) {
luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */
luaK_reserveregs(fs, 1);
}
}


static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
expdesc e;
check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
"syntax error");
if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
struct LHS_assign nv;
nv.prev = lh;
primaryexp(ls, &nv.v);
if (nv.v.k == VLOCAL)
check_conflict(ls, lh, &nv.v);
luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls,
"variables in assignment");
assignment(ls, &nv, nvars+1);
}
else { /* assignment -> `=' explist1 */
int nexps;
checknext(ls, '=');
nexps = explist1(ls, &e);
if (nexps != nvars) {
adjust_assign(ls, nvars, nexps, &e);
if (nexps > nvars)
ls->fs->freereg -= nexps - nvars; /* remove extra values */
}
else {
luaK_setoneret(ls->fs, &e); /* close last expression */
luaK_storevar(ls->fs, &lh->v, &e);
return; /* avoid default */
}
}
init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
luaK_storevar(ls->fs, &lh->v, &e);
}


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;
}


static void breakstat (LexState *ls) {
FuncState *fs = ls->fs;
BlockCnt *bl = fs->bl;
int upval = 0;
while (bl && !bl->isbreakable) {
upval |= bl->upval;
bl = bl->previous;
}
if (!bl)
luaX_syntaxerror(ls, "no loop to break");
if (upval)
luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
}


static void whilestat (LexState *ls, int line) {
/* whilestat -> WHILE cond DO block END */
FuncState *fs = ls->fs;
int whileinit;
int condexit;
BlockCnt bl;
luaX_next(ls); /* skip WHILE */
whileinit = luaK_getlabel(fs);
condexit = cond(ls);
enterblock(fs, &bl, 1);
checknext(ls, TK_DO);
block(ls);
luaK_patchlist(fs, luaK_jump(fs), whileinit);
check_match(ls, TK_END, TK_WHILE, line);
leaveblock(fs);
luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
}


static void repeatstat (LexState *ls, int line) {
/* repeatstat -> REPEAT block UNTIL cond */
int condexit;
FuncState *fs = ls->fs;
int repeat_init = luaK_getlabel(fs);
BlockCnt bl1, bl2;
enterblock(fs, &bl1, 1); /* loop block */
enterblock(fs, &bl2, 0); /* scope block */
luaX_next(ls); /* skip REPEAT */
chunk(ls);
check_match(ls, TK_UNTIL, TK_REPEAT, line);
condexit = cond(ls); /* read condition (inside scope block) */
if (!bl2.upval) { /* no upvalues? */
leaveblock(fs); /* finish scope */
luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */
}
else { /* complete semantics when there are upvalues */
breakstat(ls); /* if condition then break */
luaK_patchtohere(ls->fs, condexit); /* else... */
leaveblock(fs); /* finish scope... */
luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */
}
leaveblock(fs); /* finish loop */
}


static int exp1 (LexState *ls) {
expdesc e;
int k;
expr(ls, &e);
k = e.k;
luaK_exp2nextreg(ls->fs, &e);
return k;
}


static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
/* forbody -> DO block */
BlockCnt bl;
FuncState *fs = ls->fs;
int prep, endfor;
adjustlocalvars(ls, 3); /* control variables */
checknext(ls, TK_DO);
prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
enterblock(fs, &bl, 0); /* scope for declared variables */
adjustlocalvars(ls, nvars);
luaK_reserveregs(fs, nvars);
block(ls);
leaveblock(fs); /* end of scope for declared variables */
luaK_patchtohere(fs, prep);
endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
}


static void fornum (LexState *ls, TString *varname, int line) {
/* fornum -> NAME = exp1,exp1[,exp1] forbody */
FuncState *fs = ls->fs;
int base = fs->freereg;
new_localvarliteral(ls, "(for index)", 0);
new_localvarliteral(ls, "(for limit)", 1);
new_localvarliteral(ls, "(for step)", 2);
new_localvar(ls, varname, 3);
checknext(ls, '=');
exp1(ls); /* initial value */
checknext(ls, ',');
exp1(ls); /* limit */
if (testnext(ls, ','))
exp1(ls); /* optional step */
else { /* default step = 1 */
luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
luaK_reserveregs(fs, 1);
}
forbody(ls, base, line, 1, 1);
}


static void forlist (LexState *ls, TString *indexname) {
/* forlist -> NAME {,NAME} IN explist1 forbody */
FuncState *fs = ls->fs;
expdesc e;
int nvars = 0;
int line;
int base = fs->freereg;
/* create control variables */
new_localvarliteral(ls, "(for generator)", nvars++);
new_localvarliteral(ls, "(for state)", nvars++);
new_localvarliteral(ls, "(for control)", nvars++);
/* create declared variables */
new_localvar(ls, indexname, nvars++);
while (testnext(ls, ','))
new_localvar(ls, str_checkname(ls), nvars++);
checknext(ls, TK_IN);
line = ls->linenumber;
adjust_assign(ls, 3, explist1(ls, &e), &e);
luaK_checkstack(fs, 3); /* extra space to call generator */
forbody(ls, base, line, nvars - 3, 0);
}


static void forstat (LexState *ls, int line) {
/* forstat -> FOR (fornum | forlist) END */
FuncState *fs = ls->fs;
TString *varname;
BlockCnt bl;
enterblock(fs, &bl, 1); /* scope for loop and control variables */
luaX_next(ls); /* skip `for' */
varname = str_checkname(ls); /* first variable name */
switch (ls->t.token) {
case '=': fornum(ls, varname, line); break;
case ',': case TK_IN: forlist(ls, varname); break;
default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
}
check_match(ls, TK_END, TK_FOR, line);
leaveblock(fs); /* loop scope (`break' jumps to this point) */
}


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 void ifstat (LexState *ls, int line) {
/* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
FuncState *fs = ls->fs;
int flist; /* false'list */
int escapelist = NO_JUMP; /* 块结束的addr */
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);
}


static void localfunc (LexState *ls) {
expdesc v, b;
FuncState *fs = ls->fs;

/* local function funA(...) end
** 注册locvar(函数名)到Proto.nlocvars,填充name信息,建立fs->actvar[fs->nactvars]到p.nlocvars的映射
*/
new_localvar(ls, str_checkname(ls), 0);

/* 给表达式填个初值先 */
init_exp(&v, VLOCAL, fs->freereg);

/* 上面新增了一个locvar,用掉了一个freereg,这里扩大点maxstacksize, 更新freereg */
luaK_reserveregs(fs, 1); /* reserve reg:准备寄存器 */

/* 更新fs->nactvar, 填充上面新增的p.nlocvars变量的startpc */
adjustlocalvars(ls, 1);

body(ls, &b, 0, ls->linenumber);
luaK_storevar(fs, &v, &b);

/* debug information will only see the variable after this point! */
getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
}

static void localstat (LexState *ls) {
/* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
int nvars = 0;
int nexps;
expdesc e;

do { /* 登记左边的变量名到 Proto.locvars */
new_localvar(ls, str_checkname(ls), nvars++);
} while (testnext(ls, ','));

if (testnext(ls, '='))
nexps = explist1(ls, &e); /* 解析表达式 */
else {
e.k = VVOID;
nexps = 0;
}
adjust_assign(ls, nvars, nexps, &e);
adjustlocalvars(ls, nvars);
}


static int funcname (LexState *ls, expdesc *v) {
/* funcname -> NAME {field} [`:' NAME] */
int needself = 0;
singlevar(ls, v);
while (ls->t.token == '.')
field(ls, v);
if (ls->t.token == ':') {
needself = 1; /* 需要给函数添加一个self参数 eg: function modName:sub () body end */
field(ls, v);
}
return needself;
}


static void funcstat (LexState *ls, int line) {
/* funcstat -> FUNCTION funcname body */
int needself;
expdesc v, b;
luaX_next(ls); /* skip FUNCTION */
needself = funcname(ls, &v);
body(ls, &b, needself, line);
luaK_storevar(ls->fs, &v, &b);
luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
}

/* 处理表达式stat */
static void exprstat (LexState *ls) {
/* stat -> func | assignment */
FuncState *fs = ls->fs;
struct LHS_assign v;
primaryexp(ls, &v.v);
if (v.v.k == VCALL) /* stat -> func */
SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
else { /* stat -> assignment */
v.prev = NULL;
assignment(ls, &v, 1);
}
}


static void retstat (LexState *ls) {
/* stat -> RETURN explist */
FuncState *fs = ls->fs;
expdesc e;
int first, nret; /* registers with returned values */
luaX_next(ls); /* skip RETURN */
if (block_follow(ls->t.token) || ls->t.token == ';')
first = nret = 0; /* return no values */
else {
nret = explist1(ls, &e); /* optional return values */
if (hasmultret(e.k)) {
luaK_setmultret(fs, &e);
if (e.k == VCALL && nret == 1) { /* tail call? */
SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
}
first = fs->nactvar;
nret = LUA_MULTRET; /* return all values */
}
else {
if (nret == 1) /* only one single value? */
first = luaK_exp2anyreg(fs, &e);
else {
luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
first = fs->nactvar; /* return all `active' values */
lua_assert(nret == fs->freereg - first);
}
}
}
luaK_ret(fs, first, nret);
}


static int statement (LexState *ls) {
int line = ls->linenumber; /* may be needed for error messages */
switch (ls->t.token) {
case TK_IF: { /* stat -> ifstat */
ifstat(ls, line);
return 0;
}
case TK_WHILE: { /* stat -> whilestat */
whilestat(ls, line);
return 0;
}
case TK_DO: { /* stat -> DO block END */
luaX_next(ls); /* skip DO */
block(ls);
check_match(ls, TK_END, TK_DO, line);
return 0;
}
case TK_FOR: { /* stat -> forstat */
forstat(ls, line);
return 0;
}
case TK_REPEAT: { /* stat -> repeatstat */
repeatstat(ls, line);
return 0;
}
case TK_FUNCTION: {
funcstat(ls, line); /* stat -> funcstat */
return 0;
}
case TK_LOCAL: { /* stat -> localstat */
luaX_next(ls); /* skip LOCAL */
if (testnext(ls, TK_FUNCTION)) /* local function? */
/*
** local function funName()
** end
*/
localfunc(ls);
else
localstat(ls);
return 0;
}
case TK_RETURN: { /* stat -> retstat */
retstat(ls);
return 1; /* must be last statement */
}
case TK_BREAK: { /* stat -> breakstat */
luaX_next(ls); /* skip BREAK */
breakstat(ls);
return 1; /* must be last statement */
}
default: {
exprstat(ls);
return 0; /* to avoid warnings */
}
}
}


static void chunk (LexState *ls) {
/* chunk -> { stat [`;'] } */
int islast = 0;
enterlevel(ls);
while (!islast && !block_follow(ls->t.token)) {
islast = statement(ls);
/* statement后面的';'是可选的 */
testnext(ls, ';');
lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
ls->fs->freereg >= ls->fs->nactvar);

/* 释放上一个块占用的临时寄存器 */
ls->fs->freereg = ls->fs->nactvar; /* free registers */
}
leavelevel(ls);
}

/* }====================================================================== */
-------------本文结束 感谢阅读-------------