Loading libacc/acc.cpp +85 −48 Original line number Diff line number Diff line Loading @@ -3425,6 +3425,17 @@ class Compiler : public ErrorSink { return isalnum(ch) | (ch == '_'); } int decodeHex(int c) { if (isdigit(c)) { c -= '0'; } else if (c <= 'F') { c = c - 'A' + 10; } else { c =c - 'a' + 10; } return c; } /* read a character constant, advances ch to after end of constant */ int getq() { int val = ch; Loading @@ -3448,15 +3459,7 @@ class Compiler : public ErrorSink { } else { val = 0; while (isxdigit(ch)) { int d = ch; if (isdigit(d)) { d -= '0'; } else if (d <= 'F') { d = d - 'A' + 10; } else { d = d - 'a' + 10; } val = (val << 4) + d; val = (val << 4) + decodeHex(ch); inp(); } } Loading Loading @@ -3535,30 +3538,33 @@ class Compiler : public ErrorSink { void parseFloat() { tok = TOK_NUM_DOUBLE; // mTokenString already has the integral part of the number. if(mTokenString.len() == 0) { mTokenString.append('0'); } acceptCh('.'); acceptDigitsCh(); bool doExp = true; if (acceptCh('e') || acceptCh('E')) { // Don't need to do any extra work } else if (ch == 'f' || ch == 'F') { pdef('e'); // So it can be parsed by strtof. inp(); tok = TOK_NUM_FLOAT; } else { doExp = false; } if (doExp) { bool digitsRequired = acceptCh('-'); bool digitsFound = acceptDigitsCh(); if (digitsRequired && ! digitsFound) { error("malformed exponent"); acceptCh('-') || acceptCh('+'); acceptDigitsCh(); } if (ch == 'f' || ch == 'F') { tok = TOK_NUM_FLOAT; inp(); } else if (ch == 'l' || ch == 'L') { inp(); error("Long floating point constants not supported."); } char* pText = mTokenString.getUnwrapped(); char* pEnd = pText + strlen(pText); char* pEndPtr = 0; errno = 0; if (tok == TOK_NUM_FLOAT) { tokd = strtof(pText, 0); tokd = strtof(pText, &pEndPtr); } else { tokd = strtod(pText, 0); tokd = strtod(pText, &pEndPtr); } if (errno || pEndPtr != pEnd) { error("Can't parse constant: %s", pText); } // fprintf(stderr, "float constant: %s (%d) %g\n", pText, tok, tokd); } Loading @@ -3584,26 +3590,58 @@ class Compiler : public ErrorSink { tokl = 0; tok = ch; /* encode identifiers & numbers */ if (isid()) { if (isdigit(ch) || ch == '.') { // Start of a numeric constant. Could be integer, float, or // double, won't know until we look further. mTokenString.clear(); while (isid()) { pdef(ch); inp(); int base = 10; if (tok == '0') { if (ch == 'x' || ch == 'X') { base = 16; tok = TOK_NUM; tokc = 0; inp(); while ( isxdigit(ch) ) { tokc = (tokc << 4) + decodeHex(ch); inp(); } if (isdigit(tok)) { // Start of a numeric constant. Could be integer, float, or // double, won't know until we look further. if (ch == '.' || ch == 'e' || ch == 'e' || ch == 'f' || ch == 'F') { } else if (isoctal(ch)){ base = 8; tok = TOK_NUM; tokc = 0; while ( isoctal(ch) ) { tokc = (tokc << 3) + (ch - '0'); inp(); } } } else if (isdigit(tok)){ acceptDigitsCh(); } if (base == 10) { if (tok == '.' || ch == '.' || ch == 'e' || ch == 'E') { parseFloat(); } else { // It's an integer constant tokc = strtol(mTokenString.getUnwrapped(), 0, 0); char* pText = mTokenString.getUnwrapped(); char* pEnd = pText + strlen(pText); char* pEndPtr = 0; errno = 0; tokc = strtol(pText, &pEndPtr, base); if (errno || pEndPtr != pEnd) { error("Can't parse constant: %s %d %d", pText, base, errno); } tok = TOK_NUM; } } else { tok = mTokenTable.intern(mTokenString.getUnwrapped(), mTokenString.len()); } } else if (isid()) { mTokenString.clear(); while (isid()) { pdef(ch); inp(); } tok = mTokenTable.intern(mTokenString.getUnwrapped(), mTokenString.len()); // Is this a macro? char* pMacroDefinition = mTokenTable[tok].mpMacroDefinition; if (pMacroDefinition) { Loading @@ -3613,7 +3651,6 @@ class Compiler : public ErrorSink { inp(); next(); } } } else { inp(); if (tok == '\'') { Loading libacc/tests/data/float.c +6 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,11 @@ double itod(int i) { float f0, f1; double d0, d1; void testParseConsts() { printf("Constants: %g %g %g %g %g %g %g %g %g\n", 0e1, 0E1, 0.f, .01f, .01e0f, 1.0e-1, 1.0e1, 1.0e+1, .1f); } void testVars(float arg0, float arg1, double arg2, double arg3) { float local0, local1; double local2, local3; Loading @@ -41,6 +46,7 @@ void testVars(float arg0, float arg1, double arg2, double arg3) { } int main() { testParseConsts(); printf("int: %d float: %g double: %g\n", 1, 2.2f, 3.3); printf(" ftoi(1.4f)=%d\n", ftoi(1.4f)); printf(" dtoi(2.4)=%d\n", dtoi(2.4)); Loading libacc/tests/test.py +12 −1 Original line number Diff line number Diff line Loading @@ -174,7 +174,18 @@ class TestACC(unittest.TestCase): def testRunFloat(self): self.compileCheck(["-R", "data/float.c"], "Executing compiled code:\nresult: 0\n", "int: 1 float: 2.2 double: 3.3\n ftoi(1.4f)=1\n dtoi(2.4)=2\n itof(3)=3\n itod(4)=4\nglobals: 1 2 3 4\nargs: 1 2 3 4\nlocals: 1 2 3 4\ncast rval: 2 4\ncast lval: 1.1 2 3.3 4\n") """Constants: 0 0 0 0.01 0.01 0.1 10 10 0.1 int: 1 float: 2.2 double: 3.3 ftoi(1.4f)=1 dtoi(2.4)=2 itof(3)=3 itod(4)=4 globals: 1 2 3 4 args: 1 2 3 4 locals: 1 2 3 4 cast rval: 2 4 cast lval: 1.1 2 3.3 4 """) def testRunFlops(self): self.compileCheck(["-R", "data/flops.c"], Loading Loading
libacc/acc.cpp +85 −48 Original line number Diff line number Diff line Loading @@ -3425,6 +3425,17 @@ class Compiler : public ErrorSink { return isalnum(ch) | (ch == '_'); } int decodeHex(int c) { if (isdigit(c)) { c -= '0'; } else if (c <= 'F') { c = c - 'A' + 10; } else { c =c - 'a' + 10; } return c; } /* read a character constant, advances ch to after end of constant */ int getq() { int val = ch; Loading @@ -3448,15 +3459,7 @@ class Compiler : public ErrorSink { } else { val = 0; while (isxdigit(ch)) { int d = ch; if (isdigit(d)) { d -= '0'; } else if (d <= 'F') { d = d - 'A' + 10; } else { d = d - 'a' + 10; } val = (val << 4) + d; val = (val << 4) + decodeHex(ch); inp(); } } Loading Loading @@ -3535,30 +3538,33 @@ class Compiler : public ErrorSink { void parseFloat() { tok = TOK_NUM_DOUBLE; // mTokenString already has the integral part of the number. if(mTokenString.len() == 0) { mTokenString.append('0'); } acceptCh('.'); acceptDigitsCh(); bool doExp = true; if (acceptCh('e') || acceptCh('E')) { // Don't need to do any extra work } else if (ch == 'f' || ch == 'F') { pdef('e'); // So it can be parsed by strtof. inp(); tok = TOK_NUM_FLOAT; } else { doExp = false; } if (doExp) { bool digitsRequired = acceptCh('-'); bool digitsFound = acceptDigitsCh(); if (digitsRequired && ! digitsFound) { error("malformed exponent"); acceptCh('-') || acceptCh('+'); acceptDigitsCh(); } if (ch == 'f' || ch == 'F') { tok = TOK_NUM_FLOAT; inp(); } else if (ch == 'l' || ch == 'L') { inp(); error("Long floating point constants not supported."); } char* pText = mTokenString.getUnwrapped(); char* pEnd = pText + strlen(pText); char* pEndPtr = 0; errno = 0; if (tok == TOK_NUM_FLOAT) { tokd = strtof(pText, 0); tokd = strtof(pText, &pEndPtr); } else { tokd = strtod(pText, 0); tokd = strtod(pText, &pEndPtr); } if (errno || pEndPtr != pEnd) { error("Can't parse constant: %s", pText); } // fprintf(stderr, "float constant: %s (%d) %g\n", pText, tok, tokd); } Loading @@ -3584,26 +3590,58 @@ class Compiler : public ErrorSink { tokl = 0; tok = ch; /* encode identifiers & numbers */ if (isid()) { if (isdigit(ch) || ch == '.') { // Start of a numeric constant. Could be integer, float, or // double, won't know until we look further. mTokenString.clear(); while (isid()) { pdef(ch); inp(); int base = 10; if (tok == '0') { if (ch == 'x' || ch == 'X') { base = 16; tok = TOK_NUM; tokc = 0; inp(); while ( isxdigit(ch) ) { tokc = (tokc << 4) + decodeHex(ch); inp(); } if (isdigit(tok)) { // Start of a numeric constant. Could be integer, float, or // double, won't know until we look further. if (ch == '.' || ch == 'e' || ch == 'e' || ch == 'f' || ch == 'F') { } else if (isoctal(ch)){ base = 8; tok = TOK_NUM; tokc = 0; while ( isoctal(ch) ) { tokc = (tokc << 3) + (ch - '0'); inp(); } } } else if (isdigit(tok)){ acceptDigitsCh(); } if (base == 10) { if (tok == '.' || ch == '.' || ch == 'e' || ch == 'E') { parseFloat(); } else { // It's an integer constant tokc = strtol(mTokenString.getUnwrapped(), 0, 0); char* pText = mTokenString.getUnwrapped(); char* pEnd = pText + strlen(pText); char* pEndPtr = 0; errno = 0; tokc = strtol(pText, &pEndPtr, base); if (errno || pEndPtr != pEnd) { error("Can't parse constant: %s %d %d", pText, base, errno); } tok = TOK_NUM; } } else { tok = mTokenTable.intern(mTokenString.getUnwrapped(), mTokenString.len()); } } else if (isid()) { mTokenString.clear(); while (isid()) { pdef(ch); inp(); } tok = mTokenTable.intern(mTokenString.getUnwrapped(), mTokenString.len()); // Is this a macro? char* pMacroDefinition = mTokenTable[tok].mpMacroDefinition; if (pMacroDefinition) { Loading @@ -3613,7 +3651,6 @@ class Compiler : public ErrorSink { inp(); next(); } } } else { inp(); if (tok == '\'') { Loading
libacc/tests/data/float.c +6 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,11 @@ double itod(int i) { float f0, f1; double d0, d1; void testParseConsts() { printf("Constants: %g %g %g %g %g %g %g %g %g\n", 0e1, 0E1, 0.f, .01f, .01e0f, 1.0e-1, 1.0e1, 1.0e+1, .1f); } void testVars(float arg0, float arg1, double arg2, double arg3) { float local0, local1; double local2, local3; Loading @@ -41,6 +46,7 @@ void testVars(float arg0, float arg1, double arg2, double arg3) { } int main() { testParseConsts(); printf("int: %d float: %g double: %g\n", 1, 2.2f, 3.3); printf(" ftoi(1.4f)=%d\n", ftoi(1.4f)); printf(" dtoi(2.4)=%d\n", dtoi(2.4)); Loading
libacc/tests/test.py +12 −1 Original line number Diff line number Diff line Loading @@ -174,7 +174,18 @@ class TestACC(unittest.TestCase): def testRunFloat(self): self.compileCheck(["-R", "data/float.c"], "Executing compiled code:\nresult: 0\n", "int: 1 float: 2.2 double: 3.3\n ftoi(1.4f)=1\n dtoi(2.4)=2\n itof(3)=3\n itod(4)=4\nglobals: 1 2 3 4\nargs: 1 2 3 4\nlocals: 1 2 3 4\ncast rval: 2 4\ncast lval: 1.1 2 3.3 4\n") """Constants: 0 0 0 0.01 0.01 0.1 10 10 0.1 int: 1 float: 2.2 double: 3.3 ftoi(1.4f)=1 dtoi(2.4)=2 itof(3)=3 itod(4)=4 globals: 1 2 3 4 args: 1 2 3 4 locals: 1 2 3 4 cast rval: 2 4 cast lval: 1.1 2 3.3 4 """) def testRunFlops(self): self.compileCheck(["-R", "data/flops.c"], Loading