diff --git a/src/lua/lauxlib.c b/src/lua/lauxlib.c
index f7a3836..7b26158 100644
--- a/src/lua/lauxlib.c
+++ b/src/lua/lauxlib.c
@@ -1030,6 +1030,11 @@ LUALIB_API lua_State *luaL_newstate (void) {
 }
 
 
+LUALIB_API void luaL_setoutput (lua_State *L, FILE *output) {
+  lua_setoutput(L, output);
+}
+
+
 LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) {
   const lua_Number *v = lua_version(L);
   if (sz != LUAL_NUMSIZES)  /* check numeric types */
diff --git a/src/lua/lauxlib.h b/src/lua/lauxlib.h
index 9a2e66a..190fa98 100644
--- a/src/lua/lauxlib.h
+++ b/src/lua/lauxlib.h
@@ -91,6 +91,8 @@ LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
 
 LUALIB_API lua_State *(luaL_newstate) (void);
 
+LUALIB_API void (luaL_setoutput) (lua_State *L, FILE *output);
+
 LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
 
 LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
@@ -234,6 +236,9 @@ LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
         (fprintf(stderr, (s), (p)), fflush(stderr))
 #endif
 
+#define lua_writestringout(s,l,ls)  fwrite((s), sizeof(char), (l), ls->output)
+#define lua_writelineout(ls)  (lua_writestringout("\n", 1, ls), fflush(ls->output))
+
 /* }================================================================== */
 
 
diff --git a/src/lua/lbaselib.c b/src/lua/lbaselib.c
index 08523e6..dd741b8 100644
--- a/src/lua/lbaselib.c
+++ b/src/lua/lbaselib.c
@@ -19,6 +19,7 @@
 
 #include "lauxlib.h"
 #include "lualib.h"
+#include "lstate.h"
 
 
 static int luaB_print (lua_State *L) {
@@ -34,11 +35,11 @@ static int luaB_print (lua_State *L) {
     s = lua_tolstring(L, -1, &l);  /* get result */
     if (s == NULL)
       return luaL_error(L, "'tostring' must return a string to 'print'");
-    if (i>1) lua_writestring("\t", 1);
-    lua_writestring(s, l);
+    if (i>1) lua_writestringout("\t", 1, L);
+    lua_writestringout(s, l, L);
     lua_pop(L, 1);  /* pop result */
   }
-  lua_writeline();
+  lua_writelineout(L);
   return 0;
 }
 
diff --git a/src/lua/llex.c b/src/lua/llex.c
index 7032827..92de8e3 100644
--- a/src/lua/llex.c
+++ b/src/lua/llex.c
@@ -44,7 +44,8 @@ static const char *const luaX_tokens [] = {
     "return", "then", "true", "until", "while",
     "//", "..", "...", "==", ">=", "<=", "~=",
     "<<", ">>", "::", "<eof>",
-    "<number>", "<integer>", "<name>", "<string>"
+    "<number>", "<integer>", "<name>", "<string>",
+    "!="
 };
 
 
@@ -494,6 +495,11 @@ static int llex (LexState *ls, SemInfo *seminfo) {
         if (check_next1(ls, '=')) return TK_NE;
         else return '~';
       }
+      case '!': {
+        next(ls);
+        if (ls->current != '=') return '!';
+        else { next(ls); return TK_NE2; }
+      }
       case ':': {
         next(ls);
         if (check_next1(ls, ':')) return TK_DBCOLON;
diff --git a/src/lua/llex.h b/src/lua/llex.h
index 2363d87..443f2d9 100644
--- a/src/lua/llex.h
+++ b/src/lua/llex.h
@@ -33,7 +33,8 @@ enum RESERVED {
   TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,
   TK_SHL, TK_SHR,
   TK_DBCOLON, TK_EOS,
-  TK_FLT, TK_INT, TK_NAME, TK_STRING
+  TK_FLT, TK_INT, TK_NAME, TK_STRING,
+  TK_NE2
 };
 
 /* number of reserved words */
diff --git a/src/lua/lparser.c b/src/lua/lparser.c
index cd4512d..00d9a29 100644
--- a/src/lua/lparser.c
+++ b/src/lua/lparser.c
@@ -1010,6 +1010,7 @@ static BinOpr getbinopr (int op) {
     case TK_SHR: return OPR_SHR;
     case TK_CONCAT: return OPR_CONCAT;
     case TK_NE: return OPR_NE;
+    case TK_NE2: return OPR_NE;
     case TK_EQ: return OPR_EQ;
     case '<': return OPR_LT;
     case TK_LE: return OPR_LE;
@@ -1143,6 +1144,71 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
   }
 }
 
+static void append_assignment (LexState *ls, struct LHS_assign *lh) {
+  FuncState * fs=ls->fs;
+  TString *appendfunc_name;
+  expdesc appendfunc;
+  expdesc var;
+  expdesc value;
+  int base;
+
+  luaX_next(ls);
+
+  checknext(ls, '=');
+
+  /* Push tup_append_assignment onto the stack */
+  /* Note: copied from function call suffixedexp -> primaryexp -> singlevar */
+  appendfunc_name = luaS_new(ls->L, "tup_append_assignment");
+  singlevaraux(fs, appendfunc_name, &appendfunc, 1);
+  if (appendfunc.k == VVOID) {
+    /* If tup_append_assignment isn't global, then check _ENV/locals
+     * Note: reuse appendfunc to reference _ENV temporarily
+     */
+    expdesc key;
+    /* Locate _ENV and make it an upvalue if necessary */
+    singlevaraux(fs, ls->envn, &appendfunc, 1);
+    lua_assert(appendfunc.k == VLOCAL || appendfunc.k == VUPVAL);
+    codestring(ls, &key, appendfunc_name);  /* Make func_name a constant */
+    luaK_indexed(fs, &appendfunc, &key);  /* env[varname] */
+  }
+  luaK_exp2nextreg(fs, &appendfunc);
+
+  /* Push assignment lhs as first function argument */
+  var = lh->v; /* exp2nextreg disables the expr somehow, so copy it first */
+  if (var.k == VINDEXED) {
+    /* exp2nextreg if INDEXED will try to pop/reuse the source table and
+     * index stack positions.
+     * Increase freeregs to prevent that.
+     * The conditions need to match those in and around freereg in
+     * luaK_dischargevars exactly.
+     */
+    if (!ISK(var.u.ind.idx) && var.u.ind.idx >= fs->nactvar) {
+      fs->freereg += 1;
+    }
+    if (var.u.ind.vt == VLOCAL) {
+      if (!ISK(var.u.ind.t) && var.u.ind.t >= fs->nactvar) {
+	fs->freereg += 1;
+      }
+    }
+  }
+  luaK_exp2nextreg(fs, &var);
+
+  /* Push original rhs as second function argument */
+  expr(ls, &value);
+  luaK_exp2nextreg(fs, &value);
+
+  /* Call the function */
+  /* Note: copied from funcargs */
+  lua_assert(appendfunc.k == VNONRELOC);
+  base = appendfunc.u.info;  /* base register for call */
+  init_exp(&appendfunc, VCALL,
+	   luaK_codeABC(fs, OP_CALL, base, fs->freereg - (base + 1) + 1, 2));
+  fs->freereg = base + 1;  /* call removes function and arguments and leaves
+			      (unless changed) one result */
+
+  /* Store the call result */
+  luaK_storevar(fs, &lh->v, &appendfunc);
+}
 
 static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
   expdesc e;
@@ -1159,6 +1225,13 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
   }
   else {  /* assignment -> '=' explist */
     int nexps;
+
+    if(nvars==1) {
+      if(ls->t.token == '+') {
+        append_assignment(ls, lh);
+        return;
+      }
+    }
     checknext(ls, '=');
     nexps = explist(ls, &e);
     if (nexps != nvars)
@@ -1490,7 +1563,7 @@ static void exprstat (LexState *ls) {
   FuncState *fs = ls->fs;
   struct LHS_assign v;
   suffixedexp(ls, &v.v);
-  if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */
+  if (ls->t.token == '=' || ls->t.token == ',' || ls->t.token == '+') { /* stat -> assignment ? */
     v.prev = NULL;
     assignment(ls, &v, 1);
   }
diff --git a/src/lua/lstate.c b/src/lua/lstate.c
index 9194ac3..a439055 100644
--- a/src/lua/lstate.c
+++ b/src/lua/lstate.c
@@ -334,10 +334,16 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
     close_state(L);
     L = NULL;
   }
+  L->output = stdout;
   return L;
 }
 
 
+LUA_API void lua_setoutput (lua_State *L, FILE *output) {
+  L->output = output;
+}
+
+
 LUA_API void lua_close (lua_State *L) {
   L = G(L)->mainthread;  /* only the main thread can be closed */
   lua_lock(L);
diff --git a/src/lua/lstate.h b/src/lua/lstate.h
index a469466..7d56528 100644
--- a/src/lua/lstate.h
+++ b/src/lua/lstate.h
@@ -12,6 +12,7 @@
 #include "lobject.h"
 #include "ltm.h"
 #include "lzio.h"
+#include <stdio.h>
 
 
 /*
@@ -38,7 +39,9 @@ struct lua_longjmp;  /* defined in ldo.c */
 ** is thread safe
 */
 #if !defined(l_signalT)
+#if !defined(_WIN32)
 #include <signal.h>
+#endif
 #define l_signalT	sig_atomic_t
 #endif
 
@@ -181,6 +184,7 @@ struct lua_State {
   unsigned short nCcalls;  /* number of nested C calls */
   l_signalT hookmask;
   lu_byte allowhook;
+  FILE *output;
 };
 
 
diff --git a/src/lua/lua.h b/src/lua/lua.h
index 26c0e2d..c107621 100644
--- a/src/lua/lua.h
+++ b/src/lua/lua.h
@@ -9,6 +9,7 @@
 #ifndef lua_h
 #define lua_h
 
+#include <stdio.h>
 #include <stdarg.h>
 #include <stddef.h>
 
@@ -143,6 +144,7 @@ extern const char lua_ident[];
 ** state manipulation
 */
 LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
+LUA_API void       (lua_setoutput) (lua_State *L, FILE *output);
 LUA_API void       (lua_close) (lua_State *L);
 LUA_API lua_State *(lua_newthread) (lua_State *L);
 
