Interpreteur brainfuck

Description

c'est ma troisieme source du genre.

un interpreteur brainfuck, j'ai tente de le rendre "aux normes GNU", il manque la doc, et les options longues, mais ca devrait etre bon.
pour le lancer :
./programme -c fichier_source

on peut rediriger les sorties et entrees. -o fichier_output -i fichier_input

il passe sans difficultes : valgrind, -Wall, --ansi, --pedantic.

Source / Exemple :


#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>

#define BOUCLE_ERROR 1
#define MALLOC_ERROR 2
#define READING_ERROR 3
#define OPT_ERROR 4

#define F_DEBUG  1
/* stack */
struct stack {
  struct stack *prev;
  int content;
};

struct stack * newStack(){
  struct stack *s = malloc(sizeof(struct stack));
  if (!s){
    fputs("malloc error\n", stderr);
    exit(MALLOC_ERROR);
  }
  return s;
}

void stack_push(struct stack **s, int content){
  struct stack *s2 = newStack();
  s2->prev = *s;
  s2->content = content;

  • s=s2;
} int stack_pop(struct stack **s){ struct stack *s2 = (*s); int c = s2->content;
  • s=s2->prev;
free(s2); return c; } /* liste doublement chainee */ struct mem { struct mem *prev, *next; unsigned char content; }; struct mem * newMem(){ struct mem *m = malloc(sizeof(struct mem)); if (!m){ fputs("malloc error\n", stderr); exit(MALLOC_ERROR); } m->prev = NULL; m->next = NULL; m->content = 0; return m; } void link_listes(struct mem * prev, struct mem *next){ prev->next = next; next->prev = prev; } struct mem * prev(struct mem *m){ struct mem *p; if (m->prev) return m->prev; p = newMem(); link_listes(p, m); return p; } struct mem * next(struct mem *m){ struct mem *n; if (m->next) return m->next; n = newMem(); link_listes(m, n); return n; } void freeMem(struct mem *m){ struct mem *m2, *m3; m3=m->next; while (m3){ m2 = m3->next; free(m3); m3 = m2; } m3=m->prev; while (m3){ m2 = m3->prev; free(m3); m3 = m2; } free(m); } int brainfuck(char * code, int len, int flags, FILE *out, FILE * in){ int i, j; struct mem *m = newMem(); struct stack *s = newStack(); int * jmps; jmps = malloc(len * sizeof(int)); if (!jmps){ freeMem(m); fputs("malloc error\n", stderr); exit(MALLOC_ERROR); } s->content = -1; for(i=0;i<len;i++){ if (code[i]=='['){ stack_push(&s, i); }else if(code[i]==']'){ j=stack_pop(&s); if ( j == -1 ) return BOUCLE_ERROR; jmps[i]=j-1; jmps[j]=i; } } if ( s->content != -1 ) return BOUCLE_ERROR; free(s); for(i=0;i<len;i++){ if (flags & F_DEBUG) fprintf(out, "\t %c %d\n", code[i], i); switch(code[i]){ case 0: goto fin; case '+': m->content++; break; case '-': m->content--; break; case '<': m = prev(m); break; case '>': m = next(m); break; case '.': fputc(m->content, out); break; case ',': m->content = fgetc(in); break; case '[': if (m->content) break; case ']': i=jmps[i]; break; } } fin: freeMem(m); free(jmps); return 0; } int main(int argc, char **argv){ int flags = 0; int c; FILE *out = stdout; FILE *in = stdin; FILE *code = NULL; size_t length; int err; char * content; while ( (c=getopt(argc, argv, "do:i:c:")) != -1 ){ switch (c){ case 'd': flags = flags | F_DEBUG; break; case 'o': out = fopen(optarg, "w"); if (out == NULL){ fprintf(stderr, "output error (%s)\n", optarg); return READING_ERROR; } break; case 'i': in = fopen(optarg, "r"); if (in == NULL){ fprintf(stderr, "input error (%s)\n", optarg); return READING_ERROR; } break; case 'c': code = fopen(optarg, "r"); break; case '?': if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); return OPT_ERROR; default: abort (); } } if (code == NULL){ fputs("code file error\n", stderr); exit(1); } fseek(code, 0, SEEK_END); length=ftell(code); content=malloc(length); if (!content){ fputs("malloc error\n", stderr); return MALLOC_ERROR; } fseek(code, 0, SEEK_SET); c = fread (content,1,length,code); fclose(code); if (c != length) { fputs("Reading error\n", stderr); return READING_ERROR; } if ( (err=brainfuck(content, length, flags, out, in)) ){ fprintf(stderr, "erreur (%d)\n", err); return err; } free(content); return 0; }

Conclusion :


source faite pour l'occasion :

http://www.siteduzero.com/forum-83-311802-2884187-atelier-tous-langages-codez-un-interpreteur-de-brainfuck.html

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.