/*
** $Id: lparser.c $
** Lua Parser
** See Copyright Notice in lua.h
*/
#define lparser_c
#define LUA_CORE
#include "lprefix.h"
#include <limits.h>
#include <string.h>
#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"
/* maximum number of local variables per function (must be smaller
than 250, due to the bytecode format) */
#define MAXVARS 200
#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
/* because all strings are unified by the scanner, the parser
can use pointer equality for string equality */
#define eqstr(a,b) ((a) == (b))
/*
** nodes for block list (list of active blocks)
*/
typedef struct BlockCnt {
struct BlockCnt *previous; /* chain */
int firstlabel; /* index of first label in this block */
int firstgoto; /* index of first pending goto in this block */
lu_byte nactvar; /* # active locals outside the block */
lu_byte upval; /* true if some variable in the block is an upvalue */
lu_byte isloop; /* true if 'block' is a loop */
lu_byte insidetbc; /* true if inside the scope of a to-be-closed var. */
} BlockCnt;
/*
** prototypes for recursive non-terminal functions
*/
static void statement (LexState *ls);
static void expr (LexState *ls, expdesc *v);
static l_noret error_expected (LexState *ls, int token) {
luaX_syntaxerror(ls,
luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token)));
}
static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
lua_State *L = fs->ls->L;
const char *msg;
int line = fs->f->linedefined;
const char *where = (line == 0)
? "main function"
: luaO_pushfstring(L, "function at line %d", line);
msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s",
what, limit, where);
luaX_syntaxerror(fs->ls, msg);
}
static void checklimit (FuncState *fs, int v, int l, const char *what) {
if (v > l) errorlimit(fs, l, what);
}
/*
** Test whether next token is 'c'; if so, skip it.
*/
static int testnext (LexState *ls, int c) {
if (ls->t.token == c) {
luaX_next(ls);
return 1;
}
else return 0;
}
/*
** Check that next token is 'c'.
*/
static void check (LexState *ls, int c) {
if (ls->t.token != c)
error_expected(ls, c);
}
/*
** Check that next token is 'c' and skip it.
*/
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); }
/*
** Check that next token is 'what' and skip it. In case of error,
** raise an error that the expected 'what' should match a 'who'
** in line 'where' (if that is not the current line).
*/
static void check_match (LexState *ls, int what, int who, int where) {
if (unlikely(!testnext(ls, what))) {
if (where == ls->linenumber) /* all in the same line? */
error_expected(ls, what); /* do not need a complex message */
else {
luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
"%s expected (to close %s at line %d)",
luaX_token2str(ls, what), luaX_token2str(ls, who), where));
}
}
}
static TString *str_checkname (LexState *ls) {
TString *ts;
check(ls, TK_NAME);
ts = ls->t.seminfo.ts;
luaX_next(ls);
return ts;
}
static void init_exp (expdesc *e, expkind k, int i) {
e->f = e->t = NO_JUMP;
e->k = k;
e->u.info = i;
}
static void codestring (expdesc *e, TString *s) {
e->f = e->t = NO_JUMP;
e->k = VKSTR;
e->u.strval = s;
}
static void codename (LexState *ls, expdesc *e) {
codestring(e, str_checkname(ls));
}
/*
** Register a new local variable in the active 'Proto' (for debug
** information).
*/
static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) {
Proto *f = fs->f;
int oldsize = f->sizelocvars;
luaM_growvector(ls->L, f->locvars, fs->ndebugvars, f->sizelocvars,
LocVar, SHRT_MAX, "local variables");
while (oldsize < f->sizelocvars)
f->locvars[oldsize++].varname = NULL;
f->locvars[fs->ndebugvars].varname = varname;
f->locvars[fs->ndebugvars].startpc = fs->pc;
luaC_objbarrier(ls->L, f, varname);
return fs->ndebugvars++;
}
/*
** Create a new local variable with the given 'name'. Return its index
** in the function.
*/
static int new_localvar (LexState *ls, TString *name) {
lua_State *L = ls->L;
FuncState *fs = ls->fs;
Dyndata *dyd = ls->dyd;
Vardesc *var;
checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
MAXVARS, "local variables");
luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
dyd->actvar.size, Vardesc, USHRT_MAX, "local variables");
var = &dyd->actvar.arr[dyd->actvar.n++];
var->vd.kind = VDKREG; /* default */
var->vd.name = name;
return dyd->actvar.n - 1 - fs->firstlocal;
}
#define new_localvarliteral(ls,v) \
new_localvar(ls, \
luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1));
/*
** Return the "variable description" (Vardesc) of a given variable.
** (Unless noted otherwise, all variables are referred to by their
** compiler indices.)
*/
static Vardesc *getlocalvardesc (FuncState *fs, int vidx) {
return &fs->ls->dyd->actvar.arr[fs->firstlocal + vidx];
}
/*
** Convert 'nvar', a compiler index level, to it corresponding
** stack index level. For that, search for the highest variable
** below that level that is in the stack and uses its stack
** index ('sidx').
*/
static int stacklevel (FuncState *fs, int nvar) {
while (nvar-- > 0) {
Vardesc *vd = getlocalvardesc(fs, nvar); /* get variable */
if (vd->vd.kind != RDKCTC) /* is in the stack? */
return vd->vd.sidx + 1;
}
return 0; /* no variables in the stack */
}
/*
** Return the number of variables in the stack for function 'fs'
*/
int luaY_nvarstack (FuncState *fs) {
return stacklevel(fs, fs->nactvar);
}
/*
** Get the debug-information entry for current variable 'vidx'.
*/
static LocVar *localdebuginfo (FuncState *fs, int vidx) {
Vardesc *vd = getlocalvardesc(fs, vidx);
if (vd->vd.kind == RDKCTC)
return NULL; /* no debug info. for constants */
else {
int idx = vd->vd.pidx;
lua_assert(idx < fs->ndebugvars);
return &fs->f->locvars[idx];
}
}
/*
** Create an expression representing variable 'vidx'
*/
static void init_var (FuncState *fs, expdesc *e, int vidx) {
e->f = e->t = NO_JUMP;
e->k = VLOCAL;
e->u.var.vidx = vidx;
e->u.var.sidx = getlocalvardesc(fs, vidx)->vd.sidx;
}
/*
** Raises an error if variable described by 'e' is read only
*/
static void check_readonly (LexState *ls, expdesc *e) {
FuncState *fs = ls->fs;
TString *varname = NULL; /* to be set if variable is const */
switch (e->k) {
case VCONST: {
varname = ls->dyd->actvar.arr[e->u.info].vd.name;
break;
}
case VLOCAL: {
Vardesc *vardesc = getlocalvardesc(fs, e->u.var.vidx);
if (vardesc->vd.kind != VDKREG) /* not a regular variable? */
varname = vardesc->vd.name;
break;
}
case VUPVAL: {
Upvaldesc *up = &fs->f->upvalues[e->u.info];
if (up->kind != VDKREG)
varname = up->name;
break;
}
default:
return; /* other cases cannot be read-only */
}
if (varname) {
const char *msg = luaO_pushfstring(ls->L,
"attempt to assign to const variable '%s'", getstr(varname));
luaK_semerror(ls, msg); /* error */
}
}
/*
** Start the scope for the last 'nvars' created variables.
*/
static void adjustlocalvars (LexState *ls, int nvars) {
FuncState *fs = ls->fs;
int stklevel = luaY_nvarstack(fs);
int i;
for (i = 0; i < nvars; i++) {
int vidx = fs->nactvar++;
Vardesc *var = getlocalvardesc(fs, vidx);
var->vd.sidx = stklevel++;
var->vd.pidx = registerlocalvar(ls, fs, var->vd.name);
}
}
/*
** Close
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
系统环境: windows 10 编译环境: VS2019 安装使用: 在windows + VS2019环境下面编译即可; 文档情况: /doc目录下可以找到合适的文档 新手只需要有一定的C语言基础,就看懂并实现简单的脚本编写和运行,和Python不一样,lua一直以简单高效、扩展性强著称。 教程网址: https://www.lua.org/docs.html
资源推荐
资源详情
资源评论
收起资源包目录
LUA脚本工具在windows平台下编译的版本 (128个子文件)
luac.1 3KB
lua.1 3KB
liblua.a 334KB
build.bat 247B
lparser.c 56KB
lvm.c 55KB
lstrlib.c 53KB
lgc.c 50KB
lcode.c 50KB
lapi.c 34KB
lauxlib.c 30KB
ltable.c 29KB
ldo.c 26KB
ldebug.c 24KB
loadlib.c 22KB
liolib.c 21KB
lmathlib.c 18KB
lua.c 18KB
lobject.c 18KB
llex.c 16KB
luac.c 15KB
lbaselib.c 14KB
ldblib.c 13KB
ltablib.c 13KB
lstate.c 12KB
loslib.c 12KB
lfunc.c 9KB
ltm.c 8KB
lutf8lib.c 8KB
lstring.c 8KB
lundump.c 7KB
lmem.c 6KB
ldump.c 5KB
lcorolib.c 4KB
lopcodes.c 4KB
lctype.c 2KB
linit.c 2KB
lzio.c 1KB
lua.css 2KB
manual.css 256B
index.css 240B
lua.def 2KB
lua54.dll 440KB
lua54.dll 440KB
luac.exe 448KB
luac.exe 448KB
lua.exe 119KB
lua.exe 119KB
lua54.exp 18KB
luac.exp 18KB
luac.vcxproj.filters 7KB
LuaExe.vcxproj.filters 7KB
lua.vcxproj.filters 6KB
logo.gif 10KB
lobject.h 21KB
lobject.h 21KB
luaconf.h 21KB
luaconf.h 21KB
lua.h 15KB
lua.h 15KB
lstate.h 13KB
lstate.h 13KB
lopcodes.h 12KB
lopcodes.h 12KB
lauxlib.h 9KB
lauxlib.h 9KB
llimits.h 8KB
llimits.h 8KB
lgc.h 6KB
lgc.h 6KB
lparser.h 6KB
lparser.h 6KB
lvm.h 4KB
lvm.h 4KB
lcode.h 4KB
lcode.h 4KB
lmem.h 3KB
lmem.h 3KB
ldo.h 3KB
ldo.h 3KB
ltm.h 3KB
ltm.h 3KB
llex.h 2KB
llex.h 2KB
ldebug.h 2KB
ldebug.h 2KB
lctype.h 2KB
lctype.h 2KB
lfunc.h 2KB
ltable.h 2KB
lfunc.h 2KB
ltable.h 2KB
ljumptab.h 2KB
ljumptab.h 2KB
lstring.h 2KB
lstring.h 2KB
lzio.h 1KB
lzio.h 1KB
lapi.h 1KB
lapi.h 1KB
共 128 条
- 1
- 2
资源评论
程序员王马
- 粉丝: 5851
- 资源: 10
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于javaweb的网上拍卖系统,采用Spring + SpringMvc+Mysql + Hibernate+ JSP技术
- polygon-mumbai
- Chrome代理 switchyOmega
- GVC-全球价值链参与地位指数,基于ICIO表,(Wang等 2017a)计算方法
- 易语言ADS指纹浏览器管理工具
- 易语言奇易模块5.3.6
- cad定制家具平面图工具-(FG)门板覆盖柜体
- asp.net 原生js代码及HTML实现多文件分片上传功能(自定义上传文件大小、文件上传类型)
- whl@pip install pyaudio ERROR: Failed building wheel for pyaudio
- Constantsfd密钥和权限集合.kt
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功