Repository 32bit  Forum
Repository 64bit  Wiki

[JAVA] Compilatore BrainFuck

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.

[JAVA] Compilatore BrainFuck

Messaggioda Porky » gio ago 27, 2009 14:25

Ecco la mia ultima creazione in java: un compilatore per BrainFuck, il linguaggio di programmazione esoterico.

Download: http://porkynator.altervista.org/pbfi-1.1.zip

Sorgenti:

Main.java

Codice: Seleziona tutto
/*
Copyright 2009 Sebastiano Tronto <sebastiano@luganega.org>

This file is part of PBFI (Porky's Brain F*** Interpreter).

    PBFI is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    PBFI is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with PBFI; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

*/

import javax.swing.JFrame;
import java.util.Scanner;
public class Main {
   public static Scanner scanner;
   public static char totalCode[], charCodeAux[], charCode[], chars;
   public static byte a[];
   public static int i;
   public static void main( String args[] ) {
      Frame frame = new Frame();
      frame.setSize( 200, 300 );
      frame.setVisible( true );
      frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
   }
   public static void run( String code ) {
      chars = 'a';
      int j = 0;
      totalCode = code.toCharArray();
      charCodeAux = new char[totalCode.length*2];
      for ( int k = 0; k < totalCode.length; k++ ) {
         switch ( totalCode[k] ) {
            case '>':
            case '<':
            case '+':
            case '-':
            case '.':
            case ',':
               charCodeAux[j] = totalCode[k];
               j++;
               break;
            case '[':
               charCodeAux[j] = totalCode[k];
               j++;
               charCodeAux[j] = chars;
               chars++;
               j++;
               break;
            case ']':
               chars--;
               charCodeAux[j] = chars;
               j++;
               charCodeAux[j] = totalCode[k];
               j++;
               break;
         }
      }
      charCode = new char[j];
      for ( int k = 0; k < charCode.length; k++ )
         charCode[k] = charCodeAux[k];
      scanner = new Scanner( System.in );
      a = new byte[30000];
      for ( int count = 0; count < a.length; count++ )
         a[count] = 0;
      i = 0;
      execute( scanner, charCode, a, i, 0, charCode.length );
   }
   public static void execute( Scanner scanner, char charCode[], byte a[], int i, int start, int stop ) {
      for ( int count = start; count < stop; count++ ) {
         switch ( charCode[count] ) {
            case '>':
               i++;
               break;
            case '<':
               i--;
               break;
            case '+':
               a[i]++;
               break;
            case '-':
               a[i]--;
               break;
            case '.':
               System.out.print( (char) a[i] );
               break;
            case ',':
               String stringa = scanner.nextLine();
               a[i] = (byte) ( ( stringa.toCharArray() )[0] );
               break;
            case '[':
               if ( a[i] == 0 ) {
                  count++;
                  char key = charCode[count];
                  count++;
                  for ( ; charCode[count] != key; count++ ) ;
                  count++;
               }
               break;
            case ']':
               if ( a[i] != 0 ) {
                  count --;
                  char key = charCode[count];
                  count --;
                  for ( ; charCode[count] != key; count-- ) ;
               }
               break;
         }
      }
   }
}

Frame.java

Codice: Seleziona tutto
/*
Copyright 2009 Sebastiano Tronto <sebastiano@luganega.org>

This file is part of PBFI (Porky's Brain F*** Interpreter).

    PBFI is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    PBFI is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with PBFI; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

*/

import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.event.*;
import java.io.*;

public class Frame extends JFrame {
public static int valoreChooser;
   public static boolean firstSave;
   public static String defaultSave;
   public static Main main;
   public static JTextArea textArea;
   public static JButton runButton;
   public static JMenuBar bar;
   public static JMenu menuFile, menuAiuto;
   public static JMenuItem esci, esegui, salva, salvaConNome, apri, info;
   public static JFileChooser chooser;
   public static FileInputStream in;
   public static FileOutputStream out;
      public Frame() {
      super( "Porky's BrainF** Interpreter - v1.1" );
      firstSave = true;
      main = new Main();
      defaultSave = "";
      chooser = new JFileChooser();
      textArea = new JTextArea( "Digitare qui il codice BrainF***", 15, 15 );
      bar = new JMenuBar();
      menuFile = new JMenu( "File" );
      menuAiuto = new JMenu( "?" );
      esci = new JMenuItem( "Esci" );
      esegui = new JMenuItem( "Esegui" );
      salva = new JMenuItem( "Salva" );
      salvaConNome = new JMenuItem( "Salva con nome" );
      apri = new JMenuItem( "Apri" );
      info = new JMenuItem( "Aiuto" );
      menuFile.setMnemonic( 'F' );
      menuAiuto.setMnemonic( '?' );
      esci.setMnemonic( 'E' );
      esegui.setMnemonic( 's' );
      salva.setMnemonic( 'a' );
      salvaConNome.setMnemonic( 'n' );
      apri.setMnemonic( 'p' );
      info.setMnemonic( 'i' );
      esci.addActionListener(
         new ActionListener() {
            public void actionPerformed ( ActionEvent e ) {
               System.exit( 0 );
            }
         }
      );
      esegui.addActionListener(
         new ActionListener() {
            public void actionPerformed ( ActionEvent e ) {
               main.run( textArea.getText() );
            }
         }
      );
      salva.addActionListener(
         new ActionListener() {
            public void actionPerformed ( ActionEvent e ) {
               if ( firstSave ) {
                  valoreChooser = chooser.showSaveDialog( Frame.this );
                  switch ( valoreChooser ) {
                     case JFileChooser.APPROVE_OPTION:
                        try {
                           out = new FileOutputStream( chooser.getSelectedFile().getPath() );
                           defaultSave = chooser.getSelectedFile().getPath();
                           char caratteri[];
                           byte bytes[];
                           caratteri = textArea.getText().toCharArray();
                           bytes = new byte[caratteri.length];
                           for ( int i = 0; i <  caratteri.length; i++ )
                              bytes[i] = ( byte ) caratteri[i];
                           out.write( bytes );
                        } catch ( Exception ex ) {
                           JOptionPane.showMessageDialog( Frame.this, "Errore sconosciuto:\n\n" + ex + "\n\nPer favore riportare il bug a sebastiano@luganega.org", "Errore", JOptionPane.ERROR_MESSAGE );
                        }
                        break;
                     case JFileChooser.ERROR_OPTION:
                        JOptionPane.showMessageDialog( Frame.this, "Errore sconosciuto:\n\n" + e + "\n\nPer favore riportare il bug a sebastiano@luganega.org", "Errore", JOptionPane.ERROR_MESSAGE );
                        break;
                     //case JFileChooser.CANCEL_OPTION:
                  }
                  firstSave = false;
               } else {
                  try {
                     out = new FileOutputStream( defaultSave );
                     char caratteri[];
                     byte bytes[];
                     caratteri = textArea.getText().toCharArray();
                     bytes = new byte[caratteri.length];
                     for ( int i = 0; i <  caratteri.length; i++ )
                        bytes[i] = ( byte ) caratteri[i];
                     out.write( bytes );
                  } catch ( Exception ex ) {
                     JOptionPane.showMessageDialog( Frame.this, "Errore sconosciuto:\n\n" + ex + "\n\nPer favore riportare il bug a sebastiano@luganega.org", "Errore", JOptionPane.ERROR_MESSAGE );
                  }
               }
            }
         }
      );
      salvaConNome.addActionListener(
         new ActionListener() {
            public void actionPerformed ( ActionEvent e ) {
               valoreChooser = chooser.showSaveDialog( Frame.this );
               switch ( valoreChooser ) {
                  case JFileChooser.APPROVE_OPTION:
                     try {
                        out = new FileOutputStream( chooser.getSelectedFile().getPath() );
                        defaultSave = chooser.getSelectedFile().getPath();
                        char caratteri[];
                        byte bytes[];
                        caratteri = textArea.getText().toCharArray();
                        bytes = new byte[caratteri.length];
                        for ( int i = 0; i <  caratteri.length; i++ )
                           bytes[i] = ( byte ) caratteri[i];
                        out.write( bytes );
                     } catch ( Exception ex ) {
                        JOptionPane.showMessageDialog( Frame.this, "Errore sconosciuto:\n\n" + ex + "\n\nPer favore riportare il bug a sebastiano@luganega.org", "Errore", JOptionPane.ERROR_MESSAGE );
                     }
                     break;
                  case JFileChooser.ERROR_OPTION:
                     JOptionPane.showMessageDialog( Frame.this, "Errore sconosciuto:\n\n" + e + "\n\nPer favore riportare il bug a sebastiano@luganega.org", "Errore", JOptionPane.ERROR_MESSAGE );
                     break;
                  //case JFileChooser.CANCEL_OPTION:
               }
               firstSave = false;
            }
         }
      );
      apri.addActionListener(
         new ActionListener() {
            public void actionPerformed ( ActionEvent e ) {
               valoreChooser = chooser.showOpenDialog( Frame.this );
               switch ( valoreChooser ) {
                  case JFileChooser.APPROVE_OPTION:
                     try {
                        String stringa;
                        byte bytes[];
                        char caratteri[];
                        in = new FileInputStream( chooser.getSelectedFile().getPath() );
                        bytes = new byte[in.available()];
                        caratteri = new char[in.available()];
                        in.read( bytes );
                        for ( int i = 0; i < bytes.length; i++ )
                           caratteri[i] = ( char ) bytes[i];
                        stringa = new String( caratteri );
                        textArea.setText( stringa );
                     } catch ( Exception ex ) {
                        JOptionPane.showMessageDialog( Frame.this, "Errore sconosciuto:\n\n" + ex + "\n\nPer favore riportare il bug a sebastiano@luganega.org", "Errore", JOptionPane.ERROR_MESSAGE );
                     }
                     break;
                  case JFileChooser.ERROR_OPTION:
                     JOptionPane.showMessageDialog( Frame.this, "Errore sconosciuto:\n\n" + e + "\n\nPer favore riportare il bug a sebastiano@luganega.org", "Errore", JOptionPane.ERROR_MESSAGE );
                     break;
                  //case JFileChooser.CANCEL_OPTION:
               }
            }
         }
      );
      info.addActionListener(
         new ActionListener() {
            public void actionPerformed ( ActionEvent e ) {
               JOptionPane.showMessageDialog( Frame.this, "Brainfuck è un linguaggio di programmazione esoterico per computer,\ncreato da Urban Müller intorno al 1993. Il linguaggio viene\nin taluni casi denominato Brainf*ck, Brainf***\no anche soltanto BF per evitare di offendere\nla sensibilità altrui.\nNella directory src trovate alcuni esempi di programmi in questo linguaggio.\n\nPer maggiori informazioni visitate la pagina:\nhttp://it.wikipedia.org/wiki/Brainfuck", "BrainF*** - Informazioni", JOptionPane.INFORMATION_MESSAGE );
            }
         }
      );
      menuFile.add( esegui );
      menuFile.add( salva );
      menuFile.add( salvaConNome );
      menuFile.add( apri );
      menuFile.add( esci );
      menuAiuto.add( info );
      bar.add( menuFile );
      bar.add( menuAiuto );
      runButton = new JButton( "Esegui" );
      runButton.addActionListener(
         new ActionListener() {
            public void actionPerformed( ActionEvent e ) {
               main.run( textArea.getText() );
            }
         }
      );
      setLayout( new BorderLayout() );
      setJMenuBar( bar );
      add( new JScrollPane( textArea ), BorderLayout.CENTER );
      add( runButton, BorderLayout.SOUTH );
   }
}

Permette anche di salvare/aprire un progetto.

Riguardo alla gestione delle parentesi: non riuscivo a uscirne (scusate il gioco di parole), quindi ho usato questo " trucchetto": innanzitutto creo un array di char che contiene tutti i caratteri .,+-><[] che trova nella casella di testo e aggiunge un carattere (da 'a' in avanti) dopo ogni parentesi aperta e prima di ogni chiusa, in modo da segnare le corrispondenti. quindi se inserite il codice:

Codice: Seleziona tutto
codice casuale che non ho la minima idea di cosa faccia:
,+++++++[ dg< +++++++. [ -- <] [ ++ > [ +. <] --> ]>>]

il mio compilatore se lo traduce in :

Codice: Seleziona tutto
,+++++++[a<+++++++.[b --<b][b++>[c+.<c]-->b]>>a]

per riuscire a trovare le parentesi corrispondenti.
Ad esempio quando arriva a una parentesi aperta, se il byte al puntatore è 0, guarda il byte successivo e lo memorizza come "chiave", poi va avanti fino all'istruzione dopo la parentesi quadra chiusa che segue il successivo simbolo chiave.

Si lo so è un casino, mi sono scervellato 2 giorni (o erano 3? ho anche perso il conto...) per arrivarci.
Avatar utente
Porky
Linux 2.0
Linux 2.0
 
Messaggi: 104
Iscritto il: mer lug 23, 2008 19:52
Località: Belluno
Nome Cognome: Sebastiano Tronto
Slackware: 13.37
Kernel: 2.6.37.6-prk
Desktop: KDE
Distribuzione: Archlinux

Re: [JAVA] Compilatore BrainFuck

Messaggioda wakkokid » gio ago 27, 2009 15:49

Per chi vuole divertirsi 10 minuti con questo linguaggio, segnalo il blog di un amico che ne ha implementato un debugger in Javascript
http://www.lordalcol.com/blog/2008/03/0 ... -debugger/
Avatar utente
wakkokid
Linux 2.4
Linux 2.4
 
Messaggi: 339
Iscritto il: gio gen 27, 2005 0:00
Kernel: 2.6.3*
Desktop: Kde4
Distribuzione: Debian


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 2 ospiti

cron