// reads a STON address path segment private IStonPathSegment ReadPathSegment(StonTokenReader reader) { int pathOpen = reader.ExpectAndSkip(StonChartype.PathSegmentBegin); if (pathOpen == '.') { // ancestor access segment if (reader.TryAndSkip(StonChartype.AncestorAccess)) { int ancestorOrder = 1; while (reader.TryAndSkip(StonChartype.AncestorAccess)) { ++ancestorOrder; } return(ElementFactory.CreateAncestorPathSegment(ancestorOrder)); } // named member access segment else { return(ElementFactory.CreateMemberPathSegment(ReadBindingName(reader))); } } else { // collection element access segment if (reader.TryAndSkip(StonChartype.PathSegmentCollection)) { int currentPosition = reader.Position; int currentLine = reader.Line; int currentColumn = reader.Column; if (reader.Peek().HasChartype(StonChartype.Sign)) { if (reader.Peek() == '-') { throw new StonParsingException(currentPosition, currentLine, currentColumn, "Collection element index cannot be negative."); } reader.ReadAndSkip(); if (!reader.Peek().HasChartype(StonChartype.Digit)) { throw reader.MakeUnexpectedCharacterException(StonChartype.Digit); } } IStonEntity elementIndex; // number or binary integer index if (reader.Peek().HasChartype(StonChartype.ZeroDigit)) { reader.ReadAndSkip(); if (reader.Peek().HasChartype(StonChartype.BaseIdentifier)) { elementIndex = ElementFactory.CreateSimpleEntity(ElementFactory.CreateSimpleValue(StonDataType.Binary, reader.ReadBinaryContent(false))); } else { elementIndex = ElementFactory.CreateSimpleEntity(ElementFactory.CreateSimpleValue(StonDataType.Number, reader.ReadNumberContent(false))); } } // number integer index else if (reader.Peek().HasChartype(StonChartype.NonZeroDigit)) { elementIndex = ElementFactory.CreateSimpleEntity(ElementFactory.CreateSimpleValue(StonDataType.Number, reader.ReadNumberContent(false))); } // resolved reference index else if (reader.Peek().HasChartype(StonChartype.AddressBegin)) { elementIndex = ElementFactory.CreateReferenceEntity(ReadAddress(reader)); } else { throw reader.MakeUnexpectedCharacterException(StonChartype.Digit | StonChartype.AddressBegin | StonChartype.Sign); } reader.ExpectAndSkip(StonChartype.IndexClose); return(ElementFactory.CreateCollectionElementPathSegment(elementIndex)); } // index member access segment else { IEnumerable <IStonEntity> indexParameters = ReadSequence(reader, ReadAddressEntity, StonChartype.IndexClose); return(ElementFactory.CreateMemberPathSegment(ElementFactory.CreateBindingIndex(indexParameters))); } } }