RNA/rna.c
Jump to navigation
Jump to search
//
// main.c
// RNA
//
// Created by Cyrus Hackford on 2011.
// Copyright 2011 SI devIk. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define RNA_INTERP_VERSION "1.0"
#define RNA_STR_INIT_SIZE 32
#ifndef OBJC_BOOL_DEFINED
#define OBJC_BOOL_DEFINED
typedef signed char BOOL;
#define NO ((BOOL)0)
#define YES ((BOOL)1)
#endif
typedef struct _Memory {
unsigned char *mem;
unsigned long alloc;
unsigned long used;
} Memory;
static BOOL appendMem(Memory *memory, const char *appendable) {
size_t leng=strlen(appendable);
if((memory->alloc-memory->used)<leng) {
unsigned char *test=(unsigned char *)realloc(memory->mem, (size_t)(memory->used+leng+1));
if(test==NULL)
return NO;
memory->mem=test;
memory->alloc+=leng;
}
{
unsigned char *temp=memory->mem;
size_t length=leng;
while(*temp!='\0')
temp++;
while(length!=0 && (*temp=*appendable++)!='\0') {
length--;
temp++;
}
if(*temp!='\0')
*temp='\0';
}
memory->used+=leng;
return YES;
}
static BOOL createMem(Memory **memory) {
*memory=(Memory *)malloc(sizeof(Memory));
if(*memory==NULL)
return NO;
(*memory)->mem=(unsigned char *)malloc(RNA_STR_INIT_SIZE+1);
if((*memory)->mem==NULL) {
free(*memory);
return NO;
}
memset((*memory)->mem, 0, RNA_STR_INIT_SIZE+1);
(*memory)->alloc=RNA_STR_INIT_SIZE;
(*memory)->used=0;
return YES;
}
static void destroyMem(Memory **memory, BOOL completely) {
if(completely==YES)
free((*memory)->mem);
free(*memory);
}
static void dumpMem(Memory *memory, unsigned long limit) { // debugging purpose
unsigned long loop=0, loopy;
if(limit==0)
loop=memory->alloc;
else
loop=limit<memory->alloc?limit:memory->alloc;
printf("\nMemory#%lu: [", (unsigned long)memory);
for(loopy=0; loopy<loop; ++loopy) {
printf("%u", memory->mem[loopy]);
if(loopy!=(loop-1))
printf(", ");
}
printf("]\n");
}
static BOOL expandMem(Memory *memory, size_t size) {
unsigned char *test;
if(memory->alloc>=size)
return YES;
test=(unsigned char *)realloc(memory->mem, size+1);
if(test==NULL)
return NO;
memory->mem=test;
return YES;
}
static size_t ustrlen(const unsigned char *s) {
const unsigned char *p=s;
while(*p!='\0')
p++;
return (size_t)(p-s);
}
int main(int argc, const char **argv) {
unsigned char *instructions;
if(argc==1) {
printf("The RNA Programming Language -- Interpreter v%s\nUsage: %s filename\n", RNA_INTERP_VERSION, argv[0]);
return EXIT_FAILURE;
}
{
BOOL failed;
char *tempStrg;
FILE *stream;
Memory *instructionHolder;
if(createMem(&instructionHolder)==NO) {
printf("Interpreter error: Cannot allocate memory to hold RNA instructions.\nTerminated.\n");
return EXIT_FAILURE;
}
if((stream=fopen(argv[1], "r"))==NULL) {
printf("Interpreter error: Cannot open RNA instruction file: %s.\nTerminated.\n", argv[1]);
destroyMem(&instructionHolder, YES);
return EXIT_FAILURE;
}
failed=NO;
if((tempStrg=(char *)malloc(sizeof(char)*512))==NULL) {
printf("Interpreter error: Cannot allocate memory to hold RNA instructions.\nTerminated.\n");
fclose(stream);
destroyMem(&instructionHolder, YES);
return EXIT_FAILURE;
}
while(feof(stream)==0) {
fread(tempStrg, sizeof(char), 512, stream);
if(appendMem(instructionHolder, tempStrg)==NO) {
failed=YES;
break;
}
}
free(tempStrg);
fclose(stream);
if(failed==YES) {
printf("Interpreter error: Cannot resize memory space used to hold RNA instructions.\nTerminated.\n");
destroyMem(&instructionHolder, YES);
return EXIT_FAILURE;
}
instructions=instructionHolder->mem;
destroyMem(&instructionHolder, NO);
}
{
// A=1 U=2 G=3 C=4
unsigned char *ptr;
Memory *memory;
if(createMem(&memory)==NO) {
printf("Interpreter error: Cannot allocate memory to hold on-execution data.\nTerminated.\n");
free(instructions);
return EXIT_FAILURE;
}
unsigned int codon=0, codonSize=100, loopActivatorIndex=0;
unsigned long loop, loopActivators[2][64], loopy, strg;
BOOL loopActivated=NO, skipUntilLoopTerminator=NO, started=NO;
for(loop=ustrlen(instructions), loopy=0; loopy<loop; ++loopy) {
{
unsigned int inst=0;
switch(instructions[loopy]) {
case 'A':
case 'a':
inst=1;
break;
case 'U':
case 'u':
inst=2;
break;
case 'G':
case 'g':
inst=3;
break;
case 'C':
case 'c':
inst=4;
break;
}
if(inst==0)
continue;
codon+=inst*codonSize;
}
if(codonSize==1) {
if(started==NO) {
if(codon==123) { // Metionine
started=YES;
strg=0;
ptr=memory->mem;
}
} else {
if(skipUntilLoopTerminator==YES && (codon==212 || codon==214))
skipUntilLoopTerminator=NO;
else {
switch(codon) {
case 211: // Termination
case 213:
case 231:
started=NO;
break;
case 233: // Tryptophan
strg=0;
break;
case 111: // Lysine
case 113:
++strg;
break;
case 112: // Asparagin
case 114:
--strg;
break;
case 341: // Alanine
case 342:
case 343:
case 344:
strg=(unsigned long)*ptr;
break;
case 141: // Threonine
case 142:
case 143:
case 144:
expandMem(memory, strg+1);
ptr=&(memory->mem[strg]);
break;
case 441: // Proline
case 442:
case 443:
case 444:
{
int temp;
scanf("%d", &temp);
*ptr=(unsigned char)(temp&0xF);
}
break;
case 421: // Leucine
case 422:
case 423:
case 424:
printf("%c", (char)(*ptr&0x7F));
break;
case 131: // Arginine
case 133:
case 431:
case 432:
case 433:
case 434:
expandMem(memory, strg+1);
*ptr+=memory->mem[strg];
break;
case 132: // Serine
case 134:
case 241:
case 242:
case 243:
case 244:
expandMem(memory, strg+1);
*ptr*=memory->mem[strg];
break;
case 411: // Glutamine
case 413:
expandMem(memory, strg+1);
*ptr-=memory->mem[strg];
break;
case 412: // Histidine
case 414:
expandMem(memory, strg+1);
*ptr/=memory->mem[strg];
break;
case 311: // Glutamic acid
case 313:
expandMem(memory, strg+1);
*ptr=(*ptr==memory->mem[strg]?1:0);
break;
case 312: // Aspartic acid
case 314:
if(*ptr==0) {
if(loopActivated==NO)
skipUntilLoopTerminator=YES;
else {
loopy=loopActivators[1][loopActivatorIndex--];
loopActivated=NO;
}
} else {
loopActivated=YES;
loopActivators[0][loopActivatorIndex]=loopy-2;
}
break;
case 212: // Tyrosine
case 214:
if(loopActivated==YES) {
loopActivators[1][loopActivatorIndex]=codon+1;
loopy=loopActivators[0][loopActivatorIndex--];
}
break;
// Other codons are no-op yet. :)
}
}
}
codon=0;
codonSize=100;
} else
codonSize/=10;
}
}
free(instructions);
return EXIT_SUCCESS;
}