Full implementation of Append(), including error messages & semicolon requirement

This commit is contained in:
Brychan Dempsey 2021-03-12 11:00:29 +13:00
parent be780d54e2
commit 34ecfc0f46

View File

@ -7,6 +7,7 @@ namespace Assignment_1
{ {
class Program class Program
{ {
[Flags]
enum VariableFlags enum VariableFlags
{ {
Empty = 0, Empty = 0,
@ -90,8 +91,7 @@ namespace Assignment_1
// parse the statement or list of statements; // parse the statement or list of statements;
// This is done by reading the next word // This is done by reading the next word
SkipWhitespace(source); SkipWhitespace(source);
string word = ""; long position = FindNextWord(source, out string word);
long position = FindNextWord(source, out word);
object statementType; object statementType;
if (Enum.TryParse(typeof(statements), word, out statementType)) if (Enum.TryParse(typeof(statements), word, out statementType))
{ {
@ -134,40 +134,78 @@ namespace Assignment_1
} }
#region Function Handling #region Function Handling
bool Append(Stream source) bool Append(Stream source, long lineStart = -1)
{ {
// If it wasn't explicitly set, assume line starts the length of 'append ' before the current position
if (lineStart == -1)
{
lineStart = source.Position - "append ".Length;
}
string key; string key;
long advance = FindIdentifier(source, out key); long keyEndPos = FindIdentifier(source, out key);
if (advance < 0) if (keyEndPos < 0 || !Symbols.ContainsKey(key))
{ {
// Error on finding object // Error on finding object
if (lineStart != -1)
{
source.Position = lineStart;
}
string fullLine = GetNextLine(source); // Grab a copy of the line to show the user
// append x
string errorMSG = " ^ could not identify object";
Console.WriteLine(fullLine);
Console.WriteLine(errorMSG);
source.SetLength(source.Position);
return false; return false;
} }
else else
{ {
source.Position = advance; source.Position = keyEndPos;
} }
string value; string value;
advance = FindValue(source, out value); long valuePos = FindValue(source, out value);
if (advance < 0) if (valuePos < 0)
{ {
// Error on parsing value // Error on finding object
source.Position = lineStart;
string fullLine = GetNextLine(source); // Grab a copy of the line to show the user
// append x
string errorMSG = new string(' ', (keyEndPos - source.Position) > 0 ? (int)(keyEndPos - source.Position) : "append".Length) + "^ could not evaluate value";
Console.WriteLine(fullLine);
Console.WriteLine(errorMSG);
// Value didn't parse, set stream length to current length (removes excess characters from the stream
// so the next command is parsed correctly)
source.SetLength(source.Position);
return false; return false;
} }
else else
{ {
source.Position = advance; source.Position = valuePos;
} }
string eol; string eol;
FindNextWord(source, out eol); FindNextWord(source, out eol);
if (eol[0] != ';') if (eol.Length == 0 || eol[0] != ';')
{ {
// Expected end-of-statement/end-of-line (;) // reset our position to the start of this line
source.Position = lineStart;
string fullLine = GetNextLine(source); // Grab a copy of the line to show the user
// Align the message carat to the point which could not be parsed
string errorMSG = new string(' ', (valuePos - source.Position) > 0 ? (int)(valuePos - source.Position) : "append".Length) + "^ expected a semicolon";
Console.WriteLine(fullLine);
Console.WriteLine(errorMSG);
source.SetLength(source.Position);
return false; return false;
} }
if (Symbols[key].Item2 == VariableFlags.Reserved) if (Symbols[key].Item2.HasFlag(VariableFlags.Reserved))
{ {
// Can't assign to reserved items // reset our position to the start of this line
source.Position = lineStart;
string fullLine = GetNextLine(source); // Grab a copy of the line to show the user
// Align the message carat to the point which could not be parsed
string errorMSG = new string(' ', (keyEndPos - (key.Length + 1) - source.Position) > 0 ? (int)(keyEndPos-(key.Length + 1) - source.Position) : "append".Length) + "^ cannot assign a value to a reserved constant";
Console.WriteLine(fullLine);
Console.WriteLine(errorMSG);
source.SetLength(source.Position);
return false; return false;
} }
Symbols[key] = new Tuple<string, VariableFlags>(Symbols[key].Item1 + value, Symbols[key].Item2); Symbols[key] = new Tuple<string, VariableFlags>(Symbols[key].Item1 + value, Symbols[key].Item2);
@ -352,7 +390,14 @@ namespace Assignment_1
{ {
s.Position--; s.Position--;
string keyValue; string keyValue;
long t = FindExistingIdentifier(s, out keyValue); long t = FindExistingIdentifier(s, out keyValue);
if (!Symbols.ContainsKey(keyValue))
{
returnedValue = "";
return -1;
}
returnedValue = Symbols[keyValue].Item1; returnedValue = Symbols[keyValue].Item1;
return t; return t;