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
21typedef void (*ScriptPtr)();
22
23// This is a separate function so it can easily be set by breakpoint in gdb.
24void run(ScriptPtr scriptFn) {
25    scriptFn();
26}
27
28// Private API for development:
29
30extern "C"
31void accDisassemble(ACCscript* script);
32
33int globalVar;
34
35void op_int(int a) {
36    printf("op_int(%d)\n", a);
37}
38
39void 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
46const 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
56ACCvoid* 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
69int 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
113exit:
114
115    accDeleteScript(script);
116
117    return result;
118}
119