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