Repository 32bit  Forum
Repository 64bit  Wiki

[JAVA] Compilatore BrainFuck

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare sempre la versione di Slackware usata e la versione del Kernel. Questi dati aiutano le persone che possono rispondere.
2) Specificare sempre il tipo di shell (bash, sh, csh, etc...)
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 dell'ultima regola 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 15: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 20: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 16: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: 337
Iscritto il: gio gen 27, 2005 1:00
Kernel: 2.6.3*
Desktop: Kde4
Distribuzione: Debian


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite