Commit 4df67d8e authored by Alexander Dietsch's avatar Alexander Dietsch

New:

- Parser
- First code interpretation
- Revert registers to original value
- More Feedback in Log Window

Bug fixes:
- Registers can now be edited even if they are at their limit if no
  further digit is added with the edit (e.g. if one or multiple digits are
  marked before pressing a digit key)
- Changing callback functions now only works when not running simulation
- Editing registers per method call only works when not running simulation
parent 3b5cc133
This diff is collapsed.
......@@ -12,14 +12,17 @@ using System.Threading.Tasks;
using System.Windows.Forms;
using ICSharpCode.AvalonEdit;
using MainLWSimulator;
using System.IO;
namespace LWSimulatorGUI
{
public partial class MainGUI : Form
{
#if NO_MONO
#if NO_MONO
private TextEditor textArea;
private System.Windows.Forms.Integration.ElementHost eHostTextArea;
#else
private TextBox tBProgram;
#endif
private LWCoordinator simulator;
private LogWindow log;
......@@ -46,11 +49,27 @@ namespace LWSimulatorGUI
textArea.SyntaxHighlighting = ICSharpCode.AvalonEdit.Highlighting.HighlightingManager.Instance.GetDefinition("C#");
eHostTextArea.Child = textArea;
this.spCMainGUI.Panel1.Controls.Add(this.eHostTextArea);
this.ResumeLayout(false);
this.PerformLayout();
#else
this.SuspendLayout();
this.tBProgram = new System.Windows.Forms.TextBox();
this.spCMainGUI.Panel1.Controls.Add(this.tBProgram);
this.tBProgram.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tBProgram.Location = new System.Drawing.Point(4, 4);
this.tBProgram.Multiline = true;
this.tBProgram.Name = "tBProgram";
this.tBProgram.Size = new System.Drawing.Size(556, 447);
this.tBProgram.TabIndex = 0;
this.tBProgram.ReadOnly = true;
this.ResumeLayout(false);
this.PerformLayout();
#endif
// Remove ugly selection colors (usually cell has blue background => cell is selected)
this.dGVRegisters.DefaultCellStyle.SelectionBackColor = this.dGVRegisters.DefaultCellStyle.BackColor;
this.dGVRegisters.DefaultCellStyle.SelectionForeColor = this.dGVRegisters.DefaultCellStyle.ForeColor;
/* this.dGVRegisters.DefaultCellStyle.SelectionBackColor = SystemColors.Highlight;
this.dGVRegisters.DefaultCellStyle.SelectionForeColor = SystemColors.HighlightText;*/
simulator = new LWCoordinator();
for (int i = 0; i < simulator.getRegisterAmount(); i++)
{
......@@ -326,7 +345,7 @@ namespace LWSimulatorGUI
/// <param name="e">Arguments of the type <see cref="KeyPressEventArgs">KeyPressEventArgs</see></param>
private void dGVRegisters_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar)&&(sender as TextBox).Text.Length >= this.cValues.MaxInputLength)
if (!char.IsControl(e.KeyChar)&&(sender as TextBox).Text.Length >= this.cValues.MaxInputLength && (sender as TextBox).SelectedText.Length == 0)
{
e.Handled = true;
return;
......@@ -382,6 +401,7 @@ namespace LWSimulatorGUI
if (long.TryParse(e.FormattedValue.ToString(), out parsedVal) == false)
e.Cancel = true;
}
//dGVRegisters.CurrentCell.Selected = false;
}
/// <summary>
......@@ -461,7 +481,7 @@ namespace LWSimulatorGUI
/// <param name="e">Arguments of the type <see cref="EventArgs">EventArgs</see></param>
private void tSBStop_Click(object sender, EventArgs e)
{
simulator.stopProgram();
simulator.stopProgram(true);
}
/// <summary>
......@@ -490,6 +510,64 @@ namespace LWSimulatorGUI
log.addLine_Notify("WARNING: FailSafe timed out; Rechecking state.");
UpdateRunningStateChange();
}
#endregion
/// <summary>
/// Eventhandler for clicking Import->Program
/// </summary>
/// <param name="sender">Sender of the event</param>
/// <param name="e">Arguments of the type <see cref="EventArgs">EventArgs</see></param>
private void programToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog programFileDialog = new OpenFileDialog();
programFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
programFileDialog.FilterIndex = 1;
programFileDialog.RestoreDirectory = true;
programFileDialog.CheckFileExists = true;
programFileDialog.CheckPathExists = true;
programFileDialog.Multiselect = false;
if (programFileDialog.ShowDialog() == DialogResult.OK)
{
if (File.Exists(programFileDialog.FileName))
{
try
{
tBProgram.Text = File.ReadAllText(programFileDialog.FileName);
if (!simulator.setProgramFile(programFileDialog.FileName))
MessageBox.Show("Failed to open file in simulator.\nMore detailed information possibly in log.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show(string.Format("When opening the file the following exception occured\n{0}", ex.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void bRevertReg_Click(object sender, EventArgs e)
{
simulator.revertRegister(dGVRegisters.CurrentCell.RowIndex);
}
private void bRevertAllReg_Click(object sender, EventArgs e)
{
simulator.revertAllRegisters();
}
/// <summary>
/// TO DO: Change open to opening a project file.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
programToolStripMenuItem_Click(sender, e);
}
#endregion
}
}
\ No newline at end of file
......@@ -34,6 +34,8 @@
this.nUDTime = new System.Windows.Forms.NumericUpDown();
this.lTime = new System.Windows.Forms.Label();
this.gBLog = new System.Windows.Forms.GroupBox();
this.pBHelpAdvancedLog = new System.Windows.Forms.PictureBox();
this.chBAdvancedLog = new System.Windows.Forms.CheckBox();
this.lExportFolder = new System.Windows.Forms.Label();
this.bDefineDirExport = new System.Windows.Forms.Button();
this.tBDirPath = new System.Windows.Forms.TextBox();
......@@ -51,19 +53,17 @@
this.bPrefCancel = new System.Windows.Forms.Button();
this.bPrefOK = new System.Windows.Forms.Button();
this.fBDiaExportLog = new System.Windows.Forms.FolderBrowserDialog();
this.chBAdvancedLog = new System.Windows.Forms.CheckBox();
this.pBHelpAdvancedLog = new System.Windows.Forms.PictureBox();
this.pPreferences.SuspendLayout();
this.gBSimulation.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nUDTime)).BeginInit();
this.gBLog.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pBHelpAdvancedLog)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nUDLogLines)).BeginInit();
this.gBRegisters.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pBHelpRegDefVal)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nUDRegDefVal)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pBHelpReg)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nUDRegisters)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pBHelpAdvancedLog)).BeginInit();
this.SuspendLayout();
//
// pPreferences
......@@ -135,6 +135,25 @@
this.gBLog.TabStop = false;
this.gBLog.Text = "Log";
//
// pBHelpAdvancedLog
//
this.pBHelpAdvancedLog.Image = ((System.Drawing.Image)(resources.GetObject("pBHelpAdvancedLog.Image")));
this.pBHelpAdvancedLog.Location = new System.Drawing.Point(142, 69);
this.pBHelpAdvancedLog.Name = "pBHelpAdvancedLog";
this.pBHelpAdvancedLog.Size = new System.Drawing.Size(16, 16);
this.pBHelpAdvancedLog.TabIndex = 6;
this.pBHelpAdvancedLog.TabStop = false;
//
// chBAdvancedLog
//
this.chBAdvancedLog.AutoSize = true;
this.chBAdvancedLog.Location = new System.Drawing.Point(10, 69);
this.chBAdvancedLog.Name = "chBAdvancedLog";
this.chBAdvancedLog.Size = new System.Drawing.Size(126, 17);
this.chBAdvancedLog.TabIndex = 7;
this.chBAdvancedLog.Text = "Show Advanced Log";
this.chBAdvancedLog.UseVisualStyleBackColor = true;
//
// lExportFolder
//
this.lExportFolder.AutoSize = true;
......@@ -335,25 +354,6 @@
//
this.fBDiaExportLog.RootFolder = System.Environment.SpecialFolder.MyComputer;
//
// chBAdvancedLog
//
this.chBAdvancedLog.AutoSize = true;
this.chBAdvancedLog.Location = new System.Drawing.Point(10, 69);
this.chBAdvancedLog.Name = "chBAdvancedLog";
this.chBAdvancedLog.Size = new System.Drawing.Size(126, 17);
this.chBAdvancedLog.TabIndex = 7;
this.chBAdvancedLog.Text = "Show Advanced Log";
this.chBAdvancedLog.UseVisualStyleBackColor = true;
//
// pBHelpAdvancedLog
//
this.pBHelpAdvancedLog.Image = ((System.Drawing.Image)(resources.GetObject("pBHelpAdvancedLog.Image")));
this.pBHelpAdvancedLog.Location = new System.Drawing.Point(142, 69);
this.pBHelpAdvancedLog.Name = "pBHelpAdvancedLog";
this.pBHelpAdvancedLog.Size = new System.Drawing.Size(16, 16);
this.pBHelpAdvancedLog.TabIndex = 6;
this.pBHelpAdvancedLog.TabStop = false;
//
// Preferences
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
......@@ -373,6 +373,7 @@
((System.ComponentModel.ISupportInitialize)(this.nUDTime)).EndInit();
this.gBLog.ResumeLayout(false);
this.gBLog.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pBHelpAdvancedLog)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nUDLogLines)).EndInit();
this.gBRegisters.ResumeLayout(false);
this.gBRegisters.PerformLayout();
......@@ -380,7 +381,6 @@
((System.ComponentModel.ISupportInitialize)(this.nUDRegDefVal)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pBHelpReg)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nUDRegisters)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pBHelpAdvancedLog)).EndInit();
this.ResumeLayout(false);
}
......
This diff is collapsed.
This diff is collapsed.
using System;
using System.IO;
using System.Threading;
using System.Runtime.Caching;
using System.Collections.Generic;
using System.Linq;
namespace MainLWSimulator
{
internal class LWParser
{
private LWCoordinator parent;
private FileSystemWatcher watcher = null;
private bool reloadFile = false;
private int line =-1;
private List<string> program;
private string path;
private object pathLock = new object();
internal LWParser(LWCoordinator parent)
{
this.parent = parent;
}
/// <summary>
/// Sets the path the File that needs to be parsed and sets a FileWatcher on it.
/// </summary>
/// <param name="path">Path the file is at</param>
/// <returns>False if file does not exists</returns>
internal bool setFilePath(string path)
{
if (!File.Exists(path))
{
parent.writeLogMessage("ERROR: Tried to set a non existant file as path.");
return false;
}
lock(pathLock)
{
if (this.path == path)
return true;
if (watcher != null)
watcher.EnableRaisingEvents = false;
else
{
watcher = new FileSystemWatcher();
// Add event handlers.
watcher.Changed += OnChanged;
watcher.Created += OnChanged;
watcher.Deleted += OnChanged;
watcher.Renamed += OnRenamed;
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
}
watcher.Filter = Path.GetFileName(path);
watcher.Path = Path.GetDirectoryName(path);
watcher.EnableRaisingEvents = true;
this.path = path;
reloadFile = true;
return true;
}
}
/// <summary>
/// Reads program of the file specified in the private variable path.
/// Use setFilePath to change the specified path.
/// NOT THREAD SAFE
/// </summary>
/// <returns>True on success; false otherwise</returns>
internal bool importProgram()
{
lock(pathLock)
{
if (String.IsNullOrEmpty(path))
{
parent.writeLogMessage("ERROR: Location of code file was not specified.");
return false;
}
if (!File.Exists(path))
{
parent.writeLogMessage("ERROR: Specified code file does not exist.");
return false;
}
if (!reloadFile)
{
line = -1;
return true;
}
try
{
program = new List<string>(File.ReadAllLines(path));
}
catch (Exception e)
{
parent.writeLogMessage("ERROR: An exception occured when trying to load program: " + e.Message);
return false;
}
line = -1; // Set line to very beginning
reloadFile = false;
}
return true;
}
/// <summary>
/// Increases the variable 'line' until a command (= line not consisting of only whitespace chars or a comment symbol as first character) is found
/// </summary>
private void skipNonCommandLines()
{
while (line < program.Count)
{
int firstNonWhiteSpace = program[line].TakeWhile(char.IsWhiteSpace).Count();
if (firstNonWhiteSpace == program[line].Length || program[line].ElementAt(firstNonWhiteSpace) == '#')
line++;
else
break;
}
}
/// <summary>
/// Returns the line of the command that was just returned by 'getNextCommand'.
/// </summary>
/// <returns>Line of the current command.</returns>
internal int getCurrentLine()
{
return line;
}
/// <summary>
/// Gets the next command line or null.
/// NOT THREAD-SAFE
/// </summary>
/// <returns>Null if no program loaded; empty string if last command of a program was already returned once; otherwise the next command in the program</returns>
internal string getNextCommand()
{
if (program == null)
{
parent.writeLogMessage("WARNING: Tried to read non-loaded program");
return null;
}
line++;
skipNonCommandLines();
if (line >= program.Count)
return "";
return program[line];
}
/// <summary>
/// Sets variable line to a value so the line with the index 'newLine' (or later lines if some lines are sorted out by 'skipNonCommandLines')
/// is returned on next call of getNextCommand.
/// </summary>
/// <param name="newLine">Index of line to return on next call of 'getNextCommand'</param>
internal void setCurrentLine(int newLine)
{
if(newLine < 0)
{
parent.writeLogMessage("WARNING: Tried to set line of program to negative value.");
return;
}
line = newLine - 1;
}
/// <summary>
/// Handler for about-to-be-disposed Callback methods so a late call won't do any damage
/// </summary>
/// <param name="state">The state of the dependant object that was changed</param>
private void emptyMethod(object state)
{
return;
}
/// <summary>
/// Event Handler if a change occurs on the file.
/// </summary>
/// <param name="sender">Sender of the event.</param>
/// <param name="e">Arguments of the type <see cref="FileSystemEventArgs">FileSystemEventArgs</see></param>
private void OnChanged(object sender, FileSystemEventArgs e)
{
lock(pathLock)
{
parent.writeLogMessage("WARNING: Detected a change in file or path.");
reloadFile = true;
}
}
/// <summary>
/// Event Handler if a rename occurs on the file or path.
/// </summary>
/// <param name="sender">Sender of the event.</param>
/// <param name="e">Arguments of the type <see cref="RenamedEventArgs">RenamedEventArgs</see></param>
private void OnRenamed(object sender, RenamedEventArgs e)
{
lock (pathLock)
{
parent.writeLogMessage("WARNING: Detected a change in file or path.");
reloadFile = true;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MainLWSimulator
{
internal class LWRegisters
{
private List<long> registers;
private volatile List<long> registers;
private volatile List<long> backupRegisters = null;
private long maxVal = 1000L*1000L*1000L*1000L*1000L - 1L; //999,999,999,999,999
private long defVal;
......@@ -87,6 +86,8 @@ namespace MainLWSimulator
parent.writeLogMessage("ERROR: When editing Registers, value was higher than the max allowed value.");
return false;
}
if (value < 0)
value = 0;
if (registers[index] != value)
{
registers[index] = value;
......@@ -300,5 +301,95 @@ namespace MainLWSimulator
lock(registers)
return registers.Count;
}
/// <summary>
/// Creates a backup of the current registers for later use
/// </summary>
internal void createBackup()
{
lock(registers)
{
backupRegisters = new List<long>(registers);
}
}
/// <summary>
/// Invalidates the backup registers; can be useful when layout of the registers changes (e.g. shift or increase/decrease)
/// </summary>
internal void invalidateBackup()
{
lock(registers) // Make sure no other Thread writes Backup to registers or other way round
{
backupRegisters = null;
}
}
/// <summary>
/// Reverts one register to have the value of the backup register
/// </summary>
/// <param name="index">Index of the register to revert</param>
internal void revertRegister(int index)
{
if (index < 0)
{
parent.writeLogMessage("ERROR: When reverting Registers; index was smaller than 0.");
return;
}
lock (registers)
{
if(backupRegisters == null)
{
parent.writeLogMessage("ERROR: When reverting Registers, no backup was found.");
return;
}
if (index >= registers.Count)
{
parent.writeLogMessage("ERROR: When removing Registers, index was out of range.");
return;
}
long value = backupRegisters[index];
registers[index] = value;
parent.updateRegister(index, value);
}
}
/// <summary>
/// Reverts all registers to state of backup
/// </summary>
internal void revertAllRegisters()
{
lock (registers)
{
if (backupRegisters == null)
{
parent.writeLogMessage("ERROR: When reverting Registers, no backup was found.");
return;
}
int toIndex = backupRegisters.Count;
if (toIndex > registers.Count)
toIndex = registers.Count;
for(int i = 0; i < toIndex; i++)
{
long newVal = backupRegisters[i];
if(registers[i] != newVal)
{
registers[i] = newVal;
parent.updateRegister(i, newVal);
}
}
}
}
/// <summary>
/// Returns the maximum value of a register.
/// </summary>
/// <returns>Maximum value of a register</returns>
internal long getMaxVal()
{
return maxVal;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Threading;
namespace MainLWSimulator
{
......
......@@ -32,6 +32,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Caching" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
......@@ -42,6 +43,7 @@
<ItemGroup>
<Compile Include="LWCoordinator.cs" />
<Compile Include="LWInterpreter.cs" />
<Compile Include="LWParser.cs" />
<Compile Include="LWRegisters.cs" />
<Compile Include="LWTimer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
......
x0:=1;
x1:=1000000
x3:=400;
x0:=30;
x2:=x1
x4:=x1+x2
x5:= x4 - 21002
x6 := x1 / 2
x6:= 1 - x5;
x7:= x0 * x3
x8 := 3 /2
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment