Exemplo n.º 1
0
        /// <summary>
        /// Declares a method (a function in a class).
        /// Possible todo: merge this with FunctionDeclaration, as they share a lot of code.
        /// </summary>
        private void MethodDeclaration(string fnType, ELoxFunctionType fnType2)
        {
            Tokens.Consume(IDENTIFIER, $"Expect {fnType} name.");
            if (Tokens.Previous().Lexeme == "init")
            {
                fnType2 = ELoxFunctionType.TYPE_INITIALIZER;
            }
            string      fnName     = Tokens.Previous().Lexeme;
            int         fnLine     = LineOfLastToken;
            LoxCompiler fnCompiler = new LoxCompiler(Tokens, fnType2, fnName, this, _CurrentClass);

            fnCompiler.FunctionBody();
            fnCompiler.EndCompiler();
            EmitOpcode(fnLine, OP_LOAD_FUNCTION);
            EmitData(fnLine, (byte)fnCompiler.Arity);
            // EmitConstantIndex(MakeBitStrConstant(fnName), _FixupConstants); // has fixup
            AddFixup(fnLine, fnCompiler);
            EmitData(fnLine, (byte)fnCompiler._UpvalueCount);
            for (int i = 0; i < fnCompiler._UpvalueCount; i++)
            {
                EmitData(fnLine, (byte)(fnCompiler._UpvalueData[i].IsLocal ? 1 : 0));
                EmitData(fnLine, (byte)(fnCompiler._UpvalueData[i].Index));
            }
            EmitOpcode(fnLine, OP_METHOD);
            EmitConstantIndex(fnLine, MakeBitStrConstant(fnName), _FixupConstants); // has fixup
        }
Exemplo n.º 2
0
 private LoxCompiler(TokenList tokens, ELoxFunctionType type, string name, LoxCompiler enclosing, LoxCompilerClass enclosingClass)
     : base(tokens, name)
 {
     _FunctionType      = type;
     Arity              = 0;
     _Chunk             = new GearsChunk(name);
     _Rules             = new List <Rule>();
     _EnclosingCompiler = enclosing;
     _CurrentClass      = enclosingClass;
     // stack slot zero is used for 'this' reference in methods, and is empty for script/functions:
     if (type != ELoxFunctionType.TYPE_FUNCTION)
     {
         _LocalVarData[_LocalCount++] = new LoxCompilerLocal("this", 0);
     }
     else
     {
         _LocalVarData[_LocalCount++] = new LoxCompilerLocal(string.Empty, 0);
     }
 }
Exemplo n.º 3
0
        /// <summary>
        /// function    → IDENTIFIER "(" parameters? ")" block ;
        /// parameters  → IDENTIFIER( "," IDENTIFIER )* ;
        /// </summary>
        private void FunctionDeclaration(string fnType, ELoxFunctionType fnType2)
        {
            int global = ParseVariable($"Expect {fnType} name.");

            MarkInitialized();
            string      fnName     = Tokens.Previous().Lexeme;
            int         fnLine     = LineOfLastToken;
            LoxCompiler fnCompiler = new LoxCompiler(Tokens, fnType2, fnName, this, _CurrentClass);

            fnCompiler.FunctionBody();
            fnCompiler.EndCompiler();
            EmitOpcode(fnLine, OP_LOAD_FUNCTION);
            EmitData(fnLine, (byte)fnCompiler.Arity);
            // EmitConstantIndex(MakeBitStrConstant(fnName), _FixupConstants); // has fixup
            AddFixup(fnLine, fnCompiler);
            // EmitOpcode(OP_CLOSURE);
            EmitData(fnLine, (byte)fnCompiler._UpvalueCount);
            for (int i = 0; i < fnCompiler._UpvalueCount; i++)
            {
                EmitData(fnLine, (byte)(fnCompiler._UpvalueData[i].IsLocal ? 1 : 0));
                EmitData(fnLine, (byte)(fnCompiler._UpvalueData[i].Index));
            }
            DefineVariable(fnLine, global);
        }