Example #1
0
        public Void VisitFunctionStmt(Stmt.Function stmt)
        {
            ElizFunction function = new ElizFunction(stmt, environment, false);

            environment.Define(stmt.name.Lexeme, function);

            return(null);
        }
Example #2
0
        public object VisitBaseExpr(Expr.Base expr)
        {
            int distance = locals[expr];

            ElizClass superclass = (ElizClass)environment.GetAt(distance, "base");

            // "this" is always one level nearer than "super"'s environment.
            ElizInstance @object = (ElizInstance)environment.GetAt(distance - 1, "this");

            ElizFunction method = superclass.FindMethod(expr.method.Lexeme);

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

            return(method.Bind(@object));
        }
Example #3
0
        public Void VisitClassStmt(Stmt.Class stmt)
        {
            object baseclass = null;

            if (stmt.baseclass != null)
            {
                baseclass = Evaluate(stmt.baseclass);

                if (!(baseclass is ElizClass))
                {
                    throw new RuntimeError(stmt.baseclass.name, "Baseclass must be a class.");
                }
            }

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

            if (stmt.baseclass != null)
            {
                environment = new Environment(environment);
                environment.Define("base", baseclass);
            }

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

            foreach (Stmt.Function method in stmt.methods)
            {
                ElizFunction function = new ElizFunction(method, environment, method.name.Lexeme.Equals("init"));
                methods[method.name.Lexeme] = function;
            }

            ElizClass klass = new ElizClass(stmt.name.Lexeme, (ElizClass)baseclass, methods);

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

            environment.Assign(stmt.name, klass);
            return(null);
        }