Example #1
0
        public object visitSuperExpr(Expr.Super super)
        {
            int distance = -1;

            locals.TryGetValue(super, out distance);
            List <LoxClass> superClasses = (List <LoxClass>)environment.getAt(distance, "super");
            LoxInstance     _object      = (LoxInstance)environment.getAt(distance - 1, "this");
            LoxFunction     method       = null;
            LoxClass        foundInClass = null;

            foreach (LoxClass superClass in superClasses)
            {
                LoxFunction methodFind = superClass.findMethod(super.method.lexeme);
                if (methodFind != null)
                {
                    if (method != null)
                    {
                        throw new Exceptions.RuntimeError(super.method, "Error: Found '" + super.method.lexeme + "' in " + foundInClass.name + " and " + superClass.name + ".");
                    }
                    method       = methodFind;
                    foundInClass = superClass;
                }
            }
            if (method == null)
            {
                throw new Exceptions.RuntimeError(super.method, "Undefined property '" + super.method.lexeme + "'.");
            }
            return(method.bind(_object));
        }
        public object VisitFunctionStmt(Stmt.Function stmt)
        {
            LoxFunction function = new LoxFunction(stmt, environment, false);

            environment.Define(stmt.name.lexeme, function);
            return(null);
        }
Example #3
0
        private object EvaluateFunctionStatement(FunctionStatement expr)
        {
            LoxFunction function = new LoxFunction(expr, _environment, false);

            _environment.Define(expr.Name.Lexeme, function);
            return(null);
        }
Example #4
0
        public int arity()
        {
            LoxFunction initializer = findMethod("init");

            if (initializer == null)
            {
                return(0);
            }
            return(initializer.arity());
        }
Example #5
0
        public int arity()
        {
            LoxFunction initializer = methods.ContainsKey("init") ? methods["init"] : null;

            if (initializer == null)
            {
                return(0);
            }
            return(initializer.arity());
        }
Example #6
0
        public object call(Interpreter interpreter, List <object> arguments)
        {
            LoxInstance instance    = new LoxInstance(this);
            LoxFunction initializer = findMethod("init");

            if (initializer != null)
            {
                initializer.bind(instance).call(interpreter, arguments);
            }
            return(instance);
        }
Example #7
0
        public object call(Interpreter interpreter, List <object> arguments)
        {
            LoxInstance instance    = new LoxInstance(this);
            LoxFunction initializer = methods.ContainsKey("init") ? methods["init"] : null;

            if (initializer != null)
            {
                initializer.bind(instance).call(interpreter, arguments);
            }
            return(instance);
        }
        public object VisitSuperExpr(Expr.Super expr)
        {
            int distance = locals[expr];

            // Find reference to the superclass and current instance ("this").
            IClass      superclass   = (IClass)environment.GetAt(distance, "super");
            LoxInstance thisInstance = (LoxInstance)environment.GetAt(distance, "this");
            // Find method from superclass.
            LoxFunction method = superclass.FindMethod(thisInstance, expr.method.lexeme);

            return(method);
        }
Example #9
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
        }
Example #10
0
        public object Call(Evaluator evaluator, List <object> arguments)
        {
            LoxInstance instance    = new LoxInstance(this);
            LoxFunction initializer = FindMethod("init");

            if (initializer != null)
            {
                initializer.Bind(instance).Call(evaluator, arguments);
            }

            return(instance);
        }
Example #11
0
        private object EvaluateSuperExpression(SuperExpression expr)
        {
            int         distance   = _locals[expr];
            LoxClass    superclass = _environment.GetAt(distance, new Token(SyntaxKind.Super, "super", null, 0)) as LoxClass;
            LoxInstance obj        = _environment.GetAt(distance - 1, new Token(SyntaxKind.This, "this", null, 0)) as LoxInstance;

            LoxFunction method = superclass.FindMethod(expr.Method.Lexeme);

            if (method is null)
            {
                throw new RuntimeError(expr.Method, $"Undefine property {expr.Method.Lexeme}");
            }
            return(method.Bind(obj));
        }
Example #12
0
        public object get(Token name)
        {
            if (fields.ContainsKey(name.lexeme))
            {
                return(fields[name.lexeme]);
            }
            LoxFunction method = _class.findMethod(name.lexeme);

            if (method != null)
            {
                return(method.bind(this));
            }

            throw new Exceptions.RuntimeError(name, "Undefined property '" + name.lexeme + "'.");
        }
Example #13
0
        public object VisitSuperExpr(Super expr)
        {
            int      distance   = locals[expr];
            LoxClass superclass = (LoxClass)environment.GetAt(distance, "super");

            LoxInstance obj = (LoxInstance)environment.GetAt(distance - 1, "this");

            LoxFunction method = superclass.FindMethod(expr.Method.Lexeme);

            if (method == null)
            {
                throw new RuntimeError(expr.Method, "Undefined property '" + expr.Method.Lexeme + "'.");
            }

            return(method.Bind(obj));
        }
Example #14
0
        public object Get(Token name)
        {
            if (fields.ContainsKey(name.Lexeme))
            {
                return(fields[name.Lexeme]);
            }

            LoxFunction method = klass.FindMethod(name.Lexeme);

            if (method != null)
            {
                return(method.Bind(this));
            }

            throw new RuntimeError(name, "Undefined property '" + name.Lexeme + "'.");
        }
Example #15
0
        public object get(Token name)
        {
            if (fields.ContainsKey(name.lexeme))
            {
                return(fields[name.lexeme]);
            }

            LoxFunction method = klass.findMethod(this, name.lexeme);

            if (method != null)
            {
                return(method);
            }

            throw new RuntimeError(name, $"Undefined properrty '{name.lexeme}'.");
        }
Example #16
0
        public object visit_Super_Expr(GExpr.Super expr)
        {
            int      distance   = locals[expr];
            LoxClass superClass = (LoxClass)environment.getAt(distance, "super");
            // "this" is always 1 level nearer than "super's" environment

            LoxInstance obj = (LoxInstance)environment.getAt(distance - 1, "this");

            LoxFunction method = superClass.findMethod(obj, expr.method.lexeme);

            if (method == null)
            {
                throw new RuntimeError(expr.method, $"Undefined property '{expr.method.lexeme}'");
            }

            return(method);
        }
Example #17
0
        object Expr.IVisitor <object> .Visit(Expr.Super _super)
        {
            int      distance   = _locals[_super];
            LoxClass superclass = (LoxClass)_environment.GetAt(distance, "super");

            // "this" is always one level nearer than "super"'s environment.
            LoxInstance _object = (LoxInstance)_environment.GetAt(distance - 1, "this");

            LoxFunction method = superclass.FindMethod(_super.method.lexeme);

            if (method == null)
            {
                throw new RuntimeError(_super.method, "Undefined property '" + _super.method.lexeme + "'.");
            }

            return(method.Bind(_object));
        }
Example #18
0
        public Void VisitClassStmt(Stmt.Class stmt)
        {
            object superclass = null;

            if (stmt.Superclass != null)
            {
                superclass = Evaluate(stmt.Superclass);

                if (!(superclass is LoxClass))
                {
                    throw new RuntimeError(stmt.Superclass.Name, "Superclass must be a class");
                }
            }
            _environment.Define(stmt.Name.Lexeme, null);

            if (stmt.Superclass != null)
            {
                _environment = new LoxEnvironment(_environment);
                _environment.Define("super", superclass);
            }

            var methods = new Dictionary <string, LoxFunction>();

            foreach (var method in stmt.Methods)
            {
                var isInitializer = method.Name.Lexeme.Equals("init", StringComparison.Ordinal);
                var function      = new LoxFunction(method, _environment, isInitializer);
                methods[method.Name.Lexeme] = function;
            }

            var lclass = new LoxClass(stmt.Name.Lexeme, superclass as LoxClass, methods);

            if (superclass != null)
            {
                _environment = _environment.Enclosing;
            }

            _environment.Assign(stmt.Name, lclass);
            return(null);
        }
Example #19
0
        public object visit_Class_Stmt(GStmt.Class stmt)
        {
            Object superclass = null;

            if (stmt.superclass != null)
            {
                superclass = evaluate(stmt.superclass);
                if (!(superclass is LoxClass))
                {
                    throw new RuntimeError(stmt.superclass.name, "Superclass must be a class");
                }
            }

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

            if (stmt.superclass != null)
            {
                environment = new Environment(environment);
                environment.define("super", superclass);
            }

            Dictionary <string, LoxFunction> methods = new Dictionary <string, LoxFunction>();

            foreach (GStmt.Function method in stmt.methods)
            {
                LoxFunction function = new LoxFunction(method, environment, method.name.lexeme == "init");
                methods.Add(method.name.lexeme, function);
            }

            LoxClass klass = new LoxClass(stmt.name.lexeme, (LoxClass)superclass, methods);

            if (superclass != null)
            {
                environment = environment.enclosing;
            }

            environment.assign(stmt.name, klass);
            return(null);
        }
Example #20
0
        public object VisitClassStmt(Stmt.Class stmt)
        {
            object superclass = null;

            if (stmt.Superclass != null)
            {
                superclass = Evaluate(stmt.Superclass);
                if (!(superclass is LoxClass))
                {
                    throw new RuntimeError(stmt.Superclass.Name, "Superclass must be a class.");
                }
            }

            environment.Define(stmt.Name.Lexeme, null);

            if (stmt.Superclass != null)
            {
                environment = new Environment(environment);
                environment.Define("super", superclass);
            }

            Dictionary <string, LoxFunction> methods = new Dictionary <string, LoxFunction>();

            foreach (var method in stmt.Methods)
            {
                LoxFunction function = new LoxFunction(method, environment, method.Name.Lexeme.Equals("init"));
                methods[method.Name.Lexeme] = function;
            }

            LoxClass klass = new LoxClass(stmt.Name.Lexeme, (LoxClass)superclass, methods);

            if (superclass != null)
            {
                environment = environment.Enclosing;
            }

            environment.Assign(stmt.Name, klass);
            return(null);
        }
Example #21
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));
        }
Example #22
0
        private object EvaluateClassStatement(ClassStatement expr)
        {
            object superclass = null;

            if (expr.SuperClass != null)
            {
                superclass = Evaluate(expr.SuperClass);
                if (!(superclass is LoxClass))
                {
                    throw new RuntimeError(expr.SuperClass.Name, "Superclass must be a class");
                }
            }
            _environment.Define(expr.Name.Lexeme, null);

            if (expr.SuperClass != null)
            {
                _environment = new Environment(_environment);
                _environment.Define("super", superclass);
            }

            var methods = new Dictionary <string, LoxFunction>();

            foreach (var method in expr.Methods)
            {
                var function = new LoxFunction(method, _environment, method.Name.Lexeme.Equals("init"));
                methods.Add(method.Name.Lexeme, function);
            }
            LoxClass klass = new LoxClass(expr.Name.Lexeme, (LoxClass)superclass, methods);

            if (superclass != null)
            {
                _environment = _environment.Enclosing;
            }
            _environment.Assign(expr.Name, klass);
            return(null);
        }
Example #23
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);
        }
Example #24
0
        public object visitLambdaFunction(Expr.Lambda lambdaFunction)
        {
            LoxFunction function = new LoxFunction(lambdaFunction, environment, false);

            return(function); //If the function is lambda
        }