Ejemplo n.º 1
0
        private static Expression ParseSExpression(SExpression sExpression)
        {
            var expressions = sExpression.Tokens.Select(ct => ParseExpression(ct)).ToArray();

            if (expressions.Any() && expressions.First() is SpecialFormToken)
            {
                return(ParseSpecialForm((expressions.First() as SpecialFormToken).Token, expressions.Skip(1).ToList(), sExpression));
            }
            return(new Application(expressions));
        }
Ejemplo n.º 2
0
 private static Expression ParseSpecialForm(string specialForm, List <Expression> expressions, SExpression sExpression)
 {
     if (specialForm == "if")
     {
         if (expressions.Count < 2)
         {
             throw new ParseException(sExpression.ToString(), "An \"if\" expression must contains at least 2 arguments");
         }
         if (expressions.Count > 3)
         {
             throw new ParseException(sExpression.ToString(), "An \"if\" expression must contains at most 3 arguments");
         }
         var falseBranch = expressions.Count == 3 ? expressions[2] : new PrimitiveWrapper <bool>()
         {
             Value = false
         };
         return(new If(expressions[0], expressions[1], falseBranch));
     }
     if (specialForm == "define")
     {
         if (expressions[0] is Variable)
         {
             if (expressions.Count != 2)
             {
                 throw new ParseException(sExpression.ToString(), "A variable type \"define\" expression must contains exactly 2 arguments");
             }
             return(new Define(expressions[0], expressions[1]));
         }
         if (expressions[0] is Application)
         {
             if (expressions.Count == 1)
             {
                 throw new ParseException(sExpression.ToString(), "A procedure type \"define\" expression must contains at least 2 arguments");
             }
             var name    = expressions[0];
             var defined = MakeBeginIfNeeded(expressions.Skip(1).ToList());
             return(new Define(name, defined));
         }
         throw new ParseException(sExpression.ToString(), "A \"define\" expression's first part must be either a string or a list");
     }
     if (specialForm == "lambda")
     {
         if (expressions.Count == 1)
         {
             throw new ParseException(sExpression.ToString(), "A \"lambda\" expression must contains at least 2 arguments");
         }
         var defined = MakeBeginIfNeeded(expressions.Skip(1).ToList());
         if (!(expressions[0] is Application))
         {
             throw new ParseException(sExpression.ToString(), "A \"lambda\" expression's first part must be a list");
         }
         var formalArgs = (expressions[0] as Application).Expressions;
         if (formalArgs.Any(e => !(e is Variable)))
         {
             throw new ParseException(sExpression.ToString(), "A \"lambda\" expression's first part must be a list of arguments");
         }
         return(new Lambda((expressions[0] as Application).Expressions.Cast <Variable>().ToArray(), defined));
     }
     if (specialForm == "let" || specialForm == "let*")
     {
         if (expressions.Count < 2)
         {
             throw new ParseException(sExpression.ToString(), string.Format("A \"{0}\" expression must contains at least 2 arguments", specialForm));
         }
         if (!(expressions[0] is Application))
         {
             throw new ParseException(sExpression.ToString(), string.Format("A \"{0}\" expression's first part must be a list", specialForm));
         }
         var tuples = new List <Tuple <Variable, Expression> >();
         foreach (var expression in (expressions[0] as Application).Expressions)
         {
             if (!(expression is Application && (expression as Application).Expressions.Length == 2))
             {
                 throw new ParseException(sExpression.ToString(), string.Format("A \"{0}\" definition must be a two-element list", specialForm));
             }
             var applcation = expression as Application;
             if (!(applcation.Expressions[0] is Variable))
             {
                 throw new ParseException(sExpression.ToString(), string.Format("A \"{0}\" definition must begin with a variable", specialForm));
             }
             tuples.Add(new Tuple <Variable, Expression>(applcation.Expressions[0] as Variable, applcation.Expressions[1]));
         }
         var body = MakeBeginIfNeeded(expressions.Skip(1).ToList());
         if (specialForm == "let")
         {
             return(new Let(tuples, body));
         }
         else if (specialForm == "let*")
         {
             return(new LetStar(tuples, body));
         }
     }
     if (specialForm == "begin")
     {
         return(new Begin(expressions));
     }
     if (specialForm == "cond")
     {
         var        last      = expressions.Last() as Application;
         Expression condition = last.Expressions[0];
         if (last.Expressions[0] is SpecialToken && (last.Expressions[0] as SpecialToken).Token == "else")
         {
             condition = new PrimitiveWrapper <bool>()
             {
                 Value = true
             }
         }
         ;
         var accIf = new If(condition, last.Expressions[1], Void.Instance);
         return(expressions.Cast <Application>().Reverse().Skip(1)
                .Aggregate(accIf, (acc, x) => new If(x.Expressions[0], x.Expressions[1], acc)));
     }
     if (specialForm == "delay")
     {
         var expr = expressions.Single();
         return(new Promise(expr));
     }
     throw new InternalException(string.Format("Illegal special form {0}", specialForm));
 }