• Lucid Dreaming - Dream Views




    Results 1 to 3 of 3
    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.

    2. #2
      ├┼┼┼┼┤
      Join Date
      Jun 2006
      Gender
      Location
      Equestria
      Posts
      6,315
      Likes
      1191
      DJ Entries
      1
      What a waste of time. Write a java compiler next time.

      ---------
      Lost count of how many lucid dreams I've had
      ---------

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

    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
    •