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