Home | History | Annotate | Download | only in tests
      1 /*
      2  * RuntimeTest for ACC compiler.
      3  *
      4  */
      5 
      6 #include <ctype.h>
      7 #include <dlfcn.h>
      8 #include <stdarg.h>
      9 #include <stdint.h>
     10 #include <stdio.h>
     11 #include <stdlib.h>
     12 #include <string.h>
     13 
     14 #if defined(__arm__)
     15 #include <unistd.h>
     16 #endif
     17 
     18 #include <acc/acc.h>
     19 
     20 
     21 typedef void (*ScriptPtr)();
     22 
     23 // This is a separate function so it can easily be set by breakpoint in gdb.
     24 void run(ScriptPtr scriptFn) {
     25     scriptFn();
     26 }
     27 
     28 // Private API for development:
     29 
     30 extern "C"
     31 void accDisassemble(ACCscript* script);
     32 
     33 int globalVar;
     34 
     35 void op_int(int a) {
     36     printf("op_int(%d)\n", a);
     37 }
     38 
     39 void op_float12(float a, float b, float c, float d,
     40                 float e, float f, float g, float h,
     41                 float i, float j, float k, float l) {
     42     printf("op_float12(%g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g)\n",
     43            a, b, c, d, e, f, g, h, i, j, k, l);
     44 }
     45 
     46 const char* text = "void op_int(int a);\n"
     47     "void op_float12(float a, float b, float c, float d,\n"
     48     "           float e, float f, float g, float h,\n"
     49     "           float i, float j, float k, float l);\n"
     50     "void script() {\n"
     51     "  globalVar += 3;\n"
     52     "  op_int(123);\n"
     53     "  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"
     54     "}\n";
     55 
     56 ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) {
     57     if (strcmp("op_int", name) == 0) {
     58         return (ACCvoid*) op_int;
     59     }
     60     if (strcmp("op_float12", name) == 0) {
     61         return (ACCvoid*) op_float12;
     62     }
     63     if (strcmp("globalVar", name) == 0) {
     64         return (ACCvoid*) &globalVar;
     65     }
     66     return (ACCvoid*) dlsym(RTLD_DEFAULT, name);
     67 }
     68 
     69 int main(int argc, char** argv) {
     70     ACCscript* script = accCreateScript();
     71 
     72     accRegisterSymbolCallback(script, symbolLookup, NULL);
     73 
     74     const ACCchar* scriptSource[] = {text};
     75     accScriptSource(script, 1, scriptSource, NULL);
     76 
     77     accCompileScript(script);
     78     int result = accGetError(script);
     79     ScriptPtr scriptPointer = 0;
     80     if (result != 0) {
     81         char buf[1024];
     82         accGetScriptInfoLog(script, sizeof(buf), NULL, buf);
     83         fprintf(stderr, "%s", buf);
     84         goto exit;
     85     }
     86 
     87     {
     88         ACCsizei numPragmaStrings;
     89         accGetPragmas(script, &numPragmaStrings, 0, NULL);
     90         if (numPragmaStrings) {
     91             char** strings = new char*[numPragmaStrings];
     92             accGetPragmas(script, NULL, numPragmaStrings, strings);
     93             for(ACCsizei i = 0; i < numPragmaStrings; i += 2) {
     94                 fprintf(stderr, "#pragma %s(%s)\n", strings[i], strings[i+1]);
     95             }
     96             delete[] strings;
     97         }
     98     }
     99 
    100     accGetScriptLabel(script, "script", (ACCvoid**) & scriptPointer);
    101 
    102     result = accGetError(script);
    103     if (result != ACC_NO_ERROR) {
    104         fprintf(stderr, "Could not find script: %d\n", result);
    105     } else {
    106         fprintf(stderr, "Executing script:\n");
    107         globalVar = 17;
    108         run(scriptPointer);
    109         fprintf(stderr, "After script globalVar = %d\n", globalVar);
    110     }
    111 
    112 
    113 exit:
    114 
    115     accDeleteScript(script);
    116 
    117     return result;
    118 }
    119