Ye Olde Clue

Random musings on random stuff.

Compiled Kamaelia: A Mini Axon that compiles to C++ using Shed Skin (+ one minor piece of assistance)

Well, after getting a mini axon standing" compiling using shedskin yesterday, I've taken the next steps to see if we can get a full mini-axon system compiling. The good news is that, with 1 piece of manual assistance, we can! As a result I have here a compiled version of a mini-axon system.
Yes, you heard right - we have a compilable to executable version of Kamaelia thanks to shedskin.

First of all, what manual change do we need to make? Well, due to the fact we activate various microprocesses in the same way, we need to warn the C++ compiler of this fact, and help shedskin out a bit. The code shedskin creates that's problematic is this:

This is the fixed code:

A corresponding change occurs in the generated .hpp file as well. The resulting code then compiles cleanly and runs correctly :-) Yay!

The mini-axon code looks like this:

As you can see, this isn't really so very different from the usual code. (There's lots of sugar missing of course!)

Reply to this post

Comments

Generated C++ Header code #

C++ Header Code generated (editted lines in red)
#ifndef __TEST_HPP
#define __TEST_HPP

#include "builtin.hpp"

using namespace __shedskin__;
namespace __test__ {

class microprocess;
class scheduler;
class component;
class postman;
class Producer;
class Consumer;

typedef __iter<int> *(*lambda0)(Consumer *);
typedef __iter<int> *(*lambda1)(postman *);
typedef __iter<int> *(*lambda2)(Producer *);

extern class_ *cl_microprocess;
class microprocess : public pyobj {
public:
    static void *__init__;

    str *name;

    microprocess();
    microprocess(str *name);
};

extern class_ *cl_scheduler;
class scheduler : public microprocess {
public:
    list<__iter<int> *> *newqueue;
    list<__iter<int> *> *active;

    template<class Klass>
    int activateMicroprocess( __iter<int> *(*some_gen)(Klass *), Klass *some_obj);

    scheduler();
};

extern class_ *cl_component;
class component : public microprocess {
public:
    dict<str *, list<str *> *> *boxes;

    str *recv(str *inboxname);
    int send(str *value, str *outboxname);
    int dataReady(str *inboxname);
    component();
};

extern class_ *cl_postman;
class postman : public microprocess {
public:
    str *sinkbox;
    Producer *source;
    Consumer *sink;
    str *sourcebox;

    postman(Producer *source, str *sourcebox, Consumer *sink, str *sinkbox);
};

extern class_ *cl_Producer;
class Producer : public component {
public:
    str *message;

    Producer(str *message);
};

extern class_ *cl_Consumer;
class Consumer : public component {
public:

    Consumer();
};

__iter<int> *scheduler_main(scheduler *zelf);
__iter<int> *postman_main(postman *zelf);
__iter<int> *Producer_main(Producer *zelf);
__iter<int> *Consumer_main(Consumer *zelf);

} // module namespace
#endif

-- Michael, 22 Feb 2007 at 15:19, Rating: 0 (Reply) (Moderated by: anon)

Generated C++ code (.cpp file) #

And here's the main C++ file. Again, manually changed lines in red:

#include "test.hpp"

namespace __test__ {

str *const_0, *const_1, *const_2, *const_3;

__iter<int> *MT, *__13, *__14;
int __15, i;
postman *postie;
str *__name__;
Consumer *c;
scheduler *myscheduler;
Producer *p;

/**
class microprocess
*/

class_ *cl_microprocess;

microprocess::microprocess() {}
microprocess::microprocess(str *name) {
    this->__class__ = cl_microprocess;
   
    this->name = name;
}

void *microprocess::__init__;

/**
class scheduler
*/

class_ *cl_scheduler;

template<class Klass>
int scheduler::activateMicroprocess(__iter<int> *(*some_gen)(Klass *), Klass *some_obj) {

    __iter<int> *microthread;

    microthread = some_gen(some_obj);
    (this->newqueue)->append(microthread);
    return 0;
}

scheduler::scheduler() : microprocess(const_0) {
    this->__class__ = cl_scheduler;
   
    this->active = (new list<__iter<int> *>());
    this->newqueue = (new list<__iter<int> *>());
}

/**
class component
*/

class_ *cl_component;

str *component::recv(str *inboxname) {
    str *result;

    result = ((this->boxes)->__getitem__(inboxname))->__getfast__(0);
    (this->boxes)->__getitem__(inboxname)->__delete__(0);
    return result;
}

int component::send(str *value, str *outboxname) {
   
    ((this->boxes)->__getitem__(outboxname))->append(value);
    return 0;
}

int component::dataReady(str *inboxname) {
   
    return len((this->boxes)->__getitem__(inboxname));
}

component::component() : microprocess(const_0) {
    this->__class__ = cl_component;
   
    this->boxes = (new dict<str *, list<str *> *>(2, new tuple2<str *, list<str *> *>(2,const_1,(new list<str *>())), new tuple2<str *, list<str *> *>(2,const_2,(new list<str *>()))));
}

/**
class postman
*/

class_ *cl_postman;

postman::postman(Producer *source, str *sourcebox, Consumer *sink, str *sinkbox) : microprocess(const_0) {
    this->__class__ = cl_postman;
   
    this->source = source;
    this->sourcebox = sourcebox;
    this->sink = sink;
    this->sinkbox = sinkbox;
}

/**
class Producer
*/

class_ *cl_Producer;

Producer::Producer(str *message) : component() {
    this->__class__ = cl_Producer;
   
    this->message = message;
}

/**
class Consumer
*/

class_ *cl_Consumer;

Consumer::Consumer() : component() {
    this->__class__ = cl_Consumer;
   
}

void __init() {
    const_0 = new str("hello");
    const_1 = new str("inbox");
    const_2 = new str("outbox");
    const_3 = new str("Hello World");

    __name__ = new str("__main__");

    cl_postman = new class_("postman", 32, 32);
    cl_Producer = new class_("Producer", 34, 34);
    cl_microprocess = new class_("microprocess", 31, 36);
    cl_component = new class_("component", 33, 35);
    cl_scheduler = new class_("scheduler", 36, 36);
    cl_Consumer = new class_("Consumer", 35, 35);

    p = (new Producer(const_3));
    c = (new Consumer());
    postie = (new postman(p, const_2, c, const_1));
    myscheduler = (new scheduler());
    myscheduler->activateMicroprocess(Consumer_main, c);
    myscheduler->activateMicroprocess(Producer_main, p);
    myscheduler->activateMicroprocess(postman_main, postie);
    MT = scheduler_main(myscheduler);

    FOR_IN(i,MT,14)
    END_FOR

}

class __gen_scheduler_main : public __iter<int> {
public:
    int a;
    StopIteration *__5;
    int c;
    __iter<int> *b;
    int __11;
    scheduler *zelf;
    int __10;
    int i;
    __iter<int> *current;
    int __4;
    int __7;
    int __6;
    int __1;
    int __0;
    __iter<__iter<int> *> *__3;
    list<__iter<int> *> *__2;
    __iter<__iter<int> *> *__9;
    list<__iter<int> *> *__8;
    int __12;
    int result;
    int __last_yield;

    __gen_scheduler_main(scheduler *zelf) {
        this->zelf = zelf;
        __last_yield = -1;
    }

    int next() {
        switch(__last_yield) {
            case 0: goto __after_yield_0;
            default: break;
        }
        result = 1;

        FAST_FOR(i,0,100,1,0,1)

            FOR_IN_SEQ(current,zelf->active,2,4)
                __last_yield = 0;
                return 1;
                __after_yield_0:;
                try {
                    result = current->next();
                    if ((result!=-1)) {
                        (zelf->newqueue)->append(current);
                    }
                } catch (StopIteration *) {
                }
            END_FOR


            FAST_FOR(a,0,len(zelf->active),1,6,7)
                (zelf->active)->pop();
            END_FOR


            FOR_IN_SEQ(b,zelf->newqueue,8,10)
                (zelf->active)->append(b);
            END_FOR


            FAST_FOR(c,0,len(zelf->newqueue),1,11,12)
                (zelf->newqueue)->pop();
            END_FOR

        END_FOR

        throw new StopIteration();
    }

};

__iter<int> *scheduler_main(scheduler *zelf) {
    return new __gen_scheduler_main(zelf);

}

class __gen_postman_main : public __iter<int> {
public:
    postman *zelf;
    str *d;
    int __last_yield;

    __gen_postman_main(postman *zelf) {
        this->zelf = zelf;
        __last_yield = -1;
    }

    int next() {
        switch(__last_yield) {
            case 0: goto __after_yield_0;
            default: break;
        }

        while(1) {
            __last_yield = 0;
            return 1;
            __after_yield_0:;
            if ((zelf->source)->dataReady(zelf->sourcebox)) {
                d = (zelf->source)->recv(zelf->sourcebox);
                (zelf->sink)->send(d, zelf->sinkbox);
            }
        }
        throw new StopIteration();
    }

};

__iter<int> *postman_main(postman *zelf) {
    return new __gen_postman_main(zelf);

}

class __gen_Producer_main : public __iter<int> {
public:
    Producer *zelf;
    int __last_yield;

    __gen_Producer_main(Producer *zelf) {
        this->zelf = zelf;
        __last_yield = -1;
    }

    int next() {
        switch(__last_yield) {
            case 0: goto __after_yield_0;
            default: break;
        }

        while(1) {
            __last_yield = 0;
            return 1;
            __after_yield_0:;
            zelf->send(zelf->message, const_2);
        }
        throw new StopIteration();
    }

};

__iter<int> *Producer_main(Producer *zelf) {
    return new __gen_Producer_main(zelf);

}

class __gen_Consumer_main : public __iter<int> {
public:
    int count;
    str *data;
    Consumer *zelf;
    int __last_yield;

    __gen_Consumer_main(Consumer *zelf) {
        this->zelf = zelf;
        __last_yield = -1;
    }

    int next() {
        switch(__last_yield) {
            case 0: goto __after_yield_0;
            default: break;
        }
        count = 0;

        while(1) {
            __last_yield = 0;
            return 1;
            __after_yield_0:;
            count += 1;
            if (zelf->dataReady(const_1)) {
                data = zelf->recv(const_1);
                print("%s %d\n", data, count);
            }
        }
        throw new StopIteration();
    }

};

__iter<int> *Consumer_main(Consumer *zelf) {
    return new __gen_Consumer_main(zelf);

}

} // module namespace

int main(int argc, char **argv) {
    __shedskin__::__init();
    __test__::__init();
    __shedskin__::__exit();
}

-- Michael, 22 Feb 2007 at 15:21, Rating: 0 (Reply) (Moderated by: anon)

Back to front page