IMPORTS

BlitzMax Forums/BlitzMax Programming/IMPORTS

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Its a cyclic import cause the two files will keep importing eachother until theres a memory leak. Usually the preprocessor will report an error after some large number of inclusions. You can even include the same file over and over again:

program.c:

#include "program.c"


When run with the GNU C Preprocessor on my Mac it includes itself about 200 times before it reports the error "program.c:1:21: error: #include nested too deeply" and aborts.

Luckily you can use this to your advantage by using conditional includes and the traditional defines at the top of a header:

program.c:

#include "ship.h"
#include "missile.h"

/* ... */


ship.h:

#ifndef SHIP_H
#define SHIP_H

#include "missile.h"

struct ship
{
    float x;
    float y;
    struct missile m;
    /* ... */
};

#endif


missile.h:

#ifndef MISSILE_H
#define MISSILE_H

#include "ship.h"

struct missile
{
    float x;
    float y;
    struct ship parent_ship;
    /* ... */
};

#endif


This would work as each header is only included once but theres no cyclic include and error because both have information about ships and missiles.

So basically, cyclic imports with out memory leaks and errors are possible in Java and to an equivalent effect in C/C++, but in BlitzMax, you can't.

My suggestion would be this: When compiling a .bmx file, scan the file and create a header like file ( .i file I think ) that contains information about Types, Functions, other Imports, variables, etc. from that current .bmx file. Then the source .bmx file is run through the actual compiler. When you encounter an Import statement, find the file thats being imported and check if it already has an up-to-date .i file created. If not, create it in the same way the original was created, and if it needs to import the original file, THE HEADER IS ALREADY THERE. And viola! TShips can know about TMissiles and TMissiles can know about TShips and everybody is happy because the project works AND is organized into sepparate, managable files.

For those who like to read psuedocode:

compile("program.bmx")

function compile(file)
    if header doesn't exists for file then
        generate header for file
    end if

    parse(file)
end function

function parse(file)
    /* ... */

    if statement = import statement then
        if header doesn't exist for imported file then
            generate header for imported file
        end if

        import(imported file)
    end if

    /* ... */
end function

function import(file)
    /* ... */
end function


The header or .i file would look something like this:

type TShip extends TObject
    field x:float
    field y:float
    /* ... */

    method firemissile()
    /* ... */
end type


If I ever design a programming language, it will have this feature.