public object GetValue(string variableName) { switch (ContainerType) { case VariableContainerType.InstanceSave: #if DEBUG if (ElementStack.Count != 0) { if (ElementStack.Last().Element == null) { throw new InvalidOperationException("The ElementStack contains an ElementWithState with no Element"); } } #endif VariableSave variable = GetVariable(variableName); if (variable != null) { return(variable.Value); } else { return(null); } //return mInstanceSave.GetValueFromThisOrBase(mElementStack, variableName); //break; case VariableContainerType.StateSave: return(mStateSave.GetValueRecursive(variableName)); //break; } throw new NotImplementedException(); }
public void Should_add_objects_to_the_ObjectStack(int initialValue, int addToStack) { var stack = new ElementStack(CommonElements.Hydrogen, initialValue); stack.IncreaseStackSize(addToStack); Assert.Equal(stack.Count, initialValue + addToStack); }
/// <summary> /// Process comments up until nextElement. /// Group comments into blocks, and associate blocks with elements. /// </summary> /// /// <param name="commentEnumerator">Enumerator for all comments in the program.</param> /// <param name="nextElement">The next element in the list.</param> /// <param name="elementStack">A stack of nested program elements.</param> /// <param name="cb">Where to send the results.</param> /// <returns>true if there are more comments to process, false otherwise.</returns> bool GenerateBindings( IEnumerator <KeyValuePair <Location, ICommentLine> > commentEnumerator, KeyValuePair <Location, Label>?nextElement, ElementStack elementStack, CommentBindingCallback cb ) { CommentBlock block = new CommentBlock(); // Iterate comments until the commentEnumerator has gone past nextElement while (nextElement == null || Compare(commentEnumerator.Current.Value.Location, nextElement.Value.Key) < 0) { if (!block.CombinesWith(commentEnumerator.Current.Value)) { // Start of a new block, so generate the bindings for the old block first. GenerateBindings(block, elementStack, nextElement, cb); block = new CommentBlock(); } block.AddCommentLine(commentEnumerator.Current.Value); // Get the next comment. if (!commentEnumerator.MoveNext()) { // If there are no more comments, generate the remaining bindings and return false. GenerateBindings(block, elementStack, nextElement, cb); return(false); } } GenerateBindings(block, elementStack, nextElement, cb); return(true); }
public void Should_calculate_electrons_neutrons_protons_for_ElementStack() { foreach (var element in Container.Elements) { var randomElementNumberOnStack = new Random().Next(); var stack = new ElementStack(element, randomElementNumberOnStack); Assert.Equal(stack.GetTotalElectronsCount(), element.Structure.ElectronsCount * randomElementNumberOnStack); Assert.Equal(stack.GetTotalNeutronsCount(), element.Structure.NeutronsCount * randomElementNumberOnStack); Assert.Equal(stack.GetTotalProtonsCount(), element.Structure.ProtonsCount * randomElementNumberOnStack); Assert.Equal(stack.GetAtoms().Count(), 1); } }
public VariableListSave GetVariableList(string variableName) { switch (ContainerType) { case VariableContainerType.InstanceSave: return(mInstanceSave.GetVariableListFromThisOrBase(ElementStack.Last().Element, variableName)); case VariableContainerType.StateSave: return(mStateSave.GetVariableListRecursive(variableName)); //break; } throw new NotImplementedException(); }
public VariableSave GetVariable(string variableName) { switch (ContainerType) { case VariableContainerType.InstanceSave: string instanceName = null; if (ElementStack.Count != 0) { instanceName = ElementStack.Last().InstanceName; } bool onlyIfSetsValue = false; #if DEBUG if (ElementStack.Count != 0) { if (ElementStack.Last().Element == null) { throw new InvalidOperationException("The ElementStack contains an ElementWithState with no Element"); } } #endif var found = mInstanceSave.GetVariableFromThisOrBase(ElementStack, this, variableName, false, onlyIfSetsValue); if (found != null && !string.IsNullOrEmpty(found.ExposedAsName)) { var allExposed = GetExposedVariablesForThisInstance(mInstanceSave, instanceName, ElementStack, variableName); var exposed = allExposed.FirstOrDefault(); if (exposed != null && exposed.Value != null) { found = exposed; } } if (found == null || found.SetsValue == false || found.Value == null) { onlyIfSetsValue = true; found = mInstanceSave.GetVariableFromThisOrBase(ElementStack, this, variableName, false, true); } return(found); case VariableContainerType.StateSave: return(mStateSave.GetVariableRecursive(variableName)); //break; } throw new NotImplementedException(); }
private static void AddStackToRoot(CompoundStack root, ElementStack stack) { foreach (var node in root) { if (!(node is ElementStack elementStack) || elementStack.Element != stack.Element) { continue; } elementStack.IncreaseStackSize(); return; } root.Nodes.Add(stack); }
// Generate binding information for one CommentBlock. private void GenerateBindings( ICommentBlock block, ElementStack elementStack, KeyValuePair <Location, Label>?nextElement, CommentBindingCallback cb ) { if (block.CommentLines.Any()) { GenerateBindings( block, elementStack.FindBefore(block.Location), elementStack.FindAfter(block.Location, nextElement), elementStack.FindParent(block.Location), cb); } }
protected override void StoreElement(Element element) { var stack = m_stacks.FirstOrDefault(s => s.Elements.FirstOrDefault() == element); if (stack == null) { stack = m_stacks.FirstOrDefault(s => !s.Elements.Any()); } if (stack == null) { stack = new ElementStack { ID = m_stacks.Count() }; m_stacks.Add(stack); } stack.Elements.Push(element); stack.MaxCount = Math.Max(stack.MaxCount, stack.Elements.Count); CommandSequence.Add(CommandType.Consume, element, this, stack.ID); }
/// <summary> /// Merge comments into blocks and associate comment blocks with program elements. /// </summary> /// <param name="cb">Callback for the binding information</param> public void GenerateBindings(CommentBindingCallback cb) { /* Algorithm: * Do a merge of elements and comments, which are both sorted in location order. * * Iterate through all elements, and iterate all comment lines between adjacent pairs of elements. * Maintain a stack of elements, such that the top of the stack must be fully nested in the * element below it. This enables comments to be associated with the "parent" element, as well as * elements before, after and "best" element match for a comment. * * This is an O(n) algorithm because the list of elements and comments are traversed once. * (Note that comment processing is O(n.log n) overall due to dictionary of elements and comments.) */ ElementStack elementStack = new ElementStack(); using (IEnumerator <KeyValuePair <Location, Label> > elementEnumerator = elements.GetEnumerator()) using (IEnumerator <KeyValuePair <Location, ICommentLine> > commentEnumerator = comments.GetEnumerator()) { if (!commentEnumerator.MoveNext()) { // There are no comments to process. return; } while (elementEnumerator.MoveNext()) { if (!GenerateBindings(commentEnumerator, elementEnumerator.Current, elementStack, cb)) { // No more comments to process. return; } elementStack.Push(elementEnumerator.Current); } // Generate remaining comments at end of file GenerateBindings(commentEnumerator, null, elementStack, cb); } }
public T GetValue <T>(string variableName) { #if DEBUG if (ElementStack.Count != 0) { if (ElementStack.Last().Element == null) { throw new InvalidOperationException("The ElementStack contains an ElementWithState with no Element"); } } #endif object valueAsObject = GetValue(variableName); if (valueAsObject is T) { return((T)valueAsObject); } else { return(default(T)); } }
protected override void ReadTree(string input, CompoundStack root, ref int currentIndex) { if (currentIndex >= input.Length) { return; } var currentChar = input[currentIndex]; currentIndex++; var nextChar = currentIndex < input.Length ? input[currentIndex] : char.Parse("@"); if (char.IsUpper(currentChar)) { if (char.IsLower(nextChar)) { ReadTree(input, root, ref currentIndex); return; } var numberOfAtoms = 1; if (nextChar == ')' && currentIndex + 1 < input.Length) { if (char.IsNumber(input[currentIndex + 1])) // We can have a number after closing bracket ') { currentIndex++; } else if (char.IsNumber(input[currentIndex + 2])) // We can have a number after line '|' which is after the closing bracket ') { currentIndex += 2; } numberOfAtoms = GetFullNumber(input, ref currentIndex); } var stack = new ElementStack(currentChar.ToString().ToElement(), numberOfAtoms); AddStackToRoot(root, stack); ReadTree(input, root, ref currentIndex); } else if (char.IsLower(currentChar)) { var numberOfAtoms = 1; var toMoveBack = 1; if ((nextChar == ')' || nextChar == '|') && currentIndex + 1 < input.Length) { if (char.IsNumber(input[currentIndex + 1])) // We can have a number after closing bracket ') { currentIndex++; toMoveBack = 3; } else if (char.IsNumber(input[currentIndex + 2])) // We can have a number after line '|' which is after the closing bracket ') { currentIndex += 2; toMoveBack = 4; } numberOfAtoms = GetFullNumber(input, ref currentIndex); } var previousChar = input[currentIndex - numberOfAtoms.ToString().Length - toMoveBack]; var stack = new ElementStack($"{ previousChar }{ currentChar }".ToElement(), numberOfAtoms); AddStackToRoot(root, stack); ReadTree(input, root, ref currentIndex); } else if (currentChar.Equals('(')) { var stack = new CompoundStack(); root.Nodes.Add(stack); InnerStacks.Push(stack); ReadTree(input, stack, ref currentIndex); ReadTree(input, InnerStacks.Peek(), ref currentIndex); } else if (currentChar.Equals(')')) { var numberOfAtoms = 1; if (char.IsNumber(nextChar)) { numberOfAtoms = GetFullNumber(input, ref currentIndex); } root.IncreaseStackSize(numberOfAtoms); InnerStacks.Pop(); } else if (currentChar == '-' || currentChar == '=') { // Possible format's of chars next to the '-' or '=' // Where: C - upper char; r - lower char; 0 - number; // C - ( // ) - C // C - C // ) - ( // 0 - ( // 0 - C // r - ( // For now on it will skip parsing the connections - not supported yet // There is no support (yet) of how to store the number of connections between atoms // This is something that will need to be added later on // TODO: Add support for storing the information about number of connections between atoms if (char.IsNumber(nextChar)) { while (input[currentIndex] != '|') { currentIndex++; } } ReadTree(input, root, ref currentIndex); } else if (currentChar == '|') { // Possible format's of chars next to the '|' // Where: C - upper char; r - lower char; 0 - number; // C | 0 // r | 0 // 0 | C // 0 | ( // For now on it will skip parsing the number of connections - not supported yet // There is no support (yet) of how to store the number of connections between atoms // This is something that will need to be added later on // TODO: Add support for storing the information about number of connections between atoms if (char.IsNumber(nextChar)) { while (input[currentIndex] != '|') { currentIndex++; } } ReadTree(input, root, ref currentIndex); } else { throw new FormatException($"Unknown char: '{ currentChar }', at position: { currentIndex }"); } }
private static void ParseFile(string filename) { SaveFile fileItem; fileItem = new SaveFile() { FileName = filename, FileTime = long.TryParse(filename.Split("_")[0], out long timeInTick) ? new DateTime(timeInTick) : DateTime.Now, Processed = (int)SaveFileProcessedEnum.NotProcessed }; string jsonex = File.ReadAllText(filename).Replace(" NULL", " \"NULL\""); dynamic jsonFile = JObject.Parse(jsonex); var elementStacks = jsonFile["elementStacks"]; foreach (JProperty property in elementStacks.Properties()) { ElementStack element = new ElementStack { ElementStackIdentification = property.Name, SaveFile = fileItem }; fileItem.ElementStacks.Add(element); //var elementStackItems = JObject.Parse(property.Values); foreach (JProperty subprop in property.Values()) { ElementStackItem item = new ElementStackItem { Value = subprop.Value.ToString(), Key = subprop.Name, ElementStack = element }; element.ElementStackItems.Add(item); } } var decks = jsonFile["decks"]; foreach (JProperty property in decks.Properties()) { Deck deck = new Deck() { Name = property.Name, SaveFile = fileItem }; fileItem.Decks.Add(deck); //How to identify eliminated cards? foreach (JProperty subprop in property.Values()) { if (subprop.Name == "eliminatedCards") { //Aqui eu tenho uma sub parte foreach (JToken subsubprop in subprop.Values()) { DeckItem decksubItem = new DeckItem() { Eliminated = true, Value = subsubprop.Value <string>(), Key = "0", Deck = deck }; deck.DeckItems.Add(decksubItem); } continue; } DeckItem deckItem = new DeckItem() { Eliminated = false, Key = subprop.Name, Value = subprop.Value.ToString(), Deck = deck }; deck.DeckItems.Add(deckItem); } } var metainfo = jsonFile["metainfo"]; MetaInfo meta = new MetaInfo(); foreach (JProperty property in metainfo.Properties()) { if (property.Name.ToUpper() == "BirdWormSlider".ToUpper()) { meta.BirdWormSlider = int.Parse(property.Value.ToString()); } if (property.Name.ToUpper() == "VERSIONNUMBER".ToUpper()) { meta.Version = property.Value.ToString(); } if (property.Name.ToUpper() == "WeAwaitSTE".ToUpper()) { meta.WeAwaitSTE = property.Value.ToString(); } } fileItem.MetaInfo = meta; var characterDetails = jsonFile["characterDetails"]; CharacterDetail characterDetail = new CharacterDetail() { SaveFile = fileItem, Levers = new List <Lever>() }; fileItem.CharacterDetail = characterDetail; foreach (JProperty property in characterDetails.Properties()) { if (property.Name.ToUpper() == "activeLegacy".ToUpper()) { characterDetail.ActiveLegacy = property.Value.HasValues ? property.Value.ToString() : string.Empty; continue; } if (property.Name.ToUpper() == "name".ToUpper()) { characterDetail.Name = property.Value.ToString(); continue; } if (property.Name.ToUpper() == "profession".ToUpper()) { characterDetail.Profession = property.Value.ToString(); continue; } LeverPartEnum leverPart = LeverPartEnum.Error; if (property.Name.ToUpper() == "pastLevers".ToUpper()) { leverPart = LeverPartEnum.PastLevers; } if (property.Name.ToUpper() == "futureLevers".ToUpper()) { leverPart = LeverPartEnum.FutureLevers; } if (property.Name.ToUpper() == "executions".ToUpper()) { leverPart = LeverPartEnum.Executions; } foreach (JProperty subprop in property.Values()) { Lever lever = new Lever() { CharacterDetail = characterDetail, Part = (int)leverPart, Key = subprop.Name, Value = subprop.Value.ToString() }; characterDetail.Levers.Add(lever); } } var situations = jsonFile["situations"]; foreach (JProperty property in situations.Properties()) { Situation situation = new Situation() { SaveFile = fileItem, SituationIdentification = property.Name }; fileItem.Situations.Add(situation); foreach (JProperty sitItem in property.Values()) { //ongoingSlotElements if (sitItem.Name.ToUpper() == "ongoingSlotElements".ToUpper()) { foreach (JProperty subprop in sitItem.Values()) { OngoingSlotElement ongoingSlotElement = new OngoingSlotElement() { Situation = situation, OngoingSlotElementIdentification = subprop.Name }; situation.OngoingSlotElements.Add(ongoingSlotElement); foreach (JProperty subpropitem in subprop.Values()) { OngoingSlotElementItem ongoingSlotElementItem = new OngoingSlotElementItem() { OngoingSlotElement = ongoingSlotElement, Key = subpropitem.Name, Value = subpropitem.Value.ToString(), }; ongoingSlotElement.OngoingSlotElementItems.Add(ongoingSlotElementItem); } } continue; } //situationOutputNotes if (sitItem.Name.ToUpper() == "situationOutputNotes".ToUpper()) { foreach (JProperty subprop in sitItem.Values()) { string indexValue = subprop.Name; foreach (JProperty subpropitem in subprop.Values()) { SituationOutputNote situationOutputNote = new SituationOutputNote() { Situation = situation, Index = indexValue, Key = subpropitem.Name, Value = subpropitem.Value.ToString(), }; situation.SituationOutputNotes.Add(situationOutputNote); } } continue; } //situationStoredElements if (sitItem.Name.ToUpper() == "situationStoredElements".ToUpper()) { foreach (JProperty subprop in sitItem.Values()) { SituationStoredElement situationStoredElement = new SituationStoredElement() { Situation = situation, SituationStoredElementIdentification = subprop.Name }; situation.SituationStoredElements.Add(situationStoredElement); foreach (JProperty subpropitem in subprop.Values()) { SituationStoredElementItem situationStoredElementItem = new SituationStoredElementItem() { SituationStoredElement = situationStoredElement, Key = subpropitem.Name, Value = subpropitem.Value.ToString(), }; situationStoredElement.SituationStoredElementItems.Add(situationStoredElementItem); } } continue; } SituationItem situationItem = new SituationItem() { Key = sitItem.Name, Value = sitItem.Value.ToString(), Situation = situation }; situation.SituationItems.Add(situationItem); } } //Verify some properties: VerifyFile(fileItem); }
protected override void ReadTree(string input, CompoundStack root, ref int currentIndex) { if (currentIndex >= input.Length) { return; } var currentChar = input[currentIndex]; currentIndex++; var nextChar = currentIndex < input.Length ? input[currentIndex] : char.Parse("@"); if (char.IsUpper(currentChar)) { if (char.IsLower(nextChar)) { ReadTree(input, root, ref currentIndex); return; } var numberOfAtoms = 1; if (char.IsNumber(nextChar)) { numberOfAtoms = GetFullNumber(input, ref currentIndex); } var stack = new ElementStack(currentChar.ToString().ToElement(), numberOfAtoms); root.Nodes.Add(stack); ReadTree(input, root, ref currentIndex); } else if (currentChar.Equals('(')) { var stack = new CompoundStack(); root.Nodes.Add(stack); InnerStacks.Push(stack); ReadTree(input, stack, ref currentIndex); ReadTree(input, InnerStacks.Peek(), ref currentIndex); } else if (currentChar.Equals(')')) { var numberOfAtoms = 1; if (char.IsNumber(nextChar)) { numberOfAtoms = GetFullNumber(input, ref currentIndex); } root.IncreaseStackSize(numberOfAtoms); InnerStacks.Pop(); } else if (char.IsLower(currentChar)) { var numberOfAtoms = 1; if (char.IsNumber(nextChar)) { numberOfAtoms = GetFullNumber(input, ref currentIndex); } var previousChar = GetPreviousUpperChar(input, currentIndex, numberOfAtoms); var stack = new ElementStack($"{ previousChar }{ currentChar }".ToElement(), numberOfAtoms); root.Nodes.Add(stack); ReadTree(input, root, ref currentIndex); } else if (char.IsNumber(currentChar) && currentIndex < 2) // Only for the number before the compound { currentIndex = 0; var numberOfMoles = GetFullNumber(input, ref currentIndex); if (input[currentIndex] == '(') { currentIndex++; numberOfMoles--; } root.Count = numberOfMoles; ReadTree(input, root, ref currentIndex); } else { throw new FormatException($"Unknown char: '{ currentChar }', at position: { currentIndex }"); } }