среда, 7. децембар 2011.

TCC


Tcc sample
Tcc sample is included in package Tcc Demo Gui.

This sample may serve as a base for any program that could use Tcc. It is explained in this chapter.


#include <CtrlLib/CtrlLib.h>

using namespace Upp;

#define LAYOUTFILE <Tcc Demo Gui/Tcc Demo Gui.lay>
#include <CtrlCore/lay.h>

class Tcc_Demo : public WithMainLayout<TopWindow> {
public:
    void RunProgram();
    void OpGetExe_Action();

    typedef Tcc_Demo CLASSNAME;
    Tcc_Demo();
};

It is always necessary to include Tcc.h

#include "Tcc/Tcc.h"

This function will be called from the Tcc program in memory.

double plus(double a, double b)
{
   return a + b;
}

Program to be run in memory source code. '\n' are not necessary.

char my_program_in memory[] =

If AddIncludePath() is not used TCC will not find probably the #include files

        "#include <stdio.h>\n"
        "#include <math.h>\n"
        "\n"

As with any C source, library functions have to be declared.

        "double plus(double a, double b);\n"
        "\n"

This is the function called from the main program.
As many functions as necessary can be called from the main program.

        "double pow2(double d)\n"
        "{\n"
        "    return (d*d);\n"
        "}\n"
        "\n"

Remember that all static and global variables will be lost between function calls. All durable storage has to be located in the main program.
There is no need for any "main()" function.

        "double test(double a, char *str)\n"
        "{\n"    
        "    if (a < 0.)\n"
        "        throw(\"Argument is negative!\");\n"    
        "    double ret = 0;\n"
        "    int i;\n"
        "    for (i = 0; i < 10000000; ++i)\n"    
        "        ret += 0.000000001*pow2(sqrt(plus(a, 10)));\n"
        "    snprintf(str, 1024, \"The result is %f\", ret);\n"
        "    return ret;\n"
        "}";

Program to be copied to an executable file source code

char my_program_in_file[] =
        "#include <stdio.h>\n"
        "\n"
        "int fib(n)\n"
        "{\n"
        "    if (n <= 2)\n"
        "        return 1;\n"
        "    else\n"
        "        return fib(n-1) + fib(n-2);\n"
        "}\n"
        "\n"
        "int main(int argc, char **argv)\n"
        "{\n"
        "    int n = 30;\n"
        "\n"
        "    printf(\"\\nCompute nth Fibonacci number fib(%d) = \", n);\n"
        "    printf(\"%d\", fib(n));\n"
        "\n"
        "    printf(\"\\nPress a key to end\");\n"
        "    getchar();\n"
        "    return 0;\n"
        "}";

void Tcc_Demo::RunProgram()
{
    try {

In Windows. .dll has been copied to windows/system folder. If not it has to be defined in the Tcc constructor.

        Tcc tcc;
    
Here it is defined what to do with the compiled program

        if (OpGetExe)
            tcc.SetOutputExe();
        else
            tcc.SetOutputMemory();


Set here the include and library directories located in Tcc/lib/include and Tcc/lib/lib

        tcc.AddIncludePath(EditIncludePath.GetData().ToString());
        tcc.AddLibraryPath(EditLibsPath.GetData().ToString());
    
This order has to be followed:
1. Compile source C script

        tcc.Compile(SourceCode.GetData().ToString());

2.1 If compiled and run in memory

        if (!OpGetExe) {

2.1.1 Add all functions in the main program that can be called from the C script.
As many functions as necessary can be called from the main program.
Remember to declare them in the C script

            tcc.AddSymbol("plus", (void *)&plus);

2.1.2 Link the C script to the main program functions

            tcc.Link();

2.1.3 Get the addresses of all C Script functions to be called from the main program

            double (*mytest1)(double, char *) = (double (*)(double, char *))tcc.GetSymbol("test");
        
            char str[1024];

2.1.4 Call the C script functions

            double res = mytest1(90, str);
            PromptOK("The result for Test is " + FormatDouble(res) + ". " + str);

2.2 If compiled to an executable file

        } else {

2.2.2 Link the C script to the executable file

            tcc.Link(EditExeFile.GetData().ToString());
            PromptOK("Program compiled in " + DeQtf(EditExeFile.GetData().ToString()));
        }
    } catch(Exc err){

3. Catch the compiling, linking and running (if run in memory) errors.

        Exclamation(DeQtfLf(err));
    }
}

void Tcc_Demo::OpGetExe_Action()
{
    switch (OpGetExe) {
        case 0:
            EditExeFile.Enable(false);
            SourceCode.SetData(my_program_in_memory);
            break;
        default:
            EditExeFile.Enable(true);
            SourceCode.SetData(my_program_in_file);
    }
}

Tcc_Demo::Tcc_Demo()
{
    CtrlLayout(*this, "Tcc Demo");
    ButRun.WhenPush = THISBACK(RunProgram);
    OpGetExe.WhenAction = THISBACK(OpGetExe_Action);
    OpGetExe = 0;
    OpGetExe_Action();
#if defined(PLATFORM_WIN32)
    EditExeFile.SetData(AppendFileName(GetHomeDirectory(), "tccdemo.exe"));
#else
    EditExeFile.SetData(AppendFileName(GetHomeDirectory(), "tccdemo"));
#endif
    EditIncludePath <<= "/mnt/C/Desarrollo/Aplicaciones/zlibs/Tcc/lib/include";//"...put here right path.../Tcc/lib/include";        
    EditLibsPath <<= "/mnt/C/Desarrollo/Aplicaciones/zlibs/Tcc/lib/lib";//"...put here right path.../Tcc/lib/lib";
    SourceCode.SetFont(Courier(12));
    Sizeable();
}

GUI_APP_MAIN
{
    Tcc_Demo().Run();
}

This is the sample running.



Нема коментара:

Постави коментар