Merge change 6257
* changes:
resolved conflicts for merge of 72eead43 to master
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index 0d26a5c..0209031 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -1875,9 +1875,15 @@
SymbolStack mGlobals;
SymbolStack mLocals;
+ // Prebuilt types, makes things slightly faster.
Type* mkpInt;
Type* mkpChar;
Type* mkpVoid;
+ Type* mkpFloat;
+ Type* mkpDouble;
+ Type* mkpIntPtr;
+ Type* mkpCharPtr;
+ Type* mkpPtrIntFn;
InputStream* file;
@@ -1995,10 +2001,18 @@
}
}
+ bool isSymbol(tokenid_t t) {
+ return t >= TOK_SYMBOL &&
+ ((size_t) (t-TOK_SYMBOL)) < mTokenTable.size();
+ }
+
+ bool isSymbolOrKeyword(tokenid_t t) {
+ return t >= TOK_KEYWORD &&
+ ((size_t) (t-TOK_KEYWORD)) < mTokenTable.size();
+ }
+
VariableInfo* VI(tokenid_t t) {
- if ( t < TOK_SYMBOL || ((size_t) (t-TOK_SYMBOL)) >= mTokenTable.size()) {
- internalError();
- }
+ assert(isSymbol(t));
VariableInfo* pV = mTokenTable[t].mpVariableInfo;
if (pV && pV->tok != t) {
internalError();
@@ -2010,7 +2024,8 @@
return t >= TOK_SYMBOL && VI(t) != 0;
}
- inline const char* nameof(tokenid_t t) {
+ const char* nameof(tokenid_t t) {
+ assert(isSymbolOrKeyword(t));
return mTokenTable[t].pText;
}
@@ -2324,37 +2339,48 @@
return false;
}
- /* l is one if '=' parsing wanted (quick hack) */
- void unary(intptr_t l) {
- intptr_t n, t, a;
- int c;
- String tString;
- t = 0;
- n = 1; /* type of expression 0 = forward, 1 = value, other = lvalue */
- if (tok == '\"') {
+ bool acceptStringLiteral() {
+ if (tok == '"') {
pGen->li((int) glo);
- while (ch != '\"' && ch != EOF) {
- *allocGlobalSpace(1) = getq();
+ // This while loop merges multiple adjacent string constants.
+ while (tok == '"') {
+ while (ch != '"' && ch != EOF) {
+ *allocGlobalSpace(1) = getq();
+ }
+ if (ch != '"') {
+ error("Unterminated string constant.");
+ }
+ inp();
+ next();
}
- if (ch != '\"') {
- error("Unterminated string constant.");
- }
+ /* Null terminate */
*glo = 0;
/* align heap */
allocGlobalSpace((char*) (((intptr_t) glo + 4) & -4) - glo);
- inp();
- next();
+
+ return true;
+ }
+ return false;
+ }
+ /* Parse and evaluate a unary expression.
+ * allowAssignment is true if '=' parsing wanted (quick hack)
+ */
+ void unary(bool allowAssignment) {
+ intptr_t n, t, a;
+ t = 0;
+ n = 1; /* type of expression 0 = forward, 1 = value, other = lvalue */
+ if (acceptStringLiteral()) {
+ // Nothing else to do.
} else {
- c = tokl;
+ int c = tokl;
a = tokc;
t = tok;
- tString = mTokenString;
next();
if (t == TOK_NUM) {
pGen->li(a);
} else if (c == 2) {
/* -, +, !, ~ */
- unary(0);
+ unary(false);
pGen->clearR1();
if (t == '!')
pGen->gcmp(a);
@@ -2364,23 +2390,29 @@
expr();
skip(')');
} else if (t == '*') {
- /* parse cast */
+ /* This is a pointer dereference, but we currently only
+ * support a pointer dereference if it's immediately
+ * in front of a cast. So parse the cast right here.
+ */
skip('(');
- t = tok; /* get type */
- next(); /* skip int/char/void */
- next(); /* skip '*' or '(' */
- if (tok == '*') {
- /* function type */
- skip('*');
- skip(')');
- skip('(');
- skip(')');
+ Type* pCast = expectCastTypeDeclaration(mLocalArena);
+ // We currently only handle 3 types of cast:
+ // (int*), (char*) , (int (*)())
+ if(typeEqual(pCast, mkpIntPtr)) {
+ t = TOK_INT;
+ } else if (typeEqual(pCast, mkpCharPtr)) {
+ t = TOK_CHAR;
+ } else if (typeEqual(pCast, mkpPtrIntFn)){
t = 0;
+ } else {
+ String buffer;
+ decodeType(buffer, pCast);
+ error("Unsupported cast type %s", buffer.getUnwrapped());
+ decodeType(buffer, mkpPtrIntFn);
}
skip(')');
- unary(0);
- if (tok == '=') {
- next();
+ unary(false);
+ if (accept('=')) {
pGen->pushR0();
expr();
pGen->popR1();
@@ -2388,12 +2420,14 @@
} else if (t) {
pGen->loadR0FromR0(t == TOK_INT);
}
+ // Else we fall through to the function call below, with
+ // t == 0 to trigger an indirect function call. Hack!
} else if (t == '&') {
pGen->leaR0((int) VI(tok)->pAddress);
next();
} else if (t == EOF ) {
error("Unexpected EOF.");
- } else if (!checkSymbol(t, &tString)) {
+ } else if (!checkSymbol(t)) {
// Don't have to do anything special here, the error
// message was printed by checkSymbol() above.
} else {
@@ -2405,11 +2439,10 @@
n = (intptr_t) VI(t)->pAddress;
/* forward reference: try dlsym */
if (!n) {
- n = (intptr_t) dlsym(RTLD_DEFAULT,
- tString.getUnwrapped());
+ n = (intptr_t) dlsym(RTLD_DEFAULT, nameof(t));
VI(t)->pAddress = (void*) n;
}
- if ((tok == '=') & l) {
+ if ((tok == '=') & allowAssignment) {
/* assignment */
next();
expr();
@@ -2417,7 +2450,7 @@
} else if (tok != '(') {
/* variable */
if (!n) {
- error("Undefined variable %s", tString.getUnwrapped());
+ error("Undefined variable %s", nameof(t));
}
pGen->loadR0(n, tokl == 11, tokc);
if (tokl == 11) {
@@ -2435,13 +2468,16 @@
/* push args and invert order */
a = pGen->beginFunctionCallArguments();
next();
- l = 0;
+ int l = 0;
while (tok != ')' && tok != EOF) {
expr();
pGen->storeR0ToArg(l);
- if (tok == ',')
- next();
l = l + 4;
+ if (accept(',')) {
+ // fine
+ } else if ( tok != ')') {
+ error("Expected ',' or ')'");
+ }
}
pGen->endFunctionCallArguments(a, l);
skip(')');
@@ -2458,28 +2494,30 @@
}
}
- void sum(int l) {
+ /* Recursive descent parser for binary operations.
+ */
+ void binaryOp(int level) {
intptr_t t, n, a;
t = 0;
- if (l-- == 1)
- unary(1);
+ if (level-- == 1)
+ unary(true);
else {
- sum(l);
+ binaryOp(level);
a = 0;
- while (l == tokl) {
+ while (level == tokl) {
n = tok;
t = tokc;
next();
- if (l > 8) {
+ if (level > 8) {
a = pGen->gtst(t == OP_LOGICAL_OR, a); /* && and || output code generation */
- sum(l);
+ binaryOp(level);
} else {
pGen->pushR0();
- sum(l);
+ binaryOp(level);
pGen->popR1();
- if ((l == 4) | (l == 5)) {
+ if ((level == 4) | (level == 5)) {
pGen->gcmp(t);
} else {
pGen->genOp(t);
@@ -2487,7 +2525,7 @@
}
}
/* && and || output code generation */
- if (a && l > 8) {
+ if (a && level > 8) {
a = pGen->gtst(t == OP_LOGICAL_OR, a);
pGen->li(t != OP_LOGICAL_OR);
pGen->gjmp(5); /* jmp $ + 5 (sizeof li, FIXME for ARM) */
@@ -2498,7 +2536,7 @@
}
void expr() {
- sum(11);
+ binaryOp(11);
}
int test_expr() {
@@ -2509,9 +2547,10 @@
void block(intptr_t l, bool outermostFunctionBlock) {
intptr_t a, n, t;
- if (tok == TOK_INT || tok == TOK_CHAR) {
+ Type* pBaseType;
+ if ((pBaseType = acceptPrimitiveType(mLocalArena))) {
/* declarations */
- localDeclarations();
+ localDeclarations(pBaseType);
} else if (tok == TOK_IF) {
next();
skip('(');
@@ -2567,13 +2606,11 @@
mLocals.popLevel();
}
} else {
- if (tok == TOK_RETURN) {
- next();
+ if (accept(TOK_RETURN)) {
if (tok != ';')
expr();
rsym = pGen->gjmp(rsym); /* jmp */
- } else if (tok == TOK_BREAK) {
- next();
+ } else if (accept(TOK_BREAK)) {
*(int *) l = pGen->gjmp(*(int *) l);
} else if (tok != ';')
expr();
@@ -2582,7 +2619,8 @@
}
enum TypeTag {
- TY_INT, TY_CHAR, TY_VOID, TY_POINTER, TY_FUNC, TY_PARAM
+ TY_INT, TY_CHAR, TY_VOID, TY_FLOAT, TY_DOUBLE,
+ TY_POINTER, TY_FUNC, TY_PARAM
};
struct Type {
@@ -2592,6 +2630,26 @@
Type* pTail;
};
+ bool typeEqual(Type* a, Type* b) {
+ if (a == b) {
+ return true;
+ }
+ if (a == NULL || b == NULL) {
+ return false;
+ }
+ TypeTag at = a->tag;
+ if (at != b->tag) {
+ return false;
+ }
+ if (at == TY_POINTER) {
+ return typeEqual(a->pHead, b->pHead);
+ } else if (at == TY_FUNC || at == TY_PARAM) {
+ return typeEqual(a->pHead, b->pHead)
+ && typeEqual(a->pTail, b->pTail);
+ }
+ return true;
+ }
+
Type* createType(TypeTag tag, Type* pHead, Type* pTail, Arena& arena) {
assert(tag >= TY_INT && tag <= TY_PARAM);
Type* pType = (Type*) arena.alloc(sizeof(Type));
@@ -2602,43 +2660,83 @@
return pType;
}
+ Type* createPtrType(Type* pType, Arena& arena) {
+ return createType(TY_POINTER, pType, NULL, arena);
+ }
+
+ /**
+ * Try to print a type in declaration order
+ */
void decodeType(String& buffer, Type* pType) {
+ buffer.clear();
if (pType == NULL) {
buffer.appendCStr("null");
return;
}
- buffer.append('(');
+ decodeTypeImp(buffer, pType);
+ }
+
+ void decodeTypeImp(String& buffer, Type* pType) {
+ decodeTypeImpPrefix(buffer, pType);
+
String temp;
if (pType->id != 0) {
decodeToken(temp, pType->id);
buffer.append(temp);
+ }
+
+ decodeTypeImpPostfix(buffer, pType);
+ }
+
+ void decodeTypeImpPrefix(String& buffer, Type* pType) {
+ TypeTag tag = pType->tag;
+
+ if (tag >= TY_INT && tag <= TY_VOID) {
+ switch (tag) {
+ case TY_INT:
+ buffer.appendCStr("int");
+ break;
+ case TY_CHAR:
+ buffer.appendCStr("char");
+ break;
+ case TY_VOID:
+ buffer.appendCStr("void");
+ break;
+ case TY_FLOAT:
+ buffer.appendCStr("float");
+ break;
+ case TY_DOUBLE:
+ buffer.appendCStr("double");
+ break;
+ default:
+ break;
+ }
buffer.append(' ');
}
- bool printHead = false;
- bool printTail = false;
- switch (pType->tag) {
+
+ switch (tag) {
case TY_INT:
- buffer.appendCStr("int");
break;
case TY_CHAR:
- buffer.appendCStr("char");
break;
case TY_VOID:
- buffer.appendCStr("void");
+ break;
+ case TY_FLOAT:
+ break;
+ case TY_DOUBLE:
break;
case TY_POINTER:
- buffer.appendCStr("*");
- printHead = true;
+ decodeTypeImpPrefix(buffer, pType->pHead);
+ if(pType->pHead && pType->pHead->tag == TY_FUNC) {
+ buffer.append('(');
+ }
+ buffer.append('*');
break;
case TY_FUNC:
- buffer.appendCStr("func");
- printHead = true;
- printTail = true;
+ decodeTypeImp(buffer, pType->pHead);
break;
case TY_PARAM:
- buffer.appendCStr("param");
- printHead = true;
- printTail = true;
+ decodeTypeImp(buffer, pType->pHead);
break;
default:
String temp;
@@ -2646,15 +2744,31 @@
buffer.append(temp);
break;
}
- if (printHead) {
- buffer.append(' ');
- decodeType(buffer, pType->pHead);
+ }
+
+ void decodeTypeImpPostfix(String& buffer, Type* pType) {
+ TypeTag tag = pType->tag;
+
+ switch(tag) {
+ case TY_POINTER:
+ if(pType->pHead && pType->pHead->tag == TY_FUNC) {
+ buffer.append(')');
+ }
+ decodeTypeImpPostfix(buffer, pType->pHead);
+ break;
+ case TY_FUNC:
+ buffer.append('(');
+ for(Type* pArg = pType->pTail; pArg; pArg = pArg->pTail) {
+ decodeTypeImp(buffer, pArg);
+ if (pArg->pTail) {
+ buffer.appendCStr(", ");
+ }
+ }
+ buffer.append(')');
+ break;
+ default:
+ break;
}
- if (printTail) {
- buffer.append(' ');
- decodeType(buffer, pType->pTail);
- }
- buffer.append(')');
}
void printType(Type* pType) {
@@ -2671,6 +2785,10 @@
pType = mkpChar;
} else if (tok == TOK_VOID) {
pType = mkpVoid;
+ } else if (tok == TOK_FLOAT) {
+ pType = mkpFloat;
+ } else if (tok == TOK_DOUBLE) {
+ pType = mkpDouble;
} else {
return NULL;
}
@@ -2678,60 +2796,108 @@
return pType;
}
- Type* acceptDeclaration(const Type* pBaseType, Arena& arena) {
- Type* pType = createType(pBaseType->tag, pBaseType->pHead,
- pBaseType->pTail, arena);
- tokenid_t declName;
- if (pType) {
- pType = acceptDecl2(pType, declName, arena);
+ Type* acceptDeclaration(Type* pType, bool nameAllowed, bool nameRequired,
+ Arena& arena) {
+ tokenid_t declName = 0;
+ pType = acceptDecl2(pType, declName, nameAllowed,
+ nameRequired, arena);
+ if (declName) {
+ // Clone the parent type so we can set a unique ID
+ pType = createType(pType->tag, pType->pHead,
+ pType->pTail, arena);
+
pType->id = declName;
- // fprintf(stderr, "Parsed a declaration: ");
- // printType(pType);
}
+ // fprintf(stderr, "Parsed a declaration: ");
+ // printType(pType);
return pType;
}
- Type* expectDeclaration(const Type* pBaseType, Arena& arena) {
- Type* pType = acceptDeclaration(pBaseType, arena);
+ Type* expectDeclaration(Type* pBaseType, Arena& arena) {
+ Type* pType = acceptDeclaration(pBaseType, true, true, arena);
if (! pType) {
error("Expected a declaration");
}
return pType;
}
- Type* acceptDecl2(Type* pType, tokenid_t& declName, Arena& arena) {
- while (tok == '*') {
- pType = createType(TY_POINTER, pType, NULL, arena);
- next();
+ /* Used for accepting types that appear in casts */
+ Type* acceptCastTypeDeclaration(Arena& arena) {
+ Type* pType = acceptPrimitiveType(arena);
+ if (pType) {
+ pType = acceptDeclaration(pType, false, false, arena);
}
- pType = acceptDecl3(pType, declName, arena);
return pType;
}
- Type* acceptDecl3(Type* pType, tokenid_t& declName, Arena& arena) {
- if (accept('(')) {
- pType = acceptDecl2(pType, declName, arena);
- skip(')');
- } else {
- declName = acceptSymbol();
+ Type* expectCastTypeDeclaration(Arena& arena) {
+ Type* pType = acceptCastTypeDeclaration(arena);
+ if (! pType) {
+ error("Expected a declaration");
}
- while (tok == '(') {
+ return pType;
+ }
+
+ Type* acceptDecl2(Type* pType, tokenid_t& declName,
+ bool nameAllowed, bool nameRequired, Arena& arena) {
+ int ptrCounter = 0;
+ while (accept('*')) {
+ ptrCounter++;
+ }
+ pType = acceptDecl3(pType, declName, nameAllowed, nameRequired, arena);
+ while (ptrCounter-- > 0) {
+ pType = createType(TY_POINTER, pType, NULL, arena);
+ }
+ return pType;
+ }
+
+ Type* acceptDecl3(Type* pType, tokenid_t& declName,
+ bool nameAllowed, bool nameRequired, Arena& arena) {
+ // direct-dcl :
+ // name
+ // (dcl)
+ // direct-dcl()
+ // direct-dcl[]
+ Type* pNewHead = NULL;
+ if (accept('(')) {
+ pNewHead = acceptDecl2(pNewHead, declName, nameAllowed,
+ nameRequired, arena);
+ skip(')');
+ } else if ((declName = acceptSymbol()) != 0) {
+ if (nameAllowed == false && declName) {
+ error("Symbol %s not allowed here", nameof(declName));
+ } else if (nameRequired && ! declName) {
+ String temp;
+ decodeToken(temp, tok);
+ error("Expected symbol. Got %s", temp.getUnwrapped());
+ }
+ }
+ while (accept('(')) {
// Function declaration
- skip('(');
- Type* pTail = acceptArgs(arena);
+ Type* pTail = acceptArgs(nameAllowed, arena);
pType = createType(TY_FUNC, pType, pTail, arena);
skip(')');
}
+
+ if (pNewHead) {
+ Type* pA = pNewHead;
+ while (pA->pHead) {
+ pA = pA->pHead;
+ }
+ pA->pHead = pType;
+ pType = pNewHead;
+ }
return pType;
}
- Type* acceptArgs(Arena& arena) {
+ Type* acceptArgs(bool nameAllowed, Arena& arena) {
Type* pHead = NULL;
Type* pTail = NULL;
for(;;) {
Type* pBaseArg = acceptPrimitiveType(arena);
if (pBaseArg) {
- Type* pArg = acceptDeclaration(pBaseArg, arena);
+ Type* pArg = acceptDeclaration(pBaseArg, nameAllowed, false,
+ arena);
if (pArg) {
Type* pParam = createType(TY_PARAM, pArg, NULL, arena);
if (!pHead) {
@@ -2781,11 +2947,10 @@
mLocals.add(pDecl);
}
- void localDeclarations() {
+ void localDeclarations(Type* pBaseType) {
intptr_t a;
- Type* pBaseType;
- while ((pBaseType = acceptPrimitiveType(mLocalArena)) != NULL) {
+ while (pBaseType) {
while (tok != ';' && tok != EOF) {
Type* pDecl = expectDeclaration(pBaseType, mLocalArena);
if (!pDecl) {
@@ -2805,11 +2970,12 @@
next();
}
skip(';');
+ pBaseType = acceptPrimitiveType(mLocalArena);
}
}
bool checkSymbol() {
- return checkSymbol(tok, &mTokenString);
+ return checkSymbol(tok);
}
void decodeToken(String& buffer, tokenid_t token) {
@@ -2830,7 +2996,7 @@
}
}
- bool checkSymbol(tokenid_t token, String* pText) {
+ bool checkSymbol(tokenid_t token) {
bool result = token >= TOK_SYMBOL;
if (!result) {
String temp;
@@ -2845,10 +3011,6 @@
if (tok >= TOK_SYMBOL) {
result = tok;
next();
- } else {
- String temp;
- decodeToken(temp, tok);
- error("Expected symbol. Got %s", temp.getUnwrapped());
}
return result;
}
@@ -2901,31 +3063,35 @@
skip(';');
} else {
// Function declaration
- if (name) {
- /* patch forward references (XXX: does not work for function
- pointers) */
- pGen->gsym((int) name->pForward);
- /* put function address */
- name->pAddress = (void*) codeBuf.getPC();
+ if (accept(';')) {
+ // forward declaration.
+ } else {
+ if (name) {
+ /* patch forward references (XXX: does not work for function
+ pointers) */
+ pGen->gsym((int) name->pForward);
+ /* put function address */
+ name->pAddress = (void*) codeBuf.getPC();
+ }
+ // Calculate stack offsets for parameters
+ mLocals.pushLevel();
+ intptr_t a = 8;
+ int argCount = 0;
+ for (Type* pP = pDecl->pTail; pP; pP = pP->pTail) {
+ Type* pArg = pP->pHead;
+ addLocalSymbol(pArg);
+ /* read param name and compute offset */
+ VI(pArg->id)->pAddress = (void*) a;
+ a = a + 4;
+ argCount++;
+ }
+ rsym = loc = 0;
+ a = pGen->functionEntry(argCount);
+ block(0, true);
+ pGen->gsym(rsym);
+ pGen->functionExit(argCount, a, loc);
+ mLocals.popLevel();
}
- // Calculate stack offsets for parameters
- mLocals.pushLevel();
- intptr_t a = 8;
- int argCount = 0;
- for (Type* pP = pDecl->pTail; pP; pP = pP->pTail) {
- Type* pArg = pP->pHead;
- addLocalSymbol(pArg);
- /* read param name and compute offset */
- VI(pArg->id)->pAddress = (void*) a;
- a = a + 4;
- argCount++;
- }
- rsym = loc = 0;
- a = pGen->functionEntry(argCount);
- block(0, true);
- pGen->gsym(rsym);
- pGen->functionExit(argCount, a, loc);
- mLocals.popLevel();
}
}
}
@@ -3064,6 +3230,13 @@
mkpInt = createType(TY_INT, NULL, NULL, mGlobalArena);
mkpChar = createType(TY_CHAR, NULL, NULL, mGlobalArena);
mkpVoid = createType(TY_VOID, NULL, NULL, mGlobalArena);
+ mkpFloat = createType(TY_FLOAT, NULL, NULL, mGlobalArena);
+ mkpDouble = createType(TY_DOUBLE, NULL, NULL, mGlobalArena);
+ mkpIntPtr = createPtrType(mkpInt, mGlobalArena);
+ mkpCharPtr = createPtrType(mkpChar, mGlobalArena);
+ mkpPtrIntFn = createPtrType(
+ createType(TY_FUNC, mkpInt, NULL, mGlobalArena),
+ mGlobalArena);
}
void checkForUndefinedForwardReferences() {
diff --git a/libacc/tests/data/double.c b/libacc/tests/data/double.c
new file mode 100644
index 0000000..5bc20a3
--- /dev/null
+++ b/libacc/tests/data/double.c
@@ -0,0 +1,7 @@
+double atof(char *nptr);
+
+int main() {
+ printf("Value = %g\n", atof("10.42"));
+ return 0;
+}
+
diff --git a/libacc/tests/data/testStringConcat.c b/libacc/tests/data/testStringConcat.c
new file mode 100644
index 0000000..bf06ae1
--- /dev/null
+++ b/libacc/tests/data/testStringConcat.c
@@ -0,0 +1,4 @@
+int main() {
+ return printf("Hello" "," " world\n");
+}
+
diff --git a/libacc/tests/test.py b/libacc/tests/test.py
index ef5963b..016c587 100644
--- a/libacc/tests/test.py
+++ b/libacc/tests/test.py
@@ -58,8 +58,15 @@
def compare(a, b):
if a != b:
- firstDiff = firstDifference(a,b)
- print "Strings differ at character", firstDiff, a[firstDiff], b[firstDiff]
+ firstDiff = firstDifference(a, b)
+ print "Strings differ at character %d '%s' != '%s'" % (
+ firstDiff, safeAccess(a, firstDiff), safeAccess(b, firstDiff))
+
+def safeAccess(s, i):
+ if 0 <= i < len(s):
+ return s[i]
+ else:
+ return '?'
def firstDifference(a, b):
commonLen = min(len(a), len(b))
@@ -89,6 +96,11 @@
def testRunReturnVal(self):
self.compileCheck(["-R", "data/returnval-ansi.c"],
"Executing compiled code:\nresult: 42\n")
+
+ def testStingLiteralConcatenation(self):
+ self.compileCheck(["-R", "data/testStringConcat.c"],
+ "Executing compiled code:\nresult: 13\n", "Hello, world\n")
+
def testRunOTCCANSI(self):
self.compileCheck(["-R", "data/otcc-ansi.c", "data/returnval.c"],
"Executing compiled code:\notcc-ansi.c: About to execute compiled code:\natcc-ansi.c: result: 42\nresult: 42\n")