Loading libacc/acc.cpp +175 −36 Original line number Diff line number Diff line Loading @@ -148,7 +148,8 @@ class Compiler : public ErrorSink { struct Type { TypeTag tag; tokenid_t id; // For function arguments (stores length for array) tokenid_t id; // For function arguments, local vars int length; // length of array Type* pHead; Type* pTail; }; Loading Loading @@ -405,7 +406,16 @@ class Compiler : public ErrorSink { /** * Convert R0 to the given type. */ virtual void convertR0(Type* pType) = 0; void convertR0(Type* pType) { convertR0Imp(pType, false); } void castR0(Type* pType) { convertR0Imp(pType, true); } virtual void convertR0Imp(Type* pType, bool isCast) = 0; /* Emit code to adjust the stack for a function call. Return the * label for the address of the instruction that adjusts the Loading Loading @@ -622,14 +632,40 @@ class Compiler : public ErrorSink { return collapseType(getR0Type()->tag); } bool isFloatType(Type* pType) { static bool isFloatType(Type* pType) { return isFloatTag(pType->tag); } bool isFloatTag(TypeTag tag) { static bool isFloatTag(TypeTag tag) { return tag == TY_FLOAT || tag == TY_DOUBLE; } static bool isPointerType(Type* pType) { return isPointerTag(pType->tag); } static bool isPointerTag(TypeTag tag) { return tag == TY_POINTER || tag == TY_ARRAY; } Type* getPointerArithmeticResultType(Type* a, Type* b) { TypeTag aTag = a->tag; TypeTag bTag = b->tag; if (aTag == TY_POINTER) { return a; } if (bTag == TY_POINTER) { return b; } if (aTag == TY_ARRAY) { return a->pTail; } if (bTag == TY_ARRAY) { return b->pTail; } return NULL; } Type* mkpInt; private: Loading Loading @@ -848,8 +884,8 @@ class Compiler : public ErrorSink { bool isFloatTOS = isFloatTag(tagTOS); if (!isFloatR0 && !isFloatTOS) { setupIntPtrArgs(); bool isPtrR0 = tagR0 == TY_POINTER; bool isPtrTOS = tagTOS == TY_POINTER; bool isPtrR0 = isPointerTag(tagR0); bool isPtrTOS = isPointerTag(tagTOS); if (isPtrR0 || isPtrTOS) { if (isPtrR0 && isPtrTOS) { if (op != OP_MINUS) { Loading @@ -871,7 +907,8 @@ class Compiler : public ErrorSink { if (! (op == OP_PLUS || (op == OP_MINUS && isPtrR0))) { error("Unsupported pointer-scalar operation %d", op); } Type* pPtrType = isPtrR0 ? pR0Type : pTOSType; Type* pPtrType = getPointerArithmeticResultType( pR0Type, pTOSType); int size = sizeOf(pPtrType->pHead); if (size != 1) { // TODO: Optimize for power-of-two. Loading Loading @@ -1131,7 +1168,8 @@ class Compiler : public ErrorSink { virtual void loadR0FromR0() { Type* pPointerType = getR0Type(); assert(pPointerType->tag == TY_POINTER); switch (pPointerType->pHead->tag) { TypeTag tag = pPointerType->pHead->tag; switch (tag) { case TY_POINTER: case TY_INT: case TY_FLOAT: Loading @@ -1147,7 +1185,7 @@ class Compiler : public ErrorSink { o4(0xE1C000D0); // ldrd r0, [r0] break; default: error("loadR0FromR0: unimplemented type"); error("loadR0FromR0: unimplemented type %d", tag); break; } setR0Type(pPointerType->pHead); Loading Loading @@ -1197,9 +1235,27 @@ class Compiler : public ErrorSink { return result; } virtual void convertR0(Type* pType){ virtual void convertR0Imp(Type* pType, bool isCast){ Type* pR0Type = getR0Type(); if (bitsSame(pType, pR0Type)) { if (isPointerType(pType) && isPointerType(pR0Type)) { Type* pA = pR0Type; Type* pB = pType; // Array decays to pointer if (pA->tag == TY_ARRAY && pB->tag == TY_POINTER) { pA = pA->pTail; } if (typeEqual(pA, pB)) { return; // OK } if (pB->pHead->tag == TY_VOID) { return; // convert to void* is OK. } if (pA->tag == TY_POINTER && pB->tag == TY_POINTER && isCast) { return; // OK } error("Incompatible pointer or array types"); } else if (bitsSame(pType, pR0Type)) { // do nothing special } else { TypeTag r0Tag = collapseType(pR0Type->tag); Loading Loading @@ -1423,14 +1479,17 @@ class Compiler : public ErrorSink { return 2; case TY_CHAR: return 1; default: return 0; case TY_FLOAT: return 4; case TY_DOUBLE: return 8; case TY_POINTER: return 4; case TY_ARRAY: return pType->length * sizeOf(pType->pHead); default: error("Unsupported type %d", pType->tag); return 0; } } Loading @@ -1438,6 +1497,8 @@ class Compiler : public ErrorSink { switch(pType->tag) { case TY_DOUBLE: return 8; case TY_ARRAY: return stackAlignmentOf(pType->pHead); default: return 4; } Loading @@ -1447,6 +1508,11 @@ class Compiler : public ErrorSink { switch(pType->tag) { case TY_DOUBLE: return 8; case TY_ARRAY: return sizeOf(pType); case TY_FUNC: error("stackSizeOf func not supported"); return 4; default: return 4; } Loading Loading @@ -1911,8 +1977,8 @@ class Compiler : public ErrorSink { bool isFloatR0 = isFloatTag(tagR0); bool isFloatTOS = isFloatTag(tagTOS); if (!isFloatR0 && !isFloatTOS) { bool isPtrR0 = tagR0 == TY_POINTER; bool isPtrTOS = tagTOS == TY_POINTER; bool isPtrR0 = isPointerTag(tagR0); bool isPtrTOS = isPointerTag(tagTOS); if (isPtrR0 || isPtrTOS) { if (isPtrR0 && isPtrTOS) { if (op != OP_MINUS) { Loading @@ -1936,7 +2002,8 @@ class Compiler : public ErrorSink { if (! (op == OP_PLUS || (op == OP_MINUS && isPtrR0))) { error("Unsupported pointer-scalar operation %d", op); } Type* pPtrType = isPtrR0 ? pR0Type : pTOSType; Type* pPtrType = getPointerArithmeticResultType( pR0Type, pTOSType); o(0x59); /* pop %ecx */ int size = sizeOf(pPtrType->pHead); if (size != 1) { Loading Loading @@ -2146,7 +2213,8 @@ class Compiler : public ErrorSink { virtual void loadR0FromR0() { Type* pPointerType = getR0Type(); assert(pPointerType->tag == TY_POINTER); switch (pPointerType->pHead->tag) { TypeTag tag = pPointerType->pHead->tag; switch (tag) { case TY_POINTER: case TY_INT: o2(0x008b); /* mov (%eax), %eax */ Loading @@ -2166,7 +2234,7 @@ class Compiler : public ErrorSink { o2(0x00dd); // fldl (%eax) break; default: error("loadR0FromR0: unsupported type"); error("loadR0FromR0: unsupported type %d", tag); break; } setR0Type(pPointerType->pHead); Loading @@ -2183,14 +2251,32 @@ class Compiler : public ErrorSink { return getPC() - 4; } virtual void convertR0(Type* pType){ virtual void convertR0Imp(Type* pType, bool isCast){ Type* pR0Type = getR0Type(); if (pR0Type == NULL) { assert(false); setR0Type(pType); return; } if (bitsSame(pType, pR0Type)) { if (isPointerType(pType) && isPointerType(pR0Type)) { Type* pA = pR0Type; Type* pB = pType; // Array decays to pointer if (pA->tag == TY_ARRAY && pB->tag == TY_POINTER) { pA = pA->pTail; } if (typeEqual(pA, pB)) { return; // OK } if (pB->pHead->tag == TY_VOID) { return; // convert to void* is OK. } if (pA->tag == TY_POINTER && pB->tag == TY_POINTER && isCast) { return; // OK } error("Incompatible pointer or array types"); } else if (bitsSame(pType, pR0Type)) { // do nothing special } else if (isFloatType(pType) && isFloatType(pR0Type)) { // do nothing special, both held in same register on x87. Loading Loading @@ -2326,6 +2412,11 @@ class Compiler : public ErrorSink { return 1; case TY_SHORT: return 2; case TY_ARRAY: return alignmentOf(pType->pHead); case TY_FUNC: error("alignment of func not supported"); return 1; default: return 4; } Loading @@ -2342,14 +2433,17 @@ class Compiler : public ErrorSink { return 2; case TY_CHAR: return 1; default: return 0; case TY_FLOAT: return 4; case TY_DOUBLE: return 8; case TY_POINTER: return 4; case TY_ARRAY: return pType->length * sizeOf(pType->pHead); default: error("Unsupported type %d", pType->tag); return 0; } } Loading @@ -2361,6 +2455,11 @@ class Compiler : public ErrorSink { switch(pType->tag) { case TY_DOUBLE: return 8; case TY_ARRAY: return sizeOf(pType); case TY_FUNC: error("stackSizeOf func not supported"); return 4; default: return 4; } Loading Loading @@ -3911,7 +4010,7 @@ class Compiler : public ErrorSink { skip(')'); unary(); pGen->forceR0RVal(); pGen->convertR0(pCast); pGen->castR0(pCast); } else { commaExpr(); skip(')'); Loading Loading @@ -3959,10 +4058,18 @@ class Compiler : public ErrorSink { } } // load a variable Type* pVal = createPtrType(pVI->pType); Type* pVal; ExpressionType et; if (pVI->pType->tag == TY_ARRAY) { pVal = pVI->pType; et = ET_RVALUE; } else { pVal = createPtrType(pVI->pType); et = ET_LVALUE; } if (n) { ExpressionType et = ET_LVALUE; if (pVal->pHead->tag == TY_FUNC) { int tag = pVal->pHead->tag; if (tag == TY_FUNC) { et = ET_RVALUE; } pGen->leaR0(n, pVal, et); Loading Loading @@ -4251,6 +4358,8 @@ class Compiler : public ErrorSink { } if (at == TY_POINTER) { return typeEqual(a->pHead, b->pHead); } else if (at == TY_ARRAY) { return a->length == b->length && typeEqual(a->pHead, b->pHead); } else if (at == TY_FUNC || at == TY_PARAM) { return typeEqual(a->pHead, b->pHead) && typeEqual(a->pTail, b->pTail); Loading Loading @@ -4345,6 +4454,9 @@ class Compiler : public ErrorSink { } buffer.append('*'); break; case TY_ARRAY: decodeTypeImpPrefix(buffer, pType->pHead); break; case TY_FUNC: decodeTypeImp(buffer, pType->pHead); break; Loading @@ -4369,6 +4481,13 @@ class Compiler : public ErrorSink { } decodeTypeImpPostfix(buffer, pType->pHead); break; case TY_ARRAY: { String temp; temp.printf("[%d]", pType->length); buffer.append(temp); } break; case TY_FUNC: buffer.append('('); for(Type* pArg = pType->pTail; pArg; pArg = pArg->pTail) { Loading Loading @@ -4418,9 +4537,13 @@ class Compiler : public ErrorSink { nameRequired, reportFailure); if (declName) { // Clone the parent type so we can set a unique ID Type* pOldType = pType; pType = createType(pType->tag, pType->pHead, pType->pTail); pType->id = declName; pType->length = pOldType->length; } else if (nameRequired) { error("Expected a variable name"); } // fprintf(stderr, "Parsed a declaration: "); // printType(pType); Loading Loading @@ -4490,11 +4613,27 @@ class Compiler : public ErrorSink { error("Expected name. Got %s", temp.getUnwrapped()); reportFailure = true; } while (accept('(')) { for(;;) { if (accept('(')) { // Function declaration Type* pTail = acceptArgs(nameAllowed); pType = createType(TY_FUNC, pType, pTail); skip(')'); } if (accept('[')) { if (tok != ']') { if (tok != TOK_NUM || tokc <= 0) { error("Expected positive integer constant"); } else { Type* pDecayType = createPtrType(pType); pType = createType(TY_ARRAY, pType, pDecayType); pType->length = tokc; } next(); } skip(']'); } else { break; } } if (pNewHead) { Loading libacc/tests/data/array.c 0 → 100644 +77 −0 Original line number Diff line number Diff line // Array allocation tests void testLocalInt() { int a[3]; a[0] = 1; a[1] = 2; a[2] = a[0] + a[1]; printf("localInt: %d\n", a[2]); } char a[3]; double d[3]; void testGlobalChar() { a[0] = 1; a[1] = 2; a[2] = a[0] + a[1]; printf("globalChar: %d\n", a[2]); } void testGlobalDouble() { d[0] = 1; d[1] = 2; d[2] = d[0] + d[1]; printf("globalDouble: %g\n", d[2]); } void testLocalDouble() { double d[3]; float m[12]; m[0] = 1.0f; m[1] = 2.0f; d[0] = 1.0; d[1] = 2.0; d[2] = d[0] + d[1]; m[2] = m[0] + m[1]; printf("localDouble: %g %g\n", d[2], m[2]); } void vectorAdd(int* a, int* b, float* c, int len) { int i; for(i = 0; i < len; i++) { c[i] = a[i] + b[i]; } } void testArgs() { int a[3], b[3]; float c[3]; int i; int len = 3; for(i = 0; i < len; i++) { a[i] = i; b[i] = i; c[i] = 0; } vectorAdd(a,b,c, len); printf("testArgs:"); for(i = 0; i < len; i++) { printf(" %g", c[i]); } printf("\n"); } int main() { testLocalInt(); testLocalDouble(); testGlobalChar(); testGlobalDouble(); testArgs(); return 0; } libacc/tests/test.py +10 −0 Original line number Diff line number Diff line Loading @@ -385,6 +385,16 @@ result: 0 def testShort(self): self.compileCheck(["-R", "data/short.c"], """Executing compiled code: result: -2 ""","""""") def testArray(self): self.compileCheck(["-R", "data/array.c"], """Executing compiled code: localInt: 3 localDouble: 3 3 globalChar: 3 globalDouble: 3 testArgs: 0 2 4 result: 0 ""","""""") if __name__ == '__main__': Loading Loading
libacc/acc.cpp +175 −36 Original line number Diff line number Diff line Loading @@ -148,7 +148,8 @@ class Compiler : public ErrorSink { struct Type { TypeTag tag; tokenid_t id; // For function arguments (stores length for array) tokenid_t id; // For function arguments, local vars int length; // length of array Type* pHead; Type* pTail; }; Loading Loading @@ -405,7 +406,16 @@ class Compiler : public ErrorSink { /** * Convert R0 to the given type. */ virtual void convertR0(Type* pType) = 0; void convertR0(Type* pType) { convertR0Imp(pType, false); } void castR0(Type* pType) { convertR0Imp(pType, true); } virtual void convertR0Imp(Type* pType, bool isCast) = 0; /* Emit code to adjust the stack for a function call. Return the * label for the address of the instruction that adjusts the Loading Loading @@ -622,14 +632,40 @@ class Compiler : public ErrorSink { return collapseType(getR0Type()->tag); } bool isFloatType(Type* pType) { static bool isFloatType(Type* pType) { return isFloatTag(pType->tag); } bool isFloatTag(TypeTag tag) { static bool isFloatTag(TypeTag tag) { return tag == TY_FLOAT || tag == TY_DOUBLE; } static bool isPointerType(Type* pType) { return isPointerTag(pType->tag); } static bool isPointerTag(TypeTag tag) { return tag == TY_POINTER || tag == TY_ARRAY; } Type* getPointerArithmeticResultType(Type* a, Type* b) { TypeTag aTag = a->tag; TypeTag bTag = b->tag; if (aTag == TY_POINTER) { return a; } if (bTag == TY_POINTER) { return b; } if (aTag == TY_ARRAY) { return a->pTail; } if (bTag == TY_ARRAY) { return b->pTail; } return NULL; } Type* mkpInt; private: Loading Loading @@ -848,8 +884,8 @@ class Compiler : public ErrorSink { bool isFloatTOS = isFloatTag(tagTOS); if (!isFloatR0 && !isFloatTOS) { setupIntPtrArgs(); bool isPtrR0 = tagR0 == TY_POINTER; bool isPtrTOS = tagTOS == TY_POINTER; bool isPtrR0 = isPointerTag(tagR0); bool isPtrTOS = isPointerTag(tagTOS); if (isPtrR0 || isPtrTOS) { if (isPtrR0 && isPtrTOS) { if (op != OP_MINUS) { Loading @@ -871,7 +907,8 @@ class Compiler : public ErrorSink { if (! (op == OP_PLUS || (op == OP_MINUS && isPtrR0))) { error("Unsupported pointer-scalar operation %d", op); } Type* pPtrType = isPtrR0 ? pR0Type : pTOSType; Type* pPtrType = getPointerArithmeticResultType( pR0Type, pTOSType); int size = sizeOf(pPtrType->pHead); if (size != 1) { // TODO: Optimize for power-of-two. Loading Loading @@ -1131,7 +1168,8 @@ class Compiler : public ErrorSink { virtual void loadR0FromR0() { Type* pPointerType = getR0Type(); assert(pPointerType->tag == TY_POINTER); switch (pPointerType->pHead->tag) { TypeTag tag = pPointerType->pHead->tag; switch (tag) { case TY_POINTER: case TY_INT: case TY_FLOAT: Loading @@ -1147,7 +1185,7 @@ class Compiler : public ErrorSink { o4(0xE1C000D0); // ldrd r0, [r0] break; default: error("loadR0FromR0: unimplemented type"); error("loadR0FromR0: unimplemented type %d", tag); break; } setR0Type(pPointerType->pHead); Loading Loading @@ -1197,9 +1235,27 @@ class Compiler : public ErrorSink { return result; } virtual void convertR0(Type* pType){ virtual void convertR0Imp(Type* pType, bool isCast){ Type* pR0Type = getR0Type(); if (bitsSame(pType, pR0Type)) { if (isPointerType(pType) && isPointerType(pR0Type)) { Type* pA = pR0Type; Type* pB = pType; // Array decays to pointer if (pA->tag == TY_ARRAY && pB->tag == TY_POINTER) { pA = pA->pTail; } if (typeEqual(pA, pB)) { return; // OK } if (pB->pHead->tag == TY_VOID) { return; // convert to void* is OK. } if (pA->tag == TY_POINTER && pB->tag == TY_POINTER && isCast) { return; // OK } error("Incompatible pointer or array types"); } else if (bitsSame(pType, pR0Type)) { // do nothing special } else { TypeTag r0Tag = collapseType(pR0Type->tag); Loading Loading @@ -1423,14 +1479,17 @@ class Compiler : public ErrorSink { return 2; case TY_CHAR: return 1; default: return 0; case TY_FLOAT: return 4; case TY_DOUBLE: return 8; case TY_POINTER: return 4; case TY_ARRAY: return pType->length * sizeOf(pType->pHead); default: error("Unsupported type %d", pType->tag); return 0; } } Loading @@ -1438,6 +1497,8 @@ class Compiler : public ErrorSink { switch(pType->tag) { case TY_DOUBLE: return 8; case TY_ARRAY: return stackAlignmentOf(pType->pHead); default: return 4; } Loading @@ -1447,6 +1508,11 @@ class Compiler : public ErrorSink { switch(pType->tag) { case TY_DOUBLE: return 8; case TY_ARRAY: return sizeOf(pType); case TY_FUNC: error("stackSizeOf func not supported"); return 4; default: return 4; } Loading Loading @@ -1911,8 +1977,8 @@ class Compiler : public ErrorSink { bool isFloatR0 = isFloatTag(tagR0); bool isFloatTOS = isFloatTag(tagTOS); if (!isFloatR0 && !isFloatTOS) { bool isPtrR0 = tagR0 == TY_POINTER; bool isPtrTOS = tagTOS == TY_POINTER; bool isPtrR0 = isPointerTag(tagR0); bool isPtrTOS = isPointerTag(tagTOS); if (isPtrR0 || isPtrTOS) { if (isPtrR0 && isPtrTOS) { if (op != OP_MINUS) { Loading @@ -1936,7 +2002,8 @@ class Compiler : public ErrorSink { if (! (op == OP_PLUS || (op == OP_MINUS && isPtrR0))) { error("Unsupported pointer-scalar operation %d", op); } Type* pPtrType = isPtrR0 ? pR0Type : pTOSType; Type* pPtrType = getPointerArithmeticResultType( pR0Type, pTOSType); o(0x59); /* pop %ecx */ int size = sizeOf(pPtrType->pHead); if (size != 1) { Loading Loading @@ -2146,7 +2213,8 @@ class Compiler : public ErrorSink { virtual void loadR0FromR0() { Type* pPointerType = getR0Type(); assert(pPointerType->tag == TY_POINTER); switch (pPointerType->pHead->tag) { TypeTag tag = pPointerType->pHead->tag; switch (tag) { case TY_POINTER: case TY_INT: o2(0x008b); /* mov (%eax), %eax */ Loading @@ -2166,7 +2234,7 @@ class Compiler : public ErrorSink { o2(0x00dd); // fldl (%eax) break; default: error("loadR0FromR0: unsupported type"); error("loadR0FromR0: unsupported type %d", tag); break; } setR0Type(pPointerType->pHead); Loading @@ -2183,14 +2251,32 @@ class Compiler : public ErrorSink { return getPC() - 4; } virtual void convertR0(Type* pType){ virtual void convertR0Imp(Type* pType, bool isCast){ Type* pR0Type = getR0Type(); if (pR0Type == NULL) { assert(false); setR0Type(pType); return; } if (bitsSame(pType, pR0Type)) { if (isPointerType(pType) && isPointerType(pR0Type)) { Type* pA = pR0Type; Type* pB = pType; // Array decays to pointer if (pA->tag == TY_ARRAY && pB->tag == TY_POINTER) { pA = pA->pTail; } if (typeEqual(pA, pB)) { return; // OK } if (pB->pHead->tag == TY_VOID) { return; // convert to void* is OK. } if (pA->tag == TY_POINTER && pB->tag == TY_POINTER && isCast) { return; // OK } error("Incompatible pointer or array types"); } else if (bitsSame(pType, pR0Type)) { // do nothing special } else if (isFloatType(pType) && isFloatType(pR0Type)) { // do nothing special, both held in same register on x87. Loading Loading @@ -2326,6 +2412,11 @@ class Compiler : public ErrorSink { return 1; case TY_SHORT: return 2; case TY_ARRAY: return alignmentOf(pType->pHead); case TY_FUNC: error("alignment of func not supported"); return 1; default: return 4; } Loading @@ -2342,14 +2433,17 @@ class Compiler : public ErrorSink { return 2; case TY_CHAR: return 1; default: return 0; case TY_FLOAT: return 4; case TY_DOUBLE: return 8; case TY_POINTER: return 4; case TY_ARRAY: return pType->length * sizeOf(pType->pHead); default: error("Unsupported type %d", pType->tag); return 0; } } Loading @@ -2361,6 +2455,11 @@ class Compiler : public ErrorSink { switch(pType->tag) { case TY_DOUBLE: return 8; case TY_ARRAY: return sizeOf(pType); case TY_FUNC: error("stackSizeOf func not supported"); return 4; default: return 4; } Loading Loading @@ -3911,7 +4010,7 @@ class Compiler : public ErrorSink { skip(')'); unary(); pGen->forceR0RVal(); pGen->convertR0(pCast); pGen->castR0(pCast); } else { commaExpr(); skip(')'); Loading Loading @@ -3959,10 +4058,18 @@ class Compiler : public ErrorSink { } } // load a variable Type* pVal = createPtrType(pVI->pType); Type* pVal; ExpressionType et; if (pVI->pType->tag == TY_ARRAY) { pVal = pVI->pType; et = ET_RVALUE; } else { pVal = createPtrType(pVI->pType); et = ET_LVALUE; } if (n) { ExpressionType et = ET_LVALUE; if (pVal->pHead->tag == TY_FUNC) { int tag = pVal->pHead->tag; if (tag == TY_FUNC) { et = ET_RVALUE; } pGen->leaR0(n, pVal, et); Loading Loading @@ -4251,6 +4358,8 @@ class Compiler : public ErrorSink { } if (at == TY_POINTER) { return typeEqual(a->pHead, b->pHead); } else if (at == TY_ARRAY) { return a->length == b->length && typeEqual(a->pHead, b->pHead); } else if (at == TY_FUNC || at == TY_PARAM) { return typeEqual(a->pHead, b->pHead) && typeEqual(a->pTail, b->pTail); Loading Loading @@ -4345,6 +4454,9 @@ class Compiler : public ErrorSink { } buffer.append('*'); break; case TY_ARRAY: decodeTypeImpPrefix(buffer, pType->pHead); break; case TY_FUNC: decodeTypeImp(buffer, pType->pHead); break; Loading @@ -4369,6 +4481,13 @@ class Compiler : public ErrorSink { } decodeTypeImpPostfix(buffer, pType->pHead); break; case TY_ARRAY: { String temp; temp.printf("[%d]", pType->length); buffer.append(temp); } break; case TY_FUNC: buffer.append('('); for(Type* pArg = pType->pTail; pArg; pArg = pArg->pTail) { Loading Loading @@ -4418,9 +4537,13 @@ class Compiler : public ErrorSink { nameRequired, reportFailure); if (declName) { // Clone the parent type so we can set a unique ID Type* pOldType = pType; pType = createType(pType->tag, pType->pHead, pType->pTail); pType->id = declName; pType->length = pOldType->length; } else if (nameRequired) { error("Expected a variable name"); } // fprintf(stderr, "Parsed a declaration: "); // printType(pType); Loading Loading @@ -4490,11 +4613,27 @@ class Compiler : public ErrorSink { error("Expected name. Got %s", temp.getUnwrapped()); reportFailure = true; } while (accept('(')) { for(;;) { if (accept('(')) { // Function declaration Type* pTail = acceptArgs(nameAllowed); pType = createType(TY_FUNC, pType, pTail); skip(')'); } if (accept('[')) { if (tok != ']') { if (tok != TOK_NUM || tokc <= 0) { error("Expected positive integer constant"); } else { Type* pDecayType = createPtrType(pType); pType = createType(TY_ARRAY, pType, pDecayType); pType->length = tokc; } next(); } skip(']'); } else { break; } } if (pNewHead) { Loading
libacc/tests/data/array.c 0 → 100644 +77 −0 Original line number Diff line number Diff line // Array allocation tests void testLocalInt() { int a[3]; a[0] = 1; a[1] = 2; a[2] = a[0] + a[1]; printf("localInt: %d\n", a[2]); } char a[3]; double d[3]; void testGlobalChar() { a[0] = 1; a[1] = 2; a[2] = a[0] + a[1]; printf("globalChar: %d\n", a[2]); } void testGlobalDouble() { d[0] = 1; d[1] = 2; d[2] = d[0] + d[1]; printf("globalDouble: %g\n", d[2]); } void testLocalDouble() { double d[3]; float m[12]; m[0] = 1.0f; m[1] = 2.0f; d[0] = 1.0; d[1] = 2.0; d[2] = d[0] + d[1]; m[2] = m[0] + m[1]; printf("localDouble: %g %g\n", d[2], m[2]); } void vectorAdd(int* a, int* b, float* c, int len) { int i; for(i = 0; i < len; i++) { c[i] = a[i] + b[i]; } } void testArgs() { int a[3], b[3]; float c[3]; int i; int len = 3; for(i = 0; i < len; i++) { a[i] = i; b[i] = i; c[i] = 0; } vectorAdd(a,b,c, len); printf("testArgs:"); for(i = 0; i < len; i++) { printf(" %g", c[i]); } printf("\n"); } int main() { testLocalInt(); testLocalDouble(); testGlobalChar(); testGlobalDouble(); testArgs(); return 0; }
libacc/tests/test.py +10 −0 Original line number Diff line number Diff line Loading @@ -385,6 +385,16 @@ result: 0 def testShort(self): self.compileCheck(["-R", "data/short.c"], """Executing compiled code: result: -2 ""","""""") def testArray(self): self.compileCheck(["-R", "data/array.c"], """Executing compiled code: localInt: 3 localDouble: 3 3 globalChar: 3 globalDouble: 3 testArgs: 0 2 4 result: 0 ""","""""") if __name__ == '__main__': Loading