diff -ur lua-5.1.5-cc-form/lauxlib.cc lua_src/lauxlib.cc
--- lua-5.1.5-cc-form/lauxlib.cc	2023-12-26 01:09:24.564618500 -0800
+++ lua_src/lauxlib.cc	2023-12-09 23:33:55.564519700 -0800
@@ -574,8 +574,8 @@
     lf.f = freopen(filename, "rb", lf.f);  /* reopen in binary mode */
     if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
     /* skip eventual `#!...' */
-   while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
-    lf.extraline = 0;
+   while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) {}
+   lf.extraline = 0;
   }
   ungetc(c, lf.f);
   status = lua_load(L, getF, &lf, lua_tostring(L, -1));
diff -ur lua-5.1.5-cc-form/lbaselib.cc lua_src/lbaselib.cc
--- lua-5.1.5-cc-form/lbaselib.cc	2023-12-26 01:09:24.612653600 -0800
+++ lua_src/lbaselib.cc	2023-12-09 23:33:55.592547700 -0800
@@ -631,7 +631,7 @@
   luaL_register(L, "_G", base_funcs);
   lua_pushliteral(L, LUA_VERSION);
   lua_setglobal(L, "_VERSION");  /* set global _VERSION */
-  /* `ipairs' and `pairs' need auxiliary functions as upvalues */
+  /* `ipairs' and `pairs' need auxliliary functions as upvalues */
   auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
   auxopen(L, "pairs", luaB_pairs, luaB_next);
   /* `newproxy' needs a weaktable as upvalue */
diff -ur lua-5.1.5-cc-form/lcode.cc lua_src/lcode.cc
--- lua-5.1.5-cc-form/lcode.cc	2023-12-26 01:09:24.635738100 -0800
+++ lua_src/lcode.cc	2023-12-09 23:33:56.178547700 -0800
@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 2.25.1.5 2011/01/31 14:53:16 roberto Exp $
+** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -411,6 +411,13 @@
 }
 
 
+void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) {
+  luaK_dischargevars(fs, e);
+  freeexp(fs, e);
+  exp2reg(fs, e, reg);
+}
+
+
 void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
   luaK_dischargevars(fs, e);
   freeexp(fs, e);
diff -ur lua-5.1.5-cc-form/lcode.h lua_src/lcode.h
--- lua-5.1.5-cc-form/lcode.h	2023-12-26 01:09:24.663593600 -0800
+++ lua_src/lcode.h	2023-12-09 23:33:55.843620800 -0800
@@ -52,6 +52,7 @@
 LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
 LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
 LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
+LUAI_FUNC void luaK_exp2reg (FuncState *fs, expdesc *e, int reg);
 LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
 LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
 LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
diff -ur lua-5.1.5-cc-form/llex.cc lua_src/llex.cc
--- lua-5.1.5-cc-form/llex.cc	2023-12-26 01:09:25.016396300 -0800
+++ lua_src/llex.cc	2023-12-09 23:33:55.906615800 -0800
@@ -1,5 +1,5 @@
 /*
-** $Id: llex.c,v 2.20.1.2 2009/11/23 14:58:22 roberto Exp $
+** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $
 ** Lexical Analyzer
 ** See Copyright Notice in lua.h
 */
@@ -35,11 +35,11 @@
 
 /* ORDER RESERVED */
 const char *const luaX_tokens [] = {
-    "and", "break", "do", "else", "elseif",
+    "and", "break", "continue", "each", "do", "else", "elseif",
     "end", "false", "for", "function", "if",
     "in", "local", "nil", "not", "or", "repeat",
     "return", "then", "true", "until", "while",
-    "..", "...", "==", ">=", "<=", "~=",
+    "..", "...", "==", ">=", "<=", "~=", "!=",
     "<number>", "<name>", "<string>", "<eof>",
     NULL
 };
@@ -388,6 +388,11 @@
         if (ls->current != '=') return '~';
         else { next(ls); return TK_NE; }
       }
+      case '!': {
+        next(ls);
+        if (ls->current != '=') return '!';
+        else { next(ls); return TK_NE; }
+      }
       case '"':
       case '\'': {
         read_string(ls, ls->current, seminfo);
diff -ur lua-5.1.5-cc-form/llex.h lua_src/llex.h
--- lua-5.1.5-cc-form/llex.h	2023-12-26 01:09:25.048415200 -0800
+++ lua_src/llex.h	2023-12-09 23:33:55.406530700 -0800
@@ -23,13 +23,13 @@
 */
 enum RESERVED {
   /* terminal symbols denoted by reserved words */
-  TK_AND = FIRST_RESERVED, TK_BREAK,
+  TK_AND = FIRST_RESERVED, TK_BREAK, TK_CONTINUE, TK_EACH,
   TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
   TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
   TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
   /* other terminal symbols */
-  TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
-  TK_NAME, TK_STRING, TK_EOS
+  TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_CNE,
+  TK_NUMBER, TK_NAME, TK_STRING, TK_EOS
 };
 
 /* number of reserved words */
diff -ur lua-5.1.5-cc-form/lparser.cc lua_src/lparser.cc
--- lua-5.1.5-cc-form/lparser.cc	2023-12-26 01:09:25.332105800 -0800
+++ lua_src/lparser.cc	2023-12-09 23:33:56.064573500 -0800
@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 2.42.1.4 2011/10/21 19:31:42 roberto Exp $
+** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -40,6 +40,7 @@
 typedef struct BlockCnt {
   struct BlockCnt *previous;  /* chain */
   int breaklist;  /* list of jumps out of this loop */
+  int continuelist;  /* list of jumps to the loop's test */
   lu_byte nactvar;  /* # active locals outside the breakable structure */
   lu_byte upval;  /* true if some variable in the block is an upvalue */
   lu_byte isbreakable;  /* true if `block' is a loop */
@@ -284,6 +285,7 @@
 
 static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
   bl->breaklist = NO_JUMP;
+  bl->continuelist = NO_JUMP;
   bl->isbreakable = isbreakable;
   bl->nactvar = fs->nactvar;
   bl->upval = 0;
@@ -507,7 +509,8 @@
   init_exp(&cc.v, VVOID, 0);  /* no value (yet) */
   luaK_exp2nextreg(ls->fs, t);  /* fix it at stack top (for gc) */
   checknext(ls, '{');
-  do {
+  for (;;) {
+    int itemline = ls->linenumber;
     lua_assert(cc.v.k == VVOID || cc.tostore > 0);
     if (ls->t.token == '}') break;
     closelistfield(fs, &cc);
@@ -529,7 +532,11 @@
         break;
       }
     }
-  } while (testnext(ls, ',') || testnext(ls, ';'));
+    // -AJA- 2011/04/14: data tables: optional commas at end of a line
+    if (! (testnext(ls, ',') || testnext(ls, ';')))
+      if (ls->linenumber == itemline)
+        break;
+  }
   check_match(ls, '}', '{', line);
   lastlistfield(fs, &cc);
   SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
@@ -988,6 +995,23 @@
 }
 
 
+static void continuestat (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 continue");
+  if (upval)
+    luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
+  luaK_concat(fs, &bl->continuelist, luaK_jump(fs));
+}
+
+
+
 static void whilestat (LexState *ls, int line) {
   /* whilestat -> WHILE cond DO block END */
   FuncState *fs = ls->fs;
@@ -1001,6 +1025,7 @@
   checknext(ls, TK_DO);
   block(ls);
   luaK_patchlist(fs, luaK_jump(fs), whileinit);
+  luaK_patchlist(fs, bl.continuelist, whileinit);  /* continue goes to start, too */
   check_match(ls, TK_END, TK_WHILE, line);
   leaveblock(fs);
   luaK_patchtohere(fs, condexit);  /* false conditions finish the loop */
@@ -1017,6 +1042,7 @@
   enterblock(fs, &bl2, 0);  /* scope block */
   luaX_next(ls);  /* skip REPEAT */
   chunk(ls);
+  luaK_patchtohere(fs, bl1.continuelist);
   check_match(ls, TK_UNTIL, TK_REPEAT, line);
   condexit = cond(ls);  /* read condition (inside scope block) */
   if (!bl2.upval) {  /* no upvalues? */
@@ -1057,6 +1083,7 @@
   block(ls);
   leaveblock(fs);  /* end of scope for declared variables */
   luaK_patchtohere(fs, prep);
+  luaK_patchtohere(fs, bl.previous->continuelist);	/* continue, if any, jumps to here */
   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 */
@@ -1127,6 +1154,95 @@
 }
 
 
+static int eachexpr (LexState *ls, expdesc *v, int islist)
+{
+  // -AJA- parse an expression and call 'ipairs' or 'pairs' with the
+  //       expression as its single argument.
+
+  const char *funcname = islist ? "ipairs" : "pairs";
+  TString *t_funcname = luaX_newstring(ls, funcname, islist ? 6 : 5);
+
+  FuncState *fs = ls->fs;
+  expdesc f;
+  expdesc args;
+  int base;
+  int nparams;
+  int line;
+
+  init_exp(&f, VGLOBAL, NO_REG);
+  f.u.s.info = luaK_stringK(fs, t_funcname);
+  luaK_exp2nextreg(fs, &f);
+
+///--- funcargs(ls, &f);
+///--- memcpy(v, &f, sizeof(*v));
+
+  line = ls->linenumber;
+  expr(ls, &args);
+  luaK_exp2nextreg(fs, &args);
+  luaK_setmultret(fs, &args);
+
+  lua_assert(f.k == VNONRELOC);
+  lua_assert(hasmultret(args.k));
+  base = f.u.s.info;  // base register for call
+  nparams = LUA_MULTRET;  // open call
+
+  init_exp(v, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
+  luaK_fixline(fs, line);
+  fs->freereg = base+1;
+
+  return 1;
+}
+
+
+// -AJA- 2011/04/16: implemented this syntactic sugar.
+//       Equivalent to normal for loop with 'ipairs' if one variable is
+//       present or 'pairs' if two variables are given.
+static void eachstat (LexState *ls, int line) {
+  /* eachstat -> EACH [ key, ] val IN expr DO */
+  FuncState *fs = ls->fs;
+  TString *indexname;
+  TString *valuename = NULL;
+  int islist;
+  BlockCnt bl;
+
+  enterblock(fs, &bl, 1);  /* scope for loop and control variables */
+  luaX_next(ls);  /* skip `each' */
+  indexname = str_checkname(ls);  /* first variable name */
+  if (ls->t.token == ',') {
+    luaX_next(ls);
+    valuename = str_checkname(ls);  /* second variable name */
+    islist = 0;
+  } else {
+    valuename = indexname;
+    indexname = luaX_newstring(ls, "_index", 6);
+    islist = 1;
+  }
+
+  {
+  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++);
+  new_localvar(ls, valuename, nvars++);
+  checknext(ls, TK_IN);
+  line = ls->linenumber;
+  adjust_assign(ls, 3, eachexpr(ls, &e, islist), &e);
+  luaK_checkstack(fs, 3);  /* extra space to call generator */
+  forbody(ls, base, line, nvars - 3, 0);
+  }
+
+  check_match(ls, TK_END, TK_EACH, 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;
@@ -1289,6 +1405,10 @@
       forstat(ls, line);
       return 0;
     }
+    case TK_EACH: {  /* stat -> eachstat */
+      eachstat(ls, line);
+      return 0;
+    }
     case TK_REPEAT: {  /* stat -> repeatstat */
       repeatstat(ls, line);
       return 0;
@@ -1314,6 +1434,11 @@
       breakstat(ls);
       return 1;  /* must be last statement */
     }
+    case TK_CONTINUE: {  /* stat -> continuestat */
+      luaX_next(ls);  /* skip CONTINUE */
+      continuestat(ls);
+      return 1;	  /* must be last statement */
+    }
     default: {
       exprstat(ls);
       return 0;  /* to avoid warnings */
diff -ur lua-5.1.5-cc-form/lstrlib.cc lua_src/lstrlib.cc
--- lua-5.1.5-cc-form/lstrlib.cc	2023-12-26 01:09:25.509866300 -0800
+++ lua_src/lstrlib.cc	2023-12-09 23:33:56.278521300 -0800
@@ -1,5 +1,5 @@
 /*
-** $Id: lstrlib.c,v 1.132.1.5 2010/05/14 15:34:19 roberto Exp $
+** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $
 ** Standard library for string operations and pattern-matching
 ** See Copyright Notice in lua.h
 */
@@ -797,6 +797,15 @@
           continue;  /* skip the 'addsize' at the end */
         }
         case 's': {
+          // -AJA- 2017/07/01: allow '%s' to call __tostring metamethod
+          //                   on tables.  A power patch by Doug Currie.
+          if (!lua_isstring(L, arg))
+          {
+            lua_getglobal(L, "tostring");
+            lua_pushvalue(L, arg);
+            lua_call(L, 1, 1);
+            lua_replace(L, arg);
+          }
           size_t l;
           const char *s = luaL_checklstring(L, arg, &l);
           if (!strchr(form, '.') && l >= 100) {
diff -ur lua-5.1.5-cc-form/ltablib.cc lua_src/ltablib.cc
--- lua-5.1.5-cc-form/ltablib.cc	2023-12-26 01:09:25.605850700 -0800
+++ lua_src/ltablib.cc	2023-12-09 23:33:56.406483200 -0800
@@ -137,7 +137,7 @@
   if (!lua_isstring(L, -1))
     luaL_error(L, "invalid value (%s) at index %d in table for "
                   LUA_QL("concat"), luaL_typename(L, -1), i);
-    luaL_addvalue(b);
+  luaL_addvalue(b);
 }