Ejemplo n.º 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());
        }
Ejemplo n.º 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)
                       ));
        }
Ejemplo n.º 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());
 }
Ejemplo n.º 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));
        }
Ejemplo n.º 5
0
 public LetBinding(IdOrKeywordToken variable, SymplExpr value) {
     _variable = variable;
     _value = value;
 }
Ejemplo n.º 6
0
 public SymplImportExpr(IdOrKeywordToken[] nsOrModule,
                         IdOrKeywordToken[] members,
                         IdOrKeywordToken[] asNames) {
     _nsOrModule = nsOrModule;
     _members = members;
     _asNames = asNames;
 }
Ejemplo n.º 7
0
 public SymplLambdaExpr(IdOrKeywordToken[] parms, SymplExpr[] body) {
     _params = parms;
     _body = body;
 }
Ejemplo n.º 8
0
 public SymplDefunExpr(string name, IdOrKeywordToken[] parms,
                        SymplExpr[] body) {
     _name = name;
     _params = parms;
     _body = body;
 }
Ejemplo n.º 9
0
 public SymplIdExpr(IdOrKeywordToken id) {
     _idToken = id;
 }
Ejemplo n.º 10
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)
            );
        }
Ejemplo n.º 11
0
 private static Expression AnalyzeLambdaDef
         (IdOrKeywordToken[] parms, SymplExpr[] body,
          AnalysisScope scope, string description) {
     var funscope = new AnalysisScope(scope, description);
     funscope.IsLambda = true;  // needed for return support.
     var paramsInOrder = new List<ParameterExpression>();
     foreach (var p in parms) {
         var pe = Expression.Parameter(typeof(object), p.Name);
         paramsInOrder.Add(pe);
         funscope.Names[p.Name.ToLower()] = pe;
     }
     // No need to add fun name to module scope since recursive call just looks
     // up global name late bound.  For lambdas,to get the effect of flet to
     // support recursion, bind a variable to nil and then set it to a lambda.
     // Then the lambda's body can refer to the let bound var in its def.
     var bodyexprs = new List<Expression>();
     foreach (var e in body) {
         bodyexprs.Add(AnalyzeExpr(e, funscope));
     }
     // Set up the Type arg array for the delegate type.  Must include
     // the return type as the last Type, which is object for Sympl defs.
     var funcTypeArgs = new List<Type>();
     for (int i = 0; i < parms.Length + 1; i++) {
         funcTypeArgs.Add(typeof(object));
     }
     return Expression.Lambda(
                Expression.GetFuncType(funcTypeArgs.ToArray()),
                Expression.Block(bodyexprs),
                paramsInOrder);
 }
Ejemplo n.º 12
0
 public SymplIdExpr(IdOrKeywordToken id)
 {
     _idToken = id;
 }
Ejemplo n.º 13
0
 public LetBinding(IdOrKeywordToken variable, SymplExpr value)
 {
     _variable = variable;
     _value    = value;
 }