diff --git a/Assignment 1.sln b/Assignment 1.sln
new file mode 100644
index 0000000..6a64dba
--- /dev/null
+++ b/Assignment 1.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31025.194
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assignment 1", "Assignment 1\Assignment 1.csproj", "{90821384-3BA4-4373-A08C-DA6BC25D688A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {90821384-3BA4-4373-A08C-DA6BC25D688A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {90821384-3BA4-4373-A08C-DA6BC25D688A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {90821384-3BA4-4373-A08C-DA6BC25D688A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {90821384-3BA4-4373-A08C-DA6BC25D688A}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {E0DB9C36-B3F8-40EA-B829-0EF4C528D43B}
+ EndGlobalSection
+EndGlobal
diff --git a/Assignment 1/Assignment 1.csproj b/Assignment 1/Assignment 1.csproj
new file mode 100644
index 0000000..76fc6da
--- /dev/null
+++ b/Assignment 1/Assignment 1.csproj
@@ -0,0 +1,9 @@
+
+
+
+ Exe
+ net5.0
+ Assignment_1
+
+
+
diff --git a/Assignment 1/Program.cs b/Assignment 1/Program.cs
new file mode 100644
index 0000000..31ff4c2
--- /dev/null
+++ b/Assignment 1/Program.cs
@@ -0,0 +1,177 @@
+using System;
+using System.IO;
+using System.Text;
+
+namespace Assignment_1
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓");
+ Console.WriteLine("┃ 159.341 2021 Semester 1, Assignment 1 ┃");
+ Console.WriteLine("┃ Submitted by Brychan Dempsey, 14299890 ┃");
+ Console.WriteLine("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
+ MemoryStream sourceStream = new MemoryStream(1024); // Creates a memory stream to retain source while being interpreted.
+ Parser parser = new Parser();
+ bool dynamicInput = false;
+ // 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
+ if (Console.IsInputRedirected)
+ {
+ sourceStream.Write(Encoding.UTF8.GetBytes(Console.In.ReadToEnd()));
+ sourceStream.Position = 0;
+ }
+ else
+ {
+ sourceStream.Write(Encoding.UTF8.GetBytes("{\r\n"));
+ sourceStream.Position = 0;
+ dynamicInput = true;
+ }
+ parser.FindProgram(sourceStream, dynamicInput);
+ }
+ public class Parser
+ {
+ public int FindProgram(Stream sourceStream, bool dynamicInput = false)
+ {
+ if (sourceStream.ReadByte() == '{')
+ {
+ FindStatement();
+ }
+ else return -1; // Could not find the start of the program
+ }
+
+ void Command_Exit()
+ {
+ Environment.Exit(0);
+ }
+
+ int FindStatement(Stream s)
+ {
+ string statement;
+ if (dynamicInput)
+ {
+ Console.Write("Enter a \'Statement\': ");
+ statement = Console.ReadLine();
+ }
+ else
+ {
+ statement = GetNextLine(s);
+ }
+
+ int wordBound = 0;
+ string nextWord = GetNextWord(statement, out wordBound);
+ switch (nextWord)
+ {
+ case "append":
+ FindIdentifier();
+ FindExpression();
+ break;
+ case "list":
+ break;
+ case "exit":
+ Environment.Exit(0);
+ break;
+ case "print":
+ break;
+ case "printlength":
+ break;
+ case "printwords":
+ break;
+ case "printwordcount":
+ break;
+ case "set":
+ break;
+ case "reverse":
+ break;
+ default:
+ break;
+ }
+
+ // Look for further elements
+ return 1;
+ }
+
+ int FindIdentifier(Stream s)
+ {
+
+ }
+ }
+
+
+
+ ///
+ /// Reads the memory stream as a UTF-8 encoded string until the next occurance of '\n' or '\r\n' (consuming, and excluded)
+ ///
+ ///
+ ///
+ static string GetNextLine(Stream s)
+ {
+ long start = s.Position;
+ StringBuilder sb = new StringBuilder();
+ bool newLineFound = false;
+ while (!newLineFound)
+ {
+ // As UTF-8 allows codepoints to span multiple bytes, reading a single byte as a character will not always give the expected
+ // value.
+ // Fortunately, the standard ASCII table is 7-bits long. The 8th bit is used to determine the character size
+ int readAmount = 0;
+ int firstChar = s.ReadByte();
+ if ((firstChar >> 3) == 0x1E) // 11110xxx implies a 4-byte length character
+ {
+ readAmount = 3;
+ }
+ else if((firstChar >> 4) == 0xE) // 1110xxxx, 3-byte
+ {
+ readAmount = 2;
+ }
+ else if ((firstChar >> 5) == 0x6) // 110xxxxx, 2-byte
+ {
+ readAmount = 1;
+ }
+
+ byte[] charBytes = new byte[readAmount + 1];
+ charBytes[0] = (byte)firstChar;
+ for (int i = 1; i < readAmount; i++)
+ {
+ int nextChar = s.ReadByte();
+ if (nextChar >> 6 != 2) throw new Exception("Character is not a valid UTF-8 code point!");
+ charBytes[i] = (byte)nextChar;
+ }
+ string converted = Encoding.UTF8.GetString(charBytes);
+ if (converted == "\r" || converted == "\n")
+ {
+ if (s.ReadByte() != '\n') s.Position--; // Return the position if the next character isn't a new line
+ newLineFound = true;
+ }
+ else
+ {
+ sb.Append(converted);
+ }
+ }
+ return sb.ToString();
+ }
+
+ static string GetNextWord(string s, out int wordEndPos)
+ {
+ // remove whitespace from the start
+ int wordStart = 0;
+ if (char.IsWhiteSpace(s[0]))
+ {
+ for (int i = 0; i < s.Length; i++)
+ {
+ if (char.IsWhiteSpace(s[i])) break;
+ wordStart = i;
+ }
+ }
+ int wordEnd = wordStart;
+ for (int i = wordEnd; i < s.Length; i++)
+ {
+ if (char.IsWhiteSpace(s[i])) break;
+ wordEnd = i;
+ }
+ wordEndPos = wordEnd;
+ return s.Substring(wordStart, wordEnd);
+ }
+ }
+}