Esoterische Programmiersprache Interpreter öffnen?



  • Also ich habe folgende Dateien dabei:

    ._aunts-beatnik
    ._beatnik.c
    ._beatnik.pl

    aunts.beatnik
    beatnik.c
    beatnik.o
    istack.c
    istack.h
    Makefile

    muss ich die jetzt irgendwie verknüpfen oder wie? Dachte bisher beatnik.c muss das richtige sein 😕

    hier mal der code vom istack.c

    /*  Copyright (C) 2007 Rami Chowdhury
        Simple generic stack, built around integers
    
        Licensed under the GNU Lesser General Public License, version 2
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include "istack.h"
    #ifdef _SIMPLE_INT_STACK
    
    istack* stack_init(unsigned long start_size)
    {   // Allocates memory and sets initial variables
        unsigned long alloc_size = (start_size + 1) * sizeof(int);
        istack* s = calloc(sizeof(istack), 1);
        s->pile = calloc(alloc_size + 2, 1);
        s->capacity = start_size;
        s->size = 0;
    
        return s;
    }
    
    void stack_destroy(istack* s)
    {   // The pile *has* to be freed!
        free(s->pile);
        free(s);
    }
    
    int stack_is_empty(istack* s)
    {
        return (s->size == 0);
    }
    
    void stack_resize(istack* s)
    {   // Allocates a double-size pile, copies data over, and frees the old one.
        unsigned long csize = s->capacity;
        unsigned long nsize = (csize * 2);
        unsigned long n_alloc_size = (nsize + 1) * sizeof(int);
        // printf("\tAllocating new pile to be %ld\n", nsize);
    
        int* new = calloc(n_alloc_size + 2, 1);
        int* scur = s->pile; int* ncur = new;
        int i = 0;
        for (i = 0; i <= csize; i++)
        {
            // printf("\t\tAt pointers s = %p (%d), n = %p (%d)\n", scur, *scur, ncur, *ncur);
            *(ncur++) = *(scur++);
        }
        free(s->pile);
    
        s->pile = new;
        s->capacity = nsize;
    }
    
    int stack_pop(istack* s)
    {   // Checks stack isn't empty, then returns the value on 'top' of the stack. This is actually
        // pile + (size - 1), because of zero-based indexing, so we decrement size *before* getting
        // the value and returning it.
        // printf("Pre-pop "); stack_print(s);
        if ((s->size) < 1)
        {
            fprintf(stderr, "Cannot pop off empty stack!\n");
            return 0;
        }
    
        (s->size)--;
        int value = *(s->pile + s->size);
    
        // printf("Pos-pop "); stack_print(s);
        return value;
    }
    
    void stack_push(istack* s, int value)
    {   // Ensures seamless addition by checking capacity and resizing if necessary. Due to zero-
        // based indexing, to avoid leaving a blank slot at the start assigns to the array and
        // *then* increments the size (so the 'current' value is actually pile + (size - 1).
        if (s->size >= s->capacity)
        {
            stack_resize(s);
        }
    
        *(s->pile + s->size) = value;
        (s->size)++;
    }
    
    int stack_peek(istack* s)
    {   // NB: See comments to stack_push and stack_pop for explanation of non-intuitive 'current' position
        return *(s->pile + (s->size - 1));
    }
    
    void stack_test(int test_cap, int test_max)
    {   // For i from 0 to test_max, pushes i^2 onto stack; later pops all values off it, reporting status each step.
        istack* s = stack_init(test_cap);
        int i = 0;
        for (i = 0; i < test_max; i++)
        {
            printf("Pushed %d onto stack\n", (i*i));
            stack_push(s, (i*i));
            printf("\tStack status: Pile %p, Size %ld, Capacity %ld, Current (Pile + Size) %p\n", s->pile, s->size, s->capacity, (s->pile + s->size));
    
        }
    
        int sv;
        while(!stack_is_empty(s))
        {
            sv = stack_pop(s);
            printf("Popped %d off stack\n", sv);
            printf("\tStack status: Pile %p, Size %ld, Capacity %ld, Current (Pile + Size) %p\n", s->pile, s->size, s->capacity, (s->pile + s->size));
        }
        printf("Stack status: Pile %p, Size %ld, Capacity %ld, Current (Pile + Size) %p\n", s->pile, s->size, s->capacity, (s->pile + s->size));
    }
    
    void stack_print(istack* s)
    {   // Prints out the contents of the stack, plus a status report
        printf("[ ");
        int i = 0;
        for (i = 0; i < (s->size); i++)
        {
            printf("%d ", *(s->pile + i));
        }
        printf("] -- Pile %p, Size %ld, Capacity %ld, Current (Pile + Size) %p\n", s->pile, s->size, s->capacity, (s->pile + s->size));
    }
    
    #endif
    


  • In dein Codeblocks Projekt muss du mindestens

    beatnik.c
    istack.c
    istack.h

    einbinden.



  • wenn ich i stack.h weglasse dann startet er! allerdings kommt die Meldung "no sourcecode file specified"

    d.h. ich muss hier:

    // Now try and get the source code file...
        FILE* f = fopen(config.filename, "");
        if(!f)
    

    irgendwie die quelldatei sprich meinen programm code angeben oder? Wie muss ich denn da den Pfad zur Datei genau angeben? Wenn ich z.B. helloworld.beatnik eingebe (die sich im selben Ordner befindet) führt das zu nix 😞

    Irgendow muss ich meine datei einbinden ich weiß nur nicht wo bzw. wie genau

    Hier nochmal der ganze code der beatnik.c :

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    // My own simple integer-based stack implementation
    #include "istack.c"
    
    typedef struct _configuration
    {   // Obviously, holds configuration values
        int stack_size;
        char* filename;
    } configuration;
    
    // Forward declaration of functions, for convenience and so main() can go up top
    unsigned char get_score(char* word);
    int           handle_cmdline(int argc, char** argv, configuration* config);
    char*         parse(char* source, unsigned long* len);
    int           execute(char* bytecode, unsigned long max_len, istack* stack);
    
    int main(int argc, char** argv)
    {   // First, set configuration defaults
        configuration config;
        config.stack_size = 128;
        config.filename = NULL;
    
        if(handle_cmdline(argc, argv, &config) == -1)
        { // Error handling command-line. Just die gracefully.
            return -1;
        }
    
        // Now try and get the source code file...
        FILE* f = fopen(config.filename, "");
        if(!f)
        {
            fprintf(stderr, "Error opening Beatnik file (%s)!\n", config.filename);
            return -1;
        }
        // Determine file size by seeking to the end and checking position, then resetting
        unsigned long fsize = 0;
        fseek(f, 0, SEEK_END);
        fsize = (unsigned long) ftell(f);
        fseek(f, 0, SEEK_SET);
        // Allocates some memory for the file contents, and initializes some variables to
        // help read it in
        char* source = calloc(fsize + 1, 1);
        char* src_ptr = source;
        unsigned long byte_count;
        while(!feof(f) && !ferror(f))
        {   // 4k at a time
            byte_count = fread(src_ptr, 1, 4096, f);
            src_ptr += byte_count;
        }
        // An error occured -- die
        if(ferror(f))
        {
            fprintf(stderr, "Error reading the file %s!\n", config.filename);
            fclose(f);
            return -1;
        }
        // Close file like a good program
        fclose(f);
        // Initialize program execution state (parse() returns bytecode and sets max_len to length of
        // bytecode). Also, free source as it's now redundant.
        unsigned long max_len;
        char* bytecode = parse(source, &max_len);
        istack* stack = stack_init(config.stack_size);
        free(source);
        // Go, go Beatnik rangers!
        int return_val = execute(bytecode, max_len, stack);
        // Cleanup
        stack_destroy(stack);
        free(bytecode);
        // If execute() returned nonzero, do that as well.
        return return_val;
    }
    
    int handle_cmdline(int argc, char** argv, configuration* config)
    {   // Parses command-line options with getopt() (POSIX). Returns -1 on error.
        char opt;
        opterr = 0; // Disable getopt() errors
    
        while ((opt = getopt(argc, argv, "f:s:h")) != -1)
        {
            switch(opt)
            {
                case 'f':
                    /* Explicit setting of the filename. Generally unnecessary... */
                    config->filename = optarg;
                    break;
                case 's':
                    /* Setting the initial stack size (it will grow as required) */
                    config->stack_size = strtol(optarg, (char**) NULL, 10);
                    if ((config->stack_size < 1) || (config->stack_size > 16384))
                    {
                        fprintf(stderr, "Invalid initial stack size specified (%d)! Value must be between 1 and 16384!\n", config->stack_size);
                        return -1;
                    }
                    break;
                case 'h':
                    /* Duh, help and usage */
                    printf("Beatnik programming language interpreter\n");
                    printf("Copyright (C) 2007 Rami Chowdhury\n");
                    printf("----------------------------------------\n");
                    printf("Executes programs written in the Beatnik language, as specified by\n");
                    printf("Cliff Biffle (http://www.cliff.biffle.org/esoterica/beatnik.html).\n");
                    printf("USAGE: %s [-OPTS] [-f] FILENAME\n", argv[0]);
                    printf("\n");
                    printf("Recognizes the following options:\n");
                    printf("  -h            Shows this help message.\n");
                    printf("  -s [number]   Sets the initial size of the 'stack' on which Beatnik\n");
                    printf("                performs arithmetic. Low values of this may mean the\n");
                    printf("                stack  has to be resized often, which is slow and in-\n");
                    printf("                efficient. High values can waste memory.\n");
                    printf("                Defaults to 128, and can range from 1 to 16384. \n");
                    printf("  -f [file]     Specifies the Beatnik source code file to execute.\n");
                    printf("                This is generally unnecessary as the first non-option\n");
                    printf("                argument is assumed to be a Beatnik program file.\n");
                    return -1;
                    break;
                default:
                    fprintf(stderr, "Unrecognized option (-%c). Please try %s -h for usage information.\n", optopt, argv[0]);
                    return -1;
                    break;
            }
        }
    
        if (config->filename == NULL)
        {   // We need a file to execute!
            if (argv[optind] != NULL)
            {
                config->filename = argv[optind];
            }
            else
            {
                fprintf(stderr, "No source code file specified!\n");
                return -1;
            }
        }
    
        return optind;
    }
    
    char* parse(char* source, unsigned long* len)
    {   // Tokenizes source and returns a pointer to memory filled with bytecode
        /* REMINDER: uses strtok() so mutates source! */
        // Initially allocates enough memory for all the source text
        char* buf = calloc(strlen(source) + 1, 1);
        char* buf_ptr = buf;
        // Delimiters for tokenizing are any punctuation characters
        const char* punct = "!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ \n\t\r";
        char* word = strtok(source, punct);
        while(word != NULL)
        {   // Keeps going till we run out of tokens
            (*buf_ptr) = get_score(word); buf_ptr++;
            // printf("%s scored %d\n", word, *(buf_ptr - 1));
            word = strtok(NULL, punct);
        }
        // Now allocates a properly sized bytecode region, and copies it in
        unsigned long code_len = (unsigned long) (buf_ptr - buf);
        char* bytecode = calloc(code_len + 2, 1);
        strncpy(bytecode, buf, code_len);
        free(buf);
    
        (*len) = code_len;  // tells main() how long the bytecode is
        return bytecode;
    }
    
    unsigned char get_score(char* word)
    {   // For convenience, Scrabble data is hardcoded ;-)
        unsigned short tile_scores[] =
        {
            1,  // a
            3,  // b
            3,  // c
            2,  // d
            1,  // e
            4,  // f
            2,  // g
            4,  // h
            1,  // i
            8,  // j
            5,  // k
            1,  // l
            3,  // m
            1,  // n
            1,  // o
            3,  // p
            10, // q
            1,  // r
            1,  // s
            1,  // t
            1,  // u
            4,  // v
            4,  // w
            8,  // x
            4,  // y
            10  // z
        };
    
        // Now making use of the above...
        unsigned char word_score = 0;
        unsigned int wlen = strlen(word);
        char *w = word, *wmax = word + wlen, c = 0;
        while (w <= wmax)
        {
            c = (*w);
            if (c < 91)
            {   // Uppercase letters are ASCII 65-90, lowercase are 97-122 -- thus
                // ('a' - 'A') == 32, adding it turns everything to lowercase.
                c += 32;
            }
            if ((c > 96) && (c < 123))
            {   // It's a letter, so increment word_score by its score. Since
                // 'a' == 97, subtracting 97 makes c a valid index into tile_scores
                word_score += tile_scores[c - 97];
                // printf("\t%c scored %d, total = %d\n", c, tile_scores[c - 97], word_score);
            }
            w++;
        }
        return word_score;
    }
    
    int execute(char* bytecode, unsigned long max_len, istack* stack)
    {
        char* cur_byte = bytecode;
        char opcode = 0; int tmp1 = 0, tmp2 = 0;
        while((cur_byte - bytecode) <= max_len)
        {   // Keep going till we run out of opcodes. The 'stop' opcode will exit the function as well.
            opcode = *cur_byte;
            switch(opcode)
            {
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                    /* Does nothing. The Beatnik Interpreter may mock you for your poor scoring, at its discretion. */
                    if (rand() < 5)
                    {
                        fprintf(stderr, "Yeah, dude, %d's a *great* score... <rolls eyes>", opcode);
                    }
                    cur_byte++;
                    break;
                case 5:
                    /* Finds the score of the next word and pushes it onto the stack. Skips the aforementioned next word. */
                    stack_push(stack, *(cur_byte + 1));
                    cur_byte += 2;
                    break;
                case 6:
                    /* Pops the top number off the stack and discards it. */
                    stack_pop(stack);
                    cur_byte++;
                    break;
                case 7:
                    /* Adds the top two values on the stack together, pushing the result. */
                    tmp1 = stack_pop(stack); tmp2 = stack_pop(stack);
                    stack_push(stack, (tmp1 + tmp2));
                    cur_byte++;
                    break;
                case 8:
                    /* Input a character from the user and push its value on the stack. Waits for a keypress. */
                    printf("Type a character: ");
                    tmp1 = getchar();
                    stack_push(stack, tmp1);
                    cur_byte++;
                    break;
                case 9:
                    /* Pop a number off the stack and output the corresponding ASCII character to the screen.*/
                    tmp1 = stack_pop(stack);
                    putchar(tmp1);
                    cur_byte++;
                    break;
                case 10:
                    /* Subtract the top value on the stack from the next value on the stack, pushing the result.*/
                    tmp1 = stack_pop(stack); tmp2 = stack_pop(stack);
                    stack_push(stack, (tmp2 - tmp1));
                    cur_byte++;
                    break;
                case 11:
                    /* Swap the top two values on the stack.*/
                    tmp1 = stack_pop(stack); tmp2 = stack_pop(stack);
                    stack_push(stack, tmp1); stack_push(stack, tmp2);
                    cur_byte++;
                    break;
                case 12:
                    /* Pop a value of the stack, and push it twice.*/
                    tmp1 = stack_pop(stack);
                    stack_push(stack, tmp1); stack_push(stack, tmp1);
                    cur_byte++;
                    break;
                case 13:
                    /* Pop a number from the stack, and figure out the score of the next word. If the number from the stack is zero, skip ahead by [score-of-next-word] words. (The skipping is actually n+1 words, because the word scored is also skipped.)*/
                    if(stack_pop(stack) == 0)
                    {
                        cur_byte += *(cur_byte + 1);
                    }
                    cur_byte += 2;
                    break;
                case 14:
                    /* Same as above, except skip if the value on the stack isn't zero. */
                    if(stack_pop(stack) != 0)
                    {
                        cur_byte += *(cur_byte + 1);
                    }
                    cur_byte += 2;
                    break;
                case 15:
                    /* Skip back n words, if the value on the stack is zero. */
                    if(stack_pop(stack) == 0)
                    {
                        cur_byte -= *(cur_byte + 1);
                    }
                    cur_byte++;
                    break;
                case 16:
                    /* Skip back if it's not zero. */
                    if(stack_pop(stack) == 0)
                    {
                        cur_byte -= *(cur_byte + 1);
                    }
                    cur_byte++;
                    break;
                case 17:
                    /* Stop the program */
                    return 0;
                    break;
                case 18:
                case 19:
                case 20:
                case 21:
                case 22:
                case 23:
                    /* Does nothing. However, the score is high enough that the Beatnik Interpreter will not mock you, unless it's had a really bad day.*/
                    break;
                default:
                    /* Garners "Beatnik applause" for the programmer. This generally consists of reserved finger-snapping.*/
                    fprintf(stderr, "Wow <snap> I'm impressed <snap>\n");
                    cur_byte++;
                    break;
            }
            // printf("Opcode %d, ", opcode);
            // stack_print(stack);
        }
        return 0;
    }
    

    lg

    wenn ich istack.h drinne lasse kommt dieser fehler:

    Compiling: C:\Users\Vale\Desktop\beatnik\beatnik.c
    In file included from C:\Users\Vale\Desktop\beatnik\beatnik.c:17:
    C:\Users\Vale\Desktop\beatnik\istack.h:16: error: redefinition of 'struct int_stack'
    C:\Users\Vale\Desktop\beatnik\istack.h:20: error: conflicting types for 'istack'
    C:\Users\Vale\Desktop\beatnik\istack.h:20: note: previous declaration of 'istack' was here
    C:\Users\Vale\Desktop\beatnik\istack.h:23: error: conflicting types for 'stack_init'
    C:\Users\Vale\Desktop\beatnik\istack.c:14: note: previous definition of 'stack_init' was here
    C:\Users\Vale\Desktop\beatnik\istack.h:24: error: conflicting types for 'stack_destroy'
    C:\Users\Vale\Desktop\beatnik\istack.c:25: note: previous definition of 'stack_destroy' was here
    C:\Users\Vale\Desktop\beatnik\istack.h:25: error: conflicting types for 'stack_is_empty'
    C:\Users\Vale\Desktop\beatnik\istack.c:31: note: previous definition of 'stack_is_empty' was here
    C:\Users\Vale\Desktop\beatnik\istack.h:26: error: conflicting types for 'stack_resize'
    C:\Users\Vale\Desktop\beatnik\istack.c:36: note: previous definition of 'stack_resize' was here
    C:\Users\Vale\Desktop\beatnik\istack.h:27: error: conflicting types for 'stack_pop'
    C:\Users\Vale\Desktop\beatnik\istack.c:57: note: previous definition of 'stack_pop' was here
    C:\Users\Vale\Desktop\beatnik\istack.h:28: error: conflicting types for 'stack_push'
    C:\Users\Vale\Desktop\beatnik\istack.c:75: note: previous definition of 'stack_push' was here
    C:\Users\Vale\Desktop\beatnik\istack.h:29: error: conflicting types for 'stack_peek'
    C:\Users\Vale\Desktop\beatnik\istack.c:88: note: previous definition of 'stack_peek' was here
    C:\Users\Vale\Desktop\beatnik\istack.h:31: error: conflicting types for 'stack_print'
    C:\Users\Vale\Desktop\beatnik\istack.c:115: note: previous definition of 'stack_print' was here
    Process terminated with status 1 (0 minutes, 0 seconds)
    10 errors, 0 warnings


  • Mod

    Hast du irgendwie die Möglichkeit, den gcc von der Kommandozeile aufzurufen? Das sollte irgendwie gehen, versuch rauszufinden wie. Dann machste:

    gcc beatnik.c istack.c -o beatnik.exe
    

    Und dann sollte das gut sein.



  • SeppJ schrieb:

    Hast du irgendwie die Möglichkeit, den gcc von der Kommandozeile aufzurufen? Das sollte irgendwie gehen, versuch rauszufinden wie. Dann machste:

    gcc beatnik.c istack.c -o beatnik.exe
    

    Und dann sollte das gut sein.

    weiß leider weder was ein "gcc" ist noch was die kommandozeile ist 😞

    was bewirkt dieser befehl? Er gibt doch auch keine sourcecode file an oder brauch ich die nicht?

    er startet ja mittlerweile eine .exe die mir aber anzeigt "no sourcecode file specified"
    lg



  • da du anscheinend windows hast, musst du nur auf start/programme/zubehör gehen und auf eingabeaufforderung gehen, dann in öffnet sich ein schwarzes fenster. dort gibts du dann den pfad zu deinen dateien in der form ein:

    cd C:\Pfad\zu\deiner\Datei
    

    für pfad\zu\deiner\datei gibst du natürlich deinen pfad an.
    dann gibst du

    gcc beatnik.c istack.c -o beatnik.exe
    

    ein und drückst enter.
    dann müsste es gehen



  • so das teil startet nun ohne rumzumaulen. allerdings ist meine quelldatei in deutsch und ich bräuchte jetz die deutschen scrabble regeln für diese Beatniksprache...

    naja er wirft mir jetzt halt nichts vernüftiges aus. Doof



  • lolhonk2 schrieb:

    die deutschen scrabble regeln

    Was meinst du damit??

    lolhonk2 schrieb:

    naja er wirft mir jetzt halt nichts vernüftiges

    Was wird dir denn ausgeworfen??

    EDIT:

    Sorry wegen der ersten frage
    sucht do sowas [http://de.wikipedia.org/wiki/Beatnik_(Programmiersprache](http://de.wikipedia.org/wiki/Beatnik_(Programmiersprache)



  • das sollte dir hallo welt ausgeben:

    bet you comments secret
     this file prints "Hello World!".
     It really does! (said me)
     Comments allowed
     See http://zaaf.nl/emacs/beatnik.html for the interpreter used.
     Edit here
          we have reasons,
     but whether mouse droppin' are holding up schools, feel if I want
     letters.
     Regardless of truth, agents are abandonin' units again.
     Print between lines are separate works.
        load sequentially, include users explicitly. Later and evil can me over! (antinormal)
     Does I says?
     Dust duchess schools foolings. My, my, is iceleaf over genius imposed. Can Neo have decided systems?
     But free flips become lines between continued stops. Start gets made standard.
     Help! Old world skool really stink (really!) Prerent third closest
     from weird deletion.
     Interestingly!
    


  • ja allerdings funktioniert, dass teil mit meinem deutschen Text nicht. Es gibt einfach überhaupt nichts aus? Die Scrabble Werte habe ich in der beatnik.c auf deutsch geändert!


Anmelden zum Antworten