Interpreteur brainfuck

Soyez le premier à donner votre avis sur cette source.

Vue 5 817 fois - Téléchargée 259 fois

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

Ajouter un commentaire

Commentaires

Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
36
euh... j'ai tente cette nuit l'interpreteur whitespace, mais euh... c'est _beaucoup_ plus complique...
Messages postés
173
Date d'inscription
jeudi 20 décembre 2001
Statut
Membre
Dernière intervention
22 août 2008

Wow c'est excellent :)

La prochaine étape dans la geekitude, c'est l'interpréteur de whitespace ?
http://compsoc.dur.ac.uk/whitespace/index.php

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.