/*********************************************************************************************** The Xastha Compiler Beta (Untested, bleeding edge) Use at your own risk... (c)2004, lovepump lovepump@gatheringofgray.com This implements Xastha, a minimalist language imagined and designed by Enjoi. See http://www.snkenjoi.com/ for details. ************************************************************************************************/ #include #include #include #define MEMCHUNK 1024 /* Size of realloc */ #define _MEMCHUNK "1024" #define ERRORFILE "xastha.errlog" #define NAME "xastha-0.03b" FILE *logfile; char mess[1024]; int exit_error(const char *text) { char out[1100]; printf("Fatal Error: %s\n", text); sprintf(out, "Fatal Error: %s\n", text); fwrite(out, strlen(out), 1, logfile); close(logfile); exit(EXIT_FAILURE); } int warning(const char *text) { char out[1100]; printf("Warning: %s\n", text); sprintf(out, "Warning: %s\n", text); fwrite(out, strlen(out), 1, logfile); } int getnumber(const char* t, int* len) { char *x; int i, j; i = 0; while((t[i] >= '0' && t[i] <= '9') && i < 4) i++; if(i > 3 || i <= 0) return -1; x = (char *)malloc(i + 1); strncpy(x, t, i); x[i] = '\0'; *len = i; return atoi(x); } int range_random(const char * t, int* len) { int a, b, a_len, b_len; a = getnumber(t, &a_len); b = getnumber((t + a_len + 1), &b_len); if(a == -1 || b == -1) return -1; *len = a_len + b_len + 2; srand(time(NULL)); return (rand()%(b-a)+a); } void banner() { printf("\n----------------------------------------------------------------------\n"); printf("\nThe %s Compiler\nBy lovepump (c) 2004\n\nImplements Xastha, a langauge created by Enjoi.", NAME); printf("\n----------------------------------------------------------------------\n\n"); } int main(int argc, char **argv) { banner(); char command[1024], tmp; char *inbuf, *inpos; char c[] = {0x25, 0x63, 0x00}; int ret, numlen, filesize, buf_size = 0; int in = 0; int bufp = 0; FILE *infile, *outfile; infile = fopen("try.e", "r"); fseek(infile, 0, SEEK_END); filesize = ftell(infile); rewind(infile); inbuf = (char *)malloc(filesize+1); ret = fread(inbuf, 1, filesize, infile); if(ret < filesize) { exit_error("File read error."); } inbuf[filesize] = '\0'; outfile = fopen("code.c", "w"); buf_size = MEMCHUNK; sprintf(command, "main(){char *p, *buf, *tmp; buf=(char*)malloc(%s);p=buf;", _MEMCHUNK); fwrite(command, strlen(command), 1, outfile); logfile = fopen(ERRORFILE, "w"); inpos = inbuf; while(*inpos != '\0') { sprintf(command, "X"); /*printf("%c: ", *inpos);*/ switch(*inpos) { case('>'): sprintf(command, "p++;"); bufp++; break; case('<'): if(bufp > 0) { sprintf(command, "p--;"); bufp--; } break; case('+'): sprintf(command, "(*p)++;"); break; case('-'): sprintf(command, "(*p)--;"); break; case('.'): sprintf(command, "printf(\"%s\", *p);", c); break; case(','): inpos++; sprintf(command, "*p = '%c';", *inpos); break; case('['): sprintf(command, "tmp = p; while(tmp != 0x00) {"); in++; break; case(']'): if(in > 0) { sprintf(command, "}"); in--; } break; case('^'): sprintf(command, "(*p)+=10;"); break; case('v'): sprintf(command, "(*p)-=10;"); break; case('/'): sprintf(command, "(*p)+=100;"); break; case('\\'): sprintf(command, "(*p)-=100;"); break; case('0'): sprintf(command, "(*p) = 0x00;"); break; case('('): inpos++; ret = getnumber(inpos, &numlen); if(ret < 0) { sprintf(mess, "No terminating bracket at %d", inpos-inbuf); exit_error(mess); } sprintf(command, "printf(\"%c\"); (*p) = 0x00;", ret); inpos+=numlen; break; case('{'): inpos++; ret = range_random(inpos, &numlen); if(ret < 0) { sprintf(mess, "Range random error at %d", inpos-inbuf); exit_error(mess); } sprintf(command, "(*p) = %d;", ret); inpos+=numlen; break; case('~'): sprintf(command, "memset(buf, 0, %d); p = buf;", buf_size); break; case('?'): srand(time(NULL)); ret = rand(); sprintf(command, "(*p) = %d;", ret); break; case('*'): sprintf(command, "*"); break; case('#'): inpos++; ret = getnumber(inpos, &numlen); if(ret < 0) { sprintf(mess, "Index Error at %d", inpos-inbuf); exit_error(mess); } if((ret+(inpos-inbuf)) >= buf_size) { sprintf(mess, "Index out of Range at %d", inpos-inbuf); exit_error(mess); } (*(inpos+ret))=*inpos; break; default: sprintf(command, "X"); sprintf(mess, "Bad syntax at: %d\n", inpos-inbuf); warning(mess); } if(command[0] == '*') break; inpos++; if(command[0] == 'X') continue; /*printf("%s\n", command);*/ fwrite(command, strlen(command), 1, outfile); fwrite("\n", 1, 1, outfile); } sprintf(command, "free(buf); exit(0);}\n"); fwrite(command, strlen(command), 1, outfile); fclose(infile); fclose(outfile); fclose(logfile); sprintf(command, "gcc code.c -o code"); system(command); sprintf(command, "gcc code.c -S -o code.s"); system(command); printf("\n\n-----------------------------------------------------------"); printf("\nOutput is to:\n\nAssembly - code.s\nExecutable - code\nErrors - xastha.errlog\n\n"); }