/*
** $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
资源评论
sului
- 粉丝: 4934
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于Java、CSS、JavaScript的综合性购物网站设计源码
- 基于Html与Java混合技术的第一小组项目设计源码
- 基于Java语言的游客服务设计源码
- 基于Python和HTML的自动化Excel处理脚本设计源码
- fortran语言编程源代码,处理txt格式的气象数据
- A collection Unreal Engine example projects demonstrating variou
- 基于Java语言的Vue登录系统设计源码
- 基于Java实现的英语绘本处理功能设计源码
- 基于 Matlab 的数字图像处理系统 包含GUI界面 界面非常美观 功能包括:亮度对比度色彩调整、几何变,图像反色,中值
- YOLOv11深度学习目标检测详解及应用示例
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功