예제 #1
0
        public Unit VisitClassStmt(Stmt.Class stmt)
        {
            ClassType enclosingClass = this.CurrentClass;

            CurrentClass = ClassType.CLASS;
            Declare(stmt.Name);
            Define(stmt.Name);

            BeginScope();
            Scopes.Peek().Add("this", true);

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

                if (method.Name.Lexeme.Equals("init"))
                {
                    declaration = FunctionType.INITIALISER;
                }
                ResolveFunction(method, declaration);
            }

            EndScope();
            this.CurrentClass = enclosingClass;
            return(new Unit());
        }
예제 #2
0
        public static TrashObject ClassStmt(this Interpreter interpreter, Stmt.Class stmt)
        {
            var cls = new Class(stmt.Name);

            foreach (var def in stmt.Body.Statements)
            {
                if (def.Body is null)
                {
                    if (def.Initialiser is null)
                    {
                        cls.Add(def.Name, null);
                    }
                    else
                    {
                        cls.Add(def.Name, interpreter.Evaluate(def.Initialiser));
                    }
                }
                else
                {
                    cls.Add(def.Name, new TrashObject(new Stmt.Macro(def.Name, def.Body, def.Arguments)));
                }
            }

            interpreter.IntEnvironment.Define(stmt.Name, cls);
            return(null);
        }
예제 #3
0
        public LoxVoid VisitClassStmt(Stmt.Class stmt)
        {
            ClassType enclosingClass = _currentClass;

            _currentClass = ClassType.Class;

            Declare(stmt.Name);
            stmt.Superclass.MatchSome(superclass => Resolve(superclass));

            Define(stmt.Name);

            stmt.Superclass.MatchSome(super =>
            {
                _currentClass = ClassType.SubClass;
                BeginScope();
                _scopes.Peek()["Super"] = new Variable(super.Name, VariableState.Defined);
            });

            BeginScope();
            _scopes.Peek()["this"] = new Variable(_thisPlaceHolder, VariableState.Defined);

            foreach (Stmt.Function method in stmt.Methods)
            {
                var declaration = method.Name.Lexeme == "init"
                    ? FunctionType.Initializer
                    : FunctionType.Method;
                ResolveFunction(method.Parameter, method.Body, declaration);
            }

            stmt.Superclass.MatchSome(super => EndScope());

            EndScope();
            _currentClass = enclosingClass;
            return(null);
        }
예제 #4
0
    public object VisitClassStmt(Stmt.Class stmt)
    {
        ClassType enclosingClass = CurrentClass;

        CurrentClass = ClassType.Class;

        Declare(stmt.Name);
        Define(stmt.Name);

        if (stmt.Superclass != null &&
            stmt.Name.Lexeme.Equals(stmt.Superclass.Name.Lexeme))
        {
            Lox.Error(stmt.Superclass.Name,
                      "A class can't inherit from itself.");
        }

        if (stmt.Superclass != null)
        {
            CurrentClass = ClassType.Subclass;
            Resolve(stmt.Superclass);
        }

        if (stmt.Superclass != null)
        {
            BeginScope();
            Scopes.Peek()["super"] = true;
        }

        BeginScope();
        Scopes.Peek()["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.Superclass != null)
        {
            EndScope();
        }

        CurrentClass = enclosingClass;
        return(null);
    }
예제 #5
0
        public IEnumerable <string> VisitClassStmt(Stmt.Class stmt)
        {
            yield return($"class {stmt.Name} {{");

            foreach (var method in stmt.Methods)
            {
                foreach (string line in PrintStmt(method))
                {
                    yield return($"  {line}");
                }
            }
            yield return("}");
        }
예제 #6
0
        public VoidObject VisitClassStmt(Stmt.Class stmt)
        {
            // TODO: Implement resolution related to classes: handle fields defined in the class, resolve method
            // TODO: arguments, etc.

            Declare(stmt.Name);

            var perlangClass = new PerlangClass(stmt.Name.Lexeme, stmt.Methods);

            DefineClass(stmt.Name, perlangClass);

            return(VoidObject.Void);
        }
예제 #7
0
파일: Resolver.cs 프로젝트: sisakat/cslox
        public object VisitClassStmt(Stmt.Class stmt)
        {
            var enclosingType = currentClass;

            currentClass = ClassType.CLASS;

            Declare(stmt.Name);
            Define(stmt.Name);

            if (stmt.Superclass != null &&
                stmt.Name.Lexeme == stmt.Superclass.Name.Lexeme)
            {
                throw new InterpretingException(stmt.Name,
                                                "A class cannot inherit from itself.");
            }

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

            if (stmt.Superclass != null)
            {
                BeginScope();
                scopes.Peek()["super"] = true;
            }

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

            foreach (var method in stmt.Methods)
            {
                var declaration = FunctionType.METHOD;
                if (method.Name.Lexeme == stmt.Name.Lexeme)
                {
                    declaration = FunctionType.INITIALIZER;
                }
                ResolveFunction(method, declaration);
            }

            EndScope();

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

            currentClass = enclosingType;
            return(null);
        }
예제 #8
0
파일: Resolver.cs 프로젝트: richsoft/CsLox
        /// <summary>
        /// Resolve a class declaration
        /// </summary>
        /// <param name="stmt">The statement</param>
        /// <returns></returns>
        public object Visit(Stmt.Class stmt)
        {
            Declare(stmt.Name);
            Define(stmt.Name);

            ClassType enclosing_class = _current_class;

            _current_class = ClassType.CLASS;

            // Superclass
            if (stmt.Superclass != null)
            {
                _current_class = ClassType.SUBCLASS;
                Resolve(stmt.Superclass);

                // Create a new super class scope
                BeginScope();
                _scopes.Peek().Put("super", true);
            }


            // This
            BeginScope();
            _scopes.Peek().Put("this", true);

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

                // Check if this is the initalizer
                if (method.Name.Lexeme.Equals("init"))
                {
                    declaration = FunctionType.INITIALIZER;
                }

                ResolveFunction(method, declaration);
            }

            EndScope();

            // If we have a superclass, we need to end that scope too
            if (stmt.Superclass != null)
            {
                EndScope();
            }

            _current_class = enclosing_class;

            return(null);
        }
예제 #9
0
        public object visitClassStmt(Stmt.Class stmt)
        {
            ClassType enclosingClass = currentClass;

            currentClass = ClassType.CLASS;

            declare(stmt.name);
            define(stmt.name);

            if (stmt.superclass != null && stmt.name.lexeme().Equals(stmt.superclass.name.lexeme()))
            {
                Interpreter.error(stmt.superclass.name, "A class cannot inherit from itself.");
            }

            if (stmt.superclass != null)
            {
                currentClass = ClassType.SUBCLASS;
                resolve(stmt.superclass);
            }

            if (stmt.superclass != null)
            {
                beginScope();
                scopes[scopes.Count - 1].Add("super", true);
            }

            beginScope();
            scopes[scopes.Count - 1].Add("this", true);

            foreach (Stmt.Function method in stmt.methods)
            {
                FunctionType declaration = FunctionType.TYPE_METHOD;
                if (method.name.lexeme().Equals("init"))
                {
                    declaration = FunctionType.TYPE_INITIALIZER;
                }
                resolveFunction(method, declaration);
            }

            endScope();

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

            currentClass = enclosingClass;
            return(null);
        }
예제 #10
0
        public string VisitClassStmt(Stmt.Class stmt)
        {
            StringBuilder builder = new();

            builder.Append("(class " + stmt.Name.Lexeme);

            foreach (Stmt.Function method in stmt.Methods)
            {
                builder.Append(" " + Print(method));
            }

            builder.Append(')');

            return(builder.ToString());
        }
예제 #11
0
        public object VisitClassStmt(Stmt.Class stmt)
        {
            var enclosingClass = _currentClass;

            _currentClass = ClassType.Class;

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

            if (stmt.superclass is not null)
            {
                if (stmt.name.Lexeme == stmt.superclass.name.Lexeme)
                {
                    Lox.Error(stmt.superclass.name, "A class can't inherit from itself.");
                }

                _currentClass = ClassType.Subclass;
                Resolve(stmt.superclass);

                BeginScope();
                _scopes.Peek()["super"] = new Variable(stmt.name, VariableState.Read);
            }

            BeginScope();
            _scopes.Peek()["this"] = new Variable(stmt.name, VariableState.Read);

            foreach (var method in stmt.methods)
            {
                var declaration = FunctionType.Method;
                if (method.name.Lexeme == "init")
                {
                    declaration = FunctionType.Initializer;
                }

                ResolveFunction(method.function, declaration);
            }

            EndScope();

            if (stmt.superclass is not null)
            {
                EndScope();
            }

            _currentClass = enclosingClass;

            return(null);
        }
예제 #12
0
        public Unit VisitClassStmt(Stmt.Class stmt)
        {
            ClassType enclosingClass = this.CurrentClass;

            CurrentClass = ClassType.CLASS;
            Declare(stmt.Name);
            Define(stmt.Name);

            if (stmt.SuperClass != null && stmt.Name.Lexeme == stmt.SuperClass.Name.Lexeme)
            {
                CSLox.Error(stmt.SuperClass.Name, "A class can't inherit from itself.");
            }
            /// Resolver doesn't resolve Global variables and that environment. (Where most inheritence will occur.)
            /// Lox allows delcaraions inside of existing blocks, and as they are variable must be resolved.
            if (stmt.SuperClass != null)
            {
                CurrentClass = ClassType.SUBCLASS;
                Resolve(stmt.SuperClass);
            }
            if (stmt.SuperClass != null)
            {
                BeginScope();
                Scopes.Peek().Add("super", true);
            }
            BeginScope();
            Scopes.Peek().Add("this", true);

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

                if (method.Name.Lexeme.Equals("init"))
                {
                    declaration = FunctionType.INITIALISER;
                }
                ResolveFunction(method, declaration);
            }

            EndScope();

            if (stmt.SuperClass != null)
            {
                EndScope();
            }
            this.CurrentClass = enclosingClass;
            return(new Unit());
        }
예제 #13
0
        public LoxVoid VisitClassStmt(Stmt.Class stmt)
        {
            Option <LoxClass> superclassOption = stmt.Superclass.Match(
                some: variableStmt =>
            {
                object superclassObj = Evalutate(variableStmt);
                if (superclassObj is LoxClass superclass)
                {
                    return(superclass.Some());
                }
                throw new RuntimeError(variableStmt.Name, "Superclass must be a class");
            },
                none: Option.None <LoxClass>
                );

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

            superclassOption.MatchSome(super =>
            {
                _environment = new Environment(_environment);
                _environment.Define("super", super);
            });

            Dictionary <string, LoxFunction> methods = stmt.Methods
                                                       .Select(method => (
                                                                   name: method.Name.Lexeme,
                                                                   method: new LoxFunction(method, _environment, method.Name.Lexeme == "init")
                                                                   ))
                                                       .ToDictionary(
                x => x.name,
                x => x.method
                );

            LoxClass @class = new LoxClass(stmt.Name.Lexeme, superclassOption, methods);

            superclassOption.MatchSome(super =>
            {
                _environment = _environment.Enclosing.Match(
                    some: env => env,
                    none: () => throw new Exception("Expected enclosing scope none found")
                    );
            });

            _environment.Assign(stmt.Name, @class);
            return(null);
        }
예제 #14
0
        public object VisitClassStmt(Stmt.Class stmt)
        {
            object superclass = null;

            if (stmt.Superclass != null)
            {
                superclass = Evaluate(stmt.Superclass);
                if (!(superclass is LoxClass))
                {
                    throw new InterpretingException(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)
            {
                var function = new LoxFunction(method,
                                               environment,
                                               method.Name.Lexeme == stmt.Name.Lexeme);
                methods[method.Name.Lexeme] = function;
            }

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

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

            environment.Assign(stmt.Name, lclass);
            return(null);
        }
예제 #15
0
    public object VisitClassStmt(Stmt.Class stmt)
    {
        object superclass = null;

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

            if (!(superclass is LoxClass))
            {
                throw new RuntimeException(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 (Stmt.Function 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);
    }
예제 #16
0
        public object VisitClassStmt(Stmt.Class stmt)
        {
            object superclass = null;

            if (stmt.superclass is not null)
            {
                superclass = Evaluate(stmt.superclass);
                if (superclass is not LoxClass)
                {
                    throw new RuntimeException(stmt.superclass.name, "Superclass must be a class.");
                }
            }

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

            if (stmt.superclass is not null)
            {
                _environment = new Environment(_environment);
                _environment.Define("super", superclass);
            }

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

            foreach (var method in stmt.methods)
            {
                var function = new LoxFunction(stmt.name, method.function, _environment, method.name.Lexeme == "init");
                methods[method.name.Lexeme] = function;
            }

            var clas = new LoxClass(stmt.name.Lexeme, superclass as LoxClass, methods);

            if (stmt.superclass is not null)
            {
                _environment = _environment.Enclosing;
            }

            _environment.Assign(stmt.name, clas);

            return(null);
        }
예제 #17
0
        public object Visit(Stmt.Class stmt)
        {
            _environment.Define(stmt.Name.Lexeme, null);

            // Superclass
            object superclass = null;

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

                _environment = new LoxEnvironment(_environment);
                _environment.Define("super", superclass);
            }


            // Methods
            HashMap <string, LoxFunction> methods = new HashMap <string, LoxFunction>();

            foreach (Stmt.Function method in stmt.Methods)
            {
                LoxFunction function = new LoxFunction(method, _environment, method.Name.Lexeme.Equals("init"));
                methods.Put(method.Name.Lexeme, function);
            }

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

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

            _environment.Assign(stmt.Name, @class);
            return(null);
        }
예제 #18
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 (Stmt.Function method in stmt.methods)
            {
                LoxFunction function = new LoxFunction(method, environment, method.name.lexeme().Equals("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);
        }
예제 #19
0
        public object visitClassStmt(Stmt.Class klass)
        {
            Token className = klass.name;

            captureToken(className);

            byte nameConstant = identifierConstant(className);

            declareVariable(className);

            emitBytes((byte)OpCode.OP_CLASS, nameConstant);
            defineVariable(nameConstant);

            ClassCompiler classCompiler = new ClassCompiler();

            classCompiler.name          = className;
            classCompiler.hasSuperclass = false;
            classCompiler.enclosing     = currentClass;
            currentClass = classCompiler;

            if (klass.superclass != null)
            {
                Token superName = klass.superclass.name;
                getNamedVariable(superName);

                if (identifiersEqual(className, superName))
                {
                    error("A class cannot inherit from itself.");
                }

                beginScope();
                addLocal(syntheticToken("super"));
                defineVariable(0);

                getNamedVariable(className);
                emitByte(OpCode.OP_INHERIT);
                classCompiler.hasSuperclass = true;
                currentClass = classCompiler; // CS ref fix
            }

            getNamedVariable(className);


            // stuff done in clox: method()
            foreach (Stmt.Function method in klass.methods)
            {
                Token methodName = method.name;

                captureToken(methodName);

                byte         constant = identifierConstant(methodName);
                FunctionType type     = FunctionType.TYPE_METHOD;

                if (methodName.length == 4 && util.util._memcmp(methodName._char_ptr, methodName.start, "init", 4))
                {
                    type = FunctionType.TYPE_INITIALIZER;
                }

                function(method, type);
                emitBytes((byte)OpCode.OP_METHOD, constant);
            }
            emitByte(OpCode.OP_POP);

            if (classCompiler.hasSuperclass)
            {
                endScope();
            }

            currentClass = currentClass.enclosing;

            return(null);
        }
예제 #20
0
파일: Resolver.cs 프로젝트: jukaLang/Juka
 public object VisitClassStmt(Stmt.Class stmt)
 {
     throw new NotImplementedException("Resolver VisitClassStmt is not implemented");
 }
예제 #21
0
 public TrashObject VisitClassStmt(Stmt.Class stmt)
 {
     return(this.ClassStmt(stmt));
 }
예제 #22
0
 public Stmt VisitClassStmt(Stmt.Class stmt)
 {
     throw new NotImplementedException();
 }