forked from memo1195/L5K
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRung.cs
162 lines (150 loc) · 6.46 KB
/
Rung.cs
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace L5K
{
public class Rung
{
private List<string> _comment;
private List<string> _content;
private List<Alarm> _alarmList;
private HashSet<string> _tags;//changed to string Hashset because this will not be reading the tags from the tag section, this is reading it from the logic and
//only delivers the name of the Tag, not the content of it
private List<string> _specialcasesList;//This is a list of Studio5000 Methods that dont necesarily implement a Tag
private Regex _parametersRegex;
private readonly string _action;
private readonly string _parameters;
private Regex _tagFinderRegex;
private readonly string _tagName;
private List<string> _addonInstructions;
private bool _addonInstructionsPresent;
public static string RCInit
{
get
{
return " RC:";
}
}
public static string NInit
{
get
{
return " N:";
}
}
public string[] Comment
{
get
{
return _comment.ToArray();
}
}
//public string Content { get; }maybe wont be using this
public bool HasComment { get; }
public bool HasAlarm
{
get
{
return _alarmList.Count > 0;
}
}
/*public Rung(List<string> comment, string content)
{
_comment = comment;
Content = content;
FindAlarms();
}*/
public Rung(List<string> content)
{
//This will be the only constructor, Routine will identify each rung and rung class will take care of
//identifying if there is a rung comment or not and separate them.
_content = new List<string>();
_comment = new List<string>();
_alarmList = new List<Alarm>();
_tags = new HashSet<string>();
_specialcasesList = new List<string>() { "GSV", "SSV", "JSR" };
_parametersRegex = new Regex(@"(?<action>[A-Za-z_][\w]*)(?<parenthesis>\((?<params>[\w.,\[\]\?\+\-\#]*)\))");
//This regex will be used to find functions and their parenthesis content
_addonInstructions = new List<string>();
_addonInstructionsPresent = false;
_action = "action";
_parameters = "params";
_tagFinderRegex = new Regex(@"\b(?<tagname>[A-Za-z_][\w]*)((?<limiter>([.]|[\[]\d*]))(?<remain>[A-Za-z][\w]*))*");
_tagName = "tagname";
DefineTags();
HasComment = content.Contains(RCInit);
var viewingComment = HasComment;
//If the code finds an RC: then it will add the content to _comment List, else it will add it will identify
//that it is not reading a comment and then will be adding the content to _content which is the actual logic of the rung
for (var i = 0; i < content.Count; i++)
{
if (!content[i].StartsWith(NInit) && viewingComment)
_comment.Add(content[i]);
else
{
viewingComment = false;
_content.Add(content[i]);
}
}
//if (HasComment)
// FindAlarms();
//Content = content;
}
private void DefineTags()
{
var testableString = "";//This will carry all the content of N: and be tested in a Regex
foreach (var line in _content)//Gets all the content and makes it a single line string;
{
testableString += line;
}
var matches = _parametersRegex.Matches(testableString);
foreach (Match match in matches)
{
var actionType = match.Groups[_action].Value;
var parameter = match.Groups[_parameters].Value;
var tagMatches = _tagFinderRegex.Matches(parameter);
if (actionType.ToUpper() != actionType)
{
_addonInstructionsPresent = true;
_addonInstructions.Add(actionType);
}
if (_specialcasesList.Contains(actionType))
{
if(actionType==_specialcasesList[0]|| actionType == _specialcasesList[1])
_tags.Add(tagMatches[tagMatches.Count-1].Groups[_tagName].Value);//This only gets the last value acquired
//Since SSV and GSV only use tags in the last parameter
else if (actionType == _specialcasesList[2])//used an else if in case I want to add more instructions later
//This are the instructions of a JSR, this instructions uses a program name as the first parameter and after that it uses only tags
//so this ignores only the first values
{
for(var i = 1; i < tagMatches.Count; i++)
{
_tags.Add(tagMatches[i].Groups[_tagName].Value);
}
}
}
else
{
foreach (Match tag in tagMatches)
{
_tags.Add(tag.Groups[_tagName].Value);
}
}
}
}
//only for GM Alarms, probably will remove this from library and add it as an extention from other library specialized for GM programs
private void FindAlarms()
{
//This is an algorithm that checks the content of the RC and identifies the number of alamrs it has,
//gets them in an array with their Index number and adds them to a List of Alarms
var numberofAlarms = _comment.FindAllIndex(x => x.StartsWith(Alarm.AlarmInit)).ToArray();
foreach (var alarmIndex in numberofAlarms)
{
_alarmList.Add(new Alarm(_comment[alarmIndex]));
}
}
public IEnumerable<string> GetTags()
{
return _tags;
}
}
}