• Lucid Dreaming - Dream Views




    Results 1 to 3 of 3

    Threaded View

    1. #1
      Banned
      Join Date
      May 2007
      LD Count
      Loads
      Gender
      Location
      Digital Forest.
      Posts
      6,864
      Likes
      386

      My brainfuck (Java)

      So this term I am taking a Java course, and as a simple exercise I implemented my own version of >>>Brainfuck<<<

      It can take a brainfuck string as a commandline parameter and interpret and execute it immediately, and it can take file input as well. Additionally it can compile brainfuck into a binary file to be executed without having to be precompiled.

      An array of 30,000 short integers [chars] to play around with, currently.

      Here're the language specs:

      Code:
      Commands --
      + -- Increment the current memory cell
      -  -- Decrement the current memory cell
      < -- Decrement the memory position
      > -- Increment the memory position
      [ -- If the current memory cell is 0, skip to the next matching ']'
      ] -- If the current memory cell is non zero, skip to the previous matching '['
      . -- Print the value of the current memory cell as an integer to standard output
      , -- Print the value of the current memory cell as a single character to standard output
      ^ -- Accept one 16 bit integer from standard input and assign the current memory cell that value
      $ -- Accept one character from standard input and assign the current memory cell that value
      c -- For simplicity's sake, this takes the following character from a source file and places its value into the current memory cell
      w -- This takes the characters proceeding it as a single 16 bit integer and places it into the current memory cell
      
      Comments --
      
      / -- Start and end a comment block
      
      Macros -- I implemented a simple #macro system as well
      #place <location/of/filename> 
      #define <MyMacro> (param1,param2) wparam1 > wparam2 [-<+>] / Adds param2 to param1 /
      
      #MyMacro (23,12)
      Here's an example program --

      PHP Code:
      #define <PrintInt> (x) wx.
      #define <Putstring> (r,s,t,u,v,w,x,y,z) cr,cs,ct,cu,cv,cw,cx,cy,cz,
      #define <AddTwo> (f,s) wf >ws [-<+>]< / This adds two numbers together by using the second parameter as a loop counter /
      #AddTwo (23,57)
      .w10,
      #Putstring (D,e,r,p,!, , , , ) / This prints 'Derp!' lolo /
      w10,

      [-] / 
      Zero out out mems for s's 'n g's /


      #Putstring (P,i,c,k, ,a, ,n,u)
      #Putstring (m,b,e,r,:, ,\b,\b, )
      ^
      / Get a number from stdin /
      >
      #Putstring (P,i,c,k, ,a, ,n,u)
      #Putstring (m,b,e,r,:, ,\b,\b, )
      ^
      / Get another # from stdin /
      >
      #Putstring (T,h,e, ,s,u,m, ,=)
      c ,
      <
      / Tell the user what'
      s coming up /
      [- < + >]<.
      Get the sum /
      #AddTwo (78,12)
      This is just proof of concept /

      This shit down here returns 1 or the inverse boolean value of the current mem celli.e. !(boolean)memory[memcell] /
      [
        [
          -
        ]
        @
      ]
      +

      Call the program with --

      Code:
      java -jar brainfuck.jar "brainfuck code to interpret"
      java -jar brainfuck.jar -f "name of file to interpret"
      java -jar brainfuck.jar -c "name of file to compile" "name of binary file to output"
      java -jar brainfuck.jar -e "name of binary file to execute"
      java -jar brainfuck.jar -h (Shows help stuff)
      and finally, the source code -

      Code:
      import java.io.*;
      import java.util.ArrayList;
      import java.util.Hashtable;
      import java.util.regex.Matcher;
      
      class BrainFKParser{
          private Hashtable<String, Integer> symbol_map;
          private Hashtable<String, ArrayList<String>> def_macros;
          private Hashtable<String, String> exp_macros;
          
          BrainFKParser(){
              symbol_map = new Hashtable<String, Integer>();
              def_macros = new Hashtable<String, ArrayList<String>>();
              exp_macros = new Hashtable<String, String>();
          }
          
          public boolean AddSymbol(String name, int opcode){
               if(!symbol_map.containsKey(name)){
                   symbol_map.put(name, opcode);
                   return true;
               }
               return false;
           }
           
           public ArrayList<Integer> ParseString(String fn){
               if(!MatchBraces(fn)){
                  return null;
               }
               ArrayList<Integer> program = new ArrayList();
               
               String temp = "";
               for(int i=0;i<fn.length();++i){
                   temp += fn.charAt(i);
                   
                   if("c".equals(temp) && (i+1<fn.length())){
                       if(fn.charAt(i+1) != '\\'){
                          //System.out.println("Found character: " + fn.charAt(i) + " " + fn.charAt(i+1));
                          program.add(symbol_map.get(temp) | fn.charAt(i+1));
                       }else if(i+2<fn.length()){
                           //System.out.println("Found control character: " + fn.charAt(i+1) + " " + fn.charAt(i+2));
                           switch(fn.charAt(i+2)){
                               case 'n':
                                   program.add(symbol_map.get(temp) | '\n');
                                   break;
                               case 'b':
                                   program.add(symbol_map.get(temp) | '\b');
                                   break;
                               case 'r':
                                   program.add(symbol_map.get(temp) | '\r');
                                   break;
                               case '\\':
                                   program.add(symbol_map.get(temp) | '\\');
                                   break;
                               case '0':
                                   program.add(symbol_map.get(temp) | '\0');
                                   break;
                           }
                           ++i;
                       }
                       ++i;
                   }
                   else if("w".equals(temp)){
                       String number = "", temp2 = "";
                       for(++i;i<fn.length();++i){
                           temp2 += fn.charAt(i);
                           if(!symbol_map.containsKey(temp2) && Character.isDigit(fn.charAt(i))){
                               number += temp2;
                           }
                           else if(symbol_map.containsKey(temp2)){
                               --i;
                               break;
                           }
                           temp2 = "";
                       }
                       if(number.length() > 0){
                          program.add(symbol_map.get(temp) | Short.valueOf(number));   
                       }
                   }
                   else if(symbol_map.containsKey(temp)){
                      program.add(symbol_map.get(temp));
                   }
                   temp = "";
               }
               
               return program;
          }
           
          public String PreParse(String fn) throws FileNotFoundException, IOException{
              String brainFKCode = "", temp = "";
              
               for(int i=0;i<fn.length();++i){
                   boolean ischar = false;
                   temp += fn.charAt(i);
                   
                   if(i > 0){
                       if(fn.charAt(i-1) == 'c'){
                           ischar = true;
                       }
                   }
                   
                   if("#".equals(temp) && !ischar){
                       String macroname = "", filename = "", params = "", expression = "", temp2 = "";
                       
                       for(++i;i<fn.length();++i){
                           
                           temp2 += fn.charAt(i);
                           
                           if(!Character.isWhitespace(fn.charAt(i)) && !(filename.length() > 0) && !(params.length() > 0) && !(expression.length() > 0) && !"\n".equals(temp2) && !"\r".equals(temp2) && !"<".equals(temp2) && !"(".equals(temp2)){
                               macroname += temp2;
                           }
                           else if("<".equals(temp2) && !(expression.length() > 0)){
                               for(;i<fn.length();++i){
                                   if(fn.charAt(i) != '>' && fn.charAt(i) != '<'){
                                       filename += fn.charAt(i);
                                   }
                                   else if(fn.charAt(i) == '>'){
                                       break;
                                   }
                               }
                           }
                           else if("(".equals(temp2)){
                               for(++i;i<fn.length();++i){
                                   if(fn.charAt(i) != ')' && fn.charAt(i) != '('){
                                       params += fn.charAt(i);
                                   }
                                   else{
                                       break;
                                   }
                               }
                           }
                           else if(!Character.isWhitespace(fn.charAt(i)) && filename.length() > 0 && params.length() > 0 && !"\n".equals(temp2) && !"\r".equals(temp2)){
                               expression += temp2;
                           }
                           else if("\n".equals(temp2) || "\r".equals(temp2)){
                               --i;
                               break;
                           }
                           
                           temp2 = "";
                       }
                       if(macroname.length() > 0 ){
                          brainFKCode += FillMacro(macroname, filename, params, expression);
                       }
                   }
                   else if("/".equals(temp) && !ischar && i < fn.length()){
                       for(++i;i < fn.length();++i){
                           temp += fn.charAt(i);
                           if (fn.charAt(i) == '/'){
                               break;
                           }
                       }
                       //System.out.println("Found a comment: " + temp);
                       temp = "";
                   }
                   else{
                       brainFKCode += temp;
                   }
                   
                   temp = "";
               }
               
               return brainFKCode;        
          }
           
          public boolean MatchBraces(String fn){
              
              int braces = 0;
              for(int i=0;i<fn.length();++i){
                  switch(fn.charAt(i)){
                      case '[': //Beginning of brace/brace nest
                      {
                          braces = 1;
                          for(++i;braces != 0 && i<fn.length();++i){
                              switch(fn.charAt(i)){
                                  case '[':
                                  {
                                      ++braces;
                                  }break;
                                  case ']':
                                  {
                                      --braces;
                                  }break;
                              }
                          }
                      }break;
                      case ']': //Out of place brace
                      {
                          System.out.println("Fatal error:\n\t\tMismatched braces");
                          return false;
                      }
                  }
              }
              
              return braces == 0 ? true : false;
          }
          
          private String FillMacro(String macroname, String filename, String params, String expression) throws FileNotFoundException, IOException{
              
              String expansion = "";
              //macroname  = macroname.toLowerCase();
              
              //System.out.println(params);
              
              if("place".equals(macroname) && filename.length() > 0){
                  BufferedReader inputStream = new BufferedReader(new FileReader(filename));
                  while(inputStream.ready()){
                      expansion += String.valueOf((char)inputStream.read());
                  }
              }
              else if("sysplace".equals(macroname) && filename.length() > 0){
                  filename = "/usr/include/brainfk/" + filename;
                  BufferedReader inputStream = new BufferedReader(new FileReader(filename));
                  while(inputStream.ready()){
                      expansion += String.valueOf((char)inputStream.read());
                  }
              }
              else if("define".equals(macroname) && filename.length() > 0 && params.length() > 0 && expression.length() > 0){
                  //System.out.println("Defining a macro... " + macroname + " " + filename + " " + params + " " + expression);
                  String temp = "";
                  ArrayList<String> parameters = new ArrayList<String>();
                  for(int i=0;i<params.length();++i){
                      if(params.charAt(i) != ','){
                          temp += params.charAt(i);
                          //System.out.println(temp);
                      }
                      else{
                          parameters.add(temp);
                          temp ="";
                      }
                  }
                  if(temp.length() > 0){
                      parameters.add(temp);
                  }
                  def_macros.put(filename, parameters);
                  exp_macros.put(filename, PreParse(expression));
                  //System.out.println("Macro defined");
              }
              else if(def_macros.containsKey(macroname) && exp_macros.containsKey(macroname)){
                  //System.out.println("Found def'd macro");
                  String temp = "";
                  ArrayList<String> parameters = new ArrayList<String>();
                  for(int i=0;i<params.length();++i){
                      if(params.charAt(i) != ','){
                          temp += params.charAt(i);
                      }
                      else if(params.charAt(i) == ',' || (i+1) == params.length()){
                          parameters.add(temp);
                          temp ="";
                      }
                  }
                  if(temp.length() > 0){
                      parameters.add(temp);
                      temp = "";
                  }
                  //System.out.println(parameters.size() + " " + def_macros.get(macroname).size());
                  temp = exp_macros.get(macroname);
                  //System.out.println(temp);
                  if(parameters. size() == def_macros.get(macroname).size()){
                      for(int i=0;i<parameters.size();++i){
                          //System.out.println(def_macros.get(macroname).get(i) + " " + parameters.get(i));
                          temp = temp.replace(def_macros.get(macroname).get(i), parameters.get(i));
                          //System.out.println(temp);
                      }
                  }
                  
                  expansion += temp;
                  //System.out.println(expansion);
              }
              
              return PreParse(expansion);
              
          }
           
      }
      
      class BrainFKEngine{
          private ArrayList<Integer> code;
          private char[] memory;
          private int step, mem_ptr, memory_size;
          private boolean exit = false;
          
          BrainFKEngine(ArrayList<Integer> program, int memsize){
              code = program;
              memory_size = memsize;
              mem_ptr = 0;
              step = 0;
              memory = new char[memory_size];
      
              for(int i = 0;i<memory_size;++i){
                  memory[i] = 0;
              }
          }
          
          public Integer Execute() throws IOException{
              while(!exit && step<code.size()){
                  switch(code.get(step) >> 16){
                      case 0x01: // '+'
                          ++memory[mem_ptr];
                          break;
      
                      case 0x02: // '-'
                          --memory[mem_ptr];
                          break;
      
                      case 0x03: // '>'
                      {
                         if(mem_ptr < memory_size-1){
                             ++mem_ptr;
                         }
                         else{
                             mem_ptr = 0;
                         }
                      }
                          break;
      
                      case 0x04: // '<'
                      {
                         if(mem_ptr > 0){
                             --mem_ptr;
                         }
                         else{
                             mem_ptr = memory_size-1;
                         }
                      }
                          break;
      
                      case 0x05: // '['
                      {
                          if(memory[mem_ptr] == 0){
                              int brackets = 1;
                              while(step < code.size() && brackets != 0){
                                  ++step;
                                  if(code.get(step) >> 16 == 0x05){
                                      ++brackets;
                                  }
                                  if(code.get(step) >> 16 == 0x06){
                                      --brackets;
                                  }
                              }
                          }
                      }
                          break;
      
                      case 0x06: // ']'
                      {
                          if(memory[mem_ptr] != 0){
                              int brackets = 1;
                              while(brackets != 0 && step > 0){
                                  --step;
                                  if(code.get(step) >> 16 == 0x05){
                                      --brackets;
                                  }
                                  if(code.get(step) >> 16 == 0x06){
                                      ++brackets;
                                  }
                              }
                          }
                      }
                          break;
      
                      case 0x07: // '.'
                          System.out.print((int)memory[mem_ptr]);
                          break;
      
                      case 0x08: // ','
                          System.out.print(String.valueOf(memory[mem_ptr]));
                          break;
                      case 0x09: // '$'
                          memory[mem_ptr] = (char)System.in.read();
                          break;
                      case 0x0A: // '^'
                      {
                          BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
                          String number = in.readLine();
                          memory[mem_ptr] = (char)Integer.valueOf(number).intValue();
                      }
                          break;
                      case 0x0B: // '@'
                          exit = true;
                          break;
                      case 0x0C: // 'c' + char
                          memory[mem_ptr] = (char)(code.get(step) ^ 0x0C0000);
                          break;
                      case 0x0D: // 'w' + short integer
                          memory[mem_ptr] = (char)(code.get(step) ^ 0x0D0000);
                          break;
                  }
                  ++step;
              }
              return (int)memory[mem_ptr];
          }
          
      }
      
      public class BrainFKInterpreter {
      
          public static void main(String[] args) throws IOException {
             
             BrainFKParser Compiler = new BrainFKParser();
             
             
             Compiler.AddSymbol("+",  0x010000); //Incrument Current Memory Cell
             Compiler.AddSymbol("-",  0x020000); //Decrument Current Memory Cell
             Compiler.AddSymbol(">",  0x030000); //Incrument Memory Pointer
             Compiler.AddSymbol("<",  0x040000); //Decrument Memory Pointer
             Compiler.AddSymbol("[",  0x050000); //Jump to next matching ] if zero
             Compiler.AddSymbol("]",  0x060000); //Jump to previous matching [ if not zero
             Compiler.AddSymbol(".",  0x070000); //Print current memory cell as an integer
             Compiler.AddSymbol(",",  0x080000); //Print current memory cell as a character
             Compiler.AddSymbol("$",  0x090000); //Read one character from standard input
             Compiler.AddSymbol("^",  0x0A0000); //Read integer from standard input
             Compiler.AddSymbol("@",  0x0B0000); //Halt Program Execution
             Compiler.AddSymbol("c",  0x0C0000); //Take next tape token as character and set the current memory cell to that value
             Compiler.AddSymbol("w",  0x0D0000); //Take next tape tokens as decimal digits until another command is found and set current memory cell to the short integer value
             
             BrainFKEngine Executioner;
             if(args.length>2){ // 3 commandline args or more
                  if("-c".equals(args[0].toLowerCase()) && args[1].length() > 0 && args[2].length() > 0){
                      BufferedReader inputStream = new BufferedReader(new FileReader(args[1]));
                      String brainfksource = "";
                      while(inputStream.ready()){
                          brainfksource += String.valueOf((char)inputStream.read());
                      }
                      ArrayList<Integer> brainfkopcodes = Compiler.ParseString(Compiler.PreParse(brainfksource));
                      
                      if(brainfkopcodes == null){
                          return;
                      }
                      
                      BufferedWriter outputStream = new BufferedWriter(new FileWriter(args[2]));
                      for(int i=0;i<brainfkopcodes.size();++i){
                          char[] buffer = new char[2];
                          buffer[0] = (char)(brainfkopcodes.get(i) >> 16);
                          buffer[1] = (char)((brainfkopcodes.get(i) << 16) >> 16);
                          outputStream.write(buffer);
                          //System.out.println(buffer);
                      }
                      outputStream.close();
                      System.out.println("Compiled file \'" + args[1] + "\' into binary file \'" + args[2] + "\' - execute with command brainfk -e " + args[2]);
                  }
                  
             }
             else if(args.length>1){ // 2 commandline args or more
                 if("-f".equals(args[0].toLowerCase()) && args[1].length() > 0){
                      BufferedReader inputStream = new BufferedReader(new FileReader(args[1]));
                      String brainfksource = "";
                      while(inputStream.ready()){
                          brainfksource += String.valueOf((char)inputStream.read());
                      }
                      inputStream.close();
                      Executioner = new BrainFKEngine(Compiler.ParseString(Compiler.PreParse(brainfksource)), 30000);
                      
                      if(Executioner == null){
                          return;
                      }
                      
                      System.out.println("\nReturned Status: " + Executioner.Execute());
                  }else if("-e".equals(args[0].toLowerCase()) && args[1].length() > 0){
                      BufferedReader inputStream = new BufferedReader(new FileReader(args[1]));
                      ArrayList<Integer> bfkbinary = new ArrayList<Integer>();
                      
                      while(inputStream.ready()){
                          char[] buffer = new char[2];
                          inputStream.read(buffer);
                          int opcode = buffer[0]; 
                          opcode <<= 16;
                          opcode += buffer[1];
                          bfkbinary.add(opcode);
                          //System.out.println(opcode);
                      }
                      inputStream.close();
                      Executioner = new BrainFKEngine(bfkbinary, 30000);
                      System.out.println("\nReturned Status: " + Executioner.Execute());
                  }
                  
             }
             else if(args.length>0 && !"-h".equals(args[0])){ // Just one commandline arg
                 Executioner = new BrainFKEngine(Compiler.ParseString(Compiler.PreParse(args[0])), 30000);
                 
                 if(Executioner == null){
                      return;
                  }
                 
                 System.out.println("\nReturned Status: " + Executioner.Execute());
             }else{ // No commandline arguments
                 System.out.println("brainfk - \n\tUseage: brainfk \"brainfk source code to interpret\"\t\t\tParse and execute enquoted code\n\t\t[-f][brainfk source filename]\t\t\t\t\tParse and execute brainfk source file\n\t\t[-c][brainfk source filename]"
                         + "[compiled output filename]\t\tCompile input filename and output to output filename as brainfk binary\n\t\t[-e][compiled brainfk filename]\t\t\t\t\tExecute brainfk binary code\n\t\t[-h/--help]\t\t\t\t\t\t\tShow this help message");
             }
          }
      }
      Last edited by Sornaensis; 02-03-2012 at 04:58 PM.

    Similar Threads

    1. quick java question
      By Abra in forum Tech Talk
      Replies: 7
      Last Post: 05-20-2009, 03:10 AM
    2. Help me with java problem. (quickly!)
      By pyroguy305 in forum Ask/Tell Me About
      Replies: 0
      Last Post: 03-23-2009, 05:59 AM
    3. PHP / Java scripting help.
      By Adam in forum Tech Talk
      Replies: 11
      Last Post: 05-16-2008, 08:42 AM
    4. Hmm, anyone know why Java never loads?
      By Jdeadevil in forum Tech Talk
      Replies: 7
      Last Post: 07-29-2007, 03:16 PM
    5. Starting On Java
      By Lonestar in forum Tech Talk
      Replies: 6
      Last Post: 01-02-2007, 02:18 PM

    Bookmarks

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •