Пример #1
0
 public LoxFunction(Statement.function decl, Environment enclosure, bool isIn, bool isGetter)
 {
     declaration   = decl;
     closure       = enclosure;
     isInitializer = isIn;
     this.isGet    = isGetter;
 }
Пример #2
0
 public LoxFunction(Expr.Lambda decl, Environment enclosure, bool isIn)
 {
     declaration   = new Statement.function(decl.keyword, decl._params, decl.body);
     closure       = enclosure;
     isInitializer = isIn;
     isGet         = false;
 }
Пример #3
0
 public LoxFunction(Statement.function decl, Environment enclosure, bool isIn)
 {
     declaration   = decl;
     closure       = enclosure;
     isInitializer = isIn;
     isGet         = false;
 }
Пример #4
0
        public object visitFunction(Statement.function func)
        {
            declare(func.name);
            define(func.name);

            resolveFunction(func, FunctionType.FUNCTION);
            return(null);
        }
Пример #5
0
        public object visitFunction(Statement.function func)
        {
            LoxFunction function = new LoxFunction(func, environment, false);

            if (func.name != null) //If the function is named
            {
                environment.define(func.name.lexeme, function, func.name);
                return(null);
            }

            return(function); //If the function is lambda
        }
Пример #6
0
        private void resolveFunction(Statement.function function, FunctionType type)
        {
            FunctionType enclosingFunction = currentFunction;

            currentFunction = type;
            beginScope();
            foreach (Token _param in function._params)
            {
                declare(_param);
                define(_param);
            }
            resolve(function.body);
            endScope();
            currentFunction = enclosingFunction;
        }
Пример #7
0
 public string visitCallExpr(Expr.Call call)
 {
     Expr[] expressions = new Expr[call.expressionArguments.Count];
     for (int i = 0; i < call.expressionArguments.Count; i++)
     {
         if (call.expressionArguments[i] is Expr)
         {
             expressions[i] = (Expr)call.expressionArguments[i];
         }
         else if (call.expressionArguments[i] is Statement.function)
         {
             Statement.function lambda = (Statement.function)call.expressionArguments[i];
             expressions[i] = new Expr.Lambda(lambda.name, lambda._params, lambda.body);
         }
     }
     return(parenthesize(call.callee.ToString(), expressions));
 }
Пример #8
0
        public object visitCallExpr(Expr.Call call)
        {
            Object callee = evaluate(call.callee);

            List <Object> arguments = new List <Object>();

            foreach (Object argument in call.expressionArguments)
            {
                if (argument is Expr)
                {
                    arguments.Add(evaluate((Expr)argument));
                }
                else if (argument is Statement.function)
                {
                    arguments.Add((Statement.function)argument);
                }
            }

            if (!(callee is LoxCallable) && !(callee is Statement.function))
            {
                throw new Exceptions.RuntimeError(call.paren, "Can only call functions and classes.");
            }
            else if (callee is Statement.function)
            {
                Statement.function staticFunction      = (Statement.function)callee;
                LoxFunction        classStaticFunction = new LoxFunction(staticFunction, globals, false);
                return(classStaticFunction.call(this, arguments));
            }
            LoxCallable function = (LoxCallable)callee;

            if (arguments.Count != function.arity())
            {
                throw new Exceptions.RuntimeError(call.paren, "Expected " +
                                                  function.arity() + " arguments but got " +
                                                  arguments.Count + ".");
            }
            return(function.call(this, arguments));
        }
Пример #9
0
        public object visitClassStatement(Statement.Class classStatement)
        {
            List <LoxClass> superClasses = new List <LoxClass>();

            if (classStatement.superclass.Count != 0)
            {
                foreach (Object superClass in classStatement.superclass)
                {
                    Object eval = evaluate((Expr.Variable)superClass);
                    if (!(eval is LoxClass))
                    {
                        throw new Exceptions.RuntimeError(new HelperFunctions.GetToken().evaluate((Expr)superClass), "Superclass must be a class.");
                    }
                    else
                    {
                        superClasses.Add((LoxClass)eval);
                    }
                }
            }

            environment.define(classStatement.name.lexeme, null, classStatement.name);

            if (classStatement.superclass.Count != 0)
            {
                environment = new Environment(environment);
                environment.define("super", superClasses);
            }

            Dictionary <string, LoxFunction> methods     = new Dictionary <string, LoxFunction>();
            Dictionary <LoxFunction, Token>  getters     = new Dictionary <LoxFunction, Token>();
            List <Statement.function>        methodsList = classStatement.methods;

            foreach (Statement.function method in methodsList)
            {
                if (method._params.Count == 1 && method._params.ElementAt(0).type == TokenType.SEMICOLON && method._params.ElementAt(0).lexeme.Equals("getter"))
                {
                    Statement.function noParams = new Statement.function(method.name, new List <Token>(), method.body);
                    LoxFunction        getter   = new LoxFunction(noParams, environment, false, true);
                    methods.Add(method.name.lexeme, getter);
                    getters[getter] = method.name;
                }
                else
                {
                    LoxFunction function = new LoxFunction(method, environment, method.name.lexeme.Equals("init"));
                    if (!methods.ContainsKey(method.name.lexeme))
                    {
                        methods.Add(method.name.lexeme, function);
                    }
                    else
                    {
                        throw new Exceptions.RuntimeError(method.name, "Cannot have two functions with the same name in the same class.");
                    }
                }
            }
            LoxClass _class = new LoxClass(classStatement.name.lexeme, superClasses, methods);

            foreach (Statement.function staticFunction in classStatement.staticFunctions)
            {
                _class.set(staticFunction.name, staticFunction);
            }
            foreach (LoxFunction getter in getters.Keys)
            {
                _class.set(getters[getter], getter);
            }
            if (superClasses.Count != 0)
            {
                environment = environment.enclosing;
            }
            environment.assign(classStatement.name, _class);
            return(null);
        }