Cleaned up some code,
Some checks failed
continuous-integration/appveyor/branch AppVeyor build failed

Fixed append operator requirement (Closes #10)
This commit is contained in:
Brychan Dempsey 2021-03-24 13:40:16 +13:00
parent 65a7b0e497
commit 17d4a3672b

View File

@ -35,8 +35,6 @@ namespace Assignment_1
'\'' '\''
}; };
static bool nonStrict = false;
static void Main(string[] args) static void Main(string[] args)
{ {
Console.WriteLine("┌──────────────────────────────────────────┐"); Console.WriteLine("┌──────────────────────────────────────────┐");
@ -50,20 +48,14 @@ namespace Assignment_1
MemoryStream sourceStream = new(1024); MemoryStream sourceStream = new(1024);
Parser parser = new(); Parser parser = new();
bool dynamicInput = false; bool dynamicInput = false;
/*foreach (var arg in args)
{
if (arg == "-ns")
{
nonStrict = true;
}
}*/
// From https://stackoverflow.com/questions/3453220/how-to-detect-if-console-in-stdin-has-been-redirected // From https://stackoverflow.com/questions/3453220/how-to-detect-if-console-in-stdin-has-been-redirected
// Reading from pipes is equivalent to reading user input, though the input is redirected // Reading from pipes is equivalent to reading user input, though the input is redirected
if (Console.IsInputRedirected) if (Console.IsInputRedirected)
{ {
// To simplify reading, we read all input bytes from the piped input to the stream. // To simplify reading, we read all input bytes from the piped input to the stream.
// This is by far not the best way to do it; reading line-by-line would reduce memory space, // Not the best way to do it; we don't need to keep any data that has already been read.
// but it allows a simple read into the console // Whilst the stream could be copied excluding already parsed data at each input step, this would rely
// on GC to cleanup afterwards
sourceStream.Write(Encoding.UTF8.GetBytes(Console.In.ReadToEnd())); sourceStream.Write(Encoding.UTF8.GetBytes(Console.In.ReadToEnd()));
// Dispose will close a piped input, or piped file in further iterations of the program // Dispose will close a piped input, or piped file in further iterations of the program
Console.In.Dispose(); Console.In.Dispose();
@ -157,13 +149,6 @@ namespace Assignment_1
public void StartParsing(Stream source, bool dynamicInput = false) public void StartParsing(Stream source, bool dynamicInput = false)
{ {
long initSourceLength = source.Length; long initSourceLength = source.Length;
//if (nonStrict || PeekChar(source) == '{')
if (true)
{
/*if (PeekChar(source) == '{')
{
source.ReadByte();
}*/
long lastLinePos = 0; long lastLinePos = 0;
long initPos = 0; long initPos = 0;
bool cont = false; bool cont = false;
@ -200,9 +185,6 @@ namespace Assignment_1
{ {
// By turning the result of the command into an action, // By turning the result of the command into an action,
// we can defer processing the final result until the end of this control flow // we can defer processing the final result until the end of this control flow
// I.e. "I don't know what action to do, but I will need it, when I know where this statement ends"
// In some ways, it makes more sense. The action is determined by the interpreter's result
Action result = () => { }; Action result = () => { };
source.Position = position; source.Position = position;
switch ((Statements)statementType) switch ((Statements)statementType)
@ -322,11 +304,6 @@ namespace Assignment_1
} }
} }
} }
else
{
Console.WriteLine("First read character was not \'{\'. Use the launch flag -ns for non-strict syntax checking");
}
}
#region Function Handling #region Function Handling
/// <summary> /// <summary>
@ -432,8 +409,14 @@ namespace Assignment_1
for (int i = 0; i < eligibleKeys.Count; i++) for (int i = 0; i < eligibleKeys.Count; i++)
{ {
string entryFormat = "│{0," + -1 * keyWidth + "}│{1," + -1 * valueWidth + "}│{2," + -1 * flagWidth + "}│\n"; string entryFormat = "│{0," + -1 * keyWidth + "}│{1," + -1 * valueWidth + "}│{2," + -1 * flagWidth + "}│\n";
List<string> keyLines = GetStringLines(eligibleKeys[i], keyWidth);
List<string> valueLines = GetStringLines(Symbols[eligibleKeys[i]].Item1.Replace("\r", "\\r").Replace("\n", "\\n").Replace("\t", "\\t"), valueWidth);
consoleOutput.Append(string.Format(entryFormat, eligibleKeys[i], Symbols[eligibleKeys[i]].Item1.Replace("\r", "\\r").Replace("\n", "\\n").Replace("\t", "\\t"), Convert.ToString((byte)Symbols[eligibleKeys[i]].Item2, 2).PadLeft(8, '0'))); for (int j = 0; j < (keyLines.Count > valueLines.Count ? keyLines.Count : valueLines.Count); j++)
{
consoleOutput.Append(string.Format(entryFormat, j >= keyLines.Count ? "" : keyLines[j], j >= valueLines.Count ? "" : valueLines[j], j == 0 ? Convert.ToString((byte)Symbols[eligibleKeys[i]].Item2, 2).PadLeft(8, '0'): ""));
}
//consoleOutput.Append(string.Format(entryFormat, eligibleKeys[i], Symbols[eligibleKeys[i]].Item1.Replace("\r", "\\r").Replace("\n", "\\n").Replace("\t", "\\t"), Convert.ToString((byte)Symbols[eligibleKeys[i]].Item2, 2).PadLeft(8, '0')));
if (i + 1 < eligibleKeys.Count) if (i + 1 < eligibleKeys.Count)
{ {
consoleOutput.Append(string.Format("├" + new string('─', keyWidth) + "┼" + new string('─', valueWidth) + "┼" + new string('─', flagWidth) + "┤\n")); consoleOutput.Append(string.Format("├" + new string('─', keyWidth) + "┼" + new string('─', valueWidth) + "┼" + new string('─', flagWidth) + "┤\n"));
@ -558,11 +541,13 @@ namespace Assignment_1
{ {
string result = ""; string result = "";
// iterate through values until we reach either the end of the stream or the end-of-statement // iterate through values until we reach either the end of the stream or the end-of-statement
bool IsAppendSet = true;
while (s.Position < s.Length && !IsNextEoS(s)) while (s.Position < s.Length && !IsNextEoS(s))
{ {
if (IsNextEoS(s, '+')) if (IsNextEoS(s, '+'))
{ {
s.Position = FindNextWord(s, out _); s.Position = FindNextWord(s, out _);
IsAppendSet = true;
} }
else else
{ {
@ -571,8 +556,17 @@ namespace Assignment_1
{ {
Console.WriteLine("Could not parse value"); Console.WriteLine("Could not parse value");
} }
if (IsAppendSet)
{
s.Position = val; s.Position = val;
result += value; result += value;
IsAppendSet = false;
}
else
{
throw new ParserException("Append operator not set", 0, s.Position);
}
} }
} }
expression = result; expression = result;
@ -701,8 +695,7 @@ namespace Assignment_1
/// <returns></returns> /// <returns></returns>
static string GetNextLine(Stream s) static string GetNextLine(Stream s)
{ {
string nextLine; FindNextOccurance(s, '\n', out string nextLine);
FindNextOccurance(s, '\n', out nextLine);
return nextLine; return nextLine;
} }
@ -718,7 +711,7 @@ namespace Assignment_1
// Record our current position // Record our current position
long start = s.Position; long start = s.Position;
// Check if the character at the current pos is whitespace, if so, keep advancing until it isn't. // Check if the character at the current pos is whitespace, if so, keep advancing until it isn't.
// NB: Whitespace includes carriage returns or line feeds, // NB: Whitespace includes carriage returns and line feeds,
// so 'set\r\n // so 'set\r\n
// var // var
// "expression"; // "expression";
@ -900,6 +893,18 @@ namespace Assignment_1
string result = string.Format(t, source[..rightHalf], source[rightHalf..]); string result = string.Format(t, source[..rightHalf], source[rightHalf..]);
return result; return result;
} }
static List<string> GetStringLines(string source, int maxWidth)
{
List<string> lines = new();
for (int i = 0; i < source.Length; i++)
{
int max = i + maxWidth <= source.Length ? i + maxWidth : source.Length;
lines.Add(source[i..max]);
i = max;
}
return lines;
}
#endregion #endregion
public class ParserException : Exception public class ParserException : Exception
{ {