Ejemplo n.º 1
0
        private void Resolve(Stmt statement)
        {
            if (statement is BlockStmt block)
            {
                BeginScope();
                Resolve(block.Statements);
                EndScope();
            }
            else if (statement is VariableStmt variable)
            {
                Declare(variable.Name);
                if (variable.Initializer != null)
                {
                    Resolve(variable.Initializer);
                }
                Define(variable.Name);
            }
            else if (statement is FunctionStmt functionStatement)
            {
                Declare(functionStatement.Name);
                Define(functionStatement.Name);

                ResolveFunction(functionStatement, FunctionType.Function);
            }
            else if (statement is ConditionalStmt conditional)
            {
                Resolve(conditional.Condition);
                Resolve(conditional.ThenBranch);
                if (conditional.ElseBranch != null)
                {
                    Resolve(conditional.ElseBranch);
                }
            }
            else if (statement is ReturnStmt returnStmt)
            {
                if (currentFunction == FunctionType.None)
                {
                    Program.Error(returnStmt.Keyword, "Cannot return from top-level code.");
                }

                if (returnStmt.Value != null)
                {
                    if (currentFunction == FunctionType.Initializer)
                    {
                        Program.Error(returnStmt.Keyword, "Cannot return a value from an initializer.");
                    }
                    Resolve(returnStmt.Value);
                }
            }
            else if (statement is WhileStmt whileStmt)
            {
                Resolve(whileStmt.Condition);
                Resolve(whileStmt.Body);
            }
            else if (statement is ExpressionStmt expression)
            {
                Resolve(expression.Expression);
            }
            else if (statement is PrintStmt print)
            {
                Resolve(print.Expression);
            }
            else if (statement is ClassStmt cls)
            {
                var enclosingClass = currentClass;
                currentClass = ClassType.Class;

                Declare(cls.Name);
                Define(cls.Name);

                if (cls.Superclass != null && cls.Name.Lexeme.Equals(cls.Superclass.Name.Lexeme))
                {
                    Program.Error(cls.Superclass.Name, "A class cannot inherit from itself.");
                }

                if (cls.Superclass != null)
                {
                    currentClass = ClassType.Subclass;
                    Resolve(cls.Superclass);
                }

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

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

                foreach (var method in cls.Methods)
                {
                    var declaration = method.Name.Lexeme.Equals(LoxClass.ConstructorName) ? FunctionType.Initializer : FunctionType.Method;
                    ResolveFunction(method, declaration);
                }

                EndScope();

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

                currentClass = enclosingClass;
            }
            else
            {
                // After print statment was forgotten
                throw new System.Exception("You have forgotten something, haven't you?");
            }
        }
Ejemplo n.º 2
0
 private Unit execute(Stmt stmt) => stmt.accept(this);
Ejemplo n.º 3
0
 public If(Expr condition, Stmt thenBranch, Stmt elseBranch)
 {
     this.condition  = condition;
     this.thenBranch = thenBranch;
     this.elseBranch = elseBranch;
 }
Ejemplo n.º 4
0
        private void Execute(Stmt statement)
        {
            if (statement is PrintStmt p)
            {
                Print(p.Expression);
                return;
            }
            if (statement is VariableStmt s)
            {
                object value = s.Initializer is null ? null : Evaluate(s.Initializer);

                env.Define(s.Name.Lexeme, value);
                return;
            }
            if (statement is ExpressionStmt e)
            {
                Discard(e.Expression);
                return;
            }
            if (statement is BlockStmt b)
            {
                ExecuteBlock(b.Statements, new Environment(env));
                return;
            }
            if (statement is ConditionalStmt c)
            {
                if (IsTruthy(Evaluate(c.Condition)))
                {
                    Execute(c.ThenBranch);
                }
                else if (c.ElseBranch != null)
                {
                    Execute(c.ElseBranch);
                }
                return;
            }
            if (statement is WhileStmt w)
            {
                while (IsTruthy(Evaluate(w.Condition)))
                {
                    Execute(w.Body);
                }
                return;
            }
            if (statement is FunctionStmt f)
            {
                var fn = new LoxFunction(f, env, false);
                env.Define(f.Name.Lexeme, fn);
                return;
            }
            if (statement is ClassStmt cl)
            {
                LoxClass superclass = null;
                if (cl.Superclass != null)
                {
                    var scls = Evaluate(cl.Superclass);
                    if (scls is LoxClass super)
                    {
                        superclass = super;
                    }
                    else
                    {
                        throw new RuntimeException(cl.Superclass.Name, "Superclass must be a class.");
                    }
                }

                env.Define(cl.Name.Lexeme, null);

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

                var methods = new Dictionary <string, LoxFunction>();
                foreach (var method in cl.Methods)
                {
                    var func = new LoxFunction(method, env, method.Name.Lexeme.Equals(LoxClass.ConstructorName));
                    methods.Add(method.Name.Lexeme, func);
                }

                var cls = new LoxClass(cl.Name.Lexeme, superclass, methods);

                if (cl.Superclass != null)
                {
                    env = env.Enclosing;
                }

                env.Assign(cl.Name, cls);
                return;
            }
            if (statement is ReturnStmt r)
            {
                object value = null;
                if (r.Value != null)
                {
                    value = Evaluate(r.Value);
                }
                throw new ReturnException(value);
            }
            throw new RuntimeException("Unknown statement type.");
        }
Ejemplo n.º 5
0
 public While(Expr condition, Stmt body)
 {
     this.condition = condition;
     this.body      = body;
 }