[Scummvm-git-logs] scummvm master -> 81d31390015787a38838bb7069d2b3a1c3adc705

djsrv dservilla at gmail.com
Wed Jun 10 16:33:05 UTC 2020


This automated email contains information about 14 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
dd74683f10 DIRECTOR: LINGO: Add XObject type
9906f637e3 DIRECTOR: LINGO: Add Object destructor
d43d5592a6 DIRECTOR: LINGO: Stub FileIO
be7e414d0f DIRECTOR: LINGO: Implement FileIO methods
1c6b519197 DIRECTOR: LINGO: Print object pointers
a547ff408a DIRECTOR: LINGO: Fix re-assignment of object var
0b2c92d99b DIRECTOR: LINGO: Implement FileIO append mode
c0c296ea3c DIRECTOR: LINGO: Fix context issues
7f579c2dd2 DIRECTOR: LINGO: Future proof for Xtras
58c1a72f09 DIRECTOR: LINGO: Load FileIO by default on Mac
4301a75df5 DIRECTOR: LINGO: Don't print nonexistent localvars
66894ea8db DIRECTOR: LINGO: Print function vars
85077477c3 DIRECTOR: LINGO: Don't destroy local vars
81d3139001 DIRECTOR: LINGO: Correctly reset _indef


Commit: dd74683f10a4d3bc3f6e8f8ff8c4e61402c8b7c9
    https://github.com/scummvm/scummvm/commit/dd74683f10a4d3bc3f6e8f8ff8c4e61402c8b7c9
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-10T12:18:29-04:00

Commit Message:
DIRECTOR: LINGO: Add XObject type

Changed paths:
  A engines/director/lingo/xobject/fileio.cpp
  A engines/director/lingo/xobject/fileio.h
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo-codegen.cpp
    engines/director/lingo/lingo-object.cpp
    engines/director/lingo/lingo-object.h
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h
    engines/director/module.mk


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 4f098e4fda..96c27cd86c 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1041,8 +1041,13 @@ void LB::b_openResFile(int nargs) {
 
 void LB::b_openXlib(int nargs) {
 	Datum d = g_lingo->pop();
-
-	warning("STUB: b_openXlib(%s)", d.asString().c_str());
+	Common::String xlibName = d.asString();
+	if (g_lingo->_xlibs.contains(xlibName)) {
+		Symbol sym = g_lingo->_xlibs[xlibName];
+		(*sym.u.bltin)(0);
+	} else {
+		warning("STUB: b_openXLib(%s)", xlibName.c_str());
+	}
 }
 
 void LB::b_saveMovie(int nargs) {
@@ -1298,7 +1303,7 @@ void LB::b_factory(int nargs) {
 	Datum factoryName = g_lingo->pop();
 	factoryName.type = VAR;
 	Datum o = g_lingo->varFetch(factoryName, true);
-	if (o.type == OBJECT && o.u.obj->type == kFactoryObj
+	if (o.type == OBJECT && (o.u.obj->type & (kFactoryObj | kXObj))
 			&& o.u.obj->name->equalsIgnoreCase(*factoryName.u.s) && o.u.obj->inheritanceLevel == 1) {
 		g_lingo->push(o);
 	} else {
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 5551328b21..a2b8989ac9 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -1304,7 +1304,7 @@ void LC::call(const Common::String &name, int nargs) {
 		Datum eventName(name);
 		eventName.type = VAR;
 		Datum d = g_lingo->varFetch(eventName);
-		if (d.type == OBJECT) {
+		if (d.type == OBJECT && (d.u.obj->type & (kFactoryObj | kXObj))) {
 			debugC(3, kDebugLingoExec,  "Dereferencing object reference: %s to <%s>", name.c_str(), d.asString(true).c_str());
 			Object *target = d.u.obj;
 			Datum methodName = g_lingo->_stack.remove_at(g_lingo->_stack.size() - nargs); // Take method name out of stack
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 1dd0d8e613..e7c6846d85 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -279,13 +279,7 @@ void Lingo::varCreate(const Common::String &name, bool global, SymbolHash *local
 }
 
 void Lingo::codeFactory(Common::String &name) {
-	Object *obj = new Object;
-	obj->name = new Common::String(name);
-	obj->type = kFactoryObj;
-	obj->disposed = false;
-	obj->inheritanceLevel = 1;
-	obj->scriptContext = _currentScriptContext;
-	obj->objArray = new Common::HashMap<uint32, Datum>;
+	Object *obj = new Object(name, kFactoryObj);
 
 	_currentFactory = obj;
 	if (!_globalvars.contains(name)) {
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index bd0feb1a67..3c39045bcc 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -24,6 +24,7 @@
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-code.h"
 #include "director/lingo/lingo-object.h"
+#include "director/lingo/xobject/fileio.h"
 
 namespace Director {
 
@@ -32,20 +33,29 @@ static struct MethodProto {
 	void (*func)(int);
 	int minArgs;	// -1 -- arglist
 	int maxArgs;
+	int type;
 	int version;
 } predefinedMethods[] = {
-	// "mAtFrame"													// D2 - XObject or user-defined
-	// "mDescribe",													// D2 - XObject
-	{ "mDispose",				LM::m_dispose,		 0, 0, 2 },		// D2
-	{ "mGet",					LM::m_get,			 1, 1, 2 },		// D2
-	// "mInstanceRespondsTo",										// D2 - XObject
-	// "mMessageList",			 									// D2 - XObject
-	// "mName",														// D2 - XObject
-	{ "mNew",					LM::m_new,			-1, 0, 2 },		// D2
-	// "mPerform",				 									// D2 - XObject
-	{ "mPut",					LM::m_put,			 2, 2, 2 },		// D2
-	// "mRespondsTo",		 										// D2 - XObject
-	{ 0, 0, 0, 0, 0 }
+	{ "mDescribe",				LM::m_describe,				 0, 0, kXObj,				2 },	// D2
+	{ "mDispose",				LM::m_dispose,				 0, 0, kFactoryObj | kXObj,	2 },	// D2
+	{ "mGet",					LM::m_get,					 1, 1, kFactoryObj,			2 },	// D2
+	{ "mInstanceRespondsTo",	LM::m_instanceRespondsTo,	 1, 1, kXObj,				3 },		// D3
+	{ "mMessageList",			LM::m_messageList,			 0, 0, kXObj,				3 },		// D3
+	{ "mName",					LM::m_name,					 0, 0, kXObj,				3 },		// D3
+	{ "mNew",					LM::m_new,					-1, 0, kFactoryObj | kXObj, 2 },	// D2
+	{ "mPerform",				LM::m_perform,				-1, 0, kFactoryObj | kXObj, 3 },		// D3
+	{ "mPut",					LM::m_put,					 2, 2, kFactoryObj,			2 },	// D2
+	{ "mRespondsTo",			LM::m_respondsTo,			 1, 1, kXObj,				2 },	// D2
+	{ 0, 0, 0, 0, 0, 0 }
+};
+
+static struct XLibProto {
+	const char *name;
+	void (*initializer)(int);
+	int version;
+} xlibs[] = {
+	{ "FileIO",					FileIO::b_openXLib,										2 },	// D2
+	{ 0, 0, 0 }
 };
 
 void Lingo::initMethods() {
@@ -58,16 +68,26 @@ void Lingo::initMethods() {
 		sym.type = FBLTIN;
 		sym.nargs = mtd->minArgs;
 		sym.maxArgs = mtd->maxArgs;
-		sym.parens = false;
+		sym.methodType = mtd->type;
 		sym.u.bltin = mtd->func;
 		_methods[mtd->name] = sym;
 	}
+
+	for (XLibProto *lib = xlibs; lib->name; lib++) {
+		if (lib->version > _vm->getVersion())
+			continue;
+
+		Symbol sym;
+		sym.type = FBLTIN;
+		sym.nargs = 0;
+		sym.maxArgs = 0;
+		sym.u.bltin = lib->initializer;
+		_xlibs[lib->name] = sym;
+	}
 }
 
 Object *Object::clone() {
-	Object *res = new Object;
-	res->name = name;
-	res->type = type;
+	Object *res = new Object(*name, type);
 	res->disposed = disposed;
 	res->prototype = this;
 	res->properties = properties;
@@ -80,14 +100,21 @@ Object *Object::clone() {
 	return res;
 }
 
+void Object::addProperty(const Common::String &propName) {
+	g_lingo->_currentMeObj->properties[propName] = Symbol();
+	g_lingo->_currentMeObj->properties[propName].name = new Common::String(propName);
+}
+
 Symbol Object::getMethod(const Common::String &methodName) {
 	if (disposed) {
 		error("Method '%s' called on disposed object '%s'", methodName.c_str(), name->c_str());
 	}
-	if (methods.contains(methodName)) {
+	if (methods.contains(methodName) && (inheritanceLevel > 1 || type == kFactoryObj)) {
+		// Instance methods can be called on an original factory object,
+		// but not on an original XObject
 		return methods[methodName];
 	}
-	if (g_lingo->_methods.contains(methodName)) {
+	if (g_lingo->_methods.contains(methodName) && (type & g_lingo->_methods[methodName].type)) {
 		return g_lingo->_methods[methodName];
 	}
 	return Symbol();
@@ -113,6 +140,7 @@ Symbol &Object::getVar(const Common::String &varName) {
 
 void LM::m_new(int nargs) {
 	// This is usually overridden by a user-defined mNew
+	g_lingo->printSTUBWithArglist("m_new", nargs);
 	Datum res;
 	res.type = OBJECT;
 	res.u.obj = g_lingo->_currentMeObj;
@@ -142,4 +170,63 @@ void LM::m_put(int nargs) {
 	(*g_lingo->_currentMeObj->objArray)[index] = value;
 }
 
+// Other
+
+void LM::m_perform(int nargs) {
+	// Lingo doesn't seem to bother cloning the object when
+	// mNew is called with mPerform
+	Datum methodName = g_lingo->_stack.remove_at(g_lingo->_stack.size() - nargs); // Take method name out of stack
+	nargs -= 1;
+	Symbol funcSym = g_lingo->_currentMeObj->getMethod(*methodName.u.s);
+	LC::call(funcSym, nargs, g_lingo->_currentMeObj);
+}
+
+// XObject
+
+void LM::m_describe(int nargs) {
+	warning("STUB: m_describe");
 }
+
+void LM::m_instanceRespondsTo(int nargs) {
+	Object *me = g_lingo->_currentMeObj;
+	Datum d = g_lingo->pop();
+	Common::String methodName = d.asString();
+
+	if (me->methods.contains(methodName)) {
+		g_lingo->push(Datum(1));
+		return;
+	}
+	if (g_lingo->_methods.contains(methodName) && (me->type & g_lingo->_methods[methodName].type)) {
+		g_lingo->push(Datum(1));
+		return;
+	}
+	g_lingo->push(Datum(0));
+}
+
+void LM::m_messageList(int nargs) {
+	warning("STUB: m_messageList");
+	g_lingo->push(Datum(""));
+}
+
+void LM::m_name(int nargs) {
+	Common::String name = *g_lingo->_currentMeObj->name;
+	g_lingo->push(Datum(name));
+}
+
+void LM::m_respondsTo(int nargs) {
+	Object *me = g_lingo->_currentMeObj;
+	Datum d = g_lingo->pop();
+	Common::String methodName = d.asString();
+
+	if (me->methods.contains(methodName) && me->inheritanceLevel > 1) {
+		g_lingo->push(Datum(1));
+		return;
+	}
+	if (g_lingo->_methods.contains(methodName) && (me->type & g_lingo->_methods[methodName].type)) {
+		g_lingo->push(Datum(1));
+		return;
+	}
+	g_lingo->push(Datum(0));
+}
+
+} // End of namespace Director
diff --git a/engines/director/lingo/lingo-object.h b/engines/director/lingo/lingo-object.h
index db818fbfd0..7ff8ba16a3 100644
--- a/engines/director/lingo/lingo-object.h
+++ b/engines/director/lingo/lingo-object.h
@@ -27,10 +27,16 @@ namespace Director {
 
 namespace LM {
 	// predefined methods
+	void m_describe(int nargs);
 	void m_dispose(int nargs);
 	void m_get(int nargs);
+	void m_instanceRespondsTo(int nargs);
+	void m_messageList(int nargs);
+	void m_name(int nargs);
 	void m_new(int nargs);
+	void m_perform(int nargs);
 	void m_put(int nargs);
+	void m_respondsTo(int nargs);
 
 } // End of namespace LM
 
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 2ffe060891..772327dc8a 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -46,6 +46,7 @@ Symbol::Symbol() {
 	nargs = 0;
 	maxArgs = 0;
 	parens = true;
+	methodType = kNoneObj;
 	global = false;
 	argNames = nullptr;
 	varNames = nullptr;
@@ -62,6 +63,7 @@ Symbol::Symbol(const Symbol &s) {
 	nargs = s.nargs;
 	maxArgs = s.maxArgs;
 	parens = s.parens;
+	methodType = s.methodType;
 	global = s.global;
 	argNames = s.argNames;
 	varNames = s.varNames;
@@ -80,6 +82,7 @@ Symbol& Symbol::operator=(const Symbol &s) {
 		nargs = s.nargs;
 		maxArgs = s.maxArgs;
 		parens = s.parens;
+		methodType = s.methodType;
 		global = s.global;
 		argNames = s.argNames;
 		varNames = s.varNames;
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index c0a5a8e247..27a760348c 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -96,6 +96,7 @@ struct Symbol {	/* symbol table entry */
 	int nargs;		/* number of arguments */
 	int maxArgs;	/* maximal number of arguments, for builtins */
 	bool parens;	/* whether parens required or not, for builitins */
+	int methodType;	/* valid target objects, for method builtins */
 
 	bool global;
 	Common::Array<Common::String> *argNames;
@@ -246,8 +247,10 @@ typedef Common::HashMap<Common::String, TheEntity *, Common::IgnoreCase_Hash, Co
 typedef Common::HashMap<Common::String, TheEntityField *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> TheEntityFieldHash;
 
 enum ObjectType {
-	kFactoryObj = 0,
-	kScriptObj = 1
+	kNoneObj = 0,
+	kFactoryObj = 1 << 0,
+	kXObj = 1 << 1,
+	kScriptObj = 1 << 2
 };
 
 struct Object {
@@ -264,7 +267,21 @@ struct Object {
 	// used only for factories
 	Common::HashMap<uint32, Datum> *objArray;
 
+	Object(const Common::String &objName, ObjectType objType, ScriptContext *objContext = nullptr) {
+		name = new Common::String(objName);
+		type = objType;
+		disposed = false;
+		inheritanceLevel = 1;
+		scriptContext = objContext;
+		if (objType == kFactoryObj) {
+			objArray = new Common::HashMap<uint32, Datum>;
+		} else {
+			objArray = nullptr;
+		}
+	}
+
 	Object *clone();
+	void addProperty(const Common::String &propName);
 	Symbol getMethod(const Common::String &methodName);
 	bool hasVar(const Common::String &varName);
 	Symbol &getVar(const Common::String &varName);
@@ -498,6 +515,7 @@ public:
 
 	SymbolHash _builtins;
 	SymbolHash _methods;
+	SymbolHash _xlibs;
 
 	Common::String _floatPrecisionFormat;
 
diff --git a/engines/director/lingo/xobject/fileio.cpp b/engines/director/lingo/xobject/fileio.cpp
new file mode 100644
index 0000000000..696ca064a4
--- /dev/null
+++ b/engines/director/lingo/xobject/fileio.cpp
@@ -0,0 +1,82 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "director/director.h"
+#include "director/lingo/lingo.h"
+#include "director/lingo/lingo-object.h"
+#include "director/lingo/xobject/fileio.h"
+
+namespace Director {
+
+static struct MethodProto {
+	const char *name;
+	void (*func)(int);
+	int minArgs;	// -1 -- arglist
+	int maxArgs;
+	int type;
+	int version;
+} predefinedMethods[] = {
+	{ "mNew",					FileIO::m_new,				 2, 2, kFactoryObj,			2 },	// D2
+	{ 0, 0, 0, 0, 0, 0 }
+};
+
+void FileIO::b_openXLib(int nargs) {
+	const Common::String name = "FileIO";
+
+	if (g_lingo->_globalvars.contains(name)) {
+		warning("FileIO already initialized");
+		return;
+	}
+
+	Object *obj = new Object(name, kXObj);
+
+	for (MethodProto *mtd = predefinedMethods; mtd->name; mtd++) {
+		if (mtd->version > g_lingo->_vm->getVersion())
+			continue;
+
+		Symbol sym;
+		sym.name = new Common::String(mtd->name);
+		sym.type = FBLTIN;
+		sym.nargs = mtd->minArgs;
+		sym.maxArgs = mtd->maxArgs;
+		sym.methodType = mtd->type;
+		sym.u.bltin = mtd->func;
+		obj->methods[mtd->name] = sym;
+	}
+
+	g_lingo->_globalvars[name] = Symbol();
+	g_lingo->_globalvars[name].name = new Common::String(name);
+	g_lingo->_globalvars[name].global = true;
+	g_lingo->_globalvars[name].type = OBJECT;
+	g_lingo->_globalvars[name].u.obj = obj;
+}
+
+// Initialization/disposal
+
+void FileIO::m_new(int nargs) {
+	Datum res;
+	res.type = OBJECT;
+	res.u.obj = g_lingo->_currentMeObj;
+	g_lingo->push(res);
+}
+
+} // End of namespace Director
diff --git a/engines/director/lingo/xobject/fileio.h b/engines/director/lingo/xobject/fileio.h
new file mode 100644
index 0000000000..4a14714133
--- /dev/null
+++ b/engines/director/lingo/xobject/fileio.h
@@ -0,0 +1,38 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef DIRECTOR_LINGO_XOBJECT_FILEIO_H
+#define DIRECTOR_LINGO_XOBJECT_FILEIO_H
+
+#include "director/lingo/lingo-object.h"
+
+namespace Director {
+
+namespace FileIO {
+	void b_openXLib(int nargs);
+	void m_new(int nargs);
+
+} // End of namespace FileIO
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/module.mk b/engines/director/module.mk
index 6b6c755bf7..f9cdf5fa72 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -32,7 +32,8 @@ MODULE_OBJS = \
 	lingo/lingo-object.o \
 	lingo/lingo-patcher.o \
 	lingo/lingo-preprocessor.o \
-	lingo/lingo-the.o
+	lingo/lingo-the.o \
+	lingo/xobject/fileio.o
 
 director-grammar:
 	`brew --prefix flex`/bin/flex engines/director/lingo/lingo-lex.l


Commit: 9906f637e390e3f9000bbf27867209f4c70222ce
    https://github.com/scummvm/scummvm/commit/9906f637e390e3f9000bbf27867209f4c70222ce
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-10T12:18:29-04:00

Commit Message:
DIRECTOR: LINGO: Add Object destructor

Changed paths:
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 772327dc8a..fe1a8131b5 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -114,6 +114,9 @@ void Symbol::reset() {
 		case PARRAY:
 			delete u.parr;
 			break;
+		case OBJECT:
+			delete u.obj;
+			break;
 		case VAR:
 			// fallthrough
 		case REFERENCE:
@@ -681,6 +684,42 @@ int Lingo::getAlignedType(Datum &d1, Datum &d2) {
 	return opType;
 }
 
+void Datum::reset() {
+	*refCount -= 1;
+	if (*refCount <= 0) {
+		switch (type) {
+		case VAR:
+			// fallthrough
+		case STRING:
+			delete u.s;
+			break;
+		case ARRAY:
+			// fallthrough
+		case POINT:
+			// fallthrough
+		case RECT:
+			delete u.farr;
+			break;
+		case PARRAY:
+			delete u.parr;
+			break;
+		case OBJECT:
+			delete u.obj;
+			break;
+		case REFERENCE:
+			// fallthrough
+		case INT:
+			// fallthrough
+		case FLOAT:
+			// fallthrough
+		default:
+			break;
+		}
+		delete refCount;
+	}
+
+}
+
 Datum Datum::eval() {
 	if (type != VAR) { // It could be cast ref
 		lazy = false;
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 27a760348c..61fb38c659 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -171,38 +171,8 @@ struct Datum {	/* interpreter stack type */
 		refCount = new int;
 		*refCount = 1;
 	}
-	void reset() {
-		*refCount -= 1;
-		if (*refCount <= 0) {
-			switch (type) {
-			case VAR:
-				// fallthrough
-			case STRING:
-				delete u.s;
-				break;
-			case ARRAY:
-				// fallthrough
-			case POINT:
-				// fallthrough
-			case RECT:
-				delete u.farr;
-				break;
-			case PARRAY:
-				delete u.parr;
-				break;
-			case REFERENCE:
-				// fallthrough
-			case INT:
-				// fallthrough
-			case FLOAT:
-				// fallthrough
-			default:
-				break;
-			}
-			delete refCount;
-		}
 
-	}
+	void reset();
 
 	~Datum() {
 		reset();
@@ -280,7 +250,12 @@ struct Object {
 		}
 	}
 
-	Object *clone();
+	virtual ~Object() {
+		delete name;
+		delete objArray;
+	}
+
+	virtual Object *clone();
 	void addProperty(const Common::String &propName);
 	Symbol getMethod(const Common::String &methodName);
 	bool hasVar(const Common::String &varName);


Commit: d43d5592a68ce3b0a40f948e79dffaf7b033b267
    https://github.com/scummvm/scummvm/commit/d43d5592a68ce3b0a40f948e79dffaf7b033b267
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-10T12:18:29-04:00

Commit Message:
DIRECTOR: LINGO: Stub FileIO

Changed paths:
    engines/director/lingo/xobject/fileio.cpp
    engines/director/lingo/xobject/fileio.h


diff --git a/engines/director/lingo/xobject/fileio.cpp b/engines/director/lingo/xobject/fileio.cpp
index 696ca064a4..e34055a74c 100644
--- a/engines/director/lingo/xobject/fileio.cpp
+++ b/engines/director/lingo/xobject/fileio.cpp
@@ -20,6 +20,8 @@
  *
  */
 
+#include "gui/filebrowser-dialog.h"
+
 #include "director/director.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-object.h"
@@ -35,7 +37,19 @@ static struct MethodProto {
 	int type;
 	int version;
 } predefinedMethods[] = {
-	{ "mNew",					FileIO::m_new,				 2, 2, kFactoryObj,			2 },	// D2
+	{ "mDelete",				FileIO::m_delete,			 0, 0, kXObj,				2 },	// D2
+	{ "mDispose",				FileIO::m_dispose,			 0, 0, kXObj,				2 },	// D2
+	{ "mFileName",				FileIO::m_fileName,			 0, 0, kXObj,				2 },	// D2
+	{ "mGetLength",				FileIO::m_getLength,		 0, 0, kXObj,				2 },	// D2
+	{ "mGetPosition",			FileIO::m_getPosition,		 0, 0, kXObj,				2 },	// D2
+	{ "mNew",					FileIO::m_new,				 2, 2, kXObj,				2 },	// D2
+	{ "mReadChar",				FileIO::m_readChar,			 0, 0, kXObj,				2 },	// D2
+	{ "mReadLine",				FileIO::m_readLine,			 0, 0, kXObj,				2 },	// D2
+	{ "mReadToken",				FileIO::m_readToken,		 2, 2, kXObj,				2 },	// D2
+	{ "mReadWord",				FileIO::m_readWord,			 0, 0, kXObj,				2 },	// D2
+	{ "mSetPosition",			FileIO::m_setPosition,		 1, 1, kXObj,				2 },	// D2
+	{ "mWriteChar",				FileIO::m_writeChar,		 1, 1, kXObj,				2 },	// D2
+	{ "mWriteString",			FileIO::m_writeString,		 1, 1, kXObj,				2 },	// D2
 	{ 0, 0, 0, 0, 0, 0 }
 };
 
@@ -47,7 +61,7 @@ void FileIO::b_openXLib(int nargs) {
 		return;
 	}
 
-	Object *obj = new Object(name, kXObj);
+	FileXObject *obj = new FileXObject();
 
 	for (MethodProto *mtd = predefinedMethods; mtd->name; mtd++) {
 		if (mtd->version > g_lingo->_vm->getVersion())
@@ -72,11 +86,145 @@ void FileIO::b_openXLib(int nargs) {
 
 // Initialization/disposal
 
+Object *FileXObject::clone() {
+	FileXObject *res = new FileXObject();
+	res->disposed = disposed;
+	res->prototype = this;
+	res->properties = properties;
+	res->methods = methods;
+	res->inheritanceLevel = inheritanceLevel + 1;
+	return res;
+}
+
 void FileIO::m_new(int nargs) {
+	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+
+	Datum d2 = g_lingo->pop();
+	Datum d1 = g_lingo->pop();
+
+	Common::String option = *d1.u.s;
+	Common::String filename = *d2.u.s;
+
+	if (option.hasPrefix("?")) {
+		option = option.substr(1);
+		GUI::FileBrowserDialog browser(0, filename.c_str(), option.equalsIgnoreCase("read") ? GUI::kFBModeLoad : GUI::kFBModeSave);
+		if (browser.runModal() <= 0) {
+			g_lingo->push(Datum(kErrorFileNotFound));
+			return;
+		}
+		filename = browser.getResult();
+	}
+
+	if (option.equalsIgnoreCase("read")) {
+		me->infile = g_system->getSavefileManager()->openForLoading(filename);
+		if (!me->infile) {
+			g_lingo->push(Datum(kErrorIO));
+			return;
+		}
+	} else if (option.equalsIgnoreCase("write")) {
+		me->outfile = g_system->getSavefileManager()->openForSaving(filename);
+		if (!me->outfile) {
+			g_lingo->push(Datum(kErrorIO));
+			return;
+		}
+	} else if (option.equalsIgnoreCase("append")) {
+		warning("FileIO: append is unimplemented");
+	} else {
+		error("Unsupported FileIO option: '%s'", option.c_str());
+	}
+
 	Datum res;
 	res.type = OBJECT;
-	res.u.obj = g_lingo->_currentMeObj;
+	res.u.obj = me;
 	g_lingo->push(res);
 }
 
+void FileIO::m_dispose(int nargs) {
+	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+
+	me->disposed = true;
+
+	if (me->infile) {
+		delete me->infile;
+		me->infile = nullptr;
+	}
+	if (me->outfile) {
+		me->outfile->finalize();
+		delete me->outfile;
+		me->outfile = nullptr;
+	}
+}
+
+// Read
+
+void FileIO::m_readChar(int nargs) {
+	g_lingo->printSTUBWithArglist("m_readChar", 0);
+	g_lingo->push(Datum(0));
+}
+
+void FileIO::m_readLine(int nargs) {
+	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+
+	if (me->infile) {
+		Common::String line = me->infile->readLine();
+		g_lingo->push(Datum(line));
+	} else {
+		g_lingo->push(Datum(""));
+	}
+}
+
+void FileIO::m_readWord(int nargs) {
+	g_lingo->printSTUBWithArglist("m_readWord", 0);
+	g_lingo->push(Datum(""));
+}
+
+void FileIO::m_readToken(int nargs) {
+	g_lingo->printSTUBWithArglist("m_readToken", 2);
+	g_lingo->push(Datum(""));
+}
+
+// Write
+
+void FileIO::m_writeChar(int nargs) {
+	g_lingo->printSTUBWithArglist("m_writeChar", 1);
+	g_lingo->push(Datum(0));
+}
+
+void FileIO::m_writeString(int nargs) {
+	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	Datum d = g_lingo->pop();
+
+	if (me->outfile) {
+		me->outfile->writeString(d.asString());
+		g_lingo->push(Datum(kErrorNone));
+	} else {
+		g_lingo->push(Datum(kErrorReadOnly));
+	}
+}
+
+// Other
+
+void FileIO::m_getPosition(int nargs) {
+	g_lingo->printSTUBWithArglist("m_getPosition", 0);
+	g_lingo->push(Datum(0));
+}
+
+void FileIO::m_setPosition(int nargs) {
+	g_lingo->printSTUBWithArglist("m_setPosition", 1);
+}
+
+void FileIO::m_getLength(int nargs) {
+	g_lingo->printSTUBWithArglist("m_getLength", 0);
+	g_lingo->push(Datum(0));
+}
+
+void FileIO::m_fileName(int nargs) {
+	g_lingo->printSTUBWithArglist("m_fileName", 0);
+	g_lingo->push(Datum(""));
+}
+
+void FileIO::m_delete(int nargs) {
+	g_lingo->printSTUBWithArglist("m_delete", 0);
+}
+
 } // End of namespace Director
diff --git a/engines/director/lingo/xobject/fileio.h b/engines/director/lingo/xobject/fileio.h
index 4a14714133..5c7146c1e8 100644
--- a/engines/director/lingo/xobject/fileio.h
+++ b/engines/director/lingo/xobject/fileio.h
@@ -23,13 +23,59 @@
 #ifndef DIRECTOR_LINGO_XOBJECT_FILEIO_H
 #define DIRECTOR_LINGO_XOBJECT_FILEIO_H
 
+#include "common/savefile.h"
 #include "director/lingo/lingo-object.h"
 
 namespace Director {
 
+enum FileIOError {
+	kErrorNone = 0,
+	kErrorDirectoryFull = -33,
+	kErrorVolumeFull = -34,
+	kErrorVolumeNotFound = -35,
+	kErrorIO = -36,
+	kErrorBadFileName = -37,
+	kErrorFileNotOpen = -38,
+	kErrorTooManyFilesOpen = -42,
+	kErrorFileNotFound = -43,
+	kErrorNoSuchDrive = -56,
+	kErrorReadOnly = -61, // undocumented
+	kErrorNoDiskInDrive = -65,
+	kErrorDirectoryNotFound = -120
+};
+
+struct FileXObject : Object {
+	Common::InSaveFile *infile;
+	Common::OutSaveFile *outfile;
+
+	FileXObject() : Object("FileIO", kXObj) {
+		infile = nullptr;
+		outfile = nullptr;
+	}
+
+	virtual ~FileXObject() {
+		delete infile;
+		delete outfile;
+	}
+
+	virtual Object *clone();
+};
+
 namespace FileIO {
 	void b_openXLib(int nargs);
+	void m_delete(int nargs);
+	void m_dispose(int nargs);
+	void m_fileName(int nargs);
+	void m_getLength(int nargs);
+	void m_getPosition(int nargs);
 	void m_new(int nargs);
+	void m_readChar(int nargs);
+	void m_readLine(int nargs);
+	void m_readToken(int nargs);
+	void m_readWord(int nargs);
+	void m_setPosition(int nargs);
+	void m_writeChar(int nargs);
+	void m_writeString(int nards);
 
 } // End of namespace FileIO
 


Commit: be7e414d0f7feb5c4c2b7d9322c6c8dae6da312e
    https://github.com/scummvm/scummvm/commit/be7e414d0f7feb5c4c2b7d9322c6c8dae6da312e
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-10T12:18:29-04:00

Commit Message:
DIRECTOR: LINGO: Implement FileIO methods

Changed paths:
    engines/director/lingo/xobject/fileio.cpp
    engines/director/lingo/xobject/fileio.h


diff --git a/engines/director/lingo/xobject/fileio.cpp b/engines/director/lingo/xobject/fileio.cpp
index e34055a74c..821bc5eb0f 100644
--- a/engines/director/lingo/xobject/fileio.cpp
+++ b/engines/director/lingo/xobject/fileio.cpp
@@ -34,23 +34,22 @@ static struct MethodProto {
 	void (*func)(int);
 	int minArgs;	// -1 -- arglist
 	int maxArgs;
-	int type;
 	int version;
 } predefinedMethods[] = {
-	{ "mDelete",				FileIO::m_delete,			 0, 0, kXObj,				2 },	// D2
-	{ "mDispose",				FileIO::m_dispose,			 0, 0, kXObj,				2 },	// D2
-	{ "mFileName",				FileIO::m_fileName,			 0, 0, kXObj,				2 },	// D2
-	{ "mGetLength",				FileIO::m_getLength,		 0, 0, kXObj,				2 },	// D2
-	{ "mGetPosition",			FileIO::m_getPosition,		 0, 0, kXObj,				2 },	// D2
-	{ "mNew",					FileIO::m_new,				 2, 2, kXObj,				2 },	// D2
-	{ "mReadChar",				FileIO::m_readChar,			 0, 0, kXObj,				2 },	// D2
-	{ "mReadLine",				FileIO::m_readLine,			 0, 0, kXObj,				2 },	// D2
-	{ "mReadToken",				FileIO::m_readToken,		 2, 2, kXObj,				2 },	// D2
-	{ "mReadWord",				FileIO::m_readWord,			 0, 0, kXObj,				2 },	// D2
-	{ "mSetPosition",			FileIO::m_setPosition,		 1, 1, kXObj,				2 },	// D2
-	{ "mWriteChar",				FileIO::m_writeChar,		 1, 1, kXObj,				2 },	// D2
-	{ "mWriteString",			FileIO::m_writeString,		 1, 1, kXObj,				2 },	// D2
-	{ 0, 0, 0, 0, 0, 0 }
+	{ "mDelete",				FileIO::m_delete,			 0, 0,						2 },	// D2
+	{ "mDispose",				FileIO::m_dispose,			 0, 0,						2 },	// D2
+	{ "mFileName",				FileIO::m_fileName,			 0, 0,						2 },	// D2
+	{ "mGetLength",				FileIO::m_getLength,		 0, 0,						2 },	// D2
+	{ "mGetPosition",			FileIO::m_getPosition,		 0, 0,						2 },	// D2
+	{ "mNew",					FileIO::m_new,				 2, 2,						2 },	// D2
+	{ "mReadChar",				FileIO::m_readChar,			 0, 0,						2 },	// D2
+	{ "mReadLine",				FileIO::m_readLine,			 0, 0,						2 },	// D2
+	{ "mReadToken",				FileIO::m_readToken,		 2, 2,						2 },	// D2
+	{ "mReadWord",				FileIO::m_readWord,			 0, 0,						2 },	// D2
+	{ "mSetPosition",			FileIO::m_setPosition,		 1, 1,						2 },	// D2
+	{ "mWriteChar",				FileIO::m_writeChar,		 1, 1,						2 },	// D2
+	{ "mWriteString",			FileIO::m_writeString,		 1, 1,						2 },	// D2
+	{ 0, 0, 0, 0, 0 }
 };
 
 void FileIO::b_openXLib(int nargs) {
@@ -72,7 +71,7 @@ void FileIO::b_openXLib(int nargs) {
 		sym.type = FBLTIN;
 		sym.nargs = mtd->minArgs;
 		sym.maxArgs = mtd->maxArgs;
-		sym.methodType = mtd->type;
+		sym.methodType = kXObj;
 		sym.u.bltin = mtd->func;
 		obj->methods[mtd->name] = sym;
 	}
@@ -96,6 +95,30 @@ Object *FileXObject::clone() {
 	return res;
 }
 
+void FileXObject::dispose() {
+	disposed = true;
+
+	if (filename) {
+		delete filename;
+		filename = nullptr;
+	}
+	if (inFile) {
+		delete inFile;
+		if (inStream != inFile)
+			delete inStream;
+		inFile = nullptr;
+		inStream = nullptr;
+	}
+	if (outFile) {
+		outFile->write(outStream->getData(), outStream->size());
+		outFile->finalize();
+		delete outFile;
+		delete outStream;
+		outFile = nullptr;
+		outStream = nullptr;
+	}
+}
+
 void FileIO::m_new(int nargs) {
 	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
 
@@ -116,14 +139,20 @@ void FileIO::m_new(int nargs) {
 	}
 
 	if (option.equalsIgnoreCase("read")) {
-		me->infile = g_system->getSavefileManager()->openForLoading(filename);
-		if (!me->infile) {
+		me->inFile = g_system->getSavefileManager()->openForLoading(filename);
+		me->inStream = me->inFile;
+		if (!me->inFile) {
+			delete me;
 			g_lingo->push(Datum(kErrorIO));
 			return;
 		}
 	} else if (option.equalsIgnoreCase("write")) {
-		me->outfile = g_system->getSavefileManager()->openForSaving(filename);
-		if (!me->outfile) {
+		// OutSaveFile is not seekable so create a separate seekable stream
+		// which will be written to the outfile upon disposal
+		me->outFile = g_system->getSavefileManager()->openForSaving(filename);
+		me->outStream = new Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES);
+		if (!me->outFile) {
+			delete me;
 			g_lingo->push(Datum(kErrorIO));
 			return;
 		}
@@ -133,6 +162,8 @@ void FileIO::m_new(int nargs) {
 		error("Unsupported FileIO option: '%s'", option.c_str());
 	}
 
+	me->filename = new Common::String(filename);
+
 	Datum res;
 	res.type = OBJECT;
 	res.u.obj = me;
@@ -141,90 +172,197 @@ void FileIO::m_new(int nargs) {
 
 void FileIO::m_dispose(int nargs) {
 	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
-
-	me->disposed = true;
-
-	if (me->infile) {
-		delete me->infile;
-		me->infile = nullptr;
-	}
-	if (me->outfile) {
-		me->outfile->finalize();
-		delete me->outfile;
-		me->outfile = nullptr;
-	}
+	me->dispose();
 }
 
 // Read
 
 void FileIO::m_readChar(int nargs) {
-	g_lingo->printSTUBWithArglist("m_readChar", 0);
-	g_lingo->push(Datum(0));
+	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+
+	if (!me->inStream || me->inStream->eos() || me->inStream->err()) {
+		g_lingo->push(Datum(kErrorEOF));
+		return;
+	}
+
+	int ch = me->inStream->readByte();
+	if (me->inStream->eos() || me->inStream->err()) {
+		ch = kErrorEOF;
+	}
+	g_lingo->push(Datum(ch));
 }
 
 void FileIO::m_readLine(int nargs) {
-	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	// file(mReadLine) is equivalent to file(mReadToken, "", RETURN)
+	// See D4 Using Lingo p. 323
 
-	if (me->infile) {
-		Common::String line = me->infile->readLine();
-		g_lingo->push(Datum(line));
-	} else {
-		g_lingo->push(Datum(""));
-	}
+	g_lingo->push(Datum(""));
+	g_lingo->push(Datum("\n"));
+	FileIO::m_readToken(2);
 }
 
 void FileIO::m_readWord(int nargs) {
-	g_lingo->printSTUBWithArglist("m_readWord", 0);
-	g_lingo->push(Datum(""));
+	// file(mReadWord) is equivalent to file(mReadToken, " ", " " & RETURN)
+	// See D4 Using Lingo p. 323
+
+	g_lingo->push(Datum(" "));
+	g_lingo->push(Datum(" \n"));
+	FileIO::m_readToken(2);
 }
 
 void FileIO::m_readToken(int nargs) {
-	g_lingo->printSTUBWithArglist("m_readToken", 2);
-	g_lingo->push(Datum(""));
+	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+
+	Datum d2 = g_lingo->pop();
+	Datum d1 = g_lingo->pop();
+
+	Common::String skipString = *d1.u.s;
+	Common::String breakString = *d2.u.s;
+
+	if (!me->inStream || me->inStream->eos() || me->inStream->err()) {
+		g_lingo->push(Datum(""));
+		return;
+	}
+
+	Common::String tok = "";
+	char ch;
+	do {
+		ch = me->inStream->readByte();
+		if (me->inStream->eos() || me->inStream->err()) {
+			g_lingo->push(Datum(tok));
+			return;
+		}
+	} while (skipString.contains(ch));
+
+	while (!breakString.contains(ch)) {
+		tok += ch;
+		ch = me->inStream->readByte();
+
+		if (me->inStream->eos() || me->inStream->err()) {
+			g_lingo->push(Datum(tok));
+			return;
+		}
+	}
+
+	// Include the break character when the skipString is empty
+	if (skipString.size() == 0) {
+		tok += ch;
+	} else {
+		me->inStream->seek(-1, SEEK_CUR);
+	}
+
+	g_lingo->push(Datum(tok));
 }
 
 // Write
 
 void FileIO::m_writeChar(int nargs) {
-	g_lingo->printSTUBWithArglist("m_writeChar", 1);
-	g_lingo->push(Datum(0));
+	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	Datum d = g_lingo->pop();
+
+	if (!me->outStream) {
+		g_lingo->push(Datum(kErrorReadOnly));
+		return;
+	}
+
+	me->outStream->writeByte(d.asInt());
+	g_lingo->push(Datum(kErrorNone));
 }
 
 void FileIO::m_writeString(int nargs) {
 	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
 	Datum d = g_lingo->pop();
 
-	if (me->outfile) {
-		me->outfile->writeString(d.asString());
-		g_lingo->push(Datum(kErrorNone));
-	} else {
+	if (!me->outStream) {
 		g_lingo->push(Datum(kErrorReadOnly));
+		return;
 	}
+
+	me->outStream->writeString(d.asString());
+	g_lingo->push(Datum(kErrorNone));
 }
 
 // Other
 
 void FileIO::m_getPosition(int nargs) {
-	g_lingo->printSTUBWithArglist("m_getPosition", 0);
-	g_lingo->push(Datum(0));
+	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+
+	if (me->inStream) {
+		g_lingo->push(Datum(me->inStream->pos()));
+	} else if (me->outStream) {
+		g_lingo->push(Datum(me->outStream->pos()));
+	} else {
+		warning("FileIO: No file open");
+		g_lingo->push(Datum(kErrorFileNotOpen));
+	}
 }
 
 void FileIO::m_setPosition(int nargs) {
-	g_lingo->printSTUBWithArglist("m_setPosition", 1);
+	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	Datum d = g_lingo->pop();
+	int pos = d.asInt();
+
+	if (me->inStream) {
+		if (pos <= me->inStream->size()) {
+			me->inStream->seek(pos, SEEK_SET);
+			g_lingo->push(Datum(kErrorNone));
+		} else {
+			me->inStream->seek(me->inStream->size(), SEEK_SET);
+			g_lingo->push(Datum(kErrorInvalidPos));
+		}
+	} else if (me->outStream) {
+		if (pos <= me->outStream->size()) {
+			me->outStream->seek(pos, SEEK_SET);
+			g_lingo->push(Datum(kErrorNone));
+		} else {
+			me->outStream->seek(me->outStream->size(), SEEK_SET);
+			g_lingo->push(Datum(kErrorInvalidPos));
+		}
+	} else {
+		warning("FileIO: No file open");
+		g_lingo->push(Datum(kErrorFileNotOpen));
+	}
 }
 
 void FileIO::m_getLength(int nargs) {
-	g_lingo->printSTUBWithArglist("m_getLength", 0);
-	g_lingo->push(Datum(0));
+	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+
+	if (me->inStream) {
+		g_lingo->push(Datum(me->inStream->size()));
+	} else if (me->outStream) {
+		g_lingo->push(Datum(me->outStream->size()));
+	} else {
+		warning("FileIO: No file open");
+		g_lingo->push(Datum(kErrorFileNotOpen));
+	}
 }
 
 void FileIO::m_fileName(int nargs) {
-	g_lingo->printSTUBWithArglist("m_fileName", 0);
-	g_lingo->push(Datum(""));
+	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+
+	if (me->filename) {
+		g_lingo->push(Datum(*me->filename));
+	} else {
+		warning("FileIO: No file open");
+		g_lingo->push(Datum(kErrorFileNotOpen));
+	}
 }
 
 void FileIO::m_delete(int nargs) {
-	g_lingo->printSTUBWithArglist("m_delete", 0);
+	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+
+	if (me->filename) {
+		Common::String filename = *me->filename;
+		me->dispose();
+		if (g_system->getSavefileManager()->removeSavefile(filename)) {
+			g_lingo->push(Datum(kErrorNone));
+		} else {
+			g_lingo->push(Datum(kErrorIO));
+		}
+	} else {
+		warning("FileIO: No file open");
+		g_lingo->push(Datum(kErrorFileNotOpen));
+	}
 }
 
 } // End of namespace Director
diff --git a/engines/director/lingo/xobject/fileio.h b/engines/director/lingo/xobject/fileio.h
index 5c7146c1e8..8f8f8ca8d8 100644
--- a/engines/director/lingo/xobject/fileio.h
+++ b/engines/director/lingo/xobject/fileio.h
@@ -23,6 +23,7 @@
 #ifndef DIRECTOR_LINGO_XOBJECT_FILEIO_H
 #define DIRECTOR_LINGO_XOBJECT_FILEIO_H
 
+#include "common/memstream.h"
 #include "common/savefile.h"
 #include "director/lingo/lingo-object.h"
 
@@ -30,12 +31,14 @@ namespace Director {
 
 enum FileIOError {
 	kErrorNone = 0,
+	kErrorEOF = -1,
 	kErrorDirectoryFull = -33,
 	kErrorVolumeFull = -34,
 	kErrorVolumeNotFound = -35,
 	kErrorIO = -36,
 	kErrorBadFileName = -37,
 	kErrorFileNotOpen = -38,
+	kErrorInvalidPos = -39, // undocumented
 	kErrorTooManyFilesOpen = -42,
 	kErrorFileNotFound = -43,
 	kErrorNoSuchDrive = -56,
@@ -45,20 +48,26 @@ enum FileIOError {
 };
 
 struct FileXObject : Object {
-	Common::InSaveFile *infile;
-	Common::OutSaveFile *outfile;
+	Common::String *filename;
+	Common::InSaveFile *inFile;
+	Common::SeekableReadStream *inStream;
+	Common::OutSaveFile *outFile;
+	Common::MemoryWriteStreamDynamic *outStream;
 
 	FileXObject() : Object("FileIO", kXObj) {
-		infile = nullptr;
-		outfile = nullptr;
+		filename = nullptr;
+		inFile = nullptr;
+		inStream = nullptr;
+		outFile = nullptr;
+		outStream = nullptr;
 	}
 
 	virtual ~FileXObject() {
-		delete infile;
-		delete outfile;
+		dispose();
 	}
 
 	virtual Object *clone();
+	void dispose();
 };
 
 namespace FileIO {


Commit: 1c6b519197d4390f225c91f9b800060f4d5ed649
    https://github.com/scummvm/scummvm/commit/1c6b519197d4390f225c91f9b800060f4d5ed649
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-10T12:18:29-04:00

Commit Message:
DIRECTOR: LINGO: Print object pointers

Changed paths:
    engines/director/lingo/lingo-object.cpp
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 3c39045bcc..e8f2ee834c 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -107,7 +107,7 @@ void Object::addProperty(const Common::String &propName) {
 
 Symbol Object::getMethod(const Common::String &methodName) {
 	if (disposed) {
-		error("Method '%s' called on disposed object '%s'", methodName.c_str(), name->c_str());
+		error("Method '%s' called on disposed object <%s>", methodName.c_str(), Datum(this).asString(true).c_str());
 	}
 	if (methods.contains(methodName) && (inheritanceLevel > 1 || type == kFactoryObj)) {
 		// Instance methods can be called on an original factory object,
@@ -122,7 +122,7 @@ Symbol Object::getMethod(const Common::String &methodName) {
 
 bool Object::hasVar(const Common::String &varName) {
 	if (disposed) {
-		error("Variable '%s' accessed on disposed object '%s'", varName.c_str(), name->c_str());
+		error("Variable '%s' accessed on disposed object <%s>", varName.c_str(), Datum(this).asString(true).c_str());
 	}
 	// Factory object instance vars are accessed like normal vars
 	// Script object properties cannot be accessed like normal vars until D5
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index fe1a8131b5..398a403424 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -832,7 +832,7 @@ Common::String Datum::asString(bool printonly) {
 		if (!printonly) {
 			s = Common::String::format("#%s", u.obj->name->c_str());
 		} else {
-			s = Common::String::format("object: #%s %d", u.obj->name->c_str(), u.obj->inheritanceLevel);
+			s = Common::String::format("object: #%s %d %p", u.obj->name->c_str(), u.obj->inheritanceLevel, (void *)u.obj);
 		}
 		break;
 	case VOID:
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 61fb38c659..9732c76e37 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -171,6 +171,13 @@ struct Datum {	/* interpreter stack type */
 		refCount = new int;
 		*refCount = 1;
 	}
+	Datum(Object *val) {
+		u.obj = val;
+		type = OBJECT;
+		lazy = false;
+		refCount = new int;
+		*refCount = 1;
+	}
 
 	void reset();
 


Commit: a547ff408a0f25b73552d8919d0fe86e05635bc6
    https://github.com/scummvm/scummvm/commit/a547ff408a0f25b73552d8919d0fe86e05635bc6
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-10T12:18:29-04:00

Commit Message:
DIRECTOR: LINGO: Fix re-assignment of object var

Changed paths:
    engines/director/lingo/lingo.cpp


diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 398a403424..8c4c5911f1 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1128,7 +1128,7 @@ void Lingo::varAssign(Datum &var, Datum &value, bool global, SymbolHash *localva
 
 		if (sym->type != INT && sym->type != VOID &&
 				sym->type != FLOAT && sym->type != STRING &&
-				sym->type != ARRAY && sym->type != PARRAY) {
+				sym->type != ARRAY && sym->type != PARRAY && sym->type != OBJECT) {
 			warning("varAssign: assignment to non-variable '%s'", sym->name->c_str());
 			return;
 		}


Commit: 0b2c92d99ba695fb1bc547d00cb382687d95e159
    https://github.com/scummvm/scummvm/commit/0b2c92d99ba695fb1bc547d00cb382687d95e159
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-10T12:18:29-04:00

Commit Message:
DIRECTOR: LINGO: Implement FileIO append mode

Changed paths:
    engines/director/lingo/xobject/fileio.cpp


diff --git a/engines/director/lingo/xobject/fileio.cpp b/engines/director/lingo/xobject/fileio.cpp
index 821bc5eb0f..608bfb73ff 100644
--- a/engines/director/lingo/xobject/fileio.cpp
+++ b/engines/director/lingo/xobject/fileio.cpp
@@ -157,7 +157,23 @@ void FileIO::m_new(int nargs) {
 			return;
 		}
 	} else if (option.equalsIgnoreCase("append")) {
-		warning("FileIO: append is unimplemented");
+		Common::InSaveFile *inFile = g_system->getSavefileManager()->openForLoading(filename);
+		if (!inFile) {
+			delete me;
+			g_lingo->push(Datum(kErrorIO));
+			return;
+		}
+		me->outFile = g_system->getSavefileManager()->openForSaving(filename);
+		me->outStream = new Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES);
+		if (!me->outFile) {
+			delete me;
+			g_lingo->push(Datum(kErrorIO));
+			return;
+		}
+		while (!inFile->eos() && !inFile->err()) {
+			me->outStream->writeByte(inFile->readByte());
+		}
+		delete inFile;
 	} else {
 		error("Unsupported FileIO option: '%s'", option.c_str());
 	}


Commit: c0c296ea3c87c7aec9bd8bc3ab9401ff10bf14c3
    https://github.com/scummvm/scummvm/commit/c0c296ea3c87c7aec9bd8bc3ab9401ff10bf14c3
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-10T12:18:29-04:00

Commit Message:
DIRECTOR: LINGO: Fix context issues

addCode needs to push a new context.
executeScript and executeHandler should not touch things pushContext
will take care of.

Changed paths:
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo-events.cpp
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index a2b8989ac9..928f02af55 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -209,7 +209,7 @@ void LC::c_xpop() {
 	g_lingo->pop();
 }
 
-void Lingo::pushContext(const Symbol *funcSym) {
+void Lingo::pushContext(const Symbol *funcSym, bool newVarFrame) {
 	debugC(5, kDebugLingoExec, "Pushing frame %d", g_lingo->_callstack.size() + 1);
 	CFrame *fp = new CFrame;
 
@@ -219,9 +219,11 @@ void Lingo::pushContext(const Symbol *funcSym) {
 	fp->retarchive = g_lingo->_archiveIndex;
 	fp->localvars = g_lingo->_localvars;
 	fp->retMeObj = g_lingo->_currentMeObj;
-	if (funcSym) {
+	if (funcSym)
 		fp->sp = *funcSym;
-	}
+
+	if (newVarFrame)
+		g_lingo->_localvars = new SymbolHash;
 
 	g_lingo->_callstack.push_back(fp);
 
@@ -1389,7 +1391,7 @@ void LC::call(const Symbol &funcSym, int nargs, Object *target) {
 		g_lingo->push(d);
 	}
 
-	g_lingo->pushContext(&funcSym);
+	g_lingo->pushContext(&funcSym, false);
 
 	// Create new set of local variables
 	SymbolHash *localvars = new SymbolHash;
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index c30580a486..763e286e2e 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -101,10 +101,7 @@ int Lingo::getEventCount() {
 void Lingo::setPrimaryEventHandler(LEvent event, const Common::String &code) {
 	debugC(3, kDebugLingoExec, "setting primary event handler (%s)", _eventHandlerTypes[event]);
 	_archives[_archiveIndex].primaryEventHandlers[event] = code;
-	pushContext();
-	g_lingo->_localvars = new SymbolHash;
 	addCode(code.c_str(), kGlobalScript, event);
-	popContext();
 }
 
 void Lingo::primaryEventHandler(LEvent event) {
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 8c4c5911f1..58b3039607 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -283,6 +283,8 @@ const char *Lingo::findNextDefinition(const char *s) {
 }
 
 void Lingo::addCode(const char *code, ScriptType type, uint16 id) {
+	pushContext();
+
 	debugC(1, kDebugCompile, "Add code for type %s(%d) with id %d\n"
 			"***********\n%s\n\n***********", scriptType2str(type), type, id, code);
 
@@ -411,6 +413,8 @@ void Lingo::addCode(const char *code, ScriptType type, uint16 id) {
 	currentFunc.varNames = varNames;
 	_currentScriptContext->functions.push_back(currentFunc);
 	_currentAssembly = nullptr;
+
+	popContext();
 }
 
 void Lingo::printStack(const char *s, uint pc) {
@@ -577,6 +581,7 @@ void Lingo::execute(uint pc) {
 
 void Lingo::executeScript(ScriptType type, uint16 id, uint16 function) {
 	ScriptContext *sc = getScriptContext(type, id);
+
 	if (!sc) {
 		debugC(3, kDebugLingoExec, "Request to execute non-existant script type %d id %d", type, id);
 		return;
@@ -586,26 +591,17 @@ void Lingo::executeScript(ScriptType type, uint16 id, uint16 function) {
 		return;
 	}
 
-	_localvars = new SymbolHash;
-
 	debugC(1, kDebugLingoExec, "Executing script type: %s, id: %d, function: %d", scriptType2str(type), id, function);
 
-	_currentScriptContext = sc;
-	Symbol sym = _currentScriptContext->functions[function];
+	Symbol sym = sc->functions[function];
 	LC::call(sym, 0);
 	execute(_pc);
-
-	cleanLocalVars();
 }
 
 void Lingo::executeHandler(Common::String name) {
-	_localvars = new SymbolHash;
-
 	debugC(1, kDebugLingoExec, "Executing script handler : %s", name.c_str());
 	LC::call(name, 0);
 	execute(_pc);
-
-	cleanLocalVars();
 }
 
 void Lingo::restartLingo() {
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 9732c76e37..a4a93f128f 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -365,7 +365,7 @@ public:
 
 public:
 	void execute(uint pc);
-	void pushContext(const Symbol *funcSym = nullptr);
+	void pushContext(const Symbol *funcSym = nullptr, bool newVarFrame = true);
 	void popContext();
 	void cleanLocalVars();
 	int castIdFetch(Datum &var);


Commit: 7f579c2dd28cdb210cab74be73c6ff4cbe247059
    https://github.com/scummvm/scummvm/commit/7f579c2dd28cdb210cab74be73c6ff4cbe247059
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-10T12:18:29-04:00

Commit Message:
DIRECTOR: LINGO: Future proof for Xtras

Changed paths:
  A engines/director/lingo/xlibs/fileio.cpp
  A engines/director/lingo/xlibs/fileio.h
  R engines/director/lingo/xobject/fileio.cpp
  R engines/director/lingo/xobject/fileio.h
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-object.cpp
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h
    engines/director/module.mk


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 96c27cd86c..abb6699fb0 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1040,11 +1040,14 @@ void LB::b_openResFile(int nargs) {
 }
 
 void LB::b_openXlib(int nargs) {
+	// TODO: When Xtras are implemented, determine whether to initialize
+	// the XObject or Xtra version of FileIO
+
 	Datum d = g_lingo->pop();
 	Common::String xlibName = d.asString();
-	if (g_lingo->_xlibs.contains(xlibName)) {
-		Symbol sym = g_lingo->_xlibs[xlibName];
-		(*sym.u.bltin)(0);
+	if (g_lingo->_xlibInitializers.contains(xlibName)) {
+		Symbol sym = g_lingo->_xlibInitializers[xlibName];
+		(*sym.u.bltin)(kXObj);
 	} else {
 		warning("STUB: b_openXLib(%s)", xlibName.c_str());
 	}
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index e8f2ee834c..546987920e 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -24,7 +24,7 @@
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-code.h"
 #include "director/lingo/lingo-object.h"
-#include "director/lingo/xobject/fileio.h"
+#include "director/lingo/xlibs/fileio.h"
 
 namespace Director {
 
@@ -36,28 +36,19 @@ static struct MethodProto {
 	int type;
 	int version;
 } predefinedMethods[] = {
-	{ "mDescribe",				LM::m_describe,				 0, 0, kXObj,				2 },	// D2
-	{ "mDispose",				LM::m_dispose,				 0, 0, kFactoryObj | kXObj,	2 },	// D2
-	{ "mGet",					LM::m_get,					 1, 1, kFactoryObj,			2 },	// D2
-	{ "mInstanceRespondsTo",	LM::m_instanceRespondsTo,	 1, 1, kXObj,				3 },		// D3
-	{ "mMessageList",			LM::m_messageList,			 0, 0, kXObj,				3 },		// D3
-	{ "mName",					LM::m_name,					 0, 0, kXObj,				3 },		// D3
-	{ "mNew",					LM::m_new,					-1, 0, kFactoryObj | kXObj, 2 },	// D2
-	{ "mPerform",				LM::m_perform,				-1, 0, kFactoryObj | kXObj, 3 },		// D3
-	{ "mPut",					LM::m_put,					 2, 2, kFactoryObj,			2 },	// D2
-	{ "mRespondsTo",			LM::m_respondsTo,			 1, 1, kXObj,				2 },	// D2
+	{ "describe",				LM::m_describe,				 0, 0,	kXObj,					2 },	// D2
+	{ "dispose",				LM::m_dispose,				 0, 0,	kFactoryObj | kXObj,	2 },	// D2
+	{ "get",					LM::m_get,					 1, 1,	kFactoryObj,			2 },	// D2
+	{ "instanceRespondsTo",		LM::m_instanceRespondsTo,	 1, 1,	kXObj,					3 },		// D3
+	{ "messageList",			LM::m_messageList,			 0, 0,	kXObj,					3 },		// D3
+	{ "name",					LM::m_name,					 0, 0,	kXObj,					3 },		// D3
+	{ "new",					LM::m_new,					-1, 0,	kFactoryObj | kXObj, 	2 },	// D2
+	{ "perform",				LM::m_perform,				-1, 0,	kFactoryObj | kXObj, 	3 },		// D3
+	{ "put",					LM::m_put,					 2, 2,	kFactoryObj,			2 },	// D2
+	{ "respondsTo",				LM::m_respondsTo,			 1, 1,	kXObj,					2 },	// D2
 	{ 0, 0, 0, 0, 0, 0 }
 };
 
-static struct XLibProto {
-	const char *name;
-	void (*initializer)(int);
-	int version;
-} xlibs[] = {
-	{ "FileIO",					FileIO::b_openXLib,										2 },	// D2
-	{ 0, 0, 0 }
-};
-
 void Lingo::initMethods() {
 	for (MethodProto *mtd = predefinedMethods; mtd->name; mtd++) {
 		if (mtd->version > _vm->getVersion())
@@ -68,21 +59,35 @@ void Lingo::initMethods() {
 		sym.type = FBLTIN;
 		sym.nargs = mtd->minArgs;
 		sym.maxArgs = mtd->maxArgs;
-		sym.methodType = mtd->type;
+		sym.targetType = mtd->type;
 		sym.u.bltin = mtd->func;
 		_methods[mtd->name] = sym;
 	}
+}
 
+static struct XLibProto {
+	const char *name;
+	void (*initializer)(int);
+	int type;
+	int version;
+} xlibs[] = {
+	{ "FileIO",					FileIO::initialize,					kXObj | kFactoryObj,	2 },	// D2
+	{ 0, 0, 0, 0 }
+};
+
+void Lingo::initXLibs() {
 	for (XLibProto *lib = xlibs; lib->name; lib++) {
 		if (lib->version > _vm->getVersion())
 			continue;
 
 		Symbol sym;
+		sym.name = new Common::String(lib->name);
 		sym.type = FBLTIN;
 		sym.nargs = 0;
 		sym.maxArgs = 0;
+		sym.targetType = lib->type;
 		sym.u.bltin = lib->initializer;
-		_xlibs[lib->name] = sym;
+		_xlibInitializers[lib->name] = sym;
 	}
 }
 
@@ -109,14 +114,29 @@ Symbol Object::getMethod(const Common::String &methodName) {
 	if (disposed) {
 		error("Method '%s' called on disposed object <%s>", methodName.c_str(), Datum(this).asString(true).c_str());
 	}
-	if (methods.contains(methodName) && (inheritanceLevel > 1 || type == kFactoryObj)) {
-		// Instance methods can be called on an original factory object,
-		// but not on an original XObject
+
+	// instance method (factory, script object, and Xtra)
+	if ((type | (kFactoryObj & kScriptObj & kXtraObj)) && methods.contains(methodName)) {
 		return methods[methodName];
 	}
-	if (g_lingo->_methods.contains(methodName) && (type & g_lingo->_methods[methodName].type)) {
-		return g_lingo->_methods[methodName];
+
+	if ((type & (kFactoryObj | kXObj)) && methodName.hasPrefixIgnoreCase("m")) {
+		Common::String shortName = methodName.substr(1);
+		// instance method (XObject)
+		if (type == kXObj && methods.contains(shortName) && inheritanceLevel > 1) {
+			return methods[shortName];
+		}
+		// predefined method (factory and XObject)
+		if (g_lingo->_methods.contains(shortName) && (type & g_lingo->_methods[shortName].type)) {
+			return g_lingo->_methods[shortName];
+		}
+	} else if (type & (kScriptObj | kXtraObj)) {
+		// predefined method (script object and Xtra)
+		if (g_lingo->_methods.contains(methodName) && (type & g_lingo->_methods[methodName].type)) {
+			return g_lingo->_methods[methodName];
+		}
 	}
+
 	return Symbol();
 }
 
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 58b3039607..4e8403cecf 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -46,7 +46,7 @@ Symbol::Symbol() {
 	nargs = 0;
 	maxArgs = 0;
 	parens = true;
-	methodType = kNoneObj;
+	targetType = kNoneObj;
 	global = false;
 	argNames = nullptr;
 	varNames = nullptr;
@@ -63,7 +63,7 @@ Symbol::Symbol(const Symbol &s) {
 	nargs = s.nargs;
 	maxArgs = s.maxArgs;
 	parens = s.parens;
-	methodType = s.methodType;
+	targetType = s.targetType;
 	global = s.global;
 	argNames = s.argNames;
 	varNames = s.varNames;
@@ -82,7 +82,7 @@ Symbol& Symbol::operator=(const Symbol &s) {
 		nargs = s.nargs;
 		maxArgs = s.maxArgs;
 		parens = s.parens;
-		methodType = s.methodType;
+		targetType = s.targetType;
 		global = s.global;
 		argNames = s.argNames;
 		varNames = s.varNames;
@@ -193,6 +193,7 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
 	initBytecode();
 	initTheEntities();
 	initMethods();
+	initXLibs();
 
 	warning("Lingo Inited");
 }
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index a4a93f128f..b6c9c80d5a 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -96,7 +96,7 @@ struct Symbol {	/* symbol table entry */
 	int nargs;		/* number of arguments */
 	int maxArgs;	/* maximal number of arguments, for builtins */
 	bool parens;	/* whether parens required or not, for builitins */
-	int methodType;	/* valid target objects, for method builtins */
+	int targetType;	/* valid target objects, for method builtins */
 
 	bool global;
 	Common::Array<Common::String> *argNames;
@@ -227,7 +227,8 @@ enum ObjectType {
 	kNoneObj = 0,
 	kFactoryObj = 1 << 0,
 	kXObj = 1 << 1,
-	kScriptObj = 1 << 2
+	kScriptObj = 1 << 2,
+	kXtraObj = 1 << 3
 };
 
 struct Object {
@@ -324,6 +325,7 @@ public:
 	void initFuncs();
 	void initBytecode();
 	void initMethods();
+	void initXLibs();
 
 	void runTests();
 
@@ -497,7 +499,7 @@ public:
 
 	SymbolHash _builtins;
 	SymbolHash _methods;
-	SymbolHash _xlibs;
+	SymbolHash _xlibInitializers;
 
 	Common::String _floatPrecisionFormat;
 
diff --git a/engines/director/lingo/xobject/fileio.cpp b/engines/director/lingo/xlibs/fileio.cpp
similarity index 73%
rename from engines/director/lingo/xobject/fileio.cpp
rename to engines/director/lingo/xlibs/fileio.cpp
index 608bfb73ff..22a6233e41 100644
--- a/engines/director/lingo/xobject/fileio.cpp
+++ b/engines/director/lingo/xlibs/fileio.cpp
@@ -24,46 +24,60 @@
 
 #include "director/director.h"
 #include "director/lingo/lingo.h"
-#include "director/lingo/lingo-object.h"
-#include "director/lingo/xobject/fileio.h"
+#include "director/lingo/xlibs/fileio.h"
 
 namespace Director {
 
+static Common::String xlibName = "FileIO";
+
 static struct MethodProto {
 	const char *name;
 	void (*func)(int);
 	int minArgs;	// -1 -- arglist
 	int maxArgs;
+	int type;
 	int version;
-} predefinedMethods[] = {
-	{ "mDelete",				FileIO::m_delete,			 0, 0,						2 },	// D2
-	{ "mDispose",				FileIO::m_dispose,			 0, 0,						2 },	// D2
-	{ "mFileName",				FileIO::m_fileName,			 0, 0,						2 },	// D2
-	{ "mGetLength",				FileIO::m_getLength,		 0, 0,						2 },	// D2
-	{ "mGetPosition",			FileIO::m_getPosition,		 0, 0,						2 },	// D2
-	{ "mNew",					FileIO::m_new,				 2, 2,						2 },	// D2
-	{ "mReadChar",				FileIO::m_readChar,			 0, 0,						2 },	// D2
-	{ "mReadLine",				FileIO::m_readLine,			 0, 0,						2 },	// D2
-	{ "mReadToken",				FileIO::m_readToken,		 2, 2,						2 },	// D2
-	{ "mReadWord",				FileIO::m_readWord,			 0, 0,						2 },	// D2
-	{ "mSetPosition",			FileIO::m_setPosition,		 1, 1,						2 },	// D2
-	{ "mWriteChar",				FileIO::m_writeChar,		 1, 1,						2 },	// D2
-	{ "mWriteString",			FileIO::m_writeString,		 1, 1,						2 },	// D2
-	{ 0, 0, 0, 0, 0 }
+} xlibMethods[] = {
+	{ "delete",					FileIO::m_delete,			 0, 0,	kXObj | kXtraObj,		2 },	// D2
+	{ "dispose",				FileIO::m_dispose,			 0, 0,	kXObj,					2 },	// D2
+	{ "fileName",				FileIO::m_fileName,			 0, 0,	kXObj | kXtraObj,		2 },	// D2
+	{ "getLength",				FileIO::m_getLength,		 0, 0,	kXObj | kXtraObj,		2 },	// D2
+	{ "getPosition",			FileIO::m_getPosition,		 0, 0,	kXObj | kXtraObj,		2 },	// D2
+	{ "new",					FileIO::m_new,				 2, 2,	kXObj | kXtraObj,		2 },	// D2
+	{ "readChar",				FileIO::m_readChar,			 0, 0,	kXObj | kXtraObj,		2 },	// D2
+	{ "readLine",				FileIO::m_readLine,			 0, 0,	kXObj | kXtraObj,		2 },	// D2
+	{ "readToken",				FileIO::m_readToken,		 2, 2,	kXObj | kXtraObj,		2 },	// D2
+	{ "readWord",				FileIO::m_readWord,			 0, 0,	kXObj | kXtraObj,		2 },	// D2
+	{ "setPosition",			FileIO::m_setPosition,		 1, 1,	kXObj | kXtraObj,		2 },	// D2
+	{ "writeChar",				FileIO::m_writeChar,		 1, 1,	kXObj | kXtraObj,		2 },	// D2
+	{ "writeString",			FileIO::m_writeString,		 1, 1,	kXObj | kXtraObj,		2 },	// D2
+	{ 0, 0, 0, 0, 0, 0 }
 };
 
-void FileIO::b_openXLib(int nargs) {
-	const Common::String name = "FileIO";
-
-	if (g_lingo->_globalvars.contains(name)) {
-		warning("FileIO already initialized");
-		return;
+void FileIO::initialize(int type) {
+	if (type & kXObj) {
+		if (!g_lingo->_globalvars.contains(xlibName)) {
+			FileObject *xobj = new FileObject(kXObj);
+			xobj->initMethods();
+			g_lingo->_globalvars[xlibName] = Symbol();
+			g_lingo->_globalvars[xlibName].name = new Common::String(xlibName);
+			g_lingo->_globalvars[xlibName].global = true;
+			g_lingo->_globalvars[xlibName].type = OBJECT;
+			g_lingo->_globalvars[xlibName].u.obj = xobj;
+		} else {
+			warning("FileIO XObject already initialized");
+		}
+	}
+	if (type & kXtraObj) {
+		// TODO - Implement Xtra
 	}
+}
 
-	FileXObject *obj = new FileXObject();
+// Initialization/disposal
 
-	for (MethodProto *mtd = predefinedMethods; mtd->name; mtd++) {
-		if (mtd->version > g_lingo->_vm->getVersion())
+void FileObject::initMethods() {
+	for (MethodProto *mtd = xlibMethods; mtd->name; mtd++) {
+		if (mtd->version > g_lingo->_vm->getVersion() || !(type & mtd->type))
 			continue;
 
 		Symbol sym;
@@ -71,22 +85,14 @@ void FileIO::b_openXLib(int nargs) {
 		sym.type = FBLTIN;
 		sym.nargs = mtd->minArgs;
 		sym.maxArgs = mtd->maxArgs;
-		sym.methodType = kXObj;
+		sym.targetType = mtd->type;
 		sym.u.bltin = mtd->func;
-		obj->methods[mtd->name] = sym;
+		methods[mtd->name] = sym;
 	}
-
-	g_lingo->_globalvars[name] = Symbol();
-	g_lingo->_globalvars[name].name = new Common::String(name);
-	g_lingo->_globalvars[name].global = true;
-	g_lingo->_globalvars[name].type = OBJECT;
-	g_lingo->_globalvars[name].u.obj = obj;
 }
 
-// Initialization/disposal
-
-Object *FileXObject::clone() {
-	FileXObject *res = new FileXObject();
+Object *FileObject::clone() {
+	FileObject *res = new FileObject(type);
 	res->disposed = disposed;
 	res->prototype = this;
 	res->properties = properties;
@@ -95,7 +101,7 @@ Object *FileXObject::clone() {
 	return res;
 }
 
-void FileXObject::dispose() {
+void FileObject::dispose() {
 	disposed = true;
 
 	if (filename) {
@@ -120,7 +126,7 @@ void FileXObject::dispose() {
 }
 
 void FileIO::m_new(int nargs) {
-	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	FileObject *me = static_cast<FileObject *>(g_lingo->_currentMeObj);
 
 	Datum d2 = g_lingo->pop();
 	Datum d1 = g_lingo->pop();
@@ -187,14 +193,14 @@ void FileIO::m_new(int nargs) {
 }
 
 void FileIO::m_dispose(int nargs) {
-	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	FileObject *me = static_cast<FileObject *>(g_lingo->_currentMeObj);
 	me->dispose();
 }
 
 // Read
 
 void FileIO::m_readChar(int nargs) {
-	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	FileObject *me = static_cast<FileObject *>(g_lingo->_currentMeObj);
 
 	if (!me->inStream || me->inStream->eos() || me->inStream->err()) {
 		g_lingo->push(Datum(kErrorEOF));
@@ -227,7 +233,7 @@ void FileIO::m_readWord(int nargs) {
 }
 
 void FileIO::m_readToken(int nargs) {
-	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	FileObject *me = static_cast<FileObject *>(g_lingo->_currentMeObj);
 
 	Datum d2 = g_lingo->pop();
 	Datum d1 = g_lingo->pop();
@@ -273,7 +279,7 @@ void FileIO::m_readToken(int nargs) {
 // Write
 
 void FileIO::m_writeChar(int nargs) {
-	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	FileObject *me = static_cast<FileObject *>(g_lingo->_currentMeObj);
 	Datum d = g_lingo->pop();
 
 	if (!me->outStream) {
@@ -286,7 +292,7 @@ void FileIO::m_writeChar(int nargs) {
 }
 
 void FileIO::m_writeString(int nargs) {
-	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	FileObject *me = static_cast<FileObject *>(g_lingo->_currentMeObj);
 	Datum d = g_lingo->pop();
 
 	if (!me->outStream) {
@@ -301,7 +307,7 @@ void FileIO::m_writeString(int nargs) {
 // Other
 
 void FileIO::m_getPosition(int nargs) {
-	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	FileObject *me = static_cast<FileObject *>(g_lingo->_currentMeObj);
 
 	if (me->inStream) {
 		g_lingo->push(Datum(me->inStream->pos()));
@@ -314,7 +320,7 @@ void FileIO::m_getPosition(int nargs) {
 }
 
 void FileIO::m_setPosition(int nargs) {
-	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	FileObject *me = static_cast<FileObject *>(g_lingo->_currentMeObj);
 	Datum d = g_lingo->pop();
 	int pos = d.asInt();
 
@@ -341,7 +347,7 @@ void FileIO::m_setPosition(int nargs) {
 }
 
 void FileIO::m_getLength(int nargs) {
-	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	FileObject *me = static_cast<FileObject *>(g_lingo->_currentMeObj);
 
 	if (me->inStream) {
 		g_lingo->push(Datum(me->inStream->size()));
@@ -354,7 +360,7 @@ void FileIO::m_getLength(int nargs) {
 }
 
 void FileIO::m_fileName(int nargs) {
-	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	FileObject *me = static_cast<FileObject *>(g_lingo->_currentMeObj);
 
 	if (me->filename) {
 		g_lingo->push(Datum(*me->filename));
@@ -365,7 +371,7 @@ void FileIO::m_fileName(int nargs) {
 }
 
 void FileIO::m_delete(int nargs) {
-	FileXObject *me = static_cast<FileXObject *>(g_lingo->_currentMeObj);
+	FileObject *me = static_cast<FileObject *>(g_lingo->_currentMeObj);
 
 	if (me->filename) {
 		Common::String filename = *me->filename;
diff --git a/engines/director/lingo/xobject/fileio.h b/engines/director/lingo/xlibs/fileio.h
similarity index 93%
rename from engines/director/lingo/xobject/fileio.h
rename to engines/director/lingo/xlibs/fileio.h
index 8f8f8ca8d8..fc38cd8073 100644
--- a/engines/director/lingo/xobject/fileio.h
+++ b/engines/director/lingo/xlibs/fileio.h
@@ -25,7 +25,6 @@
 
 #include "common/memstream.h"
 #include "common/savefile.h"
-#include "director/lingo/lingo-object.h"
 
 namespace Director {
 
@@ -47,14 +46,14 @@ enum FileIOError {
 	kErrorDirectoryNotFound = -120
 };
 
-struct FileXObject : Object {
+struct FileObject : Object {
 	Common::String *filename;
 	Common::InSaveFile *inFile;
 	Common::SeekableReadStream *inStream;
 	Common::OutSaveFile *outFile;
 	Common::MemoryWriteStreamDynamic *outStream;
 
-	FileXObject() : Object("FileIO", kXObj) {
+	FileObject(ObjectType objType) : Object("FileIO", objType) {
 		filename = nullptr;
 		inFile = nullptr;
 		inStream = nullptr;
@@ -62,16 +61,17 @@ struct FileXObject : Object {
 		outStream = nullptr;
 	}
 
-	virtual ~FileXObject() {
+	virtual ~FileObject() {
 		dispose();
 	}
 
+	void initMethods();
 	virtual Object *clone();
 	void dispose();
 };
 
 namespace FileIO {
-	void b_openXLib(int nargs);
+	void initialize(int type);
 	void m_delete(int nargs);
 	void m_dispose(int nargs);
 	void m_fileName(int nargs);
diff --git a/engines/director/module.mk b/engines/director/module.mk
index f9cdf5fa72..ad04ef32e7 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -33,7 +33,7 @@ MODULE_OBJS = \
 	lingo/lingo-patcher.o \
 	lingo/lingo-preprocessor.o \
 	lingo/lingo-the.o \
-	lingo/xobject/fileio.o
+	lingo/xlibs/fileio.o
 
 director-grammar:
 	`brew --prefix flex`/bin/flex engines/director/lingo/lingo-lex.l


Commit: 58c1a72f0922fac350f3f8586528f2f3ac8a9722
    https://github.com/scummvm/scummvm/commit/58c1a72f0922fac350f3f8586528f2f3ac8a9722
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-10T12:18:29-04:00

Commit Message:
DIRECTOR: LINGO: Load FileIO by default on Mac

Changed paths:
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-object.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index abb6699fb0..e79678a19a 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1045,12 +1045,7 @@ void LB::b_openXlib(int nargs) {
 
 	Datum d = g_lingo->pop();
 	Common::String xlibName = d.asString();
-	if (g_lingo->_xlibInitializers.contains(xlibName)) {
-		Symbol sym = g_lingo->_xlibInitializers[xlibName];
-		(*sym.u.bltin)(kXObj);
-	} else {
-		warning("STUB: b_openXLib(%s)", xlibName.c_str());
-	}
+	g_lingo->openXLib(xlibName, kXObj);
 }
 
 void LB::b_saveMovie(int nargs) {
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 546987920e..bb71cbf84d 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -89,6 +89,21 @@ void Lingo::initXLibs() {
 		sym.u.bltin = lib->initializer;
 		_xlibInitializers[lib->name] = sym;
 	}
+
+	if (_vm->getPlatform() == Common::kPlatformMacintosh) {
+		// TODO: Mac executables can contain XObjects in XCOD resources.
+		// If a Mac executable exists, check which XObjects should be loaded.
+		openXLib("FileIO", kXObj);
+	}
+}
+
+void Lingo::openXLib(const Common::String &name, ObjectType type) {
+	if (_xlibInitializers.contains(name)) {
+		Symbol sym = _xlibInitializers[name];
+		(*sym.u.bltin)(type);
+	} else {
+		warning("Unimplemented xlib: '%s'", name.c_str());
+	}
 }
 
 Object *Object::clone() {
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index b6c9c80d5a..0f1d70fa61 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -326,6 +326,7 @@ public:
 	void initBytecode();
 	void initMethods();
 	void initXLibs();
+	void openXLib(const Common::String &name, ObjectType type);
 
 	void runTests();
 


Commit: 4301a75df58bcfcf8a21d4bdec388d49fcd52a17
    https://github.com/scummvm/scummvm/commit/4301a75df58bcfcf8a21d4bdec388d49fcd52a17
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-10T12:18:29-04:00

Commit Message:
DIRECTOR: LINGO: Don't print nonexistent localvars

Changed paths:
    engines/director/lingo/lingo.cpp


diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 4e8403cecf..25021bc056 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1041,8 +1041,12 @@ void Lingo::executePerFrameHook(int frame, int subframe) {
 
 void Lingo::printAllVars() {
 	debugN("  Local vars: ");
-	for (SymbolHash::iterator i = _localvars->begin(); i != _localvars->end(); ++i) {
-		debugN("%s, ", (*i)._key.c_str());
+	if (_localvars) {
+		for (SymbolHash::iterator i = _localvars->begin(); i != _localvars->end(); ++i) {
+			debugN("%s, ", (*i)._key.c_str());
+		}
+	} else {
+		debugN("(no local vars)");
 	}
 	debugN("\n");
 


Commit: 66894ea8db8e45daf84201bd60811c84288d94fd
    https://github.com/scummvm/scummvm/commit/66894ea8db8e45daf84201bd60811c84288d94fd
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-10T12:18:29-04:00

Commit Message:
DIRECTOR: LINGO: Print function vars

Changed paths:
    engines/director/lingo/lingo-codegen.cpp
    engines/director/lingo/lingo.cpp


diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index e7c6846d85..4262b834d5 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -126,6 +126,20 @@ Symbol Lingo::codeDefine(Common::String &name, int start, int nargs, Object *fac
 	}
 	Symbol sym = define(name, nargs, code, argNames, varNames, factory);
 
+	if (debugChannelSet(1, kDebugCompile)) {
+		debug("Function vars");
+		debugN("  Args: ");
+		for (uint i = 0; i < argNames->size(); i++) {
+			debugN("%s, ", (*argNames)[i].c_str());
+		}
+		debugN("\n");
+		debugN("  Local vars: ");
+		for (uint i = 0; i < varNames->size(); i++) {
+			debugN("%s, ", (*varNames)[i].c_str());
+		}
+		debugN("\n");
+	}
+
 	// Now remove all defined code from the _currentAssembly
 	if (removeCode)
 		for (int i = end - 1; i >= start; i--) {
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 25021bc056..e8b8a21fb4 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -410,6 +410,20 @@ void Lingo::addCode(const char *code, ScriptType type, uint16 id) {
 	delete _methodVars;
 	_methodVars = nullptr;
 
+	if (debugChannelSet(1, kDebugCompile)) {
+		debug("Function vars");
+		debugN("  Args: ");
+		for (uint i = 0; i < argNames->size(); i++) {
+			debugN("%s, ", (*argNames)[i].c_str());
+		}
+		debugN("\n");
+		debugN("  Local vars: ");
+		for (uint i = 0; i < varNames->size(); i++) {
+			debugN("%s, ", (*varNames)[i].c_str());
+		}
+		debugN("\n");
+	}
+
 	currentFunc.argNames = argNames;
 	currentFunc.varNames = varNames;
 	_currentScriptContext->functions.push_back(currentFunc);


Commit: 85077477c35a9d444e6f6085050a4b276b320b13
    https://github.com/scummvm/scummvm/commit/85077477c35a9d444e6f6085050a4b276b320b13
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-10T12:18:29-04:00

Commit Message:
DIRECTOR: LINGO: Don't destroy local vars

Functions' local vars weren't being saved after parse as intended.

Changed paths:
    engines/director/lingo/lingo-gr.cpp
    engines/director/lingo/lingo-gr.h
    engines/director/lingo/lingo-gr.y
    engines/director/lingo/lingo.cpp


diff --git a/engines/director/lingo/lingo-gr.cpp b/engines/director/lingo/lingo-gr.cpp
index 83cd52daf9..ae29a00b8e 100644
--- a/engines/director/lingo/lingo-gr.cpp
+++ b/engines/director/lingo/lingo-gr.cpp
@@ -107,8 +107,6 @@ static void inNone() { g_lingo->_indef = kStateNone; }
 
 static void startDef() {
 	inArgs();
-	g_lingo->_methodVarsStash = g_lingo->_methodVars;
-	g_lingo->_methodVars = new Common::HashMap<Common::String, VarType, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>();
 
 	if (g_lingo->_inFactory) {
 		for (SymbolHash::iterator i = g_lingo->_currentFactory->properties.begin(); i != g_lingo->_currentFactory->properties.end(); ++i) {
@@ -120,10 +118,6 @@ static void startDef() {
 static void endDef() {
 	g_lingo->clearArgStack();
 	inNone();
-
-	delete g_lingo->_methodVars;
-	g_lingo->_methodVars = g_lingo->_methodVarsStash;
-	g_lingo->_methodVarsStash = nullptr;
 }
 
 static VarType globalCheck() {
@@ -152,7 +146,7 @@ static void mVar(Common::String *s, VarType type) {
 }
 
 
-#line 156 "engines/director/lingo/lingo-gr.cpp"
+#line 150 "engines/director/lingo/lingo-gr.cpp"
 
 # ifndef YY_CAST
 #  ifdef __cplusplus
@@ -289,7 +283,7 @@ extern int yydebug;
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 union YYSTYPE
 {
-#line 139 "engines/director/lingo/lingo-gr.y"
+#line 133 "engines/director/lingo/lingo-gr.y"
 
 	Common::String *s;
 	int i;
@@ -309,7 +303,7 @@ union YYSTYPE
 		Common::String *field;
 	} objectref;
 
-#line 313 "engines/director/lingo/lingo-gr.cpp"
+#line 307 "engines/director/lingo/lingo-gr.cpp"
 
 };
 typedef union YYSTYPE YYSTYPE;
@@ -863,24 +857,24 @@ static const yytype_int8 yytranslate[] =
   /* YYRLINEYYN -- Source line where rule number YYN was defined.  */
 static const yytype_int16 yyrline[] =
 {
-       0,   198,   198,   199,   201,   202,   203,   205,   212,   216,
-     227,   228,   229,   236,   243,   250,   257,   263,   270,   281,
-     288,   289,   290,   292,   293,   298,   310,   314,   317,   309,
-     341,   345,   348,   340,   374,   381,   387,   373,   415,   417,
-     420,   421,   423,   425,   432,   440,   441,   443,   449,   453,
-     457,   461,   464,   466,   467,   468,   470,   473,   476,   480,
-     484,   488,   496,   502,   503,   504,   515,   516,   517,   520,
-     523,   529,   529,   534,   537,   540,   545,   551,   552,   553,
-     554,   555,   556,   557,   558,   559,   560,   561,   562,   563,
-     564,   565,   566,   567,   568,   569,   570,   571,   572,   573,
-     575,   576,   577,   578,   579,   580,   581,   582,   584,   587,
-     589,   590,   591,   592,   593,   594,   594,   595,   595,   596,
-     596,   597,   600,   603,   604,   606,   609,   613,   618,   624,
-     627,   638,   639,   640,   641,   645,   649,   654,   655,   657,
-     661,   665,   669,   669,   699,   699,   699,   705,   706,   706,
-     712,   720,   726,   726,   729,   730,   731,   733,   734,   735,
-     737,   739,   747,   748,   749,   751,   752,   754,   756,   757,
-     758,   759,   761,   762,   764,   765,   767,   771
+       0,   192,   192,   193,   195,   196,   197,   199,   206,   210,
+     221,   222,   223,   230,   237,   244,   251,   257,   264,   275,
+     282,   283,   284,   286,   287,   292,   304,   308,   311,   303,
+     335,   339,   342,   334,   368,   375,   381,   367,   409,   411,
+     414,   415,   417,   419,   426,   434,   435,   437,   443,   447,
+     451,   455,   458,   460,   461,   462,   464,   467,   470,   474,
+     478,   482,   490,   496,   497,   498,   509,   510,   511,   514,
+     517,   523,   523,   528,   531,   534,   539,   545,   546,   547,
+     548,   549,   550,   551,   552,   553,   554,   555,   556,   557,
+     558,   559,   560,   561,   562,   563,   564,   565,   566,   567,
+     569,   570,   571,   572,   573,   574,   575,   576,   578,   581,
+     583,   584,   585,   586,   587,   588,   588,   589,   589,   590,
+     590,   591,   594,   597,   598,   600,   603,   607,   612,   618,
+     621,   632,   633,   634,   635,   639,   643,   648,   649,   651,
+     655,   659,   663,   663,   693,   693,   693,   699,   700,   700,
+     706,   714,   720,   720,   723,   724,   725,   727,   728,   729,
+     731,   733,   741,   742,   743,   745,   746,   748,   750,   751,
+     752,   753,   755,   756,   758,   759,   761,   765
 };
 #endif
 
@@ -1951,81 +1945,81 @@ yydestruct (const char *yymsg,
   switch (yykind)
     {
     case 22: /* BLTIN  */
-#line 193 "engines/director/lingo/lingo-gr.y"
+#line 187 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1957 "engines/director/lingo/lingo-gr.cpp"
+#line 1951 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 23: /* FBLTIN  */
-#line 193 "engines/director/lingo/lingo-gr.y"
+#line 187 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1963 "engines/director/lingo/lingo-gr.cpp"
+#line 1957 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 24: /* RBLTIN  */
-#line 193 "engines/director/lingo/lingo-gr.y"
+#line 187 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1969 "engines/director/lingo/lingo-gr.cpp"
+#line 1963 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 25: /* THEFBLTIN  */
-#line 193 "engines/director/lingo/lingo-gr.y"
+#line 187 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1975 "engines/director/lingo/lingo-gr.cpp"
+#line 1969 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 26: /* ID  */
-#line 193 "engines/director/lingo/lingo-gr.y"
+#line 187 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1981 "engines/director/lingo/lingo-gr.cpp"
+#line 1975 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 27: /* STRING  */
-#line 193 "engines/director/lingo/lingo-gr.y"
+#line 187 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1987 "engines/director/lingo/lingo-gr.cpp"
+#line 1981 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 28: /* HANDLER  */
-#line 193 "engines/director/lingo/lingo-gr.y"
+#line 187 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1993 "engines/director/lingo/lingo-gr.cpp"
+#line 1987 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 29: /* SYMBOL  */
-#line 193 "engines/director/lingo/lingo-gr.y"
+#line 187 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1999 "engines/director/lingo/lingo-gr.cpp"
+#line 1993 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 30: /* ENDCLAUSE  */
-#line 193 "engines/director/lingo/lingo-gr.y"
+#line 187 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 2005 "engines/director/lingo/lingo-gr.cpp"
+#line 1999 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 31: /* tPLAYACCEL  */
-#line 193 "engines/director/lingo/lingo-gr.y"
+#line 187 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 2011 "engines/director/lingo/lingo-gr.cpp"
+#line 2005 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 32: /* tMETHOD  */
-#line 193 "engines/director/lingo/lingo-gr.y"
+#line 187 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 2017 "engines/director/lingo/lingo-gr.cpp"
+#line 2011 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 33: /* THEOBJECTFIELD  */
-#line 194 "engines/director/lingo/lingo-gr.y"
+#line 188 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).objectfield).os; }
-#line 2023 "engines/director/lingo/lingo-gr.cpp"
+#line 2017 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 148: /* on  */
-#line 193 "engines/director/lingo/lingo-gr.y"
+#line 187 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 2029 "engines/director/lingo/lingo-gr.cpp"
+#line 2023 "engines/director/lingo/lingo-gr.cpp"
         break;
 
       default:
@@ -2304,7 +2298,7 @@ yyreduce:
   switch (yyn)
     {
   case 7:
-#line 205 "engines/director/lingo/lingo-gr.y"
+#line 199 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_varpush);
 		g_lingo->codeString((yyvsp[0].s)->c_str());
@@ -2312,19 +2306,19 @@ yyreduce:
 		g_lingo->code1(LC::c_assign);
 		(yyval.code) = (yyvsp[-2].code);
 		delete (yyvsp[0].s); }
-#line 2316 "engines/director/lingo/lingo-gr.cpp"
+#line 2310 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 8:
-#line 212 "engines/director/lingo/lingo-gr.y"
+#line 206 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->code1(LC::c_assign);
 		(yyval.code) = (yyvsp[-2].code); }
-#line 2324 "engines/director/lingo/lingo-gr.cpp"
+#line 2318 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 9:
-#line 216 "engines/director/lingo/lingo-gr.y"
+#line 210 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		if (!(yyvsp[-3].s)->equalsIgnoreCase("menu")) {
 			warning("LEXER: keyword 'menu' expected");
@@ -2336,23 +2330,23 @@ yyreduce:
 		g_lingo->codeInt((yyvsp[-4].e)[1]);
 		g_lingo->code1(LC::c_assign);
 		(yyval.code) = (yyvsp[0].code); }
-#line 2340 "engines/director/lingo/lingo-gr.cpp"
+#line 2334 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 10:
-#line 227 "engines/director/lingo/lingo-gr.y"
+#line 221 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.code) = g_lingo->code1(LC::c_after); }
-#line 2346 "engines/director/lingo/lingo-gr.cpp"
+#line 2340 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 11:
-#line 228 "engines/director/lingo/lingo-gr.y"
+#line 222 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.code) = g_lingo->code1(LC::c_before); }
-#line 2352 "engines/director/lingo/lingo-gr.cpp"
+#line 2346 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 12:
-#line 229 "engines/director/lingo/lingo-gr.y"
+#line 223 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->code1(LC::c_varpush);
 		g_lingo->codeString((yyvsp[-2].s)->c_str());
@@ -2360,11 +2354,11 @@ yyreduce:
 		g_lingo->code1(LC::c_assign);
 		(yyval.code) = (yyvsp[0].code);
 		delete (yyvsp[-2].s); }
-#line 2364 "engines/director/lingo/lingo-gr.cpp"
+#line 2358 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 13:
-#line 236 "engines/director/lingo/lingo-gr.y"
+#line 230 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(0); // Put dummy id
@@ -2372,11 +2366,11 @@ yyreduce:
 		g_lingo->codeInt((yyvsp[-2].e)[0]);
 		g_lingo->codeInt((yyvsp[-2].e)[1]);
 		(yyval.code) = (yyvsp[0].code); }
-#line 2376 "engines/director/lingo/lingo-gr.cpp"
+#line 2370 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 14:
-#line 243 "engines/director/lingo/lingo-gr.y"
+#line 237 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->code1(LC::c_varpush);
 		g_lingo->codeString((yyvsp[-2].s)->c_str());
@@ -2384,11 +2378,11 @@ yyreduce:
 		g_lingo->code1(LC::c_assign);
 		(yyval.code) = (yyvsp[0].code);
 		delete (yyvsp[-2].s); }
-#line 2388 "engines/director/lingo/lingo-gr.cpp"
+#line 2382 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 15:
-#line 250 "engines/director/lingo/lingo-gr.y"
+#line 244 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(0); // Put dummy id
@@ -2396,33 +2390,33 @@ yyreduce:
 		g_lingo->codeInt((yyvsp[-2].e)[0]);
 		g_lingo->codeInt((yyvsp[-2].e)[1]);
 		(yyval.code) = (yyvsp[0].code); }
-#line 2400 "engines/director/lingo/lingo-gr.cpp"
+#line 2394 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 16:
-#line 257 "engines/director/lingo/lingo-gr.y"
+#line 251 "engines/director/lingo/lingo-gr.y"
                                                         {
 		g_lingo->code1(LC::c_swap);
 		g_lingo->code1(LC::c_theentityassign);
 		g_lingo->codeInt((yyvsp[-3].e)[0]);
 		g_lingo->codeInt((yyvsp[-3].e)[1]);
 		(yyval.code) = (yyvsp[0].code); }
-#line 2411 "engines/director/lingo/lingo-gr.cpp"
+#line 2405 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 17:
-#line 263 "engines/director/lingo/lingo-gr.y"
+#line 257 "engines/director/lingo/lingo-gr.y"
                                                         {
 		g_lingo->code1(LC::c_swap);
 		g_lingo->code1(LC::c_theentityassign);
 		g_lingo->codeInt((yyvsp[-3].e)[0]);
 		g_lingo->codeInt((yyvsp[-3].e)[1]);
 		(yyval.code) = (yyvsp[0].code); }
-#line 2422 "engines/director/lingo/lingo-gr.cpp"
+#line 2416 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 18:
-#line 270 "engines/director/lingo/lingo-gr.y"
+#line 264 "engines/director/lingo/lingo-gr.y"
                                                                         {
 		if (!(yyvsp[-3].s)->equalsIgnoreCase("menu")) {
 			warning("LEXER: keyword 'menu' expected");
@@ -2434,54 +2428,54 @@ yyreduce:
 		g_lingo->codeInt((yyvsp[-6].e)[0]);
 		g_lingo->codeInt((yyvsp[-6].e)[1]);
 		(yyval.code) = (yyvsp[0].code); }
-#line 2438 "engines/director/lingo/lingo-gr.cpp"
+#line 2432 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 19:
-#line 281 "engines/director/lingo/lingo-gr.y"
+#line 275 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_objectfieldassign);
 		g_lingo->codeString((yyvsp[-2].objectfield).os->c_str());
 		g_lingo->codeInt((yyvsp[-2].objectfield).oe);
 		delete (yyvsp[-2].objectfield).os;
 		(yyval.code) = (yyvsp[0].code); }
-#line 2449 "engines/director/lingo/lingo-gr.cpp"
+#line 2443 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 25:
-#line 298 "engines/director/lingo/lingo-gr.y"
+#line 292 "engines/director/lingo/lingo-gr.y"
                                                                                 {
 		inst start = 0, end = 0;
 		WRITE_UINT32(&start, (yyvsp[-5].code) - (yyvsp[-1].code) + 1);
 		WRITE_UINT32(&end, (yyvsp[-1].code) - (yyvsp[-3].code) + 2);
 		(*g_lingo->_currentAssembly)[(yyvsp[-3].code)] = end;		/* end, if cond fails */
 		(*g_lingo->_currentAssembly)[(yyvsp[-1].code)] = start; }
-#line 2460 "engines/director/lingo/lingo-gr.cpp"
+#line 2454 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 26:
-#line 310 "engines/director/lingo/lingo-gr.y"
+#line 304 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_varpush);
 				  g_lingo->codeString((yyvsp[-2].s)->c_str());
 				  mVar((yyvsp[-2].s), globalCheck()); }
-#line 2468 "engines/director/lingo/lingo-gr.cpp"
+#line 2462 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 27:
-#line 314 "engines/director/lingo/lingo-gr.y"
+#line 308 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_eval);
 				  g_lingo->codeString((yyvsp[-4].s)->c_str()); }
-#line 2475 "engines/director/lingo/lingo-gr.cpp"
+#line 2469 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 28:
-#line 317 "engines/director/lingo/lingo-gr.y"
+#line 311 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_le); }
-#line 2481 "engines/director/lingo/lingo-gr.cpp"
+#line 2475 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 29:
-#line 317 "engines/director/lingo/lingo-gr.y"
+#line 311 "engines/director/lingo/lingo-gr.y"
                                                                                           {
 
 		g_lingo->code1(LC::c_eval);
@@ -2500,32 +2494,32 @@ yyreduce:
 		WRITE_UINT32(&end, pos - (yyvsp[-2].code) + 2);
 		(*g_lingo->_currentAssembly)[pos] = loop;		/* final count value */
 		(*g_lingo->_currentAssembly)[(yyvsp[-2].code)] = end;	}
-#line 2504 "engines/director/lingo/lingo-gr.cpp"
+#line 2498 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 30:
-#line 341 "engines/director/lingo/lingo-gr.y"
+#line 335 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_varpush);
 				  g_lingo->codeString((yyvsp[-2].s)->c_str());
 				  mVar((yyvsp[-2].s), globalCheck()); }
-#line 2512 "engines/director/lingo/lingo-gr.cpp"
+#line 2506 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 31:
-#line 345 "engines/director/lingo/lingo-gr.y"
+#line 339 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_eval);
 				  g_lingo->codeString((yyvsp[-4].s)->c_str()); }
-#line 2519 "engines/director/lingo/lingo-gr.cpp"
+#line 2513 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 32:
-#line 348 "engines/director/lingo/lingo-gr.y"
+#line 342 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_ge); }
-#line 2525 "engines/director/lingo/lingo-gr.cpp"
+#line 2519 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 33:
-#line 349 "engines/director/lingo/lingo-gr.y"
+#line 343 "engines/director/lingo/lingo-gr.y"
                                                     {
 
 		g_lingo->code1(LC::c_eval);
@@ -2544,32 +2538,32 @@ yyreduce:
 		WRITE_UINT32(&end, pos - (yyvsp[-2].code) + 2);
 		(*g_lingo->_currentAssembly)[pos] = loop;		/* final count value */
 		(*g_lingo->_currentAssembly)[(yyvsp[-2].code)] = end;	}
-#line 2548 "engines/director/lingo/lingo-gr.cpp"
+#line 2542 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 34:
-#line 374 "engines/director/lingo/lingo-gr.y"
+#line 368 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_stackpeek);
 				  g_lingo->codeInt(0);
 				  Common::String count("count");
 				  g_lingo->codeFunc(&count, 1);
 				  g_lingo->code1(LC::c_intpush);	// start counter
 				  g_lingo->codeInt(1); }
-#line 2559 "engines/director/lingo/lingo-gr.cpp"
+#line 2553 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 35:
-#line 381 "engines/director/lingo/lingo-gr.y"
+#line 375 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_stackpeek);	// get counter
 				  g_lingo->codeInt(0);
 				  g_lingo->code1(LC::c_stackpeek);	// get array size
 				  g_lingo->codeInt(2);
 				  g_lingo->code1(LC::c_le); }
-#line 2569 "engines/director/lingo/lingo-gr.cpp"
+#line 2563 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 36:
-#line 387 "engines/director/lingo/lingo-gr.y"
+#line 381 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_stackpeek);	// get list
 				  g_lingo->codeInt(2);
 				  g_lingo->code1(LC::c_stackpeek);	// get counter
@@ -2580,11 +2574,11 @@ yyreduce:
 				  g_lingo->codeString((yyvsp[-6].s)->c_str());
 				  mVar((yyvsp[-6].s), globalCheck());
 				  g_lingo->code1(LC::c_assign); }
-#line 2584 "engines/director/lingo/lingo-gr.cpp"
+#line 2578 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 37:
-#line 397 "engines/director/lingo/lingo-gr.y"
+#line 391 "engines/director/lingo/lingo-gr.y"
                                             {
 
 		g_lingo->code1(LC::c_intpush);
@@ -2602,44 +2596,44 @@ yyreduce:
 
 		(*g_lingo->_currentAssembly)[jump + 1] = loop;		/* final count value */
 		(*g_lingo->_currentAssembly)[(yyvsp[-3].code)] = end;	}
-#line 2606 "engines/director/lingo/lingo-gr.cpp"
+#line 2600 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 38:
-#line 415 "engines/director/lingo/lingo-gr.y"
+#line 409 "engines/director/lingo/lingo-gr.y"
                         {
 		g_lingo->code1(LC::c_nextRepeat); }
-#line 2613 "engines/director/lingo/lingo-gr.cpp"
+#line 2607 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 39:
-#line 417 "engines/director/lingo/lingo-gr.y"
+#line 411 "engines/director/lingo/lingo-gr.y"
                               {
 		g_lingo->code1(LC::c_whencode);
 		g_lingo->codeString((yyvsp[-2].s)->c_str()); }
-#line 2621 "engines/director/lingo/lingo-gr.cpp"
+#line 2615 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 40:
-#line 420 "engines/director/lingo/lingo-gr.y"
+#line 414 "engines/director/lingo/lingo-gr.y"
                                                           { g_lingo->code1(LC::c_telldone); }
-#line 2627 "engines/director/lingo/lingo-gr.cpp"
+#line 2621 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 41:
-#line 421 "engines/director/lingo/lingo-gr.y"
+#line 415 "engines/director/lingo/lingo-gr.y"
                                                     { g_lingo->code1(LC::c_telldone); }
-#line 2633 "engines/director/lingo/lingo-gr.cpp"
+#line 2627 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 42:
-#line 423 "engines/director/lingo/lingo-gr.y"
+#line 417 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_tell); }
-#line 2639 "engines/director/lingo/lingo-gr.cpp"
+#line 2633 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 43:
-#line 425 "engines/director/lingo/lingo-gr.y"
+#line 419 "engines/director/lingo/lingo-gr.y"
                                                                                          {
 		inst else1 = 0, end3 = 0;
 		WRITE_UINT32(&else1, (yyvsp[-3].code) + 1 - (yyvsp[-6].code) + 1);
@@ -2647,11 +2641,11 @@ yyreduce:
 		(*g_lingo->_currentAssembly)[(yyvsp[-6].code)] = else1;		/* elsepart */
 		(*g_lingo->_currentAssembly)[(yyvsp[-3].code)] = end3;		/* end, if cond fails */
 		g_lingo->processIf((yyvsp[-3].code), (yyvsp[-1].code)); }
-#line 2651 "engines/director/lingo/lingo-gr.cpp"
+#line 2645 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 44:
-#line 432 "engines/director/lingo/lingo-gr.y"
+#line 426 "engines/director/lingo/lingo-gr.y"
                                                                                                           {
 		inst else1 = 0, end = 0;
 		WRITE_UINT32(&else1, (yyvsp[-5].code) + 1 - (yyvsp[-8].code) + 1);
@@ -2659,107 +2653,107 @@ yyreduce:
 		(*g_lingo->_currentAssembly)[(yyvsp[-8].code)] = else1;		/* elsepart */
 		(*g_lingo->_currentAssembly)[(yyvsp[-5].code)] = end;		/* end, if cond fails */
 		g_lingo->processIf((yyvsp[-5].code), (yyvsp[-1].code)); }
-#line 2663 "engines/director/lingo/lingo-gr.cpp"
+#line 2657 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 47:
-#line 443 "engines/director/lingo/lingo-gr.y"
+#line 437 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		inst else1 = 0;
 		WRITE_UINT32(&else1, (yyvsp[0].code) + 1 - (yyvsp[-3].code) + 1);
 		(*g_lingo->_currentAssembly)[(yyvsp[-3].code)] = else1;	/* end, if cond fails */
 		g_lingo->codeLabel((yyvsp[0].code)); }
-#line 2673 "engines/director/lingo/lingo-gr.cpp"
+#line 2667 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 48:
-#line 449 "engines/director/lingo/lingo-gr.y"
+#line 443 "engines/director/lingo/lingo-gr.y"
                                 {
 		g_lingo->code2(LC::c_jumpifz, 0);
 		(yyval.code) = g_lingo->_currentAssembly->size() - 1; }
-#line 2681 "engines/director/lingo/lingo-gr.cpp"
+#line 2675 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 49:
-#line 453 "engines/director/lingo/lingo-gr.y"
+#line 447 "engines/director/lingo/lingo-gr.y"
                                 {
 		g_lingo->code2(LC::c_jump, 0);
 		(yyval.code) = g_lingo->_currentAssembly->size() - 1; }
-#line 2689 "engines/director/lingo/lingo-gr.cpp"
+#line 2683 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 50:
-#line 457 "engines/director/lingo/lingo-gr.y"
+#line 451 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_assign);
 		(yyval.code) = g_lingo->_currentAssembly->size() - 1; }
-#line 2697 "engines/director/lingo/lingo-gr.cpp"
+#line 2691 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 51:
-#line 461 "engines/director/lingo/lingo-gr.y"
+#line 455 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->codeLabel(0); }
-#line 2704 "engines/director/lingo/lingo-gr.cpp"
+#line 2698 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 52:
-#line 464 "engines/director/lingo/lingo-gr.y"
+#line 458 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.code) = g_lingo->_currentAssembly->size(); }
-#line 2710 "engines/director/lingo/lingo-gr.cpp"
+#line 2704 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 53:
-#line 466 "engines/director/lingo/lingo-gr.y"
+#line 460 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.code) = g_lingo->_currentAssembly->size(); }
-#line 2716 "engines/director/lingo/lingo-gr.cpp"
+#line 2710 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 56:
-#line 470 "engines/director/lingo/lingo-gr.y"
+#line 464 "engines/director/lingo/lingo-gr.y"
                         {
 		(yyval.code) = g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt((yyvsp[0].i)); }
-#line 2724 "engines/director/lingo/lingo-gr.cpp"
+#line 2718 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 57:
-#line 473 "engines/director/lingo/lingo-gr.y"
+#line 467 "engines/director/lingo/lingo-gr.y"
                         {
 		(yyval.code) = g_lingo->code1(LC::c_floatpush);
 		g_lingo->codeFloat((yyvsp[0].f)); }
-#line 2732 "engines/director/lingo/lingo-gr.cpp"
+#line 2726 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 58:
-#line 476 "engines/director/lingo/lingo-gr.y"
+#line 470 "engines/director/lingo/lingo-gr.y"
                         {											// D3
 		(yyval.code) = g_lingo->code1(LC::c_symbolpush);
 		g_lingo->codeString((yyvsp[0].s)->c_str());
 		delete (yyvsp[0].s); }
-#line 2741 "engines/director/lingo/lingo-gr.cpp"
+#line 2735 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 59:
-#line 480 "engines/director/lingo/lingo-gr.y"
+#line 474 "engines/director/lingo/lingo-gr.y"
                                 {
 		(yyval.code) = g_lingo->code1(LC::c_stringpush);
 		g_lingo->codeString((yyvsp[0].s)->c_str());
 		delete (yyvsp[0].s); }
-#line 2750 "engines/director/lingo/lingo-gr.cpp"
+#line 2744 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 60:
-#line 484 "engines/director/lingo/lingo-gr.y"
+#line 478 "engines/director/lingo/lingo-gr.y"
                         {
 		(yyval.code) = g_lingo->code1(LC::c_eval);
 		g_lingo->codeString((yyvsp[0].s)->c_str());
 		delete (yyvsp[0].s); }
-#line 2759 "engines/director/lingo/lingo-gr.cpp"
+#line 2753 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 61:
-#line 488 "engines/director/lingo/lingo-gr.y"
+#line 482 "engines/director/lingo/lingo-gr.y"
                         {
 		(yyval.code) = g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(0); // Put dummy id
@@ -2768,28 +2762,28 @@ yyreduce:
 		WRITE_UINT32(&e, (yyvsp[0].e)[0]);
 		WRITE_UINT32(&f, (yyvsp[0].e)[1]);
 		g_lingo->code2(e, f); }
-#line 2772 "engines/director/lingo/lingo-gr.cpp"
+#line 2766 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 62:
-#line 496 "engines/director/lingo/lingo-gr.y"
+#line 490 "engines/director/lingo/lingo-gr.y"
                                      {
 		(yyval.code) = g_lingo->code1(LC::c_theentitypush);
 		inst e = 0, f = 0;
 		WRITE_UINT32(&e, (yyvsp[-1].e)[0]);
 		WRITE_UINT32(&f, (yyvsp[-1].e)[1]);
 		g_lingo->code2(e, f); }
-#line 2783 "engines/director/lingo/lingo-gr.cpp"
+#line 2777 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 63:
-#line 502 "engines/director/lingo/lingo-gr.y"
+#line 496 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.code) = (yyvsp[-1].code); }
-#line 2789 "engines/director/lingo/lingo-gr.cpp"
+#line 2783 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 65:
-#line 504 "engines/director/lingo/lingo-gr.y"
+#line 498 "engines/director/lingo/lingo-gr.y"
                                 {
 		// Director parser till D3 was forgiving for any hanging parentheses
 		if (g_lingo->_ignoreError) {
@@ -2800,549 +2794,549 @@ yyreduce:
 			yyerrok;
 		}
 	}
-#line 2804 "engines/director/lingo/lingo-gr.cpp"
+#line 2798 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 66:
-#line 515 "engines/director/lingo/lingo-gr.y"
+#line 509 "engines/director/lingo/lingo-gr.y"
                  { (yyval.code) = (yyvsp[0].code); }
-#line 2810 "engines/director/lingo/lingo-gr.cpp"
+#line 2804 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 68:
-#line 517 "engines/director/lingo/lingo-gr.y"
+#line 511 "engines/director/lingo/lingo-gr.y"
                                  {
 		g_lingo->codeFunc((yyvsp[-3].s), (yyvsp[-1].narg));
 		delete (yyvsp[-3].s); }
-#line 2818 "engines/director/lingo/lingo-gr.cpp"
+#line 2812 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 69:
-#line 520 "engines/director/lingo/lingo-gr.y"
+#line 514 "engines/director/lingo/lingo-gr.y"
                                 {
 		g_lingo->codeFunc((yyvsp[-1].s), (yyvsp[0].narg));
 		delete (yyvsp[-1].s); }
-#line 2826 "engines/director/lingo/lingo-gr.cpp"
+#line 2820 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 70:
-#line 523 "engines/director/lingo/lingo-gr.y"
+#line 517 "engines/director/lingo/lingo-gr.y"
                                       {
 			g_lingo->code1(LC::c_lazyeval);
 			g_lingo->codeString((yyvsp[-1].s)->c_str());
 			g_lingo->codeFunc((yyvsp[-3].s), 1);
 			delete (yyvsp[-3].s);
 			delete (yyvsp[-1].s); }
-#line 2837 "engines/director/lingo/lingo-gr.cpp"
+#line 2831 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 71:
-#line 529 "engines/director/lingo/lingo-gr.y"
+#line 523 "engines/director/lingo/lingo-gr.y"
                                       { g_lingo->code1(LC::c_lazyeval); g_lingo->codeString((yyvsp[-1].s)->c_str()); }
-#line 2843 "engines/director/lingo/lingo-gr.cpp"
+#line 2837 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 72:
-#line 530 "engines/director/lingo/lingo-gr.y"
+#line 524 "engines/director/lingo/lingo-gr.y"
                                                     {
 			g_lingo->codeFunc((yyvsp[-6].s), (yyvsp[-1].narg) + 1);
 			delete (yyvsp[-6].s);
 			delete (yyvsp[-4].s); }
-#line 2852 "engines/director/lingo/lingo-gr.cpp"
+#line 2846 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 73:
-#line 534 "engines/director/lingo/lingo-gr.y"
+#line 528 "engines/director/lingo/lingo-gr.y"
                                 {
 		(yyval.code) = g_lingo->codeFunc((yyvsp[-3].s), (yyvsp[-1].narg));
 		delete (yyvsp[-3].s); }
-#line 2860 "engines/director/lingo/lingo-gr.cpp"
+#line 2854 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 74:
-#line 537 "engines/director/lingo/lingo-gr.y"
+#line 531 "engines/director/lingo/lingo-gr.y"
                                         {
 		(yyval.code) = g_lingo->codeFunc((yyvsp[-2].s), 1);
 		delete (yyvsp[-2].s); }
-#line 2868 "engines/director/lingo/lingo-gr.cpp"
+#line 2862 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 75:
-#line 540 "engines/director/lingo/lingo-gr.y"
+#line 534 "engines/director/lingo/lingo-gr.y"
                          {
 		g_lingo->code1(LC::c_objectfieldpush);
 		g_lingo->codeString((yyvsp[0].objectfield).os->c_str());
 		g_lingo->codeInt((yyvsp[0].objectfield).oe);
 		delete (yyvsp[0].objectfield).os; }
-#line 2878 "engines/director/lingo/lingo-gr.cpp"
+#line 2872 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 76:
-#line 545 "engines/director/lingo/lingo-gr.y"
+#line 539 "engines/director/lingo/lingo-gr.y"
                        {
 		g_lingo->code1(LC::c_objectrefpush);
 		g_lingo->codeString((yyvsp[0].objectref).obj->c_str());
 		g_lingo->codeString((yyvsp[0].objectref).field->c_str());
 		delete (yyvsp[0].objectref).obj;
 		delete (yyvsp[0].objectref).field; }
-#line 2889 "engines/director/lingo/lingo-gr.cpp"
+#line 2883 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 78:
-#line 552 "engines/director/lingo/lingo-gr.y"
+#line 546 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_add); }
-#line 2895 "engines/director/lingo/lingo-gr.cpp"
+#line 2889 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 79:
-#line 553 "engines/director/lingo/lingo-gr.y"
+#line 547 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_sub); }
-#line 2901 "engines/director/lingo/lingo-gr.cpp"
+#line 2895 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 80:
-#line 554 "engines/director/lingo/lingo-gr.y"
+#line 548 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_mul); }
-#line 2907 "engines/director/lingo/lingo-gr.cpp"
+#line 2901 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 81:
-#line 555 "engines/director/lingo/lingo-gr.y"
+#line 549 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_div); }
-#line 2913 "engines/director/lingo/lingo-gr.cpp"
+#line 2907 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 82:
-#line 556 "engines/director/lingo/lingo-gr.y"
+#line 550 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_mod); }
-#line 2919 "engines/director/lingo/lingo-gr.cpp"
+#line 2913 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 83:
-#line 557 "engines/director/lingo/lingo-gr.y"
+#line 551 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_gt); }
-#line 2925 "engines/director/lingo/lingo-gr.cpp"
+#line 2919 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 84:
-#line 558 "engines/director/lingo/lingo-gr.y"
+#line 552 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_lt); }
-#line 2931 "engines/director/lingo/lingo-gr.cpp"
+#line 2925 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 85:
-#line 559 "engines/director/lingo/lingo-gr.y"
+#line 553 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_eq); }
-#line 2937 "engines/director/lingo/lingo-gr.cpp"
+#line 2931 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 86:
-#line 560 "engines/director/lingo/lingo-gr.y"
+#line 554 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_neq); }
-#line 2943 "engines/director/lingo/lingo-gr.cpp"
+#line 2937 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 87:
-#line 561 "engines/director/lingo/lingo-gr.y"
+#line 555 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_ge); }
-#line 2949 "engines/director/lingo/lingo-gr.cpp"
+#line 2943 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 88:
-#line 562 "engines/director/lingo/lingo-gr.y"
+#line 556 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_le); }
-#line 2955 "engines/director/lingo/lingo-gr.cpp"
+#line 2949 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 89:
-#line 563 "engines/director/lingo/lingo-gr.y"
+#line 557 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_and); }
-#line 2961 "engines/director/lingo/lingo-gr.cpp"
+#line 2955 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 90:
-#line 564 "engines/director/lingo/lingo-gr.y"
+#line 558 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_or); }
-#line 2967 "engines/director/lingo/lingo-gr.cpp"
+#line 2961 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 91:
-#line 565 "engines/director/lingo/lingo-gr.y"
+#line 559 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_not); }
-#line 2973 "engines/director/lingo/lingo-gr.cpp"
+#line 2967 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 92:
-#line 566 "engines/director/lingo/lingo-gr.y"
+#line 560 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_ampersand); }
-#line 2979 "engines/director/lingo/lingo-gr.cpp"
+#line 2973 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 93:
-#line 567 "engines/director/lingo/lingo-gr.y"
+#line 561 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_concat); }
-#line 2985 "engines/director/lingo/lingo-gr.cpp"
+#line 2979 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 94:
-#line 568 "engines/director/lingo/lingo-gr.y"
+#line 562 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_contains); }
-#line 2991 "engines/director/lingo/lingo-gr.cpp"
+#line 2985 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 95:
-#line 569 "engines/director/lingo/lingo-gr.y"
+#line 563 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_starts); }
-#line 2997 "engines/director/lingo/lingo-gr.cpp"
+#line 2991 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 96:
-#line 570 "engines/director/lingo/lingo-gr.y"
+#line 564 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.code) = (yyvsp[0].code); }
-#line 3003 "engines/director/lingo/lingo-gr.cpp"
+#line 2997 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 97:
-#line 571 "engines/director/lingo/lingo-gr.y"
+#line 565 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.code) = (yyvsp[0].code); g_lingo->code1(LC::c_negate); }
-#line 3009 "engines/director/lingo/lingo-gr.cpp"
+#line 3003 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 98:
-#line 572 "engines/director/lingo/lingo-gr.y"
+#line 566 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_intersects); }
-#line 3015 "engines/director/lingo/lingo-gr.cpp"
+#line 3009 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 99:
-#line 573 "engines/director/lingo/lingo-gr.y"
+#line 567 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_within); }
-#line 3021 "engines/director/lingo/lingo-gr.cpp"
+#line 3015 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 100:
-#line 575 "engines/director/lingo/lingo-gr.y"
+#line 569 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_charOf); }
-#line 3027 "engines/director/lingo/lingo-gr.cpp"
+#line 3021 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 101:
-#line 576 "engines/director/lingo/lingo-gr.y"
+#line 570 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_charToOf); }
-#line 3033 "engines/director/lingo/lingo-gr.cpp"
+#line 3027 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 102:
-#line 577 "engines/director/lingo/lingo-gr.y"
+#line 571 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_itemOf); }
-#line 3039 "engines/director/lingo/lingo-gr.cpp"
+#line 3033 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 103:
-#line 578 "engines/director/lingo/lingo-gr.y"
+#line 572 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_itemToOf); }
-#line 3045 "engines/director/lingo/lingo-gr.cpp"
+#line 3039 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 104:
-#line 579 "engines/director/lingo/lingo-gr.y"
+#line 573 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_lineOf); }
-#line 3051 "engines/director/lingo/lingo-gr.cpp"
+#line 3045 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 105:
-#line 580 "engines/director/lingo/lingo-gr.y"
+#line 574 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_lineToOf); }
-#line 3057 "engines/director/lingo/lingo-gr.cpp"
+#line 3051 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 106:
-#line 581 "engines/director/lingo/lingo-gr.y"
+#line 575 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_wordOf); }
-#line 3063 "engines/director/lingo/lingo-gr.cpp"
+#line 3057 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 107:
-#line 582 "engines/director/lingo/lingo-gr.y"
+#line 576 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_wordToOf); }
-#line 3069 "engines/director/lingo/lingo-gr.cpp"
+#line 3063 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 108:
-#line 584 "engines/director/lingo/lingo-gr.y"
+#line 578 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->codeFunc((yyvsp[-1].s), 1);
 		delete (yyvsp[-1].s); }
-#line 3077 "engines/director/lingo/lingo-gr.cpp"
+#line 3071 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 110:
-#line 589 "engines/director/lingo/lingo-gr.y"
+#line 583 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_printtop); }
-#line 3083 "engines/director/lingo/lingo-gr.cpp"
+#line 3077 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 113:
-#line 592 "engines/director/lingo/lingo-gr.y"
+#line 586 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_exitRepeat); }
-#line 3089 "engines/director/lingo/lingo-gr.cpp"
+#line 3083 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 114:
-#line 593 "engines/director/lingo/lingo-gr.y"
+#line 587 "engines/director/lingo/lingo-gr.y"
                                                         { g_lingo->code1(LC::c_procret); }
-#line 3095 "engines/director/lingo/lingo-gr.cpp"
+#line 3089 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 115:
-#line 594 "engines/director/lingo/lingo-gr.y"
+#line 588 "engines/director/lingo/lingo-gr.y"
                                                         { inArgs(); }
-#line 3101 "engines/director/lingo/lingo-gr.cpp"
+#line 3095 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 116:
-#line 594 "engines/director/lingo/lingo-gr.y"
+#line 588 "engines/director/lingo/lingo-gr.y"
                                                                                  { inNone(); }
-#line 3107 "engines/director/lingo/lingo-gr.cpp"
+#line 3101 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 117:
-#line 595 "engines/director/lingo/lingo-gr.y"
+#line 589 "engines/director/lingo/lingo-gr.y"
                                                         { inArgs(); }
-#line 3113 "engines/director/lingo/lingo-gr.cpp"
+#line 3107 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 118:
-#line 595 "engines/director/lingo/lingo-gr.y"
+#line 589 "engines/director/lingo/lingo-gr.y"
                                                                                    { inNone(); }
-#line 3119 "engines/director/lingo/lingo-gr.cpp"
+#line 3113 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 119:
-#line 596 "engines/director/lingo/lingo-gr.y"
+#line 590 "engines/director/lingo/lingo-gr.y"
                                                         { inArgs(); }
-#line 3125 "engines/director/lingo/lingo-gr.cpp"
+#line 3119 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 120:
-#line 596 "engines/director/lingo/lingo-gr.y"
+#line 590 "engines/director/lingo/lingo-gr.y"
                                                                                    { inNone(); }
-#line 3131 "engines/director/lingo/lingo-gr.cpp"
+#line 3125 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 121:
-#line 597 "engines/director/lingo/lingo-gr.y"
+#line 591 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->codeFunc((yyvsp[-3].s), (yyvsp[-1].narg));
 		delete (yyvsp[-3].s); }
-#line 3139 "engines/director/lingo/lingo-gr.cpp"
+#line 3133 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 122:
-#line 600 "engines/director/lingo/lingo-gr.y"
+#line 594 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->codeFunc((yyvsp[-1].s), (yyvsp[0].narg));
 		delete (yyvsp[-1].s); }
-#line 3147 "engines/director/lingo/lingo-gr.cpp"
+#line 3141 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 123:
-#line 603 "engines/director/lingo/lingo-gr.y"
+#line 597 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_open); }
-#line 3153 "engines/director/lingo/lingo-gr.cpp"
+#line 3147 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 124:
-#line 604 "engines/director/lingo/lingo-gr.y"
+#line 598 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code2(LC::c_voidpush, LC::c_open); }
-#line 3159 "engines/director/lingo/lingo-gr.cpp"
+#line 3153 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 125:
-#line 606 "engines/director/lingo/lingo-gr.y"
+#line 600 "engines/director/lingo/lingo-gr.y"
                                                 {
 		mVar((yyvsp[0].s), kVarGlobal);
 		delete (yyvsp[0].s); }
-#line 3167 "engines/director/lingo/lingo-gr.cpp"
+#line 3161 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 126:
-#line 609 "engines/director/lingo/lingo-gr.y"
+#line 603 "engines/director/lingo/lingo-gr.y"
                                                 {
 		mVar((yyvsp[0].s), kVarGlobal);
 		delete (yyvsp[0].s); }
-#line 3175 "engines/director/lingo/lingo-gr.cpp"
+#line 3169 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 127:
-#line 613 "engines/director/lingo/lingo-gr.y"
+#line 607 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->code1(LC::c_property);
 		g_lingo->codeString((yyvsp[0].s)->c_str());
 		mVar((yyvsp[0].s), kVarProperty);
 		delete (yyvsp[0].s); }
-#line 3185 "engines/director/lingo/lingo-gr.cpp"
+#line 3179 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 128:
-#line 618 "engines/director/lingo/lingo-gr.y"
+#line 612 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_property);
 		g_lingo->codeString((yyvsp[0].s)->c_str());
 		mVar((yyvsp[0].s), kVarProperty);
 		delete (yyvsp[0].s); }
-#line 3195 "engines/director/lingo/lingo-gr.cpp"
+#line 3189 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 129:
-#line 624 "engines/director/lingo/lingo-gr.y"
+#line 618 "engines/director/lingo/lingo-gr.y"
                                                 {
 		mVar((yyvsp[0].s), kVarInstance);
 		delete (yyvsp[0].s); }
-#line 3203 "engines/director/lingo/lingo-gr.cpp"
+#line 3197 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 130:
-#line 627 "engines/director/lingo/lingo-gr.y"
+#line 621 "engines/director/lingo/lingo-gr.y"
                                         {
 		mVar((yyvsp[0].s), kVarInstance);
 		delete (yyvsp[0].s); }
-#line 3211 "engines/director/lingo/lingo-gr.cpp"
+#line 3205 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 131:
-#line 638 "engines/director/lingo/lingo-gr.y"
+#line 632 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_gotoloop); }
-#line 3217 "engines/director/lingo/lingo-gr.cpp"
+#line 3211 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 132:
-#line 639 "engines/director/lingo/lingo-gr.y"
+#line 633 "engines/director/lingo/lingo-gr.y"
                                                         { g_lingo->code1(LC::c_gotonext); }
-#line 3223 "engines/director/lingo/lingo-gr.cpp"
+#line 3217 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 133:
-#line 640 "engines/director/lingo/lingo-gr.y"
+#line 634 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_gotoprevious); }
-#line 3229 "engines/director/lingo/lingo-gr.cpp"
+#line 3223 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 134:
-#line 641 "engines/director/lingo/lingo-gr.y"
+#line 635 "engines/director/lingo/lingo-gr.y"
                                                         {
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(1);
 		g_lingo->code1(LC::c_goto); }
-#line 3238 "engines/director/lingo/lingo-gr.cpp"
+#line 3232 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 135:
-#line 645 "engines/director/lingo/lingo-gr.y"
+#line 639 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(3);
 		g_lingo->code1(LC::c_goto); }
-#line 3247 "engines/director/lingo/lingo-gr.cpp"
+#line 3241 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 136:
-#line 649 "engines/director/lingo/lingo-gr.y"
+#line 643 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(2);
 		g_lingo->code1(LC::c_goto); }
-#line 3256 "engines/director/lingo/lingo-gr.cpp"
+#line 3250 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 139:
-#line 657 "engines/director/lingo/lingo-gr.y"
+#line 651 "engines/director/lingo/lingo-gr.y"
                                         { // "play #done" is also caught by this
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(1);
 		g_lingo->code1(LC::c_play); }
-#line 3265 "engines/director/lingo/lingo-gr.cpp"
+#line 3259 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 140:
-#line 661 "engines/director/lingo/lingo-gr.y"
+#line 655 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(3);
 		g_lingo->code1(LC::c_play); }
-#line 3274 "engines/director/lingo/lingo-gr.cpp"
+#line 3268 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 141:
-#line 665 "engines/director/lingo/lingo-gr.y"
+#line 659 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(2);
 		g_lingo->code1(LC::c_play); }
-#line 3283 "engines/director/lingo/lingo-gr.cpp"
+#line 3277 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 142:
-#line 669 "engines/director/lingo/lingo-gr.y"
+#line 663 "engines/director/lingo/lingo-gr.y"
                      { g_lingo->codeSetImmediate(true); }
-#line 3289 "engines/director/lingo/lingo-gr.cpp"
+#line 3283 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 143:
-#line 669 "engines/director/lingo/lingo-gr.y"
+#line 663 "engines/director/lingo/lingo-gr.y"
                                                                   {
 		g_lingo->codeSetImmediate(false);
 		g_lingo->codeFunc((yyvsp[-2].s), (yyvsp[0].narg));
 		delete (yyvsp[-2].s); }
-#line 3298 "engines/director/lingo/lingo-gr.cpp"
+#line 3292 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 144:
-#line 699 "engines/director/lingo/lingo-gr.y"
+#line 693 "engines/director/lingo/lingo-gr.y"
              { startDef(); }
-#line 3304 "engines/director/lingo/lingo-gr.cpp"
+#line 3298 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 145:
-#line 699 "engines/director/lingo/lingo-gr.y"
+#line 693 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->_currentFactory = NULL; }
-#line 3310 "engines/director/lingo/lingo-gr.cpp"
+#line 3304 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 146:
-#line 700 "engines/director/lingo/lingo-gr.y"
+#line 694 "engines/director/lingo/lingo-gr.y"
                                                                         {
 		g_lingo->code1(LC::c_procret);
 		g_lingo->codeDefine(*(yyvsp[-6].s), (yyvsp[-4].code), (yyvsp[-3].narg));
 		endDef();
 		delete (yyvsp[-6].s); }
-#line 3320 "engines/director/lingo/lingo-gr.cpp"
+#line 3314 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 147:
-#line 705 "engines/director/lingo/lingo-gr.y"
+#line 699 "engines/director/lingo/lingo-gr.y"
                         { g_lingo->codeFactory(*(yyvsp[0].s)); delete (yyvsp[0].s); }
-#line 3326 "engines/director/lingo/lingo-gr.cpp"
+#line 3320 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 148:
-#line 706 "engines/director/lingo/lingo-gr.y"
+#line 700 "engines/director/lingo/lingo-gr.y"
                   { startDef(); }
-#line 3332 "engines/director/lingo/lingo-gr.cpp"
+#line 3326 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 149:
-#line 707 "engines/director/lingo/lingo-gr.y"
+#line 701 "engines/director/lingo/lingo-gr.y"
                                                                         {
 		g_lingo->code1(LC::c_procret);
 		g_lingo->codeDefine(*(yyvsp[-6].s), (yyvsp[-4].code), (yyvsp[-3].narg), g_lingo->_currentFactory);
 		endDef();
 		delete (yyvsp[-6].s); }
-#line 3342 "engines/director/lingo/lingo-gr.cpp"
+#line 3336 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 150:
-#line 712 "engines/director/lingo/lingo-gr.y"
+#line 706 "engines/director/lingo/lingo-gr.y"
                                                                    {	// D3
 		g_lingo->code1(LC::c_procret);
 		g_lingo->codeDefine(*(yyvsp[-7].s), (yyvsp[-6].code), (yyvsp[-5].narg));
@@ -3351,70 +3345,70 @@ yyreduce:
 		checkEnd((yyvsp[-1].s), (yyvsp[-7].s)->c_str(), false);
 		delete (yyvsp[-7].s);
 		delete (yyvsp[-1].s); }
-#line 3355 "engines/director/lingo/lingo-gr.cpp"
+#line 3349 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 151:
-#line 720 "engines/director/lingo/lingo-gr.y"
+#line 714 "engines/director/lingo/lingo-gr.y"
                                                {	// D4. No 'end' clause
 		g_lingo->code1(LC::c_procret);
 		g_lingo->codeDefine(*(yyvsp[-5].s), (yyvsp[-4].code), (yyvsp[-3].narg));
 		endDef();
 		delete (yyvsp[-5].s); }
-#line 3365 "engines/director/lingo/lingo-gr.cpp"
+#line 3359 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 152:
-#line 726 "engines/director/lingo/lingo-gr.y"
+#line 720 "engines/director/lingo/lingo-gr.y"
          { startDef(); }
-#line 3371 "engines/director/lingo/lingo-gr.cpp"
+#line 3365 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 153:
-#line 726 "engines/director/lingo/lingo-gr.y"
+#line 720 "engines/director/lingo/lingo-gr.y"
                                 {
 		(yyval.s) = (yyvsp[0].s); g_lingo->_currentFactory = NULL; }
-#line 3378 "engines/director/lingo/lingo-gr.cpp"
+#line 3372 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 154:
-#line 729 "engines/director/lingo/lingo-gr.y"
+#line 723 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.narg) = 0; }
-#line 3384 "engines/director/lingo/lingo-gr.cpp"
+#line 3378 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 155:
-#line 730 "engines/director/lingo/lingo-gr.y"
+#line 724 "engines/director/lingo/lingo-gr.y"
                                                         { g_lingo->codeArg((yyvsp[0].s)); mVar((yyvsp[0].s), kVarArgument); (yyval.narg) = 1; delete (yyvsp[0].s); }
-#line 3390 "engines/director/lingo/lingo-gr.cpp"
+#line 3384 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 156:
-#line 731 "engines/director/lingo/lingo-gr.y"
+#line 725 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->codeArg((yyvsp[0].s)); mVar((yyvsp[0].s), kVarArgument); (yyval.narg) = (yyvsp[-2].narg) + 1; delete (yyvsp[0].s); }
-#line 3396 "engines/director/lingo/lingo-gr.cpp"
+#line 3390 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 158:
-#line 734 "engines/director/lingo/lingo-gr.y"
+#line 728 "engines/director/lingo/lingo-gr.y"
                                                         { delete (yyvsp[0].s); }
-#line 3402 "engines/director/lingo/lingo-gr.cpp"
+#line 3396 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 159:
-#line 735 "engines/director/lingo/lingo-gr.y"
+#line 729 "engines/director/lingo/lingo-gr.y"
                                                 { delete (yyvsp[0].s); }
-#line 3408 "engines/director/lingo/lingo-gr.cpp"
+#line 3402 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 160:
-#line 737 "engines/director/lingo/lingo-gr.y"
+#line 731 "engines/director/lingo/lingo-gr.y"
                                         { inDef(); }
-#line 3414 "engines/director/lingo/lingo-gr.cpp"
+#line 3408 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 161:
-#line 739 "engines/director/lingo/lingo-gr.y"
+#line 733 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_call);
 		g_lingo->codeString((yyvsp[-1].s)->c_str());
@@ -3422,113 +3416,113 @@ yyreduce:
 		WRITE_UINT32(&numpar, (yyvsp[0].narg));
 		g_lingo->code1(numpar);
 		delete (yyvsp[-1].s); }
-#line 3426 "engines/director/lingo/lingo-gr.cpp"
+#line 3420 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 162:
-#line 747 "engines/director/lingo/lingo-gr.y"
+#line 741 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.narg) = 0; }
-#line 3432 "engines/director/lingo/lingo-gr.cpp"
+#line 3426 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 163:
-#line 748 "engines/director/lingo/lingo-gr.y"
+#line 742 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.narg) = 1; }
-#line 3438 "engines/director/lingo/lingo-gr.cpp"
+#line 3432 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 164:
-#line 749 "engines/director/lingo/lingo-gr.y"
+#line 743 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.narg) = (yyvsp[-2].narg) + 1; }
-#line 3444 "engines/director/lingo/lingo-gr.cpp"
+#line 3438 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 165:
-#line 751 "engines/director/lingo/lingo-gr.y"
+#line 745 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.narg) = 1; }
-#line 3450 "engines/director/lingo/lingo-gr.cpp"
+#line 3444 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 166:
-#line 752 "engines/director/lingo/lingo-gr.y"
+#line 746 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.narg) = (yyvsp[-2].narg) + 1; }
-#line 3456 "engines/director/lingo/lingo-gr.cpp"
+#line 3450 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 167:
-#line 754 "engines/director/lingo/lingo-gr.y"
+#line 748 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.code) = (yyvsp[-1].code); }
-#line 3462 "engines/director/lingo/lingo-gr.cpp"
+#line 3456 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 168:
-#line 756 "engines/director/lingo/lingo-gr.y"
+#line 750 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.code) = g_lingo->code2(LC::c_arraypush, 0); }
-#line 3468 "engines/director/lingo/lingo-gr.cpp"
+#line 3462 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 169:
-#line 757 "engines/director/lingo/lingo-gr.y"
+#line 751 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.code) = g_lingo->code2(LC::c_proparraypush, 0); }
-#line 3474 "engines/director/lingo/lingo-gr.cpp"
+#line 3468 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 170:
-#line 758 "engines/director/lingo/lingo-gr.y"
+#line 752 "engines/director/lingo/lingo-gr.y"
                      { (yyval.code) = g_lingo->code1(LC::c_arraypush); (yyval.code) = g_lingo->codeInt((yyvsp[0].narg)); }
-#line 3480 "engines/director/lingo/lingo-gr.cpp"
+#line 3474 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 171:
-#line 759 "engines/director/lingo/lingo-gr.y"
+#line 753 "engines/director/lingo/lingo-gr.y"
                          { (yyval.code) = g_lingo->code1(LC::c_proparraypush); (yyval.code) = g_lingo->codeInt((yyvsp[0].narg)); }
-#line 3486 "engines/director/lingo/lingo-gr.cpp"
+#line 3480 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 172:
-#line 761 "engines/director/lingo/lingo-gr.y"
+#line 755 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.narg) = 1; }
-#line 3492 "engines/director/lingo/lingo-gr.cpp"
+#line 3486 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 173:
-#line 762 "engines/director/lingo/lingo-gr.y"
+#line 756 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.narg) = (yyvsp[-2].narg) + 1; }
-#line 3498 "engines/director/lingo/lingo-gr.cpp"
+#line 3492 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 174:
-#line 764 "engines/director/lingo/lingo-gr.y"
+#line 758 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.narg) = 1; }
-#line 3504 "engines/director/lingo/lingo-gr.cpp"
+#line 3498 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 175:
-#line 765 "engines/director/lingo/lingo-gr.y"
+#line 759 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.narg) = (yyvsp[-2].narg) + 1; }
-#line 3510 "engines/director/lingo/lingo-gr.cpp"
+#line 3504 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 176:
-#line 767 "engines/director/lingo/lingo-gr.y"
+#line 761 "engines/director/lingo/lingo-gr.y"
                                 {
 		g_lingo->code1(LC::c_symbolpush);
 		g_lingo->codeString((yyvsp[-2].s)->c_str());
 		delete (yyvsp[-2].s); }
-#line 3519 "engines/director/lingo/lingo-gr.cpp"
+#line 3513 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 177:
-#line 771 "engines/director/lingo/lingo-gr.y"
+#line 765 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_stringpush);
 		g_lingo->codeString((yyvsp[-2].s)->c_str());
 		delete (yyvsp[-2].s); }
-#line 3528 "engines/director/lingo/lingo-gr.cpp"
+#line 3522 "engines/director/lingo/lingo-gr.cpp"
     break;
 
 
-#line 3532 "engines/director/lingo/lingo-gr.cpp"
+#line 3526 "engines/director/lingo/lingo-gr.cpp"
 
       default: break;
     }
@@ -3727,7 +3721,7 @@ yyreturn:
   return yyresult;
 }
 
-#line 777 "engines/director/lingo/lingo-gr.y"
+#line 771 "engines/director/lingo/lingo-gr.y"
 
 
 int yyreport_syntax_error(const yypcontext_t *ctx) {
diff --git a/engines/director/lingo/lingo-gr.h b/engines/director/lingo/lingo-gr.h
index 4310d7d043..43e1079c9a 100644
--- a/engines/director/lingo/lingo-gr.h
+++ b/engines/director/lingo/lingo-gr.h
@@ -147,7 +147,7 @@ extern int yydebug;
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 union YYSTYPE
 {
-#line 139 "engines/director/lingo/lingo-gr.y"
+#line 133 "engines/director/lingo/lingo-gr.y"
 
 	Common::String *s;
 	int i;
diff --git a/engines/director/lingo/lingo-gr.y b/engines/director/lingo/lingo-gr.y
index 16a21955c1..0db3bc4553 100644
--- a/engines/director/lingo/lingo-gr.y
+++ b/engines/director/lingo/lingo-gr.y
@@ -90,8 +90,6 @@ static void inNone() { g_lingo->_indef = kStateNone; }
 
 static void startDef() {
 	inArgs();
-	g_lingo->_methodVarsStash = g_lingo->_methodVars;
-	g_lingo->_methodVars = new Common::HashMap<Common::String, VarType, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>();
 
 	if (g_lingo->_inFactory) {
 		for (SymbolHash::iterator i = g_lingo->_currentFactory->properties.begin(); i != g_lingo->_currentFactory->properties.end(); ++i) {
@@ -103,10 +101,6 @@ static void startDef() {
 static void endDef() {
 	g_lingo->clearArgStack();
 	inNone();
-
-	delete g_lingo->_methodVars;
-	g_lingo->_methodVars = g_lingo->_methodVarsStash;
-	g_lingo->_methodVarsStash = nullptr;
 }
 
 static VarType globalCheck() {
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index e8b8a21fb4..932ed7c9bb 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -322,6 +322,9 @@ void Lingo::addCode(const char *code, ScriptType type, uint16 id) {
 	// macros and factories have conflicting grammar. Thus we ease life for the parser.
 	if ((end = findNextDefinition(code))) {
 		do {
+			g_lingo->_methodVarsStash = g_lingo->_methodVars;
+			g_lingo->_methodVars = new Common::HashMap<Common::String, VarType, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>();
+
 			Common::String chunk(begin, end);
 
 			if (chunk.hasPrefixIgnoreCase("factory") || chunk.hasPrefixIgnoreCase("method"))
@@ -346,6 +349,10 @@ void Lingo::addCode(const char *code, ScriptType type, uint16 id) {
 				debugC(2, kDebugCompile, "<end code>");
 			}
 
+			delete g_lingo->_methodVars;
+			g_lingo->_methodVars = g_lingo->_methodVarsStash;
+			g_lingo->_methodVarsStash = nullptr;
+
 			begin = end;
 		} while ((end = findNextDefinition(begin + 1)));
 


Commit: 81d31390015787a38838bb7069d2b3a1c3adc705
    https://github.com/scummvm/scummvm/commit/81d31390015787a38838bb7069d2b3a1c3adc705
Author: djsrv (dservilla at gmail.com)
Date: 2020-06-10T12:18:29-04:00

Commit Message:
DIRECTOR: LINGO: Correctly reset _indef

Changed paths:
    engines/director/lingo/lingo-gr.cpp
    engines/director/lingo/lingo-gr.h
    engines/director/lingo/lingo-gr.y
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-gr.cpp b/engines/director/lingo/lingo-gr.cpp
index ae29a00b8e..d78dcd6e98 100644
--- a/engines/director/lingo/lingo-gr.cpp
+++ b/engines/director/lingo/lingo-gr.cpp
@@ -101,9 +101,10 @@ static void checkEnd(Common::String *token, const char *expect, bool required) {
 	}
 }
 
-static void inArgs() { g_lingo->_indef = kStateInArgs; }
-static void inDef()  { g_lingo->_indef = kStateInDef; }
-static void inNone() { g_lingo->_indef = kStateNone; }
+static void inArgs() { g_lingo->_indefStore = g_lingo->_indef; g_lingo->_indef = kStateInArgs; }
+static void inDef()  { g_lingo->_indefStore = g_lingo->_indef; g_lingo->_indef = kStateInDef; }
+static void inNone() { g_lingo->_indefStore = g_lingo->_indef; g_lingo->_indef = kStateNone; }
+static void inLast() { g_lingo->_indef = g_lingo->_indefStore; }
 
 static void startDef() {
 	inArgs();
@@ -146,7 +147,7 @@ static void mVar(Common::String *s, VarType type) {
 }
 
 
-#line 150 "engines/director/lingo/lingo-gr.cpp"
+#line 151 "engines/director/lingo/lingo-gr.cpp"
 
 # ifndef YY_CAST
 #  ifdef __cplusplus
@@ -283,7 +284,7 @@ extern int yydebug;
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 union YYSTYPE
 {
-#line 133 "engines/director/lingo/lingo-gr.y"
+#line 134 "engines/director/lingo/lingo-gr.y"
 
 	Common::String *s;
 	int i;
@@ -303,7 +304,7 @@ union YYSTYPE
 		Common::String *field;
 	} objectref;
 
-#line 307 "engines/director/lingo/lingo-gr.cpp"
+#line 308 "engines/director/lingo/lingo-gr.cpp"
 
 };
 typedef union YYSTYPE YYSTYPE;
@@ -857,24 +858,24 @@ static const yytype_int8 yytranslate[] =
   /* YYRLINEYYN -- Source line where rule number YYN was defined.  */
 static const yytype_int16 yyrline[] =
 {
-       0,   192,   192,   193,   195,   196,   197,   199,   206,   210,
-     221,   222,   223,   230,   237,   244,   251,   257,   264,   275,
-     282,   283,   284,   286,   287,   292,   304,   308,   311,   303,
-     335,   339,   342,   334,   368,   375,   381,   367,   409,   411,
-     414,   415,   417,   419,   426,   434,   435,   437,   443,   447,
-     451,   455,   458,   460,   461,   462,   464,   467,   470,   474,
-     478,   482,   490,   496,   497,   498,   509,   510,   511,   514,
-     517,   523,   523,   528,   531,   534,   539,   545,   546,   547,
-     548,   549,   550,   551,   552,   553,   554,   555,   556,   557,
-     558,   559,   560,   561,   562,   563,   564,   565,   566,   567,
-     569,   570,   571,   572,   573,   574,   575,   576,   578,   581,
-     583,   584,   585,   586,   587,   588,   588,   589,   589,   590,
-     590,   591,   594,   597,   598,   600,   603,   607,   612,   618,
-     621,   632,   633,   634,   635,   639,   643,   648,   649,   651,
-     655,   659,   663,   663,   693,   693,   693,   699,   700,   700,
-     706,   714,   720,   720,   723,   724,   725,   727,   728,   729,
-     731,   733,   741,   742,   743,   745,   746,   748,   750,   751,
-     752,   753,   755,   756,   758,   759,   761,   765
+       0,   193,   193,   194,   196,   197,   198,   200,   207,   211,
+     222,   223,   224,   231,   238,   245,   252,   258,   265,   276,
+     283,   284,   285,   287,   288,   293,   305,   309,   312,   304,
+     336,   340,   343,   335,   369,   376,   382,   368,   410,   412,
+     415,   416,   418,   420,   427,   435,   436,   438,   444,   448,
+     452,   456,   459,   461,   462,   463,   465,   468,   471,   475,
+     479,   483,   491,   497,   498,   499,   510,   511,   512,   515,
+     518,   524,   524,   529,   532,   535,   540,   546,   547,   548,
+     549,   550,   551,   552,   553,   554,   555,   556,   557,   558,
+     559,   560,   561,   562,   563,   564,   565,   566,   567,   568,
+     570,   571,   572,   573,   574,   575,   576,   577,   579,   582,
+     584,   585,   586,   587,   588,   589,   589,   590,   590,   591,
+     591,   592,   595,   598,   599,   601,   604,   608,   613,   619,
+     622,   633,   634,   635,   636,   640,   644,   649,   650,   652,
+     656,   660,   664,   664,   694,   694,   694,   700,   701,   701,
+     707,   715,   721,   721,   724,   725,   726,   728,   729,   730,
+     732,   734,   742,   743,   744,   746,   747,   749,   751,   752,
+     753,   754,   756,   757,   759,   760,   762,   766
 };
 #endif
 
@@ -1945,81 +1946,81 @@ yydestruct (const char *yymsg,
   switch (yykind)
     {
     case 22: /* BLTIN  */
-#line 187 "engines/director/lingo/lingo-gr.y"
+#line 188 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1951 "engines/director/lingo/lingo-gr.cpp"
+#line 1952 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 23: /* FBLTIN  */
-#line 187 "engines/director/lingo/lingo-gr.y"
+#line 188 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1957 "engines/director/lingo/lingo-gr.cpp"
+#line 1958 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 24: /* RBLTIN  */
-#line 187 "engines/director/lingo/lingo-gr.y"
+#line 188 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1963 "engines/director/lingo/lingo-gr.cpp"
+#line 1964 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 25: /* THEFBLTIN  */
-#line 187 "engines/director/lingo/lingo-gr.y"
+#line 188 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1969 "engines/director/lingo/lingo-gr.cpp"
+#line 1970 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 26: /* ID  */
-#line 187 "engines/director/lingo/lingo-gr.y"
+#line 188 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1975 "engines/director/lingo/lingo-gr.cpp"
+#line 1976 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 27: /* STRING  */
-#line 187 "engines/director/lingo/lingo-gr.y"
+#line 188 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1981 "engines/director/lingo/lingo-gr.cpp"
+#line 1982 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 28: /* HANDLER  */
-#line 187 "engines/director/lingo/lingo-gr.y"
+#line 188 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1987 "engines/director/lingo/lingo-gr.cpp"
+#line 1988 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 29: /* SYMBOL  */
-#line 187 "engines/director/lingo/lingo-gr.y"
+#line 188 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1993 "engines/director/lingo/lingo-gr.cpp"
+#line 1994 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 30: /* ENDCLAUSE  */
-#line 187 "engines/director/lingo/lingo-gr.y"
+#line 188 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 1999 "engines/director/lingo/lingo-gr.cpp"
+#line 2000 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 31: /* tPLAYACCEL  */
-#line 187 "engines/director/lingo/lingo-gr.y"
+#line 188 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 2005 "engines/director/lingo/lingo-gr.cpp"
+#line 2006 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 32: /* tMETHOD  */
-#line 187 "engines/director/lingo/lingo-gr.y"
+#line 188 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 2011 "engines/director/lingo/lingo-gr.cpp"
+#line 2012 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 33: /* THEOBJECTFIELD  */
-#line 188 "engines/director/lingo/lingo-gr.y"
+#line 189 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).objectfield).os; }
-#line 2017 "engines/director/lingo/lingo-gr.cpp"
+#line 2018 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case 148: /* on  */
-#line 187 "engines/director/lingo/lingo-gr.y"
+#line 188 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 2023 "engines/director/lingo/lingo-gr.cpp"
+#line 2024 "engines/director/lingo/lingo-gr.cpp"
         break;
 
       default:
@@ -2298,7 +2299,7 @@ yyreduce:
   switch (yyn)
     {
   case 7:
-#line 199 "engines/director/lingo/lingo-gr.y"
+#line 200 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_varpush);
 		g_lingo->codeString((yyvsp[0].s)->c_str());
@@ -2306,19 +2307,19 @@ yyreduce:
 		g_lingo->code1(LC::c_assign);
 		(yyval.code) = (yyvsp[-2].code);
 		delete (yyvsp[0].s); }
-#line 2310 "engines/director/lingo/lingo-gr.cpp"
+#line 2311 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 8:
-#line 206 "engines/director/lingo/lingo-gr.y"
+#line 207 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->code1(LC::c_assign);
 		(yyval.code) = (yyvsp[-2].code); }
-#line 2318 "engines/director/lingo/lingo-gr.cpp"
+#line 2319 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 9:
-#line 210 "engines/director/lingo/lingo-gr.y"
+#line 211 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		if (!(yyvsp[-3].s)->equalsIgnoreCase("menu")) {
 			warning("LEXER: keyword 'menu' expected");
@@ -2330,23 +2331,23 @@ yyreduce:
 		g_lingo->codeInt((yyvsp[-4].e)[1]);
 		g_lingo->code1(LC::c_assign);
 		(yyval.code) = (yyvsp[0].code); }
-#line 2334 "engines/director/lingo/lingo-gr.cpp"
+#line 2335 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 10:
-#line 221 "engines/director/lingo/lingo-gr.y"
+#line 222 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.code) = g_lingo->code1(LC::c_after); }
-#line 2340 "engines/director/lingo/lingo-gr.cpp"
+#line 2341 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 11:
-#line 222 "engines/director/lingo/lingo-gr.y"
+#line 223 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.code) = g_lingo->code1(LC::c_before); }
-#line 2346 "engines/director/lingo/lingo-gr.cpp"
+#line 2347 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 12:
-#line 223 "engines/director/lingo/lingo-gr.y"
+#line 224 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->code1(LC::c_varpush);
 		g_lingo->codeString((yyvsp[-2].s)->c_str());
@@ -2354,11 +2355,11 @@ yyreduce:
 		g_lingo->code1(LC::c_assign);
 		(yyval.code) = (yyvsp[0].code);
 		delete (yyvsp[-2].s); }
-#line 2358 "engines/director/lingo/lingo-gr.cpp"
+#line 2359 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 13:
-#line 230 "engines/director/lingo/lingo-gr.y"
+#line 231 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(0); // Put dummy id
@@ -2366,11 +2367,11 @@ yyreduce:
 		g_lingo->codeInt((yyvsp[-2].e)[0]);
 		g_lingo->codeInt((yyvsp[-2].e)[1]);
 		(yyval.code) = (yyvsp[0].code); }
-#line 2370 "engines/director/lingo/lingo-gr.cpp"
+#line 2371 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 14:
-#line 237 "engines/director/lingo/lingo-gr.y"
+#line 238 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->code1(LC::c_varpush);
 		g_lingo->codeString((yyvsp[-2].s)->c_str());
@@ -2378,11 +2379,11 @@ yyreduce:
 		g_lingo->code1(LC::c_assign);
 		(yyval.code) = (yyvsp[0].code);
 		delete (yyvsp[-2].s); }
-#line 2382 "engines/director/lingo/lingo-gr.cpp"
+#line 2383 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 15:
-#line 244 "engines/director/lingo/lingo-gr.y"
+#line 245 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(0); // Put dummy id
@@ -2390,33 +2391,33 @@ yyreduce:
 		g_lingo->codeInt((yyvsp[-2].e)[0]);
 		g_lingo->codeInt((yyvsp[-2].e)[1]);
 		(yyval.code) = (yyvsp[0].code); }
-#line 2394 "engines/director/lingo/lingo-gr.cpp"
+#line 2395 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 16:
-#line 251 "engines/director/lingo/lingo-gr.y"
+#line 252 "engines/director/lingo/lingo-gr.y"
                                                         {
 		g_lingo->code1(LC::c_swap);
 		g_lingo->code1(LC::c_theentityassign);
 		g_lingo->codeInt((yyvsp[-3].e)[0]);
 		g_lingo->codeInt((yyvsp[-3].e)[1]);
 		(yyval.code) = (yyvsp[0].code); }
-#line 2405 "engines/director/lingo/lingo-gr.cpp"
+#line 2406 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 17:
-#line 257 "engines/director/lingo/lingo-gr.y"
+#line 258 "engines/director/lingo/lingo-gr.y"
                                                         {
 		g_lingo->code1(LC::c_swap);
 		g_lingo->code1(LC::c_theentityassign);
 		g_lingo->codeInt((yyvsp[-3].e)[0]);
 		g_lingo->codeInt((yyvsp[-3].e)[1]);
 		(yyval.code) = (yyvsp[0].code); }
-#line 2416 "engines/director/lingo/lingo-gr.cpp"
+#line 2417 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 18:
-#line 264 "engines/director/lingo/lingo-gr.y"
+#line 265 "engines/director/lingo/lingo-gr.y"
                                                                         {
 		if (!(yyvsp[-3].s)->equalsIgnoreCase("menu")) {
 			warning("LEXER: keyword 'menu' expected");
@@ -2428,54 +2429,54 @@ yyreduce:
 		g_lingo->codeInt((yyvsp[-6].e)[0]);
 		g_lingo->codeInt((yyvsp[-6].e)[1]);
 		(yyval.code) = (yyvsp[0].code); }
-#line 2432 "engines/director/lingo/lingo-gr.cpp"
+#line 2433 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 19:
-#line 275 "engines/director/lingo/lingo-gr.y"
+#line 276 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_objectfieldassign);
 		g_lingo->codeString((yyvsp[-2].objectfield).os->c_str());
 		g_lingo->codeInt((yyvsp[-2].objectfield).oe);
 		delete (yyvsp[-2].objectfield).os;
 		(yyval.code) = (yyvsp[0].code); }
-#line 2443 "engines/director/lingo/lingo-gr.cpp"
+#line 2444 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 25:
-#line 292 "engines/director/lingo/lingo-gr.y"
+#line 293 "engines/director/lingo/lingo-gr.y"
                                                                                 {
 		inst start = 0, end = 0;
 		WRITE_UINT32(&start, (yyvsp[-5].code) - (yyvsp[-1].code) + 1);
 		WRITE_UINT32(&end, (yyvsp[-1].code) - (yyvsp[-3].code) + 2);
 		(*g_lingo->_currentAssembly)[(yyvsp[-3].code)] = end;		/* end, if cond fails */
 		(*g_lingo->_currentAssembly)[(yyvsp[-1].code)] = start; }
-#line 2454 "engines/director/lingo/lingo-gr.cpp"
+#line 2455 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 26:
-#line 304 "engines/director/lingo/lingo-gr.y"
+#line 305 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_varpush);
 				  g_lingo->codeString((yyvsp[-2].s)->c_str());
 				  mVar((yyvsp[-2].s), globalCheck()); }
-#line 2462 "engines/director/lingo/lingo-gr.cpp"
+#line 2463 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 27:
-#line 308 "engines/director/lingo/lingo-gr.y"
+#line 309 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_eval);
 				  g_lingo->codeString((yyvsp[-4].s)->c_str()); }
-#line 2469 "engines/director/lingo/lingo-gr.cpp"
+#line 2470 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 28:
-#line 311 "engines/director/lingo/lingo-gr.y"
+#line 312 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_le); }
-#line 2475 "engines/director/lingo/lingo-gr.cpp"
+#line 2476 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 29:
-#line 311 "engines/director/lingo/lingo-gr.y"
+#line 312 "engines/director/lingo/lingo-gr.y"
                                                                                           {
 
 		g_lingo->code1(LC::c_eval);
@@ -2494,32 +2495,32 @@ yyreduce:
 		WRITE_UINT32(&end, pos - (yyvsp[-2].code) + 2);
 		(*g_lingo->_currentAssembly)[pos] = loop;		/* final count value */
 		(*g_lingo->_currentAssembly)[(yyvsp[-2].code)] = end;	}
-#line 2498 "engines/director/lingo/lingo-gr.cpp"
+#line 2499 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 30:
-#line 335 "engines/director/lingo/lingo-gr.y"
+#line 336 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_varpush);
 				  g_lingo->codeString((yyvsp[-2].s)->c_str());
 				  mVar((yyvsp[-2].s), globalCheck()); }
-#line 2506 "engines/director/lingo/lingo-gr.cpp"
+#line 2507 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 31:
-#line 339 "engines/director/lingo/lingo-gr.y"
+#line 340 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_eval);
 				  g_lingo->codeString((yyvsp[-4].s)->c_str()); }
-#line 2513 "engines/director/lingo/lingo-gr.cpp"
+#line 2514 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 32:
-#line 342 "engines/director/lingo/lingo-gr.y"
+#line 343 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_ge); }
-#line 2519 "engines/director/lingo/lingo-gr.cpp"
+#line 2520 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 33:
-#line 343 "engines/director/lingo/lingo-gr.y"
+#line 344 "engines/director/lingo/lingo-gr.y"
                                                     {
 
 		g_lingo->code1(LC::c_eval);
@@ -2538,32 +2539,32 @@ yyreduce:
 		WRITE_UINT32(&end, pos - (yyvsp[-2].code) + 2);
 		(*g_lingo->_currentAssembly)[pos] = loop;		/* final count value */
 		(*g_lingo->_currentAssembly)[(yyvsp[-2].code)] = end;	}
-#line 2542 "engines/director/lingo/lingo-gr.cpp"
+#line 2543 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 34:
-#line 368 "engines/director/lingo/lingo-gr.y"
+#line 369 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_stackpeek);
 				  g_lingo->codeInt(0);
 				  Common::String count("count");
 				  g_lingo->codeFunc(&count, 1);
 				  g_lingo->code1(LC::c_intpush);	// start counter
 				  g_lingo->codeInt(1); }
-#line 2553 "engines/director/lingo/lingo-gr.cpp"
+#line 2554 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 35:
-#line 375 "engines/director/lingo/lingo-gr.y"
+#line 376 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_stackpeek);	// get counter
 				  g_lingo->codeInt(0);
 				  g_lingo->code1(LC::c_stackpeek);	// get array size
 				  g_lingo->codeInt(2);
 				  g_lingo->code1(LC::c_le); }
-#line 2563 "engines/director/lingo/lingo-gr.cpp"
+#line 2564 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 36:
-#line 381 "engines/director/lingo/lingo-gr.y"
+#line 382 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_stackpeek);	// get list
 				  g_lingo->codeInt(2);
 				  g_lingo->code1(LC::c_stackpeek);	// get counter
@@ -2574,11 +2575,11 @@ yyreduce:
 				  g_lingo->codeString((yyvsp[-6].s)->c_str());
 				  mVar((yyvsp[-6].s), globalCheck());
 				  g_lingo->code1(LC::c_assign); }
-#line 2578 "engines/director/lingo/lingo-gr.cpp"
+#line 2579 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 37:
-#line 391 "engines/director/lingo/lingo-gr.y"
+#line 392 "engines/director/lingo/lingo-gr.y"
                                             {
 
 		g_lingo->code1(LC::c_intpush);
@@ -2596,44 +2597,44 @@ yyreduce:
 
 		(*g_lingo->_currentAssembly)[jump + 1] = loop;		/* final count value */
 		(*g_lingo->_currentAssembly)[(yyvsp[-3].code)] = end;	}
-#line 2600 "engines/director/lingo/lingo-gr.cpp"
+#line 2601 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 38:
-#line 409 "engines/director/lingo/lingo-gr.y"
+#line 410 "engines/director/lingo/lingo-gr.y"
                         {
 		g_lingo->code1(LC::c_nextRepeat); }
-#line 2607 "engines/director/lingo/lingo-gr.cpp"
+#line 2608 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 39:
-#line 411 "engines/director/lingo/lingo-gr.y"
+#line 412 "engines/director/lingo/lingo-gr.y"
                               {
 		g_lingo->code1(LC::c_whencode);
 		g_lingo->codeString((yyvsp[-2].s)->c_str()); }
-#line 2615 "engines/director/lingo/lingo-gr.cpp"
+#line 2616 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 40:
-#line 414 "engines/director/lingo/lingo-gr.y"
+#line 415 "engines/director/lingo/lingo-gr.y"
                                                           { g_lingo->code1(LC::c_telldone); }
-#line 2621 "engines/director/lingo/lingo-gr.cpp"
+#line 2622 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 41:
-#line 415 "engines/director/lingo/lingo-gr.y"
+#line 416 "engines/director/lingo/lingo-gr.y"
                                                     { g_lingo->code1(LC::c_telldone); }
-#line 2627 "engines/director/lingo/lingo-gr.cpp"
+#line 2628 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 42:
-#line 417 "engines/director/lingo/lingo-gr.y"
+#line 418 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->code1(LC::c_tell); }
-#line 2633 "engines/director/lingo/lingo-gr.cpp"
+#line 2634 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 43:
-#line 419 "engines/director/lingo/lingo-gr.y"
+#line 420 "engines/director/lingo/lingo-gr.y"
                                                                                          {
 		inst else1 = 0, end3 = 0;
 		WRITE_UINT32(&else1, (yyvsp[-3].code) + 1 - (yyvsp[-6].code) + 1);
@@ -2641,11 +2642,11 @@ yyreduce:
 		(*g_lingo->_currentAssembly)[(yyvsp[-6].code)] = else1;		/* elsepart */
 		(*g_lingo->_currentAssembly)[(yyvsp[-3].code)] = end3;		/* end, if cond fails */
 		g_lingo->processIf((yyvsp[-3].code), (yyvsp[-1].code)); }
-#line 2645 "engines/director/lingo/lingo-gr.cpp"
+#line 2646 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 44:
-#line 426 "engines/director/lingo/lingo-gr.y"
+#line 427 "engines/director/lingo/lingo-gr.y"
                                                                                                           {
 		inst else1 = 0, end = 0;
 		WRITE_UINT32(&else1, (yyvsp[-5].code) + 1 - (yyvsp[-8].code) + 1);
@@ -2653,107 +2654,107 @@ yyreduce:
 		(*g_lingo->_currentAssembly)[(yyvsp[-8].code)] = else1;		/* elsepart */
 		(*g_lingo->_currentAssembly)[(yyvsp[-5].code)] = end;		/* end, if cond fails */
 		g_lingo->processIf((yyvsp[-5].code), (yyvsp[-1].code)); }
-#line 2657 "engines/director/lingo/lingo-gr.cpp"
+#line 2658 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 47:
-#line 437 "engines/director/lingo/lingo-gr.y"
+#line 438 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		inst else1 = 0;
 		WRITE_UINT32(&else1, (yyvsp[0].code) + 1 - (yyvsp[-3].code) + 1);
 		(*g_lingo->_currentAssembly)[(yyvsp[-3].code)] = else1;	/* end, if cond fails */
 		g_lingo->codeLabel((yyvsp[0].code)); }
-#line 2667 "engines/director/lingo/lingo-gr.cpp"
+#line 2668 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 48:
-#line 443 "engines/director/lingo/lingo-gr.y"
+#line 444 "engines/director/lingo/lingo-gr.y"
                                 {
 		g_lingo->code2(LC::c_jumpifz, 0);
 		(yyval.code) = g_lingo->_currentAssembly->size() - 1; }
-#line 2675 "engines/director/lingo/lingo-gr.cpp"
+#line 2676 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 49:
-#line 447 "engines/director/lingo/lingo-gr.y"
+#line 448 "engines/director/lingo/lingo-gr.y"
                                 {
 		g_lingo->code2(LC::c_jump, 0);
 		(yyval.code) = g_lingo->_currentAssembly->size() - 1; }
-#line 2683 "engines/director/lingo/lingo-gr.cpp"
+#line 2684 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 50:
-#line 451 "engines/director/lingo/lingo-gr.y"
+#line 452 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_assign);
 		(yyval.code) = g_lingo->_currentAssembly->size() - 1; }
-#line 2691 "engines/director/lingo/lingo-gr.cpp"
+#line 2692 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 51:
-#line 455 "engines/director/lingo/lingo-gr.y"
+#line 456 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->codeLabel(0); }
-#line 2698 "engines/director/lingo/lingo-gr.cpp"
+#line 2699 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 52:
-#line 458 "engines/director/lingo/lingo-gr.y"
+#line 459 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.code) = g_lingo->_currentAssembly->size(); }
-#line 2704 "engines/director/lingo/lingo-gr.cpp"
+#line 2705 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 53:
-#line 460 "engines/director/lingo/lingo-gr.y"
+#line 461 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.code) = g_lingo->_currentAssembly->size(); }
-#line 2710 "engines/director/lingo/lingo-gr.cpp"
+#line 2711 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 56:
-#line 464 "engines/director/lingo/lingo-gr.y"
+#line 465 "engines/director/lingo/lingo-gr.y"
                         {
 		(yyval.code) = g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt((yyvsp[0].i)); }
-#line 2718 "engines/director/lingo/lingo-gr.cpp"
+#line 2719 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 57:
-#line 467 "engines/director/lingo/lingo-gr.y"
+#line 468 "engines/director/lingo/lingo-gr.y"
                         {
 		(yyval.code) = g_lingo->code1(LC::c_floatpush);
 		g_lingo->codeFloat((yyvsp[0].f)); }
-#line 2726 "engines/director/lingo/lingo-gr.cpp"
+#line 2727 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 58:
-#line 470 "engines/director/lingo/lingo-gr.y"
+#line 471 "engines/director/lingo/lingo-gr.y"
                         {											// D3
 		(yyval.code) = g_lingo->code1(LC::c_symbolpush);
 		g_lingo->codeString((yyvsp[0].s)->c_str());
 		delete (yyvsp[0].s); }
-#line 2735 "engines/director/lingo/lingo-gr.cpp"
+#line 2736 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 59:
-#line 474 "engines/director/lingo/lingo-gr.y"
+#line 475 "engines/director/lingo/lingo-gr.y"
                                 {
 		(yyval.code) = g_lingo->code1(LC::c_stringpush);
 		g_lingo->codeString((yyvsp[0].s)->c_str());
 		delete (yyvsp[0].s); }
-#line 2744 "engines/director/lingo/lingo-gr.cpp"
+#line 2745 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 60:
-#line 478 "engines/director/lingo/lingo-gr.y"
+#line 479 "engines/director/lingo/lingo-gr.y"
                         {
 		(yyval.code) = g_lingo->code1(LC::c_eval);
 		g_lingo->codeString((yyvsp[0].s)->c_str());
 		delete (yyvsp[0].s); }
-#line 2753 "engines/director/lingo/lingo-gr.cpp"
+#line 2754 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 61:
-#line 482 "engines/director/lingo/lingo-gr.y"
+#line 483 "engines/director/lingo/lingo-gr.y"
                         {
 		(yyval.code) = g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(0); // Put dummy id
@@ -2762,28 +2763,28 @@ yyreduce:
 		WRITE_UINT32(&e, (yyvsp[0].e)[0]);
 		WRITE_UINT32(&f, (yyvsp[0].e)[1]);
 		g_lingo->code2(e, f); }
-#line 2766 "engines/director/lingo/lingo-gr.cpp"
+#line 2767 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 62:
-#line 490 "engines/director/lingo/lingo-gr.y"
+#line 491 "engines/director/lingo/lingo-gr.y"
                                      {
 		(yyval.code) = g_lingo->code1(LC::c_theentitypush);
 		inst e = 0, f = 0;
 		WRITE_UINT32(&e, (yyvsp[-1].e)[0]);
 		WRITE_UINT32(&f, (yyvsp[-1].e)[1]);
 		g_lingo->code2(e, f); }
-#line 2777 "engines/director/lingo/lingo-gr.cpp"
+#line 2778 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 63:
-#line 496 "engines/director/lingo/lingo-gr.y"
+#line 497 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.code) = (yyvsp[-1].code); }
-#line 2783 "engines/director/lingo/lingo-gr.cpp"
+#line 2784 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 65:
-#line 498 "engines/director/lingo/lingo-gr.y"
+#line 499 "engines/director/lingo/lingo-gr.y"
                                 {
 		// Director parser till D3 was forgiving for any hanging parentheses
 		if (g_lingo->_ignoreError) {
@@ -2794,549 +2795,549 @@ yyreduce:
 			yyerrok;
 		}
 	}
-#line 2798 "engines/director/lingo/lingo-gr.cpp"
+#line 2799 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 66:
-#line 509 "engines/director/lingo/lingo-gr.y"
+#line 510 "engines/director/lingo/lingo-gr.y"
                  { (yyval.code) = (yyvsp[0].code); }
-#line 2804 "engines/director/lingo/lingo-gr.cpp"
+#line 2805 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 68:
-#line 511 "engines/director/lingo/lingo-gr.y"
+#line 512 "engines/director/lingo/lingo-gr.y"
                                  {
 		g_lingo->codeFunc((yyvsp[-3].s), (yyvsp[-1].narg));
 		delete (yyvsp[-3].s); }
-#line 2812 "engines/director/lingo/lingo-gr.cpp"
+#line 2813 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 69:
-#line 514 "engines/director/lingo/lingo-gr.y"
+#line 515 "engines/director/lingo/lingo-gr.y"
                                 {
 		g_lingo->codeFunc((yyvsp[-1].s), (yyvsp[0].narg));
 		delete (yyvsp[-1].s); }
-#line 2820 "engines/director/lingo/lingo-gr.cpp"
+#line 2821 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 70:
-#line 517 "engines/director/lingo/lingo-gr.y"
+#line 518 "engines/director/lingo/lingo-gr.y"
                                       {
 			g_lingo->code1(LC::c_lazyeval);
 			g_lingo->codeString((yyvsp[-1].s)->c_str());
 			g_lingo->codeFunc((yyvsp[-3].s), 1);
 			delete (yyvsp[-3].s);
 			delete (yyvsp[-1].s); }
-#line 2831 "engines/director/lingo/lingo-gr.cpp"
+#line 2832 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 71:
-#line 523 "engines/director/lingo/lingo-gr.y"
+#line 524 "engines/director/lingo/lingo-gr.y"
                                       { g_lingo->code1(LC::c_lazyeval); g_lingo->codeString((yyvsp[-1].s)->c_str()); }
-#line 2837 "engines/director/lingo/lingo-gr.cpp"
+#line 2838 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 72:
-#line 524 "engines/director/lingo/lingo-gr.y"
+#line 525 "engines/director/lingo/lingo-gr.y"
                                                     {
 			g_lingo->codeFunc((yyvsp[-6].s), (yyvsp[-1].narg) + 1);
 			delete (yyvsp[-6].s);
 			delete (yyvsp[-4].s); }
-#line 2846 "engines/director/lingo/lingo-gr.cpp"
+#line 2847 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 73:
-#line 528 "engines/director/lingo/lingo-gr.y"
+#line 529 "engines/director/lingo/lingo-gr.y"
                                 {
 		(yyval.code) = g_lingo->codeFunc((yyvsp[-3].s), (yyvsp[-1].narg));
 		delete (yyvsp[-3].s); }
-#line 2854 "engines/director/lingo/lingo-gr.cpp"
+#line 2855 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 74:
-#line 531 "engines/director/lingo/lingo-gr.y"
+#line 532 "engines/director/lingo/lingo-gr.y"
                                         {
 		(yyval.code) = g_lingo->codeFunc((yyvsp[-2].s), 1);
 		delete (yyvsp[-2].s); }
-#line 2862 "engines/director/lingo/lingo-gr.cpp"
+#line 2863 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 75:
-#line 534 "engines/director/lingo/lingo-gr.y"
+#line 535 "engines/director/lingo/lingo-gr.y"
                          {
 		g_lingo->code1(LC::c_objectfieldpush);
 		g_lingo->codeString((yyvsp[0].objectfield).os->c_str());
 		g_lingo->codeInt((yyvsp[0].objectfield).oe);
 		delete (yyvsp[0].objectfield).os; }
-#line 2872 "engines/director/lingo/lingo-gr.cpp"
+#line 2873 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 76:
-#line 539 "engines/director/lingo/lingo-gr.y"
+#line 540 "engines/director/lingo/lingo-gr.y"
                        {
 		g_lingo->code1(LC::c_objectrefpush);
 		g_lingo->codeString((yyvsp[0].objectref).obj->c_str());
 		g_lingo->codeString((yyvsp[0].objectref).field->c_str());
 		delete (yyvsp[0].objectref).obj;
 		delete (yyvsp[0].objectref).field; }
-#line 2883 "engines/director/lingo/lingo-gr.cpp"
+#line 2884 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 78:
-#line 546 "engines/director/lingo/lingo-gr.y"
+#line 547 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_add); }
-#line 2889 "engines/director/lingo/lingo-gr.cpp"
+#line 2890 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 79:
-#line 547 "engines/director/lingo/lingo-gr.y"
+#line 548 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_sub); }
-#line 2895 "engines/director/lingo/lingo-gr.cpp"
+#line 2896 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 80:
-#line 548 "engines/director/lingo/lingo-gr.y"
+#line 549 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_mul); }
-#line 2901 "engines/director/lingo/lingo-gr.cpp"
+#line 2902 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 81:
-#line 549 "engines/director/lingo/lingo-gr.y"
+#line 550 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_div); }
-#line 2907 "engines/director/lingo/lingo-gr.cpp"
+#line 2908 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 82:
-#line 550 "engines/director/lingo/lingo-gr.y"
+#line 551 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_mod); }
-#line 2913 "engines/director/lingo/lingo-gr.cpp"
+#line 2914 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 83:
-#line 551 "engines/director/lingo/lingo-gr.y"
+#line 552 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_gt); }
-#line 2919 "engines/director/lingo/lingo-gr.cpp"
+#line 2920 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 84:
-#line 552 "engines/director/lingo/lingo-gr.y"
+#line 553 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_lt); }
-#line 2925 "engines/director/lingo/lingo-gr.cpp"
+#line 2926 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 85:
-#line 553 "engines/director/lingo/lingo-gr.y"
+#line 554 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_eq); }
-#line 2931 "engines/director/lingo/lingo-gr.cpp"
+#line 2932 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 86:
-#line 554 "engines/director/lingo/lingo-gr.y"
+#line 555 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_neq); }
-#line 2937 "engines/director/lingo/lingo-gr.cpp"
+#line 2938 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 87:
-#line 555 "engines/director/lingo/lingo-gr.y"
+#line 556 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_ge); }
-#line 2943 "engines/director/lingo/lingo-gr.cpp"
+#line 2944 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 88:
-#line 556 "engines/director/lingo/lingo-gr.y"
+#line 557 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_le); }
-#line 2949 "engines/director/lingo/lingo-gr.cpp"
+#line 2950 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 89:
-#line 557 "engines/director/lingo/lingo-gr.y"
+#line 558 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_and); }
-#line 2955 "engines/director/lingo/lingo-gr.cpp"
+#line 2956 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 90:
-#line 558 "engines/director/lingo/lingo-gr.y"
+#line 559 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_or); }
-#line 2961 "engines/director/lingo/lingo-gr.cpp"
+#line 2962 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 91:
-#line 559 "engines/director/lingo/lingo-gr.y"
+#line 560 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_not); }
-#line 2967 "engines/director/lingo/lingo-gr.cpp"
+#line 2968 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 92:
-#line 560 "engines/director/lingo/lingo-gr.y"
+#line 561 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_ampersand); }
-#line 2973 "engines/director/lingo/lingo-gr.cpp"
+#line 2974 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 93:
-#line 561 "engines/director/lingo/lingo-gr.y"
+#line 562 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_concat); }
-#line 2979 "engines/director/lingo/lingo-gr.cpp"
+#line 2980 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 94:
-#line 562 "engines/director/lingo/lingo-gr.y"
+#line 563 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_contains); }
-#line 2985 "engines/director/lingo/lingo-gr.cpp"
+#line 2986 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 95:
-#line 563 "engines/director/lingo/lingo-gr.y"
+#line 564 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_starts); }
-#line 2991 "engines/director/lingo/lingo-gr.cpp"
+#line 2992 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 96:
-#line 564 "engines/director/lingo/lingo-gr.y"
+#line 565 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.code) = (yyvsp[0].code); }
-#line 2997 "engines/director/lingo/lingo-gr.cpp"
+#line 2998 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 97:
-#line 565 "engines/director/lingo/lingo-gr.y"
+#line 566 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.code) = (yyvsp[0].code); g_lingo->code1(LC::c_negate); }
-#line 3003 "engines/director/lingo/lingo-gr.cpp"
+#line 3004 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 98:
-#line 566 "engines/director/lingo/lingo-gr.y"
+#line 567 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_intersects); }
-#line 3009 "engines/director/lingo/lingo-gr.cpp"
+#line 3010 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 99:
-#line 567 "engines/director/lingo/lingo-gr.y"
+#line 568 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_within); }
-#line 3015 "engines/director/lingo/lingo-gr.cpp"
+#line 3016 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 100:
-#line 569 "engines/director/lingo/lingo-gr.y"
+#line 570 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_charOf); }
-#line 3021 "engines/director/lingo/lingo-gr.cpp"
+#line 3022 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 101:
-#line 570 "engines/director/lingo/lingo-gr.y"
+#line 571 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_charToOf); }
-#line 3027 "engines/director/lingo/lingo-gr.cpp"
+#line 3028 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 102:
-#line 571 "engines/director/lingo/lingo-gr.y"
+#line 572 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_itemOf); }
-#line 3033 "engines/director/lingo/lingo-gr.cpp"
+#line 3034 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 103:
-#line 572 "engines/director/lingo/lingo-gr.y"
+#line 573 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_itemToOf); }
-#line 3039 "engines/director/lingo/lingo-gr.cpp"
+#line 3040 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 104:
-#line 573 "engines/director/lingo/lingo-gr.y"
+#line 574 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_lineOf); }
-#line 3045 "engines/director/lingo/lingo-gr.cpp"
+#line 3046 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 105:
-#line 574 "engines/director/lingo/lingo-gr.y"
+#line 575 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_lineToOf); }
-#line 3051 "engines/director/lingo/lingo-gr.cpp"
+#line 3052 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 106:
-#line 575 "engines/director/lingo/lingo-gr.y"
+#line 576 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_wordOf); }
-#line 3057 "engines/director/lingo/lingo-gr.cpp"
+#line 3058 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 107:
-#line 576 "engines/director/lingo/lingo-gr.y"
+#line 577 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_wordToOf); }
-#line 3063 "engines/director/lingo/lingo-gr.cpp"
+#line 3064 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 108:
-#line 578 "engines/director/lingo/lingo-gr.y"
+#line 579 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->codeFunc((yyvsp[-1].s), 1);
 		delete (yyvsp[-1].s); }
-#line 3071 "engines/director/lingo/lingo-gr.cpp"
+#line 3072 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 110:
-#line 583 "engines/director/lingo/lingo-gr.y"
+#line 584 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_printtop); }
-#line 3077 "engines/director/lingo/lingo-gr.cpp"
+#line 3078 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 113:
-#line 586 "engines/director/lingo/lingo-gr.y"
+#line 587 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_exitRepeat); }
-#line 3083 "engines/director/lingo/lingo-gr.cpp"
+#line 3084 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 114:
-#line 587 "engines/director/lingo/lingo-gr.y"
+#line 588 "engines/director/lingo/lingo-gr.y"
                                                         { g_lingo->code1(LC::c_procret); }
-#line 3089 "engines/director/lingo/lingo-gr.cpp"
+#line 3090 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 115:
-#line 588 "engines/director/lingo/lingo-gr.y"
+#line 589 "engines/director/lingo/lingo-gr.y"
                                                         { inArgs(); }
-#line 3095 "engines/director/lingo/lingo-gr.cpp"
+#line 3096 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 116:
-#line 588 "engines/director/lingo/lingo-gr.y"
-                                                                                 { inNone(); }
-#line 3101 "engines/director/lingo/lingo-gr.cpp"
+#line 589 "engines/director/lingo/lingo-gr.y"
+                                                                                 { inLast(); }
+#line 3102 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 117:
-#line 589 "engines/director/lingo/lingo-gr.y"
+#line 590 "engines/director/lingo/lingo-gr.y"
                                                         { inArgs(); }
-#line 3107 "engines/director/lingo/lingo-gr.cpp"
+#line 3108 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 118:
-#line 589 "engines/director/lingo/lingo-gr.y"
-                                                                                   { inNone(); }
-#line 3113 "engines/director/lingo/lingo-gr.cpp"
+#line 590 "engines/director/lingo/lingo-gr.y"
+                                                                                   { inLast(); }
+#line 3114 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 119:
-#line 590 "engines/director/lingo/lingo-gr.y"
+#line 591 "engines/director/lingo/lingo-gr.y"
                                                         { inArgs(); }
-#line 3119 "engines/director/lingo/lingo-gr.cpp"
+#line 3120 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 120:
-#line 590 "engines/director/lingo/lingo-gr.y"
-                                                                                   { inNone(); }
-#line 3125 "engines/director/lingo/lingo-gr.cpp"
+#line 591 "engines/director/lingo/lingo-gr.y"
+                                                                                   { inLast(); }
+#line 3126 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 121:
-#line 591 "engines/director/lingo/lingo-gr.y"
+#line 592 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->codeFunc((yyvsp[-3].s), (yyvsp[-1].narg));
 		delete (yyvsp[-3].s); }
-#line 3133 "engines/director/lingo/lingo-gr.cpp"
+#line 3134 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 122:
-#line 594 "engines/director/lingo/lingo-gr.y"
+#line 595 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->codeFunc((yyvsp[-1].s), (yyvsp[0].narg));
 		delete (yyvsp[-1].s); }
-#line 3141 "engines/director/lingo/lingo-gr.cpp"
+#line 3142 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 123:
-#line 597 "engines/director/lingo/lingo-gr.y"
+#line 598 "engines/director/lingo/lingo-gr.y"
                                         { g_lingo->code1(LC::c_open); }
-#line 3147 "engines/director/lingo/lingo-gr.cpp"
+#line 3148 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 124:
-#line 598 "engines/director/lingo/lingo-gr.y"
+#line 599 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code2(LC::c_voidpush, LC::c_open); }
-#line 3153 "engines/director/lingo/lingo-gr.cpp"
+#line 3154 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 125:
-#line 600 "engines/director/lingo/lingo-gr.y"
+#line 601 "engines/director/lingo/lingo-gr.y"
                                                 {
 		mVar((yyvsp[0].s), kVarGlobal);
 		delete (yyvsp[0].s); }
-#line 3161 "engines/director/lingo/lingo-gr.cpp"
+#line 3162 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 126:
-#line 603 "engines/director/lingo/lingo-gr.y"
+#line 604 "engines/director/lingo/lingo-gr.y"
                                                 {
 		mVar((yyvsp[0].s), kVarGlobal);
 		delete (yyvsp[0].s); }
-#line 3169 "engines/director/lingo/lingo-gr.cpp"
+#line 3170 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 127:
-#line 607 "engines/director/lingo/lingo-gr.y"
+#line 608 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->code1(LC::c_property);
 		g_lingo->codeString((yyvsp[0].s)->c_str());
 		mVar((yyvsp[0].s), kVarProperty);
 		delete (yyvsp[0].s); }
-#line 3179 "engines/director/lingo/lingo-gr.cpp"
+#line 3180 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 128:
-#line 612 "engines/director/lingo/lingo-gr.y"
+#line 613 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_property);
 		g_lingo->codeString((yyvsp[0].s)->c_str());
 		mVar((yyvsp[0].s), kVarProperty);
 		delete (yyvsp[0].s); }
-#line 3189 "engines/director/lingo/lingo-gr.cpp"
+#line 3190 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 129:
-#line 618 "engines/director/lingo/lingo-gr.y"
+#line 619 "engines/director/lingo/lingo-gr.y"
                                                 {
 		mVar((yyvsp[0].s), kVarInstance);
 		delete (yyvsp[0].s); }
-#line 3197 "engines/director/lingo/lingo-gr.cpp"
+#line 3198 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 130:
-#line 621 "engines/director/lingo/lingo-gr.y"
+#line 622 "engines/director/lingo/lingo-gr.y"
                                         {
 		mVar((yyvsp[0].s), kVarInstance);
 		delete (yyvsp[0].s); }
-#line 3205 "engines/director/lingo/lingo-gr.cpp"
+#line 3206 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 131:
-#line 632 "engines/director/lingo/lingo-gr.y"
+#line 633 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_gotoloop); }
-#line 3211 "engines/director/lingo/lingo-gr.cpp"
+#line 3212 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 132:
-#line 633 "engines/director/lingo/lingo-gr.y"
+#line 634 "engines/director/lingo/lingo-gr.y"
                                                         { g_lingo->code1(LC::c_gotonext); }
-#line 3217 "engines/director/lingo/lingo-gr.cpp"
+#line 3218 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 133:
-#line 634 "engines/director/lingo/lingo-gr.y"
+#line 635 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->code1(LC::c_gotoprevious); }
-#line 3223 "engines/director/lingo/lingo-gr.cpp"
+#line 3224 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 134:
-#line 635 "engines/director/lingo/lingo-gr.y"
+#line 636 "engines/director/lingo/lingo-gr.y"
                                                         {
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(1);
 		g_lingo->code1(LC::c_goto); }
-#line 3232 "engines/director/lingo/lingo-gr.cpp"
+#line 3233 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 135:
-#line 639 "engines/director/lingo/lingo-gr.y"
+#line 640 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(3);
 		g_lingo->code1(LC::c_goto); }
-#line 3241 "engines/director/lingo/lingo-gr.cpp"
+#line 3242 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 136:
-#line 643 "engines/director/lingo/lingo-gr.y"
+#line 644 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(2);
 		g_lingo->code1(LC::c_goto); }
-#line 3250 "engines/director/lingo/lingo-gr.cpp"
+#line 3251 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 139:
-#line 651 "engines/director/lingo/lingo-gr.y"
+#line 652 "engines/director/lingo/lingo-gr.y"
                                         { // "play #done" is also caught by this
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(1);
 		g_lingo->code1(LC::c_play); }
-#line 3259 "engines/director/lingo/lingo-gr.cpp"
+#line 3260 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 140:
-#line 655 "engines/director/lingo/lingo-gr.y"
+#line 656 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(3);
 		g_lingo->code1(LC::c_play); }
-#line 3268 "engines/director/lingo/lingo-gr.cpp"
+#line 3269 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 141:
-#line 659 "engines/director/lingo/lingo-gr.y"
+#line 660 "engines/director/lingo/lingo-gr.y"
                                                 {
 		g_lingo->code1(LC::c_intpush);
 		g_lingo->codeInt(2);
 		g_lingo->code1(LC::c_play); }
-#line 3277 "engines/director/lingo/lingo-gr.cpp"
+#line 3278 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 142:
-#line 663 "engines/director/lingo/lingo-gr.y"
+#line 664 "engines/director/lingo/lingo-gr.y"
                      { g_lingo->codeSetImmediate(true); }
-#line 3283 "engines/director/lingo/lingo-gr.cpp"
+#line 3284 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 143:
-#line 663 "engines/director/lingo/lingo-gr.y"
+#line 664 "engines/director/lingo/lingo-gr.y"
                                                                   {
 		g_lingo->codeSetImmediate(false);
 		g_lingo->codeFunc((yyvsp[-2].s), (yyvsp[0].narg));
 		delete (yyvsp[-2].s); }
-#line 3292 "engines/director/lingo/lingo-gr.cpp"
+#line 3293 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 144:
-#line 693 "engines/director/lingo/lingo-gr.y"
+#line 694 "engines/director/lingo/lingo-gr.y"
              { startDef(); }
-#line 3298 "engines/director/lingo/lingo-gr.cpp"
+#line 3299 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 145:
-#line 693 "engines/director/lingo/lingo-gr.y"
+#line 694 "engines/director/lingo/lingo-gr.y"
                                 { g_lingo->_currentFactory = NULL; }
-#line 3304 "engines/director/lingo/lingo-gr.cpp"
+#line 3305 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 146:
-#line 694 "engines/director/lingo/lingo-gr.y"
+#line 695 "engines/director/lingo/lingo-gr.y"
                                                                         {
 		g_lingo->code1(LC::c_procret);
 		g_lingo->codeDefine(*(yyvsp[-6].s), (yyvsp[-4].code), (yyvsp[-3].narg));
 		endDef();
 		delete (yyvsp[-6].s); }
-#line 3314 "engines/director/lingo/lingo-gr.cpp"
+#line 3315 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 147:
-#line 699 "engines/director/lingo/lingo-gr.y"
+#line 700 "engines/director/lingo/lingo-gr.y"
                         { g_lingo->codeFactory(*(yyvsp[0].s)); delete (yyvsp[0].s); }
-#line 3320 "engines/director/lingo/lingo-gr.cpp"
+#line 3321 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 148:
-#line 700 "engines/director/lingo/lingo-gr.y"
+#line 701 "engines/director/lingo/lingo-gr.y"
                   { startDef(); }
-#line 3326 "engines/director/lingo/lingo-gr.cpp"
+#line 3327 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 149:
-#line 701 "engines/director/lingo/lingo-gr.y"
+#line 702 "engines/director/lingo/lingo-gr.y"
                                                                         {
 		g_lingo->code1(LC::c_procret);
 		g_lingo->codeDefine(*(yyvsp[-6].s), (yyvsp[-4].code), (yyvsp[-3].narg), g_lingo->_currentFactory);
 		endDef();
 		delete (yyvsp[-6].s); }
-#line 3336 "engines/director/lingo/lingo-gr.cpp"
+#line 3337 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 150:
-#line 706 "engines/director/lingo/lingo-gr.y"
+#line 707 "engines/director/lingo/lingo-gr.y"
                                                                    {	// D3
 		g_lingo->code1(LC::c_procret);
 		g_lingo->codeDefine(*(yyvsp[-7].s), (yyvsp[-6].code), (yyvsp[-5].narg));
@@ -3345,70 +3346,70 @@ yyreduce:
 		checkEnd((yyvsp[-1].s), (yyvsp[-7].s)->c_str(), false);
 		delete (yyvsp[-7].s);
 		delete (yyvsp[-1].s); }
-#line 3349 "engines/director/lingo/lingo-gr.cpp"
+#line 3350 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 151:
-#line 714 "engines/director/lingo/lingo-gr.y"
+#line 715 "engines/director/lingo/lingo-gr.y"
                                                {	// D4. No 'end' clause
 		g_lingo->code1(LC::c_procret);
 		g_lingo->codeDefine(*(yyvsp[-5].s), (yyvsp[-4].code), (yyvsp[-3].narg));
 		endDef();
 		delete (yyvsp[-5].s); }
-#line 3359 "engines/director/lingo/lingo-gr.cpp"
+#line 3360 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 152:
-#line 720 "engines/director/lingo/lingo-gr.y"
+#line 721 "engines/director/lingo/lingo-gr.y"
          { startDef(); }
-#line 3365 "engines/director/lingo/lingo-gr.cpp"
+#line 3366 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 153:
-#line 720 "engines/director/lingo/lingo-gr.y"
+#line 721 "engines/director/lingo/lingo-gr.y"
                                 {
 		(yyval.s) = (yyvsp[0].s); g_lingo->_currentFactory = NULL; }
-#line 3372 "engines/director/lingo/lingo-gr.cpp"
+#line 3373 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 154:
-#line 723 "engines/director/lingo/lingo-gr.y"
+#line 724 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.narg) = 0; }
-#line 3378 "engines/director/lingo/lingo-gr.cpp"
+#line 3379 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 155:
-#line 724 "engines/director/lingo/lingo-gr.y"
+#line 725 "engines/director/lingo/lingo-gr.y"
                                                         { g_lingo->codeArg((yyvsp[0].s)); mVar((yyvsp[0].s), kVarArgument); (yyval.narg) = 1; delete (yyvsp[0].s); }
-#line 3384 "engines/director/lingo/lingo-gr.cpp"
+#line 3385 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 156:
-#line 725 "engines/director/lingo/lingo-gr.y"
+#line 726 "engines/director/lingo/lingo-gr.y"
                                                 { g_lingo->codeArg((yyvsp[0].s)); mVar((yyvsp[0].s), kVarArgument); (yyval.narg) = (yyvsp[-2].narg) + 1; delete (yyvsp[0].s); }
-#line 3390 "engines/director/lingo/lingo-gr.cpp"
+#line 3391 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 158:
-#line 728 "engines/director/lingo/lingo-gr.y"
+#line 729 "engines/director/lingo/lingo-gr.y"
                                                         { delete (yyvsp[0].s); }
-#line 3396 "engines/director/lingo/lingo-gr.cpp"
+#line 3397 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 159:
-#line 729 "engines/director/lingo/lingo-gr.y"
+#line 730 "engines/director/lingo/lingo-gr.y"
                                                 { delete (yyvsp[0].s); }
-#line 3402 "engines/director/lingo/lingo-gr.cpp"
+#line 3403 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 160:
-#line 731 "engines/director/lingo/lingo-gr.y"
+#line 732 "engines/director/lingo/lingo-gr.y"
                                         { inDef(); }
-#line 3408 "engines/director/lingo/lingo-gr.cpp"
+#line 3409 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 161:
-#line 733 "engines/director/lingo/lingo-gr.y"
+#line 734 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_call);
 		g_lingo->codeString((yyvsp[-1].s)->c_str());
@@ -3416,113 +3417,113 @@ yyreduce:
 		WRITE_UINT32(&numpar, (yyvsp[0].narg));
 		g_lingo->code1(numpar);
 		delete (yyvsp[-1].s); }
-#line 3420 "engines/director/lingo/lingo-gr.cpp"
+#line 3421 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 162:
-#line 741 "engines/director/lingo/lingo-gr.y"
+#line 742 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.narg) = 0; }
-#line 3426 "engines/director/lingo/lingo-gr.cpp"
+#line 3427 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 163:
-#line 742 "engines/director/lingo/lingo-gr.y"
+#line 743 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.narg) = 1; }
-#line 3432 "engines/director/lingo/lingo-gr.cpp"
+#line 3433 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 164:
-#line 743 "engines/director/lingo/lingo-gr.y"
+#line 744 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.narg) = (yyvsp[-2].narg) + 1; }
-#line 3438 "engines/director/lingo/lingo-gr.cpp"
+#line 3439 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 165:
-#line 745 "engines/director/lingo/lingo-gr.y"
+#line 746 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.narg) = 1; }
-#line 3444 "engines/director/lingo/lingo-gr.cpp"
+#line 3445 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 166:
-#line 746 "engines/director/lingo/lingo-gr.y"
+#line 747 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.narg) = (yyvsp[-2].narg) + 1; }
-#line 3450 "engines/director/lingo/lingo-gr.cpp"
+#line 3451 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 167:
-#line 748 "engines/director/lingo/lingo-gr.y"
+#line 749 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.code) = (yyvsp[-1].code); }
-#line 3456 "engines/director/lingo/lingo-gr.cpp"
+#line 3457 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 168:
-#line 750 "engines/director/lingo/lingo-gr.y"
+#line 751 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.code) = g_lingo->code2(LC::c_arraypush, 0); }
-#line 3462 "engines/director/lingo/lingo-gr.cpp"
+#line 3463 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 169:
-#line 751 "engines/director/lingo/lingo-gr.y"
+#line 752 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.code) = g_lingo->code2(LC::c_proparraypush, 0); }
-#line 3468 "engines/director/lingo/lingo-gr.cpp"
+#line 3469 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 170:
-#line 752 "engines/director/lingo/lingo-gr.y"
+#line 753 "engines/director/lingo/lingo-gr.y"
                      { (yyval.code) = g_lingo->code1(LC::c_arraypush); (yyval.code) = g_lingo->codeInt((yyvsp[0].narg)); }
-#line 3474 "engines/director/lingo/lingo-gr.cpp"
+#line 3475 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 171:
-#line 753 "engines/director/lingo/lingo-gr.y"
+#line 754 "engines/director/lingo/lingo-gr.y"
                          { (yyval.code) = g_lingo->code1(LC::c_proparraypush); (yyval.code) = g_lingo->codeInt((yyvsp[0].narg)); }
-#line 3480 "engines/director/lingo/lingo-gr.cpp"
+#line 3481 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 172:
-#line 755 "engines/director/lingo/lingo-gr.y"
+#line 756 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.narg) = 1; }
-#line 3486 "engines/director/lingo/lingo-gr.cpp"
+#line 3487 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 173:
-#line 756 "engines/director/lingo/lingo-gr.y"
+#line 757 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.narg) = (yyvsp[-2].narg) + 1; }
-#line 3492 "engines/director/lingo/lingo-gr.cpp"
+#line 3493 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 174:
-#line 758 "engines/director/lingo/lingo-gr.y"
+#line 759 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.narg) = 1; }
-#line 3498 "engines/director/lingo/lingo-gr.cpp"
+#line 3499 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 175:
-#line 759 "engines/director/lingo/lingo-gr.y"
+#line 760 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.narg) = (yyvsp[-2].narg) + 1; }
-#line 3504 "engines/director/lingo/lingo-gr.cpp"
+#line 3505 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 176:
-#line 761 "engines/director/lingo/lingo-gr.y"
+#line 762 "engines/director/lingo/lingo-gr.y"
                                 {
 		g_lingo->code1(LC::c_symbolpush);
 		g_lingo->codeString((yyvsp[-2].s)->c_str());
 		delete (yyvsp[-2].s); }
-#line 3513 "engines/director/lingo/lingo-gr.cpp"
+#line 3514 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 177:
-#line 765 "engines/director/lingo/lingo-gr.y"
+#line 766 "engines/director/lingo/lingo-gr.y"
                                         {
 		g_lingo->code1(LC::c_stringpush);
 		g_lingo->codeString((yyvsp[-2].s)->c_str());
 		delete (yyvsp[-2].s); }
-#line 3522 "engines/director/lingo/lingo-gr.cpp"
+#line 3523 "engines/director/lingo/lingo-gr.cpp"
     break;
 
 
-#line 3526 "engines/director/lingo/lingo-gr.cpp"
+#line 3527 "engines/director/lingo/lingo-gr.cpp"
 
       default: break;
     }
@@ -3721,7 +3722,7 @@ yyreturn:
   return yyresult;
 }
 
-#line 771 "engines/director/lingo/lingo-gr.y"
+#line 772 "engines/director/lingo/lingo-gr.y"
 
 
 int yyreport_syntax_error(const yypcontext_t *ctx) {
diff --git a/engines/director/lingo/lingo-gr.h b/engines/director/lingo/lingo-gr.h
index 43e1079c9a..acc9da4c70 100644
--- a/engines/director/lingo/lingo-gr.h
+++ b/engines/director/lingo/lingo-gr.h
@@ -147,7 +147,7 @@ extern int yydebug;
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 union YYSTYPE
 {
-#line 133 "engines/director/lingo/lingo-gr.y"
+#line 134 "engines/director/lingo/lingo-gr.y"
 
 	Common::String *s;
 	int i;
diff --git a/engines/director/lingo/lingo-gr.y b/engines/director/lingo/lingo-gr.y
index 0db3bc4553..fcd6ba2111 100644
--- a/engines/director/lingo/lingo-gr.y
+++ b/engines/director/lingo/lingo-gr.y
@@ -84,9 +84,10 @@ static void checkEnd(Common::String *token, const char *expect, bool required) {
 	}
 }
 
-static void inArgs() { g_lingo->_indef = kStateInArgs; }
-static void inDef()  { g_lingo->_indef = kStateInDef; }
-static void inNone() { g_lingo->_indef = kStateNone; }
+static void inArgs() { g_lingo->_indefStore = g_lingo->_indef; g_lingo->_indef = kStateInArgs; }
+static void inDef()  { g_lingo->_indefStore = g_lingo->_indef; g_lingo->_indef = kStateInDef; }
+static void inNone() { g_lingo->_indefStore = g_lingo->_indef; g_lingo->_indef = kStateNone; }
+static void inLast() { g_lingo->_indef = g_lingo->_indefStore; }
 
 static void startDef() {
 	inArgs();
@@ -585,9 +586,9 @@ proc: tPUT expr					{ g_lingo->code1(LC::c_printtop); }
 	| playfunc
 	| tEXIT tREPEAT				{ g_lingo->code1(LC::c_exitRepeat); }
 	| tEXIT						{ g_lingo->code1(LC::c_procret); }
-	| tGLOBAL					{ inArgs(); } globallist { inNone(); }
-	| tPROPERTY					{ inArgs(); } propertylist { inNone(); }
-	| tINSTANCE					{ inArgs(); } instancelist { inNone(); }
+	| tGLOBAL					{ inArgs(); } globallist { inLast(); }
+	| tPROPERTY					{ inArgs(); } propertylist { inLast(); }
+	| tINSTANCE					{ inArgs(); } instancelist { inLast(); }
 	| BLTIN '(' arglist ')'		{
 		g_lingo->codeFunc($BLTIN, $arglist);
 		delete $BLTIN; }
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 932ed7c9bb..6325b26091 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -161,6 +161,7 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
 	_abort = false;
 	_nextRepeat = false;
 	_indef = kStateNone;
+	_indef = kStateNone;
 	_immediateMode = false;
 
 	_linenumber = _colnumber = _bytenumber = _lastbytenumber = _errorbytenumber = 0;
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 0f1d70fa61..253359087c 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -464,6 +464,7 @@ public:
 
 	ScriptData *_currentAssembly;
 	LexerDefineState _indef;
+	LexerDefineState _indefStore;
 	int _linenumber;
 	int _colnumber;
 	int _bytenumber;




More information about the Scummvm-git-logs mailing list