FinishBody() private method

private FinishBody ( bool isConstructor ) : void
isConstructor bool
return void
Esempio n. 1
0
        // Compiles a method definition inside a class body. Returns the symbol in the
        // method table for the new method.
        private bool Method(ClassCompiler classCompiler, int classSlot)
        {

            bool isForeign = Match(TokenType.Foreign);
            classCompiler.IsStaticMethod = Match(TokenType.Static);

            SignatureFn signatureFn = GetRule(_parser.Current.Type).Method;
            NextToken();

            if (signatureFn == null)
            {
                Error("Expect method definition.");
                return false;
            }

            // Build the method signature.
            Signature signature = SignatureFromToken(new Signature(), SignatureType.Getter);
            classCompiler.Signature = signature;

            Compiler methodCompiler = new Compiler(_parser, this, false);
            signatureFn(methodCompiler, signature);

            if (classCompiler.IsStaticMethod && signature.Type == SignatureType.Initializer)
            {
                Error("A constructor cannot be static.");
            }

            String fullSignature = SignatureToString(signature);

            if (isForeign)
            {
                int constant = AddConstant(Obj.MakeString(fullSignature));

                EmitShortArg(Instruction.CONSTANT, constant);
            }
            else
            {
                Consume(TokenType.LeftBrace, "Expect '{' to begin method body.");
                methodCompiler.FinishBody(signature.Type == SignatureType.Initializer);
                methodCompiler.EndCompiler(fullSignature);
            }

            // Define the method. For a constructor, this defines the instance
            // initializer method.
            int methodSymbol = SignatureSymbol(signature);
            DefineMethod(classSlot, classCompiler.IsStaticMethod, methodSymbol);

            if (signature.Type == SignatureType.Initializer)
            {
                signature.Type = SignatureType.Method;
                int constructorSymbol = SignatureSymbol(signature);
                CreateConstructor(signature, methodSymbol);
                DefineMethod(classSlot, true, constructorSymbol);
            }

            return true;
        }
Esempio n. 2
0
        // Compiles a method definition inside a class body. Returns the symbol in the
        // method table for the new method.
        private bool Method(ClassCompiler classCompiler, int classSlot, out bool hasConstructor)
        {
            hasConstructor = false;

            bool isForeign = Match(TokenType.TOKEN_FOREIGN);
            classCompiler.isStaticMethod = Match(TokenType.TOKEN_STATIC);

            SignatureFn signatureFn = GetRule(parser.current.type).method;
            NextToken();

            if (signatureFn == null)
            {
                Error("Expect method definition.");
                return false;
            }

            // Build the method signature.
            Signature signature = SignatureFromToken(SignatureType.SIG_GETTER);
            classCompiler.signature = signature;

            Compiler methodCompiler = new Compiler(parser, this, false);
            signatureFn(methodCompiler, signature);

            if (classCompiler.isStaticMethod && signature.Type == SignatureType.SIG_INITIALIZER)
            {
                Error("A constructor cannot be static.");
            }

            String fullSignature = SignatureToString(signature);

            if (isForeign)
            {
                int constant = AddConstant(new Value(fullSignature));

                EmitShortArg(Instruction.CONSTANT, constant);
            }
            else
            {
                Consume(TokenType.TOKEN_LEFT_BRACE, "Expect '{' to begin method body.");
                methodCompiler.FinishBody(signature.Type == SignatureType.SIG_INITIALIZER);
                methodCompiler.EndCompiler(fullSignature);
            }

            // Define the method. For a constructor, this defines the instance
            // initializer method.
            int methodSymbol = SignatureSymbol(signature);
            DefineMethod(classSlot, classCompiler.isStaticMethod, methodSymbol);

            if (signature.Type == SignatureType.SIG_INITIALIZER)
            {
                signature.Type = SignatureType.SIG_METHOD;
                int constructorSymbol = SignatureSymbol(signature);
                CreateConstructor(signature, methodSymbol);
                DefineMethod(classSlot, true, constructorSymbol);

                hasConstructor = true;
            }

            return true;
        }
Esempio n. 3
0
        // Compiles an (optional) argument list and then calls it.
        private void MethodCall(Instruction instruction, Signature signature)
        {
            Signature called = new Signature { Type = SignatureType.Getter, Arity = 0, Name = signature.Name, Length = signature.Length };

            // Parse the argument list, if any.
            if (Match(TokenType.LeftParen))
            {
                called.Type = SignatureType.Method;

                // Allow empty an argument list.
                if (Peek() != TokenType.RightParen)
                {
                    FinishArgumentList(called);
                }
                Consume(TokenType.RightParen, "Expect ')' after arguments.");
            }

            // Parse the block argument, if any.
            if (Match(TokenType.LeftBrace))
            {
                // Include the block argument in the arity.
                called.Type = SignatureType.Method;
                called.Arity++;

                Compiler fnCompiler = new Compiler(_parser, this, true);

                // Make a dummy signature to track the arity.
                Signature fnSignature = new Signature { Arity = 0 };

                // Parse the parameter list, if any.
                if (Match(TokenType.Pipe))
                {
                    fnCompiler.FinishParameterList(fnSignature);
                    Consume(TokenType.Pipe, "Expect '|' after function parameters.");
                }

                fnCompiler._numParams = fnSignature.Arity;

                fnCompiler.FinishBody(false);

                String blockName = SignatureToString(called) + " block argument";
                fnCompiler.EndCompiler(blockName);
            }

            // TODO: Allow Grace-style mixfix methods?

            // If this is a super() call for an initializer, make sure we got an actual
            // argument list.
            if (signature.Type == SignatureType.Initializer)
            {
                if (called.Type != SignatureType.Method)
                {
                    Error("A superclass constructor must have an argument list.");
                }

                called.Type = SignatureType.Initializer;
            }

            CallSignature(instruction, called);
        }
Esempio n. 4
0
        // Compiles an (optional) argument list and then calls it.
        private void MethodCall(Instruction instruction, Signature signature)
        {
            Signature called = new Signature { Type = SignatureType.SIG_GETTER, Arity = 0, Name = signature.Name, Length = signature.Length };

            // Parse the argument list, if any.
            if (Match(TokenType.TOKEN_LEFT_PAREN))
            {
                called.Type = SignatureType.SIG_METHOD;

                // Allow empty an argument list.
                if (Peek() != TokenType.TOKEN_RIGHT_PAREN)
                {
                    FinishArgumentList(called);
                }
                Consume(TokenType.TOKEN_RIGHT_PAREN, "Expect ')' after arguments.");
            }

            // Parse the block argument, if any.
            if (Match(TokenType.TOKEN_LEFT_BRACE))
            {
                // Include the block argument in the arity.
                called.Type = SignatureType.SIG_METHOD;
                called.Arity++;

                Compiler fnCompiler = new Compiler(parser, this, true);

                // Make a dummy signature to track the arity.
                Signature fnSignature = new Signature { Arity = 0 };

                // Parse the parameter list, if any.
                if (Match(TokenType.TOKEN_PIPE))
                {
                    fnCompiler.FinishParameterList(fnSignature);
                    Consume(TokenType.TOKEN_PIPE, "Expect '|' after function parameters.");
                }

                fnCompiler.numParams = fnSignature.Arity;

                fnCompiler.FinishBody(false);

                String blockName = SignatureToString(called) + " block argument";
                fnCompiler.EndCompiler(blockName);
            }

            // TODO: Allow Grace-style mixfix methods?

            // If this is a super() call for an initializer, make sure we got an actual
            // argument list.
            if (signature.Type == SignatureType.SIG_INITIALIZER)
            {
                if (called.Type != SignatureType.SIG_METHOD)
                {
                    Error("A superclass constructor must have an argument list.");
                }

                called.Type = SignatureType.SIG_INITIALIZER;
            }

            CallSignature(instruction, called);
        }