Loading libacc/acc.cpp +147 −109 Original line number Diff line number Diff line Loading @@ -161,6 +161,17 @@ class compiler { X86CodeGenerator() {} virtual ~X86CodeGenerator() {} /* returns address to patch with local variable size */ int functionEntry() { o(0xe58955); /* push %ebp, mov %esp, %ebp */ return oad(0xec81, 0); /* sub $xxx, %esp */ } void functionExit() { o(0xc3c9); /* leave, ret */ } /* load immediate value */ int li(int t) { oad(0xb8, t); /* mov $xx, %eax */ Loading @@ -176,7 +187,8 @@ class compiler { return psym(0x84 + l, t); } int gcmp(int t) { int gcmp(int op) { int t = decodeOp(op); o(0xc139); /* cmp %eax,%ecx */ li(0); o(0x0f); /* setxx %al */ Loading @@ -184,6 +196,12 @@ class compiler { o(0xc0); } int genOp(int op) { o(decodeOp(op)); if (op == OP_MOD) o(0x92); /* xchg %edx, %eax */ } void clearECX() { oad(0xb9, 0); /* movl $0, %ecx */ } Loading @@ -192,8 +210,11 @@ class compiler { o(0x50); /* push %eax */ } void storeEAXIntoPoppedLVal(bool isInt) { void popECX() { o(0x59); /* pop %ecx */ } void storeEAXToAddressECX(bool isInt) { o(0x0188 + isInt); /* movl %eax/%al, (%ecx) */ } Loading @@ -217,12 +238,11 @@ class compiler { gmov(8, ea); /* mov EA, %eax */ } void puzzleAdd(int n, int tokc) { /* Not sure what this does, related to variable loading with an * operator at level 11. void postIncrementOrDecrement(int n, int op) { /* Implement post-increment or post decrement. */ gmov(0, n); /* 83 ADD */ o(tokc); o(decodeOp(op)); } int allocStackSpaceForArgs() { Loading @@ -249,14 +269,16 @@ class compiler { oad(0xc481, l); /* add $xxx, %esp */ } void oHack(int n) { o(n); } private: static const int operatorHelper[]; void oadHack(int n, int t) { oad(n, t); int decodeOp(int op) { if (op < 0 || op > OP_COUNT) { fprintf(stderr, "Out-of-range operator: %d\n", op); exit(1); } return operatorHelper[op]; } private: int gmov(int l, int t) { o(l + 0x83); Loading Loading @@ -310,6 +332,37 @@ class compiler { static const int TAG_TOK = ' '; static const int TAG_MACRO = 2; static const int OP_INCREMENT = 0; static const int OP_DECREMENT = 1; static const int OP_MUL = 2; static const int OP_DIV = 3; static const int OP_MOD = 4; static const int OP_PLUS = 5; static const int OP_MINUS = 6; static const int OP_SHIFT_LEFT = 7; static const int OP_SHIFT_RIGHT = 8; static const int OP_LESS_EQUAL = 9; static const int OP_GREATER_EQUAL = 10; static const int OP_LESS = 11; static const int OP_GREATER = 12; static const int OP_EQUALS = 13; static const int OP_NOT_EQUALS = 14; static const int OP_LOGICAL_AND = 15; static const int OP_LOGICAL_OR = 16; static const int OP_BIT_AND = 17; static const int OP_BIT_XOR = 18; static const int OP_BIT_OR = 19; static const int OP_BIT_NOT = 20; static const int OP_LOGICAL_NOT = 21; static const int OP_COUNT = 22; /* Operators are searched from front, the two-character operators appear * before the single-character operators with the same first character. * @ is used to pad out single-character operators. */ static const char* operatorChars; static const char operatorLevel[]; void pdef(int t) { *(char *) dstk++ = t; } Loading Loading @@ -414,14 +467,12 @@ class compiler { inp(); next(); } else { const char * t = "++#m--%am*@R<^1c/@%[_[H3c%@%[_[H3c+@.B#d-@%:_^BKd<<Z/03e>>`/03e<=0f>=/f<@.f>@1f==&g!=\'g&&k||#l&@.BCh^@.BSi|@.B+j~@/%Yd!@&d*@b"; const char* t = operatorChars; int opIndex = 0; while (l = *t++) { a = *t++; tokc = 0; while ((tokl = *t++ - 'b') < 0) tokc = tokc * 64 + tokl + 64; tokl = operatorLevel[opIndex]; tokc = opIndex; if (l == tok & (a == ch | a == '@')) { #if 0 printf("%c%c -> tokl=%d tokc=0x%x\n", Loading @@ -433,6 +484,11 @@ class compiler { } break; } opIndex++; } if (l == 0) { tokl = 0; tokc = 0; } } } Loading Loading @@ -477,59 +533,6 @@ class compiler { next(); } /* load immediate value */ int li(int t) { return pGen->li(t); } int gjmp(int t) { return pGen->gjmp(t); } /* l = 0: je, l == 1: jne */ int gtst(int l, int t) { return pGen->gtst(l, t); } int gcmp(int t) { return pGen->gcmp(t); } void clearEXC() { pGen->clearECX(); } void storeEAXIntoPoppedLVal(bool isInt) { pGen->storeEAXIntoPoppedLVal(isInt); } void loadEAXIndirect(bool isInt) { pGen->loadEAXIndirect(isInt); } void leaEAX(int ea) { pGen->leaEAX(ea); } /* Temporary hack for emitting x86 code directly. */ void o(int n) { pGen->oHack(n); } /* instruction + address */ int oad(int n, int t) { pGen->oadHack(n,t); } /* instruction + address */ int psym(int n, int t) { pGen->oadHack(n,t); } void gsym(int n) { pGen->gsym(n); } /* l is one if '=' parsing wanted (quick hack) */ void unary(int l) { int n, t, a, c; Loading @@ -537,7 +540,7 @@ class compiler { n = 1; /* type of expression 0 = forward, 1 = value, other = lvalue */ if (tok == '\"') { li(glo); pGen->li(glo); while (ch != '\"') { getq(); *(char *) glo++ = ch; Loading @@ -553,15 +556,15 @@ class compiler { t = tok; next(); if (t == TOK_NUM) { li(a); pGen->li(a); } else if (c == 2) { /* -, +, !, ~ */ unary(0); clearEXC(); pGen->clearECX(); if (t == '!') gcmp(a); pGen->gcmp(a); else o(a); pGen->genOp(a); } else if (t == '(') { expr(); skip(')'); Loading @@ -585,12 +588,13 @@ class compiler { next(); pGen->pushEAX(); expr(); storeEAXIntoPoppedLVal(t == TOK_INT); pGen->popECX(); pGen->storeEAXToAddressECX(t == TOK_INT); } else if (t) { loadEAXIndirect(t == TOK_INT); pGen->loadEAXIndirect(t == TOK_INT); } } else if (t == '&') { leaEAX(*(int *) tok); pGen->leaEAX(*(int *) tok); next(); } else { n = *(int *) t; Loading @@ -606,7 +610,7 @@ class compiler { /* variable */ pGen->loadEAX(n); if (tokl == 11) { pGen->puzzleAdd(n, tokc); pGen->postIncrementOrDecrement(n, tokc); next(); } } Loading Loading @@ -660,29 +664,27 @@ class compiler { next(); if (l > 8) { a = gtst(t, a); /* && and || output code generation */ a = pGen->gtst(t == OP_LOGICAL_OR, a); /* && and || output code generation */ sum(l); } else { o(0x50); /* push %eax */ pGen->pushEAX(); sum(l); o(0x59); /* pop %ecx */ pGen->popECX(); if (l == 4 | l == 5) { gcmp(t); pGen->gcmp(t); } else { o(t); if (n == '%') o(0x92); /* xchg %edx, %eax */ pGen->genOp(t); } } } /* && and || output code generation */ if (a && l > 8) { a = gtst(t, a); li(t ^ 1); gjmp(5); /* jmp $ + 5 */ gsym(a); li(t); a = pGen->gtst(t == OP_LOGICAL_OR, a); pGen->li(t != OP_LOGICAL_OR); pGen->gjmp(5); /* jmp $ + 5 */ pGen->gsym(a); pGen->li(t == OP_LOGICAL_OR); } } } Loading @@ -693,7 +695,7 @@ class compiler { int test_expr() { expr(); return gtst(0, 0); return pGen->gtst(0, 0); } void block(int l) { Loading @@ -707,12 +709,12 @@ class compiler { block(l); if (tok == TOK_ELSE) { next(); n = gjmp(0); /* jmp */ gsym(a); n = pGen->gjmp(0); /* jmp */ pGen->gsym(a); block(l); gsym(n); /* patch else jmp */ pGen->gsym(n); /* patch else jmp */ } else { gsym(a); /* patch if test */ pGen->gsym(a); /* patch if test */ } } else if (tok == TOK_WHILE | tok == TOK_FOR) { t = tok; Loading @@ -731,17 +733,17 @@ class compiler { a = test_expr(); skip(';'); if (tok != ')') { t = gjmp(0); t = pGen->gjmp(0); expr(); gjmp(n - codeBuf.getPC() - 5); gsym(t); pGen->gjmp(n - codeBuf.getPC() - 5); pGen->gsym(t); n = t + 4; } } skip(')'); block((int) &a); gjmp(n - codeBuf.getPC() - 5); /* jmp */ gsym(a); pGen->gjmp(n - codeBuf.getPC() - 5); /* jmp */ pGen->gsym(a); } else if (tok == '{') { next(); /* declarations */ Loading @@ -754,10 +756,10 @@ class compiler { next(); if (tok != ';') expr(); rsym = gjmp(rsym); /* jmp */ rsym = pGen->gjmp(rsym); /* jmp */ } else if (tok == TOK_BREAK) { next(); *(int *) l = gjmp(*(int *) l); *(int *) l = pGen->gjmp(*(int *) l); } else if (tok != ';') expr(); skip(';'); Loading Loading @@ -787,7 +789,7 @@ class compiler { } else { /* patch forward references (XXX: do not work for function pointers) */ gsym(*(int *) (tok + 4)); pGen->gsym(*(int *) (tok + 4)); /* put function address */ *(int *) tok = codeBuf.getPC(); next(); Loading @@ -803,11 +805,10 @@ class compiler { } next(); /* skip ')' */ rsym = loc = 0; o(0xe58955); /* push %ebp, mov %esp, %ebp */ a = oad(0xec81, 0); /* sub $xxx, %esp */ a = pGen->functionEntry(); block(0); gsym(rsym); o(0xc3c9); /* leave, ret */ pGen->gsym(rsym); pGen->functionExit(); *(int *) a = loc; /* save local variables */ } } Loading Loading @@ -899,6 +900,42 @@ public: }; const char* compiler::operatorChars = "++--*@/@%@+@-@<<>><=>=<@>@==!=&&||&@^@|@~@!@"; const char compiler::operatorLevel[] = {11, 11, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, /* ==, != */ 9, 10, /* &&, || */ 6, 7, 8, /* & ^ | */ 2, 2 /* ~ ! */ }; const int compiler::X86CodeGenerator::operatorHelper[] = { 0x1, // ++ 0xff, // -- 0xc1af0f, // * 0xf9f79991, // / 0xf9f79991, // % (With manual assist to swap results) 0xc801, // + 0xd8f7c829, // - 0xe0d391, // << 0xf8d391, // >> 0xe, // <= 0xd, // >= 0xc, // < 0xf, // > 0x4, // == 0x5, // != 0x0, // && 0x1, // || 0xc821, // & 0xc831, // ^ 0xc809, // | 0xd0f7, // ~ 0x4 // ! }; } // namespace acc int main(int argc, char** argv) { Loading Loading @@ -956,6 +993,7 @@ int main(int argc, char** argv) { compiler.dump(save); fclose(save); } else { fprintf(stderr, "Executing compiled code:\n"); int codeArgc = argc - i + 1; char** codeArgv = argv + i - 1; codeArgv[0] = (char*) (inFile ? inFile : "stdin"); Loading libacc/tests/expr.c 0 → 100644 +60 −0 Original line number Diff line number Diff line /* Test operators */ testInc() { int a, b; a = 3; b = a++; printf("3++ = %d %d\n", b, a); } testDec() { int a, b; a = 3; b = a--; printf("3-- = %d %d\n", b, a); } testTimes(){ printf("%d * %d = %d\n", 10, 4, 10 * 4); } testDiv(){ printf("%d / %d = %d\n", 11, 4, 11 / 4); } testMod(){ printf("%d %% %d = %d\n", 11, 4, 11 % 4); } testPlus(){ printf("%d + %d = %d\n", 10, 4, 10 + 4); } testMinus(){ printf("%d - %d = %d\n", 10, 4, 10 - 4); } testShiftLeft(){ printf("%d << %d = %d\n", 10, 4, 10 << 4); } testShiftRight(){ printf("%d >> %d = %d\n", 100, 4, 100 >> 4); } testLess(){ printf("%d < %d = %d\n", 10, 4, 10 < 4); } testLesEqual(){ printf("%d <= %d = %d\n", 10, 4, 10 <= 4); } testGreater(){ printf("%d > %d = %d\n", 10, 4, 10 > 4); } testGreaterEqual(){ printf("%d >= %d = %d\n", 10, 4, 10 >= 4); } testEqualTo(){ printf("%d == %d = %d\n", 10, 4, 10 == 4); } testNotEqualTo(){ printf("%d != %d = %d\n", 10, 4, 10 != 4); } testBitAnd(){ printf("%d & %d = %d\n", 10, 7, 10 & 7); } testBitXor(){ printf("%d ^ %d = %d\n", 10, 7, 10 ^ 7); } testBitOr(){ printf("%d | %d = %d\n", 10, 4, 10 | 4); } testAssignment(){ int a, b; a = 3; b = a; printf("b == %d\n", b); } testLogicalAnd(){ printf("%d && %d = %d\n", 10, 4, 10 && 4); } testLogicalOr(){ printf("%d || %d = %d\n", 10, 4, 10 || 4); } testAddressOf(){ int a; printf("&a is %d\n", &a); } testPointerIndirection(){ int a, b; a = &b; b = 17; printf("*%d = %d =?= %d\n", a, * (int*) a, b); } testNegation(){ printf("-%d = %d\n", 10, -10); } testUnaryPlus(){ printf("+%d = %d\n", 10, +10); } testUnaryNot(){ printf("!%d = %d\n", 10, !10); } testBitNot(){ printf("~%d = %d\n", 10, ~10); } main(a,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; } No newline at end of file Loading
libacc/acc.cpp +147 −109 Original line number Diff line number Diff line Loading @@ -161,6 +161,17 @@ class compiler { X86CodeGenerator() {} virtual ~X86CodeGenerator() {} /* returns address to patch with local variable size */ int functionEntry() { o(0xe58955); /* push %ebp, mov %esp, %ebp */ return oad(0xec81, 0); /* sub $xxx, %esp */ } void functionExit() { o(0xc3c9); /* leave, ret */ } /* load immediate value */ int li(int t) { oad(0xb8, t); /* mov $xx, %eax */ Loading @@ -176,7 +187,8 @@ class compiler { return psym(0x84 + l, t); } int gcmp(int t) { int gcmp(int op) { int t = decodeOp(op); o(0xc139); /* cmp %eax,%ecx */ li(0); o(0x0f); /* setxx %al */ Loading @@ -184,6 +196,12 @@ class compiler { o(0xc0); } int genOp(int op) { o(decodeOp(op)); if (op == OP_MOD) o(0x92); /* xchg %edx, %eax */ } void clearECX() { oad(0xb9, 0); /* movl $0, %ecx */ } Loading @@ -192,8 +210,11 @@ class compiler { o(0x50); /* push %eax */ } void storeEAXIntoPoppedLVal(bool isInt) { void popECX() { o(0x59); /* pop %ecx */ } void storeEAXToAddressECX(bool isInt) { o(0x0188 + isInt); /* movl %eax/%al, (%ecx) */ } Loading @@ -217,12 +238,11 @@ class compiler { gmov(8, ea); /* mov EA, %eax */ } void puzzleAdd(int n, int tokc) { /* Not sure what this does, related to variable loading with an * operator at level 11. void postIncrementOrDecrement(int n, int op) { /* Implement post-increment or post decrement. */ gmov(0, n); /* 83 ADD */ o(tokc); o(decodeOp(op)); } int allocStackSpaceForArgs() { Loading @@ -249,14 +269,16 @@ class compiler { oad(0xc481, l); /* add $xxx, %esp */ } void oHack(int n) { o(n); } private: static const int operatorHelper[]; void oadHack(int n, int t) { oad(n, t); int decodeOp(int op) { if (op < 0 || op > OP_COUNT) { fprintf(stderr, "Out-of-range operator: %d\n", op); exit(1); } return operatorHelper[op]; } private: int gmov(int l, int t) { o(l + 0x83); Loading Loading @@ -310,6 +332,37 @@ class compiler { static const int TAG_TOK = ' '; static const int TAG_MACRO = 2; static const int OP_INCREMENT = 0; static const int OP_DECREMENT = 1; static const int OP_MUL = 2; static const int OP_DIV = 3; static const int OP_MOD = 4; static const int OP_PLUS = 5; static const int OP_MINUS = 6; static const int OP_SHIFT_LEFT = 7; static const int OP_SHIFT_RIGHT = 8; static const int OP_LESS_EQUAL = 9; static const int OP_GREATER_EQUAL = 10; static const int OP_LESS = 11; static const int OP_GREATER = 12; static const int OP_EQUALS = 13; static const int OP_NOT_EQUALS = 14; static const int OP_LOGICAL_AND = 15; static const int OP_LOGICAL_OR = 16; static const int OP_BIT_AND = 17; static const int OP_BIT_XOR = 18; static const int OP_BIT_OR = 19; static const int OP_BIT_NOT = 20; static const int OP_LOGICAL_NOT = 21; static const int OP_COUNT = 22; /* Operators are searched from front, the two-character operators appear * before the single-character operators with the same first character. * @ is used to pad out single-character operators. */ static const char* operatorChars; static const char operatorLevel[]; void pdef(int t) { *(char *) dstk++ = t; } Loading Loading @@ -414,14 +467,12 @@ class compiler { inp(); next(); } else { const char * t = "++#m--%am*@R<^1c/@%[_[H3c%@%[_[H3c+@.B#d-@%:_^BKd<<Z/03e>>`/03e<=0f>=/f<@.f>@1f==&g!=\'g&&k||#l&@.BCh^@.BSi|@.B+j~@/%Yd!@&d*@b"; const char* t = operatorChars; int opIndex = 0; while (l = *t++) { a = *t++; tokc = 0; while ((tokl = *t++ - 'b') < 0) tokc = tokc * 64 + tokl + 64; tokl = operatorLevel[opIndex]; tokc = opIndex; if (l == tok & (a == ch | a == '@')) { #if 0 printf("%c%c -> tokl=%d tokc=0x%x\n", Loading @@ -433,6 +484,11 @@ class compiler { } break; } opIndex++; } if (l == 0) { tokl = 0; tokc = 0; } } } Loading Loading @@ -477,59 +533,6 @@ class compiler { next(); } /* load immediate value */ int li(int t) { return pGen->li(t); } int gjmp(int t) { return pGen->gjmp(t); } /* l = 0: je, l == 1: jne */ int gtst(int l, int t) { return pGen->gtst(l, t); } int gcmp(int t) { return pGen->gcmp(t); } void clearEXC() { pGen->clearECX(); } void storeEAXIntoPoppedLVal(bool isInt) { pGen->storeEAXIntoPoppedLVal(isInt); } void loadEAXIndirect(bool isInt) { pGen->loadEAXIndirect(isInt); } void leaEAX(int ea) { pGen->leaEAX(ea); } /* Temporary hack for emitting x86 code directly. */ void o(int n) { pGen->oHack(n); } /* instruction + address */ int oad(int n, int t) { pGen->oadHack(n,t); } /* instruction + address */ int psym(int n, int t) { pGen->oadHack(n,t); } void gsym(int n) { pGen->gsym(n); } /* l is one if '=' parsing wanted (quick hack) */ void unary(int l) { int n, t, a, c; Loading @@ -537,7 +540,7 @@ class compiler { n = 1; /* type of expression 0 = forward, 1 = value, other = lvalue */ if (tok == '\"') { li(glo); pGen->li(glo); while (ch != '\"') { getq(); *(char *) glo++ = ch; Loading @@ -553,15 +556,15 @@ class compiler { t = tok; next(); if (t == TOK_NUM) { li(a); pGen->li(a); } else if (c == 2) { /* -, +, !, ~ */ unary(0); clearEXC(); pGen->clearECX(); if (t == '!') gcmp(a); pGen->gcmp(a); else o(a); pGen->genOp(a); } else if (t == '(') { expr(); skip(')'); Loading @@ -585,12 +588,13 @@ class compiler { next(); pGen->pushEAX(); expr(); storeEAXIntoPoppedLVal(t == TOK_INT); pGen->popECX(); pGen->storeEAXToAddressECX(t == TOK_INT); } else if (t) { loadEAXIndirect(t == TOK_INT); pGen->loadEAXIndirect(t == TOK_INT); } } else if (t == '&') { leaEAX(*(int *) tok); pGen->leaEAX(*(int *) tok); next(); } else { n = *(int *) t; Loading @@ -606,7 +610,7 @@ class compiler { /* variable */ pGen->loadEAX(n); if (tokl == 11) { pGen->puzzleAdd(n, tokc); pGen->postIncrementOrDecrement(n, tokc); next(); } } Loading Loading @@ -660,29 +664,27 @@ class compiler { next(); if (l > 8) { a = gtst(t, a); /* && and || output code generation */ a = pGen->gtst(t == OP_LOGICAL_OR, a); /* && and || output code generation */ sum(l); } else { o(0x50); /* push %eax */ pGen->pushEAX(); sum(l); o(0x59); /* pop %ecx */ pGen->popECX(); if (l == 4 | l == 5) { gcmp(t); pGen->gcmp(t); } else { o(t); if (n == '%') o(0x92); /* xchg %edx, %eax */ pGen->genOp(t); } } } /* && and || output code generation */ if (a && l > 8) { a = gtst(t, a); li(t ^ 1); gjmp(5); /* jmp $ + 5 */ gsym(a); li(t); a = pGen->gtst(t == OP_LOGICAL_OR, a); pGen->li(t != OP_LOGICAL_OR); pGen->gjmp(5); /* jmp $ + 5 */ pGen->gsym(a); pGen->li(t == OP_LOGICAL_OR); } } } Loading @@ -693,7 +695,7 @@ class compiler { int test_expr() { expr(); return gtst(0, 0); return pGen->gtst(0, 0); } void block(int l) { Loading @@ -707,12 +709,12 @@ class compiler { block(l); if (tok == TOK_ELSE) { next(); n = gjmp(0); /* jmp */ gsym(a); n = pGen->gjmp(0); /* jmp */ pGen->gsym(a); block(l); gsym(n); /* patch else jmp */ pGen->gsym(n); /* patch else jmp */ } else { gsym(a); /* patch if test */ pGen->gsym(a); /* patch if test */ } } else if (tok == TOK_WHILE | tok == TOK_FOR) { t = tok; Loading @@ -731,17 +733,17 @@ class compiler { a = test_expr(); skip(';'); if (tok != ')') { t = gjmp(0); t = pGen->gjmp(0); expr(); gjmp(n - codeBuf.getPC() - 5); gsym(t); pGen->gjmp(n - codeBuf.getPC() - 5); pGen->gsym(t); n = t + 4; } } skip(')'); block((int) &a); gjmp(n - codeBuf.getPC() - 5); /* jmp */ gsym(a); pGen->gjmp(n - codeBuf.getPC() - 5); /* jmp */ pGen->gsym(a); } else if (tok == '{') { next(); /* declarations */ Loading @@ -754,10 +756,10 @@ class compiler { next(); if (tok != ';') expr(); rsym = gjmp(rsym); /* jmp */ rsym = pGen->gjmp(rsym); /* jmp */ } else if (tok == TOK_BREAK) { next(); *(int *) l = gjmp(*(int *) l); *(int *) l = pGen->gjmp(*(int *) l); } else if (tok != ';') expr(); skip(';'); Loading Loading @@ -787,7 +789,7 @@ class compiler { } else { /* patch forward references (XXX: do not work for function pointers) */ gsym(*(int *) (tok + 4)); pGen->gsym(*(int *) (tok + 4)); /* put function address */ *(int *) tok = codeBuf.getPC(); next(); Loading @@ -803,11 +805,10 @@ class compiler { } next(); /* skip ')' */ rsym = loc = 0; o(0xe58955); /* push %ebp, mov %esp, %ebp */ a = oad(0xec81, 0); /* sub $xxx, %esp */ a = pGen->functionEntry(); block(0); gsym(rsym); o(0xc3c9); /* leave, ret */ pGen->gsym(rsym); pGen->functionExit(); *(int *) a = loc; /* save local variables */ } } Loading Loading @@ -899,6 +900,42 @@ public: }; const char* compiler::operatorChars = "++--*@/@%@+@-@<<>><=>=<@>@==!=&&||&@^@|@~@!@"; const char compiler::operatorLevel[] = {11, 11, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, /* ==, != */ 9, 10, /* &&, || */ 6, 7, 8, /* & ^ | */ 2, 2 /* ~ ! */ }; const int compiler::X86CodeGenerator::operatorHelper[] = { 0x1, // ++ 0xff, // -- 0xc1af0f, // * 0xf9f79991, // / 0xf9f79991, // % (With manual assist to swap results) 0xc801, // + 0xd8f7c829, // - 0xe0d391, // << 0xf8d391, // >> 0xe, // <= 0xd, // >= 0xc, // < 0xf, // > 0x4, // == 0x5, // != 0x0, // && 0x1, // || 0xc821, // & 0xc831, // ^ 0xc809, // | 0xd0f7, // ~ 0x4 // ! }; } // namespace acc int main(int argc, char** argv) { Loading Loading @@ -956,6 +993,7 @@ int main(int argc, char** argv) { compiler.dump(save); fclose(save); } else { fprintf(stderr, "Executing compiled code:\n"); int codeArgc = argc - i + 1; char** codeArgv = argv + i - 1; codeArgv[0] = (char*) (inFile ? inFile : "stdin"); Loading
libacc/tests/expr.c 0 → 100644 +60 −0 Original line number Diff line number Diff line /* Test operators */ testInc() { int a, b; a = 3; b = a++; printf("3++ = %d %d\n", b, a); } testDec() { int a, b; a = 3; b = a--; printf("3-- = %d %d\n", b, a); } testTimes(){ printf("%d * %d = %d\n", 10, 4, 10 * 4); } testDiv(){ printf("%d / %d = %d\n", 11, 4, 11 / 4); } testMod(){ printf("%d %% %d = %d\n", 11, 4, 11 % 4); } testPlus(){ printf("%d + %d = %d\n", 10, 4, 10 + 4); } testMinus(){ printf("%d - %d = %d\n", 10, 4, 10 - 4); } testShiftLeft(){ printf("%d << %d = %d\n", 10, 4, 10 << 4); } testShiftRight(){ printf("%d >> %d = %d\n", 100, 4, 100 >> 4); } testLess(){ printf("%d < %d = %d\n", 10, 4, 10 < 4); } testLesEqual(){ printf("%d <= %d = %d\n", 10, 4, 10 <= 4); } testGreater(){ printf("%d > %d = %d\n", 10, 4, 10 > 4); } testGreaterEqual(){ printf("%d >= %d = %d\n", 10, 4, 10 >= 4); } testEqualTo(){ printf("%d == %d = %d\n", 10, 4, 10 == 4); } testNotEqualTo(){ printf("%d != %d = %d\n", 10, 4, 10 != 4); } testBitAnd(){ printf("%d & %d = %d\n", 10, 7, 10 & 7); } testBitXor(){ printf("%d ^ %d = %d\n", 10, 7, 10 ^ 7); } testBitOr(){ printf("%d | %d = %d\n", 10, 4, 10 | 4); } testAssignment(){ int a, b; a = 3; b = a; printf("b == %d\n", b); } testLogicalAnd(){ printf("%d && %d = %d\n", 10, 4, 10 && 4); } testLogicalOr(){ printf("%d || %d = %d\n", 10, 4, 10 || 4); } testAddressOf(){ int a; printf("&a is %d\n", &a); } testPointerIndirection(){ int a, b; a = &b; b = 17; printf("*%d = %d =?= %d\n", a, * (int*) a, b); } testNegation(){ printf("-%d = %d\n", 10, -10); } testUnaryPlus(){ printf("+%d = %d\n", 10, +10); } testUnaryNot(){ printf("!%d = %d\n", 10, !10); } testBitNot(){ printf("~%d = %d\n", 10, ~10); } main(a,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; } No newline at end of file