/*------------------------------------------------------------------------------

 Example source code demonstrating how to use metacode to increase performance
 if a prgram is to be executed multiple times.

*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <exec/exec.h>
#include <utility/tagitem.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <pragmas/exec_pragmas.h>

// includes for BASIC.library

#include "include/basic.h"
#include "clib/basiclib_protos.h"
#include "pragmas/basiclib_pragmas.h"

// globals

struct Library *BASICBase;

/*------------------------------------------------------------------------------

 Main entry point. Note that this program should be started with the stack set
 to 16 KB or higher (because the interpreter is executed synchronously, ie. it
 uses our stack).

*/

int
main(int argc, UBYTE **argv)
{
    int rc = 20;

    if (BASICBase = OpenLibrary("BASIC.library", BASIC_VERSION))
    {
        static struct TagItem ctags[] = { BASIC_CONSOLE, (ULONG)NULL, TAG_END };

        void *context;

        // create interactive interpreter; use current console (BASIC_CONSOLE, NULL) if not started via wb, ie. if argc != 0

        if (argc)
            context = basic_context(&ctags[0]);
        else
            context = basic_context(&ctags[1]);

        if (context)
        {
            // compile source code into metacode

            static struct TagItem mtags[] = { BASIC_FILENAME, (ULONG)"test.basic", TAG_END };

            void *metacode;

            if (metacode = basic_tokenize(context, mtags))
            {
                struct TagItem ltags[] = { BASIC_METACODE, (ULONG)NULL, TAG_END };
                UWORD          n;

                ltags[0].ti_Data = (ULONG)metacode;

                // load metacode of test program five times into interpreter

                for (n = 0; n < 5; ++ n)
                {
                    if (rc = basic_load(context, ltags))
                    {
                        printf("Error loading program test.basic (error code %d)\n", rc);
                    }
                    else
                    {
                        // main loop: execute program synchronously

                        do
                        {
                            rc = basic_iterate(context);

                        } while (rc == BASIC_OK);
                    }
                }

                // dispose of metacode

                basic_unload(context, metacode);
            }
            else
                puts("Failed to compile code");

            rc = basic_dispose(context);
        }
        else
            puts("Failed to create interpreter context");

        CloseLibrary(BASICBase);
    }
    else
        puts("Can not open BASIC.library");

    return(rc);
}
