Execute SNUSP/Java: Difference between revisions

From Rosetta Code
Content added Content deleted
m (grammar)
(Changed direction to an enum...do we have an enum task?)
Line 47: Line 47:
return code;
return code;
}
}

}</java>
}</java>
The code pointer class:<java>import java.awt.Point;
The code pointer class:<java>import java.awt.Point;
Line 57: Line 56:


public class CodePtr{
public class CodePtr{
final int LEFT= 2, RIGHT= 0, UP= 3, DOWN= 1;//directions
final String instChars= "><.,/\\+-#@$%!?";//valid chars
final String instChars= "><.,/\\+%-#@$!?";//valid chars
ArrayList<String> code;//code array
ArrayList<String> code;//code array
int dir;//current direction
Direction dir;//current direction
ArrayList<Character> mem;//memory space
ArrayList<Character> mem;//memory space
int memPtr;//memory pointer
int memPtr;//memory pointer
Point place;//code pointer
Point place;//code pointer
LinkedList<Point> pStack;//code pointer stack
LinkedList<Point> pStack;//code pointer stack
LinkedList<Integer> dStack;//direction stack
LinkedList<Direction> dStack;//direction stack
//input stream
//input stream
BufferedReader input= new BufferedReader(new InputStreamReader(System.in));
BufferedReader input= new BufferedReader(new InputStreamReader(System.in));
Line 71: Line 69:
public CodePtr(final ArrayList<String> code, final Point place){
public CodePtr(final ArrayList<String> code, final Point place){
this.code= code;
this.code= code;
dir= RIGHT;
dir= Direction.RIGHT;
this.place= place;
this.place= place;
mem = new ArrayList<Character>();
mem = new ArrayList<Character>();
mem.add('\0');//initial memory
mem.add('\0');//initial memory
memPtr= 0;
memPtr= 0;
dStack= new LinkedList<Integer>();
dStack= new LinkedList<Direction>();
pStack= new LinkedList<Point>();
pStack= new LinkedList<Point>();
}
}


public CodePtr(final Point place, final int dir){
public CodePtr(final Point place, final Direction dir){
//This constructor is left over from attempts at '&'
this.dir= dir;
this.dir= dir;
this.place= place;
this.place= place;
Line 130: Line 129:
switch(dir){
switch(dir){
case RIGHT:
case RIGHT:
dir= UP;
dir= Direction.UP;
break;
break;
case DOWN:
case DOWN:
dir= LEFT;
dir= Direction.LEFT;
break;
break;
case LEFT:
case LEFT:
dir= DOWN;
dir= Direction.DOWN;
break;
break;
case UP:
case UP:
dir= RIGHT;
dir= Direction.RIGHT;
break;
break;
default:
default:
Line 147: Line 146:
switch(dir){
switch(dir){
case RIGHT:
case RIGHT:
dir= DOWN;
dir= Direction.DOWN;
break;
break;
case DOWN:
case DOWN:
dir= RIGHT;
dir= Direction.RIGHT;
break;
break;
case LEFT:
case LEFT:
dir= UP;
dir= Direction.UP;
break;
break;
case UP:
case UP:
dir= LEFT;
dir= Direction.LEFT;
break;
break;
default:
default:
Line 169: Line 168:
case '#'://pop
case '#'://pop
if(dStack.size() > 0){
if(dStack.size() > 0){
final int oldDir= dStack.pop();
final Direction oldDir= dStack.pop();
final Point oldPlace= pStack.pop();
final Point oldPlace= pStack.pop();
place= oldPlace;
place= oldPlace;
Line 183: Line 182:
break;
break;
case '%':
case '%':
//use a random regular ASCII character
mem.set(memPtr, (char)(Math.random() * 256));
mem.set(memPtr, (char)(Math.random() * 256));
break;
default:
default:
}
}
Line 208: Line 207:
}
}
if(retVal.x<0 || retVal.y<0 ||
if(retVal.x<0 || retVal.y<0 ||
retVal.y >= code.size() ||
retVal.y >= code.size() || retVal.x >= code.get(0).length()){
retVal.x >= code.get(0).length()){
System.err.println("Code pointer has left the code space");
System.err.println("Code pointer has left the code space");
System.exit(-1);
System.exit(-1);
Line 215: Line 213:
return retVal;
return retVal;
}
}
enum Direction{
}</java>
UP,DOWN,LEFT,RIGHT;
}
}
</java>

Revision as of 16:49, 5 May 2008

Execute SNUSP/Java is an implementation of SNUSP. Other implementations of SNUSP.
Execute SNUSP/Java is part of RCSNUSP. You may find other members of RCSNUSP at Category:RCSNUSP.

This implementation has all of the basic characters plus '%', '@', and '#' (characters from modular and bloated SNUSP found on esolangs). The memory space grows to the right as needed, and the memory pointer cannot go negative. The program will exit if the memory pointer moves to a negative value or if the code pointer leaves the code space. The input ignores return characters because of the way BufferedReader is set up. The random command places a random ASCII character (code 0 through 255 inclusive) in the current memory space.

The implementation comes in two classes: the main program and a code pointer class. The separation is for the easier addition of '&' (split) which could come in the future (the code pointer class would only need to extend Thread and code would need to be added to deal with the command). The main class decides on the input method (file or std in), reads the code, and starts the code pointer. It also figures out where the starting point in the code is ('$' or 0,0).

Works with: Java version 1.5+

The main class:<java>import java.awt.Point; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList;

public class SNUSP{ static Point start; public static void main(String[] args){ try{ start= new Point(0,0); BufferedReader in; ArrayList<String> code = new ArrayList<String>(); if(args.length > 0){ in= new BufferedReader(new FileReader(args[0])); }else{ in= new BufferedReader(new InputStreamReader(System.in)); } code= parse(in); CodePtr cp = new CodePtr(code, start); cp.run(); }catch(FileNotFoundException e){ e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); } }

private static ArrayList<String> parse(BufferedReader in) throws IOException{ String line; ArrayList<String> code= new ArrayList<String>(); while((line= in.readLine())!=null){ code.add(line); if(line.contains("$")){ start = new Point(line.indexOf('$'), code.size() - 1); } } return code; } }</java> The code pointer class:<java>import java.awt.Point; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.LinkedList;

public class CodePtr{ final String instChars= "><.,/\\+-#@$%!?";//valid chars ArrayList<String> code;//code array Direction dir;//current direction ArrayList<Character> mem;//memory space int memPtr;//memory pointer Point place;//code pointer LinkedList<Point> pStack;//code pointer stack LinkedList<Direction> dStack;//direction stack //input stream BufferedReader input= new BufferedReader(new InputStreamReader(System.in));

public CodePtr(final ArrayList<String> code, final Point place){ this.code= code; dir= Direction.RIGHT; this.place= place; mem = new ArrayList<Character>(); mem.add('\0');//initial memory memPtr= 0; dStack= new LinkedList<Direction>(); pStack= new LinkedList<Point>(); }

public CodePtr(final Point place, final Direction dir){ //This constructor is left over from attempts at '&' this.dir= dir; this.place= place; }

public void run(){ place= moveCP();//move past $ while(execute(code.get(place.y).charAt(place.x))){ place= moveCP(); } }

private boolean execute(final char inst){ //ignore char and keep going if(!instChars.contains("" + inst)) return true; switch(inst){ case '.'://print System.out.print(mem.get(memPtr)); break; case ','://input try{ int in; while((in= input.read()) == 10 || in == 13);//skip return chars mem.set(memPtr, (char)in); }catch(final IOException e){ e.printStackTrace(); } break; case '!'://skip place= moveCP(); break; case '?'://conditional skip if(mem.get(memPtr) == 0) place= moveCP(); break; case '>'://move pointer right memPtr++; while(mem.size() <= memPtr){ mem.add('\0');//add more memory cells if necessary } break; case '<'://move memory pointer left memPtr--; if(memPtr < 0){//no negative values System.err.println("memory pointer out of range (negative)"); return false;//stop executing } break; case '/'://mirror switch(dir){ case RIGHT: dir= Direction.UP; break; case DOWN: dir= Direction.LEFT; break; case LEFT: dir= Direction.DOWN; break; case UP: dir= Direction.RIGHT; break; default: } break; case '\\'://mirror switch(dir){ case RIGHT: dir= Direction.DOWN; break; case DOWN: dir= Direction.RIGHT; break; case LEFT: dir= Direction.UP; break; case UP: dir= Direction.LEFT; break; default: } break; case '+'://inc mem.set(memPtr, (char)(mem.get(memPtr) + 1)); break; case '-'://dec mem.set(memPtr, (char)(mem.get(memPtr) - 1)); break; case '#'://pop if(dStack.size() > 0){ final Direction oldDir= dStack.pop(); final Point oldPlace= pStack.pop(); place= oldPlace; dir= oldDir; return true; } return false; case '@'://push //protect the reference with a new object pStack.push(new Point(place)); dStack.push(dir); place= moveCP();//skip break; case '%': mem.set(memPtr, (char)(Math.random() * 256)); break; default: } return true; }

private Point moveCP(){ final Point retVal= new Point(place); switch(dir){ case RIGHT: retVal.x++; break; case DOWN: retVal.y++; break; case LEFT: retVal.x--; break; case UP: retVal.y--; break; default: } if(retVal.x<0 || retVal.y<0 || retVal.y >= code.size() || retVal.x >= code.get(0).length()){ System.err.println("Code pointer has left the code space"); System.exit(-1); } return retVal; } enum Direction{ UP,DOWN,LEFT,RIGHT; } } </java>