/// <summary> /// Takes a sequence of quotes and an expression to quote and returns quoted expression. /// </summary> /// <param name="quoteList">A list of quotes.</param> /// <param name="expression">An expression to quote.</param> /// <returns>Quoted expression.</returns> private static IExpression QuoteExpression(List <IExpression> quoteList, IExpression expression) { AbstractQuotation quotedExpression = null; var quoteListCount = quoteList.Count; for (int i = 0; i < quoteListCount; ++i) { // We process them in an inside-out manner. var quote = quoteList[quoteListCount - i - 1]; // isQuoted is true here, since the expression could be a combination, and we want // any combination within that combination to be converted to lists when we quote // it. if (quote is ScmQuoteSpecialForm) { quotedExpression = new ScmQuoteSpecialForm(QuotationSyntacticSugar(expression, true)); } else if (quote is ScmUnquoteSpecialForm) { quotedExpression = new ScmUnquoteSpecialForm(QuotationSyntacticSugar(expression, true)); } else if (quote is ScmQuasiquoteSpecialForm) { quotedExpression = new ScmQuasiquoteSpecialForm(QuotationSyntacticSugar(expression, true)); } expression = quotedExpression; } return(quotedExpression); }
/// <summary> /// This methods analyses the given tokens and produces a list of combinations /// and expressions that can be parsed further for syntax consistency etc. /// </summary> /// <param name="tokens">A list of tokens.</param> /// <returns>A list of combinations and expressions.</returns> private static List <IExpression> CombineExpressions(List <Token> tokens) { CheckParanthesisBalance(tokens); var program = new List <IExpression> (); var eStack = new Stack <IExpression> (); ScmCombination currentCombination = null; for (int i = 0; i < tokens.Count; ++i) { var token = tokens[i]; if (token is BeginToken) { if (currentCombination != null) { eStack.Push(currentCombination); } currentCombination = new ScmCombination(token); } else if (token is EndToken) { IExpression cExpr = currentCombination as IExpression; currentCombination = cExpr as ScmCombination; if (eStack.Count > 0) { var stackExprOnTop = eStack.Peek() as ScmCombination; stackExprOnTop.Expressions.Add(currentCombination); currentCombination = eStack.Pop() as ScmCombination; } else { program.Add(currentCombination); currentCombination = null; } } else { if (token is SymbolToken) { IExpression scmSymbol = new ScmSymbol(token); AddExpression(scmSymbol, currentCombination, program); } else if (token is NumberToken) { IExpression scmNumber = NumberParser(token as NumberToken); AddExpression(scmNumber, currentCombination, program); } else if (token is StringToken) { IExpression scmString = new ScmString(token); AddExpression(scmString, currentCombination, program); } else if (token is DotToken) { IExpression scmString = new ScmDotModifier(token); AddExpression(scmString, currentCombination, program); } else if (token is QuoteToken || token is QuasiquoteToken || token is UnquoteToken) { IExpression scmQuote = null; if (token is QuoteToken) { scmQuote = new ScmQuoteSpecialForm(null); } else if (token is UnquoteToken) { scmQuote = new ScmUnquoteSpecialForm(null); } else { scmQuote = new ScmQuasiquoteSpecialForm(null); } AddExpression(scmQuote, currentCombination, program); } } } return(QuotationSyntacticSugar(program, false)); }