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:
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:
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:
The header or .i file would look something like this:
If I ever design a programming language, it will have this feature.
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.