示例#1
0
        private static void initCompiler(ref Compiler_t compiler, FunctionType type)
        {
            compiler.enclosing  = current;
            compiler.function   = null;
            compiler.type       = type;
            compiler.localCount = 0;
            compiler.scopeDepth = 0;
            compiler.function   = Object.newFunction();
            current             = compiler;

            if (type != FunctionType.TYPE_SCRIPT)
            {
                current.function.name = Object.copyString(parser.previous._char_ptr, parser.previous.start, parser.previous.length);
            }

            Local local = current.locals[current.localCount++];

            local.depth      = 0;
            local.isCaptured = false;

            if (type != FunctionType.TYPE_FUNCTION)
            {
                local.name._char_ptr = "this\0".ToCharArray();
                local.name.start     = 0;
                local.name.length    = 4;
            }
            else
            {
                local.name._char_ptr = new char[] { '\0' };
                local.name.start     = 0;
                local.name.length    = 0;
            }

            current.locals[current.localCount - 1] = local; // C sharp fix.
        }
示例#2
0
        public static void markCompilerRoots()
        {
            Compiler_t compiler = current;

            while (compiler != null)
            {
                Memory.markObject((Obj)compiler.function);
                compiler = compiler.enclosing;
            }
        }
示例#3
0
 private static int resolveLocal(ref Compiler_t compiler, ref Token name)
 {
     for (int i = compiler.localCount - 1; i >= 0; i--)
     {
         Local local = compiler.locals[i];
         if (identifiersEqual(ref name, ref local.name))
         {
             if (local.depth == -1)
             {
                 error("Cannot read local variable in its own intializer.");
             }
             return(i);
         }
     }
     return(-1);
 }
示例#4
0
        private static ObjFunction endCompiler()
        {
            emitReturn();
            ObjFunction function = current.function;

#if DEBUG_PRINT_CODE
            if (!parser.hadError)
            {
                Chunk_t _chunk = currentChunk();
                Debug.disassembleChunk(ref _chunk, function.name != null ? function.name.chars : "<script>".ToCharArray());
            }
#endif

            current = current.enclosing;
            return(function);
        }
示例#5
0
        private static void function(FunctionType type)
        {
            Compiler_t compiler = new Compiler_t();

            initCompiler(ref compiler, type);
            beginScope();

            // Compile parameter list.
            consume(TokenType.TOKEN_LEFT_PAREN, "Expect '(' after function name.");
            if (!check(TokenType.TOKEN_RIGHT_PAREN))
            {
                do
                {
                    current.function.arity++;
                    if (current.function.arity > 255)
                    {
                        errorAtCurrent("Cannot have more than 255 parameters.");
                    }

                    byte paramConstant = parseVariable("Expect parameter name.");
                    defineVariable(paramConstant);
                }while (match(TokenType.TOKEN_COMMA));
            }
            consume(TokenType.TOKEN_RIGHT_PAREN, "Expect ')' after parameters.");

            // The body.
            consume(TokenType.TOKEN_LEFT_BRACE, "Expect '{' before funciton body.");
            block();

            // Create the function object.
            ObjFunction function = endCompiler();

            emitBytes((byte)OpCode.OP_CLOSURE, makeConstant(Value.OBJ_VAL(function)));

            for (int i = 0; i < function.upvalueCount; i++)
            {
                emitByte((byte)(compiler.upvalues[i].isLocal ? 1 : 0));
                emitByte(compiler.upvalues[i].index);
            }
        }
示例#6
0
        public static ObjFunction compile(char[] source)
        {
            Scanner.initScanner(source);

            Compiler_t compiler = new Compiler_t();

            initCompiler(ref compiler, FunctionType.TYPE_SCRIPT);

            parser.hadError  = false;
            parser.panicMode = false;

            advance();

            while (!match(TokenType.TOKEN_EOF))
            {
                declaration();
            }

            ObjFunction function = endCompiler();

            return(parser.hadError ? null : function);
        }
示例#7
0
        private static int addUpvalue(ref Compiler_t compiler, byte index, bool isLocal)
        {
            int upvalueCount = compiler.function.upvalueCount;

            for (int i = 0; i < upvalueCount; i++)
            {
                Upvalue upvalue = compiler.upvalues[i];
                if (upvalue.index == index && upvalue.isLocal == isLocal)
                {
                    return(i);
                }
            }

            if (upvalueCount == UINT8_COUNT)
            {
                error("Too many closure variables in function.");
                return(0);
            }

            compiler.upvalues[upvalueCount].isLocal = isLocal;
            compiler.upvalues[upvalueCount].index   = index;
            return(compiler.function.upvalueCount++);
        }
示例#8
0
        private static int resolveUpvalue(ref Compiler_t compiler, ref Token name)
        {
            if (compiler.enclosing == null)
            {
                return(-1);
            }

            int local = resolveLocal(ref compiler.enclosing, ref name);

            if (local != -1)
            {
                compiler.enclosing.locals[local].isCaptured = true;
                return(addUpvalue(ref compiler, (byte)local, true));
            }

            int upvalue = resolveUpvalue(ref compiler.enclosing, ref name);

            if (upvalue != -1)
            {
                return(addUpvalue(ref compiler, (byte)upvalue, false));
            }

            return(-1);
        }