/// <summary> /// Instancia um novo objecto do tipo <see cref="LispStyleList{T}"/>. /// </summary> /// <param name="copy">A lista LISP a ser copiada.</param> public LispStyleList(LispStyleList <T> copy) { foreach (var item in copy.values) { this.values.Add(item.Clone()); } }
/// <summary> /// Tenta realizar a leitura do elemento. /// </summary> /// <param name="symbolListToParse">A lista de símbolos a ler.</param> /// <param name="value">O valor que conterá a leitura.</param> /// <returns>Verdadeiro caso a leitura seja bem-sucedida e falso caso contrário.</returns> public bool TryParse( ISymbol <string, string>[] symbolListToParse, out LispStyleList <Q> .ElementList <Q> value) { var error = new LogStatus <string, EParseErrorLevel>(); Q tempVal = this.parserForT.Parse(symbolListToParse, error); if (error.HasLogs(EParseErrorLevel.ERROR)) { value = null; return(false); } else { List <LispStyleList <Q> .ElementList <Q> > tempList = new List <LispStyleList <Q> .ElementList <Q> >(); tempList.Add(new LispStyleList <Q> .ElementList <Q>() { Element = tempVal, Elements = null }); value = new LispStyleList <Q> .ElementList <Q>() { Element = default(Q), Elements = tempList }; return(true); } }
/// <summary> /// Executa a função aquando da identificação de parêntesis. /// </summary> /// <param name="arg">O argumento.</param> /// <returns>A lista.</returns> private LispStyleList <R> .ElementList <R> Parenthesis(LispStyleList <R> .ElementList <R> arg) { LispStyleList <R> .ElementList <R> result = new LispStyleList <R> .ElementList <R>(); result.Elements = new List <LispStyleList <R> .ElementList <R> >(); result.Elements.Add(arg); return(result); }
/// <summary> /// Obtém ou atribui a lista LISP especificada pelo índice. /// </summary> /// <value> /// A lista. /// </value> /// <param name="index">O índice.</param> /// <returns></returns> /// <exception cref="ArgumentOutOfRangeException"> /// Se o índice não se encontrar nos limites da lista. /// </exception> public LispStyleList <T> this[int index] { get { if (index >= this.values.Count) { throw new ArgumentOutOfRangeException("index"); } LispStyleList <T> result = new LispStyleList <T>(); if (this.values[index].Elements == null) { result.values.Add(new ElementList <T>() { Element = this.values[index].Element, Elements = null }); } else { result.values.AddRange(this.values[index].Elements); } return(result); } set { if (index >= this.values.Count) { throw new ArgumentOutOfRangeException("index"); } if (value.values.Count == 0) { this.values.RemoveAt(index); } else if (value.values.Count == 1 && value.values[0].Elements == null) { this.values[index].Element = value.values[0].Element; this.values[index].Elements = null; } else { if (this.values[index].Elements == null) { this.values[index].Elements = new List <ElementList <T> >(); } List <ElementList <T> > temp = new List <ElementList <T> >(); foreach (var elem in value.values) { temp.Add(elem.Clone()); } this.values[index].Element = default(T); this.values[index].Elements.Clear(); this.values[index].Elements.AddRange(temp); } } }
/// <summary> /// Obtém o último elemento da lista. /// </summary> /// <returns>O último elemento da lista.</returns> public LispStyleList <T> Tail() { LispStyleList <T> result = new LispStyleList <T>(); if (this.values.Count > 0) { result.values.Add(this.values[this.values.Count - 1]); } return(result); }
/// <summary> /// Obtém o primeiro elemento da lista. /// </summary> /// <returns>O primeiro elemento da lista.</returns> public LispStyleList <T> Header() { LispStyleList <T> result = new LispStyleList <T>(); if (this.values.Count > 0) { result.values.Add(this.values[0]); } return(result); }
/// <summary> /// Concatena a lista especificada. /// </summary> /// <param name="toAppend">A lista a ser concatenada.</param> public void Concatenate(LispStyleList <T> toAppend) { List <ElementList <T> > temp = new List <ElementList <T> >(); foreach (var app in toAppend.values) { ElementList <T> element = app.Clone(); temp.Add(element); } this.values.AddRange(temp); }
/// <summary> /// Concatena duas listas. /// </summary> /// <param name="left">A primeira lisa a ser concatenada.</param> /// <param name="right">A segunda lista a ser concatenada.</param> /// <returns>O resultado da concatenação.</returns> private LispStyleList <R> .ElementList <R> Concatenate( LispStyleList <R> .ElementList <R> left, LispStyleList <R> .ElementList <R> right) { LispStyleList <R> .ElementList <R> result = left.Clone(); if (result.Elements != null) { if (right.Elements != null) { foreach (var item in right.Elements) { result.Elements.Add(item.Clone()); } } else { result.Elements.Add(new LispStyleList <R> .ElementList <R>() { Element = right.Element }); } } else { result.Elements = new List <LispStyleList <R> .ElementList <R> >(); result.Elements.Add(new LispStyleList <R> .ElementList <R>() { Element = left.Element }); if (right.Elements != null) { foreach (var item in right.Elements) { result.Elements.Add(item.Clone()); } } else { result.Elements.Add(new LispStyleList <R> .ElementList <R>() { Element = right.Element }); } } return(result); }
/// <summary> /// Injecta um valor no final da lista. /// </summary> /// <param name="val">O valor a ser injectado.</param> public void Push(LispStyleList <T> val) { if (val.values.Count == 1) { this.values.Add(new ElementList <T>() { Element = val.values[0].Element, Elements = null }); } else if (val.values.Count > 1) { this.values.Add(new ElementList <T>() { Element = default(T), Elements = val.values }); } }
/// <summary> /// Tenta realizar a leitura. /// </summary> /// <param name="strToParse">O texto a ler.</param> /// <param name="value">O valor para onde a lista será lida.</param> /// <returns>Verdadeiro se a leitura for bem-sucedida e falso caso contrário.</returns> /// <exception cref="FormatException"> /// Se o texto contiver erros. /// </exception> /// <exception cref="CollectionsException">Em caso de erro interno.</exception> public bool TryParse(ISymbol <string, string>[] strToParse, out LispStyleList <R> value) { var strValue = strToParse[0]; string clean = strValue.SymbolValue.Trim(); if (clean.Equals(string.Empty)) { throw new FormatException("Can't construct a lisp style list from empty strings."); } if (this.delimiters == LispDelimiterType.PARENTHESIS) { if (clean[0] != '(' || clean[clean.Length - 1] != ')') { throw new FormatException("A lisp style list must begin with '(' and finish with ')'"); } } else if (this.delimiters == LispDelimiterType.BAR_GREATER) { if (clean[0] != '|' || clean[clean.Length - 1] != '>') { throw new FormatException("A lisp style list must begin with '|' and finish with '>'"); } } else if (this.delimiters == LispDelimiterType.BRACES) { if (clean[0] != '{' || clean[clean.Length - 1] != '}') { throw new FormatException("A lisp style list must begin with '{' and finish with '}'"); } } else if (this.delimiters == LispDelimiterType.BRACKETS) { if (clean[0] != '[' || clean[clean.Length - 1] != ']') { throw new FormatException("A lisp style list must begin with '[' and finish with ']'"); } } else if (this.delimiters == LispDelimiterType.LESSER_GREATER) { if (clean[0] != '<' || clean[clean.Length - 1] != '>') { throw new FormatException("A lisp style list must begin with '<' and finish with '>'"); } } else { throw new CollectionsException("An internal error has occured."); } LispStyleList <R> .ElementList <R> elementList = this.expressionReader.Parse( new StringSymbolReader(new StringReader(clean), false)); LispStyleList <R> result = new LispStyleList <R>(); if (elementList.Elements != null) { result.values.AddRange(elementList.Elements); } else { result.values.Add(elementList); } value = result; return(true); }