Improve local variable scoping.

Until now we faked local variables -- they only worked correctly if
there was no overlap between local variables and global variables.

Use a symbol table stack instead of a string list.

Fix bug with looking up undefined symbols.
diff --git a/libacc/tests/Android.mk b/libacc/tests/Android.mk
index 1e4d328..f8907b4 100644
--- a/libacc/tests/Android.mk
+++ b/libacc/tests/Android.mk
@@ -26,7 +26,8 @@
 LOCAL_SHARED_LIBRARIES := \
     libacc
 
+LOCAL_CFLAGS := -O0 -g 
 
 LOCAL_MODULE_TAGS := tests
 
-include $(BUILD_EXECUTABLE)
\ No newline at end of file
+include $(BUILD_EXECUTABLE)
diff --git a/libacc/tests/data/expr-ansi.c b/libacc/tests/data/expr-ansi.c
new file mode 100644
index 0000000..d463659
--- /dev/null
+++ b/libacc/tests/data/expr-ansi.c
@@ -0,0 +1,60 @@
+/* Test operators */
+
+void testInc() { int a, b; a = 3; b = a++; printf("3++ = %d %d\n", b, a); }
+void testDec() { int a, b; a = 3; b = a--; printf("3-- = %d %d\n", b, a); }
+void testTimes(){ printf("%d * %d = %d\n", 10, 4, 10 * 4); }
+void testDiv(){ printf("%d / %d = %d\n", 11, 4, 11 / 4); }
+void testMod(){ printf("%d %% %d = %d\n", 11, 4, 11 % 4); }
+void testPlus(){ printf("%d + %d = %d\n", 10, 4, 10 + 4); }
+void testMinus(){ printf("%d - %d = %d\n", 10, 4, 10 - 4); }
+void testShiftLeft(){ printf("%d << %d = %d\n", 10, 4, 10 << 4); }
+void testShiftRight(){ printf("%d >> %d = %d\n", 100, 4, 100 >> 4); }
+void testLess(){ printf("%d < %d = %d\n", 10, 4, 10 < 4); }
+void testLesEqual(){ printf("%d <= %d = %d\n", 10, 4, 10 <= 4); }
+void testGreater(){ printf("%d > %d = %d\n", 10, 4, 10 > 4); }
+void testGreaterEqual(){ printf("%d >= %d = %d\n", 10, 4, 10 >= 4); }
+void testEqualTo(){ printf("%d == %d = %d\n", 10, 4, 10 == 4); }
+void testNotEqualTo(){ printf("%d != %d = %d\n", 10, 4, 10 != 4); }
+void testBitAnd(){ printf("%d & %d = %d\n", 10, 7, 10 & 7); }
+void testBitXor(){ printf("%d ^ %d = %d\n", 10, 7, 10 ^ 7); }
+void testBitOr(){ printf("%d | %d = %d\n", 10, 4, 10 | 4); }
+void testAssignment(){ int a, b; a = 3; b = a; printf("b == %d\n", b); }
+void testLogicalAnd(){ printf("%d && %d = %d\n", 10, 4, 10 && 4); }
+void testLogicalOr(){ printf("%d || %d = %d\n", 10, 4, 10 || 4); }
+void testAddressOf(){ int a; printf("&a is %d\n", &a); }
+void testPointerIndirection(){ int a, b; a = &b; b = 17; printf("*%d  = %d =?= %d\n", a, * (int*) a, b); }
+void testNegation(){ printf("-%d = %d\n", 10, -10); }
+void testUnaryPlus(){ printf("+%d = %d\n", 10, +10); }
+void testUnaryNot(){ printf("!%d = %d\n", 10, !10); }
+void testBitNot(){ printf("~%d = %d\n", 10, ~10); }
+
+int main(int a, char** b) {
+    testInc();
+    testDec();
+    testTimes();
+    testDiv();
+    testMod();
+    testPlus();
+    testMinus();
+    testShiftLeft();
+    testShiftRight();
+    testLess();
+    testLesEqual();
+    testGreater();
+    testGreaterEqual();
+    testEqualTo();
+    testNotEqualTo();
+    testBitAnd();
+    testBinXor();
+    testBitOr();
+    testAssignment();
+    testLogicalAnd();
+    testLogicalOr();
+    testAddressOf();
+    testPointerIndirection();
+    testNegation();
+    testUnaryPlus();
+    testUnaryNot();
+    testBitNot();
+    return 0;
+}
diff --git a/libacc/tests/data/expr2.c b/libacc/tests/data/expr2.c
new file mode 100644
index 0000000..04b6a38
--- /dev/null
+++ b/libacc/tests/data/expr2.c
@@ -0,0 +1,6 @@
+/* Test operators */
+
+main() {
+    int a;
+    a = a++;
+}
diff --git a/libacc/tests/data/locals.c b/libacc/tests/data/locals.c
new file mode 100644
index 0000000..318162d
--- /dev/null
+++ b/libacc/tests/data/locals.c
@@ -0,0 +1,49 @@
+int a;
+
+int f() {
+    int a;
+    printf("f 0: a = %d b = %d\n", a, b);
+    a = 2;
+    printf("f 1: a = %d\n", a);
+}
+
+int g(int a) {
+    printf("g 0: a = %d\n", a);
+    a = 3;
+    printf("g 1: a = %d\n", a);
+}
+
+int h(int a) {
+    int a; // gcc 4.3 says error: 'a' redeclared as different kind of symbol
+
+    printf("h 0: a = %d\n", a);
+    a = 4;
+    printf("h 1: a = %d\n", a);
+}
+
+int globCheck() {
+    fprintf(stdout, "globCheck()\n");
+}
+
+int fwdCheck() {
+    b();
+}
+
+int b() {
+    printf("b()\n");
+}
+
+int main() {
+    globCheck();
+    fwdCheck();
+    printf("main 0: a = %d\n", a);
+    a = 5;
+    printf("main 1: a = %d\n", a);
+    f();
+    printf("main 2: a = %d\n", a);
+    g(77);
+    printf("main 3: a = %d\n", a);
+    h(30);
+    printf("main 4: a = %d\n", a);
+    return 0;
+}
diff --git a/libacc/tests/data/otcc-ansi.c b/libacc/tests/data/otcc-ansi.c
index 3ffad36..72580e9 100644
--- a/libacc/tests/data/otcc-ansi.c
+++ b/libacc/tests/data/otcc-ansi.c
@@ -442,6 +442,10 @@
     if (g-- > 1) {
         e = e + 4;
         Q = fopen(*(int*) e, "r");
+        if (!Q) {
+            fprintf(stderr, "otcc-ansi.c: could not open file %s\n", *(int*) e);
+            return -2;
+        }
     }
     D = strcpy(R = calloc(1, 99999), " int if else while break return for define main ") + 48;
     v = calloc(1, 99999);
diff --git a/libacc/tests/testlocal b/libacc/tests/testlocal
index 1650bf9..1a0b4c5 100755
--- a/libacc/tests/testlocal
+++ b/libacc/tests/testlocal
@@ -12,9 +12,11 @@
 
 if file $ACC | grep -q "ELF 32-bit LSB executable, Intel 80386"; then
 	echo "Linux 32bit Intel."
+	echo "TESTING returnval-ansi.c:"
         $ACC -R $DATA/returnval-ansi.c
-        echo Testing otcc-ansi.c
+        echo TESTING otcc-ansi.c returnval-ansi.c
 	$ACC -R "$DATA/otcc-ansi.c" "$DATA/returnval.c"
+	echo TESTING otcc-ansi.c otcc.c returnval-ansi.c
 	$ACC -R $DATA/otcc-ansi.c $DATA/otcc.c $DATA/returnval.c
 fi