#include "../common/types.h" #include "../common/opcodeInfo.h" #include "../common/buffer.h" #include "../common/sourceFile.h" #include "assembler.h" #include "assemblerConfig.h" #include #include #define error(...) fprintf(stderr, __VA_ARGS__) int main(int argc, char** argv) { //BEGIN variable definitions int sourceFile=-1, outputFile=-1, configFile=-1; buffer_t sourceBuffer, outputBuffer, configBuffer, infoBuffer; int sourceLen, configLen, outputPos; assembler_config_t config; source_file_t header; mapping_t mapping; assembler_t assembler; int hasConfig; //END variable definitions //BEGIN check usage argc--; if(argc!=2&&argc!=3) { error("Usage: %s [config]\n", argv[0]); return 1; } else { printf("Using %d arguments\n", argc); } hasConfig=argc==3; //END check usage //BEGIN open the files sourceFile=File_open(argv[1], FILE_OPEN_read); outputFile=File_open(argv[2], FILE_OPEN_write|FILE_OPEN_create); if(hasConfig) configFile=File_open(argv[3], FILE_OPEN_read); //END open the files //BEGIN check if opening the files went well if(sourceFile==-1) { error("ERR: Couldn't open input file %s\n", argv[1]); return 1; } if(outputFile==-1) { error("ERR: Couldn't open output file %s\n", argv[2]); return 1; } if(hasConfig&&configFile==-1) { error("ERR: Couldn't open config file %s\n", argv[3]); return 1; } //END check if opening the files went well //BEGIN read the source file sourceLen=File_length(sourceFile); if(!allocBuffer(&sourceBuffer, sourceLen)) { error("ERR: Failed to allocate memory for reading source file\n"); return 1; } File_read(sourceFile, 0, sourceBuffer.data, sourceLen); File_close(sourceFile); printf("Successfully loaded source file in memory\n"); //END read the source file //BEGIN read the config file if(hasConfig) { configLen=File_length(configFile); if(!allocBuffer(&configBuffer, configLen)) { error("ERR: Failed to allocate memory for reading config file\n"); return 1; } File_read(configFile, 0, configBuffer.data, configLen); File_close(configFile); printf("Successfully loaded config file in memory\n"); } //END read the config file //BEGIN allocate the output and info buffer if(!allocBuffer(&outputBuffer, 256)) { error("ERR: Failed to allocate memory for output buffer\n"); return 1; } outputBuffer.size=0; outputPos=0; if(!allocBuffer(&infoBuffer, 256)) { error("ERR: Failed to allocate memory for info buffer\n"); return 1; } infoBuffer.size=0; //END allocate the output and info buffer //BEGIN read the config if(hasConfig) { if(!readConfig(&configBuffer, &config)) { error("ERR: Error while reading config file\n"); return 1; } freeBuffer(&configBuffer); printf("Successfully read the config\n"); } //END read the config //BEGIN assemble the code printf("Preparing to assemble the code\n"); //setup the assembler struct if(hasConfig) assembler.offset=config.codeOffset; else assembler.offset=0x0000; assembler.pos=0; assembler.line=1; assembler.col=1; assembler.labelCount=0; assembler.in=&sourceBuffer; assembler.out=&outputBuffer; assembler.stdout=&infoBuffer; //register opcodes Opcode_registerOpcodes(); //assemble the code if(!Assembler_assemble(&assembler)) { error("ERR: Failed to assemble the code\n"); toStringBuffer(&infoBuffer); error("%s", (char*) infoBuffer.data); return 1; } //print information printf("Successfully assembled the code\n"); toStringBuffer(&infoBuffer); printf("%s", (char*) infoBuffer.data); freeBuffer(&infoBuffer); //END assemble the code //BEGIN compute the header //we hash the source file and push source version printf("Computing hash\n"); header.magic=MAGIC; header.hash=strsuml((char*) sourceBuffer.data, sourceBuffer.size); header.version=SOURCE_VERSION; freeBuffer(&sourceBuffer); if(hasConfig) { //add the header printf("Injecting config\n"); header.entryPoint=config.entryPoint; header.mappings=config.mappingCount; File_write(outputFile, outputPos, &header, HEADER_LENGTH); outputPos+=HEADER_LENGTH; for(int i=0; i