diff --git a/pseudocodeIde/PseudocodeIDEForm.Designer.cs b/pseudocodeIde/PseudocodeIDEForm.Designer.cs
index cb5c1c1..b9205e4 100644
--- a/pseudocodeIde/PseudocodeIDEForm.Designer.cs
+++ b/pseudocodeIde/PseudocodeIDEForm.Designer.cs
@@ -61,6 +61,7 @@ private void InitializeComponent()
//
// menuStrip
//
+ this.menuStrip.GripMargin = new System.Windows.Forms.Padding(2, 2, 0, 2);
this.menuStrip.ImageScalingSize = new System.Drawing.Size(24, 24);
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileMenuItem,
@@ -81,7 +82,7 @@ private void InitializeComponent()
this.openMenuItem,
this.saveMenuItem});
this.fileMenuItem.Name = "fileMenuItem";
- this.fileMenuItem.Size = new System.Drawing.Size(69, 29);
+ this.fileMenuItem.Size = new System.Drawing.Size(69, 32);
this.fileMenuItem.Text = "Datei";
//
// newMenuItem
@@ -120,7 +121,7 @@ private void InitializeComponent()
this.toolStripSeparator4,
this.goToMenuItem});
this.editMenuItem.Name = "editMenuItem";
- this.editMenuItem.Size = new System.Drawing.Size(111, 29);
+ this.editMenuItem.Size = new System.Drawing.Size(111, 32);
this.editMenuItem.Text = "Bearbeiten";
//
// undoToolStripMenuItem
@@ -180,7 +181,7 @@ private void InitializeComponent()
this.viewMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.wordWrapMenuItem});
this.viewMenuItem.Name = "viewMenuItem";
- this.viewMenuItem.Size = new System.Drawing.Size(86, 29);
+ this.viewMenuItem.Size = new System.Drawing.Size(86, 32);
this.viewMenuItem.Text = "Ansicht";
//
// wordWrapMenuItem
@@ -199,7 +200,7 @@ private void InitializeComponent()
this.toolStripSeparator2,
this.singleEqualIsCompareOperatorMenuItem});
this.runMenuItem.Name = "runMenuItem";
- this.runMenuItem.Size = new System.Drawing.Size(109, 29);
+ this.runMenuItem.Size = new System.Drawing.Size(109, 32);
this.runMenuItem.Text = "Ausführen";
//
// runProgramMenuItem
@@ -242,7 +243,7 @@ private void InitializeComponent()
this.updateMenuItem,
this.updateBetaMenuItem});
this.helpMenuItem.Name = "helpMenuItem";
- this.helpMenuItem.Size = new System.Drawing.Size(64, 29);
+ this.helpMenuItem.Size = new System.Drawing.Size(64, 32);
this.helpMenuItem.Text = "Hilfe";
//
// showHelpMenuItem
diff --git a/pseudocodeIde/PseudocodeIDEForm.cs b/pseudocodeIde/PseudocodeIDEForm.cs
index 975086b..9a8eff2 100644
--- a/pseudocodeIde/PseudocodeIDEForm.cs
+++ b/pseudocodeIde/PseudocodeIDEForm.cs
@@ -24,6 +24,7 @@
using System.Drawing;
using System.IO;
using System.Linq;
+using System.Net;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows.Forms;
@@ -37,6 +38,17 @@ public partial class PseudocodeIDEForm : Form
///
private const int MAX_UNDO_SIZE = 250;
+ // Indicators 0-7 could be in use by a lexer so we'll use indicator 8
+ ///
+ /// Indicator ID for highlighting words.
+ ///
+ public const int WORD_HIGHLIGHT_INDICATOR_ID = 8;
+
+ ///
+ /// Indicator ID for selecting the next word via tab.
+ ///
+ public const int TAB_SELECTION_INDICATOR_ID = 9;
+
///
/// do not update the undo stack when the last char is a letter from A-Z (case ignored), a number from 0-9 or a underscore
///
@@ -100,9 +112,15 @@ public string Code
///
private int _maxLineNumberCharLength;
+ ///
+ /// Contains the instance of this form
+ ///
+ public static PseudocodeIDEForm Instance;
public PseudocodeIDEForm()
{
+ Instance = this;
+
InitializeComponent();
_outputForm = new OutputForm(this);
_findReplace = new FindReplace(codeTextBox);
@@ -224,9 +242,12 @@ private void PseudocodeIDE_FormClosing(object sender, FormClosingEventArgs e)
}
// ---------------------------------------------
- // CODE TEXTBOX EVENT LISTENERS
+ // CODE TEXTBOX (Scintilla)
// ---------------------------------------------
+ ///
+ /// Updates the undo stack, when user updated the code
+ ///
private void UserUpdatedText()
{
// only update undo stack if next event not ignored
@@ -240,6 +261,36 @@ private void UserUpdatedText()
}
}
+ ///
+ /// User changed selection
+ ///
+ private void UserChangedSelection()
+ {
+ HighlightWord(codeTextBox.SelectedText);
+ RemovePreviousTabSelectionIndicators();
+
+ TryHandleSelectionChange();
+ }
+
+ ///
+ /// Forcefully updates the undoStack, when the cursor moved more than 1 since last check or the user selected something
+ ///
+ private void TryHandleSelectionChange()
+ {
+ // ignore when we already undid something
+ if (_redoStack.Count != 0)
+ {
+ _lastCursorPosition = codeTextBox.SelectionStart;
+ return;
+ }
+
+ if (codeTextBox.SelectionEnd - codeTextBox.SelectionStart != 0 || Math.Abs(_lastCursorPosition - codeTextBox.SelectionStart) > 1)
+ {
+ UpdateUndoStack(true);
+ }
+ _lastCursorPosition = codeTextBox.SelectionStart;
+ }
+
private void CodeTextBox_UpdateUI(object sender, UpdateUIEventArgs e)
{
switch (e.Change)
@@ -257,6 +308,12 @@ private void CodeTextBox_TextChanged(object sender, EventArgs e)
{
// when the code is modified, the code is no longer saved in the file
SetFileNotSaved();
+
+ // only update undo stack if next event not ignored
+ if (!IgnoreTextChange)
+ {
+ TryHandleSelectionChange();
+ }
// Did the number of characters in the line number display change?
int maxLineNumberCharLength = codeTextBox.Lines.Count.ToString().Length;
@@ -274,6 +331,11 @@ private void CodeTextBox_TextChanged(object sender, EventArgs e)
private void CodeTextBox_KeyDown(object sender, KeyEventArgs e)
{
+ if (e.KeyCode == Keys.Tab && e.Modifiers == Keys.None)
+ {
+ e.SuppressKeyPress = TrySelectNextTabIndicator();
+ }
+
// hack to allow enter to autocomplete even if down wasnt pressed before
if ((e.KeyCode == Keys.Enter || e.KeyCode == Keys.Tab) && e.Modifiers == Keys.None && autoCompleteMenu.SelectedItemIndex < 0)
{
@@ -296,11 +358,13 @@ private void CodeTextBox_KeyDown(object sender, KeyEventArgs e)
e.SuppressKeyPress = false;
return;
}
+ // find replace: find previous
else if (e.Shift && e.KeyCode == Keys.F3)
{
_findReplace.Window.FindPrevious();
e.SuppressKeyPress = true;
}
+ // find replace: find next
else if (e.KeyCode == Keys.F3)
{
_findReplace.Window.FindNext();
@@ -308,6 +372,116 @@ private void CodeTextBox_KeyDown(object sender, KeyEventArgs e)
}
}
+ ///
+ /// Add indicators to scintilla, where the variables are, so that the user can tab through them
+ ///
+ ///
+ ///
+ public void AddTabSelectionIndicators(List<(int selectionStart, int selectionEnd)> tabSelections)
+ {
+ if (tabSelections.Count >= 1)
+ {
+ codeTextBox.SelectionStart = tabSelections.First().selectionStart;
+ codeTextBox.SelectionEnd = tabSelections.First().selectionEnd;
+ tabSelections.RemoveAt(0);
+ }
+
+ // remove all uses of our indicator
+ codeTextBox.IndicatorCurrent = TAB_SELECTION_INDICATOR_ID;
+ codeTextBox.IndicatorClearRange(0, codeTextBox.TextLength);
+
+ if (tabSelections.Count == 0)
+ {
+ return;
+ }
+
+ // update indicator appearance
+ codeTextBox.Indicators[TAB_SELECTION_INDICATOR_ID].Style = IndicatorStyle.StraightBox;
+ codeTextBox.Indicators[TAB_SELECTION_INDICATOR_ID].Under = true;
+ codeTextBox.Indicators[TAB_SELECTION_INDICATOR_ID].ForeColor = Color.LightBlue;
+ codeTextBox.Indicators[TAB_SELECTION_INDICATOR_ID].OutlineAlpha = 255;
+ codeTextBox.Indicators[TAB_SELECTION_INDICATOR_ID].Alpha = 100;
+
+ foreach ((int selectionStart, int selectionEnd) in tabSelections)
+ {
+ codeTextBox.IndicatorFillRange(selectionStart, selectionEnd - selectionStart);
+ }
+
+ UpdateUndoStack(true);
+ }
+
+ ///
+ /// Try to select the next tab indicator on tab press
+ ///
+ /// true if the next indicator was selected
+ private bool TrySelectNextTabIndicator()
+ {
+ (int, int)? firstSelection = GetFirstTabSelectionTuple();
+ if (firstSelection != null)
+ {
+ (int selectionStart, int selectionEnd) = firstSelection.Value;
+
+ codeTextBox.IndicatorCurrent = TAB_SELECTION_INDICATOR_ID;
+ codeTextBox.IndicatorClearRange(selectionStart, selectionEnd - selectionStart);
+ codeTextBox.SelectionStart = selectionStart;
+ codeTextBox.SelectionEnd = selectionEnd;
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Get the selection start and end of the first tab selection indicator
+ ///
+ /// null if there is no tab selection indicator
+ private (int selectionStart, int selectionEnd)? GetFirstTabSelectionTuple()
+ {
+ int textLength = codeTextBox.TextLength;
+ Indicator indicator = codeTextBox.Indicators[TAB_SELECTION_INDICATOR_ID];
+ int bitmapFlag = (1 << indicator.Index);
+
+ int endPos = 0;
+ do
+ {
+ int startPos = indicator.Start(endPos);
+ endPos = indicator.End(startPos);
+
+ // Is this range filled with our indicator (TAB_SELECTION_INDICATOR_ID)?
+ uint bitmap = codeTextBox.IndicatorAllOnFor(startPos);
+ bool filled = ((bitmapFlag & bitmap) == bitmapFlag);
+ if (filled)
+ {
+ return (startPos, endPos);
+ }
+ } while (endPos != 0 && endPos < textLength);
+
+ return null;
+ }
+
+ ///
+ /// Removes all tab completion that are present before the selection end
+ ///
+ private void RemovePreviousTabSelectionIndicators()
+ {
+ (int, int)? firstSelection = GetFirstTabSelectionTuple();
+ while (firstSelection != null)
+ {
+ (int selectionStart, int selectionEnd) = firstSelection.Value;
+
+ if (selectionEnd <= codeTextBox.SelectionEnd)
+ {
+ codeTextBox.IndicatorCurrent = TAB_SELECTION_INDICATOR_ID;
+ codeTextBox.IndicatorClearRange(selectionStart, selectionEnd - selectionStart);
+ }
+ else
+ {
+ break;
+ }
+
+ firstSelection = GetFirstTabSelectionTuple();
+ }
+ }
+
private void CodeTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
// keep tab indentation from previous line on new line
@@ -330,27 +504,11 @@ private void CodeTextBox_CharAdded(object sender, CharAddedEventArgs e)
{
int caretPos = codeTextBox.CurrentPosition;
bool docStart = caretPos == 1;
- bool docEnd = caretPos == codeTextBox.Text.Length;
-
- int charPrev = docStart ? codeTextBox.GetCharAt(caretPos) : codeTextBox.GetCharAt(caretPos - 2);
- int charNext = codeTextBox.GetCharAt(caretPos);
-
- bool isCharPrevBlank = charPrev == ' ' || charPrev == '\t' ||
- charPrev == '\n' || charPrev == '\r';
- bool isCharNextBlank = charNext == ' ' || charNext == '\t' ||
- charNext == '\n' || charNext == '\r' ||
- docEnd;
+ char charPrev = (char)(docStart ? codeTextBox.GetCharAt(caretPos) : codeTextBox.GetCharAt(caretPos - 2));
+ char charNext = (char)codeTextBox.GetCharAt(caretPos);
- bool isEnclosed = (charPrev == '(' && charNext == ')') ||
- (charPrev == '{' && charNext == '}') ||
- (charPrev == '[' && charNext == ']');
-
- bool isSpaceEnclosed = (charPrev == '(' && isCharNextBlank) || (isCharPrevBlank && charNext == ')') ||
- (charPrev == '{' && isCharNextBlank) || (isCharPrevBlank && charNext == '}') ||
- (charPrev == '[' && isCharNextBlank) || (isCharPrevBlank && charNext == ']');
-
- bool isCharOrString = docStart || (isCharPrevBlank && isCharNextBlank) || isEnclosed || isSpaceEnclosed;
+ bool addClosingQuotes = docStart || !Scanner.IsAlphaNumeric(charNext) && !Scanner.IsAlphaNumeric(charPrev);
switch (e.Char)
{
@@ -395,7 +553,7 @@ private void CodeTextBox_CharAdded(object sender, CharAddedEventArgs e)
return;
}
- if (isCharOrString)
+ if (addClosingQuotes)
{
codeTextBox.InsertText(caretPos, "\"");
}
@@ -408,7 +566,7 @@ private void CodeTextBox_CharAdded(object sender, CharAddedEventArgs e)
return;
}
- if (isCharOrString)
+ if (addClosingQuotes)
{
codeTextBox.InsertText(caretPos, "'");
}
@@ -416,34 +574,11 @@ private void CodeTextBox_CharAdded(object sender, CharAddedEventArgs e)
}
}
- private void UserChangedSelection()
- {
- // ignore when we already undid something
- if (_redoStack.Count != 0)
- {
- _lastCursorPosition = codeTextBox.SelectionStart;
- return;
- }
-
- // update undo stack when user selected something or cursor moved by more then one since last time
- if (codeTextBox.SelectionEnd - codeTextBox.SelectionStart != 0 || Math.Abs(_lastCursorPosition - codeTextBox.SelectionStart) > 1)
- {
- UpdateUndoStack(true);
- }
- _lastCursorPosition = codeTextBox.SelectionStart;
-
- HighlightWord(codeTextBox.SelectedText);
- }
-
// adapted from https://github.com/desjarlais/Scintilla.NET/wiki/Find-and-Highlight-Words
private void HighlightWord(string text)
{
- // Indicators 0-7 could be in use by a lexer
- // so we'll use indicator 8 to highlight words.
- const int NUM = 8;
-
// Remove all uses of our indicator
- codeTextBox.IndicatorCurrent = NUM;
+ codeTextBox.IndicatorCurrent = WORD_HIGHLIGHT_INDICATOR_ID;
codeTextBox.IndicatorClearRange(0, codeTextBox.TextLength);
if (string.IsNullOrEmpty(text))
@@ -452,11 +587,11 @@ private void HighlightWord(string text)
}
// Update indicator appearance
- codeTextBox.Indicators[NUM].Style = IndicatorStyle.StraightBox;
- codeTextBox.Indicators[NUM].Under = true;
- codeTextBox.Indicators[NUM].ForeColor = Color.Lime;
- codeTextBox.Indicators[NUM].OutlineAlpha = 127;
- codeTextBox.Indicators[NUM].Alpha = 100;
+ codeTextBox.Indicators[WORD_HIGHLIGHT_INDICATOR_ID].Style = IndicatorStyle.StraightBox;
+ codeTextBox.Indicators[WORD_HIGHLIGHT_INDICATOR_ID].Under = true;
+ codeTextBox.Indicators[WORD_HIGHLIGHT_INDICATOR_ID].ForeColor = Color.Lime;
+ codeTextBox.Indicators[WORD_HIGHLIGHT_INDICATOR_ID].OutlineAlpha = 100;
+ codeTextBox.Indicators[WORD_HIGHLIGHT_INDICATOR_ID].Alpha = 100;
// Search the document
codeTextBox.TargetStart = 0;
@@ -734,14 +869,13 @@ private void UndoToolStripMenuItem_Click(object sender, EventArgs e)
redoToolStripMenuItem.Enabled = true;
}
+ int oldSelectionStart = codeTextBox.SelectionStart;
// the undo stack always has at least one item in it
if (_undoStack.Count <= 1)
{
// set the textbox text to the item without removing it from the stack
IgnoreTextChange = true;
- int oldSelectionStart = codeTextBox.SelectionStart;
codeTextBox.Text = _undoStack.Peek();
- codeTextBox.SelectionStart = Math.Min(oldSelectionStart, codeTextBox.TextLength);
// no more things to undo
undoToolStripMenuItem.Enabled = false;
@@ -749,7 +883,6 @@ private void UndoToolStripMenuItem_Click(object sender, EventArgs e)
else
{
string currentText = codeTextBox.Text;
- int oldSelectionStart = codeTextBox.SelectionStart;
// set the textbox text to the first item that doesn't match the current text. also remove them from the undo stack
do
@@ -757,9 +890,8 @@ private void UndoToolStripMenuItem_Click(object sender, EventArgs e)
IgnoreTextChange = true;
codeTextBox.Text = _undoStack.Peek();
} while (_undoStack.Count > 1 && currentText.Equals(_undoStack.Pop()));
-
- codeTextBox.SelectionStart = Math.Min(oldSelectionStart, codeTextBox.TextLength);
}
+ codeTextBox.SelectionStart = oldSelectionStart;
}
private void RedoToolStripMenuItem_Click(object sender, EventArgs e)
diff --git a/pseudocodeIde/SetClipboardHelper.cs b/pseudocodeIde/SetClipboardHelper.cs
index e5e6d33..44ec2ab 100644
--- a/pseudocodeIde/SetClipboardHelper.cs
+++ b/pseudocodeIde/SetClipboardHelper.cs
@@ -20,20 +20,20 @@ namespace pseudocode_ide
public class SetClipboardHelper : StaHelper
{
- readonly string FORMAT;
- readonly object DATA;
+ private readonly string _format;
+ private readonly object _data;
public SetClipboardHelper(string format, object data)
{
- FORMAT = format;
- DATA = data;
+ _format = format;
+ _data = data;
}
protected override void Work()
{
DataObject obj = new System.Windows.Forms.DataObject(
- FORMAT,
- DATA
+ _format,
+ _data
);
Clipboard.SetDataObject(obj, true);
@@ -42,7 +42,7 @@ protected override void Work()
public abstract class StaHelper
{
- readonly ManualResetEvent COMPLETE = new ManualResetEvent(false);
+ readonly ManualResetEvent _complete = new ManualResetEvent(false);
public void Go()
{
@@ -59,7 +59,7 @@ private void DoWork()
{
try
{
- COMPLETE.Reset();
+ _complete.Reset();
Work();
}
catch (Exception ex)
@@ -78,13 +78,13 @@ private void DoWork()
catch
{
// ex from first exception
- Debug.WriteLine(ex);
+ MessageBox.Show(ex.ToString(), "Error");
}
}
}
finally
{
- COMPLETE.Set();
+ _complete.Set();
}
}
diff --git a/pseudocodeIde/interpreter/pseudocode/PseudocodeAutocompleteItem.cs b/pseudocodeIde/interpreter/pseudocode/PseudocodeAutocompleteItem.cs
index 3c4e1c4..7fd04ae 100644
--- a/pseudocodeIde/interpreter/pseudocode/PseudocodeAutocompleteItem.cs
+++ b/pseudocodeIde/interpreter/pseudocode/PseudocodeAutocompleteItem.cs
@@ -12,6 +12,11 @@
using AutocompleteMenuNS;
using pseudocodeIde;
using ScintillaNET;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using static System.Net.Mime.MediaTypeNames;
namespace pseudocode_ide.interpreter.pseudocode
{
@@ -43,8 +48,56 @@ public override string GetTextForReplace()
string line = scintilla.Lines[scintilla.LineFromPosition(Parent.Fragment.Start)].Text;
string indents = new string('\t', line.GetIndentationLevel());
+ Text = Text.Replace("\n", $"\n{indents}");
- return Text.Replace("\n", $"\n{indents}");
+ return Text;
+ }
+
+ ///
+ /// After this item got selected (the text is already pasted in scintilla), put all the variable locations in a list
+ ///
+ ///
+ public override void OnSelected(SelectedEventArgs e)
+ {
+ Scintilla scintilla = (Scintilla)Parent.TargetControlWrapper.TargetControl;
+ List<(int selectionStart, int selectionEnd)> tabSelections = new List<(int selectionStart, int selectionEnd)>();
+
+ bool inSelection = false;
+ int textLengthWithoutMarkers = Text.Replace("\\^", " ").Replace("^", "").Length;
+ for (int i = Parent.Fragment.Start; ; i++)
+ {
+ recheck:
+ if (i >= Parent.Fragment.Start + textLengthWithoutMarkers) {
+ break;
+ }
+
+ if (scintilla.Text[i] == '^')
+ {
+ if (i != 0 && scintilla.Text[i - 1] == '\\')
+ {
+ scintilla.Text = scintilla.Text.Remove(i - 1, 1);
+ goto recheck;
+ }
+
+ scintilla.Text = scintilla.Text.Remove(i, 1);
+
+ if (!inSelection) // && firstOccurrenceSelected
+ {
+ tabSelections.Add((selectionStart: i, selectionEnd: Parent.Fragment.Start + textLengthWithoutMarkers ));
+ inSelection = true;
+ }
+ else // inSelection && firstOccurrenceSelected
+ {
+ (int selectionStart, int selectionEnd) lastSelection = tabSelections.Last();
+ lastSelection.selectionEnd = i;
+ tabSelections[tabSelections.Count - 1] = lastSelection;
+
+ inSelection = false;
+ }
+ }
+ }
+
+ PseudocodeIDEForm.Instance.AddTabSelectionIndicators(tabSelections);
}
}
}
diff --git a/pseudocodeIde/interpreter/pseudocode/PseudocodeKeywords.cs b/pseudocodeIde/interpreter/pseudocode/PseudocodeKeywords.cs
index 2bd8faa..c7f4b83 100644
--- a/pseudocodeIde/interpreter/pseudocode/PseudocodeKeywords.cs
+++ b/pseudocodeIde/interpreter/pseudocode/PseudocodeKeywords.cs
@@ -29,42 +29,25 @@ static PseudocodeKeywords()
// code block snippets
KEYWORDS.Add(new PseudocodeType("WENN", IF, new List()
{
- new PseudocodeAutocompleteItem("WENN ^\n\t\nENDE WENN", "WENN Block"),
- new PseudocodeAutocompleteItem("WENN ^\n\t\nSONST\n\t\nENDE WENN", "WENN-SONST Block")
+ new PseudocodeAutocompleteItem("WENN ^bedingung^\n\t^code^\nENDE WENN", "WENN Block"),
+ new PseudocodeAutocompleteItem("WENN ^bedingung^\n\t^code^\nSONST\n\t^code^\nENDE WENN", "WENN-SONST Block")
}));
- KEYWORDS.Add(new PseudocodeType("FALLS", SWITCH_PREFIX, "FALLS ^ GLEICH\n\tbedingung1:\n\t\t\n\tSONST:\n\t\t\nENDE FALLS"));
- KEYWORDS.Add(new PseudocodeType("SOLANGE", WHILE, "SOLANGE ^\n\t\nENDE SOLANGE"));
- KEYWORDS.Add(new PseudocodeType("WIEDERHOLE", DO, "WIEDERHOLE\n\t\nSOLANGE ^"));
+ KEYWORDS.Add(new PseudocodeType("FALLS", SWITCH_PREFIX, "FALLS ^variable^ GLEICH\n\t^bedingung1^:\n\t\t^code^\n\tSONST:\n\t\t^code^\nENDE FALLS"));
+ KEYWORDS.Add(new PseudocodeType("SOLANGE", WHILE, "SOLANGE ^bedingung^\n\t\nENDE SOLANGE"));
+ KEYWORDS.Add(new PseudocodeType("WIEDERHOLE", DO, "WIEDERHOLE\n\t\nSOLANGE ^bedingung^"));
KEYWORDS.Add(new PseudocodeType("FÜR", FOR, new List()
{
- new PseudocodeAutocompleteItem("FÜR ^ BIS SCHRITT \n\t\nENDE FÜR", "FÜR-BIS Block"),
- new PseudocodeAutocompleteItem("FÜR ^ IN \n\t\nENDE FÜR", "FÜR-IN Block")
+ new PseudocodeAutocompleteItem("FÜR ^variable^ BIS ^endwert^ SCHRITT ^erhöhung^\n\t^code^\nENDE FÜR", "FÜR-BIS Block"),
+ new PseudocodeAutocompleteItem("FÜR ^variable^ IN ^liste^\n\t^code^\nENDE FÜR", "FÜR-IN Block")
}));
- KEYWORDS.Add(new PseudocodeType("OPERATION", FUNCTION, "OPERATION ^()\n\t"));
- KEYWORDS.Add(new PseudocodeType("Liste", TYPE_LIST, "Liste<^>"));
+ KEYWORDS.Add(new PseudocodeType("OPERATION", FUNCTION, "OPERATION ^name^()\n\t"));
+ KEYWORDS.Add(new PseudocodeType("Liste", TYPE_LIST, "Liste<^Typ^>"));
// built-in methods
- KEYWORDS.Add(new PseudocodeType("schreibe", IDENTIFIER, "schreibe(^)"));
- KEYWORDS.Add(new PseudocodeType("warte", IDENTIFIER, "warte(^)"));
- KEYWORDS.Add(new PseudocodeType("benutzereingabe", IDENTIFIER, "benutzereingabe<^>(\"\", \"\")"));
+ KEYWORDS.Add(new PseudocodeType("schreibe", IDENTIFIER, "schreibe(^wert^)"));
+ KEYWORDS.Add(new PseudocodeType("warte", IDENTIFIER, "warte(^millisekunden^)"));
+ KEYWORDS.Add(new PseudocodeType("benutzereingabe", IDENTIFIER, "benutzereingabe<^Rückgabetyp^>(^nachricht^, ^titel^)"));
- // if/else
- KEYWORDS.Add(new PseudocodeType("SONST", ELSE));
- KEYWORDS.Add(new PseudocodeType("ENDE WENN", END_IF));
-
-
- // switch/case
- KEYWORDS.Add(new PseudocodeType("GLEICH", SWITCH_SUFFIX));
- KEYWORDS.Add(new PseudocodeType("ENDE FALLS", END_SWITCH));
-
- // (do) while
- KEYWORDS.Add(new PseudocodeType("ENDE SOLANGE", END_WHILE));
-
- // for
- KEYWORDS.Add(new PseudocodeType("BIS", FOR_TO));
- KEYWORDS.Add(new PseudocodeType("SCHRITT", FOR_STEP));
- KEYWORDS.Add(new PseudocodeType("IN", FOR_IN));
- KEYWORDS.Add(new PseudocodeType("ENDE FÜR", END_FOR));
// break
KEYWORDS.Add(new PseudocodeType("ABBRUCH", BREAK));
@@ -83,19 +66,19 @@ static PseudocodeKeywords()
KEYWORDS.Add(new PseudocodeType("ODER", OR));
// boolean types
+ KEYWORDS.Add(new PseudocodeType("bool", TYPE_BOOL));
KEYWORDS.Add(new PseudocodeType("Boolean", TYPE_BOOL));
KEYWORDS.Add(new PseudocodeType("boolean", TYPE_BOOL));
- KEYWORDS.Add(new PseudocodeType("bool", TYPE_BOOL));
// int types
KEYWORDS.Add(new PseudocodeType("GZ", TYPE_INT));
- KEYWORDS.Add(new PseudocodeType("Integer", TYPE_INT));
KEYWORDS.Add(new PseudocodeType("int", TYPE_INT));
+ KEYWORDS.Add(new PseudocodeType("Integer", TYPE_INT));
// double types
KEYWORDS.Add(new PseudocodeType("FKZ", TYPE_DOUBLE));
- KEYWORDS.Add(new PseudocodeType("Real", TYPE_DOUBLE));
KEYWORDS.Add(new PseudocodeType("double", TYPE_DOUBLE));
+ KEYWORDS.Add(new PseudocodeType("Real", TYPE_DOUBLE));
// char types
KEYWORDS.Add(new PseudocodeType("Zeichen", TYPE_CHAR));
@@ -103,14 +86,31 @@ static PseudocodeKeywords()
// string types
KEYWORDS.Add(new PseudocodeType("Text", TYPE_STRING));
- KEYWORDS.Add(new PseudocodeType("String", TYPE_STRING));
KEYWORDS.Add(new PseudocodeType("string", TYPE_STRING));
+ KEYWORDS.Add(new PseudocodeType("String", TYPE_STRING));
+
+ // null
+ KEYWORDS.Add(new PseudocodeType("NICHTS", NULL));
// new keyword
KEYWORDS.Add(new PseudocodeType("NEU", NEW));
- // null
- KEYWORDS.Add(new PseudocodeType("NICHTS", NULL));
+ // if/else
+ KEYWORDS.Add(new PseudocodeType("SONST", ELSE));
+ KEYWORDS.Add(new PseudocodeType("ENDE WENN", END_IF));
+
+ // switch/case
+ KEYWORDS.Add(new PseudocodeType("GLEICH", SWITCH_SUFFIX));
+ KEYWORDS.Add(new PseudocodeType("ENDE FALLS", END_SWITCH));
+
+ // (do) while
+ KEYWORDS.Add(new PseudocodeType("ENDE SOLANGE", END_WHILE));
+
+ // for
+ KEYWORDS.Add(new PseudocodeType("BIS", FOR_TO));
+ KEYWORDS.Add(new PseudocodeType("SCHRITT", FOR_STEP));
+ KEYWORDS.Add(new PseudocodeType("IN", FOR_IN));
+ KEYWORDS.Add(new PseudocodeType("ENDE FÜR", END_FOR));
}
}
}
diff --git a/pseudocodeIde/interpreter/scanner/Scanner.cs b/pseudocodeIde/interpreter/scanner/Scanner.cs
index cdf8f7b..b80eb54 100644
--- a/pseudocodeIde/interpreter/scanner/Scanner.cs
+++ b/pseudocodeIde/interpreter/scanner/Scanner.cs
@@ -29,12 +29,12 @@ public class Scanner
///
/// User-written Pseudocode
///
- private readonly string CODE;
+ private readonly string _code;
///
/// The list of tokens that will be generated from the CODE.
///
- private readonly LinkedList TOKENS = new LinkedList();
+ private readonly LinkedList _tokens = new LinkedList();
///
/// start position of the current lexeme
@@ -57,7 +57,7 @@ public class Scanner
/// the Pseudocode text string
public Scanner(string code)
{
- this.CODE = code;
+ this._code = code;
}
///
@@ -73,8 +73,8 @@ public LinkedList ScanTokens()
ScanToken();
}
- TOKENS.AddLast(Token.CreateEofToken(_line));
- return TOKENS;
+ _tokens.AddLast(Token.CreateEofToken(_line));
+ return _tokens;
}
///
@@ -234,7 +234,7 @@ private void HandleIdentifier(bool textEmpty = true)
Advance();
}
- string text = CODE.Substring(_start, _current - _start);
+ string text = _code.Substring(_start, _current - _start);
// allow something like "ENDE WENN"; when text is ENDE and the next char is a space, allow the space in the identifier
if (textEmpty && text.Equals("ENDE") && (IsAtEnd() || Peek() == ' ' || Peek() == '\t'))
@@ -297,7 +297,7 @@ private void HandleNumber()
Advance();
}
// start + 2 because the '0x' must be removed
- AddToken(NUMBER, Convert.ToInt32(CODE.Substring(_start + 2, _current - _start), 16));
+ AddToken(NUMBER, Convert.ToInt32(_code.Substring(_start + 2, _current - _start), 16));
return;
}
else if (Peek() == 'b' && IsBinaryDigit(PeekNext()))
@@ -310,11 +310,11 @@ private void HandleNumber()
Advance();
}
// start + 2 because the '0b' must be removed
- AddToken(NUMBER, Convert.ToInt32(CODE.Substring(_start, _current - _start).Substring(2), 2));
+ AddToken(NUMBER, Convert.ToInt32(_code.Substring(_start, _current - _start).Substring(2), 2));
return;
}
- AddToken(NUMBER, double.Parse(CODE.Substring(_start, _current - _start)));
+ AddToken(NUMBER, double.Parse(_code.Substring(_start, _current - _start)));
}
///
@@ -357,7 +357,7 @@ private void HandleChar()
Advance();
// trim the surrounding quotes
- string value = CODE.Substring(_start + 1, _current - _start - 2);
+ string value = _code.Substring(_start + 1, _current - _start - 2);
AddToken(CHAR, value);
}
@@ -386,7 +386,7 @@ private void HandleString()
Advance();
// trim the surrounding quotes
- string value = CODE.Substring(_start + 1, _current - _start - 2);
+ string value = _code.Substring(_start + 1, _current - _start - 2);
AddToken(STRING, value);
}
@@ -402,7 +402,7 @@ private bool Match(char expected)
return false;
}
- if (CODE[_current] != expected)
+ if (_code[_current] != expected)
{
return false;
}
@@ -418,7 +418,7 @@ private bool Match(char expected)
///
private char Peek()
{
- return IsAtEnd() ? '\0' : CODE[_current];
+ return IsAtEnd() ? '\0' : _code[_current];
}
///
@@ -427,14 +427,14 @@ private char Peek()
///
private char PeekNext()
{
- return _current + 1 >= CODE.Length ? '\0' : CODE[_current + 1];
+ return _current + 1 >= _code.Length ? '\0' : _code[_current + 1];
}
///
/// check if a char is a digit
///
///
- private bool IsDigit(char c)
+ public static bool IsDigit(char c)
{
return c >= '0' && c <= '9';
}
@@ -463,7 +463,7 @@ private bool IsBinaryDigit(char c)
/// Check if a char is in the (German) alphabet
///
///
- private bool IsAlpha(char c)
+ public static bool IsAlpha(char c)
{
return (c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
@@ -476,7 +476,7 @@ private bool IsAlpha(char c)
/// Check if a char is alphanumeric
///
///
- private bool IsAlphaNumeric(char c)
+ public static bool IsAlphaNumeric(char c)
{
return IsAlpha(c) || IsDigit(c);
}
@@ -487,7 +487,7 @@ private bool IsAlphaNumeric(char c)
///
private bool IsAtEnd()
{
- return _current >= CODE.Length;
+ return _current >= _code.Length;
}
///
@@ -496,7 +496,7 @@ private bool IsAtEnd()
///
private char Advance()
{
- return CODE[_current++];
+ return _code[_current++];
}
///
@@ -506,8 +506,8 @@ private char Advance()
/// the literal object
private void AddToken(TokenType type, object literal = null)
{
- string text = CODE.Substring(_start, _current - _start);
- TOKENS.AddLast(new Token(type, text, literal, _line));
+ string text = _code.Substring(_start, _current - _start);
+ _tokens.AddLast(new Token(type, text, literal, _line));
}
}
}
diff --git a/pseudocodeIde/interpreter/scanner/SyntaxHighlightingScanner.cs b/pseudocodeIde/interpreter/scanner/SyntaxHighlightingScanner.cs
index 84cbb5b..21e3c3d 100644
--- a/pseudocodeIde/interpreter/scanner/SyntaxHighlightingScanner.cs
+++ b/pseudocodeIde/interpreter/scanner/SyntaxHighlightingScanner.cs
@@ -160,8 +160,6 @@ public static void Style(Scintilla scintilla, int startPos, int endPos)
identifier = scintilla.GetTextRange(startPos - length, length);
}
- Debug.WriteLine($"'{identifier}'");
-
int style = STYLE_IDENTIFIER;
// if the identifier is in the keyword list, then it will has a differnt color
if (PseudocodeKeywords.KEYWORDS.ContainsKey(identifier))