aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/director/director.cpp7
-rw-r--r--engines/director/lingo/lingo-code.cpp26
-rw-r--r--engines/director/lingo/lingo-codegen.cpp28
-rw-r--r--engines/director/lingo/lingo.cpp2
-rw-r--r--engines/director/lingo/lingo.h5
5 files changed, 36 insertions, 32 deletions
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 9a22e675cb..7463a9e77a 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -105,6 +105,7 @@ _lingo->executeScript(kMovieScript, 2);
_lingo->addCode("--\n\
macro SHIPX\n\
+global x\n\
set x = 5\n\
if x = 1 then\n\
go \"Zoom\"\n\
@@ -117,12 +118,13 @@ put 100\n\
\n\
--\n\
macro ZIPX\n\
-set x = 5\n\
+set x = 7\n\
if x = 1 then\n\
go \"ZIP\"\n\
exit\n\
end if\n\
if x >1 then\n\
+put x\n\
exit\n\
end if\n\
\n\
@@ -136,8 +138,11 @@ end if\n\
", kMovieScript, 1);
_lingo->addCode("check(2, 3)\n\
+global x\n\
shipx\n\
put x\n\
+zipx\n\
+put x\n\
", kMovieScript, 2);
_lingo->executeScript(kMovieScript, 2);
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 9bc6b48b90..1a297e50fd 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -406,10 +406,7 @@ void Lingo::c_call() {
fp->retscript = g_lingo->_currentScript;
fp->localvars = g_lingo->_localvars;
- // Clean up current scope local variables
- for (SymbolHash::const_iterator h = g_lingo->_localvars->begin(); h != g_lingo->_localvars->end(); ++h)
- g_lingo->_vars.erase(h->_key);
-
+ // Create new set of local variables
g_lingo->_localvars = new SymbolHash;
g_lingo->_callstack.push_back(fp);
@@ -426,17 +423,10 @@ void Lingo::c_procret() {
g_lingo->_currentScript = fp->retscript;
g_lingo->_pc = fp->retpc;
- // Clean up current scope local variables and clean up memory
- for (SymbolHash::const_iterator h = g_lingo->_localvars->begin(); h != g_lingo->_localvars->end(); ++h) {
- g_lingo->_vars.erase(h->_key);
- delete h->_value;
- }
- delete g_lingo->_localvars;
+ g_lingo->cleanLocalVars();
// Restore local variables
g_lingo->_localvars = fp->localvars;
- for (SymbolHash::const_iterator h = g_lingo->_localvars->begin(); h != g_lingo->_localvars->end(); ++h)
- g_lingo->_vars[h->_key] = h->_value;
delete fp;
@@ -447,17 +437,11 @@ void Lingo::c_global() {
Common::String name((char *)&(*g_lingo->_currentScript)[g_lingo->_pc]);
Symbol *s = g_lingo->lookupVar(name.c_str(), false);
- if (s) {
- if (s->global) {
- warning("Redefinition of global variable %s", name.c_str());
- } else {
- warning("Local variable %s declared as global", name.c_str());
- }
-
- return;
+ if (s && !s->global) {
+ warning("Local variable %s declared as global", name.c_str());
}
- s = g_lingo->lookupVar(name.c_str(), true, false);
+ s = g_lingo->lookupVar(name.c_str(), true, true);
s->global = true;
g_lingo->_pc += g_lingo->calcStringAlignment(name.c_str());
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index ae6242867a..89d30bec47 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -64,10 +64,10 @@ void Lingo::execute(int pc) {
}
}
-Symbol *Lingo::lookupVar(const char *name, bool create, bool putInLocalList) {
+Symbol *Lingo::lookupVar(const char *name, bool create, bool putInGlobalList) {
Symbol *sym;
- if (!_vars.contains(name)) { // Create variable if it was not defined
+ if (!_localvars->contains(name)) { // Create variable if it was not defined
if (!create)
return NULL;
@@ -77,17 +77,31 @@ Symbol *Lingo::lookupVar(const char *name, bool create, bool putInLocalList) {
sym->type = VOID;
sym->u.val = 0;
- _vars[name] = sym;
+ (*_localvars)[name] = sym;
+
+ if (putInGlobalList) {
+ sym->global = true;
+ _globalvars[name] = sym;
+ }
} else {
- sym = g_lingo->_vars[name];
- }
+ sym = (*_localvars)[name];
- if (putInLocalList)
- (*_localvars)[name] = sym;
+ if (sym->global)
+ sym = _globalvars[name];
+ }
return sym;
}
+void Lingo::cleanLocalVars() {
+ // Clean up current scope local variables and clean up memory
+ for (SymbolHash::const_iterator h = _localvars->begin(); h != _localvars->end(); ++h) {
+ if (!h->_value->global)
+ delete h->_value;
+ }
+ delete g_lingo->_localvars;
+}
+
void Lingo::define(Common::String &name, int start, int nargs) {
debug(3, "define(\"%s\", %d, %d, %d)", name.c_str(), start, _currentScript->size() - 1, nargs);
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index accd9a113d..e584ac02b9 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -167,7 +167,7 @@ void Lingo::executeScript(ScriptType type, uint16 id) {
execute(_pc);
- delete _localvars;
+ cleanLocalVars();
}
void Lingo::processEvent(LEvent event, int entityId) {
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index e30d8a465a..f9c58f0fa4 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -138,7 +138,8 @@ public:
void execute(int pc);
void pushContext();
void popContext();
- Symbol *lookupVar(const char *name, bool create = true, bool putInLocalList = true);
+ Symbol *lookupVar(const char *name, bool create = true, bool putInGlobalList = false);
+ void cleanLocalVars();
void define(Common::String &s, int start, int nargs);
void codeArg(Common::String *s);
void codeArgStore();
@@ -204,7 +205,7 @@ private:
ScriptHash _scripts[kMaxScriptType + 1];
- SymbolHash _vars;
+ SymbolHash _globalvars;
SymbolHash *_localvars;
SymbolHash _handlers;