-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathParser.cs
More file actions
107 lines (91 loc) · 3.26 KB
/
Copy pathParser.cs
File metadata and controls
107 lines (91 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using System.Text.RegularExpressions;
namespace hackAssembler;
partial class Parser
{
private int _lineIndex = -1; // no instruction initially
private string[] _instructions;
private List<string> _cparts = new List<string>() {"", "", ""};
public Parser(string inputFile)
{
_instructions = File.ReadAllLines(inputFile);
}
public Boolean HasMoreLines()
{
return _lineIndex + 1 < _instructions.Length ? true : false;
}
//debug only
public string CurrentInstruction() => _instructions[_lineIndex];
public void Advance()
{
while(true)
{
if (HasMoreLines() is true) _lineIndex++;
//ignore comments and trim
string raw = _instructions[_lineIndex];
Regex rgx = new Regex(@"\/\/.*");
string result = rgx.Replace(raw, String.Empty);
result = result.Trim();
_instructions[_lineIndex] = result;
// keep going in case it's comments only
if (result != String.Empty) break;
}
CInstructionParts();
}
public InstructType InstructionType()
{
char firstChar = _instructions[_lineIndex][0];
if (firstChar == '@') return InstructType.A_INSTRUCTION;
else if (firstChar == '(') return InstructType.L_INSTRUCTION;
else return InstructType.C_INSTRUCTION;
//!! Not checking if it is, in fact, a valid instruction!!
}
public string Symbol()
{
if (InstructionType() == InstructType.C_INSTRUCTION)
{
return "N/A";
}
if (InstructionType() == InstructType.A_INSTRUCTION)
{
// ignore the first '@' of the instruction
return _instructions[_lineIndex].Substring(1);
}
if (InstructionType() == InstructType.L_INSTRUCTION)
{
Regex rgx = new Regex(@"[^()]+");
Match match = rgx.Match(_instructions[_lineIndex]);
if (match.Success is true)
{
return match.Value;
}
}
return $"Unknown Symbol, instruction: {_instructions[_lineIndex]}";
}
// collects the current C-instruction parts,
// but doesn't check the validity
private void CInstructionParts()
{
if (InstructionType() is not InstructType.C_INSTRUCTION) return;
Regex rgx = MyRegex();
Match match = rgx.Match(_instructions[_lineIndex]);
if (match.Success is false)
{
Console.WriteLine(
"Error: can't understand the instruction: "
+_instructions[_lineIndex]);
}
Group dest = match.Groups["dest"];
Group comp = match.Groups["comp"];
Group jmp = match.Groups["jmp" ];
_cparts[0] = dest.Success ? dest.Value : "null";
_cparts[1] = comp.Success ? comp.Value : "null";
_cparts[2] = jmp.Success ? jmp.Value : "null";
}
public string Dest() => _cparts[0];
public string Comp() => _cparts[1];
public string Jump() => _cparts[2];
//overly complex regex!
[GeneratedRegex(@"(?:(?'dest'[AMD]{0,3})=)?(?'comp'[AMD\-+!10&\|]{0,3})(?:;(?'jmp'[A-Z]{0,3}))?")]
private static partial Regex MyRegex();
}
enum InstructType { A_INSTRUCTION, C_INSTRUCTION, L_INSTRUCTION }