⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lparser.c

📁 一个2D电磁场FEM计算的VC++源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    default: {  /* constructor_part -> listfields */    case_default:      cd->n = listfields(ls);      cd->k = 0;  /* list */      break;    }  }}static void constructor (LexState *ls) {  /* constructor -> '{' constructor_part [';' constructor_part] '}' */  FuncState *fs = ls->fs;  int line = ls->linenumber;  int pc = luaK_code1(fs, OP_CREATETABLE, 0);  int nelems;  Constdesc cd;  check(ls, '{');  constructor_part(ls, &cd);  nelems = cd.n;  if (optional(ls, ';')) {    Constdesc other_cd;    constructor_part(ls, &other_cd);    check_condition(ls, (cd.k != other_cd.k), "invalid constructor syntax");    nelems += other_cd.n;  }  check_match(ls, '}', '{', line);  luaX_checklimit(ls, nelems, MAXARG_U, "elements in a table constructor");  SETARG_U(fs->f->code[pc], nelems);  /* set initial table size */}/* }====================================================================== *//*** {======================================================================** Expression parsing** =======================================================================*/static void simpleexp (LexState *ls, expdesc *v) {  FuncState *fs = ls->fs;  switch (ls->t.token) {    case TK_NUMBER: {  /* simpleexp -> NUMBER */      Number r = ls->t.seminfo.r;      next(ls);      luaK_number(fs, r);      break;    }    case TK_STRING: {  /* simpleexp -> STRING */      code_string(ls, ls->t.seminfo.ts);  /* must use `seminfo' before `next' */      next(ls);      break;    }    case TK_NIL: {  /* simpleexp -> NIL */      luaK_adjuststack(fs, -1);      next(ls);      break;    }    case '{': {  /* simpleexp -> constructor */      constructor(ls);      break;    }    case TK_FUNCTION: {  /* simpleexp -> FUNCTION body */      next(ls);      body(ls, 0, ls->linenumber);      break;    }    case '(': {  /* simpleexp -> '(' expr ')' */      next(ls);      expr(ls, v);      check(ls, ')');      return;    }    case TK_NAME: case '%': {      var_or_func(ls, v);      return;    }    default: {      luaK_error(ls, "<expression> expected");      return;    }  }  v->k = VEXP;  v->u.l.t = v->u.l.f = NO_JUMP;}static void exp1 (LexState *ls) {  expdesc v;  expr(ls, &v);  luaK_tostack(ls, &v, 1);}static UnOpr getunopr (int op) {  switch (op) {    case TK_NOT: return OPR_NOT;    case '-': return OPR_MINUS;    default: return OPR_NOUNOPR;  }}static BinOpr getbinopr (int op) {  switch (op) {    case '+': return OPR_ADD;    case '-': return OPR_SUB;    case '*': return OPR_MULT;    case '/': return OPR_DIV;    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 {  char left;  /* left priority for each binary operator */  char right; /* right priority */} priority[] = {  /* ORDER OPR */   {5, 5}, {5, 5}, {6, 6}, {6, 6},  /* arithmetic */   {9, 8}, {4, 3},                  /* power and concat (right associative) */   {2, 2}, {2, 2},                  /* equality */   {2, 2}, {2, 2}, {2, 2}, {2, 2},  /* order */   {1, 1}, {1, 1}                   /* logical */};#define UNARY_PRIORITY	7  /* priority for unary operators *//*** subexpr -> (simplexep | unop subexpr) { binop subexpr }** where `binop' is any binary operator with a priority higher than `limit'*/static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {  BinOpr op;  UnOpr uop = getunopr(ls->t.token);  if (uop != OPR_NOUNOPR) {    next(ls);    subexpr(ls, v, UNARY_PRIORITY);    luaK_prefix(ls, 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;    next(ls);    luaK_infix(ls, op, v);    /* read sub-expression with higher priority */    nextop = subexpr(ls, &v2, priority[op].right);    luaK_posfix(ls, op, v, &v2);    op = nextop;  }  return op;  /* return first untreated operator */}static void expr (LexState *ls, expdesc *v) {  subexpr(ls, v, -1);}/* }==================================================================== *//*** {======================================================================** Rules for Statements** =======================================================================*/static int block_follow (int token) {  switch (token) {    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;  int nactloc = fs->nactloc;  chunk(ls);  luaK_adjuststack(fs, fs->nactloc - nactloc);  /* remove local variables */  removelocalvars(ls, fs->nactloc - nactloc);}static int assignment (LexState *ls, expdesc *v, int nvars) {  int left = 0;  /* number of values left in the stack after assignment */  luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment");  if (ls->t.token == ',') {  /* assignment -> ',' NAME assignment */    expdesc nv;    next(ls);    var_or_func(ls, &nv);    check_condition(ls, (nv.k != VEXP), "syntax error");    left = assignment(ls, &nv, nvars+1);  }  else {  /* assignment -> '=' explist1 */    int nexps;    check(ls, '=');    nexps = explist1(ls);    adjust_mult_assign(ls, nvars, nexps);  }  if (v->k != VINDEXED)    luaK_storevar(ls, v);  else {  /* there may be garbage between table-index and value */    luaK_code2(ls->fs, OP_SETTABLE, left+nvars+2, 1);    left += 2;  }  return left;}static void cond (LexState *ls, expdesc *v) {  /* cond -> exp */  expr(ls, v);  /* read condition */  luaK_goiftrue(ls->fs, v, 0);}static void whilestat (LexState *ls, int line) {  /* whilestat -> WHILE cond DO block END */  FuncState *fs = ls->fs;  int while_init = luaK_getlabel(fs);  expdesc v;  Breaklabel bl;  enterbreak(fs, &bl);  next(ls);  cond(ls, &v);  check(ls, TK_DO);  block(ls);  luaK_patchlist(fs, luaK_jump(fs), while_init);  luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));  check_match(ls, TK_END, TK_WHILE, line);  leavebreak(fs, &bl);}static void repeatstat (LexState *ls, int line) {  /* repeatstat -> REPEAT block UNTIL cond */  FuncState *fs = ls->fs;  int repeat_init = luaK_getlabel(fs);  expdesc v;  Breaklabel bl;  enterbreak(fs, &bl);  next(ls);  block(ls);  check_match(ls, TK_UNTIL, TK_REPEAT, line);  cond(ls, &v);  luaK_patchlist(fs, v.u.l.f, repeat_init);  leavebreak(fs, &bl);}static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) {  /* forbody -> DO block END */  FuncState *fs = ls->fs;  int prep = luaK_code1(fs, prepfor, NO_JUMP);  int blockinit = luaK_getlabel(fs);  check(ls, TK_DO);  adjustlocalvars(ls, nvar);  /* scope for control variables */  block(ls);  luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit);  luaK_patchlist(fs, prep, luaK_getlabel(fs));  removelocalvars(ls, nvar);}static void fornum (LexState *ls, TString *varname) {  /* fornum -> NAME = exp1,exp1[,exp1] forbody */  FuncState *fs = ls->fs;  check(ls, '=');  exp1(ls);  /* initial value */  check(ls, ',');  exp1(ls);  /* limit */  if (optional(ls, ','))    exp1(ls);  /* optional step */  else    luaK_code1(fs, OP_PUSHINT, 1);  /* default step */  new_localvar(ls, varname, 0);  new_localvarstr(ls, "(limit)", 1);  new_localvarstr(ls, "(step)", 2);  forbody(ls, 3, OP_FORPREP, OP_FORLOOP);}static void forlist (LexState *ls, TString *indexname) {  /* forlist -> NAME,NAME IN exp1 forbody */  TString *valname;  check(ls, ',');  valname = str_checkname(ls);  /* next test is dirty, but avoids `in' being a reserved word */  check_condition(ls,       (ls->t.token == TK_NAME && ls->t.seminfo.ts == luaS_new(ls->L, "in")),       "`in' expected");  next(ls);  /* skip `in' */  exp1(ls);  /* table */  new_localvarstr(ls, "(table)", 0);  new_localvar(ls, indexname, 1);  new_localvar(ls, valname, 2);  forbody(ls, 3, OP_LFORPREP, OP_LFORLOOP);}static void forstat (LexState *ls, int line) {  /* forstat -> fornum | forlist */  FuncState *fs = ls->fs;  TString *varname;  Breaklabel bl;  enterbreak(fs, &bl);  next(ls);  /* skip `for' */  varname = str_checkname(ls);  /* first variable name */  switch (ls->t.token) {    case '=': fornum(ls, varname); break;    case ',': forlist(ls, varname); break;    default: luaK_error(ls, "`=' or `,' expected");  }  check_match(ls, TK_END, TK_FOR, line);  leavebreak(fs, &bl);}static void test_then_block (LexState *ls, expdesc *v) {  /* test_then_block -> [IF | ELSEIF] cond THEN block */  next(ls);  /* skip IF or ELSEIF */  cond(ls, v);  check(ls, TK_THEN);  block(ls);  /* `then' part */}static void ifstat (LexState *ls, int line) {  /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */  FuncState *fs = ls->fs;  expdesc v;  int escapelist = NO_JUMP;  test_then_block(ls, &v);  /* IF cond THEN block */  while (ls->t.token == TK_ELSEIF) {    luaK_concat(fs, &escapelist, luaK_jump(fs));    luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));    test_then_block(ls, &v);  /* ELSEIF cond THEN block */  }  if (ls->t.token == TK_ELSE) {    luaK_concat(fs, &escapelist, luaK_jump(fs));    luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));    next(ls);  /* skip ELSE */    block(ls);  /* `else' part */  }  else    luaK_concat(fs, &escapelist, v.u.l.f);  luaK_patchlist(fs, escapelist, luaK_getlabel(fs));  check_match(ls, TK_END, TK_IF, line);}static void localstat (LexState *ls) {  /* stat -> LOCAL NAME {',' NAME} ['=' explist1] */  int nvars = 0;  int nexps;  do {    next(ls);  /* skip LOCAL or ',' */    new_localvar(ls, str_checkname(ls), nvars++);  } while (ls->t.token == ',');  if (optional(ls, '='))    nexps = explist1(ls);  else    nexps = 0;  adjust_mult_assign(ls, nvars, nexps);  adjustlocalvars(ls, nvars);}static int funcname (LexState *ls, expdesc *v) {  /* funcname -> NAME [':' NAME | '.' NAME] */  int needself = 0;  singlevar(ls, str_checkname(ls), v);  if (ls->t.token == ':' || ls->t.token == '.') {    needself = (ls->t.token == ':');    next(ls);    luaK_tostack(ls, v, 1);    luaK_kstr(ls, checkname(ls));    v->k = VINDEXED;  }  return needself;}static void funcstat (LexState *ls, int line) {  /* funcstat -> FUNCTION funcname body */  int needself;  expdesc v;  next(ls);  /* skip FUNCTION */  needself = funcname(ls, &v);  body(ls, needself, line);  luaK_storevar(ls, &v);}static void namestat (LexState *ls) {  /* stat -> func | ['%'] NAME assignment */  FuncState *fs = ls->fs;  expdesc v;  var_or_func(ls, &v);  if (v.k == VEXP) {  /* stat -> func */    check_condition(ls, luaK_lastisopen(fs), "syntax error");  /* an upvalue? */    luaK_setcallreturns(fs, 0);  /* call statement uses no results */  }  else {  /* stat -> ['%'] NAME assignment */    int left = assignment(ls, &v, 1);    luaK_adjuststack(fs, left);  /* remove eventual garbage left on stack */  }}static void retstat (LexState *ls) {  /* stat -> RETURN explist */  FuncState *fs = ls->fs;  next(ls);  /* skip RETURN */  if (!block_follow(ls->t.token))    explist1(ls);  /* optional return values */  luaK_code1(fs, OP_RETURN, ls->fs->nactloc);  fs->stacklevel = fs->nactloc;  /* removes all temp values */}static void breakstat (LexState *ls) {  /* stat -> BREAK [NAME] */  FuncState *fs = ls->fs;  int currentlevel = fs->stacklevel;  Breaklabel *bl = fs->bl;  if (!bl)    luaK_error(ls, "no loop to break");  next(ls);  /* skip BREAK */  luaK_adjuststack(fs, currentlevel - bl->stacklevel);  luaK_concat(fs, &bl->breaklist, luaK_jump(fs));  /* correct stack for compiler and symbolic execution */  luaK_adjuststack(fs, bl->stacklevel - currentlevel);}static int stat (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 */      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: {  /* stat -> funcstat */      funcstat(ls, line);      return 0;    }    case TK_LOCAL: {  /* stat -> localstat */      localstat(ls);      return 0;    }    case TK_NAME: case '%': {  /* stat -> namestat */      namestat(ls);      return 0;    }    case TK_RETURN: {  /* stat -> retstat */      retstat(ls);      return 1;  /* must be last statement */    }    case TK_BREAK: {  /* stat -> breakstat */      breakstat(ls);      return 1;  /* must be last statement */    }    default: {      luaK_error(ls, "<statement> expected");      return 0;  /* to avoid warnings */    }  }}static void parlist (LexState *ls) {  /* parlist -> [ param { ',' param } ] */  int nparams = 0;  int dots = 0;  if (ls->t.token != ')') {  /* is `parlist' not empty? */    do {      switch (ls->t.token) {        case TK_DOTS: next(ls); dots = 1; break;        case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break;        default: luaK_error(ls, "<name> or `...' expected");      }    } while (!dots && optional(ls, ','));  }  code_params(ls, nparams, dots);}static void body (LexState *ls, int needself, int line) {  /* body ->  '(' parlist ')' chunk END */  FuncState new_fs;  open_func(ls, &new_fs);  new_fs.f->lineDefined = line;  check(ls, '(');  if (needself) {    new_localvarstr(ls, "self", 0);    adjustlocalvars(ls, 1);  }  parlist(ls);  check(ls, ')');  chunk(ls);  check_match(ls, TK_END, TK_FUNCTION, line);  close_func(ls);  pushclosure(ls, &new_fs);}/* }====================================================================== */static void chunk (LexState *ls) {  /* chunk -> { stat [';'] } */  int islast = 0;  while (!islast && !block_follow(ls->t.token)) {    islast = stat(ls);    optional(ls, ';');    LUA_ASSERT(ls->fs->stacklevel == ls->fs->nactloc,               "stack size != # local vars");  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -