Use a separate table for keywords.
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index e7f95b0..fb4f4f6 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -1204,8 +1204,8 @@
*/
class FakeString : public String {
public:
- FakeString(char* string, size_t length) :
- String(string, length, true) {}
+ FakeString(const char* string, size_t length) :
+ String((char*) string, length, true) {}
~FakeString() {
orphan();
@@ -1220,6 +1220,7 @@
~StringTable() {
clear();
+ hashmapFree(mpMap);
}
void clear() {
@@ -1278,6 +1279,71 @@
MacroTable() : StringTable<String>(10) {}
};
+ class KeywordTable {
+ public:
+
+ KeywordTable(){
+ mpMap = hashmapCreate(40, hashFn, equalsFn);
+ put("int", TOK_INT);
+ put("char", TOK_CHAR);
+ put("void", TOK_VOID);
+ put("if", TOK_IF);
+ put("else", TOK_ELSE);
+ put("while", TOK_WHILE);
+ put("break", TOK_BREAK);
+ put("return", TOK_RETURN);
+ put("for", TOK_FOR);
+ put("pragma", TOK_PRAGMA);
+ }
+
+ ~KeywordTable() {
+ hashmapFree(mpMap);
+ }
+
+ int get(char* key) {
+ return (int) hashmapGet(mpMap, key);
+ }
+
+ const char* lookupKeyFor(int value) {
+ FindValContext context;
+ context.key = 0;
+ hashmapForEach(mpMap, findKeyFn, &context);
+ return context.key;
+ }
+
+ private:
+ void put(const char* kw, int val) {
+ hashmapPut(mpMap, (void*) kw, (void*) val);
+ }
+
+ static int hashFn(void* pKey) {
+ char* pString = (char*) pKey;
+ return hashmapHash(pString, strlen(pString));
+ }
+
+ static bool equalsFn(void* keyA, void* keyB) {
+ const char* pStringA = (const char*) keyA;
+ const char* pStringB = (const char*) keyB;
+ return strcmp(pStringA, pStringB) == 0;
+ }
+
+ struct FindValContext {
+ char* key;
+ int value;
+ };
+
+ static bool findKeyFn(void* key, void* value, void* context) {
+ FindValContext* pContext = (FindValContext*) context;
+ if ((int) value == pContext->value) {
+ pContext->key = (char*) key;
+ return false;
+ }
+ return true;
+ }
+
+ Hashmap* mpMap;
+ };
+
template<class E> class Array {
public:
Array() {
@@ -1346,6 +1412,11 @@
int oldCh;
};
+ struct VariableInfo {
+ void* pA;
+ void* pB;
+ };
+
int ch; // Current input character, or EOF
intptr_t tok; // token
@@ -1360,7 +1431,8 @@
int dch; // Macro state: Saves old value of ch during a macro playback.
char* last_id;
char* pGlobalBase;
- char* pVarsBase; // Value of variables
+ VariableInfo* pVarsBase; // Value of variables
+ KeywordTable mKeywords;
InputStream* file;
@@ -1377,20 +1449,22 @@
static const int ALLOC_SIZE = 99999;
- // 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_CHAR = TOK_INT + 4*8;
- static const int TOK_VOID = TOK_CHAR + 5*8;
- static const int TOK_IF = TOK_VOID + 5*8;
- static const int TOK_ELSE = TOK_IF + 3*8;
- static const int TOK_WHILE = TOK_ELSE + 5*8;
- static const int TOK_BREAK = TOK_WHILE + 6*8;
- static const int TOK_RETURN = TOK_BREAK + 6*8;
- static const int TOK_FOR = TOK_RETURN + 7*8;
- static const int TOK_PRAGMA = TOK_FOR + 4*8;
- static const int TOK_DEFINE = TOK_PRAGMA + 7*8;
- static const int TOK_MAIN = TOK_DEFINE + 7*8;
+ // Keywords start at 0x100 and increase by 1
+ static const int TOK_KEYWORD = 0x100;
+ static const int TOK_INT = TOK_KEYWORD + 0;
+ static const int TOK_CHAR = TOK_KEYWORD + 1;
+ static const int TOK_VOID = TOK_KEYWORD + 2;
+ static const int TOK_IF = TOK_KEYWORD + 3;
+ static const int TOK_ELSE = TOK_KEYWORD + 4;
+ static const int TOK_WHILE = TOK_KEYWORD + 5;
+ static const int TOK_BREAK = TOK_KEYWORD + 6;
+ static const int TOK_RETURN = TOK_KEYWORD + 7;
+ static const int TOK_FOR = TOK_KEYWORD + 8;
+ static const int TOK_PRAGMA = TOK_KEYWORD + 9;
+ static const int TOK_DEFINE = TOK_KEYWORD + 10;
+
+ // Symbols start at 0x200
+ static const int TOK_SYMBOL = 0x200;
static const int TOK_DUMMY = 1;
static const int TOK_NUM = 2;
@@ -1514,18 +1588,20 @@
inp();
next();
} else {
- * dstk = TAG_TOK; /* no need to mark end of string (we
- suppose data is initialized to zero by calloc) */
- tok = (intptr_t) (strstr(sym_stk, (last_id - 1))
- - sym_stk);
- * dstk = 0; /* mark real end of ident for dlsym() */
- tok = tok * 8 + TOK_IDENT;
- if (tok > TOK_DEFINE) {
- if (tok + 8 > ALLOC_SIZE) {
- error("Variable Table overflow.");
- }
- tok = (intptr_t) (pVarsBase + tok);
- /* printf("tok=%s %x\n", last_id, tok); */
+ // Is this a keyword?
+ * dstk = 0;
+ int kwtok = mKeywords.get(last_id);
+ if (kwtok) {
+ tok = kwtok;
+ // fprintf(stderr, "tok= keyword %s %x\n", last_id, tok);
+ } else {
+ * dstk = TAG_TOK; /* no need to mark end of string (we
+ suppose data is initialized to zero by calloc) */
+ tok = (intptr_t) (strstr(sym_stk, (last_id - 1))
+ - sym_stk);
+ * dstk = 0; /* mark real end of ident for dlsym() */
+ tok = (intptr_t) & (pVarsBase[tok]);
+ // fprintf(stderr, "tok= symbol %s %x\n", last_id, tok);
}
}
}
@@ -1583,15 +1659,19 @@
}
#if 0
{
- char* p;
+ const char* p;
printf("tok=0x%x ", tok);
- if (tok >= TOK_IDENT) {
+ if (tok >= TOK_KEYWORD) {
printf("'");
- if (tok> TOK_DEFINE)
- p = sym_stk + 1 + ((char*) tok - pVarsBase - TOK_IDENT) / 8;
- else
- p = sym_stk + 1 + (tok - TOK_IDENT) / 8;
+ if (tok>= TOK_SYMBOL)
+ p = sym_stk + 1 + ((char*) tok - (char*) pVarsBase) / 8;
+ else {
+ p = mKeywords.lookupKeyFor(tok);
+ if (!p) {
+ p = "unknown keyword";
+ }
+ }
while (*p != TAG_TOK && *p)
printf("%c", *p++);
printf("'\n");
@@ -1979,7 +2059,7 @@
}
void checkSymbol() {
- if (tok <= TOK_DEFINE) {
+ if (tok < TOK_SYMBOL) {
error("Expected a symbol");
}
}
@@ -2174,15 +2254,10 @@
pGen->init(&codeBuf);
file = new TextInputStream(text, textLength);
sym_stk = (char*) calloc(1, ALLOC_SIZE);
- static const char* predefinedSymbols =
- " int char void"
- " if else while break return for"
- " pragma define main ";
- dstk = strcpy(sym_stk, predefinedSymbols)
- + strlen(predefinedSymbols);
+ dstk = sym_stk;
pGlobalBase = (char*) calloc(1, ALLOC_SIZE);
glo = pGlobalBase;
- pVarsBase = (char*) calloc(1, ALLOC_SIZE);
+ pVarsBase = (VariableInfo*) calloc(1, ALLOC_SIZE);
inp();
next();
globalDeclarations();
@@ -2195,16 +2270,6 @@
return result;
}
- int run(int argc, char** argv) {
- typedef int (*mainPtr)(int argc, char** argv);
- mainPtr aMain = (mainPtr) *(int*) (pVarsBase + TOK_MAIN);
- if (!aMain) {
- fprintf(stderr, "Could not find function \"main\".\n");
- return -1;
- }
- return aMain(argc, argv);
- }
-
int dump(FILE* out) {
fwrite(codeBuf.getBase(), 1, codeBuf.getSize(), out);
return 0;
@@ -2233,13 +2298,9 @@
if (memcmp(pSym, name, nameLen) == 0
&& pSym[nameLen] == TAG_TOK) {
int tok = pSym - 1 - sym_stk;
- tok = tok * 8 + TOK_IDENT;
- if (tok <= TOK_DEFINE) {
- return 0;
- } else {
- tok = (intptr_t) (pVarsBase + tok);
- return * (void**) tok;
- }
+ tok = tok * sizeof(VariableInfo);
+ tok = (intptr_t) ((intptr_t) pVarsBase + tok);
+ return * (void**) tok;
}
}
}
diff --git a/libacc/tests/main.cpp b/libacc/tests/main.cpp
index d624cbb..4f8a65d 100644
--- a/libacc/tests/main.cpp
+++ b/libacc/tests/main.cpp
@@ -109,16 +109,20 @@
}
}
- accGetScriptLabel(script, "main", (ACCvoid**) & mainPointer);
+ if (runResults) {
+ accGetScriptLabel(script, "main", (ACCvoid**) & mainPointer);
- result = accGetError(script);
- if (result == ACC_NO_ERROR && runResults) {
- fprintf(stderr, "Executing compiled code:\n");
- int codeArgc = argc - i + 1;
- char** codeArgv = argv + i - 1;
- codeArgv[0] = (char*) (inFile ? inFile : "stdin");
- result = run(mainPointer, codeArgc, codeArgv);
- fprintf(stderr, "result: %d\n", result);
+ result = accGetError(script);
+ if (result != ACC_NO_ERROR) {
+ fprintf(stderr, "Could not find main: %d\n", result);
+ } else {
+ fprintf(stderr, "Executing compiled code:\n");
+ int codeArgc = argc - i + 1;
+ char** codeArgv = argv + i - 1;
+ codeArgv[0] = (char*) (inFile ? inFile : "stdin");
+ result = run(mainPointer, codeArgc, codeArgv);
+ fprintf(stderr, "result: %d\n", result);
+ }
}
exit: