Add support for #pragma foo(bar)

Report unsupported/unknown preprocessor directives.
Report line number of error rather than character offset.
This commit is contained in:
Jack Palevich 2009-06-04 16:23:40 -07:00
parent f4c94943a9
commit eedf9d2083
6 changed files with 658 additions and 44 deletions

View File

@ -69,6 +69,9 @@ void accGetScriptInfoLog(ACCscript* script,
void accGetScriptLabel(ACCscript* script, const ACCchar * name,
ACCvoid** address);
void accGetPragmas(ACCscript* script, ACCsizei* actualStringCount,
ACCsizei maxStringCount, ACCchar** strings);
#ifdef __cplusplus
};
#endif

View File

@ -1039,16 +1039,35 @@ class Compiler : public ErrorSink {
class InputStream {
public:
int getChar() {
if (bumpLine) {
line++;
bumpLine = false;
}
int ch = get();
if (ch == '\n') {
bumpLine = true;
}
return ch;
}
int getLine() {
return line;
}
protected:
InputStream() :
line(1), bumpLine(false) {
}
private:
virtual int get() = 0;
virtual long tell() = 0;
int line;
bool bumpLine;
};
class FileInputStream : public InputStream {
public:
FileInputStream(FILE* in) : f(in) {}
virtual int get() { return fgetc(f); }
virtual long tell() { return ftell(f); }
private:
virtual int get() { return fgetc(f); }
FILE* f;
};
@ -1057,14 +1076,12 @@ class Compiler : public ErrorSink {
TextInputStream(const char* text, size_t textLength)
: pText(text), mTextLength(textLength), mPosition(0) {
}
private:
virtual int get() {
return mPosition < mTextLength ? pText[mPosition++] : EOF;
}
virtual long tell() {
return mPosition;
}
private:
const char* pText;
size_t mTextLength;
size_t mPosition;
@ -1091,14 +1108,83 @@ class Compiler : public ErrorSink {
CodeBuf codeBuf;
CodeGenerator* pGen;
static const int ERROR_BUF_SIZE = 512;
char mErrorBuf[ERROR_BUF_SIZE];
class String {
public:
String() {
mpBase = 0;
mUsed = 0;
mSize = 0;
}
~String() {
if (mpBase) {
free(mpBase);
}
}
char* getUnwrapped() {
return mpBase;
}
void appendCStr(const char* s) {
int n = strlen(s);
memcpy(ensure(n), s, n + 1);
}
void append(char c) {
* ensure(1) = c;
}
void printf(const char* fmt,...) {
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
void vprintf(const char* fmt, va_list ap) {
char* temp;
int numChars = vasprintf(&temp, fmt, ap);
memcpy(ensure(numChars), temp, numChars+1);
free(temp);
}
size_t len() {
return mUsed;
}
private:
char* ensure(int n) {
size_t newUsed = mUsed + n;
if (newUsed > mSize) {
size_t newSize = mSize * 2 + 10;
if (newSize < newUsed) {
newSize = newUsed;
}
mpBase = (char*) realloc(mpBase, newSize + 1);
mSize = newSize;
}
mpBase[newUsed] = '\0';
char* result = mpBase + mUsed;
mUsed = newUsed;
return result;
}
char* mpBase;
size_t mUsed;
size_t mSize;
};
String mErrorBuf;
jmp_buf mErrorRecoveryJumpBuf;
String mPragmas;
int mPragmaStringCount;
static const int ALLOC_SIZE = 99999;
/* depends on the init string */
static const int TOK_STR_SIZE = 48;
// Indentifiers start at 0x100 and increase by # (chars + 1) * 8
static const int TOK_IDENT = 0x100;
static const int TOK_INT = 0x100;
static const int TOK_IF = 0x120;
@ -1107,8 +1193,9 @@ class Compiler : public ErrorSink {
static const int TOK_BREAK = 0x190;
static const int TOK_RETURN = 0x1c0;
static const int TOK_FOR = 0x1f8;
static const int TOK_DEFINE = 0x218;
static const int TOK_MAIN = 0x250;
static const int TOK_PRAGMA = 0x218;
static const int TOK_DEFINE = TOK_PRAGMA + (7*8);
static const int TOK_MAIN = TOK_DEFINE + (7*8);
static const int TOK_DUMMY = 1;
static const int TOK_NUM = 2;
@ -1168,7 +1255,7 @@ class Compiler : public ErrorSink {
ch = dch;
}
} else
ch = file->get();
ch = file->getChar();
/* printf("ch=%c 0x%x\n", ch, ch); */
}
@ -1197,14 +1284,18 @@ class Compiler : public ErrorSink {
pdef(TAG_TOK); /* fill last ident tag */
*(int *) tok = SYM_DEFINE;
*(char* *) (tok + 4) = dstk; /* define stack */
}
/* well we always save the values ! */
while (ch != '\n') {
while (ch != '\n') {
pdef(ch);
inp();
}
pdef(ch);
inp();
pdef(TAG_MACRO);
} else if (tok == TOK_PRAGMA) {
doPragma();
} else {
error("Unsupported preprocessor directive \"%s\"", last_id);
}
pdef(ch);
pdef(TAG_MACRO);
}
inp();
}
@ -1321,23 +1412,54 @@ class Compiler : public ErrorSink {
#endif
}
void doPragma() {
// # pragma name(val)
int state = 0;
while(ch != EOF && ch != '\n' && state < 10) {
switch(state) {
case 0:
if (isspace(ch)) {
inp();
} else {
state++;
}
break;
case 1:
if (isalnum(ch)) {
mPragmas.append(ch);
inp();
} else if (ch == '(') {
mPragmas.append(0);
inp();
state++;
} else {
state = 11;
}
break;
case 2:
if (isalnum(ch)) {
mPragmas.append(ch);
inp();
} else if (ch == ')') {
mPragmas.append(0);
inp();
state = 10;
} else {
state = 11;
}
break;
}
}
if(state != 10) {
error("Unexpected pragma syntax");
}
mPragmaStringCount += 2;
}
virtual void verror(const char* fmt, va_list ap) {
char* pBase = mErrorBuf;
int bytesLeft = sizeof(mErrorBuf);
int bytesAdded = snprintf(pBase, bytesLeft, "%ld: ", file->tell());
bytesLeft -= bytesAdded;
pBase += bytesAdded;
if (bytesLeft > 0) {
bytesAdded = vsnprintf(pBase, bytesLeft, fmt, ap);
bytesLeft -= bytesAdded;
pBase += bytesAdded;
}
if (bytesLeft > 0) {
bytesAdded = snprintf(pBase, bytesLeft, "\n");
bytesLeft -= bytesAdded;
pBase += bytesAdded;
}
mErrorBuf.printf("%ld: ", file->getLine());
mErrorBuf.vprintf(fmt, ap);
mErrorBuf.printf("\n");
longjmp(mErrorRecoveryJumpBuf, 1);
}
@ -1680,7 +1802,7 @@ class Compiler : public ErrorSink {
pGlobalBase = 0;
pVarsBase = 0;
pGen = 0;
mErrorBuf[0] = 0;
mPragmaStringCount = 0;
}
void setArchitecture(const char* architecture) {
@ -1745,9 +1867,10 @@ public:
pGen->init(&codeBuf);
file = new TextInputStream(text, textLength);
sym_stk = (char*) calloc(1, ALLOC_SIZE);
dstk = strcpy(sym_stk,
" int if else while break return for define main ")
+ TOK_STR_SIZE;
static const char* predefinedSymbols =
" int if else while break return for pragma define main ";
dstk = strcpy(sym_stk, predefinedSymbols)
+ strlen(predefinedSymbols);
pGlobalBase = (char*) calloc(1, ALLOC_SIZE);
glo = pGlobalBase;
pVarsBase = (char*) calloc(1, ALLOC_SIZE);
@ -1810,8 +1933,26 @@ public:
return NULL;
}
void getPragmas(ACCsizei* actualStringCount,
ACCsizei maxStringCount, ACCchar** strings) {
int stringCount = mPragmaStringCount;
if (actualStringCount) {
*actualStringCount = stringCount;
}
if (stringCount > maxStringCount) {
stringCount = maxStringCount;
}
if (strings) {
char* pPragmas = mPragmas.getUnwrapped();
while (stringCount-- > 0) {
*strings++ = pPragmas;
pPragmas += strlen(pPragmas) + 1;
}
}
}
char* getErrorMessage() {
return mErrorBuf;
return mErrorBuf.getUnwrapped();
}
};
@ -1988,5 +2129,12 @@ void accGetScriptLabel(ACCscript* script, const ACCchar * name,
}
}
extern "C"
void accGetPragmas(ACCscript* script, ACCsizei* actualStringCount,
ACCsizei maxStringCount, ACCchar** strings){
script->compiler.getPragmas(actualStringCount, maxStringCount, strings);
}
} // namespace acc

View File

@ -0,0 +1,446 @@
// #include <stdio.h>
#define k *(int*)
#define a if(
#define c ad()
#define i else
#define p while(
#define x *(char*)
#define b ==
#define V =calloc(1,99999)
#define f ()
#define J return
#define l ae(
#define n e)
#define u d!=
#define F int
#define y (j)
#define r m=
#define t +4
F d,z,C,h,P,K,ac,q,G,v,Q,R,D,L,W,M;
E(n{
x D++=e;
}
o f{
a L){
h=x L++;
a h b 2){
L=0;
h=W;
}
}
i h=fgetc(Q);
}
X f{
J isalnum(h)|h b 95;
}
Y f{
a h b 92){
o f;
a h b 110)h=10;
}
}
c{
F e,j,m;
p isspace(h)|h b 35){
a h b 35){
o f;
c;
a d b 536){
c;
E(32);
k d=1;
k(d t)=D;
}
p h!=10){
E(h);
o f;
}
E(h);
E(2);
}
o f;
}
C=0;
d=h;
a X f){
E(32);
M=D;
p X f){
E(h);
o f;
}
a isdigit(d)){
z=strtol(M,0,0);
d=2;
}
i{
x D=32;
d=strstr(R,M-1)-R;
x D=0;
d=d*8+256;
a d>536){
d=P+d;
a k d b 1){
L=k(d t);
W=h;
o f;
c;
}
}
}
}
i{
o f;
a d b 39){
d=2;
Y f;
z=h;
o f;
o f;
}
i a d b 47&h b 42){
o f;
p h){
p h!=42)o f;
o f;
a h b 47)h=0;
}
o f;
c;
}
i{
e="++#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";
p j=x e++){
r x e++;
z=0;
p(C=x e++-98)<0)z=z*64+C+64;
a j b d&(m b h|m b 64)){
a m b h){
o f;
d=1;
}
break;
}
}
}
}
}
l g){
p g&&g!=-1){
x q++=g;
g=g>>8;
}
}
A(n{
F g;
p n{
g=k e;
k e=q-e-4;
e=g;
}
}
s(g,n{
l g);
k q=e;
e=q;
q=q t;
J e;
}
H(n{
s(184,n;
}
B(n{
J s(233,n;
}
S(j,n{
l 1032325);
J s(132+j,n;
}
Z(n{
l 49465);
H(0);
l 15);
l e+144);
l 192);
}
N(j,n{
l j+131);
s((e<512)<<7|5,n;
}
T y{
F g,e,m,aa;
g=1;
a d b 34){
H(v);
p h!=34){
Y f;
x v++=h;
o f;
}
x v=0;
v=v t&-4;
o f;
c;
}
i{
aa=C;
r z;
e=d;
c;
a e b 2){
H(m);
}
i a aa b 2){
T(0);
s(185,0);
a e b 33)Z(m);
i l m);
}
i a e b 40){
w f;
c;
}
i a e b 42){
c;
e=d;
c;
c;
a d b 42){
c;
c;
c;
c;
e=0;
}
c;
T(0);
a d b 61){
c;
l 80);
w f;
l 89);
l 392+(e b 256));
}
i a n{
a e b 256)l 139);
i l 48655);
q++;
}
}
i a e b 38){
N(10,k d);
c;
}
i{
g=k e;
a!g)g=dlsym(0,M);
a d b 61&j){
c;
w f;
N(6,g);
}
i a u 40){
N(8,g);
a C b 11){
N(0,g);
l z);
c;
}
}
}
}
a d b 40){
a g b 1)l 80);
r s(60545,0);
c;
j=0;
p u 41){
w f;
s(2393225,j);
a d b 44)c;
j=j t;
}
k r j;
c;
a!g){
e=e t;
k e=s(232,k n;
}
i a g b 1){
s(2397439,j);
j=j t;
}
i{
s(232,g-q-5);
}
a j)s(50305,j);
}
}
O y{
F e,g,m;
a j--b 1)T(1);
i{
O y;
r 0;
p j b C){
g=d;
e=z;
c;
a j>8){
r S(e,m);
O y;
}
i{
l 80);
O y;
l 89);
a j b 4|j b 5){
Z(n;
}
i{
l n;
a g b 37)l 146);
}
}
}
a m&&j>8){
r S(e,m);
H(e^1);
B(5);
A(m);
H(n;
}
}
}
w f{
O(11);
}
U f{
w f;
J S(0,0);
}
I y{
F m,g,e;
a d b 288){
c;
c;
r U f;
c;
I y;
a d b 312){
c;
g=B(0);
A(m);
I y;
A(g);
}
i{
A(m);
}
}
i a d b 352|d b 504){
e=d;
c;
c;
a e b 352){
g=q;
r U f;
}
i{
a u 59)w f;
c;
g=q;
r 0;
a u 59)r U f;
c;
a u 41){
e=B(0);
w f;
B(g-q-5);
A(n;
g=e t;
}
}
c;
I(&m);
B(g-q-5);
A(m);
}
i a d b 123){
c;
ab(1);
p u 125)I y;
c;
}
i{
a d b 448){
c;
a u 59)w f;
K=B(K);
}
i a d b 400){
c;
k j=B(k j);
}
i a u 59)w f;
c;
}
}
ab y{
F m;
p d b 256|u-1&!j){
a d b 256){
c;
p u 59){
a j){
G=G t;
k d=-G;
}
i{
k d=v;
v=v t;
}
c;
a d b 44)c;
}
c;
}
i{
A(k(d t));
k d=q;
c;
c;
r 8;
p u 41){
k d=m;
r m t;
c;
a d b 44)c;
}
c;
K=G=0;
l 15042901);
r s(60545,0);
I(0);
A(K);
l 50121);
k r G;
}
}
}
main(g,n{
Q=stdin;
a g-->1){
e=e t;
Q=fopen(k e,"r");
}
D=strcpy(R V," int if else while break return for define main ")+48;
v V;
q=ac V;
P V;
o f;
c;
ab(0);
J(*(int(*)f)k(P+592))(g,n;
}

View File

@ -1,3 +1,7 @@
#pragma foo3(bar) //sdfsfd
#pragma a(b)
main() {
return 42;
}
}

View File

@ -86,10 +86,23 @@ int main(int argc, char** argv) {
if (result != 0) {
char buf[1024];
accGetScriptInfoLog(script, sizeof(buf), NULL, buf);
fprintf(stderr, "%ss", buf);
fprintf(stderr, "%s", buf);
goto exit;
}
{
ACCsizei numPragmaStrings;
accGetPragmas(script, &numPragmaStrings, 0, NULL);
if (numPragmaStrings) {
char** strings = new char*[numPragmaStrings];
accGetPragmas(script, NULL, numPragmaStrings, strings);
for(ACCsizei i = 0; i < numPragmaStrings; i += 2) {
fprintf(stderr, "#pragma %s(%s)\n", strings[i], strings[i+1]);
}
delete[] strings;
}
}
accGetScriptLabel(script, "main", (ACCvoid**) & mainPointer);
result = accGetError(script);

View File

@ -8,8 +8,8 @@ if [ -x "test-acc" ]; then
if [ "$(uname)" = "Linux" ]; then
if [ "$(uname -m)" = "i686" ]; then
echo "Linux i686. Testing otcc.c"
./test-acc data/otcc.c data/otcc.c data/returnval.c
echo "Linux i686. Testing otcc-noinclude.c"
./test-acc data/otcc-noinclude.c data/otcc.c data/returnval.c
fi
fi
fi