Add project files.
This commit is contained in:
parent
97093bc510
commit
6d73e88105
25
Assignment 1.sln
Normal file
25
Assignment 1.sln
Normal file
@ -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
|
9
Assignment 1/Assignment 1.csproj
Normal file
9
Assignment 1/Assignment 1.csproj
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<RootNamespace>Assignment_1</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
177
Assignment 1/Program.cs
Normal file
177
Assignment 1/Program.cs
Normal file
@ -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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads the memory stream as a UTF-8 encoded string until the next occurance of '\n' or '\r\n' (consuming, and excluded)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user