Beispiel #1
0
        public Void VisitClassStmt(Stmt.Class stmt)
        {
            ClassType enclosingClass = currentClass;

            currentClass = ClassType.CLASS;

            Declare(stmt.name);
            Define(stmt.name);

            if (stmt.baseclass != null && stmt.name.Lexeme.Equals(stmt.baseclass.name.Lexeme))
            {
                ElizScriptCompiler.Error(stmt.baseclass.name, "A class cannot inherit from itself.");
            }

            if (stmt.baseclass != null)
            {
                currentClass = ClassType.SUBCLASS;
                Resolve(stmt.baseclass);
            }

            if (stmt.baseclass != null)
            {
                BeginScope();
                scopes.Last()["base"] = true;
            }

            BeginScope();
            scopes.Last()["this"] = true;

            foreach (Stmt.Function method in stmt.methods)
            {
                FunctionType declaration = FunctionType.METHOD;

                if (method.name.Lexeme.Equals("init"))
                {
                    declaration = FunctionType.INITIALIZER;
                }

                ResolveFunction(method, declaration);
            }

            EndScope();

            if (stmt.baseclass != null)
            {
                EndScope();
            }

            currentClass = enclosingClass;
            return(null);
        }
Beispiel #2
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);
        }