dragons-and-bytecode / comfy

Comfy - the comfortable C dialect
Mozilla Public License 2.0
1 stars 0 forks source link

Modules #3

Open RavenNevermore opened 9 years ago

RavenNevermore commented 9 years ago

The include mechanism in C allows for a lot of goodness, but also for a lot of strange behaviour, since it crudly includes the whole file at the possition of the #include directive.

Comfy has a nice module logic, which can avoid namespace clutter and some of the strangeness, while providing you with a very comfy syntax.

Instead of including a header file like you're used to, you can import any .comfy file into another as a module.

As an example, let's write a simple module:

mymodule.comfy

    public char* name(const char* firstname, const char* lastname)
    {
        int len = strlen(firstname) + strlen(lastname) + 1;
        char* name = malloc(len * sizeof(char));
        sprintf(name, "%s %s", firstname, lastname);
        return name;
    }

Including this somewhere else would look like this:

    // Note that no '#', '"' or '<>' is needed
    import mymodule

    int main(int arc, char* argv[])
    {
        char* name = mymodule.name(argv[1], argv[2]);
        printf("Hello %s", name);
        return 0;
    }

When importing a comfy module into another, Comfy will create a struct with the name of the imported module, containing any public elements of the included module. This way, it handles namespacing and lets you access any member of the module as a parameter of the generated struct.


this issue depends on #4.

RavenNevermore commented 9 years ago

Another option (other than structs) is, to simply replace any references to foo.bar with foo_bar and rely on the header generation in #4, to handle the namespace.

RavenNevermore commented 9 years ago

This may work:

#include "stdio.h"
#include "string.h"
#include "stdlib.h"

void foo_tell(){
    printf("Yeeehaaaa\n");
}

char* foo_show(const char* me){
    char* world = "Hello ";
    char* hi = malloc(sizeof(char) * (strlen(world) + strlen(me)));
    sprintf(hi, "%s%s", world, me);
    return hi;
}

struct {
    char* name;
    char* (*show)(const char*);
    void (*tell)();
} foo = {"12345", &foo_show, &foo_tell};

int main(){

    printf("Show and Tell\n\n");
    printf("%s\n", foo.name);
    printf("%s\n", foo.show("12345"));
    foo.tell();

}
RavenNevermore commented 9 years ago

Next revision:

Modules will be a special form of including a header:

Given a header called 'foo.h', which has all it's specifiers namespaced (foo_something), When using the comfy command import foo Then the header's types and methods become usable as members of a new module-stuct called 'foo'.

In code:

This comfy code:

import(importme);

int main(){
    importme.foo();
}

Given the header 'importme.h' which defines a method void importme_foo(); will produce the following C code:

#include "importme.h"
struct {
    void (*foo)();
} importme = {
    .foo = importme_foo
};

int main(){
    importme.foo();
}
RavenNevermore commented 9 years ago

Problem here is, that this still allows for #define pollution, and the only point in this may be, to replace an underscore with a dot...

Which is kind of pointless.