18c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich/*
28c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich * RuntimeTest for ACC compiler.
38c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich *
48c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich */
58c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
68c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich#include <ctype.h>
78c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich#include <dlfcn.h>
88c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich#include <stdarg.h>
98c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich#include <stdint.h>
108c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich#include <stdio.h>
118c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich#include <stdlib.h>
128c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich#include <string.h>
138c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
148c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich#if defined(__arm__)
158c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich#include <unistd.h>
168c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich#endif
178c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
188c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich#include <acc/acc.h>
198c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
208c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
218c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevichtypedef void (*ScriptPtr)();
228c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
238c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich// This is a separate function so it can easily be set by breakpoint in gdb.
248c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevichvoid run(ScriptPtr scriptFn) {
258c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    scriptFn();
268c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich}
278c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
288c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich// Private API for development:
298c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
308c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevichextern "C"
318c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevichvoid accDisassemble(ACCscript* script);
328c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
33c9b8ffc3897952deef9e23949ce42fdc09f14a24Jack Palevichint globalVar;
34c9b8ffc3897952deef9e23949ce42fdc09f14a24Jack Palevich
358c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevichvoid op_int(int a) {
368c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    printf("op_int(%d)\n", a);
378c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich}
388c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
398c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevichvoid op_float12(float a, float b, float c, float d,
408c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich                float e, float f, float g, float h,
418c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich                float i, float j, float k, float l) {
428c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    printf("op_float12(%g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g)\n",
438c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich           a, b, c, d, e, f, g, h, i, j, k, l);
448c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich}
458c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
468c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevichconst char* text = "void op_int(int a);\n"
478c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    "void op_float12(float a, float b, float c, float d,\n"
488c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    "           float e, float f, float g, float h,\n"
498c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    "           float i, float j, float k, float l);\n"
508c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    "void script() {\n"
51c9b8ffc3897952deef9e23949ce42fdc09f14a24Jack Palevich    "  globalVar += 3;\n"
528c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    "  op_int(123);\n"
538c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    "  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"
548c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    "}\n";
558c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
568c246a9dc294760f2a981cf5144fe4939d1554e6Jack PalevichACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) {
578c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    if (strcmp("op_int", name) == 0) {
588c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich        return (ACCvoid*) op_int;
598c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    }
608c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    if (strcmp("op_float12", name) == 0) {
618c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich        return (ACCvoid*) op_float12;
628c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    }
63c9b8ffc3897952deef9e23949ce42fdc09f14a24Jack Palevich    if (strcmp("globalVar", name) == 0) {
64c9b8ffc3897952deef9e23949ce42fdc09f14a24Jack Palevich        return (ACCvoid*) &globalVar;
65c9b8ffc3897952deef9e23949ce42fdc09f14a24Jack Palevich    }
668c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    return (ACCvoid*) dlsym(RTLD_DEFAULT, name);
678c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich}
688c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
698c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevichint main(int argc, char** argv) {
708c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    ACCscript* script = accCreateScript();
718c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
728c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    accRegisterSymbolCallback(script, symbolLookup, NULL);
738c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
748c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    const ACCchar* scriptSource[] = {text};
758c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    accScriptSource(script, 1, scriptSource, NULL);
768c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
778c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    accCompileScript(script);
788c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    int result = accGetError(script);
798c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    ScriptPtr scriptPointer = 0;
808c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    if (result != 0) {
818c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich        char buf[1024];
828c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich        accGetScriptInfoLog(script, sizeof(buf), NULL, buf);
838c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich        fprintf(stderr, "%s", buf);
848c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich        goto exit;
858c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    }
868c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
878c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    {
888c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich        ACCsizei numPragmaStrings;
898c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich        accGetPragmas(script, &numPragmaStrings, 0, NULL);
908c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich        if (numPragmaStrings) {
918c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich            char** strings = new char*[numPragmaStrings];
928c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich            accGetPragmas(script, NULL, numPragmaStrings, strings);
938c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich            for(ACCsizei i = 0; i < numPragmaStrings; i += 2) {
948c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich                fprintf(stderr, "#pragma %s(%s)\n", strings[i], strings[i+1]);
958c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich            }
968c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich            delete[] strings;
978c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich        }
988c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    }
998c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
1008c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    accGetScriptLabel(script, "script", (ACCvoid**) & scriptPointer);
1018c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
1028c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    result = accGetError(script);
1038c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    if (result != ACC_NO_ERROR) {
1048c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich        fprintf(stderr, "Could not find script: %d\n", result);
1058c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    } else {
1068c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich        fprintf(stderr, "Executing script:\n");
107c9b8ffc3897952deef9e23949ce42fdc09f14a24Jack Palevich        globalVar = 17;
1088c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich        run(scriptPointer);
109c9b8ffc3897952deef9e23949ce42fdc09f14a24Jack Palevich        fprintf(stderr, "After script globalVar = %d\n", globalVar);
1108c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    }
1118c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
1128c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
1138c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevichexit:
1148c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
1158c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    accDeleteScript(script);
1168c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich
1178c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich    return result;
1188c246a9dc294760f2a981cf5144fe4939d1554e6Jack Palevich}
119