While looking around for simple compilers to see how easy it is to modify their assembly output syntax, I ran across this tiny file, cc68iii3.zip which bills itself as:
This compiler consists of various modules that build up a
front end — these modules are common to all versions of
this compiler — consisting of parser, analyzer and optimizer,
of modules that are specific for the target processor,
namely *68k.c (for the 68000) and *386.c (for the i386),
and of assembly language output modules that are further
dependent on the (syntax of the) target assembler.
Well isn’t that interesting! So instead of doing something 68000 based, I setup the i386-gas compiler, and tried it with MinGW. And amazingly a hello world program worked!
C:\temp\ccc\cc\infocom> type hello.c void main(){printf("Hello World!\n");} C:\temp\ccc\cc\infocom> ..\c386gas hello.c hello.s C:\temp\ccc\cc\infocom> gcc hello.s -o hello C:\temp\ccc\cc\infocom> hello Hello World! C:\temp\ccc\cc\infocom> type hello.s .file "C386GENERATED" .version "C386 V 1.0" .optim c386_compiled.: .text L1: .byte 72,101,108,108,111,32,87,111,114,108,100,33 .byte 10,0 .align 2 _main: pushl %ebp movl %esp,%ebp pushl $L1 call _printf popl %ecx leave ret .globl _main .globl _printf C:\temp\ccc\cc\infocom>
Well that was unexpected, but great! So I thought I’d modify the simple Infocom interpreter to build with this. I came up with this as a block for gnumake to read in a Makefile
%.o: %.c $(CC) $(CFLAGS) -E $< -o $*.i c386gas $*.i $*.s as $*.s -o $@ rm -f $*.i $*.s
The key substitute is $* which is the 'root' of the file being passed in. Although it's lame doing it this way but it works in a nice automatic enough fashion.
The compiler must be K&R only as it doesn't like standard includes, so I built file.c/io.c/term.c using GCC but all the rest were able to be built just fine. And even better it works!
Although I'd never recommend using something like this in a place that matters. If anything GCC 1.x is probably a better choice, but it's still kind of neat.