Skip to content

Commit

Permalink
DIRECTOR: Lingo: Make global/local vars work
Browse files Browse the repository at this point in the history
  • Loading branch information
sev- committed Aug 3, 2016
1 parent 0b6d950 commit c53e4b5
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 32 deletions.
7 changes: 6 additions & 1 deletion engines/director/director.cpp
Expand Up @@ -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\
Expand All @@ -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\
Expand All @@ -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);
Expand Down
26 changes: 5 additions & 21 deletions engines/director/lingo/lingo-code.cpp
Expand Up @@ -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);
Expand All @@ -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;

Expand All @@ -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());
Expand Down
28 changes: 21 additions & 7 deletions engines/director/lingo/lingo-codegen.cpp
Expand Up @@ -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;

Expand All @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion engines/director/lingo/lingo.cpp
Expand Up @@ -167,7 +167,7 @@ void Lingo::executeScript(ScriptType type, uint16 id) {

execute(_pc);

delete _localvars;
cleanLocalVars();
}

void Lingo::processEvent(LEvent event, int entityId) {
Expand Down
5 changes: 3 additions & 2 deletions engines/director/lingo/lingo.h
Expand Up @@ -138,7 +138,8 @@ class Lingo {
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();
Expand Down Expand Up @@ -204,7 +205,7 @@ class Lingo {

ScriptHash _scripts[kMaxScriptType + 1];

SymbolHash _vars;
SymbolHash _globalvars;
SymbolHash *_localvars;
SymbolHash _handlers;

Expand Down

0 comments on commit c53e4b5

Please sign in to comment.