Loading libacc/FEATURES +40 −22 Original line number Diff line number Diff line Supported C language subset (read joint example 'otccex.c' to have an introduction to OTCC dialect): Supported C language subset: - Expressions: Loading @@ -13,35 +12,51 @@ Supported C language subset (read joint example 'otccex.c' to have * Parenthesis are supported. * Comma operator is supported. * Trinary operator (?:) is not supported. * Unary operators: '&', '*' (pointer indirection), '-' (negation), '+', '!', '~', post fixed '++' and '--'. (negation), '+', '!', '~', '++' and '--'. * Pointer indirection ('*') is supported. * Pointer indirection ('*') only works with explicit cast to 'char *', 'int *' or 'int (*)()' (function pointer). * Square brackets can be used for pointer arithmetic. * '++', '--', and unary '&' can only be used with variable lvalue (left value). * '=' and <op>= are supported. * '=' can only be used with variable or '*' (pointer indirection) lvalue. * Function calls are supported with standard Linux calling convention. Function pointers are supported. Functions can be used before being declared. * Function calls are supported with standard i386 calling convention. Function pointers are supported with explicit cast. Functions can be used before being declared. - sizeof() is not supported. - Types: only signed integer ('int') variables and functions can be declared. Variables cannot be initialized in declarations. Only old K&R function declarations are parsed (implicit integer return value and no types on arguments). - Types: + int, short, char, float, double + pointers + variables can be initialized in declarations. + Only ANSI-style function declarations are supported. - "..." is not supported. - short is not supported - const is not supported - arrays are not supported - long doubles are not supported - structs are not supported - Any function or variable from the libc can be used because OTCC uses the libc dynamic linker to resolve undefined symbols. - Unknown functions and variables are bound at compile time by calling back to the caller. For the 'acc' command-line tool unknown functions and variables are looked up using dlsym, to allow using many libc functions and variables. - Instructions: blocks ('{' '}') are supported as in C. 'if' and 'else' can be used for tests. The 'while' and 'for' C constructs are supported for loops. 'break' can be used to exit loops. 'return' is used for the return value of a function. - switch / case is not supported. - goto and labels are not supported. - continue is not supported. - Identifiers are parsed the same way as C. Local variables are handled, but there is no local name space (not a problem if different names are used for local and global variables). Loading @@ -49,16 +64,19 @@ Supported C language subset (read joint example 'otccex.c' to have - Numbers can be entered in decimal, hexadecimal ('0x' or '0X' prefix), or octal ('0' prefix). - Float and double constants are supported. - '#define' is supported without function like arguments. No macro recursion is tolerated. Other preprocessor directives are ignored. - C Strings and C character constants are supported. Only '\n', '\"', '\'' and '\\' escapes are recognized. - C Strings and C character constants are supported. All ANSI C character escapes are supported. - Both C comments ( /* */ ) and C++ comments ( // ... end-of-line ) can be used. - Both C comments ( /* */ ) and C++ comments ( // ... end-of-line ) are supported. - No error is displayed if an incorrect program is given. - Some syntax errors are reported, others may cause a crash. - Memory: the code, data, and symbol sizes are limited to 100KB (it can be changed in the source code). Loading libacc/acc.cpp +56 −6 Original line number Diff line number Diff line Loading @@ -133,13 +133,22 @@ public: class Compiler : public ErrorSink { typedef int tokenid_t; enum TypeTag { TY_INT, TY_CHAR, TY_VOID, TY_FLOAT, TY_DOUBLE, TY_POINTER, TY_FUNC, TY_PARAM TY_INT, // 0 TY_CHAR, // 1 TY_SHORT, // 2 TY_VOID, // 3 TY_FLOAT, // 4 TY_DOUBLE, // 5 TY_POINTER, // 6 TY_ARRAY, // 7 TY_STRUCT, // 8 TY_FUNC, // 9 TY_PARAM // 10 }; struct Type { TypeTag tag; tokenid_t id; // For function arguments tokenid_t id; // For function arguments (stores length for array) Type* pHead; Type* pTail; }; Loading Loading @@ -594,8 +603,18 @@ class Compiler : public ErrorSink { TypeTag collapseType(TypeTag tag) { static const TypeTag collapsedTag[] = { TY_INT, TY_INT, TY_VOID, TY_FLOAT, TY_DOUBLE, TY_INT, TY_VOID, TY_VOID}; TY_INT, TY_INT, TY_INT, TY_VOID, TY_FLOAT, TY_DOUBLE, TY_INT, TY_INT, TY_VOID, TY_VOID, TY_VOID }; return collapsedTag[tag]; } Loading Loading @@ -1093,6 +1112,9 @@ class Compiler : public ErrorSink { case TY_FLOAT: o4(0xE5820000); // str r0, [r2] break; case TY_SHORT: o4(0xE1C200B0); // strh r0, [r2] break; case TY_CHAR: o4(0xE5C20000); // strb r0, [r2] break; Loading @@ -1115,6 +1137,9 @@ class Compiler : public ErrorSink { case TY_FLOAT: o4(0xE5900000); // ldr r0, [r0] break; case TY_SHORT: o4(0xE1D000F0); // ldrsh r0, [r0] break; case TY_CHAR: o4(0xE5D00000); // ldrb r0, [r0] break; Loading Loading @@ -1378,6 +1403,8 @@ class Compiler : public ErrorSink { switch(pType->tag) { case TY_CHAR: return 1; case TY_SHORT: return 1; case TY_DOUBLE: return 8; default: Loading @@ -1392,6 +1419,8 @@ class Compiler : public ErrorSink { switch(pType->tag) { case TY_INT: return 4; case TY_SHORT: return 2; case TY_CHAR: return 1; default: Loading Loading @@ -2095,6 +2124,9 @@ class Compiler : public ErrorSink { case TY_INT: o(0x0189); /* movl %eax/%al, (%ecx) */ break; case TY_SHORT: o(0x018966); /* movw %ax, (%ecx) */ break; case TY_CHAR: o(0x0188); /* movl %eax/%al, (%ecx) */ break; Loading @@ -2119,6 +2151,10 @@ class Compiler : public ErrorSink { case TY_INT: o2(0x008b); /* mov (%eax), %eax */ break; case TY_SHORT: o(0xbf0f); /* movswl (%eax), %eax */ ob(0); break; case TY_CHAR: o(0xbe0f); /* movsbl (%eax), %eax */ ob(0); /* add zero in code */ Loading Loading @@ -2288,6 +2324,8 @@ class Compiler : public ErrorSink { switch (pType->tag) { case TY_CHAR: return 1; case TY_SHORT: return 2; default: return 4; } Loading @@ -2300,6 +2338,8 @@ class Compiler : public ErrorSink { switch(pType->tag) { case TY_INT: return 4; case TY_SHORT: return 2; case TY_CHAR: return 1; default: Loading Loading @@ -3158,6 +3198,7 @@ class Compiler : public ErrorSink { // Prebuilt types, makes things slightly faster. Type* mkpInt; // int Type* mkpShort; // short Type* mkpChar; // char Type* mkpVoid; // void Type* mkpFloat; Loading Loading @@ -4013,7 +4054,8 @@ class Compiler : public ErrorSink { pGen->pushR0(); pGen->loadR0FromR0(); int tag = pGen->getR0Type()->tag; if (!(tag == TY_INT || tag == TY_CHAR || tag == TY_POINTER)) { if (!(tag == TY_INT || tag == TY_SHORT || tag == TY_CHAR || tag == TY_POINTER)) { error("++/-- illegal for this type. %d", tag); } if (isPost) { Loading Loading @@ -4262,6 +4304,9 @@ class Compiler : public ErrorSink { case TY_INT: buffer.appendCStr("int"); break; case TY_SHORT: buffer.appendCStr("short"); break; case TY_CHAR: buffer.appendCStr("char"); break; Loading @@ -4283,6 +4328,8 @@ class Compiler : public ErrorSink { switch (tag) { case TY_INT: break; case TY_SHORT: break; case TY_CHAR: break; case TY_VOID: Loading Loading @@ -4347,6 +4394,8 @@ class Compiler : public ErrorSink { Type* pType; if (tok == TOK_INT) { pType = mkpInt; } else if (tok == TOK_SHORT) { pType = mkpShort; } else if (tok == TOK_CHAR) { pType = mkpChar; } else if (tok == TOK_VOID) { Loading Loading @@ -4844,6 +4893,7 @@ public: void createPrimitiveTypes() { mkpInt = createType(TY_INT, NULL, NULL); mkpShort = createType(TY_SHORT, NULL, NULL); mkpChar = createType(TY_CHAR, NULL, NULL); mkpVoid = createType(TY_VOID, NULL, NULL); mkpFloat = createType(TY_FLOAT, NULL, NULL); Loading libacc/tests/data/short.c 0 → 100644 +6 −0 Original line number Diff line number Diff line short a = 3; int main() { short* b = &a; *b = *b - 5; return a; } libacc/tests/runtimeTest.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ void run(ScriptPtr scriptFn) { extern "C" void accDisassemble(ACCscript* script); int globalVar; void op_int(int a) { printf("op_int(%d)\n", a); } Loading @@ -46,6 +48,7 @@ const char* text = "void op_int(int a);\n" " float e, float f, float g, float h,\n" " float i, float j, float k, float l);\n" "void script() {\n" " globalVar += 3;\n" " op_int(123);\n" " op_float12(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);\n" "}\n"; Loading @@ -57,6 +60,9 @@ ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) { if (strcmp("op_float12", name) == 0) { return (ACCvoid*) op_float12; } if (strcmp("globalVar", name) == 0) { return (ACCvoid*) &globalVar; } return (ACCvoid*) dlsym(RTLD_DEFAULT, name); } Loading Loading @@ -98,7 +104,9 @@ int main(int argc, char** argv) { fprintf(stderr, "Could not find script: %d\n", result); } else { fprintf(stderr, "Executing script:\n"); globalVar = 17; run(scriptPointer); fprintf(stderr, "After script globalVar = %d\n", globalVar); } Loading libacc/tests/test.py +5 −0 Original line number Diff line number Diff line Loading @@ -380,6 +380,11 @@ arg: 12 Errors: 0 2D Errors: 0 result: 0 ""","""""") def testShort(self): self.compileCheck(["-R", "data/short.c"], """Executing compiled code: result: -2 ""","""""") if __name__ == '__main__': Loading Loading
libacc/FEATURES +40 −22 Original line number Diff line number Diff line Supported C language subset (read joint example 'otccex.c' to have an introduction to OTCC dialect): Supported C language subset: - Expressions: Loading @@ -13,35 +12,51 @@ Supported C language subset (read joint example 'otccex.c' to have * Parenthesis are supported. * Comma operator is supported. * Trinary operator (?:) is not supported. * Unary operators: '&', '*' (pointer indirection), '-' (negation), '+', '!', '~', post fixed '++' and '--'. (negation), '+', '!', '~', '++' and '--'. * Pointer indirection ('*') is supported. * Pointer indirection ('*') only works with explicit cast to 'char *', 'int *' or 'int (*)()' (function pointer). * Square brackets can be used for pointer arithmetic. * '++', '--', and unary '&' can only be used with variable lvalue (left value). * '=' and <op>= are supported. * '=' can only be used with variable or '*' (pointer indirection) lvalue. * Function calls are supported with standard Linux calling convention. Function pointers are supported. Functions can be used before being declared. * Function calls are supported with standard i386 calling convention. Function pointers are supported with explicit cast. Functions can be used before being declared. - sizeof() is not supported. - Types: only signed integer ('int') variables and functions can be declared. Variables cannot be initialized in declarations. Only old K&R function declarations are parsed (implicit integer return value and no types on arguments). - Types: + int, short, char, float, double + pointers + variables can be initialized in declarations. + Only ANSI-style function declarations are supported. - "..." is not supported. - short is not supported - const is not supported - arrays are not supported - long doubles are not supported - structs are not supported - Any function or variable from the libc can be used because OTCC uses the libc dynamic linker to resolve undefined symbols. - Unknown functions and variables are bound at compile time by calling back to the caller. For the 'acc' command-line tool unknown functions and variables are looked up using dlsym, to allow using many libc functions and variables. - Instructions: blocks ('{' '}') are supported as in C. 'if' and 'else' can be used for tests. The 'while' and 'for' C constructs are supported for loops. 'break' can be used to exit loops. 'return' is used for the return value of a function. - switch / case is not supported. - goto and labels are not supported. - continue is not supported. - Identifiers are parsed the same way as C. Local variables are handled, but there is no local name space (not a problem if different names are used for local and global variables). Loading @@ -49,16 +64,19 @@ Supported C language subset (read joint example 'otccex.c' to have - Numbers can be entered in decimal, hexadecimal ('0x' or '0X' prefix), or octal ('0' prefix). - Float and double constants are supported. - '#define' is supported without function like arguments. No macro recursion is tolerated. Other preprocessor directives are ignored. - C Strings and C character constants are supported. Only '\n', '\"', '\'' and '\\' escapes are recognized. - C Strings and C character constants are supported. All ANSI C character escapes are supported. - Both C comments ( /* */ ) and C++ comments ( // ... end-of-line ) can be used. - Both C comments ( /* */ ) and C++ comments ( // ... end-of-line ) are supported. - No error is displayed if an incorrect program is given. - Some syntax errors are reported, others may cause a crash. - Memory: the code, data, and symbol sizes are limited to 100KB (it can be changed in the source code). Loading
libacc/acc.cpp +56 −6 Original line number Diff line number Diff line Loading @@ -133,13 +133,22 @@ public: class Compiler : public ErrorSink { typedef int tokenid_t; enum TypeTag { TY_INT, TY_CHAR, TY_VOID, TY_FLOAT, TY_DOUBLE, TY_POINTER, TY_FUNC, TY_PARAM TY_INT, // 0 TY_CHAR, // 1 TY_SHORT, // 2 TY_VOID, // 3 TY_FLOAT, // 4 TY_DOUBLE, // 5 TY_POINTER, // 6 TY_ARRAY, // 7 TY_STRUCT, // 8 TY_FUNC, // 9 TY_PARAM // 10 }; struct Type { TypeTag tag; tokenid_t id; // For function arguments tokenid_t id; // For function arguments (stores length for array) Type* pHead; Type* pTail; }; Loading Loading @@ -594,8 +603,18 @@ class Compiler : public ErrorSink { TypeTag collapseType(TypeTag tag) { static const TypeTag collapsedTag[] = { TY_INT, TY_INT, TY_VOID, TY_FLOAT, TY_DOUBLE, TY_INT, TY_VOID, TY_VOID}; TY_INT, TY_INT, TY_INT, TY_VOID, TY_FLOAT, TY_DOUBLE, TY_INT, TY_INT, TY_VOID, TY_VOID, TY_VOID }; return collapsedTag[tag]; } Loading Loading @@ -1093,6 +1112,9 @@ class Compiler : public ErrorSink { case TY_FLOAT: o4(0xE5820000); // str r0, [r2] break; case TY_SHORT: o4(0xE1C200B0); // strh r0, [r2] break; case TY_CHAR: o4(0xE5C20000); // strb r0, [r2] break; Loading @@ -1115,6 +1137,9 @@ class Compiler : public ErrorSink { case TY_FLOAT: o4(0xE5900000); // ldr r0, [r0] break; case TY_SHORT: o4(0xE1D000F0); // ldrsh r0, [r0] break; case TY_CHAR: o4(0xE5D00000); // ldrb r0, [r0] break; Loading Loading @@ -1378,6 +1403,8 @@ class Compiler : public ErrorSink { switch(pType->tag) { case TY_CHAR: return 1; case TY_SHORT: return 1; case TY_DOUBLE: return 8; default: Loading @@ -1392,6 +1419,8 @@ class Compiler : public ErrorSink { switch(pType->tag) { case TY_INT: return 4; case TY_SHORT: return 2; case TY_CHAR: return 1; default: Loading Loading @@ -2095,6 +2124,9 @@ class Compiler : public ErrorSink { case TY_INT: o(0x0189); /* movl %eax/%al, (%ecx) */ break; case TY_SHORT: o(0x018966); /* movw %ax, (%ecx) */ break; case TY_CHAR: o(0x0188); /* movl %eax/%al, (%ecx) */ break; Loading @@ -2119,6 +2151,10 @@ class Compiler : public ErrorSink { case TY_INT: o2(0x008b); /* mov (%eax), %eax */ break; case TY_SHORT: o(0xbf0f); /* movswl (%eax), %eax */ ob(0); break; case TY_CHAR: o(0xbe0f); /* movsbl (%eax), %eax */ ob(0); /* add zero in code */ Loading Loading @@ -2288,6 +2324,8 @@ class Compiler : public ErrorSink { switch (pType->tag) { case TY_CHAR: return 1; case TY_SHORT: return 2; default: return 4; } Loading @@ -2300,6 +2338,8 @@ class Compiler : public ErrorSink { switch(pType->tag) { case TY_INT: return 4; case TY_SHORT: return 2; case TY_CHAR: return 1; default: Loading Loading @@ -3158,6 +3198,7 @@ class Compiler : public ErrorSink { // Prebuilt types, makes things slightly faster. Type* mkpInt; // int Type* mkpShort; // short Type* mkpChar; // char Type* mkpVoid; // void Type* mkpFloat; Loading Loading @@ -4013,7 +4054,8 @@ class Compiler : public ErrorSink { pGen->pushR0(); pGen->loadR0FromR0(); int tag = pGen->getR0Type()->tag; if (!(tag == TY_INT || tag == TY_CHAR || tag == TY_POINTER)) { if (!(tag == TY_INT || tag == TY_SHORT || tag == TY_CHAR || tag == TY_POINTER)) { error("++/-- illegal for this type. %d", tag); } if (isPost) { Loading Loading @@ -4262,6 +4304,9 @@ class Compiler : public ErrorSink { case TY_INT: buffer.appendCStr("int"); break; case TY_SHORT: buffer.appendCStr("short"); break; case TY_CHAR: buffer.appendCStr("char"); break; Loading @@ -4283,6 +4328,8 @@ class Compiler : public ErrorSink { switch (tag) { case TY_INT: break; case TY_SHORT: break; case TY_CHAR: break; case TY_VOID: Loading Loading @@ -4347,6 +4394,8 @@ class Compiler : public ErrorSink { Type* pType; if (tok == TOK_INT) { pType = mkpInt; } else if (tok == TOK_SHORT) { pType = mkpShort; } else if (tok == TOK_CHAR) { pType = mkpChar; } else if (tok == TOK_VOID) { Loading Loading @@ -4844,6 +4893,7 @@ public: void createPrimitiveTypes() { mkpInt = createType(TY_INT, NULL, NULL); mkpShort = createType(TY_SHORT, NULL, NULL); mkpChar = createType(TY_CHAR, NULL, NULL); mkpVoid = createType(TY_VOID, NULL, NULL); mkpFloat = createType(TY_FLOAT, NULL, NULL); Loading
libacc/tests/data/short.c 0 → 100644 +6 −0 Original line number Diff line number Diff line short a = 3; int main() { short* b = &a; *b = *b - 5; return a; }
libacc/tests/runtimeTest.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ void run(ScriptPtr scriptFn) { extern "C" void accDisassemble(ACCscript* script); int globalVar; void op_int(int a) { printf("op_int(%d)\n", a); } Loading @@ -46,6 +48,7 @@ const char* text = "void op_int(int a);\n" " float e, float f, float g, float h,\n" " float i, float j, float k, float l);\n" "void script() {\n" " globalVar += 3;\n" " op_int(123);\n" " op_float12(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0);\n" "}\n"; Loading @@ -57,6 +60,9 @@ ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) { if (strcmp("op_float12", name) == 0) { return (ACCvoid*) op_float12; } if (strcmp("globalVar", name) == 0) { return (ACCvoid*) &globalVar; } return (ACCvoid*) dlsym(RTLD_DEFAULT, name); } Loading Loading @@ -98,7 +104,9 @@ int main(int argc, char** argv) { fprintf(stderr, "Could not find script: %d\n", result); } else { fprintf(stderr, "Executing script:\n"); globalVar = 17; run(scriptPointer); fprintf(stderr, "After script globalVar = %d\n", globalVar); } Loading
libacc/tests/test.py +5 −0 Original line number Diff line number Diff line Loading @@ -380,6 +380,11 @@ arg: 12 Errors: 0 2D Errors: 0 result: 0 ""","""""") def testShort(self): self.compileCheck(["-R", "data/short.c"], """Executing compiled code: result: -2 ""","""""") if __name__ == '__main__': Loading