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))); }
internal Instance() { locals = new Local[byte.MaxValue]; localCount = 0; scopeDepth = 0; function = new ObjFunction(); locals[localCount++] = new Local { depth = 0, name = new Token { Lexeme = "", } }; }
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); }
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); }
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(); }
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); }