void initByteCodes() { if (gCompilingByteCodes) { freeByteCodes(gCompilingByteCodes); gCompilingByteCodes = NULL; } }
/* Takes given latria code & compiles it for increased efficiency (removes whitespace, tabs, comments, etc) * Takes latria code from a provided file to compile */ void compileLatria(char *fn) { JumpUpdate *ju = NULL; FILE *in, *out; size_t len = strlen(fn); /* Create our output file name */ char *nf = malloc(len+2); /* Copy the file name we were given */ strncpy( nf, fn, len); /* Append 'c' to the end and \0 (compiled files have the extension .lrac) */ nf[len] = 'c'; nf[len+1] = '\0'; /* Open the file to read */ in = fopen(fn,"r"); /* Check we have an opened file */ if(in == NULL) { /* We did NOT open a file, fail and exit */ /* free our output file name */ free(nf); /* no file */ printf("\nThe file you provided %s could not be found!\n\n", fn); exit(1026); } /* Input file is good, open our new (compiled) file */ out = fopen(nf, "wb"); /* Validate we actually opened a file */ if(out == NULL) { /* output file was not opened, cleanup and exit */ printf("Tmp file file %s could not be opened/created to write to!\n\n", nf); free(nf); exit(1027); } /* A files are good, start reading input and compiling */ /* Read a line from our input */ while(fgets( input, INPUT_SIZE, in)) { short retSize; /* Compile this line of latria */ compileLine(input); /* Check to see if this line created any bytecode to read */ if((retSize = getByteCodeCount()) > 0) { /* Bytecode available, write it into our output file */ fwrite(readByteCodes(), sizeof(unsigned char), (size_t)retSize, out); } } /* Dispatch up any pending conditional jumps */ dispatchIfAndElseIf(); /* Loop over any jump updates we need to process */ while((ju = popJumpUpdate()) != NULL) { /* Create an array to hold our new jump instruction address */ char jumpCode[LAT_ADDRESS_SIZE+1] = {0}; /* Seek to the indicated address to update */ fseek( out, ju->bytecodeAddr, SEEK_SET); /* Convert our new jump address into a hexcode */ sprintf(jumpCode, LAT_ADDRESS_FORMAT_STRING, ju->jumpAddr); /* Update the address we are currently at with our new hex one */ fwrite(jumpCode, sizeof(unsigned char), LAT_ADDRESS_SIZE, out); } /* Close our input and output files */ fclose(in); fclose(out); /* free underlying byte code allocations */ freeByteCodes(); /* free underlying lexical allocations */ freeLexicalAllocations(); /* deallocate the stack */ deallocStackStates(); /* free our compiled file name */ free(nf); }