Full implementation of Append(), including error messages & semicolon requirement
This commit is contained in:
parent
be780d54e2
commit
34ecfc0f46
@ -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;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user