Пример #1
0
        // Parses list of member names to import from the object represented in the
        // result of _parseImportNameOrModule, which will be a file module or object
        // from Sympl.Globals.  This is also used to parse the list of renames for
        // these same members.
        //
        private IdOrKeywordToken[] ParseImportNames(Lexer lexer, string nameKinds,
                                                    bool allowKeywords)
        {
            Token token = lexer.GetToken();
            List <IdOrKeywordToken> names = new List <IdOrKeywordToken>();

            if (token is IdOrKeywordToken)
            {
                IdOrKeywordToken idToken = (IdOrKeywordToken)token;
                if (!idToken.IsKeywordToken)
                {
                    names.Add(idToken);
                }
            }
            else if (token == SyntaxToken.Paren)
            {
                lexer.PutToken(token);
                object[] memberTokens = ParseList(lexer, "Import " + nameKinds + ".")
                                        .Elements;
                IdOrKeywordToken[] memberIdTokens =
                    EnsureListOfIds(memberTokens, allowKeywords,
                                    "Import " + nameKinds + " must be valid IDs.");
            }
            else if (token == SyntaxToken.CloseParen)
            {
                lexer.PutToken(token);
            }
            else
            {
                throw new SymplParseException(
                          "Import takes dotted names, then member vars.");
            }
            return(names.ToArray());
        }
Пример #2
0
        public static Expression AnalyzeBinaryExpr(SymplBinaryExpr expr,
                                                   AnalysisScope scope)
        {
            // The language has the following special logic to handle And and Or
            // x And y == if x then y
            // x Or y == if x then x else (if y then y)
            if (expr.Operation == ExpressionType.And)
            {
                return(AnalyzeIfExpr(
                           new SymplIfExpr(
                               expr.Left, expr.Right, null),
                           scope));
            }
            else if (expr.Operation == ExpressionType.Or)
            {
                // Use (LetStar (tmp expr) (if tmp tmp)) to represent (if expr expr)
                // to remore duplicate evaluation.
                // So x Or y is translated into
                // (Let* (tmp1 x)
                //    (If tmp1 tmp1
                //       (Let* (tmp2 y) (If tmp2 tmp2))))
                //

                IdOrKeywordToken tmp2 = new IdOrKeywordToken(
                    // Real implementation needs to ensure unique ID in scope chain.
                    "__tmpLetVariable2");
                var tmpExpr2 = new SymplIdExpr(tmp2);
                var binding2 = new LetBinding(tmp2, expr.Right);;
                var ifExpr2  = new SymplIfExpr(
                    tmpExpr2, tmpExpr2, null);
                var letExpr2 = new SymplLetStarExpr(
                    new[] { binding2 },
                    new[] { ifExpr2 });

                IdOrKeywordToken tmp1 = new IdOrKeywordToken(
                    // Real implementation needs to ensure unique ID in scope chain.
                    "__tmpLetVariable1");
                var        tmpExpr1 = new SymplIdExpr(tmp1);
                LetBinding binding1 = new LetBinding(tmp1, expr.Left);;
                SymplExpr  ifExpr1  = new SymplIfExpr(
                    tmpExpr1, tmpExpr1, letExpr2);
                return(AnalyzeLetStarExpr(
                           new SymplLetStarExpr(
                               new[] { binding1 },
                               new[] { ifExpr1 }
                               ),
                           scope
                           ));
            }

            return(Expression.Dynamic(
                       scope.GetRuntime().GetBinaryOperationBinder(expr.Operation),
                       typeof(object),
                       AnalyzeExpr(expr.Left, scope),
                       AnalyzeExpr(expr.Right, scope)
                       ));
        }
Пример #3
0
 private IdOrKeywordToken[] EnsureListOfIds(object[] list,
                                            bool allowKeywords,
                                            string error)
 {
     foreach (var t in list)
     {
         IdOrKeywordToken id = t as IdOrKeywordToken;
         if (id == null || (!allowKeywords && id.IsKeywordToken))
         {
             throw new SymplParseException(error);
         }
     }
     return(list.Select(t => (IdOrKeywordToken)t).ToArray());
 }
Пример #4
0
        private SymplExpr ParseDefun(Lexer lexer)
        {
            Token token = lexer.GetToken();

            if (token != KeywordToken.Defun)
            {
                throw new SymplParseException("Internal: parsing Defun?");
            }
            IdOrKeywordToken name = lexer.GetToken() as IdOrKeywordToken;

            if (name == null || name.IsKeywordToken)
            {
                throw new SymplParseException(
                          "Defun must have an ID for name -- " + name.ToString());
            }
            var parms = ParseParams(lexer, "Defun");
            var body  = ParseBody(lexer, "Hit EOF in function body" +
                                  name.Name);

            return(new SymplDefunExpr(name.Name, parms, body));
        }
Пример #5
0
 public SymplIdExpr(IdOrKeywordToken id)
 {
     _idToken = id;
 }
Пример #6
0
 public LetBinding(IdOrKeywordToken variable, SymplExpr value)
 {
     _variable = variable;
     _value    = value;
 }