コード例 #1
0
ファイル: Compiler.cs プロジェクト: Moosemorals/csharp-lox
        private void Function(FunctionType type)
        {
            current = new Instance {
                type      = type,
                enclosing = current
            };
            current.function.name = ObjString.CopyString(parser.previous.Lexeme);

            BeginScope();

            Consume(TokenType.LeftParen, "Expect '(' after function name.");
            if (!Check(TokenType.RightParen))
            {
                do
                {
                    current.function.arity += 1;
                    if (current.function.arity > 255)
                    {
                        ErrorAtCurrent("Can't have more than 255 parameters.");
                    }

                    byte paramConst = ParseVariable("Expect parameter name.");
                    DefineVariable(paramConst);
                } while (Match(TokenType.Comma));
            }
            Consume(TokenType.RightParen, "Expect ')' after parameters.");

            Consume(TokenType.LeftBrace, "Expect '{' before function body.");
            Block();

            ObjFunction fun = EndCompiler();

            EmitBytes(OpCode.Constant, MakeConstant(Value.Obj(fun)));
        }
コード例 #2
0
ファイル: Compiler.cs プロジェクト: Moosemorals/csharp-lox
            internal Instance()
            {
                locals     = new Local[byte.MaxValue];
                localCount = 0;
                scopeDepth = 0;
                function   = new ObjFunction();

                locals[localCount++] = new Local {
                    depth = 0,
                    name  = new Token {
                        Lexeme = "",
                    }
                };
            }
コード例 #3
0
ファイル: Compiler.cs プロジェクト: Moosemorals/csharp-lox
        private ObjFunction EndCompiler()
        {
            EmitReturn();
            ObjFunction fun = current.function;

#if DEBUG
            if (!parser.hadError)
            {
                CurrentChunk().Disassemble(writer, fun.name == null ? "<script>" : fun.name.Chars);
            }
#endif
            current = current.enclosing;

            return(fun);
        }
コード例 #4
0
ファイル: Compiler.cs プロジェクト: Moosemorals/csharp-lox
        internal ObjFunction Compile(TextWriter writer, string source)
        {
            scanner          = new Scanner(source);
            this.writer      = writer;
            parser.hadError  = false;
            parser.panicMode = false;

            Advance();

            while (!Match(TokenType.Eof))
            {
                Declaration();
            }

            ObjFunction fun = EndCompiler();

            return(parser.hadError ? null : fun);
        }
コード例 #5
0
        private void RuntimeError(string format, params object[] args)
        {
            CallFrame frame = frames[frameCount - 1];

            int line = frame.function.chunk.GetLine(frame.ip);

            writer.WriteLine(format, args);

            for (int i = frameCount - 1; i >= 0; i -= 1)
            {
                CallFrame   f           = frames[i];
                ObjFunction func        = f.function;
                int         instruction = frame.ip - 1;
                writer.WriteLine($"[line {func.chunk.GetLine(instruction)} in {(func.name == null ? "<script>" : func.name.Chars)}");
            }


            ResetStack();
        }
コード例 #6
0
        private bool Call(ObjFunction function, int argCount)
        {
            if (argCount != function.arity)
            {
                RuntimeError("Expected {0} arguments but got {1}", function.arity, argCount);
                return(false);
            }

            if (frameCount == FramesMax)
            {
                RuntimeError("Stack overflow.");
                return(false);
            }

            frames[frameCount++] = new CallFrame {
                function = function,
                ip       = 0,
                slots    = stack.Slice(stackTop - argCount - 1),
            };

            return(true);
        }