/*
* CLAW compiler. © Copyright 2003 Terrasoft Technologies. This program
* is governed by the GNU public license. See the file COPYING.TXT for details.
*
* This compiler generates native machine code for whatever processor.
* It is currently configured to generate an MS-DOS .COM file, but it
* should be relatively easy to alter.
*/
#include <stdio.h>
void compile(); // prototyping, don't leave home without it
unsigned short location = 3; // oh, those silly unsigned's... ha ha.
unsigned short datasize = 1;
unsigned short ptr = 1;
FILE *z, *Z; // FILES: z = the file being compiled, Z = compiled output
char b;
int q;
unsigned short n;
main( int argc, char *argv[] ) {
q=argc; // doo doo doo, making global variables, doo doo doo!
if(q<3) // if there are less than three arguments
printf("usage: clawc [input] [output]\n"); // tell them how to fucking use clawC
else { // otherwise
if ( z = fopen( argv[1], "r" ) ) // if you can open the file for input
{ // then
if ( Z = fopen( argv[2], "wb" ) ) // if you can open the file for output
{ // THEN
fwrite( "\xbe\x00\x00", 1, 3, Z ); // start doing that crazy COM shit
compile();
fwrite( "\xb8\x00\x4c\xcd\x21", 1, 5, Z );
location += 261;
for ( ptr = 0; ptr < datasize; ptr++ )
{
fwrite( "\x00", 1, 1, Z );
}
fseek( Z, 1, SEEK_SET );
fwrite( &location, 1, 2, Z );
fclose( Z );
}
else // else, if you CAN'T write to the file
printf("error: file `%s' can not be written to\n",argv[2]); // then bitch
fclose(z); // close the fucking file
}
else // else, if you can't read the file
printf("error: file `%s' does not exist\n",argv[1]); // then bitch
}
}
void compile() {
unsigned short m;
while( ( b=getc(z) ) != EOF ) // while the end of the file hasn't been reached
{
switch ( b )
{
// do all of this shit
case '<': fwrite( "\x4e", 1, 1, Z ); location++; ptr--; break;
case '>':
fwrite( "\x46", 1, 1, Z );
location++;
ptr++;
if ( ptr > datasize ) datasize = ptr;
break;
case '+': fwrite( "\xfe\x04", 1, 2, Z ); location += 2; break;
case '-': fwrite( "\xfe\x0c", 1, 2, Z ); location += 2; break;
case '.':
fwrite( "\xb4\x40\xbb\x01\x00\x89\xd9\x89\xf2\xcd\x21", 1, 11, Z );
location += 11;
break;
case ',':
fwrite( "\xb4\x01\xcd\x21\x3c\x0d\x75\x07\xb8\x0a\x02\xb2\x0a\xcd\x21\x88\x04", 1, 17, Z );
location += 17;
break;
case '[':
m = location;
fwrite( "\x80\x3c\x00\x75\x03\xe9\x00\x00", 1, 8, Z );
location += 8;
compile();
fwrite( "\xe9", 1, 1, Z );
location += 3;
n = m - location;
fwrite( &n, 1, 2, Z );
fseek( Z, m + 6, SEEK_SET );
n = location - m - 8;
fwrite( &n, 1, 2, Z );
fseek( Z, 0, SEEK_END );
break;
case ']': return;
}
}
}