Ejemplo n.º 1
0
        public object visitFunctionStmt(Stmt.Function stmt)
        {
            LoxFunction function = new LoxFunction(function: stmt, closure: environment, false);

            environment.Define(function);
            return(null);
        }
Ejemplo n.º 2
0
 public LoxClass(string name, LoxClass superclass, Dictionary <string, LoxFunction> staticMethods, Dictionary <string, LoxFunction> methods)
 {
     this.name          = name;
     this.superclass    = superclass;
     this.staticMethods = staticMethods;
     this.methods       = methods;
     initializer        = FindMethod("init");
 }
Ejemplo n.º 3
0
        public object visitSuperExpr(Expr.Super expr)
        {
            var      exprLocationData = locals[expr];
            LoxClass superclass       = (LoxClass)environment.GetAt(exprLocationData.depth, exprLocationData.index);
            // We know "this" is one environment removed from "super" because of the way we set the environments up
            // in visitClassStmt. Hacky fix but it works. We also know its index is 0 because "this" is the only variable
            // in its environment.
            LoxInstance instance = (LoxInstance)environment.GetAt(exprLocationData.depth - 1, 0);
            LoxFunction method   = superclass.FindMethod(expr.method.lexeme);

            if (method == null)
            {
                throw new RuntimeError(expr.method, "Undefined superclass property '" + expr.method.lexeme + "'.");
            }
            return(method.Bind(instance));
        }
Ejemplo n.º 4
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.");
                }
            }

            int classIndex = environment.Define(null);

            if (stmt.superclass != null)
            {
                environment = new Environment(enclosing: environment);
                environment.Define(superclass);
            }

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

            foreach (Stmt.Function method in stmt.methods)
            {
                LoxFunction loxFunc = new LoxFunction(method, closure: environment, method.name.lexeme == "init");
                methods.Add(method.name.lexeme, loxFunc);
            }
            Dictionary <string, LoxFunction> staticMethods = new Dictionary <string, LoxFunction>();

            foreach (Stmt.Function method in stmt.staticMethods)
            {
                LoxFunction loxFunc = new LoxFunction(method, closure: environment, false);
                staticMethods.Add(method.name.lexeme, loxFunc);
            }
            LoxClass loxClass = new LoxClass(stmt.name.lexeme, (LoxClass)superclass, staticMethods, methods);

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

            environment.Assign(classIndex, loxClass);

            return(null);
        }
Ejemplo n.º 5
0
        public object Get(Token name)
        {
            // Fields shadow properties
            if (fields.TryGetValue(name.lexeme, out object value))
            {
                return(value);
            }

            // Property
            LoxFunction method = loxClass.FindMethod(name.lexeme);

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

            throw new RuntimeError(name, "Undefined property '" + name.data + "'.");
        }