From 8fbb32c4ddb29b7f4cdb17dbda00ec98f8ed61eb Mon Sep 17 00:00:00 2001 From: Harm Berntsen Date: Sun, 17 May 2015 12:16:30 +0200 Subject: [PATCH] CLI mode --- src/nl/uu/cs/ssmui/CliRunner.java | 140 +++++++++++++++++++++++++ src/nl/uu/cs/ssmui/CodeTableModel.java | 2 +- src/nl/uu/cs/ssmui/Runner.java | 112 +++++++++++++++++--- src/nl/uu/cs/ssmui/SSMRunner.java | 31 ++++-- src/nl/uu/cs/ssmui/StepManager.java | 16 +-- 5 files changed, 270 insertions(+), 31 deletions(-) create mode 100644 src/nl/uu/cs/ssmui/CliRunner.java diff --git a/src/nl/uu/cs/ssmui/CliRunner.java b/src/nl/uu/cs/ssmui/CliRunner.java new file mode 100644 index 0000000..a0f2e0d --- /dev/null +++ b/src/nl/uu/cs/ssmui/CliRunner.java @@ -0,0 +1,140 @@ +package nl.uu.cs.ssmui; + +import java.io.Reader; +import java.util.Vector; + +import nl.uu.cs.ssm.Machine; +import nl.uu.cs.ssm.MachineState; +import nl.uu.cs.ssm.Messenger; + +public class CliRunner implements Messenger { + private static final long STEPS_INFINITE = -1; + + private long steps; + private MachineState machineState = new MachineState(5000, 2000, this); + private Machine machine = new Machine(machineState, this); + private StepManager stepManager = new StepManager(machine, false); + private CodeTableModel codeTableModel= new CodeTableModel(null, machineState); + + public CliRunner(long steps) { + this.steps = steps; + } + + public void run() { + long count = 0; + while (count != steps) { + if(doAStepForward()) { + return; + } + + if(count != STEPS_INFINITE) { + count ++; + } + } + } + + /** + * @return True if we are halted + */ + protected boolean doAStepForward() + { + stepManager.beginForwardStep() ; + machine.executeOne() ; + if ( machineState.isHalted() ) + return true; + + stepManager.endForwardStep() ; + return false; + } + + private void reset() + { + codeTableModel.beforeReset() ; + + machine.reset() ; + machineState = machine.getMachineState() ; + + codeTableModel.reset() ; + } + + private void resetToInitialState() + { + machineState.resetToInitialState() ; + } + + public void load( Reader r ) + { + String msg ; + try + { + Vector leftOverLabels ; + AssemblyParseResult apr ; + AssemblyParser ap = new AssemblyParser( r ) ; + reset() ; + codeTableModel.parseInitialize() ; + for ( apr = null ; ! ap.isAtEOF() ; ) + { + apr = ap.parse1Line( apr ) ; + if ( apr.message != null ) + println( "Line " + apr.lineNr + ": " + apr.message ) ; + else if ( apr.instrNArgs.size() > 0 ) + { + leftOverLabels = new Vector() ; + msg = codeTableModel.enterParsedLine( apr.definedLabels, apr.instrNArgs, leftOverLabels ) ; + if ( msg != null ) + println( "Line " + apr.lineNr + ": " + msg ) ; + if ( leftOverLabels.size() == 0 ) + apr = null ; + else + apr.addLabels( leftOverLabels ) ; + } + } + } + catch ( Exception ex ) + { + ex.printStackTrace() ; + } + finally + { + msg = codeTableModel.parseFinalize() ; + if ( msg != null ) + println( msg ) ; + } + resetToInitialState() ; + } + + @Override + public void println(String s) { + System.out.println(s); + } + + @Override + public void print(String s) { + System.out.print(s); + } + + @Override + public int promptInt() { + System.out.print("Please enter an integer: "); + return Integer.parseInt(System.console().readLine()); + } + + @Override + public int promptChar() { + System.out.print("Please enter a character: "); + String line = System.console().readLine(); + return line.charAt(0); + } + + @Override + public int[] promptCharArray() { + System.out.print("Please enter a string: "); + String s = System.console().readLine(); + int[] result = new int[s.length()]; + for(int i = 0; i < s.length(); i++) + { + result[i] = s.codePointAt(i); + } + return result; + } +} diff --git a/src/nl/uu/cs/ssmui/CodeTableModel.java b/src/nl/uu/cs/ssmui/CodeTableModel.java index e6ebb93..7867462 100755 --- a/src/nl/uu/cs/ssmui/CodeTableModel.java +++ b/src/nl/uu/cs/ssmui/CodeTableModel.java @@ -381,7 +381,7 @@ public class CodeTableModel extends AbstractTableModel { //fireTableChanged( new TableModelEvent( this, row ) ) ; fireTableRowsUpdated( row, row ) ; - if ( ! ssmRunner.isSettingUp() ) + if ( ssmRunner != null && ! ssmRunner.isSettingUp() ) ssmRunner.println( "Warning: code modified at " + Utils.asHex( e.cellIndex ) ) ; } } diff --git a/src/nl/uu/cs/ssmui/Runner.java b/src/nl/uu/cs/ssmui/Runner.java index 08c7d31..527b0ad 100755 --- a/src/nl/uu/cs/ssmui/Runner.java +++ b/src/nl/uu/cs/ssmui/Runner.java @@ -8,18 +8,26 @@ package nl.uu.cs.ssmui; +import java.io.BufferedReader; import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; import javax.swing.UIManager; +import nl.uu.cs.ssm.Config; + public class Runner extends Thread { protected int delay = 50 ; SSMRunner ssmRunner ; - public Runner( File initialFile ) + public Runner(int delay) { + this.delay = delay; try { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); @@ -29,16 +37,33 @@ public class Runner extends Thread ssmRunner = new SSMRunner( this ); ssmRunner.initComponents(); ssmRunner.setVisible(true); - //System.out.println( "Foc Trav=" + ssmRunner.isFocusTraversable() ) ; ssmRunner.requestFocus() ; - if ( initialFile != null ) - ssmRunner.loadFile( initialFile ) ; } catch (Exception e) { e.printStackTrace(); } } + public void loadFile(File initialFile) { + ssmRunner.loadFile( initialFile ) ; + } + + public void loadReader(Reader reader) { + ssmRunner.load( reader ) ; + } + + public static void usage() { + System.out.println("Simple Stack Machine Interpreter"); + System.out.println("Version " + Config.version() + ", " + Config.versionDate()); + System.out.println("usage: [--clisteps ] [--cli] [--file OR --stdin]"); + System.out.println("\t--clisteps : The amount of steps to run. -1 for infinite(default). Only in cli mode"); + System.out.println("\t--stdin: Read code from stdin"); + System.out.println("\t--file : Read code from path"); + System.out.println("\t--cli: No GUI, runs code and exits on halt"); + System.out.println("\t--guidelay: Amount of time to sleep in milliseconds between steps in the GUI. Default: 50"); + System.exit(1); + } + public void run() { while( true ) @@ -58,16 +83,77 @@ public class Runner extends Thread } // Main entry point - static public void main(String[] args) - { - File initialFile = null ; - if ( args.length > 0 ) - { - File f = new File( args[0] ) ; - if ( f.exists() ) - initialFile = f ; + static public void main(String[] args) throws IOException { + File initialFile = null; + long steps = -1; + boolean stdin = false; + boolean cli = false; + int guiDelay =50; + for (int i = 0; i< args.length; i++) { + String key = args[i]; + switch(key) { + case "--clisteps": + i++; + steps = Long.parseLong(args[i]); + break; + case "--stdin": + if(initialFile != null) { + System.out.println("--stdin cannot be used with --file"); + usage(); + } + stdin=true; + break; + case "--file": + if(stdin) { + System.out.println("--file cannot be used with --stdin"); + usage(); + } else { + i++; + initialFile = new File(args[i]); + } + break; + case "--cli": + cli=true; + break; + case "--guidelay": + i++; + guiDelay = Integer.parseInt(args[i]); + break; + default: + usage(); + } + } + + if(initialFile != null && !initialFile.exists()) { + System.out.println("Input file does not exist"); + usage(); + } + + if(cli) { + CliRunner cliRunner = new CliRunner( steps); + if(stdin) { + BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + cliRunner.load(reader); + reader.close(); + } else { + if(!stdin && initialFile == null) { + System.out.println("Need some input in CLI mode"); + } + FileReader fr = new FileReader( initialFile ) ; + cliRunner.load(fr); + fr.close(); + } + cliRunner.run(); + } else { + Runner r = new Runner(guiDelay); + if(stdin) { + BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + r.loadReader(reader); + reader.close(); + } else if(initialFile != null) { + r.loadFile(initialFile); + } } - new Runner( initialFile ) ; } } diff --git a/src/nl/uu/cs/ssmui/SSMRunner.java b/src/nl/uu/cs/ssmui/SSMRunner.java index 20ca7c7..4720b10 100755 --- a/src/nl/uu/cs/ssmui/SSMRunner.java +++ b/src/nl/uu/cs/ssmui/SSMRunner.java @@ -12,8 +12,7 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; import java.io.FileReader; -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; +import java.io.Reader; import java.util.Arrays; import java.util.Enumeration; import java.util.Vector; @@ -148,7 +147,7 @@ public class SSMRunner extends JFrame setupState = SETUP_BUSY ; machineState = new MachineState( 5000, 2000, this ) ; // TBD: automatic increase with reasonable increments machine = new Machine( machineState, this ) ; - stepManager = new StepManager( machine ) ; + stepManager = new StepManager( machine, true ) ; codeTableModel = new CodeTableModel( this, machineState ) ; stackTableModel = new StackTableModel( machineState ) ; @@ -810,18 +809,16 @@ public class SSMRunner extends JFrame loadFile( recentLoadedFile ) ; } - protected void loadFile( File f ) - { + protected void load (Reader r) { setupState = SETUP_BUSY ; String msg ; - recentLoadedFile = f ; + try { Vector leftOverLabels ; AssemblyParseResult apr ; - FileReader fr = new FileReader( f ) ; - AssemblyParser ap = new AssemblyParser( fr ) ; + AssemblyParser ap = new AssemblyParser( r ) ; reset() ; codeTableModel.parseInitialize() ; for ( apr = null ; ! ap.isAtEOF() ; ) @@ -841,8 +838,6 @@ public class SSMRunner extends JFrame apr.addLabels( leftOverLabels ) ; } } - fr.close() ; - setTitle(title + " - " + f.getName()); } catch ( Exception ex ) { @@ -858,6 +853,22 @@ public class SSMRunner extends JFrame setupState = SETUP_READY ; } + + protected void loadFile( File f ) + { + recentLoadedFile = f ; + try + { + FileReader fr = new FileReader( f ) ; + load(fr); + fr.close() ; + setTitle(title + " - " + f.getName()); + } + catch ( Exception ex ) + { + ex.printStackTrace() ; + } + } class SSMFileFilter extends javax.swing.filechooser.FileFilter { diff --git a/src/nl/uu/cs/ssmui/StepManager.java b/src/nl/uu/cs/ssmui/StepManager.java index 367b7a3..acf0a00 100644 --- a/src/nl/uu/cs/ssmui/StepManager.java +++ b/src/nl/uu/cs/ssmui/StepManager.java @@ -30,16 +30,17 @@ public class StepManager private Vector> history ; private Vector curStepHistory ; - private StepManager( Memory m, Registers r ) + private StepManager( Memory m, Registers r, boolean enableHistory ) { memory = m ; registers = r ; - history = new Vector>() ; + if(enableHistory) + history = new Vector>() ; } - protected StepManager( Machine m ) + protected StepManager( Machine m, boolean enableHistory ) { - this( m.memory(), m.registers() ) ; + this( m.memory(), m.registers(), enableHistory ) ; machineState = m.state() ; } @@ -66,18 +67,19 @@ public class StepManager machineState.removeMachineStateListener( this ) ; memory.removeMemoryCellListener( this ) ; registers.removeMemoryCellListener( this ) ; - history.addElement( curStepHistory ) ; + if(history != null) + history.addElement( curStepHistory ) ; } protected boolean canDoBackStep() { - return history.size() > 0 ; + return history != null && history.size() > 0 ; } protected void backStep() { int sz ; - if ( (sz=history.size()) > 0 ) + if ( history != null && (sz=history.size()) > 0 ) { Vector events = history.elementAt( sz-1 ) ; for ( int i = events.size() - 1 ; i >= 0 ; i-- ) -- GitLab