[QUIZ#3] teambeta (C)


Teambeta

Erfahrenes Mitglied
Hier ist mal meine Lösung in C.

C:
#include <stdio.h>
#include <stdlib.h>

typedef 
long long int
i64_t;

typedef
enum
{
    false = 0,
    true
} bool;

void generate_table( FILE* src );
void evaluate_table( void );

char*           ins_table       = NULL;
unsigned char*  val_table       = NULL;

int main( int argc, char **argv )
{
    FILE    *input = NULL;
    
    if( argc != 2 )
    {
        printf("[usage] %s: <file>\n",*argv);
        return 0;
    }
    
    input = fopen( *(argv+1), "r" );
    
    if( NULL == input )
    {
        fprintf(stderr, "[error] %s: File does not exist\n", *(argv+1) );
        return 1;
    }
    
    generate_table( input );
    fclose( input );
    
    evaluate_table();
    
    if( NULL != ins_table )
        free( ins_table );
    
    if( NULL != val_table )
        free( val_table );
    
    getchar();    
    return 0;
}

void generate_table( FILE* src )
{
    i64_t   it      = 0;
    char    byte    = 0;
    bool    bracket = false;
    
    while( EOF != ( byte = fgetc(src) ) )
    {
        switch( byte )
        {
            case '+': case '-':
            case '>': case '<':
            case '.': case ',':
            case '[': case ']':
            {
                if( byte == ']' ) bracket = !bracket;
                if( byte == '[' ) bracket = true;
            
                if( NULL == ins_table )
                {
                    ins_table       = malloc( 2 );
                    
                    if( !ins_table )
                    {
                        printf( "[error] no space left.\n" );
                        
                        fclose(src);
                        exit(1);
                    }
                    
                    *(ins_table+it) = byte;
                    it++;
                }
                else
                {
                    ins_table = realloc( ins_table, (size_t)it+2 );
                    
                    if( !ins_table )
                    {
                        printf( "[error] no space left.\n" );
                        
                        if( NULL != ins_table )
                            free( ins_table );
                        
                        fclose(src);
                        exit(1);
                    }
                    
                    *(ins_table+it) = byte;
                    it++;
                }
            } break;
            
            case '\n': case ' ': case '\t': case '\r': break;
            
            default:
            {
                printf("[error] %c: Undefined instruction.\n", byte);
                
                if( NULL != ins_table )
                    free( ins_table );
                
                fclose(src);                
                exit(1);
            } break;
        }
    }

    if( bracket )
    {
        printf("[error] Never ending bracket(s) in code\n");
        
        if( NULL != ins_table )
            free( ins_table );

        fclose(src);                
        exit(1);
    }
    
    *(ins_table+it) = '\0';
}

void evaluate_table( void )
{
    i64_t       bracket     = 0,
                val_ptr     = 1,
                ptr         = 0;
                
    bool        nop         = false;

    val_table = malloc( 2 );
    
    if( NULL == val_table )
    {
        printf( "[error] no more space left.\n" );
        return;
    }
    
    *val_table = 0;
          
    while( 0 != *(ins_table+ptr) )
    { 
        if( nop )
            while( *(ins_table+ptr) != ']' ) ++ptr;    
    
        switch(*(ins_table+ptr))
        {
            case '+':
            {
                if( *(val_table+ptr) == 255 )
                    *(val_table+ptr) = 0;
                else
                    *(val_table+val_ptr) += 1;
            } break;
            
            case '-':
            {
                if( *(val_table+ptr) == 0 )
                    *(val_table+ptr) = 255;
                else
                    *(val_table+val_ptr) -= 1;
            } break;
            
            case '>':
            {
                val_ptr++;
                
                val_table = realloc( val_table, val_ptr+1 );
                
                if( NULL == val_table )
                {
                    printf("[error] Val.-table memory defect (%ld)\n", val_ptr);
                    return;
                }
                
                *(val_table+val_ptr) = 0;
            } break;
            
            case '<':
            {
                val_ptr--;
                
                if( val_ptr < 0 )
                {
                    printf("[error] Val.-ptr. underflow (%ld)\n", val_ptr);
                    return;
                }
            } break;
                        
            case '.':
            {
                printf( "%c", *(val_table+val_ptr) );
            } break;
            
            case ',':
            {
                *(val_table+val_ptr) = getchar();
                
                if( *(val_table+val_ptr) == '\n' )
                    *(val_table+val_ptr) = 0;
            } break;
            
            case '[':
            {
                if( *(val_table+val_ptr) == 0 )
                    nop = true;
            
                bracket = ptr;
            } break;
            
            case ']':
            {
                if( !bracket )
                {
                    printf("\n[error] no end-bracket set\n");
                    return;
                }
                        
                if( !nop )
                    ptr = bracket-1;
                
                nop     = false;
                bracket = 0;
            } break;
        }

        ++ptr;
    }
}

Da die ganze Sache eigentlich recht simpel ist hab ich die Kommentare mal gelassen,
wer aber noch Fragen hat, der soll diese natürlich direkt stellen ;))).
 

OnlyFoo

Erfahrenes Mitglied
Hm, funktioniert bei mir nicht. Stürzt bei mir sofort ab:
*** glibc detected *** ./bf-teambeta: realloc(): invalid next size: 0x0804a008 ***
 

Neue Beiträge