Thanks for all the replies. The solution that I am currently using is
a linked list of symbol tables. Each time a new scope is entered (ie.
a function) a new symbol table is created that is linked to the outer
scope symbol table. Then when a variable is referenced it searches the
linked list of symbol tables starting from the local symbol table and
working out to the top level symbol table (ie. global symbol table).

As Torben said this can result in memory leaks as all variables are
preserved in scope. Eg:
memoryLeak = function() {
largeObject = // some large data structure
return function() {
// some code that does not use largeObject
};};
f = memoryLeak();
// The function f has preserved the variable largeObject even though
it is not in use

My next step will be to try using indirect references to variables in
the outer scope and only bringing in references that are used.